3 // FORESTER -- software libraries and applications
4 // for evolutionary biology research and applications.
6 // Copyright (C) 2008-2009 Christian M. Zmasek
7 // Copyright (C) 2008-2009 Burnham Institute for Medical Research
10 // This library is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Lesser General Public
12 // License as published by the Free Software Foundation; either
13 // version 2.1 of the License, or (at your option) any later version.
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 // Contact: phylosoft @ gmail . com
25 // WWW: www.phylosoft.org/forester
27 package org.forester.application;
30 import java.io.IOException;
31 import java.util.ArrayList;
32 import java.util.HashSet;
33 import java.util.List;
36 import org.forester.io.writers.PhylogenyWriter;
37 import org.forester.phylogeny.Phylogeny;
38 import org.forester.phylogeny.PhylogenyNode;
39 import org.forester.phylogeny.factories.ParserBasedPhylogenyFactory;
40 import org.forester.phylogeny.factories.PhylogenyFactory;
41 import org.forester.phylogeny.iterators.PhylogenyNodeIterator;
42 import org.forester.tools.ConfidenceAssessor;
43 import org.forester.util.CommandLineArguments;
44 import org.forester.util.ForesterUtil;
46 public class confadd {
48 final static private String HELP_OPTION_1 = "help";
49 final static private String HELP_OPTION_2 = "h";
50 final static private String FIRST_OPTION = "f";
51 final static private String LAST_OPTION = "l";
52 final static private String STRICT_OPTION = "s";
53 final static private String NORMALIZE_OPTION = "n";
54 final static private String PRG_NAME = "confadd";
55 final static private String PRG_VERSION = "1.01";
56 final static private String PRG_DATE = "2010.10.26";
57 final static private String E_MAIL = "czmasek@burnham.org";
58 final static private String WWW = "www.phylosoft.org/forester/";
60 public static void main( final String args[] ) {
61 ForesterUtil.printProgramInformation( PRG_NAME, PRG_VERSION, PRG_DATE, E_MAIL, WWW );
62 CommandLineArguments cla = null;
64 cla = new CommandLineArguments( args );
66 catch ( final Exception e ) {
67 ForesterUtil.fatalError( PRG_NAME, e.getMessage() );
69 if ( cla.isOptionSet( HELP_OPTION_1 ) || cla.isOptionSet( HELP_OPTION_2 ) || ( args.length == 0 ) ) {
73 if ( args.length < 4 ) {
75 System.out.println( "[" + PRG_NAME + "] incorrect number of arguments" );
80 if ( cla.getNumberOfNames() != 4 ) {
82 System.out.println( "[" + PRG_NAME + "] incorrect number of arguments" );
87 final List<String> allowed_options = new ArrayList<String>();
88 allowed_options.add( FIRST_OPTION );
89 allowed_options.add( LAST_OPTION );
90 allowed_options.add( STRICT_OPTION );
91 allowed_options.add( NORMALIZE_OPTION );
92 final String dissallowed_options = cla.validateAllowedOptionsAsString( allowed_options );
93 if ( dissallowed_options.length() > 0 ) {
94 ForesterUtil.fatalError( PRG_NAME, "unknown option(s): " + dissallowed_options );
96 final String confidence_type = cla.getName( 0 );
97 final File target_file = cla.getFile( 1 );
98 final File evaluators_file = cla.getFile( 2 );
99 final File outfile = cla.getFile( 3 );
100 if ( ForesterUtil.isEmpty( confidence_type ) ) {
101 ForesterUtil.fatalError( PRG_NAME, "attempt to use empty confidence type" );
103 if ( outfile.exists() ) {
104 ForesterUtil.fatalError( PRG_NAME, "[" + outfile + "] already exists" );
106 if ( !target_file.exists() ) {
107 ForesterUtil.fatalError( PRG_NAME, "target [" + target_file + "] does not exist" );
109 if ( !evaluators_file.exists() ) {
110 ForesterUtil.fatalError( PRG_NAME, "evaluators [" + evaluators_file + "] does not exist" );
112 boolean strict = false;
117 if ( cla.isOptionSet( STRICT_OPTION ) ) {
118 if ( cla.isOptionHasAValue( STRICT_OPTION ) ) {
119 ForesterUtil.fatalError( PRG_NAME, "no value allowed for -" + STRICT_OPTION + " allowed" );
123 if ( cla.isOptionSet( FIRST_OPTION ) ) {
124 first = cla.getOptionValueAsInt( FIRST_OPTION );
126 if ( cla.isOptionSet( LAST_OPTION ) ) {
127 last = cla.getOptionValueAsInt( LAST_OPTION );
129 if ( cla.isOptionSet( NORMALIZE_OPTION ) ) {
130 norm = cla.getOptionValueAsDouble( NORMALIZE_OPTION );
133 catch ( final Exception e ) {
134 ForesterUtil.fatalError( PRG_NAME, "error in command line: " + e.getLocalizedMessage() );
136 if ( ( first < 0 ) || ( last < 0 ) ) {
138 .fatalError( PRG_NAME,
139 "attempt to set first or last evaluator topology to use to a number less than zero" );
142 ForesterUtil.fatalError( PRG_NAME, "illegal value for normalizer [" + norm + "]" );
144 Phylogeny[] targets = null;
145 Phylogeny[] evaluators = null;
146 final PhylogenyFactory factory = ParserBasedPhylogenyFactory.getInstance();
148 targets = factory.create( target_file, ForesterUtil.createParserDependingOnFileType( target_file, true ) );
150 catch ( final IOException e ) {
151 ForesterUtil.fatalError( PRG_NAME,
152 "failed to read target phylogenies from [" + target_file + "]: "
153 + e.getLocalizedMessage() );
156 for( final Phylogeny target : targets ) {
158 checkUniquenessOfExternalNodes( target, "target " + counter );
160 catch ( final IllegalArgumentException e ) {
161 ForesterUtil.fatalError( PRG_NAME, e.getLocalizedMessage() );
165 if ( targets.length == 1 ) {
166 ForesterUtil.programMessage( PRG_NAME, "read in one target" );
169 ForesterUtil.programMessage( PRG_NAME, "read in a total of " + targets.length + " targets" );
172 evaluators = factory.create( evaluators_file,
173 ForesterUtil.createParserDependingOnFileType( evaluators_file, true ) );
175 catch ( final IOException e ) {
176 ForesterUtil.fatalError( PRG_NAME, "failed to read evaluator topologies from [" + evaluators_file + "]: "
177 + e.getLocalizedMessage() );
180 for( final Phylogeny evaluator : evaluators ) {
182 checkUniquenessOfExternalNodes( evaluator, "evaluator " + counter );
184 catch ( final IllegalArgumentException e ) {
185 ForesterUtil.fatalError( PRG_NAME, e.getLocalizedMessage() );
189 ForesterUtil.programMessage( PRG_NAME, "read in a total of " + evaluators.length + " evaluator topologies" );
192 last = evaluators.length - 1;
194 if ( ( last >= evaluators.length ) || ( last <= first ) ) {
195 ForesterUtil.fatalError( PRG_NAME, "illegal value for first or last evaluator topology to use [" + first
196 + ", " + last + "]" );
200 value = norm / ( 1 + last - first );
202 ForesterUtil.programMessage( PRG_NAME, "first topology to use: " + first );
204 if ( last == ( evaluators.length - 1 ) ) {
205 is_last = " (corresponds to last topology in file)";
207 ForesterUtil.programMessage( PRG_NAME, "last topology to use : " + last + is_last );
208 ForesterUtil.programMessage( PRG_NAME, "sum of topologies used as evaluators: " + ( last - first + 1 ) );
210 ForesterUtil.programMessage( PRG_NAME, "normalizer: " + norm + " (" + ForesterUtil.round( value, 6 ) + ")" );
213 ForesterUtil.programMessage( PRG_NAME, "normalizer: n/a" );
215 ForesterUtil.programMessage( PRG_NAME, "strict: " + strict );
216 for( final Phylogeny target : targets ) {
218 ConfidenceAssessor.evaluate( confidence_type, evaluators, target, strict, value, first, last );
220 catch ( final IllegalArgumentException e ) {
221 ForesterUtil.fatalError( PRG_NAME, e.getLocalizedMessage() );
225 final PhylogenyWriter writer = new PhylogenyWriter();
226 writer.toPhyloXML( targets, 0, outfile, ForesterUtil.LINE_SEPARATOR );
228 catch ( final IOException e ) {
229 ForesterUtil.fatalError( PRG_NAME, "failed to write to [" + outfile + "]: " + e.getLocalizedMessage() );
231 ForesterUtil.programMessage( PRG_NAME, "wrote output to: [" + outfile + "]" );
232 ForesterUtil.programMessage( PRG_NAME, "OK" );
233 System.out.println();
236 private static void printHelp() {
237 System.out.println( "Usage:" );
238 System.out.println();
239 System.out.println( PRG_NAME
240 + " [options] <confidence type> <target tree file> <evaluators tree file> <outfile>" );
241 System.out.println();
242 System.out.println( "options:" );
243 System.out.println();
244 System.out.println( " -" + STRICT_OPTION
245 + " : strict [default: non-strict]: all nodes between 'target' and 'evaluators' must match" );
246 System.out.println( " -" + NORMALIZE_OPTION
247 + "=<d>: normalize to this value (e.g. 100 for most bootstrap analyses) [default: no normalization]" );
248 System.out.println( " -" + FIRST_OPTION + "=<i>: first evaluator topology to use (0-based) [default: 0]" );
249 System.out.println( " -" + LAST_OPTION
250 + "=<i>: last evaluator topology to use (0-based) [default: use all until final topology]" );
251 System.out.println();
254 private static void checkUniquenessOfExternalNodes( final Phylogeny phy, final String msg )
255 throws IllegalArgumentException {
256 final Set<PhylogenyNode> ext_nodes = new HashSet<PhylogenyNode>( phy.getNumberOfExternalNodes() );
257 for( final PhylogenyNodeIterator it = phy.iteratorExternalForward(); it.hasNext(); ) {
258 final PhylogenyNode node = it.next();
259 if ( ext_nodes.contains( node ) ) {
260 throw new IllegalArgumentException( "external node [" + node.toString() + "] of " + msg
261 + " is not unique" );
263 ext_nodes.add( node );