package test.beast.app.beauti; import beast.app.util.Utils; import org.fest.swing.data.Index; import org.fest.swing.data.TableCell; import org.fest.swing.edt.GuiTask; import org.fest.swing.fixture.*; import org.fest.swing.image.ScreenshotTaker; import org.junit.Test; import javax.swing.*; import java.awt.*; import java.io.File; import java.util.Arrays; import static org.fest.swing.edt.GuiActionRunner.execute; import static org.fest.swing.finder.JFileChooserFinder.findFileChooser; public class BeautiRateTutorialTest extends BeautiBase { // file used to store, then reload xml final static String XML_FILE = "rsv.xml"; final static String PREFIX = "doc/tutorials/MEPs/figures/generated/BEAUti_"; @Test public void MEPTutorial() throws Exception { long t0 = System.currentTimeMillis(); ScreenshotTaker screenshotTaker = new ScreenshotTaker(); beauti.frame.setSize(1024, 640); File dir = new File(PREFIX.substring(0, PREFIX.lastIndexOf('/'))); if (!dir.exists()) { dir.mkdir(); } for (File file : dir.listFiles()) { file.delete(); } // 0. Load primate-mtDNA.nex warning("// 0. Load RSV2.nex"); importAlignment("examples/nexus", new File("RSV2.nex")); beautiFrame.menuItemWithPath("Mode", "Automatic set fix mean substitution rate flag").click(); // load anolis.nex JTabbedPaneFixture f = beautiFrame.tabbedPane(); f.requireVisible(); f.requireTitle("Partitions", Index.atIndex(0)); String[] titles = f.tabTitles(); assertArrayEquals(titles,"[Partitions, Tip Dates, Site Model, Clock Model, Priors, MCMC]"); System.err.println(Arrays.toString(titles)); f = f.selectTab("Partitions"); JTableFixture t = beautiFrame.table(); t.selectCell(TableCell.row(0).column(2)); //0. Split partition... warning("0. Split partition..."); beautiFrame.button("Split").click(); JOptionPaneFixture dialog = new JOptionPaneFixture(robot()); dialog.comboBox().selectItem("1 + 2 + 3 frame 3"); dialog.okButton().click(); // check table t = beautiFrame.table(); printTableContents(t); checkTableContents(t, "[RSV2_1, RSV2, 129, 209, nucleotide, RSV2_1, RSV2_1, RSV2_1, false]*" + "[RSV2_2, RSV2, 129, 210, nucleotide, RSV2_2, RSV2_2, RSV2_1, false]*" + "[RSV2_3, RSV2, 129, 210, nucleotide, RSV2_3, RSV2_3, RSV2_1, false]" ); printBeautiState(f); // assertStateEquals("Tree.t:RSV2_2", "clockRate.c:RSV2_2", "birthRate.t:RSV2_2", "Tree.t:RSV2_3", "clockRate.c:RSV2_3", "birthRate.t:RSV2_3", "Tree.t:RSV2_1", "birthRate.t:RSV2_1"); // assertOperatorsEqual("StrictClockRateScaler.c:RSV2_2", "YuleBirthRateScaler.t:RSV2_2", "YuleModelTreeScaler.t:RSV2_2", "YuleModelTreeRootScaler.t:RSV2_2", "YuleModelUniformOperator.t:RSV2_2", "YuleModelSubtreeSlide.t:RSV2_2", "YuleModelNarrow.t:RSV2_2", "YuleModelWide.t:RSV2_2", "YuleModelWilsonBalding.t:RSV2_2", "strictClockUpDownOperator.c:RSV2_2", "StrictClockRateScaler.c:RSV2_3", "YuleBirthRateScaler.t:RSV2_3", "YuleModelTreeScaler.t:RSV2_3", "YuleModelTreeRootScaler.t:RSV2_3", "YuleModelUniformOperator.t:RSV2_3", "YuleModelSubtreeSlide.t:RSV2_3", "YuleModelNarrow.t:RSV2_3", "YuleModelWide.t:RSV2_3", "YuleModelWilsonBalding.t:RSV2_3", "strictClockUpDownOperator.c:RSV2_3", "YuleBirthRateScaler.t:RSV2_1", "YuleModelTreeScaler.t:RSV2_1", "YuleModelTreeRootScaler.t:RSV2_1", "YuleModelUniformOperator.t:RSV2_1", "YuleModelSubtreeSlide.t:RSV2_1", "YuleModelNarrow.t:RSV2_1", "YuleModelWide.t:RSV2_1", "YuleModelWilsonBalding.t:RSV2_1"); // assertPriorsEqual("YuleModel.t:RSV2_1", "YuleModel.t:RSV2_2", "YuleModel.t:RSV2_3", "ClockPrior.c:RSV2_2", "YuleBirthRatePrior.t:RSV2_2", "ClockPrior.c:RSV2_3", "YuleBirthRatePrior.t:RSV2_3", "YuleBirthRatePrior.t:RSV2_1"); // assertTraceLogEqual("posterior", "likelihood", "prior", "treeLikelihood.RSV2_2", "TreeHeight.t:RSV2_2", "clockRate.c:RSV2_2", "YuleModel.t:RSV2_2", "birthRate.t:RSV2_2", "treeLikelihood.RSV2_3", "TreeHeight.t:RSV2_3", "clockRate.c:RSV2_3", "YuleModel.t:RSV2_3", "birthRate.t:RSV2_3", "treeLikelihood.RSV2_1", "TreeHeight.t:RSV2_1", "YuleModel.t:RSV2_1", "birthRate.t:RSV2_1"); assertStateEquals("Tree.t:RSV2_1", "clockRate.c:RSV2_2", "birthRate.t:RSV2_1", "clockRate.c:RSV2_3"); assertOperatorsEqual("StrictClockRateScaler.c:RSV2_2", "YuleBirthRateScaler.t:RSV2_1", "strictClockUpDownOperator.c:RSV2_2", "YuleModelTreeScaler.t:RSV2_1", "YuleModelTreeRootScaler.t:RSV2_1", "YuleModelUniformOperator.t:RSV2_1", "YuleModelSubtreeSlide.t:RSV2_1", "YuleModelNarrow.t:RSV2_1", "YuleModelWide.t:RSV2_1", "YuleModelWilsonBalding.t:RSV2_1", "StrictClockRateScaler.c:RSV2_3", "strictClockUpDownOperator.c:RSV2_3"); assertPriorsEqual("YuleModel.t:RSV2_1", "ClockPrior.c:RSV2_2", "YuleBirthRatePrior.t:RSV2_1", "ClockPrior.c:RSV2_3"); assertTraceLogEqual("posterior", "likelihood", "prior", "treeLikelihood.RSV2_2", "treeLikelihood.RSV2_3", "TreeHeight.t:RSV2_1", "clockRate.c:RSV2_2", "YuleModel.t:RSV2_1", "birthRate.t:RSV2_1", "treeLikelihood.RSV2_1", "clockRate.c:RSV2_3"); //1a. Link trees... warning("1a. Link trees..."); f.selectTab("Partitions"); t = beautiFrame.table(); t.selectCells(TableCell.row(0).column(2), TableCell.row(1).column(2), TableCell.row(2).column(2)); JButtonFixture linkTreesButton = beautiFrame.button("Link Trees"); linkTreesButton.click(); printBeautiState(f); //1b. ...and call the tree "tree" warning("1b. ...and call the tree \"tree\""); f.selectTab("Partitions"); JTableCellFixture cell = beautiFrame.table().cell(TableCell.row(0).column(7)); Component editor = cell.editor(); JComboBoxFixture comboBox = new JComboBoxFixture(robot(), (JComboBox<?>) editor); cell.startEditing(); comboBox.selectAllText(); comboBox.enterText("tree"); cell.stopEditing(); printBeautiState(f); assertStateEquals("clockRate.c:RSV2_2", "clockRate.c:RSV2_3", "Tree.t:tree", "birthRate.t:tree"); assertOperatorsEqual("StrictClockRateScaler.c:RSV2_2", "StrictClockRateScaler.c:RSV2_3", "YuleBirthRateScaler.t:tree", "YuleModelTreeScaler.t:tree", "YuleModelTreeRootScaler.t:tree", "YuleModelUniformOperator.t:tree", "YuleModelSubtreeSlide.t:tree", "YuleModelNarrow.t:tree", "YuleModelWide.t:tree", "YuleModelWilsonBalding.t:tree", "strictClockUpDownOperator.c:RSV2_3", "strictClockUpDownOperator.c:RSV2_2"); assertPriorsEqual("YuleModel.t:tree", "ClockPrior.c:RSV2_2", "ClockPrior.c:RSV2_3", "YuleBirthRatePrior.t:tree"); assertTraceLogEqual("posterior", "likelihood", "prior", "treeLikelihood.RSV2_2", "clockRate.c:RSV2_2", "treeLikelihood.RSV2_3", "clockRate.c:RSV2_3", "treeLikelihood.RSV2_1", "TreeHeight.t:tree", "YuleModel.t:tree", "birthRate.t:tree"); //2a. Link clocks warning("2a. Link clocks"); f.selectTab("Partitions"); t = beautiFrame.table(); t.selectCells(TableCell.row(0).column(2), TableCell.row(1).column(2), TableCell.row(2).column(2)); JButtonFixture linkClocksButton = beautiFrame.button("Link Clock Models"); linkClocksButton.click(); //2b. and call the uncorrelated relaxed molecular clock "clock" warning("2b. and call the uncorrelated relaxed molecular clock \"clock\""); cell = beautiFrame.table().cell(TableCell.row(0).column(6)); editor = cell.editor(); comboBox = new JComboBoxFixture(robot(), (JComboBox<?>) editor); cell.startEditing(); comboBox.selectAllText(); comboBox.enterText("clock"); cell.stopEditing(); printBeautiState(f); assertStateEquals("Tree.t:tree", "birthRate.t:tree"); assertOperatorsEqual("YuleBirthRateScaler.t:tree", "YuleModelTreeScaler.t:tree", "YuleModelTreeRootScaler.t:tree", "YuleModelUniformOperator.t:tree", "YuleModelSubtreeSlide.t:tree", "YuleModelNarrow.t:tree", "YuleModelWide.t:tree", "YuleModelWilsonBalding.t:tree"); assertPriorsEqual("YuleModel.t:tree", "YuleBirthRatePrior.t:tree"); assertTraceLogEqual("posterior", "likelihood", "prior", "treeLikelihood.RSV2_2", "treeLikelihood.RSV2_3", "treeLikelihood.RSV2_1", "TreeHeight.t:tree", "YuleModel.t:tree", "birthRate.t:tree"); //3a. Link site models warning("3a. link site models"); f.selectTab("Partitions"); t = beautiFrame.table(); t.selectCells(TableCell.row(0).column(2), TableCell.row(1).column(2), TableCell.row(2).column(2)); JButtonFixture linkSiteModelsButton = beautiFrame.button("Link Site Models"); linkSiteModelsButton.click(); //3b. Set the site model to HKY (empirical) warning("3b. Set the site model to HKY (empirical)"); f.selectTab("Site Model"); beautiFrame.comboBox("substModel").selectItem("HKY"); JComboBoxFixture freqs = beautiFrame.comboBox("frequencies"); freqs.selectItem("Empirical"); beautiFrame.checkBox("mutationRate.isEstimated").check(); JCheckBoxFixture fixMeanMutationRate = beautiFrame.checkBox("FixMeanMutationRate"); fixMeanMutationRate.check(); screenshotTaker.saveComponentAsPng(beauti.frame, PREFIX + "Site_Model.png"); printBeautiState(f); //3c. Unlink site models warning("3c. unlink site models"); f.selectTab("Partitions"); t = beautiFrame.table(); t.selectCells(TableCell.row(0).column(2), TableCell.row(1).column(2), TableCell.row(2).column(2)); JButtonFixture unlinkSiteModelsButton = beautiFrame.button("Unlink Site Models"); unlinkSiteModelsButton.click(); printBeautiState(f); assertStateEquals("Tree.t:tree", "birthRate.t:tree", "kappa.s:RSV2_1", "mutationRate.s:RSV2_1", "kappa.s:RSV2_2", "mutationRate.s:RSV2_2", "kappa.s:RSV2_3", "mutationRate.s:RSV2_3"); assertOperatorsEqual("YuleBirthRateScaler.t:tree", "YuleModelTreeScaler.t:tree", "YuleModelTreeRootScaler.t:tree", "YuleModelUniformOperator.t:tree", "YuleModelSubtreeSlide.t:tree", "YuleModelNarrow.t:tree", "YuleModelWide.t:tree", "YuleModelWilsonBalding.t:tree", "KappaScaler.s:RSV2_1", "KappaScaler.s:RSV2_2", "KappaScaler.s:RSV2_3", "FixMeanMutationRatesOperator"); assertPriorsEqual("YuleModel.t:tree", "YuleBirthRatePrior.t:tree", "KappaPrior.s:RSV2_1", "KappaPrior.s:RSV2_2", "KappaPrior.s:RSV2_3"); assertTraceLogEqual("posterior", "likelihood", "prior", "treeLikelihood.RSV2_2", "treeLikelihood.RSV2_3", "treeLikelihood.RSV2_1", "TreeHeight.t:tree", "YuleModel.t:tree", "birthRate.t:tree", "kappa.s:RSV2_1", "mutationRate.s:RSV2_1", "kappa.s:RSV2_2", "mutationRate.s:RSV2_2", "kappa.s:RSV2_3", "mutationRate.s:RSV2_3"); screenshotTaker.saveComponentAsPng(beauti.frame, PREFIX + "partition.png"); //4. set up tip dates f = f.selectTab("Tip Dates"); warning("4. Seting up tip dates"); beautiFrame.checkBox().click(); beautiFrame.button("Guess").click(); JOptionPaneFixture dialog2 = new JOptionPaneFixture(robot()); dialog2.textBox("SplitChar").deleteText().enterText("s"); screenshotTaker.saveComponentAsPng(dialog2.component(), PREFIX + "GuessDates.png"); dialog2.comboBox("delimiterCombo").selectItem("after last"); dialog2.okButton().click(); screenshotTaker.saveComponentAsPng(beauti.frame, PREFIX + "dates.png"); printBeautiState(f); assertStateEquals("Tree.t:tree", "birthRate.t:tree", "kappa.s:RSV2_1", "mutationRate.s:RSV2_1", "kappa.s:RSV2_2", "mutationRate.s:RSV2_2", "kappa.s:RSV2_3", "mutationRate.s:RSV2_3", "clockRate.c:clock"); assertOperatorsEqual("YuleBirthRateScaler.t:tree", "YuleModelTreeScaler.t:tree", "YuleModelTreeRootScaler.t:tree", "YuleModelUniformOperator.t:tree", "YuleModelSubtreeSlide.t:tree", "YuleModelNarrow.t:tree", "YuleModelWide.t:tree", "YuleModelWilsonBalding.t:tree", "KappaScaler.s:RSV2_1", "KappaScaler.s:RSV2_2", "KappaScaler.s:RSV2_3", "FixMeanMutationRatesOperator", "StrictClockRateScaler.c:clock", "strictClockUpDownOperator.c:clock"); assertPriorsEqual("YuleModel.t:tree", "YuleBirthRatePrior.t:tree", "KappaPrior.s:RSV2_1", "KappaPrior.s:RSV2_2", "KappaPrior.s:RSV2_3", "ClockPrior.c:clock"); assertTraceLogEqual("posterior", "likelihood", "prior", "treeLikelihood.RSV2_2", "treeLikelihood.RSV2_3", "treeLikelihood.RSV2_1", "TreeHeight.t:tree", "YuleModel.t:tree", "birthRate.t:tree", "kappa.s:RSV2_1", "mutationRate.s:RSV2_1", "kappa.s:RSV2_2", "mutationRate.s:RSV2_2", "kappa.s:RSV2_3", "mutationRate.s:RSV2_3", "clockRate.c:clock"); //5. Change tree prior to Coalescent with constant pop size warning("5a. Change tree prior to Coalescent with constant pop size"); f.selectTab("Priors"); beautiFrame.comboBox("TreeDistribution").selectItem("Coalescent Constant Population"); warning("5b. Change clock prior to Log Normal with M = -5, S = 1.25"); beautiFrame.comboBox("clockRate.c:clock.distr").selectItem("Log Normal"); beautiFrame.button("ClockPrior.c:clock.editButton").click(); beautiFrame.textBox("M").selectAll().setText("-5"); beautiFrame.textBox("S").selectAll().setText("1.25"); screenshotTaker.saveComponentAsPng(beauti.frame, PREFIX + "priors.png"); printBeautiState(f); assertStateEquals("Tree.t:tree", "kappa.s:RSV2_1", "mutationRate.s:RSV2_1", "kappa.s:RSV2_2", "mutationRate.s:RSV2_2", "kappa.s:RSV2_3", "mutationRate.s:RSV2_3", "clockRate.c:clock", "popSize.t:tree"); assertOperatorsEqual("CoalescentConstantTreeScaler.t:tree", "CoalescentConstantTreeRootScaler.t:tree", "CoalescentConstantUniformOperator.t:tree", "CoalescentConstantSubtreeSlide.t:tree", "CoalescentConstantNarrow.t:tree", "CoalescentConstantWide.t:tree", "CoalescentConstantWilsonBalding.t:tree", "KappaScaler.s:RSV2_1", "KappaScaler.s:RSV2_2", "KappaScaler.s:RSV2_3", "FixMeanMutationRatesOperator", "StrictClockRateScaler.c:clock", "strictClockUpDownOperator.c:clock", "PopSizeScaler.t:tree"); assertPriorsEqual("CoalescentConstant.t:tree", "ClockPrior.c:clock", "KappaPrior.s:RSV2_1", "KappaPrior.s:RSV2_2", "KappaPrior.s:RSV2_3", "PopSizePrior.t:tree"); assertTraceLogEqual("posterior", "likelihood", "prior", "treeLikelihood.RSV2_2", "treeLikelihood.RSV2_3", "treeLikelihood.RSV2_1", "TreeHeight.t:tree", "kappa.s:RSV2_1", "mutationRate.s:RSV2_1", "kappa.s:RSV2_2", "mutationRate.s:RSV2_2", "kappa.s:RSV2_3", "mutationRate.s:RSV2_3", "clockRate.c:clock", "popSize.t:tree", "CoalescentConstant.t:tree"); //6. Run MCMC and look at results in Tracer, TreeAnnotator->FigTree warning("6. Setting up MCMC parameters"); f = f.selectTab("MCMC"); beautiFrame.textBox("chainLength").selectAll().setText("2000000"); beautiFrame.button("tracelog.editButton").click(); beautiFrame.textBox("logEvery").selectAll().setText("400"); beautiFrame.button("tracelog.editButton").click(); beautiFrame.button("treelog.t:tree.editButton").click(); beautiFrame.textBox("logEvery").selectAll().setText("400"); screenshotTaker.saveComponentAsPng(beauti.frame, PREFIX + "mcmc.png"); beautiFrame.button("treelog.t:tree.editButton").click(); printBeautiState(f); assertStateEquals("Tree.t:tree", "kappa.s:RSV2_1", "mutationRate.s:RSV2_1", "kappa.s:RSV2_2", "mutationRate.s:RSV2_2", "kappa.s:RSV2_3", "mutationRate.s:RSV2_3", "clockRate.c:clock", "popSize.t:tree"); assertOperatorsEqual("CoalescentConstantTreeScaler.t:tree", "CoalescentConstantTreeRootScaler.t:tree", "CoalescentConstantUniformOperator.t:tree", "CoalescentConstantSubtreeSlide.t:tree", "CoalescentConstantNarrow.t:tree", "CoalescentConstantWide.t:tree", "CoalescentConstantWilsonBalding.t:tree", "KappaScaler.s:RSV2_1", "KappaScaler.s:RSV2_2", "KappaScaler.s:RSV2_3", "FixMeanMutationRatesOperator", "StrictClockRateScaler.c:clock", "strictClockUpDownOperator.c:clock", "PopSizeScaler.t:tree"); assertPriorsEqual("CoalescentConstant.t:tree", "ClockPrior.c:clock", "KappaPrior.s:RSV2_1", "KappaPrior.s:RSV2_2", "KappaPrior.s:RSV2_3", "PopSizePrior.t:tree"); assertTraceLogEqual("posterior", "likelihood", "prior", "treeLikelihood.RSV2_2", "treeLikelihood.RSV2_3", "treeLikelihood.RSV2_1", "TreeHeight.t:tree", "kappa.s:RSV2_1", "mutationRate.s:RSV2_1", "kappa.s:RSV2_2", "mutationRate.s:RSV2_2", "kappa.s:RSV2_3", "mutationRate.s:RSV2_3", "clockRate.c:clock", "popSize.t:tree", "CoalescentConstant.t:tree"); //7. Run MCMC and look at results in Tracer, TreeAnnotator->FigTree warning("7. Run MCMC and look at results in Tracer, TreeAnnotator->FigTree"); makeSureXMLParses(); long t1 = System.currentTimeMillis(); System.err.println("total time: " + (t1 - t0)/1000 + " seconds"); } @Test public void MEPBSPTutorial() throws InterruptedException { if (true) {return;} try { long t0 = System.currentTimeMillis(); ScreenshotTaker screenshotTaker = new ScreenshotTaker(); beauti.frame.setSize(1024, 640); // 1. reaload XML file warning("1. reload rsv.xml"); String dir = "" + org.fest.util.Files.temporaryFolder(); String file = XML_FILE; if (!Utils.isMac()) { beautiFrame.menuItemWithPath("File", "Load").click(); JFileChooserFixture fileChooser = findFileChooser().using(robot()); fileChooser.setCurrentDirectory(new File(dir)); fileChooser.selectFile(new File(file)).approve(); } else { _file = new File(dir + "/" + file); execute(new GuiTask() { @Override protected void executeInEDT() { doc.newAnalysis(); doc.setFileName(_file.getAbsolutePath()); try { doc.loadXML(new File(doc.getFileName())); } catch (Exception e) { e.printStackTrace(); } } }); } JTabbedPaneFixture f = beautiFrame.tabbedPane(); printBeautiState(f); // 2. change tree prior to BSP warning("2. change tree prior to BSP"); f.selectTab("Priors"); beautiFrame.comboBox("TreeDistribution").selectItem("Coalescent Bayesian Skyline"); screenshotTaker.saveComponentAsPng(beauti.frame, PREFIX + "priors2.png"); printBeautiState(f); // 3. change tree prior to BSP warning("3. change group and population size parameters"); beautiFrame.menuItemWithPath("View","Show Initialization panel").click(); beautiFrame.button("isPopSizes.t:tree.editButton").click(); beautiFrame.textBox("dimension").selectAll().setText("3"); beautiFrame.button("isPopSizes.t:tree.editButton").click(); beautiFrame.button("isGroupSizes.t:tree.editButton").click(); beautiFrame.textBox("dimension").selectAll().setText("3"); screenshotTaker.saveComponentAsPng(beauti.frame, PREFIX + "init.png"); printBeautiState(f); // 4. set chain-length to 10M, log every 10K warning("4. set chain-length to 10M, log every 10K"); f = f.selectTab("MCMC"); beautiFrame.textBox("chainLength").selectAll().setText("10000000"); beautiFrame.button("tracelog.editButton").click(); beautiFrame.textBox("logEvery").selectAll().setText("10000"); beautiFrame.button("tracelog.editButton").click(); beautiFrame.button("treelog.t:tree.editButton").click(); beautiFrame.textBox("logEvery").selectAll().setText("10000"); beautiFrame.button("treelog.t:tree.editButton").click(); printBeautiState(f); // 5. save XML file warning("5. save XML file"); File fout = new File(org.fest.util.Files.temporaryFolder() + "/" + XML_FILE); if (fout.exists()) { fout.delete(); } saveFile(""+org.fest.util.Files.temporaryFolder(), XML_FILE); //4. Run MCMC and look at results in Tracer, TreeAnnotator->FigTree makeSureXMLParses(); long t1 = System.currentTimeMillis(); System.err.println("total time: " + (t1 - t0)/1000 + " seconds"); } catch (Exception e) { e.printStackTrace(); } } }