Skip to content

Commit 043aa41

Browse files
committed
Support bcftools as optional liftover tool
1 parent d177bc4 commit 043aa41

File tree

3 files changed

+124
-7
lines changed

3 files changed

+124
-7
lines changed

SequenceAnalysis/resources/web/SequenceAnalysis/window/LiftoverWindow.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,19 @@ Ext4.define('SequenceAnalysis.window.LiftoverWindow', {
104104
maxValue: 1.0,
105105
value: 0.95,
106106
fieldLabel: 'Min Percent Match',
107-
helpPopup: 'In order to lift to the target genome, the feature must have at least this percent match. Lower this value to be more permissive; however, this risks incorrect liftovers',
107+
helpPopup: 'In order to lift to the target genome, the feature must have at least this percent match. Lower this value to be more permissive; however, this risks incorrect liftovers. This is ignored if using bcftools.',
108108
itemId: 'pctField'
109109
},{
110110
xtype: 'checkbox',
111111
itemId: 'dropGenotypes',
112112
checked: false,
113113
helpPopup: 'If checked, no genotypes will be written to the output file (applies to VCFs only). This can be useful (and necessary) when lifting VCFs with extremely high sample number.',
114114
fieldLabel: 'Drop Genotypes'
115+
},{
116+
xtype: 'checkbox',
117+
itemId: 'useBcfTools',
118+
checked: false,
119+
fieldLabel: 'Use bcftools'
115120
}].concat(SequenceAnalysis.window.OutputHandlerWindow.getCfgForToolParameters(this.toolParameters)),
116121
buttons: [{
117122
text: 'Submit',

SequenceAnalysis/src/org/labkey/sequenceanalysis/analysis/LiftoverHandler.java

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@
2828
import org.labkey.api.sequenceanalysis.pipeline.ReferenceGenome;
2929
import org.labkey.api.sequenceanalysis.pipeline.SequenceAnalysisJobSupport;
3030
import org.labkey.api.sequenceanalysis.pipeline.SequenceOutputHandler;
31+
import org.labkey.api.sequenceanalysis.pipeline.VariantProcessingStep;
3132
import org.labkey.api.sequenceanalysis.run.SelectVariantsWrapper;
3233
import org.labkey.api.util.FileType;
3334
import org.labkey.api.util.FileUtil;
3435
import org.labkey.api.view.ActionURL;
3536
import org.labkey.api.writer.PrintWriters;
3637
import org.labkey.sequenceanalysis.SequenceAnalysisModule;
3738
import org.labkey.sequenceanalysis.pipeline.ProcessVariantsHandler;
39+
import org.labkey.sequenceanalysis.run.util.LiftoverBcfToolsWrapper;
3840
import org.labkey.sequenceanalysis.run.util.LiftoverVcfWrapper;
3941
import org.labkey.sequenceanalysis.util.SequenceUtil;
4042

@@ -49,7 +51,7 @@
4951
/**
5052
* Created by bimber on 8/26/2014.
5153
*/
52-
public class LiftoverHandler implements SequenceOutputHandler<SequenceOutputHandler.SequenceOutputProcessor>
54+
public class LiftoverHandler implements SequenceOutputHandler<SequenceOutputHandler.SequenceOutputProcessor>, VariantProcessingStep.SupportsScatterGather
5355
{
5456
private final FileType _bedFileType = new FileType(".bed", false);
5557
//private FileType _gffFileType = new FileType("gff", false);
@@ -60,6 +62,12 @@ public LiftoverHandler()
6062

6163
}
6264

65+
@Override
66+
public boolean doSortAfterMerge()
67+
{
68+
return true;
69+
}
70+
6371
@Override
6472
public String getName()
6573
{
@@ -167,8 +175,9 @@ public void processFilesRemote(List<SequenceOutputFile> inputFiles, JobContext c
167175
JSONObject params = ctx.getParams();
168176

169177
boolean dropGenotypes = params.optBoolean("dropGenotypes", false);
178+
boolean useBcfTools = params.optBoolean("useBcfTools", false);
170179

171-
Integer chainFileId = params.getInt("chainFileId");
180+
int chainFileId = params.getInt("chainFileId");
172181
File chainFile = ctx.getSequenceSupport().getCachedData(chainFileId);
173182
int targetGenomeId = params.getInt("targetGenomeId");
174183

@@ -217,7 +226,7 @@ else if (_vcfFileType.isType(f.getFile()))
217226
{
218227
ReferenceGenome targetGenome = ctx.getSequenceSupport().getCachedGenome(targetGenomeId);
219228
ReferenceGenome sourceGenome = ctx.getSequenceSupport().getCachedGenome(f.getLibrary_id());
220-
liftOverVcf(ctx, targetGenome, sourceGenome, chainFile, f.getFile(), lifted, unmappedOutput, job, pct, dropGenotypes);
229+
liftOverVcf(ctx, targetGenome, sourceGenome, chainFile, f.getFile(), lifted, unmappedOutput, job, pct, dropGenotypes, useBcfTools);
221230
}
222231
}
223232
catch (Exception e)
@@ -293,7 +302,7 @@ else if (!SequenceUtil.hasLineCount(unmappedOutput))
293302
}
294303
}
295304

296-
public void liftOverVcf(JobContext ctx, ReferenceGenome targetGenome, ReferenceGenome sourceGenome, File chain, File input, File output, @Nullable File unmappedOutput, PipelineJob job, double pct, boolean dropGenotypes) throws IOException, PipelineJobException
305+
public void liftOverVcf(JobContext ctx, ReferenceGenome targetGenome, ReferenceGenome sourceGenome, File chain, File input, File output, @Nullable File unmappedOutput, PipelineJob job, double pct, boolean dropGenotypes, boolean useBcfTools) throws IOException, PipelineJobException
297306
{
298307
File currentVCF = input;
299308
if (dropGenotypes)
@@ -315,8 +324,16 @@ public void liftOverVcf(JobContext ctx, ReferenceGenome targetGenome, ReferenceG
315324
ctx.getFileManager().addIntermediateFile(new File(outputFile.getPath() + ".tbi"));
316325
}
317326

318-
LiftoverVcfWrapper wrapper = new LiftoverVcfWrapper(job.getLogger());
319-
wrapper.doLiftover(currentVCF, chain, targetGenome.getWorkingFastaFile(), unmappedOutput, output, pct);
327+
if (useBcfTools)
328+
{
329+
LiftoverBcfToolsWrapper wrapper = new LiftoverBcfToolsWrapper(job.getLogger());
330+
wrapper.doLiftover(currentVCF, chain, sourceGenome.getWorkingFastaFile(), targetGenome.getWorkingFastaFile(), unmappedOutput, output);
331+
}
332+
else
333+
{
334+
LiftoverVcfWrapper wrapper = new LiftoverVcfWrapper(job.getLogger());
335+
wrapper.doLiftover(currentVCF, chain, targetGenome.getWorkingFastaFile(), unmappedOutput, output, pct);
336+
}
320337

321338
Long mapped = null;
322339
if (output.exists())
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package org.labkey.sequenceanalysis.run.util;
2+
3+
import org.apache.logging.log4j.Logger;
4+
import org.jetbrains.annotations.Nullable;
5+
import org.labkey.api.pipeline.PipelineJobException;
6+
import org.labkey.api.sequenceanalysis.SequenceAnalysisService;
7+
import org.labkey.api.sequenceanalysis.pipeline.SequencePipelineService;
8+
import org.labkey.api.sequenceanalysis.run.PicardWrapper;
9+
10+
import java.io.File;
11+
import java.io.IOException;
12+
import java.util.ArrayList;
13+
import java.util.List;
14+
15+
/**
16+
* Created by bimber on 3/24/2016.
17+
*/
18+
public class LiftoverBcfToolsWrapper extends PicardWrapper
19+
{
20+
public LiftoverBcfToolsWrapper(@Nullable Logger logger)
21+
{
22+
super(logger);
23+
}
24+
25+
public void doLiftover(File inputVcf, File chainFile, File sourceGenomeFasta, File targetGenomeFasta, @Nullable File rejectVcf, File outputVcf) throws PipelineJobException
26+
{
27+
getLogger().info("Liftover VCF (bcftools): " + inputVcf.getPath());
28+
29+
List<String> params = new ArrayList<>();
30+
params.add(SequencePipelineService.get().getExeForPackage("BCFTOOLS", "bcftools").getPath());
31+
params.add("+liftover");
32+
33+
params.add("--no-version");
34+
params.add("-Oz");
35+
36+
Integer threads = SequencePipelineService.get().getMaxThreads(getLogger());
37+
if (threads != null)
38+
{
39+
params.add("--threads");
40+
params.add(threads.toString());
41+
}
42+
43+
params.add("-o");
44+
params.add(outputVcf.getPath());
45+
46+
params.add(inputVcf.getPath());
47+
params.add("--");
48+
49+
params.add("-s");
50+
params.add(sourceGenomeFasta.getPath());
51+
52+
params.add("-f");
53+
params.add(targetGenomeFasta.getPath());
54+
55+
params.add("-c");
56+
params.add(chainFile.getPath());
57+
58+
params.add("--write-src");
59+
params.add("--fix-tags");
60+
61+
if (rejectVcf != null)
62+
{
63+
params.add("--reject");
64+
params.add(rejectVcf.getPath());
65+
66+
params.add("--reject-type");
67+
params.add("z");
68+
}
69+
70+
execute(params);
71+
72+
if (!outputVcf.exists())
73+
{
74+
throw new PipelineJobException("Output file could not be found: " + outputVcf.getPath());
75+
}
76+
77+
if (rejectVcf != null && rejectVcf.exists())
78+
{
79+
try
80+
{
81+
SequenceAnalysisService.get().ensureVcfIndex(rejectVcf, getLogger());
82+
}
83+
catch (IOException e)
84+
{
85+
throw new PipelineJobException(e);
86+
}
87+
}
88+
}
89+
90+
@Override
91+
protected String getToolName()
92+
{
93+
return "LiftoverVcf";
94+
}
95+
}

0 commit comments

Comments
 (0)