variantPeptides = new HashSet<>();
+ String[] alleles = alls.toUpperCase(Locale.ROOT).split(",");
+ StringBuilder vars = new StringBuilder();
+
+ for (String allele : alleles)
+ {
+ allele = allele.trim().toUpperCase(Locale.ROOT);
+ if (allele.length() > 1 || "-".equals(allele))
{
- // not handling multi-locus variant features
- continue;
+ continue; // multi-locus variant
}
- if (cdsPos != codonPos[0] && cdsPos != codonPos[1]
- && cdsPos != codonPos[2])
+ char[] variantCodon = new char[3];
+ variantCodon[0] = baseCodon[0];
+ variantCodon[1] = baseCodon[1];
+ variantCodon[2] = baseCodon[2];
+
+ /*
+ * poke variant base into canonical codon;
+ * ignore first 'allele' (canonical base)
+ */
+ final int i = cdsPos == codonPos[0] ? 0
+ : (cdsPos == codonPos[1] ? 1 : 2);
+ variantCodon[i] = allele.toUpperCase(Locale.ROOT).charAt(0);
+ if (variantCodon[i] == baseCodon[i])
{
- // e.g. feature on intron within spliced codon!
continue;
}
-
- String alls = (String) sf.getValue(Gff3Helper.ALLELES);
- if (alls == null)
+ String codon = new String(variantCodon);
+ String peptide = ResidueProperties.codonTranslate(codon);
+ boolean synonymous = toResidue == peptide.charAt(0);
+ StringBuilder var = new StringBuilder();
+ if (synonymous)
{
- continue;
+ /*
+ * synonymous variant notation e.g. c.1062C>A(p.=)
+ */
+ var.append("c.").append(String.valueOf(cdsPos))
+ .append(String.valueOf(baseCodon[i])).append(">")
+ .append(String.valueOf(variantCodon[i])).append("(p.=)");
}
- String from3 = StringUtils.toSentenceCase(
- ResidueProperties.aa2Triplet
- .get(String.valueOf(fromResidue)));
-
- /*
- * make a peptide variant for each SNP allele
- * e.g. C,G,T gives variants G and T for base C
- */
- String[] alleles = alls.toUpperCase().split(",");
- for (String allele : alleles)
+ else
{
- allele = allele.trim().toUpperCase();
- if (allele.length() > 1)
- {
- continue; // multi-locus variant
- }
- char[] variantCodon = new char[3];
- variantCodon[0] = baseCodon[0];
- variantCodon[1] = baseCodon[1];
- variantCodon[2] = baseCodon[2];
-
/*
- * poke variant base into canonical codon
+ * missense variant notation e.g. p.Arg355Met
*/
- int i = cdsPos == codonPos[0] ? 0 : (cdsPos == codonPos[1] ? 1 : 2);
- variantCodon[i] = allele.toUpperCase().charAt(0);
- String codon = new String(variantCodon);
- String peptide = ResidueProperties.codonTranslate(codon);
- if (fromResidue != peptide.charAt(0))
+ String to3 = ResidueProperties.STOP.equals(peptide) ? "Ter"
+ : StringUtils.toSentenceCase(
+ ResidueProperties.aa2Triplet.get(peptide));
+ var.append("p.").append(from3).append(String.valueOf(toPosition))
+ .append(to3);
+ }
+ if (!variantPeptides.contains(peptide)) // duplicate consequence
+ {
+ variantPeptides.add(peptide);
+ if (vars.length() > 0)
{
- String to3 = StringUtils.toSentenceCase(
- ResidueProperties.aa2Triplet.get(peptide));
- String var = "p." + from3 + fromPosition + to3;
- if (!vars.contains(var))
- {
- vars.add(var);
- }
+ vars.append(",");
}
+ vars.append(var);
}
}
- return vars;
+ return vars.toString();
+ }
+
+ /**
+ * Answers the name of the linked sequence holding any mapped features
+ *
+ * @return
+ */
+ public String getLinkedSequenceName()
+ {
+ return featureSequence == null ? null : featureSequence.getName();
+ }
+
+ /**
+ * Answers the mapped ranges (as one or more [start, end] positions) which
+ * correspond to the given [begin, end] range of the linked sequence.
+ *
+ *
+ * Example: MappedFeatures with CDS features mapped to peptide
+ * CDS/200-220 gtc aac TGa acGt att AAC tta
+ * mapped to PEP/6-7 WN by mapping [206, 207, 210, 210, 215, 217] to [6, 7]
+ * getMappedPositions(206, 206) should return [6, 6]
+ * getMappedPositions(200, 214) should return [6, 6]
+ * getMappedPositions(210, 215) should return [6, 7]
+ *
+ *
+ * @param begin
+ * @param end
+ * @return
+ */
+ public int[] getMappedPositions(int begin, int end)
+ {
+ MapList map = mapping.getMap();
+ return mapping.to == featureSequence ? map.getOverlapsInFrom(begin, end)
+ : map.getOverlapsInTo(begin, end);
+ }
+
+ /**
+ * Answers true if the linked features are on coding sequence, false if on
+ * peptide
+ *
+ * @return
+ */
+ public boolean isFromCds()
+ {
+ if (mapping.getMap().getFromRatio() == 3)
+ {
+ return mapping.to != featureSequence;
+ }
+ return mapping.to == featureSequence;
}
}