生物信息必備技能 -- 查找 SNP 突變后的氨基酸

生信虐我系列之--幾個(gè)必備小程序:
這個(gè)程序可以根據(jù)提供的 SNP位點(diǎn)信息野哭,以及參考注釋信息對 SNP 位點(diǎn)突變前后的 氨基酸 進(jìn)行比較双吆。

** 修改了部分代碼眨唬,重新設(shè)計(jì)了 SNP 突變位點(diǎn)落在反向轉(zhuǎn)錄本上的情況**
** 重新設(shè)計(jì)了結(jié)果的輸出格式**
** 歡迎積極提出設(shè)計(jì)上的不足**

輸入文件格式:
1. 參考注釋的 GTF 文件;
2. 參考注釋的基因組 fasta 文件好乐;
3. 輸入的 SNP 列表文件:
  1       49527   A       G       Exon:Zm00001d027230;
  1       51053   A       T       Exon:Zm00001d027231;
  1       53013   A       G       Exon:Zm00001d027231;
  1       53109   C       T       Exon:Zm00001d027231;
第一列: 染色體
第二列:突變位置
第三列:SNP 參考的堿基
第四列:SNP 位點(diǎn)突變后的堿基
第五列:[可選]匾竿,SNP 的信息

使用方法:

perl script.pl zma.gtf zma.fa in.txt >result.txt

程序源碼如下:(遵循 GPL v3 Licenses

#!/usr/bin/perl -w
use strict;
die "Usage: perl $0 <zma.GTF> <zma.FA> <in.TXT> >Result.txt \n" if @ARGV < 3;

&timing("start")
my (%tr, %cds, %seq);

open IN, $ARGV[0] or die $!;
while (<IN>){
    chomp;
    next if /^#/;
    my @a = split /\t/,$_;
    if ($a[2] eq "transcript"){
#        (my $gene) = $a[8] =~ /gene_id\s"(\S+)";/;
        (my $id) = $a[8] =~ /transcript_id\s"(\S+)";/;

#        $tr{$a[0]}{$gene}{$id} = [@a[3,4,6]];
        $tr{$a[0]}{$id} = [@a[3,4,6]];
    }
    if ($a[2] eq "CDS"){
#        (my $gene) = $a[8] =~ /gene_id\s"(\S+)";/;
        (my $id) = $a[8] =~ /transcript_id\s"(\S+)";/;
        next unless exists $tr{$a[0]}{$id};
        push @{$cds{$a[0]}{$id}},[@a[3,4,7]];
    }
}
close IN;

# make fasta hash

open FA,$ARGV[1] or die $!;
$/ = ">"; <FA>;
while(<FA>){
    chomp;
    my ($info,$fa) = split /\n/,$_,2;
    my ($chr,$tmp) = split /\s/,$info,2;
    $fa =~ s/\n+//g;
    $seq{$chr} = $fa;
}
$/ = "\n";
close FA;

# deal with input 
open IN,$ARGV[2] or die $!;
print "# Chrom:Loci:Ref->Alt\tTranscript\tStrand\tCDS(Ref->Alt)\tRef_Codon\tAlt_Codon\tRef_aa\tAlt_aa\tAlt_Pos\tCDS_Pos\n";
while (<IN>){
    chomp;
    my ($chr,$loci,$ref,$alt,$tmp) = split /\t/,$_;
    my ($strand,$j,$tr_id);
    my @arr;
    my $flag = 0;

    if ( exists $tr{$chr} ){
        foreach my $k (sort keys $tr{$chr}){
            if ($loci >= $tr{$chr}{$k}->[0] && $loci <= $tr{$chr}{$k}->[1]){
                $flag = 1;
                $strand = $tr{$chr}{$k}->[2];
                @arr = sort{$a->[0] <=> $b->[0] || $a->[1] <=> $b->[1]} @{$cds{$chr}{$k}};
                for (my $i=0;$i<@arr;$i++){
                    if ($loci >= $arr[$i]->[0] && $loci <= $arr[$i]->[1]){
                        $flag = 2;
                        $j = $i;
                        $tr_id = $k;
                        last;
                    }
                }
            }
        }
    }
if ($flag == 2 ){
        my ($pos, $seq, $site, $ref_codon, $alt_codon, $ref_aa, $alt_aa);
        my ($ref_nucl, $alt_nucl, $alt_pos);
        my $c = &code();

        if ($strand eq "+"){
            foreach (0..($j-1)){
                $pos += $arr[$_]->[1] - $arr[$_]->[0] + 1;
            }
            $pos += $loci - $arr[$j]->[0] + 1;
            foreach my $v (@arr){
                my ($x,$y) = @$v[0,1];
                $seq .= uc(substr($seq{$chr},$x-1,$y-$x+1));
            }
            $ref_nucl = substr($seq,$pos-1,1);
            $alt_nucl = $alt;

            $site = $pos % 3 ;
            if($site == 1){
                $ref_codon = uc(substr($seq,$pos - 1,3));
                $alt_codon = &ref2alt($ref_codon,1,$alt_nucl);
                $alt_pos = 1;
            }elsif($site == 2){
                $ref_codon = uc(substr($seq,$pos - 2,3));
                $alt_codon = &ref2alt($ref_codon,2,$alt_nucl);
                $alt_pos = 2;
            }elsif($site == 0){
                $ref_codon = uc(substr($seq,$pos - 3,3));
                $alt_codon = &ref2alt($ref_codon,3,$alt_nucl);
                $alt_pos = 3;
            }
        }
        if ($strand eq "-"){
            my $pos1;
            foreach (0..($j-1)){
                $pos1 += $arr[$_]->[1] - $arr[$_]->[0] + 1;
            }
            $pos1 += $loci - $arr[$j]->[0] + 1;
            foreach my $v (@arr){
                my ($x,$y) = @$v[0,1];
                $seq .= uc(substr($seq{$chr},$x-1,$y-$x+1));
            }
            my $len = length $seq;
            $pos = $len - $pos1 + 1;
            $seq = reverse $seq;
            $seq =~ tr/AaGgCcTt/TtCcGgAa/;
 
            $ref_nucl = substr($seq,$pos-1,1);
            $alt_nucl = $alt;
            $alt_nucl =~ tr/AaGgCcTt/TtCcGgAa/;
            
            $site = $pos % 3;
            if($site == 1){
                $ref_codon = uc(substr($seq,$pos - 1,3));
                $alt_codon = &ref2alt($ref_codon,1,$alt_nucl);
                $alt_pos = 1;
            }elsif($site == 2){
                $ref_codon = uc(substr($seq,$pos - 2,3));
                $alt_codon = &ref2alt($ref_codon,2,$alt_nucl);
                $alt_pos = 2;
            }elsif($site == 0){
                $ref_codon = uc(substr($seq,$pos - 3,3));
                $alt_codon = &ref2alt($ref_codon,3,$alt_nucl);
                $alt_pos = 3;
            }
        }
        $ref_aa = exists $c->{"standard"}{$ref_codon} ? $c->{"standard"}{$ref_codon} : "-";
        $alt_aa = exists $c->{"standard"}{$alt_codon} ? $c->{"standard"}{$alt_codon} : "-";
        print "$chr:$loci:$ref->$alt\t$tr_id\t$strand\t$ref_nucl->$alt_nucl\t$ref_codon\t$alt_codon\t$ref_aa\t$alt_aa\t$alt_pos\tcds_$pos\n"; 
    }
}
close IN;

&timing("end");

# time
sub timing{
    my $state=shift;
    my $time=strftime("%Y-%m-%d.%H:%M:%S",localtime);
    print STDOUT "## ==== >> Start at $time\n" if $state eq "start";
    print STDOUT "## ==== >> End at $time\n" if $state eq "end";
}
# ref2alt
sub ref2alt{
    my ($codon, $pos, $alt) = @_;
    my ($c1, $c2, $c3) = split //,$codon;
    my $out;
    
    if ($pos == 1){
        $out = join ("",$alt,$c2,$c3);
    }elsif ($pos == 2){
        $out = join ("",$c1,$alt,$c3);
    }else{
        $out = join ("",$c1,$c2,$alt);
    }
    return $out;
}

# code
sub code{
    my $p = {
        "standard" =>
        {       
            'GCA' => 'A', 'GCC' => 'A', 'GCG' => 'A', 'GCT' => 'A',                               # Alanine
            'TGC' => 'C', 'TGT' => 'C',                                                           # Cysteine
            'GAC' => 'D', 'GAT' => 'D',                                                           # Aspartic Aci
            'GAA' => 'E', 'GAG' => 'E',                                                           # Glutamic Aci
            'TTC' => 'F', 'TTT' => 'F',                                                           # Phenylalanin
            'GGA' => 'G', 'GGC' => 'G', 'GGG' => 'G', 'GGT' => 'G',                               # Glycine
            'CAC' => 'H', 'CAT' => 'H',                                                           # Histidine
            'ATA' => 'I', 'ATC' => 'I', 'ATT' => 'I',                                             # Isoleucine
            'AAA' => 'K', 'AAG' => 'K',                                                           # Lysine
            'CTA' => 'L', 'CTC' => 'L', 'CTG' => 'L', 'CTT' => 'L', 'TTA' => 'L', 'TTG' => 'L',   # Leucine
            'ATG' => 'M',                                                                         # Methionine
            'AAC' => 'N', 'AAT' => 'N',                                                           # Asparagine
            'CCA' => 'P', 'CCC' => 'P', 'CCG' => 'P', 'CCT' => 'P',                               # Proline
            'CAA' => 'Q', 'CAG' => 'Q',                                                           # Glutamine
            'CGA' => 'R', 'CGC' => 'R', 'CGG' => 'R', 'CGT' => 'R', 'AGA' => 'R', 'AGG' => 'R',   # Arginine
            'TCA' => 'S', 'TCC' => 'S', 'TCG' => 'S', 'TCT' => 'S', 'AGC' => 'S', 'AGT' => 'S',   # Serine
            'ACA' => 'T', 'ACC' => 'T', 'ACG' => 'T', 'ACT' => 'T',                               # Threonine
            'GTA' => 'V', 'GTC' => 'V', 'GTG' => 'V', 'GTT' => 'V',                               # Valine
            'TGG' => 'W',                                                                         # Tryptophan
            'TAC' => 'Y', 'TAT' => 'Y',                                                           # Tyrosine
            'TAA' => 'U', 'TAG' => 'U', 'TGA' => 'U'                                              # Stop
        }
    }
}


__END__

1       49527   A       G       Exon:Zm00001d027230;
1       51053   A       T       Exon:Zm00001d027231;
1       53013   A       G       Exon:Zm00001d027231;
1       53109   C       T       Exon:Zm00001d027231;
1       53826   T       C       Exon:Zm00001d027231;
1       53885   T       C       Exon:Zm00001d027231;

本文原創(chuàng),轉(zhuǎn)載請注明出處蔚万!
歡迎留言討論岭妖!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子昵慌,更是在濱河造成了極大的恐慌假夺,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件斋攀,死亡現(xiàn)場離奇詭異已卷,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)淳蔼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進(jìn)店門侧蘸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鹉梨,你說我怎么就攤上這事讳癌。” “怎么了俯画?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵析桥,是天一觀的道長。 經(jīng)常有香客問我艰垂,道長泡仗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任猜憎,我火速辦了婚禮娩怎,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘胰柑。我一直安慰自己截亦,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布柬讨。 她就那樣靜靜地躺著崩瓤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪踩官。 梳的紋絲不亂的頭發(fā)上却桶,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天,我揣著相機(jī)與錄音蔗牡,去河邊找鬼颖系。 笑死,一個(gè)胖子當(dāng)著我的面吹牛辩越,可吹牛的內(nèi)容都是我干的嘁扼。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼黔攒,長吁一口氣:“原來是場噩夢啊……” “哼趁啸!你這毒婦竟也來了强缘?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤莲绰,失蹤者是張志新(化名)和其女友劉穎欺旧,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蛤签,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡辞友,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了震肮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片称龙。...
    茶點(diǎn)故事閱讀 40,030評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖戳晌,靈堂內(nèi)的尸體忽然破棺而出鲫尊,到底是詐尸還是另有隱情,我是刑警寧澤沦偎,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布疫向,位于F島的核電站,受9級特大地震影響豪嚎,放射性物質(zhì)發(fā)生泄漏搔驼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一侈询、第九天 我趴在偏房一處隱蔽的房頂上張望舌涨。 院中可真熱鬧,春花似錦扔字、人聲如沸囊嘉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽分尸。三九已至馒胆,卻和暖如春扬舒,著一層夾襖步出監(jiān)牢的瞬間正罢,已是汗流浹背芽淡。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工哲嘲, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嫌变,地道東北人响禽。 一個(gè)月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓俩滥,卻偏偏與公主長得像嘉蕾,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子霜旧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容