1 # -*-Perl-*- Test Harness script for Bioperl
10 test_begin(-tests => 97,
11 -requires_modules => [qw(XML::LibXML XML::LibXML::Reader)]);
13 use_ok('Bio::TreeIO');
16 my $verbose = test_debug();
20 skip("Reader interface only supported in Perl >= 5.8",96);
21 } elsif (XML::LibXML::LIBXML_VERSION() <= 20620) {
22 skip("Reader not supported for libxml2 <= 2.6.20",96);
24 use_ok('Bio::TreeIO::phyloxml');
27 diag("libxml version: ", XML::LibXML::LIBXML_VERSION());
30 ok my $treeio = Bio::TreeIO->new(
32 -format => 'phyloxml',
33 -file => test_input_file('phyloxml_examples.xml'));
35 # tree1: clade and attribute
36 # <phylogeny> <clade> <name>
39 diag("\ntree1: clade and attribute");
41 my $tree = $treeio->next_tree;
42 isa_ok($tree, 'Bio::Tree::TreeI');
43 is($tree->id, 'example from Prof. Joe Felsenstein\'s book "Inferring Phylogenies"');
44 is($tree->get_tag_values('description'), 'phyloXML allows to use either a "branch_length" attribute or element to indicate branch lengths.');
46 diag("tree id: ",$tree->id);
47 diag("tree description: ", $tree->get_tag_values('description'));
49 is($tree->get_tag_values('rooted'), 'true');
50 my @nodes = $tree->get_nodes;
52 my ($A) = $tree->find_node('A');
54 is($A->branch_length, '0.102');
56 diag("node A: branch_length ", $A->branch_length);
58 is($A->ancestor->id, '');
59 is($A->ancestor->branch_length, '0.06');
60 my $leaves_string = $tree->simplify_to_leaves_string();
64 is($leaves_string, '((A,B),C)');
68 diag("\ntest write_tree");
70 my $FILE1 = test_output_file();
71 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
72 -format => 'phyloxml',
74 $treeio->write_tree($tree);
81 # tree2: branch_length
85 diag("\ntree2: branch_length");
87 my $tree = $treeio->next_tree;
88 isa_ok($tree, 'Bio::Tree::TreeI');
90 diag("tree id: ",$tree->id);
92 my @nodes = $tree->get_nodes;
94 my $A = $tree->find_node('A');
96 is($A->branch_length, '0.102');
98 diag("node A: branch_length ", $A->branch_length);
100 is($A->ancestor->id, '');
101 is($A->ancestor->branch_length, '0.06');
102 my $leaves_string = $tree->simplify_to_leaves_string();
104 diag($leaves_string);
106 is($leaves_string, '((A,B),C)');
110 diag("\ntest write_tree");
112 my $FILE1 = test_output_file();
113 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
114 -format => 'phyloxml',
116 $treeio->write_tree($tree);
123 # tree3: confidence (bootstrap)
127 diag("\ntree3: confidence (bootstrap)");
129 my $tree = $treeio->next_tree;
130 isa_ok($tree, 'Bio::Tree::TreeI');
132 diag("tree id: ",$tree->id);
134 my $AB = $tree->find_node('AB');
136 is($AB->bootstrap, '89');
138 diag("node AB: bootstrap ", $AB->bootstrap);
140 my $leaves_string = $tree->simplify_to_leaves_string();
142 diag($leaves_string);
144 is($leaves_string, '((A,B),C)');
148 diag("\ntest write_tree");
150 my $FILE1 = test_output_file();
151 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
152 -format => 'phyloxml',
154 $treeio->write_tree($tree);
161 # tree4: species and sequence
162 # <taxonomy> <scientific_name> <sequence> <annotation>
165 diag("\ntree4: taxonomy and sequence");
167 my $tree = $treeio->next_tree;
168 isa_ok($tree, 'Bio::Tree::TreeI');
170 diag("tree id: ",$tree->id);
172 my $C = $tree->find_node('C');
173 my ($ac) = $C->annotation->get_Annotations('taxonomy');
174 isa_ok( $ac, 'Bio::Annotation::Collection');
175 my ($ac2) = $ac->get_Annotations('scientific_name');
176 isa_ok( $ac2, 'Bio::Annotation::Collection');
177 my ($scientificname) = $ac2->get_Annotations('_text');
178 is($scientificname->value, 'C. elegans');
180 diag( "Node C Scientific Name: ",$scientificname->value);
182 my ($ac3) = $C->annotation->get_nested_Annotations(-keys=>['scientific_name'], -recursive=>1);
183 isa_ok( $ac3, 'Bio::Annotation::Collection');
184 ($scientificname) = $ac2->get_Annotations('_text');
185 is($scientificname->value, 'C. elegans');
187 diag( "Node C Scientific Name: ",$scientificname->value);
189 my ($seq) = @{$C->sequence};
190 isa_ok( $seq, 'Bio::SeqI');
191 my ($seqac) = $seq->annotation;
192 isa_ok( $seqac, 'Bio::Annotation::Collection');
193 my ($descac) = $seqac->get_nested_Annotations(-keys=>['desc'], -recursive=>1);
194 my ($desc) = $descac->get_Annotations('_text');
195 is($desc->value, 'alcohol dehydrogenase');
197 diag( "Node C Sequence description: ",$desc->value);
199 ($descac) = $seqac->get_nested_Annotations(-keys=>['desc'], -recursive=>1);
203 diag("\ntest write_tree");
205 my $FILE1 = test_output_file();
206 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
207 -format => 'phyloxml',
209 $treeio->write_tree($tree);
216 # tree5: homolog relationship and sequence relationship
217 # <events> <speciations> <duplications> <symbol> <accession>
218 # <sequence_relation>
221 diag("\ntree5: events and relations");
223 my $tree = $treeio->next_tree;
224 isa_ok($tree, 'Bio::Tree::TreeI');
226 diag("tree id: ",$tree->id);
228 my $node = $tree->get_root_node;
229 my ($speciationsac) = $node->annotation->get_nested_Annotations(-keys=>['speciations'], -recursive=>1);
230 my ($speciationval) = $speciationsac->get_Annotations('_text');
231 is($speciationval->value, '1');
233 diag("root node speciation event: ", $speciationval->value);
235 my @children = ($node);
237 push @children, $_->each_Descendent();
241 push @leaves, $_ if $_->is_Leaf;
243 my ($z) = $leaves[0];
244 my $z_seq = $z->sequence->[0];
245 isa_ok ($z_seq, 'Bio::SeqI');
246 my ($z_id) = $z_seq->annotation->get_nested_Annotations('-keys'=>['id_source'], '-recursive'=>1);
247 my ($z_id_text) = $z_id->value;
248 my @seq_rels = $z_seq->annotation->get_nested_Annotations('-keys'=>['sequence_relation'], '-recursive'=>1);
249 foreach my $rel (@seq_rels) {
250 isa_ok($rel, 'Bio::Annotation::Relation');
251 is ($rel->tagname, 'sequence_relation');
252 my $seqto = $rel->to;
253 isa_ok ($seqto, 'Bio::SeqI');
254 my ($seqto_id) = $seqto->annotation->get_nested_Annotations('-keys'=>['id_source'], '-recursive'=>1);
255 my $seqto_text = $seqto_id->value;
257 diag( "node ", $z_id_text, " has ", $rel->type, " relation to ", $seqto_text);
260 my ($x) = $leaves[1];
265 diag("\ntest write_tree");
267 my $FILE1 = test_output_file();
268 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
269 -format => 'phyloxml',
271 $treeio->write_tree($tree);
278 # tree6: detailed sequence data
279 # <mol_seq> <annotation> <code>
282 diag("\ntree6: detailed sequence annotation");
284 my $tree = $treeio->next_tree;
285 isa_ok($tree, 'Bio::Tree::TreeI');
287 diag("tree id: ",$tree->id);
289 my @children = ($tree->get_root_node);
291 push @children, $_->each_Descendent();
295 push @leaves, $_ if $_->is_Leaf;
297 my ($z) = $leaves[0];
298 my $z_seq = $z->sequence->[0];
299 isa_ok ($z_seq, 'Bio::SeqI');
300 my ($z_seqname) = $z_seq->annotation->get_nested_Annotations('-keys'=>['name'], '-recursive'=>1);
301 my ($z_seqname_text) = $z_seqname->get_Annotations('_text');
302 is ($z_seqname_text->value, 'NADH-dependent butanol dehydrogenase B');
303 my ($z_molseq) = $z_seq->seq;
304 is ($z_molseq, 'MVDFEYSIPTRIFFGKDKINVLGRELKKYGSKVLIVYGGGSIKRNGIYDK');
306 diag("Sequence ", $z_seqname_text->value, " is ", $z_molseq);
308 my ($z_seqname_text2) = $treeio->read_annotation('-obj'=>$z_seq, '-path'=>'name');
309 is ($z_seqname_text->value, $z_seqname_text2);
313 diag("\ntest write_tree");
315 my $FILE1 = test_output_file();
316 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
317 -format => 'phyloxml',
319 $treeio->write_tree($tree);
327 # <clade_relation> @id_source & @id_ref
330 diag("\ntree7: network using id_source/id_ref");
332 my $tree = $treeio->next_tree;
333 isa_ok($tree, 'Bio::Tree::TreeI');
335 diag("tree id: ",$tree->id);
337 my @children = ($tree->get_root_node);
339 push @children, $_->each_Descendent();
343 push @leaves, $_ if $_->is_Leaf;
345 my ($c) = $leaves[0];
346 my ($c_id) = $c->annotation->get_nested_Annotations('-keys'=>['id_source'], '-recursive'=>1);
347 my @clade_rels = $c->annotation->get_nested_Annotations('-keys'=>['clade_relation'], '-recursive'=>1);
348 foreach my $rel (@clade_rels) {
349 isa_ok($rel, 'Bio::Annotation::Relation');
350 is ($rel->tagname, 'clade_relation');
351 my $nodeto = $rel->to;
352 isa_ok ($nodeto, 'Bio::Tree::AnnotatableNode');
353 my ($nodeto_id) = $nodeto->annotation->get_nested_Annotations('-keys'=>['id_source'], '-recursive'=>1);
354 is ($nodeto_id->value, 'b');
355 my ($nodeto_id2) = $treeio->read_annotation('-obj'=>$nodeto, '-path'=>'id_source', '-attr'=>1);
356 is ($nodeto_id->value, $nodeto_id2);
358 diag( "node ", $c_id->value, " has ", $rel->type, " relation to ", $nodeto_id->value);
364 diag("\ntest write_tree");
366 my $FILE1 = test_output_file();
367 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
368 -format => 'phyloxml',
370 $treeio->write_tree($tree);
377 # tree8: property elements
381 diag("\ntree8: property");
383 my $tree = $treeio->next_tree;
384 isa_ok($tree, 'Bio::Tree::TreeI');
386 diag("tree id: ",$tree->id);
388 my ($A) = $tree->find_node('A');
389 isa_ok($A, 'Bio::Tree::AnnotatableNode');
390 my ($ac) = $A->annotation();
391 isa_ok($ac, 'Bio::AnnotationCollectionI');
392 my (@annotations) = $ac->get_Annotations('property');
393 isa_ok( $annotations[0], 'Bio::Annotation::Collection');
394 diag("property:",$annotations[0]) if $verbose;
395 my (@keys) = $annotations[0]->get_all_annotation_keys();
396 diag("keys:",@keys) if $verbose;
397 my (@value) = $annotations[0]->get_Annotations('_text');
398 is($value[0]->value, ' 1200 ');
400 diag( "Annotation NOAA:depth ",$value[0]->value);
402 my $leaves_string = $tree->simplify_to_leaves_string();
404 diag($leaves_string);
406 is($leaves_string, '((A,B),C)');
410 diag("\ntest write_tree");
412 my $FILE1 = test_output_file();
413 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
414 -format => 'phyloxml',
416 $treeio->write_tree($tree);
423 # tree9: property outside tree topology using id refs
424 # <property> @id_source @id_ref
427 diag("\ntree9: property using id_source/id_ref");
429 my $tree = $treeio->next_tree;
430 isa_ok($tree, 'Bio::Tree::TreeI');
432 diag("tree id: ",$tree->id);
434 my $A = $tree->find_node('A');
435 isa_ok($A, 'Bio::Tree::AnnotatableNode');
436 my $ac = $A->annotation();
437 isa_ok($ac, 'Bio::AnnotationCollectionI');
438 my @annotations = $ac->get_Annotations('property');
439 isa_ok( $annotations[0], 'Bio::Annotation::Collection');
440 my @value = $annotations[0]->get_Annotations('_text');
441 is($value[0]->value, ' 1200 ');
443 diag( "Annotation NOAA:depth ",$value[0]->value);
445 my $leaves_string = $tree->simplify_to_leaves_string();
447 diag($leaves_string);
449 is($leaves_string, '((A,B),C)');
453 diag("\ntest write_tree");
455 my $FILE1 = test_output_file();
456 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
457 -format => 'phyloxml',
459 $treeio->write_tree($tree);
466 # tree10: detailed taxonomy and distribution
467 # <id> <rank> <uri> <common_name> <distribution>
470 diag("\ntree10: taxonomy and distribution");
472 my $tree = $treeio->next_tree;
473 isa_ok($tree, 'Bio::Tree::TreeI');
475 diag("tree id: ",$tree->id);
477 my $node = $tree->get_root_node;
479 my @children = ($node);
481 push @children, $_->each_Descendent();
484 push @leaves, $_ if $_->is_Leaf;
486 my ($A) = $leaves[0];
487 my ($scientificname) = $A->annotation->get_nested_Annotations('-keys'=>['scientific_name'], '-recursive'=>1);
488 my ($scientificname_text) = $scientificname->get_Annotations('_text');
489 my ($commonname) = $A->annotation->get_nested_Annotations('-keys'=>['common_name'], '-recursive'=>1);
490 my ($commonname_text) = $commonname->get_Annotations('_text');
491 my ($rank) = $A->annotation->get_nested_Annotations('-keys'=>['rank'], '-recursive'=>1);
492 my ($rank_text) = $rank->get_Annotations('_text');
494 diag("node rank is ", $rank_text->value);
495 diag("node scientific name is ", $scientificname_text->value);
496 diag("node common name is ", $commonname_text->value);
498 my ($distribution) = $A->annotation->get_nested_Annotations('-keys'=>['distribution'], '-recursive'=>1);
499 my ($desc) = $distribution->get_Annotations('desc');
500 my ($desc_text) = $desc->get_Annotations('_text');
502 diag("node distribution is ", $desc_text->value);
507 diag("\ntest write_tree");
509 my $FILE1 = test_output_file();
510 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
511 -format => 'phyloxml',
513 $treeio->write_tree($tree);
520 # tree11: phylogeographic information
521 # <distribution> <point> <lat> <long> <alt>
524 diag("\ntree11: phylogenographic information");
526 my $tree = $treeio->next_tree;
527 isa_ok($tree, 'Bio::Tree::TreeI');
529 diag("tree id: ",$tree->id);
531 my $node = $tree->get_root_node;
533 my @children = ($node);
535 push @children, $_->each_Descendent();
538 push @leaves, $_ if $_->is_Leaf;
540 my ($D) = $leaves[0];
541 my ($point) = $treeio->read_annotation('-obj'=>$D, '-path'=>'distribution/point/geodetic_datum', '-attr'=>1);
542 is ($point, 'WGS84');
543 my ($lat) = $treeio->read_annotation('-obj'=>$D, '-path'=>'distribution/point/lat');
544 my ($long) = $treeio->read_annotation('-obj'=>$D, '-path'=>'distribution/point/long');
545 my ($alt) = $treeio->read_annotation('-obj'=>$D, '-path'=>'distribution/point/alt');
546 is ($lat, '32.880933');
547 is ($long, '-117.217543');
550 diag("node distribution lat: $lat long $long alt $alt");
556 diag("\ntest write_tree");
558 my $FILE1 = test_output_file();
559 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
560 -format => 'phyloxml',
562 $treeio->write_tree($tree);
569 # tree12: date information
570 # <date> <desc> <value>
573 diag("\ntree12: date");
575 my $tree = $treeio->next_tree;
576 isa_ok($tree, 'Bio::Tree::TreeI');
578 diag("tree id: ",$tree->id);
580 my $node = $tree->get_root_node;
582 my @children = ($node);
584 push @children, $_->each_Descendent();
587 push @leaves, $_ if $_->is_Leaf;
589 my ($D) = $leaves[0];
590 my ($dateunit) = $treeio->read_annotation('-obj'=>$D, '-path'=>'date/unit', '-attr'=>1);
591 my ($daterange) = $treeio->read_annotation('-obj'=>$D, '-path'=>'date/range', '-attr'=>1);
592 my ($datevalue) = $treeio->read_annotation('-obj'=>$D, '-path'=>'date/value');
593 is ($dateunit, 'mya');
594 is ($daterange, '30');
595 is ($datevalue, '600');
597 diag("node date unit: $dateunit range $daterange value $datevalue");
602 diag("\ntest write_tree");
604 my $FILE1 = test_output_file();
605 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
606 -format => 'phyloxml',
608 $treeio->write_tree($tree);
615 # tree13: alignment outside <phylogeny>
616 # <align:alignment> <seq>
619 diag("\ntree13: alignment outside <phylogeny>");
621 my $tree = $treeio->next_tree;
622 isa_ok($tree, 'Bio::Tree::TreeI');
624 diag("tree id: ",$tree->id);
626 my $leaves_string = $tree->simplify_to_leaves_string();
628 diag($leaves_string);
630 is($leaves_string, '((A,B),C)');
632 # add annotation in phyloxml
634 diag("test add annotation in phyloXML format");
636 my $node = $tree->get_root_node;
638 my @children = ($node);
640 push @children, $_->each_Descendent();
643 push @leaves, $_ if $_->is_Leaf;
645 my ($D) = $leaves[0];
646 isa_ok($D, 'Bio::Tree::AnnotatableNode');
647 $treeio->add_phyloXML_annotation(
649 -xml => " <name>D</name>
650 <date unit=\"mya\" range=\"30\">
652 <value>veryveryold</value>
656 my ($dateunit) = $treeio->read_annotation('-obj'=>$D, '-path'=>'date/unit', '-attr'=>1);
657 my ($daterange) = $treeio->read_annotation('-obj'=>$D, '-path'=>'date/range', '-attr'=>1);
658 my ($datevalue) = $treeio->read_annotation('-obj'=>$D, '-path'=>'date/value');
659 is ($dateunit, 'mya');
660 is ($daterange, '30');
661 is ($datevalue, 'veryveryold');
665 diag("\ntest write_tree");
667 my $FILE1 = test_output_file();
668 my $treeio = Bio::TreeIO->new(-verbose => $verbose,
669 -format => 'phyloxml',
671 $treeio->write_tree($tree);
679 # convert between nhx-phyloxml
682 diag("\n test translation between nhx and phyloxml");
684 ok my $nhxio = Bio::TreeIO->new(
685 -verbose => $verbose,
687 -file => test_input_file('test.nhx'));
688 my $tree = $nhxio->next_tree;
689 isa_ok($tree, 'Bio::Tree::TreeI');
690 my $FILE1 = test_output_file();
691 my $phyloxmlio = Bio::TreeIO->new(-verbose => $verbose,
692 -format => 'phyloxml',
694 $phyloxmlio->write_tree($tree);