public static boolean hasAnyOverlap(Variant current, Variant other, Collection<AlternateCoordinate> alts) { if (current.overlapWith(other, true)) { return true; // Important for REF region } return alts.stream().filter(a -> current.overlapWith(a.getChromosome(), a.getStart(), a.getEnd(), true)) .findAny().isPresent(); }
protected void validateAlternate(AlternateCoordinate alt) { if (alt.getChromosome() == null) { throw new IllegalStateException("Chromosome of alt is null: " + alt); } if (alt.getStart() == null) { throw new IllegalStateException("Start of alt is null: " + alt); } if (alt.getEnd() == null) { throw new IllegalStateException("End of alt is null: " + alt); } if (alt.getReference() == null) { throw new IllegalStateException("Reference of alt is null: " + alt); } if (alt.getAlternate() == null) { throw new IllegalStateException("Alternate of alt is null: " + alt); } }
public static boolean isSameVariant(AlternateCoordinate a, AlternateCoordinate b){ return StringUtils.equals(a.getChromosome(), b.getChromosome()) && a.getStart().equals(b.getStart()) && a.getEnd().equals(b.getEnd()) && StringUtils.equals(a.getReference(), b.getReference()) && StringUtils.equals(a.getAlternate(), b.getAlternate()); } }
/** * Create a list of alternates as Integers to speed up the creation of the VariantAlternateRearranger. * * The creation of the VariantAlternateRearranger makes a lot of comparitions among elements from the list of alternates. * Creating a list of hashCodes from the alternates, speeds up significantly the creation of the rearrangers. * @param alternates List of alternates * @return List of hashCodes for each alternate */ private List<Integer> alternatesToHash(List<AlternateCoordinate> alternates) { List<Integer> list = new ArrayList<>(alternates.size()); for (AlternateCoordinate a : alternates) { // list.add(Objects.hash(a.getChromosome(), a.getStart(), a.getEnd(), a.getReference(), a.getAlternate(), a.getType())); int result = 1; result = 31 * result + a.getChromosome().hashCode(); result = 31 * result + a.getStart().hashCode(); result = 31 * result + a.getEnd().hashCode(); result = 31 * result + a.getReference().hashCode(); result = 31 * result + a.getAlternate().hashCode(); result = 31 * result + a.getType().hashCode(); list.add(result); } return list; }
public static boolean hasAnyOverlap(Variant current, Variant other) { if (current.overlapWith(other, true)) { return true; } // SecAlt of query return other.getStudies().stream() .filter( s -> // foreach study s.getSecondaryAlternates().stream() .filter(a -> { // Avoid NPE a = copyAlt(other, a); return current.overlapWith(a.getChromosome(), a.getStart(), a.getEnd(), true); } ) .findAny() .isPresent() ) .findAny() .isPresent(); }
/** * Adjust start/end if a reference base is required due to an empty allele. All variants are checked due to SecAlts. * @param variant {@link Variant} object. * @return Pair<Integer, Integer> The adjusted (or same) start/end position e.g. SV and MNV as SecAlt, INDEL, etc. */ protected Pair<Integer, Integer> adjustedVariantStart(Variant variant) { Integer start = variant.getStart(); Integer end = variant.getEnd(); if (StringUtils.isBlank(variant.getReference()) || StringUtils.isBlank(variant.getAlternate())) { start = start - 1; } for (AlternateCoordinate alternateCoordinate : variant.getStudy(this.studyConfiguration.getStudyName()).getSecondaryAlternates()) { start = Math.min(start, alternateCoordinate.getStart()); end = Math.max(end, alternateCoordinate.getEnd()); if (StringUtils.isBlank(alternateCoordinate.getAlternate()) || StringUtils.isBlank(alternateCoordinate.getReference())) { start = Math.min(start, alternateCoordinate.getStart() - 1); } } return new ImmutablePair<>(start, end); }
public static boolean isInsertion(AlternateCoordinate alt) { return isInsertion(alt.getType(), alt.getStart(), alt.getEnd()); }
public static boolean isSameVariant(Variant a, AlternateCoordinate b){ return StringUtils.equals(a.getChromosome(), b.getChromosome()) && a.getStart().equals(b.getStart()) && a.getEnd().equals(b.getEnd()) && StringUtils.equals(a.getReference(), b.getReference()) && StringUtils.equals(a.getAlternate(), b.getAlternate()); }
public static boolean isDeletion(AlternateCoordinate alt) { return isDeletion(alt.getType(), alt.getStart(), alt.getEnd()); }
private String getSecondaryAlternates(Variant variant, StudyEntry studyEntry) { StringBuilder sb = new StringBuilder(); Iterator<AlternateCoordinate> iterator = studyEntry.getSecondaryAlternates().iterator(); while (iterator.hasNext()) { AlternateCoordinate alt = iterator.next(); sb.append(alt.getChromosome() == null ? variant.getChromosome() : alt.getChromosome()); sb.append(ALTERNATE_COORDINATE_SEPARATOR); sb.append(alt.getStart() == null ? variant.getStart() : alt.getStart()); sb.append(ALTERNATE_COORDINATE_SEPARATOR); sb.append(alt.getEnd() == null ? variant.getEnd() : alt.getEnd()); sb.append(ALTERNATE_COORDINATE_SEPARATOR); sb.append(alt.getReference() == null ? variant.getReference() : alt.getReference()); sb.append(ALTERNATE_COORDINATE_SEPARATOR); sb.append(alt.getAlternate() == null ? variant.getAlternate() : alt.getAlternate()); sb.append(ALTERNATE_COORDINATE_SEPARATOR); sb.append(alt.getType() == null ? variant.getType() : alt.getType()); if (iterator.hasNext()) { sb.append(','); } } return sb.toString(); }
.map(Pair::getValue) .flatMap(Collection::stream) .filter(a -> (start >= a.getStart() && end <= a.getEnd())) .forEach(altSets::add); } else if (this.collapseDeletions && isInsertion(current.getType(), current.getStart(), current.getEnd())) { .filter(a -> { if (isInsertion(a)) { return (start.equals(a.getStart()) && end.equals(a.getEnd()) && (a.getAlternate().equals("*") } else if (this.collapseDeletions && current.getType().equals(VariantType.SNP)) { varToAlts.forEach(p -> p.getValue().stream() .filter(a -> current.overlapWith(a.getChromosome(), a.getStart(), a.getEnd(), true)) .forEach(altSets::add)); } else { if (variant.getType().equals(VariantType.NO_VARIATION) && !alts.isEmpty()) { AlternateCoordinate mainAlternate = alts.get(0); mainAlternate.setStart(Math.max(mainAlternate.getStart(), current.getStart())); mainAlternate.setEnd(Math.min(mainAlternate.getEnd(), current.getEnd()));
public List<String> buildAlleles(Variant variant, Pair<Integer, Integer> adjustedRange) { String reference = variant.getReference(); String alternate = variant.getAlternate(); List<AlternateCoordinate> secAlts = variant.getStudy(this.studyConfiguration.getStudyName()).getSecondaryAlternates(); List<String> alleles = new ArrayList<>(secAlts.size() + 2); Integer origStart = variant.getStart(); Integer origEnd = variant.getEnd(); alleles.add(buildAllele(variant.getChromosome(), origStart, origEnd, reference, adjustedRange)); alleles.add(buildAllele(variant.getChromosome(), origStart, origEnd, alternate, adjustedRange)); secAlts.forEach(alt -> { alleles.add(buildAllele(variant.getChromosome(), alt.getStart(), alt.getEnd(), alt.getAlternate(), adjustedRange)); }); return alleles; }
@Override public List<String> buildAlleles(Variant variant, Pair<Integer, Integer> adjustedRange, Map<Integer, Character> referenceAlleles) { String reference = variant.getReference(); String alternate = variant.getAlternate(); if (variant.getSv() != null && variant.getSv().getType() == StructuralVariantType.TANDEM_DUPLICATION && alternate.equals(VariantBuilder.DUP_ALT)) { alternate = VariantBuilder.DUP_TANDEM_ALT; } if (variant.getType().equals(VariantType.NO_VARIATION)) { return Arrays.asList(reference, "."); } StudyEntry study = getStudy(variant); List<AlternateCoordinate> secAlts = study.getSecondaryAlternates(); List<String> alleles = new ArrayList<>(secAlts.size() + 2); int origStart = variant.getStart(); int origEnd; if (variant.getLength() == Variant.UNKNOWN_LENGTH) { // Variant::getLengthReference would return UNKNOWN_LENGTH, as the reference could have incomplete reference length origEnd = variant.getStart() + variant.getReference().length() - 1; } else { origEnd = variant.getEnd(); } alleles.add(buildAllele(variant.getChromosome(), origStart, origEnd, reference, adjustedRange, referenceAlleles)); alleles.add(buildAllele(variant.getChromosome(), origStart, origEnd, alternate, adjustedRange, referenceAlleles)); secAlts.forEach(alt -> { int alternateStart = alt.getStart() == null ? variant.getStart() : alt.getStart().intValue(); int alternateEnd = alt.getEnd() == null ? variant.getEnd() : alt.getEnd().intValue(); alleles.add(buildAllele(variant.getChromosome(), alternateStart, alternateEnd, alt.getAlternate(), adjustedRange, referenceAlleles)); }); return alleles; }
.filter(a -> { if (a.getType().equals(VariantType.INDEL)) { return current.overlapWith(a.getChromosome(), a.getStart(), a.getEnd(), true); pair.getValue().stream() .filter(a -> start >= a.getStart() && end <= a.getEnd()) .forEach(updateAlt); return pair; return (start.equals(a.getStart()) && end.equals(a.getEnd()) && a.getAlternate().length() >= currAlt.getAlternate().length()
alt.put(ALTERNATES_REF, coordinate.getReference() != null ? coordinate.getReference() : variant.getReference()); alt.put(ALTERNATES_ALT, coordinate.getAlternate()); alt.put(ALTERNATES_START, coordinate.getStart() != null ? coordinate.getStart() : variant.getStart()); alt.put(ALTERNATES_END, coordinate.getEnd() != null ? coordinate.getEnd() : variant.getEnd()); alt.put(ALTERNATES_TYPE, coordinate.getType() != null ? coordinate.getType().toString() : variant.getType().toString());
/** * Adjust start/end if a reference base is required due to an empty allele. All variants are checked due to SecAlts. * @param variant {@link Variant} object. * @param study Study * @return Pair<Integer, Integer> The adjusted (or same) start/end position e.g. SV and MNV as SecAlt, INDEL, etc. */ public static Pair<Integer, Integer> adjustedVariantStart(Variant variant, StudyEntry study, Map<Integer, Character> referenceAlleles) { if (variant.getType().equals(VariantType.NO_VARIATION)) { return new ImmutablePair<>(variant.getStart(), variant.getEnd()); } MutablePair<Integer, Integer> pos = adjustedVariantStart(variant.getStart(), variant.getEnd(), variant.getReference(), variant.getAlternate(), referenceAlleles, null); for (AlternateCoordinate alternateCoordinate : study.getSecondaryAlternates()) { int alternateStart = alternateCoordinate.getStart() == null ? variant.getStart() : alternateCoordinate.getStart().intValue(); int alternateEnd = alternateCoordinate.getEnd() == null ? variant.getEnd() : alternateCoordinate.getEnd().intValue(); String reference = alternateCoordinate.getReference() == null ? variant.getReference() : alternateCoordinate.getReference(); String alternate = alternateCoordinate.getAlternate() == null ? variant.getAlternate() : alternateCoordinate.getAlternate(); adjustedVariantStart(alternateStart, alternateEnd, reference, alternate, referenceAlleles, pos); } return pos; }
private static AlternateCoordinate copyAlt(Variant var, AlternateCoordinate orig) { AlternateCoordinate copy = new AlternateCoordinate(); copy.setChromosome(orig.getChromosome() == null ? var.getChromosome() : orig.getChromosome()); copy.setStart(orig.getStart() == null ? var.getStart() : orig.getStart()); copy.setEnd(orig.getEnd() == null ? var.getEnd() : orig.getEnd()); copy.setReference(orig.getReference() == null ? var.getReference() : orig.getReference()); copy.setAlternate(orig.getAlternate() == null ? var.getAlternate() : orig.getAlternate()); copy.setType(orig.getType() == null ? var.getType() : orig.getType()); return copy; }
public static Variant asVariant(Variant a, AlternateCoordinate altA) { String chr = ObjectUtils.firstNonNull(altA.getChromosome(), a.getChromosome()); Integer start = ObjectUtils.firstNonNull(altA.getStart(), a.getStart()); Integer end = ObjectUtils.firstNonNull(altA.getEnd(), a.getEnd()); String ref = ObjectUtils.firstNonNull(altA.getReference(), a.getReference()); String alt = ObjectUtils.firstNonNull(altA.getAlternate(), a.getAlternate()); VariantType type = ObjectUtils.firstNonNull(altA.getType(), a.getType()); try { Variant variant = new Variant(chr, start, end, ref, alt); variant.setType(type); return variant; } catch (IllegalArgumentException e) { String msg = altA + "\n" + a.toJson() + "\n"; throw new IllegalStateException(msg, e); } }