/* * 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.beauti.util; import dr.app.beauti.generator.BeastGenerator; import dr.app.beauti.options.BeautiOptions; import dr.app.beauti.options.PartitionData; import dr.evolution.alignment.Alignment; import dr.evolution.io.Importer; import dr.evolution.io.NexusImporter; import dr.evolution.tree.Tree; import dr.evolution.util.Taxa; import dr.evolution.util.TaxonList; 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 final BeautiOptions options = new BeautiOptions(); 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; } //options.guessDates(); try { BeastGenerator generator = new BeastGenerator(options, null); generator.generateXML(new File(outputFileName)); } catch (Exception ioe) { System.err.println("Unable to generate file: " + ioe.getMessage()); } } private boolean readFromFile(File file) throws IOException { try { SAXBuilder parser = new SAXBuilder(); Document doc = parser.build(file); options.beautiTemplate.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 IOException { Alignment alignment = null; Tree tree = null; TaxonList taxa = null; try { FileReader reader = new FileReader(file); NexusApplicationImporter importer = new NexusApplicationImporter(reader); boolean done = false; while (!done) { try { NexusImporter.NexusBlock block = importer.findNextBlock(); if (block == NexusImporter.TAXA_BLOCK) { if (taxa != null) { throw new NexusImporter.MissingBlockException("TAXA block already defined"); } taxa = importer.parseTaxaBlock(); } else if (block == NexusImporter.CALIBRATION_BLOCK) { if (taxa == null) { throw new NexusImporter.MissingBlockException("TAXA or DATA block must be defined before a CALIBRATION block"); } importer.parseCalibrationBlock(options.taxonList); } else if (block == NexusImporter.CHARACTERS_BLOCK) { if (taxa == null) { throw new NexusImporter.MissingBlockException("TAXA block must be defined before a CHARACTERS block"); } if (alignment != null) { throw new NexusImporter.MissingBlockException("CHARACTERS or DATA block already defined"); } alignment = importer.parseCharactersBlock(options.taxonList); } else if (block == NexusImporter.DATA_BLOCK) { if (alignment != 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. alignment = importer.parseDataBlock(options.taxonList); if (taxa == null) { taxa = alignment; } } else if (block == NexusImporter.TREES_BLOCK) { if (taxa == null) { throw new NexusImporter.MissingBlockException("TAXA or DATA block must be defined before a TREES block"); } if (tree != null) { throw new NexusImporter.MissingBlockException("TREES block already defined"); } Tree[] trees = importer.parseTreesBlock(taxa); if (trees.length > 0) { tree = trees[0]; } /* } else if (block == NexusApplicationImporter.PAUP_BLOCK) { importer.parsePAUPBlock(options); } else if (block == NexusApplicationImporter.MRBAYES_BLOCK) { importer.parseMrBayesBlock(options); } else if (block == NexusApplicationImporter.RHINO_BLOCK) { importer.parseRhinoBlock(options); */ } else { // Ignore the block.. } } catch (EOFException ex) { done = true; } } if (alignment == null && taxa == null) { throw new NexusImporter.MissingBlockException("TAXON, 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; } if (options.taxonList == null) { // This is the first partition to be loaded... options.taxonList = new Taxa(taxa); // check the taxon names for invalid characters boolean foundAmp = false; for (int i = 0; i < taxa.getTaxonCount(); i++) { String name = taxa.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 reloading the data file."); return false; } // make sure they all have dates... for (int i = 0; i < taxa.getTaxonCount(); i++) { if (taxa.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); taxa.getTaxon(i).setAttribute("date", date); } } options.fileNameStem = dr.app.util.Utils.trimExtensions(file.getName(), new String[]{"nex", "NEX", "tre", "TRE", "nexus", "NEXUS"}); if (alignment != null) { PartitionData partition = new PartitionData(options, options.fileNameStem, file.getName(), alignment); options.dataPartitions.add(partition); // options.dataType = alignment.getDataType(); // Patterns patterns = new Patterns(alignment); // DistanceMatrix distances = new JukesCantorDistanceMatrix(patterns); // options.meanDistance = distances.getMeanDistance(); } else { // options.meanDistance = 0.0; } } else { // This is an additional partition so check it uses the same taxa } return true; } }