From a2fbd64e02c876d0a31296a39c3b3b5450d804ed Mon Sep 17 00:00:00 2001 From: Olga Chernikova Date: Tue, 2 Oct 2018 12:55:30 +0300 Subject: [PATCH 01/19] delete connection betwwen small vertex --- UI/scripts/handleAlongChromosomes.js | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/UI/scripts/handleAlongChromosomes.js b/UI/scripts/handleAlongChromosomes.js index 4971ccd..2430fcc 100644 --- a/UI/scripts/handleAlongChromosomes.js +++ b/UI/scripts/handleAlongChromosomes.js @@ -117,7 +117,7 @@ function isBigContig(cb, ce, dz) { return (ce - cb > dz/10 && ce - cb > min_contig_len); } -function findNodeAroundChr(inode, area_size, min_contig_len, isGoodEdge, curNodeSet, openNode) { +function findNodeAroundChr(inode, area_size, min_contig_len, isGoodEdge, curNodeSet, openNode, cy) { var ypos = {}; var newvert = []; var sumw = {}; @@ -129,9 +129,11 @@ function findNodeAroundChr(inode, area_size, min_contig_len, isGoodEdge, curNode for (var i = 0; i < inode.length; ++i) { var v = inode[i]; - used_id.add(v.id); - rank[v.id] = 0; - que.push(v); + if (contigHasEdgesInThisScala(cy, v.id)) { + used_id.add(v.id); + rank[v.id] = 0; + que.push(v); + } } var bg = 0; @@ -147,7 +149,7 @@ function findNodeAroundChr(inode, area_size, min_contig_len, isGoodEdge, curNode if (isGoodEdge(curedge.id)) { var curu = curedge.to; - if (isBigContig(0, scaffoldgraph.nodes[curu].len, defZoom)) { + if (isBigContig(0, scaffoldgraph.nodes[curu].len, defZoom) && (!curNodeSet.has(curu) || contigHasEdgesInThisScala(cy, curu))) { if ((!used_id.has(curu)) && (curd < area_size || curNodeSet.has(curu) || openNode.has(curu))) { rank[curu] = curd + 1; used_id.add(curu); @@ -183,7 +185,7 @@ function findNodeAroundChr(inode, area_size, min_contig_len, isGoodEdge, curNode curedge = scaffoldgraph.gr[curv][i]; if (isGoodEdge(curedge.id)) { curu = curedge.from; - if (isBigContig(0, scaffoldgraph.nodes[curu].len, defZoom)) { + if (isBigContig(0, scaffoldgraph.nodes[curu].len, defZoom) && (!curNodeSet.has(curu) || contigHasEdgesInThisScala(cy, curu))) { if ((!used_id.has(curu)) && (curd < area_size || curNodeSet.has(curu) || openNode.has(curu))) { rank[curu] = curd + 1; used_id.add(curu); @@ -289,6 +291,10 @@ function getContigXPosD() { return 1000/defZoom; } +function contigHasEdgesInThisScala(cy, v) { + return cy.getElementById(v).data('len') >= 5; +} + function getRankDist() { return 50; } @@ -613,7 +619,8 @@ function calculateDinamicForDistPoint(cy, deepsPOS, toSmallCoord) { var tv = scaffoldgraph.edges[edges_to_draw[g]].to; if (special_nodes.has(fv) && special_nodes.has(tv)) { - deepsPOS[toSmallCoord[cy.getElementById(fv).data('order')]][toSmallCoord[cy.getElementById(tv).data('order')] - toSmallCoord[cy.getElementById(fv).data('order')]] = 1; + deepsPOS[toSmallCoord[cy.getElementById(fv).data('order')]] + [toSmallCoord[cy.getElementById(tv).data('order')] - toSmallCoord[cy.getElementById(fv).data('order')]] = 1; } } @@ -639,8 +646,6 @@ function addEdges(cy) { calculateDinamicForDistPoint(cy, deepsPOS, toSmallCoord); for (var g = 0; g < edges_to_draw.length; ++g) { - - if (!(isAlign(scaffoldgraph.edges[edges_to_draw[g]].from)) || !(isAlign(scaffoldgraph.edges[edges_to_draw[g]].to))) { cy.add({ @@ -696,7 +701,7 @@ function createGraph(chr, cy, curNodeSet, posx, posmin, posmax, oldPosition, ope findContigs(cy, chr, inode, posx, posmin, posmax, curNodeSet); addContigs(cy, inode, posx, posmin, posmax); - var vert_to_draw = findNodeAroundChr(inode, area_size, min_contig_len, isGoodEdge, curNodeSet, openNode); + var vert_to_draw = findNodeAroundChr(inode, area_size, min_contig_len, isGoodEdge, curNodeSet, openNode, cy); addOtherNodes(cy, curNodeSet, vert_to_draw, oldPosition); addEdges(cy); @@ -771,6 +776,7 @@ function drawAlongChromosome(chr) { var posmin = new Map(); var posmax = new Map(); var oldPosition = new Map(); + cy = cytoscape({ container: document.getElementById('mainpanel'), @@ -818,6 +824,7 @@ function drawAlongChromosome(chr) { createGraph(chr, cy, curNodeSet, posx, posmin, posmax, oldPosition, openNode); (document.getElementById("zoomInput")).innerText = Math.floor(cy.zoom() * 100 * 100/ defZoom).toString() + "%"; }); + cy.on('pan', function() { if (cy.extent().x1 >= lastMinX && cy.extent().x2 <= lastMaxX) { updateGraph(chr, cy); From 945b5a6327927d98bc30c931198564f3e352c580 Mon Sep 17 00:00:00 2001 From: Olga Chernikova Date: Tue, 2 Oct 2018 19:44:12 +0300 Subject: [PATCH 02/19] other way to find vertex rank --- CMakeLists.txt | 4 +- UI/mainPage.html | 5 +- UI/scripts/chromFindVertexRank.js | 195 +++++++++++++++++++++++++++ UI/scripts/handleAlongChromosomes.js | 114 +--------------- 4 files changed, 202 insertions(+), 116 deletions(-) create mode 100644 UI/scripts/chromFindVertexRank.js diff --git a/CMakeLists.txt b/CMakeLists.txt index ed27a19..0c20f01 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,7 +124,9 @@ install(PROGRAMS "${CMAKE_CURRENT_SOURCE_DIR}/UI/scripts/handleAmbiguous.js" install(PROGRAMS "${CMAKE_CURRENT_SOURCE_DIR}/UI/scripts/freeLayout.js" DESTINATION bin/scripts/ COMPONENT runtime) - +install(PROGRAMS "${CMAKE_CURRENT_SOURCE_DIR}/UI/scripts/chromFindVertexRank.js" + DESTINATION bin/scripts/ + COMPONENT runtime) install(PROGRAMS "${CMAKE_CURRENT_SOURCE_DIR}/UI/scripts/Icon.png" DESTINATION bin/scripts/ diff --git a/UI/mainPage.html b/UI/mainPage.html index 15e8bc8..4a94675 100644 --- a/UI/mainPage.html +++ b/UI/mainPage.html @@ -234,8 +234,9 @@

- - + + + diff --git a/UI/scripts/chromFindVertexRank.js b/UI/scripts/chromFindVertexRank.js new file mode 100644 index 0000000..1c15346 --- /dev/null +++ b/UI/scripts/chromFindVertexRank.js @@ -0,0 +1,195 @@ +function getLeftOrder(curu, area_size, isGoodEdge, curNodeSet, openNode, cy) { + var mnOrder = -1; + for (var i = 0; i < scaffoldgraph.g[curu].length; ++i) { + var curedge = scaffoldgraph.g[curu][i]; + if (isGoodEdge(curedge.id)) { + var u = curedge.to; + if (curNodeSet.has(u)) { + if (mnOrder === -1 || mnOrder > cy.getElementById(u).data('order')) { + mnOrder = cy.getElementById(u).data('order'); + } + } + } + } + + for (i = 0; i < scaffoldgraph.gr[curu].length; ++i) { + curedge = scaffoldgraph.gr[curu][i]; + if (isGoodEdge(curedge.id)) { + u = curedge.from; + if (curNodeSet.has(u)) { + if (mnOrder === -1 || mnOrder > cy.getElementById(curu).data('order')) { + mnOrder = cy.getElementById(curu).data('order'); + } + } + } + } + return mnOrder; +} + +function getRightOrder(curu, area_size, isGoodEdge, curNodeSet, openNode, cy) { + var mxOrder = -1; + for (var i = 0; i < scaffoldgraph.g[curu].length; ++i) { + var curedge = scaffoldgraph.g[curu][i]; + if (isGoodEdge(curedge.id)) { + var u = curedge.to; + if (curNodeSet.has(u)) { + if (mxOrder === -1 || mxOrder < cy.getElementById(u).data('order')) { + mxOrder = cy.getElementById(u).data('order'); + } + } + } + } + + for (i = 0; i < scaffoldgraph.gr[curu].length; ++i) { + curedge = scaffoldgraph.gr[curu][i]; + if (isGoodEdge(curedge.id)) { + u = curedge.from; + if (curNodeSet.has(u)) { + if (mxOrder === -1 || mxOrder < cy.getElementById(u).data('order')) { + mxOrder = cy.getElementById(u).data('order'); + } + } + } + } + return mxOrder; +} + +function handleVertexConnectedToAlignContig(curu, curv, curedge, curNodeSet, cy, used_id, isGoodEdge, + area_size, newvert, que, ypos, sumw, process, curd, openNode, rank, maxRank) { + if (!isBigContig(0, scaffoldgraph.nodes[curu].len, defZoom)) { + return -1; + } + var rightPos = getRightOrder(curu, area_size, isGoodEdge, curNodeSet, openNode, cy); + console.log("Order " + cy.getElementById(curv).data('order') + " " + rightPos); + if (cy.getElementById(curv).data('order') !== rightPos) { + return -1; + } + + var leftPos = getLeftOrder(curu, area_size, isGoodEdge, curNodeSet, openNode, cy); + var maxR = 0; + for (var i = leftPos; i < rightPos; ++i) { + if ((i in maxRank) && maxRank[i] > maxR) { + maxR = maxRank[i] + } + } + + maxRank[rightPos] = maxR + 1; + + return maxR; +} + +function handleEdge(curedge, curv, curNodeSet, cy, used_id, isGoodEdge, area_size, newvert, que, ypos, sumw, process, curd, openNode, rank, maxRank, v) { + var isForward = (curedge.to !== curv); + if (isGoodEdge(curedge.id)) { + var curu = curedge.to; + if (!isForward) { + curu = curedge.from; + } + + var curdd = curd; + if (!curNodeSet.has(curu) && curNodeSet.has(curv)) { + curdd = handleVertexConnectedToAlignContig(curu, curv, curedge, curNodeSet, cy, used_id, isGoodEdge, + area_size, newvert, que, ypos, sumw, process, curd, openNode, rank, maxRank); + console.log("curdd " + curdd); + if (curdd === -1) { + return; + } + } + + if (isBigContig(0, scaffoldgraph.nodes[curu].len, defZoom) && (!curNodeSet.has(curu) || contigHasEdgesInThisScala(cy, curu))) { + if ((!used_id.has(curu)) && (curd < area_size || curNodeSet.has(curu) || openNode.has(curu))) { + rank[curu] = curdd + 1; + used_id.add(curu); + newvert.push(curu); + que.push({id: curu}); + + ypos[curu] = 0; + sumw[curu] = 0; + } + + if (!process.has(curu)) { + var yc = 0; + if (curd === 0) { + yc = v.ce; + if (!isForward) { + yc = v.cb; + } + } else { + yc = calcY(curv, ypos[curv], sumw[curv]); + } + if (isForward) { + yc = yc + getYC_D(); + } else { + yc = yc - getYC_D(); + } + + ypos[curu] += curedge.weight * yc; + sumw[curu] += curedge.weight; + } + + console.log(rank[curu]); + if ((curd < area_size || curNodeSet.has(curu) || openNode.has(curu) || (curd === area_size && used_id.has(curu)))) { + edges_to_draw.push(curedge.id); + } + } + } +} + +function findNodeAroundChr(inode, area_size, min_contig_len, isGoodEdge, curNodeSet, openNode, cy) { + var maxRank = {}; + var ypos = {}; + var newvert = []; + var sumw = {}; + var rank = {}; + + var used_id = new Set(); + var que = []; + var process = new Set(); + + inode.sort(function (a, b) { + return a.order - b.order; + }); + + for (var i = 0; i < inode.length; ++i) { + var v = inode[i]; + + if (contigHasEdgesInThisScala(cy, v.id)) { + used_id.add(v.id); + rank[v.id] = 0; + que.push(v); + } + } + + var bg = 0; + while (bg < que.length) { + v = que[bg]; + bg += 1; + + var curd = rank[v.id]; + var curv = v.id; + process.add(curv); + for (i = 0; i < scaffoldgraph.g[curv].length; ++i) { + var curedge = scaffoldgraph.g[curv][i]; + handleEdge(curedge, curv, curNodeSet, cy, used_id, isGoodEdge, area_size, + newvert, que, ypos, sumw, process, curd, openNode, rank, maxRank, v); + } + + for (i = 0; i < scaffoldgraph.gr[curv].length; ++i) { + curedge = scaffoldgraph.gr[curv][i]; + handleEdge(curedge, curv, curNodeSet, cy, used_id, isGoodEdge, area_size, + newvert, que, ypos, sumw, process, curd, openNode, rank, maxRank, v); + } + + edges_to_draw = edges_to_draw.filter(function (value, index, self) { + return self.indexOf(value) === index; + }); + } + + var res = []; + + for (i = 0; i < newvert.length; ++i) { + res.push({id: newvert[i], rank: rank[newvert[i]], x: calcY(newvert[i], ypos[newvert[i]], sumw[newvert[i]])}); + } + + return res; +} \ No newline at end of file diff --git a/UI/scripts/handleAlongChromosomes.js b/UI/scripts/handleAlongChromosomes.js index 2430fcc..3bd31c4 100644 --- a/UI/scripts/handleAlongChromosomes.js +++ b/UI/scripts/handleAlongChromosomes.js @@ -117,119 +117,6 @@ function isBigContig(cb, ce, dz) { return (ce - cb > dz/10 && ce - cb > min_contig_len); } -function findNodeAroundChr(inode, area_size, min_contig_len, isGoodEdge, curNodeSet, openNode, cy) { - var ypos = {}; - var newvert = []; - var sumw = {}; - var rank = {}; - - var used_id = new Set(); - var que = []; - var process = new Set(); - for (var i = 0; i < inode.length; ++i) { - var v = inode[i]; - - if (contigHasEdgesInThisScala(cy, v.id)) { - used_id.add(v.id); - rank[v.id] = 0; - que.push(v); - } - } - - var bg = 0; - while (bg < que.length) { - v = que[bg]; - bg += 1; - - var curd = rank[v.id]; - var curv = v.id; - process.add(curv); - for (i = 0; i < scaffoldgraph.g[curv].length; ++i) { - var curedge = scaffoldgraph.g[curv][i]; - if (isGoodEdge(curedge.id)) { - var curu = curedge.to; - - if (isBigContig(0, scaffoldgraph.nodes[curu].len, defZoom) && (!curNodeSet.has(curu) || contigHasEdgesInThisScala(cy, curu))) { - if ((!used_id.has(curu)) && (curd < area_size || curNodeSet.has(curu) || openNode.has(curu))) { - rank[curu] = curd + 1; - used_id.add(curu); - newvert.push(curu); - que.push({id: curu}); - - ypos[curu] = 0; - sumw[curu] = 0; - } - - if (!process.has(curu)) { - var yc = 0; - if (curd === 0) { - yc = v.ce; - } else { - yc = calcY(curv, ypos[curv], sumw[curv]); - } - yc = yc + getYC_D(); - - ypos[curu] += curedge.weight * yc; - sumw[curu] += curedge.weight; - } - - if ((curd < area_size || curNodeSet.has(curu) || openNode.has(curu) || (curd === area_size && used_id.has(curu)))) { - edges_to_draw.push(curedge.id); - } - } - } - } - - - for (i = 0; i < scaffoldgraph.gr[curv].length; ++i) { - curedge = scaffoldgraph.gr[curv][i]; - if (isGoodEdge(curedge.id)) { - curu = curedge.from; - if (isBigContig(0, scaffoldgraph.nodes[curu].len, defZoom) && (!curNodeSet.has(curu) || contigHasEdgesInThisScala(cy, curu))) { - if ((!used_id.has(curu)) && (curd < area_size || curNodeSet.has(curu) || openNode.has(curu))) { - rank[curu] = curd + 1; - used_id.add(curu); - newvert.push(curu); - que.push({id: curu}); - - ypos[curu] = 0; - sumw[curu] = 0; - } - - if (!process.has(curu)) { - yc = 0; - if (curd === 0) { - yc = v.cb; - } else { - yc = calcY(curv, ypos[curv], sumw[curv]); - } - yc = yc - getYC_D(); - - ypos[curu] += curedge.weight * yc; - sumw[curu] += curedge.weight; - } - - if ((curd < area_size || curNodeSet.has(curu) || openNode.has(curu) || (curd == area_size && used_id.has(curu)))) { - edges_to_draw.push(curedge.id); - } - } - } - } - - edges_to_draw = edges_to_draw.filter(function (value, index, self) { - return self.indexOf(value) === index; - }); - } - - var res = []; - - for (i = 0; i < newvert.length; ++i) { - res.push({id: newvert[i], rank: rank[newvert[i]], x: calcY(newvert[i], ypos[newvert[i]], sumw[newvert[i]])}); - } - - return res; -} - function getWeight(e) { var curW = scaffoldgraph.edges[e].weight; @@ -692,6 +579,7 @@ function createGraph(chr, cy, curNodeSet, posx, posmin, posmax, oldPosition, ope cy.elements().remove(); special_nodes.clear(); curNodeSet.clear(); + oldPosition.clear(); var inode = []; From 1a3b5070b384f3b76564944b58179fac0c2d404b Mon Sep 17 00:00:00 2001 From: Olga Chernikova Date: Tue, 2 Oct 2018 20:15:14 +0300 Subject: [PATCH 03/19] other way to find vertex rank FIX --- UI/scripts/chromFindVertexRank.js | 43 +++++++++++++++++----------- UI/scripts/handleAlongChromosomes.js | 9 ------ 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/UI/scripts/chromFindVertexRank.js b/UI/scripts/chromFindVertexRank.js index 1c15346..2d7a8b3 100644 --- a/UI/scripts/chromFindVertexRank.js +++ b/UI/scripts/chromFindVertexRank.js @@ -1,3 +1,11 @@ +function calcY(curv, ypos, sumw) { + return ypos/sumw; +} + +function getYC_D() { + return 1000/defZoom; +} + function getLeftOrder(curu, area_size, isGoodEdge, curNodeSet, openNode, cy) { var mnOrder = -1; for (var i = 0; i < scaffoldgraph.g[curu].length; ++i) { @@ -17,8 +25,8 @@ function getLeftOrder(curu, area_size, isGoodEdge, curNodeSet, openNode, cy) { if (isGoodEdge(curedge.id)) { u = curedge.from; if (curNodeSet.has(u)) { - if (mnOrder === -1 || mnOrder > cy.getElementById(curu).data('order')) { - mnOrder = cy.getElementById(curu).data('order'); + if (mnOrder === -1 || mnOrder > cy.getElementById(u).data('order')) { + mnOrder = cy.getElementById(u).data('order'); } } } @@ -60,7 +68,6 @@ function handleVertexConnectedToAlignContig(curu, curv, curedge, curNodeSet, cy, return -1; } var rightPos = getRightOrder(curu, area_size, isGoodEdge, curNodeSet, openNode, cy); - console.log("Order " + cy.getElementById(curv).data('order') + " " + rightPos); if (cy.getElementById(curv).data('order') !== rightPos) { return -1; } @@ -90,19 +97,19 @@ function handleEdge(curedge, curv, curNodeSet, cy, used_id, isGoodEdge, area_siz if (!curNodeSet.has(curu) && curNodeSet.has(curv)) { curdd = handleVertexConnectedToAlignContig(curu, curv, curedge, curNodeSet, cy, used_id, isGoodEdge, area_size, newvert, que, ypos, sumw, process, curd, openNode, rank, maxRank); - console.log("curdd " + curdd); - if (curdd === -1) { - return; - } } if (isBigContig(0, scaffoldgraph.nodes[curu].len, defZoom) && (!curNodeSet.has(curu) || contigHasEdgesInThisScala(cy, curu))) { - if ((!used_id.has(curu)) && (curd < area_size || curNodeSet.has(curu) || openNode.has(curu))) { - rank[curu] = curdd + 1; - used_id.add(curu); - newvert.push(curu); - que.push({id: curu}); + if (curdd !== -1) { + if ((!used_id.has(curu)) && (curd < area_size || curNodeSet.has(curu) || openNode.has(curu))) { + rank[curu] = curdd + 1; + used_id.add(curu); + newvert.push(curu); + que.push({id: curu}); + } + } + if (!(curu in ypos)) { ypos[curu] = 0; sumw[curu] = 0; } @@ -123,13 +130,15 @@ function handleEdge(curedge, curv, curNodeSet, cy, used_id, isGoodEdge, area_siz yc = yc - getYC_D(); } - ypos[curu] += curedge.weight * yc; - sumw[curu] += curedge.weight; + ypos[curu] += /*curedge.weight*/ yc; + sumw[curu] += /*curedge.weight*/ 1; } - console.log(rank[curu]); - if ((curd < area_size || curNodeSet.has(curu) || openNode.has(curu) || (curd === area_size && used_id.has(curu)))) { - edges_to_draw.push(curedge.id); + if (curdd !== -1) { + //TODO: mistake calculate real dist, not rank; + if ((curd < area_size || curNodeSet.has(curu) || openNode.has(curu) || (curd === area_size && used_id.has(curu)))) { + edges_to_draw.push(curedge.id); + } } } } diff --git a/UI/scripts/handleAlongChromosomes.js b/UI/scripts/handleAlongChromosomes.js index 3bd31c4..5b227e8 100644 --- a/UI/scripts/handleAlongChromosomes.js +++ b/UI/scripts/handleAlongChromosomes.js @@ -104,15 +104,6 @@ function createCoordinates(chr, cy) { } } -function calcY(curv, ypos, sumw) { - return ypos/sumw; -} - -function getYC_D() { - return 1000/defZoom; -} - - function isBigContig(cb, ce, dz) { return (ce - cb > dz/10 && ce - cb > min_contig_len); } From 65da0460ba4aa1858fa3b23f31809606f8471e9d Mon Sep 17 00:00:00 2001 From: Olga Chernikova Date: Tue, 2 Oct 2018 22:51:12 +0300 Subject: [PATCH 04/19] don't update graph while zoom --- UI/scripts/chromFindVertexRank.js | 40 ++++++++++++ UI/scripts/handleAlongChromosomes.js | 93 ++++++++++++---------------- 2 files changed, 80 insertions(+), 53 deletions(-) diff --git a/UI/scripts/chromFindVertexRank.js b/UI/scripts/chromFindVertexRank.js index 2d7a8b3..98af886 100644 --- a/UI/scripts/chromFindVertexRank.js +++ b/UI/scripts/chromFindVertexRank.js @@ -6,6 +6,46 @@ function getYC_D() { return 1000/defZoom; } +function calcYforV(u, area_size, min_contig_len, isGoodEdge, newNode, curNodeSet, cy, rcoef) { + var ypos = 0; + var sumw = 0; + for (var h = 0; h < scaffoldgraph.g[u].length; ++h) { + if (isGoodEdge(scaffoldgraph.g[u][h].id)) { + if (scaffoldgraph.nodes[scaffoldgraph.g[u][h].to].len >= min_contig_len) { + if (curNodeSet.has(scaffoldgraph.g[u][h].to)) { + if (!newNode.has(scaffoldgraph.g[u][h].to)) { + var v = scaffoldgraph.g[u][h].to; + var curedge = scaffoldgraph.g[u][h]; + var yc = cy.$('#' + v).position().x - rcoef * Math.random(); + ypos += curedge.weight * yc; + sumw += curedge.weight; + } + } + } + } + } + + + for (h = 0; h < scaffoldgraph.gr[u].length; ++h) { + if (isGoodEdge(scaffoldgraph.gr[u][h].id)) { + if (scaffoldgraph.nodes[scaffoldgraph.gr[u][h].from].len >= min_contig_len) { + if (curNodeSet.has(scaffoldgraph.gr[u][h].from)) { + if (!newNode.has(scaffoldgraph.gr[u][h].from)) { + v = scaffoldgraph.gr[u][h].from; + curedge = scaffoldgraph.gr[u][h]; + yc = cy.$('#' + v).position().x + rcoef * Math.random(); + ypos += curedge.weight * yc; + sumw += curedge.weight; + } + } + } + } + } + + return calcY(u, ypos, sumw); +} + + function getLeftOrder(curu, area_size, isGoodEdge, curNodeSet, openNode, cy) { var mnOrder = -1; for (var i = 0; i < scaffoldgraph.g[curu].length; ++i) { diff --git a/UI/scripts/handleAlongChromosomes.js b/UI/scripts/handleAlongChromosomes.js index 5b227e8..056b43c 100644 --- a/UI/scripts/handleAlongChromosomes.js +++ b/UI/scripts/handleAlongChromosomes.js @@ -3,6 +3,10 @@ var maxZoom = 10000000; var IntervalTree = {}; var lastMinX = 0; var lastMaxX = 0; +var mulConst = 10; +var minZoomUpdate = 1; +var maxZoomUpdate = 10; +var widthMulConst = 1; function generateCoordinateLabel(x, delta) { if (defZoom*delta >= 1000000) { @@ -117,50 +121,14 @@ function getWeight(e) { return curW } -function calcYforV(u, area_size, min_contig_len, isGoodEdge, newNode, curNodeSet, cy, rcoef) { - var ypos = 0; - var sumw = 0; - for (var h = 0; h < scaffoldgraph.g[u].length; ++h) { - if (isGoodEdge(scaffoldgraph.g[u][h].id)) { - if (scaffoldgraph.nodes[scaffoldgraph.g[u][h].to].len >= min_contig_len) { - if (curNodeSet.has(scaffoldgraph.g[u][h].to)) { - if (!newNode.has(scaffoldgraph.g[u][h].to)) { - var v = scaffoldgraph.g[u][h].to; - var curedge = scaffoldgraph.g[u][h]; - var yc = cy.$('#' + v).position().x - rcoef * Math.random(); - ypos += curedge.weight * yc; - sumw += curedge.weight; - } - } - } - } - } - - - for (h = 0; h < scaffoldgraph.gr[u].length; ++h) { - if (isGoodEdge(scaffoldgraph.gr[u][h].id)) { - if (scaffoldgraph.nodes[scaffoldgraph.gr[u][h].from].len >= min_contig_len) { - if (curNodeSet.has(scaffoldgraph.gr[u][h].from)) { - if (!newNode.has(scaffoldgraph.gr[u][h].from)) { - v = scaffoldgraph.gr[u][h].from; - curedge = scaffoldgraph.gr[u][h]; - yc = cy.$('#' + v).position().x + rcoef * Math.random(); - ypos += curedge.weight * yc; - sumw += curedge.weight; - } - } - } - } - } - - return calcY(u, ypos, sumw); -} - - function getWidth(cy) { return 10/cy.zoom(); } +function getScala(cy) { + return 1.5/cy.zoom(); +} + function getDispersion() { return 10;//50; } @@ -182,11 +150,11 @@ function getEdgeWeight(cy, e) { if (scaffoldgraph.libs[edge.lib].type === "FASTG" || scaffoldgraph.libs[edge.lib].type === "GFA") { - return 5/cy.zoom(); + return widthMulConst*5/cy.zoom(); } if (scaffoldgraph.libs[edge.lib].type === "SCAFF") { - return 3/cy.zoom(); + return widthMulConst*3/cy.zoom(); } if (scaffoldgraph.libs[edge.lib].type === "DNA_PAIR" || @@ -195,14 +163,10 @@ function getEdgeWeight(cy, e) { scaffoldgraph.libs[edge.lib].type === "RNA_SPLIT_50" || scaffoldgraph.libs[edge.lib].type === "RNA_SPLIT_30" || scaffoldgraph.libs[edge.lib].type === "CONNECTION") { - return 1/cy.zoom(); + return widthMulConst*1/cy.zoom(); } - return Math.min(5, Math.log(getWeight(e)) + 1)/cy.zoom(); -} - -function getScala(cy) { - return 1.5/cy.zoom(); + return widthMulConst*Math.min(5, Math.log(getWeight(e)) + 1)/cy.zoom(); } function geOtherNodeWidth(id) { @@ -279,11 +243,11 @@ function createNewVerAlongChr(cy, area_size, min_contig_len, isGoodEdge, curNode function updateZooming(cy, posx, posmin, posmax, oldPosition) { var mul = 1; - while (cy.zoom()/mul > 10 && defZoom/mul > 1) { - mul = mul * 10; + while (cy.zoom()/mul > maxZoomUpdate && defZoom/mul > 1) { + mul = mul * mulConst; } - while (cy.zoom()/mul < 1 && defZoom/mul < maxZoom) { - mul = mul / 10; + while (cy.zoom()/mul < minZoomUpdate && defZoom/mul < maxZoom) { + mul = mul / mulConst; } cy.zoom(cy.zoom()/mul); @@ -591,6 +555,24 @@ function createGraph(chr, cy, curNodeSet, posx, posmin, posmax, oldPosition, ope function updateGraph(chr, cy) { createCoordinates(chr, cy); + var wght = getWidth(cy); + cy.nodes().filter(function (ele) { + return ele.data('rank') === 0; + }).data('width', wght); + + + cy.nodes().filter(function (ele) { + return ele.data('faveShape') === 'ellipse'; + }).forEach(function (node, i) { + console.log("node id " + node.id() + " " + geOtherNodeWidth(node.id())); + node.data('len', geOtherNodeWidth(node.id())); + node.data('width', geOtherNodeWidth(node.id())); + }); + + cy.edges().forEach(function (edge) { + edge.data('weight', getEdgeWeight(cy, parseInt(edge.id().substr(1)))); + edge.data('scala', getScala(cy)); + }); } @@ -700,7 +682,12 @@ function drawAlongChromosome(chr) { createNewVerAlongChr(cy, area_size, min_contig_len, isGoodEdge, curNodeSet, openNode); cy.on('zoom', function () { - createGraph(chr, cy, curNodeSet, posx, posmin, posmax, oldPosition, openNode); + if (cy.zoom() < maxZoomUpdate && cy.zoom() > minZoomUpdate && cy.extent().x1 >= lastMinX && cy.extent().x2 <= lastMaxX) { + updateGraph(chr, cy); + } else { + createGraph(chr, cy, curNodeSet, posx, posmin, posmax, oldPosition, openNode); + } + (document.getElementById("zoomInput")).innerText = Math.floor(cy.zoom() * 100 * 100/ defZoom).toString() + "%"; }); From a1033939d6f507c84adfa0cb4b84f6edb7c27c68 Mon Sep 17 00:00:00 2001 From: Olga Chernikova Date: Sun, 7 Oct 2018 20:05:57 +0300 Subject: [PATCH 05/19] change nucmer on minimap2 --- visualize_scaffold_graph.py | 163 ++++++++++++++++++++++++------------ 1 file changed, 109 insertions(+), 54 deletions(-) diff --git a/visualize_scaffold_graph.py b/visualize_scaffold_graph.py index 7f74cc5..5e1fb44 100755 --- a/visualize_scaffold_graph.py +++ b/visualize_scaffold_graph.py @@ -535,37 +535,98 @@ def sortcmp(x, y): return 0 return 1 +def save_lens_from_sam(scafflen_by_name, file_name): + with open(file_name) as f: + for line in f: + if (line[0] != '@'): + return + if (line[0:3] != '@SQ'): + continue + parts = line.split() + scafname = "" + curlen = 0 + for part in parts: + if (part[0:2] == 'LN'): + curlen = int(part[3:]) + if (part[0:2] == 'SN'): + scafname = part[3:] + scafflen_by_name[scafname] = curlen + return + +def parse_cigar(cigar): + letCnt = {'S': 0, 'H': 0, 'M': 0, '=': 0, 'X': 0, 'I': 0, 'D': 0, 'N': 0} + num = 0 + for i in range(len(cigar)): + if (cigar[i].isdigit()): + num = int(num)*10 + int(cigar[i]) + else: + letCnt[cigar[i]] += num + num = 0 + return letCnt + + +def get_align_from_sam_line(line): + tokens = line.split("\t") + if (len(tokens) < 10): + return -1, -1, -1, -1, "", "" + + if (tokens[len(tokens) - 1] == '\n'): + tokens.pop() + if (tokens[len(tokens) - 1][-1] == '\n'): + tokens[len(tokens) - 1] = tokens[len(tokens) - 1][0:-1] + + qcont = tokens[0] + rcont = tokens[2] + if (rcont == '*'): + return -1, -1, -1, -1, "", "" + + l = int(tokens[3]) + cigar = tokens[5] + + cntSH = 0 + while (cntSH < len(cigar) and (cigar[cntSH].isdigit() or cigar[cntSH] == 'S' or cigar[cntSH] == 'H') ): + cntSH += 1 + + letCnt = parse_cigar(cigar[:cntSH]) + lq = letCnt['S'] + letCnt['H'] + + letCnt = parse_cigar(cigar) + + rq = lq + letCnt['M'] + letCnt['='] + letCnt['X'] + letCnt['I'] + r = l + letCnt['M'] + letCnt['='] + letCnt['X'] + letCnt['D'] + letCnt['N'] + + if ((int(tokens[1]) & (1 << 4)) != 0): + rq, lq = lq, rq + + return lq, rq, l, r, qcont, rcont + def save_scaffolds_from_fasta(contig_file_name, lib, f): prevdir = os.getcwd() lib_dir = os.path.dirname(os.path.abspath(lib.name) + "/") os.chdir(lib_dir) - os.system("nucmer " + lib.path[0] + " " + contig_file_name) - os.system("show-coords out.delta -THrgl > out.coords") + os.system("minimap2 -ax asm5 " + lib.path[0] + " " + contig_file_name + " > out.sam") + #os.system("nucmer " + lib.path[0] + " " + contig_file_name) + #os.system("show-coords out.delta -THrgl > out.coords") global cntedge global cntlib global idbyname - with open("out.coords") as g: - f.write("scaffoldlibs.push(new ScaffoldEdgeLib(" + str(cntlib) + ", '" + str(lib.color) + "', '" + str(lib.label) + "', 'SCAFF'));\n") - contigsAlignment = dict() - rcontlist = [] + f.write("scaffoldlibs.push(new ScaffoldEdgeLib(" + str(cntlib) + ", '" + str(lib.color) + "', '" + str(lib.label) + "', 'SCAFF'));\n") + contigsAlignment = dict() + rcontlist = [] + + scafflen_by_name = dict() + save_lens_from_sam(scafflen_by_name, "out.sam") + + with open("out.sam") as g: for line in g: - tokens = line.split("\t") - print(tokens) - if (tokens[len(tokens) - 1] == '\n'): - tokens.pop() - if (tokens[len(tokens) - 1][-1] == '\n'): - tokens[len(tokens) - 1] = tokens[len(tokens) - 1][0:-1] - - lq = int(tokens[2]) - rq = int(tokens[3]) - l = int(tokens[0]) - r = int(tokens[1]) - qcont = tokens[10] - rcont = tokens[9] - chrlen = int(tokens[7]) + lq, rq, l, r, qcont, rcont = get_align_from_sam_line(line) + if (lq == -1): + continue + + chrlen = scafflen_by_name[rcont] if (lq > rq): qcont += "-rev" lq, rq = rq, lq @@ -582,25 +643,25 @@ def save_scaffolds_from_fasta(contig_file_name, lib, f): contigsAlignment[rcont + "-rev"].append((chrlen - r, chrlen - l, id^1)) - scafnum = 0 - for rc in rcontlist: - contigsAlignment[rc].sort(key=lambda x: (x[0], -x[1])) - f.write("scaffoldlibs["+ str(cntlib) +"].scaffolds.push(new Scaffold('" + rc + "'));\n") + scafnum = 0 + for rc in rcontlist: + contigsAlignment[rc].sort(key=lambda x: (x[0], -x[1])) + f.write("scaffoldlibs["+ str(cntlib) +"].scaffolds.push(new Scaffold('" + rc + "'));\n") - lst = 0 - for i in range(1, len(contigsAlignment[rc])): - if (contigsAlignment[rc][i][0] >= contigsAlignment[rc][lst][1] - 100): - f.write("scaffoldedges.push(new ScaffoldEdge(" + str(cntedge) + ", "+ str(contigsAlignment[rc][lst][2]) + - ", " + str(contigsAlignment[rc][i][2]) + ", " + str(cntlib) + ", 1));\n") - f.write("scaffoldedges["+str(cntedge)+"].name='"+ rc + "';\n") - f.write("scaffoldedges["+str(cntedge)+"].len=" + str(contigsAlignment[rc][i][0] - contigsAlignment[rc][lst][1]) + "\n") - f.write("scaffoldlibs["+ str(cntlib) +"].scaffolds["+str(scafnum) +"].edges.push(scaffoldedges["+str(cntedge)+"]);\n") - cntedge += 1 - lst = i + lst = 0 + for i in range(1, len(contigsAlignment[rc])): + if (contigsAlignment[rc][i][0] >= contigsAlignment[rc][lst][1] - 100): + f.write("scaffoldedges.push(new ScaffoldEdge(" + str(cntedge) + ", "+ str(contigsAlignment[rc][lst][2]) + + ", " + str(contigsAlignment[rc][i][2]) + ", " + str(cntlib) + ", 1));\n") + f.write("scaffoldedges["+str(cntedge)+"].name='"+ rc + "';\n") + f.write("scaffoldedges["+str(cntedge)+"].len=" + str(contigsAlignment[rc][i][0] - contigsAlignment[rc][lst][1]) + "\n") + f.write("scaffoldlibs["+ str(cntlib) +"].scaffolds["+str(scafnum) +"].edges.push(scaffoldedges["+str(cntedge)+"]);\n") + cntedge += 1 + lst = i - scafnum += 1 + scafnum += 1 - cntlib += 1 + cntlib += 1 os.chdir(prevdir) @@ -665,12 +726,10 @@ def save_scaffolds_from_path(lib, f): scafname = lines[il] if (scafname[-1] == '\n'): scafname = scafname[:-1] - print(scafname) if (scafname[-1] == "'"): continue tokens = lines[il + 1].split(",") - print(tokens) if (tokens[len(tokens) - 1] == '\n'): tokens.pop() @@ -767,7 +826,6 @@ def add_refcoord_to_res_file(contig_file_name, f): for fasta in fasta_seq: name, lenn = fasta.id, len(fasta.seq.tostring()) - print(name) chrid[name] = curid chrid[name + "-rev"] = curid + 1 chrlen.append(lenn) @@ -791,7 +849,6 @@ def add_refcoord_to_res_file(contig_file_name, f): continue info = line.split(" ") info[-1] = info[-1][:-1] - print(info) vid = idbyname[info[12]] curid = chrid[info[11].split('_')[0]] lq = int(info[3]) @@ -846,8 +903,9 @@ def add_ref_to_res_file(contig_file_name, f): prevdir = os.getcwd() lib_dir = os.path.dirname(os.path.abspath(lib.name) + "/") os.chdir(lib_dir) - os.system("nucmer -b 10000 " + lib.path[0] + " " + contig_file_name) - os.system("show-coords out.delta -THrgl > out.coords") + os.system("minimap2 -ax asm5 " + lib.path[0] + " " + contig_file_name + " > out.sam") + #os.system("nucmer -b 10000 " + lib.path[0] + " " + contig_file_name) + #os.system("show-coords out.delta -THrgl > out.coords") global idbyname global lenbyid @@ -858,13 +916,16 @@ def add_ref_to_res_file(contig_file_name, f): curid = -2 lastname = '-' - with open("out.coords") as cf: + chrm_len_by_name = dict() + save_lens_from_sam(chrm_len_by_name, "out.sam") + + with open("out.sam") as cf: for line in cf: - info = line.split("\t") - info[10] = info[10][:-1] - vid = idbyname[info[10]] - chrname = info[9] - lenf = int(info[7]) + lq, rq, l, r, qcont, chrname = get_align_from_sam_line(line) + if (lq == -1): + continue + vid = idbyname[qcont] + lenf = int(chrm_len_by_name[chrname]) if (chrname != lastname): curid += 2 chrlist.append("new Chromosome(" + str(curid) + ", '" + chrname + "', " + str(lenf) + ")") @@ -873,12 +934,6 @@ def add_ref_to_res_file(contig_file_name, f): chralig.append([]) lastname = chrname - lq = int(info[2]) - rq = int(info[3]) - l = int(info[0]) - r = int(info[1]) - - if ((max(rq, lq) - min(rq, lq)) * 100 < lenbyid[vid]): continue From cbda768ebfdc9aa24521db0ca39a51b9fbcb19ab Mon Sep 17 00:00:00 2001 From: Olga Chernikova Date: Tue, 9 Oct 2018 17:38:25 +0300 Subject: [PATCH 06/19] constant for zooming in along chromosome mode --- UI/scripts/handleAlongChromosomes.js | 94 +++++++++++++++------------- 1 file changed, 52 insertions(+), 42 deletions(-) diff --git a/UI/scripts/handleAlongChromosomes.js b/UI/scripts/handleAlongChromosomes.js index 056b43c..82a559c 100644 --- a/UI/scripts/handleAlongChromosomes.js +++ b/UI/scripts/handleAlongChromosomes.js @@ -4,9 +4,9 @@ var IntervalTree = {}; var lastMinX = 0; var lastMaxX = 0; var mulConst = 10; -var minZoomUpdate = 1; -var maxZoomUpdate = 10; -var widthMulConst = 1; +var minZoomUpdate = 0.1; +var maxZoomUpdate = 1; +var widthAddConst = 1; function generateCoordinateLabel(x, delta) { if (defZoom*delta >= 1000000) { @@ -38,7 +38,8 @@ function createCoordinates(chr, cy) { len: 2 / cy.zoom(), color: '#ff0000', width: 20 / cy.zoom(), - faveShape: 'rectangle' + faveShape: 'rectangle', + notALL: 0 }, position: { y: 0, @@ -62,7 +63,8 @@ function createCoordinates(chr, cy) { len: 2 / cy.zoom(), color: '#ff0000', width: 20 / cy.zoom(), - faveShape: 'rectangle' + faveShape: 'rectangle', + notALL: 0 }, position: { y: 0, @@ -89,7 +91,8 @@ function createCoordinates(chr, cy) { len: 2 / cy.zoom(), color: '#2A4986', width: 20 / cy.zoom(), - faveShape: 'rectangle' + faveShape: 'rectangle', + notALL: 0 }, position: { y: 30, @@ -108,10 +111,6 @@ function createCoordinates(chr, cy) { } } -function isBigContig(cb, ce, dz) { - return (ce - cb > dz/10 && ce - cb > min_contig_len); -} - function getWeight(e) { var curW = scaffoldgraph.edges[e].weight; @@ -126,7 +125,7 @@ function getWidth(cy) { } function getScala(cy) { - return 1.5/cy.zoom(); + return 2; } function getDispersion() { @@ -137,12 +136,24 @@ function getContigXPosD() { return 1000/defZoom; } +function getRankDist() { + return 500; +} + +function getNotAllValue() { + return 5/cy.zoom() + 'px'; +} + function contigHasEdgesInThisScala(cy, v) { - return cy.getElementById(v).data('len') >= 5; + return cy.getElementById(v).data('len') >= 50; } -function getRankDist() { - return 50; +function isBigContig(cb, ce, dz) { + return (/*ce - cb > dz*5 &&*/ ce - cb > min_contig_len); +} + +function geOtherNodeWidth(id) { + return (Math.log(scaffoldgraph.nodes[id].len)*4)/cy.zoom(); } function getEdgeWeight(cy, e) { @@ -150,11 +161,11 @@ function getEdgeWeight(cy, e) { if (scaffoldgraph.libs[edge.lib].type === "FASTG" || scaffoldgraph.libs[edge.lib].type === "GFA") { - return widthMulConst*5/cy.zoom(); + return (widthAddConst + 5)/cy.zoom(); } if (scaffoldgraph.libs[edge.lib].type === "SCAFF") { - return widthMulConst*3/cy.zoom(); + return (widthAddConst + 3)/cy.zoom(); } if (scaffoldgraph.libs[edge.lib].type === "DNA_PAIR" || @@ -163,16 +174,31 @@ function getEdgeWeight(cy, e) { scaffoldgraph.libs[edge.lib].type === "RNA_SPLIT_50" || scaffoldgraph.libs[edge.lib].type === "RNA_SPLIT_30" || scaffoldgraph.libs[edge.lib].type === "CONNECTION") { - return widthMulConst*1/cy.zoom(); + return (widthAddConst + 1)/cy.zoom(); } - return widthMulConst*Math.min(5, Math.log(getWeight(e)) + 1)/cy.zoom(); + return (widthAddConst + Math.min(5, Math.log(getWeight(e)) + 1))/cy.zoom(); } -function geOtherNodeWidth(id) { - return Math.log(scaffoldgraph.nodes[id].len)*2/cy.zoom(); +function getPointDistances(cy, e, deepsPOS, toSmallCoord) { + var bg = scaffoldgraph.edges[e].from; + var ed = scaffoldgraph.edges[e].to; + + var order1 = cy.getElementById(bg).data('order'); + var order2 = cy.getElementById(ed).data('order'); + + var oneStepDistant = 75; + var randFree = 100; + return -5*(deepsPOS[toSmallCoord[Math.min(order1, order2)]][toSmallCoord[Math.max(order1, order2)] - + toSmallCoord[Math.min(order1, order2)]] * oneStepDistant + randFree*Math.random()); + + + /*deepsPOS[toSmallCoord[Math.min(order1, order2)]][toSmallCoord[Math.max(order1, order2)] - + toSmallCoord[Math.min(order1, order2)]]*/ + //return Math.min(5, (Math.max(order1, order2) - Math.min(order1, order2))) * oneStepDistant/cy.zoom() + randFree*Math.random()/cy.zoom(); } + function createNewVerAlongChr(cy, area_size, min_contig_len, isGoodEdge, curNodeSet, openNode) { cy.on('tap', 'node', function (evt) { var newNode = new Set(); @@ -232,7 +258,7 @@ function createNewVerAlongChr(cy, area_size, min_contig_len, isGoodEdge, curNode for (g = 0; g < nodes_to_draw.length; ++g) { if (hasOtherEdges(nodes_to_draw[g], curNodeSet)) { - cy.$('#' + nodes_to_draw[g]).data('notALL', 1); + cy.$('#' + nodes_to_draw[g]).data('notALL', getNotAllValue()); } else { cy.$('#' + nodes_to_draw[g]).data('notALL', 0); } @@ -338,7 +364,8 @@ function addContigs(cy, inode, posx, posmin, posmax) { ymin: inode[i].cb, ymax: inode[i].ce, faveShape: 'rectangle', - order: inode[i].order + order: inode[i].order, + notALL: 0 }, position: { y: posx.get(vid), @@ -363,7 +390,7 @@ function addOtherNodes(cy, curNodeSet, vert_to_draw, oldPosition) { nodes_to_draw.push(vert_to_draw[g].id); var nall = 0; if (hasOtherEdges(vert_to_draw[g].id, curNodeSet)) { - nall = 1; + nall = getNotAllValue(); } if (!(oldPosition.has(vert_to_draw[g].id.toString()))) { @@ -398,23 +425,6 @@ function addOtherNodes(cy, curNodeSet, vert_to_draw, oldPosition) { } } - -function getPointDistances(cy, e, deepsPOS, toSmallCoord) { - var bg = scaffoldgraph.edges[e].from; - var ed = scaffoldgraph.edges[e].to; - - var order1 = cy.getElementById(bg).data('order'); - var order2 = cy.getElementById(ed).data('order'); - - var oneStepDistant = 75; - var randFree = 100; - return -(deepsPOS[toSmallCoord[Math.min(order1, order2)]][toSmallCoord[Math.max(order1, order2)] - - toSmallCoord[Math.min(order1, order2)]] * oneStepDistant/cy.zoom() + randFree*Math.random()/cy.zoom()); - /*deepsPOS[toSmallCoord[Math.min(order1, order2)]][toSmallCoord[Math.max(order1, order2)] - - toSmallCoord[Math.min(order1, order2)]]*/ - //return Math.min(5, (Math.max(order1, order2) - Math.min(order1, order2))) * oneStepDistant/cy.zoom() + randFree*Math.random()/cy.zoom(); -} - function calculateDinamicForDistPoint(cy, deepsPOS, toSmallCoord) { var idslist = []; @@ -564,9 +574,9 @@ function updateGraph(chr, cy) { cy.nodes().filter(function (ele) { return ele.data('faveShape') === 'ellipse'; }).forEach(function (node, i) { - console.log("node id " + node.id() + " " + geOtherNodeWidth(node.id())); node.data('len', geOtherNodeWidth(node.id())); node.data('width', geOtherNodeWidth(node.id())); + node.data('notALL', getNotAllValue()); }); cy.edges().forEach(function (edge) { @@ -659,7 +669,7 @@ function drawAlongChromosome(chr) { 'width': 'data(len)', 'height': 'data(width)', 'background-color': 'data(color)', - 'border-width': 'mapData(notALL, 0, 1, 0px, 1px)' + 'border-width': 'data(notALL)' }) .selector('edge') .css({ From d66ab773568df41e6c4d000d879962453c9735b6 Mon Sep 17 00:00:00 2001 From: Olga Chernikova Date: Tue, 9 Oct 2018 19:25:39 +0300 Subject: [PATCH 07/19] add popup --- UI/mainPage.html | 300 ++++++++++++++------------- UI/scripts/handleAlongChromosomes.js | 12 +- UI/scripts/light.css | 33 ++- 3 files changed, 196 insertions(+), 149 deletions(-) diff --git a/UI/mainPage.html b/UI/mainPage.html index 4a94675..c74d689 100644 --- a/UI/mainPage.html +++ b/UI/mainPage.html @@ -11,82 +11,82 @@ -
- icon - SGTK - +
+ icon + SGTK + -
- -
+
+ +
-
-
+
+
100%
-
-
- -
+
+
+
+
- + -
-
-
-
-
+
+
+
+
+
-
-
-

- Layout: -

-
- -
+
+
+

+ Layout: +

+
+
+
-
-
+
+

- Filtration: + Filtration:

- -
+
+
-
-
+
+
-
-
+
+

Edge types:

@@ -98,11 +98,11 @@

Min Edge Weight -

+
-
-
+
+

Vertices:

@@ -146,120 +146,128 @@

Min contig len:

-

+
-
-

- Edges: -

+
+

+ Edges: +

-
-
-
+ +
-
+
-
-
-
- - of 0 -
-
-
+
+ +
+

Update the graph?

+ +
+
+ +
+
+
+ + of 0
+
+
+
- - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + - - - - + + + + - + \ No newline at end of file diff --git a/UI/scripts/handleAlongChromosomes.js b/UI/scripts/handleAlongChromosomes.js index 82a559c..e99bec7 100644 --- a/UI/scripts/handleAlongChromosomes.js +++ b/UI/scripts/handleAlongChromosomes.js @@ -695,7 +695,9 @@ function drawAlongChromosome(chr) { if (cy.zoom() < maxZoomUpdate && cy.zoom() > minZoomUpdate && cy.extent().x1 >= lastMinX && cy.extent().x2 <= lastMaxX) { updateGraph(chr, cy); } else { - createGraph(chr, cy, curNodeSet, posx, posmin, posmax, oldPosition, openNode); + document.getElementById("UpdateGraph").style.visibility = "visible"; + document.getElementById("updateGrpahButton").focus(); + updateGraph(chr, cy); } (document.getElementById("zoomInput")).innerText = Math.floor(cy.zoom() * 100 * 100/ defZoom).toString() + "%"; @@ -705,10 +707,16 @@ function drawAlongChromosome(chr) { if (cy.extent().x1 >= lastMinX && cy.extent().x2 <= lastMaxX) { updateGraph(chr, cy); } else { - createGraph(chr, cy, curNodeSet, posx, posmin, posmax, oldPosition, openNode); + document.getElementById("UpdateGraph").style.visibility = "visible"; + document.getElementById("updateGrpahButton").focus(); + updateGraph(chr, cy); } }); + document.getElementById("updateGrpahButton").onclick = function(){ + createGraph(chr, cy, curNodeSet, posx, posmin, posmax, oldPosition, openNode); + document.getElementById("UpdateGraph").style.visibility = "hidden"; + }; cy.ready(function () { window.cy = this; diff --git a/UI/scripts/light.css b/UI/scripts/light.css index 97bac6d..19a05e9 100644 --- a/UI/scripts/light.css +++ b/UI/scripts/light.css @@ -525,4 +525,35 @@ table tr th { .dropdown-content p:hover {background-color: #ddd} /* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */ -.show {display:block;} \ No newline at end of file +.show {display:block;} + +.AlertBox { + visibility: hidden; + position: fixed; + border-style: solid; + border-width: 2px; + background-color: #ddd; + + top: 0; + left: 50%; + transform: translate(-50%, 0); + text-align: center; + + width: 300px; + height: 80px; +} + +.updateGrpahButton { + position: absolute; + bottom: 10px; + width: 100px; + right: 10px; +} + +.dontUpdateGrpahButton { + position: absolute; + bottom: 10px; + width: 100px; + right: 120px; +} + From 0d5d28b9f9826fdc49f82ab3631e0d1128314b7c Mon Sep 17 00:00:00 2001 From: Olga Chernikova Date: Tue, 9 Oct 2018 21:33:50 +0300 Subject: [PATCH 08/19] alt plus zoom --- UI/scripts/handleAlongChromosomes.js | 4 +++- UI/scripts/zoomChoose.js | 16 ++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/UI/scripts/handleAlongChromosomes.js b/UI/scripts/handleAlongChromosomes.js index e99bec7..384006b 100644 --- a/UI/scripts/handleAlongChromosomes.js +++ b/UI/scripts/handleAlongChromosomes.js @@ -1,4 +1,4 @@ -var defZoom = 100; +var defZoom = 10; var maxZoom = 10000000; var IntervalTree = {}; var lastMinX = 0; @@ -275,6 +275,7 @@ function updateZooming(cy, posx, posmin, posmax, oldPosition) { while (cy.zoom()/mul < minZoomUpdate && defZoom/mul < maxZoom) { mul = mul / mulConst; } + cy.zoom(cy.zoom()/mul); cy.nodes().forEach(function (ele) { @@ -716,6 +717,7 @@ function drawAlongChromosome(chr) { document.getElementById("updateGrpahButton").onclick = function(){ createGraph(chr, cy, curNodeSet, posx, posmin, posmax, oldPosition, openNode); document.getElementById("UpdateGraph").style.visibility = "hidden"; + (document.getElementById("zoomInput")).innerText = Math.floor(cy.zoom() * 100 * 100/ defZoom).toString() + "%"; }; cy.ready(function () { diff --git a/UI/scripts/zoomChoose.js b/UI/scripts/zoomChoose.js index 01c8313..8cff1eb 100644 --- a/UI/scripts/zoomChoose.js +++ b/UI/scripts/zoomChoose.js @@ -6,9 +6,11 @@ function zoomPlus() { if (cy !== null) { var width = document.getElementById('mainpanel').clientWidth; var height = document.getElementById('mainpanel').clientHeight; - cy.panBy({x: -(width - width/1.5)/2, y: -(height - height/1.5)/2}); - cy.pan({x: cy.pan().x * 1.5, y: cy.pan().y * 1.5}); - cy.zoom(cy.zoom() * 1.5); + var changeIn = Math.min(cy.zoom()*1.5, cy.maxZoom())/cy.zoom(); + + cy.panBy({x: -(width - width/changeIn)/2, y: -(height - height/changeIn)/2}); + cy.pan({x: cy.pan().x * changeIn, y: cy.pan().y * changeIn}); + cy.zoom(cy.zoom() * changeIn); if ((document.getElementById("select_layout").value !== "free_layout")) { cy.pan({x:cy.pan().x, y: height/3}); } @@ -19,9 +21,11 @@ function zoomMinus() { if (cy !== null) { var width = document.getElementById('mainpanel').clientWidth; var height = document.getElementById('mainpanel').clientHeight; - cy.panBy({x: -(width - width*1.5)/2, y: -(height - height*1.5)/2}); - cy.pan({x: cy.pan().x / 1.5, y: cy.pan().y / 1.5}); - cy.zoom(cy.zoom() / 1.5); + var changeIn = Math.max(cy.zoom()/1.5, cy.minZoom())/cy.zoom(); + + cy.panBy({x: -(width - width/changeIn)/2, y: -(height - height/changeIn)/2}); + cy.pan({x: cy.pan().x * changeIn, y: cy.pan().y * changeIn}); + cy.zoom(cy.zoom() * changeIn); if ((document.getElementById("select_layout").value !== "free_layout")) { cy.pan({x: cy.pan().x, y: height/3}); } From dbf2132e0ef78463d5ef6d23da393df7df3fb36b Mon Sep 17 00:00:00 2001 From: Olga Chernikova Date: Tue, 9 Oct 2018 21:57:35 +0300 Subject: [PATCH 09/19] zooming for change number --- UI/scripts/handleAlongChromosomes.js | 2 ++ UI/scripts/zoomChoose.js | 23 +++++++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/UI/scripts/handleAlongChromosomes.js b/UI/scripts/handleAlongChromosomes.js index 384006b..a943932 100644 --- a/UI/scripts/handleAlongChromosomes.js +++ b/UI/scripts/handleAlongChromosomes.js @@ -725,6 +725,8 @@ function drawAlongChromosome(chr) { }); setTimeout(function() { createGraph(chr, cy, curNodeSet, posx, posmin, posmax, oldPosition, openNode); + var height = document.getElementById('mainpanel').clientHeight; + cy.pan({x: cy.pan().x, y: height/3}); }, 1); } diff --git a/UI/scripts/zoomChoose.js b/UI/scripts/zoomChoose.js index 8cff1eb..d73e005 100644 --- a/UI/scripts/zoomChoose.js +++ b/UI/scripts/zoomChoose.js @@ -107,10 +107,29 @@ function updateZoomFromInput() { var inputVal = parseInt(document.getElementById("zoomInput").innerText); if (cy !== null) { - if (inputVal > 0 && inputVal < 10000) { - cy.zoom((inputVal*defZoom/(100 * 100))); + var width = document.getElementById('mainpanel').clientWidth; + var height = document.getElementById('mainpanel').clientHeight; + if (inputVal > 10000) { + inputVal = 9999; + } + if (inputVal < 0) { + inputVal = 1; + } + + var changeIn = (inputVal*defZoom/(100 * 100))/cy.zoom(); + + cy.panBy({x: -(width - width/changeIn)/2, y: -(height - height/changeIn)/2}); + cy.pan({x: cy.pan().x * changeIn, y: cy.pan().y * changeIn}); + cy.zoom(cy.zoom() * changeIn); + if ((document.getElementById("select_layout").value !== "free_layout")) { + cy.pan({x: cy.pan().x, y: height/3}); } + (document.getElementById("zoomInput")).innerText = (cy.zoom() * 100 * 100/defZoom).toString() + "%"; + + if ((document.getElementById("select_layout").value !== "free_layout")) { + cy.pan({x: cy.pan().x, y: height/3}); + } } else { (document.getElementById("zoomInput")).innerText = "100%"; } From 916af5d417c1100d2366f951340fd4465f9f32eb Mon Sep 17 00:00:00 2001 From: Olga Chernikova Date: Thu, 11 Oct 2018 13:26:08 +0300 Subject: [PATCH 10/19] draw graph, when open --- UI/mainPage.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UI/mainPage.html b/UI/mainPage.html index c74d689..978e954 100644 --- a/UI/mainPage.html +++ b/UI/mainPage.html @@ -249,6 +249,7 @@

+ @@ -266,7 +267,6 @@

- From 3d0b54e6bdf53b70c6f5e22cd2c830d6ead224d2 Mon Sep 17 00:00:00 2001 From: Olga Chernikova Date: Thu, 11 Oct 2018 13:52:22 +0300 Subject: [PATCH 11/19] correct calculate rank --- UI/scripts/chromFindVertexRank.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/UI/scripts/chromFindVertexRank.js b/UI/scripts/chromFindVertexRank.js index 98af886..fa1da6a 100644 --- a/UI/scripts/chromFindVertexRank.js +++ b/UI/scripts/chromFindVertexRank.js @@ -125,7 +125,7 @@ function handleVertexConnectedToAlignContig(curu, curv, curedge, curNodeSet, cy, return maxR; } -function handleEdge(curedge, curv, curNodeSet, cy, used_id, isGoodEdge, area_size, newvert, que, ypos, sumw, process, curd, openNode, rank, maxRank, v) { +function handleEdge(curedge, curv, curNodeSet, cy, used_id, isGoodEdge, area_size, newvert, que, ypos, sumw, process, curd, openNode, rank, maxRank, v, distFromChrm) { var isForward = (curedge.to !== curv); if (isGoodEdge(curedge.id)) { var curu = curedge.to; @@ -141,8 +141,9 @@ function handleEdge(curedge, curv, curNodeSet, cy, used_id, isGoodEdge, area_siz if (isBigContig(0, scaffoldgraph.nodes[curu].len, defZoom) && (!curNodeSet.has(curu) || contigHasEdgesInThisScala(cy, curu))) { if (curdd !== -1) { - if ((!used_id.has(curu)) && (curd < area_size || curNodeSet.has(curu) || openNode.has(curu))) { + if ((!used_id.has(curu)) && (distFromChrm[curv] < area_size || curNodeSet.has(curu) || openNode.has(curu))) { rank[curu] = curdd + 1; + distFromChrm[curu] = distFromChrm[curv] + 1; used_id.add(curu); newvert.push(curu); que.push({id: curu}); @@ -176,7 +177,7 @@ function handleEdge(curedge, curv, curNodeSet, cy, used_id, isGoodEdge, area_siz if (curdd !== -1) { //TODO: mistake calculate real dist, not rank; - if ((curd < area_size || curNodeSet.has(curu) || openNode.has(curu) || (curd === area_size && used_id.has(curu)))) { + if ((distFromChrm[curv] < area_size || curNodeSet.has(curu) || openNode.has(curu) || (distFromChrm[curv] === area_size && used_id.has(curu)))) { edges_to_draw.push(curedge.id); } } @@ -190,6 +191,7 @@ function findNodeAroundChr(inode, area_size, min_contig_len, isGoodEdge, curNode var newvert = []; var sumw = {}; var rank = {}; + var distFromChrm = {}; var used_id = new Set(); var que = []; @@ -205,6 +207,7 @@ function findNodeAroundChr(inode, area_size, min_contig_len, isGoodEdge, curNode if (contigHasEdgesInThisScala(cy, v.id)) { used_id.add(v.id); rank[v.id] = 0; + distFromChrm[v.id] = 0; que.push(v); } } @@ -220,13 +223,13 @@ function findNodeAroundChr(inode, area_size, min_contig_len, isGoodEdge, curNode for (i = 0; i < scaffoldgraph.g[curv].length; ++i) { var curedge = scaffoldgraph.g[curv][i]; handleEdge(curedge, curv, curNodeSet, cy, used_id, isGoodEdge, area_size, - newvert, que, ypos, sumw, process, curd, openNode, rank, maxRank, v); + newvert, que, ypos, sumw, process, curd, openNode, rank, maxRank, v, distFromChrm); } for (i = 0; i < scaffoldgraph.gr[curv].length; ++i) { curedge = scaffoldgraph.gr[curv][i]; handleEdge(curedge, curv, curNodeSet, cy, used_id, isGoodEdge, area_size, - newvert, que, ypos, sumw, process, curd, openNode, rank, maxRank, v); + newvert, que, ypos, sumw, process, curd, openNode, rank, maxRank, v, distFromChrm); } edges_to_draw = edges_to_draw.filter(function (value, index, self) { From 0ed8e8c25916bc56ddc635e74549a67c3c8ff0cf Mon Sep 17 00:00:00 2001 From: Olga Chernikova Date: Thu, 11 Oct 2018 14:55:39 +0300 Subject: [PATCH 12/19] redrawing open vertex --- UI/scripts/handleAlongChromosomes.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/UI/scripts/handleAlongChromosomes.js b/UI/scripts/handleAlongChromosomes.js index a943932..74d4afa 100644 --- a/UI/scripts/handleAlongChromosomes.js +++ b/UI/scripts/handleAlongChromosomes.js @@ -577,7 +577,10 @@ function updateGraph(chr, cy) { }).forEach(function (node, i) { node.data('len', geOtherNodeWidth(node.id())); node.data('width', geOtherNodeWidth(node.id())); - node.data('notALL', getNotAllValue()); + console.log(node.data('notALL')); + if (node.data('notALL') != 0) { + node.data('notALL', getNotAllValue()); + } }); cy.edges().forEach(function (edge) { From 195fc108a1ab3dd3003c0bc3fb2afca46bbd0ade Mon Sep 17 00:00:00 2001 From: Olga Chernikova Date: Thu, 11 Oct 2018 17:17:37 +0300 Subject: [PATCH 13/19] highlight found vertex --- UI/scripts/freeLayout.js | 4 +++ UI/scripts/handleAlongChromosomes.js | 4 +++ UI/scripts/search.js | 37 +++++++++++++++++++++++++--- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/UI/scripts/freeLayout.js b/UI/scripts/freeLayout.js index 8aca235..e511e99 100644 --- a/UI/scripts/freeLayout.js +++ b/UI/scripts/freeLayout.js @@ -214,6 +214,10 @@ function DrawGraphCytoscapeWithPresetNode(dnodes, dedges, curNodeSet) { //'target-endpoint': '-25% 0px', 'target-distance-from-node': '1px' }) + .selector('.found') + .css({ + 'opacity': 0.3 + }) }); var element = document.getElementById("cynav"); diff --git a/UI/scripts/handleAlongChromosomes.js b/UI/scripts/handleAlongChromosomes.js index 74d4afa..50f8ce7 100644 --- a/UI/scripts/handleAlongChromosomes.js +++ b/UI/scripts/handleAlongChromosomes.js @@ -687,6 +687,10 @@ function drawAlongChromosome(chr) { 'width': 'data(weight)', 'content': 'data(label)' }) + .selector('.found') + .css({ + 'opacity': 0.3 + }) }); var element = document.getElementById("cynav"); diff --git a/UI/scripts/search.js b/UI/scripts/search.js index 0d314d8..7786851 100644 --- a/UI/scripts/search.js +++ b/UI/scripts/search.js @@ -95,13 +95,34 @@ function search() { var scr = 0; var nodes = []; + var highlightFoundNode = function() { + if (cntChanges % 2 === 0) { + cy.getElementById(idd).addClass('found'); + } else { + cy.getElementById(idd).removeClass('found'); + } + ++cntChanges; + if (cntChanges < 6) { + setTimeout(highlightFoundNode, 300); + } + }; + if (opt === "genome_browser") { getNodesId(IntervalTree[1], nodes); var res = parseNode(nodes, scr, vid, request); vid = res[1]; cy.zoom((1000/(vid.ce - vid.cb))*defZoom); - cy.pan({y: 0, x: -cy.zoom()*vid.cb/defZoom}); + + var width = document.getElementById('mainpanel').clientWidth; + var height = document.getElementById('mainpanel').clientHeight; + + cy.pan({y: height/3, x: width/2 -cy.zoom()*(vid.cb + vid.ce)/(2*defZoom)}); + + var cntChanges = 0; + var idd = vid.id; + + highlightFoundNode(); } else { nodes = cy.filter('node'); for (var i = 0; i < nodes.length; ++i) { @@ -141,12 +162,22 @@ function search() { if (scr > 0 && scr >= scre) { - cy.fit(cy.$('#' + vid)) + cy.fit(cy.$('#' + vid)); + + cntChanges = 0; + idd = vid; + + highlightFoundNode(); } if (scre > 0 && scre > scr) { - cy.fit(cy.$('#' + eid)) + cy.fit(cy.$('#' + eid)); + + cntChanges = 0; + idd = eid; + + highlightFoundNode(); } } } From 5c869e8aa2b4d9aad5f5b8cdabb8a3c7258ce245 Mon Sep 17 00:00:00 2001 From: Olga Chernikova Date: Thu, 11 Oct 2018 18:59:09 +0300 Subject: [PATCH 14/19] move only by y in along chrom mode --- UI/scripts/handleAlongChromosomes.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/UI/scripts/handleAlongChromosomes.js b/UI/scripts/handleAlongChromosomes.js index 50f8ce7..6314ab0 100644 --- a/UI/scripts/handleAlongChromosomes.js +++ b/UI/scripts/handleAlongChromosomes.js @@ -199,6 +199,19 @@ function getPointDistances(cy, e, deepsPOS, toSmallCoord) { } +function nodePositionChange(cy, posmin, posmax) { + cy.on('position', 'node', function (evt) { + var v = evt.target.id(); + if (cy.getElementById(v).data('rank') == 0) { + if (posmin.has(parseInt(v))) { + if (cy.getElementById(v).position('x') != ((posmin.get(parseInt(v)) + posmax.get(parseInt(v))) / 2)) { + cy.getElementById(v).position('x', (posmin.get(parseInt(v)) + posmax.get(parseInt(v))) / 2); + } + } + } + }); +} + function createNewVerAlongChr(cy, area_size, min_contig_len, isGoodEdge, curNodeSet, openNode) { cy.on('tap', 'node', function (evt) { var newNode = new Set(); @@ -577,7 +590,6 @@ function updateGraph(chr, cy) { }).forEach(function (node, i) { node.data('len', geOtherNodeWidth(node.id())); node.data('width', geOtherNodeWidth(node.id())); - console.log(node.data('notALL')); if (node.data('notALL') != 0) { node.data('notALL', getNotAllValue()); } @@ -698,6 +710,7 @@ function drawAlongChromosome(chr) { document.getElementById("cynav").remove(); } createNewVerAlongChr(cy, area_size, min_contig_len, isGoodEdge, curNodeSet, openNode); + nodePositionChange(cy, posmin, posmax); cy.on('zoom', function () { if (cy.zoom() < maxZoomUpdate && cy.zoom() > minZoomUpdate && cy.extent().x1 >= lastMinX && cy.extent().x2 <= lastMaxX) { From 31e526ea3d7aa3160b1abbc43dbd91eac8354f67 Mon Sep 17 00:00:00 2001 From: Olga Chernikova Date: Fri, 12 Oct 2018 13:03:17 +0300 Subject: [PATCH 15/19] contig position don't intersec --- UI/scripts/handleAlongChromosomes.js | 76 +++++++++++++++++++--------- 1 file changed, 52 insertions(+), 24 deletions(-) diff --git a/UI/scripts/handleAlongChromosomes.js b/UI/scripts/handleAlongChromosomes.js index 6314ab0..338f529 100644 --- a/UI/scripts/handleAlongChromosomes.js +++ b/UI/scripts/handleAlongChromosomes.js @@ -133,7 +133,7 @@ function getDispersion() { } function getContigXPosD() { - return 1000/defZoom; + return 10/cy.zoom();//;1000/defZoom; } function getRankDist() { @@ -310,11 +310,9 @@ function updateZooming(cy, posx, posmin, posmax, oldPosition) { } } -function processFoundContig(elem, inode, posx, posmin, posmax, curNodeSet, order) { +function processFoundContig(elem, inode, posx, posmin, posmax, curNodeSet, order, levelX) { var vid = elem.id; - if (!(posx.has(vid))) { - posx.set(vid, Math.random() * getContigXPosD()); - } + posx.set(vid, -1*levelX.get(vid) * getContigXPosD()); if (!(posmin.has(vid))) { posmin.set(vid, elem.cb); posmax.set(vid, elem.ce); @@ -324,43 +322,43 @@ function processFoundContig(elem, inode, posx, posmin, posmax, curNodeSet, order curNodeSet.add(vid); } -function findContigsByTree(tr, inode, posx, posmin, posmax, curNodeSet, ymin, ymax, lsm) { +function findContigsByTree(tr, inode, posx, posmin, posmax, curNodeSet, ymin, ymax, lsm, levelX) { if (tr["lstL"].length === 0) { return; } if (ymin <= tr["md"] && ymax >= tr["md"]) { for (var i = 0; i < tr["lstL"].length; ++i) { - processFoundContig(tr["lstL"][i], inode, posx, posmin, posmax, curNodeSet, tr["lt"]["size"] + i + lsm); + processFoundContig(tr["lstL"][i], inode, posx, posmin, posmax, curNodeSet, tr["lt"]["size"] + i + lsm, levelX); } } else if (ymax < tr["md"]) { for (i = 0; i < tr["lstL"].length; ++i) { if (tr["lstL"][i].cb > ymax) { break; } - processFoundContig(tr["lstL"][i], inode, posx, posmin, posmax, curNodeSet, tr["lt"]["size"] + i + lsm); + processFoundContig(tr["lstL"][i], inode, posx, posmin, posmax, curNodeSet, tr["lt"]["size"] + i + lsm, levelX); } } else if (ymin > tr["md"]) { for (i = 0; i < tr["lstR"].length; ++i) { if (tr["lstR"][i].ce < ymin) { break; } - processFoundContig(tr["lstR"][i], inode, posx, posmin, posmax, curNodeSet, tr["lt"]["size"] + tr["lstR"].length - i - 1 + lsm); + processFoundContig(tr["lstR"][i], inode, posx, posmin, posmax, curNodeSet, tr["lt"]["size"] + tr["lstR"].length - i - 1 + lsm, levelX); } } if (ymin < tr["md"]) { - findContigsByTree(tr["lt"], inode, posx, posmin, posmax, curNodeSet, ymin, ymax, lsm); + findContigsByTree(tr["lt"], inode, posx, posmin, posmax, curNodeSet, ymin, ymax, lsm, levelX); } if (ymax > tr["md"]) { - findContigsByTree(tr["rt"], inode, posx, posmin, posmax, curNodeSet, ymin, ymax, lsm + tr["lt"]["size"] + tr["lstR"].length); + findContigsByTree(tr["rt"], inode, posx, posmin, posmax, curNodeSet, ymin, ymax, lsm + tr["lt"]["size"] + tr["lstR"].length, levelX); } } -function findContigs(cy, chr, inode, posx, posmin, posmax, curNodeSet) { +function findContigs(cy, chr, inode, posx, posmin, posmax, curNodeSet, levelX) { lastMinX = cy.extent().x1 - (cy.extent().x2 - cy.extent().x1); lastMaxX = cy.extent().x2 + (cy.extent().x2 - cy.extent().x1); - findContigsByTree(IntervalTree[defZoom], inode, posx, posmin, posmax, curNodeSet, lastMinX, lastMaxX, 0); + findContigsByTree(IntervalTree[defZoom], inode, posx, posmin, posmax, curNodeSet, lastMinX, lastMaxX, 0, levelX); } function addContigs(cy, inode, posx, posmin, posmax) { @@ -553,7 +551,7 @@ function addEdges(cy) { } } -function createGraph(chr, cy, curNodeSet, posx, posmin, posmax, oldPosition, openNode) { +function createGraph(chr, cy, curNodeSet, posx, posmin, posmax, oldPosition, openNode, levelX) { updateZooming(cy, posx, posmin, posmax, oldPosition); cy.elements().remove(); special_nodes.clear(); @@ -565,7 +563,7 @@ function createGraph(chr, cy, curNodeSet, posx, posmin, posmax, oldPosition, ope nodes_to_draw = []; edges_to_draw = []; - findContigs(cy, chr, inode, posx, posmin, posmax, curNodeSet); + findContigs(cy, chr, inode, posx, posmin, posmax, curNodeSet, levelX); addContigs(cy, inode, posx, posmin, posmax); var vert_to_draw = findNodeAroundChr(inode, area_size, min_contig_len, isGoodEdge, curNodeSet, openNode, cy); @@ -577,12 +575,15 @@ function createGraph(chr, cy, curNodeSet, posx, posmin, posmax, oldPosition, ope createCoordinates(chr, cy); } -function updateGraph(chr, cy) { +function updateGraph(chr, cy, levelX) { createCoordinates(chr, cy); var wght = getWidth(cy); cy.nodes().filter(function (ele) { return ele.data('rank') === 0; - }).data('width', wght); + }).forEach(function (node, index) { + node.data('width', wght); + node.position('y', -1*getContigXPosD()*levelX.get(parseInt(node.id()))); + }); cy.nodes().filter(function (ele) { @@ -649,6 +650,31 @@ function buildIT(chr, dz) { return buildITree(lst); } +function calculateContigLevelX(chr, levelX) { + var lst = []; + var j = 0; + var levelList = new Array(20); + for (var i = 0; i < chromosomes[chr].alignments.length; ++i) { + var curalig = chromosomes[chr].alignments[i]; + for (j = 0; j < 20; ++j) { + levelList[parseInt(j)] = 0; + } + for (j = 0; j < lst.length; ++j) { + if ((curalig.coordb <= lst[j].cb && lst[j].cb <= curalig.coorde) || + (curalig.coordb <= lst[j].ce && lst[j].ce <= curalig.coorde) || + (lst[j].cb <= curalig.coordb && curalig.coordb <= lst[j].ce)) { + levelList[parseInt(levelX.get(lst[j].id))] = 1; + } + } + lst.push({id: curalig.node_id, cb: curalig.coordb, ce: curalig.coorde}); + for (j = 19; j >= 0; --j) { + if (levelList[j] === 0) { + levelX.set(curalig.node_id, j); + } + } + } +} + function drawAlongChromosome(chr) { defZoom = 100; lastMinX = 0; @@ -663,7 +689,9 @@ function drawAlongChromosome(chr) { var posmin = new Map(); var posmax = new Map(); var oldPosition = new Map(); - + var levelX = new Map(); + calculateContigLevelX(chr, levelX); + cy = cytoscape({ container: document.getElementById('mainpanel'), @@ -714,11 +742,11 @@ function drawAlongChromosome(chr) { cy.on('zoom', function () { if (cy.zoom() < maxZoomUpdate && cy.zoom() > minZoomUpdate && cy.extent().x1 >= lastMinX && cy.extent().x2 <= lastMaxX) { - updateGraph(chr, cy); + updateGraph(chr, cy, levelX); } else { document.getElementById("UpdateGraph").style.visibility = "visible"; document.getElementById("updateGrpahButton").focus(); - updateGraph(chr, cy); + updateGraph(chr, cy, levelX); } (document.getElementById("zoomInput")).innerText = Math.floor(cy.zoom() * 100 * 100/ defZoom).toString() + "%"; @@ -726,16 +754,16 @@ function drawAlongChromosome(chr) { cy.on('pan', function() { if (cy.extent().x1 >= lastMinX && cy.extent().x2 <= lastMaxX) { - updateGraph(chr, cy); + updateGraph(chr, cy, levelX); } else { document.getElementById("UpdateGraph").style.visibility = "visible"; document.getElementById("updateGrpahButton").focus(); - updateGraph(chr, cy); + updateGraph(chr, cy, levelX); } }); document.getElementById("updateGrpahButton").onclick = function(){ - createGraph(chr, cy, curNodeSet, posx, posmin, posmax, oldPosition, openNode); + createGraph(chr, cy, curNodeSet, posx, posmin, posmax, oldPosition, openNode, levelX); document.getElementById("UpdateGraph").style.visibility = "hidden"; (document.getElementById("zoomInput")).innerText = Math.floor(cy.zoom() * 100 * 100/ defZoom).toString() + "%"; }; @@ -744,7 +772,7 @@ function drawAlongChromosome(chr) { window.cy = this; }); setTimeout(function() { - createGraph(chr, cy, curNodeSet, posx, posmin, posmax, oldPosition, openNode); + createGraph(chr, cy, curNodeSet, posx, posmin, posmax, oldPosition, openNode, levelX); var height = document.getElementById('mainpanel').clientHeight; cy.pan({x: cy.pan().x, y: height/3}); }, 1); From 208e41ae4a6fd26875c3e788e3c033a46b35df48 Mon Sep 17 00:00:00 2001 From: Olga Chernikova Date: Fri, 12 Oct 2018 13:24:20 +0300 Subject: [PATCH 16/19] dispersion --- UI/scripts/handleAlongChromosomes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UI/scripts/handleAlongChromosomes.js b/UI/scripts/handleAlongChromosomes.js index 338f529..a4ed2fa 100644 --- a/UI/scripts/handleAlongChromosomes.js +++ b/UI/scripts/handleAlongChromosomes.js @@ -129,7 +129,7 @@ function getScala(cy) { } function getDispersion() { - return 10;//50; + return 250; } function getContigXPosD() { From e40bb399089f8c3d0c97830a2ec85382763e4c9a Mon Sep 17 00:00:00 2001 From: Olga Chernikova Date: Tue, 16 Oct 2018 23:00:09 +0300 Subject: [PATCH 17/19] fix shebang --- visualize_scaffold_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/visualize_scaffold_graph.py b/visualize_scaffold_graph.py index 5e1fb44..58eaf70 100755 --- a/visualize_scaffold_graph.py +++ b/visualize_scaffold_graph.py @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/usr/bin/env python3 import sys import os import argparse From 988f49be0db8edf0542a4ede3361b52d0502cad9 Mon Sep 17 00:00:00 2001 From: Olga Chernikova Date: Fri, 19 Oct 2018 13:25:43 +0300 Subject: [PATCH 18/19] change color of nodes --- UI/scripts/scaffoldgraph.js | 20 ++++++++++++++++++-- compile.sh | 2 +- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/UI/scripts/scaffoldgraph.js b/UI/scripts/scaffoldgraph.js index 82d9b04..22c2f33 100644 --- a/UI/scripts/scaffoldgraph.js +++ b/UI/scripts/scaffoldgraph.js @@ -1,12 +1,28 @@ colors = [ + "#3B7423", + "#90C479", + "#B35E0B", + "#F6B26B", + "#1A55CD", + "#6A9EEA", + "#732149", + "#C378A1", + "#BE8F03", + "#FFD867", + "#1A505C", + "#75A4AE", + "#9A0700", + "#E06663", + "#1A5388", + "#71A6D8", + "#008000", + "#D0FF14", "#E32636", "#F19CBB", "#FF7E00", "#FFBF00", "#0048BA", "#7CB9E8", - "#008000", - "#D0FF14", "#8A2BE2", "#D19FE8", "#88540B", diff --git a/compile.sh b/compile.sh index a8a1c21..7f26856 100755 --- a/compile.sh +++ b/compile.sh @@ -16,4 +16,4 @@ cd "$BASEDIR/$BUILD_DIR" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$PREFIX" $* "$BASEDIR" make -j 8 make install -cd $PREFIX \ No newline at end of file +cd $PREFIX From 8996273887c240984bd6aa45749df1179fee32a1 Mon Sep 17 00:00:00 2001 From: Olga Chernikova Date: Fri, 19 Oct 2018 13:54:48 +0300 Subject: [PATCH 19/19] visualize_scaffold_graph -> sgtk --- CMakeLists.txt | 2 +- visualize_scaffold_graph.py => sgtk.py | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename visualize_scaffold_graph.py => sgtk.py (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c20f01..3efa92d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,7 +43,7 @@ add_subdirectory(src) install(PROGRAMS "${CMAKE_CURRENT_SOURCE_DIR}/rna_scaffolder.py" DESTINATION bin COMPONENT runtime) -install(PROGRAMS "${CMAKE_CURRENT_SOURCE_DIR}/visualize_scaffold_graph.py" +install(PROGRAMS "${CMAKE_CURRENT_SOURCE_DIR}/sgtk.py" DESTINATION bin COMPONENT runtime) install(PROGRAMS "${CMAKE_CURRENT_SOURCE_DIR}/resources/test_dataset/ref.fasta" diff --git a/visualize_scaffold_graph.py b/sgtk.py similarity index 100% rename from visualize_scaffold_graph.py rename to sgtk.py