inprogress
[jalview.git] / forester / java / src / org / forester / util / ForesterUtil.java
1 // $Id:
2 // FORESTER -- software libraries and applications
3 // for evolutionary biology research and applications.
4 //
5 // Copyright (C) 2008-2009 Christian M. Zmasek
6 // Copyright (C) 2008-2009 Burnham Institute for Medical Research
7 // All rights reserved
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 //
23 // Contact: phylosoft @ gmail . com
24 // WWW: https://sites.google.com/site/cmzmasek/home/software/forester
25
26 package org.forester.util;
27
28 import java.awt.Color;
29 import java.io.BufferedReader;
30 import java.io.BufferedWriter;
31 import java.io.File;
32 import java.io.FileInputStream;
33 import java.io.FileNotFoundException;
34 import java.io.FileOutputStream;
35 import java.io.FileReader;
36 import java.io.FileWriter;
37 import java.io.IOException;
38 import java.io.InputStream;
39 import java.io.InputStreamReader;
40 import java.io.StringReader;
41 import java.io.Writer;
42 import java.math.BigDecimal;
43 import java.net.URL;
44 import java.text.DateFormat;
45 import java.text.DecimalFormat;
46 import java.text.DecimalFormatSymbols;
47 import java.text.NumberFormat;
48 import java.text.ParseException;
49 import java.text.SimpleDateFormat;
50 import java.util.ArrayList;
51 import java.util.Collection;
52 import java.util.Date;
53 import java.util.List;
54 import java.util.Map;
55 import java.util.Map.Entry;
56 import java.util.Set;
57 import java.util.SortedMap;
58 import java.util.SortedSet;
59 import java.util.TreeMap;
60 import java.util.TreeSet;
61 import java.util.regex.Matcher;
62 import java.util.regex.Pattern;
63
64 import org.forester.archaeopteryx.Constants;
65 import org.forester.phylogeny.PhylogenyNode;
66 import org.forester.phylogeny.data.Distribution;
67 import org.forester.phylogeny.data.Sequence;
68 import org.forester.phylogeny.data.Taxonomy;
69 import org.forester.protein.BasicProtein;
70 import org.forester.protein.Domain;
71 import org.forester.protein.Protein;
72 import org.forester.surfacing.SurfacingUtil;
73
74 public final class ForesterUtil {
75
76     public final static String       FILE_SEPARATOR                   = System.getProperty( "file.separator" );
77     public final static String       LINE_SEPARATOR                   = System.getProperty( "line.separator" );
78     public final static String       JAVA_VENDOR                      = System.getProperty( "java.vendor" );
79     public final static String       JAVA_VERSION                     = System.getProperty( "java.version" );
80     public final static String       OS_ARCH                          = System.getProperty( "os.arch" );
81     public final static String       OS_NAME                          = System.getProperty( "os.name" );
82     public final static String       OS_VERSION                       = System.getProperty( "os.version" );
83     public final static Pattern      PARANTHESESABLE_NH_CHARS_PATTERN = Pattern.compile( "[(),;\\s]" );
84     public final static double       ZERO_DIFF                        = 1.0E-9;
85     public static final BigDecimal   NULL_BD                          = new BigDecimal( 0 );
86     public static final NumberFormat FORMATTER_9;
87     public static final NumberFormat FORMATTER_6;
88     public static final NumberFormat FORMATTER_06;
89     public static final NumberFormat FORMATTER_3;
90     public static final String       NCBI_PROTEIN                     = "http://www.ncbi.nlm.nih.gov/protein/";
91     public static final String       NCBI_NUCCORE                     = "http://www.ncbi.nlm.nih.gov/nuccore/";
92     public final static String       UNIPROT_KB                       = "http://www.uniprot.org/uniprot/";
93     public static final String       NCBI_GI                          = "http://www.ncbi.nlm.nih.gov/protein/gi:";
94     public static final String       PDB                              = "http://www.pdb.org/pdb/explore/explore.do?pdbId=";
95     static {
96         final DecimalFormatSymbols dfs = new DecimalFormatSymbols();
97         dfs.setDecimalSeparator( '.' );
98         // dfs.setGroupingSeparator( ( char ) 0 );
99         FORMATTER_9 = new DecimalFormat( "#.#########", dfs );
100         FORMATTER_6 = new DecimalFormat( "#.######", dfs );
101         FORMATTER_06 = new DecimalFormat( "0.######", dfs );
102         FORMATTER_3 = new DecimalFormat( "#.###", dfs );
103     }
104
105     private ForesterUtil() {
106     }
107
108     public static int calculateOverlap( final Domain domain, final List<Boolean> covered_positions ) {
109         int overlap_count = 0;
110         for( int i = domain.getFrom(); i <= domain.getTo(); ++i ) {
111             if ( ( i < covered_positions.size() ) && ( covered_positions.get( i ) == true ) ) {
112                 ++overlap_count;
113             }
114         }
115         return overlap_count;
116     }
117
118     final public static void appendSeparatorIfNotEmpty( final StringBuffer sb, final char separator ) {
119         if ( sb.length() > 0 ) {
120             sb.append( separator );
121         }
122     }
123
124     /**
125      * 
126      * Example regarding engulfment: ------------0.1 ----------0.2 --0.3 =>
127      * domain with 0.3 is ignored
128      * 
129      * -----------0.1 ----------0.2 --0.3 => domain with 0.3 is ignored
130      * 
131      * 
132      * ------------0.1 ----------0.3 --0.2 => domains with 0.3 and 0.2 are _not_
133      * ignored
134      * 
135      * @param max_allowed_overlap
136      *            maximal allowed overlap (inclusive) to be still considered not
137      *            overlapping (zero or negative value to allow any overlap)
138      * @param remove_engulfed_domains
139      *            to remove domains which are completely engulfed by coverage of
140      *            domains with better support
141      * @param protein
142      * @return
143      */
144     public static Protein removeOverlappingDomains( final int max_allowed_overlap,
145                                                     final boolean remove_engulfed_domains,
146                                                     final Protein protein ) {
147         final Protein pruned_protein = new BasicProtein( protein.getProteinId().getId(), protein.getSpecies()
148                 .getSpeciesId(), protein.getLength() );
149         final List<Domain> sorted = SurfacingUtil.sortDomainsWithAscendingConfidenceValues( protein );
150         final List<Boolean> covered_positions = new ArrayList<Boolean>();
151         for( final Domain domain : sorted ) {
152             if ( ( ( max_allowed_overlap < 0 ) || ( ForesterUtil.calculateOverlap( domain, covered_positions ) <= max_allowed_overlap ) )
153                     && ( !remove_engulfed_domains || !isEngulfed( domain, covered_positions ) ) ) {
154                 final int covered_positions_size = covered_positions.size();
155                 for( int i = covered_positions_size; i < domain.getFrom(); ++i ) {
156                     covered_positions.add( false );
157                 }
158                 final int new_covered_positions_size = covered_positions.size();
159                 for( int i = domain.getFrom(); i <= domain.getTo(); ++i ) {
160                     if ( i < new_covered_positions_size ) {
161                         covered_positions.set( i, true );
162                     }
163                     else {
164                         covered_positions.add( true );
165                     }
166                 }
167                 pruned_protein.addProteinDomain( domain );
168             }
169         }
170         return pruned_protein;
171     }
172
173     /**
174      * Returns true is Domain domain falls in an uninterrupted stretch of
175      * covered positions.
176      * 
177      * @param domain
178      * @param covered_positions
179      * @return
180      */
181     public static boolean isEngulfed( final Domain domain, final List<Boolean> covered_positions ) {
182         for( int i = domain.getFrom(); i <= domain.getTo(); ++i ) {
183             if ( ( i >= covered_positions.size() ) || ( covered_positions.get( i ) != true ) ) {
184                 return false;
185             }
186         }
187         return true;
188     }
189
190     /**
191      * This calculates a color. If value is equal to min the returned color is
192      * minColor, if value is equal to max the returned color is maxColor,
193      * otherwise a color 'proportional' to value is returned.
194      * 
195      * @param value
196      *            the value 
197      * @param min
198      *            the smallest value 
199      * @param max
200      *            the largest value 
201      * @param minColor
202      *            the color for min
203      * @param maxColor
204      *            the color for max
205      * @return a Color
206      */
207     final public static Color calcColor( double value,
208                                          final double min,
209                                          final double max,
210                                          final Color minColor,
211                                          final Color maxColor ) {
212         if ( value < min ) {
213             value = min;
214         }
215         if ( value > max ) {
216             value = max;
217         }
218         final double x = ForesterUtil.calculateColorFactor( value, max, min );
219         final int red = ForesterUtil.calculateColorComponent( minColor.getRed(), maxColor.getRed(), x );
220         final int green = ForesterUtil.calculateColorComponent( minColor.getGreen(), maxColor.getGreen(), x );
221         final int blue = ForesterUtil.calculateColorComponent( minColor.getBlue(), maxColor.getBlue(), x );
222         return new Color( red, green, blue );
223     }
224
225     /**
226      * This calculates a color. If value is equal to min the returned color is
227      * minColor, if value is equal to max the returned color is maxColor, if
228      * value is equal to mean the returned color is meanColor, otherwise a color
229      * 'proportional' to value is returned -- either between min-mean or
230      * mean-max
231      * 
232      * @param value
233      *            the value
234      * @param min
235      *            the smallest value
236      * @param max
237      *            the largest value 
238      * @param mean
239      *            the mean/median value 
240      * @param minColor
241      *            the color for min
242      * @param maxColor
243      *            the color for max
244      * @param meanColor
245      *            the color for mean
246      * @return a Color
247      */
248     final public static Color calcColor( double value,
249                                          final double min,
250                                          final double max,
251                                          final double mean,
252                                          final Color minColor,
253                                          final Color maxColor,
254                                          final Color meanColor ) {
255         if ( value < min ) {
256             value = min;
257         }
258         if ( value > max ) {
259             value = max;
260         }
261         if ( value < mean ) {
262             final double x = ForesterUtil.calculateColorFactor( value, mean, min );
263             final int red = ForesterUtil.calculateColorComponent( minColor.getRed(), meanColor.getRed(), x );
264             final int green = ForesterUtil.calculateColorComponent( minColor.getGreen(), meanColor.getGreen(), x );
265             final int blue = ForesterUtil.calculateColorComponent( minColor.getBlue(), meanColor.getBlue(), x );
266             return new Color( red, green, blue );
267         }
268         else if ( value > mean ) {
269             final double x = ForesterUtil.calculateColorFactor( value, max, mean );
270             final int red = ForesterUtil.calculateColorComponent( meanColor.getRed(), maxColor.getRed(), x );
271             final int green = ForesterUtil.calculateColorComponent( meanColor.getGreen(), maxColor.getGreen(), x );
272             final int blue = ForesterUtil.calculateColorComponent( meanColor.getBlue(), maxColor.getBlue(), x );
273             return new Color( red, green, blue );
274         }
275         else {
276             return meanColor;
277         }
278     }
279
280     final public static String collapseWhiteSpace( final String s ) {
281         return s.replaceAll( "[\\s]+", " " );
282     }
283
284     final public static void collection2file( final File file, final Collection<?> data, final String separator )
285             throws IOException {
286         final Writer writer = new BufferedWriter( new FileWriter( file ) );
287         collection2writer( writer, data, separator );
288         writer.close();
289     }
290
291     final public static void collection2writer( final Writer writer, final Collection<?> data, final String separator )
292             throws IOException {
293         boolean first = true;
294         for( final Object object : data ) {
295             if ( !first ) {
296                 writer.write( separator );
297             }
298             else {
299                 first = false;
300             }
301             writer.write( object.toString() );
302         }
303     }
304
305     final public static String colorToHex( final Color color ) {
306         final String rgb = Integer.toHexString( color.getRGB() );
307         return rgb.substring( 2, rgb.length() );
308     }
309
310     synchronized public static void copyFile( final File in, final File out ) throws IOException {
311         final FileInputStream in_s = new FileInputStream( in );
312         final FileOutputStream out_s = new FileOutputStream( out );
313         try {
314             final byte[] buf = new byte[ 1024 ];
315             int i = 0;
316             while ( ( i = in_s.read( buf ) ) != -1 ) {
317                 out_s.write( buf, 0, i );
318             }
319         }
320         catch ( final IOException e ) {
321             throw e;
322         }
323         finally {
324             if ( in_s != null ) {
325                 in_s.close();
326             }
327             if ( out_s != null ) {
328                 out_s.close();
329             }
330         }
331     }
332
333     final public static int countChars( final String str, final char c ) {
334         int count = 0;
335         for( int i = 0; i < str.length(); ++i ) {
336             if ( str.charAt( i ) == c ) {
337                 ++count;
338             }
339         }
340         return count;
341     }
342
343     final public static BufferedWriter createBufferedWriter( final File file ) throws IOException {
344         if ( file.exists() ) {
345             throw new IOException( "[" + file + "] already exists" );
346         }
347         return new BufferedWriter( new FileWriter( file ) );
348     }
349
350     final public static BufferedWriter createBufferedWriter( final String name ) throws IOException {
351         return new BufferedWriter( new FileWriter( createFileForWriting( name ) ) );
352     }
353
354     final public static EasyWriter createEasyWriter( final File file ) throws IOException {
355         return new EasyWriter( createBufferedWriter( file ) );
356     }
357
358     final public static BufferedWriter createEasyWriter( final String name ) throws IOException {
359         return createEasyWriter( createFileForWriting( name ) );
360     }
361
362     final public static File createFileForWriting( final String name ) throws IOException {
363         final File file = new File( name );
364         if ( file.exists() ) {
365             throw new IOException( "[" + name + "] already exists" );
366         }
367         return file;
368     }
369
370     final public static void ensurePresenceOfDate( final PhylogenyNode node ) {
371         if ( !node.getNodeData().isHasDate() ) {
372             node.getNodeData().setDate( new org.forester.phylogeny.data.Date() );
373         }
374     }
375
376     final public static void ensurePresenceOfDistribution( final PhylogenyNode node ) {
377         if ( !node.getNodeData().isHasDistribution() ) {
378             node.getNodeData().setDistribution( new Distribution( "" ) );
379         }
380     }
381
382     public static void ensurePresenceOfSequence( final PhylogenyNode node ) {
383         if ( !node.getNodeData().isHasSequence() ) {
384             node.getNodeData().setSequence( new Sequence() );
385         }
386     }
387
388     public static void ensurePresenceOfTaxonomy( final PhylogenyNode node ) {
389         if ( !node.getNodeData().isHasTaxonomy() ) {
390             node.getNodeData().setTaxonomy( new Taxonomy() );
391         }
392     }
393
394     public static void fatalError( final String message ) {
395         System.err.println();
396         System.err.println( "error: " + message );
397         System.err.println();
398         System.exit( -1 );
399     }
400
401     public static void fatalError( final String prg_name, final String message ) {
402         System.err.println();
403         System.err.println( "[" + prg_name + "] > " + message );
404         System.err.println();
405         System.exit( -1 );
406     }
407
408     public static void fatalErrorIfFileNotReadable( final File file ) {
409         final String error = isReadableFile( file );
410         if ( !isEmpty( error ) ) {
411             System.err.println();
412             System.err.println( "error: " + error );
413             System.err.println();
414             System.exit( -1 );
415         }
416     }
417
418     public static void fatalErrorIfFileNotReadable( final String prg_name, final File file ) {
419         final String error = isReadableFile( file );
420         if ( !isEmpty( error ) ) {
421             System.err.println();
422             System.err.println( "[" + prg_name + "] > " + error );
423             System.err.println();
424             System.exit( -1 );
425         }
426     }
427
428     public static String[] file2array( final File file ) throws IOException {
429         final List<String> list = file2list( file );
430         final String[] ary = new String[ list.size() ];
431         int i = 0;
432         for( final String s : list ) {
433             ary[ i++ ] = s;
434         }
435         return ary;
436     }
437
438     public static String[][] file22dArray( final File file ) throws IOException {
439         final List<String> list = new ArrayList<String>();
440         final BufferedReader in = new BufferedReader( new FileReader( file ) );
441         String str;
442         while ( ( str = in.readLine() ) != null ) {
443             str = str.trim();
444             if ( ( str.length() > 0 ) && !str.startsWith( "#" ) ) {
445                 list.add( str );
446             }
447         }
448         in.close();
449         final String[][] ary = new String[ list.size() ][ 2 ];
450         final Pattern pa = Pattern.compile( "(\\S+)\\s+(\\S+)" );
451         int i = 0;
452         for( final String s : list ) {
453             final Matcher m = pa.matcher( s );
454             if ( m.matches() ) {
455                 ary[ i ][ 0 ] = m.group( 1 );
456                 ary[ i ][ 1 ] = m.group( 2 );
457                 ++i;
458             }
459             else {
460                 throw new IOException( "unexpcted format: " + s );
461             }
462         }
463         return ary;
464     }
465
466     final public static List<String> file2list( final File file ) throws IOException {
467         final List<String> list = new ArrayList<String>();
468         final BufferedReader in = new BufferedReader( new FileReader( file ) );
469         String str;
470         while ( ( str = in.readLine() ) != null ) {
471             str = str.trim();
472             if ( ( str.length() > 0 ) && !str.startsWith( "#" ) ) {
473                 for( final String s : splitString( str ) ) {
474                     list.add( s );
475                 }
476             }
477         }
478         in.close();
479         return list;
480     }
481
482     final public static SortedSet<String> file2set( final File file ) throws IOException {
483         final SortedSet<String> set = new TreeSet<String>();
484         final BufferedReader in = new BufferedReader( new FileReader( file ) );
485         String str;
486         while ( ( str = in.readLine() ) != null ) {
487             str = str.trim();
488             if ( ( str.length() > 0 ) && !str.startsWith( "#" ) ) {
489                 for( final String s : splitString( str ) ) {
490                     set.add( s );
491                 }
492             }
493         }
494         in.close();
495         return set;
496     }
497
498     final public static String getCurrentDateTime() {
499         final DateFormat format = new SimpleDateFormat( "yyyy/MM/dd HH:mm:ss" );
500         return format.format( new Date() );
501     }
502
503     final public static String getFileSeparator() {
504         return ForesterUtil.FILE_SEPARATOR;
505     }
506
507     final public static String getFirstLine( final Object source ) throws FileNotFoundException, IOException {
508         BufferedReader reader = null;
509         if ( source instanceof File ) {
510             final File f = ( File ) source;
511             if ( !f.exists() ) {
512                 throw new IOException( "[" + f.getAbsolutePath() + "] does not exist" );
513             }
514             else if ( !f.isFile() ) {
515                 throw new IOException( "[" + f.getAbsolutePath() + "] is not a file" );
516             }
517             else if ( !f.canRead() ) {
518                 throw new IOException( "[" + f.getAbsolutePath() + "] is not a readable" );
519             }
520             reader = new BufferedReader( new FileReader( f ) );
521         }
522         else if ( source instanceof InputStream ) {
523             reader = new BufferedReader( new InputStreamReader( ( InputStream ) source ) );
524         }
525         else if ( source instanceof String ) {
526             reader = new BufferedReader( new StringReader( ( String ) source ) );
527         }
528         else if ( source instanceof StringBuffer ) {
529             reader = new BufferedReader( new StringReader( source.toString() ) );
530         }
531         else if ( source instanceof URL ) {
532             reader = new BufferedReader( new InputStreamReader( ( ( URL ) source ).openStream() ) );
533         }
534         else {
535             throw new IllegalArgumentException( "dont know how to read [" + source.getClass() + "]" );
536         }
537         String line;
538         while ( ( line = reader.readLine() ) != null ) {
539             line = line.trim();
540             if ( !ForesterUtil.isEmpty( line ) ) {
541                 if ( reader != null ) {
542                     reader.close();
543                 }
544                 return line;
545             }
546         }
547         if ( reader != null ) {
548             reader.close();
549         }
550         return line;
551     }
552
553     final public static String getForesterLibraryInformation() {
554         return "forester " + ForesterConstants.FORESTER_VERSION + " (" + ForesterConstants.FORESTER_DATE + ")";
555     }
556
557     final public static String getLineSeparator() {
558         return ForesterUtil.LINE_SEPARATOR;
559     }
560
561     final public static void increaseCountingMap( final Map<String, Integer> counting_map, final String item_name ) {
562         if ( !counting_map.containsKey( item_name ) ) {
563             counting_map.put( item_name, 1 );
564         }
565         else {
566             counting_map.put( item_name, counting_map.get( item_name ) + 1 );
567         }
568     }
569
570     final public static boolean isContainsParanthesesableNhCharacter( final String nh ) {
571         return PARANTHESESABLE_NH_CHARS_PATTERN.matcher( nh ).find();
572     }
573
574     final public static boolean isEmpty( final List<?> l ) {
575         if ( ( l == null ) || l.isEmpty() ) {
576             return true;
577         }
578         for( final Object o : l ) {
579             if ( o != null ) {
580                 return false;
581             }
582         }
583         return true;
584     }
585
586     final public static boolean isEmpty( final Set<?> s ) {
587         if ( ( s == null ) || s.isEmpty() ) {
588             return true;
589         }
590         for( final Object o : s ) {
591             if ( o != null ) {
592                 return false;
593             }
594         }
595         return true;
596     }
597
598     final public static boolean isEmpty( final String s ) {
599         return ( ( s == null ) || ( s.length() < 1 ) );
600     }
601
602     final public static boolean isEqual( final double a, final double b ) {
603         return ( ( Math.abs( a - b ) ) < ZERO_DIFF );
604     }
605
606     final public static boolean isEven( final int n ) {
607         return ( n % 2 ) == 0;
608     }
609
610     /**
611      * This determines whether String[] a and String[] b have at least one
612      * String in common (intersect). Returns false if at least one String[] is
613      * null or empty.
614      * 
615      * @param a
616      *            a String[] b a String[]
617      * @return true if both a and b or not empty or null and contain at least
618      *         one element in common false otherwise
619      */
620     final public static boolean isIntersecting( final String[] a, final String[] b ) {
621         if ( ( a == null ) || ( b == null ) ) {
622             return false;
623         }
624         if ( ( a.length < 1 ) || ( b.length < 1 ) ) {
625             return false;
626         }
627         for( final String ai : a ) {
628             for( final String element : b ) {
629                 if ( ( ai != null ) && ( element != null ) && ai.equals( element ) ) {
630                     return true;
631                 }
632             }
633         }
634         return false;
635     }
636
637     final public static double isLargerOrEqualToZero( final double d ) {
638         if ( d > 0.0 ) {
639             return d;
640         }
641         else {
642             return 0.0;
643         }
644     }
645
646     final public static boolean isNull( final BigDecimal s ) {
647         return ( ( s == null ) || ( s.compareTo( NULL_BD ) == 0 ) );
648     }
649
650     final public static String isReadableFile( final File f ) {
651         if ( !f.exists() ) {
652             return "file [" + f + "] does not exist";
653         }
654         if ( f.isDirectory() ) {
655             return "[" + f + "] is a directory";
656         }
657         if ( !f.isFile() ) {
658             return "[" + f + "] is not a file";
659         }
660         if ( !f.canRead() ) {
661             return "file [" + f + "] is not readable";
662         }
663         if ( f.length() < 1 ) {
664             return "file [" + f + "] is empty";
665         }
666         return null;
667     }
668
669     final public static String isReadableFile( final String s ) {
670         return isReadableFile( new File( s ) );
671     }
672
673     public final static boolean isWindows() {
674         try {
675             return OS_NAME.toLowerCase().indexOf( "win" ) > -1;
676         }
677         catch ( final Exception e ) {
678             ForesterUtil.printWarningMessage( Constants.PRG_NAME, "minor error: " + e );
679             return false;
680         }
681     }
682
683     public final static boolean isMac() {
684         try {
685             return OS_NAME.toLowerCase().startsWith( "mac" );
686         }
687         catch ( final Exception e ) {
688             ForesterUtil.printWarningMessage( Constants.PRG_NAME, "minor error: " + e );
689             return false;
690         }
691     }
692
693     final public static String isWritableFile( final File f ) {
694         if ( f.isDirectory() ) {
695             return "[" + f + "] is a directory";
696         }
697         if ( f.exists() ) {
698             return "[" + f + "] already exists";
699         }
700         return null;
701     }
702
703     /**
704      * Helper for method "stringToColor".
705      * <p>
706      * (Last modified: 12/20/03)
707      */
708     final public static int limitRangeForColor( int i ) {
709         if ( i > 255 ) {
710             i = 255;
711         }
712         else if ( i < 0 ) {
713             i = 0;
714         }
715         return i;
716     }
717
718     final public static SortedMap<Object, Integer> listToSortedCountsMap( final List<?> list ) {
719         final SortedMap<Object, Integer> map = new TreeMap<Object, Integer>();
720         for( final Object key : list ) {
721             if ( !map.containsKey( key ) ) {
722                 map.put( key, 1 );
723             }
724             else {
725                 map.put( key, map.get( key ) + 1 );
726             }
727         }
728         return map;
729     }
730
731     final public static void map2file( final File file,
732                                        final Map<?, ?> data,
733                                        final String entry_separator,
734                                        final String data_separator ) throws IOException {
735         final Writer writer = new BufferedWriter( new FileWriter( file ) );
736         map2writer( writer, data, entry_separator, data_separator );
737         writer.close();
738     }
739
740     final public static void map2writer( final Writer writer,
741                                          final Map<?, ?> data,
742                                          final String entry_separator,
743                                          final String data_separator ) throws IOException {
744         boolean first = true;
745         for( final Entry<?, ?> entry : data.entrySet() ) {
746             if ( !first ) {
747                 writer.write( data_separator );
748             }
749             else {
750                 first = false;
751             }
752             writer.write( entry.getKey().toString() );
753             writer.write( entry_separator );
754             writer.write( entry.getValue().toString() );
755         }
756     }
757
758     final public static StringBuffer mapToStringBuffer( final Map<Object, Object> map, final String key_value_separator ) {
759         final StringBuffer sb = new StringBuffer();
760         for( final Object key : map.keySet() ) {
761             sb.append( key.toString() );
762             sb.append( key_value_separator );
763             sb.append( map.get( key ).toString() );
764             sb.append( ForesterUtil.getLineSeparator() );
765         }
766         return sb;
767     }
768
769     final public static String normalizeString( final String s,
770                                                 final int length,
771                                                 final boolean left_pad,
772                                                 final char pad_char ) {
773         if ( s.length() > length ) {
774             return s.substring( 0, length );
775         }
776         else {
777             final StringBuffer pad = new StringBuffer( length - s.length() );
778             for( int i = 0; i < ( length - s.length() ); ++i ) {
779                 pad.append( pad_char );
780             }
781             if ( left_pad ) {
782                 return pad + s;
783             }
784             else {
785                 return s + pad;
786             }
787         }
788     }
789
790     final public static BufferedReader obtainReader( final Object source ) throws IOException, FileNotFoundException {
791         BufferedReader reader = null;
792         if ( source instanceof File ) {
793             final File f = ( File ) source;
794             if ( !f.exists() ) {
795                 throw new IOException( "\"" + f.getAbsolutePath() + "\" does not exist" );
796             }
797             else if ( !f.isFile() ) {
798                 throw new IOException( "\"" + f.getAbsolutePath() + "\" is not a file" );
799             }
800             else if ( !f.canRead() ) {
801                 throw new IOException( "\"" + f.getAbsolutePath() + "\" is not a readable" );
802             }
803             reader = new BufferedReader( new FileReader( f ) );
804         }
805         else if ( source instanceof InputStream ) {
806             reader = new BufferedReader( new InputStreamReader( ( InputStream ) source ) );
807         }
808         else if ( source instanceof String ) {
809             reader = new BufferedReader( new StringReader( ( String ) source ) );
810         }
811         else if ( source instanceof StringBuffer ) {
812             reader = new BufferedReader( new StringReader( source.toString() ) );
813         }
814         else {
815             throw new IllegalArgumentException( "attempt to parse object of type [" + source.getClass()
816                     + "] (can only parse objects of type File, InputStream, String, or StringBuffer)" );
817         }
818         return reader;
819     }
820
821     final public static StringBuffer pad( final double number, final int size, final char pad, final boolean left_pad ) {
822         return pad( new StringBuffer( number + "" ), size, pad, left_pad );
823     }
824
825     final public static StringBuffer pad( final String string, final int size, final char pad, final boolean left_pad ) {
826         return pad( new StringBuffer( string ), size, pad, left_pad );
827     }
828
829     final public static StringBuffer pad( final StringBuffer string,
830                                           final int size,
831                                           final char pad,
832                                           final boolean left_pad ) {
833         final StringBuffer padding = new StringBuffer();
834         final int s = size - string.length();
835         if ( s < 1 ) {
836             return new StringBuffer( string.substring( 0, size ) );
837         }
838         for( int i = 0; i < s; ++i ) {
839             padding.append( pad );
840         }
841         if ( left_pad ) {
842             return padding.append( string );
843         }
844         else {
845             return string.append( padding );
846         }
847     }
848
849     final public static double parseDouble( final String str ) throws ParseException {
850         if ( ForesterUtil.isEmpty( str ) ) {
851             return 0.0;
852         }
853         return Double.parseDouble( str );
854     }
855
856     final public static int parseInt( final String str ) throws ParseException {
857         if ( ForesterUtil.isEmpty( str ) ) {
858             return 0;
859         }
860         return Integer.parseInt( str );
861     }
862
863     final public static void printArray( final Object[] a ) {
864         for( int i = 0; i < a.length; ++i ) {
865             System.out.println( "[" + i + "]=" + a[ i ] );
866         }
867     }
868
869     final public static void printCountingMap( final Map<String, Integer> counting_map ) {
870         for( final String key : counting_map.keySet() ) {
871             System.out.println( key + ": " + counting_map.get( key ) );
872         }
873     }
874
875     final public static void printErrorMessage( final String prg_name, final String message ) {
876         System.err.println( "[" + prg_name + "] > error: " + message );
877     }
878
879     final public static void printProgramInformation( final String prg_name, final String prg_version, final String date ) {
880         final int l = prg_name.length() + prg_version.length() + date.length() + 4;
881         System.out.println();
882         System.out.println( prg_name + " " + prg_version + " (" + date + ")" );
883         for( int i = 0; i < l; ++i ) {
884             System.out.print( "_" );
885         }
886         System.out.println();
887     }
888
889     final public static void printProgramInformation( final String prg_name,
890                                                       final String prg_version,
891                                                       final String date,
892                                                       final String email,
893                                                       final String www ) {
894         printProgramInformation( prg_name, null, prg_version, date, email, www, null );
895     }
896
897     final public static void printProgramInformation( final String prg_name,
898                                                       final String desc,
899                                                       final String prg_version,
900                                                       final String date,
901                                                       final String email,
902                                                       final String www,
903                                                       final String based_on ) {
904         String my_prg_name = new String( prg_name );
905         if ( !ForesterUtil.isEmpty( desc ) ) {
906             my_prg_name += ( " - " + desc );
907         }
908         final int l = my_prg_name.length() + prg_version.length() + date.length() + 4;
909         System.out.println();
910         System.out.println( my_prg_name + " " + prg_version + " (" + date + ")" );
911         for( int i = 0; i < l; ++i ) {
912             System.out.print( "_" );
913         }
914         System.out.println();
915         System.out.println();
916         System.out.println( "WWW     : " + www );
917         System.out.println( "Contact : " + email );
918         if ( !ForesterUtil.isEmpty( based_on ) ) {
919             System.out.println( "Based on: " + based_on );
920         }
921         if ( !ForesterUtil.isEmpty( ForesterUtil.JAVA_VERSION ) && !ForesterUtil.isEmpty( ForesterUtil.JAVA_VENDOR ) ) {
922             System.out.println();
923             System.out.println( "[running on Java " + ForesterUtil.JAVA_VERSION + " " + ForesterUtil.JAVA_VENDOR + "]" );
924         }
925         System.out.println();
926     }
927
928     final public static void printWarningMessage( final String prg_name, final String message ) {
929         System.out.println( "[" + prg_name + "] > warning: " + message );
930     }
931
932     final public static void programMessage( final String prg_name, final String message ) {
933         System.out.println( "[" + prg_name + "] > " + message );
934     }
935
936     final public static String removeSuffix( final String file_name ) {
937         final int i = file_name.lastIndexOf( '.' );
938         if ( i > 1 ) {
939             return file_name.substring( 0, i );
940         }
941         return file_name;
942     }
943
944     /**
945      * Removes all white space from String s.
946      * 
947      * @return String s with white space removed
948      */
949     final public static String removeWhiteSpace( String s ) {
950         int i;
951         for( i = 0; i <= ( s.length() - 1 ); i++ ) {
952             if ( ( s.charAt( i ) == ' ' ) || ( s.charAt( i ) == '\t' ) || ( s.charAt( i ) == '\n' )
953                     || ( s.charAt( i ) == '\r' ) ) {
954                 s = s.substring( 0, i ) + s.substring( i + 1 );
955                 i--;
956             }
957         }
958         return s;
959     }
960
961     final public static String replaceIllegalNhCharacters( final String nh ) {
962         if ( nh == null ) {
963             return "";
964         }
965         return nh.trim().replaceAll( "[\\[\\]:]+", "_" );
966     }
967
968     final public static String replaceIllegalNhxCharacters( final String nhx ) {
969         if ( nhx == null ) {
970             return "";
971         }
972         return nhx.trim().replaceAll( "[\\[\\](),:;\\s]+", "_" );
973     }
974
975     final public static double round( final double value, final int decimal_place ) {
976         BigDecimal bd = new BigDecimal( value );
977         bd = bd.setScale( decimal_place, BigDecimal.ROUND_HALF_UP );
978         return bd.doubleValue();
979     }
980
981     /**
982      * Rounds d to an int.
983      */
984     final public static int roundToInt( final double d ) {
985         return ( int ) ( d + 0.5 );
986     }
987
988     final public static int roundToInt( final float f ) {
989         return ( int ) ( f + 0.5f );
990     }
991
992     final public static short roundToShort( final double d ) {
993         return ( short ) ( d + 0.5 );
994     }
995
996     final public static String sanitizeString( final String s ) {
997         if ( s == null ) {
998             return "";
999         }
1000         else {
1001             return s.trim();
1002         }
1003     }
1004
1005     public static boolean seqIsLikelyToBeAa( final String s ) {
1006         final String seq = s.toLowerCase();
1007         if ( ( seq.indexOf( 'r' ) > -1 ) || ( seq.indexOf( 'd' ) > -1 ) || ( seq.indexOf( 'e' ) > -1 )
1008                 || ( seq.indexOf( 'q' ) > -1 ) || ( seq.indexOf( 'h' ) > -1 ) || ( seq.indexOf( 'k' ) > -1 )
1009                 || ( seq.indexOf( 'w' ) > -1 ) || ( seq.indexOf( 's' ) > -1 ) || ( seq.indexOf( 'm' ) > -1 )
1010                 || ( seq.indexOf( 'p' ) > -1 ) || ( seq.indexOf( 'v' ) > -1 ) ) {
1011             return true;
1012         }
1013         return false;
1014     }
1015
1016     final public static String stringArrayToString( final String[] a ) {
1017         return stringArrayToString( a, ", " );
1018     }
1019
1020     final public static String stringArrayToString( final String[] a, final String separator ) {
1021         final StringBuilder sb = new StringBuilder();
1022         if ( ( a != null ) && ( a.length > 0 ) ) {
1023             for( int i = 0; i < ( a.length - 1 ); ++i ) {
1024                 sb.append( a[ i ] + separator );
1025             }
1026             sb.append( a[ a.length - 1 ] );
1027         }
1028         return sb.toString();
1029     }
1030
1031     final public static String[] stringListToArray( final List<String> list ) {
1032         if ( list != null ) {
1033             final String[] str = new String[ list.size() ];
1034             int i = 0;
1035             for( final String l : list ) {
1036                 str[ i++ ] = l;
1037             }
1038             return str;
1039         }
1040         return null;
1041     }
1042
1043     final public static String stringListToString( final List<String> l, final String separator ) {
1044         final StringBuilder sb = new StringBuilder();
1045         if ( ( l != null ) && ( l.size() > 0 ) ) {
1046             for( int i = 0; i < ( l.size() - 1 ); ++i ) {
1047                 sb.append( l.get( i ) + separator );
1048             }
1049             sb.append( l.get( l.size() - 1 ) );
1050         }
1051         return sb.toString();
1052     }
1053
1054     final public static String[] stringSetToArray( final Set<String> strings ) {
1055         final String[] str_array = new String[ strings.size() ];
1056         int i = 0;
1057         for( final String e : strings ) {
1058             str_array[ i++ ] = e;
1059         }
1060         return str_array;
1061     }
1062
1063     final public static void unexpectedFatalError( final Exception e ) {
1064         System.err.println();
1065         System.err.println( "unexpected exception: should not have occured! Please contact program author(s)." );
1066         e.printStackTrace( System.err );
1067         System.err.println();
1068         System.exit( -1 );
1069     }
1070
1071     final public static void unexpectedFatalError( final Error e ) {
1072         System.err.println();
1073         System.err.println( "unexpected error: should not have occured! Please contact program author(s)." );
1074         e.printStackTrace( System.err );
1075         System.err.println();
1076         System.exit( -1 );
1077     }
1078
1079     final public static void unexpectedFatalError( final String message ) {
1080         System.err.println();
1081         System.err.println( "unexpected error: should not have occured! Please contact program author(s)." );
1082         System.err.println( message );
1083         System.err.println();
1084         System.exit( -1 );
1085     }
1086
1087     final public static void unexpectedFatalError( final String prg_name, final Exception e ) {
1088         System.err.println();
1089         System.err.println( "[" + prg_name
1090                 + "] > unexpected error; should not have occured! Please contact program author(s)." );
1091         e.printStackTrace( System.err );
1092         System.err.println();
1093         System.exit( -1 );
1094     }
1095
1096     final public static void unexpectedFatalError( final String prg_name, final String message ) {
1097         System.err.println();
1098         System.err.println( "[" + prg_name
1099                 + "] > unexpected error: should not have occured! Please contact program author(s)." );
1100         System.err.println( message );
1101         System.err.println();
1102         System.exit( -1 );
1103     }
1104
1105     final public static void unexpectedFatalError( final String prg_name, final String message, final Exception e ) {
1106         System.err.println();
1107         System.err.println( "[" + prg_name
1108                 + "] > unexpected error: should not have occured! Please contact program author(s)." );
1109         System.err.println( message );
1110         e.printStackTrace( System.err );
1111         System.err.println();
1112         System.exit( -1 );
1113     }
1114
1115     public final static void updateProgress( final double progress_percentage ) {
1116         final int width = 50;
1117         System.out.print( "\r[" );
1118         int i = 0;
1119         for( ; i <= ForesterUtil.roundToInt( progress_percentage * width ); i++ ) {
1120             System.out.print( "." );
1121         }
1122         for( ; i < width; i++ ) {
1123             System.out.print( " " );
1124         }
1125         System.out.print( "]" );
1126     }
1127
1128     public final static void updateProgress( final int i, final DecimalFormat f ) {
1129         System.out.print( "\r[" + f.format( i ) + "]" );
1130     }
1131
1132     public final static String wordWrap( final String str, final int width ) {
1133         final StringBuilder sb = new StringBuilder( str );
1134         int start = 0;
1135         int ls = -1;
1136         int i = 0;
1137         while ( i < sb.length() ) {
1138             if ( sb.charAt( i ) == ' ' ) {
1139                 ls = i;
1140             }
1141             if ( sb.charAt( i ) == '\n' ) {
1142                 ls = -1;
1143                 start = i + 1;
1144             }
1145             if ( i > ( ( start + width ) - 1 ) ) {
1146                 if ( ls != -1 ) {
1147                     sb.setCharAt( ls, '\n' );
1148                     start = ls + 1;
1149                     ls = -1;
1150                 }
1151                 else {
1152                     sb.insert( i, '\n' );
1153                     start = i + 1;
1154                 }
1155             }
1156             i++;
1157         }
1158         return sb.toString();
1159     }
1160
1161     /**
1162      * Helper method for calcColor methods.
1163      * 
1164      * @param smallercolor_component_x
1165      *            color component the smaller color
1166      * @param largercolor_component_x
1167      *            color component the larger color
1168      * @param x
1169      *            factor
1170      * @return an int representing a color component
1171      */
1172     final private static int calculateColorComponent( final double smallercolor_component_x,
1173                                                       final double largercolor_component_x,
1174                                                       final double x ) {
1175         return ( int ) ( smallercolor_component_x + ( ( x * ( largercolor_component_x - smallercolor_component_x ) ) / 255.0 ) );
1176     }
1177
1178     /**
1179      * Helper method for calcColor methods.
1180      * 
1181      * 
1182      * @param value
1183      *            the value
1184      * @param larger
1185      *            the largest value
1186      * @param smaller
1187      *            the smallest value
1188      * @return a normalized value between larger and smaller
1189      */
1190     final private static double calculateColorFactor( final double value, final double larger, final double smaller ) {
1191         return ( 255.0 * ( value - smaller ) ) / ( larger - smaller );
1192     }
1193
1194     final private static String[] splitString( final String str ) {
1195         final String regex = "[\\s;,]+";
1196         return str.split( regex );
1197     }
1198
1199     public final static void outOfMemoryError( final OutOfMemoryError e ) {
1200         System.err.println();
1201         System.err.println( "Java memory allocation might be too small, try \"-Xmx2048m\" java command line option" );
1202         System.err.println();
1203         e.printStackTrace( System.err );
1204         System.err.println();
1205         System.exit( -1 );
1206     }
1207
1208     public final static Color obtainColorDependingOnTaxonomyGroup( final String tax_group ) {
1209         if ( !ForesterUtil.isEmpty( tax_group ) ) {
1210             if ( tax_group.equals( TaxonomyGroups.DEUTEROSTOMIA ) ) {
1211                 return TaxonomyColors.DEUTEROSTOMIA_COLOR;
1212             }
1213             else if ( tax_group.equals( TaxonomyGroups.PROTOSTOMIA ) ) {
1214                 return TaxonomyColors.PROTOSTOMIA_COLOR;
1215             }
1216             else if ( tax_group.equals( TaxonomyGroups.CNIDARIA ) ) {
1217                 return TaxonomyColors.CNIDARIA_COLOR;
1218             }
1219             else if ( tax_group.equals( TaxonomyGroups.PLACOZOA ) ) {
1220                 return TaxonomyColors.PLACOZOA_COLOR;
1221             }
1222             else if ( tax_group.equals( TaxonomyGroups.CTENOPHORA ) ) {
1223                 return TaxonomyColors.CTENOPHORA_COLOR;
1224             }
1225             else if ( tax_group.equals( TaxonomyGroups.PORIFERA ) ) {
1226                 return TaxonomyColors.PORIFERA_COLOR;
1227             }
1228             else if ( tax_group.equals( TaxonomyGroups.CHOANOFLAGELLIDA ) ) {
1229                 return TaxonomyColors.CHOANOFLAGELLIDA;
1230             }
1231             else if ( tax_group.equals( TaxonomyGroups.ICHTHYOPHONIDA_FILASTEREA ) ) {
1232                 return TaxonomyColors.ICHTHYOSPOREA_AND_FILASTEREA;
1233             }
1234             else if ( tax_group.equals( TaxonomyGroups.DIKARYA ) ) {
1235                 return TaxonomyColors.DIKARYA_COLOR;
1236             }
1237             else if ( tax_group.equalsIgnoreCase( TaxonomyGroups.FUNGI )
1238                     || tax_group.equalsIgnoreCase( TaxonomyGroups.OTHER_FUNGI ) ) {
1239                 return TaxonomyColors.OTHER_FUNGI_COLOR;
1240             }
1241             else if ( tax_group.equals( TaxonomyGroups.NUCLEARIIDAE_AND_FONTICULA_GROUP ) ) {
1242                 return TaxonomyColors.NUCLEARIIDAE_AND_FONTICULA_GROUP_COLOR;
1243             }
1244             else if ( tax_group.equals( TaxonomyGroups.AMOEBOZOA ) ) {
1245                 return TaxonomyColors.AMOEBOZOA_COLOR;
1246             }
1247             else if ( tax_group.equals( TaxonomyGroups.EMBRYOPHYTA ) ) {
1248                 return TaxonomyColors.EMBRYOPHYTA_COLOR;
1249             }
1250             else if ( tax_group.equals( TaxonomyGroups.CHLOROPHYTA ) ) {
1251                 return TaxonomyColors.CHLOROPHYTA_COLOR;
1252             }
1253             else if ( tax_group.equals( TaxonomyGroups.RHODOPHYTA ) ) {
1254                 return TaxonomyColors.RHODOPHYTA_COLOR;
1255             }
1256             else if ( tax_group.equals( TaxonomyGroups.HACROBIA ) ) {
1257                 return TaxonomyColors.HACROBIA_COLOR;
1258             }
1259             else if ( tax_group.equals( TaxonomyGroups.GLAUCOCYSTOPHYCEAE ) ) {
1260                 return TaxonomyColors.GLAUCOPHYTA_COLOR;
1261             }
1262             else if ( tax_group.equals( TaxonomyGroups.STRAMENOPILES ) ) {
1263                 return TaxonomyColors.STRAMENOPILES_COLOR;
1264             }
1265             else if ( tax_group.equals( TaxonomyGroups.ALVEOLATA ) ) {
1266                 return TaxonomyColors.ALVEOLATA_COLOR;
1267             }
1268             else if ( tax_group.equals( TaxonomyGroups.RHIZARIA ) ) {
1269                 return TaxonomyColors.RHIZARIA_COLOR;
1270             }
1271             else if ( tax_group.equals( TaxonomyGroups.EXCAVATA ) ) {
1272                 return TaxonomyColors.EXCAVATA_COLOR;
1273             }
1274             else if ( tax_group.equals( TaxonomyGroups.APUSOZOA ) ) {
1275                 return TaxonomyColors.APUSOZOA_COLOR;
1276             }
1277             else if ( tax_group.equals( TaxonomyGroups.ARCHAEA ) ) {
1278                 return TaxonomyColors.ARCHAEA_COLOR;
1279             }
1280             else if ( tax_group.equals( TaxonomyGroups.BACTERIA ) ) {
1281                 return TaxonomyColors.BACTERIA_COLOR;
1282             }
1283         }
1284         return null;
1285     }
1286
1287     public final static String obtainNormalizedTaxonomyGroup( final String tax ) {
1288         if ( tax.equalsIgnoreCase( TaxonomyGroups.DEUTEROSTOMIA ) ) {
1289             return TaxonomyGroups.DEUTEROSTOMIA;
1290         }
1291         else if ( tax.equalsIgnoreCase( TaxonomyGroups.PROTOSTOMIA ) ) {
1292             return TaxonomyGroups.PROTOSTOMIA;
1293         }
1294         else if ( tax.equalsIgnoreCase( TaxonomyGroups.CNIDARIA ) ) {
1295             return TaxonomyGroups.CNIDARIA;
1296         }
1297         else if ( tax.toLowerCase().startsWith( "trichoplax" ) || tax.equalsIgnoreCase( TaxonomyGroups.PLACOZOA ) ) {
1298             return TaxonomyGroups.PLACOZOA;
1299         }
1300         else if ( tax.toLowerCase().startsWith( "mnemiopsis" ) || tax.equalsIgnoreCase( TaxonomyGroups.CTENOPHORA ) ) {
1301             return TaxonomyGroups.CTENOPHORA;
1302         }
1303         else if ( tax.toLowerCase().startsWith( "amphimedon" ) || tax.equalsIgnoreCase( TaxonomyGroups.PORIFERA ) ) {
1304             return TaxonomyGroups.PORIFERA;
1305         }
1306         else if ( tax.equalsIgnoreCase( "codonosigidae" ) || tax.equalsIgnoreCase( TaxonomyGroups.CHOANOFLAGELLIDA ) ) {
1307             return TaxonomyGroups.CHOANOFLAGELLIDA;
1308         }
1309         else if ( tax.toLowerCase().startsWith( TaxonomyGroups.ICHTHYOPHONIDA_FILASTEREA )
1310                 || tax.toLowerCase().startsWith( "ichthyophonida and filasterea" )
1311                 || tax.toLowerCase().startsWith( "ichthyosporea & filasterea" )
1312                 || tax.toLowerCase().startsWith( "ichthyosporea and filasterea" ) ) {
1313             return TaxonomyGroups.ICHTHYOPHONIDA_FILASTEREA;
1314         }
1315         else if ( tax.equalsIgnoreCase( TaxonomyGroups.DIKARYA ) ) {
1316             return TaxonomyGroups.DIKARYA;
1317         }
1318         else if ( tax.equalsIgnoreCase( TaxonomyGroups.FUNGI ) || tax.equalsIgnoreCase( TaxonomyGroups.OTHER_FUNGI ) ) {
1319             return TaxonomyGroups.OTHER_FUNGI;
1320         }
1321         else if ( tax.toLowerCase().startsWith( "nucleariidae and fonticula" ) ) {
1322             return TaxonomyGroups.NUCLEARIIDAE_AND_FONTICULA_GROUP;
1323         }
1324         else if ( tax.equalsIgnoreCase( TaxonomyGroups.AMOEBOZOA ) ) {
1325             return TaxonomyGroups.AMOEBOZOA;
1326         }
1327         else if ( tax.equalsIgnoreCase( TaxonomyGroups.EMBRYOPHYTA ) ) {
1328             return TaxonomyGroups.EMBRYOPHYTA;
1329         }
1330         else if ( tax.equalsIgnoreCase( TaxonomyGroups.CHLOROPHYTA ) ) {
1331             return TaxonomyGroups.CHLOROPHYTA;
1332         }
1333         else if ( tax.equalsIgnoreCase( TaxonomyGroups.RHODOPHYTA ) ) {
1334             return TaxonomyGroups.RHODOPHYTA;
1335         }
1336         else if ( tax.toLowerCase().startsWith( TaxonomyGroups.HACROBIA ) ) {
1337             return TaxonomyGroups.HACROBIA;
1338         }
1339         else if ( tax.equalsIgnoreCase( TaxonomyGroups.GLAUCOCYSTOPHYCEAE ) || tax.equalsIgnoreCase( "glaucophyta" ) ) {
1340             return TaxonomyGroups.GLAUCOCYSTOPHYCEAE;
1341         }
1342         else if ( tax.equalsIgnoreCase( TaxonomyGroups.STRAMENOPILES ) ) {
1343             return TaxonomyGroups.STRAMENOPILES;
1344         }
1345         else if ( tax.equalsIgnoreCase( TaxonomyGroups.ALVEOLATA ) ) {
1346             return TaxonomyGroups.ALVEOLATA;
1347         }
1348         else if ( tax.equalsIgnoreCase( TaxonomyGroups.RHIZARIA ) ) {
1349             return TaxonomyGroups.RHIZARIA;
1350         }
1351         else if ( tax.equalsIgnoreCase( TaxonomyGroups.EXCAVATA ) ) {
1352             return TaxonomyGroups.EXCAVATA;
1353         }
1354         else if ( tax.equalsIgnoreCase( TaxonomyGroups.APUSOZOA ) ) {
1355             return TaxonomyGroups.APUSOZOA;
1356         }
1357         else if ( tax.equalsIgnoreCase( TaxonomyGroups.ARCHAEA ) ) {
1358             return TaxonomyGroups.ARCHAEA;
1359         }
1360         else if ( tax.equalsIgnoreCase( TaxonomyGroups.BACTERIA ) ) {
1361             return TaxonomyGroups.BACTERIA;
1362         }
1363         return null;
1364     }
1365 }