/* * BeautiMacFileMenuFactory.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.oldbeauti; import dr.evolution.alignment.Patterns; import dr.evolution.alignment.SimpleAlignment; import dr.evolution.distance.DistanceMatrix; import dr.evolution.distance.JukesCantorDistanceMatrix; import dr.evolution.io.Importer; import dr.evolution.io.NexusImporter; import dr.evolution.tree.Tree; import dr.evolution.util.Units; import org.jdom.Document; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; import java.io.*; /** * @author Andrew Rambaut * @author Alexei Drummond * @version $Id: BeautiFrame.java,v 1.22 2006/09/09 16:07:06 rambaut Exp $ */ public class CommandLineBeauti { private BeastGenerator beautiOptions = new BeastGenerator(); public CommandLineBeauti(String inputFileName, String templateFileName, String outputFileName) { try { if (!importFromFile(new File(inputFileName))) { return; } } catch (FileNotFoundException fnfe) { System.err.println("Error: Input file not found"); return; } catch (IOException ioe) { System.err.println("Error reading input file: " + ioe.getMessage()); return; } try { if (!readFromFile(new File(templateFileName))) { return; } } catch (FileNotFoundException fnfe) { System.err.println("Error: Template file not found"); return; } catch (IOException ioe) { System.err.println("Error reading template file: " + ioe.getMessage()); return; } beautiOptions.guessDates(); try { generate(new File(outputFileName)); } catch (IOException ioe) { System.err.println("Unable to generate file: " + ioe.getMessage()); return; } } private boolean readFromFile(File file) throws FileNotFoundException, IOException { try { SAXBuilder parser = new SAXBuilder(); Document doc = parser.build(file); beautiOptions.parse(doc); } catch (dr.xml.XMLParseException xpe) { System.err.println("Error reading file: This may not be a BEAUti Template file"); System.err.println(xpe.getMessage()); return false; } catch (JDOMException e) { System.err.println("Unable to open file: This may not be a BEAUti Template file"); System.err.println(e.getMessage()); return false; } return true; } private boolean importFromFile(File file) throws FileNotFoundException, IOException { try { FileReader reader = new FileReader(file); NexusApplicationImporter importer = new NexusApplicationImporter(reader); boolean done = false; beautiOptions.originalAlignment = null; beautiOptions.alignment = null; beautiOptions.tree = null; beautiOptions.taxonList = null; while (!done) { try { NexusImporter.NexusBlock block = importer.findNextBlock(); if (block == NexusImporter.TAXA_BLOCK) { if (beautiOptions.taxonList != null) { throw new NexusImporter.MissingBlockException("TAXA block already defined"); } beautiOptions.taxonList = importer.parseTaxaBlock(); } else if (block == NexusImporter.CALIBRATION_BLOCK) { if (beautiOptions.taxonList == null) { throw new NexusImporter.MissingBlockException("TAXA or DATA block must be defined before a CALIBRATION block"); } importer.parseCalibrationBlock(beautiOptions.taxonList); } else if (block == NexusImporter.CHARACTERS_BLOCK) { if (beautiOptions.taxonList == null) { throw new NexusImporter.MissingBlockException("TAXA block must be defined before a CHARACTERS block"); } if (beautiOptions.originalAlignment != null) { throw new NexusImporter.MissingBlockException("CHARACTERS or DATA block already defined"); } beautiOptions.originalAlignment = (SimpleAlignment)importer.parseCharactersBlock(beautiOptions.taxonList); } else if (block == NexusImporter.DATA_BLOCK) { if (beautiOptions.originalAlignment != null) { throw new NexusImporter.MissingBlockException("CHARACTERS or DATA block already defined"); } // A data block doesn't need a taxon block before it // but if one exists then it will use it. beautiOptions.originalAlignment = (SimpleAlignment)importer.parseDataBlock(beautiOptions.taxonList); if (beautiOptions.taxonList == null) { beautiOptions.taxonList = beautiOptions.originalAlignment; } } else if (block == NexusImporter.TREES_BLOCK) { if (beautiOptions.taxonList == null) { throw new NexusImporter.MissingBlockException("TAXA or DATA block must be defined before a TREES block"); } if (beautiOptions.tree != null) { throw new NexusImporter.MissingBlockException("TREES block already defined"); } Tree[] trees = importer.parseTreesBlock(beautiOptions.taxonList); if (trees.length > 0) { beautiOptions.tree = trees[0]; } /* } else if (block == NexusApplicationImporter.PAUP_BLOCK) { importer.parsePAUPBlock(beautiOptions); } else if (block == NexusApplicationImporter.MRBAYES_BLOCK) { importer.parseMrBayesBlock(beautiOptions); } else if (block == NexusApplicationImporter.RHINO_BLOCK) { importer.parseRhinoBlock(beautiOptions); */ } else { // Ignore the block.. } } catch (EOFException ex) { done = true; } } if (beautiOptions.originalAlignment == null) { throw new NexusImporter.MissingBlockException("DATA or CHARACTERS block is missing"); } } catch (Importer.ImportException ime) { System.err.println("Error parsing imported file: " + ime); return false; } catch (IOException ioex) { System.err.println("File I/O Error: " + ioex); return false; } catch (Exception ex) { System.err.println("Fatal exception: " + ex); return false; } // check the taxon names for invalid characters boolean foundAmp = false; for (int i = 0; i < beautiOptions.originalAlignment.getTaxonCount(); i++) { String name = beautiOptions.originalAlignment.getTaxon(i).getId(); if (name.indexOf('&') >= 0) { foundAmp = true; } } if (foundAmp) { System.err.println("One or more taxon names include an illegal character ('&').\n" + "These characters will prevent BEAST from reading the resulting XML file.\n\n" + "Please edit the taxon name(s) before generating the BEAST file."); } // make sure they all have dates... for (int i = 0; i < beautiOptions.originalAlignment.getTaxonCount(); i++) { if (beautiOptions.originalAlignment.getTaxonAttribute(i, "date") == null) { java.util.Date origin = new java.util.Date(0); dr.evolution.util.Date date = dr.evolution.util.Date.createTimeSinceOrigin(0.0, Units.Type.YEARS, origin); beautiOptions.originalAlignment.getTaxon(i).setAttribute("date", date); } } beautiOptions.fileNameStem = dr.app.util.Utils.trimExtensions(file.getName(), new String[] {"nex", "NEX", "tre", "TRE", "nexus", "NEXUS"}); beautiOptions.alignment = beautiOptions.originalAlignment; beautiOptions.alignmentReset = true; if (beautiOptions.alignment != null) { Patterns patterns = new Patterns(beautiOptions.alignment); DistanceMatrix distances = new JukesCantorDistanceMatrix(patterns); beautiOptions.meanDistance = distances.getMeanDistance(); } return true; } private void generate(File file) throws IOException { FileWriter fw = new FileWriter(file); beautiOptions.generateXML(fw); fw.close(); } }