JAL-1632 add score model params to PCAModel and PCA constructors
[jalview.git] / src / jalview / gui / PCAPanel.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.gui;
22
23 import jalview.analysis.scoremodels.ScoreModels;
24 import jalview.analysis.scoremodels.SimilarityParams;
25 import jalview.api.analysis.ScoreModelI;
26 import jalview.api.analysis.ViewBasedAnalysisI;
27 import jalview.bin.Cache;
28 import jalview.datamodel.Alignment;
29 import jalview.datamodel.AlignmentI;
30 import jalview.datamodel.AlignmentView;
31 import jalview.datamodel.ColumnSelection;
32 import jalview.datamodel.SeqCigar;
33 import jalview.datamodel.SequenceI;
34 import jalview.jbgui.GPCAPanel;
35 import jalview.util.MessageManager;
36 import jalview.viewmodel.AlignmentViewport;
37 import jalview.viewmodel.PCAModel;
38
39 import java.awt.BorderLayout;
40 import java.awt.Color;
41 import java.awt.Graphics;
42 import java.awt.event.ActionEvent;
43 import java.awt.event.ActionListener;
44 import java.awt.print.PageFormat;
45 import java.awt.print.Printable;
46 import java.awt.print.PrinterException;
47 import java.awt.print.PrinterJob;
48
49 import javax.swing.ButtonGroup;
50 import javax.swing.JCheckBoxMenuItem;
51 import javax.swing.JColorChooser;
52 import javax.swing.JMenuItem;
53 import javax.swing.JRadioButtonMenuItem;
54 import javax.swing.event.InternalFrameAdapter;
55 import javax.swing.event.InternalFrameEvent;
56
57 /**
58  * DOCUMENT ME!
59  * 
60  * @author $author$
61  * @version $Revision$
62  */
63 public class PCAPanel extends GPCAPanel implements Runnable,
64         IProgressIndicator
65 {
66
67   private IProgressIndicator progressBar;
68
69   RotatableCanvas rc;
70
71   AlignmentPanel ap;
72
73   AlignmentViewport av;
74
75   PCAModel pcaModel;
76
77   int top = 0;
78
79   /**
80    * Creates a new PCAPanel object.
81    * 
82    * @param av
83    *          DOCUMENT ME!
84    * @param s
85    *          DOCUMENT ME!
86    */
87   public PCAPanel(AlignmentPanel alignPanel)
88   {
89     super();
90     this.av = alignPanel.av;
91     this.ap = alignPanel;
92
93     progressBar = new ProgressBar(statusPanel, statusBar);
94
95     addInternalFrameListener(new InternalFrameAdapter()
96     {
97       @Override
98       public void internalFrameClosed(InternalFrameEvent e)
99       {
100         close_actionPerformed();
101       }
102     });
103
104     boolean selected = av.getSelectionGroup() != null
105             && av.getSelectionGroup().getSize() > 0;
106     AlignmentView seqstrings = av.getAlignmentView(selected);
107     boolean nucleotide = av.getAlignment().isNucleotide();
108     SequenceI[] seqs;
109     if (!selected)
110     {
111       seqs = av.getAlignment().getSequencesArray();
112     }
113     else
114     {
115       seqs = av.getSelectionGroup().getSequencesInOrder(av.getAlignment());
116     }
117
118     // TODO can we allow PCA on unaligned data given choice of
119     // similarity measure parameters?
120     if (!checkAligned(seqstrings))
121     {
122       JvOptionPane.showMessageDialog(Desktop.desktop,
123               MessageManager.getString("label.pca_sequences_not_aligned"),
124               MessageManager.getString("label.sequences_not_aligned"),
125               JvOptionPane.WARNING_MESSAGE);
126
127       return;
128     }
129
130     pcaModel = new PCAModel(seqstrings, seqs, nucleotide,
131             SimilarityParams.SeqSpace);
132     PaintRefresher.Register(this, av.getSequenceSetId());
133
134     rc = new RotatableCanvas(alignPanel);
135     this.getContentPane().add(rc, BorderLayout.CENTER);
136     Thread worker = new Thread(this);
137     worker.start();
138   }
139
140   /**
141    * Answers true if all sequences have the same aligned length, else false
142    * 
143    * @param seqstrings
144    * @return
145    */
146   protected boolean checkAligned(AlignmentView seqstrings)
147   {
148     SeqCigar sq[] = seqstrings.getSequences();
149     int length = sq[0].getWidth();
150     boolean sameLength = true;
151     for (int i = 0; i < sq.length; i++)
152     {
153       if (sq[i].getWidth() != length)
154       {
155         sameLength = false;
156         break;
157       }
158     }
159     return sameLength;
160   }
161
162   /**
163    * Ensure references to potentially very large objects (the PCA matrices) are
164    * nulled when the frame is closed
165    */
166   protected void close_actionPerformed()
167   {
168     pcaModel = null;
169   }
170
171   /**
172    * Repopulate the options and actions under the score model menu when it is
173    * selected. Options will depend on whether 'nucleotide' or 'peptide'
174    * modelling is selected (and also possibly on whether any additional score
175    * models have been added).
176    */
177   @Override
178   protected void scoreModel_menuSelected()
179   {
180     scoreModelMenu.removeAll();
181     for (final ScoreModelI sm : ScoreModels.getInstance().getModels())
182     {
183       final String name = sm.getName();
184       // create an entry for this score matrix for use in PCA
185       JCheckBoxMenuItem jm = new JCheckBoxMenuItem();
186       jm.setText(MessageManager.getStringOrReturn("label.score_model_",
187               name));
188       jm.setSelected(pcaModel.getScoreModelName().equals(name));
189       if ((pcaModel.isNucleotide() && sm.isDNA())
190               || (!pcaModel.isNucleotide() && sm.isProtein()))
191       {
192         jm.addActionListener(new ActionListener()
193         {
194           @Override
195           public void actionPerformed(ActionEvent e)
196           {
197             if (!pcaModel.getScoreModelName().equals(name))
198             {
199               ScoreModelI sm2 = configureScoreModel(sm);
200               pcaModel.setScoreModel(sm2);
201               Thread worker = new Thread(PCAPanel.this);
202               worker.start();
203             }
204           }
205         });
206         scoreModelMenu.add(jm);
207       }
208     }
209   }
210
211   @Override
212   public void bgcolour_actionPerformed(ActionEvent e)
213   {
214     Color col = JColorChooser.showDialog(this,
215             MessageManager.getString("label.select_background_colour"),
216             rc.bgColour);
217
218     if (col != null)
219     {
220       rc.bgColour = col;
221     }
222     rc.repaint();
223   }
224
225   /**
226    * DOCUMENT ME!
227    */
228   @Override
229   public void run()
230   {
231     long progId = System.currentTimeMillis();
232     IProgressIndicator progress = this;
233     String message = MessageManager.getString("label.pca_recalculating");
234     if (getParent() == null)
235     {
236       progress = ap.alignFrame;
237       message = MessageManager.getString("label.pca_calculating");
238     }
239     progress.setProgressBar(message, progId);
240     try
241     {
242       calcSettings.setEnabled(false);
243       pcaModel.run();
244       // ////////////////
245       xCombobox.setSelectedIndex(0);
246       yCombobox.setSelectedIndex(1);
247       zCombobox.setSelectedIndex(2);
248
249       pcaModel.updateRc(rc);
250       // rc.invalidate();
251       nuclSetting.setSelected(pcaModel.isNucleotide());
252       protSetting.setSelected(!pcaModel.isNucleotide());
253       jvVersionSetting.setSelected(pcaModel.isJvCalcMode());
254       top = pcaModel.getTop();
255
256     } catch (OutOfMemoryError er)
257     {
258       new OOMWarning("calculating PCA", er);
259       return;
260     } finally
261     {
262       progress.setProgressBar("", progId);
263     }
264     calcSettings.setEnabled(true);
265     repaint();
266     if (getParent() == null)
267     {
268       addKeyListener(rc);
269       Desktop.addInternalFrame(this, MessageManager
270               .getString("label.principal_component_analysis"), 475, 450);
271     }
272   }
273
274   @Override
275   protected void nuclSetting_actionPerfomed(ActionEvent arg0)
276   {
277     if (!pcaModel.isNucleotide())
278     {
279       pcaModel.setNucleotide(true);
280       pcaModel.setScoreModel(ScoreModels.getInstance().getDefaultModel(
281               false));
282       Thread worker = new Thread(this);
283       worker.start();
284     }
285
286   }
287
288   @Override
289   protected void protSetting_actionPerfomed(ActionEvent arg0)
290   {
291
292     if (pcaModel.isNucleotide())
293     {
294       pcaModel.setNucleotide(false);
295       pcaModel.setScoreModel(ScoreModels.getInstance()
296               .getDefaultModel(true));
297       Thread worker = new Thread(this);
298       worker.start();
299     }
300   }
301
302   @Override
303   protected void jvVersionSetting_actionPerfomed(ActionEvent arg0)
304   {
305     pcaModel.setJvCalcMode(jvVersionSetting.isSelected());
306     Thread worker = new Thread(this);
307     worker.start();
308   }
309
310   /**
311    * DOCUMENT ME!
312    */
313   void doDimensionChange()
314   {
315     if (top == 0)
316     {
317       return;
318     }
319
320     int dim1 = top - xCombobox.getSelectedIndex();
321     int dim2 = top - yCombobox.getSelectedIndex();
322     int dim3 = top - zCombobox.getSelectedIndex();
323     pcaModel.updateRcView(dim1, dim2, dim3);
324     rc.img = null;
325     rc.rotmat.setIdentity();
326     rc.initAxes();
327     rc.paint(rc.getGraphics());
328   }
329
330   /**
331    * DOCUMENT ME!
332    * 
333    * @param e
334    *          DOCUMENT ME!
335    */
336   @Override
337   protected void xCombobox_actionPerformed(ActionEvent e)
338   {
339     doDimensionChange();
340   }
341
342   /**
343    * DOCUMENT ME!
344    * 
345    * @param e
346    *          DOCUMENT ME!
347    */
348   @Override
349   protected void yCombobox_actionPerformed(ActionEvent e)
350   {
351     doDimensionChange();
352   }
353
354   /**
355    * DOCUMENT ME!
356    * 
357    * @param e
358    *          DOCUMENT ME!
359    */
360   @Override
361   protected void zCombobox_actionPerformed(ActionEvent e)
362   {
363     doDimensionChange();
364   }
365
366   @Override
367   public void outputValues_actionPerformed(ActionEvent e)
368   {
369     CutAndPasteTransfer cap = new CutAndPasteTransfer();
370     try
371     {
372       cap.setText(pcaModel.getDetails());
373       Desktop.addInternalFrame(cap,
374               MessageManager.getString("label.pca_details"), 500, 500);
375     } catch (OutOfMemoryError oom)
376     {
377       new OOMWarning("opening PCA details", oom);
378       cap.dispose();
379     }
380   }
381
382   @Override
383   public void showLabels_actionPerformed(ActionEvent e)
384   {
385     rc.showLabels(showLabels.getState());
386   }
387
388   @Override
389   public void print_actionPerformed(ActionEvent e)
390   {
391     PCAPrinter printer = new PCAPrinter();
392     printer.start();
393   }
394
395   @Override
396   public void originalSeqData_actionPerformed(ActionEvent e)
397   {
398     // this was cut'n'pasted from the equivalent TreePanel method - we should
399     // make this an abstract function of all jalview analysis windows
400     if (pcaModel.getSeqtrings() == null)
401     {
402       jalview.bin.Cache.log
403               .info("Unexpected call to originalSeqData_actionPerformed - should have hidden this menu action.");
404       return;
405     }
406     // decide if av alignment is sufficiently different to original data to
407     // warrant a new window to be created
408     // create new alignmnt window with hidden regions (unhiding hidden regions
409     // yields unaligned seqs)
410     // or create a selection box around columns in alignment view
411     // test Alignment(SeqCigar[])
412     char gc = '-';
413     try
414     {
415       // we try to get the associated view's gap character
416       // but this may fail if the view was closed...
417       gc = av.getGapCharacter();
418     } catch (Exception ex)
419     {
420     }
421     ;
422     Object[] alAndColsel = pcaModel.getSeqtrings()
423             .getAlignmentAndColumnSelection(gc);
424
425     if (alAndColsel != null && alAndColsel[0] != null)
426     {
427       // AlignmentOrder origorder = new AlignmentOrder(alAndColsel[0]);
428
429       AlignmentI al = new Alignment((SequenceI[]) alAndColsel[0]);
430       AlignmentI dataset = (av != null && av.getAlignment() != null) ? av
431               .getAlignment().getDataset() : null;
432       if (dataset != null)
433       {
434         al.setDataset(dataset);
435       }
436
437       if (true)
438       {
439         // make a new frame!
440         AlignFrame af = new AlignFrame(al,
441                 (ColumnSelection) alAndColsel[1], AlignFrame.DEFAULT_WIDTH,
442                 AlignFrame.DEFAULT_HEIGHT);
443
444         // >>>This is a fix for the moment, until a better solution is
445         // found!!<<<
446         // af.getFeatureRenderer().transferSettings(alignFrame.getFeatureRenderer());
447
448         // af.addSortByOrderMenuItem(ServiceName + " Ordering",
449         // msaorder);
450
451         Desktop.addInternalFrame(af, MessageManager.formatMessage(
452                 "label.original_data_for_params",
453                 new String[] { this.title }), AlignFrame.DEFAULT_WIDTH,
454                 AlignFrame.DEFAULT_HEIGHT);
455       }
456     }
457     /*
458      * CutAndPasteTransfer cap = new CutAndPasteTransfer(); for (int i = 0; i <
459      * seqs.length; i++) { cap.appendText(new jalview.util.Format("%-" + 15 +
460      * "s").form( seqs[i].getName())); cap.appendText(" " + seqstrings[i] +
461      * "\n"); }
462      * 
463      * Desktop.addInternalFrame(cap, "Original Data", 400, 400);
464      */
465   }
466
467   class PCAPrinter extends Thread implements Printable
468   {
469     @Override
470     public void run()
471     {
472       PrinterJob printJob = PrinterJob.getPrinterJob();
473       PageFormat pf = printJob.pageDialog(printJob.defaultPage());
474
475       printJob.setPrintable(this, pf);
476
477       if (printJob.printDialog())
478       {
479         try
480         {
481           printJob.print();
482         } catch (Exception PrintException)
483         {
484           PrintException.printStackTrace();
485         }
486       }
487     }
488
489     @Override
490     public int print(Graphics pg, PageFormat pf, int pi)
491             throws PrinterException
492     {
493       pg.translate((int) pf.getImageableX(), (int) pf.getImageableY());
494
495       rc.drawBackground(pg, rc.bgColour);
496       rc.drawScene(pg);
497       if (rc.drawAxes == true)
498       {
499         rc.drawAxes(pg);
500       }
501
502       if (pi == 0)
503       {
504         return Printable.PAGE_EXISTS;
505       }
506       else
507       {
508         return Printable.NO_SUCH_PAGE;
509       }
510     }
511   }
512
513   /**
514    * DOCUMENT ME!
515    * 
516    * @param e
517    *          DOCUMENT ME!
518    */
519   @Override
520   public void eps_actionPerformed(ActionEvent e)
521   {
522     makePCAImage(jalview.util.ImageMaker.TYPE.EPS);
523   }
524
525   /**
526    * DOCUMENT ME!
527    * 
528    * @param e
529    *          DOCUMENT ME!
530    */
531   @Override
532   public void png_actionPerformed(ActionEvent e)
533   {
534     makePCAImage(jalview.util.ImageMaker.TYPE.PNG);
535   }
536
537   void makePCAImage(jalview.util.ImageMaker.TYPE type)
538   {
539     int width = rc.getWidth();
540     int height = rc.getHeight();
541
542     jalview.util.ImageMaker im;
543
544     if (type == jalview.util.ImageMaker.TYPE.PNG)
545     {
546       im = new jalview.util.ImageMaker(this,
547               jalview.util.ImageMaker.TYPE.PNG, "Make PNG image from PCA",
548               width, height, null, null, null, 0, false);
549     }
550     else if (type == jalview.util.ImageMaker.TYPE.EPS)
551     {
552       im = new jalview.util.ImageMaker(this,
553               jalview.util.ImageMaker.TYPE.EPS, "Make EPS file from PCA",
554               width, height, null, this.getTitle(), null, 0, false);
555     }
556     else
557     {
558       im = new jalview.util.ImageMaker(this,
559               jalview.util.ImageMaker.TYPE.SVG, "Make SVG file from PCA",
560               width, height, null, this.getTitle(), null, 0, false);
561
562     }
563
564     if (im.getGraphics() != null)
565     {
566       rc.drawBackground(im.getGraphics(), Color.black);
567       rc.drawScene(im.getGraphics());
568       if (rc.drawAxes == true)
569       {
570         rc.drawAxes(im.getGraphics());
571       }
572       im.writeImage();
573     }
574   }
575
576   @Override
577   public void viewMenu_menuSelected()
578   {
579     buildAssociatedViewMenu();
580   }
581
582   void buildAssociatedViewMenu()
583   {
584     AlignmentPanel[] aps = PaintRefresher.getAssociatedPanels(av
585             .getSequenceSetId());
586     if (aps.length == 1 && rc.av == aps[0].av)
587     {
588       associateViewsMenu.setVisible(false);
589       return;
590     }
591
592     associateViewsMenu.setVisible(true);
593
594     if ((viewMenu.getItem(viewMenu.getItemCount() - 2) instanceof JMenuItem))
595     {
596       viewMenu.insertSeparator(viewMenu.getItemCount() - 1);
597     }
598
599     associateViewsMenu.removeAll();
600
601     JRadioButtonMenuItem item;
602     ButtonGroup buttonGroup = new ButtonGroup();
603     int i, iSize = aps.length;
604     final PCAPanel thisPCAPanel = this;
605     for (i = 0; i < iSize; i++)
606     {
607       final AlignmentPanel ap = aps[i];
608       item = new JRadioButtonMenuItem(ap.av.viewName, ap.av == rc.av);
609       buttonGroup.add(item);
610       item.addActionListener(new ActionListener()
611       {
612         @Override
613         public void actionPerformed(ActionEvent evt)
614         {
615           rc.applyToAllViews = false;
616           rc.av = ap.av;
617           rc.ap = ap;
618           PaintRefresher.Register(thisPCAPanel, ap.av.getSequenceSetId());
619         }
620       });
621
622       associateViewsMenu.add(item);
623     }
624
625     final JRadioButtonMenuItem itemf = new JRadioButtonMenuItem("All Views");
626
627     buttonGroup.add(itemf);
628
629     itemf.setSelected(rc.applyToAllViews);
630     itemf.addActionListener(new ActionListener()
631     {
632       @Override
633       public void actionPerformed(ActionEvent evt)
634       {
635         rc.applyToAllViews = itemf.isSelected();
636       }
637     });
638     associateViewsMenu.add(itemf);
639
640   }
641
642   /*
643    * (non-Javadoc)
644    * 
645    * @see
646    * jalview.jbgui.GPCAPanel#outputPoints_actionPerformed(java.awt.event.ActionEvent
647    * )
648    */
649   @Override
650   protected void outputPoints_actionPerformed(ActionEvent e)
651   {
652     CutAndPasteTransfer cap = new CutAndPasteTransfer();
653     try
654     {
655       cap.setText(pcaModel.getPointsasCsv(false,
656               xCombobox.getSelectedIndex(), yCombobox.getSelectedIndex(),
657               zCombobox.getSelectedIndex()));
658       Desktop.addInternalFrame(cap, MessageManager.formatMessage(
659               "label.points_for_params", new String[] { this.getTitle() }),
660               500, 500);
661     } catch (OutOfMemoryError oom)
662     {
663       new OOMWarning("exporting PCA points", oom);
664       cap.dispose();
665     }
666   }
667
668   /*
669    * (non-Javadoc)
670    * 
671    * @see
672    * jalview.jbgui.GPCAPanel#outputProjPoints_actionPerformed(java.awt.event
673    * .ActionEvent)
674    */
675   @Override
676   protected void outputProjPoints_actionPerformed(ActionEvent e)
677   {
678     CutAndPasteTransfer cap = new CutAndPasteTransfer();
679     try
680     {
681       cap.setText(pcaModel.getPointsasCsv(true,
682               xCombobox.getSelectedIndex(), yCombobox.getSelectedIndex(),
683               zCombobox.getSelectedIndex()));
684       Desktop.addInternalFrame(cap, MessageManager.formatMessage(
685               "label.transformed_points_for_params",
686               new String[] { this.getTitle() }), 500, 500);
687     } catch (OutOfMemoryError oom)
688     {
689       new OOMWarning("exporting transformed PCA points", oom);
690       cap.dispose();
691     }
692   }
693
694   /*
695    * (non-Javadoc)
696    * 
697    * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
698    */
699   @Override
700   public void setProgressBar(String message, long id)
701   {
702     progressBar.setProgressBar(message, id);
703     // if (progressBars == null)
704     // {
705     // progressBars = new Hashtable();
706     // progressBarHandlers = new Hashtable();
707     // }
708     //
709     // JPanel progressPanel;
710     // Long lId = new Long(id);
711     // GridLayout layout = (GridLayout) statusPanel.getLayout();
712     // if (progressBars.get(lId) != null)
713     // {
714     // progressPanel = (JPanel) progressBars.get(new Long(id));
715     // statusPanel.remove(progressPanel);
716     // progressBars.remove(lId);
717     // progressPanel = null;
718     // if (message != null)
719     // {
720     // statusBar.setText(message);
721     // }
722     // if (progressBarHandlers.contains(lId))
723     // {
724     // progressBarHandlers.remove(lId);
725     // }
726     // layout.setRows(layout.getRows() - 1);
727     // }
728     // else
729     // {
730     // progressPanel = new JPanel(new BorderLayout(10, 5));
731     //
732     // JProgressBar progressBar = new JProgressBar();
733     // progressBar.setIndeterminate(true);
734     //
735     // progressPanel.add(new JLabel(message), BorderLayout.WEST);
736     // progressPanel.add(progressBar, BorderLayout.CENTER);
737     //
738     // layout.setRows(layout.getRows() + 1);
739     // statusPanel.add(progressPanel);
740     //
741     // progressBars.put(lId, progressPanel);
742     // }
743     // // update GUI
744     // // setMenusForViewport();
745     // validate();
746   }
747
748   @Override
749   public void registerHandler(final long id,
750           final IProgressIndicatorHandler handler)
751   {
752     progressBar.registerHandler(id, handler);
753     // if (progressBarHandlers == null || !progressBars.contains(new Long(id)))
754     // {
755     // throw new
756     // Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler"));
757     // }
758     // progressBarHandlers.put(new Long(id), handler);
759     // final JPanel progressPanel = (JPanel) progressBars.get(new Long(id));
760     // if (handler.canCancel())
761     // {
762     // JButton cancel = new JButton(
763     // MessageManager.getString("action.cancel"));
764     // final IProgressIndicator us = this;
765     // cancel.addActionListener(new ActionListener()
766     // {
767     //
768     // @Override
769     // public void actionPerformed(ActionEvent e)
770     // {
771     // handler.cancelActivity(id);
772     // us.setProgressBar(MessageManager.formatMessage("label.cancelled_params",
773     // new String[]{((JLabel) progressPanel.getComponent(0)).getText()}), id);
774     // }
775     // });
776     // progressPanel.add(cancel, BorderLayout.EAST);
777     // }
778   }
779
780   /**
781    * 
782    * @return true if any progress bars are still active
783    */
784   @Override
785   public boolean operationInProgress()
786   {
787     return progressBar.operationInProgress();
788   }
789
790   @Override
791   protected void resetButton_actionPerformed(ActionEvent e)
792   {
793     int t = top;
794     top = 0; // ugly - prevents dimensionChanged events from being processed
795     xCombobox.setSelectedIndex(0);
796     yCombobox.setSelectedIndex(1);
797     top = t;
798     zCombobox.setSelectedIndex(2);
799   }
800
801   /**
802    * If the score model is one that requires to get state data from the current
803    * view, allow it to do so
804    * 
805    * @param sm
806    * @return
807    */
808   protected ScoreModelI configureScoreModel(ScoreModelI sm)
809   {
810     if (sm instanceof ViewBasedAnalysisI)
811     {
812       try
813       {
814         sm = sm.getClass().newInstance();
815         ((ViewBasedAnalysisI) sm).configureFromAlignmentView(ap);
816       } catch (Exception q)
817       {
818         Cache.log.error("Couldn't create a scoremodel instance for "
819                 + sm.getName());
820       }
821     }
822     return sm;
823   }
824 }