File Coverage

blib/lib/GenOO/Region.pm
Criterion Covered Total %
statement 71 88 80.6
branch 36 46 78.2
condition 36 53 67.9
subroutine 20 24 83.3
pod 0 20 0.0
total 163 231 70.5


line stmt bran cond sub pod time code
1             # POD documentation - main docs before the code
2              
3             =head1 NAME
4              
5             GenOO::Region - Role that represents a region on a reference sequence
6              
7             =head1 SYNOPSIS
8              
9             This role when consumed requires specific attributes and provides
10             methods that correspond to a region on a reference sequence.
11              
12             =head1 DESCRIPTION
13              
14             A region object is an area on another reference sequence. It has a
15             specific start and stop position on the reference and a specific
16             direction (strand). It has methods that combine the direction with
17             the positional information a give positions for the head or the tail
18             of the region. It also offers methods that calculate distances or
19             overlaps with other object that also consume the role.
20              
21             =head1 EXAMPLES
22              
23             # Get the location information on the reference sequence
24             $obj_with_role->start; # 10
25             $obj_with_role->stop; # 20
26             $obj_with_role->strand; # -1
27            
28             # Get the head position on the reference sequence
29             $obj_with_role->head_position; # 20
30              
31             =cut
32              
33             # Let the code begin...
34              
35             package GenOO::Region;
36             $GenOO::Region::VERSION = '1.5.1';
37              
38             #######################################################################
39             ####################### Load External modules #####################
40             #######################################################################
41 2     2   1200 use Modern::Perl;
  2         2  
  2         15  
42 2     2   254 use Moose::Role;
  2         3  
  2         15  
43              
44              
45             #######################################################################
46             ####################### Required attributes #######################
47             #######################################################################
48             requires qw(strand rname start stop copy_number);
49              
50              
51             #######################################################################
52             ####################### Interface attributes ######################
53             #######################################################################
54             has 'length' => (
55             is => 'ro',
56             builder => '_calculate_length',
57             init_arg => undef,
58             lazy => 1,
59             );
60              
61              
62             #######################################################################
63             ######################## Interface Methods ########################
64             #######################################################################
65             sub location {
66 34     34 0 2383 my ($self) = @_;
67            
68 34         79 return $self->rname . ':' . $self->start . '-' . $self->stop . ':' . $self->strand;
69             }
70              
71             sub strand_symbol {
72 5     5 0 3332 my ($self) = @_;
73            
74 5 100       205 return undef if !defined $self->strand;
75            
76 4 100       130 if ($self->strand == 1) {
    50          
77 3         23 return '+';
78             }
79             elsif ($self->strand == -1) {
80 1         7 return '-';
81             }
82 0         0 return undef;
83             }
84              
85             sub head_position {
86 44     44 0 2400 my ($self) = @_;
87            
88 44 100       1330 if ($self->strand == 1) {
    50          
89 22         627 return $self->start;
90             }
91             elsif ($self->strand == -1) {
92 22         617 return $self->stop;
93             }
94             else {
95 0         0 return undef;
96             }
97             }
98              
99             sub tail_position {
100 36     36 0 2422 my ($self) = @_;
101            
102 36 100       1108 if ($self->strand == 1) {
    50          
103 18         526 return $self->stop;
104             }
105             elsif ($self->strand == -1) {
106 18         561 return $self->start;
107             }
108             else {
109 0         0 return undef;
110             }
111             }
112              
113             sub mid_position {
114 33     33 0 2092 my ($self) = @_;
115            
116 33         809 return ($self->start + $self->stop)/2;
117             }
118              
119             sub mid_mid_distance_from {
120 10     10 0 1971 my ($self, $from_locus) = @_;
121            
122 10 100       29 die join(' ', 'Comparing relative position for regions on different reference (rname)',$self->rname,'ne',$from_locus->rname)."\n" if ($self->rname ne $from_locus->rname);
123 8         16 return ($self->mid_position - $from_locus->mid_position) * $self->strand;
124             }
125              
126             sub mid_head_distance_from {
127 10     10 0 1999 my ($self, $from_locus) = @_;
128            
129 10 100       27 die join(' ', 'Comparing relative position for regions on different reference (rname)',$self->rname,'ne',$from_locus->rname)."\n" if ($self->rname ne $from_locus->rname);
130 8         28 return ($self->mid_position - $from_locus->head_position) * $self->strand;
131             }
132              
133             sub mid_tail_distance_from {
134 0     0 0 0 my ($self, $from_locus) = @_;
135            
136 0 0       0 die join(' ', 'Comparing relative position for regions on different reference (rname)',$self->rname,'ne',$from_locus->rname)."\n" if ($self->rname ne $from_locus->rname);
137 0         0 return ($self->mid_position - $from_locus->tail_position) * $self->strand;
138             }
139              
140             sub head_mid_distance_from {
141 0     0 0 0 my ($self, $from_locus) = @_;
142            
143 0 0       0 die join(' ', 'Comparing relative position for regions on different reference (rname)',$self->rname,'ne',$from_locus->rname)."\n" if ($self->rname ne $from_locus->rname);
144 0         0 return ($self->head_position - $from_locus->mid_position) * $self->strand;
145             }
146              
147             sub head_head_distance_from {
148 10     10 0 1938 my ($self, $from_locus) = @_;
149            
150 10 100       32 die join(' ', 'Comparing relative position for regions on different reference (rname)',$self->rname,'ne',$from_locus->rname)."\n" if ($self->rname ne $from_locus->rname);
151 8         36 return ($self->head_position - $from_locus->head_position) * $self->strand;
152             }
153              
154             sub head_tail_distance_from {
155 10     10 0 2397 my ($self, $from_locus) = @_;
156            
157 10 100       30 die join(' ', 'Comparing relative position for regions on different reference (rname)',$self->rname,'ne',$from_locus->rname)."\n" if ($self->rname ne $from_locus->rname);
158 8         30 return ($self->head_position - $from_locus->tail_position) * $self->strand;
159             }
160              
161             sub tail_mid_distance_from {
162 0     0 0 0 my ($self, $from_locus) = @_;
163            
164 0 0       0 die join(' ', 'Comparing relative position for regions on different reference (rname)',$self->rname,'ne',$from_locus->rname)."\n" if ($self->rname ne $from_locus->rname);
165 0         0 return ($self->tail_position - $from_locus->mid_position) * $self->strand;
166             }
167              
168             sub tail_head_distance_from {
169 10     10 0 2213 my ($self, $from_locus) = @_;
170            
171 10 100       38 die join(' ', 'Comparing relative position for regions on different reference (rname)',$self->rname,'ne',$from_locus->rname)."\n" if ($self->rname ne $from_locus->rname);
172 8         29 return ($self->tail_position - $from_locus->head_position) * $self->strand;
173             }
174              
175             sub tail_tail_distance_from {
176 10     10 0 2423 my ($self, $from_locus) = @_;
177            
178 10 100       34 die join(' ', 'Comparing relative position for regions on different reference (rname)',$self->rname,'ne',$from_locus->rname)."\n" if ($self->rname ne $from_locus->rname);
179 8         25 return ($self->tail_position - $from_locus->tail_position) * $self->strand;
180             }
181              
182             sub to_string {
183 2     2 0 2384 my ($self, $params) = @_;
184            
185 2         10 return $self->location;
186             }
187              
188             sub overlaps_with_offset {
189 22     22 0 2571 my ($self, $region2, $use_strand, $offset) = @_;
190            
191 22   100     84 $offset //= 0;
192 22   100     60 $use_strand //= 1;
193            
194 22 100 100     776 if (($use_strand == 0 or $self->strand == $region2->strand) and ($self->rname eq $region2->rname) and (($self->start-$offset) <= $region2->stop) and ($region2->start <= ($self->stop+$offset))) {
      66        
      66        
      66        
195 10         54 return 1; #overlap
196             }
197             else {
198 12         67 return 0; #no overlap
199             }
200             }
201              
202             sub overlaps {
203 232     232 0 2731 my ($self, $region2, $use_strand) = @_;
204            
205 232   100     721 $use_strand //= 1;
206            
207 232 100 100     5870 if (($use_strand == 0 or $self->strand == $region2->strand) and ($self->rname eq $region2->rname) and ($self->start <= $region2->stop) and ($region2->start <= $self->stop)) {
      66        
      66        
      33        
208 223         839 return 1; #overlap
209             }
210             else {
211 9         40 return 0; #no overlap
212             }
213             }
214              
215             sub overlap_length {
216 8     8 0 2760 my ($self, $region2) = @_;
217            
218 8 100       27 if ($self->overlaps($region2)) {
219 4 100       135 my $max_start = $self->start > $region2->start ? $self->start : $region2->start;
220 4 50       115 my $min_stop = $self->stop < $region2->stop ? $self->stop : $region2->stop;
221 4         25 return $min_stop - $max_start + 1 ;
222             }
223             else {
224 4         18 return 0;
225             }
226             }
227              
228             sub contains {
229 12     12 0 2202 my ($self, $region2, $use_strand) = @_;
230            
231 12   50     60 $use_strand //= 1;
232            
233 12 100 66     408 if (($use_strand == 0 or $self->strand == $region2->strand) and ($self->rname eq $region2->rname) and ($self->start <= $region2->start) and ($region2->stop <= $self->stop)) {
      66        
      100        
      66        
234 4         24 return 1;
235             }
236             else {
237 8         48 return 0;
238             }
239             }
240              
241             sub contains_position {
242 22     22 0 2227 my ($self, $position) = @_;
243            
244 22 100 100     507 if (($self->start <= $position) and ($position <= $self->stop)) {
245 7         36 return 1;
246             }
247             else {
248 15         42 return 0;
249             }
250             }
251              
252             #######################################################################
253             ######################### Private methods ##########################
254             #######################################################################
255             sub _calculate_length {
256 51     51   57 my ($self) = @_;
257            
258 51         1286 return $self->stop - $self->start + 1;
259             }
260              
261             sub _to_string_bed {
262 0     0     my ($self) = @_;
263            
264 0   0       my $strand_symbol = $self->strand_symbol || '.';
265 0   0       my $name = $self->name || '.';
266 0   0       my $score = $self->copy_number || 1;
267            
268 0           return $self->rname."\t".$self->start."\t".($self->stop+1)."\t".$name."\t".$score."\t".$strand_symbol;
269             }
270              
271             1;