[Bioperl-l] Bio::*Taxonomy* changes

Sendu Bala bix at sendu.me.uk
Mon Jul 24 13:49:42 UTC 2006


Hilmar Lapp wrote:
> Sounds good to me, except there is no Bio::TaxonomyI yet,

Indeed, I propose making one.


> Bio::Species shouldn't fully depend on an internet connection or flat 
> file to do anything meaningful.
> 
> I.e., it should take advantage of a lookup database if there is one, but 
> in the absence of that one should also be able to statically set 
> attribute values to whatever one thinks can be gleaned from a parsed 
> text or whatever.

Yes, which is why Bio::Taxonomy is appropriate here. Assuming that 
Bio::Species isa Bio::TaxonomyI:

...
SOURCE      Saccharomyces cerevisiae (baker's yeast)
    ORGANISM  Saccharomyces cerevisiae
              Eukaryota; Fungi; Ascomycota; Saccharomycotina;
              Saccharomycetes;
              Saccharomycetales; Saccharomycetaceae; Saccharomyces.

...

## the fully-manual way
my $species = new Bio::Species;
my $node = new Bio::Taxonomy::Node(-name => 'Saccharomyces cerevisiae',
                                    -rank => 'species', -object_id => 1,
                                    -parent_id => 2);
my $n2 = new Bio::Taxonomy::Node(-name => 'Saccharomyces',
                                  -object_id => 2, -parent_id => 3);
# (no assumption that 'Saccharomyces' is the genus, so rank() undefined)
my $n3 = [etc]
$species->add_node($node);
$species->add_node($n2);
[etc]

## Using a factory without db access
# assume that Bio::Taxonomy::GenbankFactory implements
# some modified Bio::Taxonomy::FactoryI
my $factory = Bio::Taxonomy::GenbankFactory->new();
my $species = $factory->generate(-classification => ['Saccharomyces
             cerevisiae', 'Saccharomyces', 'Saccharomycetaceae' ...]);
# the generate() method above just does the fully-manual way for you

## Using a factory with db access
# assume that Bio::Taxonomy::EntrezFactory implements some
# modified Bio::Taxonomy::FactoryI and uses Bio::DB::Taxonomy::entrez
# to get the nodes
my $factory = Bio::Taxonomy::EntrezFactory->new();
my $species = $factory->fetch(-scientifc_name => 'Saccharomyces
                                                   cerevisiae');

# (would probably want to come up with a more generic name for the
#  fetch() and generate() methods, so that all Factories use the same
#  same method name)


It's very clean and flexible this way. Ultimately you always make your 
Bio::Species the same way - you add nodes to it. You can make those 
nodes yourself or use a factory.

We also solve Chris' earlier quandary:

[ in a world where Bio::Taxonomy::Node and Bio::Taxonomy::SpeciesNode 
exist, and given that Bio::DB::Taxonomy* currently directly make Node 
objects ]
> The only problem I can foresee is which class to use with
> Bio::DB::Taxonomy*?  I guess one could settle on one class by default and
> have the option to use another Bio::Taxonomy::NodeI-implementing class if
> you wanted more data/methods available...

The way to do it is to have the Bio::DB::Taxonomy* modules return only 
the information that a Bio::Taxonomy::FactoryI would need to make a 
NodeI. The specific Factory that you use could generate whatever type of 
Node you wanted.

But actually I propose there is only one Node and the specific Factory 
that you use determines the kind of Bio::TaxonomyI made; GenbankFactory 
might make a Bio::Species, while EntrezFactory might make a Bio::Taxonomy.

Bio::Species differs from Bio::Taxonomy only so it contains all the 
legacy methods names that Bio::Species currently has, for backward 
compatibility. Setting $species->classification() would delete all nodes 
of self, use a GenbankFactory to make a new Bio::Species, then pull out 
all its Nodes and add them to self.


Unless anyone can think of a better way of doing things, I'll explore 
the above ideas and start writing code. To summarise: major changes to 
Bio::DB::Taxonomy* (make them factory slaves), implementation of some 
Bio::Taxonomy::FactoryIs, tweak Bio::Taxonomy::FactoryI and make 
Bio::TaxonomyI, make Bio::Species a Bio::TaxonomyI.

Oh, Bio::Taxonomy might need some changes as well. It has a classify() 
method does something with a Bio::Species, which would be all wrong in 
the new way of doing things.



More information about the Bioperl-l mailing list