annotate scripts/bam_analysis.pl @ 0:05c27700e5ca

initial commit
author biomonika <biomonika@psu.edu>
date Thu, 04 Sep 2014 18:24:19 -0400
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
1 #!/usr/bin/perl
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
2 #NOTE: The following code is adapted from the post http://www.biostars.org/p/44867/#44906
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
3
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
4 use strict;
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
5 use warnings;
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
6
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
7 use Bio::DB::Sam;
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
8 open (MP, '>mpileup');
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
9
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
10 # all necessary inputs (I use Getopt::Long to obtain input parameters)
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
11 my $opt_i = $ARGV[0]; #"mother.bam"; # should have an index file named input.bam.bai
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
12 my $opt_f = $ARGV[1]; #"reference.fasta";
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
13 my $chr_id = $ARGV[2]; #'comp1_c0_seq1'; # your chromosome-id
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
14 my $snp_pos = $ARGV[3]; # position you want to call all variants in this position
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
15 # create the object
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
16 my $sam = Bio::DB::Sam->new( -fasta => $opt_f, -bam => $opt_i );
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
17
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
18 # get all reads that cover this SNP -- therefore, start and end set to $snp_pos
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
19 my @alignments = $sam->get_features_by_location(-seq_id => $chr_id, -start => $snp_pos, -end => $snp_pos );
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
20
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
21 my $depth=@alignments;
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
22 print MP "DEPTH:".$depth."\n";
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
23
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
24 my %res; # output hash that'll contain the count of each available nucleotide (or blank if the read covering the SNP is spliced in this position).
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
25 # loop over all alignments
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
26 for my $cAlign (@alignments) {
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
27 # parameters we'll need from our bam file
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
28
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
29 my $start = $cAlign->start; # get start coordinate
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
30 my $end = $cAlign->end; # get end coordinate
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
31 my $ref_seq = $cAlign->dna; # get reference DNA sequence
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
32 my $read_seq = $cAlign->query->dna; # get query DNA sequence
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
33
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
34 #print $read_seq."\n";
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
35 #print "start: ".$start." end: ".$end."\n";
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
36
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
37 my $cigar = $cAlign->cigar_str; # get CIGAR sequence
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
38 my $cigar_ref = $cAlign->cigar_array; # probably the important useful of all. splits cigar to array of array reference
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
39
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
40 #print $cigar."\n"; # Ex: $cigar = 20M100N50M => $cigar_ref = [ [ 'M' 20 ] [ 'N' 100] ['M' 50] ]
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
41
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
42 my $ref_cntr = $start; # $ref_cntr = assign start to counter variable for reference. This will ultimately
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
43 # keep track of the current position on the chromosome
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
44 my $read_cntr = 0; # $read_cntr = computes offset on the read
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
45 my $read_snp_pos = ""; # variable to hold base at $snp_pos from current read
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
46
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
47 foreach my $deref ( @$cigar_ref ) {
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
48 my $cigar_chr = $deref->[0]; # cigar character (ex: M, N, I, D etc...)
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
49 my $len_chr = $deref->[1]; # number corresponding to `this` cigar character ( ex: 20, 100 )
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
50
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
51 # NOTE: I => insertion in to the reference, meaning the read has the base(s) but the REFERENCE fasta does NOT
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
52 # D => deletion from the reference, meaning the READ does NOT have the base(s), but the reference does
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
53
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
54 # modify reference counter only on M, N or D occurrence
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
55 if( $cigar_chr eq "M" || $cigar_chr eq "N" || $cigar_chr eq "D") {
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
56 $ref_cntr += $len_chr;
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
57 }
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
58
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
59 if( $cigar_chr eq "S" ) {
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
60 #print "soft_clipped.\n";
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
61 }
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
62
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
63 # modify offset only on M or I occurrence
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
64 if( $cigar_chr eq "M" || $cigar_chr eq "I" || $cigar_chr eq "S") {
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
65 $read_cntr += $len_chr;
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
66 }
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
67
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
68
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
69 # now, check if the current operation takes ref_cntr past the SNP position. If it does,
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
70 # 1) If the current operation is NOT "M", then its either "N" or "D". Both of them mean
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
71 # that the read doesn't have a base at the SNP. So, this read is either spliced or has
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
72 # a deletion at that point and is not useful for your SNP location.
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
73 # 2) If the current position IS "M", then the current operation has gotten is past SNP
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
74 # location. So, we FIRST SUBTRACT what we added in this operation for ref_cntr and read_cntr,
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
75 # and then just add the difference ($snp_pos - $ref_cntr + 1)
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
76
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
77 #print "read_cntr: ".$read_cntr."\nref_cntr: ".$ref_cntr." cigar: ".$cigar_chr."\n";
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
78
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
79 if( $ref_cntr > $snp_pos ) {
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
80 if( $cigar_chr eq "M" || $cigar_chr eq "S") {
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
81 $ref_cntr -= $len_chr;
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
82 $read_cntr -= $len_chr;
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
83
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
84 #print "backing\n";
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
85 #print "read_cntr: ".$read_cntr."\nref_cntr: ".$ref_cntr."\n";
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
86
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
87 #IMPORTANT
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
88 my $pos = $snp_pos - $ref_cntr + $read_cntr;
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
89
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
90 #print "SNP position: ".$snp_pos;
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
91 #print "position: ".$pos;
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
92
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
93 $read_snp_pos = substr( $read_seq, $pos, 1 );
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
94
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
95 #print "This is what we add: ".$read_snp_pos."\n";
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
96 }
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
97 # if $cigar_chr is "N" or "D", do nothing. $read_snp_pos is set to ""
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
98
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
99 if( $cigar_chr eq "N" || $cigar_chr eq "D") {
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
100 print MP "NAN\n";
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
101 }
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
102
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
103 # add value of $read_snp_pos to hash and get out of loop - to next read
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
104 $res{$read_snp_pos}++;
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
105 last;
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
106 }
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
107 }
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
108 }
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
109
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
110 #Here, I am just printing to output.
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
111 #print "Count\n";
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
112 foreach my $key ( keys %res ) {
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
113 print MP "$key:$res{$key}\n";
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
114 }
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
115 #print "--\n";
05c27700e5ca initial commit
biomonika <biomonika@psu.edu>
parents:
diff changeset
116 close MP;