def generate_html(region_layer: RegionLayer, results: ThioResults, record_layer: RecordLayer, options_layer: OptionsLayer) -> HTMLSections: """ Generates HTML for the module """ html = HTMLSections("thiopeptides") if not results: return html thio_layer = ThiopeptideLayer(record_layer, results, region_layer.region_feature) template = FileTemplate( path.get_full_path(__file__, "templates", "details.html")) details = template.render(record=record_layer, cluster=thio_layer, options=options_layer) html.add_detail_section("Thiopeptides", details) template = FileTemplate( path.get_full_path(__file__, "templates", "sidepanel.html")) sidepanel = template.render(record=record_layer, cluster=thio_layer, options=options_layer) html.add_sidepanel_section("Thiopeptides", sidepanel) return html
def generate_html(region_layer: RegionLayer, results: SactiResults, record_layer: RecordLayer, options_layer: OptionsLayer) -> HTMLSections: """ Generates HTML for the module """ html = HTMLSections("sactipeptides") motifs_in_region = defaultdict(list) # type: Dict[str, List[CDSMotif]] for locus, motifs in results.motifs_by_locus.items(): for motif in motifs: if motif.is_contained_by(region_layer.region_feature): motifs_in_region[locus].append(motif) sacti_layer = SactipeptideLayer(record_layer, region_layer.region_feature) detail_tooltip = ("Lists the possible core peptides for each biosynthetic enzyme, including the predicted class. " "Each core peptide shows the leader and core peptide sequences, separated by a dash.") template = FileTemplate(path.get_full_path(__file__, "templates", "details.html")) details = template.render(record=record_layer, region=sacti_layer, options=options_layer, results=motifs_in_region, tooltip=detail_tooltip) html.add_detail_section("Sactipeptides", details) side_tooltip = ("Lists the possible core peptides in the region. " "Each core peptide lists its RODEO score and predicted core sequence.") template = FileTemplate(path.get_full_path(__file__, "templates", "sidepanel.html")) sidepanel = template.render(record=record_layer, region=sacti_layer, options=options_layer, results=motifs_in_region, tooltip=side_tooltip) html.add_sidepanel_section("Sactipeptides", sidepanel) return html
def generate_html(region_layer: RegionLayer, results: ThioResults, record_layer: RecordLayer, options_layer: OptionsLayer ) -> HTMLSections: """ Generates HTML for the module """ html = HTMLSections("thiopeptides") if not results: return html thio_layer = ThiopeptideLayer(record_layer, results, region_layer.region_feature) detail_tooltip = ("Lists the possible core peptides for each biosynthetic enzyme, including the predicted class. " "Each core peptide shows the leader and core peptide sequences, separated by a dash. " "Predicted tail sequences are also shown.") template = FileTemplate(path.get_full_path(__file__, "templates", "details.html")) details = template.render(record=record_layer, cluster=thio_layer, options=options_layer, tooltip=detail_tooltip) html.add_detail_section("Thiopeptides", details) side_tooltip = ("Lists the possible core peptides in the region. " "Each core peptide lists its possible molecular weights " "and the scores for cleavage site prediction and RODEO. " "If relevant, other features, such as macrocycle and amidation, will also be listed.") template = FileTemplate(path.get_full_path(__file__, "templates", "sidepanel.html")) sidepanel = template.render(record=record_layer, cluster=thio_layer, options=options_layer, tooltip=side_tooltip) html.add_sidepanel_section("Thiopeptides", sidepanel) return html
def generate_html(region_layer: RegionLayer, results: SactiResults, record_layer: RecordLayer, options_layer: OptionsLayer) -> HTMLSections: """ Generates HTML for the module """ html = HTMLSections("sactipeptides") motifs_in_region = defaultdict(list) # type: Dict[str, List[CDSMotif]] for locus, motifs in results.motifs_by_locus.items(): for motif in motifs: if motif.is_contained_by(region_layer.region_feature): motifs_in_region[locus].append(motif) sacti_layer = SactipeptideLayer(record_layer, region_layer.region_feature) template = FileTemplate( path.get_full_path(__file__, "templates", "details.html")) details = template.render(record=record_layer, region=sacti_layer, options=options_layer, results=motifs_in_region) html.add_detail_section("Sactipeptides", details) template = FileTemplate( path.get_full_path(__file__, "templates", "sidepanel.html")) sidepanel = template.render(record=record_layer, region=sacti_layer, options=options_layer, results=motifs_in_region) html.add_sidepanel_section("Sactipeptides", sidepanel) return html
def generate_html(region_layer: RegionLayer, results: LanthiResults, _record_layer: RecordLayer, _options_layer: OptionsLayer) -> HTMLSections: """ Generates HTML output for the module """ html = HTMLSections("lanthipeptides") detail_tooltip = ( "Lists the possible core peptides for each biosynthetic enzyme, including the predicted class. " "Each core peptide shows the leader and core peptide sequences, separated by a dash." ) template = FileTemplate( path.get_full_path(__file__, "templates", "details.html")) motifs = results.get_motifs_for_region(region_layer.region_feature) html.add_detail_section( "Lanthipeptides", template.render(results=motifs, tooltip=detail_tooltip)) side_tooltip = ( "Lists the possible core peptides in the region. " "Each core peptide lists the number of lanthionine bridges, possible molecular weights, " "and the scores for cleavage site prediction and RODEO.") template = FileTemplate( path.get_full_path(__file__, "templates", "sidepanel.html")) motifs = results.get_motifs_for_region(region_layer.region_feature) html.add_sidepanel_section( "Lanthipeptides", template.render(results=motifs, tooltip=side_tooltip)) return html
def generate_html(region_layer: RegionLayer, results: LanthiResults, _record_layer: RecordLayer, _options_layer: OptionsLayer ) -> HTMLSections: """ Generates HTML output for the module """ html = HTMLSections("lanthipeptides") template = FileTemplate(path.get_full_path(__file__, "templates", "details.html")) motifs = results.get_motifs_for_region(region_layer.region_feature) html.add_detail_section("Lanthipeptides", template.render(results=motifs)) template = FileTemplate(path.get_full_path(__file__, "templates", "sidepanel.html")) motifs = results.get_motifs_for_region(region_layer.region_feature) html.add_sidepanel_section("Lanthipeptides", template.render(results=motifs)) return html
def generate_div(tag: str, region_layer: RegionLayer, record_layer: RecordLayer, template_name: str, tooltip: str, results: List[Tuple[ReferenceRegion, float]], proto_results: ScoresByProtocluster, active: bool, label: str, url: Optional[str]) -> Markup: """ Generates a single div within the details body for different kinds of comparisons against a particular database. Arguments: tag: the type of analysis region_layer: the relevant RegionLayer record_layer: the relevant RecordLayer template_name: the name of the template file to use tooltip: the tooltip to use for the section results: a ranked list of ReferenceRegion and scores proto_results: details usd in calculating the region ranking active: whether this particular div should be the default drawn label: the name of the database to use within the div url: a optional URL to use for linking a reference region externally Returns: a Markup instance of the generated div """ template = FileTemplate( path.get_full_path(__file__, "templates", f"{template_name}.html")) return template.render( tag=tag, record=record_layer, region=region_layer, tooltip=tooltip, results=results, proto_results=proto_results, extra_class="comparison-container-active" if active else "", class_name=label, url=url)
def generate_html(region_layer: RegionLayer, results: ModuleResults, _record_layer: RecordLayer, _options_layer: OptionsLayer) -> HTMLSections: """ Generates the HTML sections for all sideloaded annotations """ assert isinstance(results, SideloadedResults) template = FileTemplate( path.get_full_path(__file__, "templates", "general.html")) tooltip_content = ( "This annotation was made externally by %r and not by antiSMASH") html = HTMLSections("sideloaded") tools_by_name = {} areas_by_tool_name = defaultdict(list) for area in results.get_areas(): if not region_layer.location.start <= area.start <= region_layer.location.end: continue areas_by_tool_name[area.tool.name].append(area) tools_by_name[area.tool.name] = area.tool for tool_name, areas in areas_by_tool_name.items(): # avoid HTML class names containing spaces html_name = tool_name.replace(" ", "-") html.add_detail_section( tool_name, template.render( tool=tools_by_name[tool_name], areas=areas, tooltip_content=tooltip_content % tool_name, ), html_name) return html
def generate_html(region_layer: RegionLayer, results: T2PKSResults, _record_layer: RecordLayer, options_layer: OptionsLayer) -> HTMLSections: """ Generate the sidepanel HTML with results from the type II PKS module """ html = HTMLSections("t2pks") predictions = [] for cluster in region_layer.get_unique_clusters(): if cluster.product == "T2PKS": predictions.append( results.cluster_predictions[cluster.get_cluster_number()]) template = FileTemplate( path.get_full_path(__file__, "templates", "sidepanel.html")) docs_url = options_layer.urls.docs_baseurl + "modules/t2pks" tooltip_content = ( "Predictions of starter units, elongations, product classes, " "and potential molecular weights for type II PKS clusters.") tooltip_content += "<br>More detailed information is available <a href='%s' target='_blank'>here</a>." % docs_url html.add_sidepanel_section( "Type II PKS", template.render(predictions=predictions, tooltip_content=tooltip_content)) return html
def generate_html(region_layer: RegionLayer, _results: ModuleResults, _record_layer: RecordLayer, _options_layer: OptionsLayer ) -> HTMLSections: """ Generate the details section of NRPS/PKS domains in the main HTML output """ template = FileTemplate(path.get_full_path(__file__, 'templates', 'details.html')) section = template.render(has_domain_details=has_domain_details, region=region_layer) html = HTMLSections("nrps_pks") html.add_detail_section("NRPS/PKS domains", section) return html
def generate_webpage(records: List[Record], results: List[Dict[str, module_results.ModuleResults]], options: ConfigType) -> None: """ Generates and writes the HTML itself """ generate_searchgtr_htmls(records, options) json_records, js_domains = build_json_data(records, results, options) write_regions_js(json_records, options.output_dir, js_domains) with open(os.path.join(options.output_dir, 'index.html'), 'w') as result_file: template = FileTemplate( path.get_full_path(__file__, "templates", "overview.html")) options_layer = OptionsLayer(options) record_layers_with_regions = [] record_layers_without_regions = [] results_by_record_id = { } # type: Dict[str, Dict[str, module_results.ModuleResults]] for record, record_results in zip(records, results): if record.get_regions(): record_layers_with_regions.append( RecordLayer(record, None, options_layer)) else: record_layers_without_regions.append( RecordLayer(record, None, options_layer)) results_by_record_id[record.id] = record_results regions_written = sum(len(record.get_regions()) for record in records) job_id = os.path.basename(options.output_dir) page_title = "" if options.html_title: page_title = options.html_title elif options.sequences: page_title, _ = os.path.splitext( os.path.basename(options.sequences[0])) elif options.reuse_results: page_title, _ = os.path.splitext( os.path.basename(options.reuse_results)) html_sections = generate_html_sections(record_layers_with_regions, results_by_record_id, options) aux = template.render( records=record_layers_with_regions, options=options_layer, version=options.version, extra_data=js_domains, regions_written=regions_written, sections=html_sections, results_by_record_id=results_by_record_id, config=options, job_id=job_id, page_title=page_title, records_without_regions=record_layers_without_regions) result_file.write(aux)
def generate_div(region_layer: RegionLayer, record_layer: RecordLayer, options_layer: OptionsLayer, search_type: str) -> Markup: """ Generates the specific HTML section of the body for a given variant of clusterblast """ template = FileTemplate( path.get_full_path(__file__, "templates", "%s.html" % search_type)) return template.render(record=record_layer, region=region_layer, options=options_layer)
def generate_html(region_layer: RegionLayer, results: NRPS_PKS_Results, record_layer: RecordLayer, options_layer: OptionsLayer) -> HTMLSections: """ Generate the sidepanel HTML with results from the NRPS/PKS module """ html = HTMLSections("nrps_pks") nrps_layer = NrpspksLayer(results, region_layer.region_feature, record_layer) features_with_domain_predictions: Dict[str, List[str]] = {} for domain_name, consensus in results.consensus.items(): if not consensus: continue domain = record_layer.get_domain_by_name(domain_name) features_with_domain_predictions[domain.locus_tag] = [] for feature_name, monomers in features_with_domain_predictions.items(): for domain in record_layer.get_cds_by_name( feature_name).nrps_pks.domains: monomer = results.consensus.get(domain.feature_name) if monomer: monomers.append(monomer) prod_tt = ( "Shows estimated product structure and polymer for each candidate cluster in the region. " "To show the product, click on the expander or the candidate cluster feature drawn in the overview. " ) mon_tt = ( "Shows the predicted monomers for each adynelation domain and acyltransferase within genes. " "Each gene prediction can be expanded to view detailed predictions of each domain. " "Each prediction can be expanded to view the predictions by tool " " (and, for some tools, further expanded for extra details). ") if not nrps_layer.has_any_polymer(): return html for filename, name, class_name, tooltip in [ ("products.html", "NRPS/PKS products", "nrps_pks_products", prod_tt), ("monomers.html", "NRPS/PKS monomers", "", mon_tt) ]: template = FileTemplate( path.get_full_path(__file__, "templates", filename)) section = template.render( record=record_layer, region=nrps_layer, results=results, relevant_features=features_with_domain_predictions, options=options_layer, tooltip=tooltip) html.add_sidepanel_section(name, section, class_name) return html
def generate_html_sections( records: List[RecordLayer], results: Dict[str, Dict[str, module_results.ModuleResults]], options: ConfigType) -> Dict[str, Dict[int, List[HTMLSections]]]: """ Generates a mapping of record->region->HTMLSections for each record, region and module Arguments: records: a list of RecordLayers to pass through to the modules results: a dictionary mapping record name to a dictionary mapping each module name to its results object options: the current antiSMASH config Returns: a dictionary mapping record id to a dictionary mapping region number to a list of HTMLSections, one for each module """ details = {} for record in records: record_details = {} record_result = results[record.id] for region in record.regions: sections = [] for handler in region.handlers: if handler.will_handle(region.products): handler_results = record_result.get(handler.__name__) if handler_results is None: continue sections.append( handler.generate_html(region, handler_results, record, options)) record_details[region.get_region_number()] = sections if any( record.get_pfam_domains_in_cds(cds) for cds in region.cds_children): html = HTMLSections("pfam-domains") template = FileTemplate( path.get_full_path(__file__, "templates", "pfam_domains.html")) tooltip = """Shows Pfam domains found in each gene within the region. Click on each domain for more information about the domain's accession, location, description, and any relevant Gene Ontology. Domains with a bold border have Gene Ontology information. """ section = template.render(region=region, record=record, tooltip=tooltip) html.add_detail_section("Pfam domains", section, "pfam-details") sections.append(html) details[record.id] = record_details return details
def generate_html(region_layer: RegionLayer, results: LassoResults, record_layer: RecordLayer, _options_layer: OptionsLayer) -> HTMLSections: """ Generates HTML for the module """ html = HTMLSections("lassopeptides") motifs_in_region = {} for locus in results.motifs_by_locus: if record_layer.get_cds_by_name(locus).is_contained_by( region_layer.region_feature): motifs_in_region[locus] = results.motifs_by_locus[locus] template = FileTemplate( path.get_full_path(__file__, "templates", "details.html")) html.add_detail_section("Lasso peptides", template.render(results=motifs_in_region)) template = FileTemplate( path.get_full_path(__file__, "templates", "sidepanel.html")) html.add_sidepanel_section("Lasso peptides", template.render(results=motifs_in_region)) return html
def generate_html(region_layer: RegionLayer, results: ClusterCompareResults, record_layer: RecordLayer, _options_layer: OptionsLayer) -> HTMLSections: """ Generates the HTML sections for all variants """ html = HTMLSections("cluster-compare") base_tooltip = ( "Shows careas that are similar to the current region to a reference database.<br>" "Mouseover a score cell in the table to get a breakdown of how " "the score was calculated.") for label, db_results in results.by_database.items(): tooltip = base_tooltip if db_results.description: tooltip += f"{db_results.description}<br>" if db_results.url: tooltip += f"<br>Click on an accession to open that entry in the {db_results.name} database." variant_results = db_results.by_region.get( region_layer.get_region_number(), {}) divs: List[Tuple[str, str, Markup]] = [] for variant, result in sorted(variant_results.items()): scores = result.scores_by_region[:DISPLAY_LIMIT] scores_by_proto = result.details.details tag = variant.replace(" ", "-") search_type = "row" kind = "Protocluster to Region" if "ProtoToProto" in variant: kind = "Protocluster to Protocluster" search_type = "matrix" elif "RegionToRegion" in variant: kind = "Region to Region" search_type = "single" assert isinstance(scores_by_proto, list) scores_by_proto = scores_by_proto[:DISPLAY_LIMIT] div = generate_div(tag, region_layer, record_layer, search_type, tooltip, scores, scores_by_proto, len(divs) == 0, label, db_results.url) divs.append((tag, kind, div)) template = FileTemplate( path.get_full_path(__file__, "templates", "gathered.html")) markup = template.render(variants=divs, class_name=label, description="Similar gene clusters", tooltip=tooltip, anchor=region_layer.anchor_id) html.add_detail_section(f"{label} comparison", markup, label + "-cluster-compare") return html
def generate_html(region_layer: RegionLayer, results: LassoResults, record_layer: RecordLayer, _options_layer: OptionsLayer) -> HTMLSections: """ Generates HTML for the module """ html = HTMLSections("lassopeptides") motifs_in_region = {} for locus in results.motifs_by_locus: if record_layer.get_cds_by_name(locus).is_contained_by(region_layer.region_feature): motifs_in_region[locus] = results.motifs_by_locus[locus] detail_tooltip = ("Lists the possible core peptides for each biosynthetic enzyme, including the predicted class. " "Each core peptide shows the leader and core peptide sequences, separated by a dash.") template = FileTemplate(path.get_full_path(__file__, "templates", "details.html")) html.add_detail_section("Lasso peptides", template.render(results=motifs_in_region, tooltip=detail_tooltip)) side_tooltip = ("Lists the possible core peptides in the region. " "Each core peptide lists the number of disulfide bridges, possible molecular weights, " "and the scores for cleavage site prediction and RODEO.") template = FileTemplate(path.get_full_path(__file__, "templates", "sidepanel.html")) html.add_sidepanel_section("Lasso peptides", template.render(results=motifs_in_region, tooltip=side_tooltip)) return html
def generate_html(region_layer: RegionLayer, results: RREFinderResults, _record_layer: RecordLayer, _options_layer: OptionsLayer) -> HTMLSections: """ Generates HTML output for the module """ html = HTMLSections("rrefinder") side_tooltip = ("RREfinder results sidepanel.") template = FileTemplate( path.get_full_path(__file__, "templates", "sidepanel.html")) html.add_sidepanel_section( "RREFinder", template.render(results=results, region=region_layer.region_feature, tooltip=side_tooltip), "RREfinder") return html
def generate_html(region_layer: RegionLayer, results: T2PKSResults, _record_layer: RecordLayer, _options_layer: OptionsLayer) -> HTMLSections: """ Generate the sidepanel HTML with results from the type II PKS module """ html = HTMLSections("t2pks") predictions = [] for cluster in region_layer.get_unique_clusters(): if cluster.product == "t2pks": predictions.append( results.cluster_predictions[cluster.get_cluster_number()]) template = FileTemplate( path.get_full_path(__file__, "templates", "sidepanel.html")) html.add_sidepanel_section("Type II PKS", template.render(predictions=predictions)) return html
def generate_html(region_layer: RegionLayer, _results: ModuleResults, _record_layer: RecordLayer, options_layer: OptionsLayer) -> HTMLSections: """ Generate the details section of NRPS/PKS domains in the main HTML output """ template = FileTemplate( path.get_full_path(__file__, 'templates', 'details.html')) html = HTMLSections("nrps_pks") if not has_domain_details(region_layer): return html # hide lids by default if none have predictions (e.g. in a minimal run) hide_lids = not domains_have_predictions(region_layer) section = template.render(has_domain_details=has_domain_details, region=region_layer, docs_url=options_layer.urls.docs_baseurl, hide_lids=hide_lids) html.add_detail_section("NRPS/PKS domains", section) return html
def generate_html(region_layer: RegionLayer, results: NRPS_PKS_Results, record_layer: RecordLayer, options_layer: OptionsLayer) -> HTMLSections: """ Generate the sidepanel HTML with results from the NRPS/PKS module """ html = HTMLSections("nrps_pks") nrps_layer = NrpspksLayer(results, region_layer.region_feature, record_layer) features_with_domain_predictions = {} # type: Dict[str, List[str]] for domain_name, consensus in results.consensus.items(): if not consensus: continue domain = record_layer.get_domain_by_name(domain_name) features_with_domain_predictions[domain.locus_tag] = [] for feature_name, monomers in features_with_domain_predictions.items(): for domain in record_layer.get_cds_by_name( feature_name).nrps_pks.domains: monomer = results.consensus.get(domain.feature_name) if monomer: monomers.append(monomer) for filename, name, class_name in [ ("products.html", "NRPS/PKS products", "nrps_pks_products"), ("monomers.html", "NRPS/PKS monomers", "") ]: template = FileTemplate( path.get_full_path(__file__, "templates", filename)) section = template.render( record=record_layer, region=nrps_layer, results=results, relevant_features=features_with_domain_predictions, options=options_layer) html.add_sidepanel_section(name, section, class_name) return html
def generate_html(region_layer: RegionLayer, results: RREFinderResults, _record_layer: RecordLayer, _options_layer: OptionsLayer) -> HTMLSections: """ Generates HTML output for the module """ html = HTMLSections("rrefinder") side_tooltip = ("RREfinder results sidepanel.") template = FileTemplate( path.get_full_path(__file__, "templates", "sidepanel.html")) protoclusters = [] for proto in region_layer.get_unique_protoclusters(): if proto.get_protocluster_number() in results.hits_by_protocluster: protoclusters.append(proto) if protoclusters: section = template.render(results=results, protoclusters=protoclusters, tooltip=side_tooltip) html.add_sidepanel_section("RREFinder", section, class_name="RREfinder") return html
def generate_webpage(records: List[Record], results: List[Dict[str, module_results.ModuleResults]], options: ConfigType) -> None: """ Generates and writes the HTML itself """ generate_searchgtr_htmls(records, options) json_records, js_domains = build_json_data(records, results, options) write_regions_js(json_records, options.output_dir, js_domains) with open(os.path.join(options.output_dir, 'index.html'), 'w') as result_file: template = FileTemplate( path.get_full_path(__file__, "templates", "overview.html")) options_layer = OptionsLayer(options) record_layers_with_regions = [] record_layers_without_regions = [] results_by_record_id = { } # type: Dict[str, Dict[str, module_results.ModuleResults]] for record, record_results in zip(records, results): if record.get_regions(): record_layers_with_regions.append( RecordLayer(record, None, options_layer)) else: record_layers_without_regions.append( RecordLayer(record, None, options_layer)) results_by_record_id[record.id] = record_results regions_written = sum(len(record.get_regions()) for record in records) job_id = os.path.basename(options.output_dir) page_title = "" if options.html_title: page_title = options.html_title elif options.sequences: page_title, _ = os.path.splitext( os.path.basename(options.sequences[0])) elif options.reuse_results: page_title, _ = os.path.splitext( os.path.basename(options.reuse_results)) html_sections = generate_html_sections(record_layers_with_regions, results_by_record_id, options) doc_url = options.urls.docs_baseurl + "understanding_output/#the-antismash-5-region-concept" svg_tooltip = ( "Shows the layout of the region, marking coding sequences and areas of interest. " "Clicking a gene will select it and show any relevant details. " "Clicking an area feature (e.g. a candidate cluster) will select all coding " "sequences within that area. Double clicking an area feature will zoom to that area. " "Multiple genes and area features can be selected by clicking them while holding the Ctrl key." ) svg_tooltip += "<br>More detailed help is available <a href='%s' target='_blank'>here</a>." % doc_url aux = template.render( records=record_layers_with_regions, options=options_layer, version=options.version, extra_data=js_domains, regions_written=regions_written, sections=html_sections, results_by_record_id=results_by_record_id, config=options, job_id=job_id, page_title=page_title, records_without_regions=record_layers_without_regions, svg_tooltip=svg_tooltip) result_file.write(aux)