diff --git a/backend/apis/analyze.py b/backend/apis/analyze.py index f98652d..5a134f7 100644 --- a/backend/apis/analyze.py +++ b/backend/apis/analyze.py @@ -20,7 +20,8 @@ client = MongoClient(uri) db = client.gcm_gisaid -collection_db = db.seq_2021_08_26_2 +# collection_db = db.seq_2021_08_26_2 +collection_db = db.viruclust_db_0 collection_update_date = db.db_meta ######################################################################################################## @@ -306,7 +307,10 @@ class FieldList(Resource): @api.doc('update_date') def get(self): - results = collection_update_date.find({}, {"date": {"$toString": '$date_of_import'}}) + # results = collection_update_date.find({"collection_name": "seq_2021_08_26_2"}, + # {"date": {"$toString": '$date_of_import'}}) + results = collection_update_date.find({"collection_name": "viruclust_db_0"}, + {"date": {"$toString": '$date_of_import'}}) result_to_return = results[0]['date'].split('T')[0] return result_to_return diff --git a/backend/app.py b/backend/app.py index 5f0cfad..abde4f1 100644 --- a/backend/app.py +++ b/backend/app.py @@ -8,7 +8,7 @@ from apis import api_blueprint -base_url = '/viruclust_gisaid/' +base_url = '/viruclust/' api_url = base_url + 'api' repo_static_url = base_url + 'repo_static' diff --git a/frontend/src/components/AnalyzeProvinceRegion.vue b/frontend/src/components/AnalyzeProvinceRegion.vue index 03afe78..6505609 100644 --- a/frontend/src/components/AnalyzeProvinceRegion.vue +++ b/frontend/src/components/AnalyzeProvinceRegion.vue @@ -7,33 +7,33 @@

EVOLUTION IN SPACE

- +

PICK A LINEAGE, PLACE AND INTERVAL OF TIME

- + - + - + - + - + @@ -167,7 +167,7 @@ % BACKGROUND - ... + This filter allows to reduce the number of mutations shown in the results, based on the percentage of appearance of each mutation in the background population. @@ -234,7 +234,7 @@ # SEQUENCES IN BACKGROUND - ... + This filter allows to reduce the number of mutations shown in the results, based on the appearance (in absolute numbers) of each mutation in the background population. @@ -301,7 +301,7 @@ % TARGET - ... + This filter allows to reduce the number of mutations shown in the results, based on the percentage of appearance of each mutation in the target population. @@ -368,7 +368,7 @@ # SEQUENCES IN TARGET - ... + This filter allows to reduce the number of mutations shown in the results, based on the appearance (in absolute numbers) of each mutation in the target population. @@ -435,7 +435,7 @@ P-VALUE - ... + This filter allows to reduce the number of mutations shown in the results, based on their p-values. The p-value is calculated through a chi-squared test. @@ -504,7 +504,7 @@ ODDS RATIO - ... + This filter allows to reduce the number of mutations shown in the results, based on their odds ratio. The odds ratio is calculated as: (percentage in target + epsilon) / (percentage in background + epsilon) @@ -588,7 +588,7 @@ FILTER PROTEIN - ... + This filter allows to reduce the number of mutations shown in the results, based on their protein. diff --git a/frontend/src/components/AnalyzeTimeLinCou.vue b/frontend/src/components/AnalyzeTimeLinCou.vue index 7dd41ab..2e2dcc4 100644 --- a/frontend/src/components/AnalyzeTimeLinCou.vue +++ b/frontend/src/components/AnalyzeTimeLinCou.vue @@ -2,41 +2,39 @@
- - + +

EVOLUTION IN TIME

- +

PICK LINEAGE AND PLACE OF INTEREST

- + - - - + - + - + - + @@ -44,7 +42,7 @@

Exclude one or more places

- + @@ -180,7 +178,7 @@ % BACKGROUND
- ... + This filter allows to reduce the number of mutations shown in the results, based on the percentage of appearance of each mutation in the background population.
@@ -247,7 +245,7 @@ # SEQUENCES IN BACKGROUND - ... + This filter allows to reduce the number of mutations shown in the results, based on the appearance (in absolute numbers) of each mutation in the background population.
@@ -314,7 +312,7 @@ % TARGET - ... + This filter allows to reduce the number of mutations shown in the results, based on the percentage of appearance of each mutation in the target population. @@ -381,7 +379,7 @@ # SEQUENCES IN TARGET - ... + This filter allows to reduce the number of mutations shown in the results, based on the appearance (in absolute numbers) of each mutation in the target population. @@ -448,7 +446,7 @@ P-VALUE - ... + This filter allows to reduce the number of mutations shown in the results, based on their p-values. The p-value is calculated through a chi-squared test. @@ -517,7 +515,7 @@ ODDS RATIO - ... + This filter allows to reduce the number of mutations shown in the results, based on their odds ratio. The odds ratio is calculated as: (percentage in target + epsilon) / (percentage in background + epsilon) @@ -601,7 +599,7 @@ FILTER PROTEIN - ... + This filter allows to reduce the number of mutations shown in the results, based on their protein. @@ -1912,7 +1910,66 @@ export default { for(let i = 0; i < this.rowsAnalyzeTime.length; i = i + 1) { let result = JSON.parse(JSON.stringify(this.fixedRowAnalyzeTime[i])); - var that = this; + let that = this; + + // ASSOCIATE FILTERs TO BAR_CHARTs + + // if (this.selectedProteinForTable !== null) { + // let that = this; + // result = result.filter(function (i) { + // let background_frequency = JSON.parse(JSON.stringify(i['percentage_background'])); + // let target_frequency = JSON.parse(JSON.stringify(i['percentage_target'])); + // let p_value = JSON.parse(JSON.stringify(i['p_value'])); + // let background_numerator = JSON.parse(JSON.stringify(i['numerator_background'])); + // let target_numerator = JSON.parse(JSON.stringify(i['numerator_target'])); + // let odds_ratio = JSON.parse(JSON.stringify(i['odd_ratio'])); + // let product = JSON.parse(JSON.stringify(i['product'])); + // return (background_frequency >= that.selectedMinBackgroundFrequency + // && background_frequency <= that.selectedMaxBackgroundFrequency + // && target_frequency >= that.selectedMinTargetFrequency + // && target_frequency <= that.selectedMaxTargetFrequency + // && p_value >= that.selectedMinPValue + // && p_value <= that.selectedMaxPValue + // && background_numerator >= that.selectedMinBackgroundNumerator + // && background_numerator <= that.selectedMaxBackgroundNumerator + // && target_numerator >= that.selectedMinTargetNumerator + // && target_numerator <= that.selectedMaxTargetNumerator + // && + // ((odds_ratio >= that.selectedMinOddsRatio + // && odds_ratio <= that.selectedMaxOddsRatio) || + // (that.isInfinite + // && odds_ratio > that.totalMaxOddsRatio) + // ) + // && product === that.selectedProteinForTable); + // }) + // } else { + // let that = this; + // result = result.filter(function (i) { + // let background_frequency = JSON.parse(JSON.stringify(i['percentage_background'])); + // let target_frequency = JSON.parse(JSON.stringify(i['percentage_target'])); + // let p_value = JSON.parse(JSON.stringify(i['p_value'])); + // let background_numerator = JSON.parse(JSON.stringify(i['numerator_background'])); + // let target_numerator = JSON.parse(JSON.stringify(i['numerator_target'])); + // let odds_ratio = JSON.parse(JSON.stringify(i['odd_ratio'])); + // return (background_frequency >= that.selectedMinBackgroundFrequency + // && background_frequency <= that.selectedMaxBackgroundFrequency + // && target_frequency >= that.selectedMinTargetFrequency + // && target_frequency <= that.selectedMaxTargetFrequency + // && p_value >= that.selectedMinPValue + // && p_value <= that.selectedMaxPValue + // && background_numerator >= that.selectedMinBackgroundNumerator + // && background_numerator <= that.selectedMaxBackgroundNumerator + // && target_numerator >= that.selectedMinTargetNumerator + // && target_numerator <= that.selectedMaxTargetNumerator + // && + // ((odds_ratio >= that.selectedMinOddsRatio + // && odds_ratio <= that.selectedMaxOddsRatio) || + // (that.isInfinite + // && odds_ratio > that.totalMaxOddsRatio) + // )); + // }) + // } + result = result.filter(function (i){ let p_value = JSON.parse(JSON.stringify(i['p_value'])); let product = JSON.parse(JSON.stringify(i['product'])); @@ -2309,6 +2366,7 @@ export default { this.pValueBarChartApplied = false; }, selectedMinBackgroundFrequency(){ + // this.pValueBarChartApplied = false; if (this.selectedMinBackgroundFrequency < 0 ){ this.selectedMinBackgroundFrequency= 0; } @@ -2317,6 +2375,7 @@ export default { } }, selectedMaxBackgroundFrequency(){ + // this.pValueBarChartApplied = false; if (this.selectedMaxBackgroundFrequency < this.selectedMinBackgroundFrequency ){ this.selectedMaxBackgroundFrequency = this.selectedMinBackgroundFrequency; } @@ -2325,6 +2384,7 @@ export default { } }, selectedMinTargetFrequency(){ + // this.pValueBarChartApplied = false; if (this.selectedMinTargetFrequency < 0 ){ this.selectedMinTargetFrequency= 0; } @@ -2333,6 +2393,7 @@ export default { } }, selectedMaxTargetFrequency(){ + // this.pValueBarChartApplied = false; if (this.selectedMaxTargetFrequency < this.selectedMinTargetFrequency ){ this.selectedMaxTargetFrequency = this.selectedMinTargetFrequency; } @@ -2341,6 +2402,7 @@ export default { } }, selectedMinPValue(){ + // this.pValueBarChartApplied = false; if (this.selectedMinPValue < 0 ){ this.selectedMinPValue = 0; } @@ -2349,6 +2411,7 @@ export default { } }, selectedMaxPValue(){ + // this.pValueBarChartApplied = false; if (this.selectedMaxPValue < this.selectedMinPValue ){ this.selectedMaxPValue = this.selectedMinPValue; } @@ -2357,6 +2420,7 @@ export default { } }, selectedMinBackgroundNumerator(){ + // this.pValueBarChartApplied = false; if (this.selectedMinBackgroundNumerator < 0 ){ this.selectedMinBackgroundNumerator= 0; } @@ -2365,6 +2429,7 @@ export default { } }, selectedMaxBackgroundNumerator(){ + // this.pValueBarChartApplied = false; if (this.selectedMaxBackgroundNumerator < this.selectedMinBackgroundNumerator ){ this.selectedMaxBackgroundNumerator = this.selectedMinBackgroundNumerator; } @@ -2373,6 +2438,7 @@ export default { } }, selectedMinTargetNumerator(){ + // this.pValueBarChartApplied = false; if (this.selectedMinTargetNumerator < 0 ){ this.selectedMinTargetNumerator = 0; } @@ -2381,6 +2447,7 @@ export default { } }, selectedMaxTargetNumerator(){ + // this.pValueBarChartApplied = false; if (this.selectedMaxTargetNumerator < this.selectedMinTargetNumerator ){ this.selectedMaxTargetNumerator = this.selectedMinTargetNumerator; } @@ -2389,6 +2456,7 @@ export default { } }, selectedMinOddsRatio(){ + // this.pValueBarChartApplied = false; if (this.selectedMinOddsRatio < 0 ){ this.selectedMinOddsRatio = 0; } @@ -2397,6 +2465,7 @@ export default { } }, selectedMaxOddsRatio(){ + // this.pValueBarChartApplied = false; if (this.selectedMaxOddsRatio < this.selectedMinOddsRatio ){ this.selectedMaxOddsRatio = this.selectedMinOddsRatio; } diff --git a/frontend/src/components/FreeQuery.vue b/frontend/src/components/FreeQuery.vue index 30b5432..1d328d1 100644 --- a/frontend/src/components/FreeQuery.vue +++ b/frontend/src/components/FreeQuery.vue @@ -1,10 +1,10 @@ @@ -53,6 +84,9 @@ export default { return { begin_value_domain: 0, end_value_domain: 0, + params: null, + dialog_single_position: false, + single_position: null, barChart: { title: { }, @@ -101,32 +135,81 @@ export default { } ], xAxis: { - type: 'value', - splitLine: { - show: false - }, - max: 0, - minInterval: 1, - // data: [], - // splitArea: { - // interval: 0, - // show: true, - // areaStyle: { - // color: [] - // } - // } + type: 'category', + // splitLine: { + // show: false + // }, + // max: 0, + // minInterval: 1, }, yAxis: { type: 'value', // max: 0, + name: 'log(odds_ratio)', + nameTextStyle: { + fontSize: 10, + }, }, dataZoom: [ { type: 'slider', + realtime: false, + maxValueSpan: 398, }, ], }, + barChartSinglePosition: { + title: { + }, + series: [ + { + type: 'bar', + radius: '50%', + data: [], + itemStyle: {color: '#457B9D'}, + emphasis: { + itemStyle: { + shadowBlur: 10, + shadowOffsetX: 0, + shadowColor: '#457B9D' + } + }, + stack: 'one', + markArea: { + tooltip: { + show: false, + }, + data: [ [{ + xAxis: 0, + itemStyle: { + color: 'rgba(50, 255, 50, 0.5)', + }, + }, { + xAxis: 0 + }] + ] + } + } + ], + xAxis: { + type: 'category', + axisTick: { + interval: 0, + }, + axisLabel: { + interval: 0, + }, + }, + yAxis: { + type: 'value', + name: 'log(odds_ratio)', + nameTextStyle: { + fontSize: 10, + } + }, + }, my_chart: null, + my_chart_single_position: null, } }, computed: { @@ -145,6 +228,17 @@ export default { 'setStartValuePValueBarChartGeo', 'setEndValuePValueBarChartGeo', 'setStartValuePValueBarChartFree', 'setEndValuePValueBarChartFree']), ...mapActions([]), + closeDialogSinglePosition(){ + this.dialog_single_position = false; + this.params = null; + this.single_position = null; + }, + filterPoint(){ + let that = this; + this.my_chart.on('click', function (params) { + that.params = params; + }); + }, download(){ let url = this.my_chart.getConnectedDataURL({ pixelRatio: 2, @@ -304,14 +398,14 @@ export default { }, createArrayOfZeros(){ let arrY = []; - for (let j = 1; j <= this.startStopProtein['stop']; j = j + 1){ - arrY.push([j, 0, 0, 0]); + for (let j = 0; j <= this.startStopProtein['stop']; j = j + 1){ + arrY.push([j.toString(), 0, 0, 0]); } return arrY; }, createArrayOfColor(toColor){ let arrColor = []; - for (let j = 1; j <= this.startStopProtein['stop']; j = j + 1){ + for (let j = 0; j <= this.startStopProtein['stop']; j = j + 1){ if(toColor[j]){ arrColor.push(toColor[j]); } @@ -332,44 +426,55 @@ export default { let arrX = []; let arr_of_arrY = []; let arrY = []; - for (let j = 1; j <= this.startStopProtein['stop']; j = j + 1){ - arrX.push(j); - arrY.push([j, 0, 0, 0]); + for (let j = 0; j <= this.startStopProtein['stop']; j = j + 1){ + arrX.push(j.toString()); + arrY.push([j.toString(), 0, 0, 0]); } arr_of_arrY.push(arrY); this.begin_value_domain = 0; this.end_value_domain = 0; - let maxY = 0; + // let maxY = 0; while (i < len) { let single_line = met[i]; // arrX.push(single_line['name']); let single_cell; if (single_line['odds_ratio'] > this.totalMaxOddsRatio) { - if(single_line['value'] > maxY){ - maxY = single_line['value']; - } - single_cell = [single_line['position'] - 1, single_line['value'], single_line['p_value'], 'INF', single_line['name']]; + // if(Math.log(single_line['odds_ratio']) > maxY){ + // maxY = Math.log(single_line['odds_ratio']); + // } + single_cell = [single_line['position'].toString(), Math.log(single_line['odds_ratio']), single_line['p_value'], 'INF', single_line['name']]; } else { - if(single_line['value'] > maxY){ - maxY = single_line['value']; - } - single_cell = [single_line['position'] - 1, single_line['value'], single_line['p_value'], single_line['odds_ratio'], single_line['name']]; + // if(Math.log(single_line['odds_ratio']) > maxY){ + // maxY = Math.log(single_line['odds_ratio']); + // } + single_cell = [single_line['position'].toString(), Math.log(single_line['odds_ratio']), single_line['p_value'], single_line['odds_ratio'], single_line['name']]; } + // if (single_line['odds_ratio'] > this.totalMaxOddsRatio) { + // if(single_line['value'] > maxY){ + // maxY = single_line['value']; + // } + // single_cell = [single_line['position'] - 1, single_line['value'], single_line['p_value'], 'INF', single_line['name']]; + // } else { + // if(single_line['value'] > maxY){ + // maxY = single_line['value']; + // } + // single_cell = [single_line['position'] - 1, single_line['value'], single_line['p_value'], single_line['odds_ratio'], single_line['name']]; + // } let while_condition = true; let k = 0; while (while_condition) { let arr = arr_of_arrY[k]; - if (JSON.stringify(arr[single_line['position'] - 1]) === JSON.stringify([single_line['position'], 0, 0, 0])) { - arr[single_line['position'] - 1] = single_cell; + if (JSON.stringify(arr[single_line['position']].toString()) === JSON.stringify([single_line['position'], 0, 0, 0].toString())) { + arr[single_line['position']] = single_cell; while_condition = false; } else { if (k + 1 >= arr_of_arrY.length) { arr_of_arrY.push(this.createArrayOfZeros()); let arr2 = arr_of_arrY[k + 1]; - arr2[single_line['position'] - 1] = single_cell; + arr2[single_line['position']] = single_cell; while_condition = false; } } @@ -391,7 +496,7 @@ export default { else{ let color ; if(ii %2 === 1){ - color = '#A8DADC'; + color = '#A8DADC' } else{ color = '#457B9D'; @@ -595,7 +700,7 @@ export default { } // this.barChart.yAxis.max = maxY * 1.5; - this.barChart.xAxis.max = this.startStopProtein['stop']; + // this.barChart.xAxis.max = this.startStopProtein['stop']; // this.barChart.xAxis.data = arrX; // this.barChart.xAxis.splitArea.areaStyle.color = this.createArrayOfColor(toColor); @@ -622,7 +727,10 @@ export default { this.my_chart.dispose(); this.my_chart = echarts.init(document.getElementById(this.namePValue)); } + console.log("qui", this.barChart); this.my_chart.setOption(this.barChart, true); + let my_c = document.getElementById(this.namePValue); + my_c.click(); let that = this; this.my_chart.on('dataZoom', function (params) { @@ -639,6 +747,33 @@ export default { that.setEndValuePValueBarChartFree(params.end / 100 * arrX.length); } }); + }, + renderGraphSinglePosition(met){ + + this.dialog_single_position = true; + let elem = document.getElementById(this.namePValue + '_single_position'); + elem.style['width'] = 450 + 'px'; + + let len = met.length; + let arrX = []; + let arrY = []; + for (let j = 0; j < len; j++){ + arrX.push(met[j]['name'].split('_')[1]); + // arrY.push([met[j]['name'], met[j]['odds_ratio'], met[j]['p_value']]); + arrY.push(Math.log(met[j]['odds_ratio'])); + } + + this.barChartSinglePosition.series[0]['data'] = arrY; + this.barChartSinglePosition.xAxis.data = arrX; + + if(this.my_chart_single_position === null) { + this.my_chart_single_position = echarts.init(document.getElementById(this.namePValue + '_single_position')); + } + else{ + this.my_chart_single_position.dispose(); + this.my_chart_single_position = echarts.init(document.getElementById(this.namePValue + '_single_position')); + } + this.my_chart_single_position.setOption(this.barChartSinglePosition, true); } }, mounted() { @@ -646,6 +781,19 @@ export default { this.renderGraph(met); }, watch: { + params(){ + if(this.params !== null) { + this.dialog_single_position = true; + this.single_position = this.params['data'][0]; + let filtered_value = this.pValueContent.filter(x => x.position === parseInt(this.params['data'][0])); + + let delayInMilliseconds = 100; + let that = this; + setTimeout(function() { + that.renderGraphSinglePosition(filtered_value); + }, delayInMilliseconds); + } + }, metadataContent(){ let met = JSON.parse(JSON.stringify(this.pValueContent)); this.renderGraph(met); diff --git a/frontend/src/components/SelectorsPieChart.vue b/frontend/src/components/SelectorsPieChart.vue index b45dcfc..debe05e 100644 --- a/frontend/src/components/SelectorsPieChart.vue +++ b/frontend/src/components/SelectorsPieChart.vue @@ -82,6 +82,7 @@ export default { { type: 'pie', radius: '50%', + cursor: 'default', data: [], emphasis: { itemStyle: { @@ -109,11 +110,34 @@ export default { if(!this.chartBlocked) { - this.pieChart.series[0].data = met.sort(function (a, b) { + let array_values = []; + let total_seq = 0; + for(let i = 0; i < met.length; i++){ + total_seq = total_seq + met[i]['value']; + } + let single_ob_others = {'name': 'Others', 'value': 0}; + for(let i = 0; i < met.length; i++){ + if(met[i]['value'] > total_seq * 0.01){ + let single_ob = {'name': met[i]['name'], 'value': met[i]['value']}; + array_values.push(single_ob); + } + else{ + single_ob_others['value'] = single_ob_others['value'] + met[i]['value']; + } + } + + array_values = array_values.sort(function (a, b) { let num1 = a['value']; let num2 = b['value']; return num1 - num2; }); + + if(single_ob_others['value'] > 0) { + array_values.push(single_ob_others); + } + + this.pieChart.series[0].data = array_values; + if (this.my_chart === null) { this.my_chart = echarts.init(document.getElementById(this.nameField)); } diff --git a/frontend/src/components/SelectorsQueryFree.vue b/frontend/src/components/SelectorsQueryFree.vue index d1af12d..026cfad 100644 --- a/frontend/src/components/SelectorsQueryFree.vue +++ b/frontend/src/components/SelectorsQueryFree.vue @@ -26,6 +26,9 @@ :multiple="checkMultiple()" :disabled="isLoading || possibleValues.length === 0" > + + Data of multiple location is merged.   +