File Coverage

blib/lib/BioX/Workflow/Command/run/Utils/Samples.pm
Criterion Covered Total %
statement 21 136 15.4
branch 0 46 0.0
condition 0 3 0.0
subroutine 7 17 41.1
pod n/a
total 28 202 13.8


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