/*
* BeastMC3Dialog.java
*
* Copyright (C) 2002-2006 Alexei Drummond and Andrew Rambaut
*
* 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.beast;
import dr.app.gui.FileDrop;
import dr.app.gui.components.RealNumberField;
import dr.app.gui.components.WholeNumberField;
import jam.panels.OptionsPanel;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.text.DecimalFormat;
public class BeastMC3Dialog {
private final JFrame frame;
private final OptionsPanel optionPanel;
private final WholeNumberField chainsText = new WholeNumberField((int) 2, 100);
private final JTextField temperaturesArrayText = new JTextField("-1");
private final RealNumberField deltaText = new RealNumberField((double) 0.0, Double.MAX_VALUE);
private final WholeNumberField swapText = new WholeNumberField((int) 1, Integer.MAX_VALUE);
private final JCheckBox overwriteCheckBox = new JCheckBox("Allow overwriting of log files");
private final JRadioButton deltaButton = new JRadioButton("Delta: ");
private final JRadioButton temperaturesButton = new JRadioButton("Temperatures: ");
private File inputFile = null;
public BeastMC3Dialog(final JFrame frame, final String titleString, final Icon icon) {
this.frame = frame;
optionPanel = new OptionsPanel(12, 12);
//this.frame = frame;
JPanel panel = new JPanel(new BorderLayout());
panel.setOpaque(false);
final JLabel titleText = new JLabel(titleString);
titleText.setIcon(icon);
optionPanel.addSpanningComponent(titleText);
titleText.setFont(new Font("sans-serif", 0, 12));
final JButton inputFileButton = new JButton("Choose File...");
final JTextField inputFileNameText = new JTextField("not selected", 16);
inputFileButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
FileDialog dialog = new FileDialog(frame,
"Select target file...",
FileDialog.LOAD);
dialog.setVisible(true);
if (dialog.getFile() == null) {
// the dialog was cancelled...
return;
}
inputFile = new File(dialog.getDirectory(), dialog.getFile());
inputFileNameText.setText(inputFile.getName());
}
});
inputFileNameText.setEditable(false);
JPanel panel1 = new JPanel(new BorderLayout(0, 0));
panel1.add(inputFileNameText, BorderLayout.CENTER);
panel1.add(inputFileButton, BorderLayout.EAST);
optionPanel.addComponentWithLabel("BEAST XML File: ", panel1);
Color focusColor = UIManager.getColor("Focus.color");
Border focusBorder = BorderFactory.createMatteBorder(2, 2, 2, 2, focusColor);
new FileDrop(null, inputFileNameText, focusBorder, new FileDrop.Listener() {
public void filesDropped(File[] files) {
inputFile = files[0];
inputFileNameText.setText(inputFile.getName());
} // end filesDropped
}); // end FileDrop.Listener
optionPanel.addComponent(overwriteCheckBox);
optionPanel.addSeparator();
ActionListener buttonGroupListener = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
deltaText.setEnabled(ae.getActionCommand().startsWith("D"));
temperaturesArrayText.setEnabled(!ae.getActionCommand().startsWith("D"));
}
};
String MESSAGE_DELTA_TEMP = "Either delta or temperatures option should be used, not both";
deltaButton.setActionCommand("D");
deltaButton.addActionListener(buttonGroupListener);
deltaButton.setToolTipText(MESSAGE_DELTA_TEMP);
temperaturesButton.addActionListener(buttonGroupListener);
temperaturesButton.setActionCommand("T");
temperaturesButton.setToolTipText(MESSAGE_DELTA_TEMP);
ButtonGroup group = new ButtonGroup();
group.add(deltaButton);
group.add(temperaturesButton);
deltaButton.setSelected(true);
chainsText.setColumns(6);
optionPanel.addComponentWithLabel("Number of chains: ", chainsText);
chainsText.setToolTipText("number of chains");
chainsText.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent e) {
temperaturesArrayText.setText(getDefaultTemperaturesArrayString());
}
});
optionPanel.addLabel(MESSAGE_DELTA_TEMP + " :");
deltaText.setColumns(6);
// optionPanel.addComponentWithLabel("Delta: ", deltaText);
deltaText.setToolTipText("temperature increment parameter");
optionPanel.addComponents(deltaButton, deltaText);
temperaturesArrayText.setColumns(20);
// optionPanel.addComponentWithLabel("Temperatures: ", temperaturesArrayText);
temperaturesArrayText.setToolTipText("a comma-separated list of the hot chain temperatures");
optionPanel.addComponents(temperaturesButton, temperaturesArrayText);
swapText.setColumns(10);
optionPanel.addComponentWithLabel("Swap chain every: ", swapText);
swapText.setToolTipText("frequency at which chains temperatures will be swapped");
chainsText.setValue(BeastMC3.HOT_CHAIN_COUNT + 1);
swapText.setValue(BeastMC3.SWAP_CHAIN_EVERY);
deltaText.setValue(BeastMC3.DELTA);
temperaturesArrayText.setText(getDefaultTemperaturesArrayString());
temperaturesArrayText.setEnabled(false); // choose delta then disable temp...
}
public boolean showDialog(String title) {
JOptionPane optionPane = new JOptionPane(optionPanel,
JOptionPane.PLAIN_MESSAGE,
JOptionPane.OK_CANCEL_OPTION,
null,
new String[]{"Run", "Quit"},
"Run");
optionPane.setBorder(new EmptyBorder(12, 12, 12, 12));
final JDialog dialog = optionPane.createDialog(frame, title);
//dialog.setResizable(true);
dialog.pack();
dialog.setVisible(true);
return optionPane.getValue().equals("Run");
}
public boolean allowOverwrite() {
return overwriteCheckBox.isSelected();
}
public int getChains() {
return chainsText.getValue();
}
public double getDelta() {
return deltaText.getValue();
}
public double[] getTemperaturesArray() {
double[] chainTemperatures = new double[getChains()];
chainTemperatures[0] = 1.0;
if (temperaturesButton.isSelected()) {
String line = temperaturesArrayText.getText();
if (line != null) {
String[] tl = line.split(",\\s*");
double[] hotChainTemperatures = new double[tl.length];
assert hotChainTemperatures.length == getChains() - 1;
for (int i = 0; i < tl.length; i++) {
hotChainTemperatures[i] = Double.parseDouble(tl[i]);
}
System.arraycopy(hotChainTemperatures, 0, chainTemperatures, 1, getChains() - 1);
} else {
throw new IllegalArgumentException("Cannot parse hot chain temperatures list (" + line + ")!\n" +
"Please use a comma-separated list (e.g. 0.5,0.3)");
}
} else {
for (int i = 1; i < getChains(); i++) {
chainTemperatures[i] = 1.0 / (1.0 + (getDelta() * i));
}
}
return chainTemperatures;
}
public int getSwap() {
return swapText.getValue();
}
public File getInputFile() {
return inputFile;
}
private String getDefaultTemperaturesArrayString() { // exclude chainTemperatures[0] = 1.0
DecimalFormat df = new DecimalFormat("#0.###");
String defaultTA = "";
for (int i = 1; i < getChains(); i++) {
if (i == 1) {
defaultTA = df.format(1.0 / (1.0 + (getDelta() * 1)));
} else {
defaultTA += "," + df.format(1.0 / (1.0 + (getDelta() * i)));
}
}
return defaultTA;
}
}