-
{{header}} | - {% endfor %} - -||||||||||
---|---|---|---|---|---|---|---|---|---|---|
{{entry.1}} | -{{entry.2}} | -{{entry.3}} | -{{entry.4}} | -{{entry.5}} | -{{entry.6}} | -{{entry.7}} | -.faa | -.fna | -.ffn | -.gbk | -
Help
-This table contains the list of genomes included in the database and a summary of their content.
Clicking on the genome name (first column) a second table with the protein content is displayed. It shows to which contig each protein belongs and provides the link to the locus tags.
-
Fasta and gbk files can be downloaded.
-
+
Help
++ {{results.table_help|safe}} +
++ {{description|safe}} +
+ {% include "chlamdb/error.html" %} + {% load crispy_forms_tags %} + {% block content %} + {% csrf_token %} + {% crispy form %} + {% endblock %} ++ {{description|safe}} +
+Help
++ {{genome_table.table_help|safe}} +
+ ++ {{description|safe}} +
+{{object_name_plural}}
+{{group|safe}} |
Custom plots
+ + +
{{metadata.group_metadata.object_name_plural}}
+{{metadata.group_metadata.overview_description|safe}}
+diff --git a/webapp/templates/chlamdb/menu.html b/webapp/templates/chlamdb/menu.html index e0b9f6304..5c9e7bacc 100644 --- a/webapp/templates/chlamdb/menu.html +++ b/webapp/templates/chlamdb/menu.html @@ -106,6 +106,10 @@ Custom plots +
Clicking on the genome name " + "(first column) a second table with the protein content is displayed. " + "It shows to which contig each protein belongs and provides the link " + "to the locus tags.
Fasta and gbk files can be downloaded.") + + @property + def genome_table_help(self): + return self._genome_table_help.format(self.genome_source_object) + + def get_genomes_table(self, taxids=None): + genomes_data = get_genomes_data(self.db, taxids=taxids) + + filenames_tax_id = self.db.get_filenames_to_taxon_id() + filenames_tax_id_db = pd.DataFrame.from_dict(list(filenames_tax_id.items())) + filenames_tax_id_db.columns = ['filename', 'taxon_id'] + filenames_tax_id_db.index = list(filenames_tax_id_db['taxon_id']) + filenames_list = list(filenames_tax_id_db["filename"]) + + path_template = settings.BLAST_DB_PATH + "/{ext}/{filename}.{ext}" + link_template = ' .{{ext}} '.format(path_template) + for ext in ["faa", "fna", "ffn", "gbk"]: + filenames_tax_id_db[f'path_to_{ext}'] = [ + link_template.format(filename=filename, ext=ext) + for filename in filenames_list] + + filenames_tax_id_db = filenames_tax_id_db[ + ["path_to_faa", "path_to_fna", "path_to_ffn", "path_to_gbk"]] + genomes_data = genomes_data.join(filenames_tax_id_db, on="taxon_id") + + genomes_data["accession"] = genomes_data[["id", "description"]].apply( + format_genome, axis=1) + + data_table_header = [ + "Name", + "GC %", + "N proteins", + "N contigs", + "Size (Mbp)", + "Coding %", + "N plasmid contigs", + "faa seq", + "fna seq", + "ffn seq", + "gbk file" + ] + + table_data_accessors = [ + "accession", + "gc", + "n_prot", + "n_contigs", + "length", + "coding_density", + "has_plasmid", + "path_to_faa", + "path_to_fna", + "path_to_ffn", + "path_to_gbk"] + + table_data = genomes_data[table_data_accessors] + + return {"table_data": table_data, + "table_headers": data_table_header, + "data_table_config": DataTableConfig(), + "table_data_accessors": table_data_accessors, + "table_help": self.genome_table_help} diff --git a/webapp/views/object_type_metadata.py b/webapp/views/object_type_metadata.py index 481644ad1..562ad8fd8 100644 --- a/webapp/views/object_type_metadata.py +++ b/webapp/views/object_type_metadata.py @@ -1,3 +1,5 @@ +from urllib.parse import quote + from views.utils import (format_amr, format_cog, format_ko, format_orthogroup, format_pfam, missing_mandatory, optional2status) @@ -126,6 +128,19 @@ def index_comp_url(self): return None +class GroupMetadata(BaseObjectMetadata): + + object_type = "group" + object_name = "Genome Group" + overview_description = "Overview of defined groups of genomes." + + @staticmethod + def format_entry(entry, to_url=False): + if to_url: + return f"{entry}" + return entry + + class MetadataGetter(): metadata_classes = [AmrMetadata, CogMetadata, KoMetadata, PfamMetadata, @@ -149,6 +164,10 @@ def get_orthology_metadata(self): return (self.object_type_to_metadata[object_type] for object_type in self._orthology) + @property + def group_metadata(self): + return GroupMetadata() + def my_locals(local_dico): local_dico["optional2status"] = optional2status diff --git a/webapp/views/utils.py b/webapp/views/utils.py index 633e74119..258923e81 100644 --- a/webapp/views/utils.py +++ b/webapp/views/utils.py @@ -25,6 +25,7 @@ def safe_replace(string, search_string, replace_string): 'Genome alignments: Circos plot': ['circos'], 'Genome alignments: Plot region': ['plot_region'], 'Genomes: table of contents': ['extract_contigs'], + 'Genome groups': ['groups'], 'Homology search: Blast': ['blast'], 'Kegg Ortholog': ['fam_ko'], 'Kegg metabolic pathways': ['kegg_genomes'], @@ -205,6 +206,11 @@ def format_swissprot_entry(entry_id): return f'{entry_id}' +def format_genome(taxid_and_description): + taxid, description = taxid_and_description + return f'{description}' + + class DataTableConfig(): def __init__(self, table_id="results", ordering=True, paging=True, @@ -508,12 +514,13 @@ def get_choices(self, with_plasmids=True, with_groups=True, accession_choices.extend([(self.group_id_to_key(group[0]), group[0]) for group in self.db.get_groups()]) + exclude = set(exclude) # We also exclude taxids contained in the excluded groups groups_to_exclude = [self.group_key_to_id(key) for key in exclude if self.is_group(key)] if groups_to_exclude: in_groups = self.db.get_taxids_for_groups(groups_to_exclude) - exclude = set(exclude).union({str(el) for el in in_groups}) + exclude = exclude.union({str(el) for el in in_groups}) # And we exclude groups containing an excluded taxid taxids_to_exclude = list(filter(self.is_taxid, exclude)) @@ -528,7 +535,7 @@ def get_choices(self, with_plasmids=True, with_groups=True, if self.is_group(key)] if groups_to_exclude: in_groups = self.db.get_taxids_for_groups(groups_to_exclude) - exclude = set(exclude).union({str(el) for el in in_groups}) + exclude = exclude.union({str(el) for el in in_groups}) accession_choices = filter(lambda choice: choice[0] not in exclude, accession_choices) @@ -554,3 +561,15 @@ def extract_choices(self, indices, include_plasmids): taxids.update(self.db.get_taxids_for_groups(groups)) return list(taxids), plasmids + + +def get_genomes_data(db, taxids=None): + genomes_data = db.get_genomes_infos(taxids=taxids) + genomes_descr = db.get_genomes_description(taxids=taxids) + + genomes_data = genomes_data.join(genomes_descr) + + genomes_data.gc = genomes_data.gc.apply(lambda x: round(100 * x)) + genomes_data.coding_density = genomes_data.coding_density.apply(lambda x: round(100 * x)) + genomes_data.length = genomes_data.length.apply(lambda x: round(x / pow(10, 6), 2)) + return genomes_data diff --git a/webapp/views/views.py b/webapp/views/views.py index 4fa8618ea..731ba0e12 100644 --- a/webapp/views/views.py +++ b/webapp/views/views.py @@ -43,12 +43,14 @@ CategoriesFreqHeatmapMetadata, HeatmapMetadata) from views.errors import errors -from views.mixins import CogViewMixin, ComparisonViewMixin, KoViewMixin +from views.mixins import (BaseViewMixin, CogViewMixin, ComparisonViewMixin, + GenomesTableMixin, KoViewMixin) from views.object_type_metadata import MetadataGetter, my_locals from views.utils import (TabularResultTab, format_cog, format_gene, format_ko, format_locus, format_orthogroup, - genomic_region_df_to_js, locusx_genomic_region, - make_div, optional2status, page2title, to_s) + genomic_region_df_to_js, get_genomes_data, + locusx_genomic_region, make_div, optional2status, + page2title, to_s) def id_generator(size=6, chars=string.ascii_uppercase + string.ascii_lowercase + string.digits): @@ -142,73 +144,15 @@ def get(self, request): return render(request, 'chlamdb/index_comp.html', context) -def get_genomes_data(db): - genomes_data = db.get_genomes_infos() - genomes_descr = db.get_genomes_description() +class Genomes(BaseViewMixin, View, GenomesTableMixin): - genomes_data = genomes_data.join(genomes_descr) + template = 'chlamdb/genomes.html' + view_name = "genomes" + genome_source_object = "database" - genomes_data.gc = genomes_data.gc.apply(lambda x: round(100 * x)) - genomes_data.coding_density = genomes_data.coding_density.apply(lambda x: round(100 * x)) - genomes_data.length = genomes_data.length.apply(lambda x: round(x / pow(10, 6), 2)) - return genomes_data - - -def genomes(request): - biodb_path = settings.BIODB_DB_PATH - db = DB.load_db_from_name(biodb_path) - page_title = page2title["genomes"] - genomes_data = get_genomes_data(db) - - filenames_tax_id = db.get_filenames_to_taxon_id() - filenames_tax_id_db = pd.DataFrame.from_dict(list(filenames_tax_id.items())) - filenames_tax_id_db.columns = ['filename', 'taxon_id'] - filenames_tax_id_db.index = list(filenames_tax_id_db['taxon_id']) - filenames_list = list(filenames_tax_id_db["filename"]) - - path_faa = [settings.BLAST_DB_PATH + "/faa/" + filename + ".faa" - for filename in filenames_list] - path_fna = [settings.BLAST_DB_PATH + "/fna/" + filename + ".fna" - for filename in filenames_list] - path_ffn = [settings.BLAST_DB_PATH + "/ffn/" + filename + ".ffn" - for filename in filenames_list] - path_gbk = [settings.BLAST_DB_PATH + "/gbk/" + filename + ".gbk" - for filename in filenames_list] - - filenames_tax_id_db['path_to_faa'] = path_faa - filenames_tax_id_db['path_to_fna'] = path_fna - filenames_tax_id_db['path_to_ffn'] = path_ffn - filenames_tax_id_db['path_to_gbk'] = path_gbk - filenames_tax_id_db = filenames_tax_id_db[["path_to_faa", "path_to_fna", - "path_to_ffn", "path_to_gbk"]] - genomes_data = genomes_data.join(filenames_tax_id_db, on="taxon_id") - data_table_header = [ - "Name", - "GC %", - "N proteins", - "N contigs", - "Size (Mbp)", - "Coding %", - "N plasmid contigs", - "faa seq", - "fna seq", - "ffn seq", - "gbk file" - ] - data_table = genomes_data[[ - "id", - "description", - "gc", - "n_prot", - "n_contigs", - "length", - "coding_density", - "has_plasmid", - "path_to_faa", - "path_to_fna", - "path_to_ffn", - "path_to_gbk"]].values.tolist() - return render(request, 'chlamdb/genomes.html', my_locals(locals())) + def get(self, request, *args, **kwargs): + results = self.get_genomes_table() + return render(request, self.template, self.get_context(results=results)) def extract_contigs(request, genome):