JAL-1705 refactoring etc for fetching Ensembl --> Uniprot
[jalview.git] / src / jalview / analysis / CrossRef.java
index 2f6076a..7d09a3b 100644 (file)
@@ -30,6 +30,7 @@ import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.util.DBRefUtils;
+import jalview.util.MapList;
 import jalview.ws.SequenceFetcher;
 import jalview.ws.seqfetcher.ASequenceFetcher;
 
@@ -232,8 +233,9 @@ public class CrossRef
    *          are found e.g. alternative protein products for a protein's gene
    * @return products (as dataset sequences)
    */
-  public static Alignment findXrefSequences(SequenceI[] seqs, boolean dna,
-          String source, AlignmentI al, List<SequenceI> addedPeers)
+  public static Alignment findXrefSequences(SequenceI[] seqs,
+          final boolean dna, final String source, AlignmentI al,
+          List<SequenceI> addedPeers)
   {
     AlignmentI dataset = al.getDataset() == null ? al : al.getDataset();
     List<SequenceI> rseqs = new ArrayList<SequenceI>();
@@ -294,7 +296,9 @@ public class CrossRef
           // xrefs on this sequence.
           if (dataset != null)
           {
-            found |= searchDataset(dss, xref, dataset, rseqs, cf); // ,false,!dna);
+            found |= searchDataset(dss, xref, dataset, rseqs, cf, false,
+                    !dna);
+            // ,false,!dna);
             if (found)
             {
               xrfs[r] = null; // we've recovered seqs for this one.
@@ -355,6 +359,8 @@ public class CrossRef
 
             if (retrieved != null)
             {
+              updateDbrefMappings(dna, seq, xrfs, retrieved, cf);
+
               List<SequenceFeature> copiedFeatures = new ArrayList<SequenceFeature>();
               CrossRef me = new CrossRef();
               for (int rs = 0; rs < retrieved.length; rs++)
@@ -463,6 +469,69 @@ public class CrossRef
   }
 
   /**
+   * Updates any empty mappings in the cross-references with one to a compatible
+   * retrieved sequence if found, and adds any new mappings to the
+   * AlignedCodonFrame
+   * 
+   * @param dna
+   * @param mapFrom
+   * @param xrefs
+   * @param retrieved
+   * @param acf
+   */
+  static void updateDbrefMappings(boolean dna, SequenceI mapFrom,
+          DBRefEntry[] xrefs, SequenceI[] retrieved, AlignedCodonFrame acf)
+  {
+    SequenceIdMatcher matcher = new SequenceIdMatcher(retrieved);
+    for (DBRefEntry xref : xrefs)
+    {
+      if (!xref.hasMap())
+      {
+        String targetSeqName = xref.getSource() + "|"
+                + xref.getAccessionId();
+        SequenceI[] matches = matcher.findAllIdMatches(targetSeqName);
+        if (matches == null)
+        {
+          return;
+        }
+        for (SequenceI seq : matches)
+        {
+          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;
+          }
+        }
+      }
+    }
+  }
+
+  /**
    * find references to lrfs in the cross-reference set of each sequence in
    * dataset (that is not equal to sequenceI) Identifies matching DBRefEntry
    * based on source and accession string only - Map and Version are nulled.