=head1 NAME

iPE::Model::DurationDistribution::DEFINED

=head1 DESCRIPTION

Defines a histogram-style duration distribution for a fixed domain of lengths.

=cut

package iPE::Model::DurationDistribution::DEFINED;

use base ("iPE::Model::DurationDistribution");
use iPE;
use iPE::Globals;
use strict;


sub init {
    my ($this) = @_;

    $this->{counts_} = [];
    $this->{ids_}    = [];
    $this->{scores_} = [];
    for my $i ($this->min .. $this->max) {
        $this->{counts_}->[$i] = 0;
        $this->{scores_}->[$i] = 0;
    }
}

sub counts { shift->{counts_} }
sub scores { shift->{scores_} }

sub countFeature {
    my ($this, $feature, $wt) = @_;
    my $length = int ($feature->length/$this->{lengthUnit_});
    
    $this->{counts_}->[$length] += $wt;

    if(!defined $this->{ids_}->[$length]) {
        $this->{ids_}->[$length] = [];
    }
    push @{$this->{ids_}->[$length]}, $feature->id;
}

sub smooth {
    my ($this) = @_;
    msg("$this->{region_} $this->{model_} Density before smoothing: ".
        $this->smoother->getArefTotal($this->counts)."\n");
    $this->pseudocountSmoother->smoothAref($this->counts, $this->samples);
    $this->smoother->smoothAref($this->counts, $this->samples);
    msg("$this->{region_} $this->{model_} Density after smoothing: ".
        $this->smoother->getArefTotal($this->counts)."\n");
}

sub normalize {
    my ($this) = @_;
    # the total counts is the number counts in all distributions, so 
    # we find this by dividing by the prior probability that 
    my $totCounts;
    if ($this->density <= 0)    { $totCounts = 1; }
    else                        { $totCounts = $this->samples/$this->density; }
    msg("calculated total counts for $this->{region_}: $totCounts\n");
    #for my $length ($this->min .. $this->max) {
        #$totCounts += $this->{counts_}->[$length];
    #}
    if($totCounts) {
        for my $length ($this->min .. $this->max) {
            $this->{counts_}->[$length] /= $totCounts;
        }
    }

    $this->finalProb($this->{counts_}->[$this->max]);
}

sub score {
    my ($this) = @_;
    my $totCounts = 0;
    for my $length ($this->min .. $this->max) {
        $this->{scores_}->[$length] = 
            $this->logScore($this->{counts_}->[$length]);
    }
}

sub outputPrepare {
    my ($this, $out, $mode) = @_;

    my $pstring = "";
    for my $i ($this->min .. $this->max/$this->lengthUnit) {
        for my $j (0 .. $this->lengthUnit-1) {
            if((($i-$this->min)*$this->lengthUnit+$j)%4 == 0 && 
                ($i > $this->min || $j > 0))
                { $pstring .= "\n" }
            if($mode eq "score")    
                { $pstring .= $out->floatf($this->scores->[$i]) }
            else                    
                { $pstring .= $out->floatf($this->counts->[$i]) }
            $pstring .= $out->tab;
        }
    }

    $this->setParamString($pstring);
}

=head1 SEE ALSO

L<iPE::Model::DurationDistribution>

=head1 AUTHOR

Bob Zimmermann (rpz@cse.wustl.edu)

=cut

1;
