<commit_before>/*
 * MCMCPanel.java
 *
 * Copyright (C) 2002-2009 <NAME> and <NAME>
 *
 * 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.beauti.BeautiFrame;
import dr.app.beauti.BeautiPanel;
import dr.app.beauti.components.marginalLikelihoodEstimation.MLEDialog;
import dr.app.beauti.components.marginalLikelihoodEstimation.MarginalLikelihoodEstimationOptions;
import dr.app.beauti.components.sequenceerror.SequenceErrorModelComponentOptions;
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.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 <NAME>
 * @author <NAME>
 * @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");
    JCheckBox performMLE = new JCheckBox("Perform marginal likelihood estimation (MLE) using path sampling/stepping-stone sampling");
    JButton buttonMLE = 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 operatorAnalaysisCheck = new JCheckBox("Create operator analysis file:");
    JTextArea operatorAnalaysisFileNameField = new JTextArea(DEFAULT_FILE_NAME_STEM + ".ops");

    BeautiFrame frame = null;
    private final OptionsPanel optionsPanel;
    private BeautiOptions options;

    private MLEDialog mleDialog = null;
    private MarginalLikelihoodEstimationOptions mleOptions;

    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(operatorAnalaysisCheck);
        operatorAnalaysisCheck.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
                options.operatorAnalysis = operatorAnalaysisCheck.isSelected();

                updateOtherFileNames(options);

                frame.setDirty();
            }
        });

        operatorAnalaysisFileNameField.setColumns(32);
        operatorAnalaysisFileNameField.setEditable(false);
        operatorAnalaysisFileNameField.setEnabled(false);
        optionsPanel.addComponentWithLabel("Operator analysis file name:", operatorAnalaysisFileNameField);

        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 likelihoood " +
                "estimation (MLE) using path sampling (PS) / stepping-stone sampling (SS) " +
                "which performs an additional analysis after the standard MCMC chain has finished.");
        mleInfo.setColumns(50);
        PanelUtils.setupComponent(mleInfo);
        optionsPanel.addSpanningComponent(mleInfo);

        optionsPanel.addComponent(performMLE);
        //will be false by default
        //options.performMLE = false;
        optionsPanel.addComponent(buttonMLE);
        buttonMLE.setEnabled(false);
        performMLE.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (performMLE.isSelected()) {
                    mleOptions.performMLE = true;
                    buttonMLE.setEnabled(true);
                    updateMLEFileNameStem();
                } else {
                    mleOptions.performMLE = false;
                    buttonMLE.setEnabled(false);
                }
            }
        });
        buttonMLE.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
                updateMLEFileNameStem();

                int result = mleDialog.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 = options.fileNameStem + "." + tree.getPrefix() + "(time)." + STARBEASTOptions.TREE_FILE_NAME;
            } else {
                treeFileName = options.fileNameStem + "." + tree.getPrefix() + STARBEASTOptions.TREE_FILE_NAME; // stem.partitionName.tree
            }
            if (addTxt.isSelected()) treeFileName = treeFileName + ".txt";
            options.treeFileName.add(treeFileName);

            if (options.substTreeLog) {
                treeFileName = options.fileNameStem + "." + tree.getPrefix() + "(subst)." + STARBEASTOptions.TREE_FILE_NAME;
                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 displayTreeList(List<String> treeList) {
        String text = "";

        for (String t : treeList) {
            text = text + t;
            if (treeList.indexOf(t) < treeList.size() - 1) {
                text = text + "; ";
            }
        }

        return text;<commit_msg>Issue 709:	MCMC tab in Beautie v1.8.0 problem with multiple unlinked loci<commit_after>/*
 * MCMCPanel.java
 *
 * Copyright (C) 2002-2009 <NAME> and <NAME>
 *
 * 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.beauti.BeautiFrame;
import dr.app.beauti.BeautiPanel;
import dr.app.beauti.components.marginalLikelihoodEstimation.MLEDialog;
import dr.app.beauti.components.marginalLikelihoodEstimation.MarginalLikelihoodEstimationOptions;
import dr.app.beauti.components.sequenceerror.SequenceErrorModelComponentOptions;
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.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 <NAME>
 * @author <NAME>
 * @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");
    JCheckBox performMLE = new JCheckBox("Perform marginal likelihood estimation (MLE) using path sampling/stepping-stone sampling");
    JButton buttonMLE = 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 operatorAnalaysisCheck = new JCheckBox("Create operator analysis file:");
    JTextArea operatorAnalaysisFileNameField = new JTextArea(DEFAULT_FILE_NAME_STEM + ".ops");

    BeautiFrame frame = null;
    private final OptionsPanel optionsPanel;
    private BeautiOptions options;

    private MLEDialog mleDialog = null;
    private MarginalLikelihoodEstimationOptions mleOptions;

    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(operatorAnalaysisCheck);
        operatorAnalaysisCheck.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
                options.operatorAnalysis = operatorAnalaysisCheck.isSelected();

                updateOtherFileNames(options);

                frame.setDirty();
            }
        });

        operatorAnalaysisFileNameField.setColumns(32);
        operatorAnalaysisFileNameField.setEditable(false);
        operatorAnalaysisFileNameField.setEnabled(false);
        optionsPanel.addComponentWithLabel("Operator analysis file name:", operatorAnalaysisFileNameField);

        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 likelihoood " +
                "estimation (MLE) using path sampling (PS) / stepping-stone sampling (SS) " +
                "which performs an additional analysis after the standard MCMC chain has finished.");
        mleInfo.setColumns(50);
        PanelUtils.setupComponent(mleInfo);
        optionsPanel.addSpanningComponent(mleInfo);

        optionsPanel.addComponent(performMLE);
        //will be false by default
        //options.performMLE = false;
        optionsPanel.addComponent(buttonMLE);
        buttonMLE.setEnabled(false);
        performMLE.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (performMLE.isSelected()) {
                    mleOptions.performMLE = true;
                    buttonMLE.setEnabled(true);
                    updateMLEFileNameStem();
                } else {
                    mleOptions.performMLE = false;
                    buttonMLE.setEnabled(false);
                }
            }
        });
        buttonMLE.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
                updateMLEFileNameStem();

                int result = mleDialog.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("");
        }
{'fraction_non_alphanumeric': 0.09237333333333334, 'fraction_numerical': 0.00768, 'mean_word_length': 2.648936170212766, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5515192', 'n_tokens_mistral': 7693, 'n_tokens_neox': 7403, 'n_words': 1517}