File Coverage

blib/lib/Bio/Coordinate/ExtrapolatingPair.pm
Criterion Covered Total %
statement 59 59 100.0
branch 25 34 73.5
condition 3 3 100.0
subroutine 10 10 100.0
pod 3 3 100.0
total 100 109 91.7


line stmt bran cond sub pod time code
1             package Bio::Coordinate::ExtrapolatingPair;
2             our $AUTHORITY = 'cpan:BIOPERLML';
3             $Bio::Coordinate::ExtrapolatingPair::VERSION = '1.007001';
4 1     1   1089 use utf8;
  1         2  
  1         4  
5 1     1   29 use strict;
  1         1  
  1         16  
6 1     1   12 use warnings;
  1         2  
  1         19  
7 1     1   3 use Bio::Root::Root;
  1         1  
  1         21  
8 1     1   4 use Bio::LocationI;
  1         1  
  1         27  
9 1     1   3 use parent qw(Bio::Coordinate::Pair);
  1         1  
  1         5  
10              
11             # ABSTRACT: Continuous match between two coordinate sets.
12             # AUTHOR: Heikki Lehvaslaiho
13             # OWNER: Heikki Lehvaslaiho
14             # LICENSE: Perl_5
15              
16              
17              
18             sub new {
19 11     11 1 3573 my($class,@args) = @_;
20 11         38 my $self = $class->SUPER::new(@args);
21              
22 11         27 my($strict) =
23             $self->_rearrange([qw(STRICT
24             )],
25             @args);
26              
27 11 100       193 $strict && $self->strict($strict);
28 11         29 return $self;
29             }
30              
31              
32             sub strict {
33 42     42 1 531 my ($self,$value) = @_;
34 42 100       69 if( defined $value) {
35 1 50       6 $self->{'_strict'} = 1 if $value;
36             }
37 42         76 return $self->{'_strict'};
38             }
39              
40              
41             sub map {
42 37     37 1 8313 my ($self,$value) = @_;
43              
44 37 50       72 $self->throw("Need to pass me a value.")
45             unless defined $value;
46 37 50       100 $self->throw("I need a Bio::Location, not [$value]")
47             unless $value->isa('Bio::LocationI');
48 37 50       83 $self->throw("Input coordinate system not set")
49             unless $self->in;
50 37 50       71 $self->throw("Output coordinate system not set")
51             unless $self->out;
52              
53 37         31 my $match;
54              
55 37 100       121 if ($value->isa("Bio::Location::SplitLocationI")) {
56              
57 2         8 my $split = Bio::Coordinate::Result->new(-seq_id=>$self->out->seq_id);
58 2         23 foreach my $loc ( sort { $a->start <=> $b->start }
  4         88  
59             $value->sub_Location ) {
60              
61 5         67 $match = $self->_map($loc);
62 5 50       18 $split->add_sub_Location($match) if $match;
63              
64             }
65 2 50       28 $split->each_Location ? (return $split) : return ;
66              
67             } else {
68 35         52 return $self->_map($value);
69             }
70             }
71              
72              
73             sub _map {
74 40     40   42 my ($self,$value) = @_;
75              
76 40         36 my ($offset, $start, $end);
77              
78 40 100       89 if ($self->strand == -1) {
79 12         81 $offset = $self->in->end + $self->out->start;
80 12         105 $start = $offset - $value->end;
81 12         112 $end = $offset - $value->start ;
82             } else { # undef, 0 or 1
83 28         183 $offset = $self->in->start - $self->out->start;
84 28         238 $start = $value->start - $offset;
85 28         233 $end = $value->end - $offset;
86             }
87              
88             # strict prevents matches outside stated range
89 40 100       371 if ($self->strict) {
90 5 100 100     22 return if $start < 0 and $end < 0;
91 4 50       9 return if $start > $self->out->end;
92 4 100       42 $start = 1 if $start < 0;
93 4 100       8 $end = $self->out->end if $end > $self->out->end;
94             }
95              
96 39         146 my $match = Bio::Location::Simple->
97             new(-start => $start,
98             -end => $end,
99             -strand => $self->strand,
100             -seq_id => $self->out->seq_id,
101             -location_type => $value->location_type
102             );
103 39 50       5292 $match->strand($match->strand * $value->strand) if $value->strand;
104 39         688 bless $match, 'Bio::Coordinate::Result::Match';
105              
106 39         111 return $match;
107             }
108              
109             1;
110              
111             __END__