JAL-2110 field 'cf' moved to stack
[jalview.git] / src / jalview / analysis / CrossRef.java
index e73912d..288d60e 100644 (file)
@@ -68,11 +68,6 @@ public class CrossRef
   List<SequenceI> rseqs;
 
   /**
-   * mappings constructed
-   */
-  AlignedCodonFrame cf;
-
-  /**
    * Constructor
    * 
    * @param seqs
@@ -145,18 +140,18 @@ public class CrossRef
        * find sequence's direct (dna-to-dna, peptide-to-peptide) xrefs
        */
       DBRefEntry[] lrfs = DBRefUtils.selectDbRefs(fromDna, seq.getDBRefs());
-      List<SequenceI> rseqs = new ArrayList<SequenceI>();
+      List<SequenceI> foundSeqs = new ArrayList<SequenceI>();
 
       /*
        * find sequences in the alignment which xref one of these DBRefs
        * i.e. is xref-ed to a common sequence identifier
        */
-      searchDatasetXrefs(fromDna, seq, lrfs, rseqs, null);
+      searchDatasetXrefs(fromDna, seq, lrfs, foundSeqs, null);
 
       /*
        * add those sequences' (dna-to-peptide or peptide-to-dna) dbref sources
        */
-      for (SequenceI rs : rseqs)
+      for (SequenceI rs : foundSeqs)
       {
         DBRefEntry[] xrs = DBRefUtils
                 .selectDbRefs(!fromDna, rs.getDBRefs());
@@ -213,7 +208,7 @@ public class CrossRef
   {
 
     rseqs = new ArrayList<SequenceI>();
-    cf = new AlignedCodonFrame();
+    AlignedCodonFrame cf = new AlignedCodonFrame();
     matcher = new SequenceIdMatcher(
             dataset.getSequences());
 
@@ -295,12 +290,14 @@ public class CrossRef
               if (fromDna)
               {
                 // map is from dna seq to a protein product
-                cf.addMap(dss, rsq, xref.getMap().getMap());
+                cf.addMap(dss, rsq, xref.getMap().getMap(), xref.getMap()
+                        .getMappedFromId());
               }
               else
               {
                 // map should be from protein seq to its coding dna
-                cf.addMap(rsq, dss, xref.getMap().getMap().getInverse());
+                cf.addMap(rsq, dss, xref.getMap().getMap().getInverse(),
+                        xref.getMap().getMappedFromId());
               }
             }
           }
@@ -336,7 +333,7 @@ public class CrossRef
        */
       if (!sourceRefs.isEmpty())
       {
-        retrieveCrossRef(sourceRefs, seq, xrfs, fromDna);
+        retrieveCrossRef(sourceRefs, seq, xrfs, fromDna, cf);
       }
     }
 
@@ -353,7 +350,7 @@ public class CrossRef
   }
 
   private void retrieveCrossRef(List<DBRefEntry> sourceRefs, SequenceI seq,
-          DBRefEntry[] xrfs, boolean fromDna)
+          DBRefEntry[] xrfs, boolean fromDna, AlignedCodonFrame cf)
   {
     ASequenceFetcher sftch = SequenceFetcherFactory.getSequenceFetcher();
     SequenceI[] retrieved = null;
@@ -621,14 +618,14 @@ public class CrossRef
   void updateDbrefMappings(SequenceI mapFrom, DBRefEntry[] xrefs,
           SequenceI[] retrieved, AlignedCodonFrame acf, boolean fromDna)
   {
-    SequenceIdMatcher matcher = new SequenceIdMatcher(retrieved);
+    SequenceIdMatcher idMatcher = new SequenceIdMatcher(retrieved);
     for (DBRefEntry xref : xrefs)
     {
       if (!xref.hasMap())
       {
         String targetSeqName = xref.getSource() + "|"
                 + xref.getAccessionId();
-        SequenceI[] matches = matcher.findAllIdMatches(targetSeqName);
+        SequenceI[] matches = idMatcher.findAllIdMatches(targetSeqName);
         if (matches == null)
         {
           return;
@@ -705,6 +702,20 @@ public class CrossRef
       return false;
     }
     xref.setMap(new Mapping(mapTo, mapping));
+
+    /*
+     * and add a reverse DbRef with the inverse mapping
+     */
+    if (mapFrom.getDatasetSequence() != null
+            && mapFrom.getDatasetSequence().getSourceDBRef() != null)
+    {
+      DBRefEntry dbref = new DBRefEntry(mapFrom.getDatasetSequence()
+              .getSourceDBRef());
+      dbref.setMap(new Mapping(mapFrom.getDatasetSequence(), mapping
+              .getInverse()));
+      mapTo.addDBRef(dbref);
+    }
+
     if (fromDna)
     {
       AlignmentUtils.computeProteinFeatures(mapFrom, mapTo, mapping);
@@ -728,11 +739,11 @@ public class CrossRef
    *          context was searching from Protein sequences
    * @param sequenceI
    * @param lrfs
-   * @param rseqs
+   * @param foundSeqs
    * @return true if matches were found.
    */
   private boolean searchDatasetXrefs(boolean fromDna, SequenceI sequenceI,
-          DBRefEntry[] lrfs, List<SequenceI> rseqs, AlignedCodonFrame cf)
+          DBRefEntry[] lrfs, List<SequenceI> foundSeqs, AlignedCodonFrame cf)
   {
     boolean found = false;
     if (lrfs == null)
@@ -745,7 +756,7 @@ public class CrossRef
       // add in wildcards
       xref.setVersion(null);
       xref.setMap(null);
-      found |= searchDataset(fromDna, sequenceI, xref, rseqs, cf, false);
+      found |= searchDataset(fromDna, sequenceI, xref, foundSeqs, cf, false);
     }
     return found;
   }
@@ -757,13 +768,13 @@ public class CrossRef
    * @param fromDna
    *          true if context was searching for refs *from* dna sequence, false
    *          if context was searching for refs *from* protein sequence
-   * @param sequenceI
+   * @param fromSeq
    *          a sequence to ignore (start point of search)
    * @param xrf
    *          a cross-reference to try to match
-   * @param rseqs
+   * @param foundSeqs
    *          result list to add to
-   * @param cf
+   * @param mappings
    *          a set of sequence mappings to add to
    * @param direct
    *          - indicates the type of relationship between returned sequences,
@@ -778,8 +789,8 @@ public class CrossRef
    *          </ul>
    * @return true if relationship found and sequence added.
    */
-  boolean searchDataset(boolean fromDna, SequenceI sequenceI,
-          DBRefEntry xrf, List<SequenceI> rseqs, AlignedCodonFrame cf,
+  boolean searchDataset(boolean fromDna, SequenceI fromSeq,
+          DBRefEntry xrf, List<SequenceI> foundSeqs, AlignedCodonFrame mappings,
           boolean direct)
   {
     boolean found = false;
@@ -808,7 +819,7 @@ public class CrossRef
                             + nxt.getDatasetSequence().getDisplayId(true)
                             + ")");
           }
-          if (nxt == sequenceI || nxt == sequenceI.getDatasetSequence())
+          if (nxt == fromSeq || nxt == fromSeq.getDatasetSequence())
           {
             continue;
           }
@@ -840,13 +851,17 @@ public class CrossRef
           // }
           if (!cands.isEmpty())
           {
-            if (!rseqs.contains(nxt))
+            if (!foundSeqs.contains(nxt))
             {
               found = true;
-              rseqs.add(nxt);
-              if (cf != null)
+              foundSeqs.add(nxt);
+              if (mappings != null && !direct)
               {
-                // don't search if we aren't given a codon map object
+                /*
+                 * if the matched sequence has mapped dbrefs to
+                 * protein product / cdna, add equivalent mappings to
+                 * our source sequence
+                 */
                 for (DBRefEntry candidate : cands)
                 {
                   Mapping mapping = candidate.getMap();
@@ -856,23 +871,21 @@ public class CrossRef
                     if (mapping.getTo() != null
                             && map.getFromRatio() != map.getToRatio())
                     {
-                      // get sense of map correct for adding to product
-                      // alignment.
-                      if (fromDna)
+                      /*
+                       * add a mapping, as from dna to peptide sequence
+                       */
+                      if (map.getFromRatio() == 3)
                       {
-                        // map is from dna seq to a protein product
-                        cf.addMap(sequenceI, nxt, map);
+                        mappings.addMap(nxt, fromSeq, map);
                       }
                       else
                       {
-                        // map should be from protein seq to its coding dna
-                        cf.addMap(nxt, sequenceI, map.getInverse());
+                        mappings.addMap(nxt, fromSeq, map.getInverse());
                       }
                     }
                   }
                 }
               }
-              // TODO: add mapping between sequences if necessary
             }
           }
         }