Bio::NEXUS::SetsBlock - Represents SETS block of a NEXUS file


Bio-NEXUS documentation Contained in the Bio-NEXUS distribution.

Index


Code Index:

NAME

Top

Bio::NEXUS::SetsBlock - Represents SETS block of a NEXUS file

SYNOPSIS

Top

$block_object = new Bio::NEXUS::SetsBlock($block_type, $block, $verbose);

DESCRIPTION

Top

Parses Sets block of NEXUS file and stores Sets data.

FEEDBACK

Top

All feedback (bugs, feature enhancements, etc.) are greatly appreciated.

AUTHORS

Top

 Thomas Hladish (tjhladish at yahoo)

VERSION

Top

$Revision: 1.32 $

METHODS

Top

new

 Title   : new
 Usage   : $block_object = new Bio::NEXUS::SetsBlock($block_type, $commands, $verbose)
 Function: Creates a new Bio::NEXUS::SetsBlock object
 Returns : Bio::NEXUS::SetsBlock object
 Args    : type (string), the commands/comments to parse (array ref), and a verbose flag (0 or 1)

set_taxsets

 Title   : set_taxsets
 Usage   : $block->set_taxsets($taxsets);
 Function: Set the taxsets hash
 Returns : none
 Args    : hash of set name keys and element arrays

add_taxsets

 Title   : add_taxsets
 Usage   : $block->add_taxsets($taxsets);
 Function: add taxa sets
 Returns : none
 Args    : a reference to a hash of taxa sets

get_taxsets

 Title   : get_taxsets
 Usage   : $block->get_taxsets();
 Function: Returns a hash of taxa sets
 Returns : taxa sets
 Args    : none

get_taxset

 Title   : get_taxset
 Usage   : $block->get_taxset($setname);
 Function: Returns a list of OTU's
 Returns : OTU's
 Args    : none

get_taxset_names

 Title     : get_taxset_names
 Usage     : $block->get_taxset_names()
 Function: gets the names of all sets
 Returns : array of names
 Args     : none

delete_taxsets

 Title     : delete_taxsets
 Usage     : $block->delete_taxsets($set1 [$set2 $set3 ...])
 Function: Removes the named sets from the Sets block
 Returns : none
 Args     : Names of sets to be deleted

exclude_otus

 Title     : exclude_otus
 Usage     : $block->exclude_otus($otu_array_ref)
 Function: Finds and deletes each of the given otus from any sets they appear in
 Returns : none
 Args     : Names of otus to be removed

select_otus

 Title     : select_otus
 Usage     : $block->select_otus($otu_array_ref)
 Function: Finds the given otus and removes all others from any sets they appear in
 Returns : none
 Args     : Names of otus to be removed

rename_otus

 Title   : rename_otus
 Usage   : $block->rename_otus($names);
 Function: rename all OTUs
 Returns : none
 Args    : hash of OTU names

add_otu_clone

 Title   : add_otu_clone
 Usage   : ...
 Function: ...
 Returns : ...
 Args    : ...

rename_taxsets

 Title     : rename_taxsets
 Usage     : $block->rename_taxsets($oldsetname1, $newsetname1, ...)
 Function: Renames sets
 Returns : none
 Args     : Oldname, newname pairs

equals

 Name    : equals
 Usage   : $setsblock->equals($another);
 Function: compare if two Bio::NEXUS::SetsBlock objects are equal
 Returns : boolean 
 Args    : a Bio::NEXUS::SetsBlock object


Bio-NEXUS documentation Contained in the Bio-NEXUS distribution.
######################################################
# SetsBlock.pm
######################################################
# Author: Thomas Hladish
# $Id: SetsBlock.pm,v 1.32 2007/09/21 23:09:09 rvos Exp $
#################### START POD DOCUMENTATION ##################

package Bio::NEXUS::SetsBlock;

use strict;
#use Carp; # XXX this is not used, might as well not import it!
#use Data::Dumper; # XXX this is not used, might as well not import it!
use Bio::NEXUS::Functions;
use Bio::NEXUS::Block;
use Bio::NEXUS::Util::Exceptions;
use Bio::NEXUS::Util::Logger;
use vars qw(@ISA $VERSION $AUTOLOAD);
use Bio::NEXUS; $VERSION = $Bio::NEXUS::VERSION;

@ISA = qw(Bio::NEXUS::Block);
my $logger = Bio::NEXUS::Util::Logger->new();

sub new {
    my ( $class, $type, $commands, $verbose, $taxlabels ) = @_;
    unless ($type) { ( $type = lc $class ) =~ s/Bio::NEXUS::(.+)Block/$1/i; }
    my $self = { type => $type };
    bless $self, $class;
    $self->_parse_block( $commands, $verbose, $taxlabels )
        if ( ( defined $commands ) and @$commands );
    return $self;
}

sub _parse_taxset {
    my ( $self, $buffer ) = @_;
    my ( $setname, $equals_symb, @taxa ) = @{ _parse_nexus_words($buffer) };

    my $taxsets;
    $taxsets->{$setname} = \@taxa;

    #$self->set_taxsets($taxsets);
    $self->add_taxsets( { $setname, \@taxa } );

    return $taxsets;
}

sub set_taxsets {
    my ( $self, $taxsets ) = @_;
    $self->{'taxsets'} = $taxsets;
}

sub add_taxsets {
    my ( $self, $taxsets ) = @_;
    for my $setname ( keys %{$taxsets} ) {
        ${ $self->{'taxsets'} }{$setname} = ( $$taxsets{$setname} );
    }
}

sub get_taxsets {
    my ($self) = @_;
    return $self->{'taxsets'} || {};
}

sub get_taxset {
    my ( $self, $setname ) = @_;
    return $self->{'taxsets'}->{$setname} || [];
}

sub get_taxset_names {
    my ($self) = @_;
    return [ sort keys %{ $self->{'taxsets'} } ];
}

sub print_all_taxsets {
    my ( $self, $outfile ) = @_;
    my $fh;
    if ( $outfile eq "-" || $outfile eq \*STDOUT ) {
        $fh = \*STDOUT;
    }
    else {
        open( $fh, ">$outfile" )
            || Bio::NEXUS::Util::Exceptions::FileError->throw(
        	'error' => "Could not open $outfile for writing" 
        );
    }

    for my $setname ( sort keys %{ $self->{'taxsets'} } ) {
        print $fh "$setname = [@{$self->{'taxsets'}->{$setname}}]\n\n";
    }
}

sub delete_taxsets {
    my ( $self, @setnames ) = @_;
    for my $setname (@setnames) {
        delete ${ $self->{'taxsets'} }{$setname};
    }
}

sub exclude_otus {
    my ( $self, $otus_to_remove ) = @_;
    for my $setname ( keys %{ $self->{'taxsets'} } ) {
        for ( my $i = 0; $i < @{ $self->{'taxsets'}{$setname} }; $i++ ) {
            for my $otu_to_remove (@$otus_to_remove) {
                if ( $self->{'taxsets'}->{$setname}[$i] eq $otu_to_remove ) {
                    splice( @{ $self->{'taxsets'}{$setname} }, $i, 1 );
                }
            }
        }
    }
}

sub select_otus {
    my ( $self, $otus_to_keep ) = @_;
    my $newsets;
    for my $setname ( keys %{ $self->{'taxsets'} } ) {
        $$newsets{$setname} = [];
        for my $otu_element ( @{ $self->{'taxsets'}{$setname} } ) {
            for my $otu_to_keep (@$otus_to_keep) {
                if ( $otu_element eq $otu_to_keep ) {
                    push( @{ $$newsets{$setname} }, $otu_to_keep );
                }
            }
        }
    }
    $self->set_taxsets($newsets);
}

sub rename_otus {
    my ( $self, $translation ) = @_;
    for my $setname ( @{ $self->get_taxset_names() } ) {
        my @otu_names = @{ $self->get_taxset($setname) };
        my @new_otu_names;
        for my $otu_name (@otu_names) {
            if ( my $new_name = $$translation{$otu_name} ) {
                push( @new_otu_names, $new_name );
            }
            else {
                push( @new_otu_names, $otu_name );
            }
        }
        $self->add_taxsets( { $setname, \@new_otu_names } );
    }
}

sub add_otu_clone {
	my ( $self, $original_otu_name, $copy_otu_name ) = @_;
	# print "Warning: Bio::NEXUS::SetsBlock::add_otu_clone() method not fully implemented\n";
	
	# add the cloned otu to those sets that contain the original otu
	foreach my $set_id (keys %{ $self->get_taxsets() }) {
		#print "> set ", $set_id, "\n";
		my @set = @{ $self->get_taxsets()->{$set_id} };
		foreach my $otu (@set) {
			if ($otu eq $original_otu_name) {
				#print "> found the original otu in ", $set_id, "\n";
				push (@{$self->{'taxsets'}{$set_id}}, $copy_otu_name);
			}
		}
	}
}

sub rename_taxsets {
    my ( $self, @old_and_new ) = @_;
    my ( @old, @new );
    while (@old_and_new) {
        push( @old, shift(@old_and_new) );
        push( @new, shift(@old_and_new) );
    }
    for ( my $i = 0; $i < scalar(@old); $i++ ) {
        if ( $self->{'taxsets'}{ $old[$i] } ) {
            $self->{'taxsets'}{ $new[$i] } = $self->{'taxsets'}{ $old[$i] };
            delete $self->{'taxsets'}{ $old[$i] };
        }
        else {
            print "$old[$i] is not the name of a set in this NEXUS file.\n";
        }
    }
}

sub equals {
    my ( $block1, $block2 ) = @_;
    if ( !Bio::NEXUS::Block::equals( $block1, $block2 ) ) { return 0; }
    my $sets1 = $block1->get_taxsets();
    my $sets2 = $block2->get_taxsets();
    if ( keys %$sets1 != keys %$sets2 ) { return 0; }
    for my $setname1 ( keys %$sets1 ) {
        unless ( ( defined $$sets2{$setname1} )
            && ( @{ $$sets1{$setname1} } == @{ $$sets2{$setname1} } ) )
        {
            return 0;
        }
    }
    for my $setname1 ( keys %$sets1 ) {
        @{ $$sets1{$setname1} } = sort @{ $$sets1{$setname1} };
        @{ $$sets2{$setname1} } = sort @{ $$sets2{$setname1} };
        for ( my $i = 0; $i < @{ $$sets1{$setname1} }; $i++ ) {
            unless (
                ${ $$sets1{$setname1} }[$i] eq ${ $$sets2{$setname1} }[$i] )
            {
                return 0;
            }
        }
    }
    return 1;
}

sub _write {
    my ( $self, $fh, $verbose ) = @_;
    $fh ||= \*STDOUT;

    Bio::NEXUS::Block::_write( $self, $fh );
    for my $setname ( sort keys %{ $self->{'taxsets'} } ) {
        my @set_elements = sort @{ ${ $self->{'taxsets'} }{$setname} };
        my $i            = 0;
        for ( my $j = 0; $j + 1 < @set_elements; $j++ ) {
            if ( $set_elements[$i] eq $set_elements[ $i + 1 ] ) {
                splice( @set_elements, $i, 1 );
            }
            else {
                $i++;
            }
        }
        $setname = _nexus_formatted($setname);
        print $fh "\tTAXSET $setname =";
        for my $element (@set_elements) {
            $element = _nexus_formatted($element);
            print $fh " $element";
        }
        print $fh ";\n";
    }
    print $fh "END;\n";
}

sub AUTOLOAD {
    return if $AUTOLOAD =~ /DESTROY$/;
    my $package_name = __PACKAGE__ . '::';

    # The following methods are deprecated and are temporarily supported
    # via a warning and a redirection
    my %synonym_for = (

#        "${package_name}parse"      => "${package_name}_parse_tree",  # example
    );

    if ( defined $synonym_for{$AUTOLOAD} ) {
        $logger->warn("$AUTOLOAD() is deprecated; use $synonym_for{$AUTOLOAD}() instead");
        goto &{ $synonym_for{$AUTOLOAD} };
    }
    else {
        Bio::NEXUS::Util::Exceptions::UnknownMethod->throw(
        	'error' => "ERROR: Unknown method $AUTOLOAD called"
        );
    }
    return;
}

1;