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   147990 use 5.012;
  2         27  
5 2     2   12 use warnings;
  2         3  
  2         81  
6 2     2   2604 use File::Fetch;
  2         187855  
  2         83  
7 2     2   20 use Carp qw(confess cluck);
  2         4  
  2         123  
8 2     2   1383 use Data::Dumper;
  2         14289  
  2         142  
9 2     2   1066 use FASTX::Reader;
  2         10  
  2         103  
10 2     2   15 use File::Basename;
  2         4  
  2         108  
11 2     2   14 use File::Spec;
  2         3  
  2         82  
12 2     2   1458 use Term::ANSIColor qw(color);
  2         20961  
  2         1409  
13 2     2   3362 use JSON::PP;
  2         30047  
  2         156  
14 2     2   3110 use Capture::Tiny qw(capture);
  2         9676  
  2         128  
15 2     2   14 use Time::HiRes qw( time );
  2         3  
  2         8  
16 2     2   178 use Scalar::Util qw( blessed refaddr reftype);
  2         4  
  2         4859  
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 1195 my ($class, $args) = @_;
28              
29 3         16 my %accepted_parameters = (
30             'verbose' => 1,
31             'debug' => 1,
32             'logfile' => 1,
33             'linesize'=> 1,
34             );
35              
36 3         18 my $valid_attributes = join(', ', keys %accepted_parameters);
37              
38 3         8 for my $parameter (keys %{ $args} ) {
  3         14  
39             confess("Attribute <$parameter> is not expected. Valid attributes are: $valid_attributes\n")
40 7 100       309 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     41 linesize => $args->{linesize} // 0,
      50        
      50        
      50        
49             };
50 2         7 my $object = bless $self, $class;
51              
52             # Regular log file
53 2 50       21 if (defined $self->{logfile}) {
54 2         13 verbose($self, "Ready to log in $object->{logfile}");
55 2   33     251 open my $logfh, '>', "$object->{logfile}" || confess("ERROR: Unable to write log file to $object->{logfile}\n");
56 2         17 $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 478 my $self = undef;
71 2 50       10 if ( ref($_[0]) eq 'FASTX::ScriptHelper' ) {
72 2         10 $self = shift @_;
73             }
74              
75 2         14 my ($name, $comment, $seq) = @_;
76 2 50       11 confess("No sequence provided for $name") unless defined $seq;
77 2         11 my $print_comment = '';
78 2 50       15 if (defined $comment) {
79 0         0 $print_comment = ' ' . $comment;
80             }
81              
82 2         21 say '>', $name, $print_comment;
83 2 50       17 if ($self) {
84 2         9 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 919 my $self = undef;
115 1 50       5 if ( ref($_[0]) eq 'FASTX::ScriptHelper' ) {
116 1         3 $self = shift @_;
117             }
118 1         3 my $sequence = reverse($_[0]);
119 1 50       3 if (is_seq($sequence)) {
120 1         5 $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       3 if ( ref($_[0]) eq 'FASTX::ScriptHelper' ) {
129 0         0 $self = shift @_;
130             }
131 1         2 my $string = shift @_;
132 1 50       5 if ($string =~/[^ACGTRYSWKMBDHVN]/i) {
133 0         0 return 0;
134             } else {
135 1         34 return 1;
136             }
137             }
138              
139              
140             sub split_string {
141 2     2 1 4 my $self = undef;
142 2 50       6 if ( ref($_[0]) eq 'FASTX::ScriptHelper' ) {
143 2         4 $self = shift @_;
144             }
145 2         8 my $input_string = shift @_;
146 2 50       15 confess("No string provided") unless $input_string;
147 2         12 my $formatted = '';
148 2   33     13 my $line_width = $self->{linesize} // $main::opt_line_size // 0; # change here
      0        
149              
150 2 50       11 return $input_string. "\n" unless ($line_width);
151 2         18 for (my $i = 0; $i < length($input_string); $i += $line_width) {
152 2         11 my $frag = substr($input_string, $i, $line_width);
153 2         8 $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       9 if ( ref($_[0]) eq 'FASTX::ScriptHelper' ) {
162 2         7 $self = shift @_;
163             }
164 2         7 my ($message, $reference, $reference_name, @remainder) = @_;
165 2 50 33     17 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     12 my $variable_name = $reference_name // 'data';
180 2         9 my $timestamp = _getTimeStamp();
181 2 50 33     18 if ( (defined $self and $self->{verbose} ) or (defined $main::opt_verbose and $main::opt_verbose) ) {
      0        
      33        
182             # Print
183 2 50       8 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       219 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 893 my $self = undef;
200 3 50       31 if ( ref($_[0]) eq 'FASTX::ScriptHelper' ) {
201 3         13 $self = shift @_;
202             }
203              
204 3         20 my ($message, $reference, $reference_name) = @_;
205 3   50     43 my $variable_name = $reference_name // 'data';
206 3         15 my $timestamp = _getTimeStamp();
207 3         106 say {$self->{logfh}} "[$timestamp] $message";
  3         44  
208 3 50       31 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         3 my $time_stamp = _getTimeStamp();
240 1         3 my $self = undef;
241 1 50       5 if ( ref($_[0]) eq 'FASTX::ScriptHelper' ) {
242 1         3 $self = shift @_;
243             }
244 1         4 my %valid_attributes = (
245             candie => 1,
246             logall => 1,
247             );
248              
249              
250 1         3 my ($command, $options) = @_;
251 1         3 _validate_attributes(\%valid_attributes, $options, 'run');
252 1 50       3 if (defined $self) {
253 1         5 $self->writelog("Shell> $command");
254             }
255              
256              
257 1         3 my $cmd = _runCmd($command);
258 1 50       16 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         26 $cmd->{duration} = sprintf("%.2fs", $end_time - $begin_time);
267 1 50       13 if (defined $self) {
268 1 50       7 if ($options->{logall}) {
269 0         0 $self->writelog(" +> Output: $cmd->{stdout}");
270 0         0 $self->writelog(" +> Messages: $cmd->{stderr}");
271             }
272 1         26 $self->writelog(" +> Elapsed time: $cmd->{duration}; Exit status: $cmd->{exit};");
273              
274             }
275              
276 1         13 return ($cmd);
277              
278              
279             }
280              
281              
282             sub cpu_count {
283 1 50   1 1 709 if ( $^O =~ m/linux/i ) {
    0          
284 1         7401 my($num) = qx(grep -c ^processor /proc/cpuinfo);
285 1 50       94 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   251 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
297 6         69 my $timestamp = sprintf ( "%04d-%02d-%02d %02d:%02d:%02d",
298             $year+1900,$mon+1,$mday,$hour,$min,$sec);
299 6         22 return $timestamp;
300             }
301              
302              
303             sub _validate_attributes {
304 1     1   2 my ($hash_ref, $options, $title) = @_;
305              
306 1         2 for my $attr (sort keys %{ $options } ) {
  1         6  
307 1 50       1 confess "Invalid attribute '$attr' used calling routine '$title'\n" if (not defined ${ $hash_ref}{ $attr });
  1         5  
308             }
309 1         2 return;
310             }
311             sub _runCmd {
312 1 50   1   7 if ( ref($_[0]) eq 'FASTX::ScriptHelper' ) {
313 0         0 shift @_;
314             }
315 1         3 my @cmd = @_;
316 1         19 my $output;
317 1         7 $output->{cmd} = join(' ', @cmd);
318              
319             my ($stdout, $stderr, $exit) = capture {
320 1     1   5682 system( @cmd );
321 1         33 };
322 1         1409 chomp($stderr);
323 1         10 chomp($stdout);
324 1         10 $output->{stdout} = $stdout;
325 1         3 $output->{stderr} = $stderr;
326 1         9 $output->{exit} = $exit;
327              
328 1         15 return $output;
329             }
330              
331              
332              
333             1;
334              
335             __END__