Mercurial > repos > mahtabm > ensembl
comparison variant_effect_predictor/Bio/Taxonomy.pm @ 0:1f6dce3d34e0
Uploaded
| author | mahtabm |
|---|---|
| date | Thu, 11 Apr 2013 02:01:53 -0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:1f6dce3d34e0 |
|---|---|
| 1 # $Id: Taxonomy.pm,v 1.1 2002/11/19 00:36:47 kortsch Exp $ | |
| 2 # | |
| 3 # BioPerl module for Bio::Taxonomy | |
| 4 # | |
| 5 # Cared for by Dan Kortschak | |
| 6 # | |
| 7 # You may distribute this module under the same terms as perl itself | |
| 8 | |
| 9 # POD documentation - main docs before the code | |
| 10 | |
| 11 =head1 NAME | |
| 12 | |
| 13 Bio::Taxonomy - Conversion used bt the Taxonomy classes | |
| 14 | |
| 15 =head1 SYNOPSIS | |
| 16 | |
| 17 use Bio::Taxonomy; | |
| 18 | |
| 19 =head1 DESCRIPTION | |
| 20 | |
| 21 Provides methods for converting classifications into taxonomic | |
| 22 structures. | |
| 23 | |
| 24 =head1 CONTACT | |
| 25 | |
| 26 Dan Kortschak email B<kortschak@rsbs.anu.edu.au> | |
| 27 | |
| 28 =head1 APPENDIX | |
| 29 | |
| 30 The rest of the documentation details each of the object | |
| 31 methods. Internal methods are usually preceded with a _ | |
| 32 | |
| 33 =cut | |
| 34 | |
| 35 | |
| 36 # code begins... | |
| 37 | |
| 38 | |
| 39 package Bio::Taxonomy; | |
| 40 use vars qw(@ISA); | |
| 41 use strict; | |
| 42 | |
| 43 # Object preamble - inherits from Bio::Root::Object | |
| 44 use Bio::Root::Root; | |
| 45 | |
| 46 @ISA = qw(Bio::Root::Root); | |
| 47 | |
| 48 | |
| 49 =head2 new | |
| 50 | |
| 51 Title : new | |
| 52 Usage : my $obj = new Bio::Taxonomy(); | |
| 53 Function: Builds a new Bio::Taxonomy object | |
| 54 Returns : Bio::Taxonomy | |
| 55 Args : -method -> method used to decide classification | |
| 56 (none|trust|lookup) | |
| 57 -ranks -> what ranks are there | |
| 58 | |
| 59 =cut | |
| 60 | |
| 61 | |
| 62 sub new { | |
| 63 my ($class,@args) = @_; | |
| 64 | |
| 65 my $self = $class->SUPER::new(@args); | |
| 66 | |
| 67 $self->{'_method'}='none'; | |
| 68 $self->{'_ranks'}=[]; | |
| 69 $self->{'_rank_hash'}={}; | |
| 70 | |
| 71 my ($method,$ranks,$order) = $self->_rearrange([qw(METHOD RANKS ORDER)], @args); | |
| 72 | |
| 73 if ($method) { | |
| 74 $self->method($method); | |
| 75 } | |
| 76 | |
| 77 if (defined $ranks && | |
| 78 (ref($ranks) eq "ARRAY") ) { | |
| 79 $self->ranks(@$ranks); | |
| 80 } else { | |
| 81 # default ranks | |
| 82 # I think these are in the right order, but not sure: | |
| 83 # some parvorder|suborder and varietas|subspecies seem | |
| 84 # to be at the same level - any taxonomists? | |
| 85 # I don't expect that these will actually be used except as a way | |
| 86 # to find what ranks there are in taxonomic use | |
| 87 $self->ranks(('root', | |
| 88 'superkingdom', | |
| 89 'kingdom', | |
| 90 'superphylum', | |
| 91 'phylum', | |
| 92 'subphylum', | |
| 93 'superclass', | |
| 94 'class', | |
| 95 'subclass', | |
| 96 'infraclass', | |
| 97 'superorder', | |
| 98 'order', | |
| 99 'suborder', | |
| 100 'parvorder', | |
| 101 'infraorder', | |
| 102 'superfamily', | |
| 103 'family', | |
| 104 'subfamily', | |
| 105 'tribe', | |
| 106 'subtribe', | |
| 107 'genus', | |
| 108 'subgenus', | |
| 109 'species group', | |
| 110 'species subgroup', | |
| 111 'species', | |
| 112 'subspecies', | |
| 113 'varietas', | |
| 114 'forma', | |
| 115 'no rank')); | |
| 116 } | |
| 117 | |
| 118 return $self; | |
| 119 } | |
| 120 | |
| 121 | |
| 122 =head2 method | |
| 123 | |
| 124 Title : method | |
| 125 Usage : $obj = taxonomy->method($method); | |
| 126 Function: set or return the method used to decide classification | |
| 127 Returns : $obj | |
| 128 Args : $obj | |
| 129 | |
| 130 =cut | |
| 131 | |
| 132 | |
| 133 sub method { | |
| 134 my ($self,$value) = @_; | |
| 135 if (defined $value && $value=~/none|trust|lookup/) { | |
| 136 $self->{'_method'} = $value; | |
| 137 } | |
| 138 return $self->{'_method'}; | |
| 139 } | |
| 140 | |
| 141 | |
| 142 =head2 classify | |
| 143 | |
| 144 Title : classify | |
| 145 Usage : @obj[][0-1] = taxonomy->classify($species); | |
| 146 Function: return a ranked classification | |
| 147 Returns : @obj of taxa and ranks as word pairs separated by "@" | |
| 148 Args : Bio::Species object | |
| 149 | |
| 150 =cut | |
| 151 | |
| 152 | |
| 153 sub classify { | |
| 154 my ($self,$value) = @_; | |
| 155 my @ranks; | |
| 156 | |
| 157 if (! $value->isa('Bio::Species') ) { | |
| 158 $self->throw("Trying to classify $value which is not a Bio::Species object"); | |
| 159 } | |
| 160 | |
| 161 my @classes=reverse($value->classification); | |
| 162 | |
| 163 if ($self->method eq 'none') { | |
| 164 for (my $i=0; $i < @classes-2; $i++) { | |
| 165 ($ranks[$i][0],$ranks[$i][1])=($classes[$i],'no rank'); | |
| 166 } | |
| 167 push @ranks,[$classes[-2],'genus']; | |
| 168 push @ranks,[$value->binomial,'species']; | |
| 169 } elsif ($self->method eq 'trust') { | |
| 170 if (scalar(@classes)==scalar($self->ranks)) { | |
| 171 for (my $i=0; $i < @classes; $i++) { | |
| 172 if ($self->rank_of_number($i) eq 'species') { | |
| 173 push @ranks,[$value->binomial,$self->rank_of_number($i)]; | |
| 174 } else { | |
| 175 push @ranks,[$classes[$i],$self->rank_of_number($i)]; | |
| 176 } | |
| 177 } | |
| 178 } else { | |
| 179 $self->throw("Species object and taxonomy object cannot be reconciled"); | |
| 180 } | |
| 181 } elsif ($self->method eq 'lookup') { | |
| 182 # this will lookup a DB for the rank of a taxon name | |
| 183 # I imagine that some kind of Bio::DB class will be need to | |
| 184 # be given to the taxonomy object to act as an DB interface | |
| 185 # (I'm not sure how useful this is though - if you have a DB of | |
| 186 # taxonomy - why would you be doing things this way?) | |
| 187 $self->throw("Not yet implemented"); | |
| 188 } | |
| 189 | |
| 190 return @ranks; | |
| 191 } | |
| 192 | |
| 193 | |
| 194 =head2 level_of_rank | |
| 195 | |
| 196 Title : level_of_rank | |
| 197 Usage : $obj = taxonomy->level_of_rank($obj); | |
| 198 Function: returns the level of a rank name | |
| 199 Returns : $obj | |
| 200 Args : $obj | |
| 201 | |
| 202 =cut | |
| 203 | |
| 204 | |
| 205 sub level_of { | |
| 206 my ($self,$value) = @_; | |
| 207 | |
| 208 return $self->{'_rank_hash'}{$value}; | |
| 209 } | |
| 210 | |
| 211 | |
| 212 =head2 rank_of_number | |
| 213 | |
| 214 Title : rank_of_number | |
| 215 Usage : $obj = taxonomy->rank_of_number($obj); | |
| 216 Function: returns the rank name of a rank level | |
| 217 Returns : $obj | |
| 218 Args : $obj | |
| 219 | |
| 220 =cut | |
| 221 | |
| 222 | |
| 223 sub rank_of_number { | |
| 224 my ($self,$value) = @_; | |
| 225 | |
| 226 return ${$self->{'_ranks'}}[$value]; | |
| 227 } | |
| 228 | |
| 229 | |
| 230 =head2 ranks | |
| 231 | |
| 232 Title : ranks | |
| 233 Usage : @obj = taxonomy->ranks(@obj); | |
| 234 Function: set or return all ranks | |
| 235 Returns : @obj | |
| 236 Args : @obj | |
| 237 | |
| 238 =cut | |
| 239 | |
| 240 | |
| 241 sub ranks { | |
| 242 my ($self,@value) = @_; | |
| 243 | |
| 244 # currently this makes no uniqueness sanity check (this should be done) | |
| 245 # I am think that adding a way of converting multiple 'no rank' ranks | |
| 246 # to unique 'no rank #' ranks so that the level of a 'no rank' is | |
| 247 # abstracted way from the user - I'm not sure of the vlaue of this | |
| 248 | |
| 249 if (defined @value) { | |
| 250 $self->{'_ranks'}=\@value; | |
| 251 } | |
| 252 | |
| 253 for (my $i=0; $i <= @{$self->{'_ranks'}}-1; $i++) { | |
| 254 $self->{'_rank_hash'}{$self->{'_ranks'}[$i]}=$i unless $self->{'_ranks'}[$i] eq 'no rank'; | |
| 255 } | |
| 256 | |
| 257 return @{$self->{'_ranks'}}; | |
| 258 } | |
| 259 | |
| 260 | |
| 261 1; |
