seqProduct.put(protein, codon.product);
}
}
+
+ /**
+ * Returns true if a cDNA/Protein mapping either exists, or could be made,
+ * between at least one pair of sequences in the two alignments. Currently,
+ * the logic is:
+ * <ul>
+ * <li>One alignment must be nucleotide, and the other protein</li>
+ * <li>At least one pair of sequences must be already mapped, or mappable</li>
+ * <li>Mappable means the nucleotide translation matches the protein sequence</li>
+ * <li>The translation may ignore start and stop codons if present in the
+ * nucleotide</li>
+ * </ul>
+ *
+ * @param al1
+ * @param al2
+ * @return
+ */
+ public static boolean isMappable(AlignmentI al1, AlignmentI al2)
+ {
+ /*
+ * Require one nucleotide and one protein
+ */
+ if (al1.isNucleotide() == al2.isNucleotide())
+ {
+ return false;
+ }
+ AlignmentI dna = al1.isNucleotide() ? al1 : al2;
+ AlignmentI protein = dna == al1 ? al2 : al1;
+ Set<AlignedCodonFrame> mappings = protein.getCodonFrames();
+ for (SequenceI dnaSeq : dna.getSequences())
+ {
+ for (SequenceI proteinSeq : protein.getSequences())
+ {
+ if (isMappable(dnaSeq, proteinSeq, mappings))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if the dna sequence is mapped, or could be mapped, to the
+ * protein sequence.
+ *
+ * @param dnaSeq
+ * @param proteinSeq
+ * @param mappings
+ * @return
+ */
+ public static boolean isMappable(SequenceI dnaSeq, SequenceI proteinSeq,
+ Set<AlignedCodonFrame> mappings)
+ {
+ SequenceI dnaDs = dnaSeq.getDatasetSequence() == null ? dnaSeq : dnaSeq.getDatasetSequence();
+ SequenceI proteinDs = proteinSeq.getDatasetSequence() == null ? proteinSeq
+ : proteinSeq.getDatasetSequence();
+
+ /*
+ * Already mapped?
+ */
+ for (AlignedCodonFrame mapping : mappings) {
+ if ( proteinDs == mapping.getAaForDnaSeq(dnaDs)) {
+ return true;
+ }
+ }
+
+ /*
+ * Just try to make a mapping (it is not yet stored), test whether
+ * successful.
+ */
+ return mapProteinToCdna(proteinDs, dnaDs) != null;
+ }
}
* If one alignment is protein and one nucleotide, with at least one
* sequence name in common, offer to open a linked alignment.
*/
- if (getAlignment().isNucleotide() != al.isNucleotide())
+ if (AlignmentUtils.isMappable(al, getAlignment()))
{
- // TODO: JAL-845 try a bit harder to link up imported sequences
- final Set<String> sequenceNames = getAlignment().getSequenceNames();
- sequenceNames.retainAll(al.getSequenceNames());
- if (!sequenceNames.isEmpty()) // at least one sequence name in both
+ if (openLinkedAlignment(al, title))
{
- if (openLinkedAlignment(al, title))
- {
- return;
- }
+ return;
}
}
// TODO: JAL-407 regardless of above - identical sequences (based on ID and