From aa4117162e29870dd2c7ece9eeabbba6379f43e3 Mon Sep 17 00:00:00 2001 From: bbimber Date: Sun, 12 Oct 2025 16:10:03 -0700 Subject: [PATCH 1/6] Option to create readsets from SRA --- .../sequenceanalysis/sequence_readsets.js | 12 ++-- .../query/SequenceTriggerHelper.java | 69 +++++++++++++++++++ .../external/labModules/SequenceTest.java | 34 +++++++++ 3 files changed, 110 insertions(+), 5 deletions(-) diff --git a/SequenceAnalysis/resources/queries/sequenceanalysis/sequence_readsets.js b/SequenceAnalysis/resources/queries/sequenceanalysis/sequence_readsets.js index 4556ab827..40718160e 100644 --- a/SequenceAnalysis/resources/queries/sequenceanalysis/sequence_readsets.js +++ b/SequenceAnalysis/resources/queries/sequenceanalysis/sequence_readsets.js @@ -1,11 +1,13 @@ -/* - * Copyright (c) 2012 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ +var triggerHelper = new org.labkey.sequenceanalysis.query.SequenceTriggerHelper(LABKEY.Security.currentUser.id, LABKEY.Security.currentContainer.id); function beforeDelete(row, errors){ if (!this.extraContext.deleteFromServer){ errors._form = 'You cannot directly delete readsets. To delete these records, use the delete button above the readset grid.'; } +} + +function afterInsert(row, errors) { + if (row.sraAccessions) { + triggerHelper.createReaddataForSra(row.rowid, row.sraAccessions); + } } \ No newline at end of file diff --git a/SequenceAnalysis/src/org/labkey/sequenceanalysis/query/SequenceTriggerHelper.java b/SequenceAnalysis/src/org/labkey/sequenceanalysis/query/SequenceTriggerHelper.java index f6eb36e24..13803c667 100644 --- a/SequenceAnalysis/src/org/labkey/sequenceanalysis/query/SequenceTriggerHelper.java +++ b/SequenceAnalysis/src/org/labkey/sequenceanalysis/query/SequenceTriggerHelper.java @@ -13,9 +13,11 @@ import org.biojava.nbio.core.sequence.transcription.TranscriptionEngine; import org.junit.Assert; import org.junit.Test; +import org.labkey.api.assay.AssayFileWriter; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerManager; import org.labkey.api.data.SimpleFilter; +import org.labkey.api.data.Table; import org.labkey.api.data.TableInfo; import org.labkey.api.data.TableSelector; import org.labkey.api.exp.api.DataType; @@ -28,12 +30,19 @@ import org.labkey.api.security.User; import org.labkey.api.security.UserManager; import org.labkey.api.sequenceanalysis.RefNtSequenceModel; +import org.labkey.api.util.FileUtil; +import org.labkey.api.util.Path; +import org.labkey.sequenceanalysis.ReadDataImpl; import org.labkey.sequenceanalysis.SequenceAnalysisSchema; +import org.labkey.sequenceanalysis.SequenceAnalysisServiceImpl; +import org.labkey.sequenceanalysis.SequenceReadsetImpl; +import org.labkey.vfs.FileLike; import java.io.File; import java.io.IOException; import java.io.StringWriter; import java.util.Arrays; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -254,4 +263,64 @@ public int createExpData(String relPath) { return d.getRowId(); } + + public void createReaddataForSra(int readsetId, String sraAccessions) + { + SequenceReadsetImpl rs = SequenceAnalysisServiceImpl.get().getReadset(readsetId, _user); + if (rs == null) + { + throw new IllegalArgumentException("Unable to find readset: " + readsetId); + } + + TableInfo rd = SequenceAnalysisSchema.getTable(SequenceAnalysisSchema.TABLE_READ_DATA); + + String[] tokens = StringUtils.split(sraAccessions, ","); + for (String token : tokens) + { + if (rs.getReadData() != null && !rs.getReadData().isEmpty()) + { + throw new IllegalArgumentException("Did not expect readset to have existing readdata: " + rs.getReadsetId()); + } + + // Create new: + ReadDataImpl rd1 = new ReadDataImpl(); + rd1.setReadset(readsetId); + rd1.setContainer(rs.getContainer()); + rd1.setCreated(new Date()); + rd1.setModified(new Date()); + rd1.setCreatedBy(_user.getUserId()); + rd1.setModifiedBy(_user.getUserId()); + rd1.setSra_accession(token); + rd1.setArchived(true); + + // NOTE: this is a fragile assumption. We might need to eventually query SRA to figure out whether data is paired: + Container c = ContainerManager.getForId(rs.getContainer()); + PipeRoot pr = PipelineService.get().findPipelineRoot(c); + if (pr == null) + { + throw new IllegalStateException("Unable to find pipeline root for: " + c.getPath()); + } + + String folderName = "SequenceImport_" + FileUtil.getTimestamp(); + FileLike outDir = AssayFileWriter.findUniqueFileName(folderName, pr.getRootFileLike()); + + FileLike expectedFile1 = FileUtil.appendPath(outDir, Path.parse(token + "_1.fastq.gz")); + ExpData exp1 = ExperimentService.get().createData(c, new DataType("Data")); + exp1.setDataFileURI(expectedFile1.toURI()); + exp1.setContainer(c); + exp1.setName(expectedFile1.getName()); + exp1.save(_user); + rd1.setFileId1(exp1.getRowId()); + + FileLike expectedFile2 = FileUtil.appendPath(outDir, Path.parse(token + "_2.fastq.gz")); + ExpData exp2 = ExperimentService.get().createData(c, new DataType("Data")); + exp2.setDataFileURI(expectedFile2.toURI()); + exp2.setContainer(c); + exp2.setName(expectedFile2.getName()); + exp2.save(_user); + rd1.setFileId2(exp2.getRowId()); + + Table.insert(_user, rd, rd1); + } + } } diff --git a/SequenceAnalysis/test/src/org/labkey/test/tests/external/labModules/SequenceTest.java b/SequenceAnalysis/test/src/org/labkey/test/tests/external/labModules/SequenceTest.java index e26795289..ccffb43d1 100644 --- a/SequenceAnalysis/test/src/org/labkey/test/tests/external/labModules/SequenceTest.java +++ b/SequenceAnalysis/test/src/org/labkey/test/tests/external/labModules/SequenceTest.java @@ -195,6 +195,28 @@ private void importReadsetMetadata() log("verifying readset count correct"); waitForText("Sequence Readsets"); waitForElement(LabModuleHelper.getNavPanelItem("Sequence Readsets:", _readsetCt.toString())); + + // Repeat, adding SRA accessions: + goToProjectHome(); + waitAndClick(Locator.linkWithText("Plan Sequence Run (Create Readsets)")); + new Window.WindowFinder(getDriver()).withTitle("Create Readsets").waitFor(); + waitAndClickAndWait(Ext4Helper.Locators.ext4Button("Submit")); + + _helper.waitForField("Sample Id", WAIT_FOR_PAGE); + _ext4Helper.clickTabContainingText("Import Spreadsheet"); + waitForText("Copy/Paste Data"); + + setFormElementJS(Locator.name("text"), getIlluminaSRANames()); + + waitAndClick(Ext4Helper.Locators.ext4Button("Upload")); + new Window.WindowFinder(getDriver()).withTitle("Success").waitFor(); + _readsetCt += 3; + assertTextPresent("Success!"); + waitAndClickAndWait(Ext4Helper.Locators.ext4Button("OK")); + + log("verifying readset count correct"); + waitForText("Sequence Readsets"); + waitForElement(LabModuleHelper.getNavPanelItem("Sequence Readsets:", _readsetCt.toString())); } /** @@ -320,6 +342,18 @@ private String getIlluminaNames() return sb.toString(); } + private String getIlluminaSRANames() + { + StringBuilder sb = new StringBuilder("Name\tPlatform\tsraAccessions\n"); + int i = 0; + while (i < 3) + { + sb.append("IlluminaSRA" + (i + 1) + "\tILLUMINA\tSRA" + idx + "\n"); + i++; + } + return sb.toString(); + } + /** * This test will kick off a pipeline import using the illumina pipeline. Verification of the result * is performed by readsetFeaturesTest() From cf218d4d2ad5f1e4bfa232df2950fc66ef684374 Mon Sep 17 00:00:00 2001 From: bbimber Date: Mon, 13 Oct 2025 05:51:36 -0700 Subject: [PATCH 2/6] Test fix --- .../org/labkey/test/tests/external/labModules/SequenceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SequenceAnalysis/test/src/org/labkey/test/tests/external/labModules/SequenceTest.java b/SequenceAnalysis/test/src/org/labkey/test/tests/external/labModules/SequenceTest.java index ccffb43d1..ce837ca52 100644 --- a/SequenceAnalysis/test/src/org/labkey/test/tests/external/labModules/SequenceTest.java +++ b/SequenceAnalysis/test/src/org/labkey/test/tests/external/labModules/SequenceTest.java @@ -348,7 +348,7 @@ private String getIlluminaSRANames() int i = 0; while (i < 3) { - sb.append("IlluminaSRA" + (i + 1) + "\tILLUMINA\tSRA" + idx + "\n"); + sb.append("IlluminaSRA" + (i + 1) + "\tILLUMINA\tSRA" + i + "\n"); i++; } return sb.toString(); From 8250e7e1ec5ee9359270f2a6c1a0f491a47cade6 Mon Sep 17 00:00:00 2001 From: bbimber Date: Mon, 13 Oct 2025 09:17:59 -0700 Subject: [PATCH 3/6] Test fix --- .../resources/queries/sequenceanalysis/sequence_readsets.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SequenceAnalysis/resources/queries/sequenceanalysis/sequence_readsets.js b/SequenceAnalysis/resources/queries/sequenceanalysis/sequence_readsets.js index 40718160e..9c3c14cb4 100644 --- a/SequenceAnalysis/resources/queries/sequenceanalysis/sequence_readsets.js +++ b/SequenceAnalysis/resources/queries/sequenceanalysis/sequence_readsets.js @@ -1,3 +1,5 @@ +var LABKEY = require("labkey"); + var triggerHelper = new org.labkey.sequenceanalysis.query.SequenceTriggerHelper(LABKEY.Security.currentUser.id, LABKEY.Security.currentContainer.id); function beforeDelete(row, errors){ From d76984c2fe235053e4238239924474ad11e1bc4d Mon Sep 17 00:00:00 2001 From: bbimber Date: Mon, 13 Oct 2025 10:46:16 -0700 Subject: [PATCH 4/6] Test fix --- .../labkey/test/tests/external/labModules/SequenceTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SequenceAnalysis/test/src/org/labkey/test/tests/external/labModules/SequenceTest.java b/SequenceAnalysis/test/src/org/labkey/test/tests/external/labModules/SequenceTest.java index ce837ca52..4bba5614a 100644 --- a/SequenceAnalysis/test/src/org/labkey/test/tests/external/labModules/SequenceTest.java +++ b/SequenceAnalysis/test/src/org/labkey/test/tests/external/labModules/SequenceTest.java @@ -214,9 +214,10 @@ private void importReadsetMetadata() assertTextPresent("Success!"); waitAndClickAndWait(Ext4Helper.Locators.ext4Button("OK")); + // This is scoped to this workbook: log("verifying readset count correct"); waitForText("Sequence Readsets"); - waitForElement(LabModuleHelper.getNavPanelItem("Sequence Readsets:", _readsetCt.toString())); + waitForElement(LabModuleHelper.getNavPanelItem("Sequence Readsets:", "3")); } /** From 019a84fbe17aef954c5a836f62a0b23bc93e6aeb Mon Sep 17 00:00:00 2001 From: bbimber Date: Wed, 15 Oct 2025 14:40:10 -0700 Subject: [PATCH 5/6] Test fix --- .../external/labModules/SequenceTest.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/SequenceAnalysis/test/src/org/labkey/test/tests/external/labModules/SequenceTest.java b/SequenceAnalysis/test/src/org/labkey/test/tests/external/labModules/SequenceTest.java index 4bba5614a..d39bca2d7 100644 --- a/SequenceAnalysis/test/src/org/labkey/test/tests/external/labModules/SequenceTest.java +++ b/SequenceAnalysis/test/src/org/labkey/test/tests/external/labModules/SequenceTest.java @@ -217,7 +217,25 @@ private void importReadsetMetadata() // This is scoped to this workbook: log("verifying readset count correct"); waitForText("Sequence Readsets"); - waitForElement(LabModuleHelper.getNavPanelItem("Sequence Readsets:", "3")); + waitAndClickAndWait(LabModuleHelper.getNavPanelItem("Sequence Readsets:", "3")); + + DataRegionTable.DataRegion(getDriver()).withName("query").waitFor(); + + //verify CSV file creation + DataRegionTable.DataRegion(getDriver()).find().goToView("SRA Info"); + DataRegionTable dr = DataRegionTable.DataRegion(getDriver()).withName("query").waitFor(); + waitForElement(Locator.tagContainingText("a", "SRA0")); + waitForElement(Locator.tagContainingText("a", "SRA1")); + waitForElement(Locator.tagContainingText("a", "SRA2")); + + dr.checkAllOnPage(); + doAndWaitForPageToLoad(() -> + { + dr.clickHeaderButton("Delete"); + assertAlert("Are you sure you want to delete the selected rows?"); + }); + + _readsetCt -= 3; } /** From b0da468a290482584a2f85303a05f5eb9de96c74 Mon Sep 17 00:00:00 2001 From: bbimber Date: Wed, 15 Oct 2025 17:34:39 -0700 Subject: [PATCH 6/6] Test fix --- .../test/tests/external/labModules/SequenceTest.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/SequenceAnalysis/test/src/org/labkey/test/tests/external/labModules/SequenceTest.java b/SequenceAnalysis/test/src/org/labkey/test/tests/external/labModules/SequenceTest.java index d39bca2d7..c264ef281 100644 --- a/SequenceAnalysis/test/src/org/labkey/test/tests/external/labModules/SequenceTest.java +++ b/SequenceAnalysis/test/src/org/labkey/test/tests/external/labModules/SequenceTest.java @@ -229,11 +229,8 @@ private void importReadsetMetadata() waitForElement(Locator.tagContainingText("a", "SRA2")); dr.checkAllOnPage(); - doAndWaitForPageToLoad(() -> - { - dr.clickHeaderButton("Delete"); - assertAlert("Are you sure you want to delete the selected rows?"); - }); + dr.clickHeaderButtonAndWait("Delete"); + clickButton("OK"); _readsetCt -= 3; }