Skip to content

Commit

Permalink
Merge branch 'hotfix/v2.1.12'
Browse files Browse the repository at this point in the history
  • Loading branch information
dbolotin committed Aug 22, 2018
2 parents 295f088 + 6689e2a commit 7f76643
Show file tree
Hide file tree
Showing 11 changed files with 132 additions and 111 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@

MiXCR 2.1.12 (22 Aug 2018)
========================

-- Fixes rare inconsistency in behaviour between paired-end and single-end aligners, clone
assembler and partial sequence assembler in respect to target D gene set selection based on the
chains on V, J and C genes (#408)


MiXCR 2.1.11 (15 Jun 2018)
========================

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

<groupId>com.milaboratory</groupId>
<artifactId>mixcr</artifactId>
<version>2.1.11</version>
<version>2.1.12</version>
<packaging>jar</packaging>
<name>MiXCR</name>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,8 @@ Clone create(int id, CloneAccumulator accumulator) {
if (from < to)
hits.put(GeneType.Diversity,
dAligner.align(sequenceToAlign,
VDJCAligner.getPossibleDLoci(hits.get(GeneType.Variable), hits.get(GeneType.Joining)),
VDJCAligner.getPossibleDLoci(hits.get(GeneType.Variable), hits.get(GeneType.Joining),
null),
from, to, indexOfAssemblingFeatureWithD,
assemblingFeatures.length));
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.milaboratory.mixcr.basictypes.ClonalUpdatableParameters;
Expand Down Expand Up @@ -93,25 +94,25 @@ public VJCClonalAlignerParameters getVJCParameters(GeneType geneType) {
}

@JsonProperty("vParameters")
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
@JsonInclude(JsonInclude.Include.NON_NULL)
public VJCClonalAlignerParameters getVParameters() {
return vdcParameters.get(GeneType.Variable);
}

@JsonProperty("jParameters")
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
@JsonInclude(JsonInclude.Include.NON_NULL)
public VJCClonalAlignerParameters getJParameters() {
return vdcParameters.get(GeneType.Joining);
}

@JsonProperty("cParameters")
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
@JsonInclude(JsonInclude.Include.NON_NULL)
public VJCClonalAlignerParameters getCParameters() {
return vdcParameters.get(GeneType.Constant);
}

@JsonProperty("dParameters")
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
@JsonInclude(JsonInclude.Include.NON_NULL)
public DClonalAlignerParameters getDParameters() {
return dParameters;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ protected VDJCAlignmentResult<VDJCMultiRead> process0(VDJCMultiRead input) {
if (vAl == null || jAl == null || singleDAligner == null)
dResult = new VDJCHit[0];
else
dResult = singleDAligner.align(targets[dGeneTarget].getSequence(), getPossibleDLoci(vResult, jResult),
dResult = singleDAligner.align(targets[dGeneTarget].getSequence(), getPossibleDLoci(vResult, jResult, null),
vAl.getSequence2Range().getTo(),
jAl.getSequence2Range().getFrom(),
dGeneTarget, nReads);
Expand Down
84 changes: 77 additions & 7 deletions src/main/java/com/milaboratory/mixcr/vdjaligners/VDJCAligner.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@
package com.milaboratory.mixcr.vdjaligners;

import cc.redberry.pipe.Processor;
import com.milaboratory.core.alignment.batch.AlignmentHit;
import com.milaboratory.core.io.sequence.SequenceRead;
import com.milaboratory.core.io.sequence.SingleRead;
import com.milaboratory.mixcr.basictypes.HasGene;
import com.milaboratory.mixcr.basictypes.VDJCAlignments;
import com.milaboratory.mixcr.basictypes.VDJCHit;
import com.milaboratory.util.HashFunctions;
import com.milaboratory.util.RandomUtil;
import io.repseq.core.Chains;
Expand Down Expand Up @@ -172,12 +173,81 @@ public static VDJCAligner createAligner(VDJCAlignerParameters alignerParameters,
: new VDJCAlignerS(alignerParameters);
}

public static Chains getPossibleDLoci(VDJCHit[] vHits, VDJCHit[] jHits) {
Chains chains = new Chains();
for (VDJCHit h : vHits)
chains = chains.merge(h.getGene().getChains());
for (VDJCHit h : jHits)
chains = chains.merge(h.getGene().getChains());
// public static Chains getPossibleDLoci(VDJCHit[] vHits, VDJCHit[] jHits) {
// Chains chains = new Chains();
// for (VDJCHit h : vHits)
// chains = chains.merge(h.getGene().getChains());
// for (VDJCHit h : jHits)
// chains = chains.merge(h.getGene().getChains());
// return chains;
// }

/*
* Common utility methods
*/

static Chains getVJCommonChains(final HasGene[] vHits, final HasGene[] jHits) {
return getChains(vHits).intersection(getChains(jHits));
}

/**
* Merge chains of all V/D/J/C hits.
*
* Allows null as input.
*/
public static Chains getChains(final HasGene[] hits) {
if (hits == null || hits.length == 0)
return Chains.ALL;
Chains chains = hits[0].getGene().getChains();
for (int i = 1; i < hits.length; i++)
chains = chains.merge(hits[i].getGene().getChains());
return chains;
}

/**
* Calculates possible chains for D gene alignment, in the presence of following V, J and C genes.
*
* Allows nulls as input.
*/
public static Chains getPossibleDLoci(HasGene[] vHits, HasGene[] jHits, HasGene[] cHits) {
Chains intersection = getChains(vHits)
.intersection(getChains(jHits))
.intersection(getChains(cHits));

if (!intersection.isEmpty())
return intersection;

// If intersection is empty, we are working with chimera
// lets calculate all possible D loci by merging
Chains chains = Chains.EMPTY;
if (vHits != null)
for (HasGene h : vHits)
chains = chains.merge(h.getGene().getChains());
if (jHits != null)
for (HasGene h : jHits)
chains = chains.merge(h.getGene().getChains());
if (cHits != null)
for (HasGene h : cHits)
chains = chains.merge(h.getGene().getChains());

return chains;
}

static HasGene[] wrapAlignmentHits(final AlignmentHit<?, VDJCGene>[] hits) {
if (hits == null)
return null;
HasGene[] res = new HasGene[hits.length];
for (int i = 0; i < hits.length; i++)
res[i] = wrapAlignmentHit(hits[i]);
return res;
}

static HasGene wrapAlignmentHit(final AlignmentHit<?, VDJCGene> hit) {
return new HasGene() {
@Override
public VDJCGene getGene() {
return hit.getRecordPayload();
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ public VDJCAlignerAbstract(VDJCAlignerParameters parameters) {
}

VDJCAlignerAbstract(boolean initialized,
VDJCAlignerParameters parameters,
EnumMap<GeneType, List<VDJCGene>> genesToAlign,
List<VDJCGene> usedGenes,
SingleDAligner singleDAligner,
EnumMap<GeneType, HashMap<String, BitArray>> filters,
BatchAlignerWithBaseWithFilter<NucleotideSequence, VDJCGene, AlignmentHit<NucleotideSequence, VDJCGene>> vAligner,
BatchAlignerWithBaseWithFilter<NucleotideSequence, VDJCGene, AlignmentHit<NucleotideSequence, VDJCGene>> jAligner,
BatchAlignerWithBaseWithFilter<NucleotideSequence, VDJCGene, AlignmentHit<NucleotideSequence, VDJCGene>> cAligner) {
VDJCAlignerParameters parameters,
EnumMap<GeneType, List<VDJCGene>> genesToAlign,
List<VDJCGene> usedGenes,
SingleDAligner singleDAligner,
EnumMap<GeneType, HashMap<String, BitArray>> filters,
BatchAlignerWithBaseWithFilter<NucleotideSequence, VDJCGene, AlignmentHit<NucleotideSequence, VDJCGene>> vAligner,
BatchAlignerWithBaseWithFilter<NucleotideSequence, VDJCGene, AlignmentHit<NucleotideSequence, VDJCGene>> jAligner,
BatchAlignerWithBaseWithFilter<NucleotideSequence, VDJCGene, AlignmentHit<NucleotideSequence, VDJCGene>> cAligner) {
super(initialized, parameters, genesToAlign, usedGenes);
this.singleDAligner = singleDAligner;
this.filters = filters;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ PAlignmentHelper alignVThenJ(final Target target) {

boolean vChimera = checkAndEliminateChimera(vAl1, vAl2, GeneType.Variable);

PairedHit[] vHits = extractDoubleHits(vAl1, vAl2);
PairedHit[] vHits = createPairedHits(vAl1, vAl2);

/*
* Step 2: of round of V gene alignment with more precise algorithm
Expand Down Expand Up @@ -433,7 +433,7 @@ PAlignmentHelper alignVThenJ(final Target target) {

boolean jChimera = checkAndEliminateChimera(jAl1, jAl2, GeneType.Joining);

PairedHit[] jHits = extractDoubleHits(jAl1, jAl2);
PairedHit[] jHits = createPairedHits(jAl1, jAl2);

for (PairedHit jHit : jHits) {
if (jHit.hit0 == null) {
Expand Down Expand Up @@ -584,7 +584,7 @@ List<AlignmentHit<NucleotideSequence, VDJCGene>> performJAlignment(
/**
* Converts two AlignmentResults to an array of paired hits (each paired hit for a particular V of J gene)
*/
static PairedHit[] extractDoubleHits(List<AlignmentHit<NucleotideSequence, VDJCGene>>... results) {
static PairedHit[] createPairedHits(List<AlignmentHit<NucleotideSequence, VDJCGene>>... results) {
Map<VDJCGeneId, PairedHit> hits = new HashMap<>();
addHits(hits, results[0], 0);
addHits(hits, results[1], 1);
Expand Down Expand Up @@ -612,28 +612,6 @@ static void addHits(Map<VDJCGeneId, PairedHit> hits,
}
}

static Chains getVJCommonChains(final PairedHit[] vHits, final PairedHit[] jHits) {
return getChains(vHits).intersection(getChains(jHits));
}

static Chains getChains(final PairedHit[] hits) {
if (hits.length == 0)
return Chains.ALL;
Chains chains = hits[0].getGene().getChains();
for (int i = 1; i < hits.length; i++)
chains = chains.merge(hits[i].getGene().getChains());
return chains;
}

static Chains getChains(final VDJCHit[] hits) {
if (hits.length == 0)
return Chains.ALL;
Chains chains = hits[0].getGene().getChains();
for (int i = 1; i < hits.length; i++)
chains = chains.merge(hits[i].getGene().getChains());
return chains;
}

static final PreVDJCHit[] zeroArray = new PreVDJCHit[0];
@SuppressWarnings("unchecked")
static final AlignmentHit<NucleotideSequence, VDJCGene>[] zeroKArray = new AlignmentHit[0];
Expand Down Expand Up @@ -819,39 +797,6 @@ public void filterHits(float minTotalScore, int maxHits) {
}
}

public static Chains getPossibleDLoci(PairedHit[] vHits, PairedHit[] jHits, VDJCHit[] cHits) {
Chains intersection = getChains(vHits)
.intersection(getChains(jHits))
.intersection(getChains(cHits));

if (!intersection.isEmpty())
return intersection;

// If intersection is empty, we are working with chimer
// lets calculate all possible D loci
Chains chains = new Chains();
for (PairedHit h : vHits)
chains = chains.merge(h.getGene().getChains());
for (PairedHit h : jHits)
chains = chains.merge(h.getGene().getChains());
for (VDJCHit h : cHits)
chains = chains.merge(h.getGene().getChains());

return chains;
}

///**
// * Converts array of "internal" PairedHits to a double array of KAlignmentHits to pass this value to a VDJAlignment
// * constructor (VDJAlignmentImmediate).
// */
//@SuppressWarnings("unchecked")
//static AlignmentHit<NucleotideSequence, Allele>[][] toArray(PairedHit[] hits) {
// AlignmentHit<NucleotideSequence, Allele>[][] hitsArray = new AlignmentHit[hits.length][];
// for (int i = 0; i < hits.length; ++i)
// hitsArray[i] = new AlignmentHit[]{hits[i].hit0, hits[i].hit1};
// return hitsArray;
//}

/**
* Calculates normal "sum" score for each hit and sort hits according to this score.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,25 +190,25 @@ public KGeneAlignmentParameters getVJCGeneAlignerParameters(GeneType geneType) {
}

@JsonProperty("vParameters")
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
@JsonInclude(JsonInclude.Include.NON_NULL)
public KGeneAlignmentParameters getVAlignerParameters() {
return getVJCGeneAlignerParameters(GeneType.Variable);
}

@JsonProperty("dParameters")
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
@JsonInclude(JsonInclude.Include.NON_NULL)
public DAlignerParameters getDAlignerParameters() {
return (DAlignerParameters) getGeneAlignerParameters(GeneType.Diversity);
}

@JsonProperty("jParameters")
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
@JsonInclude(JsonInclude.Include.NON_NULL)
public KGeneAlignmentParameters getJAlignerParameters() {
return getVJCGeneAlignerParameters(GeneType.Joining);
}

@JsonProperty("cParameters")
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
@JsonInclude(JsonInclude.Include.NON_NULL)
public KGeneAlignmentParameters getCAlignerParameters() {
return getVJCGeneAlignerParameters(GeneType.Constant);
}
Expand Down
35 changes: 15 additions & 20 deletions src/main/java/com/milaboratory/mixcr/vdjaligners/VDJCAlignerS.java
Original file line number Diff line number Diff line change
Expand Up @@ -338,17 +338,6 @@ public void calculateHits(float minTotalScore, int maxHits) {
public void alignDC() {
NucleotideSequence sequence = target.targets[0].getSequence();

if (singleDAligner != null && hasKVAndJHits()) {
//Alignment of D gene
int from = vResult.get(0).getAlignment().getSequence2Range().getTo(),
to = jResult.get(0).getAlignment().getSequence2Range().getFrom();
List<PreVDJCHit> dResult = from > to ?
Collections.<PreVDJCHit>emptyList() :
singleDAligner.align0(sequence, getPossibleDLoci(), from, to);
dHits = PreVDJCHit.convert(getDGenesToAlign(),
parameters.getFeatureToAlign(GeneType.Diversity), dResult);
}

boolean doCAlignment = cAligner != null;

if (parameters.getAllowNoCDR3PartAlignments())
Expand All @@ -367,6 +356,21 @@ public void alignDC() {
cHits = createHits(res.getHits(), parameters.getFeatureToAlign(GeneType.Constant));
} else
cHits = new VDJCHit[0];

if (singleDAligner != null && hasKVAndJHits()) {
//Alignment of D gene
int from = vResult.get(0).getAlignment().getSequence2Range().getTo(),
to = jResult.get(0).getAlignment().getSequence2Range().getFrom();
List<PreVDJCHit> dResult = from > to ?
Collections.<PreVDJCHit>emptyList() :
singleDAligner.align0(sequence, getPossibleDLoci(
wrapAlignmentHits(vHits),
wrapAlignmentHits(jHits), cHits),
from, to);
dHits = PreVDJCHit.convert(getDGenesToAlign(),
parameters.getFeatureToAlign(GeneType.Diversity), dResult);
}

}

public boolean hasNoKVNorKJHits() {
Expand Down Expand Up @@ -411,15 +415,6 @@ public float sumScore() {
return score;
}

public Chains getPossibleDLoci() {
Chains chains = new Chains();
for (AlignmentHit<NucleotideSequence, VDJCGene> vHit : vResult)
chains = chains.merge(vHit.getRecordPayload().getChains());
for (AlignmentHit<NucleotideSequence, VDJCGene> jHit : jResult)
chains = chains.merge(jHit.getRecordPayload().getChains());
return chains;
}

public VDJCAlignments toVDJCAlignments(long inputId) {
EnumMap<GeneType, VDJCHit[]> hits = new EnumMap<>(GeneType.class);

Expand Down
Loading

0 comments on commit 7f76643

Please sign in to comment.