File Coverage

blib/lib/Bio/Gonzales/Range/Util.pm
Criterion Covered Total %
statement 43 43 100.0
branch 15 16 93.7
condition 9 11 81.8
subroutine 7 7 100.0
pod 0 2 0.0
total 74 79 93.6


line stmt bran cond sub pod time code
1             package Bio::Gonzales::Range::Util;
2              
3 2     2   120013 use warnings;
  2         16  
  2         88  
4 2     2   11 use strict;
  2         4  
  2         41  
5 2     2   16 use Carp;
  2         4  
  2         116  
6              
7 2     2   33 use 5.010;
  2         7  
8              
9 2     2   13 use base 'Exporter';
  2         4  
  2         1270  
10             our ( @EXPORT, @EXPORT_OK, %EXPORT_TAGS );
11             our $VERSION = '0.083'; # VERSION
12              
13             @EXPORT = qw();
14             %EXPORT_TAGS = ();
15             @EXPORT_OK = qw(overlaps cluster_overlapping_ranges);
16              
17             sub overlaps {
18 34     34 0 222 my ( $r, $q, $c ) = @_;
19 34 100       99 my $offset = defined $c->{offset} ? $c->{offset} : 0;
20 34 100       75 $offset = 1 if ( $c->{book_ended} );
21              
22             # not ( ref start greater than query end or ref end less than query start )
23 34   100     251 return not( $r->[0] - $offset > $q->[1] or $r->[1] < $q->[0] - $offset );
24             }
25              
26             sub cluster_overlapping_ranges {
27 4     4 0 5482 my ( $ranges, $c ) = @_;
28              
29             #[ start, stop, @whatever]
30              
31 4 100 50     408 carp "empty ranges" and return unless ( $ranges && @$ranges > 0 );
      100        
32              
33 2 50       13 my @sorted_ranges = sort { $a->[0] <=> $b->[0] or $a->[1] <=> $b->[1] } @$ranges;
  58         109  
34 2         4 my @range_clusters;
35              
36 2         4 my $i = 0;
37              
38 2         4 while (1) {
39 6 100       13 if ( $i >= @sorted_ranges - 1 ) {
40 2 100       6 push @range_clusters, [ $sorted_ranges[$i] ]
41             if ( $i == @sorted_ranges - 1 );
42 2         16 last;
43             }
44              
45 4         8 my $range = $sorted_ranges[$i];
46              
47 4         7 my @current_cluster = ($range);
48              
49 4         9 my $next_range = $sorted_ranges[ $i + 1 ];
50 4         6 my $max_end = $range->[1];
51 4   66     14 while ( $next_range->[0] <= $max_end
52             || overlaps( $range, $next_range, $c ) )
53             {
54 15         21 push @current_cluster, $next_range;
55              
56 15         22 $i++;
57 15 100       30 $max_end = $next_range->[1] if ( $next_range->[1] > $max_end );
58 15         20 $range = $next_range;
59              
60 15 100       27 if ( $i + 1 >= @sorted_ranges ) {
61 1         3 last;
62             }
63              
64 14         34 $next_range = $sorted_ranges[ $i + 1 ];
65             }
66 4         10 $i++;
67 4         15 push @range_clusters, \@current_cluster;
68             }
69 2         17 return \@range_clusters;
70             }
71              
72              
73              
74             1;