sync w/ main trunk
[bioperl-live.git] / Bio / Tools / Phylo / PAML / ModelResult.pm
blob234c088ea5b60568b5b526b88730216cb6c8973d
1 # $Id$
3 # BioPerl module for Bio::Tools::Phylo::PAML::ModelResult
5 # Please direct questions and support issues to <bioperl-l@bioperl.org>
7 # Cared for by Jason Stajich <jason@open-bio.org>
9 # Copyright Jason Stajich
11 # You may distribute this module under the same terms as perl itself
13 # POD documentation - main docs before the code
15 =head1 NAME
17 Bio::Tools::Phylo::PAML::ModelResult - A container for NSSite Model Result from PAML
19 =head1 SYNOPSIS
21 # get a ModelResult from a PAML::Result object
22 use Bio::Tools::Phylo::PAML;
23 my $paml = Bio::Tools::Phylo::PAML->new(-file => 'mlc');
24 my $result = $paml->next_result;
25 foreach my $model ( $result->get_NSSite_results ) {
26 print $model->model_num, " ", $model->model_description, "\n";
27 print $model->kappa, "\n";
28 print $model->run_time, "\n";
29 # if you are using PAML < 3.15 then only one place for POS sites
30 for my $sites ( $model->get_pos_selected_sites ) {
31 print join("\t",@$sites),"\n";
33 # otherwise query NEB and BEB slots
34 for my $sites ( $model->get_NEB_pos_selected_sites ) {
35 print join("\t",@$sites),"\n";
38 for my $sites ( $model->get_BEB_pos_selected_sites ) {
39 print join("\t",@$sites),"\n";
44 =head1 DESCRIPTION
46 Describe the object here
48 =head1 FEEDBACK
50 =head2 Mailing Lists
52 User feedback is an integral part of the evolution of this and other
53 Bioperl modules. Send your comments and suggestions preferably to
54 the Bioperl mailing list. Your participation is much appreciated.
56 bioperl-l@bioperl.org - General discussion
57 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
59 =head2 Support
61 Please direct usage questions or support issues to the mailing list:
63 L<bioperl-l@bioperl.org>
65 rather than to the module maintainer directly. Many experienced and
66 reponsive experts will be able look at the problem and quickly
67 address it. Please include a thorough description of the problem
68 with code and data examples if at all possible.
70 =head2 Reporting Bugs
72 Report bugs to the Bioperl bug tracking system to help us keep track
73 of the bugs and their resolution. Bug reports can be submitted via
74 email or the web:
76 http://bugzilla.open-bio.org/
78 =head1 AUTHOR - Jason Stajich
80 Email jason@open-bio.org
82 =head1 APPENDIX
84 The rest of the documentation details each of the object methods.
85 Internal methods are usually preceded with a _
87 =cut
90 # Let the code begin...
93 package Bio::Tools::Phylo::PAML::ModelResult;
94 use strict;
96 # Object preamble - inherits from Bio::Root::Root
99 use base qw(Bio::Root::Root);
101 =head2 new
103 Title : new
104 Usage : my $obj = Bio::Tools::Phylo::PAML::ModelResult->new();
105 Function: Builds a new Bio::Tools::Phylo::PAML::ModelResult object
106 Returns : an instance of Bio::Tools::Phylo::PAML::ModelResult
107 Args : -model_num => model number
108 -model_description => model description
109 -kappa => value of kappa
110 -time_used => amount of time
111 -pos_sites => arrayref of sites under positive selection
112 -neb_sites => arrayref of sites under positive selection (by NEB analysis)
113 -beb_sites => arrayref of sites under positive selection (by BEB analysis)
114 -trees => arrayref of tree(s) data for this model
115 -shape_params => hashref of parameters
116 ('shape' => 'alpha',
117 'gamma' => $g,
118 'r' => $r,
119 'f' => $f
122 ( 'shape' => 'beta',
123 'p' => $p,
124 'q' => $q
126 -likelihood => likelihood
127 -num_site_classes => number of site classes
128 -dnds_site_classes => hashref with two keys, 'p' and 'w'
129 which each point to an array, each
130 slot is for a different site class.
131 'w' is for dN/dS and 'p' is probability
133 =cut
135 sub new {
136 my($class,@args) = @_;
138 my $self = $class->SUPER::new(@args);
139 my ($modelnum,$modeldesc,$kappa,
140 $timeused,$trees,
141 $pos_sites,$neb_sites,$beb_sites,
142 $num_site_classes, $shape_params,
143 $dnds_classes,
144 $likelihood) = $self->_rearrange([qw(MODEL_NUM
145 MODEL_DESCRIPTION
146 KAPPA
147 TIME_USED
148 TREES
149 POS_SITES
150 NEB_SITES BEB_SITES
151 NUM_SITE_CLASSES
152 SHAPE_PARAMS
153 DNDS_SITE_CLASSES
154 LIKELIHOOD)],
155 @args);
156 if( $trees ) {
157 if(ref($trees) !~ /ARRAY/i ) {
158 $self->warn("Must provide a valid array reference to initialize trees");
159 } else {
160 foreach my $t ( @$trees ) {
161 $self->add_tree($t);
165 $self->{'_treeiterator'} = 0;
166 if( $pos_sites ) {
167 if(ref($pos_sites) !~ /ARRAY/i ) {
168 $self->warn("Must provide a valid array reference to initialize pos_sites");
169 } else {
170 foreach my $s ( @$pos_sites ) {
171 if( ref($s) !~ /ARRAY/i ) {
172 $self->warn("Need an array reference for each entry in the pos_sites object");
173 next;
175 $self->add_pos_selected_site(@$s);
179 if( $beb_sites ) {
180 if(ref($beb_sites) !~ /ARRAY/i ) {
181 $self->warn("Must provide a valid array reference to initialize beb_sites");
182 } else {
183 foreach my $s ( @$beb_sites ) {
184 if( ref($s) !~ /ARRAY/i ) {
185 $self->warn("need an array ref for each entry in the beb_sites object");
186 next;
188 $self->add_BEB_pos_selected_site(@$s);
192 if( $neb_sites ) {
193 if(ref($neb_sites) !~ /ARRAY/i ) {
194 $self->warn("Must provide a valid array reference to initialize neb_sites");
195 } else {
196 foreach my $s ( @$neb_sites ) {
197 if( ref($s) !~ /ARRAY/i ) {
198 $self->warn("need an array ref for each entry in the neb_sites object");
199 next;
201 $self->add_NEB_pos_selected_site(@$s);
206 defined $modelnum && $self->model_num($modelnum);
207 defined $modeldesc && $self->model_description($modeldesc);
208 defined $kappa && $self->kappa($kappa);
209 defined $timeused && $self->time_used($timeused);
210 defined $likelihood && $self->likelihood($likelihood);
212 $self->num_site_classes($num_site_classes || 0);
213 if( defined $dnds_classes ) {
214 if( ref($dnds_classes) !~ /HASH/i ||
215 ! defined $dnds_classes->{'p'} ||
216 ! defined $dnds_classes->{'w'} ) {
217 $self->warn("-dnds_site_classes expects a hashref with keys p and w");
218 } else {
219 $self->dnds_site_classes($dnds_classes);
222 if( defined $shape_params ) {
223 if( ref($shape_params) !~ /HASH/i ) {
224 $self->warn("-shape_params expects a hashref not $shape_params\n");
225 } else {
226 $self->shape_params($shape_params);
229 return $self;
233 =head2 model_num
235 Title : model_num
236 Usage : $obj->model_num($newval)
237 Function: Get/Set the Model number (0,1,2,3...)
238 Returns : value of model_num (a scalar)
239 Args : on set, new value (a scalar or undef, optional)
242 =cut
244 sub model_num {
245 my $self = shift;
246 return $self->{'_num'} = shift if @_;
247 return $self->{'_num'};
250 =head2 model_description
252 Title : model_description
253 Usage : $obj->model_description($newval)
254 Function: Get/Set the model description
255 This is something like 'one-ratio', 'neutral', 'selection'
256 Returns : value of description (a scalar)
257 Args : on set, new value (a scalar or undef, optional)
260 =cut
262 sub model_description{
263 my $self = shift;
264 return $self->{'_model_description'} = shift if @_;
265 return $self->{'_model_description'};
268 =head2 time_used
270 Title : time_used
271 Usage : $obj->time_used($newval)
272 Function: Get/Set the time it took to run this analysis
273 Returns : value of time_used (a scalar)
274 Args : on set, new value (a scalar or undef, optional)
277 =cut
279 sub time_used{
280 my $self = shift;
281 return $self->{'_time_used'} = shift if @_;
282 return $self->{'_time_used'};
285 =head2 kappa
287 Title : kappa
288 Usage : $obj->kappa($newval)
289 Function: Get/Set kappa (ts/tv)
290 Returns : value of kappa (a scalar)
291 Args : on set, new value (a scalar or undef, optional)
294 =cut
296 sub kappa{
297 my $self = shift;
298 return $self->{'_kappa'} = shift if @_;
299 return $self->{'_kappa'};
302 =head2 num_site_classes
304 Title : num_site_classes
305 Usage : $obj->num_site_classes($newval)
306 Function: Get/Set the number of site classes for this model
307 Returns : value of num_site_classes (a scalar)
308 Args : on set, new value (a scalar or undef, optional)
311 =cut
313 sub num_site_classes{
314 my $self = shift;
315 return $self->{'_num_site_classes'} = shift if @_;
316 return $self->{'_num_site_classes'};
319 =head2 dnds_site_classes
321 Title : dnds_site_classes
322 Usage : $obj->dnds_site_classes($newval)
323 Function: Get/Set dN/dS site classes, a hashref
324 with 2 keys, 'p' and 'w' which point to arrays
325 one slot for each site class.
326 Returns : value of dnds_site_classes (a hashref)
327 Args : on set, new value (a scalar or undef, optional)
330 =cut
332 sub dnds_site_classes{
333 my $self = shift;
334 return $self->{'_dnds_site_classes'} = shift if @_;
335 return $self->{'_dnds_site_classes'};
338 =head2 get_pos_selected_sites
340 Title : get_pos_selected_sites
341 Usage : my @sites = $modelresult->get_pos_selected_sites();
342 Function: Get the sites which PAML has identified as under positive
343 selection (w > 1). This returns an array with each slot
344 being a site, 4 values,
345 site location (in the original alignment)
346 Amino acid (I *think* in the first sequence)
347 P (P value)
348 Significance (** indicated > 99%, * indicates >=95%)
349 Returns : Array
350 Args : none
353 =cut
355 sub get_pos_selected_sites{
356 return @{$_[0]->{'_posselsites'} || []};
359 =head2 add_pos_selected_site
361 Title : add_pos_selected_site
362 Usage : $result->add_pos_selected_site($site,$aa,$pvalue,$signif);
363 Function: Add a site to the list of positively selected sites
364 Returns : count of the number of sites stored
365 Args : $site - site number (in the alignment)
366 $aa - amino acid under selection
367 $pvalue - float from 0->1 represent probability site is under selection according to this model
368 $signif - significance (coded as either empty, '*', or '**'
370 =cut
372 sub add_pos_selected_site{
373 my ($self,$site,$aa,$pvalue,$signif) = @_;
374 push @{$self->{'_posselsites'}}, [ $site,$aa,$pvalue,$signif ];
375 return scalar @{$self->{'_posselsites'}};
378 =head2 get_NEB_pos_selected_sites
380 Title : get_NEB_pos_selected_sites
381 Usage : my @sites = $modelresult->get_NEB_pos_selected_sites();
382 Function: Get the sites which PAML has identified as under positive
383 selection (w > 1) using Naive Empirical Bayes.
384 This returns an array with each slot being a site, 4 values,
385 site location (in the original alignment)
386 Amino acid (I *think* in the first sequence)
387 P (P value)
388 Significance (** indicated > 99%, * indicates > 95%)
389 post mean for w
390 Returns : Array
391 Args : none
394 =cut
396 sub get_NEB_pos_selected_sites{
397 return @{$_[0]->{'_NEBposselsites'} || []};
400 =head2 add_NEB_pos_selected_site
402 Title : add_NEB_pos_selected_site
403 Usage : $result->add_NEB_pos_selected_site($site,$aa,$pvalue,$signif);
404 Function: Add a site to the list of positively selected sites
405 Returns : count of the number of sites stored
406 Args : $site - site number (in the alignment)
407 $aa - amino acid under selection
408 $pvalue - float from 0->1 represent probability site is under selection according to this model
409 $signif - significance (coded as either empty, '*', or '**'
410 $postmean - post mean for w
412 =cut
414 sub add_NEB_pos_selected_site{
415 my ($self,@args) = @_;
416 push @{$self->{'_NEBposselsites'}}, [ @args ];
417 return scalar @{$self->{'_NEBposselsites'}};
422 =head2 get_BEB_pos_selected_sites
424 Title : get_BEB_pos_selected_sites
425 Usage : my @sites = $modelresult->get_BEB_pos_selected_sites();
426 Function: Get the sites which PAML has identified as under positive
427 selection (w > 1) using Bayes Empirical Bayes.
428 This returns an array with each slot being a site, 6 values,
429 site location (in the original alignment)
430 Amino acid (I *think* in the first sequence)
431 P (P value)
432 Significance (** indicated > 99%, * indicates > 95%)
433 post mean for w (mean)
434 Standard Error for w (SE)
435 Returns : Array
436 Args : none
438 =cut
440 sub get_BEB_pos_selected_sites{
441 return @{$_[0]->{'_BEBposselsites'} || []};
444 =head2 add_BEB_pos_selected_site
446 Title : add_BEB_pos_selected_site
447 Usage : $result->add_BEB_pos_selected_site($site,$aa,$pvalue,$signif);
448 Function: Add a site to the list of positively selected sites
449 Returns : count of the number of sites stored
450 Args : $site - site number (in the alignment)
451 $aa - amino acid under selection
452 $pvalue - float from 0->1 represent probability site is under selection according to this model
453 $signif - significance (coded as either empty, '*', or '**'
454 $postmean - post mean for w
455 $SE - Standard Error for w
457 =cut
459 sub add_BEB_pos_selected_site{
460 my ($self,@args) = @_;
461 push @{$self->{'_BEBposselsites'}}, [ @args ];
462 return scalar @{$self->{'_BEBposselsites'}};
465 =head2 next_tree
467 Title : next_tree
468 Usage : my $tree = $factory->next_tree;
469 Function: Get the next tree from the factory
470 Returns : L<Bio::Tree::TreeI>
471 Args : none
473 =cut
475 sub next_tree{
476 my ($self,@args) = @_;
477 return $self->{'_trees'}->[$self->{'_treeiterator'}++] || undef;
480 =head2 get_trees
482 Title : get_trees
483 Usage : my @trees = $result->get_trees;
484 Function: Get all the parsed trees as an array
485 Returns : Array of trees
486 Args : none
489 =cut
491 sub get_trees{
492 my ($self) = @_;
493 return @{$self->{'_trees'} || []};
496 =head2 rewind_tree_iterator
498 Title : rewind_tree_iterator
499 Usage : $result->rewind_tree_iterator()
500 Function: Rewinds the tree iterator so that next_tree can be
501 called again from the beginning
502 Returns : none
503 Args : none
505 =cut
507 sub rewind_tree_iterator {
508 shift->{'_treeiterator'} = 0;
511 =head2 add_tree
513 Title : add_tree
514 Usage : $result->add_tree($tree);
515 Function: Adds a tree
516 Returns : integer which is the number of trees stored
517 Args : L<Bio::Tree::TreeI>
519 =cut
521 sub add_tree{
522 my ($self,$tree) = @_;
523 if( $tree && ref($tree) && $tree->isa('Bio::Tree::TreeI') ) {
524 push @{$self->{'_trees'}},$tree;
526 return scalar @{$self->{'_trees'}};
529 =head2 shape_params
531 Title : shape_params
532 Usage : $obj->shape_params($newval)
533 Function: Get/Set shape params for the distribution, 'alpha', 'beta'
534 which is a hashref
535 with 1 keys, 'p' and 'q'
536 Returns : value of shape_params (a scalar)
537 Args : on set, new value (a scalar or undef, optional)
540 =cut
542 sub shape_params{
543 my $self = shift;
544 return $self->{'_shape_params'} = shift if @_;
545 return $self->{'_shape_params'};
548 =head2 likelihood
550 Title : likelihood
551 Usage : $obj->likelihood($newval)
552 Function: log likelihood
553 Returns : value of likelihood (a scalar)
554 Args : on set, new value (a scalar or undef, optional)
557 =cut
559 sub likelihood{
560 my $self = shift;
561 return $self->{'likelihood'} = shift if @_;
562 return $self->{'likelihood'};