BioPerl
view release on metacpan or search on metacpan
Bio/Species.pm view on Meta::CPAN
reponsive experts will be able look at the problem and quickly
address it. Please include a thorough description of the problem
with code and data examples if at all possible.
=head2 Reporting Bugs
Report bugs to the Bioperl bug tracking system to help us keep track
of the bugs and their resolution. Bug reports can be submitted via the
web:
https://github.com/bioperl/bioperl-live/issues
=head1 AUTHOR
James Gilbert email B<jgrg@sanger.ac.uk>
=head1 CONTRIBUTORS
Sendu Bala, bix@sendu.me.uk
Chris Fields, cjfields at bioperl dot org
=head1 APPENDIX
The rest of the documentation details each of the object
methods. Internal methods are usually preceded with a _
=cut
#' Let the code begin...
package Bio::Species;
use strict;
use warnings;
use Bio::DB::Taxonomy;
use Bio::Tree::Tree;
use Bio::Taxon;
use base qw(Bio::Root::Root Bio::Tree::NodeI);
=head2 new
Title : new
Usage : my $obj = Bio::Species->new(-classification => \@class)
Function: Build a new Species object
Returns : Bio::Species object
Args : -ncbi_taxid => NCBI taxonomic ID (optional)
-classification => arrayref of classification
=cut
sub new {
my($class, @args) = @_;
my $self = $class->SUPER::new(@args);
# Bio::Species is now just a proxy object that just observes the NodeI
# interface methods but delegates them to the proper classes (Bio::Taxon and
# Bio::Tree::Tree). This will be surplanted by the much simpler
# Bio::Taxon/Bio::DB::Taxonomy modules in the future.
# Using a proxy allows proper GC w/o using weaken(). This just wraps the
# older instances, which have no reciprocal refs (thus no circular refs).
# This can then run proper cleanup
$self->taxon(Bio::Taxon->new(@args));
my ($org, $sp, $var, $classification) =
$self->_rearrange([qw(ORGANELLE
SUB_SPECIES
VARIANT
CLASSIFICATION)], @args);
if (defined $classification && ref($classification) eq "ARRAY" && @{$classification}) {
$self->classification(@$classification);
}
else {
$self->tree(Bio::Tree::Tree->new());
}
defined $org && $self->organelle($org);
defined $sp && $self->sub_species($sp);
defined $var && $self->variant($var);
return $self;
}
=head2 classification
Title : classification
Usage : $self->classification(@class_array);
@classification = $self->classification();
Function: Get/set the lineage of this species. The array provided must be in
the order ... ---> SPECIES, GENUS ---> KINGDOM ---> etc.
Example : $obj->classification(qw( 'Homo sapiens' Homo Hominidae
Catarrhini Primates Eutheria Mammalia Vertebrata
Chordata Metazoa Eukaryota));
Returns : Classification array
Args : Classification array
OR
A reference to the classification array. In the latter case
if there is a second argument and it evaluates to true,
names will not be validated. NB: in any case, names are never
validated anyway.
=cut
sub classification {
my ($self, @vals) = @_;
my $taxon = $self->taxon;
if (@vals) {
if (ref($vals[0]) eq 'ARRAY') {
@vals = @{$vals[0]};
}
$vals[1] ||= '';
# make sure the lineage contains us as first or second element
# (lineage may have subspecies, species, genus ...)
my $name = $taxon->node_name;
my ($genus, $species) = (quotemeta($vals[1]), quotemeta($vals[0]));
Bio/Species.pm view on Meta::CPAN
$self->sub_species($sub_species) if $sub_species;
}
$self->{_species} = $species;
}
return $self->{_species};
}
=head2 genus
Title : genus
Usage : $self->genus( $genus );
$genus = $self->genus();
Function: Get or set the scientific genus name.
Example : $self->genus('Homo');
Returns : Scientific genus name as string
Args : Scientific genus name as string
=cut
sub genus {
my ($self, $genus) = @_;
# TODO: instead of caching the raw name, cache the actual node instance.
if ($genus) {
$self->{_genus} = $genus;
}
unless (defined $self->{_genus}) {
my $genus_taxon = $self->tree->find_node(-rank => 'genus');
unless ($genus_taxon) {
# just assume our ancestor is rank genus
$genus_taxon = $self->taxon->ancestor;
}
$self->{_genus} = $genus_taxon->scientific_name if $genus_taxon;
}
return $self->{_genus};
}
=head2 sub_species
Title : sub_species
Usage : $obj->sub_species($newval)
Function: Get or set the scientific subspecies name.
Returns : value of sub_species
Args : newvalue (optional)
=cut
sub sub_species {
my ($self, $sub) = @_;
# TODO: instead of caching the raw name, cache the actual node instance.
if (!defined $self->{'_sub_species'}) {
my $ss_taxon = $self->tree->find_node(-rank => 'subspecies');
if ($ss_taxon) {
if ($sub) {
$ss_taxon->scientific_name($sub);
# *** weakening ref to our root node in species() to solve a
# memory leak means that we have a subspecies taxon to set
# during the first call to species(), but it has vanished by
# the time a user subsequently calls sub_species() to get the
# value. So we 'cheat' and just store the subspecies name in
# our self hash, instead of the tree. Is this a problem for
# a Species object? Can't decide --sendu
# This can now be changed to deal with this information on the
# fly. For now, the caching remains, but maybe we should just
# let these things deal with mutable data as needed? -- cjfields
$self->{'_sub_species'} = $sub;
}
return $ss_taxon->scientific_name;
}
else {
# should we create a node here to be added to the tree?
}
}
# fall back to direct storage on self
$self->{'_sub_species'} = $sub if $sub;
return $self->{'_sub_species'};
}
=head2 variant
Title : variant
Usage : $obj->variant($newval)
Function: Get/set variant information for this species object (strain,
isolate, etc).
Example :
Returns : value of variant (a scalar)
Args : new value (a scalar or undef, optional)
=cut
sub variant{
my ($self, $var) = @_;
# TODO: instead of caching the raw name, cache the actual node instance.
if (!defined $self->{'_variant'}) {
my $var_taxon = $self->tree->find_node(-rank => 'variant');
if ($var_taxon) {
if ($var) {
$var_taxon->scientific_name($var);
}
return $var_taxon->scientific_name;
}
else {
# should we create a node here to be added to the tree?
}
}
# fall back to direct storage on self
$self->{'_variant'} = $var if $var;
return $self->{'_variant'};
}
=head2 binomial
( run in 0.460 second using v1.01-cache-2.11-cpan-ceb78f64989 )