diff --git a/SequenceAnalysis/api-src/org/labkey/api/sequenceanalysis/pipeline/AlignerIndexUtil.java b/SequenceAnalysis/api-src/org/labkey/api/sequenceanalysis/pipeline/AlignerIndexUtil.java index 39b08ed7f..9f5c1ee20 100644 --- a/SequenceAnalysis/api-src/org/labkey/api/sequenceanalysis/pipeline/AlignerIndexUtil.java +++ b/SequenceAnalysis/api-src/org/labkey/api/sequenceanalysis/pipeline/AlignerIndexUtil.java @@ -5,6 +5,7 @@ import org.labkey.api.data.ConvertHelper; import org.labkey.api.pipeline.PipelineJobException; import org.labkey.api.pipeline.WorkDirectory; +import org.labkey.api.util.FileUtil; import org.labkey.vfs.FileSystemLike; import java.io.File; @@ -85,13 +86,13 @@ private static boolean verifyOrCreateCachedIndex(PipelineContext ctx, @Nullable if (wd != null) { String val = ctx.getJob().getParameters().get(COPY_LOCALLY); - boolean doCopy = forceCopyLocal || (val == null || ConvertHelper.convert(val, Boolean.class)); + boolean doCopy = forceCopyLocal || (val == null || Boolean.TRUE.equals(ConvertHelper.convert(val, Boolean.class))); if (doCopy) { ctx.getLogger().info("copying index files to work location"); - File localSharedDir = new File(wd.getDir().toNioPathForRead().toFile(), "Shared"); - File destination = new File(localSharedDir, localName); + File localSharedDir = FileUtil.appendName(wd.getDir().toNioPathForRead().toFile(), "Shared"); + File destination = FileUtil.appendName(localSharedDir, localName); ctx.getLogger().debug(destination.getPath()); File[] files = webserverIndexDir.listFiles(); if (files == null) @@ -99,6 +100,11 @@ private static boolean verifyOrCreateCachedIndex(PipelineContext ctx, @Nullable return false; } + if (!destination.exists()) + { + FileUtil.mkdirs(destination); + } + destination = wd.inputFile(FileSystemLike.wrapFile(webserverIndexDir), FileSystemLike.wrapFile(destination), true).toNioPathForRead().toFile(); if (output != null && !destination.equals(webserverIndexDir)) { diff --git a/SequenceAnalysis/src/org/labkey/sequenceanalysis/SequenceAnalysisMaintenanceTask.java b/SequenceAnalysis/src/org/labkey/sequenceanalysis/SequenceAnalysisMaintenanceTask.java index a7ab7b1c9..da250d486 100644 --- a/SequenceAnalysis/src/org/labkey/sequenceanalysis/SequenceAnalysisMaintenanceTask.java +++ b/SequenceAnalysis/src/org/labkey/sequenceanalysis/SequenceAnalysisMaintenanceTask.java @@ -272,10 +272,10 @@ else if (sf.getFilePath() == null) return; } - File root = new File(sf.getFilePath()); + File root = new File(sf.getFilePath()).getParentFile(); if (!root.exists()) { - log.error("Run fileroot does not exist: " + runId + " / " + root.getPath()); + log.error("Run file root does not exist. runId: " + runId + " / jobId: " + sf.getRowId() + " / " + root.getPath()); return; } diff --git a/SequenceAnalysis/src/org/labkey/sequenceanalysis/SequenceAnalysisModule.java b/SequenceAnalysis/src/org/labkey/sequenceanalysis/SequenceAnalysisModule.java index 263c966d4..5f867bc01 100644 --- a/SequenceAnalysis/src/org/labkey/sequenceanalysis/SequenceAnalysisModule.java +++ b/SequenceAnalysis/src/org/labkey/sequenceanalysis/SequenceAnalysisModule.java @@ -127,6 +127,7 @@ import org.labkey.sequenceanalysis.run.analysis.SawfishJointCallingHandler; import org.labkey.sequenceanalysis.run.analysis.SequenceBasedTypingAnalysis; import org.labkey.sequenceanalysis.run.analysis.SnpCountAnalysis; +import org.labkey.sequenceanalysis.run.analysis.SpecHlaAnalysis; import org.labkey.sequenceanalysis.run.analysis.SubreadAnalysis; import org.labkey.sequenceanalysis.run.analysis.UnmappedReadExportHandler; import org.labkey.sequenceanalysis.run.analysis.ViralAnalysis; @@ -343,6 +344,7 @@ public static void registerPipelineSteps() SequencePipelineService.get().registerPipelineStep(new PindelAnalysis.Provider()); SequencePipelineService.get().registerPipelineStep(new PbsvAnalysis.Provider()); SequencePipelineService.get().registerPipelineStep(new GenrichStep.Provider()); + SequencePipelineService.get().registerPipelineStep(new SpecHlaAnalysis.Provider()); SequencePipelineService.get().registerPipelineStep(new SawfishAnalysis.Provider()); SequencePipelineService.get().registerPipelineStep(new PARalyzerAnalysis.Provider()); diff --git a/SequenceAnalysis/src/org/labkey/sequenceanalysis/pipeline/TaskFileManagerImpl.java b/SequenceAnalysis/src/org/labkey/sequenceanalysis/pipeline/TaskFileManagerImpl.java index dd1c000b4..424df729e 100644 --- a/SequenceAnalysis/src/org/labkey/sequenceanalysis/pipeline/TaskFileManagerImpl.java +++ b/SequenceAnalysis/src/org/labkey/sequenceanalysis/pipeline/TaskFileManagerImpl.java @@ -32,6 +32,7 @@ import org.labkey.api.util.FileType; import org.labkey.api.util.FileUtil; import org.labkey.api.util.Pair; +import org.labkey.api.util.Path; import org.labkey.api.writer.PrintWriters; import org.labkey.sequenceanalysis.SequenceAnalysisManager; import org.labkey.sequenceanalysis.SequenceAnalysisSchema; @@ -57,6 +58,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; @@ -250,7 +252,7 @@ private SequenceAnalysisJobSupport getSequenceSupport() private File getDeferredDeleteLog(boolean create) { - File logFile = new File(getSupport().getAnalysisDirectory().toNioPathForRead().toFile(), "toDelete.txt"); + File logFile = FileUtil.appendName(getSupport().getAnalysisDirectory().toNioPathForRead().toFile(), "toDelete.txt"); if (create && !logFile.exists()) { try @@ -269,7 +271,7 @@ private File getDeferredDeleteLog(boolean create) private File getMetricsLog(boolean create) { - File logFile = new File(getSupport().getAnalysisDirectory().toNioPathForRead().toFile(), "metricsToCreate.txt"); + File logFile = FileUtil.appendName(getSupport().getAnalysisDirectory().toNioPathForRead().toFile(), "metricsToCreate.txt"); if (create && !logFile.exists()) { try (PrintWriter writer = PrintWriters.getPrintWriter(logFile)) @@ -385,10 +387,10 @@ private File convertRelPathToFile(String line) return null; } - File f = new File(_workLocation, line); + File f = FileUtil.appendPath(_workLocation, Path.parse(line)); if (!f.exists()) { - File test = new File(getSupport().getAnalysisDirectory().toNioPathForRead().toFile(), line); + File test = FileUtil.appendPath(getSupport().getAnalysisDirectory().toNioPathForRead().toFile(), Path.parse(line)); if (test.exists()) { f = test; @@ -859,7 +861,7 @@ private void processCopiedFile(File original, File moved, Collection actions, @Nullable AbstractResume _job.getLogger().debug("discarding copied inputs"); _wd.discardCopiedInputs(); - if (!_wd.getDir().exists()) + if (_wd.getDir().exists()) { - throw new PipelineJobException("work dir does not exist: " + _wd.getDir()); - } - - //NOTE: preserving relative locations is a pain. therefore we copy all outputs, including directories - //then sort out which files were specified as named outputs later - for (File input : _wd.getDir().toNioPathForRead().toFile().listFiles()) - { - if (input.getName().matches("^core.[0-9]+$") || input.getName().endsWith(".hprof")) + //NOTE: preserving relative locations is a pain. therefore we copy all outputs, including directories + //then sort out which files were specified as named outputs later + for (File input : Objects.requireNonNull(_wd.getDir().toNioPathForRead().toFile().listFiles())) { - _job.getLogger().debug("Deleting core/hprof file: " + input.getPath()); - input.delete(); - continue; - } + if (input.getName().matches("^core.[0-9]+$") || input.getName().endsWith(".hprof")) + { + _job.getLogger().debug("Deleting core/hprof file: " + input.getPath()); + input.delete(); + continue; + } - copyFile(input, actions, resumer); + copyFile(input, actions, resumer); + } } } else @@ -987,7 +987,7 @@ private void doCopyFile(File input, Collection actions, @Nullabl } String path = _wd.getRelativePath(FileSystemLike.wrapFile(input)); - File dest = new File(getSupport().getAnalysisDirectory().toNioPathForRead().toFile(), path); + File dest = FileUtil.appendPath(getSupport().getAnalysisDirectory().toNioPathForRead().toFile(), Path.parse(path)); _job.getLogger().debug("to: " + dest.getPath()); boolean doMove = true; @@ -1076,7 +1076,7 @@ private File decompressFile(File i, List actions) //NOTE: we use relative paths in all cases here _job.getLogger().info("Decompressing file: " + i.getPath()); - unzipped = new File(_wd.getDir().toNioPathForRead().toFile(), i.getName().replaceAll(".gz$", "")); + unzipped = FileUtil.appendName(_wd.getDir().toNioPathForRead().toFile(), i.getName().replaceAll(".gz$", "")); unzipped = Compress.decompressGzip(i, unzipped); _job.getLogger().debug("\tunzipped: " + unzipped.getPath()); diff --git a/SequenceAnalysis/src/org/labkey/sequenceanalysis/run/analysis/SpecHlaAnalysis.java b/SequenceAnalysis/src/org/labkey/sequenceanalysis/run/analysis/SpecHlaAnalysis.java new file mode 100644 index 000000000..c7056e5da --- /dev/null +++ b/SequenceAnalysis/src/org/labkey/sequenceanalysis/run/analysis/SpecHlaAnalysis.java @@ -0,0 +1,180 @@ +package org.labkey.sequenceanalysis.run.analysis; + +import htsjdk.samtools.SAMFileHeader; +import org.apache.commons.io.FileUtils; +import org.labkey.api.pipeline.PipelineJobException; +import org.labkey.api.sequenceanalysis.model.AnalysisModel; +import org.labkey.api.sequenceanalysis.model.Readset; +import org.labkey.api.sequenceanalysis.pipeline.AbstractAnalysisStepProvider; +import org.labkey.api.sequenceanalysis.pipeline.AnalysisOutputImpl; +import org.labkey.api.sequenceanalysis.pipeline.AnalysisStep; +import org.labkey.api.sequenceanalysis.pipeline.PipelineContext; +import org.labkey.api.sequenceanalysis.pipeline.PipelineStepProvider; +import org.labkey.api.sequenceanalysis.pipeline.ReferenceGenome; +import org.labkey.api.sequenceanalysis.pipeline.SamSorter; +import org.labkey.api.sequenceanalysis.pipeline.SamtoolsRunner; +import org.labkey.api.sequenceanalysis.pipeline.SequencePipelineService; +import org.labkey.api.sequenceanalysis.run.AbstractCommandPipelineStep; +import org.labkey.api.sequenceanalysis.run.AbstractCommandWrapper; +import org.labkey.api.sequenceanalysis.run.SimpleScriptWrapper; +import org.labkey.api.util.FileUtil; +import org.labkey.api.util.Path; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class SpecHlaAnalysis extends AbstractCommandPipelineStep implements AnalysisStep +{ + public SpecHlaAnalysis(PipelineStepProvider provider, PipelineContext ctx) + { + super(provider, ctx, new SimpleScriptWrapper(ctx.getLogger())); + } + + public static class Provider extends AbstractAnalysisStepProvider + { + public Provider() + { + super("SpecHlaStep", "SpecHLA", null, "This will run SpecHLA for HLA genotyping from WGS/WXS data. This should use a BAM aligned to a custom HLA DB, rather than aligned to the full genome", Arrays.asList( + + ), null, "https://github.com/deepomicslab/SpecHLA/"); + } + + @Override + public SpecHlaAnalysis create(PipelineContext ctx) + { + return new SpecHlaAnalysis(this, ctx); + } + } + + @Override + public Output performAnalysisPerSampleRemote(Readset rs, File inputBam, ReferenceGenome referenceGenome, File outputDir) throws PipelineJobException + { + AnalysisOutputImpl output = new AnalysisOutputImpl(); + + File gzippedFasta = referenceGenome.getWorkingFastaFileGzipped(); + if (!gzippedFasta.exists()) + { + throw new PipelineJobException("Missing file: " + gzippedFasta.getPath()); + } + + File doneFile = FileUtil.appendName(outputDir, FileUtil.getBaseName(inputBam) + ".subset.done"); + output.addIntermediateFile(doneFile); + + File subsetBam = FileUtil.appendName(outputDir, FileUtil.getBaseName(inputBam) + ".subset.bam"); + SamtoolsRunner sr = new SamtoolsRunner(getWrapper().getLogger()); + if (doneFile.exists()) + { + getPipelineCtx().getLogger().debug("Done file exists, skipping samtools view"); + } + else + { + sr.execute(Arrays.asList( + sr.getSamtoolsPath().getPath(), + "view", + "-h", + "-F", "12", //This selects pairs where either mate is mapped + "-T", gzippedFasta.getPath(), + "-o", subsetBam.getPath(), + inputBam.getPath() + )); + } + output.addIntermediateFile(subsetBam); + + File queryNameSortBam = FileUtil.appendName(outputDir, FileUtil.getBaseName(inputBam) + ".querySort.bam"); + if (doneFile.exists()) + { + getPipelineCtx().getLogger().debug("Done file exists, skipping samtools sort"); + } + else + { + new SamSorter(getPipelineCtx().getLogger()).execute(subsetBam, queryNameSortBam, SAMFileHeader.SortOrder.queryname); + } + output.addIntermediateFile(queryNameSortBam); + + File fq1 = FileUtil.appendName(outputDir, FileUtil.getBaseName(inputBam) + ".R1.fastq.gz"); + File fq2 = FileUtil.appendName(outputDir, FileUtil.getBaseName(inputBam) + ".R2.fastq.gz"); + if (doneFile.exists()) + { + getPipelineCtx().getLogger().debug("Done file exists, skipping samtools fastq"); + } + else + { + sr.execute(Arrays.asList( + sr.getSamtoolsPath().getPath(), + "fastq", + "-1", + fq1.getPath(), + "-2", + fq2.getPath(), + queryNameSortBam.getPath() + )); + } + output.addIntermediateFile(fq1); + output.addIntermediateFile(fq2); + + try + { + FileUtils.touch(doneFile); + } + catch (IOException e) + { + throw new PipelineJobException(e); + } + + File specHlaExe = AbstractCommandWrapper.resolveFileInPath("spechla", null, true); + + List toRun = new ArrayList<>(Arrays.asList( + specHlaExe.getPath(), + "-n", + "specHLA", + "-u", + "1", // 1 = exon. 0 = full-length + "-1", + fq1.getPath(), + "-2", + fq2.getPath(), + "-o", + outputDir.getPath() + )); + + Integer maxThreads = SequencePipelineService.get().getMaxThreads(getWrapper().getLogger()); + if (maxThreads != null) + { + toRun.add("-j"); + toRun.add(maxThreads.toString()); + } + + getWrapper().execute(toRun); + + File spechlaDir = FileUtil.appendName(outputDir, "specHLA"); + File outFile = FileUtil.appendName(spechlaDir, "hla.result.txt"); + if (!outFile.exists()) + { + throw new PipelineJobException("SpecHLA result file does not exist: " + outFile.getPath()); + } + + output.addIntermediateFile(spechlaDir); + File copiedFile = FileUtil.appendName(outputDir, outFile.getName()); + try + { + FileUtils.copyFile(outFile, copiedFile); + } + catch (IOException e) + { + throw new PipelineJobException(e); + } + + output.addSequenceOutput(copiedFile, FileUtil.getBaseName(inputBam) + ": HLA Typing", "specHLA Genotyping", rs.getReadsetId(), null, referenceGenome.getGenomeId(), null); + + return output; + } + + @Override + public Output performAnalysisPerSampleLocal(AnalysisModel model, File inputBam, File referenceFasta, File outDir) throws PipelineJobException + { + return null; + } +} diff --git a/jbrowse/package-lock.json b/jbrowse/package-lock.json index 3b549718f..88baf553b 100644 --- a/jbrowse/package-lock.json +++ b/jbrowse/package-lock.json @@ -17,18 +17,18 @@ "@jbrowse/plugin-variants": "^4.1.13", "@jbrowse/product-core": "^4.1.13", "@jbrowse/react-linear-genome-view2": "^4.1.13", - "@labkey/api": "^1.39.0", - "@labkey/components": "^7.16.0", + "@labkey/api": "^1.51.0", + "@labkey/components": "^7.35.0", "@mui/x-data-grid": "^7.28.1", "assert": "^2.1.0", "browserify-zlib": "^0.2.0", "buffer": "^6.0.3", "child_process": "^1.0.2", - "fs": "^0.0.1-security", + "fs": "^0.0.2", "jquery": "^3.7.1", "jspdf": "^4.2.1", "jspdf-autotable": "^5.0.7", - "node-polyfill-webpack-plugin": "4.1.0", + "node-polyfill-webpack-plugin": "^4.1.0", "path-browserify": "^1.0.1", "react": "^18.3.0", "react-data-grid": "7.0.0-beta.46", @@ -38,7 +38,7 @@ "regenerator-runtime": "^0.14.1", "stream-browserify": "^3.0.0", "util": "^0.12.5", - "uuid": "^11.1.0", + "uuid": "^14.0.0", "vm-browserify": "^1.1.2" }, "devDependencies": { @@ -1016,11 +1016,10 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.0.tgz", - "integrity": "sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==", + "version": "7.29.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.4.tgz", + "integrity": "sha512-N7QmZ0xRZfjHOfZeQLJjwgX2zS9pdGHSVl/cjSGlo4dXMqvurfxXDMKY4RqEKzPozV78VMcd0lxyG13mlbKc4w==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", @@ -3604,9 +3603,9 @@ } }, "node_modules/@labkey/api": { - "version": "1.51.0", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/api/-/@labkey/api-1.51.0.tgz", - "integrity": "sha512-pyYXCNbFF3HZQ8KVapcwBl/7cHlVDz0ysPlCRBUQ9czX6s2yLwiho0OWkBd9MpbGVkqGFihbTUsUAU+Y5rz5Pw==" + "version": "1.51.1", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/api/-/@labkey/api-1.51.1.tgz", + "integrity": "sha512-RORsQpToUXkGsZMqMfqW+5d8g3r09s2Pojjz4z66hZR3nXw6K6U7xaXih/+96vFwbJ7BeqUsbv71+5dxX6Bmfg==" }, "node_modules/@labkey/build": { "version": "9.1.0", @@ -3646,12 +3645,12 @@ } }, "node_modules/@labkey/components": { - "version": "7.28.1", - "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-7.28.1.tgz", - "integrity": "sha512-hrSs8iHM2XTpB4vyzerjYVdi0aoE4VUSMusYCNB1SFXcXFR3rExZsZR6aPjkC09Ge+eequOVsHXfM//not+KQA==", + "version": "7.35.1", + "resolved": "https://labkey.jfrog.io/artifactory/api/npm/libs-client/@labkey/components/-/@labkey/components-7.35.1.tgz", + "integrity": "sha512-vsus4L0ocU89Dgb2O585TaHrtpKv9qKWgakVCkj+nlq/Os3A9a9vVXKnnlGh1QmYiPKzjyGtbImokkS5hjO8Yg==", "dependencies": { "@hello-pangea/dnd": "18.0.1", - "@labkey/api": "1.51.0", + "@labkey/api": "1.51.1", "@testing-library/dom": "~10.4.1", "@testing-library/jest-dom": "~6.9.1", "@testing-library/react": "~16.3.2", @@ -7190,10 +7189,9 @@ } }, "node_modules/dompurify": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.3.tgz", - "integrity": "sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA==", - "license": "(MPL-2.0 OR Apache-2.0)", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.2.tgz", + "integrity": "sha512-lHeS9SA/IKeIFFyYciHBr2n0v1VMPlSj843HdLOwjb2OxNwdq9Xykxqhk+FE42MzAdHvInbAolSE4mhahPpjXA==", "optionalDependencies": { "@types/trusted-types": "^2.0.7" } @@ -7573,8 +7571,19 @@ "license": "(MIT AND Zlib)" }, "node_modules/fast-uri": { - "version": "3.0.1", - "license": "MIT" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", + "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ] }, "node_modules/fastest-levenshtein": { "version": "1.0.16", @@ -7704,9 +7713,9 @@ "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", "dev": true, "funding": [ { @@ -7918,8 +7927,9 @@ } }, "node_modules/fs": { - "version": "0.0.1-security", - "license": "ISC" + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.2.tgz", + "integrity": "sha512-YAiVokMCrSIFZiroB1oz51hPiPRVcUtSa4x2U5RYXyhS9VAPdiFigKbPTnOSq7XY8wd3FIVPYmXpo5lMzFmxgg==" }, "node_modules/fs-extra": { "version": "11.3.1", @@ -9466,9 +9476,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", - "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", "dev": true, "funding": [ { @@ -10264,7 +10274,9 @@ } }, "node_modules/postcss": { - "version": "8.4.40", + "version": "8.5.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", + "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", "dev": true, "funding": [ { @@ -10280,11 +10292,10 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -12591,15 +12602,15 @@ } }, "node_modules/uuid": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", - "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz", + "integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], "bin": { - "uuid": "dist/esm/bin/uuid" + "uuid": "dist-node/bin/uuid" } }, "node_modules/vary": { @@ -12618,22 +12629,22 @@ "integrity": "sha512-m6EXlCAMetKztO1ppBhGU1/1MR3IiEevO6ESq6rcrSQ3Q77xYSW13jkfXW88o4xMrkXJhy/U7j4wFR/twMB0Eg==" }, "node_modules/vis-data": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/vis-data/-/vis-data-8.0.3.tgz", - "integrity": "sha512-jhnb6rJNqkKR1Qmlay0VuDXY9ZlvAnYN1udsrP4U+krgZEq7C0yNSKdZqmnCe13mdnf9AdVcdDGFOzy2mpPoqw==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/vis-data/-/vis-data-8.0.4.tgz", + "integrity": "sha512-TsN0sMHqIRpdfg6TNPtfdINpkgxtnQP6JNWCaiSwvou5seXqKiP5eERkaBg+Y56wyJ4FZTeOEs/dEmWEPrpltQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/visjs" }, "peerDependencies": { - "uuid": "^3.4.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^13.0.0", + "uuid": "^3.4.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^13.0.0 || ^14.0.0", "vis-util": ">=6.0.0" } }, "node_modules/vis-network": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/vis-network/-/vis-network-10.0.2.tgz", - "integrity": "sha512-qPl8GLYBeHEFqiTqp4VBbYQIJ2EA8KLr7TstA2E8nJxfEHaKCU81hQLz7hhq11NUpHbMaRzBjW5uZpVKJ45/wA==", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/vis-network/-/vis-network-10.0.3.tgz", + "integrity": "sha512-Sk8qoyY4oi8o5dh8bHsKTTtHi8wWZABbLpH0Ac95ULqVuBIFbMng95QJmEKP8kIQlkjbq3ChJrk1bPmig9Cxig==", "funding": { "type": "opencollective", "url": "https://opencollective.com/visjs" @@ -12642,7 +12653,7 @@ "@egjs/hammerjs": "^2.0.0", "component-emitter": "^1.3.0 || ^2.0.0", "keycharm": "^0.2.0 || ^0.3.0 || ^0.4.0", - "uuid": "^3.4.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^13.0.0", + "uuid": "^3.4.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^13.0.0 || ^14.0.0", "vis-data": ">=8.0.0", "vis-util": ">=6.0.0" } @@ -12936,9 +12947,9 @@ } }, "node_modules/webpack-dev-server": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.3.tgz", - "integrity": "sha512-9Gyu2F7+bg4Vv+pjbovuYDhHX+mqdqITykfzdM9UyKqKHlsE5aAjRhR+oOEfXW5vBeu8tarzlJFIZva4ZjAdrQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.4.tgz", + "integrity": "sha512-GqDPGZN9bRqKBTkp4aWkobDDHMsrXKoGSdOH56smIri8qR0JG8gfL8/v/f/OZR3/OKXjG8uwJbFVhKm/FNU/UA==", "dev": true, "license": "MIT", "dependencies": { diff --git a/jbrowse/package.json b/jbrowse/package.json index 843630364..31c0c43e2 100644 --- a/jbrowse/package.json +++ b/jbrowse/package.json @@ -23,18 +23,18 @@ "@jbrowse/plugin-variants": "^4.1.13", "@jbrowse/product-core": "^4.1.13", "@jbrowse/react-linear-genome-view2": "^4.1.13", - "@labkey/api": "^1.39.0", - "@labkey/components": "^7.16.0", + "@labkey/api": "^1.51.0", + "@labkey/components": "^7.35.0", "@mui/x-data-grid": "^7.28.1", "assert": "^2.1.0", "browserify-zlib": "^0.2.0", "buffer": "^6.0.3", "child_process": "^1.0.2", - "fs": "^0.0.1-security", + "fs": "^0.0.2", "jquery": "^3.7.1", "jspdf": "^4.2.1", "jspdf-autotable": "^5.0.7", - "node-polyfill-webpack-plugin": "4.1.0", + "node-polyfill-webpack-plugin": "^4.1.0", "path-browserify": "^1.0.1", "react": "^18.3.0", "react-data-grid": "7.0.0-beta.46", @@ -44,7 +44,7 @@ "regenerator-runtime": "^0.14.1", "stream-browserify": "^3.0.0", "util": "^0.12.5", - "uuid": "^11.1.0", + "uuid": "^14.0.0", "vm-browserify": "^1.1.2" }, "devDependencies": { diff --git a/jbrowse/src/org/labkey/jbrowse/model/JsonFile.java b/jbrowse/src/org/labkey/jbrowse/model/JsonFile.java index 3dcc8fa32..8cbbaad96 100644 --- a/jbrowse/src/org/labkey/jbrowse/model/JsonFile.java +++ b/jbrowse/src/org/labkey/jbrowse/model/JsonFile.java @@ -654,7 +654,7 @@ private JSONObject getBamOrCramTrack(Logger log, ExpData targetFile, ReferenceGe }}); put("craiLocation", new JSONObject() {{ - if (!new File(targetFile.getFile() + ".bai").exists()) + if (!new File(targetFile.getFile() + ".crai").exists()) { log.error("Track lacks an index: {}, expected: {}", getObjectId(), targetFile.getFile().getPath() + ".crai"); } diff --git a/singlecell/resources/chunks/Functions.R b/singlecell/resources/chunks/Functions.R index 8ce371233..fad2d9ceb 100644 --- a/singlecell/resources/chunks/Functions.R +++ b/singlecell/resources/chunks/Functions.R @@ -107,8 +107,8 @@ saveData <- function(seuratObj, datasetId) { # Write cell barcodes and metadata: metaDf <- seuratObj@meta.data metaDf$cellbarcode <- colnames(seuratObj) - conn <- gzfile(metaDf) - write.table(conn, file = metaFile, quote = T, row.names = F, sep = ',', col.names = T) + conn <- gzfile(metaFile, 'w') + write.table(metaDf, file = conn, quote = T, row.names = F, sep = ',', col.names = T) close(conn) write.table(data.frame(CellBarcode = colnames(seuratObj)), file = barcodeFile, quote = F, row.names = F, sep = ',', col.names = F) } diff --git a/singlecell/resources/chunks/IdentifyAndStoreActiveClonotypes.R b/singlecell/resources/chunks/IdentifyAndStoreActiveClonotypes.R index 9f7d2e9be..46bdb584f 100644 --- a/singlecell/resources/chunks/IdentifyAndStoreActiveClonotypes.R +++ b/singlecell/resources/chunks/IdentifyAndStoreActiveClonotypes.R @@ -16,8 +16,8 @@ for (datasetId in names(seuratObjects)) { seuratObj <- Rdiscvr::DownloadAndAppendTcrClonotypes(seuratObj, allowMissing = TRUE) } - Rdiscvr::IdentifyAndStoreActiveClonotypes(seuratObj, chain = 'TRA', storeStimLevelData = FALSE) - Rdiscvr::IdentifyAndStoreActiveClonotypes(seuratObj, chain = 'TRB') + Rdiscvr::IdentifyAndStoreActiveClonotypes(seuratObj, chain = 'TRA', storeStimLevelData = FALSE, minEDS = minEDS) + Rdiscvr::IdentifyAndStoreActiveClonotypes(seuratObj, chain = 'TRB', minEDS = minEDS) saveData(seuratObj, datasetId) diff --git a/singlecell/src/org/labkey/singlecell/analysis/AbstractSingleCellHandler.java b/singlecell/src/org/labkey/singlecell/analysis/AbstractSingleCellHandler.java index 6e8304383..a7d112298 100644 --- a/singlecell/src/org/labkey/singlecell/analysis/AbstractSingleCellHandler.java +++ b/singlecell/src/org/labkey/singlecell/analysis/AbstractSingleCellHandler.java @@ -1,6 +1,7 @@ package org.labkey.singlecell.analysis; import au.com.bytecode.opencsv.CSVReader; +import htsjdk.samtools.util.IOUtil; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; @@ -938,7 +939,7 @@ public static String getOutputDescription(JSONObject jsonParams, Logger log, Fil File metaTable = CellHashingServiceImpl.get().getMetaTableFromSeurat(seuratObj, false); if (metaTable != null) { - try (CSVReader reader = new CSVReader(Readers.getReader(metaTable), ',')) + try (CSVReader reader = new CSVReader(Readers.getReader(IOUtil.openFileForReading(metaTable)), ',')) { String[] line; diff --git a/singlecell/src/org/labkey/singlecell/pipeline/singlecell/IdentifyAndStoreActiveClonotypes.java b/singlecell/src/org/labkey/singlecell/pipeline/singlecell/IdentifyAndStoreActiveClonotypes.java index f5c67047f..7ce42f8f1 100644 --- a/singlecell/src/org/labkey/singlecell/pipeline/singlecell/IdentifyAndStoreActiveClonotypes.java +++ b/singlecell/src/org/labkey/singlecell/pipeline/singlecell/IdentifyAndStoreActiveClonotypes.java @@ -2,6 +2,7 @@ import org.labkey.api.sequenceanalysis.pipeline.AbstractPipelineStepProvider; import org.labkey.api.sequenceanalysis.pipeline.PipelineContext; +import org.labkey.api.singlecell.pipeline.SeuratToolParameter; import org.labkey.api.singlecell.pipeline.SingleCellStep; import java.util.List; @@ -17,7 +18,9 @@ public static class Provider extends AbstractPipelineStepProvider