Skip to content

Commit a22ab62

Browse files
simplify post_processing by not having a seq_coverage.png
1 parent 3b28bed commit a22ab62

3 files changed

Lines changed: 31 additions & 59 deletions

File tree

bin/generate_report.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def get_template_path():
4040

4141
return str(template_path)
4242

43-
def generate_report(name, out_dir, structures, num_structs_limit=5, msa_files=None, pae_files=None, prog="proteinfold", type="standard", html_template=None, write_htmls=True):
43+
def generate_report(name, out_dir, structures, num_structs_limit=5, msa_files=None, pae_files=None, prog="proteinfold", type="standard", html_template=None):
4444

4545
PLOTLY_CONFIG = {"displayModeBar": True, "displaylogo": False, "scrollZoom": True}
4646

@@ -122,13 +122,6 @@ def generate_report(name, out_dir, structures, num_structs_limit=5, msa_files=No
122122
else:
123123
html = re.sub(r'<!-- BEGIN_PAE_SECTION -->.*?<!-- END_PAE_SECTION -->', '', html, flags=re.DOTALL)
124124

125-
if write_htmls:
126-
with open(f"{out_dir}/{name}_coverage_pLDDT.html", "w") as out_file:
127-
out_file.write(plddt_html)
128-
if seq_cov_html:
129-
with open(f"{out_dir}/{name}_coverage_MSA.html", "w") as out_file:
130-
out_file.write(seq_cov_html)
131-
132125
# Write the final HTML report
133126
with open(f"{out_dir}/{name}_{type}_report.html", "w") as out_file:
134127
out_file.write(html)
@@ -143,7 +136,6 @@ def main():
143136
parser.add_argument("--prog", default="proteinfold", choices=["proteinfold", "alphafold2", "alphafold3", "esmfold", "colabfold", "rosettafold-all-atom", "rosettafold2na", "helixfold3", "boltz", "comparison"], type=str.lower, help="The program used to generate the structures.")
144137
parser.add_argument("--type", default="standard", choices=["standard", "comparison"], help="The type of report to generate.")
145138
parser.add_argument("--html_template", default=None, help="Path to the HTML report template.")
146-
parser.add_argument("--write_htmls", default=True, help="Write out separate files for each html plot.")
147139

148140
args = parser.parse_args()
149141

@@ -172,7 +164,6 @@ def main():
172164
prog=args.prog,
173165
type=args.type,
174166
html_template=html_template,
175-
write_htmls=args.write_htmls,
176167
)
177168

178169
if __name__ == "__main__":

modules/local/generate_report/main.nf

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ process GENERATE_REPORT {
1313

1414
output:
1515
tuple val(meta), path ("*report.html") , emit: report
16-
tuple val(meta), path ("*seq_coverage.png"), optional: true, emit: sequence_coverage
17-
tuple val(meta), path ("*_pLDDT.html") , emit: plddt
1816
path "versions.yml" , emit: versions
1917

2018
when:
@@ -45,8 +43,6 @@ process GENERATE_REPORT {
4543
stub:
4644
"""
4745
touch test_alphafold2_report.html
48-
touch test_seq_coverage.png
49-
touch test_pLDDT.html
5046
5147
cat <<-END_VERSIONS > versions.yml
5248
"${task.process}":

subworkflows/local/post_processing.nf

Lines changed: 30 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -40,53 +40,43 @@ workflow POST_PROCESSING {
4040
ch_comparison_report_files = channel.empty()
4141

4242
if (!skip_visualisation){
43+
ch_report_input
44+
.multiMap { meta, pdbs, msa, pae ->
45+
full: [meta, pdbs, msa, pae]
46+
msa_only: [meta, msa]
47+
}
48+
.set { ch_report_split }
49+
4350
GENERATE_REPORT(
44-
ch_report_input,
51+
ch_report_split.full,
4552
ch_report_template
4653
)
4754
ch_versions = ch_versions.mix(GENERATE_REPORT.out.versions)
4855

4956
if (requested_modes_size > 1){
50-
// Multi-mode comparison: group structures and coverage data from all modes
57+
// Multi-mode comparison: group top-ranked structures and MSA data from all modes
5158
ch_top_ranked_model
52-
.map { meta, pdb ->
53-
[["id": meta.id], meta, pdb]
59+
.join(ch_report_split.msa_only)
60+
.map { meta, pdb, msa ->
61+
[["id": meta.id], meta, pdb, msa]
5462
}
55-
.join(
56-
GENERATE_REPORT.out.sequence_coverage,
57-
by: [0],
58-
remainder: true // Include models without coverage (e.g., ESMFold)
59-
)
6063
.groupTuple(by: [0], size: requested_modes_size)
61-
.map { key, model_meta_list, coverage_list ->
62-
key.models = model_meta_list.collect { meta, pdb -> meta.model }.join(',')
63-
[key, model_meta_list.collect { meta, pdb -> pdb }, coverage_list]
64-
}
65-
.set { ch_comparison_report_input }
66-
67-
// Separate channel components for clarity
68-
ch_comparison_report_input
69-
.map { meta, structures, coverage ->
70-
[meta, structures.collect { f -> f.name }]
64+
.map { key, model_meta_list, pdbs, msas ->
65+
def models_str = model_meta_list.collect { it.model }.join(',')
66+
[key + [models: models_str], pdbs, msas]
7167
}
72-
.set { ch_pdb_input }
73-
74-
ch_comparison_report_input
75-
.map { meta, structures, coverage ->
76-
[meta, coverage.findAll { f -> f != null }.collect { f -> f.name }]
77-
}
78-
.set { ch_msa_input }
79-
80-
ch_comparison_report_input
81-
.map { meta, structures, coverage ->
82-
(structures + coverage.findAll { f -> f != null }).unique()
68+
.multiMap { meta, pdbs, msas ->
69+
def valid_msas = msas.findAll { !it.name.startsWith("DUMMY_") }
70+
pdbs: [meta, pdbs.collect { it.name }]
71+
msas: [meta, valid_msas.collect { it.name }]
72+
allfiles: (pdbs + valid_msas).unique()
8373
}
84-
.set { ch_all_files }
74+
.set { ch_split }
8575

8676
COMPARE_STRUCTURES(
87-
ch_pdb_input,
88-
ch_msa_input,
89-
ch_all_files,
77+
ch_split.pdbs,
78+
ch_split.msas,
79+
ch_split.allfiles,
9080
ch_report_template
9181
)
9282
ch_versions = ch_versions.mix(COMPARE_STRUCTURES.out.versions)
@@ -127,26 +117,21 @@ workflow POST_PROCESSING {
127117
ch_workflow_summary = channel.value(paramsSummaryMultiqc(summary_params))
128118
ch_methods_description = channel.value(methodsDescriptionText(ch_multiqc_methods_description))
129119

130-
ch_multiqc_files = channel.empty()
131-
ch_multiqc_files = ch_multiqc_files.mix(ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml'))
132-
ch_multiqc_files = ch_multiqc_files.mix(ch_methods_description.collectFile(name: 'methods_description_mqc.yaml'))
133-
ch_multiqc_files = ch_multiqc_files.mix(ch_collated_versions)
120+
ch_multiqc_files = ch_workflow_summary.collectFile(name: 'workflow_summary_mqc.yaml')
121+
.mix(ch_methods_description.collectFile(name: 'methods_description_mqc.yaml'))
122+
.mix(ch_collated_versions)
134123

135124
MULTIQC (
136125
ch_multiqc_rep
137126
.combine(
138127
ch_multiqc_files
139128
.collect()
140-
.map { it -> [it] }
129+
.map { [it] }
141130
)
142131
.map { meta, report_files, multiqc_files -> [ meta, report_files + multiqc_files ] },
143132
ch_multiqc_config,
144-
ch_multiqc_custom_config
145-
.collect()
146-
.ifEmpty([]),
147-
ch_multiqc_logo
148-
.collect()
149-
.ifEmpty([]),
133+
ch_multiqc_custom_config.toList(),
134+
ch_multiqc_logo.toList(),
150135
[],
151136
[]
152137
)

0 commit comments

Comments
 (0)