2 // FORESTER -- software libraries and applications
3 // for evolutionary biology research and applications.
5 // Copyright (C) 2008-2009 Christian M. Zmasek
6 // Copyright (C) 2008-2009 Burnham Institute for Medical Research
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.
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.
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
23 // Contact: phylosoft @ gmail . com
24 // WWW: www.phylosoft.org/forester
26 package org.forester.io.writers;
28 import java.io.BufferedWriter;
30 import java.io.FileWriter;
31 import java.io.IOException;
32 import java.io.PrintWriter;
33 import java.io.StringWriter;
34 import java.io.Writer;
35 import java.util.ArrayList;
36 import java.util.Iterator;
37 import java.util.List;
38 import java.util.Stack;
40 import org.forester.io.parsers.nexus.NexusConstants;
41 import org.forester.io.parsers.phyloxml.PhyloXmlMapping;
42 import org.forester.phylogeny.Phylogeny;
43 import org.forester.phylogeny.PhylogenyNode;
44 import org.forester.phylogeny.data.PhylogenyDataUtil;
45 import org.forester.phylogeny.iterators.PhylogenyNodeIterator;
46 import org.forester.phylogeny.iterators.PostOrderStackObject;
47 import org.forester.util.ForesterConstants;
48 import org.forester.util.ForesterUtil;
50 public final class PhylogenyWriter {
52 public final static boolean INDENT_PHYLOXML_DEAFULT = true;
53 public final static String PHYLO_XML_INTENDATION_BASE = " ";
54 public final static String PHYLO_XML_VERSION_ENCODING_LINE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
55 public final static String PHYLO_XML_NAMESPACE_LINE = "<phyloxml xmlns:xsi=\""
56 + ForesterConstants.XML_SCHEMA_INSTANCE
57 + "\" xsi:schemaLocation=\""
58 + ForesterConstants.PHYLO_XML_LOCATION
60 + ForesterConstants.PHYLO_XML_LOCATION
62 + ForesterConstants.PHYLO_XML_VERSION
63 + "/" + ForesterConstants.PHYLO_XML_XSD
65 + ForesterConstants.PHYLO_XML_LOCATION
67 public final static String PHYLO_XML_END = "</phyloxml>";
68 private boolean _saw_comma;
69 private StringBuffer _buffer;
70 private Writer _writer;
71 private PhylogenyNode _root;
72 private boolean _has_next;
73 private Stack<PostOrderStackObject> _stack;
74 private boolean _simple_nh;
75 private boolean _nh_write_distance_to_parent;
76 private boolean _write_conf_values_in_branckets_in_nh;
77 private boolean _indent_phyloxml;
78 private int _node_level;
79 private int _phyloxml_level;
80 private FORMAT _format;
82 public PhylogenyWriter() {
83 setIndentPhyloxml( INDENT_PHYLOXML_DEAFULT );
84 setWriteConfidenceValuesInBracketsInNH( false );
87 private void appendPhylogenyLevelPhyloXml( final Writer writer, final Phylogeny tree ) throws IOException {
88 final String indentation = new String();
89 if ( !ForesterUtil.isEmpty( tree.getName() ) ) {
90 PhylogenyDataUtil.appendElement( writer, PhyloXmlMapping.PHYLOGENY_NAME, tree.getName(), indentation );
92 if ( tree.getIdentifier() != null ) {
93 if ( ForesterUtil.isEmpty( tree.getIdentifier().getProvider() ) ) {
94 PhylogenyDataUtil.appendElement( writer,
95 PhyloXmlMapping.IDENTIFIER,
96 tree.getIdentifier().getValue(),
99 PhylogenyDataUtil.appendElement( writer,
100 PhyloXmlMapping.IDENTIFIER,
101 tree.getIdentifier().getValue(),
102 PhyloXmlMapping.IDENTIFIER_PROVIDER_ATTR,
103 tree.getIdentifier().getProvider(),
106 if ( !ForesterUtil.isEmpty( tree.getDescription() ) ) {
107 PhylogenyDataUtil.appendElement( writer,
108 PhyloXmlMapping.PHYLOGENY_DESCRIPTION,
109 tree.getDescription(),
112 if ( tree.getConfidence() != null ) {
113 if ( ForesterUtil.isEmpty( tree.getConfidence().getType() ) ) {
114 PhylogenyDataUtil.appendElement( writer, PhyloXmlMapping.CONFIDENCE, tree.getConfidence().getValue()
117 PhylogenyDataUtil.appendElement( writer,
118 PhyloXmlMapping.CONFIDENCE,
119 tree.getConfidence().getValue() + "",
120 PhyloXmlMapping.CONFIDENCE_TYPE_ATTR,
121 tree.getConfidence().getType(),
126 private StringBuffer createIndentation() {
127 if ( !isIndentPhyloxml() ) {
130 final StringBuffer sb = new StringBuffer( getNodeLevel() * 2 );
131 for( int i = 0; i < getNodeLevel(); ++i ) {
132 sb.append( PhylogenyWriter.PHYLO_XML_INTENDATION_BASE );
137 private void decreaseNodeLevel() {
141 private StringBuffer getBuffer() {
145 private int getNodeLevel() {
149 private StringBuffer getOutput( final Phylogeny tree ) throws IOException {
150 if ( getOutputFormt() == FORMAT.PHYLO_XML ) {
151 throw new RuntimeException( "method inappropriately called" );
153 if ( tree != null ) {
155 while ( isHasNext() ) {
158 if ( getOutputFormt() == FORMAT.NH ) {
159 getBuffer().append( ';' );
164 return new StringBuffer( 0 );
168 private FORMAT getOutputFormt() {
172 private int getPhyloXmlLevel() {
173 return _phyloxml_level;
176 private PhylogenyNode getRoot() {
180 private Stack<PostOrderStackObject> getStack() {
184 private Writer getWriter() {
188 private void increaseNodeLevel() {
192 private boolean isHasNext() {
196 private boolean isIndentPhyloxml() {
197 return _indent_phyloxml;
200 private boolean isSawComma() {
204 private boolean isSimpleNH() {
208 private boolean isWriteDistanceToParentInNH() {
209 return _nh_write_distance_to_parent;
212 private void next() throws IOException {
214 final PostOrderStackObject si = getStack().pop();
215 final PhylogenyNode node = si.getNode();
216 final int phase = si.getPhase();
217 if ( phase > node.getNumberOfDescendants() ) {
218 setHasNext( node != getRoot() );
219 if ( ( getOutputFormt() != FORMAT.PHYLO_XML ) || node.isExternal() ) {
220 if ( !node.isRoot() && node.isFirstChildNode() ) {
223 if ( getOutputFormt() == FORMAT.PHYLO_XML ) {
224 writeNode( node, createIndentation() );
227 writeNode( node, null );
230 if ( !node.isRoot() ) {
231 if ( !node.isLastChildNode() ) {
232 writeCladeSeparator();
241 getStack().push( new PostOrderStackObject( node, ( phase + 1 ) ) );
242 if ( node.isInternal() ) {
243 getStack().push( new PostOrderStackObject( node.getChildNode( phase - 1 ), 1 ) );
244 writeOpenClade( node );
245 if ( getOutputFormt() == FORMAT.PHYLO_XML ) {
247 writeNode( node, createIndentation() );
255 private void reset( final Phylogeny tree ) {
256 setBuffer( new StringBuffer() );
258 setSawComma( false );
260 setRoot( tree.getRoot() );
261 setStack( new Stack<PostOrderStackObject>() );
262 getStack().push( new PostOrderStackObject( tree.getRoot(), 1 ) );
266 private void reset( final Writer writer, final Phylogeny tree ) {
269 setSawComma( false );
271 setRoot( tree.getRoot() );
272 setStack( new Stack<PostOrderStackObject>() );
273 getStack().push( new PostOrderStackObject( tree.getRoot(), 1 ) );
277 private void setBuffer( final StringBuffer buffer ) {
281 private void setHasNext( final boolean has_next ) {
282 _has_next = has_next;
285 public void setIndentPhyloxml( final boolean indent_phyloxml ) {
286 _indent_phyloxml = indent_phyloxml;
289 private void setNodeLevel( final int level ) {
293 private void setOutputFormt( final FORMAT format ) {
297 private void setPhyloXmlLevel( final int phyloxml_level ) {
298 _phyloxml_level = phyloxml_level;
301 private void setRoot( final PhylogenyNode root ) {
305 private void setSawComma( final boolean saw_comma ) {
306 _saw_comma = saw_comma;
309 private void setSimpleNH( final boolean simple_nh ) {
310 _simple_nh = simple_nh;
313 private void setStack( final Stack<PostOrderStackObject> stack ) {
317 private void setWriteDistanceToParentInNH( final boolean nh_write_distance_to_parent ) {
318 _nh_write_distance_to_parent = nh_write_distance_to_parent;
321 private void setWriter( final Writer writer ) {
325 public void toNewHampshire( final List<Phylogeny> trees,
326 final boolean simple_nh,
327 final boolean write_distance_to_parent,
329 final String separator ) throws IOException {
330 final Iterator<Phylogeny> it = trees.iterator();
331 final StringBuffer sb = new StringBuffer();
332 while ( it.hasNext() ) {
333 sb.append( toNewHampshire( it.next(), simple_nh, write_distance_to_parent ) );
334 sb.append( separator );
336 writeToFile( sb, out_file );
339 public StringBuffer toNewHampshire( final Phylogeny tree,
340 final boolean simple_nh,
341 final boolean nh_write_distance_to_parent,
342 final boolean write_conf_values_in_branckets_in_nh ) throws IOException {
343 setOutputFormt( FORMAT.NH );
344 setWriteConfidenceValuesInBracketsInNH( write_conf_values_in_branckets_in_nh );
345 setSimpleNH( simple_nh );
346 setWriteDistanceToParentInNH( nh_write_distance_to_parent );
347 return getOutput( tree );
350 public StringBuffer toNewHampshire( final Phylogeny tree,
351 final boolean simple_nh,
352 final boolean nh_write_distance_to_parent ) throws IOException {
353 setOutputFormt( FORMAT.NH );
354 setSimpleNH( simple_nh );
355 setWriteDistanceToParentInNH( nh_write_distance_to_parent );
356 return getOutput( tree );
359 public void toNewHampshire( final Phylogeny tree,
360 final boolean simple_nh,
361 final boolean write_distance_to_parent,
362 final File out_file ) throws IOException {
363 writeToFile( toNewHampshire( tree, simple_nh, write_distance_to_parent ), out_file );
366 public void toNewHampshire( final Phylogeny tree,
367 final boolean simple_nh,
368 final boolean write_distance_to_parent,
369 final boolean use_brackets_for_confidence,
370 final File out_file ) throws IOException {
371 writeToFile( toNewHampshire( tree, simple_nh, write_distance_to_parent, use_brackets_for_confidence ), out_file );
374 public void toNewHampshire( final Phylogeny[] trees,
375 final boolean simple_nh,
376 final boolean write_distance_to_parent,
378 final String separator ) throws IOException {
379 final StringBuffer sb = new StringBuffer();
380 for( final Phylogeny element : trees ) {
381 sb.append( toNewHampshire( element, simple_nh, write_distance_to_parent ) );
382 sb.append( separator );
384 writeToFile( sb, out_file );
387 public void toNewHampshireX( final List<Phylogeny> trees, final File out_file, final String separator )
389 final Iterator<Phylogeny> it = trees.iterator();
390 final StringBuffer sb = new StringBuffer();
391 while ( it.hasNext() ) {
392 sb.append( toNewHampshireX( it.next() ) );
393 sb.append( separator );
395 writeToFile( sb, out_file );
398 public StringBuffer toNewHampshireX( final Phylogeny tree ) throws IOException {
399 setOutputFormt( FORMAT.NHX );
400 return getOutput( tree );
403 public void toNewHampshireX( final Phylogeny tree, final File out_file ) throws IOException {
404 writeToFile( toNewHampshireX( tree ), out_file );
407 public void toNewHampshireX( final Phylogeny[] trees, final File out_file, final String separator )
409 final StringBuffer sb = new StringBuffer();
410 for( final Phylogeny element : trees ) {
411 sb.append( toNewHampshireX( element ) );
412 sb.append( separator );
414 writeToFile( sb, out_file );
417 public void toNexus( final File out_file, final List<Phylogeny> trees ) throws IOException {
418 final Writer writer = new BufferedWriter( new PrintWriter( out_file ) );
419 writeNexusStart( writer );
420 writeNexusTaxaBlock( writer, trees.get( 0 ) );
421 writeNexusTreesBlock( writer, trees );
426 public void toNexus( final File out_file, final Phylogeny tree ) throws IOException {
427 final Writer writer = new BufferedWriter( new PrintWriter( out_file ) );
428 final List<Phylogeny> trees = new ArrayList<Phylogeny>( 1 );
430 writeNexusStart( writer );
431 writeNexusTaxaBlock( writer, tree );
432 writeNexusTreesBlock( writer, trees );
437 public StringBuffer toNexus( final Phylogeny tree ) throws IOException {
438 final StringWriter string_writer = new StringWriter();
439 final Writer writer = new BufferedWriter( string_writer );
440 final List<Phylogeny> trees = new ArrayList<Phylogeny>( 1 );
442 writeNexusStart( writer );
443 writeNexusTaxaBlock( writer, tree );
444 writeNexusTreesBlock( writer, trees );
447 return string_writer.getBuffer();
450 public void toPhyloXML( final File out_file,
451 final List<Phylogeny> trees,
452 final int phyloxml_level,
453 final String separator ) throws IOException {
454 final Writer writer = new BufferedWriter( new PrintWriter( out_file ) );
455 toPhyloXML( writer, trees, phyloxml_level, separator );
460 public void toPhyloXML( final File out_file, final Phylogeny tree, final int phyloxml_level ) throws IOException {
461 final Writer writer = new BufferedWriter( new PrintWriter( out_file ) );
462 writePhyloXmlStart( writer );
463 toPhyloXMLNoPhyloXmlSource( writer, tree, phyloxml_level );
464 writePhyloXmlEnd( writer );
469 public StringBuffer toPhyloXML( final Phylogeny tree, final int phyloxml_level ) throws IOException {
470 final StringWriter string_writer = new StringWriter();
471 final Writer writer = new BufferedWriter( string_writer );
472 setPhyloXmlLevel( phyloxml_level );
473 setOutputFormt( FORMAT.PHYLO_XML );
474 writePhyloXmlStart( writer );
475 writeOutput( writer, tree );
476 writePhyloXmlEnd( writer );
479 return string_writer.getBuffer();
482 public void toPhyloXML( final Phylogeny[] trees,
483 final int phyloxml_level,
485 final String separator ) throws IOException {
486 final Writer writer = new BufferedWriter( new PrintWriter( out_file ) );
487 toPhyloXML( writer, trees, phyloxml_level, separator );
492 public void toPhyloXML( final Writer writer,
493 final List<Phylogeny> trees,
494 final int phyloxml_level,
495 final String separator ) throws IOException {
496 writePhyloXmlStart( writer );
497 final Iterator<Phylogeny> it = trees.iterator();
498 while ( it.hasNext() ) {
499 toPhyloXMLNoPhyloXmlSource( writer, it.next(), phyloxml_level );
500 writer.write( separator );
502 writePhyloXmlEnd( writer );
505 public void toPhyloXML( final Writer writer, final Phylogeny tree, final int phyloxml_level ) throws IOException {
506 setPhyloXmlLevel( phyloxml_level );
507 setOutputFormt( FORMAT.PHYLO_XML );
508 writePhyloXmlStart( writer );
509 writeOutput( writer, tree );
510 writePhyloXmlEnd( writer );
513 public void toPhyloXML( final Writer writer,
514 final Phylogeny[] trees,
515 final int phyloxml_level,
516 final String separator ) throws IOException {
517 writePhyloXmlStart( writer );
518 for( final Phylogeny phylogeny : trees ) {
519 toPhyloXMLNoPhyloXmlSource( writer, phylogeny, phyloxml_level );
520 writer.write( separator );
522 writePhyloXmlEnd( writer );
525 private void toPhyloXMLNoPhyloXmlSource( final Writer writer, final Phylogeny tree, final int phyloxml_level )
527 setPhyloXmlLevel( phyloxml_level );
528 setOutputFormt( FORMAT.PHYLO_XML );
529 writeOutput( writer, tree );
532 private void writeCladeSeparator() {
534 if ( ( getOutputFormt() == FORMAT.NHX ) || ( getOutputFormt() == FORMAT.NH ) ) {
535 getBuffer().append( "," );
539 private void writeCloseClade() throws IOException {
541 if ( getOutputFormt() == FORMAT.PHYLO_XML ) {
542 getWriter().write( ForesterUtil.LINE_SEPARATOR );
543 if ( isIndentPhyloxml() ) {
544 getWriter().write( createIndentation().toString() );
546 PhylogenyDataUtil.appendClose( getWriter(), PhyloXmlMapping.CLADE );
548 else if ( ( getOutputFormt() == FORMAT.NHX ) || ( getOutputFormt() == FORMAT.NH ) ) {
549 getBuffer().append( ")" );
553 private void writeNode( final PhylogenyNode node, final StringBuffer indentation ) throws IOException {
554 if ( getOutputFormt() == FORMAT.PHYLO_XML ) {
555 if ( node.isExternal() ) {
556 getWriter().write( ForesterUtil.LINE_SEPARATOR );
557 if ( indentation != null ) {
558 getWriter().write( indentation.toString() );
560 PhylogenyDataUtil.appendOpen( getWriter(), PhyloXmlMapping.CLADE );
562 if ( indentation != null ) {
563 PhyloXmlNodeWriter.toPhyloXml( getWriter(), node, getPhyloXmlLevel(), indentation.toString() );
566 PhyloXmlNodeWriter.toPhyloXml( getWriter(), node, getPhyloXmlLevel(), "" );
568 if ( node.isExternal() ) {
569 getWriter().write( ForesterUtil.LINE_SEPARATOR );
570 if ( indentation != null ) {
571 getWriter().write( indentation.toString() );
573 PhylogenyDataUtil.appendClose( getWriter(), PhyloXmlMapping.CLADE );
576 else if ( getOutputFormt() == FORMAT.NHX ) {
577 getBuffer().append( node.toNewHampshireX() );
579 else if ( getOutputFormt() == FORMAT.NH ) {
580 getBuffer().append( node.toNewHampshire( isSimpleNH(),
581 isWriteDistanceToParentInNH(),
582 isWriteConfidenceValuesInBracketsInNH() ) );
586 private boolean isWriteConfidenceValuesInBracketsInNH() {
587 return _write_conf_values_in_branckets_in_nh;
590 private void setWriteConfidenceValuesInBracketsInNH( final boolean write_conf_values_in_branckets_in_nh ) {
591 _write_conf_values_in_branckets_in_nh = write_conf_values_in_branckets_in_nh;
594 private void writeOpenClade( final PhylogenyNode node ) throws IOException {
595 if ( !isSawComma() ) {
596 if ( !node.isRoot() && node.isFirstChildNode() ) {
599 if ( getOutputFormt() == FORMAT.PHYLO_XML ) {
600 getWriter().write( ForesterUtil.LINE_SEPARATOR );
601 if ( isIndentPhyloxml() ) {
602 getWriter().write( createIndentation().toString() );
604 PhylogenyDataUtil.appendOpen( getWriter(), PhyloXmlMapping.CLADE );
606 else if ( ( getOutputFormt() == FORMAT.NHX ) || ( getOutputFormt() == FORMAT.NH ) ) {
607 getBuffer().append( "(" );
610 setSawComma( false );
613 private void writeOutput( final Writer writer, final Phylogeny tree ) throws IOException {
614 if ( getOutputFormt() != FORMAT.PHYLO_XML ) {
615 throw new RuntimeException( "method inappropriately called" );
617 if ( tree != null ) {
618 reset( writer, tree );
619 boolean rerootable = true;
622 String rooted = "false";
623 if ( tree.isRooted() ) {
626 if ( !tree.isRerootable() ) {
629 if ( !ForesterUtil.isEmpty( tree.getDistanceUnit() ) ) {
630 unit = tree.getDistanceUnit();
632 if ( !ForesterUtil.isEmpty( tree.getType() ) ) {
633 type = tree.getType();
636 PhylogenyDataUtil.appendOpen( writer,
637 PhyloXmlMapping.PHYLOGENY,
638 PhyloXmlMapping.PHYLOGENY_IS_ROOTED_ATTR,
640 PhyloXmlMapping.PHYLOGENY_BRANCHLENGTH_UNIT_ATTR,
642 PhyloXmlMapping.PHYLOGENY_TYPE_ATTR,
646 PhylogenyDataUtil.appendOpen( writer,
647 PhyloXmlMapping.PHYLOGENY,
648 PhyloXmlMapping.PHYLOGENY_IS_ROOTED_ATTR,
650 PhyloXmlMapping.PHYLOGENY_BRANCHLENGTH_UNIT_ATTR,
652 PhyloXmlMapping.PHYLOGENY_TYPE_ATTR,
654 PhyloXmlMapping.PHYLOGENY_IS_REROOTABLE_ATTR,
657 appendPhylogenyLevelPhyloXml( writer, tree );
658 while ( isHasNext() ) {
661 writer.write( ForesterUtil.LINE_SEPARATOR );
662 PhylogenyDataUtil.appendClose( writer, PhyloXmlMapping.PHYLOGENY );
666 private void writeToFile( final StringBuffer sb, final File out_file ) throws IOException {
667 if ( out_file.exists() ) {
668 throw new IOException( "attempt to overwrite existing file \"" + out_file.getAbsolutePath() + "\"" );
670 final PrintWriter out = new PrintWriter( new FileWriter( out_file ), true );
671 if ( getOutputFormt() == FORMAT.PHYLO_XML ) {
672 out.print( PHYLO_XML_VERSION_ENCODING_LINE );
673 out.print( ForesterUtil.LINE_SEPARATOR );
674 out.print( PHYLO_XML_NAMESPACE_LINE );
675 out.print( ForesterUtil.LINE_SEPARATOR );
678 if ( getOutputFormt() == FORMAT.PHYLO_XML ) {
679 out.print( ForesterUtil.LINE_SEPARATOR );
680 out.print( PHYLO_XML_END );
686 public static PhylogenyWriter createPhylogenyWriter() {
687 return new PhylogenyWriter();
690 private static void writeNexusStart( final Writer writer ) throws IOException {
691 writer.write( NexusConstants.NEXUS );
692 writer.write( ForesterUtil.LINE_SEPARATOR );
695 public static void writeNexusTaxaBlock( final Writer writer, final Phylogeny tree ) throws IOException {
696 writer.write( NexusConstants.BEGIN_TAXA );
697 writer.write( ForesterUtil.LINE_SEPARATOR );
699 writer.write( NexusConstants.DIMENSIONS );
701 writer.write( NexusConstants.NTAX );
703 writer.write( String.valueOf( tree.getNumberOfExternalNodes() ) );
705 writer.write( ForesterUtil.LINE_SEPARATOR );
707 writer.write( NexusConstants.TAXLABELS );
708 for( final PhylogenyNodeIterator it = tree.iteratorExternalForward(); it.hasNext(); ) {
709 final PhylogenyNode node = it.next();
712 if ( !ForesterUtil.isEmpty( node.getName() ) ) {
713 data = node.getName();
715 else if ( node.getNodeData().isHasTaxonomy() ) {
716 if ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getTaxonomyCode() ) ) {
717 data = node.getNodeData().getTaxonomy().getTaxonomyCode();
719 else if ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getScientificName() ) ) {
720 data = node.getNodeData().getTaxonomy().getScientificName();
722 else if ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getCommonName() ) ) {
723 data = node.getNodeData().getTaxonomy().getCommonName();
725 else if ( node.getNodeData().getTaxonomy().getTaxonomyCode() != null ) {
726 data = node.getNodeData().getTaxonomy().getTaxonomyCode();
729 else if ( node.getNodeData().isHasSequence() ) {
730 if ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getName() ) ) {
731 data = node.getNodeData().getSequence().getName();
734 if ( data.length() > 0 ) {
735 data = data.replaceAll( " ", "_" );
737 writer.write( data );
740 writer.write( ForesterUtil.LINE_SEPARATOR );
741 writer.write( NexusConstants.END );
742 writer.write( ForesterUtil.LINE_SEPARATOR );
745 public static void writeNexusTreesBlock( final Writer writer, final List<Phylogeny> trees ) throws IOException {
746 writer.write( NexusConstants.BEGIN_TREES );
747 writer.write( ForesterUtil.LINE_SEPARATOR );
749 for( final Phylogeny phylogeny : trees ) {
751 writer.write( NexusConstants.TREE );
753 if ( !ForesterUtil.isEmpty( phylogeny.getName() ) ) {
754 writer.write( "\'" );
755 writer.write( phylogeny.getName() );
756 writer.write( "\'" );
759 writer.write( "tree" );
760 writer.write( String.valueOf( i ) );
763 if ( phylogeny.isRooted() ) {
764 writer.write( "[&R]" );
767 writer.write( "[&U]" );
769 writer.write( phylogeny.toNewHampshire( false ) );
770 writer.write( ForesterUtil.LINE_SEPARATOR );
773 writer.write( NexusConstants.END );
774 writer.write( ForesterUtil.LINE_SEPARATOR );
777 private static void writePhyloXmlEnd( final Writer writer ) throws IOException {
778 writer.write( ForesterUtil.LINE_SEPARATOR );
779 writer.write( PhylogenyWriter.PHYLO_XML_END );
782 private static void writePhyloXmlStart( final Writer writer ) throws IOException {
783 writer.write( PhylogenyWriter.PHYLO_XML_VERSION_ENCODING_LINE );
784 writer.write( ForesterUtil.LINE_SEPARATOR );
785 writer.write( PhylogenyWriter.PHYLO_XML_NAMESPACE_LINE );
786 writer.write( ForesterUtil.LINE_SEPARATOR );
789 public static enum FORMAT {
790 NH, NHX, PHYLO_XML, NEXUS;