Commit c4505d65 authored by Kenzo-Hugo Hillion's avatar Kenzo-Hugo Hillion
Browse files

Start adding filtering with a given taxonomy

parent d6ad306e
Pipeline #31356 passed with stages
in 3 minutes and 25 seconds
......@@ -78,12 +78,10 @@ class GeneStatistics(Statistics):
all_tax_ids = [el[0] for el in queryset.filter(**filter_annotation).values_list(value_to_retrieve)]
all_unique_tax_ids = list(set(all_tax_ids))
results = {
'tax_ids': [],
'tax_names': []
'tax_ids': {}
}
for taxonomy in Taxonomy.objects.filter(tax_id__in=all_unique_tax_ids):
results['tax_ids'].append(taxonomy.tax_id)
results['tax_names'].append(taxonomy.name)
results['tax_ids'][taxonomy.name] = taxonomy.tax_id
return results
......
......@@ -71,16 +71,16 @@ class TestPresentTaxonomy(BaseTestTaxonomy):
def test_present_taxonomy_no_content(self):
expected_dict = {
'tax_ids': [],
'tax_names': []
'tax_ids': {},
}
self.assertDictEqual(self.gene_stats.present_taxonomy(), expected_dict)
def test_present_taxonomy(self):
gene = GeneFactory.create(taxonomy=self.phylum) # noqa
expected_dict = {
'tax_ids': [self.phylum.tax_id],
'tax_names': [self.phylum.name]
'tax_ids': {
self.phylum.name: self.phylum.tax_id
}
}
self.assertDictEqual(self.gene_stats.present_taxonomy(), expected_dict)
......@@ -88,16 +88,18 @@ class TestPresentTaxonomy(BaseTestTaxonomy):
# Create 10 genes with the same taxonomy
GeneFactory.create_batch(10, taxonomy=self.phylum) # noqa
expected_dict = {
'tax_ids': [self.phylum.tax_id],
'tax_names': [self.phylum.name]
'tax_ids': {
self.phylum.name: self.phylum.tax_id
}
}
self.assertDictEqual(self.gene_stats.present_taxonomy(), expected_dict)
def test_taxonomy_counts_class_level(self):
gene = GeneFactory.create(taxonomy=self.class_tax) # noqa
expected_dict = {
'tax_ids': [self.class_tax.tax_id],
'tax_names': [self.class_tax.name]
'tax_ids': {
self.class_tax.name: self.class_tax.tax_id
}
}
self.assertDictEqual(self.gene_stats.present_taxonomy(level='class'), expected_dict)
......
......@@ -22,90 +22,165 @@
<template v-slot:header>
<div>Show Filters</div>
</template>
<v-card class="grey lighten-3 px-2">
<v-card-text>
<v-layout wrap align-center>
<!-- Gene source -->
<v-flex xs12 sm6 md4 lg2 d-flex>
<v-select
:items="geneSources"
v-model="geneSource"
label="Gene source"
></v-select>
</v-flex>
<!-- Taxonomy ranks -->
<v-flex xs12 sm6 md4 lg2 d-flex class="ml-2">
<v-select
:items="taxonomyRanks"
v-model="taxonomyRank"
label="Taxonomy rank"
></v-select>
</v-flex>
<!-- Function -->
<v-flex xs12 sm6 md4 lg2 d-flex class="ml-2">
<v-text-field
label="KEGG KO of EggNOG ID"
v-model="functionID"
></v-text-field>
</v-flex>
<!-- Gene length -->
<v-flex class="ml-4">
<v-switch
v-model="filterGeneLength"
label="Filter on gene length"
<v-card class="grey lighten-2">
<v-container fluid grid-list-md>
<v-layout row wrap justify-end>
<v-flex md12>
<!-- Gene Information -->
<v-toolbar dense flat dark class="primary lighten-3">
<v-toolbar-title>
Gene information
</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn icon @click="emptyGeneInformationFilter">
<v-icon>far fa-trash-alt</v-icon>
</v-btn>
</v-toolbar>
<v-card class="grey lighten-4">
<v-container fluid >
<v-layout wrap>
<!-- Gene source -->
<v-flex xs12 sm6 md4 lg2>
<v-select
:items="geneSources"
v-model="geneSource"
label="Gene source"
></v-select>
</v-flex>
<v-spacer></v-spacer>
<!-- Gene length -->
<v-flex xs12 sm6 md4 lg2>
<v-switch
v-model="filterGeneLength"
label="Filter on gene length"
color="secondary lighten-1"
></v-switch>
</v-flex>
<v-spacer></v-spacer>
<v-flex lg6>
<v-layout>
<v-flex
shrink
style="width: 60px"
v-if="filterGeneLength"
>
<v-text-field
v-model="geneLengthFilterRange[0]"
class="mt-0"
hide-details
single-line
type="number"
></v-text-field>
</v-flex>
<v-flex class="mx-4" v-if="filterGeneLength">
<v-range-slider
v-model="geneLengthFilterRange"
color="secondary lighten-1"
:max="maxGeneLength"
:min="minGeneLength"
></v-range-slider>
</v-flex>
<v-flex
shrink
style="width: 60px"
v-if="filterGeneLength"
>
<v-text-field
v-model="geneLengthFilterRange[1]"
class="mt-0"
hide-details
single-line
type="number"
></v-text-field>
</v-flex>
</v-layout>
</v-flex>
</v-layout>
</v-container>
</v-card>
</v-flex>
<v-flex xs12 md6>
<!-- Taxonomy -->
<v-toolbar dense flat dark class="taxonomy lighten-3">
<v-toolbar-title>
Taxonomy
</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn icon @click="emptyTaxonomyFilter">
<v-icon>far fa-trash-alt</v-icon>
</v-btn>
</v-toolbar>
<v-card class="grey lighten-4">
<v-container
fluid
grid-list-md
>
<v-layout>
<!-- Taxonomy ranks -->
<v-flex sm12 md8 lg4 d-flex>
<v-select
:items="taxLevels"
v-model="taxLevel"
label="Taxonomy level"
@input="getTaxoPresence"
></v-select>
</v-flex>
<v-flex sm12 md8 lg4 d-flex>
<v-select
:items="taxChoices"
v-model="taxChoice"
label="Taxonomy"
v-if="taxLevel"
></v-select>
</v-flex>
</v-layout>
</v-container>
</v-card>
</v-flex>
<v-flex xs12 md6>
<!-- Function -->
<v-toolbar dense flat dark class="function">
<v-toolbar-title>
Function
</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn icon @click="emptyFunctionFilter">
<v-icon>far fa-trash-alt</v-icon>
</v-btn>
</v-toolbar>
<v-card class="grey lighten-4">
<v-container
fluid
grid-list-md
>
<v-layout>
<!-- Function -->
<v-flex sm12 md8 lg6 d-flex>
<v-text-field
label="Enter KEGG KO of EggNOG ID"
v-model="functionID"
></v-text-field>
</v-flex>
</v-layout>
</v-container>
</v-card>
</v-flex>
</v-layout>
<v-layout row wrap justify-end>
<v-btn
color="deep-orange lighten-1 white--text"
@click="emptyFilters"
>
Clear all
</v-btn>
<v-btn
color="secondary lighten-1"
></v-switch>
</v-flex>
<v-flex
shrink
style="width: 60px"
v-if="filterGeneLength"
>
<v-text-field
v-model="geneLengthFilterRange[0]"
class="mt-0"
hide-details
single-line
type="number"
></v-text-field>
</v-flex>
<v-flex class="mx-4" v-if="filterGeneLength">
<v-range-slider
v-model="geneLengthFilterRange"
color="secondary lighten-1"
:max="maxGeneLength"
:min="minGeneLength"
></v-range-slider>
</v-flex>
<v-flex
shrink
style="width: 60px"
v-if="filterGeneLength"
>
<v-text-field
v-model="geneLengthFilterRange[1]"
class="mt-0"
hide-details
single-line
type="number"
></v-text-field>
</v-flex>
</v-layout>
<v-layout row wrap justify-end>
<v-btn
color="deep-orange lighten-1 white--text"
@click="emptyFilters"
>
Clear<v-icon right>far fa-window-close</v-icon>
</v-btn>
<v-btn
color="secondary lighten-1"
@click="runSearch"
>
Apply<v-icon right>far fa-check-square</v-icon>
</v-btn>
</v-layout>
</v-card-text>
@click="runSearch"
>
Apply<v-icon right>far fa-check-square</v-icon>
</v-btn>
</v-layout>
</v-container>
</v-card>
</v-expansion-panel-content>
</v-expansion-panel>
......
......@@ -11,13 +11,19 @@ export default {
pagination: {
rowsPerPage: 20,
},
// Filters
// - Gene info
geneSource: null,
searchGeneName: null,
taxonomyRank: null,
functionID: null,
requestDone: false,
filterGeneLength: false,
geneLengthFilterRange: [0, 2000],
// - Taxonomy
taxLevel: null,
taxItems: [],
taxChoice: null,
// - Function
functionID: null,
requestDone: false,
};
},
computed: {
......@@ -36,14 +42,14 @@ export default {
{ text: 'Source', value: 'source', sortable: false },
];
},
taxonomyRanks() {
taxLevels() {
return [
'Phylum', 'Class', 'Order', 'Family', 'Genus', 'Species'
'Kingdom', 'Superkingdom', 'Phylum', 'Class', 'Order', 'Family', 'Genus', 'Species'
];
},
geneSources() {
return [
'IGC', 'Virgo'
'IGC', 'Virgo',
]
},
rowsPerPageItems() {
......@@ -51,9 +57,6 @@ export default {
},
qParams() {
const qParams = { page_size: this.page_size };
if (this.taxonomyRank) {
qParams.taxonomy_rank = this.taxonomyRank.toLowerCase();
}
if (this.filterGeneLength) {
qParams.length__gt = this.geneLengthFilterRange[0];
qParams.length__lt = this.geneLengthFilterRange[1];
......@@ -75,6 +78,9 @@ export default {
minGeneLength() {
return 0;
},
taxChoices() {
return Object.keys(this.taxItems).sort();
},
},
mounted() {
this.getGenes();
......@@ -88,12 +94,12 @@ export default {
},
})
.then((response) => {
const ncbiTaxUrl = 'https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?name=';
const ncbiTaxUrl = 'https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?id=';
const keggUrl = 'https://www.genome.jp/dbget-bin/www_bget?ko:';
const genes = response.data.results;
genes.forEach((item, index) => {
if (item.taxonomy) {
item.tax_url = ncbiTaxUrl + item.taxonomy.name;
item.tax_url = ncbiTaxUrl + item.taxonomy.tax_id;
item.taxonomy = `${item.taxonomy.name} (${item.taxonomy.rank})`;
}
if (item.functions) {
......@@ -117,13 +123,36 @@ export default {
this.requestDone = true;
});
},
emptyFilters() {
this.taxonomyRank = null;
this.functionID = null;
emptyGeneInformationFilter() {
this.geneSource = null;
this.filterGeneLength = false;
this.geneLengthFilterRange = [0, 2000];
},
emptyTaxonomyFilter() {
this.taxonomyRank = null;
},
emptyFunctionFilter() {
this.functionID = null;
},
emptyFilters() {
this.emptyGeneInformationFilter();
this.emptyTaxonomyFilter();
this.emptyFunctionFilter();
},
getTaxoPresence() {
var endpoint = `/api/catalog/v1/statistics/genestatistics-all-present-taxonomy-${this.taxLevel}`;
axios.get(endpoint.toLowerCase(), {
headers: {
Accept: 'application/json',
},
})
.then((response) => {
this.taxItems = response.data.body.tax_ids;
})
.catch((error) => {
console.error(error);
});
},
runSearch() {
this.requestDone = false;
this.getGenes();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment