Oncodrive3D 1.0.4__py3-none-any.whl
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.
- oncodrive3d-1.0.4.dist-info/METADATA +333 -0
- oncodrive3d-1.0.4.dist-info/RECORD +36 -0
- oncodrive3d-1.0.4.dist-info/WHEEL +4 -0
- oncodrive3d-1.0.4.dist-info/entry_points.txt +5 -0
- oncodrive3d-1.0.4.dist-info/licenses/LICENSE +15 -0
- scripts/__init__.py +2 -0
- scripts/clustering_3d.code-workspace +7 -0
- scripts/datasets/__init__.py +0 -0
- scripts/datasets/af_merge.py +344 -0
- scripts/datasets/build_datasets.py +125 -0
- scripts/datasets/get_pae.py +78 -0
- scripts/datasets/get_structures.py +107 -0
- scripts/datasets/model_confidence.py +97 -0
- scripts/datasets/parse_pae.py +64 -0
- scripts/datasets/prob_contact_maps.py +258 -0
- scripts/datasets/seq_for_mut_prob.py +900 -0
- scripts/datasets/utils.py +394 -0
- scripts/globals.py +169 -0
- scripts/main.py +650 -0
- scripts/plotting/__init__.py +0 -0
- scripts/plotting/build_annotations.py +102 -0
- scripts/plotting/chimerax_plot.py +251 -0
- scripts/plotting/pdb_tool.py +149 -0
- scripts/plotting/pfam.py +94 -0
- scripts/plotting/plot.py +2484 -0
- scripts/plotting/stability_change.py +184 -0
- scripts/plotting/uniprot_feat.py +276 -0
- scripts/plotting/utils.py +594 -0
- scripts/run/__init__.py +0 -0
- scripts/run/clustering.py +749 -0
- scripts/run/communities.py +53 -0
- scripts/run/miss_mut_prob.py +206 -0
- scripts/run/mutability.py +289 -0
- scripts/run/pvalues.py +91 -0
- scripts/run/score_and_simulations.py +155 -0
- scripts/run/utils.py +461 -0
scripts/main.py
ADDED
|
@@ -0,0 +1,650 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Oncodrive3D is a fast and accurate computational method designed to analyze
|
|
5
|
+
patterns of somatic mutation across tumors, with the goal of identifying
|
|
6
|
+
three-dimensional (3D) clusters of missense mutations and detecting genes
|
|
7
|
+
under positive selection. The method leverages AlphaFold 2-predicted protein
|
|
8
|
+
structures and Predicted Aligned Error (PAE) to define residue contacts
|
|
9
|
+
within the protein's 3D space. When available, it also integrates mutational
|
|
10
|
+
profiles to build an accurate background model of neutral mutagenesis, which
|
|
11
|
+
is used to score potential clusters and simulate synthetic mutations.
|
|
12
|
+
By applying a novel rank-based statistical approach, Oncodrive3D scores
|
|
13
|
+
potential 3D clusters and computes empirical p-values."
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import os
|
|
17
|
+
import click
|
|
18
|
+
import daiquiri
|
|
19
|
+
import numpy as np
|
|
20
|
+
|
|
21
|
+
from scripts import __logger_name__, __version__
|
|
22
|
+
from scripts.globals import DATE, setup_logging_decorator, startup_message
|
|
23
|
+
|
|
24
|
+
logger = daiquiri.getLogger(__logger_name__)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@click.group(context_settings={'help_option_names': ['-h', '--help']})
|
|
28
|
+
@click.version_option(__version__)
|
|
29
|
+
def oncodrive3D():
|
|
30
|
+
"""
|
|
31
|
+
Oncodrive3D: software for the identification of 3D-clustering
|
|
32
|
+
of missense mutations for cancer driver genes detection.
|
|
33
|
+
"""
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# =============================================================================
|
|
38
|
+
# BUILD DATASETS
|
|
39
|
+
# =============================================================================
|
|
40
|
+
|
|
41
|
+
@oncodrive3D.command(context_settings=dict(help_option_names=['-h', '--help']),
|
|
42
|
+
help="Build datasets - Required once after installation.")
|
|
43
|
+
@click.option("-o", "--output_dir",
|
|
44
|
+
help="Directory where to save the files", type=str, default='datasets')
|
|
45
|
+
@click.option("-s", "--organism", type=click.Choice(["Homo sapiens", 'human', "Mus musculus", 'mouse']),
|
|
46
|
+
help="Organism name", default="Homo sapiens")
|
|
47
|
+
@click.option("-m", "--mane",
|
|
48
|
+
help="Use structures predicted from MANE Select transcripts (Homo sapiens only)", is_flag=True)
|
|
49
|
+
@click.option("-M", "--mane_version", default=1.3,
|
|
50
|
+
help="Version of the MANE Select release from NCBI")
|
|
51
|
+
@click.option("-d", "--distance_threshold", type=click.INT, default=10,
|
|
52
|
+
help="Distance threshold (Å) to define contact between amino acids")
|
|
53
|
+
@click.option("-c", "--cores", type=click.IntRange(min=1, max=len(os.sched_getaffinity(0)), clamp=False), default=len(os.sched_getaffinity(0)),
|
|
54
|
+
help="Number of cores to use in the computation")
|
|
55
|
+
@click.option("--af_version", type=click.IntRange(min=1, max=4, clamp=False), default=4,
|
|
56
|
+
help="Version of AlphaFold 2 predictions")
|
|
57
|
+
@click.option("-y", "--yes",
|
|
58
|
+
help="No interaction", is_flag=True)
|
|
59
|
+
@click.option("-v", "--verbose",
|
|
60
|
+
help="Verbose", is_flag=True)
|
|
61
|
+
@setup_logging_decorator
|
|
62
|
+
def build_datasets(output_dir,
|
|
63
|
+
organism,
|
|
64
|
+
mane,
|
|
65
|
+
distance_threshold,
|
|
66
|
+
cores,
|
|
67
|
+
af_version,
|
|
68
|
+
mane_version,
|
|
69
|
+
yes,
|
|
70
|
+
verbose):
|
|
71
|
+
""""Build datasets necessary to run Oncodrive3D."""
|
|
72
|
+
|
|
73
|
+
from scripts.datasets.build_datasets import build
|
|
74
|
+
|
|
75
|
+
startup_message(__version__, "Initializing building datasets..")
|
|
76
|
+
|
|
77
|
+
logger.info(f"Current working directory: {os.getcwd()}")
|
|
78
|
+
logger.info(f"Build folder path: {output_dir}")
|
|
79
|
+
logger.info(f"Organism: {organism}")
|
|
80
|
+
logger.info(f"MANE Select: {mane}")
|
|
81
|
+
logger.info(f"Distance threshold: {distance_threshold}Å")
|
|
82
|
+
logger.info(f"CPU cores: {cores}")
|
|
83
|
+
logger.info(f"AlphaFold version: {af_version}")
|
|
84
|
+
logger.info(f"MANE version: {mane_version}")
|
|
85
|
+
logger.info(f"Verbose: {verbose}")
|
|
86
|
+
logger.info(f'Log path: {os.path.join(output_dir, "log")}')
|
|
87
|
+
logger.info("")
|
|
88
|
+
|
|
89
|
+
build(output_dir,
|
|
90
|
+
organism,
|
|
91
|
+
mane,
|
|
92
|
+
distance_threshold,
|
|
93
|
+
cores,
|
|
94
|
+
af_version,
|
|
95
|
+
mane_version)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
# =============================================================================
|
|
100
|
+
# RUN
|
|
101
|
+
# =============================================================================
|
|
102
|
+
|
|
103
|
+
@oncodrive3D.command(context_settings=dict(help_option_names=['-h', '--help']),
|
|
104
|
+
help="Run 3D-clustering analysis.")
|
|
105
|
+
@click.option("-i", "--input_path", type=click.Path(exists=True), required=True,
|
|
106
|
+
help="Path of the MAF file (or direct VEP output) used as input")
|
|
107
|
+
@click.option("-p", "--mut_profile_path", type=click.Path(exists=True),
|
|
108
|
+
help="Path of the mutation profile (192 trinucleotide contexts) used as optional input")
|
|
109
|
+
@click.option("-m", "--mutability_config_path", type=click.Path(exists=True),
|
|
110
|
+
help="Path of the config file with information on mutability")
|
|
111
|
+
@click.option("-o", "--output_dir", type=str, default='output',
|
|
112
|
+
help="Path to output directory")
|
|
113
|
+
@click.option("-d", "--data_dir", type=click.Path(exists=True), default = os.path.join('datasets'),
|
|
114
|
+
help="Path to datasets")
|
|
115
|
+
@click.option("-n", "--n_iterations", type=int, default=10000,
|
|
116
|
+
help="Number of densities to be simulated")
|
|
117
|
+
@click.option("-a", "--alpha", type=float, default=0.01,
|
|
118
|
+
help="Significant threshold for the p-value of res and gene")
|
|
119
|
+
@click.option("-P", "--cmap_prob_thr", type=float, default=0.5,
|
|
120
|
+
help="Threshold to define AAs contacts based on distance on predicted structure and PAE")
|
|
121
|
+
@click.option("-c", "--cores", type=click.IntRange(min=1, max=len(os.sched_getaffinity(0)), clamp=False), default=len(os.sched_getaffinity(0)),
|
|
122
|
+
help="Set the number of cores to use in the computation")
|
|
123
|
+
@click.option("-s", "--seed", type=int,
|
|
124
|
+
help="Set seed to ensure reproducible results")
|
|
125
|
+
@click.option("-v", "--verbose",
|
|
126
|
+
help="Verbose", is_flag=True)
|
|
127
|
+
@click.option("-t", "--cancer_type",
|
|
128
|
+
help="Cancer type", type=str)
|
|
129
|
+
@click.option("-C", "--cohort",
|
|
130
|
+
help="Name of the cohort", type=str)
|
|
131
|
+
@click.option("--no_fragments", is_flag=True,
|
|
132
|
+
help="Disable processing of fragmented (AF-F) proteins")
|
|
133
|
+
@click.option("--only_processed", is_flag=True,
|
|
134
|
+
help="Include only processed genes in the output")
|
|
135
|
+
@click.option("--thr_mapping_issue", type=float, default=0.1,
|
|
136
|
+
help="Threshold to filter out genes by the ratio of mutations with mapping issue (out of structure, WT AA mismatch, zero prob to mutate). Threshold of 1 disable any WT AA mismatch mutations filtering.")
|
|
137
|
+
@click.option("--o3d_transcripts", is_flag=True,
|
|
138
|
+
help="Filter mutations by keeping transcripts included in Oncodrive3D built sequence dataframe. Only if input file (--i) is a raw VEP output")
|
|
139
|
+
@click.option("--use_input_symbols", is_flag=True,
|
|
140
|
+
help="Update HUGO symbols in Oncodrive3D built datasets by using input file entries. Only if input file (--i) is a raw VEP output")
|
|
141
|
+
@click.option("--mane", is_flag=True,
|
|
142
|
+
help="If multiple structures are associated to the same HUGO symbol in the input file, use the MANE ones.")
|
|
143
|
+
@click.option("--sample_info", is_flag=True,
|
|
144
|
+
help="Include sample information in position-level result (currently unavailable).") # TODO: enable sample info in output
|
|
145
|
+
@setup_logging_decorator
|
|
146
|
+
def run(input_path,
|
|
147
|
+
mut_profile_path,
|
|
148
|
+
mutability_config_path,
|
|
149
|
+
output_dir,
|
|
150
|
+
data_dir,
|
|
151
|
+
n_iterations,
|
|
152
|
+
alpha,
|
|
153
|
+
cmap_prob_thr,
|
|
154
|
+
cores,
|
|
155
|
+
seed,
|
|
156
|
+
verbose,
|
|
157
|
+
cancer_type,
|
|
158
|
+
cohort,
|
|
159
|
+
no_fragments,
|
|
160
|
+
only_processed,
|
|
161
|
+
thr_mapping_issue,
|
|
162
|
+
o3d_transcripts,
|
|
163
|
+
use_input_symbols,
|
|
164
|
+
mane,
|
|
165
|
+
sample_info):
|
|
166
|
+
"""Run Oncodrive3D."""
|
|
167
|
+
|
|
168
|
+
from scripts.run.clustering import run_clustering
|
|
169
|
+
|
|
170
|
+
# Initialize
|
|
171
|
+
plddt_path = os.path.join(data_dir, "confidence.tsv")
|
|
172
|
+
cmap_path = os.path.join(data_dir, "prob_cmaps")
|
|
173
|
+
seq_df_path = os.path.join(data_dir, "seq_for_mut_prob.tsv")
|
|
174
|
+
pae_path = os.path.join(data_dir, "pae")
|
|
175
|
+
cancer_type = cancer_type if cancer_type else np.nan
|
|
176
|
+
cohort = cohort if cohort else f"cohort_{DATE}"
|
|
177
|
+
path_prob = mut_profile_path if mut_profile_path else "Not provided, mutabilities will be used" if mutability_config_path else "Not provided, uniform distribution will be used"
|
|
178
|
+
path_mutability_config = mutability_config_path if mutability_config_path else "Not provided, mutabilities will not be used"
|
|
179
|
+
|
|
180
|
+
# Log
|
|
181
|
+
startup_message(__version__, "Initializing analysis..")
|
|
182
|
+
|
|
183
|
+
logger.info(f"Input MAF: {input_path}")
|
|
184
|
+
logger.info(f"Input mut profile: {path_prob}")
|
|
185
|
+
logger.info(f"Input mutability config: {path_mutability_config}")
|
|
186
|
+
logger.info(f"Build directory: {data_dir}")
|
|
187
|
+
logger.info(f"Output directory: {output_dir}")
|
|
188
|
+
logger.debug(f"Path to CMAPs: {cmap_path}")
|
|
189
|
+
logger.debug(f"Path to DNA sequences: {seq_df_path}")
|
|
190
|
+
logger.debug(f"Path to PAE: {pae_path}")
|
|
191
|
+
logger.debug(f"Path to pLDDT scores: {plddt_path}")
|
|
192
|
+
logger.info(f"CPU cores: {cores}")
|
|
193
|
+
logger.info(f"Iterations: {n_iterations}")
|
|
194
|
+
logger.info(f"Significant level: {alpha}")
|
|
195
|
+
logger.info(f"Probability threshold for CMAPs: {cmap_prob_thr}")
|
|
196
|
+
logger.info(f"Cohort: {cohort}")
|
|
197
|
+
logger.info(f"Cancer type: {cancer_type}")
|
|
198
|
+
logger.info(f"Disable fragments: {no_fragments}")
|
|
199
|
+
logger.info(f"Output only processed genes: {only_processed}")
|
|
200
|
+
logger.info(f"Ratio threshold mutations with mapping issue: {thr_mapping_issue}")
|
|
201
|
+
logger.info(f"Seed: {seed}")
|
|
202
|
+
logger.info(f"Filter input by Oncodrive3D transcripts: {o3d_transcripts}")
|
|
203
|
+
logger.info(f"Use HUGO symbols of input file: {use_input_symbols}")
|
|
204
|
+
logger.info(f"Prioritize MANE transcripts when using input HUGO symbols: {mane}")
|
|
205
|
+
logger.info(f"Include sample informations in output: {sample_info}")
|
|
206
|
+
logger.info(f"Verbose: {verbose}")
|
|
207
|
+
logger.info(f'Log path: {os.path.join(output_dir, "log")}')
|
|
208
|
+
logger.info("")
|
|
209
|
+
|
|
210
|
+
run_clustering(input_path,
|
|
211
|
+
mut_profile_path,
|
|
212
|
+
mutability_config_path,
|
|
213
|
+
output_dir,
|
|
214
|
+
cmap_path,
|
|
215
|
+
seq_df_path,
|
|
216
|
+
plddt_path,
|
|
217
|
+
pae_path,
|
|
218
|
+
n_iterations,
|
|
219
|
+
alpha,
|
|
220
|
+
cmap_prob_thr,
|
|
221
|
+
cores,
|
|
222
|
+
seed,
|
|
223
|
+
verbose,
|
|
224
|
+
cancer_type,
|
|
225
|
+
cohort,
|
|
226
|
+
no_fragments,
|
|
227
|
+
only_processed,
|
|
228
|
+
thr_mapping_issue,
|
|
229
|
+
o3d_transcripts,
|
|
230
|
+
use_input_symbols,
|
|
231
|
+
mane,
|
|
232
|
+
sample_info)
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
# =============================================================================
|
|
237
|
+
# BUILD ANNOTATIONS
|
|
238
|
+
# =============================================================================
|
|
239
|
+
|
|
240
|
+
@oncodrive3D.command(context_settings=dict(help_option_names=['-h', '--help']),
|
|
241
|
+
help="Build annotations - Required (once) only to plot annotations.")
|
|
242
|
+
@click.option("-d", "--data_dir", help="Path to datasets", type=str, required=True)
|
|
243
|
+
@click.option("-o", "--output_dir", help="Path to dir where to store annotations", type=str, default="annotations")
|
|
244
|
+
@click.option("-g", "--ddg_dir", help="Path to custom ddG predictions", type=str)
|
|
245
|
+
#@click.option("-S", "--path_pdb_tool_sif", help="Path to the PDB_Tool SIF", type=str, required=True)
|
|
246
|
+
@click.option("-s", "--organism", type=click.Choice(["Homo sapiens", 'human', "Mus musculus", 'mouse']), help="Organism name", default="Homo sapiens")
|
|
247
|
+
@click.option("-c", "--cores", type=click.IntRange(min=1, max=len(os.sched_getaffinity(0)), clamp=False), default=len(os.sched_getaffinity(0)),
|
|
248
|
+
help="Number of cores to use in the computation")
|
|
249
|
+
@click.option("-y", "--yes", help="No interaction", is_flag=True)
|
|
250
|
+
@click.option("-v", "--verbose", help="Verbose", is_flag=True)
|
|
251
|
+
@setup_logging_decorator
|
|
252
|
+
def build_annotations(data_dir,
|
|
253
|
+
output_dir,
|
|
254
|
+
ddg_dir,
|
|
255
|
+
#path_pdb_tool_sif,
|
|
256
|
+
organism,
|
|
257
|
+
cores,
|
|
258
|
+
yes,
|
|
259
|
+
verbose):
|
|
260
|
+
"""
|
|
261
|
+
Build datasets to plot protein annotations.
|
|
262
|
+
"""
|
|
263
|
+
|
|
264
|
+
startup_message(__version__, "Initializing building annotations..")
|
|
265
|
+
|
|
266
|
+
logger.info(f"Output directory: {output_dir}")
|
|
267
|
+
logger.info(f"Path to datasets: {data_dir}")
|
|
268
|
+
logger.info(f"Path to custom ddG predictions: {ddg_dir}")
|
|
269
|
+
#logger.info(f"Path to PDB_Tool SIF: {path_pdb_tool_sif}")
|
|
270
|
+
logger.info(f"Organism: {organism}")
|
|
271
|
+
logger.info(f"Cores: {cores}")
|
|
272
|
+
logger.info(f"Verbose: {bool(verbose)}")
|
|
273
|
+
logger.info(f'Log path: {os.path.join(output_dir, "log")}')
|
|
274
|
+
logger.info("")
|
|
275
|
+
|
|
276
|
+
from scripts.plotting.build_annotations import get_annotations
|
|
277
|
+
|
|
278
|
+
get_annotations(data_dir,
|
|
279
|
+
output_dir,
|
|
280
|
+
ddg_dir,
|
|
281
|
+
#path_pdb_tool_sif,
|
|
282
|
+
organism,
|
|
283
|
+
cores)
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
# =============================================================================
|
|
288
|
+
# PLOT
|
|
289
|
+
# =============================================================================
|
|
290
|
+
|
|
291
|
+
@oncodrive3D.command(context_settings=dict(help_option_names=['-h', '--help']),
|
|
292
|
+
help="Generate plots for a quick interpretation of the 3D-clustering analysis.")
|
|
293
|
+
@click.option("-g", "--gene_result_path", type=click.Path(exists=True), required=True,
|
|
294
|
+
help="Path to genes-level O3D result")
|
|
295
|
+
@click.option("-p", "--pos_result_path", type=click.Path(exists=True), required=True,
|
|
296
|
+
help="Path to positions-level O3D result")
|
|
297
|
+
@click.option("-i", "--maf_path", type=click.Path(exists=True), required=True,
|
|
298
|
+
help="Path to input mutations file")
|
|
299
|
+
@click.option("-m", "--miss_prob_path", type=click.Path(exists=True), required=True,
|
|
300
|
+
help="Path to missense mutations probability dictionary")
|
|
301
|
+
@click.option("-s", "--seq_df_path", type=click.Path(exists=True), required=True,
|
|
302
|
+
help="Path to dataframe of sequences")
|
|
303
|
+
@click.option("-d", "--datasets_dir", type=click.Path(exists=True), required=True,
|
|
304
|
+
help="Path to datasets directory")
|
|
305
|
+
@click.option("-a", "--annotations_dir", type=click.Path(exists=True), required=True,
|
|
306
|
+
help="Path to annotations directory")
|
|
307
|
+
@click.option("-o", "--output_dir", default="./",
|
|
308
|
+
help="Path to output directory where to save plots")
|
|
309
|
+
@click.option("-c", "--cohort",
|
|
310
|
+
help="Cohort name", type=str, required=True)
|
|
311
|
+
@click.option("--title", ## Might be redundant
|
|
312
|
+
help="Plot title", type=str)
|
|
313
|
+
@click.option("--maf_for_nonmiss_path", type=click.Path(exists=True),
|
|
314
|
+
help="Path to input mutations file including non-missense mutations")
|
|
315
|
+
@click.option("--lst_summary_tracks", type=str,
|
|
316
|
+
help="List of tracks to be included in the summary plot (e.g., score,miss_count,clusters)",
|
|
317
|
+
default="score,miss_count,res_count,res_clust_mut,clusters")
|
|
318
|
+
@click.option("--lst_summary_hratios", type=str,
|
|
319
|
+
help="List of float to define horizontal ratio of each track of the summary plot")
|
|
320
|
+
@click.option("--lst_gene_tracks", type=str,
|
|
321
|
+
help="List of tracks to be included in the gene plots (e.g., miss_count,miss_prob,score)",
|
|
322
|
+
default="miss_count,miss_prob,score,clusters,ddg,disorder,pacc,ptm,site,sse,pfam,prosite,membrane,motif")
|
|
323
|
+
@click.option("--lst_gene_hratios", type=str,
|
|
324
|
+
help="List of floats to define horizontal ratio of each track of the gene plot")
|
|
325
|
+
@click.option("--summary_fsize_x", help="Figure size x-axis for summary plots (dynamically adjusted)", type=float, default=0.5)
|
|
326
|
+
@click.option("--summary_fsize_y", help="Figure size y-axis for summary plots", type=int, default=8)
|
|
327
|
+
@click.option("--gene_fsize_x", help="Figure size x-axis for gene plots", type=int, default=24)
|
|
328
|
+
@click.option("--gene_fsize_y", help="Figure size y-axis for gene plots", type=int, default=12)
|
|
329
|
+
@click.option("--summary_alpha", help="Alpha value for score track in summary plot", type=float, default=0.7)
|
|
330
|
+
@click.option("--dist_thr", help="Threshold of ratios to avoid clashing feature names (e.g., domains and motifs)", type=float, default=0.1)
|
|
331
|
+
@click.option("--genes", help="List of genes to be analysed in the report (e.g., --genes TP53,KRAS,PIK3CA)", type=str)
|
|
332
|
+
@click.option("--c_genes_only", help="Generate gene plots only for significant genes (use --no-c_genes_only to disable)", is_flag=True, default=True)
|
|
333
|
+
@click.option("--max_n_genes", help="Max number of genes to plot", type=int, default=30)
|
|
334
|
+
@click.option("--volcano_top_n", help="Top associations to annotate in volcano plot", type=int, default=15)
|
|
335
|
+
@click.option("--volcano_fsize_x", help="Figure size x-axis for volcano plot", type=float, default=10)
|
|
336
|
+
@click.option("--volcano_fsize_y", help="Figure size y-axis for volcano plot", type=float, default=6)
|
|
337
|
+
@click.option("--volcano_subplots_fsize_x", help="Figure size x-axis for volcano subplots (dynamically adjusted)", type=float, default=3.2)
|
|
338
|
+
@click.option("--volcano_subplots_fsize_y", help="Figure size y-axis for volcano subplots (dynamically adjusted)", type=float, default=3)
|
|
339
|
+
@click.option("--log_odds_fsize_x", help="Figure size x-axis for log odds plot (dynamically adjusted)", type=float, default=1.7)
|
|
340
|
+
@click.option("--log_odds_fsize_y", help="Figure size y-axis for log odds plot (dynamically adjusted)", type=float, default=3.6)
|
|
341
|
+
@click.option("--output_csv", help="Output csv file including annotated Oncodrive3D result", is_flag=True)
|
|
342
|
+
@click.option("--output_all_pos", help="Include all position (including non-mutated ones) in the Oncodrive3D enriched result", is_flag=True)
|
|
343
|
+
@click.option("-v", "--verbose", help="Verbose", is_flag=True)
|
|
344
|
+
@setup_logging_decorator
|
|
345
|
+
def plot(gene_result_path,
|
|
346
|
+
pos_result_path,
|
|
347
|
+
maf_path,
|
|
348
|
+
miss_prob_path,
|
|
349
|
+
seq_df_path,
|
|
350
|
+
datasets_dir,
|
|
351
|
+
annotations_dir,
|
|
352
|
+
output_dir,
|
|
353
|
+
cohort,
|
|
354
|
+
title,
|
|
355
|
+
maf_for_nonmiss_path,
|
|
356
|
+
lst_summary_tracks,
|
|
357
|
+
lst_summary_hratios,
|
|
358
|
+
lst_gene_tracks,
|
|
359
|
+
lst_gene_hratios,
|
|
360
|
+
summary_fsize_x,
|
|
361
|
+
summary_fsize_y,
|
|
362
|
+
gene_fsize_x,
|
|
363
|
+
gene_fsize_y,
|
|
364
|
+
summary_alpha,
|
|
365
|
+
dist_thr,
|
|
366
|
+
genes,
|
|
367
|
+
c_genes_only,
|
|
368
|
+
max_n_genes,
|
|
369
|
+
volcano_top_n,
|
|
370
|
+
volcano_fsize_x,
|
|
371
|
+
volcano_fsize_y,
|
|
372
|
+
volcano_subplots_fsize_x,
|
|
373
|
+
volcano_subplots_fsize_y,
|
|
374
|
+
log_odds_fsize_x,
|
|
375
|
+
log_odds_fsize_y,
|
|
376
|
+
output_csv,
|
|
377
|
+
output_all_pos,
|
|
378
|
+
verbose):
|
|
379
|
+
""""Generate summary and individual gene plots for a quick interpretation of the 3D-clustering analysis."""
|
|
380
|
+
|
|
381
|
+
from scripts.plotting.plot import generate_plots
|
|
382
|
+
from scripts.plotting.utils import init_plot_pars, parse_lst_tracks
|
|
383
|
+
|
|
384
|
+
startup_message(__version__, "Starting plot generation..")
|
|
385
|
+
logger.info(f"O3D genes-result: {gene_result_path}")
|
|
386
|
+
logger.info(f"O3D positions-result: {pos_result_path}")
|
|
387
|
+
logger.info(f"O3D input mutations: {maf_path}")
|
|
388
|
+
logger.info(f"O3D missense mut prob: {miss_prob_path}")
|
|
389
|
+
logger.info(f"O3D sequences df: {seq_df_path}")
|
|
390
|
+
logger.info(f"O3D datasets: {datasets_dir}")
|
|
391
|
+
logger.info(f"O3D annotations: {annotations_dir}")
|
|
392
|
+
logger.info(f"Output: {output_dir}")
|
|
393
|
+
logger.info(f"Cohort: {cohort}")
|
|
394
|
+
logger.info(f"Title: {title}")
|
|
395
|
+
logger.info(f"Input mutations including non-missense: {maf_for_nonmiss_path}")
|
|
396
|
+
logger.info(f"Custom summary plot tracks: {lst_summary_tracks}")
|
|
397
|
+
logger.info(f"Custom summary plot h-ratios: {lst_summary_hratios}")
|
|
398
|
+
logger.info(f"Custom gene plots tracks: {lst_gene_tracks}")
|
|
399
|
+
logger.info(f"Custom gene plots h-ratios: {lst_gene_hratios}")
|
|
400
|
+
logger.info(f"Summary plot fsize_x (dynamically adjusted): {summary_fsize_x}")
|
|
401
|
+
logger.info(f"Summary plot fsize_y: {summary_fsize_y}")
|
|
402
|
+
logger.info(f"Gene plots fsize_x: {gene_fsize_x}")
|
|
403
|
+
logger.info(f"Gene plots fsize_y: {gene_fsize_y}")
|
|
404
|
+
logger.info(f"Volcano plot fsize_x: {volcano_fsize_x}")
|
|
405
|
+
logger.info(f"Volcano plot fsize_y: {volcano_fsize_y}")
|
|
406
|
+
logger.info(f"Volcano subplot fsize_x (dynamically adjusted): {volcano_subplots_fsize_x}")
|
|
407
|
+
logger.info(f"Volcano subplot fsize_y (dynamically adjusted): {volcano_subplots_fsize_y}")
|
|
408
|
+
logger.info(f"Log odds plot fsize_x (dynamically adjusted): {log_odds_fsize_x}")
|
|
409
|
+
logger.info(f"Log odds plot fsize_y (dynamically adjusted): {log_odds_fsize_y}")
|
|
410
|
+
logger.info(f"Summary plot score alpha: {summary_alpha}")
|
|
411
|
+
logger.info(f"Threshold for clashing feat: {dist_thr}")
|
|
412
|
+
logger.info(f"Subset of genes: {genes}")
|
|
413
|
+
logger.info(f"Gene plots for significant genes only: {bool(c_genes_only)}")
|
|
414
|
+
logger.info(f"Max number of genes to plot: {max_n_genes}")
|
|
415
|
+
logger.info(f"Volcano plot top associations to annotate: {volcano_top_n}")
|
|
416
|
+
logger.info(f"Output csv file: {bool(output_csv)}")
|
|
417
|
+
logger.info(f"Include non-mutated positions in csv file: {bool(output_all_pos)}")
|
|
418
|
+
logger.info(f"Verbose: {bool(verbose)}")
|
|
419
|
+
logger.info(f'Log path: {os.path.join(output_dir, "log")}')
|
|
420
|
+
logger.info("")
|
|
421
|
+
|
|
422
|
+
lst_summary_tracks = parse_lst_tracks(lst_summary_tracks, plot_type="summary")
|
|
423
|
+
lst_gene_tracks = parse_lst_tracks(lst_gene_tracks, plot_type="gene")
|
|
424
|
+
plot_pars = init_plot_pars(summary_fsize_x=summary_fsize_x,
|
|
425
|
+
summary_fsize_y=summary_fsize_y,
|
|
426
|
+
gene_fsize_x=gene_fsize_x,
|
|
427
|
+
gene_fsize_y=gene_fsize_y,
|
|
428
|
+
volcano_fsize_x=volcano_fsize_x,
|
|
429
|
+
volcano_fsize_y=volcano_fsize_y,
|
|
430
|
+
volcano_subplots_fsize_x=volcano_subplots_fsize_x,
|
|
431
|
+
volcano_subplots_fsize_y=volcano_subplots_fsize_y,
|
|
432
|
+
log_odds_fsize_x=log_odds_fsize_x,
|
|
433
|
+
log_odds_fsize_y=log_odds_fsize_y,
|
|
434
|
+
dist_thr=dist_thr,
|
|
435
|
+
summary_alpha=summary_alpha,
|
|
436
|
+
lst_summary_tracks=lst_summary_tracks,
|
|
437
|
+
lst_summary_hratios=lst_summary_hratios,
|
|
438
|
+
lst_gene_annot=lst_gene_tracks,
|
|
439
|
+
lst_gene_hratios=lst_gene_hratios,
|
|
440
|
+
volcano_top_n=volcano_top_n)
|
|
441
|
+
|
|
442
|
+
generate_plots(gene_result_path=gene_result_path,
|
|
443
|
+
pos_result_path=pos_result_path,
|
|
444
|
+
maf_path=maf_path,
|
|
445
|
+
miss_prob_path=miss_prob_path,
|
|
446
|
+
seq_df_path=seq_df_path,
|
|
447
|
+
cohort=cohort,
|
|
448
|
+
datasets_dir=datasets_dir,
|
|
449
|
+
annotations_dir=annotations_dir,
|
|
450
|
+
output_dir=output_dir,
|
|
451
|
+
plot_pars=plot_pars,
|
|
452
|
+
maf_path_for_nonmiss=maf_for_nonmiss_path,
|
|
453
|
+
c_genes_only=c_genes_only,
|
|
454
|
+
n_genes=max_n_genes,
|
|
455
|
+
lst_genes=genes,
|
|
456
|
+
save_plot=True,
|
|
457
|
+
show_plot=False,
|
|
458
|
+
save_csv=output_csv,
|
|
459
|
+
include_all_pos=output_all_pos,
|
|
460
|
+
title=title)
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
# =============================================================================
|
|
465
|
+
# COMPARATIVE PLOTS
|
|
466
|
+
# =============================================================================
|
|
467
|
+
|
|
468
|
+
@oncodrive3D.command(context_settings=dict(help_option_names=['-h', '--help']),
|
|
469
|
+
help="Generate plots to compare two runs of 3D-clustering analysis.")
|
|
470
|
+
@click.option("-i", "--o3d_result_dir_1", type=click.Path(exists=True), required=True,
|
|
471
|
+
help="Path to result A directory (including gene- and pos-level result for run A)")
|
|
472
|
+
@click.option("-I", "--o3d_result_dir_2", type=click.Path(exists=True), required=True,
|
|
473
|
+
help="Path to result B directory (including gene- and pos-level result for run B)")
|
|
474
|
+
@click.option("-c", "--cohort_1",
|
|
475
|
+
help="Cohort A name (it should match the basename of the files in o3d_result_dir)", type=str, required=True)
|
|
476
|
+
@click.option("-C", "--cohort_2",
|
|
477
|
+
help="Cohort B name (it should match the basename of the files in o3d_result_dir)", type=str, required=True)
|
|
478
|
+
@click.option("-d", "--datasets_dir", type=click.Path(exists=True), required=True,
|
|
479
|
+
help="Path to datasets directory")
|
|
480
|
+
@click.option("-a", "--annotations_dir", type=click.Path(exists=True), required=True,
|
|
481
|
+
help="Path to annotations directory")
|
|
482
|
+
@click.option("-o", "--output_dir", required=True,
|
|
483
|
+
help="Path to output directory where to save plots")
|
|
484
|
+
@click.option("--maf_path_nonmiss_1", type=click.Path(exists=True),
|
|
485
|
+
help="Path to input mutations file A including non-missense mutations")
|
|
486
|
+
@click.option("--maf_path_nonmiss_2", type=click.Path(exists=True),
|
|
487
|
+
help="Path to input mutations file B including non-missense mutations (e.g., miss_count,miss_prob,score)")
|
|
488
|
+
@click.option("--lst_tracks", type=str,
|
|
489
|
+
help="List of tracks to plot",
|
|
490
|
+
default="miss_count,miss_prob,score,clusters,ddg,disorder,pacc,ptm,site,sse,pfam,prosite,membrane,motif")
|
|
491
|
+
@click.option("--lst_hratios", type=str,
|
|
492
|
+
help="List of float to define horizontal ratio of each track of the plot")
|
|
493
|
+
@click.option("--fsize_x", help="Figure size x-axis", type=float, default=24)
|
|
494
|
+
@click.option("--fsize_y", help="Figure size y-axis", type=float, default=12)
|
|
495
|
+
@click.option("--dist_thr", help="Threshold of ratios to avoid clashing feature names (e.g., domains and motifs)", type=float, default=0.1)
|
|
496
|
+
@click.option("--genes", help="List of genes to be analysed in the report (e.g., --genes TP53,KRAS,PIK3CA)", type=str)
|
|
497
|
+
@click.option("--max_n_genes", help="Max number of genes to plot", type=int, default=30)
|
|
498
|
+
@click.option("--count_mirror", help="Missense mutation count track as mirror image", is_flag=True)
|
|
499
|
+
@click.option("--prob_mirror", help="Missense mutation prob track as mirror image", is_flag=True)
|
|
500
|
+
@click.option("--score_mirror", help="Clustering score track as mirror image", is_flag=True)
|
|
501
|
+
@click.option("-v", "--verbose", help="Verbose", is_flag=True)
|
|
502
|
+
@setup_logging_decorator
|
|
503
|
+
def comparative_plot(o3d_result_dir_1,
|
|
504
|
+
cohort_1,
|
|
505
|
+
o3d_result_dir_2,
|
|
506
|
+
cohort_2,
|
|
507
|
+
datasets_dir,
|
|
508
|
+
annotations_dir,
|
|
509
|
+
output_dir,
|
|
510
|
+
maf_path_nonmiss_1,
|
|
511
|
+
maf_path_nonmiss_2,
|
|
512
|
+
lst_tracks,
|
|
513
|
+
lst_hratios,
|
|
514
|
+
fsize_x,
|
|
515
|
+
fsize_y,
|
|
516
|
+
dist_thr,
|
|
517
|
+
count_mirror,
|
|
518
|
+
prob_mirror,
|
|
519
|
+
score_mirror,
|
|
520
|
+
genes,
|
|
521
|
+
max_n_genes,
|
|
522
|
+
verbose):
|
|
523
|
+
""""Generate genes comparative plots to comprare two runs of 3D-clustering analysis."""
|
|
524
|
+
|
|
525
|
+
from scripts.plotting.plot import generate_comparative_plots
|
|
526
|
+
from scripts.plotting.utils import init_comp_plot_pars, parse_lst_tracks
|
|
527
|
+
|
|
528
|
+
startup_message(__version__, "Starting plot generation..")
|
|
529
|
+
logger.info(f"Oncodrive3D result A: {o3d_result_dir_1}")
|
|
530
|
+
logger.info(f"Cohort B: {cohort_1}")
|
|
531
|
+
logger.info(f"Oncodrive3D result B: {o3d_result_dir_2}")
|
|
532
|
+
logger.info(f"Cohort B: {cohort_2}")
|
|
533
|
+
logger.info(f"Oncodrive3D datasets: {datasets_dir}")
|
|
534
|
+
logger.info(f"Oncodrive3D annotations: {annotations_dir}")
|
|
535
|
+
logger.info(f"Output: {output_dir}")
|
|
536
|
+
logger.info(f"Input mutations including non-missense A: {maf_path_nonmiss_1}")
|
|
537
|
+
logger.info(f"Input mutations including non-missense B: {maf_path_nonmiss_2}")
|
|
538
|
+
logger.info(f"Custom gene plots tracks: {lst_tracks}")
|
|
539
|
+
logger.info(f"Custom gene plots h-ratios: {lst_hratios}")
|
|
540
|
+
logger.info(f"Summary plot fsize_x: {fsize_x}")
|
|
541
|
+
logger.info(f"Summary plot fsize_y: {fsize_y}")
|
|
542
|
+
logger.info(f"Threshold for clashing feat: {dist_thr}")
|
|
543
|
+
logger.info(f"Missense mut as mirror image: {bool(count_mirror)}")
|
|
544
|
+
logger.info(f"Missense mut prob as mirror image: {bool(prob_mirror)}")
|
|
545
|
+
logger.info(f"Score as mirror image: {bool(score_mirror)}")
|
|
546
|
+
logger.info(f"Verbose: {bool(verbose)}")
|
|
547
|
+
logger.info(f"Subset of genes: {genes}")
|
|
548
|
+
logger.info(f"Max number of genes to plot: {max_n_genes}")
|
|
549
|
+
logger.info(f"Verbose: {bool(verbose)}")
|
|
550
|
+
logger.info(f'Log path: {os.path.join(output_dir, "log")}')
|
|
551
|
+
logger.info("")
|
|
552
|
+
|
|
553
|
+
lst_tracks = parse_lst_tracks(lst_tracks, plot_type="gene")
|
|
554
|
+
plot_pars = init_comp_plot_pars(fsize_x=fsize_x,
|
|
555
|
+
fsize_y=fsize_y,
|
|
556
|
+
dist_thr=dist_thr,
|
|
557
|
+
lst_tracks=lst_tracks,
|
|
558
|
+
lst_hratios=lst_hratios,
|
|
559
|
+
count_mirror=count_mirror,
|
|
560
|
+
score_mirror=score_mirror,
|
|
561
|
+
prob_mirror=prob_mirror)
|
|
562
|
+
|
|
563
|
+
generate_comparative_plots(o3d_result_dir_1=o3d_result_dir_1,
|
|
564
|
+
cohort_1=cohort_1,
|
|
565
|
+
o3d_result_dir_2=o3d_result_dir_2,
|
|
566
|
+
cohort_2=cohort_2,
|
|
567
|
+
datasets_dir=datasets_dir,
|
|
568
|
+
annotations_dir=annotations_dir,
|
|
569
|
+
output_dir=output_dir,
|
|
570
|
+
plot_pars=plot_pars,
|
|
571
|
+
maf_path_nonmiss_1=maf_path_nonmiss_1,
|
|
572
|
+
maf_path_nonmiss_2=maf_path_nonmiss_2,
|
|
573
|
+
n_genes=max_n_genes,
|
|
574
|
+
lst_genes=genes)
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
# =============================================================================
|
|
578
|
+
# CHIMERAX PLOTS
|
|
579
|
+
# =============================================================================
|
|
580
|
+
|
|
581
|
+
@oncodrive3D.command(context_settings=dict(help_option_names=['-h', '--help']),
|
|
582
|
+
help="Generate 3D plots using CHimeraX.")
|
|
583
|
+
@click.option("-o", "--output_dir",
|
|
584
|
+
help="Directory where to save the plots", type=str, required=True)
|
|
585
|
+
@click.option("-g", "--gene_result_path",
|
|
586
|
+
help="Path to genes-level O3D result", type=click.Path(exists=True), required=True)
|
|
587
|
+
@click.option("-p", "--pos_result_path",
|
|
588
|
+
help="Path to positions-level O3D result", type=click.Path(exists=True), required=True)
|
|
589
|
+
@click.option("-d", "--datasets_dir",
|
|
590
|
+
help="Path to datasets", type=click.Path(exists=True), required=True)
|
|
591
|
+
@click.option("-s", "--seq_df_path",
|
|
592
|
+
help="Path to sequences dataframe", type=click.Path(exists=True), required=True)
|
|
593
|
+
@click.option("-c", "--cohort",
|
|
594
|
+
help="Cohort name", default="")
|
|
595
|
+
@click.option("--max_n_genes", help="Maximum number of genes to plot", type=int, default=30)
|
|
596
|
+
@click.option("--pixel_size", help="Pixel size (smaller value is larger number of pixels)", type=float, default=0.08)
|
|
597
|
+
@click.option("--cluster_ext", help="Include extended clusters", is_flag=True)
|
|
598
|
+
@click.option("--fragmented_proteins", help="Include fragmented proteins", is_flag=True)
|
|
599
|
+
@click.option("--transparent_bg", help="Set background as transparent", type=str, is_flag=True)
|
|
600
|
+
@click.option("--chimerax_bin", help="Path to chimerax installation", type=str, default="/usr/bin/chimerax")
|
|
601
|
+
@click.option("-v", "--verbose", help="Verbose", is_flag=True)
|
|
602
|
+
@setup_logging_decorator
|
|
603
|
+
def chimerax_plot(output_dir,
|
|
604
|
+
gene_result_path,
|
|
605
|
+
pos_result_path,
|
|
606
|
+
datasets_dir,
|
|
607
|
+
seq_df_path,
|
|
608
|
+
cohort,
|
|
609
|
+
max_n_genes,
|
|
610
|
+
pixel_size,
|
|
611
|
+
cluster_ext,
|
|
612
|
+
fragmented_proteins,
|
|
613
|
+
transparent_bg,
|
|
614
|
+
chimerax_bin,
|
|
615
|
+
verbose):
|
|
616
|
+
""""Generate images of structures annotated with clustering metrics."""
|
|
617
|
+
|
|
618
|
+
from scripts.plotting.chimerax_plot import generate_chimerax_plot
|
|
619
|
+
|
|
620
|
+
startup_message(__version__, "Starting plot generation..")
|
|
621
|
+
logger.info(f"Output dir: {output_dir}")
|
|
622
|
+
logger.info(f"Gene result path: {gene_result_path}")
|
|
623
|
+
logger.info(f"Position result path: {pos_result_path}")
|
|
624
|
+
logger.info(f"Datasets dir: {datasets_dir}")
|
|
625
|
+
logger.info(f"Sequence dataframe path: {seq_df_path}")
|
|
626
|
+
logger.info(f"Cohort: {cohort}")
|
|
627
|
+
logger.info(f"Max number of genes to plot: {max_n_genes}")
|
|
628
|
+
logger.info(f"Pixel size: {pixel_size}")
|
|
629
|
+
logger.info(f"Cluster extended: {cluster_ext}")
|
|
630
|
+
logger.info(f"Fragmented proteins: {fragmented_proteins}")
|
|
631
|
+
logger.info(f"Transparent background: {transparent_bg}")
|
|
632
|
+
logger.info(f"Verbose: {bool(verbose)}")
|
|
633
|
+
logger.info(f'Log path: {os.path.join(output_dir, "log")}')
|
|
634
|
+
logger.info("")
|
|
635
|
+
|
|
636
|
+
generate_chimerax_plot(output_dir,
|
|
637
|
+
gene_result_path,
|
|
638
|
+
pos_result_path,
|
|
639
|
+
datasets_dir,
|
|
640
|
+
seq_df_path,
|
|
641
|
+
cohort,
|
|
642
|
+
max_n_genes,
|
|
643
|
+
pixel_size,
|
|
644
|
+
cluster_ext,
|
|
645
|
+
fragmented_proteins,
|
|
646
|
+
transparent_bg,
|
|
647
|
+
chimerax_bin)
|
|
648
|
+
|
|
649
|
+
if __name__ == "__main__":
|
|
650
|
+
oncodrive3D()
|
|
File without changes
|