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.2';
37              
38             #######################################################################
39             ####################### Load External modules #####################
40             #######################################################################
41 2     2   1760 use Modern::Perl;
  2         6  
  2         20  
42 2     2   861 use Moose::Role;
  2         5715  
  2         14  
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 2452 my ($self) = @_;
67            
68 34         95 return $self->rname . ':' . $self->start . '-' . $self->stop . ':' . $self->strand;
69             }
70              
71             sub strand_symbol {
72 5     5 0 3751 my ($self) = @_;
73            
74 5 100       187 return undef if !defined $self->strand;
75            
76 4 100       105 if ($self->strand == 1) {
    50          
77 3         26 return '+';
78             }
79             elsif ($self->strand == -1) {
80 1         15 return '-';
81             }
82 0         0 return undef;
83             }
84              
85             sub head_position {
86 44     44 0 2495 my ($self) = @_;
87            
88 44 100       1145 if ($self->strand == 1) {
    50          
89 22         533 return $self->start;
90             }
91             elsif ($self->strand == -1) {
92 22         528 return $self->stop;
93             }
94             else {
95 0         0 return undef;
96             }
97             }
98              
99             sub tail_position {
100 36     36 0 2520 my ($self) = @_;
101            
102 36 100       896 if ($self->strand == 1) {
    50          
103 18         438 return $self->stop;
104             }
105             elsif ($self->strand == -1) {
106 18         434 return $self->start;
107             }
108             else {
109 0         0 return undef;
110             }
111             }
112              
113             sub mid_position {
114 33     33 0 2463 my ($self) = @_;
115            
116 33         920 return ($self->start + $self->stop)/2;
117             }
118              
119             sub mid_mid_distance_from {
120 10     10 0 2508 my ($self, $from_locus) = @_;
121            
122 10 100       42 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         27 return ($self->mid_position - $from_locus->mid_position) * $self->strand;
124             }
125              
126             sub mid_head_distance_from {
127 10     10 0 2510 my ($self, $from_locus) = @_;
128            
129 10 100       43 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         35 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 2607 my ($self, $from_locus) = @_;
149            
150 10 100       33 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         40 return ($self->head_position - $from_locus->head_position) * $self->strand;
152             }
153              
154             sub head_tail_distance_from {
155 10     10 0 2494 my ($self, $from_locus) = @_;
156            
157 10 100       35 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         26 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 2602 my ($self, $from_locus) = @_;
170            
171 10 100       43 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         30 return ($self->tail_position - $from_locus->head_position) * $self->strand;
173             }
174              
175             sub tail_tail_distance_from {
176 10     10 0 2572 my ($self, $from_locus) = @_;
177            
178 10 100       61 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         27 return ($self->tail_position - $from_locus->tail_position) * $self->strand;
180             }
181              
182             sub to_string {
183 2     2 0 2426 my ($self, $params) = @_;
184            
185 2         13 return $self->location;
186             }
187              
188             sub overlaps_with_offset {
189 22     22 0 2438 my ($self, $region2, $use_strand, $offset) = @_;
190            
191 22   100     80 $offset //= 0;
192 22   100     58 $use_strand //= 1;
193            
194 22 100 100     618 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         46 return 1; #overlap
196             }
197             else {
198 12         56 return 0; #no overlap
199             }
200             }
201              
202             sub overlaps {
203 232     232 0 2950 my ($self, $region2, $use_strand) = @_;
204            
205 232   100     1098 $use_strand //= 1;
206            
207 232 100 100     6061 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         899 return 1; #overlap
209             }
210             else {
211 9         41 return 0; #no overlap
212             }
213             }
214              
215             sub overlap_length {
216 8     8 0 2406 my ($self, $region2) = @_;
217            
218 8 100       35 if ($self->overlaps($region2)) {
219 4 100       95 my $max_start = $self->start > $region2->start ? $self->start : $region2->start;
220 4 50       94 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         14 return 0;
225             }
226             }
227              
228             sub contains {
229 12     12 0 2503 my ($self, $region2, $use_strand) = @_;
230            
231 12   50     69 $use_strand //= 1;
232            
233 12 100 66     435 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         23 return 1;
235             }
236             else {
237 8         42 return 0;
238             }
239             }
240              
241             sub contains_position {
242 22     22 0 2447 my ($self, $position) = @_;
243            
244 22 100 100     651 if (($self->start <= $position) and ($position <= $self->stop)) {
245 7         35 return 1;
246             }
247             else {
248 15         52 return 0;
249             }
250             }
251              
252             #######################################################################
253             ######################### Private methods ##########################
254             #######################################################################
255             sub _calculate_length {
256 51     51   112 my ($self) = @_;
257            
258 51         1265 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;