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.align.gui;
024
025import java.awt.Dimension;
026import java.awt.event.ActionEvent;
027import java.io.File;
028import java.io.IOException;
029
030import javax.swing.AbstractAction;
031import javax.swing.Action;
032import javax.swing.Box;
033import javax.swing.JButton;
034import javax.swing.JComboBox;
035import javax.swing.JFrame;
036import javax.swing.JLabel;
037import javax.swing.JMenuBar;
038import javax.swing.JOptionPane;
039import javax.swing.JProgressBar;
040import javax.swing.JTabbedPane;
041
042import org.biojava.nbio.structure.Structure;
043import org.biojava.nbio.structure.StructureException;
044import org.biojava.nbio.structure.align.StructureAlignment;
045import org.biojava.nbio.structure.align.StructureAlignmentFactory;
046import org.biojava.nbio.structure.align.ce.AbstractUserArgumentProcessor;
047import org.biojava.nbio.structure.align.util.ResourceManager;
048import org.biojava.nbio.structure.align.util.UserConfiguration;
049import org.biojava.nbio.structure.align.webstart.AligUIManager;
050import org.biojava.nbio.structure.align.webstart.WebStartMain;
051import org.biojava.nbio.structure.gui.util.PDBUploadPanel;
052import org.biojava.nbio.structure.gui.util.ScopSelectPanel;
053import org.biojava.nbio.structure.gui.util.StructurePairSelector;
054
055/** A JFrame that allows to trigger a pairwise structure alignment,
056 * either from files in a directory,
057 * or after manual upload.
058 *
059 * @author Andreas Prlic
060 *
061 * @since 1.7
062 *
063 *
064 *
065 */
066public class AlignmentGui extends JFrame{
067
068        private final static long serialVersionUID =0l;
069
070        StructureAlignment algorithm;
071
072        JButton abortB;
073
074        SelectPDBPanel  tab1 ;
075        PDBUploadPanel  tab2;
076        ScopSelectPanel tab3;
077
078        Thread thread;
079        AlignmentCalculationRunnable alicalc;
080        JTabbedPane masterPane;
081        JTabbedPane tabPane;
082        JProgressBar progress;
083
084
085        private DBSearchGUI dbsearch;
086
087
088        public static void main(String[] args){
089
090                AlignmentGui.getInstance();
091
092        }
093
094        static final ResourceManager resourceManager = ResourceManager.getResourceManager("ce");
095
096        private static final String MAIN_TITLE = "Pairwise Structure Alignment - Main - V." + resourceManager.getString("ce.version");;
097
098        private static final AlignmentGui me = new AlignmentGui();
099
100        public static AlignmentGui getInstance(){
101
102                AbstractUserArgumentProcessor.printAboutMe();
103
104                AligUIManager.setLookAndFeel();
105
106                if (!  me.isVisible())
107                        me.setVisible(true);
108
109                if ( ! me.isActive())
110                        me.requestFocus();
111
112
113                return me;
114        }
115
116        public static AlignmentGui getInstanceNoVisibilityChange(){
117
118                return me;
119        }
120
121
122        protected AlignmentGui() {
123                super();
124
125                thread = null;
126
127                JMenuBar menu = MenuCreator.initAlignmentGUIMenu(this);
128
129                this.setJMenuBar(menu);
130
131                this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
132
133                this.setTitle(MAIN_TITLE);
134
135                tab1 = new SelectPDBPanel();
136                tab2 = new PDBUploadPanel();
137                tab3 = new ScopSelectPanel();
138
139                // setup tabPane
140                tabPane = new JTabbedPane();
141
142                tabPane.addTab("Select PDB ID", null, tab1, "Select PDB ID to align");
143
144                tabPane.addTab("Domains",null, tab3,"Select domains to align.");
145
146                tabPane.addTab("Custom files",null, tab2,"Align your own files.");
147
148
149
150                Box hBoxAlgo = setupAlgorithm();
151
152                Box vBox = Box.createVerticalBox();
153
154
155                //vBox.add(hBoxAlgo);
156
157                vBox.add(tabPane);
158                vBox.add(Box.createGlue());
159
160                //vBox.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
161
162                masterPane = new JTabbedPane();
163
164                masterPane.addTab("Pairwise Comparison", vBox);
165
166                dbsearch = new DBSearchGUI();
167
168                masterPane.addTab("Database Search",dbsearch);
169
170                //JPanel dir = tab1.getPDBDirPanel(pdbDir);
171
172                Box vBoxMain = Box.createVerticalBox();
173                vBoxMain.add(hBoxAlgo);
174
175                // pairwise or db search
176
177                vBoxMain.add(masterPane);
178
179                // algorithm selection
180
181                // PDB install config
182                //vBoxMain.add(dir);
183                // buttons
184                vBoxMain.add(initButtons());
185
186                this.getContentPane().add(vBoxMain);
187
188                //SwingUtilities.updateComponentTreeUI( me);
189
190                this.pack();
191                this.setVisible(true);
192
193
194        }
195
196        private Box setupAlgorithm()
197        {
198                String[] algorithms = StructureAlignmentFactory.getAllAlgorithmNames();
199                try {
200                        algorithm = StructureAlignmentFactory.getAlgorithm(algorithms[0]);
201                } catch (StructureException e){
202                        e.printStackTrace();
203                }
204
205                JLabel algoLabel = new JLabel("Select alignment algorithm: ");
206
207                JComboBox algorithmList = new JComboBox(algorithms);
208                algorithmList.setSelectedIndex(0);
209
210                Action actionAlgorithm = new AbstractAction("Algorithm") {
211                        public static final long serialVersionUID = 0l;
212                        // This method is called when the button is pressed
213                        @Override
214                        public void actionPerformed(ActionEvent evt) {
215                                JComboBox cb = (JComboBox)evt.getSource();
216                                String algorithmName = (String)cb.getSelectedItem();
217                                // Perform action...
218                                //System.out.println("calc structure alignment");
219                                updateAlgorithm(algorithmName);
220
221                        }
222                };
223
224
225                algorithmList.addActionListener(actionAlgorithm);
226
227
228                Action paramAction = new AbstractAction("Parameters") {
229                        public static final long serialVersionUID = 0l;
230                        // This method is called when the button is pressed
231                        @Override
232                        public void actionPerformed(ActionEvent evt) {
233                                // Perform action...
234                                //System.out.println("calc structure alignment");
235                                configureParameters();
236
237                        }
238
239                };
240
241                JButton parameterButton = new JButton(paramAction);
242
243
244
245                Box hBoxAlgo = Box.createHorizontalBox();
246                hBoxAlgo.add(Box.createGlue());
247                hBoxAlgo.add(algoLabel);
248                hBoxAlgo.add(algorithmList);
249                hBoxAlgo.add(Box.createGlue());
250                hBoxAlgo.add(parameterButton);
251                hBoxAlgo.add(Box.createGlue());
252                return hBoxAlgo;
253        }
254
255
256
257
258
259        private Box initButtons(){
260
261                //        Box hBox42 = Box.createHorizontalBox();
262                progress =new JProgressBar();
263                progress.setIndeterminate(false);
264                progress.setMaximumSize(new Dimension(10,100));
265                progress.setVisible(false);
266
267                //        hBox42.add(Box.createGlue());
268                //        hBox42.add(progress);
269                //        hBox42.add(Box.createGlue());
270                //        vBox.add(hBox42);
271                Action action1 = new AbstractAction("Align") {
272                        public static final long serialVersionUID = 0l;
273                        // This method is called when the button is pressed
274                        @Override
275                        public void actionPerformed(ActionEvent evt) {
276                                // Perform action...
277                                //System.out.println("calc structure alignment");
278                                int selectedIndex = masterPane.getSelectedIndex();
279                                if (selectedIndex == 0)
280                                        calcAlignment();
281                                else if ( selectedIndex == 1)
282                                        calcDBSearch();
283                                else {
284                                        System.err.println("Unknown TAB: " + selectedIndex);
285                                }
286
287                        }
288                };
289
290                JButton submitB = new JButton(action1);
291
292                Action action3 = new AbstractAction("Abort") {
293                        public static final long serialVersionUID = 0l;
294                        // This method is called when the button is pressed
295                        @Override
296                        public void actionPerformed(ActionEvent evt) {
297                                // Perform action...
298                                abortCalc();
299                        }
300                };
301
302                abortB = new JButton(action3);
303
304                abortB.setEnabled(false);
305
306                Action action2 = new AbstractAction("Exit") {
307                        public static final long serialVersionUID = 0l;
308                        // This method is called when the button is pressed
309                        @Override
310                        public void actionPerformed(ActionEvent evt) {
311                                // Perform action...
312                                abortCalc();
313                                dispose();
314                                System.exit(0);
315                        }
316                };
317                JButton closeB = new JButton(action2);
318                Box hBox = Box.createHorizontalBox();
319                hBox.add(closeB);
320                hBox.add(Box.createGlue());
321                hBox.add(progress);
322                hBox.add(abortB);
323                //hBox.add(Box.createGlue());
324                hBox.add(submitB);
325
326                return hBox;
327        }
328
329        protected void configureParameters() {
330                StructureAlignment algorithm = getStructureAlignment();
331                System.out.println("configure parameters for " + algorithm.getAlgorithmName());
332
333                // show a new config GUI
334                new ParameterGUI(algorithm.getParameters(), algorithm.getAlgorithmName());
335        }
336
337
338
339        public void cleanUp() {
340
341                if ( alicalc != null) {
342                        alicalc.cleanup();
343                }
344        }
345
346
347
348
349
350        private void calcAlignment() {
351
352                int pos = tabPane.getSelectedIndex();
353                StructurePairSelector tab = null;
354
355                if (pos == 0 ){
356                        tab = tab1;
357
358                } else if (pos == 1){
359                        tab = tab3;
360
361                } else if (pos == 2){
362                        tab = tab2;
363                }
364
365
366                try {
367                        Structure s1 = tab.getStructure1();
368                        Structure s2 = tab.getStructure2();
369
370                        if ( s1 == null) {
371                                System.err.println("please select structure 1");
372                                return ;
373                        }
374
375                        if ( s2 == null) {
376                                System.err.println("please select structure 2");
377                                return;
378                        }
379
380                        String name1 = "custom1";
381                        String name2 = "custom2";
382
383                        if  ( pos == 0){
384                                name1 = tab1.getName1().getIdentifier();
385                                name2 = tab1.getName2().getIdentifier();
386                        } else {
387                                name1 = s1.getName();
388                                name2 = s2.getName();
389                        }
390
391                        System.out.println("aligning: " + name1 + " " + name2);
392
393
394                        alicalc = new AlignmentCalc(this,s1,s2, name1, name2);
395
396
397                        thread = new Thread(alicalc);
398                        thread.start();
399                        abortB.setEnabled(true);
400                        progress.setIndeterminate(true);
401                        ProgressThreadDrawer drawer = new ProgressThreadDrawer(progress);
402                        drawer.start();
403                } catch (StructureException e){
404                        JOptionPane.showMessageDialog(null,"Could not align structures. Exception: " + e.getMessage());
405                } catch (IOException e) {
406                        JOptionPane.showMessageDialog(null,"Could not align structures. Exception: " + e.getMessage());
407                }
408
409        }
410
411
412        private void calcDBSearch() {
413
414                JTabbedPane tabPane = dbsearch.getTabPane();
415                System.out.println("run DB search " + tabPane.getSelectedIndex());
416
417                Structure s = null;
418                boolean domainSplit = dbsearch.isDomainSplit();
419
420                StructurePairSelector tab = null;
421                int pos = tabPane.getSelectedIndex();
422
423                if (pos == 0 ){
424
425                        tab = dbsearch.getSelectPDBPanel();
426
427                }  else if (pos == 1){
428
429                        tab = dbsearch.getScopSelectPanel();
430
431
432                } else if (pos == 2){
433
434                        tab = dbsearch.getPDBUploadPanel();
435
436                }
437
438                try {
439
440                        s = tab.getStructure1();
441
442                        if ( s == null) {
443                                JOptionPane.showMessageDialog(null,"please select structure 1");
444                                return ;
445                        }
446
447                } catch (Exception e){
448                        e.printStackTrace();
449                }
450
451                String name1 = s.getName();
452                if ( name1 == null || name1.equals(""))
453                        name1 = s.getPDBCode();
454
455
456
457                System.out.println("name1 in alig gui:" + name1);
458                String file = dbsearch.getOutFileLocation();
459                if ( file == null || file.equals("") ){
460                        JOptionPane.showMessageDialog(null,"Please select a directory to contain the DB search results.");
461                        return;
462                }
463                File outFile = new File(file);
464                if( !outFile.exists() ) {
465                        outFile.mkdirs();
466                }
467                if( !outFile.isDirectory() || !outFile.canWrite()) {
468                        JOptionPane.showMessageDialog(null,"Unable to write to "+outFile.getAbsolutePath());
469                        return;
470                }
471
472                UserConfiguration config = WebStartMain.getWebStartConfig();
473
474                int totalNrCPUs = Runtime.getRuntime().availableProcessors();
475
476                int useNrCPUs = 1;
477                if ( totalNrCPUs > 1){
478                        Object[] options = new Integer[totalNrCPUs];
479                        int posX = 0;
480                        for ( int i = totalNrCPUs; i> 0 ; i--){
481                                options[posX] = i;
482                                posX++;
483                        }
484                        int n = JOptionPane.showOptionDialog(null,
485                                        "How many would you like to use for the calculations?",
486                                        "We detected " + totalNrCPUs + " processors on your system.",
487                                        JOptionPane.OK_CANCEL_OPTION,
488                                        JOptionPane.QUESTION_MESSAGE,
489                                        null,
490                                        options,
491                                        options[0]);
492
493                        if ( n < 0)
494                                return;
495                        useNrCPUs = (Integer) options[n];
496                        System.out.println("will use " + useNrCPUs + " CPUs." );
497                }
498                System.out.println("using domainSplit data");
499                alicalc = new AlignmentCalcDB(this, s,  name1,config,file, domainSplit);
500                alicalc.setNrCPUs(useNrCPUs);
501                abortB.setEnabled(true);
502                progress.setIndeterminate(true);
503                ProgressThreadDrawer drawer = new ProgressThreadDrawer(progress);
504                drawer.start();
505
506                Thread t = new Thread(alicalc);
507                t.start();
508        }
509
510
511        public DBSearchGUI getDBSearch(){
512                return dbsearch;
513        }
514
515        public void notifyCalcFinished(){
516                abortB.setEnabled(false);
517                thread = null;
518                progress.setIndeterminate(false);
519                this.repaint();
520        }
521
522        private void abortCalc(){
523                System.err.println("Interrupting alignment ...");
524                if ( alicalc != null )
525                        alicalc.interrupt();
526                notifyCalcFinished();
527
528
529        }
530
531
532        public StructureAlignment getStructureAlignment() {
533
534                return algorithm;
535        }
536
537        private void updateAlgorithm(String algorithmName) {
538
539                //String algorithmName = (String)algorithmList.getSelectedItem();
540                try {
541                        algorithm = StructureAlignmentFactory.getAlgorithm(algorithmName);
542                } catch (StructureException ex){
543                        ex.printStackTrace();
544                }
545
546        }
547
548}
549
550class ProgressThreadDrawer extends Thread {
551
552        JProgressBar progress;
553        static int interval = 300;
554
555        public ProgressThreadDrawer(JProgressBar progress) {
556                this.progress = progress;
557        }
558
559
560        @Override
561        public void run() {
562                progress.setVisible(true);
563                boolean finished = false;
564                while ( ! finished) {
565                        try {
566                                progress.repaint();
567                                if ( ! progress.isIndeterminate() ){
568                                        finished =false;
569                                        break;
570                                }
571
572                                sleep(interval);
573                        } catch (InterruptedException e){
574                        }
575                        progress.repaint();
576                }
577                progress.setVisible(false);
578                progress = null;
579        }
580
581}