1 package Maasha::KISS::Track;
3 # Copyright (C) 2009 Martin A. Hansen.
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.
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.
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.
19 # http://www.gnu.org/copyleft/gpl.html
22 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DESCRIPTION <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
25 # Routines for creating KISS tracks.
28 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
35 use vars qw( @ISA @EXPORT );
37 @ISA = qw( Exporter );
40 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
45 my ( $width, # draw window width
46 $y_offset, # y axis draw offset
47 $beg, # base window beg
48 $end, # base window end
49 $font_size, # font size
53 my ( $factor, $step, $i, $txt, $x, @ruler );
55 $factor = $width / ( $end - $beg );
59 while ( ( $end - $beg ) / $step > 20 )
64 for ( $i = $beg; $i < $end; $i++ )
66 if ( ( $i % $step ) == 0 )
69 $x = sprintf( "%.0f", ( $i - $beg - length $txt ) * $factor );
71 if ( $x > 0 and $x + ( $font_size * length $txt ) < $width )
76 font_size => $font_size,
85 return wantarray ? @ruler : \@ruler;
91 my ( $width, # draw window width
92 $y_offset, # y axis draw offset
93 $seq, # sequence to draw
94 $font_size, # font size
98 my ( @chars, $factor, $i, @seq_list );
100 @chars = split //, $seq;
102 $factor = $width / @chars;
104 for ( $i = 0; $i < @chars; $i++ ) {
108 font_size => $font_size,
110 x1 => sprintf( "%.0f", $i * $factor ),
115 return wantarray ? @seq_list : \@seq_list;
121 my ( $width, # draw window width
122 $y_offset, # y axis draw offset
123 $beg, # base window beg
124 $end, # base window end
125 $entries, # list of unsorted KISS entries
130 my ( $feat_height, $factor, $entry, $y_step, @ladder, $w, $x1, $y1, $x2, $y2, @features );
132 @{ $entries } = sort { $a->{ 'S_BEG' } <=> $b->{ 'S_BEG' } or $a->{ 'S_END' } <=> $b->{ 'S_END' } } @{ $entries };
135 $factor = $width / ( $end - $beg );
138 foreach $entry ( @{ $entries } )
140 $w = sprintf( "%.0f", ( $entry->{ 'S_END' } - $entry->{ 'S_BEG' } + 1 ) * $factor );
144 $x1 = sprintf( "%.0f", ( $entry->{ 'S_BEG' } - $beg ) * $factor );
146 for ( $y_step = 0; $y_step < @ladder; $y_step++ )
148 last if $x1 >= $ladder[ $y_step ] + 1;
151 $y1 = $y_offset + ( $feat_height * $y_step );
155 line_width => $feat_height,
157 title => $entry->{ 'Q_ID' },
161 y2 => $y1 + $feat_height,
164 push @features, feature_align( $entry, $beg, $y1, $factor, $feat_height ) if defined $entry->{ 'ALIGN' };
166 $ladder[ $y_step ] = $x1 + $w;
170 return wantarray ? @features : \@features;
178 my ( $entry, # Partial KISS entry
179 $beg, # base window beg
180 $y_offset, # y axis draw offset
181 $factor, # scale factor
182 $feat_height, # hight of feature in pixels
187 my ( $w, $align, $pos, $nt_before, $nt_after, $x1, @features );
189 $w = sprintf( "%.0f", 1 * $factor );
193 foreach $align ( split /,/, $entry->{ 'ALIGN' } )
195 if ( $align =~ /(\d+):(\w)>(\w)/ )
206 $x1 = sprintf( "%.0f", ( $entry->{ 'S_BEG' } + $pos - $beg ) * $factor );
210 line_width => $feat_height,
216 y2 => $y_offset + $feat_height,
219 if ( $w > $feat_height )
223 font_size => $feat_height + 2,
226 x1 => $x1 + sprintf( "%.0f", ( $w / 2 ) ) - $feat_height / 2,
227 y1 => $y_offset + $feat_height,
233 return wantarray ? @features : \@features;
239 my ( $width, # draw window width
240 $y_offset, # y axis draw offset
241 $min, # minimum base position
242 $max, # maximum base position
243 $entries, # list of unsorted KISS entries
248 my ( $hist_height, $bucket_width, $factor_heigth, $factor_width, $entry, $min_bucket, $max_height, $bucket_beg, $bucket_end, $i, @buckets, $bucket, @hist, $x, $h );
250 return if $max == $min;
252 $hist_height = 100; # pixels
253 $bucket_width = 5; # pixels
255 $factor_width = ( $width / $bucket_width ) / ( $max - $min );
257 $min_bucket = 999999999;
260 foreach $entry ( @{ $entries } )
262 $bucket_beg = int( $entry->{ 'S_BEG' } * $factor_width );
263 $bucket_end = int( $entry->{ 'S_END' } * $factor_width );
265 $min_bucket = Maasha::Calc::min( $min_bucket, $bucket_beg );
267 for ( $i = $bucket_beg; $i <= $bucket_end; $i++ )
271 $max_height = Maasha::Calc::max( $max_height, $buckets[ $i ] );
275 if ( $max_height > 0 )
277 $factor_heigth = $hist_height / $max_height;
281 for ( $i = $min_bucket; $i < @buckets; $i++ )
283 if ( defined $buckets[ $i ] )
285 $h = sprintf( "%.0f", $buckets[ $i ] * $factor_heigth );
291 line_width => $bucket_width,
293 title => "Features: $buckets[ $i ]",
295 y1 => $y_offset + $hist_height,
297 y2 => $y_offset + $hist_height - $h,
306 return wantarray ? @hist : \@hist;
310 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<