diff --git a/CHANGELOG b/CHANGELOG index 1849c5b0f..53e89c538 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,14 @@ +MiXCR 3.0.7 (20 May 2019) +======================== + +-- Fixes clone oversplitting in assembleContigs in noizy (e.g. single-cell) data with substanial + fraction of sequences with errors in `CDR3` +-- Fixes wrong alignment-scoring-based filtering in pre-clustering procedure +-- Fixes rare bug in export of imputed gene feature sequences +-- minor: Better error message for mutation extraction from alignment-attached gene features + + MiXCR 3.0.6 (10 Apr 2019) ======================== diff --git a/pom.xml b/pom.xml index a598cb85f..68a6a5f70 100644 --- a/pom.xml +++ b/pom.xml @@ -33,7 +33,7 @@ com.milaboratory mixcr - 3.0.6 + 3.0.7 jar MiXCR diff --git a/src/main/java/com/milaboratory/mixcr/assembler/CloneAssembler.java b/src/main/java/com/milaboratory/mixcr/assembler/CloneAssembler.java index b3745c2cd..0cdd29408 100644 --- a/src/main/java/com/milaboratory/mixcr/assembler/CloneAssembler.java +++ b/src/main/java/com/milaboratory/mixcr/assembler/CloneAssembler.java @@ -694,7 +694,8 @@ public List build() { continue; for (int j = 0; j < 3; j++) { - if (accs[i].getBestScore(GeneType.VJC_REFERENCE[j]) < maxScores[j]) { + if (accs[i].getBestGene(GeneType.VJC_REFERENCE[j]) != null && + accs[i].getBestScore(GeneType.VJC_REFERENCE[j]) < maxScores[j]) { dropped.accept(accs[i]); accs[i] = null; break; diff --git a/src/main/java/com/milaboratory/mixcr/assembler/fullseq/FullSeqAssembler.java b/src/main/java/com/milaboratory/mixcr/assembler/fullseq/FullSeqAssembler.java index 16c416e11..6189b9023 100644 --- a/src/main/java/com/milaboratory/mixcr/assembler/fullseq/FullSeqAssembler.java +++ b/src/main/java/com/milaboratory/mixcr/assembler/fullseq/FullSeqAssembler.java @@ -64,6 +64,7 @@ import static io.repseq.core.GeneType.Variable; /** + * */ public final class FullSeqAssembler { private static int ABSENT_PACKED_VARIANT_INFO = -1; @@ -1518,6 +1519,6 @@ else if (right == -1) } private boolean inSplitRegion(int p) { - return splitRegion == null || splitRegion.contains(p); + return splitRegion != null && splitRegion.contains(p); } } diff --git a/src/main/java/com/milaboratory/mixcr/basictypes/VDJCObject.java b/src/main/java/com/milaboratory/mixcr/basictypes/VDJCObject.java index 1e6b0dce8..714b942fe 100644 --- a/src/main/java/com/milaboratory/mixcr/basictypes/VDJCObject.java +++ b/src/main/java/com/milaboratory/mixcr/basictypes/VDJCObject.java @@ -464,8 +464,11 @@ public CaseSensitiveNucleotideSequence getIncompleteFeature(GeneFeature geneFeat if (lHit == rHit) { Alignment lAl = lHit.getAlignment(lLast.iTarget); if (lAl.getSequence1Range().contains(rPositionInRef)) { - IncompleteSequencePart part = new IncompleteSequencePart(lHit, false, lLast.iTarget, lLast.begin, - aabs(lAl.convertToSeq2Position(rPositionInRef))); + int aabs = aabs(lAl.convertToSeq2Position(rPositionInRef)); + if (aabs < lLast.begin) + return null; + + IncompleteSequencePart part = new IncompleteSequencePart(lHit, false, lLast.iTarget, lLast.begin, aabs); if (part.begin == part.end) leftParts.remove(leftParts.size() - 1); else @@ -481,8 +484,11 @@ public CaseSensitiveNucleotideSequence getIncompleteFeature(GeneFeature geneFeat Alignment rAl = lHit.getAlignment(rLast.iTarget); if (rAl.getSequence1Range().contains(lPositionInRef)) { - IncompleteSequencePart part = new IncompleteSequencePart(rHit, false, rLast.iTarget, - aabs(rAl.convertToSeq2Position(lPositionInRef)), rLast.end); + int aabs = aabs(rAl.convertToSeq2Position(lPositionInRef)); + if (aabs > rLast.end) + return null; + + IncompleteSequencePart part = new IncompleteSequencePart(rHit, false, rLast.iTarget, aabs, rLast.end); if (part.begin == part.end) rightParts.remove(0); else @@ -567,7 +573,7 @@ private static final class IncompleteSequencePart { final int begin, end; IncompleteSequencePart(VDJCHit hit, boolean germline, int iTarget, int begin, int end) { - assert begin <= end; + assert begin <= end : "" + begin + " - " + end; this.hit = hit; this.germline = germline; this.iTarget = iTarget; diff --git a/src/main/java/com/milaboratory/mixcr/cli/Main.java b/src/main/java/com/milaboratory/mixcr/cli/Main.java index 3467fbfea..c2a76a8a2 100644 --- a/src/main/java/com/milaboratory/mixcr/cli/Main.java +++ b/src/main/java/com/milaboratory/mixcr/cli/Main.java @@ -64,18 +64,20 @@ protected List handle(ParseResult parseResult) throws CommandLine.Execut List parsedCommands = parseResult.asCommandLineList(); CommandLine commandLine = parsedCommands.get(parsedCommands.size() - 1); Object command = commandLine.getCommand(); - if (command instanceof CommandSpec && ((CommandSpec) command).userObject() instanceof Runnable) { - try { + try { + if (command instanceof CommandSpec && ((CommandSpec) command).userObject() instanceof Runnable) { ((Runnable) ((CommandSpec) command).userObject()).run(); return new ArrayList<>(); - } catch (ParameterException | CommandLine.ExecutionException ex) { - throw ex; - } catch (Exception ex) { - throw new CommandLine.ExecutionException(commandLine, - "Error while running command (" + command + "): " + ex, ex); } + return super.handle(parseResult); + } catch (ParameterException ex) { + throw ex; + } catch (CommandLine.ExecutionException ex) { + throw ex; + } catch (Exception ex) { + throw new CommandLine.ExecutionException(commandLine, + "Error while running command (" + command + "): " + ex, ex); } - return super.handle(parseResult); } }; diff --git a/src/main/java/com/milaboratory/mixcr/export/FeatureExtractors.java b/src/main/java/com/milaboratory/mixcr/export/FeatureExtractors.java index 272a8844c..18c15c3f0 100644 --- a/src/main/java/com/milaboratory/mixcr/export/FeatureExtractors.java +++ b/src/main/java/com/milaboratory/mixcr/export/FeatureExtractors.java @@ -58,8 +58,6 @@ void validate(GeneFeature[] features) { if (features.length == 2 && !features[1].contains(features[0])) throw new IllegalArgumentException(String.format("%s: Base feature %s does not contain relative feature %s", command, GeneFeature.encode(features[1]), GeneFeature.encode(features[0]))); - - //todo bigfeature nofloating bounds } private String header0(String[] prefixes, GeneFeature[] features) { @@ -122,6 +120,19 @@ void validate(GeneFeature[] features) { if (feature.getGeneType() == null) throw new IllegalArgumentException(String.format("%s: Gene feature %s covers several gene types " + "(not possible to select corresponding alignment)", command, GeneFeature.encode(feature))); + + if (features.length == 2 && features[1].isAlignmentAttached()) + throw new IllegalArgumentException( + String.format( + "%s: Alignment attached base gene features not allowed (error in %s)", + command, GeneFeature.encode(features[1]))); + + if (features.length == 1 && features[0].isAlignmentAttached()) + throw new IllegalArgumentException( + String.format( + "%s: Please use %s option instead and specify base gene feature to extract mutations " + + "from alignment-attached gene feature %s", + command, command + "Relative", GeneFeature.encode(features[0]))); } @Override diff --git a/src/main/java/com/milaboratory/mixcr/export/FieldExtractors.java b/src/main/java/com/milaboratory/mixcr/export/FieldExtractors.java index 967b7681e..43ab3e43a 100644 --- a/src/main/java/com/milaboratory/mixcr/export/FieldExtractors.java +++ b/src/main/java/com/milaboratory/mixcr/export/FieldExtractors.java @@ -664,7 +664,7 @@ protected String extract(VDJCObject object) { }); } - descriptorsList.add(new PL_O("-chains", "Chains", "Chains", "Chains") { + descriptorsList.add(new PL_O("-chains", "Chains", "Chains", "chains") { @Override protected String extract(VDJCObject object) { return object.commonChains().toString(); diff --git a/src/main/resources/parameters/full_seq_assembler_parameters.json b/src/main/resources/parameters/full_seq_assembler_parameters.json index 854d8cf36..dd925fa14 100644 --- a/src/main/resources/parameters/full_seq_assembler_parameters.json +++ b/src/main/resources/parameters/full_seq_assembler_parameters.json @@ -8,7 +8,7 @@ "alignedSequenceEdgeDelta": 3, "alignmentEdgeRegionSize": 7, "minimalNonEdgePointsFraction": 0.25, - "subCloningRegion": "CDR3", + "subCloningRegion": null, "trimmingParameters": { "averageQualityThreshold": 20.0, "windowSize": 8