use Graph;
use Graph::Reader::Dot;
use IPC::Run qw/ run binary /;
-@EXPORT_OK = qw/ make_character_matrix character_input phylip_pars
- parse_newick newick_to_svg /;
+use Text::Tradition::Error;
+@EXPORT_OK = qw/ character_input phylip_pars parse_newick newick_to_svg /;
-sub make_character_matrix {
+=head1 NAME
+
+Text::Tradition::StemmaUtil - standalone utilities for distance tree calculations
+
+=head1 DESCRIPTION
+
+This package contains a set of utilities for running phylogenetic analysis on
+text collations.
+
+=head1 SUBROUTINES
+
+=head2 character_input( $alignment_table )
+
+Returns a character matrix string suitable for Phylip programs, which
+corresponds to the given alignment table. See Text::Tradition::Collation
+for a description of the alignment table format.
+
+=cut
+
+sub character_input {
+ my $table = shift;
+ my $character_matrix = _make_character_matrix( $table );
+ my $input = '';
+ my $rows = scalar @{$character_matrix};
+ my $columns = scalar @{$character_matrix->[0]} - 1;
+ $input .= "\t$rows\t$columns\n";
+ foreach my $row ( @{$character_matrix} ) {
+ $input .= join( '', @$row ) . "\n";
+ }
+ return $input;
+}
+
+sub _make_character_matrix {
my( $table ) = @_;
# Push the names of the witnesses to initialize the rows of the matrix.
my @matrix = map { [ _normalize_witname( $_->{'witness'} ) ] }
my @pos_readings = map { $_->{'tokens'}->[$token_index] }
@{$table->{'alignment'}};
my @pos_text = map { $_ ? $_->{'t'} : $_ } @pos_readings;
- my @chars = convert_characters( \@pos_text );
+ my @chars = _convert_characters( \@pos_text );
foreach my $idx ( 0 .. $#matrix ) {
push( @{$matrix[$idx]}, $chars[$idx] );
}
return sprintf( "%-10s", $witname );
}
-sub convert_characters {
+sub _convert_characters {
my $row = shift;
# This is a simple algorithm that treats every reading as different.
# Eventually we will want to be able to specify how relationships
return @chars;
}
-sub character_input {
- my $table = shift;
- my $character_matrix = make_character_matrix( $table );
- my $input = '';
- my $rows = scalar @{$character_matrix};
- my $columns = scalar @{$character_matrix->[0]} - 1;
- $input .= "\t$rows\t$columns\n";
- foreach my $row ( @{$character_matrix} ) {
- $input .= join( '', @$row ) . "\n";
- }
- return $input;
-}
+=head2 phylip_pars( $character_matrix )
+
+Runs Phylip Pars on the given character matrix. Returns results in Newick format.
+
+=cut
sub phylip_pars {
my( $charmatrix ) = @_;
# And then we run the program.
my $program = File::Which::which( 'pars' );
unless( -x $program ) {
- return( undef, "Phylip pars not found in path" );
+ throw( "Phylip pars not found in path" );
}
{
@outtree = <TREE>;
close TREE;
}
- return( 1, join( '', @outtree ) ) if @outtree;
+ return join( '', @outtree ) if @outtree;
+ # If we got this far, we are about to throw an error.
my @error;
if( -f "$phylip_dir/outfile" ) {
open( OUTPUT, "$phylip_dir/outfile" ) or die "Could not open output for read";
} else {
push( @error, "Neither outtree nor output file was produced!" );
}
- return( undef, join( '', @error ) );
+ throw( join( '', @error ) );
}
+=head2 parse_newick( $newick_string )
+
+Parses the given Newick tree(s) into one or more undirected Graph objects.
+
+=cut
+
sub parse_newick {
my $newick = shift;
my @trees;
return \@trees;
}
+=head2 newick_to_svg( $newick_string )
+
+Uses the FigTree utility (if installed) to transform the given Newick tree(s)
+into a graph visualization.
+
+=cut
+
sub newick_to_svg {
my $newick = shift;
my $program = File::Which::which( 'figtree' );
unless( -x $program ) {
- warn "FigTree commandline utility not found in path";
- return;
+ throw( "FigTree commandline utility not found in path" );
}
my $svg;
my $nfile = File::Temp->new();
_add_tree_children( $graph, $child, $c->get_children() );
}
}
+
+sub throw {
+ Text::Tradition::Error->throw(
+ 'ident' => 'StemmaUtil error',
+ 'message' => $_[0],
+ );
+}
+
+1;
+
+=head1 LICENSE
+
+This package is free software and is provided "as is" without express
+or implied warranty. You can redistribute it and/or modify it under
+the same terms as Perl itself.
+
+=head1 AUTHOR
+
+Tara L Andrews E<lt>aurum@cpan.orgE<gt>