From 911199716bcf05d5847f724ec8edd2dc3f3b3581 Mon Sep 17 00:00:00 2001 From: shreyasun Date: Tue, 31 Oct 2023 09:29:13 -0700 Subject: [PATCH 01/12] Modified vg chunk call to include condition to simplify graph if that's what the user requests --- src/server.mjs | 64 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/src/server.mjs b/src/server.mjs index df6bbaf3..e6c05f38 100644 --- a/src/server.mjs +++ b/src/server.mjs @@ -312,6 +312,15 @@ async function getChunkedData(req, res, next) { console.log("no BED file provided."); } + // client is going to send ifSimplifyChecked = true if they want to simplify view + // where is the request + // add a field to the request + let ifSimplifyChecked = false; + req.simplify = false; + if (ifSimplifyChecked === true){ + req.simplify = true; + } + // This will have a conitg, start, end, or a contig, start, distance let parsedRegion; try { @@ -427,6 +436,10 @@ async function getChunkedData(req, res, next) { console.time("vg chunk"); const vgChunkCall = spawn(`${VG_PATH}vg`, vgChunkParams); + let vgSimplifyCall = null; + if (req.simplify){ + vgSimplifyCall = spawn(`${VG_PATH}vg`, ["simplify", "-"]); + } const vgViewCall = spawn(`${VG_PATH}vg`, ["view", "-j", "-"]); let graphAsString = ""; req.error = Buffer.alloc(0); @@ -453,12 +466,16 @@ async function getChunkedData(req, res, next) { }); vgChunkCall.stdout.on("data", function (data) { - vgViewCall.stdin.write(data); + if (req.simplify){ + vgSimplifyCall.stdin.write(data); + } else { + vgViewCall.stdin.write(data); + } }); vgChunkCall.on("close", (code) => { console.log(`vg chunk exited with code ${code}`); - vgViewCall.stdin.end(); + vgSimplifyCall.stdin.end(); if (code !== 0) { console.log("Error from " + VG_PATH + "vg " + vgChunkParams.join(" ")); // Execution failed @@ -469,6 +486,49 @@ async function getChunkedData(req, res, next) { } }); + // vg simplify + if (req.simplify){ + vgSimplifyCall.on("error", function (err) { + console.log( + "Error executing " + + VG_PATH + + "vg " + + "simplify " + + "- " + + ": " + + err + ); + if (!sentResponse) { + sentResponse = true; + return next(new VgExecutionError("vg simplify failed")); + } + return; + }); + + vgSimplifyCall.stderr.on("data", (data) => { + console.log(`vg simplify err data: ${data}`); + req.error += data; + }); + + vgSimplifyCall.stdout.on("data", function (data) { + vgViewCall.stdin.write(data); + }); + + vgSimplifyCall.on("close", (code) => { + console.log(`vg simplify exited with code ${code}`); + vgViewCall.stdin.end(); + if (code !== 0) { + console.log("Error from " + VG_PATH + "vg " + "simplify - "); + // Execution failed + if (!sentResponse) { + sentResponse = true; + return next(new VgExecutionError("vg simplify failed")); + } + } + }); + } + + // vg view vgViewCall.on("error", function (err) { console.log('Error executing "vg view": ' + err); if (!sentResponse) { From 4df8a116782eaba3816544639d2720c84d9e7392 Mon Sep 17 00:00:00 2001 From: shreyasun Date: Tue, 7 Nov 2023 08:22:38 -0800 Subject: [PATCH 02/12] Continuing to make changes to allow for simplifying option --- src/components/CopyLink.js | 11 ++++++++--- src/components/HeaderForm.js | 9 +++++++++ src/config.json | 4 +++- src/server.mjs | 15 ++++++++------- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/components/CopyLink.js b/src/components/CopyLink.js index 30505a43..fdf61960 100644 --- a/src/components/CopyLink.js +++ b/src/components/CopyLink.js @@ -81,9 +81,14 @@ export const urlParamsToViewTarget = (url) => { result = qs.parse(s[1]); } - // TODO: qs can't tell the difference between false and "false", and "false" - // is truthy. So we need to go through and coerce things to real booleans at - // some point. + // Ensures that the simplify field is a boolean, as the qs module can't tell + // the difference between false and "false" + let resultSimplify = result.simplify; + if (resultSimplify === "true"){ + result.simplify = true; + } else if (resultSimplify === "false"){ + result.simplify = false; + } return result; }; diff --git a/src/components/HeaderForm.js b/src/components/HeaderForm.js index a801c392..cf709cb6 100644 --- a/src/components/HeaderForm.js +++ b/src/components/HeaderForm.js @@ -155,6 +155,10 @@ function viewTargetsEqual(currViewTarget, nextViewTarget) { return false; } + if (currViewTarget.simplify !== nextViewTarget.simplify){ + return false; + } + return true; } @@ -208,6 +212,7 @@ class HeaderForm extends Component { region: ds.region, dataType: ds.dataType, name: ds.name, + simplify: ds.simplify }; return stateVals; }); @@ -465,6 +470,7 @@ class HeaderForm extends Component { name: this.state.name, region: this.state.region, dataType: this.state.dataType, + simplify: this.state.simplify }); handleGoButton = () => { @@ -796,6 +802,9 @@ class HeaderForm extends Component { onChange={this.handleInputChange} handleFileUpload={this.handleFileUpload} > + {/* Button for simplify */} + + } diff --git a/src/config.json b/src/config.json index a39f9ae9..91d1a17d 100644 --- a/src/config.json +++ b/src/config.json @@ -10,7 +10,8 @@ "dataPath": "default", "region": "17:1-100", "bedFile": "exampleData/internal/snp1kg-BRCA1.bed", - "dataType": "built-in" + "dataType": "built-in", + "simplify": false }, { "name": "vg \"small\" example", @@ -90,4 +91,5 @@ "MAXUPLOADSIZE": 5242880, "pickerTypeOptions": ["mounted", "upload"] + } diff --git a/src/server.mjs b/src/server.mjs index 55c7ff0f..9cb3a363 100644 --- a/src/server.mjs +++ b/src/server.mjs @@ -312,14 +312,11 @@ async function getChunkedData(req, res, next) { console.log("no BED file provided."); } - // client is going to send ifSimplifyChecked = true if they want to simplify view - // where is the request - // add a field to the request - let ifSimplifyChecked = false; + // client is going to send simplify = true if they want to simplify view req.simplify = false; - if (ifSimplifyChecked === true){ + if (req.body.simplify){ req.simplify = true; - } + } // This will have a conitg, start, end, or a contig, start, distance let parsedRegion; @@ -475,7 +472,11 @@ async function getChunkedData(req, res, next) { vgChunkCall.on("close", (code) => { console.log(`vg chunk exited with code ${code}`); - vgSimplifyCall.stdin.end(); + if (req.simplify){ + vgSimplifyCall.stdin.end(); + } else { + vgViewCall.stdin.end(); + } if (code !== 0) { console.log("Error from " + VG_PATH + "vg " + vgChunkParams.join(" ")); // Execution failed From 0f480e3870bd52a6177cf3828c20e3078eaddd07 Mon Sep 17 00:00:00 2001 From: shreyasun Date: Thu, 9 Nov 2023 20:24:42 -0800 Subject: [PATCH 03/12] Created new button for simplify option --- src/components/CopyLink.js | 12 +++++++----- src/components/HeaderForm.js | 13 ++++++++----- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/components/CopyLink.js b/src/components/CopyLink.js index fdf61960..273d36b6 100644 --- a/src/components/CopyLink.js +++ b/src/components/CopyLink.js @@ -83,11 +83,13 @@ export const urlParamsToViewTarget = (url) => { // Ensures that the simplify field is a boolean, as the qs module can't tell // the difference between false and "false" - let resultSimplify = result.simplify; - if (resultSimplify === "true"){ - result.simplify = true; - } else if (resultSimplify === "false"){ - result.simplify = false; + if (result != null){ + let resultSimplify = result.simplify; + if (resultSimplify === "true"){ + result.simplify = true; + } else if (resultSimplify === "false"){ + result.simplify = false; + } } return result; diff --git a/src/components/HeaderForm.js b/src/components/HeaderForm.js index cf709cb6..f8f66074 100644 --- a/src/components/HeaderForm.js +++ b/src/components/HeaderForm.js @@ -1,6 +1,6 @@ import React, { Component } from "react"; import PropTypes from "prop-types"; -import { Container, Row, Col, Label, Alert } from "reactstrap"; +import { Container, Row, Col, Label, Alert, Button } from "reactstrap"; import { dataOriginTypes } from "../enums"; import { fetchAndParse } from "../fetchAndParse"; import "../config-client.js"; @@ -108,7 +108,7 @@ function tracksEqual(curr, next) { return false; } } - //count falsy file names as the same + // count falsy file names as the same if ((!curr_file && !next_file) || curr_file === next_file) { return true; } @@ -163,7 +163,6 @@ function viewTargetsEqual(currViewTarget, nextViewTarget) { } - class HeaderForm extends Component { state = EMPTY_STATE; componentDidMount() { @@ -674,6 +673,11 @@ class HeaderForm extends Component { }; }; + /* Function for simplify */ + enableSimplify = () => { + this.setState( { simplify: !this.state.simplify }); + } + render() { let errorDiv = null; if (this.state.error) { @@ -803,8 +807,7 @@ class HeaderForm extends Component { handleFileUpload={this.handleFileUpload} > {/* Button for simplify */} - - + } From bc32dd711d581a4e6f6503084807569f97c3211e Mon Sep 17 00:00:00 2001 From: shreyasun Date: Thu, 16 Nov 2023 14:55:05 -0800 Subject: [PATCH 04/12] Allowed for simplify to not occur when reads are selected --- src/common.mjs | 12 ++++++++++++ src/components/HeaderForm.js | 14 ++++++++++---- src/server.mjs | 5 ++++- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/common.mjs b/src/common.mjs index b2ed3d3e..f7d8fc28 100644 --- a/src/common.mjs +++ b/src/common.mjs @@ -110,3 +110,15 @@ export function defaultTrackColors(trackType){ throw new Error("Invalid track type: " + trackType); } } + + +/* Function to determine if reads are added, where tracks is an object */ +export function readsExist(tracks){ + for (let key in tracks){ + if (tracks[key].trackType === "read"){ + return true; + } + } + return false; +} + diff --git a/src/components/HeaderForm.js b/src/components/HeaderForm.js index f8f66074..4d64ecee 100644 --- a/src/components/HeaderForm.js +++ b/src/components/HeaderForm.js @@ -10,7 +10,7 @@ import ExampleSelectButtons from "./ExampleSelectButtons"; import RegionInput from "./RegionInput"; import TrackPicker from "./TrackPicker"; import BedFileDropdown from "./BedFileDropdown"; -import { parseRegion, stringifyRegion } from "../common.mjs"; +import { parseRegion, stringifyRegion, readsExist } from "../common.mjs"; // See src/Types.ts @@ -469,7 +469,7 @@ class HeaderForm extends Component { name: this.state.name, region: this.state.region, dataType: this.state.dataType, - simplify: this.state.simplify + simplify: this.state.simplify && !(readsExist(this.state.tracks)) }); handleGoButton = () => { @@ -717,6 +717,9 @@ class HeaderForm extends Component { const examplesFlag = this.state.dataType === dataTypes.EXAMPLES; const viewTargetHasChange = !viewTargetsEqual(this.getNextViewTarget(), this.props.getCurrentViewTarget()); + const ifReadsExist = readsExist(this.state.tracks); + + console.log( "Rendering header form with fileSelectOptions: ", this.state.fileSelectOptions @@ -807,8 +810,11 @@ class HeaderForm extends Component { handleFileUpload={this.handleFileUpload} > {/* Button for simplify */} - - + { + !ifReadsExist && + + } + } diff --git a/src/server.mjs b/src/server.mjs index 9cb3a363..69eb0b99 100644 --- a/src/server.mjs +++ b/src/server.mjs @@ -22,7 +22,7 @@ import { server as WebSocketServer } from "websocket"; import dotenv from "dotenv"; import dirname from "es-dirname"; import { readFileSync, writeFile } from 'fs'; -import { parseRegion, convertRegionToRangeRegion, stringifyRangeRegion, stringifyRegion } from "./common.mjs"; +import { parseRegion, convertRegionToRangeRegion, stringifyRangeRegion, stringifyRegion, readsExist } from "./common.mjs"; import { Readable } from "stream"; import { finished } from "stream/promises"; import sanitize from "sanitize-filename"; @@ -315,6 +315,9 @@ async function getChunkedData(req, res, next) { // client is going to send simplify = true if they want to simplify view req.simplify = false; if (req.body.simplify){ + if (readsExist(req.body.tracks)){ + throw new BadRequestError("Simplify cannot be used on read tracks."); + } req.simplify = true; } From af9a5867e743e97c78f6448acc1620135db36bae Mon Sep 17 00:00:00 2001 From: shreyasun Date: Mon, 27 Nov 2023 19:24:20 -0800 Subject: [PATCH 05/12] updated server with a simplify option for bed files --- src/server.mjs | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/server.mjs b/src/server.mjs index 69eb0b99..a6d7bc16 100644 --- a/src/server.mjs +++ b/src/server.mjs @@ -436,10 +436,12 @@ async function getChunkedData(req, res, next) { console.time("vg chunk"); const vgChunkCall = spawn(`${VG_PATH}vg`, vgChunkParams); + // vg simplify for gam files let vgSimplifyCall = null; if (req.simplify){ vgSimplifyCall = spawn(`${VG_PATH}vg`, ["simplify", "-"]); } + const vgViewCall = spawn(`${VG_PATH}vg`, ["view", "-j", "-"]); let graphAsString = ""; req.error = Buffer.alloc(0); @@ -582,6 +584,11 @@ async function getChunkedData(req, res, next) { // We're using a shared directory for this request, so leave it in place // when the request finishes. req.rmChunk = false; + // vg simplify for bed files + let vgSimplifyCall = null; + if (req.simplify){ + vgSimplifyCall = spawn(`${VG_PATH}vg`, ["simplify", "-"]); + } const vgViewCall = spawn(`${VG_PATH}vg`, [ "view", "-j", @@ -589,6 +596,49 @@ async function getChunkedData(req, res, next) { ]); let graphAsString = ""; req.error = Buffer.alloc(0); + + // vg simplify + if (req.simplify){ + vgSimplifyCall.on("error", function (err) { + console.log( + "Error executing " + + VG_PATH + + "vg " + + "simplify " + + "- " + + ": " + + err + ); + if (!sentResponse) { + sentResponse = true; + return next(new VgExecutionError("vg simplify failed")); + } + return; + }); + + vgSimplifyCall.stderr.on("data", (data) => { + console.log(`vg simplify err data: ${data}`); + req.error += data; + }); + + vgSimplifyCall.stdout.on("data", function (data) { + vgViewCall.stdin.write(data); + }); + + vgSimplifyCall.on("close", (code) => { + console.log(`vg simplify exited with code ${code}`); + vgViewCall.stdin.end(); + if (code !== 0) { + console.log("Error from " + VG_PATH + "vg " + "simplify - "); + // Execution failed + if (!sentResponse) { + sentResponse = true; + return next(new VgExecutionError("vg simplify failed")); + } + } + }); + } + vgViewCall.on("error", function (err) { console.log('Error executing "vg view": ' + err); if (!sentResponse) { From 775c6f809a7071c1f984862cd766b122cffb2505 Mon Sep 17 00:00:00 2001 From: shreyasun Date: Wed, 29 Nov 2023 21:03:33 -0800 Subject: [PATCH 06/12] some comments --- src/server.mjs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/server.mjs b/src/server.mjs index a6d7bc16..70ca0ec3 100644 --- a/src/server.mjs +++ b/src/server.mjs @@ -586,13 +586,15 @@ async function getChunkedData(req, res, next) { req.rmChunk = false; // vg simplify for bed files let vgSimplifyCall = null; + + // if simplify is on: route input to view as simplify if (req.simplify){ vgSimplifyCall = spawn(`${VG_PATH}vg`, ["simplify", "-"]); } - const vgViewCall = spawn(`${VG_PATH}vg`, [ + const vgViewCall = spawn(`${VG_PATH}vg`, [ // vg chunk call 601 on master "view", "-j", - `${req.chunkDir}/chunk.vg`, + `${req.chunkDir}/chunk.vg`, // change this one to - for simplify ]); let graphAsString = ""; req.error = Buffer.alloc(0); From ac1e77910e3e5699379fb22f43a2690e6bfb16b4 Mon Sep 17 00:00:00 2001 From: shreyasun Date: Thu, 30 Nov 2023 13:37:13 -0800 Subject: [PATCH 07/12] Added vgViewArguments for simplify option to vgviewcall for bed files --- src/server.mjs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/server.mjs b/src/server.mjs index 6e64294d..6900f88f 100644 --- a/src/server.mjs +++ b/src/server.mjs @@ -466,7 +466,7 @@ async function getChunkedData(req, res, next) { req.withBed = false; console.log("no BED file provided."); } - + /* // This will have a conitg, start, end, or a contig, start, distance let parsedRegion; try { @@ -474,7 +474,7 @@ async function getChunkedData(req, res, next) { } catch (e) { // Whatever went wrong in the parsing, it makes the request bad. throw new BadRequestError("Wrong query: " + e.message + " See ? button above."); - } + }*/ // check the bed file if this region has been pre-fetched let chunkPath = ""; @@ -732,16 +732,16 @@ async function getChunkedData(req, res, next) { req.rmChunk = false; // vg simplify for bed files let vgSimplifyCall = null; - + let vgViewArguments = ["view", "-j"]; if (req.simplify){ - vgSimplifyCall = spawn(`${VG_PATH}vg`, ["simplify", "-"]); + vgSimplifyCall = spawn(`${VG_PATH}vg`, ["simplify",`${req.chunkDir}/chunk.vg`,]); + vgViewArguments.push("-"); + } else { + vgViewArguments.push(`${req.chunkDir}/chunk.vg`); } - - const vgViewCall = spawn(`${VG_PATH}vg`, [ - "view", - "-j", - `${req.chunkDir}/chunk.vg`, - ]); + + let vgViewCall = spawn(`${VG_PATH}vg`, vgViewArguments); + let graphAsString = ""; req.error = Buffer.alloc(0); From 49fa0bffce5c853c4e9bf7be668d2193e942e320 Mon Sep 17 00:00:00 2001 From: shreyasun Date: Thu, 30 Nov 2023 14:28:51 -0800 Subject: [PATCH 08/12] Added some imports and other fixes --- src/server.mjs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/server.mjs b/src/server.mjs index 6900f88f..391def80 100644 --- a/src/server.mjs +++ b/src/server.mjs @@ -21,7 +21,7 @@ import { server as WebSocketServer } from "websocket"; import dotenv from "dotenv"; import dirname from "es-dirname"; import { readFileSync, writeFile } from 'fs'; -import { parseRegion, convertRegionToRangeRegion, stringifyRangeRegion, stringifyRegion } from "./common.mjs"; +import { parseRegion, convertRegionToRangeRegion, stringifyRangeRegion, stringifyRegion, isValidURL, readsExist } from "./common.mjs"; import { Readable } from "stream"; import { finished } from "stream/promises"; import sanitize from "sanitize-filename"; @@ -466,15 +466,14 @@ async function getChunkedData(req, res, next) { req.withBed = false; console.log("no BED file provided."); } - /* - // This will have a conitg, start, end, or a contig, start, distance - let parsedRegion; - try { - parsedRegion = parseRegion(req.body.region); - } catch (e) { - // Whatever went wrong in the parsing, it makes the request bad. - throw new BadRequestError("Wrong query: " + e.message + " See ? button above."); - }*/ + // client is going to send simplify = true if they want to simplify view + req.simplify = false; + if (req.body.simplify){ + if (readsExist(req.body.tracks)){ + throw new BadRequestError("Simplify cannot be used on read tracks."); + } + req.simplify = true; + } // check the bed file if this region has been pre-fetched let chunkPath = ""; @@ -586,6 +585,7 @@ async function getChunkedData(req, res, next) { let vgSimplifyCall = null; if (req.simplify){ vgSimplifyCall = spawn(`${VG_PATH}vg`, ["simplify", "-"]); + console.log("Spawning vg simplify call"); } const vgViewCall = spawn(`${VG_PATH}vg`, ["view", "-j", "-"]); @@ -736,6 +736,7 @@ async function getChunkedData(req, res, next) { if (req.simplify){ vgSimplifyCall = spawn(`${VG_PATH}vg`, ["simplify",`${req.chunkDir}/chunk.vg`,]); vgViewArguments.push("-"); + console.log("Spawning vg simplify call"); } else { vgViewArguments.push(`${req.chunkDir}/chunk.vg`); } From f4896669726444170644d4d5bf2f9e282a0aad98 Mon Sep 17 00:00:00 2001 From: shreyasun Date: Thu, 30 Nov 2023 14:42:23 -0800 Subject: [PATCH 09/12] Updated help documentation with instructions for simplify --- public/help/help.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/public/help/help.md b/public/help/help.md index a4b014ed..52c1bb81 100644 --- a/public/help/help.md +++ b/public/help/help.md @@ -27,5 +27,6 @@ The following procedure describes adding and updating settings of custom tracks. * A start position and a distance (e.g. "chr1:1+100") * A node ID anchor and a distance (e.g. "node:100+10") ![Region Input Options](helpGuideImages/img8.png) -9. Click Go to see the selected tracks render in the visualization area. +4. There is an option to click on the "Simplify Off" button to enable vg simplify, which would remove eliding small snarls in the graph. This would only work for BED files or graph tracks (not reads or haplotypes). +5. Click Go to see the selected tracks render in the visualization area. ![Go Button](helpGuideImages/img9.png) \ No newline at end of file From ec1633143fd5c6cda9dfcfbb38a721b0f2117c6b Mon Sep 17 00:00:00 2001 From: shreyasun Date: Mon, 4 Dec 2023 23:20:09 -0800 Subject: [PATCH 10/12] added &simplify=false to links in test --- src/end-to-end.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/end-to-end.test.js b/src/end-to-end.test.js index b0314eb8..f33c8646 100644 --- a/src/end-to-end.test.js +++ b/src/end-to-end.test.js @@ -342,7 +342,7 @@ describe("When we wait for it to load", () => { it("produces correct link for view before & after go is pressed", async () => { // First test that after pressing go, the link reflects the dat form const expectedLinkBRCA1 = - "http://localhost?name=snp1kg-BRCA1&tracks[0][trackFile]=exampleData%2Finternal%2Fsnp1kg-BRCA1.vg.xg&tracks[0][trackType]=graph&tracks[0][trackColorSettings][mainPalette]=greys&tracks[0][trackColorSettings][auxPalette]=ygreys&tracks[1][trackFile]=exampleData%2Finternal%2FNA12878-BRCA1.sorted.gam&tracks[1][trackType]=read&dataPath=default®ion=17%3A1-100&bedFile=exampleData%2Finternal%2Fsnp1kg-BRCA1.bed&dataType=built-in"; + "http://localhost?name=snp1kg-BRCA1&tracks[0][trackFile]=exampleData%2Finternal%2Fsnp1kg-BRCA1.vg.xg&tracks[0][trackType]=graph&tracks[0][trackColorSettings][mainPalette]=greys&tracks[0][trackColorSettings][auxPalette]=ygreys&tracks[1][trackFile]=exampleData%2Finternal%2FNA12878-BRCA1.sorted.gam&tracks[1][trackType]=read&dataPath=default®ion=17%3A1-100&bedFile=exampleData%2Finternal%2Fsnp1kg-BRCA1.bed&dataType=built-in&simplify=false"; // Set up dropdown await act(async () => { let dropdown = document.getElementById("dataSourceSelect"); @@ -376,7 +376,7 @@ it("produces correct link for view before & after go is pressed", async () => { await clickCopyLink(); const expectedLinkCactus = - "http://localhost?tracks[0][trackFile]=exampleData%2Fcactus.vg.xg&tracks[0][trackType]=graph&tracks[1][trackFile]=exampleData%2Fcactus-NA12879.sorted.gam&tracks[1][trackType]=read&bedFile=exampleData%2Fcactus.bed&name=cactus®ion=ref%3A1-100&dataType=built-in"; + "http://localhost?tracks[0][trackFile]=exampleData%2Fcactus.vg.xg&tracks[0][trackType]=graph&tracks[1][trackFile]=exampleData%2Fcactus-NA12879.sorted.gam&tracks[1][trackType]=read&bedFile=exampleData%2Fcactus.bed&name=cactus®ion=ref%3A1-100&dataType=built-in&simplify=false"; // Make sure link has changed after pressing go expect(fakeClipboard).toEqual(expectedLinkCactus); }, 20000); From 77b7009e7093cb7a6c61887ef94c9a95f677bf98 Mon Sep 17 00:00:00 2001 From: shreyasun Date: Tue, 5 Dec 2023 11:45:53 -0800 Subject: [PATCH 11/12] edits to comments, error messages, and documentation --- public/help/help.md | 2 +- src/common.mjs | 2 +- src/components/CopyLink.js | 5 ++--- src/components/HeaderForm.js | 10 ++++------ src/server.mjs | 9 +++++---- 5 files changed, 13 insertions(+), 15 deletions(-) diff --git a/public/help/help.md b/public/help/help.md index 52c1bb81..f4225675 100644 --- a/public/help/help.md +++ b/public/help/help.md @@ -27,6 +27,6 @@ The following procedure describes adding and updating settings of custom tracks. * A start position and a distance (e.g. "chr1:1+100") * A node ID anchor and a distance (e.g. "node:100+10") ![Region Input Options](helpGuideImages/img8.png) -4. There is an option to click on the "Simplify Off" button to enable vg simplify, which would remove eliding small snarls in the graph. This would only work for BED files or graph tracks (not reads or haplotypes). +4. If simplifying the BED file chunk or graph is possible, users will see a "Simplify Off" button, which when clicked with toggle to "Simplify On". This option enables vg simplify, which would remove eliding small snarls. This option will only appear when there aren't any reads to be displayed. 5. Click Go to see the selected tracks render in the visualization area. ![Go Button](helpGuideImages/img9.png) \ No newline at end of file diff --git a/src/common.mjs b/src/common.mjs index ce0cd7d8..233a9260 100644 --- a/src/common.mjs +++ b/src/common.mjs @@ -111,7 +111,7 @@ export function defaultTrackColors(trackType){ } } -/* Function to determine if reads are added, where tracks is an object */ +/* Function to determine if any of the tracks are reads, where the tracks parameter is an object of track types */ export function readsExist(tracks){ for (let key in tracks){ if (tracks[key].trackType === "read"){ diff --git a/src/components/CopyLink.js b/src/components/CopyLink.js index 273d36b6..a9f38b6d 100644 --- a/src/components/CopyLink.js +++ b/src/components/CopyLink.js @@ -84,10 +84,9 @@ export const urlParamsToViewTarget = (url) => { // Ensures that the simplify field is a boolean, as the qs module can't tell // the difference between false and "false" if (result != null){ - let resultSimplify = result.simplify; - if (resultSimplify === "true"){ + if (result.simplify === "true"){ result.simplify = true; - } else if (resultSimplify === "false"){ + } else if (result.simplify === "false"){ result.simplify = false; } } diff --git a/src/components/HeaderForm.js b/src/components/HeaderForm.js index fc8be21b..2f408728 100644 --- a/src/components/HeaderForm.js +++ b/src/components/HeaderForm.js @@ -718,8 +718,8 @@ class HeaderForm extends Component { }; }; - /* Function for simplify */ - enableSimplify = () => { +/* Function for toggling simplify button, enabling vg simplify to be turned on or off */ +toggleSimplify = () => { this.setState( { simplify: !this.state.simplify }); } @@ -762,8 +762,6 @@ class HeaderForm extends Component { const examplesFlag = this.state.dataType === dataTypes.EXAMPLES; const viewTargetHasChange = !viewTargetsEqual(this.getNextViewTarget(), this.props.getCurrentViewTarget()); - const ifReadsExist = readsExist(this.state.tracks); - console.log( "Rendering header form with fileSelectOptions: ", @@ -856,8 +854,8 @@ class HeaderForm extends Component { > {/* Button for simplify */} { - !ifReadsExist && - + !(readsExist(this.state.tracks)) && + } } diff --git a/src/server.mjs b/src/server.mjs index 391def80..39f5499e 100644 --- a/src/server.mjs +++ b/src/server.mjs @@ -730,15 +730,16 @@ async function getChunkedData(req, res, next) { // We're using a shared directory for this request, so leave it in place // when the request finishes. req.rmChunk = false; + let filename = `${req.chunkDir}/chunk.vg`; // vg simplify for bed files let vgSimplifyCall = null; let vgViewArguments = ["view", "-j"]; if (req.simplify){ - vgSimplifyCall = spawn(`${VG_PATH}vg`, ["simplify",`${req.chunkDir}/chunk.vg`,]); + vgSimplifyCall = spawn(`${VG_PATH}vg`, ["simplify", filename,]); vgViewArguments.push("-"); console.log("Spawning vg simplify call"); } else { - vgViewArguments.push(`${req.chunkDir}/chunk.vg`); + vgViewArguments.push(filename); } let vgViewCall = spawn(`${VG_PATH}vg`, vgViewArguments); @@ -754,7 +755,7 @@ async function getChunkedData(req, res, next) { VG_PATH + "vg " + "simplify " + - "- " + + filename + ": " + err ); @@ -778,7 +779,7 @@ async function getChunkedData(req, res, next) { console.log(`vg simplify exited with code ${code}`); vgViewCall.stdin.end(); if (code !== 0) { - console.log("Error from " + VG_PATH + "vg " + "simplify - "); + console.log("Error from " + VG_PATH + "vg " + "simplify " + filename); // Execution failed if (!sentResponse) { sentResponse = true; From a147acbbf12de16ef88d850fddfd6854bc5fca11 Mon Sep 17 00:00:00 2001 From: Adam Novak Date: Thu, 7 Dec 2023 17:54:27 -0500 Subject: [PATCH 12/12] Drop "eliding" --- public/help/help.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/help/help.md b/public/help/help.md index f4225675..295a6d29 100644 --- a/public/help/help.md +++ b/public/help/help.md @@ -27,6 +27,6 @@ The following procedure describes adding and updating settings of custom tracks. * A start position and a distance (e.g. "chr1:1+100") * A node ID anchor and a distance (e.g. "node:100+10") ![Region Input Options](helpGuideImages/img8.png) -4. If simplifying the BED file chunk or graph is possible, users will see a "Simplify Off" button, which when clicked with toggle to "Simplify On". This option enables vg simplify, which would remove eliding small snarls. This option will only appear when there aren't any reads to be displayed. +4. If simplifying the BED file chunk or graph is possible, users will see a "Simplify Off" button, which when clicked with toggle to "Simplify On". This option enables vg simplify, which would remove small snarls. This option will only appear when there aren't any reads to be displayed. 5. Click Go to see the selected tracks render in the visualization area. -![Go Button](helpGuideImages/img9.png) \ No newline at end of file +![Go Button](helpGuideImages/img9.png)