File Coverage

blib/lib/BioX/Wrapper/Gemini.pm
Criterion Covered Total %
statement 27 126 21.4
branch 0 24 0.0
condition 0 3 0.0
subroutine 9 15 60.0
pod n/a
total 36 168 21.4


line stmt bran cond sub pod time code
1             package BioX::Wrapper::Gemini;
2              
3 1     1   16274 use 5.008_005;
  1         4  
  1         47  
4              
5             our $VERSION = '0.03';
6              
7 1     1   604 use Moose;
  1         415756  
  1         6  
8 1     1   6112 use File::Find::Rule;
  1         6852  
  1         9  
9 1     1   59 use File::Basename;
  1         2  
  1         76  
10 1     1   5 use File::Path qw(make_path remove_tree);
  1         1  
  1         47  
11 1     1   4 use File::Find::Rule;
  1         1  
  1         3  
12 1     1   24 use Cwd;
  1         1  
  1         44  
13 1     1   693 use Data::Dumper;
  1         5574  
  1         66  
14 1     1   777 use List::Compare;
  1         17507  
  1         1173  
15              
16             extends 'BioX::Wrapper';
17             with 'MooseX::Getopt';
18             with 'MooseX::Getopt::Usage';
19              
20             =head1 BioX::Wrapper::Gemini
21              
22             Wrapper around Gemini for processing files
23              
24             Read more about Gemini here: http://gemini.readthedocs.org/en/latest/
25              
26             The workflow described is taken straight from the documentation written by the
27             author of Gemini.
28              
29             =cut
30              
31             =head2 Attributes
32              
33             Moose Attributes
34              
35             =head2 vcfs
36              
37             VCF files can be given individually as well.
38              
39             #Option is an ArrayRef and can be given as either
40              
41             --vcfs 1.vcf,2.vcf,3.vcfs
42              
43             #or
44              
45             --vcfs 1.vcf --vcfs 2.vcf --vcfs 3.vcf
46              
47             Don't mix the methods
48              
49             If these vcfs are uncompressed, they will be compressed in place. Please make sure either this location has read/write access, or create a symbolic link to someplace
50              
51             Everytime you leave genomics data uncompressed a kitten dies!
52              
53             =cut
54              
55             has 'vcfs' => (
56             is => 'rw',
57             isa => 'ArrayRef',
58             required => 0,
59             );
60              
61             =head2 uncomvcfs
62              
63             Vcfs that are uncompressed
64              
65             =cut
66              
67             has 'uncomvcfs' => (
68             is => 'rw',
69             isa => 'ArrayRef',
70             required => 0,
71             default => sub{[]},
72             );
73              
74             =head2 ref
75              
76             Supply a path to a reference genome
77              
78             Default is to assume there is an environmental variable $REFGENOME
79              
80             =cut
81              
82             has 'ref' => (
83             is => 'rw',
84             isa => 'Str',
85             required => 0,
86             default => "\$REFGENOME",
87             );
88              
89             =head2 snpeff
90              
91             Base directory of snpeff
92              
93             The default assumes there is an environmental variable of $SNPEFF, being the base directory of the snpeff installation.
94              
95             =cut
96              
97             # TODO
98             # Add documentation for bioinformatics modules using environment modules
99              
100             has 'snpeff' => (
101             is => 'rw',
102             isa => 'Str',
103             required => 0,
104             default => "\$SNPEFF",
105             );
106              
107             =head2 snpeff_opt
108              
109             Options to run snpeff with
110              
111             Default is -c \$SNPEFF/snpEff.config -formatEff -classic GRCh37.75
112              
113             =cut
114              
115             has snpeff_opt => (
116             is => 'rw',
117             isa => 'Str',
118             required => 0,
119             default => '-c \$SNPEFF/snpEff.config -formatEff -classic GRCh37.75 ',
120             );
121              
122             =head2 ped
123              
124             If all vcf files are being loaded into the gemini db with the same pedigree file, simply change the --db_load_opts to correspond to your file.
125              
126             If each vcf file has its own pedigree, make sure the pedigree file matches the basename of the vcf.
127              
128             Basenames are captured like so:
129              
130             my @gzipbase = map { basename($_, ".vcf.gz") } @gzipped ;
131             my @notgzipbase = map { basename($_, ".vcf") } @notgzipped ;
132              
133             With the extension being .vcf.gz/.vcf
134              
135             Invoke this with --ped
136              
137             Exact specifications should be found here:
138              
139             http://gemini.readthedocs.org/en/latest/content/preprocessing.html#describing-samples-with-a-ped-file
140              
141             =cut
142              
143             has 'ped' => (
144             is => 'rw',
145             isa => 'Bool',
146             required => 0,
147             default => 0,
148             );
149              
150             =head2 ped_dir
151              
152             If using the --ped option you must specify this if your pedigree files are not in the same directory as the --indir option
153              
154             =cut
155              
156             has 'ped_dir' => (
157             is => 'rw',
158             isa => 'Str',
159             required => 0,
160             lazy => 1,
161             default => '',
162             );
163              
164             =head2 db_load_opts
165              
166             Options for loading VCF file into gemini sqlite db
167              
168             Default is --skip_cadd -t snpEff
169              
170             =cut
171              
172             has db_load_opts => (
173             is => 'rw',
174             isa => 'Str',
175             required => 0,
176             default => "--skip-cadd -t snpEff"
177             );
178              
179             =head2 Subroutines
180              
181             Subroutines
182              
183             =cut
184              
185             =head2 check_files
186              
187             Check to make sure either an indir or vcfs are supplied
188              
189             =cut
190              
191             sub check_files {
192 0     0     my($self) = @_;
193              
194 0           my($t);
195              
196 0 0 0       die print "Must specificy an indirectory or vcfs!\n" if (!$self->indir && !$self->vcfs);
197              
198 0 0         if($self->indir){
199 0           $t = $self->indir;
200 0           $t =~ s/\/$//g;
201 0           $self->indir($t);
202             }
203              
204 0           $t = $self->outdir;
205 0           $t =~ s/\/$//g;
206 0           $t = $t."/gemini-wrapper";
207 0           $self->outdir($t);
208              
209             #make the outdir
210 0 0         make_path($self->outdir) if ! -d $self->outdir;
211 0 0         make_path($self->outdir."/norm_annot_vcf") if ! -d $self->outdir."/norm_annot_vcf";
212 0 0         make_path($self->outdir."/gemini_sqlite") if ! -d $self->outdir."/gemini_sqlite";
213             }
214              
215             =head2 find_vcfs
216              
217             Use File::Find::Rule to find the vcfs
218              
219             Make sure they are all gzipped first. If there are any .vcf$ files without a corresponding .vcf.gz$, bgzip those
220              
221             =cut
222              
223             sub find_vcfs{
224 0     0     my($self) = @_;
225              
226 0 0         return if $self->vcfs;
227 0           $self->vcfs([]);
228              
229 0           my @gzipped = File::Find::Rule->file->name(qr/(\.vcf\.gz)$/)->in( $self->indir);
230 0           my @notgzipped = File::Find::Rule->file->name(qr/(\.vcf)$/)->in( $self->indir);
231              
232 0           my @gzipbase = map { basename($_, ".vcf.gz") } @gzipped ;
  0            
233 0           my @notgzipbase = map { basename($_, ".vcf") } @notgzipped ;
  0            
234              
235 0           my $lc = List::Compare->new(\@notgzipbase, \@gzipbase);
236              
237 0           my @gzipthese = $lc->get_Lonly;
238              
239 0 0         if(@gzipthese){
240 0           foreach my $i (@gzipthese){
241 0           push(@{$self->uncomvcfs}, $self->indir."/".$i.".vcf");
  0            
242             #push(@{$self->vcfs}, $self->indir."/".$i.".vcf.gz");
243 0           push(@{$self->vcfs}, $i);
  0            
244             }
245             }
246              
247 0           foreach my $i (@gzipbase){
248             #push(@{$self->vcfs}, $self->indir."/".$i.".vcf.gz")
249 0           push(@{$self->vcfs}, $i);
  0            
250             }
251              
252 0           print "\n\n#######################################################################\n";
253 0           print "# Starting Sample Info Section\n";
254 0           print "#######################################################################\n\n";
255              
256 0           print "# ".join(", ", @{$self->vcfs})."\n";
  0            
257              
258 0           print "\n#######################################################################\n";
259 0           print "# Ending Sample Info Section\n";
260 0           print "#######################################################################\n";
261              
262 0           $self->bgzip();
263 0 0         die print "No vcfs were found!\n" unless $self->vcfs;
264             }
265              
266             =head2 bgzip
267              
268             Run bgzip command on files found in find_vcfs
269              
270             =cut
271              
272             sub bgzip{
273 0     0     my($self) = shift;
274              
275 0 0         return unless $self->uncomvcfs;
276              
277 0           print "\n\n#######################################################################\n";
278 0           print "# Starting Bgzip Section\n";
279 0           print "#######################################################################\n";
280 0           print "# The following samples must be bgzipped before processing can begin\n";
281 0           print "# ".join(", ", @{$self->uncomvcfs})."\n";
  0            
282 0           print "#######################################################################\n\n";
283              
284 0           foreach my $i (@{$self->uncomvcfs}){
  0            
285 0           print "bgzip $i && tabix $i.gz\n"
286             }
287              
288 0           print "wait\n";
289 0           print "\n\n#######################################################################\n";
290 0           print "# Finished Bgzip Section\n";
291 0           print "#######################################################################\n\n";
292             }
293              
294             =head2 norml
295              
296             normalize vcfs using vt and annotate using SNPEFF
297              
298             =cut
299              
300             # TODO
301             # Add in option for vep annotation
302              
303             sub norml {
304 0     0     my($self) = shift;
305              
306 0           print "#######################################################################\n";
307 0           print "# Normalizing with VT and annotating with SNPEFF the following samples\n";
308 0           print "# ".join(", ", @{$self->vcfs})."\n";
  0            
309 0           print "#######################################################################\n\n";
310              
311 0           foreach my $vcf (@{$self->vcfs}){
  0            
312              
313 0           my $cmd .=<<EOF;
314             bcftools view $self->{indir}/$vcf.vcf.gz | sed 's/ID=AD,Number=./ID=AD,Number=R/' \\
315             | vt decompose -s - \\
316             | vt normalize -r $self->{ref} - \\
317             | java -Xmx4G -jar $self->{snpeff}/snpEff.jar $self->{snpeff_opt} \\
318             | bgzip -c > \\
319             $self->{outdir}/norm_annot_vcf/$vcf.norm.snpeff.gz && tabix $self->{outdir}/norm_annot_vcf/$vcf.norm.snpeff.gz
320             EOF
321              
322 0           print $cmd."\n\n";
323             }
324              
325 0           print "wait\n";
326 0           print "\n\n#######################################################################\n";
327 0           print "# Finished Normalize Annotate Section\n";
328 0           print "#######################################################################\n\n";
329             }
330              
331              
332             =head2 db_load
333              
334             Load DB into gemini
335              
336             =cut
337              
338             sub db_load {
339 0     0     my($self) = @_;
340              
341 0           print "#######################################################################\n";
342 0           print "# Gemini is loading the following samples\n";
343 0           print "# ".join(", ", @{$self->vcfs})."\n";
  0            
344 0           print "#######################################################################\n\n";
345              
346 0 0         if ($self->ped){
347 0 0         $self->ped_dir($self->indir) unless $self->ped_dir;
348             }
349              
350 0           foreach my $vcf (@{$self->vcfs}){
  0            
351              
352 0           my $cmd =<<EOF;
353             gemini load -v $self->{outdir}/norm_annot_vcf/$vcf.norm.snpeff.gz \\
354             $self->{db_load_opts} \\
355             EOF
356 0 0         if($self->ped){
357 0           $cmd .=<<EOF;
358             -p $self->{ped_dir}/$vcf.ped \\
359             EOF
360             }
361              
362 0           $cmd .=<<EOF;
363             $self->{outdir}/gemini_sqlite/$vcf.vcf.db
364             EOF
365              
366 0           print $cmd."\n\n";
367             }
368              
369 0           print "wait\n";
370 0           print "\n\n#######################################################################\n";
371 0           print "# Finished Gemini Load Section\n";
372 0           print "#######################################################################\n";
373             }
374              
375             =head2 run
376              
377             Subroutine that starts everything off
378              
379             =cut
380              
381             sub run {
382 0     0     my($self) = @_;
383              
384 0           $self->print_opts;
385              
386 0           $self->check_files;
387 0           $self->find_vcfs;
388 0           $self->norml;
389 0           $self->db_load;
390             }
391              
392             __PACKAGE__->meta->make_immutable;
393              
394             1;
395              
396             __END__
397              
398             =encoding utf-8
399              
400             =head1 NAME
401              
402             BioX::Wrapper::Gemini - A simple wrapper around the python Gemini library for annotating VCF files.
403              
404             =head1 SYNOPSIS
405              
406             Basic Usage
407              
408             gemini_wrapper.pl --indir /path/to/vcfs --outdir /location/we/can/write/to
409              
410             =head2 Using the API
411              
412             BioX::Wrapper::Gemini is written using Moose and can be extended in all the usual fashions.
413              
414             use BioX::Wrapper::Gemini;
415              
416             after 'db_load' =>
417             sub {
418             my $self = shift;
419             # Run some commands
420             # SCIENCE!
421             }
422              
423             =head1 DESCRIPTION
424              
425             BioX::Wrapper::Gemini is a simple wrapper around the python Gemini library for annotating VCF files.
426              
427             =head1 AUTHOR
428              
429             Jillian Rowe E<lt>jillian.e.rowe@gmail.comE<gt>
430              
431             =head1 ACKNOWLEDGEMENTS
432              
433             This module was originally developed at and for Weill Cornell Medical
434             College in Qatar within ITS Advanced Computing Team. With approval from
435             WCMC-Q, this information was generalized and put on github, for which
436             the authors would like to express their gratitude.
437              
438             =head1 COPYRIGHT
439              
440             Copyright 2015- Weill Cornell Medical College in Qatar
441              
442             =head1 LICENSE
443              
444             This library is free software; you can redistribute it and/or modify
445             it under the same terms as Perl itself.
446              
447             =head1 SEE ALSO
448              
449             =cut