in progress....
[jalview.git] / forester / java / src / org / forester / application / rio.java
1 // $Id:
2 // FORESTER -- software libraries and applications
3 // for evolutionary biology research and applications.
4 //
5 // Copyright (C) 2017 Christian M. Zmasek
6 // All rights reserved
7 //
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
21 //
22 // WWW: https://sites.google.com/site/cmzmasek/home/software/forester
23
24 package org.forester.application;
25
26 import java.io.File;
27 import java.io.FilenameFilter;
28 import java.io.IOException;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.List;
32
33 import org.forester.rio.RIO;
34 import org.forester.rio.RIO.REROOTING;
35 import org.forester.rio.RIOUtil;
36 import org.forester.sdi.SDIutil.ALGORITHM;
37 import org.forester.util.CommandLineArguments;
38 import org.forester.util.EasyWriter;
39 import org.forester.util.ForesterUtil;
40
41 public class rio {
42
43     public final static String  PRG_NAME                       = "rio";
44     public final static String  PRG_VERSION                    = "5.000";
45     public final static String  PRG_DATE                       = "170411";
46     final static private String E_MAIL                         = "phyloxml@gmail.com";
47     final static private String WWW                            = "https://sites.google.com/site/cmzmasek/home/software/forester";
48     final static private String HELP_OPTION_1                  = "help";
49     final static private String LOGFILE_SUFFIX                 = "_RIO_log.tsv";
50     final static private String STRIPPED_SPECIES_TREE_SUFFIX   = "_RIO_sst.xml";
51     final static private String ORTHO_OUTTABLE_SUFFIX          = "_RIO_orthologies.tsv";
52     final static private String ORTHO_OUTTABLE_WITH_MAP_SUFFIX = "_RIO_orthologies_ext_map.tsv";
53     final static private String OUT_MIN_DUP_GENE_TREE_SUFFIX   = "_RIO_gene_tree_min_dup_";
54     final static private String OUT_MED_DUP_GENE_TREE_SUFFIX   = "_RIO_gene_tree_med_dup_";
55     final static private String ORTHOLOG_GROUPS_SUFFIX         = "_RIO_ortholog_groups.tsv";
56     final static private String HELP_OPTION_2                  = "h";
57     final static private String GT_FIRST                       = "f";
58     final static private String GT_LAST                        = "l";
59     final static private String REROOTING_OPT                  = "r";
60     final static private String OUTGROUP                       = "o";
61     final static private String USE_SDIR                       = "s";
62     final static private String GENE_TREES_SUFFIX_OPTION       = "g";
63     final static private String ORTHOLOG_GROUPS_CUTOFF_OPTION  = "c";
64     final static private double ORTHOLOG_GROUPS_CUTOFF_DEFAULT = 0.5;
65
66     public static void main( final String[] args ) {
67         ForesterUtil.printProgramInformation( PRG_NAME,
68                                               "resampled inference of orthologs",
69                                               PRG_VERSION,
70                                               PRG_DATE,
71                                               E_MAIL,
72                                               WWW,
73                                               ForesterUtil.getForesterLibraryInformation() );
74         CommandLineArguments cla = null;
75         try {
76             cla = new CommandLineArguments( args );
77         }
78         catch ( final Exception e ) {
79             ForesterUtil.fatalError( e.getMessage() );
80         }
81         if ( cla.isOptionSet( HELP_OPTION_1 ) || cla.isOptionSet( HELP_OPTION_2 ) || ( args.length == 0 ) ) {
82             printHelp();
83         }
84         if ( ( args.length < 3 ) || ( args.length > 11 ) || ( cla.getNumberOfNames() < 3 ) ) {
85             System.out.println();
86             System.out.println( "error: incorrect number of arguments" );
87             System.out.println();
88             printHelp();
89         }
90         final List<String> allowed_options = new ArrayList<String>();
91         allowed_options.add( GT_FIRST );
92         allowed_options.add( GT_LAST );
93         allowed_options.add( REROOTING_OPT );
94         allowed_options.add( OUTGROUP );
95         allowed_options.add( USE_SDIR );
96         allowed_options.add( GENE_TREES_SUFFIX_OPTION );
97         allowed_options.add( ORTHOLOG_GROUPS_CUTOFF_OPTION );
98         final String dissallowed_options = cla.validateAllowedOptionsAsString( allowed_options );
99         if ( dissallowed_options.length() > 0 ) {
100             ForesterUtil.fatalError( "unknown option(s): " + dissallowed_options );
101         }
102         final File gene_trees_file = cla.getFile( 0 );
103         final boolean use_dir;
104         File indir = null;
105         File outdir = null;
106         if ( gene_trees_file.isDirectory() ) {
107             if ( !gene_trees_file.exists() ) {
108                 ForesterUtil.fatalError( "gene trees directory \"" + gene_trees_file + "\" does not exist" );
109             }
110             use_dir = true;
111             indir = gene_trees_file;
112         }
113         else {
114             use_dir = false;
115         }
116         final File species_tree_file = cla.getFile( 1 );
117         File orthology_outtable = null;
118         if ( use_dir ) {
119             outdir = cla.getFile( 2 );
120         }
121         else {
122             orthology_outtable = cla.getFile( 2 );
123         }
124         File logfile;
125         if ( use_dir ) {
126             if ( ( cla.getNumberOfNames() < 4 ) ) {
127                 System.out.println();
128                 System.out.println( "error: incorrect number of arguments" );
129                 System.out.println();
130                 printHelp();
131             }
132             logfile = cla.getFile( 3 );
133             if ( logfile.exists() ) {
134                 ForesterUtil.fatalError( "\"" + logfile + "\" already exists" );
135             }
136         }
137         else {
138             if ( cla.getNumberOfNames() > 3 ) {
139                 logfile = cla.getFile( 3 );
140                 if ( logfile.exists() ) {
141                     ForesterUtil.fatalError( "\"" + logfile + "\" already exists" );
142                 }
143             }
144             else {
145                 logfile = null;
146             }
147         }
148         boolean sdir = false;
149         if ( cla.isOptionSet( USE_SDIR ) ) {
150             if ( cla.isOptionHasAValue( USE_SDIR ) ) {
151                 ForesterUtil.fatalError( "no value allowed for -" + USE_SDIR );
152             }
153             sdir = true;
154             if ( !use_dir && logfile != null ) {
155                 ForesterUtil.fatalError( "no logfile output for SDIR algorithm" );
156             }
157         }
158         String outgroup = null;
159         if ( cla.isOptionSet( OUTGROUP ) ) {
160             if ( sdir ) {
161                 ForesterUtil.fatalError( "no outgroup option for SDIR algorithm" );
162             }
163             if ( use_dir ) {
164                 ForesterUtil.fatalError( "no outgroup option for operating on gene trees directory" );
165             }
166             if ( !cla.isOptionHasAValue( OUTGROUP ) ) {
167                 ForesterUtil.fatalError( "no value for -" + OUTGROUP );
168             }
169             outgroup = cla.getOptionValueAsCleanString( OUTGROUP );
170         }
171         REROOTING rerooting = REROOTING.BY_ALGORITHM;
172         if ( cla.isOptionSet( REROOTING_OPT ) ) {
173             if ( !cla.isOptionHasAValue( REROOTING_OPT ) ) {
174                 ForesterUtil.fatalError( "no value for -" + REROOTING_OPT );
175             }
176             if ( sdir ) {
177                 ForesterUtil.fatalError( "no re-rooting option for SDIR algorithm" );
178             }
179             final String rerooting_str = cla.getOptionValueAsCleanString( REROOTING_OPT ).toLowerCase();
180             if ( rerooting_str.equals( "none" ) ) {
181                 rerooting = REROOTING.NONE;
182             }
183             else if ( rerooting_str.equals( "midpoint" ) ) {
184                 rerooting = REROOTING.MIDPOINT;
185             }
186             else if ( rerooting_str.equals( "outgroup" ) ) {
187                 if ( use_dir ) {
188                     ForesterUtil.fatalError( "no outgroup option for operating on gene trees directory" );
189                 }
190                 rerooting = REROOTING.OUTGROUP;
191             }
192             else {
193                 ForesterUtil
194                         .fatalError( "values for re-rooting are: 'none', 'midpoint', or 'outgroup' (minizming duplications is default)" );
195             }
196         }
197         if ( ForesterUtil.isEmpty( outgroup ) && ( rerooting == REROOTING.OUTGROUP ) ) {
198             ForesterUtil.fatalError( "selected re-rooting by outgroup, but outgroup not set" );
199         }
200         if ( !ForesterUtil.isEmpty( outgroup ) && ( rerooting != REROOTING.OUTGROUP ) ) {
201             ForesterUtil.fatalError( "outgroup set, but selected re-rooting by other approach" );
202         }
203         int gt_first = RIO.DEFAULT_RANGE;
204         int gt_last = RIO.DEFAULT_RANGE;
205         if ( cla.isOptionSet( GT_FIRST ) ) {
206             if ( sdir ) {
207                 ForesterUtil.fatalError( "no gene tree range option for SDIR algorithm" );
208             }
209             if ( !cla.isOptionHasAValue( GT_FIRST ) ) {
210                 ForesterUtil.fatalError( "no value for -" + GT_FIRST );
211             }
212             try {
213                 gt_first = cla.getOptionValueAsInt( GT_FIRST );
214             }
215             catch ( final IOException e ) {
216                 ForesterUtil.fatalError( "could not parse integer for -" + GT_FIRST + " option" );
217             }
218             if ( gt_first < 0 ) {
219                 ForesterUtil.fatalError( "attempt to set index of first tree to analyze to: " + gt_first );
220             }
221         }
222         if ( cla.isOptionSet( GT_LAST ) ) {
223             if ( sdir ) {
224                 ForesterUtil.fatalError( "no gene tree range option for SDIR algorithm" );
225             }
226             if ( !cla.isOptionHasAValue( GT_LAST ) ) {
227                 ForesterUtil.fatalError( "no value for -" + GT_LAST );
228             }
229             try {
230                 gt_last = cla.getOptionValueAsInt( GT_LAST );
231             }
232             catch ( final IOException e ) {
233                 ForesterUtil.fatalError( "could not parse integer for -" + GT_LAST + " option" );
234             }
235             if ( gt_last < 0 ) {
236                 ForesterUtil.fatalError( "attempt to set index of last tree to analyze to: " + gt_last );
237             }
238         }
239         if ( ( ( gt_last != RIO.DEFAULT_RANGE ) && ( gt_first != RIO.DEFAULT_RANGE ) ) && ( ( gt_last < gt_first ) ) ) {
240             ForesterUtil.fatalError( "attempt to set range (0-based) of gene to analyze to: from " + gt_first + " to "
241                     + gt_last );
242         }
243         double ortholog_group_cutoff = ORTHOLOG_GROUPS_CUTOFF_DEFAULT;
244         if ( cla.isOptionSet( ORTHOLOG_GROUPS_CUTOFF_OPTION ) ) {
245             if ( sdir ) {
246                 ForesterUtil.fatalError( "ortholog groups cutoff for SDIR algorithm" );
247             }
248             if ( !cla.isOptionHasAValue( ORTHOLOG_GROUPS_CUTOFF_OPTION ) ) {
249                 ForesterUtil.fatalError( "no value for -" + ORTHOLOG_GROUPS_CUTOFF_OPTION );
250             }
251             try {
252                 ortholog_group_cutoff = cla.getOptionValueAsDouble( ORTHOLOG_GROUPS_CUTOFF_OPTION );
253             }
254             catch ( final IOException e ) {
255                 ForesterUtil.fatalError( "could not parse double for -" + ORTHOLOG_GROUPS_CUTOFF_OPTION + " option" );
256             }
257             if ( ortholog_group_cutoff < 0 ) {
258                 ForesterUtil.fatalError( "attempt to set ortholog groups cutoff to: " + ortholog_group_cutoff );
259             }
260             if ( ortholog_group_cutoff > 1 ) {
261                 ForesterUtil.fatalError( "attempt to set ortholog groups cutoff to: " + ortholog_group_cutoff );
262             }
263         }
264         if ( !use_dir ) {
265             ForesterUtil.fatalErrorIfFileNotReadable( gene_trees_file );
266         }
267         final String gene_trees_suffix;
268         if ( cla.isOptionSet( GENE_TREES_SUFFIX_OPTION ) ) {
269             if ( !use_dir ) {
270                 ForesterUtil.fatalError( "no gene tree suffix option when operating on indivual gene trees" );
271             }
272             if ( !cla.isOptionHasAValue( GENE_TREES_SUFFIX_OPTION ) ) {
273                 ForesterUtil.fatalError( "no value for -" + GENE_TREES_SUFFIX_OPTION );
274             }
275             gene_trees_suffix = cla.getOptionValueAsCleanString( GENE_TREES_SUFFIX_OPTION );
276         }
277         else {
278             gene_trees_suffix = ".mlt";
279         }
280         ForesterUtil.fatalErrorIfFileNotReadable( species_tree_file );
281         if ( !use_dir && orthology_outtable.exists() ) {
282             ForesterUtil.fatalError( "\"" + orthology_outtable + "\" already exists" );
283         }
284         long time = 0;
285         try {
286             if ( use_dir ) {
287                 System.out.println( "Gene trees in-dir                   :\t" + indir.getCanonicalPath() );
288                 System.out.println( "Gene trees suffix                   :\t" + gene_trees_suffix );
289             }
290             else {
291                 System.out.println( "Gene trees                          :\t" + gene_trees_file.getCanonicalPath() );
292             }
293             System.out.println( "Species tree                        :\t" + species_tree_file.getCanonicalPath() );
294         }
295         catch ( final IOException e ) {
296             ForesterUtil.fatalError( e.getLocalizedMessage() );
297         }
298         if ( use_dir ) {
299             System.out.println( "Out-dir                             :\t" + outdir );
300         }
301         else {
302             System.out.println( "All vs all orthology results table  :\t" + orthology_outtable );
303         }
304         if ( logfile != null ) {
305             System.out.println( "Logfile                             :\t" + logfile );
306         }
307         System.out.println( "Ortholog groups cutoff              :\t" + ortholog_group_cutoff );
308         if ( gt_first != RIO.DEFAULT_RANGE ) {
309             System.out.println( "First gene tree to analyze          :\t" + gt_first );
310         }
311         if ( gt_last != RIO.DEFAULT_RANGE ) {
312             System.out.println( "Last gene tree to analyze           :\t" + gt_last );
313         }
314         String rerooting_str = "";
315         switch ( rerooting ) {
316             case BY_ALGORITHM: {
317                 rerooting_str = "by minimizing duplications";
318                 break;
319             }
320             case MIDPOINT: {
321                 rerooting_str = "by midpoint method";
322                 break;
323             }
324             case OUTGROUP: {
325                 rerooting_str = "by outgroup: " + outgroup;
326                 break;
327             }
328             case NONE: {
329                 rerooting_str = "none";
330                 break;
331             }
332         }
333         System.out.println( "Re-rooting                          : \t" + rerooting_str );
334         if ( !sdir ) {
335             System.out.println( "Non binary species tree             :\tallowed" );
336         }
337         else {
338             System.out.println( "Non binary species tree             :\tdisallowed" );
339         }
340         time = System.currentTimeMillis();
341         final ALGORITHM algorithm;
342         if ( sdir ) {
343             algorithm = ALGORITHM.SDIR;
344         }
345         else {
346             algorithm = ALGORITHM.GSDIR;
347         }
348         EasyWriter log = null;
349         if ( use_dir ) {
350             if ( outdir.exists() ) {
351                 if ( !outdir.isDirectory() ) {
352                     ForesterUtil.fatalError( PRG_NAME,
353                                              "out-directory [" + outdir + "] already exists but is not a directory" );
354                 }
355             }
356             else {
357                 final boolean success = outdir.mkdirs();
358                 if ( !success ) {
359                     ForesterUtil.fatalError( PRG_NAME, "could not create out-directory [" + outdir + "]" );
360                 }
361             }
362             final String species_tree_file_name = species_tree_file.getName();
363             final File gene_trees_files[] = indir.listFiles( new FilenameFilter() {
364
365                 @Override
366                 public boolean accept( final File dir, final String name ) {
367                     return ( ( name.endsWith( gene_trees_suffix ) ) && !( name.equals( species_tree_file_name ) ) );
368                 }
369             } );
370             if ( gene_trees_files.length < 1 ) {
371                 ForesterUtil.fatalError( PRG_NAME,
372                                          "in-directory [" + indir
373                                                  + "] does not contain any gene tree files with suffix "
374                                                  + gene_trees_suffix );
375             }
376             try {
377                 log = ForesterUtil.createEasyWriter( logfile );
378             }
379             catch ( final IOException e ) {
380                 ForesterUtil.fatalError( PRG_NAME, "could not create [" + logfile + "]" );
381             }
382             Arrays.sort( gene_trees_files );
383             try {
384                 log.print( "# program" );
385                 log.print( "\t" );
386                 log.print( PRG_NAME );
387                 log.println();
388                 log.print( "# version" );
389                 log.print( "\t" );
390                 log.print( PRG_VERSION );
391                 log.println();
392                 log.print( "# date" );
393                 log.print( "\t" );
394                 log.print( PRG_DATE );
395                 log.println();
396                 log.print( "# Algorithm " );
397                 log.print( "\t" );
398                 log.print( algorithm.toString() );
399                 log.println();
400                 log.print( "# Gene trees in-dir" );
401                 log.print( "\t" );
402                 log.print( indir.getCanonicalPath() );
403                 log.println();
404                 log.print( "# Gene trees suffix" );
405                 log.print( "\t" );
406                 log.print( gene_trees_suffix );
407                 log.println();
408                 log.print( "# Species tree" );
409                 log.print( "\t" );
410                 log.print( species_tree_file.getCanonicalPath() );
411                 log.println();
412                 log.print( "# Out-dir" );
413                 log.print( "\t" );
414                 log.print( outdir.getCanonicalPath() );
415                 log.println();
416                 log.print( "# Logfile" );
417                 log.print( "\t" );
418                 log.print( logfile.getCanonicalPath() );
419                 log.println();
420                 log.print( "# Ortholog groups cutoff" );
421                 log.print( "\t" );
422                 log.print( Double.toString( ortholog_group_cutoff ) );
423                 log.println();
424                 if ( gt_first != RIO.DEFAULT_RANGE ) {
425                     log.print( "# First gene tree to analyze" );
426                     log.print( "\t" );
427                     log.print( Integer.toString( gt_first ) );
428                     log.println();
429                 }
430                 if ( gt_last != RIO.DEFAULT_RANGE ) {
431                     log.print( "# Last gene tree to analyze" );
432                     log.print( "\t" );
433                     log.print( Integer.toString( gt_last ) );
434                     log.println();
435                 }
436                 log.print( "# Re-rooting" );
437                 log.print( "\t" );
438                 log.print( rerooting_str );
439                 log.println();
440                 log.print( "# Non binary species tree" );
441                 log.print( "\t" );
442                 if ( !sdir ) {
443                     log.print( "allowed" );
444                 }
445                 else {
446                     log.print( "disallowed" );
447                 }
448                 log.println();
449                 log.println();
450                 log.print( "NAME" );
451                 log.print( "\t" );
452                 log.print( "EXT NODES" );
453                 log.print( "\t" );
454                 log.print( ortholog_group_cutoff + " O GROUPS" );
455                 log.print( "\t" );
456                 log.print( "0.05 O GROUPS" );
457                 log.print( "\t" );
458                 log.print( "0.25 O GROUPS" );
459                 log.print( "\t" );
460                 log.print( "0.5 O GROUPS" );
461                 log.print( "\t" );
462                 log.print( "0.75 O GROUPS" );
463                 log.print( "\t" );
464                 log.print( "0.95 O GROUPS" );
465                 log.print( "\t" );
466                 log.print( "MEDIAN DUP" );
467                 log.print( "\t" );
468                 log.print( "MEAN DUP" );
469                 log.print( "\t" );
470                 log.print( "MEAN DUP SD" );
471                 log.print( "\t" );
472                 log.print( "MIN DUP" );
473                 log.print( "\t" );
474                 log.print( "MAX DUP" );
475                 log.print( "\t" );
476                 log.print( "REMOVED EXT NODES" );
477                 log.print( "\t" );
478                 log.print( "N" );
479                 log.println();
480             }
481             catch ( IOException e ) {
482                 ForesterUtil.fatalError( PRG_NAME, e.getLocalizedMessage() );
483             }
484             int counter = 1;
485             for( final File gf : gene_trees_files ) {
486                 String outname = gf.getName();
487                 System.out
488                         .print( "\r                                                                                            " );
489                 System.out.print( "\r" + counter + "/" + gene_trees_files.length + ": " + outname );
490                 counter++;
491                 if ( outname.indexOf( "." ) > 0 ) {
492                     outname = outname.substring( 0, outname.lastIndexOf( "." ) );
493                 }
494                 try {
495                     boolean perform_id_mapping = true;
496                     File id_mapping_dir = new File( "mappings" );
497                     String id_mapping_suffix = ".nim";
498                     RIOUtil.executeAnalysis( gf,
499                                              species_tree_file,
500                                              new File( outdir.getCanonicalFile() + "/" + outname
501                                                      + ORTHO_OUTTABLE_SUFFIX ),
502                                              new File( outdir.getCanonicalFile() + "/" + outname
503                                                      + ORTHO_OUTTABLE_WITH_MAP_SUFFIX ),
504                                              new File( outdir.getCanonicalFile() + "/" + outname
505                                                      + ORTHOLOG_GROUPS_SUFFIX ),
506                                              new File( outdir.getCanonicalFile() + "/" + outname + LOGFILE_SUFFIX ),
507                                              outgroup,
508                                              rerooting,
509                                              gt_first,
510                                              gt_last,
511                                              new File( outdir.getCanonicalFile() + "/" + outname
512                                                      + STRIPPED_SPECIES_TREE_SUFFIX ),
513                                              new File( outdir.getCanonicalFile() + "/" + outname
514                                                      + OUT_MIN_DUP_GENE_TREE_SUFFIX ),
515                                              new File( outdir.getCanonicalFile() + "/" + outname
516                                                      + OUT_MED_DUP_GENE_TREE_SUFFIX ),
517                                              true,
518                                              algorithm,
519                                              true,
520                                              log,
521                                              ortholog_group_cutoff,
522                                              perform_id_mapping,
523                                              id_mapping_dir,
524                                              id_mapping_suffix );
525                 }
526                 catch ( IOException e ) {
527                     ForesterUtil.fatalError( PRG_NAME, e.getLocalizedMessage() );
528                 }
529             }
530             System.out
531                     .print( "\r                                                                                        " );
532             System.out.println();
533         }
534         else {
535             String outname = orthology_outtable.toString();
536             if ( outname.indexOf( "." ) > 0 ) {
537                 outname = outname.substring( 0, outname.lastIndexOf( "." ) );
538             }
539             RIOUtil.executeAnalysis( gene_trees_file,
540                                      species_tree_file,
541                                      orthology_outtable,
542                                      null,
543                                      new File( outname + ORTHOLOG_GROUPS_SUFFIX ),
544                                      logfile,
545                                      outgroup,
546                                      rerooting,
547                                      gt_first,
548                                      gt_last,
549                                      new File( outname + STRIPPED_SPECIES_TREE_SUFFIX ),
550                                      new File( outname + OUT_MIN_DUP_GENE_TREE_SUFFIX ),
551                                      new File( outname + OUT_MED_DUP_GENE_TREE_SUFFIX ),
552                                      algorithm == ALGORITHM.GSDIR,
553                                      algorithm,
554                                      false,
555                                      null,
556                                      ortholog_group_cutoff,
557                                      false,
558                                      null,
559                                      null );
560         }
561         if ( !use_dir ) {
562             time = System.currentTimeMillis() - time;
563             System.out.println( "Time                                :\t" + time + "ms" );
564         }
565         else {
566             try {
567                 log.close();
568             }
569             catch ( IOException e ) {
570                 ForesterUtil.fatalError( PRG_NAME, e.getLocalizedMessage() );
571             }
572             time = System.currentTimeMillis() - time;
573             System.out.println( "Time                                :\t" + time + "ms" );
574         }
575         System.exit( 0 );
576     }
577
578     private final static void printHelp() {
579         System.out.println( "Usage" );
580         System.out.println();
581         System.out.println( PRG_NAME
582                 + " [options] <gene trees infile> <species tree infile> <all vs all orthology table outfile> [logfile]" );
583         System.out.println();
584         System.out.println( PRG_NAME + " [options] <gene trees indir> <species tree infile> <outdir> <logfile>" );
585         System.out.println();
586         System.out.println();
587         System.out.println( " Options" );
588         System.out.println( "  -" + GT_FIRST + "=<first>     : first gene tree to analyze (0-based index)" );
589         System.out.println( "  -" + GT_LAST + "=<last>      : last gene tree to analyze (0-based index)" );
590         System.out.println( "  -" + ORTHOLOG_GROUPS_CUTOFF_OPTION
591                 + "=<cutoff>    : cutoff value for ortholog groups (default: " + ORTHOLOG_GROUPS_CUTOFF_DEFAULT + ")" );
592         System.out.println( "  -" + REROOTING_OPT
593                 + "=<re-rooting>: re-rooting method for gene trees, possible values or 'none', 'midpoint'," );
594         System.out.println( "                   or 'outgroup' (default: by minizming duplications)" );
595         System.out.println( "  -" + OUTGROUP
596                 + "=<outgroup>  : for rooting by outgroup, name of outgroup (external gene tree node)" );
597         System.out.println( "  -" + USE_SDIR
598                 + "             : to use SDIR instead of GSDIR (faster, but non-binary species trees are" );
599         System.out.println( "                   disallowed, as are most options)" );
600         System.out.println( "  -" + GENE_TREES_SUFFIX_OPTION
601                 + "=<suffix>    : suffix for gene trees when operating on gene tree directories (default: .mlt)" );
602         System.out.println();
603         System.out.println( " Formats" );
604         System.out
605                 .println( "  The gene trees, as well as the species tree, ideally are in phyloXML (www.phyloxml.org) format," );
606         System.out
607                 .println( "  but can also be in New Hamphshire (Newick) or Nexus format as long as species information can be" );
608         System.out
609                 .println( "  extracted from the gene names (e.g. \"HUMAN\" from \"BCL2_HUMAN\") and matched to a single species" );
610         System.out.println( "  in the species tree." );
611         System.out.println();
612         System.out.println( " Examples" );
613         System.out.println( "  rio -s gene_trees.nh species.xml outtable.tsv" );
614         System.out.println( "  rio gene_trees.nh species.xml outtable.tsv log.txt" );
615         System.out.println( "  rio -c=0.9 -f=10 -l=100 -r=none gene_trees.xml species.xml outtable.tsv log.txt" );
616         System.out.println( "  rio -g=.xml gene_trees_dir species.xml out_dir log.tsv" );
617         System.out.println();
618         System.exit( -1 );
619     }
620 }