File Coverage

blib/lib/FASTX/ScriptHelper.pm
Criterion Covered Total %
statement 149 199 74.8
branch 31 82 37.8
condition 11 32 34.3
subroutine 26 28 92.8
pod 11 11 100.0
total 228 352 64.7


line stmt bran cond sub pod time code
1             package FASTX::ScriptHelper;
2             #ABSTRACT: Shared routines for binaries using FASTX::Reader and FASTX::PE.
3              
4 2     2   138169 use 5.012;
  2         28  
5 2     2   11 use warnings;
  2         4  
  2         77  
6 2     2   2016 use File::Fetch;
  2         174927  
  2         78  
7 2     2   18 use Carp qw(confess cluck);
  2         5  
  2         108  
8 2     2   1502 use Data::Dumper;
  2         13823  
  2         123  
9 2     2   1035 use FASTX::Reader;
  2         6  
  2         91  
10 2     2   128 use File::Basename;
  2         6  
  2         113  
11 2     2   15 use File::Spec;
  2         5  
  2         71  
12 2     2   2564 use Term::ANSIColor qw(color);
  2         19530  
  2         1626  
13 2     2   1543 use JSON::PP;
  2         27643  
  2         137  
14 2     2   2683 use Capture::Tiny qw(capture);
  2         8759  
  2         115  
15 2     2   13 use Time::HiRes qw( time );
  2         3  
  2         8  
16 2     2   171 use Scalar::Util qw( blessed refaddr reftype);
  2         3  
  2         4595  
17             $FASTX::ScriptHelper::VERSION = '0.1.2';
18              
19             our @ISA = qw(Exporter);
20             our @EXPORT = qw(rc fu_printfasta fu_printfastq verbose);
21             our @EXPORT_OK = qw($fu_linesize $fu_verbose); # symbols to export on request
22              
23              
24             sub new {
25              
26             # Instantiate object
27 3     3 1 1022 my ($class, $args) = @_;
28              
29 3         19 my %accepted_parameters = (
30             'verbose' => 1,
31             'debug' => 1,
32             'logfile' => 1,
33             'linesize'=> 1,
34             );
35              
36 3         16 my $valid_attributes = join(', ', keys %accepted_parameters);
37              
38 3         10 for my $parameter (keys %{ $args} ) {
  3         11  
39             confess("Attribute <$parameter> is not expected. Valid attributes are: $valid_attributes\n")
40 9 100       242 if (! $accepted_parameters{$parameter} );
41             }
42              
43              
44             my $self = {
45             logfile => $args->{logfile} // undef,
46             debug => $args->{debug} // 0,
47             verbose => $args->{verbose} // 0,
48 2   50     48 linesize => $args->{linesize} // 0,
      50        
      50        
      50        
49             };
50 2         7 my $object = bless $self, $class;
51              
52             # Regular log file
53 2 50       20 if (defined $self->{logfile}) {
54 2         14 verbose($self, "Ready to log in $object->{logfile}");
55 2   33     275 open my $logfh, '>', "$object->{logfile}" || confess("ERROR: Unable to write log file to $object->{logfile}\n");
56 2         18 $object->{logfh} = $logfh;
57 2         8 $object->{do_log} = 1;
58             } else {
59             # Set {logfh} to Stderr, but do not set {do_log}
60 0         0 $object->{logfh} = *STDERR;
61             }
62              
63 2         13 return $object;
64             }
65              
66              
67              
68             sub fu_printfasta {
69              
70 2     2 1 431 my $self = undef;
71 2 50       13 if ( ref($_[0]) eq 'FASTX::ScriptHelper' ) {
72 2         4 $self = shift @_;
73             }
74              
75 2         8 my ($name, $comment, $seq) = @_;
76 2 50       7 confess("No sequence provided for $name") unless defined $seq;
77 2         7 my $print_comment = '';
78 2 50       12 if (defined $comment) {
79 0         0 $print_comment = ' ' . $comment;
80             }
81              
82 2         26 say '>', $name, $print_comment;
83 2 50       13 if ($self) {
84 2         17 print split_string($self,$seq);
85             } else {
86 0         0 print split_string($seq);
87             }
88              
89             }
90              
91              
92             sub fu_printfastq {
93 0     0 1 0 my $self = undef;
94 0 0       0 if ( ref($_[0]) eq 'FASTX::ScriptHelper' ) {
95 0         0 $self = shift @_;
96             }
97 0         0 my ($name, $comment, $seq, $qual) = @_;
98 0         0 my $print_comment = '';
99 0 0       0 if (defined $comment) {
100 0         0 $print_comment = ' ' . $comment;
101             }
102 0 0       0 $qual = 'I' x length($seq) unless (defined $qual);
103 0         0 say '@', $name, $print_comment;
104 0 0       0 if ($self) {
105 0         0 print split_string($self,$seq) , "+\n", split_string($self,$qual);
106             } else {
107 0         0 print split_string($seq) , "+\n", split_string($qual);
108             }
109              
110             }
111              
112              
113             sub rc {
114 1     1 1 954 my $self = undef;
115 1 50       6 if ( ref($_[0]) eq 'FASTX::ScriptHelper' ) {
116 1         3 $self = shift @_;
117             }
118 1         4 my $sequence = reverse($_[0]);
119 1 50       5 if (is_seq($sequence)) {
120 1         3 $sequence =~tr/ACGTacgt/TGCAtgca/;
121 1         5 return $sequence;
122             }
123             }
124              
125              
126             sub is_seq {
127 1     1 1 2 my $self = undef;
128 1 50       4 if ( ref($_[0]) eq 'FASTX::ScriptHelper' ) {
129 0         0 $self = shift @_;
130             }
131 1         4 my $string = shift @_;
132 1 50       33 if ($string =~/[^ACGTRYSWKMBDHVN]/i) {
133 0         0 return 0;
134             } else {
135 1         7 return 1;
136             }
137             }
138              
139              
140             sub split_string {
141 2     2 1 7 my $self = undef;
142 2 50       14 if ( ref($_[0]) eq 'FASTX::ScriptHelper' ) {
143 2         4 $self = shift @_;
144             }
145 2         8 my $input_string = shift @_;
146 2 50       23 confess("No string provided") unless $input_string;
147 2         8 my $formatted = '';
148 2   33     8 my $line_width = $self->{linesize} // $main::opt_line_size // 0; # change here
      0        
149              
150 2 50       9 return $input_string. "\n" unless ($line_width);
151 2         11 for (my $i = 0; $i < length($input_string); $i += $line_width) {
152 2         4 my $frag = substr($input_string, $i, $line_width);
153 2         13 $formatted .= $frag."\n";
154             }
155 2         9 return $formatted;
156             }
157              
158              
159             sub verbose {
160 2     2 1 6 my $self = undef;
161 2 50       13 if ( ref($_[0]) eq 'FASTX::ScriptHelper' ) {
162 2         5 $self = shift @_;
163             }
164 2         8 my ($message, $reference, $reference_name, @remainder) = @_;
165 2 50 33     13 if ($remainder[0]) {
    50          
166 0         0 $message .= $reference . $reference_name . join('', @remainder);
167 0         0 $reference = undef;
168 0         0 $reference_name = undef;
169             } elsif (defined $reference and reftype $reference eq undef) {
170             # Mistakenly passed list instead of string
171 0         0 $message .= $reference;
172 0 0       0 if (defined $reference_name) {
173 0         0 $message .= $reference_name;
174 0         0 $reference_name = undef;
175             }
176 0         0 $reference = undef;
177              
178             }
179 2   50     11 my $variable_name = $reference_name // 'data';
180 2         8 my $timestamp = _getTimeStamp();
181 2 50 33     53 if ( (defined $self and $self->{verbose} ) or (defined $main::opt_verbose and $main::opt_verbose) ) {
      0        
      33        
182             # Print
183 2 50       12 if (defined $self->{do_log}) {
184 0         0 $self->writelog($message, $reference, $reference_name);
185             }
186 2         14 say STDERR color('cyan'),"[$timestamp]", color('reset'), " $message";
187 2 50       163 say STDERR color('magenta'), Data::Dumper->Dump([$reference], [$variable_name])
188             if (defined $reference);
189             } else {
190             # No --verbose, don't print
191 0         0 return -1;
192             }
193              
194             }
195              
196              
197              
198             sub writelog {
199 3     3 1 807 my $self = undef;
200 3 50       25 if ( ref($_[0]) eq 'FASTX::ScriptHelper' ) {
201 3         19 $self = shift @_;
202             }
203              
204 3         18 my ($message, $reference, $reference_name) = @_;
205 3   50     43 my $variable_name = $reference_name // 'data';
206 3         91 my $timestamp = _getTimeStamp();
207 3         12 say {$self->{logfh}} "[$timestamp] $message";
  3         46  
208 3 50       18 say {$self->{logfh}} Data::Dumper->Dump([$reference], [$variable_name]) if (defined $reference);
  0         0  
209              
210              
211             }
212              
213              
214              
215              
216             sub download {
217 0     0 1 0 my $begin_time = time();
218 0         0 my $self = undef;
219 0 0       0 if ( ref($_[0]) eq 'FASTX::ScriptHelper' ) {
220 0         0 $self = shift @_;
221             }
222              
223 0         0 my ($url, $destination) = @_;
224 0 0       0 if (defined $self->{do_log}) {
225 0         0 $self->writelog( qq(Downloading "$url") );
226             }
227              
228              
229 0         0 my $downloader = File::Fetch->new(uri => $url);
230 0 0       0 my $file_path = $downloader->fetch( to => $destination ) or confess($downloader->error);
231 0         0 my $end_time = time();
232 0         0 say Dumper $downloader;
233 0         0 my $duration = sprintf("%.2fs", $end_time - $begin_time);
234 0         0 return $file_path;
235             }
236              
237             sub run {
238 1     1 1 4 my $begin_time = time();
239 1         2 my $time_stamp = _getTimeStamp();
240 1         4 my $self = undef;
241 1 50       6 if ( ref($_[0]) eq 'FASTX::ScriptHelper' ) {
242 1         8 $self = shift @_;
243             }
244 1         794 my %valid_attributes = (
245             candie => 1,
246             logall => 1,
247             );
248              
249              
250 1         7 my ($command, $options) = @_;
251 1         5 _validate_attributes(\%valid_attributes, $options, 'run');
252 1 50       3 if (defined $self) {
253 1         6 $self->writelog("Shell> $command");
254             }
255              
256              
257 1         4 my $cmd = _runCmd($command);
258 1 50       9 if ($cmd->{exit}) {
259 0         0 $cmd->{failed} = 1;
260 0 0       0 if (! $options->{candie}) {
261 0         0 confess("Execution of an external command failed:\n$command");
262             }
263             }
264 1         14 my $end_time = time();
265 1         10 $cmd->{time} = $time_stamp;
266 1         28 $cmd->{duration} = sprintf("%.2fs", $end_time - $begin_time);
267 1 50       11 if (defined $self) {
268 1 50       11 if ($options->{logall}) {
269 0         0 $self->writelog(" +> Output: $cmd->{stdout}");
270 0         0 $self->writelog(" +> Messages: $cmd->{stderr}");
271             }
272 1         21 $self->writelog(" +> Elapsed time: $cmd->{duration}; Exit status: $cmd->{exit};");
273              
274             }
275              
276 1         10 return ($cmd);
277              
278              
279             }
280              
281              
282             sub cpu_count {
283 1 50   1 1 598 if ( $^O =~ m/linux/i ) {
    0          
284 1         8168 my($num) = qx(grep -c ^processor /proc/cpuinfo);
285 1 50       88 return $1 if $num =~ m/^(\d+)/;
286             }
287             elsif ( $^O =~ m/darwin/i ) {
288 0         0 my($num) = qx(system_profiler SPHardwareDataType | grep Cores);
289 0 0       0 return $1 if $num =~ /.*Cores: (\d+)/;
290             }
291 0         0 return 1;
292             }
293              
294             sub _getTimeStamp {
295              
296 6     6   243 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
297 6         62 my $timestamp = sprintf ( "%04d-%02d-%02d %02d:%02d:%02d",
298             $year+1900,$mon+1,$mday,$hour,$min,$sec);
299 6         21 return $timestamp;
300             }
301              
302              
303             sub _validate_attributes {
304 1     1   3 my ($hash_ref, $options, $title) = @_;
305              
306 1         2 for my $attr (sort keys %{ $options } ) {
  1         5  
307 1 50       2 confess "Invalid attribute '$attr' used calling routine '$title'\n" if (not defined ${ $hash_ref}{ $attr });
  1         6  
308             }
309 1         2 return;
310             }
311             sub _runCmd {
312 1 50   1   5 if ( ref($_[0]) eq 'FASTX::ScriptHelper' ) {
313 0         0 shift @_;
314             }
315 1         20 my @cmd = @_;
316 1         3 my $output;
317 1         5 $output->{cmd} = join(' ', @cmd);
318              
319             my ($stdout, $stderr, $exit) = capture {
320 1     1   5137 system( @cmd );
321 1         33 };
322 1         1373 chomp($stderr);
323 1         9 chomp($stdout);
324 1         8 $output->{stdout} = $stdout;
325 1         7 $output->{stderr} = $stderr;
326 1         10 $output->{exit} = $exit;
327              
328 1         15 return $output;
329             }
330              
331              
332              
333             1;
334              
335             __END__