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