File Coverage

lib/App/SimulateReads/Read/PairedEnd.pm
Criterion Covered Total %
statement 30 30 100.0
branch 6 6 100.0
condition 3 3 100.0
subroutine 6 6 100.0
pod 0 2 0.0
total 45 47 95.7


line stmt bran cond sub pod time code
1             package App::SimulateReads::Read::PairedEnd;
2             # ABSTRACT: App::SimulateReads::Read subclass for simulate paired-end reads.
3              
4 6     6   42 use App::SimulateReads::Base 'class';
  6         18  
  6         42  
5 6     6   2962 use Math::Random 'random_normal';
  6         29964  
  6         567  
6              
7             extends 'App::SimulateReads::Read';
8              
9             our $VERSION = '0.05'; # VERSION
10              
11             use constant {
12 6         3295 NUM_TRIES => 1000
13 6     6   47 };
  6         11  
14              
15             #-------------------------------------------------------------------------------
16             # Moose attributes
17             #-------------------------------------------------------------------------------
18             has 'fragment_mean' => (is => 'ro', isa => 'My:IntGt0', required => 1);
19             has 'fragment_stdd' => (is => 'ro', isa => 'My:IntGe0', required => 1);
20              
21             #=== CLASS METHOD ============================================================
22             # CLASS: Read::PairedEnd
23             # METHOD: BUILD (Moose)
24             # PARAMETERS: Void
25             # RETURNS: Void
26             # DESCRIPTION: Test if fragment_mean is greater or equal to read_size
27             # THROWS: If fragment_mean is lesser than read_size, throws an error
28             # COMMENTS: none
29             # SEE ALSO: n/a
30             #===============================================================================
31             sub BUILD {
32 38     38 0 77 my $self = shift;
33 38 100       1059 unless (($self->fragment_mean - $self->fragment_stdd) >= $self->read_size) {
34 5         140 croak "fragment_mean (" . $self->fragment_mean . ") minus fragment_stdd (" . $self->fragment_stdd .
35             ") must be greater or equal to read_size (" . $self->read_size . ")\n";
36             }
37             } ## --- end sub BUILD
38              
39             #=== CLASS METHOD ============================================================
40             # CLASS: Read::PairedEnd
41             # METHOD: gen_read
42             # PARAMETERS: $seq_ref Ref Str, $seq_size Int > 0, $is_leader Bool
43             # RETURNS: $read1_ref Ref Str, $read2_ref Ref Str, $fragment_pos Int >= 0,
44             # $fragment_size Int > 0
45             # DESCRIPTION: Generate paired-end read
46             # THROWS: It complex, beacuse depending of the fragment_size, fragment_stdd
47             # and read_size the method may raffle a fragment lesser than read_size.
48             # So, the method gives NUM_TRIES chances to slice a fragment greater or
49             # equal to read_size. If it fails, throws an exception.
50             # COMMENTS: The fragment_size must be inside a normal distribution
51             # SEE ALSO: n/a
52             #===============================================================================
53             sub gen_read {
54 1177     1177 0 40931 my ($self, $seq_ref, $seq_size, $is_leader) = @_;
55              
56 1177         1853 my $fragment_size;
57 1177         1855 my $random_tries = 0;
58              
59 1177   100     1742 do {
60             # seq_size must be greater or equal to fragment_size and
61             # fragment_size must be greater or equal to read_size
62             # As fragment_size is randomly calculated, try out NUM_TRIES times
63 6177 100       64639 if (++$random_tries == NUM_TRIES) {
64 5         275 croak "Paired-end read fail: So many tries to calculate a fragment. the constraints were not met:\n" .
65             "fragment_size <= seq_size ($seq_size) and fragment_size >= read_size (" . $self->read_size . ")\n";
66             }
67              
68 6172         11339 $fragment_size = $self->_random_half_normal;
69             } until ($fragment_size <= $seq_size) && ($fragment_size >= $self->read_size);
70              
71 1172         4041 my ($fragment_ref, $fragment_pos) = $self->subseq_rand($seq_ref, $seq_size, $fragment_size);
72              
73 1172         34260 my $read1_ref = $self->subseq($fragment_ref, $fragment_size, $self->read_size, 0);
74 1172         33339 $self->update_count_base($self->read_size);
75 1172         4122 $self->insert_sequencing_error($read1_ref);
76              
77 1172         34248 my $read2_ref = $self->subseq($fragment_ref, $fragment_size, $self->read_size, $fragment_size - $self->read_size);
78 1172         3805 $self->reverse_complement($read2_ref);
79 1172         39411 $self->update_count_base($self->read_size);
80 1172         3611 $self->insert_sequencing_error($read2_ref);
81              
82 1172 100       5880 return $is_leader ?
83             ($read1_ref, $read2_ref, $fragment_pos, $fragment_size) :
84             ($read2_ref, $read1_ref, $fragment_pos, $fragment_size);
85             } ## --- end sub gen_read
86              
87             #=== CLASS METHOD ============================================================
88             # CLASS: Read::PairedEnd
89             # METHOD: _random_half_normal (PRIVATE)
90             # PARAMETERS: Void
91             # RETURNS: Int > 0
92             # DESCRIPTION: Wrapper to random_normal function that returns value inside a
93             # half normal distribution
94             # THROWS: no exceptions
95             # COMMENTS: none
96             # SEE ALSO: n/a
97             #===============================================================================
98             sub _random_half_normal {
99 6172     6172   8819 my $self = shift;
100 6172         186187 return abs(int(random_normal(1, $self->fragment_mean, $self->fragment_stdd)));
101             } ## --- end sub _random_half_normal
102              
103             __END__
104              
105             =pod
106              
107             =encoding UTF-8
108              
109             =head1 NAME
110              
111             App::SimulateReads::Read::PairedEnd - App::SimulateReads::Read subclass for simulate paired-end reads.
112              
113             =head1 VERSION
114              
115             version 0.05
116              
117             =head1 AUTHOR
118              
119             Thiago L. A. Miller <tmiller@mochsl.org.br>
120              
121             =head1 COPYRIGHT AND LICENSE
122              
123             This software is Copyright (c) 2017 by Teaching and Research Institute from Sírio-Libanês Hospital.
124              
125             This is free software, licensed under:
126              
127             The GNU General Public License, Version 3, June 2007
128              
129             =cut