- MapList mapping = null;
- if (dna)
- {
- mapping = AlignmentUtils.mapCdnaToProtein(seq, mapFrom);
- }
- else
- {
- mapping = AlignmentUtils.mapCdnaToProtein(mapFrom, seq);
- if (mapping != null)
- {
- mapping = mapping.getInverse();
- }
- }
- if (mapping != null)
- {
- xref.setMap(new Mapping(seq, mapping));
- if (dna)
- {
- AlignmentUtils.computeProteinFeatures(mapFrom, seq, mapping);
- }
- if (dna)
- {
- acf.addMap(mapFrom, seq, mapping);
- }
- else
- {
- acf.addMap(seq, mapFrom, mapping.getInverse());
- }
- continue;
- }
+ constructMapping(mapFrom, seq, xref, acf, fromDna);
+ }
+ }
+ }
+ }
+
+ /**
+ * Tries to make a mapping between sequences. If successful, adds the mapping
+ * to the dbref and the mappings collection and answers true, otherwise
+ * answers false. The following methods of making are mapping are tried in
+ * turn:
+ * <ul>
+ * <li>if 'mapTo' holds a mapping to 'mapFrom', take the inverse; this is, for
+ * example, the case after fetching EMBL cross-references for a Uniprot
+ * sequence</li>
+ * <li>else check if the dna translates exactly to the protein (give or take
+ * start and stop codons></li>
+ * <li>else try to map based on CDS features on the dna sequence</li>
+ * </ul>
+ *
+ * @param mapFrom
+ * @param mapTo
+ * @param xref
+ * @param mappings
+ * @return
+ */
+ boolean constructMapping(SequenceI mapFrom, SequenceI mapTo,
+ DBRefEntry xref, AlignedCodonFrame mappings, boolean fromDna)
+ {
+ MapList mapping = null;
+
+ /*
+ * look for a reverse mapping, if found make its inverse
+ */
+ if (mapTo.getDBRefs() != null)
+ {
+ for (DBRefEntry dbref : mapTo.getDBRefs())
+ {
+ String name = dbref.getSource() + "|" + dbref.getAccessionId();
+ if (dbref.hasMap() && mapFrom.getName().startsWith(name))
+ {
+ /*
+ * looks like we've found a map from 'mapTo' to 'mapFrom'
+ * - invert it to make the mapping the other way
+ */
+ MapList reverse = dbref.getMap().getMap().getInverse();
+ xref.setMap(new Mapping(mapTo, reverse));
+ mappings.addMap(mapFrom, mapTo, reverse);
+ return true;