/* * MCMCPanel.java * * Copyright (c) 2002-2015 Alexei Drummond, Andrew Rambaut and Marc Suchard * * This file is part of BEAST. * See the NOTICE file distributed with this work for additional * information regarding copyright ownership and licensing. * * BEAST is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * BEAST is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with BEAST; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA */ package dr.app.beauti.mcmcpanel; import dr.app.beagle.tools.Partition; import dr.app.beauti.BeautiFrame; import dr.app.beauti.BeautiPanel; import dr.app.beauti.components.marginalLikelihoodEstimation.MLEDialog; import dr.app.beauti.components.marginalLikelihoodEstimation.MLEGSSDialog; import dr.app.beauti.components.marginalLikelihoodEstimation.MarginalLikelihoodEstimationOptions; import dr.app.beauti.options.AbstractPartitionData; import dr.app.beauti.options.BeautiOptions; import dr.app.beauti.options.PartitionTreeModel; import dr.app.beauti.options.STARBEASTOptions; import dr.app.beauti.util.PanelUtils; import dr.app.gui.components.WholeNumberField; import dr.app.util.OSType; import dr.evolution.datatype.DataType; import dr.evolution.datatype.Microsatellite; import jam.panels.OptionsPanel; import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.util.List; /** * @author Andrew Rambaut * @author Alexei Drummond * @version $Id: MCMCPanel.java,v 1.16 2006/09/05 13:29:34 rambaut Exp $ */ public class MCMCPanel extends BeautiPanel { private static final long serialVersionUID = -3710586474593827540L; WholeNumberField chainLengthField = new WholeNumberField(1, Integer.MAX_VALUE); WholeNumberField echoEveryField = new WholeNumberField(1, Integer.MAX_VALUE); WholeNumberField logEveryField = new WholeNumberField(1, Integer.MAX_VALUE); JCheckBox samplePriorCheckBox = new JCheckBox("Sample from prior only - create empty alignment"); JComboBox performMLECombo = new JComboBox(new String[] {"None", "path sampling/stepping-stone sampling", "generalized stepping-stone sampling"}); // JCheckBox performMLE = new JCheckBox("Perform marginal likelihood estimation (MLE) using path sampling/stepping-stone sampling"); JButton buttonMLE = new JButton("Settings"); // JCheckBox performMLEGSS = new JCheckBox("Perform marginal likelihood estimation (MLE) using generalized stepping-stone sampling"); // JButton buttonMLEGSS = new JButton("Settings"); public static final String DEFAULT_FILE_NAME_STEM = "untitled"; JTextField fileNameStemField = new JTextField(DEFAULT_FILE_NAME_STEM); private JCheckBox addTxt = new JCheckBox("Add .txt suffix"); JTextArea logFileNameField = new JTextArea(DEFAULT_FILE_NAME_STEM + ".log"); JTextArea treeFileNameField = new JTextArea(DEFAULT_FILE_NAME_STEM + "." + STARBEASTOptions.TREE_FILE_NAME); // JCheckBox allowOverwriteLogCheck = new JCheckBox("Allow to overwrite the existing log file"); // JCheckBox mapTreeLogCheck = new JCheckBox("Create tree file containing the MAP tree:"); // JTextField mapTreeFileNameField = new JTextField("untitled.MAP.tree"); JCheckBox substTreeLogCheck = new JCheckBox("Create tree log file with branch length in substitutions:"); JTextArea substTreeFileNameField = new JTextArea("untitled(subst).trees"); JCheckBox operatorAnalysisCheck = new JCheckBox("Create operator analysis file:"); JTextArea operatorAnalysisFileNameField = new JTextArea(DEFAULT_FILE_NAME_STEM + ".ops"); BeautiFrame frame = null; private final OptionsPanel optionsPanel; private BeautiOptions options; private MLEDialog mleDialog = null; private MLEGSSDialog mleGssDialog = null; private MarginalLikelihoodEstimationOptions mleOptions = new MarginalLikelihoodEstimationOptions(); public MCMCPanel(BeautiFrame parent) { setLayout(new BorderLayout()); // Mac OS X components have more spacing round them already optionsPanel = new OptionsPanel(12, (OSType.isMac() ? 6 : 24)); this.frame = parent; setOpaque(false); optionsPanel.setOpaque(false); chainLengthField.setValue(100000); chainLengthField.setColumns(10); optionsPanel.addComponentWithLabel("Length of chain:", chainLengthField); chainLengthField.addKeyListener(new java.awt.event.KeyListener() { public void keyTyped(KeyEvent e) { } public void keyPressed(KeyEvent e) { } public void keyReleased(KeyEvent e) { options.chainLength = chainLengthField.getValue(); frame.setDirty(); } }); optionsPanel.addSeparator(); echoEveryField.setValue(1000); echoEveryField.setColumns(10); optionsPanel.addComponentWithLabel("Echo state to screen every:", echoEveryField); echoEveryField.addKeyListener(new java.awt.event.KeyListener() { public void keyTyped(KeyEvent e) { } public void keyPressed(KeyEvent e) { } public void keyReleased(KeyEvent e) { options.echoEvery = echoEveryField.getValue(); frame.setDirty(); } }); logEveryField.setValue(100); logEveryField.setColumns(10); optionsPanel.addComponentWithLabel("Log parameters every:", logEveryField); logEveryField.addKeyListener(new java.awt.event.KeyListener() { public void keyTyped(KeyEvent e) { } public void keyPressed(KeyEvent e) { } public void keyReleased(KeyEvent e) { options.logEvery = logEveryField.getValue(); frame.setDirty(); } }); optionsPanel.addSeparator(); fileNameStemField.setColumns(32); optionsPanel.addComponentWithLabel("File name stem:", fileNameStemField); fileNameStemField.setEditable(true); fileNameStemField.addKeyListener(new java.awt.event.KeyListener() { public void keyTyped(KeyEvent e) { } public void keyPressed(KeyEvent e) { } public void keyReleased(KeyEvent e) { options.fileNameStem = fileNameStemField.getText(); updateOtherFileNames(options); frame.setDirty(); } }); optionsPanel.addComponent(addTxt); if (OSType.isWindows()) { addTxt.setSelected(true); } else { addTxt.setSelected(false); } addTxt.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent changeEvent) { setOptions(options); frame.setDirty(); } }); optionsPanel.addSeparator(); logFileNameField.setColumns(32); optionsPanel.addComponentWithLabel("Log file name:", logFileNameField); logFileNameField.setEditable(false); // optionsPanel.addComponent(allowOverwriteLogCheck); // allowOverwriteLogCheck.setSelected(false); // allowOverwriteLogCheck.addChangeListener(new ChangeListener() { // public void stateChanged(ChangeEvent changeEvent) { // options.allowOverwriteLog = allowOverwriteLogCheck.isSelected(); // } // }); treeFileNameField.setColumns(32); optionsPanel.addComponentWithLabel("Trees file name:", treeFileNameField); treeFileNameField.setEditable(false); // addComponent(mapTreeLogCheck); // mapTreeLogCheck.setOpaque(false); // mapTreeLogCheck.addActionListener(new java.awt.event.ActionListener() { // public void actionPerformed(ActionEvent e) { // mapTreeFileNameField.setEnabled(mapTreeLogCheck.isSelected()); // } // }); // // mapTreeFileNameField.setColumns(32); // addComponentWithLabel("MAP tree file name:", mapTreeFileNameField); optionsPanel.addComponent(substTreeLogCheck); substTreeLogCheck.setOpaque(false); substTreeLogCheck.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(ActionEvent e) { options.substTreeLog = substTreeLogCheck.isSelected(); updateTreeFileNameList(); substTreeFileNameField.setEnabled(substTreeLogCheck.isSelected()); if (substTreeLogCheck.isSelected()) { substTreeFileNameField.setText(displayTreeList(options.substTreeFileName)); } else { substTreeFileNameField.setText(""); } frame.setDirty(); } }); substTreeFileNameField.setColumns(32); substTreeFileNameField.setEditable(false); substTreeFileNameField.setEnabled(false); optionsPanel.addComponentWithLabel("Substitutions trees file name:", substTreeFileNameField); optionsPanel.addComponent(operatorAnalysisCheck); operatorAnalysisCheck.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(ActionEvent e) { options.operatorAnalysis = operatorAnalysisCheck.isSelected(); updateOtherFileNames(options); frame.setDirty(); } }); operatorAnalysisFileNameField.setColumns(32); operatorAnalysisFileNameField.setEditable(false); operatorAnalysisFileNameField.setEnabled(false); optionsPanel.addComponentWithLabel("Operator analysis file name:", operatorAnalysisFileNameField); optionsPanel.addSeparator(); optionsPanel.addComponent(samplePriorCheckBox); samplePriorCheckBox.setOpaque(false); samplePriorCheckBox.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent changeEvent) { frame.setDirty(); } }); optionsPanel.addSeparator(); JTextArea mleInfo = new JTextArea("Select the option below to perform marginal likelihood " + "estimation (MLE) using path sampling (PS) / stepping-stone sampling (SS) " + "or generalized stepping-stone sampling (GSS) which performs an additional" + "analysis after the standard MCMC chain has finished."); mleInfo.setColumns(50); PanelUtils.setupComponent(mleInfo); optionsPanel.addSpanningComponent(mleInfo); //add PS/SS button optionsPanel.addComponentWithLabel("Marginal likelihood estimation (MLE):", performMLECombo); optionsPanel.addComponent(buttonMLE); buttonMLE.setEnabled(false); performMLECombo.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(ActionEvent e) { if (performMLECombo.getSelectedIndex() == 1) { mleOptions.performMLE = true; mleOptions.performMLEGSS = false; options.logCoalescentEventsStatistic = false; buttonMLE.setEnabled(true); updateMLEFileNameStem(); } else if (performMLECombo.getSelectedIndex() == 2) { // Generalized stepping-stone sampling for (AbstractPartitionData partition : options.getDataPartitions()) { if (partition.getDataType().getType() != DataType.NUCLEOTIDES) { JOptionPane.showMessageDialog(frame, "Generalized stepping-stone sampling is not currently\n" + "compatible with substitution models other than those\n" + "for nucleotide data. \n\n" + "Use path sampling/stepping-stone sampling instead", "Warning", JOptionPane.WARNING_MESSAGE); performMLECombo.setSelectedIndex(1); return; } } mleOptions.performMLE = false; mleOptions.performMLEGSS = true; //set to true because product of exponentials is the default option options.logCoalescentEventsStatistic = true; buttonMLE.setEnabled(true); updateMLEFileNameStem(); } else { mleOptions.performMLE = false; mleOptions.performMLEGSS = false; mleOptions.printOperatorAnalysis = false; options.logCoalescentEventsStatistic = false; buttonMLE.setEnabled(false); } } }); buttonMLE.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(ActionEvent e) { updateMLEFileNameStem(); int result = -1; if (performMLECombo.getSelectedIndex() == 1) { result = mleDialog.showDialog(); } else if (performMLECombo.getSelectedIndex() == 2) { result = mleGssDialog.showDialog(); } if (result == -1 || result == JOptionPane.CANCEL_OPTION) { return; } } }); // JTextArea mleGssInfo = new JTextArea("Select the option below to perform marginal likelihood " + // "estimation (MLE) using generalized stepping-stone sampling (GSS) which " + // "performs an additional analysis after the standard MCMC chain has finished."); // mleGssInfo.setColumns(50); // PanelUtils.setupComponent(mleGssInfo); // optionsPanel.addSpanningComponent(mleGssInfo); // //add GSS button // optionsPanel.addComponent(performMLEGSS); // //will be false by default // //options.performMLE = false; ?? // optionsPanel.addComponent(buttonMLEGSS); // buttonMLEGSS.setEnabled(false); // performMLEGSS.addActionListener(new java.awt.event.ActionListener() { // public void actionPerformed(ActionEvent e) { // if (performMLEGSS.isSelected()) { // mleOptions.performMLEGSS = true; // //set to true because product of exponentials is the default option // options.logCoalescentEventsStatistic = true; // buttonMLEGSS.setEnabled(true); // buttonMLE.setEnabled(false); // performMLE.setEnabled(false); // updateMLEFileNameStem(); // } else { // mleOptions.performMLEGSS = false; // mleOptions.printOperatorAnalysis = false; // options.logCoalescentEventsStatistic = false; // buttonMLE.setEnabled(false); // performMLE.setEnabled(true); // buttonMLEGSS.setEnabled(false); // } // } // }); // buttonMLEGSS.addActionListener(new java.awt.event.ActionListener() { // public void actionPerformed(ActionEvent e) { // updateMLEFileNameStem(); // // int result = mleGssDialog.showDialog(); // // if (result == -1 || result == JOptionPane.CANCEL_OPTION) { // return; // } // // } // }); // logFileNameField.addKeyListener(listener); // treeFileNameField.addKeyListener(listener); //mapTreeFileNameField.addKeyListener(listener); // substTreeFileNameField.addKeyListener(listener); // optionsPanel.setPreferredSize(new java.awt.Dimension(500, 600)); JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER)); panel.add(optionsPanel, BorderLayout.CENTER); panel.setOpaque(false); JScrollPane scrollPane = new JScrollPane(panel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); scrollPane.setOpaque(false); scrollPane.setBorder(null); scrollPane.getViewport().setOpaque(false); add(scrollPane, BorderLayout.CENTER); } private void updateTreeFileNameList() { options.treeFileName.clear(); options.substTreeFileName.clear(); String treeFileName; for (PartitionTreeModel tree : options.getPartitionTreeModels()) { if (options.substTreeLog) { treeFileName = getTreeFileName(tree.getPrefix() + "(time)."); } else { treeFileName = getTreeFileName(tree.getPrefix()); } if (addTxt.isSelected()) treeFileName = treeFileName + ".txt"; options.treeFileName.add(treeFileName); if (options.substTreeLog) { treeFileName = getTreeFileName(tree.getPrefix() + "(subst)."); if (addTxt.isSelected()) treeFileName = treeFileName + ".txt"; options.substTreeFileName.add(treeFileName); } } if (options.useStarBEAST) { treeFileName = options.fileNameStem + "." + options.starBEASTOptions.SPECIES_TREE_FILE_NAME; if (addTxt.isSelected()) treeFileName = treeFileName + ".txt"; options.treeFileName.add(treeFileName); //TODO: species sub tree } } private String getTreeFileName(String treeName) { return options.fileNameStem + "." + treeName + STARBEASTOptions.TREE_FILE_NAME; } private String displayTreeList(List<String> treeList) { if (treeList.size() > 1) { return getTreeFileName("[tree name]."); } else { return getTreeFileName(""); } } public void setOptions(BeautiOptions options) { this.options = options; /*System.err.println("mleOptions: " + mleOptions); System.err.println("options.pathSteps: " + mleOptions.pathSteps); System.err.println("options.mleChainLength: " + mleOptions.mleChainLength); System.err.println("options.mleLogEvery: " + mleOptions.mleLogEvery);*/ // get the MLE options mleOptions = (MarginalLikelihoodEstimationOptions)options.getComponentOptions(MarginalLikelihoodEstimationOptions.class); /*if (mleOptions == null) { mleOptions = new MarginalLikelihoodEstimationOptions(); }*/ /*System.err.println("mleOptions: " + mleOptions); System.err.println("options.pathSteps: " + mleOptions.pathSteps); System.err.println("options.mleChainLength: " + mleOptions.mleChainLength); System.err.println("options.mleLogEvery: " + mleOptions.mleLogEvery);*/ if (mleDialog != null) { //mleDialog.setOptions(mleOptions); } if (mleGssDialog != null) { //mleGssDialog.setOptions(mleOptions); } chainLengthField.setValue(options.chainLength); echoEveryField.setValue(options.echoEvery); logEveryField.setValue(options.logEvery); if (options.fileNameStem != null) { fileNameStemField.setText(options.fileNameStem); } else { fileNameStemField.setText(DEFAULT_FILE_NAME_STEM); fileNameStemField.setEnabled(false); } operatorAnalysisCheck.setSelected(options.operatorAnalysis); updateOtherFileNames(options); if (options.contains(Microsatellite.INSTANCE)) { samplePriorCheckBox.setSelected(false); samplePriorCheckBox.setVisible(false); } else { samplePriorCheckBox.setVisible(true); samplePriorCheckBox.setSelected(options.samplePriorOnly); } optionsPanel.validate(); optionsPanel.repaint(); } private void updateOtherFileNames(BeautiOptions options) { if (options.fileNameStem != null) { // fileNameStemField.setText(options.fileNameStem); options.logFileName = options.fileNameStem + ".log"; if (addTxt.isSelected()) options.logFileName = options.logFileName + ".txt"; logFileNameField.setText(options.logFileName); // if (options.mapTreeFileName == null) { // mapTreeFileNameField.setText(options.fileNameStem + ".MAP.tree"); // } else { // mapTreeFileNameField.setText(options.mapTreeFileName); // } updateTreeFileNameList(); treeFileNameField.setText(displayTreeList(options.treeFileName)); if (options.substTreeLog) { substTreeFileNameField.setText(displayTreeList(options.substTreeFileName)); } else { substTreeFileNameField.setText(""); } options.operatorAnalysisFileName = options.fileNameStem + ".ops"; if (addTxt.isSelected()) { options.operatorAnalysisFileName = options.operatorAnalysisFileName + ".txt"; } operatorAnalysisFileNameField.setEnabled(options.operatorAnalysis); if (options.operatorAnalysis) { operatorAnalysisFileNameField.setText(options.operatorAnalysisFileName); } else { operatorAnalysisFileNameField.setText(""); } // mapTreeLogCheck.setEnabled(true); // mapTreeLogCheck.setSelected(options.mapTreeLog); // mapTreeFileNameField.setEnabled(options.mapTreeLog); substTreeLogCheck.setEnabled(true); substTreeLogCheck.setSelected(options.substTreeLog); updateMLEFileNameStem(); } else { // fileNameStemField.setText(fileNameStem); // fileNameStemField.setEnabled(false); logFileNameField.setText(DEFAULT_FILE_NAME_STEM + ".log"); treeFileNameField.setText(DEFAULT_FILE_NAME_STEM + "." + STARBEASTOptions.TREE_FILE_NAME); // mapTreeLogCheck.setEnabled(false); // mapTreeFileNameField.setEnabled(false); // mapTreeFileNameField.setText("untitled"); substTreeLogCheck.setSelected(false); substTreeFileNameField.setEnabled(false); substTreeFileNameField.setText(""); operatorAnalysisCheck.setSelected(false); operatorAnalysisFileNameField.setText(""); } } private void updateMLEFileNameStem() { if (mleDialog == null) { mleDialog = new MLEDialog(frame, mleOptions); } if (mleGssDialog == null) { mleGssDialog = new MLEGSSDialog(frame, mleOptions, options); } mleDialog.setFilenameStem(options.fileNameStem, addTxt.isSelected()); mleGssDialog.setFilenameStem(options.fileNameStem, addTxt.isSelected()); } public void getOptions(BeautiOptions options) { options.fileNameStem = fileNameStemField.getText(); options.logFileName = logFileNameField.getText(); // options.mapTreeLog = mapTreeLogCheck.isSelected(); // options.mapTreeFileName = mapTreeFileNameField.getText(); options.substTreeLog = substTreeLogCheck.isSelected(); updateTreeFileNameList(); options.operatorAnalysis = operatorAnalysisCheck.isSelected(); options.operatorAnalysisFileName = operatorAnalysisFileNameField.getText(); options.samplePriorOnly = samplePriorCheckBox.isSelected(); if (mleDialog != null) { //mleDialog.getOptions(mleOptions); } if (mleGssDialog != null) { //mleGssDialog.getOptions(mleOptions); } } public JComponent getExportableComponent() { return optionsPanel; } }