Skip to content

Commit ce24519

Browse files
committed
Add support for KING on VCF files
1 parent 5aaa9d0 commit ce24519

File tree

2 files changed

+147
-0
lines changed

2 files changed

+147
-0
lines changed

SequenceAnalysis/src/org/labkey/sequenceanalysis/SequenceAnalysisModule.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ public static void registerPipelineSteps()
303303
SequencePipelineService.get().registerPipelineStep(new VariantsToTableStep.Provider());
304304
SequencePipelineService.get().registerPipelineStep(new VariantQCStep.Provider());
305305
SequencePipelineService.get().registerPipelineStep(new PlinkPcaStep.Provider());
306+
SequencePipelineService.get().registerPipelineStep(new KingInferenceStep.Provider());
306307
SequencePipelineService.get().registerPipelineStep(new MendelianViolationReportStep.Provider());
307308
SequencePipelineService.get().registerPipelineStep(new SummarizeGenotypeQualityStep.Provider());
308309

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
package org.labkey.sequenceanalysis.run.variant;
2+
3+
import htsjdk.samtools.util.Interval;
4+
import org.apache.commons.io.FileUtils;
5+
import org.apache.logging.log4j.Logger;
6+
import org.labkey.api.pipeline.PipelineJobException;
7+
import org.labkey.api.sequenceanalysis.SequenceAnalysisService;
8+
import org.labkey.api.sequenceanalysis.pipeline.AbstractVariantProcessingStepProvider;
9+
import org.labkey.api.sequenceanalysis.pipeline.PipelineContext;
10+
import org.labkey.api.sequenceanalysis.pipeline.PipelineStepProvider;
11+
import org.labkey.api.sequenceanalysis.pipeline.ReferenceGenome;
12+
import org.labkey.api.sequenceanalysis.pipeline.SequencePipelineService;
13+
import org.labkey.api.sequenceanalysis.pipeline.VariantProcessingStep;
14+
import org.labkey.api.sequenceanalysis.pipeline.VariantProcessingStepOutputImpl;
15+
import org.labkey.api.sequenceanalysis.run.AbstractCommandPipelineStep;
16+
import org.labkey.api.sequenceanalysis.run.AbstractCommandWrapper;
17+
18+
import javax.annotation.Nullable;
19+
import java.io.File;
20+
import java.io.IOException;
21+
import java.util.ArrayList;
22+
import java.util.Arrays;
23+
import java.util.List;
24+
25+
public class KingInferenceStep extends AbstractCommandPipelineStep<KingInferenceStep.KingWrapper> implements VariantProcessingStep
26+
{
27+
public KingInferenceStep(PipelineStepProvider<?> provider, PipelineContext ctx)
28+
{
29+
super(provider, ctx, new KingInferenceStep.KingWrapper(ctx.getLogger()));
30+
}
31+
32+
public static class Provider extends AbstractVariantProcessingStepProvider<KingInferenceStep>
33+
{
34+
public Provider()
35+
{
36+
super("KingInferenceStep", "KING/Relatedness", "", "This will run KING to infer kinship from a VCF", Arrays.asList(
37+
), null, "https://www.kingrelatedness.com/manual.shtml");
38+
}
39+
40+
@Override
41+
public KingInferenceStep create(PipelineContext ctx)
42+
{
43+
return new KingInferenceStep(this, ctx);
44+
}
45+
}
46+
47+
@Override
48+
public Output processVariants(File inputVCF, File outputDirectory, ReferenceGenome genome, @Nullable List<Interval> intervals) throws PipelineJobException
49+
{
50+
VariantProcessingStepOutputImpl output = new VariantProcessingStepOutputImpl();
51+
52+
output.addInput(inputVCF, "Input VCF");
53+
output.addInput(genome.getWorkingFastaFile(), "Reference Genome");
54+
55+
File plinkOut = new File(outputDirectory, "plink");
56+
output.addIntermediateFile(new File(plinkOut.getPath() + ".bed"));
57+
output.addIntermediateFile(new File(plinkOut.getPath() + ".fam"));
58+
output.addIntermediateFile(new File(plinkOut.getPath() + ".bim"));
59+
output.addIntermediateFile(new File(plinkOut.getPath() + ".log"));
60+
output.addIntermediateFile(new File(plinkOut.getPath() + "-temporary.psam"));
61+
62+
PlinkPcaStep.PlinkWrapper plink = new PlinkPcaStep.PlinkWrapper(getPipelineCtx().getLogger());
63+
List<String> plinkArgs = new ArrayList<>();
64+
plinkArgs.add(plink.getExe().getPath());
65+
plinkArgs.add("--vcf");
66+
plinkArgs.add(inputVCF.getPath());
67+
68+
plinkArgs.add("--make-bed");
69+
plinkArgs.add("--allow-extra-chr");
70+
plinkArgs.add("--max-alleles");
71+
plinkArgs.add("2");
72+
73+
plinkArgs.add("--out");
74+
plinkArgs.add(plinkOut.getPath());
75+
76+
Integer threads = SequencePipelineService.get().getMaxThreads(getPipelineCtx().getLogger());
77+
if (threads != null)
78+
{
79+
plinkArgs.add("--threads");
80+
plinkArgs.add(threads.toString());
81+
}
82+
83+
//TODO: consider --memory (in MB)
84+
85+
plink.execute(plinkArgs);
86+
87+
File plinkOutBed = new File(plinkOut.getPath() + ".bed");
88+
if (!plinkOutBed.exists())
89+
{
90+
throw new PipelineJobException("Unable to find file: " + plinkOutBed.getPath());
91+
}
92+
93+
KingWrapper wrapper = new KingWrapper(getPipelineCtx().getLogger());
94+
wrapper.setWorkingDir(outputDirectory);
95+
96+
List<String> kingArgs = new ArrayList<>();
97+
kingArgs.add(wrapper.getExe().getPath());
98+
99+
kingArgs.add("-b");
100+
kingArgs.add(plinkOut.getPath());
101+
102+
kingArgs.add("--prefix");
103+
kingArgs.add(SequenceAnalysisService.get().getUnzippedBaseName(inputVCF.getName()));
104+
105+
kingArgs.add("--kinship");
106+
107+
File kinshipOutput = new File(outputDirectory, SequenceAnalysisService.get().getUnzippedBaseName(inputVCF.getName()) + ".kin");
108+
wrapper.execute(kingArgs);
109+
if (!kinshipOutput.exists())
110+
{
111+
throw new PipelineJobException("Unable to find file: " + kinshipOutput.getPath());
112+
}
113+
114+
File kinshipOutputTxt = new File(kinshipOutput.getPath() + ".txt");
115+
if (kinshipOutputTxt.exists())
116+
{
117+
kinshipOutputTxt.delete();
118+
}
119+
120+
try
121+
{
122+
FileUtils.moveFile(kinshipOutput, kinshipOutputTxt);
123+
}
124+
catch (IOException e)
125+
{
126+
throw new PipelineJobException(e);
127+
}
128+
129+
output.addSequenceOutput(kinshipOutputTxt, "King Relatedness: " + inputVCF.getName(), "KING Relatedness", null, null, genome.getGenomeId(), null);
130+
131+
return output;
132+
}
133+
134+
public static class KingWrapper extends AbstractCommandWrapper
135+
{
136+
public KingWrapper(@Nullable Logger logger)
137+
{
138+
super(logger);
139+
}
140+
141+
public File getExe()
142+
{
143+
return SequencePipelineService.get().getExeForPackage("KINGPATH", "king");
144+
}
145+
}
146+
}

0 commit comments

Comments
 (0)