001/*
002 *                  BioJava development code
003 *
004 * This code may be freely distributed and modified under the
005 * terms of the GNU Lesser General Public Licence.  This should
006 * be distributed with the code.  If you do not have a copy,
007 * see:
008 *
009 *      http://www.gnu.org/copyleft/lesser.html
010 *
011 * Copyright for this code is held jointly by the individual
012 * authors.  These should be listed in @author doc comments.
013 *
014 * For more information on the BioJava project and its aims,
015 * or to join the biojava-l mailing list, visit the home page
016 * at:
017 *
018 *      http://www.biojava.org/
019 *
020 * Created on Jul 16, 2006
021 *
022 */
023package org.biojava.nbio.structure.gui.util;
024
025import org.biojava.nbio.structure.*;
026import org.biojava.nbio.structure.align.StructurePairAligner;
027import org.biojava.nbio.structure.align.pairwise.AlternativeAlignment;
028import org.biojava.nbio.structure.gui.BiojavaJmol;
029import org.biojava.nbio.structure.gui.ScaleableMatrixPanel;
030import org.biojava.nbio.structure.gui.SequenceDisplay;
031import org.biojava.nbio.structure.gui.events.JmolAlignedPositionListener;
032import org.biojava.nbio.structure.jama.Matrix;
033import org.slf4j.Logger;
034import org.slf4j.LoggerFactory;
035
036import javax.swing.*;
037import javax.swing.table.TableCellRenderer;
038import java.awt.*;
039import java.awt.event.MouseEvent;
040import java.awt.event.MouseListener;
041import java.awt.event.WindowAdapter;
042import java.awt.event.WindowEvent;
043import java.text.MessageFormat;
044import java.util.List;
045
046
047/** a frame showing the alternative alignments, which are the result of a structure superimposition
048 *
049 * @author Andreas Prlic
050 * @since 1.7
051 * @version %I% %G%
052 */
053public class AlternativeAlignmentFrame
054extends JFrame{
055
056        private static final long serialVersionUID=0l;
057
058
059        private static final Logger logger = LoggerFactory.getLogger(AlternativeAlignmentFrame.class);
060
061        private static String[] columnNames = new String[]{"#","eqr","score", "rms", "gaps","cluster", "show distance matrix","show alignment"};
062
063        AlternativeAlignment[] aligs;
064        JPanel panel;
065
066        Structure structure1;
067        Structure structure2;
068        StructurePairAligner structurePairAligner;
069
070        public AlternativeAlignmentFrame(Structure s1, Structure s2) {
071                super();
072                panel = new JPanel();
073                panel.setPreferredSize(new Dimension(800,400));
074                this.getContentPane().add(panel);
075
076
077                structure1  = s1;
078                structure2  = s2;
079                String pdb1 = s1.getPDBCode();
080                String pdb2 = s2.getPDBCode();
081
082                String t = "Alternative Alignments";
083                Object[] args = {pdb1,pdb2};
084
085                String title =  MessageFormat.format(t,args);
086                this.setTitle(title);
087        }
088
089        public void setStructurePairAligner(StructurePairAligner aligner){
090                this.structurePairAligner = aligner;
091        }
092
093        public void setAlternativeAlignments(AlternativeAlignment[] aligs) {
094                this.aligs = aligs;
095                panel.removeAll();
096
097                //Box vBox = Box.createVerticalBox();
098                //panel.add(vBox);
099
100                Object[][] data = getDataFromAligs(aligs);
101                JTableDataButtonModel model = new JTableDataButtonModel(data, columnNames);
102                JTable table = new JTable(model);
103
104
105                TableCellRenderer defaultRenderer = table.getDefaultRenderer(JButton.class);
106
107                JButtonTableCellRenderer myRenderer = new JButtonTableCellRenderer(defaultRenderer);
108
109                table.setDefaultRenderer(JButton.class, myRenderer);
110
111                table.addMouseListener(new JTableMouseButtonListener(table));
112
113                JScrollPane scrollPane = new JScrollPane(table);
114                scrollPane.setPreferredSize(new Dimension(800,400));
115                //vBox.add(e);
116                panel.add(scrollPane);
117
118
119        }
120
121        private Object[][] getDataFromAligs(AlternativeAlignment[] aligs){
122
123
124                Object[][] data = new Object[aligs.length][columnNames.length];
125
126                for ( int i=0;i< aligs.length;i++){
127                        AlternativeAlignment alig = aligs[i];
128
129                        data[i][0] = new Integer(i+1);
130                        data[i][1] = new Integer(alig.getEqr());
131                        data[i][2] = new Double(alig.getScore());
132                        data[i][3] = new Double(alig.getRmsd());
133                        data[i][4] = new Integer(alig.getGaps());
134                        data[i][5] = new Integer(alig.getCluster());
135                        JButton maxb = new JButton("Distance Matrix");
136                        maxb.addMouseListener(new MatrixMouseListener(this,i));
137
138                        data[i][6] = maxb;
139
140
141                        //Action action1 = new MyButtonAction(t,this,i);
142                        JButton but = new JButton("Show in Jmol");
143                        but.addMouseListener(new MyButtonMouseListener(this,i));
144                        data[i][7] = but;
145
146
147                }
148                return data;
149        }
150
151        public void showDistanceMatrix(int position){
152                if ( position > aligs.length){
153                        return;
154                }
155                AlternativeAlignment alig = aligs[position];
156                logger.info("display distance matrix for alternative alignment " + (position +1));
157
158                ScaleableMatrixPanel smp = new ScaleableMatrixPanel();
159                JFrame frame = new JFrame();
160                frame.setTitle("Alt. Alig [" + position+"] - Distance Matrix & path");
161
162                frame.addWindowListener(new WindowAdapter(){
163                        @Override
164                        public void windowClosing(WindowEvent e){
165                                JFrame f = (JFrame) e.getSource();
166                                f.setVisible(false);
167                                f.dispose();
168                        }
169
170
171
172                });
173
174                smp.setMatrix(alig.getDistanceMatrix());
175                smp.setAlternativeAligs(new AlternativeAlignment[]{alig});
176
177                frame.getContentPane().add(smp);
178
179                frame.pack();
180                frame.setVisible(true);
181
182        }
183
184        public void showAlternative(int position){
185                if ( position > aligs.length){
186                        return;
187                }
188                AlternativeAlignment alig = aligs[position];
189                logger.info("display alternative alignment " + (position +1));
190
191                // create the structure alignment object and tell the listeners ...
192
193
194//              Matrix m1 = Matrix.identity(3,3);
195                Matrix m2 = alig.getRotationMatrix();
196
197                String pdb1 = structure1.getPDBCode();
198                String pdb2 = structure2.getPDBCode();
199
200
201                Atom shift1 = new AtomImpl();
202                shift1.setCoords(new double[]{0,0,1});
203                Atom shift2 = alig.getShift();
204
205                Structure s3 = structure2.clone();
206
207                Calc.rotate(s3,m2);
208                Calc.shift(s3,shift2);
209
210                BiojavaJmol jmol = new BiojavaJmol();
211                jmol.setTitle(pdb1 + " vs. " + pdb2);
212
213                Structure n = new StructureImpl();
214
215                List<Chain> chains1 = structure1.getChains();
216
217                n.addModel(chains1);
218
219                List<Chain> chains3 = s3.getChains();
220                n.addModel(chains3);
221
222                jmol.setStructure(n);
223                String[] cmds = createRasmolScripts(alig);
224                jmol.evalString("model 0 ; select * ; wireframe off ; spacefill off; backbone 0.3;");
225                jmol.evalString(cmds[0]);
226                jmol.evalString(cmds[1]);
227
228                JFrame frame = new JFrame("Sequences for AlternativeAlignment ["+position+"]");
229
230                SequenceDisplay seqdisp;
231                seqdisp =  new SequenceDisplay(structurePairAligner);
232                seqdisp.setStructure1(structure1);
233                seqdisp.setStructure2(structure2);
234
235                seqdisp.setAlternativeAlignment(alig);
236
237                frame.getContentPane().add(seqdisp);
238
239                frame.pack();
240                frame.setVisible(true);
241                frame.addWindowListener(new WindowAdapter(){
242                        @Override
243                        public void windowClosing(WindowEvent e){
244                                JFrame f = (JFrame) e.getSource();
245                                f.setVisible(false);
246                                f.dispose();
247                        }
248
249
250
251                });
252
253                seqdisp.updateDisplay();
254
255                JmolAlignedPositionListener jmolBridge = new JmolAlignedPositionListener(jmol,structurePairAligner);
256                jmolBridge.setStructure1(structure1);
257                jmolBridge.setStructure2(s3);
258
259                seqdisp.addAlignmentPositionListener(jmolBridge);
260
261        }
262
263
264
265        private String[] createRasmolScripts(AlternativeAlignment alig){
266                String[] scripts = new String[2];
267
268                Color col1 = Color.red;
269                Color col2 = Color.blue;
270
271                Color chaincol1 = new Color(col1.getRed()/2,col1.getGreen()/2,col1.getBlue()/2);
272                Color chaincol2 = new Color(col2.getRed()/2,col2.getGreen()/2,col2.getBlue()/2);
273
274
275
276                String cmd1 = "";
277                String cmd2 = "";
278
279                cmd1 += "select */"+1+"; ";
280                cmd1 += " color [" +chaincol1.getRed()+","+chaincol1.getGreen() +","+chaincol1.getBlue() +"];";
281
282                cmd2 += "select */"+2+"; ";
283                cmd2 += " color [" +chaincol2.getRed()+","+chaincol2.getGreen() +","+chaincol2.getBlue() +"];";
284
285                cmd1 += "select ";
286                cmd2 += "select ";
287
288                String[] pdb1s = alig.getPDBresnum1();
289                String[] pdb2s = alig.getPDBresnum2();
290
291
292                for ( int i =0 ; i< pdb1s.length;i++){
293
294                        String p1 = pdb1s[i];
295                        String p2 = pdb2s[i];
296
297                        cmd1 += p1 +"/1";
298                        cmd2 += p2 +"/2";
299
300                        if ( i <= pdb1s.length -2){
301                                cmd1 += ",";
302                                cmd2 += ",";
303                        }
304                }
305
306                cmd1 += "; color [" +col1.getRed()+","+col1.getGreen() +","+col1.getBlue() +"];";
307                cmd1 += " backbone 0.6;";
308
309                cmd2 += "; color [" +col2.getRed()+","+col2.getGreen() +","+col2.getBlue() +"];";
310                cmd2 += " backbone 0.6;";
311
312                //System.out.println(cmd1);
313                scripts[0] = cmd1;
314                scripts[1] = cmd2;
315
316                return scripts;
317        }
318
319
320
321
322}
323
324class MyButtonMouseListener implements MouseListener{
325        AlternativeAlignmentFrame parent;
326        int pos;
327        public MyButtonMouseListener(AlternativeAlignmentFrame parent, int position){
328
329                this.parent = parent;
330                this.pos = position;
331        }
332
333
334
335        @Override
336        public void mouseClicked(MouseEvent arg0) {
337
338
339        }
340
341        @Override
342        public void mousePressed(MouseEvent arg0) {
343
344        }
345
346        @Override
347        public void mouseReleased(MouseEvent arg0) {
348                parent.showAlternative(pos);
349
350        }
351
352        @Override
353        public void mouseEntered(MouseEvent arg0) {
354
355        }
356
357        @Override
358        public void mouseExited(MouseEvent arg0) {
359
360        }
361
362}
363
364class MatrixMouseListener implements MouseListener{
365        AlternativeAlignmentFrame parent;
366        int pos;
367        public MatrixMouseListener( AlternativeAlignmentFrame parent, int position){
368
369                this.parent = parent;
370                this.pos = position;
371        }
372
373        @Override
374        public void mouseClicked(MouseEvent arg0) {}
375        @Override
376        public void mousePressed(MouseEvent arg0) {}
377
378        @Override
379        public void mouseReleased(MouseEvent arg0) {
380                parent.showDistanceMatrix(pos);
381
382        }
383
384
385        @Override
386        public void mouseEntered(MouseEvent arg0) { }
387
388        @Override
389        public void mouseExited(MouseEvent arg0) {}
390
391}
392