File Coverage

blib/lib/BioX/Workflow/Command/run/Utils/Samples.pm
Criterion Covered Total %
statement 24 142 16.9
branch 0 48 0.0
condition 0 3 0.0
subroutine 8 18 44.4
pod n/a
total 32 211 15.1


line stmt bran cond sub pod time code
1             package BioX::Workflow::Command::run::Utils::Samples;
2              
3 1     1   2867 use MooseX::App::Role;
  1         4  
  1         12  
4 1     1   8645 use namespace::autoclean;
  1         2  
  1         7  
5              
6             with 'BioX::Workflow::Command::run::Rules::Directives::Sample';
7             with 'BioX::Workflow::Command::run::Rules::Rules';
8              
9 1     1   523 use File::Find::Rule;
  1         6500  
  1         7  
10 1     1   71 use File::Basename;
  1         3  
  1         57  
11 1     1   5 use File::Glob;
  1         3  
  1         47  
12 1     1   6 use List::Util qw(uniq);
  1         2  
  1         56  
13              
14 1     1   5 use Storable qw(dclone);
  1         3  
  1         42  
15 1     1   6 use Path::Tiny;
  1         2  
  1         1071  
16              
17             =head1 BioX::Workflow::Command::run::Utils::Samples
18              
19             =head2 Variables
20              
21              
22             =head2 Subroutines
23              
24             =head3 get_samples
25              
26             Get basename of the files. Can add optional rules.
27              
28             sample.vcf.gz and sample.vcf would be sample if the sample_rule is (.vcf)$|(.vcf.gz)$
29              
30             Also gets the full path to infiles
31              
32             Instead of doing
33              
34             foreach my $sample (@$self->samples){
35             dostuff
36             }
37              
38             Could have
39              
40             foreach my $infile (@$self->infiles){
41             dostuff
42             }
43              
44             =cut
45              
46             sub get_samples {
47 0     0     my $self = shift;
48              
49             #Stupid resample
50 0           $self->get_global_keys;
51              
52 0           my $exists = $self->check_sample_exist;
53 0 0         return if $exists;
54              
55             #We need to evaluate the global_dirs incase the indir has a var
56             #But we don't keep it around, because that would be madness
57 0           my $attr = dclone( $self->global_attr );
58 0 0         if ( $attr->indir =~ m/\{\$/ ) {
59 0           $attr->walk_process_data( $self->global_keys );
60             }
61              
62 0           my $text = $self->get_sample_rule;
63 0           $self->find_sample_glob( $attr, $text );
64 0           $self->find_sample_file_find_rule( $attr, $text );
65              
66 0 0         if ( $self->has_no_samples ) {
67 0           $self->app_log->warn('No samples were found!');
68 0           $self->app_log->warn(
69             "Indir: " . $attr->indir . "\tSearch: " . $text . "\n" );
70             }
71              
72 0           $self->remove_excluded_samples;
73 0           $self->write_sample_meta;
74             }
75              
76             sub remove_excluded_samples {
77 0     0     my $self = shift;
78              
79 0 0         return unless $self->has_samples;
80 0 0         return unless $self->has_exclude_samples;
81              
82 0           my %sample_hash = ();
83 0           map { $sample_hash{$_} = 1 } @{ $self->samples };
  0            
  0            
84              
85 0           foreach my $sample ( $self->all_exclude_samples ) {
86 0           delete $sample_hash{$sample};
87             }
88              
89 0           my @new_samples = keys %sample_hash;
90 0           @new_samples = sort(@new_samples);
91 0           $self->samples( \@new_samples );
92             }
93              
94             sub find_sample_glob {
95 0     0     my $self = shift;
96 0           my $attr = shift;
97 0           my $text = shift;
98              
99 0 0         return if $self->has_samples;
100 0 0         return unless $attr->has_sample_glob;
101              
102 0           my @sample_files = glob( $attr->sample_glob );
103 0 0         if ( !@sample_files ) {
104 0           $self->app_log->warn( "No samples were found with the glob pattern '"
105             . $attr->sample_glob
106             . "'" );
107 0           return;
108             }
109              
110 0           @sample_files = sort(@sample_files);
111 0 0         $self->sample_files( \@sample_files ) if @sample_files;
112              
113 0           my @basename = map { $self->match_samples( $_, $text ) } @sample_files;
  0            
114 0 0         if (@basename) {
115 0           @basename = uniq(@basename);
116 0           @basename = sort(@basename);
117 0           $self->samples( \@basename );
118             }
119              
120 0           $self->global_attr->samples( dclone( $self->samples ) );
121             }
122              
123             sub get_sample_rule {
124 0     0     my $self = shift;
125 0           my $text;
126              
127             #Backwards compatibility
128             #For both file_rule and sample_rule
129 0 0   0     if ( $self->first_index_global_keys( sub { $_ eq 'file_rule' } ) != -1 ) {
  0 0          
130 0           $text = $self->global_attr->sample_rule;
131             }
132             elsif (
133 0     0     $self->first_index_global_keys( sub { $_ eq 'sample_rule' } ) != -1 )
134             {
135 0           $text = $self->global_attr->sample_rule;
136             }
137             else {
138 0           $text = $self->sample_rule;
139             }
140             }
141              
142             sub find_sample_file_find_rule {
143 0     0     my $self = shift;
144 0           my $attr = shift;
145 0           my $text = shift;
146              
147 0 0         return if $self->has_samples;
148              
149 0           my ( @whole, @basename, @sample_files, $find_sample_bydir );
150              
151 0           $find_sample_bydir = 0;
152              
153 0 0         if ( $attr->find_sample_bydir ) {
154 0           @whole = find(
155             directory => name => qr/$text/,
156             maxdepth => $attr->maxdepth,
157             in => $attr->indir,
158             extras => { follow => 1 },
159             );
160              
161 0 0         if (@whole) {
162 0 0         if ( $whole[0] eq $attr->indir ) {
163 0           shift(@whole);
164             }
165             }
166             }
167             else {
168 0           @whole = find(
169             file => name => qr/$text/,
170             maxdepth => $attr->maxdepth,
171             extras => { follow => 1 },
172             in => $attr->indir
173             );
174             }
175 0           @basename = map { $self->match_samples( $_, $text ) } @whole;
  0            
176              
177 0           @sample_files = map { path($_)->absolute } @whole;
  0            
178 0           @sample_files = sort(@sample_files);
179              
180 0 0         if (@basename) {
181 0           @basename = uniq(@basename);
182 0           @basename = sort(@basename);
183 0           $self->samples( \@basename );
184             }
185 0 0         $self->sample_files( \@sample_files ) if @sample_files;
186              
187 0           $self->global_attr->samples( dclone( $self->samples ) );
188             }
189              
190             sub check_sample_exist {
191 0     0     my $self = shift;
192              
193 0           my $exists = 0;
194 0 0 0       if ( $self->has_samples && !$self->resample ) {
    0          
195 0           my (@samples) = $self->sorted_samples;
196 0           $self->samples( \@samples );
197             ## Fixes Issue #19
198 0           $self->global_attr->samples( \@samples );
199 0           $self->app_log->info('Samples passed in on command line.');
200 0           $exists = 1;
201             }
202             elsif ( $self->global_attr->has_samples ) {
203 0           my (@samples) = @{ $self->global_attr->samples };
  0            
204 0           @samples = sort(@samples);
205 0           $self->samples( \@samples );
206 0           $self->app_log->info('Samples were defined in the global key.');
207 0           $exists = 1;
208             }
209              
210 0 0         $self->write_sample_meta if $exists;
211 0           return $exists;
212             }
213              
214             =head2 match_samples
215              
216             Match samples based on regex written in sample_rule
217              
218             =cut
219              
220             sub match_samples {
221 0     0     my $self = shift;
222 0           my $file = shift;
223 0           my $text = shift;
224              
225 0 0         if ( $text =~ m/\(/ ) {
226 0           my @tmp = fileparse($file);
227 0           my ($m) = $tmp[0] =~ qr/$text/;
228              
229 0           return $m;
230             }
231             else {
232 0           my @tmp = fileparse($file);
233 0           return $tmp[0];
234             }
235             }
236              
237             =head3 process_by_sample_outdir
238              
239             Make sure indir/outdirs are named appropriated for samples when using by
240              
241             =cut
242              
243             sub process_by_sample_outdir {
244 0     0     my $self = shift;
245 0           my $sample = shift;
246              
247 0           my ( $tt, $key );
248 0           $tt = $self->outdir;
249 0           $key = $self->key;
250 0           $tt =~ s/$key/$sample\/$key/;
251 0           $self->outdir($tt);
252 0           $self->make_outdir;
253              
254 0           $tt = $self->indir;
255 0 0         if ( $tt =~ m/\{\$self/ ) {
    0          
256 0           $tt = "$tt/{\$sample}";
257 0           $self->indir($tt);
258             }
259             elsif ( $self->has_pkey ) {
260 0           $key = $self->pkey;
261 0           $tt =~ s/$key/$sample\/$key/;
262 0           $self->indir($tt);
263             }
264             else {
265 0           $tt = "$tt/$sample";
266 0           $self->indir($tt);
267             }
268             }
269              
270             1;