e9f8dce9b5d9b4ce444326cdbc19e3fbf2568a4d
[jalview.git] / src / MCview / PDBCanvas.java
1 /*\r
2 * Jalview - A Sequence Alignment Editor and Viewer\r
3 * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4 *\r
5 * This program is free software; you can redistribute it and/or\r
6 * modify it under the terms of the GNU General Public License\r
7 * as published by the Free Software Foundation; either version 2\r
8 * of the License, or (at your option) any later version.\r
9 *\r
10 * This program is distributed in the hope that it will be useful,\r
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 * GNU General Public License for more details.\r
14 *\r
15 * You should have received a copy of the GNU General Public License\r
16 * along with this program; if not, write to the Free Software\r
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18 */\r
19 package MCview;\r
20 \r
21 import jalview.analysis.AlignSeq;\r
22 \r
23 import jalview.datamodel.*;\r
24 \r
25 // JBPNote TODO: This class is quite noisy - needs proper log.info/log.debug\r
26 import java.awt.*;\r
27 import java.awt.event.*;\r
28 \r
29 import java.io.*;\r
30 \r
31 import java.util.*;\r
32 \r
33 import javax.swing.*;\r
34 \r
35 \r
36 public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListener\r
37 {\r
38     MCMatrix idmat = new MCMatrix(3, 3);\r
39     MCMatrix objmat = new MCMatrix(3, 3);\r
40     boolean redrawneeded = true;\r
41     int omx = 0;\r
42     int mx = 0;\r
43     int omy = 0;\r
44     int my = 0;\r
45     public PDBfile pdb;\r
46     int bsize;\r
47     Image img;\r
48     Graphics ig;\r
49     Dimension prefsize;\r
50     float[] centre = new float[3];\r
51     float[] width = new float[3];\r
52     float maxwidth;\r
53     float scale;\r
54     String inStr;\r
55     String inType;\r
56     boolean bysequence = true;\r
57     boolean depthcue = true;\r
58     boolean wire = false;\r
59     boolean bymolecule = false;\r
60     boolean zbuffer = true;\r
61     boolean dragging;\r
62     int xstart;\r
63     int xend;\r
64     int ystart;\r
65     int yend;\r
66     int xmid;\r
67     int ymid;\r
68     Font font = new Font("Helvetica", Font.PLAIN, 10);\r
69     jalview.gui.SequenceRenderer sr;\r
70     jalview.gui.FeatureRenderer  fr;\r
71 \r
72     public PDBCanvas()\r
73     {\r
74 \r
75     }\r
76 \r
77   public void setPDBFile(PDBfile pdb, Sequence sequence,\r
78                      jalview.gui.SequenceRenderer sr,\r
79                      jalview.gui.FeatureRenderer fr)\r
80    {\r
81 \r
82 \r
83         this.sr = sr;\r
84         this.fr = fr;\r
85         int max = -10;\r
86         int maxchain = -1;\r
87         int pdbstart = 0;\r
88         int pdbend = 0;\r
89         int seqstart = 0;\r
90         int seqend = 0;\r
91 \r
92         for (int i = 0; i < pdb.chains.size(); i++) {\r
93             // Now lets compare the sequences to get\r
94             // the start and end points.\r
95             // Align the sequence to the pdb\r
96             AlignSeq as = new AlignSeq(sequence,\r
97                     ((PDBChain) pdb.chains.elementAt(i)).sequence, "pep");\r
98             as.calcScoreMatrix();\r
99             as.traceAlignment();\r
100             as.printAlignment();\r
101 \r
102 \r
103             if (as.maxscore > max) {\r
104                 max = as.maxscore;\r
105                 maxchain = i;\r
106 \r
107                 pdbstart = as.seq2start;\r
108                 pdbend = as.seq2end;\r
109                 seqstart = as.seq1start + sequence.getStart()-1;\r
110                 seqend = as.seq1end + sequence.getEnd()-1;\r
111             }\r
112 \r
113             System.out.println("PDB start/end "  + pdbstart + " " + pdbend);\r
114             System.out.println("SEQ start/end "+ seqstart + " " + seqend);\r
115         }\r
116 \r
117         ((PDBChain) pdb.chains.elementAt(maxchain)).pdbstart = pdbstart;\r
118         ((PDBChain) pdb.chains.elementAt(maxchain)).pdbend = pdbend;\r
119         ((PDBChain) pdb.chains.elementAt(maxchain)).seqstart = seqstart;\r
120         ((PDBChain) pdb.chains.elementAt(maxchain)).seqend = seqend;\r
121         ((PDBChain) pdb.chains.elementAt(maxchain)).isVisible = true;\r
122         ((PDBChain) pdb.chains.elementAt(maxchain)).sequence = sequence;\r
123 \r
124         this.pdb = pdb;\r
125         this.prefsize = new Dimension(getWidth(), getHeight());\r
126 \r
127         //Initialize the matrices to identity\r
128         for (int i = 0; i < 3; i++) {\r
129             for (int j = 0; j < 3; j++) {\r
130                 if (i != j) {\r
131                     idmat.addElement(i, j, 0);\r
132                     objmat.addElement(i, j, 0);\r
133                 } else {\r
134                     idmat.addElement(i, j, 1);\r
135                     objmat.addElement(i, j, 1);\r
136                 }\r
137             }\r
138         }\r
139 \r
140         addMouseMotionListener(this);\r
141         addMouseListener(this);\r
142 \r
143         findCentre();\r
144         findWidth();\r
145 \r
146         scale = findScale();\r
147 \r
148         System.out.println("Scale factor = " + scale);\r
149 \r
150         updateSeqColours();\r
151         ToolTipManager.sharedInstance().registerComponent(this);\r
152         ToolTipManager.sharedInstance().setInitialDelay(0);\r
153         ToolTipManager.sharedInstance().setDismissDelay(10000);\r
154 \r
155     }\r
156 \r
157     public void deleteBonds() {\r
158         scale = 0;\r
159         maxwidth = 0;\r
160 \r
161         width[0] = 0;\r
162         width[1] = 0;\r
163         width[2] = 0;\r
164 \r
165         centre[0] = 0;\r
166         centre[1] = 0;\r
167         centre[2] = 0;\r
168 \r
169         for (int i = 0; i < pdb.chains.size(); i++) {\r
170             ((PDBChain) pdb.chains.elementAt(i)).bonds = null;\r
171         }\r
172     }\r
173 \r
174     public void findWidth() {\r
175         float[] max = new float[3];\r
176         float[] min = new float[3];\r
177 \r
178         max[0] = (float) -1e30;\r
179         max[1] = (float) -1e30;\r
180         max[2] = (float) -1e30;\r
181 \r
182         min[0] = (float) 1e30;\r
183         min[1] = (float) 1e30;\r
184         min[2] = (float) 1e30;\r
185 \r
186         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
187             if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) {\r
188                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
189 \r
190                 for (int i = 0; i < bonds.size(); i++) {\r
191                     Bond tmp = (Bond) bonds.elementAt(i);\r
192 \r
193                     if (tmp.start[0] >= max[0]) {\r
194                         max[0] = tmp.start[0];\r
195                     }\r
196 \r
197                     if (tmp.start[1] >= max[1]) {\r
198                         max[1] = tmp.start[1];\r
199                     }\r
200 \r
201                     if (tmp.start[2] >= max[2]) {\r
202                         max[2] = tmp.start[2];\r
203                     }\r
204 \r
205                     if (tmp.start[0] <= min[0]) {\r
206                         min[0] = tmp.start[0];\r
207                     }\r
208 \r
209                     if (tmp.start[1] <= min[1]) {\r
210                         min[1] = tmp.start[1];\r
211                     }\r
212 \r
213                     if (tmp.start[2] <= min[2]) {\r
214                         min[2] = tmp.start[2];\r
215                     }\r
216 \r
217                     if (tmp.end[0] >= max[0]) {\r
218                         max[0] = tmp.end[0];\r
219                     }\r
220 \r
221                     if (tmp.end[1] >= max[1]) {\r
222                         max[1] = tmp.end[1];\r
223                     }\r
224 \r
225                     if (tmp.end[2] >= max[2]) {\r
226                         max[2] = tmp.end[2];\r
227                     }\r
228 \r
229                     if (tmp.end[0] <= min[0]) {\r
230                         min[0] = tmp.end[0];\r
231                     }\r
232 \r
233                     if (tmp.end[1] <= min[1]) {\r
234                         min[1] = tmp.end[1];\r
235                     }\r
236 \r
237                     if (tmp.end[2] <= min[2]) {\r
238                         min[2] = tmp.end[2];\r
239                     }\r
240                 }\r
241             }\r
242         }\r
243 \r
244         System.out.println("xmax " + max[0] + " min " + min[0]);\r
245         System.out.println("ymax " + max[1] + " min " + min[1]);\r
246         System.out.println("zmax " + max[2] + " min " + min[2]);\r
247 \r
248         width[0] = (float) Math.abs(max[0] - min[0]);\r
249         width[1] = (float) Math.abs(max[1] - min[1]);\r
250         width[2] = (float) Math.abs(max[2] - min[2]);\r
251 \r
252         maxwidth = width[0];\r
253 \r
254         if (width[1] > width[0]) {\r
255             maxwidth = width[1];\r
256         }\r
257 \r
258         if (width[2] > width[1]) {\r
259             maxwidth = width[2];\r
260         }\r
261 \r
262         System.out.println("Maxwidth = " + maxwidth);\r
263     }\r
264 \r
265     public float findScale() {\r
266         int dim;\r
267         int width;\r
268         int height;\r
269 \r
270         if (getWidth() != 0) {\r
271             width = getWidth();\r
272             height = getHeight();\r
273         } else {\r
274             width = prefsize.width;\r
275             height = prefsize.height;\r
276         }\r
277 \r
278         if (width < height) {\r
279             dim = width;\r
280         } else {\r
281             dim = height;\r
282         }\r
283 \r
284         return (float) (dim / (1.5d * maxwidth));\r
285     }\r
286 \r
287     public void findCentre() {\r
288         float xtot = 0;\r
289         float ytot = 0;\r
290         float ztot = 0;\r
291 \r
292         int bsize = 0;\r
293 \r
294         //Find centre coordinate\r
295         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
296             if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) {\r
297                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
298 \r
299                 bsize += bonds.size();\r
300 \r
301                 for (int i = 0; i < bonds.size(); i++) {\r
302                     xtot = xtot + ((Bond) bonds.elementAt(i)).start[0] +\r
303                         ((Bond) bonds.elementAt(i)).end[0];\r
304 \r
305                     ytot = ytot + ((Bond) bonds.elementAt(i)).start[1] +\r
306                         ((Bond) bonds.elementAt(i)).end[1];\r
307 \r
308                     ztot = ztot + ((Bond) bonds.elementAt(i)).start[2] +\r
309                         ((Bond) bonds.elementAt(i)).end[2];\r
310                 }\r
311             }\r
312         }\r
313 \r
314         centre[0] = xtot / (2 * (float) bsize);\r
315         centre[1] = ytot / (2 * (float) bsize);\r
316         centre[2] = ztot / (2 * (float) bsize);\r
317     }\r
318 \r
319     public void paintComponent(Graphics g) {\r
320 \r
321       if(pdb==null)\r
322       {\r
323         g.setColor(Color.black);\r
324         g.setFont(new Font("Verdana", Font.BOLD, 14));\r
325         g.drawString("Retrieving PDB data....", 20, getHeight()/2);\r
326 \r
327         return;\r
328       }\r
329 \r
330 \r
331         //Only create the image at the beginning -\r
332         //this saves much memory usage\r
333         if ((img == null) || (prefsize.width != getWidth()) ||\r
334                 (prefsize.height != getHeight())) {\r
335             prefsize.width = getWidth();\r
336             prefsize.height = getHeight();\r
337 \r
338             scale = findScale();\r
339             img = createImage(prefsize.width, prefsize.height);\r
340             ig = img.getGraphics();\r
341             Graphics2D ig2 = (Graphics2D) ig;\r
342 \r
343             ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
344                                  RenderingHints.VALUE_ANTIALIAS_ON);\r
345 \r
346 \r
347             redrawneeded = true;\r
348         }\r
349 \r
350 \r
351         if (redrawneeded)\r
352         {\r
353           drawAll(ig, prefsize.width, prefsize.height);\r
354           redrawneeded = false;\r
355         }\r
356 \r
357         g.drawImage(img, 0, 0, this);\r
358     }\r
359 \r
360     public void drawAll(Graphics g, int width, int height)\r
361     {\r
362       g.setColor(Color.black);\r
363       g.fillRect(0, 0, width, height);\r
364       drawScene(g);\r
365       drawLabels(g);\r
366     }\r
367 \r
368 \r
369     public void updateSeqColours()\r
370     {\r
371       if(bysequence)\r
372       {\r
373         for (int ii = 0; ii < pdb.chains.size(); ii++)\r
374         {\r
375           ( (PDBChain) pdb.chains.elementAt(ii)).colourBySequence(sr, fr);\r
376         }\r
377       }\r
378 \r
379       redrawneeded=true;\r
380       repaint();\r
381 \r
382     }\r
383 \r
384     public void drawScene(Graphics g) {\r
385         // Sort the bonds by z coord\r
386         Vector bonds = new Vector();\r
387 \r
388         for (int ii = 0; ii < pdb.chains.size(); ii++)\r
389         {\r
390           if ( ( (PDBChain) pdb.chains.elementAt(ii)).isVisible)\r
391           {\r
392             Vector tmp = ( (PDBChain) pdb.chains.elementAt(ii)).bonds;\r
393 \r
394             for (int i = 0; i < tmp.size(); i++)\r
395             {\r
396               bonds.addElement(tmp.elementAt(i));\r
397             }\r
398           }\r
399         }\r
400 \r
401         if (zbuffer) {\r
402             Zsort.Zsort(bonds);\r
403         }\r
404 \r
405         for (int i = 0; i < bonds.size(); i++) {\r
406             Bond tmpBond = (Bond) bonds.elementAt(i);\r
407 \r
408             xstart = (int) (((tmpBond.start[0] - centre[0]) * scale) +\r
409                 (getWidth() / 2));\r
410             ystart = (int) (((tmpBond.start[1] - centre[1]) * scale) +\r
411                 (getHeight() / 2));\r
412 \r
413             xend = (int) (((tmpBond.end[0] - centre[0]) * scale) +\r
414                 (getWidth() / 2));\r
415             yend = (int) (((tmpBond.end[1] - centre[1]) * scale) +\r
416                 (getHeight() / 2));\r
417 \r
418             xmid = (xend + xstart) / 2;\r
419             ymid = (yend + ystart) / 2;\r
420 \r
421             if (depthcue && !bymolecule) {\r
422                 if (tmpBond.start[2] < (centre[2] - (maxwidth / 6))) {\r
423                     g.setColor(tmpBond.startCol.darker().darker());\r
424                     drawLine(g, xstart, ystart, xmid, ymid);\r
425 \r
426                     g.setColor(tmpBond.endCol.darker().darker());\r
427                     drawLine(g, xmid, ymid, xend, yend);\r
428                 } else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6))) {\r
429                     g.setColor(tmpBond.startCol.darker());\r
430                     drawLine(g, xstart, ystart, xmid, ymid);\r
431 \r
432                     g.setColor(tmpBond.endCol.darker());\r
433                     drawLine(g, xmid, ymid, xend, yend);\r
434                 } else {\r
435                     g.setColor(tmpBond.startCol);\r
436                     drawLine(g, xstart, ystart, xmid, ymid);\r
437 \r
438                     g.setColor(tmpBond.endCol);\r
439                     drawLine(g, xmid, ymid, xend, yend);\r
440                 }\r
441             } else if (depthcue && bymolecule) {\r
442                 if (tmpBond.start[2] < (centre[2] - (maxwidth / 6))) {\r
443                     g.setColor(Color.green.darker().darker());\r
444                     drawLine(g, xstart, ystart, xend, yend);\r
445                 } else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6))) {\r
446                     g.setColor(Color.green.darker());\r
447                     drawLine(g, xstart, ystart, xend, yend);\r
448                 } else {\r
449                     g.setColor(Color.green);\r
450                     drawLine(g, xstart, ystart, xend, yend);\r
451                 }\r
452             } else if (!depthcue && !bymolecule) {\r
453                 g.setColor(tmpBond.startCol);\r
454                 drawLine(g, xstart, ystart, xmid, ymid);\r
455                 g.setColor(tmpBond.endCol);\r
456                 drawLine(g, xmid, ymid, xend, yend);\r
457             } else {\r
458                 drawLine(g, xstart, ystart, xend, yend);\r
459             }\r
460         }\r
461     }\r
462 \r
463     public void drawLine(Graphics g, int x1, int y1, int x2, int y2) {\r
464         if (!wire) {\r
465             if (((float) Math.abs(y2 - y1) / (float) Math.abs(x2 - x1)) < 0.5) {\r
466                 g.drawLine(x1, y1, x2, y2);\r
467                 g.drawLine(x1 + 1, y1 + 1, x2 + 1, y2 + 1);\r
468                 g.drawLine(x1, y1 - 1, x2, y2 - 1);\r
469             } else {\r
470                 g.setColor(g.getColor().brighter());\r
471                 g.drawLine(x1, y1, x2, y2);\r
472                 g.drawLine(x1 + 1, y1, x2 + 1, y2);\r
473                 g.drawLine(x1 - 1, y1, x2 - 1, y2);\r
474             }\r
475         } else {\r
476             g.drawLine(x1, y1, x2, y2);\r
477         }\r
478     }\r
479 \r
480     public Dimension minimumsize() {\r
481         return prefsize;\r
482     }\r
483 \r
484     public Dimension preferredsize() {\r
485         return prefsize;\r
486     }\r
487 \r
488     public void keyPressed(KeyEvent evt) {\r
489       int key = evt.getKeyChar();\r
490       System.out.println(key);\r
491       if (evt.getKeyCode() == KeyEvent.VK_UP)\r
492       {\r
493         scale = (float) (scale * 1.1);\r
494         redrawneeded = true;\r
495         repaint();\r
496       }\r
497       else if (evt.getKeyCode() == KeyEvent.VK_DOWN)\r
498       {\r
499         scale = (float) (scale * 0.9);\r
500         redrawneeded = true;\r
501         repaint();\r
502       }\r
503     }\r
504 \r
505     public void mousePressed(MouseEvent e) {\r
506         myAtom fatom = findAtom(e.getX(), e.getY());\r
507         if(fatom!=null)\r
508         {\r
509           fatom.isSelected = !fatom.isSelected;\r
510           redrawneeded = true;\r
511           repaint();\r
512         }\r
513         mx = e.getX();\r
514         my = e.getY();\r
515         omx = mx;\r
516         omy = my;\r
517         dragging = false;\r
518     }\r
519 \r
520     public void mouseMoved(MouseEvent e) {\r
521 \r
522         myAtom fatom = findAtom(e.getX(), e.getY());\r
523 \r
524         if (fatom != null) {\r
525             this.setToolTipText(fatom.resNumber+" "+ fatom.resName);\r
526         } else {\r
527             this.setToolTipText("");\r
528         }\r
529     }\r
530 \r
531     public void mouseClicked(MouseEvent e) {\r
532     }\r
533 \r
534     public void mouseEntered(MouseEvent e) {\r
535     }\r
536 \r
537     public void mouseExited(MouseEvent e) {\r
538     }\r
539 \r
540     public void mouseDragged(MouseEvent evt) {\r
541         int x = evt.getX();\r
542         int y = evt.getY();\r
543         mx = x;\r
544         my = y;\r
545 \r
546         MCMatrix objmat = new MCMatrix(3, 3);\r
547         objmat.setIdentity();\r
548 \r
549         if ((evt.getModifiers() & Event.META_MASK) != 0) {\r
550             objmat.rotatez((float) ((mx - omx)));\r
551         } else {\r
552             objmat.rotatex((float) ((my - omy)));\r
553             objmat.rotatey((float) ((omx - mx)));\r
554         }\r
555 \r
556         //Alter the bonds\r
557         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
558             Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
559 \r
560             for (int i = 0; i < bonds.size(); i++) {\r
561                 Bond tmpBond = (Bond) bonds.elementAt(i);\r
562 \r
563                 //Translate the bond so the centre is 0,0,0\r
564                 tmpBond.translate(-centre[0], -centre[1], -centre[2]);\r
565 \r
566                 //Now apply the rotation matrix\r
567                 tmpBond.start = objmat.vectorMultiply(tmpBond.start);\r
568                 tmpBond.end = objmat.vectorMultiply(tmpBond.end);\r
569 \r
570                 //Now translate back again\r
571                 tmpBond.translate(centre[0], centre[1], centre[2]);\r
572             }\r
573         }\r
574 \r
575         objmat = null;\r
576 \r
577         omx = mx;\r
578         omy = my;\r
579 \r
580         dragging = true;\r
581 \r
582         redrawneeded = true;\r
583 \r
584         repaint();\r
585     }\r
586 \r
587     public void mouseReleased(MouseEvent evt) {\r
588         dragging = false;\r
589         return;\r
590     }\r
591 \r
592     void drawLabels(Graphics g) {\r
593 \r
594         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
595             PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
596 \r
597             if (chain.isVisible) {\r
598                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
599 \r
600                 for (int i = 0; i < bonds.size(); i++) {\r
601                     Bond tmpBond = (Bond) bonds.elementAt(i);\r
602 \r
603                     if (tmpBond.at1.isSelected) {\r
604                         labelAtom(g, tmpBond, 1);\r
605                     }\r
606 \r
607                     if (tmpBond.at2.isSelected) {\r
608                         labelAtom(g, tmpBond, 2);\r
609                     }\r
610                 }\r
611             }\r
612         }\r
613     }\r
614 \r
615     public void labelAtom(Graphics g, Bond b, int n) {\r
616         g.setFont(font);\r
617 \r
618         if (n == 1) {\r
619             int xstart = (int) (((b.start[0] - centre[0]) * scale) +\r
620                 (getWidth() / 2));\r
621             int ystart = (int) (((b.start[1] - centre[1]) * scale) +\r
622                 (getHeight() / 2));\r
623 \r
624             g.setColor(Color.red);\r
625             g.drawString(b.at1.resName + "-" + b.at1.resNumber, xstart, ystart);\r
626         }\r
627 \r
628         if (n == 2) {\r
629             int xstart = (int) (((b.end[0] - centre[0]) * scale) +\r
630                 (getWidth() / 2));\r
631             int ystart = (int) (((b.end[1] - centre[1]) * scale) +\r
632                 (getHeight() / 2));\r
633 \r
634             g.setColor(Color.red);\r
635             g.drawString(b.at2.resName + "-" + b.at2.resNumber, xstart, ystart);\r
636         }\r
637     }\r
638 \r
639     public myAtom findAtom(int x, int y) {\r
640         myAtom fatom = null;\r
641 \r
642         int foundchain = -1;\r
643 \r
644         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
645             PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
646 \r
647             if (chain.isVisible) {\r
648                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
649 \r
650                 for (int i = 0; i < bonds.size(); i++) {\r
651                     Bond tmpBond = (Bond) bonds.elementAt(i);\r
652 \r
653                     int truex = (int) (((tmpBond.start[0] - centre[0]) * scale) +\r
654                         (getWidth() / 2));\r
655 \r
656                     if (Math.abs(truex - x) <= 2) {\r
657                         int truey = (int) (((tmpBond.start[1] - centre[1]) * scale) +\r
658                             (getHeight() / 2));\r
659 \r
660                         if (Math.abs(truey - y) <= 2)\r
661                         {\r
662                             fatom = tmpBond.at1;\r
663                             foundchain = ii;\r
664                         }\r
665                     }\r
666                 }\r
667             }\r
668 \r
669             if (fatom != null) //)&& chain.ds != null)\r
670              {\r
671                 chain = (PDBChain) pdb.chains.elementAt(foundchain);\r
672 \r
673                 // SMJS TODO\r
674                 // int tmp = chain.ds.seqstart + fatom.resNumber - chain.offset;\r
675                 // int pos = chain.ds.findIndex(tmp);\r
676                 // System.out.println("Found seq " + chain.ds.name + " "  + tmp + " " + pos);\r
677             }\r
678         }\r
679 \r
680         return fatom;\r
681     }\r
682 \r
683     public void update(Graphics g) {\r
684         paint(g);\r
685     }\r
686 }\r