Commit 559a8d26 authored by Floreal Cabanettes's avatar Floreal Cabanettes
Browse files

Add summary stats, Implements #18

parent e266b136
...@@ -8,6 +8,7 @@ from pathlib import Path ...@@ -8,6 +8,7 @@ from pathlib import Path
import matplotlib as mpl import matplotlib as mpl
mpl.use('Agg') mpl.use('Agg')
from matplotlib import pyplot as plt from matplotlib import pyplot as plt
import json
class Paf: class Paf:
...@@ -128,10 +129,10 @@ class Paf: ...@@ -128,10 +129,10 @@ class Paf:
min_idy = 10000000000 min_idy = 10000000000
max_idy = -10000000000 max_idy = -10000000000
lines = { lines = {
"0": [], "0": [], # idy < 0.25
"1": [], "1": [], # idy < 0.5
"2": [], "2": [], # idy < 0.75
"3": [] "3": [] # idy > 0.75
} }
try: try:
name_q, q_order, q_contigs, q_reversed, q_abs_start, q_abs_current_start, q_len = self.load_index( name_q, q_order, q_contigs, q_reversed, q_abs_start, q_abs_current_start, q_len = self.load_index(
...@@ -508,12 +509,35 @@ class Paf: ...@@ -508,12 +509,35 @@ class Paf:
Get summary of identity Get summary of identity
:return: table with percents by category :return: table with percents by category
""" """
summary_file = self.paf + ".summary"
if os.path.exists(summary_file):
with open(summary_file, "r") as summary_file:
txt = summary_file.read()
return json.loads(txt)
self.parse_paf(False, False) self.parse_paf(False, False)
if self.parsed:
percents = {} percents = {}
total = 0 position_idy = {}
for cat in self.lines:
nb_lines = len(self.lines[cat]) cats = sorted(self.lines.keys())
percents[cat] = nb_lines
total += nb_lines for cat in cats:
for cat in self.lines: for line in self.lines[cat]:
percents[cat] /= total position_idy.update(position_idy.fromkeys(range(line[0], line[1]+1), cat))
percents[cat] = 0
import time
start = time.time()
total = self.len_t
percents["-1"] = (total - len(position_idy)) / total * 100
position_idy_values = list(position_idy.values())
for cat in cats:
percents[cat] = position_idy_values.count(cat) / total * 100
with open(summary_file, "w") as summary_file:
summary_file.write(json.dumps(percents))
return percents
return None
...@@ -34,7 +34,8 @@ d3.boxplot.color_idy = { ...@@ -34,7 +34,8 @@ d3.boxplot.color_idy = {
"3": "#094b09", "3": "#094b09",
"2": "#2ebd40", "2": "#2ebd40",
"1": "#d5670b", "1": "#d5670b",
"0": "#ffd84b" "0": "#ffd84b",
"-1": "#fff"
}; };
d3.boxplot.limit_idy = null; d3.boxplot.limit_idy = null;
d3.boxplot.min_idy_draw = 0; d3.boxplot.min_idy_draw = 0;
......
...@@ -6,10 +6,28 @@ dgenies.result.controls = {}; ...@@ -6,10 +6,28 @@ dgenies.result.controls = {};
dgenies.result.controls.init = function () { dgenies.result.controls.init = function () {
$("#sort-contigs").click(dgenies.result.controls.launch_sort_contigs); $("#sort-contigs").click(dgenies.result.controls.launch_sort_contigs);
$("#hide-noise").click(dgenies.result.controls.launch_hide_noise); $("#hide-noise").click(dgenies.result.controls.launch_hide_noise);
$("#summary").click(dgenies.result.controls.summary);
$("form#select-zone input.submit").click(dgenies.result.controls.select_zone); $("form#select-zone input.submit").click(dgenies.result.controls.select_zone);
$("form#export select").change(dgenies.result.export.export); $("form#export select").change(dgenies.result.export.export);
}; };
dgenies.result.controls.summary = function () {
dgenies.show_loading("Building...");
window.setTimeout(() => {
dgenies.post(`/summary/${dgenies.result.id_res}`,
{},
function (data) {
dgenies.hide_loading();
if (data["success"]) {
dgenies.result.summary.show(data["percents"]);
}
else {
dgenies.notify(data["message"] || "An error occurred! Please contact us to report the bug", "danger");
}
})
}, 0);
};
dgenies.result.controls.launch_sort_contigs = function () { dgenies.result.controls.launch_sort_contigs = function () {
d3.boxplot.zoom.reset_scale(); d3.boxplot.zoom.reset_scale();
window.setTimeout(() => { window.setTimeout(() => {
......
if (!dgenies || !dgenies.result) {
throw "dgenies.result wasn't included!"
}
dgenies.result.summary = {};
dgenies.result.summary.show = function(percents) {
console.log(percents);
let svgcontainer = d3.select("#draw-stats").html("").append("svg:svg")
.attr("width", "500px")
.attr("height", "220px");
let container = svgcontainer.append("svg:g");
let percents_order = ["-1", "0", "1", "2", "3"];
let x = 0;
let percent_value = 0;
for (let i in percents_order) {
let percent = percents_order[i];
let label="";
switch (percent) {
case "-1":
label = "No match";
break;
case "0":
label = "< 25 %";
break;
case "1":
label = "< 50 %";
break;
case "2":
label = "< 75 %";
break;
case "3":
label = "> 75 %";
break;
}
console.log(percent);
x += percent_value;
percent_value = percents[percent];
container.append("rect")
.attr("x", x + "%")
.attr("y", 0)
.attr("width", percent_value + "%")
.attr("height", "50px")
.attr("stroke", "none")
.attr("fill", d3.boxplot.color_idy[percent]);
container.append("rect")
.attr("x", 5)
.attr("y", 70 + (i * 30))
.attr("width", "10px")
.attr("height", "10px")
.attr("fill", d3.boxplot.color_idy[percent])
.style("stroke", "#000")
.style("stroke-width", "1px");
container.append("text")
.attr("x", 30)
.attr("y", 82 + (i * 30))
.attr("font-family", "sans-serif")
.attr("font-size", "12pt")
.text(label + ":");
container.append("text")
.attr("x", 110)
.attr("y", 82 + (i * 30))
.attr("font-family", "sans-serif")
.attr("font-size", "12pt")
.text(percent_value.toFixed(2) + " %");
}
container.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", "100%")
.attr("height", "50px")
.style("stroke", "#000")
.style("fill", "none")
.style("stroke-width", "1px");
$("#modal-stats").dialog({
title: "Summary of identity",
width: "550px",
buttons: [{
text: "Export PNG",
click: dgenies.result.summary.export_png
},{
text: "Export SVG",
click: dgenies.result.summary.export_svg
},{
text: "Close",
click: function() {
$(this).dialog("close");
}
}]
})
};
dgenies.result.summary.get_svg = function () {
return $("#draw-stats").html();
};
dgenies.result.summary.save_file = function (blob, format) {
saveAs(blob, `summary_${d3.boxplot.name_y}_to_${d3.boxplot.name_x}.${format}`);
};
dgenies.result.summary.export_svg = function () {
let blob = new Blob([dgenies.result.summary.get_svg()], {type: "image/svg+xml"});
dgenies.result.summary.save_file(blob, "svg");
};
dgenies.result.summary.export_png = function () {
let export_div = $("div#export-pict");
export_div.html("").append($("<canvas>"));
canvg(export_div.find("canvas")[0], dgenies.result.summary.get_svg());
let canvas = export_div.find("canvas")[0];
canvas.toBlob(function(blob) {
dgenies.result.summary.save_file(blob, "png");
export_div.html("");
}, "image/png");
};
\ No newline at end of file
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
<title>{{ title }}</title> <title>{{ title }}</title>
{% block scripts %} {% block scripts %}
<script src="{{ url_for('static', filename='js/jquery-3.2.1.min.js') }}" type="text/JavaScript"></script> <script src="{{ url_for('static', filename='js/jquery-3.2.1.min.js') }}" type="text/JavaScript"></script>
<script src="{{ url_for('static', filename='js/jquery-ui.min.js') }}" type="text/JavaScript"></script>
<script src="{{ url_for('static', filename='js/popper.min.js') }}" type="text/JavaScript"></script> <script src="{{ url_for('static', filename='js/popper.min.js') }}" type="text/JavaScript"></script>
<script src="{{ url_for('static', filename='js/bootstrap.min.js') }}" type="text/JavaScript"></script> <script src="{{ url_for('static', filename='js/bootstrap.min.js') }}" type="text/JavaScript"></script>
<script src="{{ url_for('static', filename='js/bootstrap-notify.min.js') }}" type="text/JavaScript"></script> <script src="{{ url_for('static', filename='js/bootstrap-notify.min.js') }}" type="text/JavaScript"></script>
<script src="{{ url_for('static', filename='js/jquery-ui.min.js') }}" type="text/JavaScript"></script>
<script src="{{ url_for('static', filename='js/dgenies.js') }}" type="text/JavaScript"></script> <script src="{{ url_for('static', filename='js/dgenies.js') }}" type="text/JavaScript"></script>
<script src="{{ url_for('static', filename='js/dgenies.prototypes.js') }}" type="text/JavaScript"></script> <script src="{{ url_for('static', filename='js/dgenies.prototypes.js') }}" type="text/JavaScript"></script>
{% endblock %} {% endblock %}
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
<script src="{{ url_for('static', filename='js/dgenies.result.js') }}" type="text/JavaScript"></script> <script src="{{ url_for('static', filename='js/dgenies.result.js') }}" type="text/JavaScript"></script>
<script src="{{ url_for('static', filename='js/dgenies.result.controls.js') }}" type="text/JavaScript"></script> <script src="{{ url_for('static', filename='js/dgenies.result.controls.js') }}" type="text/JavaScript"></script>
<script src="{{ url_for('static', filename='js/dgenies.result.export.js') }}" type="text/JavaScript"></script> <script src="{{ url_for('static', filename='js/dgenies.result.export.js') }}" type="text/JavaScript"></script>
<script src="{{ url_for('static', filename='js/dgenies.result.summary.js') }}" type="text/JavaScript"></script>
<script src="{{ url_for('static', filename='js/d3.min.js') }}" type="text/JavaScript"></script> <script src="{{ url_for('static', filename='js/d3.min.js') }}" type="text/JavaScript"></script>
<script src="{{ url_for('static', filename='js/d3.boxplot.js') }}" type="text/JavaScript"></script> <script src="{{ url_for('static', filename='js/d3.boxplot.js') }}" type="text/JavaScript"></script>
<script src="{{ url_for('static', filename='js/d3.boxplot.zoom.js') }}" type="text/JavaScript"></script> <script src="{{ url_for('static', filename='js/d3.boxplot.zoom.js') }}" type="text/JavaScript"></script>
...@@ -83,5 +84,8 @@ ...@@ -83,5 +84,8 @@
</div> </div>
</div> </div>
<div id="export-pict" style="display: none;"></div> <div id="export-pict" style="display: none;"></div>
<div id="modal-stats" style="display: none;">
<div id="draw-stats" style="margin-top: 15px"></div>
</div>
</div> </div>
{% endblock %} {% endblock %}
\ No newline at end of file
...@@ -375,7 +375,26 @@ def no_assoc(id_res): ...@@ -375,7 +375,26 @@ def no_assoc(id_res):
@app.route('/summary/<id_res>', methods=['POST']) @app.route('/summary/<id_res>', methods=['POST'])
def summary(id_res): def summary(id_res):
pass paf_file = os.path.join(APP_DATA, id_res, "map.paf")
idx1 = os.path.join(APP_DATA, id_res, "query.idx")
idx2 = os.path.join(APP_DATA, id_res, "target.idx")
try:
paf = Paf(paf_file, idx1, idx2, False)
except FileNotFoundError:
return jsonify({
"success": False,
"message": "Unable to load data!"
})
percents = paf.get_summary_stats()
if percents is None:
return jsonify({
"success": False,
"message": "Build of summary failed. Please contact us to report the bug"
})
return jsonify({
"success": True,
"percents": percents
})
@app.route("/ask-upload", methods=['POST']) @app.route("/ask-upload", methods=['POST'])
......
Markdown is supported
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