1 # -*-Perl-*- Test Harness script for Bioperl
10 test_begin(-tests => 97,
11 -requires_modules => [qw(XML::LibXML XML::LibXML::Reader)],
14 plan skip_all => "Reader interface only supported in Perl >= 5.8";
16 } elsif (XML::LibXML::LIBXML_VERSION() <= 20620) {
17 plan skip_all => "Reader not supported for libxml2 <= 2.6.20";
20 use_ok('Bio::TreeIO');
21 use_ok('Bio::TreeIO::phyloxml');
22 diag("libxml version: ", XML::LibXML::LIBXML_VERSION());
25 my $verbose = test_debug();
27 ok my $treeio = Bio::TreeIO->new(
29 -format => 'phyloxml',
30 -file => test_input_file('phyloxml_examples.xml'));
32 # tree1: clade and attribute
33 # <phylogeny> <clade> <name>
36 diag("\ntree1: clade and attribute");
38 my $tree = $treeio->next_tree;
39 isa_ok($tree, 'Bio::Tree::TreeI');
40 is($tree->id, 'example from Prof. Joe Felsenstein\'s book "Inferring Phylogenies"');
41 is($tree->get_tag_values('description'), 'phyloXML allows to use either a "branch_length" attribute or element to indicate branch lengths.');
43 diag("tree id: ",$tree->id);
44 diag("tree description: ", $tree->get_tag_values('description'));
46 is($tree->get_tag_values('rooted'), 'true');
47 my @nodes = $tree->get_nodes;
49 my ($A) = $tree->find_node('A');
51 is($A->branch_length, '0.102');
53 diag("node A: branch_length ", $A->branch_length);
55 is($A->ancestor->id, '');
56 is($A->ancestor->branch_length, '0.06');
57 my $leaves_string = $tree->simplify_to_leaves_string();
61 is($leaves_string, '((A,B),C)');
65 diag("\ntest write_tree");
67 my $FILE1 = test_output_file();
68 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
69 -format => 'phyloxml',
71 $treeio->write_tree($tree);
78 # tree2: branch_length
82 diag("\ntree2: branch_length");
84 my $tree = $treeio->next_tree;
85 isa_ok($tree, 'Bio::Tree::TreeI');
87 diag("tree id: ",$tree->id);
89 my @nodes = $tree->get_nodes;
91 my $A = $tree->find_node('A');
93 is($A->branch_length, '0.102');
95 diag("node A: branch_length ", $A->branch_length);
97 is($A->ancestor->id, '');
98 is($A->ancestor->branch_length, '0.06');
99 my $leaves_string = $tree->simplify_to_leaves_string();
101 diag($leaves_string);
103 is($leaves_string, '((A,B),C)');
107 diag("\ntest write_tree");
109 my $FILE1 = test_output_file();
110 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
111 -format => 'phyloxml',
113 $treeio->write_tree($tree);
120 # tree3: confidence (bootstrap)
124 diag("\ntree3: confidence (bootstrap)");
126 my $tree = $treeio->next_tree;
127 isa_ok($tree, 'Bio::Tree::TreeI');
129 diag("tree id: ",$tree->id);
131 my $AB = $tree->find_node('AB');
133 is($AB->bootstrap, '89');
135 diag("node AB: bootstrap ", $AB->bootstrap);
137 my $leaves_string = $tree->simplify_to_leaves_string();
139 diag($leaves_string);
141 is($leaves_string, '((A,B),C)');
145 diag("\ntest write_tree");
147 my $FILE1 = test_output_file();
148 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
149 -format => 'phyloxml',
151 $treeio->write_tree($tree);
158 # tree4: species and sequence
159 # <taxonomy> <scientific_name> <sequence> <annotation>
162 diag("\ntree4: taxonomy and sequence");
164 my $tree = $treeio->next_tree;
165 isa_ok($tree, 'Bio::Tree::TreeI');
167 diag("tree id: ",$tree->id);
169 my $C = $tree->find_node('C');
170 my ($ac) = $C->annotation->get_Annotations('taxonomy');
171 isa_ok( $ac, 'Bio::Annotation::Collection');
172 my ($ac2) = $ac->get_Annotations('scientific_name');
173 isa_ok( $ac2, 'Bio::Annotation::Collection');
174 my ($scientificname) = $ac2->get_Annotations('_text');
175 is($scientificname->value, 'C. elegans');
177 diag( "Node C Scientific Name: ",$scientificname->value);
179 my ($ac3) = $C->annotation->get_nested_Annotations(-keys=>['scientific_name'], -recursive=>1);
180 isa_ok( $ac3, 'Bio::Annotation::Collection');
181 ($scientificname) = $ac2->get_Annotations('_text');
182 is($scientificname->value, 'C. elegans');
184 diag( "Node C Scientific Name: ",$scientificname->value);
186 my ($seq) = @{$C->sequence};
187 isa_ok( $seq, 'Bio::SeqI');
188 my ($seqac) = $seq->annotation;
189 isa_ok( $seqac, 'Bio::Annotation::Collection');
190 my ($descac) = $seqac->get_nested_Annotations(-keys=>['desc'], -recursive=>1);
191 my ($desc) = $descac->get_Annotations('_text');
192 is($desc->value, 'alcohol dehydrogenase');
194 diag( "Node C Sequence description: ",$desc->value);
196 ($descac) = $seqac->get_nested_Annotations(-keys=>['desc'], -recursive=>1);
200 diag("\ntest write_tree");
202 my $FILE1 = test_output_file();
203 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
204 -format => 'phyloxml',
206 $treeio->write_tree($tree);
213 # tree5: homolog relationship and sequence relationship
214 # <events> <speciations> <duplications> <symbol> <accession>
215 # <sequence_relation>
218 diag("\ntree5: events and relations");
220 my $tree = $treeio->next_tree;
221 isa_ok($tree, 'Bio::Tree::TreeI');
223 diag("tree id: ",$tree->id);
225 my $node = $tree->get_root_node;
226 my ($speciationsac) = $node->annotation->get_nested_Annotations(-keys=>['speciations'], -recursive=>1);
227 my ($speciationval) = $speciationsac->get_Annotations('_text');
228 is($speciationval->value, '1');
230 diag("root node speciation event: ", $speciationval->value);
232 my @children = ($node);
234 push @children, $_->each_Descendent();
238 push @leaves, $_ if $_->is_Leaf;
240 my ($z) = $leaves[0];
241 my $z_seq = $z->sequence->[0];
242 isa_ok ($z_seq, 'Bio::SeqI');
243 my ($z_id) = $z_seq->annotation->get_nested_Annotations('-keys'=>['id_source'], '-recursive'=>1);
244 my ($z_id_text) = $z_id->value;
245 my @seq_rels = $z_seq->annotation->get_nested_Annotations('-keys'=>['sequence_relation'], '-recursive'=>1);
246 foreach my $rel (@seq_rels) {
247 isa_ok($rel, 'Bio::Annotation::Relation');
248 is ($rel->tagname, 'sequence_relation');
249 my $seqto = $rel->to;
250 isa_ok ($seqto, 'Bio::SeqI');
251 my ($seqto_id) = $seqto->annotation->get_nested_Annotations('-keys'=>['id_source'], '-recursive'=>1);
252 my $seqto_text = $seqto_id->value;
254 diag( "node ", $z_id_text, " has ", $rel->type, " relation to ", $seqto_text);
257 my ($x) = $leaves[1];
262 diag("\ntest write_tree");
264 my $FILE1 = test_output_file();
265 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
266 -format => 'phyloxml',
268 $treeio->write_tree($tree);
275 # tree6: detailed sequence data
276 # <mol_seq> <annotation> <code>
279 diag("\ntree6: detailed sequence annotation");
281 my $tree = $treeio->next_tree;
282 isa_ok($tree, 'Bio::Tree::TreeI');
284 diag("tree id: ",$tree->id);
286 my @children = ($tree->get_root_node);
288 push @children, $_->each_Descendent();
292 push @leaves, $_ if $_->is_Leaf;
294 my ($z) = $leaves[0];
295 my $z_seq = $z->sequence->[0];
296 isa_ok ($z_seq, 'Bio::SeqI');
297 my ($z_seqname) = $z_seq->annotation->get_nested_Annotations('-keys'=>['name'], '-recursive'=>1);
298 my ($z_seqname_text) = $z_seqname->get_Annotations('_text');
299 is ($z_seqname_text->value, 'NADH-dependent butanol dehydrogenase B');
300 my ($z_molseq) = $z_seq->seq;
301 is ($z_molseq, 'MVDFEYSIPTRIFFGKDKINVLGRELKKYGSKVLIVYGGGSIKRNGIYDK');
303 diag("Sequence ", $z_seqname_text->value, " is ", $z_molseq);
305 my ($z_seqname_text2) = $treeio->read_annotation('-obj'=>$z_seq, '-path'=>'name');
306 is ($z_seqname_text->value, $z_seqname_text2);
310 diag("\ntest write_tree");
312 my $FILE1 = test_output_file();
313 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
314 -format => 'phyloxml',
316 $treeio->write_tree($tree);
324 # <clade_relation> @id_source & @id_ref
327 diag("\ntree7: network using id_source/id_ref");
329 my $tree = $treeio->next_tree;
330 isa_ok($tree, 'Bio::Tree::TreeI');
332 diag("tree id: ",$tree->id);
334 my @children = ($tree->get_root_node);
336 push @children, $_->each_Descendent();
340 push @leaves, $_ if $_->is_Leaf;
342 my ($c) = $leaves[0];
343 my ($c_id) = $c->annotation->get_nested_Annotations('-keys'=>['id_source'], '-recursive'=>1);
344 my @clade_rels = $c->annotation->get_nested_Annotations('-keys'=>['clade_relation'], '-recursive'=>1);
345 foreach my $rel (@clade_rels) {
346 isa_ok($rel, 'Bio::Annotation::Relation');
347 is ($rel->tagname, 'clade_relation');
348 my $nodeto = $rel->to;
349 isa_ok ($nodeto, 'Bio::Tree::AnnotatableNode');
350 my ($nodeto_id) = $nodeto->annotation->get_nested_Annotations('-keys'=>['id_source'], '-recursive'=>1);
351 is ($nodeto_id->value, 'b');
352 my ($nodeto_id2) = $treeio->read_annotation('-obj'=>$nodeto, '-path'=>'id_source', '-attr'=>1);
353 is ($nodeto_id->value, $nodeto_id2);
355 diag( "node ", $c_id->value, " has ", $rel->type, " relation to ", $nodeto_id->value);
361 diag("\ntest write_tree");
363 my $FILE1 = test_output_file();
364 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
365 -format => 'phyloxml',
367 $treeio->write_tree($tree);
374 # tree8: property elements
378 diag("\ntree8: property");
380 my $tree = $treeio->next_tree;
381 isa_ok($tree, 'Bio::Tree::TreeI');
383 diag("tree id: ",$tree->id);
385 my ($A) = $tree->find_node('A');
386 isa_ok($A, 'Bio::Tree::AnnotatableNode');
387 my ($ac) = $A->annotation();
388 isa_ok($ac, 'Bio::AnnotationCollectionI');
389 my (@annotations) = $ac->get_Annotations('property');
390 isa_ok( $annotations[0], 'Bio::Annotation::Collection');
391 diag("property:",$annotations[0]);
392 my (@keys) = $annotations[0]->get_all_annotation_keys();
394 my (@value) = $annotations[0]->get_Annotations('_text');
395 is($value[0]->value, ' 1200 ');
397 diag( "Annotation NOAA:depth ",$value[0]->value);
399 my $leaves_string = $tree->simplify_to_leaves_string();
401 diag($leaves_string);
403 is($leaves_string, '((A,B),C)');
407 diag("\ntest write_tree");
409 my $FILE1 = test_output_file();
410 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
411 -format => 'phyloxml',
413 $treeio->write_tree($tree);
420 # tree9: property outside tree topology using id refs
421 # <property> @id_source @id_ref
424 diag("\ntree9: property using id_source/id_ref");
426 my $tree = $treeio->next_tree;
427 isa_ok($tree, 'Bio::Tree::TreeI');
429 diag("tree id: ",$tree->id);
431 my $A = $tree->find_node('A');
432 isa_ok($A, 'Bio::Tree::AnnotatableNode');
433 my $ac = $A->annotation();
434 isa_ok($ac, 'Bio::AnnotationCollectionI');
435 my @annotations = $ac->get_Annotations('property');
436 isa_ok( $annotations[0], 'Bio::Annotation::Collection');
437 my @value = $annotations[0]->get_Annotations('_text');
438 is($value[0]->value, ' 1200 ');
440 diag( "Annotation NOAA:depth ",$value[0]->value);
442 my $leaves_string = $tree->simplify_to_leaves_string();
444 diag($leaves_string);
446 is($leaves_string, '((A,B),C)');
450 diag("\ntest write_tree");
452 my $FILE1 = test_output_file();
453 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
454 -format => 'phyloxml',
456 $treeio->write_tree($tree);
463 # tree10: detailed taxonomy and distribution
464 # <id> <rank> <uri> <common_name> <distribution>
467 diag("\ntree10: taxonomy and distribution");
469 my $tree = $treeio->next_tree;
470 isa_ok($tree, 'Bio::Tree::TreeI');
472 diag("tree id: ",$tree->id);
474 my $node = $tree->get_root_node;
476 my @children = ($node);
478 push @children, $_->each_Descendent();
481 push @leaves, $_ if $_->is_Leaf;
483 my ($A) = $leaves[0];
484 my ($scientificname) = $A->annotation->get_nested_Annotations('-keys'=>['scientific_name'], '-recursive'=>1);
485 my ($scientificname_text) = $scientificname->get_Annotations('_text');
486 my ($commonname) = $A->annotation->get_nested_Annotations('-keys'=>['common_name'], '-recursive'=>1);
487 my ($commonname_text) = $commonname->get_Annotations('_text');
488 my ($rank) = $A->annotation->get_nested_Annotations('-keys'=>['rank'], '-recursive'=>1);
489 my ($rank_text) = $rank->get_Annotations('_text');
491 diag("node rank is ", $rank_text->value);
492 diag("node scientific name is ", $scientificname_text->value);
493 diag("node common name is ", $commonname_text->value);
495 my ($distribution) = $A->annotation->get_nested_Annotations('-keys'=>['distribution'], '-recursive'=>1);
496 my ($desc) = $distribution->get_Annotations('desc');
497 my ($desc_text) = $desc->get_Annotations('_text');
499 diag("node distribution is ", $desc_text->value);
504 diag("\ntest write_tree");
506 my $FILE1 = test_output_file();
507 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
508 -format => 'phyloxml',
510 $treeio->write_tree($tree);
517 # tree11: phylogeographic information
518 # <distribution> <point> <lat> <long> <alt>
521 diag("\ntree11: phylogenographic information");
523 my $tree = $treeio->next_tree;
524 isa_ok($tree, 'Bio::Tree::TreeI');
526 diag("tree id: ",$tree->id);
528 my $node = $tree->get_root_node;
530 my @children = ($node);
532 push @children, $_->each_Descendent();
535 push @leaves, $_ if $_->is_Leaf;
537 my ($D) = $leaves[0];
538 my ($point) = $treeio->read_annotation('-obj'=>$D, '-path'=>'distribution/point/geodetic_datum', '-attr'=>1);
539 is ($point, 'WGS84');
540 my ($lat) = $treeio->read_annotation('-obj'=>$D, '-path'=>'distribution/point/lat');
541 my ($long) = $treeio->read_annotation('-obj'=>$D, '-path'=>'distribution/point/long');
542 my ($alt) = $treeio->read_annotation('-obj'=>$D, '-path'=>'distribution/point/alt');
543 is ($lat, '32.880933');
544 is ($long, '-117.217543');
547 diag("node distribution lat: $lat long $long alt $alt");
553 diag("\ntest write_tree");
555 my $FILE1 = test_output_file();
556 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
557 -format => 'phyloxml',
559 $treeio->write_tree($tree);
566 # tree12: date information
567 # <date> <desc> <value>
570 diag("\ntree12: date");
572 my $tree = $treeio->next_tree;
573 isa_ok($tree, 'Bio::Tree::TreeI');
575 diag("tree id: ",$tree->id);
577 my $node = $tree->get_root_node;
579 my @children = ($node);
581 push @children, $_->each_Descendent();
584 push @leaves, $_ if $_->is_Leaf;
586 my ($D) = $leaves[0];
587 my ($dateunit) = $treeio->read_annotation('-obj'=>$D, '-path'=>'date/unit', '-attr'=>1);
588 my ($daterange) = $treeio->read_annotation('-obj'=>$D, '-path'=>'date/range', '-attr'=>1);
589 my ($datevalue) = $treeio->read_annotation('-obj'=>$D, '-path'=>'date/value');
590 is ($dateunit, 'mya');
591 is ($daterange, '30');
592 is ($datevalue, '600');
594 diag("node date unit: $dateunit range $daterange value $datevalue");
599 diag("\ntest write_tree");
601 my $FILE1 = test_output_file();
602 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
603 -format => 'phyloxml',
605 $treeio->write_tree($tree);
612 # tree13: alignment outside <phylogeny>
613 # <align:alignment> <seq>
616 diag("\ntree13: alignment outside <phylogeny>");
618 my $tree = $treeio->next_tree;
619 isa_ok($tree, 'Bio::Tree::TreeI');
621 diag("tree id: ",$tree->id);
623 my $leaves_string = $tree->simplify_to_leaves_string();
625 diag($leaves_string);
627 is($leaves_string, '((A,B),C)');
629 # add annotation in phyloxml
631 diag("test add annotation in phyloXML format");
633 my $node = $tree->get_root_node;
635 my @children = ($node);
637 push @children, $_->each_Descendent();
640 push @leaves, $_ if $_->is_Leaf;
642 my ($D) = $leaves[0];
643 isa_ok($D, 'Bio::Tree::AnnotatableNode');
644 $treeio->add_phyloXML_annotation(
646 -xml => " <name>D</name>
647 <date unit=\"mya\" range=\"30\">
649 <value>veryveryold</value>
653 my ($dateunit) = $treeio->read_annotation('-obj'=>$D, '-path'=>'date/unit', '-attr'=>1);
654 my ($daterange) = $treeio->read_annotation('-obj'=>$D, '-path'=>'date/range', '-attr'=>1);
655 my ($datevalue) = $treeio->read_annotation('-obj'=>$D, '-path'=>'date/value');
656 is ($dateunit, 'mya');
657 is ($daterange, '30');
658 is ($datevalue, 'veryveryold');
662 diag("\ntest write_tree");
664 my $FILE1 = test_output_file();
665 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
666 -format => 'phyloxml',
668 $treeio->write_tree($tree);
676 # convert between nhx-phyloxml
679 diag("\n test translation between nhx and phyloxml");
681 ok my $nhxio = Bio::TreeIO->new(
682 -verbose => $verbose,
684 -file => test_input_file('test.nhx'));
685 my $tree = $nhxio->next_tree;
686 isa_ok($tree, 'Bio::Tree::TreeI');
687 my $FILE1 = test_output_file();
688 my $phyloxmlio = Bio::TreeIO->new(-verbose => $verbose,
689 -format => 'phyloxml',
691 $phyloxmlio->write_tree($tree);