/** * Is this deletion a LOF? * * <p>Criteria: 1) First (coding) exon deleted 2) More than 50% of coding sequence deleted * * @param changeEffect * @return */ protected boolean isLofDeletion(ChangeEffect changeEffect) { Transcript tr = changeEffect.getTranscript(); if (tr == null) throw new RuntimeException("Transcript not found for change:\n\t" + changeEffect); // --- // Criteria: // 1) First (coding) exon deleted // --- if (changeEffect.getEffectType() == EffectType.EXON_DELETED) { Variant seqChange = changeEffect.getSeqChange(); if (seqChange == null) throw new RuntimeException("Cannot retrieve 'seqChange' from EXON_DELETED effect!"); if (seqChange.includes(tr.getFirstCodingExon())) return true; } // --- // Criteria: // 2) More than 50% of coding sequence deleted // --- // Find coding part of the transcript (i.e. no UTRs) Variant seqChange = changeEffect.getSeqChange(); int cdsStart = tr.isStrandPlus() ? tr.getCdsStart() : tr.getCdsEnd(); int cdsEnd = tr.isStrandPlus() ? tr.getCdsEnd() : tr.getCdsStart(); Marker coding = new Marker(seqChange.getChromosome(), cdsStart, cdsEnd, 1, ""); // Create an interval intersecting the CDS and the deletion int start = Math.max(cdsStart, seqChange.getStart()); int end = Math.min(cdsEnd, seqChange.getEnd()); if (start >= end) return false; // No intersections with coding part of the exon? => not LOF Marker codingDeleted = new Marker(seqChange.getChromosome(), start, end, 1, ""); // Count: // - number of coding bases deleted // - number of coding bases int codingBasesDeleted = 0, codingBases = 0; for (Exon exon : tr) { codingBasesDeleted += codingDeleted.intersectSize(exon); codingBases += coding.intersectSize(exon); } // More than a threshold? => It is a LOF double percDeleted = codingBasesDeleted / ((double) codingBases); return (percDeleted > deleteProteinCodingBases); }