From 1cda40b42b9d25fc6ccf38953d87447c0af8ec6b Mon Sep 17 00:00:00 2001 From: flouris Date: Wed, 12 Apr 2017 14:02:08 +0200 Subject: [PATCH] pll_utree_newick_export/pll_rtree_newick_export now accepts a callback function for customizing the format of exported newick tree, added an example, minor memleak fix for deallocating the data element on tip nodes - issue #131 --- examples/lg4/lg4.c | 2 +- examples/load-utree/load-utree.c | 2 +- examples/newick-export/Makefile | 44 ++++ examples/newick-export/newick-export.c | 191 ++++++++++++++++++ examples/newick-export/target.mk | 2 + .../newick-fasta-rooted/newick-fasta-rooted.c | 2 +- .../newick-fasta-unrooted.c | 2 +- .../newick-phylip-unrooted.c | 2 +- examples/parsimony/npr-pars.c | 2 +- examples/partial-traversal/partial.c | 2 +- examples/protein-list/protein-list.c | 2 +- examples/stepwise/stepwise.c | 2 +- src/parse_utree.y | 1 + src/pll.h | 6 +- src/rtree.c | 88 ++++++-- src/utree.c | 80 ++++++-- test/src/rooted-tipinner.c | 2 +- test/src/rooted.c | 2 +- 18 files changed, 381 insertions(+), 53 deletions(-) create mode 100644 examples/newick-export/Makefile create mode 100644 examples/newick-export/newick-export.c create mode 100644 examples/newick-export/target.mk diff --git a/examples/lg4/lg4.c b/examples/lg4/lg4.c index d78962c..95fbc1d 100644 --- a/examples/lg4/lg4.c +++ b/examples/lg4/lg4.c @@ -124,7 +124,7 @@ int main(int argc, char * argv[]) pll_utree_show_ascii(tree, PLL_UTREE_SHOW_LABEL | PLL_UTREE_SHOW_BRANCH_LENGTH | PLL_UTREE_SHOW_CLV_INDEX); - char * newick = pll_utree_export_newick(tree); + char * newick = pll_utree_export_newick(tree,NULL); printf("%s\n", newick); free(newick); */ diff --git a/examples/load-utree/load-utree.c b/examples/load-utree/load-utree.c index f9b6323..07f4355 100644 --- a/examples/load-utree/load-utree.c +++ b/examples/load-utree/load-utree.c @@ -77,7 +77,7 @@ int main(int argc, char * argv[]) /* export the tree to newick format with the selected inner node as the root of the unrooted binary tree */ - char * newick = pll_utree_export_newick(root); + char * newick = pll_utree_export_newick(root,NULL); printf("%s\n", newick); diff --git a/examples/newick-export/Makefile b/examples/newick-export/Makefile new file mode 100644 index 0000000..f0d9b03 --- /dev/null +++ b/examples/newick-export/Makefile @@ -0,0 +1,44 @@ +# Copyright (C) 2015 Tomas Flouri +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +# Contact: Tomas Flouri , +# Heidelberg Institute for Theoretical Studies, +# Schloss-Wolfsbrunnenweg 35, D-69118 Heidelberg, Germany + +# Profiling +#PROFILING=-g -pg +PROFILING=-g + +# Compiler warnings +WARN=-Wall -Wsign-compare + +CC = gcc +CFLAGS = -Wall -g -O3 -D_GNU_SOURCE $(WARN) +LINKFLAGS = -L. $(PROFILING) +LIBS=-lpll -lm +PROG=newick-export + +all: $(PROG) + +OBJS=newick-export.o + +$(PROG): $(OBJS) + $(CC) $(LINKFLAGS) -o $@ $+ $(LIBS) $(LDFLAGS) + +%.o: %.c + $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< + +clean: + rm -f *~ $(OBJS) gmon.out $(PROG) diff --git a/examples/newick-export/newick-export.c b/examples/newick-export/newick-export.c new file mode 100644 index 0000000..e151342 --- /dev/null +++ b/examples/newick-export/newick-export.c @@ -0,0 +1,191 @@ +/* + Copyright (C) 2015 Tomas Flouri + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + Contact: Tomas Flouri , + Exelixis Lab, Heidelberg Instutute for Theoretical Studies + Schloss-Wolfsbrunnenweg 35, D-69118 Heidelberg, Germany +*/ + +#include "pll.h" +#include +#include + +static void fatal(const char * format, ...) __attribute__ ((noreturn)); + +static void fatal(const char * format, ...) +{ + va_list argptr; + va_start(argptr, format); + vfprintf(stderr, format, argptr); + va_end(argptr); + fprintf(stderr, "\n"); + exit(EXIT_FAILURE); +} + +typedef struct nodedata_s +{ + double support; + double rvalue; +} nodedata_t; + +/* a callback function that prints the following information for the two types + * of nodes, tips and inners: + + + for tip nodes: + label, branch length and support value + + for inner nodes: + label, branch length, support value, and a random value + + Note that this is not a standard format that can be read by all tree viewers + + Check the extended newick format for a more widespread notation: + http://dmi.uib.es/~gcardona/BioInfo/enewick.html + +*/ +static char * cb_serialize(const pll_unode_t * node) +{ + char * s = NULL; + nodedata_t * nd; + + + /* inner node */ + if (node->next) + { + /* find which node of the round-about has the data element */ + if (node->data) + nd = (nodedata_t *)(node->data); + else if (node->next->data) + nd = (nodedata_t *)(node->next->data); + else + nd = (nodedata_t *)(node->next->next->data); + + asprintf(&s, + "%s[&support=%f,rvalue=%f]:%f", + node->label ? node->label : "", + nd->support, + nd->rvalue, + node->length); + } + else + { + nd = (nodedata_t *)(node->data); + asprintf(&s, + "%s[&support=%f]:%f", + node->label ? node->label : "", + nd->support, + node->length); + } + + return s; +} + +pll_utree_t * load_tree_unrooted(const char * filename) +{ + pll_utree_t * utree; + pll_rtree_t * rtree; + + if (!(rtree = pll_rtree_parse_newick(filename))) + { + if (!(utree = pll_utree_parse_newick(filename))) + { + fprintf(stderr, "%s\n", pll_errmsg); + return NULL; + } + } + else + { + utree = pll_rtree_unroot(rtree); + + pll_unode_t * root = utree->nodes[utree->tip_count+utree->inner_count-1]; + + /* optional step if using default PLL clv/pmatrix index assignments */ + pll_utree_reset_template_indices(root, utree->tip_count); + + pll_rtree_destroy(rtree,NULL); + } + + return utree; +} + +int main(int argc, char * argv[]) +{ + unsigned int i; + + if (argc != 2) + fatal("syntax: %s [newick]", argv[0]); + + /* initialize pseudo-random number generator */ + srandom(time(NULL)); + + /* load tree as unrooted */ + pll_utree_t * utree = load_tree_unrooted(argv[1]); + if (!utree) + fatal("Tree must be a rooted or unrooted binary."); + + /* set random support values for tip nodes */ + for (i = 0; i < utree->tip_count; ++i) + { + pll_unode_t * node = utree->nodes[i]; + nodedata_t * data; + + node->data = malloc(sizeof(nodedata_t)); + + data = (nodedata_t *)(node->data); + + data->support = random() / (double)RAND_MAX; + } + + /* set random support values and a random value to each inner node, but + allocate the structure in only one of the three round-about nodes that make + up an inner node */ + for (i = utree->tip_count; i < utree->tip_count + utree->inner_count; ++i) + { + pll_unode_t * node = utree->nodes[i]; + nodedata_t * data; + + node->data = malloc(sizeof(nodedata_t)); + + data = (nodedata_t *)(node->data); + + data->support = random() / (double)RAND_MAX; + data->rvalue = data->support * random(); + } + + /* select a random inner node */ + long int r = random() % utree->inner_count; + pll_unode_t * root = utree->nodes[utree->tip_count + r]; + + /* export the tree to newick format with the selected inner node as the root + of the unrooted binary tree. + + If we pass NULL as the callback function, then the tree is printed in newick + format with branch lengths only, i.e. + + char * newick = pll_utree_export_newick(root,NULL); + */ + + char * newick = pll_utree_export_newick(root,cb_serialize); + + printf("%s\n", newick); + + free(newick); + + pll_utree_destroy(utree,free); + + return 0; +} diff --git a/examples/newick-export/target.mk b/examples/newick-export/target.mk new file mode 100644 index 0000000..e77819d --- /dev/null +++ b/examples/newick-export/target.mk @@ -0,0 +1,2 @@ +newick_exportdir = $(docdir)/examples/newick-export +dist_newick_export_DATA = newick-export/newick-export.c newick-export/Makefile diff --git a/examples/newick-fasta-rooted/newick-fasta-rooted.c b/examples/newick-fasta-rooted/newick-fasta-rooted.c index 391e389..0c9ef51 100644 --- a/examples/newick-fasta-rooted/newick-fasta-rooted.c +++ b/examples/newick-fasta-rooted/newick-fasta-rooted.c @@ -111,7 +111,7 @@ int main(int argc, char * argv[]) pll_rtree_show_ascii(tree, PLL_UTREE_SHOW_LABEL | PLL_UTREE_SHOW_BRANCH_LENGTH | PLL_UTREE_SHOW_CLV_INDEX); - char * newick = pll_rtree_export_newick(tree); + char * newick = pll_rtree_export_newick(tree,NULL); printf("%s\n", newick); free(newick); diff --git a/examples/newick-fasta-unrooted/newick-fasta-unrooted.c b/examples/newick-fasta-unrooted/newick-fasta-unrooted.c index ac8edb0..046cd9c 100644 --- a/examples/newick-fasta-unrooted/newick-fasta-unrooted.c +++ b/examples/newick-fasta-unrooted/newick-fasta-unrooted.c @@ -129,7 +129,7 @@ int main(int argc, char * argv[]) pll_utree_show_ascii(tree, PLL_UTREE_SHOW_LABEL | PLL_UTREE_SHOW_BRANCH_LENGTH | PLL_UTREE_SHOW_CLV_INDEX); - char * newick = pll_utree_export_newick(tree); + char * newick = pll_utree_export_newick(tree,NULL); printf("%s\n", newick); free(newick); diff --git a/examples/newick-phylip-unrooted/newick-phylip-unrooted.c b/examples/newick-phylip-unrooted/newick-phylip-unrooted.c index 826dfc2..a6b8469 100644 --- a/examples/newick-phylip-unrooted/newick-phylip-unrooted.c +++ b/examples/newick-phylip-unrooted/newick-phylip-unrooted.c @@ -136,7 +136,7 @@ int main(int argc, char * argv[]) pll_utree_show_ascii(tree, PLL_UTREE_SHOW_LABEL | PLL_UTREE_SHOW_BRANCH_LENGTH | PLL_UTREE_SHOW_CLV_INDEX); - char * newick = pll_utree_export_newick(tree); + char * newick = pll_utree_export_newick(tree,NULL); printf("%s\n", newick); free(newick); diff --git a/examples/parsimony/npr-pars.c b/examples/parsimony/npr-pars.c index 3f19ffc..871ffa7 100644 --- a/examples/parsimony/npr-pars.c +++ b/examples/parsimony/npr-pars.c @@ -103,7 +103,7 @@ int main(int argc, char * argv[]) pll_utree_show_ascii(tree, PLL_UTREE_SHOW_LABEL | PLL_UTREE_SHOW_BRANCH_LENGTH | PLL_UTREE_SHOW_CLV_INDEX); - char * newick = pll_utree_export_newick(tree); + char * newick = pll_utree_export_newick(tree,NULL); printf("%s\n", newick); free(newick); diff --git a/examples/partial-traversal/partial.c b/examples/partial-traversal/partial.c index db0ea51..2be4924 100644 --- a/examples/partial-traversal/partial.c +++ b/examples/partial-traversal/partial.c @@ -181,7 +181,7 @@ int main(int argc, char * argv[]) pll_utree_show_ascii(tree, PLL_UTREE_SHOW_LABEL | PLL_UTREE_SHOW_BRANCH_LENGTH | PLL_UTREE_SHOW_CLV_INDEX); - char * newick = pll_utree_export_newick(tree); + char * newick = pll_utree_export_newick(tree,NULL); printf("%s\n", newick); free(newick); diff --git a/examples/protein-list/protein-list.c b/examples/protein-list/protein-list.c index fceadce..89fc116 100644 --- a/examples/protein-list/protein-list.c +++ b/examples/protein-list/protein-list.c @@ -199,7 +199,7 @@ int main(int argc, char * argv[]) pll_utree_show_ascii(tree, PLL_UTREE_SHOW_LABEL | PLL_UTREE_SHOW_BRANCH_LENGTH | PLL_UTREE_SHOW_CLV_INDEX); - char * newick = pll_utree_export_newick(tree); + char * newick = pll_utree_export_newick(tree,NULL); printf("%s\n", newick); free(newick); diff --git a/examples/stepwise/stepwise.c b/examples/stepwise/stepwise.c index 08c2bfd..fb40e5c 100644 --- a/examples/stepwise/stepwise.c +++ b/examples/stepwise/stepwise.c @@ -208,7 +208,7 @@ int main(int argc, char * argv[]) /* export the tree to newick format with the selected inner node as the root of the unrooted binary tree */ - char * newick = pll_utree_export_newick(root); + char * newick = pll_utree_export_newick(root,NULL); printf("%s\n", newick); free(newick); diff --git a/src/parse_utree.y b/src/parse_utree.y index 2ca45f0..c615423 100644 --- a/src/parse_utree.y +++ b/src/parse_utree.y @@ -108,6 +108,7 @@ PLL_EXPORT void pll_utree_destroy(pll_utree_t * tree, /* deallocate tip nodes */ for (i = 0; i < tree->tip_count; ++i) { + dealloc_data(tree->nodes[i], cb_destroy); if (tree->nodes[i]->label) free(tree->nodes[i]->label); free(tree->nodes[i]); diff --git a/src/pll.h b/src/pll.h index 42906c6..007f2aa 100644 --- a/src/pll.h +++ b/src/pll.h @@ -646,7 +646,8 @@ PLL_EXPORT pll_utree_t * pll_utree_wraptree(pll_unode_t * root, PLL_EXPORT void pll_utree_show_ascii(const pll_unode_t * tree, int options); -PLL_EXPORT char * pll_utree_export_newick(const pll_unode_t * root); +PLL_EXPORT char * pll_utree_export_newick(const pll_unode_t * root, + char * (*cb_serialize)(const pll_unode_t *)); PLL_EXPORT int pll_utree_traverse(pll_unode_t * root, int traversal, @@ -697,7 +698,8 @@ PLL_EXPORT void pll_msa_destroy(pll_msa_t * msa); PLL_EXPORT void pll_rtree_show_ascii(const pll_rnode_t * root, int options); -PLL_EXPORT char * pll_rtree_export_newick(const pll_rnode_t * root); +PLL_EXPORT char * pll_rtree_export_newick(const pll_rnode_t * root, + char * (*cb_serialize)(const pll_rnode_t *)); PLL_EXPORT int pll_rtree_traverse(pll_rnode_t * root, int traversal, diff --git a/src/rtree.c b/src/rtree.c index a6c1230..a7e23af 100644 --- a/src/rtree.c +++ b/src/rtree.c @@ -124,34 +124,58 @@ PLL_EXPORT void pll_rtree_show_ascii(const pll_rnode_t * root, int options) free(active_node_order); } -static char * rtree_export_newick_recursive(const pll_rnode_t * root) +static char * rtree_export_newick_recursive(const pll_rnode_t * root, + char * (*cb_serialize)(const pll_rnode_t *)) { char * newick; int size_alloced; assert(root != NULL); if (!(root->left) || !(root->right)) - size_alloced = asprintf(&newick, "%s:%f", root->label, root->length); + { + if (cb_serialize) + { + newick = cb_serialize(root); + size_alloced = strlen(newick); + } + else + { + size_alloced = asprintf(&newick, "%s:%f", root->label, root->length); + } + } else { - char * subtree1 = rtree_export_newick_recursive(root->left); + char * subtree1 = rtree_export_newick_recursive(root->left,cb_serialize); if (subtree1 == NULL) { return NULL; } - char * subtree2 = rtree_export_newick_recursive(root->right); + char * subtree2 = rtree_export_newick_recursive(root->right,cb_serialize); if (subtree2 == NULL) { free(subtree1); return NULL; } - size_alloced = asprintf(&newick, - "(%s,%s)%s:%f", - subtree1, - subtree2, - root->label ? root->label : "", - root->length); + if (cb_serialize) + { + char * temp = cb_serialize(root); + size_alloced = asprintf(&newick, + "(%s,%s)%s", + subtree1, + subtree2, + temp); + free(temp); + } + else + { + size_alloced = asprintf(&newick, + "(%s,%s)%s:%f", + subtree1, + subtree2, + root->label ? root->label : "", + root->length); + } free(subtree1); free(subtree2); } @@ -165,24 +189,35 @@ static char * rtree_export_newick_recursive(const pll_rnode_t * root) return newick; } -PLL_EXPORT char * pll_rtree_export_newick(const pll_rnode_t * root) +PLL_EXPORT char * pll_rtree_export_newick(const pll_rnode_t * root, + char * (*cb_serialize)(const pll_rnode_t *)) { char * newick; int size_alloced; if (!root) return NULL; if (!(root->left) || !(root->right)) - size_alloced = asprintf(&newick, "%s:%f", root->label, root->length); + { + if (cb_serialize) + { + newick = cb_serialize(root); + size_alloced = strlen(newick); + } + else + { + size_alloced = asprintf(&newick, "%s:%f", root->label, root->length); + } + } else { - char * subtree1 = rtree_export_newick_recursive(root->left); + char * subtree1 = rtree_export_newick_recursive(root->left,cb_serialize); if (subtree1 == NULL) { pll_errno = PLL_ERROR_MEM_ALLOC; snprintf(pll_errmsg, 200, "Unable to allocate enough memory."); return NULL; } - char * subtree2 = rtree_export_newick_recursive(root->right); + char * subtree2 = rtree_export_newick_recursive(root->right,cb_serialize); if (subtree2 == NULL) { free(subtree1); @@ -191,12 +226,25 @@ PLL_EXPORT char * pll_rtree_export_newick(const pll_rnode_t * root) return NULL; } - size_alloced = asprintf(&newick, - "(%s,%s)%s:%f;", - subtree1, - subtree2, - root->label ? root->label : "", - root->length); + if (cb_serialize) + { + char * temp = cb_serialize(root); + size_alloced = asprintf(&newick, + "(%s,%s)%s", + subtree1, + subtree2, + temp); + free(temp); + } + else + { + size_alloced = asprintf(&newick, + "(%s,%s)%s:%f;", + subtree1, + subtree2, + root->label ? root->label : "", + root->length); + } free(subtree1); free(subtree2); } diff --git a/src/utree.c b/src/utree.c index 74f72f4..ca002cf 100644 --- a/src/utree.c +++ b/src/utree.c @@ -146,23 +146,34 @@ PLL_EXPORT void pll_utree_show_ascii(const pll_unode_t * root, int options) free(active_node_order); } -static char * newick_utree_recurse(const pll_unode_t * root) +static char * newick_utree_recurse(const pll_unode_t * root, + char * (*cb_serialize)(const pll_unode_t *)) { char * newick; int size_alloced; assert(root != NULL); if (!root->next) - size_alloced = asprintf(&newick, "%s:%f", root->label, root->length); + { + if (cb_serialize) + { + newick = cb_serialize(root); + size_alloced = strlen(newick); + } + else + { + size_alloced = asprintf(&newick, "%s:%f", root->label, root->length); + } + } else { - char * subtree1 = newick_utree_recurse(root->next->back); + char * subtree1 = newick_utree_recurse(root->next->back,cb_serialize); if (subtree1 == NULL) { pll_errno = PLL_ERROR_MEM_ALLOC; snprintf(pll_errmsg, 200, "Unable to allocate enough memory."); return NULL; } - char * subtree2 = newick_utree_recurse(root->next->next->back); + char * subtree2 = newick_utree_recurse(root->next->next->back,cb_serialize); if (subtree2 == NULL) { free(subtree1); @@ -170,12 +181,26 @@ static char * newick_utree_recurse(const pll_unode_t * root) snprintf(pll_errmsg, 200, "Unable to allocate enough memory."); return NULL; } - size_alloced = asprintf(&newick, - "(%s,%s)%s:%f", - subtree1, - subtree2, - root->label ? root->label : "", - root->length); + + if (cb_serialize) + { + char * temp = cb_serialize(root); + size_alloced = asprintf(&newick, + "(%s,%s)%s", + subtree1, + subtree2, + temp); + free(temp); + } + else + { + size_alloced = asprintf(&newick, + "(%s,%s)%s:%f", + subtree1, + subtree2, + root->label ? root->label : "", + root->length); + } free(subtree1); free(subtree2); } @@ -189,7 +214,8 @@ static char * newick_utree_recurse(const pll_unode_t * root) return newick; } -PLL_EXPORT char * pll_utree_export_newick(const pll_unode_t * root) +PLL_EXPORT char * pll_utree_export_newick(const pll_unode_t * root, + char * (*cb_serialize)(const pll_unode_t *)) { char * newick; int size_alloced; @@ -197,14 +223,14 @@ PLL_EXPORT char * pll_utree_export_newick(const pll_unode_t * root) if (!root->next) root=root->back; - char * subtree1 = newick_utree_recurse(root->back); + char * subtree1 = newick_utree_recurse(root->back,cb_serialize); if (subtree1 == NULL) { pll_errno = PLL_ERROR_MEM_ALLOC; snprintf(pll_errmsg, 200, "Unable to allocate enough memory."); return NULL; } - char * subtree2 = newick_utree_recurse(root->next->back); + char * subtree2 = newick_utree_recurse(root->next->back,cb_serialize); if (subtree2 == NULL) { free(subtree1); @@ -212,7 +238,7 @@ PLL_EXPORT char * pll_utree_export_newick(const pll_unode_t * root) snprintf(pll_errmsg, 200, "Unable to allocate enough memory."); return NULL; } - char * subtree3 = newick_utree_recurse(root->next->next->back); + char * subtree3 = newick_utree_recurse(root->next->next->back,cb_serialize); if (subtree3 == NULL) { free(subtree1); @@ -222,12 +248,26 @@ PLL_EXPORT char * pll_utree_export_newick(const pll_unode_t * root) return NULL; } - size_alloced = asprintf(&newick, - "(%s,%s,%s)%s:0.0;", - subtree1, - subtree2, - subtree3, - root->label ? root->label : ""); + if (cb_serialize) + { + char * temp = cb_serialize(root); + size_alloced = asprintf(&newick, + "(%s,%s,%s)%s", + subtree1, + subtree2, + subtree3, + temp); + free(temp); + } + else + { + size_alloced = asprintf(&newick, + "(%s,%s,%s)%s:0.0;", + subtree1, + subtree2, + subtree3, + root->label ? root->label : ""); + } free(subtree1); free(subtree2); free(subtree3); diff --git a/test/src/rooted-tipinner.c b/test/src/rooted-tipinner.c index 993d39f..1fea51d 100644 --- a/test/src/rooted-tipinner.c +++ b/test/src/rooted-tipinner.c @@ -56,7 +56,7 @@ int main(int argc, char * argv[]) PLL_UTREE_SHOW_LABEL | PLL_UTREE_SHOW_BRANCH_LENGTH | PLL_UTREE_SHOW_CLV_INDEX); - char * newick = pll_rtree_export_newick(tree->root); + char * newick = pll_rtree_export_newick(tree->root,NULL); printf("%s\n", newick); free(newick); diff --git a/test/src/rooted.c b/test/src/rooted.c index 91792bb..630241e 100644 --- a/test/src/rooted.c +++ b/test/src/rooted.c @@ -57,7 +57,7 @@ int main(int argc, char * argv[]) PLL_UTREE_SHOW_LABEL | PLL_UTREE_SHOW_BRANCH_LENGTH | PLL_UTREE_SHOW_CLV_INDEX); - char * newick = pll_rtree_export_newick(tree->root); + char * newick = pll_rtree_export_newick(tree->root,NULL); printf("%s\n", newick); free(newick);