applied copyright 2008
[jalview.git] / src / MCview / PDBCanvas.java
index bd90b19..0d807e3 100755 (executable)
@@ -1,17 +1,17 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer
- * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
- *
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4)
+ * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ * 
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
  * of the License, or (at your option) any later version.
- *
+ * 
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- *
+ * 
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
@@ -28,18 +28,19 @@ import javax.swing.*;
 
 import jalview.analysis.*;
 import jalview.datamodel.*;
+import jalview.gui.*;
+import jalview.structure.*;
 
 public class PDBCanvas
-    extends JPanel implements MouseListener, MouseMotionListener
+    extends JPanel implements MouseListener, MouseMotionListener, StructureListener
 {
-  MCMatrix idmat = new MCMatrix(3, 3);
-  MCMatrix objmat = new MCMatrix(3, 3);
   boolean redrawneeded = true;
   int omx = 0;
   int mx = 0;
   int omy = 0;
   int my = 0;
   public PDBfile pdb;
+  PDBEntry pdbentry;
   int bsize;
   Image img;
   Graphics ig;
@@ -64,7 +65,7 @@ public class PDBCanvas
   int ymid;
   Font font = new Font("Helvetica", Font.PLAIN, 10);
   jalview.gui.SeqCanvas seqcanvas;
-  public Sequence sequence;
+  public SequenceI [] sequence;
   final StringBuffer mappingDetails = new StringBuffer();
   PDBChain mainchain;
   Vector highlightRes;
@@ -72,23 +73,55 @@ public class PDBCanvas
   boolean seqColoursReady = false;
   jalview.gui.FeatureRenderer fr;
   Color backgroundColour = Color.black;
+  AlignmentPanel ap;
+  StructureSelectionManager ssm;
+  String errorMessage;
 
-  public PDBCanvas(jalview.gui.SeqCanvas seqcanvas, Sequence seq)
+
+  void init(PDBEntry pdbentry,
+                         SequenceI[] seq,
+                         String [] chains,
+                         AlignmentPanel ap,
+                         String protocol)
   {
-    this.seqcanvas = seqcanvas;
+    this.ap = ap;
+    this.pdbentry = pdbentry;
     this.sequence = seq;
-    seqcanvas.setPDBCanvas(this);
-  }
 
-  public void setPDBFile(PDBfile pdb)
-  {
+    ssm = StructureSelectionManager.getStructureSelectionManager();
+
+    try{
+      pdb = ssm.setMapping(seq, chains, pdbentry.getFile(), protocol);
+
+      if(protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
+       pdbentry.setFile("INLINE"+pdb.id);
+
+    }catch(Exception ex)
+    {
+      ex.printStackTrace();
+      return;
+    }
+
+    if(pdb==null)
+    {
+      errorMessage = "Error loading file: "+pdbentry.getId();
+      return;
+    }
+    pdbentry.setId(pdb.id);
+
+    ssm.addStructureViewerListener(this);
+
+    colourBySequence();
+
     int max = -10;
     int maxchain = -1;
     int pdbstart = 0;
     int pdbend = 0;
     int seqstart = 0;
     int seqend = 0;
-    AlignSeq maxAlignseq = null;
+
+    //JUST DEAL WITH ONE SEQUENCE FOR NOW
+    SequenceI sequence = seq[0];
 
     for (int i = 0; i < pdb.chains.size(); i++)
     {
@@ -105,7 +138,7 @@ public class PDBCanvas
       // Align the sequence to the pdb
       AlignSeq as = new AlignSeq(sequence,
                                  ( (PDBChain) pdb.chains.elementAt(i)).sequence,
-                                 AlignSeq.PEP);
+                                 "pep");
       as.calcScoreMatrix();
       as.traceAlignment();
       PrintStream ps = new PrintStream(System.out)
@@ -127,11 +160,11 @@ public class PDBCanvas
       {
         max = as.maxscore;
         maxchain = i;
+
         pdbstart = as.seq2start;
         pdbend = as.seq2end;
         seqstart = as.seq1start + sequence.getStart() - 1;
         seqend = as.seq1end + sequence.getEnd() - 1;
-        maxAlignseq = as;
       }
 
       mappingDetails.append("\nPDB start/end " + pdbstart + " " + pdbend);
@@ -145,50 +178,19 @@ public class PDBCanvas
     mainchain.seqstart = seqstart;
     mainchain.seqend = seqend;
     mainchain.isVisible = true;
-    mainchain.makeExactMapping(maxAlignseq, sequence);
-    mainchain.transferRESNUMFeatures(sequence.getDatasetSequence(), null);
-    seqcanvas.getFeatureRenderer().featuresAdded();
+
     this.pdb = pdb;
-    this.prefsize = new Dimension(getWidth(), getHeight());
+    this.prefsize = new Dimension(getSize().width, getSize().height);
 
-    //Initialize the matrices to identity
-    for (int i = 0; i < 3; i++)
-    {
-      for (int j = 0; j < 3; j++)
-      {
-        if (i != j)
-        {
-          idmat.addElement(i, j, 0);
-          objmat.addElement(i, j, 0);
-        }
-        else
-        {
-          idmat.addElement(i, j, 1);
-          objmat.addElement(i, j, 1);
-        }
-      }
-    }
 
     addMouseMotionListener(this);
     addMouseListener(this);
 
-    addMouseWheelListener(new MouseWheelListener()
+    addKeyListener(new KeyAdapter()
     {
-      public void mouseWheelMoved(MouseWheelEvent e)
+      public void keyPressed(KeyEvent evt)
       {
-        if (e.getWheelRotation() > 0)
-        {
-          scale = (float) (scale * 1.1);
-          redrawneeded = true;
-          repaint();
-        }
-
-        else
-        {
-          scale = (float) (scale * 0.9);
-          redrawneeded = true;
-          repaint();
-        }
+        keyPressed(evt);
       }
     });
 
@@ -408,11 +410,13 @@ public class PDBCanvas
   {
     super.paintComponent(g);
 
-    if (!seqColoursReady)
+    if (!seqColoursReady || errorMessage!=null)
     {
       g.setColor(Color.black);
       g.setFont(new Font("Verdana", Font.BOLD, 14));
-      g.drawString("Retrieving PDB data....", 20, getHeight() / 2);
+      g.drawString(errorMessage==null?
+                   "Retrieving PDB data....":errorMessage,
+                   20, getHeight() / 2);
       return;
     }
 
@@ -463,118 +467,84 @@ public class PDBCanvas
       return;
     }
 
-    // System.out.println("update seq colours");
-    if (bysequence && pdb != null)
-    {
-      for (int ii = 0; ii < pdb.chains.size(); ii++)
-      {
-        colourBySequence( (PDBChain) pdb.chains.elementAt(ii));
-      }
-    }
+    colourBySequence();
 
     redrawneeded = true;
     repaint();
   }
 
-  int findTrueIndex(int pos)
-  {
-    // returns the alignment position for a residue
-    int j = sequence.getStart(); // first position in PDB atom coordinate sequence
-    int i = 0;
-
-    while ( (i < sequence.getLength()) && (j <= pos + 1))
-    {
-      if (!jalview.util.Comparison.isGap(sequence.getCharAt(i)))
-      {
-        j++;
-      }
-
-      i++;
-    }
-
-    if (i > 1)
-    {
-      i--;
-    }
-
-    if (j < pos)
-    {
-      return sequence.getEnd() + 1;
-    }
-    else
-    {
-      return i;
-    }
-  }
 
   // This method has been taken out of PDBChain to allow
   // Applet and Application specific sequence renderers to be used
-  void colourBySequence(PDBChain chain)
+  void colourBySequence()
   {
-    // System.out.println("colour by seq");
+    SequenceRenderer sr = new SequenceRenderer(ap.av);
+
+    StructureMapping[] mapping = ssm.getMapping(pdbentry.getFile());
+
     boolean showFeatures = false;
-    if (seqcanvas.getViewport().getShowSequenceFeatures())
+    if (ap.av.getShowSequenceFeatures())
     {
-      showFeatures = true;
       if (fr == null)
       {
-        fr = new jalview.gui.FeatureRenderer(seqcanvas.getViewport());
+        fr = new FeatureRenderer(ap);
       }
 
-      fr.transferSettings(seqcanvas.getFeatureRenderer());
+      fr.transferSettings(ap.alignFrame.getFeatureRenderer());
+
+      showFeatures = true;
     }
 
-    Bond tmp;
-    for (int i = 0; i < chain.bonds.size(); i++)
+    PDBChain chain;
+    if (bysequence && pdb != null)
     {
-      tmp = (Bond) chain.bonds.elementAt(i);
-
-      if (chain != mainchain)
-      {
-        continue;
-      }
-
-      //if ( (tmp.at1.resNumber >= ( (chain.offset + chain.pdbstart) - 1)) &&
-      //    (tmp.at1.resNumber <= ( (chain.offset + chain.pdbend) - 1)))
-      {
-        int index = findTrueIndex(tmp.at1.alignmentMapping);
-        //sequence.findIndex(tmp.at1.alignmentMapping);
-        if (index > 0)
-        {
-          tmp.startCol = seqcanvas.getSequenceRenderer().
-              getResidueBoxColour(sequence, index);
-
-          if (showFeatures)
-          {
-            tmp.startCol = fr.findFeatureColour(tmp.startCol, sequence, index);
-          }
-
-          if (tmp.startCol == null)
-          {
-            tmp.startCol = Color.white;
-          }
-        }
-      }
-
-      //if ( (tmp.at2.resNumber >= ( (chain.offset + chain.pdbstart) - 1)) &&
-      //    (tmp.at2.resNumber <= ( (chain.pdbend + chain.offset) - 1)))
+      for (int ii = 0; ii < pdb.chains.size(); ii++)
       {
+        chain = (PDBChain) pdb.chains.elementAt(ii);
 
-        int index = findTrueIndex(tmp.at2.alignmentMapping);
-        //sequence.findIndex( tmp.at2.alignmentMapping );
-        if (index > 0)
+        for (int i = 0; i < chain.bonds.size(); i++)
         {
-          tmp.endCol = seqcanvas.getSequenceRenderer().
-              getResidueBoxColour(sequence, index);
-
-          if (showFeatures)
+          Bond tmp = (Bond) chain.bonds.elementAt(i);
+          tmp.startCol = Color.lightGray;
+          tmp.endCol = Color.lightGray;
+          if (chain != mainchain)
           {
-            tmp.endCol = fr.findFeatureColour(tmp.endCol, sequence, index);
+            continue;
           }
 
-          if (tmp.endCol == null)
+          for (int s = 0; s < sequence.length; s++)
           {
-            tmp.endCol = Color.white;
+            for (int m = 0; m < mapping.length; m++)
+            {
+              if (mapping[m].getSequence() == sequence[s])
+              {
+                int pos = mapping[m].getSeqPos(tmp.at1.resNumber)-1;
+                if (pos > 0)
+                {
+                  pos = sequence[s].findIndex(pos);
+                  tmp.startCol = sr.getResidueBoxColour(sequence[s], pos);
+                  if (showFeatures)
+                  {
+                    tmp.startCol = fr.findFeatureColour(tmp.startCol,
+                                                        sequence[s],
+                                                        pos);
+                  }
+                }
+                pos = mapping[m].getSeqPos(tmp.at2.resNumber)-1;
+                if (pos > 0)
+                {
+                  pos = sequence[s].findIndex(pos);
+                  tmp.endCol = sr.getResidueBoxColour(sequence[s], pos);
+                  if (showFeatures)
+                  {
+                    tmp.endCol = fr.findFeatureColour(tmp.endCol,
+                                                        sequence[s],
+                                                        pos);
+                  }
+                }
+
+              }
+            }
           }
         }
       }
@@ -601,12 +571,12 @@ public class PDBCanvas
 
       xstart = (int) ( ( (tmpBond.start[0] - centre[0]) * scale) +
                       (getWidth() / 2));
-      ystart = (int) ( ( (tmpBond.start[1] - centre[1]) * scale) +
+      ystart = (int) ( ( (centre[1] - tmpBond.start[1] ) * scale) +
                       (getHeight() / 2));
 
       xend = (int) ( ( (tmpBond.end[0] - centre[0]) * scale) +
                     (getWidth() / 2));
-      yend = (int) ( ( (tmpBond.end[1] - centre[1]) * scale) +
+      yend = (int) ( ( (centre[1] - tmpBond.end[1] ) * scale) +
                     (getHeight() / 2));
 
       xmid = (xend + xstart) / 2;
@@ -796,7 +766,7 @@ public class PDBCanvas
       chain = (PDBChain) pdb.chains.elementAt(foundchain);
       if (chain == mainchain)
       {
-        highlightSeqcanvas(fatom.alignmentMapping);
+        mouseOverStructure(fatom.resNumber, chain.id);
       }
     }
 
@@ -807,33 +777,11 @@ public class PDBCanvas
     }
     else
     {
-      highlightSeqcanvas( -1);
+      mouseOverStructure(-1, chain!=null?chain.id:null);
       this.setToolTipText(null);
     }
   }
 
-  void highlightSeqcanvas(int pos)
-  {
-    SearchResults searchResults = new SearchResults();
-    if (highlightRes != null)
-    {
-      for (int i = 0; i < highlightRes.size(); i++)
-      {
-        int a = Integer.parseInt(highlightRes.elementAt(
-            i).toString()) + 1;
-
-        searchResults.addResult(sequence, a, a);
-      }
-    }
-
-    if (pos != -1)
-    {
-      searchResults.addResult(sequence, pos + 1, pos + 1);
-    }
-
-    seqcanvas.highlightSearchResults(searchResults);
-  }
-
   public void mouseClicked(MouseEvent e)
   {}
 
@@ -940,7 +888,7 @@ public class PDBCanvas
     {
       int xstart = (int) ( ( (b.start[0] - centre[0]) * scale) +
                           (getWidth() / 2));
-      int ystart = (int) ( ( (b.start[1] - centre[1]) * scale) +
+      int ystart = (int) ( ( (centre[1] - b.start[1] ) * scale) +
                           (getHeight() / 2));
 
       g.drawString(b.at1.resName + "-" + b.at1.resNumber, xstart, ystart);
@@ -950,7 +898,7 @@ public class PDBCanvas
     {
       int xstart = (int) ( ( (b.end[0] - centre[0]) * scale) +
                           (getWidth() / 2));
-      int ystart = (int) ( ( (b.end[1] - centre[1]) * scale) +
+      int ystart = (int) ( ( (centre[1] - b.end[1] ) * scale) +
                           (getHeight() / 2));
 
       g.drawString(b.at2.resName + "-" + b.at2.resNumber, xstart, ystart);
@@ -983,7 +931,7 @@ public class PDBCanvas
 
           if (Math.abs(truex - x) <= 2)
           {
-            int truey = (int) ( ( (tmpBond.start[1] - centre[1]) * scale) +
+            int truey = (int) ( ( (centre[1] - tmpBond.start[1] ) * scale) +
                                (getHeight() / 2));
 
             if (Math.abs(truey - y) <= 2)
@@ -1089,4 +1037,95 @@ public class PDBCanvas
     findCentre();
     setupBonds();
   }
+
+  //////////////////////////////////
+  ///StructureListener
+  public String getPdbFile()
+  {
+    return pdbentry.getFile();
+  }
+
+
+  String lastMessage;
+  public void mouseOverStructure(int pdbResNum, String chain)
+  {
+      if (lastMessage == null || !lastMessage.equals(pdbResNum+chain))
+        ssm.mouseOverStructure(pdbResNum, chain, pdbentry.getFile());
+
+      lastMessage = pdbResNum+chain;
+  }
+
+  StringBuffer resetLastRes = new StringBuffer();
+  StringBuffer eval = new StringBuffer();
+
+  public void highlightAtom(int atomIndex, int pdbResNum, String chain, String pdbfile)
+  {
+    if (!seqColoursReady)
+    {
+      return;
+    }
+
+    if (highlightRes != null
+        && highlightRes.contains( (atomIndex - 1) + ""))
+    {
+      return;
+    }
+
+    int index = -1;
+    Bond tmpBond;
+    for (index = 0; index < mainchain.bonds.size(); index++)
+    {
+      tmpBond = (Bond) mainchain.bonds.elementAt(index);
+      if (tmpBond.at1.atomIndex == atomIndex)
+      {
+        if (highlightBond1 != null)
+        {
+          highlightBond1.at2.isSelected = false;
+        }
+
+        if (highlightBond2 != null)
+        {
+          highlightBond2.at1.isSelected = false;
+        }
+
+        highlightBond1 = null;
+        highlightBond2 = null;
+
+        if (index > 0)
+        {
+          highlightBond1 = (Bond) mainchain.bonds.elementAt(index - 1);
+          highlightBond1.at2.isSelected = true;
+        }
+
+        if (index != mainchain.bonds.size())
+        {
+          highlightBond2 = (Bond) mainchain.bonds.elementAt(index);
+          highlightBond2.at1.isSelected = true;
+        }
+
+        break;
+      }
+    }
+
+    redrawneeded = true;
+    repaint();
+  }
+
+
+  public Color getColour(int atomIndex, int pdbResNum, String chain, String pdbfile)
+  {
+    return Color.white;
+   // if (!pdbfile.equals(pdbentry.getFile()))
+   //   return null;
+
+    //return new Color(viewer.getAtomArgb(atomIndex));
+  }
+
+  public void updateColours(Object source)
+  {
+    colourBySequence();
+    redrawneeded = true;
+    repaint();
+  }
+
 }