Mapping to PDB added
[jalview.git] / src / MCview / rotCanvas.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 rotCanvas extends JPanel implements KeyListener, MouseListener,\r
37     MouseMotionListener {\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 depthcue = true;\r
57     boolean wire = false;\r
58     boolean bymolecule = false;\r
59     boolean zbuffer = true;\r
60     boolean dragging;\r
61     int xstart;\r
62     int xend;\r
63     int ystart;\r
64     int yend;\r
65     int xmid;\r
66     int ymid;\r
67     Font font = new Font("Helvetica", Font.PLAIN, 10);\r
68 \r
69     public rotCanvas(PDBfile pdb, Sequence sequence,\r
70         jalview.gui.AlignViewport av) throws IOException {\r
71         int max = -10;\r
72         int maxchain = -1;\r
73         int pdbstart = 0;\r
74         int pdbend = 0;\r
75         int seqstart = 0;\r
76         int seqend = 0;\r
77 \r
78         for (int i = 0; i < pdb.chains.size(); i++) {\r
79             // Now lets compare the sequences to get\r
80             // the start and end points.\r
81             java.util.StringTokenizer str = new java.util.StringTokenizer(sequence.getSequence(),\r
82                     ".");\r
83             String newString = "";\r
84 \r
85             while (str.hasMoreTokens()) {\r
86                 newString += str.nextToken();\r
87             }\r
88 \r
89             // Align the sequence to the pdb\r
90             AlignSeq as = new AlignSeq(sequence,\r
91                     ((PDBChain) pdb.chains.elementAt(i)).sequence, "pep");\r
92             as.calcScoreMatrix();\r
93             as.traceAlignment();\r
94             as.printAlignment();\r
95 \r
96             if (as.maxscore > max) {\r
97                 max = as.maxscore;\r
98                 maxchain = i;\r
99 \r
100                 pdbstart = as.seq2start;\r
101                 pdbend = as.seq2end;\r
102                 seqstart = as.seq1start - 1;\r
103                 seqend = as.seq1end - 1;\r
104             }\r
105 \r
106             System.out.println("PDB start/end " + pdbstart + " " + pdbend);\r
107             System.out.println("SEQ start/end " + seqstart + " " + seqend);\r
108         }\r
109 \r
110         ((PDBChain) pdb.chains.elementAt(maxchain)).pdbstart = pdbstart;\r
111         ((PDBChain) pdb.chains.elementAt(maxchain)).pdbend = pdbend;\r
112         ((PDBChain) pdb.chains.elementAt(maxchain)).seqstart = seqstart;\r
113         ((PDBChain) pdb.chains.elementAt(maxchain)).seqend = seqend;\r
114         ((PDBChain) pdb.chains.elementAt(maxchain)).isVisible = true;\r
115         ((PDBChain) pdb.chains.elementAt(maxchain)).sequence = sequence;\r
116         ((PDBChain) pdb.chains.elementAt(maxchain)).colourBySequence(av,\r
117             sequence);\r
118 \r
119         this.pdb = pdb;\r
120         this.prefsize = new Dimension(getWidth(), getHeight());\r
121 \r
122         //Initialize the matrices to identity\r
123         for (int i = 0; i < 3; i++) {\r
124             for (int j = 0; j < 3; j++) {\r
125                 if (i != j) {\r
126                     idmat.addElement(i, j, 0);\r
127                     objmat.addElement(i, j, 0);\r
128                 } else {\r
129                     idmat.addElement(i, j, 1);\r
130                     objmat.addElement(i, j, 1);\r
131                 }\r
132             }\r
133         }\r
134 \r
135         addMouseMotionListener(this);\r
136         addMouseListener(this);\r
137         addKeyListener(this);\r
138 \r
139         addPDBfile();\r
140         ToolTipManager.sharedInstance().registerComponent(this);\r
141         ToolTipManager.sharedInstance().setInitialDelay(0);\r
142         ToolTipManager.sharedInstance().setDismissDelay(10000);\r
143 \r
144     }\r
145 \r
146     public void addPDBfile() {\r
147         findCentre();\r
148         findWidth();\r
149 \r
150         scale = findScale();\r
151 \r
152         System.out.println("Scale factor = " + scale);\r
153     }\r
154 \r
155     public void deleteBonds() {\r
156         scale = 0;\r
157         maxwidth = 0;\r
158 \r
159         width[0] = 0;\r
160         width[1] = 0;\r
161         width[2] = 0;\r
162 \r
163         centre[0] = 0;\r
164         centre[1] = 0;\r
165         centre[2] = 0;\r
166 \r
167         for (int i = 0; i < pdb.chains.size(); i++) {\r
168             ((PDBChain) pdb.chains.elementAt(i)).bonds = null;\r
169         }\r
170     }\r
171 \r
172     public void findWidth() {\r
173         float[] max = new float[3];\r
174         float[] min = new float[3];\r
175 \r
176         max[0] = (float) -1e30;\r
177         max[1] = (float) -1e30;\r
178         max[2] = (float) -1e30;\r
179 \r
180         min[0] = (float) 1e30;\r
181         min[1] = (float) 1e30;\r
182         min[2] = (float) 1e30;\r
183 \r
184         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
185             if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) {\r
186                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
187 \r
188                 for (int i = 0; i < bonds.size(); i++) {\r
189                     Bond tmp = (Bond) bonds.elementAt(i);\r
190 \r
191                     if (tmp.start[0] >= max[0]) {\r
192                         max[0] = tmp.start[0];\r
193                     }\r
194 \r
195                     if (tmp.start[1] >= max[1]) {\r
196                         max[1] = tmp.start[1];\r
197                     }\r
198 \r
199                     if (tmp.start[2] >= max[2]) {\r
200                         max[2] = tmp.start[2];\r
201                     }\r
202 \r
203                     if (tmp.start[0] <= min[0]) {\r
204                         min[0] = tmp.start[0];\r
205                     }\r
206 \r
207                     if (tmp.start[1] <= min[1]) {\r
208                         min[1] = tmp.start[1];\r
209                     }\r
210 \r
211                     if (tmp.start[2] <= min[2]) {\r
212                         min[2] = tmp.start[2];\r
213                     }\r
214 \r
215                     if (tmp.end[0] >= max[0]) {\r
216                         max[0] = tmp.end[0];\r
217                     }\r
218 \r
219                     if (tmp.end[1] >= max[1]) {\r
220                         max[1] = tmp.end[1];\r
221                     }\r
222 \r
223                     if (tmp.end[2] >= max[2]) {\r
224                         max[2] = tmp.end[2];\r
225                     }\r
226 \r
227                     if (tmp.end[0] <= min[0]) {\r
228                         min[0] = tmp.end[0];\r
229                     }\r
230 \r
231                     if (tmp.end[1] <= min[1]) {\r
232                         min[1] = tmp.end[1];\r
233                     }\r
234 \r
235                     if (tmp.end[2] <= min[2]) {\r
236                         min[2] = tmp.end[2];\r
237                     }\r
238                 }\r
239             }\r
240         }\r
241 \r
242         System.out.println("xmax " + max[0] + " min " + min[0]);\r
243         System.out.println("ymax " + max[1] + " min " + min[1]);\r
244         System.out.println("zmax " + max[2] + " min " + min[2]);\r
245 \r
246         width[0] = (float) Math.abs(max[0] - min[0]);\r
247         width[1] = (float) Math.abs(max[1] - min[1]);\r
248         width[2] = (float) Math.abs(max[2] - min[2]);\r
249 \r
250         maxwidth = width[0];\r
251 \r
252         if (width[1] > width[0]) {\r
253             maxwidth = width[1];\r
254         }\r
255 \r
256         if (width[2] > width[1]) {\r
257             maxwidth = width[2];\r
258         }\r
259 \r
260         System.out.println("Maxwidth = " + maxwidth);\r
261     }\r
262 \r
263     public float findScale() {\r
264         int dim;\r
265         int width;\r
266         int height;\r
267 \r
268         if (getWidth() != 0) {\r
269             width = getWidth();\r
270             height = getHeight();\r
271         } else {\r
272             width = prefsize.width;\r
273             height = prefsize.height;\r
274         }\r
275 \r
276         if (width < height) {\r
277             dim = width;\r
278         } else {\r
279             dim = height;\r
280         }\r
281 \r
282         return (float) (dim / (1.5d * maxwidth));\r
283     }\r
284 \r
285     public void findCentre() {\r
286         float xtot = 0;\r
287         float ytot = 0;\r
288         float ztot = 0;\r
289 \r
290         int bsize = 0;\r
291 \r
292         //Find centre coordinate\r
293         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
294             if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) {\r
295                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
296 \r
297                 bsize += bonds.size();\r
298 \r
299                 for (int i = 0; i < bonds.size(); i++) {\r
300                     xtot = xtot + ((Bond) bonds.elementAt(i)).start[0] +\r
301                         ((Bond) bonds.elementAt(i)).end[0];\r
302 \r
303                     ytot = ytot + ((Bond) bonds.elementAt(i)).start[1] +\r
304                         ((Bond) bonds.elementAt(i)).end[1];\r
305 \r
306                     ztot = ztot + ((Bond) bonds.elementAt(i)).start[2] +\r
307                         ((Bond) bonds.elementAt(i)).end[2];\r
308                 }\r
309             }\r
310         }\r
311 \r
312         centre[0] = xtot / (2 * (float) bsize);\r
313         centre[1] = ytot / (2 * (float) bsize);\r
314         centre[2] = ztot / (2 * (float) bsize);\r
315     }\r
316 \r
317     public void paint(Graphics g) {\r
318         //Only create the image at the beginning -\r
319         //this saves much memory usage\r
320         if ((img == null) || (prefsize.width != getWidth()) ||\r
321                 (prefsize.height != getHeight())) {\r
322             prefsize.width = getWidth();\r
323             prefsize.height = getHeight();\r
324 \r
325             scale = findScale();\r
326             img = createImage(prefsize.width, prefsize.height);\r
327             ig = img.getGraphics();\r
328 \r
329             redrawneeded = true;\r
330         }\r
331 \r
332         if (redrawneeded == true) {\r
333             drawBackground(ig, Color.black);\r
334             drawScene(ig);\r
335             redrawneeded = false;\r
336         } else {\r
337             ig = img.getGraphics();\r
338         }\r
339 \r
340         g.drawImage(img, 0, 0, this);\r
341     }\r
342 \r
343     public void drawBackground(Graphics g, Color col) {\r
344         g.setColor(col);\r
345         g.fillRect(0, 0, prefsize.width, prefsize.height);\r
346     }\r
347 \r
348     public void drawScene(Graphics g) {\r
349         // Sort the bonds by z coord\r
350         Vector bonds = new Vector();\r
351 \r
352         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
353             if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) {\r
354                 Vector tmp = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
355 \r
356                 for (int i = 0; i < tmp.size(); i++) {\r
357                     bonds.addElement(tmp.elementAt(i));\r
358                 }\r
359             }\r
360         }\r
361 \r
362         if (zbuffer) {\r
363             Zsort.Zsort(bonds);\r
364         }\r
365 \r
366         for (int i = 0; i < bonds.size(); i++) {\r
367             Bond tmpBond = (Bond) bonds.elementAt(i);\r
368 \r
369             xstart = (int) (((tmpBond.start[0] - centre[0]) * scale) +\r
370                 (getWidth() / 2));\r
371             ystart = (int) (((tmpBond.start[1] - centre[1]) * scale) +\r
372                 (getHeight() / 2));\r
373 \r
374             xend = (int) (((tmpBond.end[0] - centre[0]) * scale) +\r
375                 (getWidth() / 2));\r
376             yend = (int) (((tmpBond.end[1] - centre[1]) * scale) +\r
377                 (getHeight() / 2));\r
378 \r
379             xmid = (xend + xstart) / 2;\r
380             ymid = (yend + ystart) / 2;\r
381 \r
382             if (depthcue && !bymolecule) {\r
383                 if (tmpBond.start[2] < (centre[2] - (maxwidth / 6))) {\r
384                     g.setColor(tmpBond.startCol.darker().darker());\r
385                     drawLine(g, xstart, ystart, xmid, ymid);\r
386 \r
387                     g.setColor(tmpBond.endCol.darker().darker());\r
388                     drawLine(g, xmid, ymid, xend, yend);\r
389                 } else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6))) {\r
390                     g.setColor(tmpBond.startCol.darker());\r
391                     drawLine(g, xstart, ystart, xmid, ymid);\r
392 \r
393                     g.setColor(tmpBond.endCol.darker());\r
394                     drawLine(g, xmid, ymid, xend, yend);\r
395                 } else {\r
396                     g.setColor(tmpBond.startCol);\r
397                     drawLine(g, xstart, ystart, xmid, ymid);\r
398 \r
399                     g.setColor(tmpBond.endCol);\r
400                     drawLine(g, xmid, ymid, xend, yend);\r
401                 }\r
402             } else if (depthcue && bymolecule) {\r
403                 if (tmpBond.start[2] < (centre[2] - (maxwidth / 6))) {\r
404                     g.setColor(Color.green.darker().darker());\r
405                     drawLine(g, xstart, ystart, xend, yend);\r
406                 } else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6))) {\r
407                     g.setColor(Color.green.darker());\r
408                     drawLine(g, xstart, ystart, xend, yend);\r
409                 } else {\r
410                     g.setColor(Color.green);\r
411                     drawLine(g, xstart, ystart, xend, yend);\r
412                 }\r
413             } else if (!depthcue && !bymolecule) {\r
414                 g.setColor(tmpBond.startCol);\r
415                 drawLine(g, xstart, ystart, xmid, ymid);\r
416                 g.setColor(tmpBond.endCol);\r
417                 drawLine(g, xmid, ymid, xend, yend);\r
418             } else {\r
419                 drawLine(g, xstart, ystart, xend, yend);\r
420             }\r
421         }\r
422     }\r
423 \r
424     public void drawLine(Graphics g, int x1, int y1, int x2, int y2) {\r
425         if (!wire) {\r
426             if (((float) Math.abs(y2 - y1) / (float) Math.abs(x2 - x1)) < 0.5) {\r
427                 g.drawLine(x1, y1, x2, y2);\r
428                 g.drawLine(x1 + 1, y1 + 1, x2 + 1, y2 + 1);\r
429                 g.drawLine(x1, y1 - 1, x2, y2 - 1);\r
430             } else {\r
431                 g.setColor(g.getColor().brighter());\r
432                 g.drawLine(x1, y1, x2, y2);\r
433                 g.drawLine(x1 + 1, y1, x2 + 1, y2);\r
434                 g.drawLine(x1 - 1, y1, x2 - 1, y2);\r
435             }\r
436         } else {\r
437             g.drawLine(x1, y1, x2, y2);\r
438         }\r
439     }\r
440 \r
441     public Dimension minimumsize() {\r
442         return prefsize;\r
443     }\r
444 \r
445     public Dimension preferredsize() {\r
446         return prefsize;\r
447     }\r
448 \r
449     public void keyTyped(KeyEvent evt) {\r
450     }\r
451 \r
452     public void keyReleased(KeyEvent evt) {\r
453     }\r
454 \r
455     public void keyPressed(KeyEvent evt) {\r
456         int key = evt.getKeyChar();\r
457 \r
458         if (evt.getKeyCode() == KeyEvent.VK_UP) {\r
459             scale = (float) (scale * 1.1);\r
460             redrawneeded = true;\r
461             repaint();\r
462         } else if (evt.getKeyCode() == KeyEvent.VK_DOWN) {\r
463             scale = (float) (scale * 0.9);\r
464             redrawneeded = true;\r
465             repaint();\r
466         } else if (key == 'w') {\r
467             wire = !wire;\r
468             System.out.println("wireframe " + wire);\r
469             redrawneeded = true;\r
470             repaint();\r
471         } else if (key == 'd') {\r
472             depthcue = !depthcue;\r
473             System.out.println("Depth cueing is " + depthcue);\r
474             redrawneeded = true;\r
475             repaint();\r
476         } else if (key == 'm') {\r
477             bymolecule = !bymolecule;\r
478             System.out.println("Bymolecule is " + bymolecule);\r
479             redrawneeded = true;\r
480             repaint();\r
481         } else if (key == 'z') {\r
482             zbuffer = !zbuffer;\r
483             System.out.println("Z buffering is " + zbuffer);\r
484             redrawneeded = true;\r
485             repaint();\r
486         } else if (key == 'c') {\r
487             bymolecule = false;\r
488             pdb.setChainColours();\r
489             System.out.println("Colouring by chain");\r
490             redrawneeded = true;\r
491             repaint();\r
492         } else if (key == 'h') {\r
493             bymolecule = false;\r
494             pdb.setHydrophobicityColours();\r
495             System.out.println("Colouring by hydrophobicity");\r
496             redrawneeded = true;\r
497             repaint();\r
498         } else if (key == 'q') {\r
499             bymolecule = false;\r
500             pdb.setChargeColours();\r
501             System.out.println("Colouring charges and cysteines");\r
502             redrawneeded = true;\r
503             repaint();\r
504         }\r
505 \r
506         return;\r
507     }\r
508 \r
509     public void mousePressed(MouseEvent e) {\r
510         mx = e.getX();\r
511         my = e.getY();\r
512         omx = mx;\r
513         omy = my;\r
514         dragging = false;\r
515     }\r
516 \r
517     public void mouseMoved(MouseEvent e) {\r
518         myAtom fatom = null;\r
519 \r
520         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
521             PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
522 \r
523             if (chain.isVisible) {\r
524                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
525 \r
526                 for (int i = 0; i < bonds.size(); i++) {\r
527                     Bond tmpBond = (Bond) bonds.elementAt(i);\r
528                     int truex = (int) (((tmpBond.start[0] - centre[0]) * scale) +\r
529                         (getWidth() / 2));\r
530 \r
531                     if (Math.abs(truex - e.getX()) <= 2) {\r
532                         int truey = (int) (((tmpBond.start[1] - centre[1]) * scale) +\r
533                             (getHeight() / 2));\r
534 \r
535                         if (Math.abs(truey - e.getY()) <= 2) {\r
536                             fatom = tmpBond.at1;\r
537                         }\r
538                     }\r
539                 }\r
540             }\r
541         }\r
542 \r
543         if (fatom != null) {\r
544             this.setToolTipText(fatom.resName);\r
545         } else {\r
546             this.setToolTipText(null);\r
547         }\r
548     }\r
549 \r
550     public void mouseClicked(MouseEvent e) {\r
551     }\r
552 \r
553     public void mouseEntered(MouseEvent e) {\r
554     }\r
555 \r
556     public void mouseExited(MouseEvent e) {\r
557     }\r
558 \r
559     public void mouseDragged(MouseEvent evt) {\r
560         int x = evt.getX();\r
561         int y = evt.getY();\r
562         mx = x;\r
563         my = y;\r
564 \r
565         MCMatrix objmat = new MCMatrix(3, 3);\r
566         objmat.setIdentity();\r
567 \r
568         if ((evt.getModifiers() & Event.META_MASK) != 0) {\r
569             objmat.rotatez((float) ((mx - omx)));\r
570         } else {\r
571             objmat.rotatex((float) ((my - omy)));\r
572             objmat.rotatey((float) ((omx - mx)));\r
573         }\r
574 \r
575         //Alter the bonds\r
576         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
577             Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
578 \r
579             for (int i = 0; i < bonds.size(); i++) {\r
580                 Bond tmpBond = (Bond) bonds.elementAt(i);\r
581 \r
582                 //Translate the bond so the centre is 0,0,0\r
583                 tmpBond.translate(-centre[0], -centre[1], -centre[2]);\r
584 \r
585                 //Now apply the rotation matrix\r
586                 tmpBond.start = objmat.vectorMultiply(tmpBond.start);\r
587                 tmpBond.end = objmat.vectorMultiply(tmpBond.end);\r
588 \r
589                 //Now translate back again\r
590                 tmpBond.translate(centre[0], centre[1], centre[2]);\r
591             }\r
592         }\r
593 \r
594         objmat = null;\r
595 \r
596         omx = mx;\r
597         omy = my;\r
598 \r
599         redrawneeded = true;\r
600 \r
601         paint(this.getGraphics());\r
602 \r
603         dragging = true;\r
604 \r
605         return;\r
606     }\r
607 \r
608     public void mouseReleased(MouseEvent evt) {\r
609         //int x = evt.getX();\r
610         //int y = evt.getY();\r
611 \r
612         //if (!dragging) {\r
613           //  myAtom tmp = findAtom(x, y);\r
614         //}\r
615 \r
616         drawLabels();\r
617 \r
618         return;\r
619     }\r
620 \r
621     public void drawLabels() {\r
622         redrawneeded = true;\r
623         paint(this.getGraphics());\r
624 \r
625         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
626             PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
627 \r
628             if (chain.isVisible) {\r
629                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
630 \r
631                 for (int i = 0; i < bonds.size(); i++) {\r
632                     Bond tmpBond = (Bond) bonds.elementAt(i);\r
633 \r
634                     if (tmpBond.at1.isSelected) {\r
635                         labelAtom(img.getGraphics(), tmpBond, 1);\r
636                     }\r
637 \r
638                     if (tmpBond.at2.isSelected) {\r
639                         labelAtom(img.getGraphics(), tmpBond, 2);\r
640                     }\r
641                 }\r
642             }\r
643         }\r
644 \r
645         this.getGraphics().drawImage(img, 0, 0, this);\r
646 \r
647         dragging = false;\r
648     }\r
649 \r
650     public void labelAtom(Graphics g, Bond b, int n) {\r
651         g.setFont(font);\r
652 \r
653         if (n == 1) {\r
654             int xstart = (int) (((b.start[0] - centre[0]) * scale) +\r
655                 (getWidth() / 2));\r
656             int ystart = (int) (((b.start[1] - centre[1]) * scale) +\r
657                 (getHeight() / 2));\r
658 \r
659             g.setColor(Color.red);\r
660             g.drawString(b.at1.resName + "-" + b.at1.resNumber, xstart, ystart);\r
661         }\r
662 \r
663         if (n == 2) {\r
664             int xstart = (int) (((b.end[0] - centre[0]) * scale) +\r
665                 (getWidth() / 2));\r
666             int ystart = (int) (((b.end[1] - centre[1]) * scale) +\r
667                 (getHeight() / 2));\r
668 \r
669             g.setColor(Color.red);\r
670             g.drawString(b.at2.resName + "-" + b.at2.resNumber, xstart, ystart);\r
671         }\r
672     }\r
673 \r
674     public myAtom findAtom(int x, int y) {\r
675         myAtom fatom = null;\r
676 \r
677         int foundchain = -1;\r
678 \r
679         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
680             PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
681 \r
682             if (chain.isVisible) {\r
683                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
684 \r
685                 for (int i = 0; i < bonds.size(); i++) {\r
686                     Bond tmpBond = (Bond) bonds.elementAt(i);\r
687 \r
688                     int truex = (int) (((tmpBond.start[0] - centre[0]) * scale) +\r
689                         (getWidth() / 2));\r
690 \r
691                     if (Math.abs(truex - x) <= 2) {\r
692                         int truey = (int) (((tmpBond.start[1] - centre[1]) * scale) +\r
693                             (getHeight() / 2));\r
694 \r
695                         if (Math.abs(truey - y) <= 2) {\r
696                             System.out.println("Found match");\r
697                             System.out.println(x + " " + y);\r
698                             System.out.println(truex + " " + truey);\r
699                             System.out.println(tmpBond.start[0] + " " +\r
700                                 tmpBond.start[1]);\r
701                             System.out.println("Atom 1 = " +\r
702                                 tmpBond.at1.resName + " " +\r
703                                 tmpBond.at1.resNumber + " " +\r
704                                 tmpBond.at1.chain);\r
705                             fatom = tmpBond.at1;\r
706                             fatom.isSelected = !fatom.isSelected;\r
707                             foundchain = ii;\r
708                         }\r
709                     }\r
710                 }\r
711             }\r
712 \r
713             if (fatom != null) //)&& chain.ds != null)\r
714              {\r
715                 chain = (PDBChain) pdb.chains.elementAt(foundchain);\r
716 \r
717                 // SMJS TODO\r
718                 // int tmp = chain.ds.seqstart + fatom.resNumber - chain.offset;\r
719                 // int pos = chain.ds.findIndex(tmp);\r
720                 // System.out.println("Found seq " + chain.ds.name + " "  + tmp + " " + pos);\r
721             }\r
722         }\r
723 \r
724         return fatom;\r
725     }\r
726 \r
727     public void update(Graphics g) {\r
728         paint(g);\r
729     }\r
730 }\r