]> git.donarmstrong.com Git - biopieces.git/blob - code_perl/Maasha/KISS/Track.pm
more work on KISS
[biopieces.git] / code_perl / Maasha / KISS / Track.pm
1 package Maasha::KISS::Track;
2
3 # Copyright (C) 2009 Martin A. Hansen.
4
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
9
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
19 # http://www.gnu.org/copyleft/gpl.html
20
21
22 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DESCRIPTION <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
23
24
25 # Routines for creating KISS tracks.
26
27
28 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
29
30
31 use warnings;
32 use strict;
33 use Data::Dumper;
34 use Maasha::Calc;
35 use vars qw( @ISA @EXPORT );
36
37 @ISA = qw( Exporter );
38
39
40 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
41
42
43 sub track_ruler
44 {
45     my ( $width,     # draw window width
46          $y_offset,  # y axis draw offset
47          $beg,       # base window beg
48          $end,       # base window end
49        ) = @_;
50
51     my ( $factor, $step, $i, $txt, $x, @ruler );
52
53     $factor = $width / ( $end - $beg );
54     
55     $step = 10;
56
57     while ( ( $end - $beg ) / $step > 20 )
58     {
59         $step *= 5;
60     }
61
62     for ( $i = $beg; $i < $end; $i++ )
63     {
64         if ( ( $i % $step ) == 0 )
65         {
66             $txt = "$i|";
67             $x   = sprintf( "%.0f", ( $i - $beg - length $txt ) * $factor );
68
69             push @ruler, { txt => $txt, x => $x, y => $y_offset };
70         }
71     }
72
73     return wantarray ? @ruler : \@ruler;
74 }
75
76
77 sub track_seq
78 {
79     my ( $width,     # draw window width
80          $y_offset,  # y axis draw offset
81          $seq,       # sequence to draw
82        ) = @_;
83
84     my ( @chars, $factor, $i, @seq_list );
85
86     @chars = split //, $seq;
87
88     $factor = $width / @chars;
89
90     for ( $i = 0; $i < @chars; $i++ ) {
91         push @seq_list, { txt => $chars[ $i ], x => sprintf( "%.0f", $i * $factor ), y => $y_offset };
92     }
93
94     return wantarray ? @seq_list : \@seq_list;
95 }
96
97
98 sub track_feature
99 {
100     my ( $width,     # draw window width
101          $y_offset,  # y axis draw offset
102          $beg,       # base window beg
103          $end,       # base window end
104          $entries,   # list of unsorted KISS entries 
105        ) = @_;
106
107     # Returns a list.
108     
109     my ( $factor, $entry, $y_step, @ladder, $w, $x1, $y1, $x2, $y2, @features );
110
111     @{ $entries } = sort { $a->{ 'S_BEG' } <=> $b->{ 'S_BEG' } or $a->{ 'S_END' } <=> $b->{ 'S_END' } } @{ $entries };
112
113     $factor = $width / ( $end - $beg );
114     $y_step = 0;
115
116     foreach $entry ( @{ $entries } )
117     {
118         $w = sprintf( "%.0f", ( $entry->{ 'S_END' } - $entry->{ 'S_BEG' } + 1 ) * $factor );
119
120         if ( $w >= 1 )
121         {
122             $x1 = sprintf( "%.0f", ( $entry->{ 'S_BEG' } - $beg ) * $factor );
123
124             for ( $y_step = 0; $y_step < @ladder; $y_step++ )
125             {
126                 last if $x1 >= $ladder[ $y_step ] + 1; 
127             }
128
129             $y1 = $y_offset + ( 5 * $y_step );
130
131             push @features, {
132                 x1 => $x1,
133                 y1 => $y1,
134                 x2 => $x1 + $w,
135                 y2 => $y1,
136             };
137
138             $ladder[ $y_step ] = $x1 + $w;
139         }
140     }
141
142     return wantarray ? @features : \@features;
143 }
144
145
146 sub track_histogram
147 {
148     my ( $width,     # draw window width
149          $y_offset,  # y axis draw offset
150          $min,       # minimum base position
151          $max,       # maximum base position
152          $entries,   # list of unsorted KISS entries 
153        ) = @_;
154
155     # Returns a list.
156
157     my ( $hist_height, $bucket_width, $factor_heigth, $factor_width, $entry, $min_bucket, $max_height, $bucket_beg, $bucket_end, $i, @buckets, $bucket, @hist, $x, $h );
158
159     return if $max == $min;
160
161     $hist_height  = 100;   # pixels
162     $bucket_width = 5;     # pixels
163
164     $factor_width = ( $width / $bucket_width ) / ( $max - $min );
165
166     $min_bucket = 999999999;
167     $max_height = 0;
168
169     foreach $entry ( @{ $entries } )
170     {
171         $bucket_beg = int( $entry->{ 'S_BEG' } * $factor_width );
172         $bucket_end = int( $entry->{ 'S_END' } * $factor_width );
173
174         $min_bucket = Maasha::Calc::min( $min_bucket, $bucket_beg );
175
176         for ( $i = $bucket_beg; $i <= $bucket_end; $i++ )
177         {
178             $buckets[ $i ]++;
179
180             $max_height = Maasha::Calc::max( $max_height, $buckets[ $i ] );
181         }
182     }
183
184     if ( $max_height > 0 )
185     {
186         $factor_heigth = $hist_height / $max_height;
187
188         $x = 0;
189
190         for ( $i = $min_bucket; $i < @buckets; $i++ )
191         {
192             if ( defined $buckets[ $i ] )
193             {
194                 $h = sprintf( "%.0f", $buckets[ $i ] * $factor_heigth );
195
196                 if ( $h >= 1 )
197                 {
198                     push @hist, {
199                         x1      => $x,
200                         y1      => $y_offset + $hist_height,
201                         x2      => $x,
202                         y2      => $y_offset + $hist_height - $h,
203                     };
204                 }
205             }
206
207             $x += $bucket_width;
208         }
209     }
210
211     return wantarray ? @hist : \@hist;
212 }
213
214
215 sub bucket_round
216 {
217     my ( $num,
218          $bucket_size,
219        ) = @_;
220     
221     my ( $div, $int );
222
223     $div = $num / $bucket_size;
224     $int = int $div;
225
226     if ( $div - $int >= 0.5 ) {
227         return $bucket_size * ( $int + 1 );
228     } else {
229         return $bucket_size * $int;
230     }
231 }
232
233
234 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
235
236 1;
237
238