enable mouseover between DNA coding regions and translated peptide location and broad...
authorjprocter <Jim Procter>
Sun, 17 Jun 2007 13:04:30 +0000 (13:04 +0000)
committerjprocter <Jim Procter>
Sun, 17 Jun 2007 13:04:30 +0000 (13:04 +0000)
src/jalview/structure/StructureSelectionManager.java
src/jalview/structure/VamsasListener.java [new file with mode: 0644]

index cf5054d..b07b7a4 100644 (file)
@@ -28,7 +28,9 @@ import jalview.datamodel.*;
 public class StructureSelectionManager
 {
   static StructureSelectionManager instance;
+
   StructureMapping[] mappings;
+
   Hashtable mappingData = new Hashtable();
 
   public static StructureSelectionManager getStructureSelectionManager()
@@ -41,7 +43,37 @@ public class StructureSelectionManager
     return instance;
   }
 
+  /**
+   * flag controlling whether SeqMappings are relayed from received sequence
+   * mouse over events to other sequences
+   */
+  boolean relaySeqMappings = true;
+
+  /**
+   * Enable or disable relay of seqMapping events to other sequences. You might
+   * want to do this if there are many sequence mappings and the host computer
+   * is slow
+   * 
+   * @param relay
+   */
+  public void setRelaySeqMappings(boolean relay)
+  {
+    relaySeqMappings = relay;
+  }
+
+  /**
+   * get the state of the relay seqMappings flag.
+   * 
+   * @return true if sequence mouse overs are being relayed to other mapped
+   *         sequences
+   */
+  public boolean isRelaySeqMappingsEnabled()
+  {
+    return relaySeqMappings;
+  }
+
   Vector listeners = new Vector();
+
   public void addStructureViewerListener(Object svl)
   {
     if (!listeners.contains(svl))
@@ -66,21 +98,17 @@ public class StructureSelectionManager
   }
 
   /*
-     There will be better ways of doing this in the future, for now we'll use
-     the tried and tested MCview pdb mapping
+   * There will be better ways of doing this in the future, for now we'll use
+   * the tried and tested MCview pdb mapping
    */
-  synchronized public MCview.PDBfile setMapping(
-      SequenceI[] sequence,
-      String[] targetChains,
-      String pdbFile,
-      String protocol)
+  synchronized public MCview.PDBfile setMapping(SequenceI[] sequence,
+          String[] targetChains, String pdbFile, String protocol)
   {
     MCview.PDBfile pdb = null;
     try
     {
       pdb = new MCview.PDBfile(pdbFile, protocol);
-    }
-    catch (Exception ex)
+    } catch (Exception ex)
     {
       ex.printStackTrace();
       return null;
@@ -89,17 +117,16 @@ public class StructureSelectionManager
     String targetChain;
     for (int s = 0; s < sequence.length; s++)
     {
-      if(targetChains!=null && targetChains[s]!=null)
+      if (targetChains != null && targetChains[s] != null)
         targetChain = targetChains[s];
       else if (sequence[s].getName().indexOf("|") > -1)
       {
         targetChain = sequence[s].getName().substring(
-            sequence[s].getName().lastIndexOf("|") + 1);
+                sequence[s].getName().lastIndexOf("|") + 1);
       }
       else
         targetChain = "";
 
-
       int max = -10;
       AlignSeq maxAlignseq = null;
       String maxChainId = " ";
@@ -107,16 +134,14 @@ public class StructureSelectionManager
 
       for (int i = 0; i < pdb.chains.size(); i++)
       {
-        AlignSeq as = new AlignSeq(sequence[s],
-                                   ( (PDBChain) pdb.chains.elementAt(i)).
-                                   sequence,
-                                   AlignSeq.PEP);
+        AlignSeq as = new AlignSeq(sequence[s], ((PDBChain) pdb.chains
+                .elementAt(i)).sequence, AlignSeq.PEP);
         as.calcScoreMatrix();
         as.traceAlignment();
-        PDBChain chain = ( (PDBChain) pdb.chains.elementAt(i));
+        PDBChain chain = ((PDBChain) pdb.chains.elementAt(i));
 
         if (as.maxscore > max
-            || (as.maxscore == max && chain.id.equals(targetChain)))
+                || (as.maxscore == max && chain.id.equals(targetChain)))
         {
           maxChain = chain;
           max = as.maxscore;
@@ -126,12 +151,10 @@ public class StructureSelectionManager
       }
 
       final StringBuffer mappingDetails = new StringBuffer();
-      mappingDetails.append("\n\nPDB Sequence is :\nSequence = " +
-                            maxChain.sequence.getSequenceAsString());
-      mappingDetails.append("\nNo of residues = " +
-                            maxChain.residues.
-                            size() +
-                            "\n\n");
+      mappingDetails.append("\n\nPDB Sequence is :\nSequence = "
+              + maxChain.sequence.getSequenceAsString());
+      mappingDetails.append("\nNo of residues = "
+              + maxChain.residues.size() + "\n\n");
       PrintStream ps = new PrintStream(System.out)
       {
         public void print(String x)
@@ -147,12 +170,11 @@ public class StructureSelectionManager
 
       maxAlignseq.printAlignment(ps);
 
-      mappingDetails.append("\nPDB start/end " + maxAlignseq.seq2start + " " +
-                            maxAlignseq.seq2end);
+      mappingDetails.append("\nPDB start/end " + maxAlignseq.seq2start
+              + " " + maxAlignseq.seq2end);
       mappingDetails.append("\nSEQ start/end "
-                            + (maxAlignseq.seq1start + sequence[s].getStart() - 1) +
-                            " "
-                            + (maxAlignseq.seq1end + sequence[s].getEnd() - 1));
+              + (maxAlignseq.seq1start + sequence[s].getStart() - 1) + " "
+              + (maxAlignseq.seq1end + sequence[s].getEnd() - 1));
 
       maxChain.makeExactMapping(maxAlignseq, sequence[s]);
 
@@ -162,20 +184,18 @@ public class StructureSelectionManager
       int resNum = -10000;
       int index = 0;
 
-
       do
       {
         Atom tmp = (Atom) maxChain.atoms.elementAt(index);
         if (resNum != tmp.resNumber && tmp.alignmentMapping != -1)
         {
           resNum = tmp.resNumber;
-          mapping[tmp.alignmentMapping+1][0] = tmp.resNumber;
-          mapping[tmp.alignmentMapping+1][1] = tmp.atomIndex;
+          mapping[tmp.alignmentMapping + 1][0] = tmp.resNumber;
+          mapping[tmp.alignmentMapping + 1][1] = tmp.atomIndex;
         }
 
         index++;
-      }
-      while(index < maxChain.atoms.size());
+      } while (index < maxChain.atoms.size());
 
       if (mappings == null)
       {
@@ -188,15 +208,15 @@ public class StructureSelectionManager
         mappings = tmp;
       }
 
-      if(protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
-        pdbFile = "INLINE"+pdb.id;
+      if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
+        pdbFile = "INLINE" + pdb.id;
 
-      mappings[mappings.length - 1]
-          = new StructureMapping(sequence[s], pdbFile, pdb.id, maxChainId,
-                                 mapping, mappingDetails.toString());
-      maxChain.transferResidueAnnotation(mappings[mappings.length-1]);
+      mappings[mappings.length - 1] = new StructureMapping(sequence[s],
+              pdbFile, pdb.id, maxChainId, mapping, mappingDetails
+                      .toString());
+      maxChain.transferResidueAnnotation(mappings[mappings.length - 1]);
     }
-    /////////
+    // ///////
 
     return pdb;
   }
@@ -221,7 +241,7 @@ public class StructureSelectionManager
       }
     }
 
-    if (removeMapping && mappings!=null)
+    if (removeMapping && mappings != null)
     {
       Vector tmp = new Vector();
       for (int i = 0; i < mappings.length; i++)
@@ -239,37 +259,44 @@ public class StructureSelectionManager
 
   public void mouseOverStructure(int pdbResNum, String chain, String pdbfile)
   {
-    SequenceListener sl;
-    SearchResults results = new SearchResults();
+    SearchResults results = null;
     for (int i = 0; i < listeners.size(); i++)
     {
       if (listeners.elementAt(i) instanceof SequenceListener)
       {
-
-        for (int j = 0; j < mappings.length; j++)
+        if (results == null)
         {
-          if (mappings[j].pdbfile.equals(pdbfile) &&
-              mappings[j].pdbchain.equals(chain))
+          results = new SearchResults();
+
+          for (int j = 0; j < mappings.length; j++)
           {
-            results.addResult(mappings[j].sequence,
-               mappings[j].getSeqPos(pdbResNum),
-               mappings[j].getSeqPos(pdbResNum)
-              );
+            if (mappings[j].pdbfile.equals(pdbfile)
+                    && mappings[j].pdbchain.equals(chain))
+            {
+              results.addResult(mappings[j].sequence, mappings[j]
+                      .getSeqPos(pdbResNum), mappings[j]
+                      .getSeqPos(pdbResNum));
+            }
           }
         }
-
-        if(results.getSize()>0)
+        if (results.getSize() > 0)
         {
-          ( (SequenceListener) listeners.elementAt(i))
-              .highlightSequence(results);
+          ((SequenceListener) listeners.elementAt(i))
+                  .highlightSequence(results);
         }
 
       }
     }
   }
 
+  Vector seqmappings = null; // should be a simpler list of mapped seuqence
+
+  // pairs
+
   public void mouseOverSequence(SequenceI seq, int index)
   {
+    boolean hasSequenceListeners = handlingVamsasMo || seqmappings != null;
+    SearchResults results = null;
     StructureListener sl;
     int atomNo = 0;
     for (int i = 0; i < listeners.size(); i++)
@@ -286,75 +313,126 @@ public class StructureSelectionManager
 
             if (atomNo > 0)
             {
-              sl.highlightAtom(atomNo,
-                               mappings[j].getPDBResNum(index),
-                               mappings[j].pdbchain,
-                               mappings[j].pdbfile);
+              sl.highlightAtom(atomNo, mappings[j].getPDBResNum(index),
+                      mappings[j].pdbchain, mappings[j].pdbfile);
             }
           }
         }
       }
-    }
-  }
-
-  public Annotation[] colourSequenceFromStructure(SequenceI seq, String pdbid)
-  {
-    return null;
-    //THIS WILL NOT BE AVAILABLE IN JALVIEW 2.3,
-    //UNTIL THE COLOUR BY ANNOTATION IS REWORKED
-   /* Annotation [] annotations = new Annotation[seq.getLength()];
-
-    StructureListener sl;
-    int atomNo = 0;
-    for (int i = 0; i < listeners.size(); i++)
-    {
-      if (listeners.elementAt(i) instanceof StructureListener)
+      else
       {
-        sl = (StructureListener) listeners.elementAt(i);
-
-        for (int j = 0; j < mappings.length; j++)
+        if (relaySeqMappings && hasSequenceListeners
+                && listeners.elementAt(i) instanceof SequenceListener)
         {
+          // DEBUG 
+          //System.err.println("relay Seq " + seq.getDisplayId(false) + " " +
+          //  index);
 
-          if (mappings[j].sequence == seq
-              && mappings[j].getPdbId().equals(pdbid)
-              && mappings[j].pdbfile.equals(sl.getPdbFile()))
+          if (results == null)
           {
-            System.out.println(pdbid+" "+mappings[j].getPdbId()
-                +" "+mappings[j].pdbfile);
-
-            java.awt.Color col;
-            for(int index=0; index<seq.getLength(); index++)
+            results = new SearchResults();
+            if (index >= seq.getStart() && index <= seq.getEnd())
             {
-              if(jalview.util.Comparison.isGap(seq.getCharAt(index)))
-                continue;
+              // construct highlighted sequence list
 
-              atomNo = mappings[j].getAtomNum(seq.findPosition(index));
-              col = java.awt.Color.white;
-              if (atomNo > 0)
+              if (seqmappings!=null)
               {
-                col = sl.getColour(atomNo,
-                                 mappings[j].getPDBResNum(index),
-                                 mappings[j].pdbchain,
-                                 mappings[j].pdbfile);
-              }
+                Enumeration e = seqmappings.elements();
+                while (e.hasMoreElements())
 
-              annotations[index] = new Annotation("X",null,' ',0,col);
+                {
+                  ((AlignedCodonFrame) e.nextElement()).markMappedRegion(
+                          seq, index, results);
+                }
+              }
+              // hasSequenceListeners = results.getSize() > 0;
+              if (handlingVamsasMo)
+              {
+                // add in additional direct sequence and/or dataset sequence
+                // highlighting
+                results.addResult(seq, index, index);
+              }
             }
-            return annotations;
           }
+          if (hasSequenceListeners)
+          {
+            ((SequenceListener) listeners.elementAt(i))
+                    .highlightSequence(results);
+          }
+        }
+        else if (listeners.elementAt(i) instanceof VamsasListener
+                && !handlingVamsasMo)
+        {
+          // DEBUG 
+          //System.err.println("Vamsas from Seq " + seq.getDisplayId(false) + " " +
+          // index);
+          // pass the mouse over onto the VamsasListener(s)
+          ((VamsasListener) listeners.elementAt(i)).mouseOver(seq, index);
         }
       }
     }
+  }
+
+  /**
+   * true if a mouse over event from an external (ie Vamsas) source is being
+   * handled
+   */
+  boolean handlingVamsasMo = false;
 
-    return annotations;*/
+  /**
+   * as mouseOverSequence but only route event to SequenceListeners
+   * 
+   * @param sequenceI
+   * @param position
+   */
+  public void mouseOverVamsasSequence(SequenceI sequenceI, int position)
+  {
+    handlingVamsasMo = true;
+    mouseOverSequence(sequenceI, position);
+    handlingVamsasMo = false;
   }
 
+  public Annotation[] colourSequenceFromStructure(SequenceI seq,
+          String pdbid)
+  {
+    return null;
+    // THIS WILL NOT BE AVAILABLE IN JALVIEW 2.3,
+    // UNTIL THE COLOUR BY ANNOTATION IS REWORKED
+    /*
+     * Annotation [] annotations = new Annotation[seq.getLength()];
+     * 
+     * StructureListener sl; int atomNo = 0; for (int i = 0; i <
+     * listeners.size(); i++) { if (listeners.elementAt(i) instanceof
+     * StructureListener) { sl = (StructureListener) listeners.elementAt(i);
+     * 
+     * for (int j = 0; j < mappings.length; j++) {
+     * 
+     * if (mappings[j].sequence == seq && mappings[j].getPdbId().equals(pdbid) &&
+     * mappings[j].pdbfile.equals(sl.getPdbFile())) { System.out.println(pdbid+"
+     * "+mappings[j].getPdbId() +" "+mappings[j].pdbfile);
+     * 
+     * java.awt.Color col; for(int index=0; index<seq.getLength(); index++) {
+     * if(jalview.util.Comparison.isGap(seq.getCharAt(index))) continue;
+     * 
+     * atomNo = mappings[j].getAtomNum(seq.findPosition(index)); col =
+     * java.awt.Color.white; if (atomNo > 0) { col = sl.getColour(atomNo,
+     * mappings[j].getPDBResNum(index), mappings[j].pdbchain,
+     * mappings[j].pdbfile); }
+     * 
+     * annotations[index] = new Annotation("X",null,' ',0,col); } return
+     * annotations; } } } }
+     * 
+     * return annotations;
+     */
+  }
 
   public void structureSelectionChanged()
-  {  }
+  {
+  }
 
   public void sequenceSelectionChanged()
-  {  }
+  {
+  }
 
   public void sequenceColoursChanged(Object source)
   {
@@ -402,4 +480,70 @@ public class StructureSelectionManager
 
     return sb.toString();
   }
+
+  private int[] seqmappingrefs = null; // refcount for seqmappings elements
+
+  private synchronized void modifySeqMappingList(boolean add,
+          AlignedCodonFrame[] codonFrames)
+  {
+    if (!add && (seqmappings == null || seqmappings.size() == 0))
+      return;
+    if (seqmappings == null)
+      seqmappings = new Vector();
+    if (codonFrames != null && codonFrames.length > 0)
+    {
+      for (int cf = 0; cf < codonFrames.length; cf++)
+      {
+        if (seqmappings.contains(codonFrames[cf]))
+        {
+          if (add)
+          {
+            seqmappingrefs[seqmappings.indexOf(codonFrames[cf])]++;
+          }
+          else
+          {
+            if (--seqmappingrefs[seqmappings.indexOf(codonFrames[cf])] <= 0)
+            {
+              int pos = seqmappings.indexOf(codonFrames[cf]);
+              int[] nr = new int[seqmappingrefs.length - 1];
+              if (pos > 0)
+              {
+                System.arraycopy(seqmappingrefs, 0, nr, 0, pos);
+              }
+              if (pos < seqmappingrefs.length - 1)
+              {
+                System.arraycopy(seqmappingrefs, pos + 1, nr, 0,
+                        seqmappingrefs.length - pos - 2);
+              }
+            }
+          }
+        }
+        else
+        {
+          if (add)
+          {
+            seqmappings.addElement(codonFrames[cf]);
+
+            int[] nsr = new int[(seqmappingrefs == null) ? 1
+                    : seqmappingrefs.length + 1];
+            if (seqmappingrefs != null && seqmappingrefs.length > 0)
+              System.arraycopy(seqmappingrefs, 0, nsr, 0,
+                      seqmappingrefs.length);
+            nsr[(seqmappingrefs == null) ? 0 : seqmappingrefs.length] = 1;
+            seqmappingrefs = nsr;
+          }
+        }
+      }
+    }
+  }
+
+  public void removeMappings(AlignedCodonFrame[] codonFrames)
+  {
+    modifySeqMappingList(false, codonFrames);
+  }
+
+  public void addMappings(AlignedCodonFrame[] codonFrames)
+  {
+    modifySeqMappingList(true, codonFrames);
+  }
 }
diff --git a/src/jalview/structure/VamsasListener.java b/src/jalview/structure/VamsasListener.java
new file mode 100644 (file)
index 0000000..1bf3931
--- /dev/null
@@ -0,0 +1,8 @@
+package jalview.structure;\r
+\r
+import jalview.datamodel.SequenceI;\r
+\r
+public interface VamsasListener\r
+{\r
+  public void mouseOver(SequenceI seq, int index);\r
+}\r