Mercurial > repos > siyuan > prada
changeset 0:acc2ca1a3ba4
Uploaded
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/INSTALL Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,62 @@ +pyPRADA installation + +pyPRADA requires python 2.6 or 2.7, third party packages pysam and biopython. + +1. Install python +By default python is installed in Linux system. To check your python version, type + + python -V + +You may choose install python in your own directory, or ask your administrator to install it for you. Here below shows how to install python to your local directory. +(1) download python + $ wget http://www.python.org/ftp/python/2.7.2/Python-2.7.2.tgz +(2) unzip + $ tar zxfv Python-2.7.2.tgz +(3) configure & make + $ cd Python-2.7.2 + $ ./configure --prefix=/where/you/want/to/install + $ make + $ make install +(4) add python path to your system path +In B shell, edit .bashrc file in your home directory, add the following line + export PATH=/python-dir/bin:$PATH +In C shell, edit .cshrc file in your home directory, add the following line + setenv PATH /python-dir/bin:$PATH +To make the changes effective, source the .bashrc file or .cshrc file + $ source .bashrc + +Now check python version again. Python 2.7 should have been installed and set to be the default python. + +2. Install third party packages +(1) download pysam and biopython + $ wget https://pysam.googlecode.com/files/pysam-0.6.tar.gz + $ wget http://biopython.org/DIST/biopython-1.60.tar.gz +(2) unzip files + $ tar zxfv biopython-1.60.tar.gz + $ tar zxfv pysam-0.6.tar.gz +(3) configure / make + $ cd biopython-1.60 + $ python setup.py install + $ cd pysam-0.6 + $ python setup.py install +(4) test +You may leave the directories and test your package installations. + $ cd + $ python +This brings you to the python interactive interface. Import the two packages, if no error occurs, your packages have been successfully installed. Otherwise, consult your administrator or someone with experiences with python. + +>>> import pysam +>>> import Bio + +3. Install pyPRADA +pyPRADA has been pre-compiled, thus does not require configure/make steps. To make it more convenient, we recommend to add its path to system path. +First, unzip the package to the location you prefer. To add the path to system, see step 1.(4) + +4. Test pyRADA +To test pyPRADA, type the following command in your terminal. It will return a user manual for prada-fusion module. + + $ prada-fusion + +5. Help +For assistance or bug report, contact Siyuan Zheng (szheng2@mdanderson.org) or Rahul Vegesna (RVegesna@mdanderson.org). +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/bioclass.py Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,190 @@ +#Module defines exon, transcript and gene object. +#It is extendable for more attributes and functions. +#It is part of py-PRADA. +#Author: Siyuan Zheng (szheng2@mdanderson.org) +#Last modified at 03/07/2013 + +class Exon(object): + """Is an object with information about Exons and the Transcripts it is found in. + + If given an exon name, returns an object with exon location inforamtion and, gene and transcript information. + + e.g. + + >>> exon=bioclass.Exon(chr,int(start),int(end),strand,'tx','gene') + exon.start + exon.end + exon.chr + exon.strand + exon.gene + exon.transcript + exon.name + exon.length + """ + + def __init__(self,chr,start,end,strand,tx,gene): + if not all([isinstance(x,int) for x in [start,end]]): + raise Exception('start,end must be int!') + self.start=start + self.end=end + self.chr=chr + self.strand=strand #'1' or '-1' + self.gene=gene + self.transcript=tx #exon may map to multi-transcripts, but for simplicity, use one + self.name='%s:%s:%s:%s:%s'%(gene,chr,str(start),str(end),strand) #keep gene in the name too + self.length=self._length() + def _length(self): + return abs(self.end-self.start)+1 + +class Transcript(object): + """ + Is an object with information about Transcript and the Gene it is found in. + + If given an transcript name, returns an object with transcript location inforamtion, gene information and exon objects. . + + e.g. + + >>> tx=bioclass.Transcript('tx','gene') + tx.start + tx.end + tx.chr + tx.strand + tx.gene + tx.exon + tx.name + tx.length + + #Add new exons to the transcript: + tx.add_exon(exon) + + #Relative position of the transcript based on the exons defined: + tx.exon_relative_pos() + """ + + def __init__(self,name,gene): + self.exon=[] + self.name=name + self.gene=gene + self.length=0 + self.strand=None + self.start=None + self.end=None + self.cds_start=None + self.cds_end=None + self.is_primary=None + def _update(self): + self._basics() + self._sort_exon() + def _basics(self): + assert len(self.exon)>0, 'no exon in the transcript' + self.strand=self.exon[0].strand + self.chr=self.exon[0].chr + self.length=reduce(lambda x,y:x+y, [e.length for e in self.exon]) + self.start=min([e.start for e in self.exon]) + self.end=max([e.end for e in self.exon]) + def _sort_exon(self): + sorted_exons=sorted(self.exon, key=lambda x:x.start) + self.exon=sorted_exons + def add_exon(self,exon): + nameset=[x.name for x in self.exon] + if exon.name not in nameset: + self.exon.append(exon) + self._update() + def set_cds(self,start,end): + self.cds_start=start + self.cds_end=end + def set_primary(self,isprim): + self.is_primary=isprim + def exon_relative_pos(self): + L=[x.length for x in self.exon] + pos=[] + if self.strand=='1': + init=0 + for item in L: + region=(init+1, init+item) + init=init+item + pos.append(region) + if self.strand=='-1': + init=self.length + for item in L: + region=(init-item+1,init) + init=init-item + pos.append(region) + relpos=dict(zip([x.name for x in self.exon],pos)) + return relpos + +class Gene(object): + """ + Is an object with information about Gene. + + If given an gene name, returns an object with gene location inforamtion, transcript and exon objects. . + + e.g. + + >>> gene=bioclass.Gene('gene') + gene.start + gene.end + gene.chr + gene.strand + gene.transcript + gene.name + gene.length + + #Add new transcript to the gene: + gene.add_transcript() + + #Obtain a list of all the exons define within that gene: + gene.get_exons() + """ + + def __init__(self,name): + self.name=name + self.transcript=[] + def _update(self): + self._basics() + def _basics(self): + assert len(self.transcript)>0, 'no transcript in the gene' + self.strand=self.transcript[0].strand + self.chr=self.transcript[0].chr + self.start=min([t.start for t in self.transcript]) + self.end=max([t.end for t in self.transcript]) + + def add_transcript(self,tx): + nameset=[x.name for x in self.transcript] + if tx.name not in nameset: + self.transcript.append(tx) + self._update() + def get_exons(self): + exons={} + for t in self.transcript: + for e in t.exon: + exons[e.name]=e + return exons + + +if __name__=='__main__': + #below for testing purpose only. + infile=open('/RIS/home/wtorres/RNAseq/hg19broad/Ensembl64.canonical.gene.exons.tab.txt') + txdb={} #keep track of all transcripts + exdb={} #keep track of all exons + genedb={} #keep track of all genes + i=0 + for line in infile: + i+=1 + if i%100000==0: + print '%d exon records loaded'%i + chr,start,end,tx,gene,strand,cat=line.split() + if cat != 'protein_coding': + continue + exon=Exon(chr,int(start),int(end),strand,tx,gene) + exdb[exon.name]=exon + if not txdb.has_key(tx): + txdb[tx]=Transcript(tx,gene) + txdb[tx].add_exon(exon) + for txname in txdb: + t=txdb[txname] + if not genedb.has_key(t.gene): + genedb[t.gene]=Gene(t.gene) + genedb[t.gene].add_transcript(t) + infile.close() +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/conf.txt Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,31 @@ +#PLEASE EDIT EACH VARIABLE BASED ON YOUR FILE SETTING! +#DON'T EDIT block title"--REF--", "--PBS--", "--BWA aln--", "--BWA samse--" +#Users may download REFERENCE files at http://bioinformatics.mdanderson.org/Software/PRADA/ +#Set REFERENCE file paths according to your own settings. + +--REF-- +compdb_fasta = /RIS/home/verhaakgroup/PRADA/hg19broad/Ensembl64.transcriptome.plus.genome.fasta +compdb_map = /RIS/home/verhaakgroup/PRADA/hg19broad/Ensembl64.transcriptome.plus.genome.map +genome_fasta = /RIS/home/verhaakgroup/PRADA/hg19broad/Homo_sapiens_assembly19.fasta +genome_gtf = /RIS/home/verhaakgroup/PRADA/hg19broad/Homo_sapiens.GRCh37.64.gtf +dbsnp_vcf = /RIS/home/verhaakgroup/PRADA/hg19broad/dbsnp_135.b37.vcf +select_tx = /RIS/home/verhaakgroup/PRADA/hg19broad/Ensembl64.selected.transcripts +feature_file = /RIS/home/verhaakgroup/PRADA/hg19broad/Ensembl64.canonical.gene.exons.tab.txt +tx_seq_file = /RIS/home/verhaakgroup/PRADA/hg19broad/Ensembl64.transcriptome.fasta +ref_anno = /RIS/home/verhaakgroup/PRADA/hg19broad/Ensembl64.transcriptome.annotations +ref_map = /RIS/home/verhaakgroup/PRADA/hg19broad/Ensembl64.transcriptome.formatted.map +ref_fasta = /RIS/home/verhaakgroup/PRADA/hg19broad/Ensembl64.transcriptome.formatted.fasta +cds_file = /RIS/home/verhaakgroup/PRADA/hg19broad/ensembl.hg19.cds.txt +txcat_file = /RIS/home/verhaakgroup/PRADA/hg19broad/Ensembl64_primary_transcript.txt + +--PBS-- +-M = szheng2@mdanderson.org +-q = long +-l = nodes=1:ppn=i2,walltime=120:00:00 #nodes and ppn are required + +--BWA aln-- +-t = 2 #This should be equal to the number of ppn + +--BWA samse-- +-n = 100 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/gfclass.py Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,127 @@ + +class Junction(object): + def __init__(self,init_str): + 'init_str looks like PCBP2:12:53873398_GFAP:17:42985517' + part1,part2=init_str.split('_') + info1,info2=part1.split(':'), part2.split(':') + self.gene1=info1[0] + self.end1_chr=info1[1] + self.end1_pos=int(info1[2]) + self.gene2=info2[0] + self.end2_chr=info2[1] + self.end2_pos=int(info2[2]) + self.name='%s.%s.%s.%s.%s.%s'%(self.gene1,self.end1_chr,self.end1_pos,self.gene2,self.end2_chr,self.end2_pos) + def distance(self): + betwn_junc_dist=None + if self.end1_chr==self.end2_chr: + betwn_junc_dist=abs(int(self.end1_pos) - int(self.end2_pos)) + return betwn_junc_dist + def junc_category(self): + cat=None + if self.end1_chr==self.end2_chr: + cat='intrachromosome' + else: + cat='interchromosome' + return cat + +class JSR(object): + '''Ideally it should extend pysam.AlignedRead class, but run into segment error. + Read is pysam.AlignedRead object''' + def __init__(self,read,junction): + self.read=read + self.junction=junction + +class GeneFusion(object): + '''discs is [(r1,r2),...]; junc_rds is [jsr1,jsr2,...];''' + def __init__(self,gene1,gene2,discordantpairs=[],junc_reads=[]): + self.gene1=gene1 + self.gene2=gene2 + self.discordantpairs=discordantpairs + self.fusionreads=junc_reads + def update(self,mm=1): + '''Generate a new PRADA object with the update parameter. Extendable.''' + filtdp,filtfus=[],[] #hold updated elements + #apply mm filter + for rp in self.discordantpairs: + r1,r2=rp + nm1=[x[1] for x in r1.tags if x[0]=='NM'][0] + nm2=[x[1] for x in r2.tags if x[0]=='NM'][0] + if nm1 <= mm and nm2 <= mm: + filtdp.append(rp) + for fp in self.fusionreads: + nm=[x[1] for x in fp.read.tags if x[0]=='NM'][0] + if nm <= mm: + filtfus.append(fp) + newobject=GeneFusion(self.gene1,self.gene2,filtdp,filtfus) + return newobject + def get_junction_freq(self): + juncs={} + for item in self.fusionreads: + if juncs.has_key(item.junction): + juncs[item.junction]+=1 + else: + juncs[item.junction]=1 + return juncs.items() + def get_junctions(self): + juncs=set([]) + for item in self.fusionreads: + juncs.add(item.junction) + junobjdb=[Junction(x) for x in juncs] + return junobjdb + def get_perfect_JSR(self): + pjsr=[] + for item in self.fusionreads: + r=item.read + nm=[x[1] for x in r.tags if x[0]=='NM'][0] + if nm==0: + pjsr.append(item) + return pjsr + def positioncheck(self): + if len(self.fusionreads)==0: #no junction and junction spanning reads. + return 'NA' + if len(self.discordantpairs)==0: + return 'NA' + junctions=self.get_junctions() + jA=[x.end1_pos for x in junctions] + jA_min,jA_max=min(jA),max(jA) + jB=[x.end2_pos for x in junctions] + jB_min,jB_max=min(jB),max(jB) ## + fwd=[x[0].pos for x in self.discordantpairs] + fwd_min,fwd_max=min(fwd),max(fwd) + rev=[x[1].pos for x in self.discordantpairs] + rev_min,rev_max=min(rev),max(rev) + #print 'junctionA',jA_min,jA_max + #print 'junctionB',jB_min,jB_max + #print 'Fwd Read',fwd_min,fwd_max + #print 'Rev Read',rev_min,rev_max + ##################################### + #The following scoring process is translated from M. Berger's perl script. + const_score=0 + if not self.discordantpairs[0][0].is_reverse: #gene A on + strand + if jA_min > fwd_max: + const_score=const_score+3 + elif jA_max > fwd_min: + const_score=const_score+2 + elif self.discordantpairs[0][0].is_reverse: #gene A on - strand + if jA_max < fwd_min: + const_score=const_score+3 + elif jA_min < fwd_max: + const_score=const_score+2 + if self.discordantpairs[0][1].is_reverse: #gene B on + strand // disc read map to - + if jB_max < rev_min: + const_score=const_score+3 + elif jB_min < rev_max: + const_score=const_score+2 + elif not self.discordantpairs[0][1].is_reverse: #gene B on - strand + if jB_min > rev_max: + const_score=const_score+3 + elif jB_max > rev_min: + const_score=const_score+2 + if const_score==6: + tag='YES' + elif const_score>=4: + tag='PARTIALLY' + else: + tag='NO' + return tag +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/ioprada.py Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,133 @@ +#define IO functions. May add more gradually. +import bioclass + +def read_conf(conffile): + '''read configure file (conf.txt)''' + ref_input=open(conffile) + refdict={} + for line in ref_input: + if not line.strip(): + continue + if '#' in line: + contline=line.split('#')[0] + content=contline.strip() + else: + content=line.strip() + if not content: + continue + if content.startswith('--'): + key=content + refdict[key]={} + else: + idx=content.index('=') + a=content[0:idx].strip() + b=content[(idx+1):].strip() + refdict[key][a]=b + ref_input.close() + return refdict + +def read_feature(featurefile,verbose=True): + '''Read exon/transcript/gene info and return bioclass obj''' + infile=open(featurefile) + txdb={} #keep track of all transcripts + exdb={} #keep track of all exons + genedb={} #keep track of all genes + i=0 + for line in infile: + i+=1 + if verbose: + if i%100000==0: + print '%d exon records loaded'%i + chr,start,end,tx,gene,strand,cat=line.split() + if cat != 'protein_coding': + continue + exon=bioclass.Exon(chr,int(start),int(end),strand,tx,gene) + exdb[exon.name]=exon + if not txdb.has_key(tx): + txdb[tx]=bioclass.Transcript(tx,gene) + txdb[tx].add_exon(exon) + for txname in txdb: + t=txdb[txname] + if not genedb.has_key(t.gene): + genedb[t.gene]=bioclass.Gene(t.gene) + genedb[t.gene].add_transcript(t) + infile.close() + return (txdb,genedb) + +def read_feature_genes(featurefile,*args): + '''Read exon/transcript/gene info for spec genes and return bioclass obj''' + infile=open(featurefile) + txdb={} + exdb={} + genedb={} + for line in infile: + chr,start,end,tx,gene,strand,cat=line.split() + if gene not in args: + continue + if cat != 'protein_coding': + continue + exon=bioclass.Exon(chr,int(start),int(end),strand,tx,gene) + exdb[exon.name]=exon + if not txdb.has_key(tx): + txdb[tx]=bioclass.Transcript(tx,gene) + txdb[tx].add_exon(exon) + for txname in txdb: + t=txdb[txname] + if not genedb.has_key(t.gene): + genedb[t.gene]=bioclass.Gene(t.gene) + genedb[t.gene].add_transcript(t) + res=[] + for g in args: + if genedb.has_key(g): + gobj=genedb[g] + else: + gobj=None + res.append(gobj) + infile.close() + return res + +def read_cds(cdsfile): + '''read CDS start/end for transcripts''' + infile=open(cdsfile) + tx_cds={} + for line in infile: + info=line.split() + tx=info[0] + cds_start,cds_end=int(info[3]),int(info[4]) + tx_cds[tx]=(cds_start,cds_end) + infile.close() + return tx_cds + +def read_tx_cat(txcatfile): + '''find primary transcript for each gene''' + tx_primary={} + tx_cat={} + infile=open(txcatfile) + for line in infile: + if not line.strip(): + continue + info=line.split() + if len(info) != 4: + continue + gene=info[2] + txid=info[1] + acc=int(info[3][-3:]) + if tx_cat.has_key(gene): + tx_cat[gene].append([txid,acc]) + else: + tx_cat[gene]=[[txid,acc]] + infile.close() + for item in tx_cat: + vv=tx_cat[item] + vv=sorted(vv,key=lambda x: x[1]) + tx_primary[item]=vv[0][0] + return tx_primary + + +if __name__=='__main__': + #The following lines are for module testing purpose only. + #They would not affect the program. + featurefile='/RIS/home/wtorres/RNAseq/hg19broad/Ensembl64.canonical.gene.exons.tab.txt' + cdsfile='/RIS/home/wtorres/RNAseq/hg19broad/ensembl.hg19.cds.txt' + txcatfile='/RIS/home/wtorres/RNAseq/hg19broad/Ensembl64_primary_transcript.txt' +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/make_exon_junctions.pl Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,201 @@ +#!/usr/bin/perl +use strict; +use warnings; + +################################## +# make_exon_junctions.pl +# +# Take as input Gene A and Gene B +# in fusion. Using Ensembl52 +# mapping information and +# transcript sequences, outputs +# sequences for all possible +# exon junctions with the 3' end +# of Gene A fused to the 5' end +# of Gene B +# +# M. Berger, January 27, 2009 +# WTG modified 7/10/2012 +# RV last modified 4/9/2013 +################################## + +if ($#ARGV!=5) {die "usage is 'perl make_exon_junctions.pl GeneA GeneB ref.annotation ref.map ref.fasta junL > output'\n";} +my $geneA = shift; +my $geneB = shift; +my $annotations = shift; +my $map = shift; +my $fasta = shift; +my $overlap = shift; + +# Get transcript Ensembl IDs and orientations for GeneA and GeneB + +my @ensembA; +my @ensembB; +my @orientationA; +my @orientationB; +my @seqidA; +my @seqidB; + +my $testerA=0; my $testerB=0; +open (ANN, "<$annotations") or die "can't open Ensembl annotations\n"; +while (my $text = <ANN>) { + chomp $text; + my @line = split " ", $text; + if ($line[3] eq $geneA) {push @ensembA, $line[1]; push @orientationA, $line[4]; push @seqidA, $line[0]; $testerA++;} + if ($line[3] eq $geneB) {push @ensembB, $line[1]; push @orientationB, $line[4]; push @seqidB, $line[0]; $testerB++;} +} +close (ANN); +if ($testerA==0 || $testerB==0) {die "couldn't find one of the genes\n";} + +# Get exon lengths for each transcript for GeneA and GeneB + +my @exon_length_A; +my @exon_length_B; + +my $chr_A; +my $chr_B; + +my @exon_end_A; +my @exon_start_B; + +open (MAP, "<$map") or die "can't open Ensembl map\n"; +while (my $text = <MAP>) { + chomp $text; + my @line = split " ", $text; + my $ensID = pop (@line); + pop @line; + for (my $i=0; $i<=$#ensembA; $i++) { + if ($ensembA[$i] eq $ensID) { + $chr_A = $line[0]; + my $num_exons = ($#line+1)/3; + for (my $exonA=0; $exonA<$num_exons; $exonA++) { + my $length = $line[3*$exonA + 2] - $line[3*$exonA + 1] + 1; + if ($orientationA[$i] == 1) { + push @{$exon_length_A[$i]}, $length; + push @{$exon_end_A[$i]}, $line[3*$exonA + 2]; + } + else { + unshift @{$exon_length_A[$i]}, $length; + unshift @{$exon_end_A[$i]}, $line[3*$exonA + 1]; + } + } + } + } + for (my $i=0; $i<=$#ensembB; $i++) { + if ($ensembB[$i] eq $ensID) { + $chr_B = $line[0]; + my $num_exons = ($#line+1)/3; + for (my $exonB=0; $exonB<$num_exons; $exonB++) { + my $length = $line[3*$exonB + 2] - $line[3*$exonB + 1] + 1; + if ($orientationB[$i] == 1) { + push @{$exon_length_B[$i]}, $length; + push @{$exon_start_B[$i]}, $line[3*$exonB + 1]; + } + else { + unshift @{$exon_length_B[$i]}, $length; + unshift @{$exon_start_B[$i]}, $line[3*$exonB + 2]; + } + } + } + } +} +close (MAP); + +# Get sequence for each transcript (take reverse complement when necessary) + +my @sequenceA; +my @sequenceB; + +open (FHSEQ, "<$fasta") or die "can't open Ensembl map\n"; +my $top = <FHSEQ>; +my $readID = 0; +while (my $text = <FHSEQ>) { + chomp $text; + if ($text =~ ">") { #WTG changed to update for specific ENST ID number which might not be in the same order in the fasta as in the annotation + $text=~ s/>//; + $readID=$text; + } + else { + for (my $i=0; $i<=$#seqidA; $i++) { + if ($seqidA[$i] == $readID) { + if ($sequenceA[$i]) { + $sequenceA[$i] = $sequenceA[$i].$text; + } + else {$sequenceA[$i] = $text;} + } + } + for (my $i=0; $i<=$#seqidB; $i++) { + if ($seqidB[$i] == $readID) { + if ($sequenceB[$i]) { + $sequenceB[$i] = $sequenceB[$i].$text; + } + else {$sequenceB[$i] = $text;} + } + } + } +} +close (FHSEQ); + +for (my $txtA=0; $txtA<=$#sequenceA; $txtA++) { + if ($orientationA[$txtA]==-1) { + $sequenceA[$txtA] = rc($sequenceA[$txtA]); + } +} +for (my $txtB=0; $txtB<=$#sequenceB; $txtB++) { + if ($orientationB[$txtB]==-1) { + $sequenceB[$txtB] = rc($sequenceB[$txtB]); + } +} + + +# Print sequences for each hypothetical exon junction (for each pair of transcripts) + + +for (my $txtA=0; $txtA<=$#sequenceA; $txtA++) { + for (my $txtB=0; $txtB<=$#sequenceB; $txtB++) { + + my $num_exon_A = $#{$exon_length_A[$txtA]}+1; + my $num_exon_B = $#{$exon_length_B[$txtB]}+1; + + my $running_pos_A=0; + for (my $exonA=0; $exonA<$num_exon_A; $exonA++) { + $running_pos_A += $exon_length_A[$txtA][$exonA]; + my $junction_start = $exon_end_A[$txtA][$exonA]; + my $start = $running_pos_A - $overlap; + my $seqA; + if ($start >= 0) { + $seqA = substr($sequenceA[$txtA], $start, $overlap); + } + else { + $start=0; + my $tmp_length = $running_pos_A; + $seqA = substr($sequenceA[$txtA], $start, $tmp_length); + } + my $running_pos_B=0; + for (my $exonB=0; $exonB<$num_exon_B; $exonB++) { + my $junction_end = $exon_start_B[$txtB][$exonB]; + my $start = $running_pos_B; + my $seqB = substr($sequenceB[$txtB], $start, $overlap); + $running_pos_B += $exon_length_B[$txtB][$exonB]; + print ">chr$chr_A\.$junction_start\.chr$chr_B\.$junction_end\n"; + my $junction = $seqA.$seqB; + print "$junction\n"; + } + } + } +} + + + +################## +################## +### SUBROUTINES +################## +################## + +sub rc{ + my $dna = shift; + my $revcom = reverse($dna); + $revcom =~ tr/ACGTacgt/TGCAtgca/; + return $revcom; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/make_intragenic_junctions.pl Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,244 @@ +#!/usr/bin/perl +use strict; +use warnings; + +################################## +# make_intragenic_junctions.pl +# +# This is an extension of MFB's perl code make_exon_junctions.pl +# Generates "abnormal" junctions between exons of a gene +# In the code GeneA, GeneB should be input as same gene +# +# RV last modified 4/9/2013 +################################## + +if ($#ARGV!=5) {die "usage is 'perl make_exon_junctions.pl GeneA GeneB ref.annotation ref.map ref.fasta junL > output'\n";} +my $geneA = shift; +my $geneB = shift; +my $annotations = shift; +my $map = shift; +my $fasta = shift; +my $overlap = shift; + +# Get transcript Ensembl IDs and orientations for GeneA and GeneB + +my @ensembA; +my @ensembB; +my @orientationA; +my @orientationB; +my @seqidA; +my @seqidB; + +my $testerA=0; my $testerB=0; +open (ANN, "<$annotations") or die "can't open Ensembl annotations\n"; +while (my $text = <ANN>) { + chomp $text; + my @line = split " ", $text; + if ($line[3] eq $geneA) {push @ensembA, $line[1]; push @orientationA, $line[4]; push @seqidA, $line[0]; $testerA++;} + if ($line[3] eq $geneB) {push @ensembB, $line[1]; push @orientationB, $line[4]; push @seqidB, $line[0]; $testerB++;} +} +close (ANN); +if ($testerA==0 || $testerB==0) {die "couldn't find one of the genes\n";} + +# Get exon lengths for each transcript for GeneA and GeneB + +my @exon_length_A; +my @exon_length_B; + +my $chr_A; +my $chr_B; + +my @exon_end_A; +my @exon_start_B; + +open (MAP, "<$map") or die "can't open Ensembl map\n"; +while (my $text = <MAP>) { + chomp $text; + my @line = split " ", $text; + my $ensID = pop (@line); + pop @line; + for (my $i=0; $i<=$#ensembA; $i++) { + if ($ensembA[$i] eq $ensID) { + $chr_A = $line[0]; + my $num_exons = ($#line+1)/3; + for (my $exonA=0; $exonA<$num_exons; $exonA++) { + my $length = $line[3*$exonA + 2] - $line[3*$exonA + 1] + 1; + if ($orientationA[$i] == 1) { + push @{$exon_length_A[$i]}, $length; + push @{$exon_end_A[$i]}, $line[3*$exonA + 2]; + } + else { + unshift @{$exon_length_A[$i]}, $length; + unshift @{$exon_end_A[$i]}, $line[3*$exonA + 1]; + } + } + } + } + for (my $i=0; $i<=$#ensembB; $i++) { + if ($ensembB[$i] eq $ensID) { + $chr_B = $line[0]; + my $num_exons = ($#line+1)/3; + for (my $exonB=0; $exonB<$num_exons; $exonB++) { + my $length = $line[3*$exonB + 2] - $line[3*$exonB + 1] + 1; + if ($orientationB[$i] == 1) { + push @{$exon_length_B[$i]}, $length; + push @{$exon_start_B[$i]}, $line[3*$exonB + 1]; + } + else { + unshift @{$exon_length_B[$i]}, $length; + unshift @{$exon_start_B[$i]}, $line[3*$exonB + 2]; + } + } + } + } +} +close (MAP); + +# Get sequence for each transcript (take reverse complement when necessary) + +my @sequenceA; +my @sequenceB; + +open (FHSEQ, "<$fasta") or die "can't open Ensembl map\n"; +my $top = <FHSEQ>; +my $readID = 0; +while (my $text = <FHSEQ>) { + chomp $text; + if ($text =~ ">") { #WTG changed to update for specific ENST ID number which might not be in the same order in the fasta as in the annotation + $text=~ s/>//; + $readID=$text; + } + else { + for (my $i=0; $i<=$#seqidA; $i++) { + if ($seqidA[$i] == $readID) { + if ($sequenceA[$i]) { + $sequenceA[$i] = $sequenceA[$i].$text; + } + else {$sequenceA[$i] = $text;} + } + } + for (my $i=0; $i<=$#seqidB; $i++) { + if ($seqidB[$i] == $readID) { + if ($sequenceB[$i]) { + $sequenceB[$i] = $sequenceB[$i].$text; + } + else {$sequenceB[$i] = $text;} + } + } + } +} +close (FHSEQ); + +for (my $txtA=0; $txtA<=$#sequenceA; $txtA++) { + if ($orientationA[$txtA]==-1) { + $sequenceA[$txtA] = rc($sequenceA[$txtA]); + } +} +for (my $txtB=0; $txtB<=$#sequenceB; $txtB++) { + if ($orientationB[$txtB]==-1) { + $sequenceB[$txtB] = rc($sequenceB[$txtB]); + } +} + + +# Print sequences for each hypothetical exon junction (for each pair of transcripts) +my %junctions; +my %junctions_known; +for (my $txtA=0; $txtA<=$#sequenceA; $txtA++) { + for (my $txtB=0; $txtB<=$#sequenceB; $txtB++) { + + my $num_exon_A = $#{$exon_length_A[$txtA]}+1; + my $num_exon_B = $#{$exon_length_B[$txtB]}+1; + + my $running_pos_A=0; + for (my $exonA=0; $exonA<$num_exon_A; $exonA++) { + $running_pos_A += $exon_length_A[$txtA][$exonA]; + my $junction_start = $exon_end_A[$txtA][$exonA]; + my $start = $running_pos_A - $overlap; + my $seqA; + if ($start >= 0) { + $seqA = substr($sequenceA[$txtA], $start, $overlap); + } + else { + $start=0; + my $tmp_length = $running_pos_A; + $seqA = substr($sequenceA[$txtA], $start, $tmp_length); + } + my $running_pos_B=0; + for (my $exonB=0; $exonB<$num_exon_B; $exonB++) { + my $junction_end = $exon_start_B[$txtB][$exonB]; + my $start = $running_pos_B; + my $seqB = substr($sequenceB[$txtB], $start, $overlap); + $running_pos_B += $exon_length_B[$txtB][$exonB]; + my $key= ">chr$chr_A\.$junction_start\.chr$chr_B\.$junction_end\n"; + my $junction = $seqA.$seqB; + #print ">chr$chr_A\.$junction_start\.chr$chr_B\.$junction_end\n"; + #print "$junction\n"; + $junctions{$key}=$junction; + } + } + } + +} + +for (my $txtA=0; $txtA<=$#sequenceA; $txtA++) { +my $num_exon_A = $#{$exon_length_A[$txtA]}; + + my $running_pos_A=0; + for (my $exonA=0; $exonA<$num_exon_A; $exonA++) { + $running_pos_A += $exon_length_A[$txtA][$exonA]; + my $junction_start = $exon_end_A[$txtA][$exonA]; + my $start = $running_pos_A - $overlap; + my $seqA; + if ($start >= 0) { + $seqA = substr($sequenceA[$txtA], $start, $overlap); + } + else { + $start=0; + my $tmp_length = $running_pos_A; + $seqA = substr($sequenceA[$txtA], $start, $tmp_length); + } + my $running_pos_B=0; + my $junction_end = $exon_start_B[$txtA][$exonA+1]; + my $start1 = $running_pos_B; + my $seqB = substr($sequenceA[$txtA], $start1, $overlap); + #$running_pos_B += $exon_length_A[$txtA][$exonA+1]; + my $key= ">chr$chr_A\.$junction_start\.chr$chr_A\.$junction_end\n"; + my $junction = $seqA.$seqB; + #print "$junction\n"; + $junctions_known{$key}=$junction; + + } +} + + my @disc; + my %count = (); + foreach my $element (keys (%junctions_known), keys (%junctions)) { $count{$element}++ } + foreach my $element (keys %count) { + if($count{$element} == 1){ + #print $element; + push @disc , $element; + } + } + +foreach my $junc(@disc){ + if($junctions_known{$junc}){print $junc,$junctions_known{$junc},"\n"; + } + else {print $junc,$junctions{$junc},"\n"; + } + +} + + +################## +################## +### SUBROUTINES +################## +################## + +sub rc{ + my $dna = shift; + my $revcom = reverse($dna); + $revcom =~ tr/ACGTacgt/TGCAtgca/; + return $revcom; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/parse_gft.py Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,110 @@ +import bioclass + +featurefile='/RIS/home/verhaakgroup/PRADA/hg19broad/Ensembl64.canonical.gene.exons.tab.txt' + +infile=open('/RIS/home/verhaakgroup/PRADA/hg19broad/Homo_sapiens.GRCh37.64.gtf') +txdb={} #keep track of all transcripts +exdb={} #keep track of all exons +genedb={} #keep track of all genes +verbose=True +i=0 +for line in infile: + i+=1 + if verbose: + if i%100000==0: + print '%d features scanned'%i + info=line.strip().split('\t') + chr,cat,entity,start,end=info[0:5] + strand=info[6] + attributes=info[8] + if cat != 'protein_coding': + continue + attinfo=attributes.split(';') + atts=dict() + for item in attinfo: + item=item.strip() + if not item: + continue + tmp=item.split() + kk=tmp[0] + vv=tmp[1][1:-1] + atts[kk]=vv + tx=atts['transcript_id'] + gene=atts['gene_name'] + if entity=='exon': + exon=bioclass.Exon(chr,int(start),int(end),strand,tx,gene) + exdb[exon.name]=exon + if not txdb.has_key(tx): + txdb[tx]=bioclass.Transcript(tx,gene) + txdb[tx].add_exon(exon) + for txname in txdb: + if not genedb.has_key(t.gene): + genedb[t.gene]=bioclass.Gene(t.gene) + genedb[t.gene].add_transcript(t) + +infile.close() + + + +def read_feature(featurefile,verbose=True): + '''Read exon/transcript/gene info and return bioclass obj''' + infile=open(featurefile) + txdb={} #keep track of all transcripts + exdb={} #keep track of all exons + genedb={} #keep track of all genes + i=0 + for line in infile: + i+=1 + if verbose: + if i%100000==0: + print '%d exon records loaded'%i + chr,start,end,tx,gene,strand,cat=line.split() + if cat != 'protein_coding': + continue + exon=bioclass.Exon(chr,int(start),int(end),strand,tx,gene) + exdb[exon.name]=exon + if not txdb.has_key(tx): + txdb[tx]=bioclass.Transcript(tx,gene) + txdb[tx].add_exon(exon) + for txname in txdb: + t=txdb[txname] + if not genedb.has_key(t.gene): + genedb[t.gene]=bioclass.Gene(t.gene) + genedb[t.gene].add_transcript(t) + infile.close() + return (txdb,genedb) + +def read_feature_genes(featurefile,*args): + '''Read exon/transcript/gene info for spec genes and return bioclass obj''' + infile=open(featurefile) + txdb={} + exdb={} + genedb={} + for line in infile: + chr,start,end,tx,gene,strand,cat=line.split() + if gene not in args: + continue + if cat != 'protein_coding': + continue + exon=bioclass.Exon(chr,int(start),int(end),strand,tx,gene) + exdb[exon.name]=exon + if not txdb.has_key(tx): + txdb[tx]=bioclass.Transcript(tx,gene) + txdb[tx].add_exon(exon) + for txname in txdb: + t=txdb[txname] + if not genedb.has_key(t.gene): + genedb[t.gene]=bioclass.Gene(t.gene) + genedb[t.gene].add_transcript(t) + res=[] + for g in args: + if genedb.has_key(g): + gobj=genedb[g] + else: + gobj=None + res.append(gobj) + infile.close() + return res + +if __name__=='__main__': + pass
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/prada-frame Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,278 @@ +#!/usr/bin/env python + +#This script is part of the pyPRADA package. It is used to predict the functional consequences of +#gene fusions. Possible predictions include in-frame, out-of-frame, UTR-UTR, UTR-CDS, Unknown etc. +#It relies on the definition of transcript CDS/UTR boundaries from ENSEMBL, and gives a prediction +#for every pair of transcripts coded by the fusion genes. The whole point is to see if the fusion +#lead to reading shift of the CDS sequences. +#Two files are generated, brief/detail result. +#Result is purely predicted, no guarantee is assumed. +#Contact: Siyuan Zheng, szheng2@mdanderson.org + +import os +import sys +import re +import time +import subprocess +import bioclass +from Bio import SeqIO +import ioprada + +###################################################################################### +help_menu='''\nUsage: prada-frame -conf xx.txt -i inputfile -docstr XX -outdir ./ +**parameters** + -conf see prada-fusion -conf + -i input file, a tab/space delimited four-column file, each row like "GeneA GeneA_break GeneB GeneB_break" + Example:FGFR3 1808661 TACC3 1739325 + -docstr outfile prefix. output to two files: XX.frame.brief.txt, XX.frame.detail.txt + -outdir output directory, default is ./ +''' + +args=sys.argv +if '-h' in args or '-help' in args or len(args)==1: + print help_menu + sys.exit(0) + +if '-i' not in sys.argv: + sys.exit('Input file needed') +else: + i=sys.argv.index('-i') + datafilename=sys.argv[i+1] + +if '-outdir' not in args: + outpath=os.path.abspath('./') +else: + i=args.index('-outdir') + outpath=os.path.abspath(args[i+1]) +if os.path.exists(outpath): + print 'WARNING: outdir %s exists'%outpath +else: + os.mkdir(outpath) + +if '-docstr' not in sys.argv: + sys.exit('docstring needed') +else: + i=sys.argv.index('-docstr') + outfile_prefix=sys.argv[i+1] + outfile_brief='%s/%s.frame.brief.txt'%(outpath,outfile_prefix) + outfile_detail='%s/%s.frame.detail.txt'%(outpath,outfile_prefix) + +#PRADA executive path +prada_path=os.path.dirname(os.path.abspath(__file__)) #### +ref_search_path=[prada_path,os.getcwd()] #search path for ref file if not specified in command line + +if '-ref' in args: + i=args.index('-conf') + reffile=args[i+1] + if os.path.exists(reffile): + pass + else: + for pth in ref_search_path: + new_reffile='%s/%s'%(pth, os.path.basename(reffile)) + if os.path.exists(new_reffile): + reffile=new_reffile + break + else: + sys.exit('ERROR: conf file %s not found'%reffile) +else: + reffile='%s/conf.txt'%prada_path + if not os.path.exists(reffile): + sys.exit('ERROR: No default conf.txt found and none specified') + +#read reference files +refdict=ioprada.read_conf(reffile) +featurefile=refdict['--REF--']['feature_file'] +cdsfile=refdict['--REF--']['cds_file'] +txcatfile=refdict['--REF--']['txcat_file'] + +#Now print all input parameters +print 'CMD: %s'%('\t'.join(args)) + +########################################################################################### +##Read information from annotation files, for all genes +print 'Reading annotations' +#call functions in ioprada module // +txdb,genedb=ioprada.read_feature(featurefile,verbose=False) +tx_cds=ioprada.read_cds(cdsfile) +tx_primary=ioprada.read_tx_cat(txcatfile) + +########################################################################################### +def maptranscript(gene,exon_end,part=''): + '''Find all transcripts of the gene having the fusion boundary. + gene is a Gene object,return a list of Transcript objects''' + if part not in ['5','3']: + raise Exception('part must be "5" or "3"') + txuse=[] ## + g=gene.name + strand=gene.strand + if part=='5': + tag='big' if strand=='1' else 'small' + else: + tag='small' if strand=='1' else 'big' + txs=gene.transcript + if tag=='small': + for tx in txs: + e_pos=[x.start for x in tx.exon] + if exon_end in e_pos: + txuse.append(tx) + elif tag=='big': + for tx in txs: + e_pos=[x.end for x in tx.exon] + if exon_end in e_pos: + txuse.append(tx) + return txuse + +def overlap(r1,r2): + '''compare two ranges, return the overlapped''' + if r1[0] <= r2[0]: + ra,rb=r1[:],r2[:] + else: + ra,rb=r2[:],r1[:] + if rb[0] > ra[1]: + return [] + else: + if rb[1] <= ra[1]: + return rb + else: + return [rb[0],ra[1]] + +def br_front_len(tx,br,part): + '''No matter it is 5'/3' partner,calculate the ORF length before the break''' + global tx_cds + txname=tx.name + strand=tx.strand + cds_start,cds_end=[int(x) for x in tx_cds[txname]] + e_pos=[[x.start,x.end] for x in tx.exon] + if part=='5' and strand=='1': + posset=[x.end for x in tx.exon] + if br not in posset: + raise Exception('Br is not exon boundary') + if br < cds_start: + return '5UTR' + elif br > cds_end: + return '3UTR' + else: + chim_r=[cds_start,br] + ol=[overlap(x,chim_r) for x in e_pos] + L=sum([x[1]-x[0]+1 for x in ol if len(x)>0]) + return L + if part=='5' and strand=='-1': + posset=[x.start for x in tx.exon] + if br not in posset: + raise Exception('Br is not exon boundary') + if br > cds_end: + return '5UTR' + elif br < cds_start: + return '3UTR' + else: + chim_r=[br,cds_end] + ol=[overlap(x,chim_r) for x in e_pos] + L=sum([x[1]-x[0]+1 for x in ol if len(x)>0]) + return L + if part=='3' and strand=='1': + posset=[x.start for x in tx.exon] + if br not in posset: + raise Exception('Br is not exon boundary') + if br < cds_start: + return '5UTR' + elif br > cds_end: + return '3UTR' + else: + chim_r=[cds_start,br-1] + ol=[overlap(x,chim_r) for x in e_pos] + L=sum([x[1]-x[0]+1 for x in ol if len(x)>0]) + return L + if part=='3' and strand=='-1': + posset=[x.end for x in tx.exon] + if br not in posset: + raise Exception('Br is not exon boundary') + if br > cds_end: + return '5UTR' + elif br < cds_start: + return '3UTR' + else: + chim_r=[br+1,cds_end] + ol=[overlap(x,chim_r) for x in e_pos] + L=sum([x[1]-x[0]+1 for x in ol if len(x)>0]) + return L + +def fusion_frame(gene_a,ga_br,gene_b,gb_br): + '''gene_a:FGFR3,gene_b:TACC3,ga_br:1808661,gb_br:1741429 + or chr4.1808661.chr4.1741429''' + global genedb,txdb + ga_br=int(ga_br) + gb_br=int(gb_br) + ga_txs=maptranscript(genedb[gene_a],ga_br,part='5') + gb_txs=maptranscript(genedb[gene_b],gb_br,part='3') + res=[] + for ta in ga_txs: + for tb in gb_txs: + s1=br_front_len(ta,ga_br,'5') + s2=br_front_len(tb,gb_br,'3') + fusion_conseq='Unknown' + if isinstance(s1,int) and isinstance(s2,int): #both br in CDS region + if s1%3==s2%3: + fusion_conseq='In-frame' + else: + fusion_conseq='Out-of-frame' + elif isinstance(s1,int) and not isinstance(s2,int): + fusion_conseq='CDS'+'-'+s2 + elif isinstance(s2,int) and not isinstance(s1,int): + fusion_conseq=s1+'-'+'CDS' + else: + fusion_conseq=s1+'-'+s2 + res.append((ta.name,tb.name,fusion_conseq)) + if ga_txs==[] and gb_txs==[]: + res.append(['NA','NA','NA']) + elif ga_txs==[]: + for tb in gb_txs: + res.append(['NA',tb.name,'NA']) + elif gb_txs==[]: + for ta in ga_txs: + res.append([ta.name,'NA','NA']) + return res + +############################################################################ +print 'Predicting...' +infile=open(datafilename) +outfile_detail=open(outfile_detail,'w') +outfile_brief=open(outfile_brief,'w') +detailM=[] +briefM=[] +for line in infile: + if not line.strip(): + continue + geneA,ga_br,geneB,gb_br=line.split() + try: + M=fusion_frame(geneA,ga_br,geneB,gb_br) + except: + M=[] + ppcollected=0 + for ccc in M: + a_cat,b_cat='alternative','alternative' + if tx_primary[geneA]==ccc[0]: + a_cat='primary' + if tx_primary[geneB]==ccc[1]: + b_cat='primary' + tag='%s_%s'%(a_cat,b_cat) + if ccc[0]=='NA' or ccc[1]=='NA': + tag='NA' + row_d=[geneA,ga_br,geneB,gb_br,ccc[0],ccc[1],tag,ccc[2]] #genea,geneb,tag,consequence + detailM.append(row_d) + if tag=='primary_primary': + row_b=[geneA,ga_br,geneB,gb_br,ccc[2]] + ppcollected=1 + if ppcollected==0: + row_b=[geneA,ga_br,geneB,gb_br,'not-classified'] + briefM.append(row_b) +infile.close() + +for line in detailM: + outfile_detail.write('%s\n'%('\t'.join(line))) +outfile_detail.close() + +for line in briefM: + outfile_brief.write('%s\n'%('\t'.join(line))) +outfile_brief.close() + +print 'Done!'
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/prada-fusion Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,630 @@ +#!/usr/bin/env python + +#PRADA: Pipeline for RnAseq Data Analysis +#Fusion detection module, algorithm published by Michael Berger et al (Genome Res, 2010) at Broad Institute. +#Implemented by Siyuan Zheng, Wandaliz Torres-Garcia and Rahul Vegesna. +#Copy Right: The Univ of Texas MD Anderson Cancer Center, Department of Bioinformatics and Computational Biology +#Contact: Roel Verhaak (rverhaak@mdanderson.org) +#Citation: to be added +#Tested with Python v2.6 and v2.7 +#The program requires NM tag and high quality mapping reads with mapping score more than -minmapq. +#Last modified: 04/11/2013 + +###################################################################################### +import sys +import time +import os +import os.path +import subprocess +import operator +import pysam +import bioclass +import gfclass +import ioprada +import privutils +from Bio import SeqIO,Seq + +###################################################################################### +args=sys.argv + +help_menu='''\nPipeline for RNAseq Data Analaysis - fusion detection (PRADA). + **Command**: + prada-fusion -bam XX.bam -conf xx.txt -tag XX -mm 1 -junL XX -minmapq 30 -outdir ./ + **Parameters**: + -h print help message + -bam input BAM file, must has a .bam suffix. BAM is the output from PRADA preprocess module. + -conf config file for references and parameters. Use conf.txt in py-PRADA installation folder if none specified. + -tag a tag to describe the sample, used to name output files. Default is ''. + -mm number of mismatches allowed in discordant pairs and fusion spanning reads.Default is 1. + -junL length of sequences taken from EACH side of exons when making hypothetical junctions. No default. + -minmapq minimum read mapping quality to be considered as fusion evidences. Default is 30. + -outdir output directory. + -v print version +''' + +if '-h' in args or '-help' in args or len(args)==1: + print help_menu + sys.exit(0) + +if '-v' in args: + import version + print version.version + sys.exit(0) + +if '-bam' not in args: + sys.exit('ERROR: BAM file needed') +i=args.index('-bam') +bampath=args[i+1] +bampath=os.path.abspath(bampath) +bam=os.path.basename(bampath) +if bam[-4:] != '.bam': + sys.exit('ERROR: BAM file must have suffix .bam') + +#Mismatch allowed. This filter is applied at the very end of the pipeline. +#I strongly suggest 1. We also record how many junction spanning reads (JSRs) are perfect matched. +if '-mm' not in args: + mm=1 +else: + i=args.index('-mm') + mm=int(args[i+1]) + +#junL should be less than the read length in the dataset. I suggest it to be read_length*0.8 +if '-junL' not in args: + sys.exit('ERROR: junL must be specified') +i=args.index('-junL') +overlap=int(args[i+1]) + +#minimum mapping quality for reads as fusion evidences +if '-minmapq' not in args: + minmapq=30 +else: + i=args.index('-minmapq') + minmapq=int(args[i+1]) + +if '-outdir' not in args: + outpath=os.path.abspath('./') +else: + i=args.index('-outdir') + outpath=os.path.abspath(args[i+1]) +if os.path.exists(outpath): + print 'WARNING: outdir %s exists'%outpath +else: + os.mkdir(outpath) + +if '-tag' not in args: + docstring='prada' +else: + i=args.index('-tag') + docstring=args[i+1] + +#by default, search conf.txt in the prada folder +prada_path=os.path.dirname(os.path.abspath(__file__)) #path to find libraries and executives. +ref_search_path=[prada_path,os.getcwd()] #search path for conf file if not specified in command line + +if '-conf' in args: + i=args.index('-ref') + reffile=args[i+1] + if os.path.exists(reffile): + pass + else: + for pth in ref_search_path: + new_reffile='%s/%s'%(pth, os.path.basename(reffile)) + if os.path.exists(new_reffile): + reffile=new_reffile + break + else: + sys.exit('ERROR: conf file %s not found'%reffile) +else: + reffile='%s/conf.txt'%prada_path + if not os.path.exists(reffile): + sys.exit('ERROR: No default conf.txt found and none specified') + +#Now print all input parameters +print 'CMD: %s'%('\t'.join(args)) + +#reference files pointing to the annotation files. +refdict=ioprada.read_conf(reffile) +featurefile=refdict['--REF--']['feature_file'] +txseqfile=refdict['--REF--']['tx_seq_file'] +txcatfile=refdict['--REF--']['txcat_file'] +cdsfile=refdict['--REF--']['cds_file'] + +#underlying utilities, automatically detected +#these are customized tools. update is needed. +samtools='%s/tools/samtools-0.1.16/samtools'%prada_path +bwa='%s/tools/bwa-0.5.7-mh/bwa'%prada_path +blastn='%s/tools/blastn'%prada_path + +###################################################################################### +print 'step 0: loading gene annotations @ %s'%time.ctime() +#call functions in ioprada module // +txdb,genedb=ioprada.read_feature(featurefile,verbose=True) +tx_primary=ioprada.read_tx_cat(txcatfile) +tx_cds=ioprada.read_cds(cdsfile) + +###################################################################################### +print 'step 1: finding discordant pairs @ %s'%time.ctime() + +#We sift through all exons of protein coding genes and get the mapping reads. +#Within, we exclude low mapping quality reads and PCR duplicates. For pairs that the two ends +#map to different genes, we all it a discordant pair. +#This is a step for finding all possible candidate fusions. + +samfile=pysam.Samfile(bampath,'rb') + +read1_ab={} +read2_ab={} +db1={} +db2={} + +i,N=0,len(genedb) +for gene in genedb: + i+=1 + if i%200==0: + print '%d/%d genes processed for discordant pairs'%(i,N) + g=genedb[gene] + exons=g.get_exons() + for e in exons.values(): + for rd in samfile.fetch(e.chr,e.start-1,e.end): + if rd.mapq < minmapq: + continue + if rd.is_duplicate: + continue + if rd.mate_is_unmapped: #at this point, only consider pairs + continue + if rd.rnext == rd.tid and rd.mpos <= g.end and rd.mpos >= g.start-1: #remove reads that fall into the same gene range + continue + if rd.is_read1: + if read1_ab.has_key(rd.qname): + read1_ab[rd.qname].add(gene) + else: + read1_ab[rd.qname]=set([gene]) + db1[rd.qname]=rd + if rd.is_read2: + if read2_ab.has_key(rd.qname): + read2_ab[rd.qname].add(gene) + else: + read2_ab[rd.qname]=set([gene]) + db2[rd.qname]=rd + +##output the discordant pairs and determine the orientation of candidate fusions +discordant={} #catalogue all discordant pairs, using gene pairs as keys +outfile=open('%s/%s.discordant.txt'%(outpath,docstring),'w') +title=['read','gene1','gene1_chr','read1_pos','read1_mm','read1_strand','read1_orient','gene2',\ + 'gene2_chr','read2_pos','read2_mm','read2_strand','read2_orient'] +outfile.write('%s\n'%('\t'.join(title))) +i=0 +for rdid in read1_ab: + i+=1 + if i%10000==0: + print '%d discordant pairs processed'%i + if not read2_ab.has_key(rdid): #skip if not all ends are catalogued + continue + g1set=read1_ab[rdid] #consider all combinations if a read maps to multiple genes + g2set=read2_ab[rdid] #consider all combinations if a read maps to multiple genes + r1,r2=db1[rdid],db2[rdid] + read1strd='-1' if r1.is_reverse else '1' + read2strd='-1' if r2.is_reverse else '1' + for g1 in g1set: + for g2 in g2set: + if g1==g2: #for some uncasual cases + continue + g1obj,g2obj=genedb[g1],genedb[g2] + read1orient='F' if read1strd == g1obj.strand else 'R' #read1 --> gene1 + read2orient='F' if read2strd == g2obj.strand else 'R' #read2 --> gene2 + fkey='' + if read1orient=='F' and read2orient=='R': ##scenario I, gene1-gene2 + fkey=g1+'_'+g2 + if read1orient=='R' and read2orient=='F': ##scenario II, gene2-gene1 + fkey=g2+'_'+g1 + if fkey: + if discordant.has_key(fkey): + discordant[fkey].update({rdid:'%s:%s'%(read1orient,read2orient)}) + else: + discordant[fkey]={rdid:'%s:%s'%(read1orient,read2orient)} + ##output + nm1=str([x[1] for x in r1.tags if x[0]=='NM'][0]) #output mismatch, but does not consider it at this point + nm2=str([x[1] for x in r2.tags if x[0]=='NM'][0]) + uvec=[rdid,g1,g1obj.chr,str(r1.pos+1),nm1,read1strd,read1orient,g2,g2obj.chr,str(r2.pos+1),nm2,read2strd,read2orient] + outfile.write('%s\n'%('\t'.join(uvec))) +outfile.close() + +########################################################################## +print 'step 2: finding recurrent pairs (candidates) @ %s'%time.ctime() + +#step 2 finds all candidates that have at least 2 discordant pairs. Meanwhile, filter out potential +#read through events. read through is defined as reads with mapping position less than 1M, while meeting +#the strand expectation. + +guess=[] +outfile=open('%s/%s.recurrent.txt'%(outpath,docstring),'w') +title=['geneA','geneA_chr','geneB','geneB_chr','num_pairs','IDs'] +outfile.write('%s\n'%('\t'.join(title))) +for pp in discordant: + if len(discordant[pp]) < 2: #consider only "recurrent" (more than 1 pair support) cases + continue + gene1,gene2=pp.split('_') + g1obj,g2obj=genedb[gene1],genedb[gene2] + rdset=discordant[pp].keys() + #filter read-through + #readthrough is defined at read level, regardless of mapping genes + for rd in rdset: + r1,r2=db1[rd],db2[rd] + read1strd='-1' if r1.is_reverse else '1' + read2strd='-1' if r2.is_reverse else '1' + readthrough=False + if db1[rd].tid == db2[rd].tid and abs(db1[rd].pos - db2[rd].pos) <= 1000000: + if discordant[pp][rd]=='F:R': + if read1strd=='1' and read2strd=='-1' and db1[rd].pos < db2[rd].pos: + readthrough=True + if read1strd=='-1' and read2strd=='1' and db1[rd].pos > db2[rd].pos: + readthrough=True + if discordant[pp][rd]=='R:F': + if read2strd=='1' and read1strd=='-1' and db2[rd].pos < db1[rd].pos: + readthrough=True + if read2strd=='-1' and read1strd=='1' and db2[rd].pos > db1[rd].pos: + readthrough=True + if readthrough: + del discordant[pp][rd] #in-place deletion!!!! Change the discordant variable in place! + if len(discordant[pp]) < 2: #skip all that have less than 2 supporting discordant read pairs after readthrough filter + continue + guess.append(pp) + #output + uvec2=[gene1,g1obj.chr,gene2,g2obj.chr,str(len(discordant[pp])),'|'.join(discordant[pp])] + outfile.write('%s\n'%('\t'.join(uvec2))) +outfile.close() + +########################################################################## +print 'step 3: finding potential junction spanning reads @ %s'%time.ctime() + +#For all candidates, find potential junction spanning reads (JSRs). A JSR is defined as a unmapped read but with the mate mapping +#to either F or R partner, with high mapping quality. Since the JSR is unmapped, it is not practical to consider PCR duplicate +#because they are not properly marked. + +Fpartners=set() +Rpartners=set() +for pp in guess: + gs=pp.split('_') + Fpartners.add(gs[0]) + Rpartners.add(gs[1]) +AllPartners=Fpartners|Rpartners + +samfile.reset() +posjun={} ##catalogue all JSRs, with track of the mate mapping genes and orientation. +i,N=0,len(AllPartners) +for gene in AllPartners: + i+=1 + if i%200==0: + print '%d/%d genes processed for potential junc reads'%(i,N) + g=genedb[gene] + exons=g.get_exons().values() + for e in exons: + for rd in samfile.fetch(e.chr,e.start-1,e.end): + if rd.mapq < minmapq: + continue + if not rd.mate_is_unmapped: + continue + readstrd='-1' if rd.is_reverse else '1' + orient='F' if readstrd == g.strand else 'R' #mapping info of mate read. JSR per se is unmapped in BAM + posjun[rd.qname]={'gene':gene,'orient':orient} + +samfile.reset() +outfile=open('%s/%s.pos_junc_unmapped.fastq'%(outpath,docstring),'w') +i,N=0,len(posjun) +for rd in samfile: + if rd.mate_is_unmapped: #since the read is potential jun spanning read, all mate map to A or B + continue + if rd.is_unmapped: + if posjun.has_key(rd.qname): + i+=1 + if i%10000==0: + print 'extracted %d/%d potential junc reads'%(i,N) + rdname='%s_prada_%s_prada_%s'%(rd.qname,posjun[rd.qname]['gene'],posjun[rd.qname]['orient']) #_prada_ as split + outfile.write('@%s\n'%rdname) + outfile.write('%s\n'%rd.seq) + outfile.write('+\n') + outfile.write('%s\n'%rd.qual) +outfile.close() + +###################################################################################### +print 'step 4: building junction database @ %s'%time.ctime() + +#Make hypothetical junctions between candidate fusion partners. To improve speed, we make a big junction database comprising +#exons of all candidates, instead of by candidate individually. This also gives the possibility to assess the JSR mapping ambiguity +#across many junctions. It turned out very useful in filtering out false positives. +#Note that in PRADA transcript sequence file, all sequences are + strand sequences. For - strand transcript, one need to +#reverse complement the sequence to get the real transcript sequences. + +seqdb={} +for record in SeqIO.parse(txseqfile,'fasta'): + seqdb[record.name]=record + +outfile=open('%s/%s.junction.fasta'%(outpath,docstring),'w') +i,N=0,len(guess) +for pp in guess: + i+=1 + if i%100==0: + print 'building junction for %d/%d pairs'%(i,N) + gene1,gene2=pp.split('_') + g1obj,g2obj=genedb[gene1],genedb[gene2] + eset1=g1obj.get_exons() #unique exons in gene 1 + eset2=g2obj.get_exons() #unique exons in gene 2 + #collect unique junctions + juncseqdict={} #save junction sequences + for e1 in eset1.values(): + for e2 in eset2.values(): + e1_jun_name='%s:%s:%s'%(gene1,e1.chr,e1.end) if e1.strand=='1' else '%s:%s:%s'%(gene1,e1.chr,e1.start) + e2_jun_name='%s:%s:%s'%(gene2,e2.chr,e2.start) if e2.strand=='1' else '%s:%s:%s'%(gene2,e2.chr,e2.end) + jun_name=e1_jun_name+'_'+e2_jun_name + tx1,tx2=txdb[e1.transcript],txdb[e2.transcript] + max_a=tx1.exon_relative_pos()[e1.name][1] + min_a=0 if max_a - overlap < 0 else max_a - overlap + min_b=tx2.exon_relative_pos()[e2.name][0]-1 + max_b=tx2.length if min_b + overlap > tx2.length else min_b + overlap + #reverse complementary when necessary + try: + tx1seq=seqdb[tx1.name].seq.tostring() if tx1.strand=='1' else seqdb[tx1.name].reverse_complement().seq.tostring() + tx2seq=seqdb[tx2.name].seq.tostring() if tx2.strand=='1' else seqdb[tx2.name].reverse_complement().seq.tostring() + except KeyError: #in case transcript not found in sequence file + continue + jun_seq=tx1seq[min_a:max_a]+tx2seq[min_b:max_b] + juncseqdict[jun_name]=jun_seq + for junc in juncseqdict: + outfile.write('>%s\n'%junc) + outfile.write('%s\n'%juncseqdict[junc]) +outfile.close() +samfile.close() + +#for memory efficiecy, del seqdb +del seqdb + +######################################################################################## +print 'step 5: aligning potential junction reads to junction database @ %s'%time.ctime() + +#Mapping potential JSRs to hypothetical junction database. +#Allow 4 mismatches at the beginning. + +idx_cmd='%s index %s/%s.junction.fasta'%(bwa,outpath,docstring) +os.system(idx_cmd) +aln_cmd='%s aln -n 4 -R 100 %s/%s.junction.fasta %s/%s.pos_junc_unmapped.fastq > %s/%s.juncmap.sai'%(bwa,outpath,docstring,outpath,docstring,outpath,docstring) +os.system(aln_cmd) +samse_cmd='%s samse -n 1000 -s %s/%s.junction.fasta %s/%s.juncmap.sai %s/%s.pos_junc_unmapped.fastq > %s/%s.juncmap.sam'%(bwa,outpath,docstring,outpath,docstring,outpath,docstring,outpath,docstring) +os.system(samse_cmd) +sam2bam_cmd='%s view -bS %s/%s.juncmap.sam -o %s/%s.juncmap.bam'%(samtools,outpath,docstring,outpath,docstring) +os.system(sam2bam_cmd) + +jsam=pysam.Samfile('%s/%s.juncmap.bam'%(outpath,docstring),'rb') +#get the junction name directory +junctions=jsam.references +junname=dict(zip(range(0,len(junctions)),junctions)) #this is essential for quick speed. +junc_align={} + +#go through the BAM file for meaningful (meeting fusion orientation etc) reads +strd_right_reads={} +rdb={} #collect all junction spanning reads +i=0 +for rd in jsam: + i+=1 + if i%100000==0: + print '%d junction alignments parsed'%i + if rd.is_unmapped: + continue + read,mate_gene,mate_orient=rd.qname.split('_prada_') + junc=junname[rd.tid] + tmp=junc.split('_') + gene1,gene2=[x.split(':')[0] for x in tmp] + if gene1==mate_gene: + if mate_orient=='F': + if rd.is_reverse: + if strd_right_reads.has_key(rd.qname): + strd_right_reads[rd.qname]+=1 #count how many times the read maps + else: + strd_right_reads[rd.qname]=1 + rdb[rd.qname]={'read':rd,'gene1':gene1,'gene2':gene2,'junc':junc} #will overwrite, but it is OK since we only look at unique ones + elif gene2==mate_gene: + if mate_orient == 'R': + if not rd.is_reverse: + if strd_right_reads.has_key(rd.qname): + strd_right_reads[rd.qname]+=1 + else: + strd_right_reads[rd.qname]=1 + rdb[rd.qname]={'read':rd,'gene1':gene1,'gene2':gene2,'junc':junc} #will overwrite, but it is OK since we only look at unique ones + +#find uniquely mapped reads and their gene pairs +junc_map={} #a dictionary from junction to mapping reads +for rdname in strd_right_reads: + if strd_right_reads[rdname] > 1: #remove non-unique junction spanning reads + continue + infodict=rdb[rdname] + pp=infodict['gene1']+'_'+infodict['gene2'] + if junc_map.has_key(pp): + junc_map[pp].add(rdname) + else: + junc_map[pp]=set([rdname]) + +######################################################################################## +print 'step 6: summarizing fusion evidences @ %s'%time.ctime() + +#Now, time to apply mismatch filter and summarize the results +#Candidate fusions --> guess +#Discordant pairs --> discordant, db1, db2 +#Junction reads --> junc_map, rdb +#Gene info --> genedb + +outfile_s=open('%s/%s.fus.candidates.txt'%(outpath,docstring),'w') +outfile_d=open('%s/%s.fus.evidences.txt'%(outpath,docstring),'w') + +title=['Gene_A','Gene_B','A_chr','B_chr','A_strand','B_strand','Discordant_n','JSR_n','perfectJSR_n','Junc_n','Position_Consist','Junction'] +outfile_s.write('%s\n'%('\t'.join(title))) + +for pp in junc_map: #all pairs with junc reads + gene1,gene2=pp.split('_') + g1obj,g2obj=genedb[gene1],genedb[gene2] + fus_disc=[] #collecting discordant pairs + for rdname in discordant[pp]: + #arrange read1/read2 into F/R so it will be easier for GeneFusion obj to handle + r1,r2=db1[rdname],db2[rdname] + orient=discordant[pp][rdname] + if orient=='F:R': + fus_disc.append((r1,r2)) + elif orient=='R:F': + fus_disc.append((r2,r1)) + fus_jsr=[] + if junc_map.has_key(pp): + for rdname in junc_map[pp]: + r=rdb[rdname]['read'] + junc=rdb[rdname]['junc'] + jsr=gfclass.JSR(r,junc) + fus_jsr.append(jsr) + gf=gfclass.GeneFusion(gene1,gene2,fus_disc,fus_jsr) + gf_new=gf.update(mm=mm) ##apply the mismatch parameter, default is 1 + #output the results + disc_n=str(len(gf_new.discordantpairs)) + junctions=sorted(gf_new.get_junction_freq(),key=operator.itemgetter(1),reverse=True) #sort junc by # of JSRs + junc_n=str(len(junctions)) + junc_str='|'.join([','.join([x[0],str(x[1])]) for x in junctions]) + jsr_n=str(len(gf_new.fusionreads)) + pjsr_n=str(len(gf_new.get_perfect_JSR())) + pos_consist=gf_new.positioncheck() + svec=[gene1,gene2,g1obj.chr,g2obj.chr,g1obj.strand,g2obj.strand,disc_n,jsr_n,pjsr_n,junc_n,pos_consist,junc_str] + outfile_s.write('%s\n'%('\t'.join(svec))) + outfile_d.write('@@\t%s,%s,%s\t%s,%s,%s\n'%(gene1,g1obj.chr,g1obj.strand,gene2,g2obj.chr,g2obj.strand)) + outfile_d.write('\n') + outfile_d.write('>discordant\n') + for rp in gf_new.discordantpairs: + rf,rr=rp + nm1=[x[1] for x in rf.tags if x[0]=='NM'][0] + nm2=[x[1] for x in rr.tags if x[0]=='NM'][0] + outfile_d.write('%s\tF\t%s.%s.mm%d\n'%(rf.qname,gene1,rf.pos+1,nm1)) ##0-based coordinates + outfile_d.write('%s\tR\t%s.%s.mm%d\n'%(rr.qname,gene2,rr.pos+1,nm2)) ##0-based coordinates + outfile_d.write('\n') + outfile_d.write('>spanning\n') + for jsr in gf_new.fusionreads: + r=jsr.read + nm=[x[1] for x in r.tags if x[0]=='NM'][0] + outfile_d.write('%s\t%s.mm%d\n'%(r.qname,jsr.junction,nm)) + outfile_d.write('\n') + outfile_d.write('>junction\n') + for junc_info in junctions: + outfile_d.write('%s\t%d\n'%(junc_info[0],junc_info[1])) + outfile_d.write('\n') + outfile_d.write('>summary\n') + outfile_d.write('Number of Discordant Pairs = %s\n'%disc_n) + outfile_d.write('Number of Fusion Reads = %s\n'%jsr_n) + outfile_d.write('Number of Perfect Fusion Reads = %s\n'%pjsr_n) + outfile_d.write('Number of Distinct Junctions = %s\n'%junc_n) + outfile_d.write('Position Consistency = %s\n'%pos_consist) + outfile_d.write('\n') + +outfile_s.close() +outfile_d.close() + +######################################################################################## +print 'step 7: generating fusion lists @ %s'%time.ctime() + +#For convenience, filter the lists to candidates with +# 1) at least 2 discordant pairs +# 2) at least 1 perfect JSR +#meanwhile, calculate sequence similarity for each pair +#user may need to manually filter the lists per this measure. + +#The following code is a copy of prada-homology +outfile_o=open('%s/%s.fus.summary.txt'%(outpath,docstring),'w') +ifname='%s/%s.fus.candidates.txt'%(outpath,docstring) +if not os.path.exists(ifname): + sys.exit('ERROR: %s was not found'%ifname) + +blastseq_tmp_dir='%s/blast_tmp/'%outpath +if not os.path.exists(blastseq_tmp_dir): + os.mkdir(blastseq_tmp_dir) + +flists=[] +infile=open(ifname) +iN=0 +for line in open(ifname): + info=line.strip().split('\t') + if iN==0: + iN+=1 #skip title + flists.append(info) + continue + else: + if int(info[6])>=2 and int(info[8])>=1 and info[10] in ['PARTIALLY','YES']: + flists.append(info) +infile.close() + +if len(flists)==1: #if no candidate passes the filters + outfile_o.write('%s\n'%'\t'.join(flists[0])) + outfile_o.close() + print 'step done @ %s'%time.ctime() + sys.exit(0) + +candidates={} +for line in flists[1:]: + geneA,geneB=line[0],line[1] + key='%s_%s'%(geneA,geneB) + candidates[key]='' + +selecttranscript={} +for gene in genedb: + txs=genedb[gene].transcript + stx=txs[0] + initlen=stx.length + for tx in txs: + if tx.length >= initlen: + stx=tx + initlen=stx.length + selecttranscript[gene]=stx.name + +allpartners=set() +for item in candidates: + sset=set(item.split('_')) + allpartners=allpartners.union(sset) + +presenttxs=[] #tx that is present in our annotation +absent=[] #tx that is not in our annotation +for gene in allpartners: + if selecttranscript.has_key(gene): + presenttxs.append(selecttranscript[gene]) + else: + absent.append(gene) + +for seq_record in SeqIO.parse(txseqfile,'fasta'): + sid=seq_record.id + seq=seq_record.seq + if sid in presenttxs: + g=txdb[sid].gene + fastafile=open('%s/%s.fasta'%(blastseq_tmp_dir,g),'w') + SeqIO.write(seq_record,fastafile,'fasta') + fastafile.close() + +for gp in candidates: + geneA,geneB=gp.split('_') + if geneA in absent or geneB in absent: + candidates[gp]=['NA']*4 + else: + gaseq='%s/%s.fasta'%(blastseq_tmp_dir,geneA) + gaobj=SeqIO.parse(gaseq,'fasta').next() + gbseq='%s/%s.fasta'%(blastseq_tmp_dir,geneB) + gbobj=SeqIO.parse(gbseq,'fasta').next() + ga_len,gb_len=str(len(gaobj.seq)),str(len(gbobj.seq)) + a=privutils.seqblast(gaseq,gbseq,blastn) + if a==None: + candidates[gp]=['NA','NA','100','0'] + else: + candidates[gp]=a + +header=flists[0][:] +header.extend(['Identity','Align_Len','Evalue','BitScore']) +outfile_o.write('%s\n'%('\t'.join(header))) + +for info in flists[1:]: + geneA,geneB=info[0],info[1] + key='%s_%s'%(geneA,geneB) + vv=candidates[key] + row=info[:] + row.extend(vv) + outfile_o.write('%s\n'%('\t'.join(row))) +outfile_o.close() + +######################################################################################## +print 'step done @ %s'%time.ctime()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/prada-guess-ft Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,321 @@ +#!/usr/bin/env python + +#GUESS-ft:General UsEr defined Supervised Search for fusion transcript. +#This program is to perform targeted search of gene fusions from RNAseq data. +#It uses samtools, pysam package. It requires a bam file and other reference files. +#Note that it is a less accurate tool than prada-fusion. + +import pysam +import subprocess +import os +import time +import sys +import bioclass +import ioprada + +args=sys.argv + +#Get all parameters +help_menu='''\nUsage: prada-guess-ft GeneA GeneB -conf xx.txt -inputbam X -mm 1 -minmapq 30 -junL X -outdir X -unmap X\n + **Parameters**: + -conf the configure file. see prada-fusion -conf for details + -inputbam the input bam file + -mm number of mismatch allowed + -minmapq mininum mapping quality for reads to be used in fusion finding + -junL length of exons to be used for junctions. see prada-fusion + -outdir output directory + -unmap the numapped reads. useful if user need to run guess-ft multiple times +''' + +if '-h' in args or '-help' in args or len(args)==1: + print help_menu + sys.exit(0) + +################################################################################## +Gene_A=args[1] +Gene_B=args[2] +if '-inputbam' not in args: + sys.exit('Input BAM needed') +else: + i=args.index('-inputbam') + sourcefile=args[i+1] +if '-outdir' not in args: + outdir='./' +else: + i=args.index('-outdir') + outdir=args[i+1] + if not os.path.exists(outdir): + os.mkdir(outdir) +if '-unmap' not in args: #get unmapped.bam yourself + unmapbam='%s/one.end.unmapped.bam'%outdir + extract_mask=1 +else: + i=args.index('-unmap') + unmapbam=args[i+1] + extract_mask=0 +if '-mm' not in args: + mm=1 +else: + i=args.index('-mm') + mm=int(args[i+1]) +#minimum mapping quality for reads as fusion evidences +if '-minmapq' not in args: + minmapq=30 +else: + i=args.index('-minmapq') + minmapq=int(args[i+1]) + +if '-junL' not in args: + sys.exit('-junL needed') +else: + i=args.index('-junL') + junL=int(args[i+1]) + +prada_path=os.path.dirname(os.path.abspath(__file__)) #### +ref_search_path=[prada_path,os.getcwd()] #search path for ref file if not specified in command line + +if '-conf' in args: + i=args.index('-conf') + reffile=args[i+1] + if os.path.exists(reffile): + pass + else: + for pth in ref_search_path: + new_reffile='%s/%s'%(pth, os.path.basename(reffile)) + if os.path.exists(new_reffile): + reffile=new_reffile + break + else: + sys.exit('ERROR: ref file %s not found'%reffile) +else: + reffile='%s/conf.txt'%prada_path + if not os.path.exists(reffile): + sys.exit('ERROR: No default conf.txt found and none specified') + +#reference files +refdict=ioprada.read_conf(reffile) +ref_anno=refdict['--REF--']['ref_anno'] +ref_map=refdict['--REF--']['ref_map'] +ref_fasta=refdict['--REF--']['ref_fasta'] +featurefile=refdict['--REF--']['feature_file'] + +samtools='%s/tools/samtools-0.1.16/samtools'%prada_path +bwa='%s/tools/bwa-0.5.7-mh/bwa'%prada_path + +print 'GUESS start: %s'%time.ctime() +print 'CMD: %s'%('\t'.join(args)) + +################################################################################## +##get gene position information + +gA,gB=ioprada.read_feature_genes(featurefile,Gene_A,Gene_B) +if gA is None: + sys.exit('%s not found'%Gene_A) +if gB is None: + sys.exit('%s not found'%Gene_B) + +#Generate unmapped reads. +if extract_mask: + cmd='%s view -b -f 4 -F 8 %s > %s'%(samtools,sourcefile,unmapbam) + cmdout=subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,shell=True) + while True: + if cmdout.poll() is None: + print 'Extracting unmapped reads...' + time.sleep(120) + pass + if cmdout.poll()==0: + print 'Extracted unmapped reads' + break + if cmdout.poll() is not None and cmdout.poll() != 0: + raise Exception('Error extracting unmapped reads') + +#Generate junction db +juncfile='%s_%s.junction.fasta'%(Gene_A,Gene_B) +cmd='perl %s/make_exon_junctions.pl %s %s %s %s %s %d > %s/%s'%(prada_path,Gene_A,Gene_B,ref_anno,ref_map,ref_fasta,junL,outdir,juncfile) +cmdout=subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,shell=True) +while True: + if cmdout.poll() is None: + print 'Generating junction db. Waiting...' + time.sleep(20) + pass + if cmdout.poll()==0: + print 'Generated Junction DB.' + break + if cmdout.poll() is not None and cmdout.poll() != 0: + raise Exception('Error generated Junction DB.') + +#read into the sam file, get gene-strand information +print 'Finding discordant read pairs.' +samfile = pysam.Samfile(sourcefile, "rb" ) + +#mapping quality based read collection +#strand information considered +#mismatch filter considered +a_reads=[] +b_reads=[] +for alignedread in samfile.fetch(gA.chr,gA.start-1,gA.end): + if alignedread.mapq >= minmapq: + readastrd='-1' if alignedread.is_reverse else '1' + mmf=[x[1] for x in alignedread.tags if x[0]=='NM'][0] + if readastrd==gA.strand and mmf <= mm: + a_reads.append(alignedread) + +for alignedread in samfile.fetch(gB.chr,gB.start-1,gB.end): + if alignedread.mapq >= minmapq: + readbstrd='-1' if alignedread.is_reverse else '1' + mmf=[x[1] for x in alignedread.tags if x[0]=='NM'][0] + if readbstrd != gB.strand and mmf <= mm: + b_reads.append(alignedread) +samfile.close() + +ar_ids=[x.qname for x in a_reads] +br_ids=[x.qname for x in b_reads] +disc=list(set(ar_ids).intersection(set(br_ids))) #discordant pairs + +#detect read pair that one end map to one partner, yet the other does not align +print 'Determining potential junction spanning reads.' +rpaonly=[] #reads that only map to gene A -- going to map the other end to junctions +for rd in a_reads: + if rd.mate_is_unmapped: + rpaonly.append(rd) +rpbonly=[] #reads that only map to gene B -- going to map the other end to junctions +for rd in b_reads: + if rd.mate_is_unmapped: + rpbonly.append(rd) +rpaonly_names=[x.qname for x in rpaonly] +rpbonly_names=[x.qname for x in rpbonly] + +#find read sequences +print 'Extracting unmapped read sequences.' +print 'mate unmapped read for gene A:',len(rpaonly) +print 'mate unmapped read for gene B:',len(rpbonly) +samfile=pysam.Samfile(unmapbam,'rb') +taga='%s-%s_a'%(Gene_A,Gene_B) +tagb='%s-%s_b'%(Gene_A,Gene_B) +resfq_a=open('%s/unmapreads_%s.fq'%(outdir,taga),'w') +resfq_b=open('%s/unmapreads_%s.fq'%(outdir,tagb),'w') +for item in samfile: + if item.qname in rpaonly_names: + resfq_a.write('@%s\n'%item.qname) + resfq_a.write('%s\n'%item.seq) + resfq_a.write('+\n') + resfq_a.write('%s\n'%item.qual) + if item.qname in rpbonly_names: + resfq_b.write('@%s\n'%item.qname) + resfq_b.write('%s\n'%item.seq) + resfq_b.write('+\n') + resfq_b.write('%s\n'%item.qual) +resfq_a.close() +resfq_b.close() +samfile.close() + +##indexing junction db +print 'Aligning reads to junction db' +cmd='%s index %s/%s'%(bwa,outdir,juncfile) +cmdout=subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,shell=True) +while True: + if cmdout.poll() is None: + time.sleep(3) + pass + if cmdout.poll()==0: + print 'Junction DB indexed.' + break + if cmdout.poll() is not None and cmdout.poll() != 0: + raise Exception('Error building junction db index') + +##align the unmapped reads to junction database +for rs in [taga,tagb]: + cmd='%s aln -n %d -R 100 %s/%s %s/unmapreads_%s.fq > %s/%s.sai'%(bwa,mm,outdir,juncfile,outdir,rs,outdir,rs) + cmdout=subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,shell=True) + while True: + if cmdout.poll() is None: + time.sleep(5) + pass + if cmdout.poll()==0: + print 'Aligned unmapped reads group %s'%rs + break + if cmdout.poll() is not None and cmdout.poll() != 0: + raise Exception('Error aligning unmapped reads for group %s'%rs) + + cmd='%s samse -n 1000 %s/%s %s/%s.sai %s/unmapreads_%s.fq > %s/%s.sam'%(bwa,outdir,juncfile,outdir,rs,outdir,rs,outdir,rs) + cmdout=subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,shell=True) + while True: + if cmdout.poll() is None: + time.sleep(2) + pass + if cmdout.poll()==0: + print 'Converting to sam for group %s'%rs + break + if cmdout.poll() is not None and cmdout.poll() != 0: + raise Exception('Error converting to sam for group %s'%rs) + +#parse results +qualrd_a=[] +junc_a=[] +samfile=pysam.Samfile('%s/%s.sam'%(outdir,taga),'r') +for rd in samfile: + if not rd.is_unmapped and rd.is_reverse: + qualrd_a.append(rd) + junc_a.append(samfile.getrname(rd.tid)) +samfile.close() +qualrd_b=[] +junc_b=[] +samfile=pysam.Samfile('%s/%s.sam'%(outdir,tagb),'r') +for rd in samfile: + if not rd.is_unmapped and not rd.is_reverse: + qualrd_b.append(rd) + junc_b.append(samfile.getrname(rd.tid)) +samfile.close() + +junc_span=[] +junc_span.extend(qualrd_a) +junc_span.extend(qualrd_b) + +junc_name=[] +junc_name.extend(junc_a) +junc_name.extend(junc_b) + +#Generate a summary report +sumfile=open('%s/%s_%s.GUESS.summary.txt'%(outdir,Gene_A,Gene_B),'w') +sumfile.write('%s\t%s\n'%(Gene_A,Gene_B)) +sumfile.write('\n') +sumfile.write('>discordant\n') +for rdname in disc: + ia=ar_ids.index(rdname) + ib=br_ids.index(rdname) + reada=a_reads[ia] + readb=b_reads[ib] + mm_a=[x[1] for x in reada.tags if x[0]=='NM'][0] + mm_b=[x[1] for x in readb.tags if x[0]=='NM'][0] + ss1='%s\tF\t%s.%d.mm%d'%(reada.qname,Gene_A,reada.pos+1,mm_a) #pysam use 0-based coordinates + ss2='%s\tR\t%s.%d.mm%d'%(readb.qname,Gene_B,readb.pos+1,mm_b) + sumfile.write('%s\n'%ss1) + sumfile.write('%s\n'%ss2) + +sumfile.write('\n') +sumfile.write('>spanning\n') +for i in range(len(junc_span)): + rd=junc_span[i] + jname=junc_name[i] + mm_j=[x[1] for x in rd.tags if x[0]=='NM'][0] + ss='%s\t%s.mm%d'%(rd.qname,jname,mm_j) + sumfile.write('%s\n'%ss) + +sumfile.write('\n') +sumfile.write('>junction\n') +juncol=[] +for item in set(junc_name): + nn=junc_name.count(item) + juncol.append([item,nn]) +juncol=sorted(juncol,key=lambda x:x[1],reverse=True) +for item in juncol: + sumfile.write('%s\t%s\n'%(item[0],item[1])) + +sumfile.write('\n') +sumfile.write('>summary\n') +sumfile.write('Number of Discordant Pairs = %d\n'%len(disc)) +sumfile.write('Number of Fusion Reads = %d\n'%len(junc_span)) +sumfile.write('Number of Distinct Junctions = %d\n'%len(set(junc_name))) + +sumfile.close() +print 'Done: %s'%time.ctime()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/prada-guess-if Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,288 @@ +#!/usr/bin/env python + +#GUESS-if is to find abnormal intragenic fusions. +#It is an extension of the GUESS-ft method. + +import pysam +import subprocess +import os +import time +import sys +import bioclass +import ioprada + +args=sys.argv + +#Get all parameters +help_menu='''\nUsage: prada-guess-if Gene -conf xx.txt -inputbam X -mm 1 -minmapq 30 -junL X -outdir ./ -unmap X\n + **Parameters**: + -conf the configure file. see prada-fusion -conf for details + -inputbam the input bam file + -mm number of mismatch allowed + -minmapq mininum mapping quality for reads to be used in fusion finding + -junL length of exons to be used for junctions. see prada-fusion + -outdir output directory + -unmap the numapped reads. useful if user need to run guess-ft multiple times +''' + +if '-h' in args or '-help' in args or len(args)==1: + print help_menu + sys.exit(0) + +######################################################################### +target=args[1] +if '-inputbam' not in args: + sys.exit('Input BAM needed') +else: + i=args.index('-inputbam') + sourcefile=args[i+1] +if '-outdir' not in args: + outdir='./' +else: + i=args.index('-outdir') + outdir=args[i+1] + if not os.path.exists(outdir): + os.mkdir(outdir) +if '-unmap' not in args: + unmapbam='%s/one.end.unmapped.bam'%outdir + extract_mask=1 +else: + i=args.index('-unmap') + unmapbam=args[i+1] + extract_mask=0 + +if '-mm' not in args: + mm=1 +else: + i=args.index('-mm') + mm=int(args[i+1]) + +#minimum mapping quality for reads as fusion evidences +if '-minmapq' not in args: + minmapq=30 +else: + i=args.index('-minmapq') + minmapq=int(args[i+1]) + +if '-junL' not in args: + sys.exit('-junL needed') +else: + i=args.index('-junL') + junL=int(args[i+1]) + +prada_path=os.path.dirname(os.path.abspath(__file__)) #### +ref_search_path=[prada_path,os.getcwd()] #search path for ref file if not specified in command line + +if '-conf' in args: + i=args.index('-conf') + reffile=args[i+1] + if os.path.exists(reffile): + pass + else: + for pth in ref_search_path: + new_reffile='%s/%s'%(pth, os.path.basename(reffile)) + if os.path.exists(new_reffile): + reffile=new_reffile + break + else: + sys.exit('ERROR: ref file %s not found'%reffile) +else: + reffile='%s/conf.txt'%prada_path + if not os.path.exists(reffile): + sys.exit('ERROR: No default conf.txt found and none specified') + +#reference files +refdict=ioprada.read_conf(reffile) +ref_anno=refdict['--REF--']['ref_anno'] +ref_map=refdict['--REF--']['ref_map'] +ref_fasta=refdict['--REF--']['ref_fasta'] +featurefile=refdict['--REF--']['feature_file'] + +samtools='%s/tools/samtools-0.1.16/samtools'%prada_path +bwa='%s/tools/bwa-0.5.7-mh/bwa'%prada_path + +######################################################################### +print 'GUESS-if start: %s'%time.ctime() +print 'CMD: %s'%('\t'.join(args)) + +##get gene position information +gobj=ioprada.read_feature_genes(featurefile,target)[0] +if gobj is None: + sys.exit('%s not found'%target) + +gchr=gobj.strand +gchr_rev=True if gchr=='-1' else False + +#Generate unmapped reads. +if extract_mask: + cmd='%s view -b -f 4 -F 8 %s > %s'%(samtools,sourcefile,unmapbam) + cmdout=subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,shell=True) + while True: + if cmdout.poll() is None: + print 'Extracting unmapped reads...' + time.sleep(120) + pass + if cmdout.poll()==0: + print 'Extracted unmapped reads' + break + if cmdout.poll() is not None and cmdout.poll() != 0: + raise Exception('Error extracting unmapped reads') + + +#Generate junction db +juncfile='%s.junction.fasta'%target +cmd='perl %s/make_intragenic_junctions.pl %s %s %s %s %s %d > %s/%s'%(prada_path,target,target,ref_anno,ref_map,ref_fasta,junL,outdir,juncfile) +cmdout=subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,shell=True) +while True: + if cmdout.poll() is None: + print 'Generating junction db. Waiting...' + time.sleep(20) + pass + if cmdout.poll()==0: + print 'Generated Junction DB.' + break + if cmdout.poll() is not None and cmdout.poll() != 0: + raise Exception('Error generated Junction DB.') + +#scan BAM file for mapping reads. +samfile=pysam.Samfile(sourcefile,'rb') +reads_se=[] +reads_as=[] +for alignedread in samfile.fetch(gobj.chr,gobj.start-1,gobj.end): + if alignedread.mapq >= minmapq: + mmf=[x[1] for x in alignedread.tags if x[0]=='NM'][0] + if mmf <= mm: + if alignedread.is_reverse==gchr_rev: #sense + reads_se.append(alignedread) + else: #anti-sense + reads_as.append(alignedread) +samfile.close() + +seonly,asonly=[],[] +for rd in reads_se: + if rd.mate_is_unmapped: + seonly.append(rd) +for rd in reads_as: + if rd.mate_is_unmapped: + asonly.append(rd) +seunmap=[x.qname for x in seonly] +asunmap=[x.qname for x in asonly] + +#find read sequences +print 'Extracting unmapped read sequences.' +print 'mate unmapped reads for sense strand:',len(seonly) +print 'mate unmapped reads for antisense strand:',len(asonly) +samfile=pysam.Samfile(unmapbam,'rb') +resfq_a=open('%s/%s_se_unmap.fq'%(outdir,target),'w') +resfq_b=open('%s/%s_as_unmap.fq'%(outdir,target),'w') +for item in samfile: + if item.qname in seunmap: + resfq_a.write('@%s\n'%item.qname) + resfq_a.write('%s\n'%item.seq) + resfq_a.write('+\n') + resfq_a.write('%s\n'%item.qual) + if item.qname in asunmap: + resfq_b.write('@%s\n'%item.qname) + resfq_b.write('%s\n'%item.seq) + resfq_b.write('+\n') + resfq_b.write('%s\n'%item.qual) +resfq_a.close() +resfq_b.close() +samfile.close() + +##indexing junction db +print 'Aligning reads to junction db' +cmd='%s index %s/%s'%(bwa,outdir,juncfile) +cmdout=subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,shell=True) +while True: + if cmdout.poll() is None: + time.sleep(3) + pass + if cmdout.poll()==0: + print 'Junction DB indexed.' + break + if cmdout.poll() is not None and cmdout.poll() != 0: + raise Exception('Error building junction db index') + +taga='%s_se'%target +tagb='%s_as'%target +for rs in [taga,tagb]: + cmd='%s aln -n %d -R 100 %s/%s %s/%s_unmap.fq > %s/%s_unmap.sai'%(bwa,mm,outdir,juncfile,outdir,rs,outdir,rs) + cmdout=subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,shell=True) + while True: + if cmdout.poll() is None: + time.sleep(5) + pass + if cmdout.poll()==0: + print 'Aligned unmapped reads group %s'%rs + break + if cmdout.poll() is not None and cmdout.poll() != 0: + raise Exception('Error aligning unmapped reads for group %s'%rs) + + cmd='%s samse -n 1000 %s/%s %s/%s_unmap.sai %s/%s_unmap.fq > %s/%s_unmap.sam'%(bwa,outdir,juncfile,outdir,rs,outdir,rs,outdir,rs) + cmdout=subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,shell=True) + while True: + if cmdout.poll() is None: + time.sleep(2) + pass + if cmdout.poll()==0: + print 'Converting to sam for group %s'%rs + break + if cmdout.poll() is not None and cmdout.poll() != 0: + raise Exception('Error converting to sam for group %s'%rs) + +qualrd_a=[] +junc_a=[] +samfile=pysam.Samfile('%s/%s_unmap.sam'%(outdir,taga),'r') +for rd in samfile: + if not rd.is_unmapped and rd.is_reverse: + qualrd_a.append(rd) + junc_a.append(samfile.getrname(rd.tid)) +samfile.close() +qualrd_b=[] +junc_b=[] +samfile=pysam.Samfile('%s/%s_unmap.sam'%(outdir,tagb),'r') +for rd in samfile: + if not rd.is_unmapped and not rd.is_reverse: + qualrd_b.append(rd) + junc_b.append(samfile.getrname(rd.tid)) +samfile.close() + +junc_span=[] +junc_span.extend(qualrd_a) +junc_span.extend(qualrd_b) + +junc_name=[] +junc_name.extend(junc_a) +junc_name.extend(junc_b) + +#Generate a summary report +sumfile=open('%s/%s.GUESS-IF.summary.txt'%(outdir,target),'w') +sumfile.write('%s\n'%(target)) +sumfile.write('\n') +sumfile.write('>spanning\n') +for i in range(len(junc_span)): + rd=junc_span[i] + jname=junc_name[i] + mm_j=[x[1] for x in rd.tags if x[0]=='NM'][0] + ss='%s\t%s.mm%d'%(rd.qname,jname,mm_j) + sumfile.write('%s\n'%ss) + +sumfile.write('\n') +sumfile.write('>junction\n') +juncol=[] +for item in set(junc_name): + nn=junc_name.count(item) + juncol.append([item,nn]) +juncol=sorted(juncol,key=lambda x:x[1],reverse=True) +for item in juncol: + sumfile.write('%s\t%s\n'%(item[0],item[1])) + +sumfile.write('\n') +sumfile.write('>summary\n') +sumfile.write('Number of Fusion Reads = %d\n'%len(junc_span)) +sumfile.write('Number of Distinct Junctions = %d\n'%len(set(junc_name))) + +sumfile.close() +print 'Done: %s'%time.ctime() +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/prada-homology Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,190 @@ +#!/usr/bin/env python + +#This script is part of the pyPRADA package. It is used to calculate sequence similarity of genes. +#In practice, it finds longest transcripts and uses blastn to compare the sequences. +#It is used to filter out fusion false positives like family genes etc. +#A temp folder is generated to save transcript fasta files. + +import os +import re +import sys +import time +import subprocess +import bioclass +from Bio import SeqIO +import ioprada + +###################################################################################### +help_menu='''\nUsage: prada-homology -conf xx.txt -i inputfile -o outputfile -tmpdir XXX +**parameters** + -conf see prada-fusion -conf for details + -i a tab/space delimited two-column file --- gene1 gene2 + -o output file + -tmpdir tmporary directory that saves fasta files +''' + +args=sys.argv + +if '-h' in args or '-help' in args or len(args)==1: + print help_menu + sys.exit(0) + +if '-i' not in sys.argv: + sys.exit('Input file needed') +else: + i=sys.argv.index('-i') + datafilename=sys.argv[i+1] +if '-o' not in sys.argv: + sys.exit('Output file needed') +else: + i=sys.argv.index('-o') + outfilename=sys.argv[i+1] +if '-tmpdir' not in sys.argv: + sys.exit('TMP dir needed') +else: + i=sys.argv.index('-tmpdir') + blastseq_tmp_dir=sys.argv[i+1] +if os.path.exists(blastseq_tmp_dir): + print 'Warning: tmpdir %s exists!'%blastseq_tmp_dir +else: + cmd='mkdir %s'%blastseq_tmp_dir + cmdout=subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,shell=True) + +prada_path=os.path.dirname(os.path.abspath(__file__)) #### +ref_search_path=[prada_path,os.getcwd()] #search path for ref file if not specified in command line + +if '-conf' in args: + i=args.index('-conf') + reffile=args[i+1] + if os.path.exists(reffile): + pass + else: + for pth in ref_search_path: + new_reffile='%s/%s'%(pth, os.path.basename(reffile)) + if os.path.exists(new_reffile): + reffile=new_reffile + break + else: + sys.exit('ERROR: conf file %s not found'%reffile) +else: + reffile='%s/conf.txt'%prada_path + if not os.path.exists(reffile): + sys.exit('ERROR: No default conf.txt found and none specified') + +#Now print all input parameters +print 'CMD: %s'%('\t'.join(args)) + +#reference files +refdict=ioprada.read_conf(reffile) +featurefile=refdict['--REF--']['feature_file'] +refdb=refdict['--REF--']['tx_seq_file'] + +blastn='%s/tools/blastn'%prada_path + +#################Here We Go############################################# +##Read information from raw file +print 'Collecting gene/Transcript info ...' +#call functions in ioprada module // +txdb,genedb=ioprada.read_feature(featurefile,verbose=False) + +################################################################## +##Get all candidate gene pairs +infile=open(datafilename) +candidates={} +for line in infile: + if line.strip(): + info=line.split() + geneA,geneB=info[0],info[1] + key='%s_%s'%(geneA,geneB) + candidates[key]='' +infile.close() +print '%d unique gene pairs collected'%len(candidates) + +##Select the transcript for each gene +selecttranscript={} +for gene in genedb: + txs=genedb[gene].transcript + stx=txs[0] + initlen=stx.length + for tx in txs: + if tx.length >= initlen: + stx=tx + initlen=stx.length + selecttranscript[gene]=stx.name +print 'Selected longest transcript for each gene.' + +##Get all needed sequences +allpartners=set() +for item in candidates: + sset=set(item.split('_')) + allpartners=allpartners.union(sset) + +#################################################################### +def seqblast(seqA,seqB): + '''seqA,seqB:fasta files''' + global blastn + cmdstr='%s -task=blastn -subject %s -query %s -outfmt 6'%(blastn,seqA,seqB) + cmdout=subprocess.Popen(cmdstr.split(),stdout=subprocess.PIPE,stderr=subprocess.STDOUT) + result=cmdout.stdout.read() + best_align=result.split('\n')[0] + if best_align=='': + return None + else: + info=best_align.split('\t') + identity=info[2].strip() + align_len=info[3].strip() + evalue=info[10].strip() + bit_score=info[11].strip() + return [identity,align_len,evalue,bit_score] + +presenttxs=[] #tx that is present in our annotation +absent=[] #tx that is not in our annotation +for gene in allpartners: + if selecttranscript.has_key(gene): + presenttxs.append(selecttranscript[gene]) + else: + absent.append(gene) + +for seq_record in SeqIO.parse(refdb,'fasta'): + sid=seq_record.id + seq=seq_record.seq + if sid in presenttxs: + g=txdb[sid].gene + fastafile=open('%s/%s.fasta'%(blastseq_tmp_dir,g),'w') + SeqIO.write(seq_record,fastafile,'fasta') + fastafile.close() + +for gp in candidates: + geneA,geneB=gp.split('_') + if geneA in absent or geneB in absent: + candidates[gp]=['NA']*6 + else: + gaseq='%s/%s.fasta'%(blastseq_tmp_dir,geneA) + gaobj=SeqIO.parse(gaseq,'fasta').next() + gbseq='%s/%s.fasta'%(blastseq_tmp_dir,geneB) + gbobj=SeqIO.parse(gbseq,'fasta').next() + ga_len,gb_len=str(len(gaobj.seq)),str(len(gbobj.seq)) + print 'Comparing %s %s'%(geneA,geneB) + a=seqblast(gaseq,gbseq) + if a==None: + candidates[gp]=[ga_len,gb_len,'NA','NA','100','0'] + else: + a[0:0]=[ga_len,gb_len] + candidates[gp]=a + + +infile=open(datafilename) +outfile=open(outfilename,'w') +header=['#Gene1','Gene2','Transcript1_Len','Transcript2_Len','Identity','Align_Len','Evalue','BitScore'] +outfile.write('%s\n'%('\t'.join(header))) +for line in infile: + if line.strip(): + info=line.split() + geneA,geneB=info[0],info[1] + key='%s_%s'%(geneA,geneB) + vv=candidates[key] + outfile.write('%s\t%s\t%s\n'%(geneA,geneB,'\t'.join(vv))) +outfile.close() +infile.close() + +print 'Homolgy test done!'
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/prada-preprocess-bi Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,325 @@ +#!/usr/bin/env python + +#This is a program to implement the PRADA pipeline "process subsection", based on the work of Rahul Vegesna and Wandaliz Torres-Garcia +#It merely generates a PBS file, depending on the user input entry point (step) +#Author: Siyuan Zheng, szheng2@mdanderson.org +#Copy right belongs to Roel Verhaak's lab from MD Anderson Cancer Center, Department of Bioinformatics and Computational Biology. +#Last revision: 02/17/2014 + +import subprocess +import os,os.path +import sys +import time +import ioprada +import re + +######################################################################################## +args=sys.argv + +help_menu='''\nPipeline for RNAseq Data Analaysis - preprocessing pipeline (PRADA). +\t**Usage**: +\tprada-preprocess-bi -conf xx.txt -inputdir .. -sample XX -tag TCGA-XX -platform illumina -step 1_1 -intermediate no -pbs xxx -outdir ... -submit no +\t**Parameters**: +\t-h print help message +\t-step_info print complete steps curated in the module. +\t-inputdir the dir where the input bam or fastq can be found. +\t-sample input sample name. PRADA searches for sample.bam or sample.end1.fastq/sample.end2.fastq, etc, depending on the +\t initiating step number. See step_info for more information. +\t-conf config file for references and parameters. Default is conf.txt in py-PRADA installation folder. +\t-tag a tag to describe the sample, likely sample ID, such as TCGA-LGG-01; no default. +\t-platform only illumina at present (default). +\t-step values: 1_1/2,2_e1/2_1/2/3/4,3_e1/2_1/2,4_1/2,5,6_1/2,7,8; example 2_e1_1; no default. +\t-outdir output dir. Default is the directory where the input bam is. +\t-pbs name for output pbs file and log file. Default (time-stamp) is used if no input. +\t-intermediate values:yes/no; if intermediate files should be kept. Default is not. +\t-submit if submit the job to HPC, default is no. If yes, ppn is set to 12. +\t-v print version information. +''' + +steps_info=''' +Command orders (sample XX) +step 1_1 --> XX.sorted.bam [sort input bam by name] +step 1_2 --> XX.end1/2.fastq [extract reads from bam] +step 2_e1_1 --> XX.end1.sai [realign end1 reads to composite reference] +step 2_e1_2 --> XX.end1.sam [generate sam] +step 2_e1_3 --> XX.end1.bam [generate bam] +step 2_e1_4 --> XX.end1.sorted.bam [sort bam] +step 2_e2_1 --> XX.end2.sai [realign end2 reads to composite reference] +step 2_e2_2 --> XX.end2.sam [generate sam] +step 2_e2_3 --> XX.end2.bam [generate bam] +step 2_e2_4 --> XX.end2.sorted.bam [sort bam] +step 3_e1_1 --> XX.end1.remapped.bam [remap end1 to genome] +step 3_e1_2 --> XX.end1.remapped.sorted.bam [sort remapped bam] +step 3_e2_1 --> XX.end2.remapped.bam [remap end2 to genome] +step 3_e2_2 --> XX.end2.remapped.sorted.bam [sort remapped bam] +step 4_1 --> XX.paired.bam [pair end1 and end1] +step 4_2 --> XX.paired.sorted.bam [sort paired bam] +step 5 --> XX.withRG.paired.sorted.bam [add read group] +step 6_1 --> XX.orig.csv [prepair recalibration table] +step 6_2 --> XX.withRG.GATKRecalibrated.bam [recalibration] +step 7 --> XX.withRG.GATKRecalibrated.flagged.bam [flag duplication reads] +step 8 --> folder XX for gene expression, QC metrics etc. [generate QC and expression] +''' + +if '-h' in args or '-help' in args or len(args)==1: + print help_menu + sys.exit(0) +if '-step_info' in args: + print steps_info + sys.exit(0) +if '-v' in args: + import version + print version.version + sys.exit(0) + +if '-sample' not in args: + sys.exit('ERROR: Sample name is needed') +if '-step' not in args: + sys.exit('ERROR: Step number is needed') +if '-tag' not in args: + sys.exit('ERROR: A tag is needed') + +i=args.index('-sample') +sample=args[i+1] +if '-inputdir' not in args: + inputpath=os.path.abspath('./') +else: + i=args.index('-inputdir') + inputpath=args[i+1] +bampath=os.path.abspath(inputpath)+'/%s.bam'%sample +fq1path=os.path.abspath(inputpath)+'/%s.end1.fastq'%sample +fq2path=os.path.abspath(inputpath)+'/%s.end2.fastq'%sample + +if '-outdir' not in args: + outpath=os.path.dirname(bampath) +else: + i=args.index('-outdir') + outpath=os.path.abspath(args[i+1]) +if not os.path.exists(outpath): + os.mkdir(outpath) + +#bam=os.path.basename(bampath) +#sample=bam[:-4] +i=args.index('-step') +step=args[i+1] +i=args.index('-tag') +tag=args[i+1] + +prada_path=os.path.dirname(os.path.abspath(__file__)) #### +ref_search_path=[prada_path,os.getcwd()] #search path for ref file if not specified in command line + +if '-conf' in args: + i=args.index('-conf') + reffile=args[i+1] + if os.path.exists(reffile): + pass + else: + for pth in ref_search_path: + new_reffile='%s/%s'%(pth, os.path.basename(reffile)) + if os.path.exists(new_reffile): + reffile=new_reffile + break + else: + sys.exit('ERROR: conf file %s not found'%reffile) +else: + reffile='%s/conf.txt'%prada_path + if not os.path.exists(reffile): + sys.exit('ERROR: No default conf.txt found and none specified') + +if '-platform' in args: + i=args.index('-platform') + plat=args[i+1] +else: + plat='illumina' +if '-submit' in args: + i=args.index('-submit') + submit=args[i+1] +else: + submit='no' +if '-intermediate' in args: + i=args.index('-intermediate') + keepmed=args[i+1] +else: + keepmed='False' + +if keepmed in ['False','FALSE','false','F','NO','No','no','n']: + keepmed_flag='no' +elif keepmed in ['True','TRUE','true','T','YES','Yes','yes','y']: + keepmed_flag='yes' +else: + sys.exit('ERROR: -intermediate value not recognized') + +if '-pbs' in args: + i=args.index('-pbs') + docstr=args[i+1] +else: + a=time.ctime().split() + b=time.time() + timestamp='_'.join([a[-1],a[1],a[2]])+'.'+str(b) + docstr='prada_prep_'+timestamp +logfilename=docstr+'.log' +pbsfilename=docstr+'.pbs' +pbspath=outpath+'/'+pbsfilename +logpath=outpath+'/'+logfilename +######################################################################################## + +######################################################################################## +#underlying utilities, automatically detected +samtools='%s/tools/samtools-0.1.16/samtools'%prada_path +bwa='%s/tools/bwa-0.5.7-mh/bwa'%prada_path +gatk='%s/tools/GATK/'%prada_path +picard='%s/tools/Picard/'%prada_path +seqc='%s/tools/RNA-SeQC_v1.1.7.jar'%prada_path +#Default uses 12 nodes in HPC +######################################################################################### + +######################################################################################### +#reference files +refdict=ioprada.read_conf(reffile) +genome_gtf=refdict['--REF--']['genome_gtf'] +compdb_fasta=refdict['--REF--']['compdb_fasta'] +compdb_map=refdict['--REF--']['compdb_map'] +genome_fasta=refdict['--REF--']['genome_fasta'] +dbsnp_vcf=refdict['--REF--']['dbsnp_vcf'] +select_tx=refdict['--REF--']['select_tx'] +pat=re.compile('ppn=(\d*)') +parallel_n=pat.search(refdict['--PBS--']['-l']).groups()[0] +######################################################################################### + +######################################################################################### +#pipeline command lines. +##Cleaning up steps: if -intermediate is yes, none will be executed. +step_1_1_cmd=['%s sort -n -m 1000000000 %s %s.sorted'%(samtools,bampath,sample)] +post_1_1_clean=[] +step_1_2_cmd=['java -Xmx8g -jar %s/SamToFastq.jar INPUT=%s.sorted.bam FASTQ=%s.end1.fastq SECOND_END_FASTQ=%s.end2.fastq INCLUDE_NON_PF_READS=true VALIDATION_STRINGENCY=SILENT TMP_DIR=tmp/'%(picard,sample,sample,sample)] +post_1_2_clean=['rm -f %s.sorted.bam'%sample] +alnparams=' '.join([' '.join(x) for x in refdict['--BWA aln--'].items()]) +samseparams=' '.join([' '.join(x) for x in refdict['--BWA samse--'].items()]) +if step == '2_e1_1' or step == '2_e2_1': + step_2_e1_1_cmd=['%s aln %s %s %s > %s.end1.sai'%(bwa,alnparams,compdb_fasta,fq1path,sample)] + post_2_e1_1_clean=[] + step_2_e1_2_cmd=['%s samse -s %s %s %s.end1.sai %s > %s.end1.sam'%(bwa,samseparams,compdb_fasta,sample,fq1path,sample)] + post_2_e1_2_clean=['rm -f %s.end1.sai'%sample] + step_2_e2_1_cmd=['%s aln %s %s %s > %s.end2.sai'%(bwa,alnparams,compdb_fasta,fq2path,sample)] + post_2_e2_1_clean=[] + step_2_e2_2_cmd=['%s samse -s %s %s %s.end2.sai %s > %s.end2.sam'%(bwa,samseparams,compdb_fasta,sample,fq2path,sample)] + post_2_e2_2_clean=['rm -f %s.end2.sai'%sample] +else: + step_2_e1_1_cmd=['%s aln %s %s %s.end1.fastq > %s.end1.sai'%(bwa,alnparams,compdb_fasta,sample,sample)] + post_2_e1_1_clean=[] + step_2_e1_2_cmd=['%s samse -s %s %s %s.end1.sai %s.end1.fastq > %s.end1.sam'%(bwa,samseparams,compdb_fasta,sample,sample,sample)] + post_2_e1_2_clean=['rm -f %s.end1.sai'%sample,'rm -f %s.end1.fastq'%sample] + step_2_e2_1_cmd=['%s aln %s %s %s.end2.fastq > %s.end2.sai'%(bwa,alnparams,compdb_fasta,sample,sample)] + post_2_e2_1_clean=[] + step_2_e2_2_cmd=['%s samse -s %s %s %s.end2.sai %s.end2.fastq > %s.end2.sam'%(bwa,samseparams,compdb_fasta,sample,sample,sample)] + post_2_e2_2_clean=['rm -f %s.end2.sai'%sample,'rm -f %s.end2.fastq'%sample] +step_2_e1_3_cmd=['%s view -bS -o %s.end1.bam %s.end1.sam'%(samtools,sample,sample)] +post_2_e1_3_clean=['rm -f %s.end1.sam'%sample] +step_2_e1_4_cmd=['%s sort -n -m 1000000000 %s.end1.bam %s.end1.sorted'%(samtools,sample,sample)] +post_2_e1_4_clean=['rm -f %s.end1.bam'%sample] +step_2_e2_3_cmd=['%s view -bS -o %s.end2.bam %s.end2.sam'%(samtools,sample,sample)] +post_2_e2_3_clean=['rm -f %s.end2.sam'%sample] +step_2_e2_4_cmd=['%s sort -n -m 1000000000 %s.end2.bam %s.end2.sorted'%(samtools,sample,sample)] +post_2_e2_4_clean=['rm -f %s.end2.bam'%sample] +step_3_e1_1_cmd=['java -Djava.io.tmpdir=tmp/ -cp %s/RemapAlignments.jar -Xmx8g org.broadinstitute.cga.tools.gatk.rna.RemapAlignments M=%s IN=%s.end1.sorted.bam OUT=%s.end1.remapped.bam R=%s REDUCE=TRUE'%(gatk,compdb_map,sample,sample,genome_fasta)] +post_3_e1_1_clean=['rm -f %s.end1.sorted.bam'%sample] +step_3_e1_2_cmd=['%s sort -n -m 1000000000 %s.end1.remapped.bam %s.end1.remapped.sorted'%(samtools,sample,sample)] +post_3_e1_2_clean=['rm -f %s.end1.remapped.bam'%sample] +step_3_e2_1_cmd=['java -Djava.io.tmpdir=tmp/ -cp %s/RemapAlignments.jar -Xmx8g org.broadinstitute.cga.tools.gatk.rna.RemapAlignments M=%s IN=%s.end2.sorted.bam OUT=%s.end2.remapped.bam R=%s REDUCE=TRUE'%(gatk,compdb_map,sample,sample,genome_fasta)] +post_3_e2_1_clean=['rm -f %s.end2.sorted.bam'%sample] +step_3_e2_2_cmd=['%s sort -n -m 1000000000 %s.end2.remapped.bam %s.end2.remapped.sorted'%(samtools,sample,sample)] +post_3_e2_2_clean=['rm -f %s.end2.remapped.bam'%sample] +step_4_1_cmd=['java -Djava.io.tmpdir=tmp/ -Xmx8g -jar %s/PairMaker.jar IN1=%s.end1.remapped.sorted.bam IN2=%s.end2.remapped.sorted.bam OUTPUT=%s.paired.bam TMP_DIR=tmp/'%(gatk,sample,sample,sample)] +post_4_1_clean=['rm -f %s.end1.remapped.sorted.bam'%sample,'rm -f %s.end2.remapped.sorted.bam'%sample] +step_4_2_cmd=['%s sort -m 1000000000 %s.paired.bam %s.paired.sorted'%(samtools,sample,sample)] +post_4_2_clean=['rm -f %s.paired.bam'%sample] +step_5_cmd=['java -Xmx8g -jar %s/AddOrReplaceReadGroups.jar I=%s.paired.sorted.bam O=%s.withRG.paired.sorted.bam RGLB=%s RGPL=%s RGPU=%s RGSM=%s'%(picard,sample,sample,tag,plat,tag,tag)] +post_5_clean=['rm -f %s.paired.sorted.bam'%sample] +step_6_1_cmd=['%s index %s.withRG.paired.sorted.bam'%(samtools,sample),'java -Xmx8g -jar %s/GenomeAnalysisTK.jar -l INFO -R %s --default_platform %s --knownSites %s -I %s.withRG.paired.sorted.bam --downsample_to_coverage 10000 -T CountCovariates -cov ReadGroupCovariate -cov QualityScoreCovariate -cov CycleCovariate -cov DinucCovariate -nt %s -recalFile %s.orig.csv'%(gatk,genome_fasta,plat,dbsnp_vcf,sample,parallel_n,sample)] +post_6_1_clean=[] +step_6_2_cmd=['java -Xmx8g -jar %s/GenomeAnalysisTK.jar -l INFO -R %s --default_platform %s -I %s.withRG.paired.sorted.bam -T TableRecalibration --out %s.withRG.GATKRecalibrated.bam -recalFile %s.orig.csv'%(gatk,genome_fasta,plat,sample,sample,sample)] +post_6_2_clean=['rm -f %s.withRG.paired.sorted.bam'%sample,'rm -f %s.withRG.paired.sorted.bam.bai'%sample,'rm -f %s.orig.csv'%sample] +step_7_cmd=['java -Xmx8g -jar %s/MarkDuplicates.jar I=%s.withRG.GATKRecalibrated.bam O=%s.withRG.GATKRecalibrated.flagged.bam METRICS_FILE=%s.Duplicates_metrics.txt VALIDATION_STRINGENCY=SILENT TMP_DIR=tmp/'%(picard,sample,sample,sample),'%s index %s.withRG.GATKRecalibrated.flagged.bam'%(samtools,sample)] +post_7_clean=['rm -f %s.withRG.GATKRecalibrated.bam'%sample,'rm -f %s.withRG.GATKRecalibrated.bai'%sample,'rm -f %s.Duplicates_metrics.txt'%sample] +step_8_cmd=["java -Xmx8g -jar %s -ttype 2 -t %s -r %s -s '%s|%s.withRG.GATKRecalibrated.flagged.bam|Disc' -o %s/"%(seqc,genome_gtf,genome_fasta,sample,sample,sample)] +post_8_clean=[] + +cmdset=[] +for item in globals().keys(): + if item.endswith('_cmd'): + cmdset.append(item) +cmdset.sort() + +######################################################################################### +#write PBS file + +###############Entry Point +try: + cmd_entry=cmdset.index('step_'+step+'_cmd') ##entry point +except ValueError: + sys.exit('ERROR: STEP not recognized') + +def _parsecmd(cmd): + '''pase cmd str for step information''' + info=cmd.split('_') + cstep='_'.join(info[1:-1]) + return cstep + +########################### +##headers +outfile=open(pbspath,'w') +outfile.write('#! /bin/sh\n') +outfile.write('#PBS -V\n') +outfile.write('#PBS -N %s\n'%tag) +outfile.write('#PBS -j oe\n') +outfile.write('#PBS -o %s\n'%logpath) +for item in refdict['--PBS--']: + outfile.write('#PBS %s %s\n'%(item,refdict['--PBS--'][item])) +outfile.write('#PBS -d %s\n'%outpath) + +#commands +outfile.write('echo "Job start: `date`"\n') + +for i in range(cmd_entry,len(cmdset)): + cmd=cmdset[i] + cstep=_parsecmd(cmd) + clean_flag=1 + outfile.write('echo "step %s start: `date`"\n'%cstep) + outfile.write('if\n') + outfile.write('\t%s\n'%('\n'.join(eval(cmd)))) + outfile.write('then\n') + outfile.write('\techo "step %s done: `date`"\n'%cstep) + outfile.write('else\n') + outfile.write('\techo "step %s ERROR"\n'%cstep) + outfile.write('\texit\n') + outfile.write('fi\n') + + if keepmed_flag=='yes': #if so, keep files by force + clean_flag=0 + + if clean_flag==1: + outfile.write('\n'.join(eval('post_%s_clean'%cstep))) + outfile.write('\n') + +outfile.write('echo "PIPELINE FINISHED"\n') +outfile.close() +###################################################################### + +if submit in ['False','FALSE','false','F','NO','No','no','n']: + jid='Not_Submitted' + logpath='None' +elif submit in ['True','TRUE','true','T','YES','Yes','yes','y']: + cmdstr='qsub %s'%pbspath + cmd=cmdstr.split() + cmdout=subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.STDOUT) + jid=cmdout.stdout.read().strip() ##JOB ID +else: + sys.exit('ERROR: submit parameter not recognized') + +print '#!#%s'%tag +print 'BAM\t%s'%bampath +print 'Entry\t%s'%step +print 'PBS\t%s'%pbspath +print 'JOB\t%s'%jid +print 'LOG\t%s'%logpath +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/prada-preprocess-unc Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,324 @@ +#!/usr/bin/env python + +#This is a program to implement the PRADA pipeline "process subsection", based on the work of Rahul Vegesna and Wandaliz Torres-Garcia +#It merely generates a PBS file, depending on the user input entry point (step) +#Author: Siyuan Zheng, szheng2@mdanderson.org +#Copy right belongs to Roel Verhaak's lab from MD Anderson Cancer Center, Department of Bioinformatics and Computational Biology. +#Last revision: 02/17/2014 + +import subprocess +import os,os.path +import sys +import time +import ioprada +import re + +######################################################################################## +args=sys.argv + +help_menu='''\nPipeline for RNAseq Data Analaysis - preprocessing pipeline (PRADA). +\t**Usage**: +\tprada-preprocess-bi -conf xx.txt -inputdir .. -sample XX -tag TCGA-XX -platform illumina -step 1_1 -intermediate no -pbs xxx -outdir ... -submit no +\t**Parameters**: +\t-h print help message +\t-step_info print complete steps curated in the module. +\t-inputdir the dir where the input bam or fastq can be found. +\t-sample input sample name. PRADA searches for sample.bam or sample.end1.fastq/sample.end2.fastq, etc, depending on the +\t initiating step number. See step_info for more information. +\t-conf config file for references and parameters. Default is conf.txt in py-PRADA installation folder. +\t-tag a tag to describe the sample, likely sample ID, such as TCGA-LGG-01; no default. +\t-platform only illumina at present (default). +\t-step values: 1_1/2,2_e1/2_1/2/3/4,3_e1/2_1/2,4_1/2,5,6_1/2,7,8; example 2_e1_1; no default. +\t-outdir output dir. Default is the directory where the input bam is. +\t-pbs name for output pbs file and log file. Default (time-stamp) is used if no input. +\t-intermediate values:yes/no; if intermediate files should be kept. Default is not. +\t-submit if submit the job to HPC, default is no. If yes, ppn is set to 12. +\t-v print version information. +''' + +steps_info=''' +Command orders (sample XX) +step 1_1 --> XX.sorted.bam [sort input bam by name] +step 1_2 --> XX.end1/2.fastq [extract reads from bam] +step 2_e1_1 --> XX.end1.sai [realign end1 reads to composite reference] +step 2_e1_2 --> XX.end1.sam [generate sam] +step 2_e1_3 --> XX.end1.bam [generate bam] +step 2_e1_4 --> XX.end1.sorted.bam [sort bam] +step 2_e2_1 --> XX.end2.sai [realign end2 reads to composite reference] +step 2_e2_2 --> XX.end2.sam [generate sam] +step 2_e2_3 --> XX.end2.bam [generate bam] +step 2_e2_4 --> XX.end2.sorted.bam [sort bam] +step 3_e1_1 --> XX.end1.remapped.bam [remap end1 to genome] +step 3_e1_2 --> XX.end1.remapped.sorted.bam [sort remapped bam] +step 3_e2_1 --> XX.end2.remapped.bam [remap end2 to genome] +step 3_e2_2 --> XX.end2.remapped.sorted.bam [sort remapped bam] +step 4_1 --> XX.paired.bam [pair end1 and end1] +step 4_2 --> XX.paired.sorted.bam [sort paired bam] +step 5 --> XX.withRG.paired.sorted.bam [add read group] +step 6_1 --> XX.orig.csv [prepair recalibration table] +step 6_2 --> XX.withRG.GATKRecalibrated.bam [recalibration] +step 7 --> XX.withRG.GATKRecalibrated.flagged.bam [flag duplication reads] +step 8 --> folder XX for gene expression, QC metrics etc. [generate QC and expression] +''' + +if '-h' in args or '-help' in args or len(args)==1: + print help_menu + sys.exit(0) +if '-step_info' in args: + print steps_info + sys.exit(0) +if '-v' in args: + import version + print version.version + sys.exit(0) + +if '-sample' not in args: + sys.exit('ERROR: Sample name is needed') +if '-step' not in args: + sys.exit('ERROR: Step number is needed') +if '-tag' not in args: + sys.exit('ERROR: A tag is needed') + +i=args.index('-sample') +sample=args[i+1] +if '-inputdir' not in args: + inputpath=os.path.abspath('./') +else: + i=args.index('-inputdir') + inputpath=args[i+1] +bampath=os.path.abspath(inputpath)+'/%s.bam'%sample + +if '-outdir' not in args: + outpath=os.path.dirname(bampath) +else: + i=args.index('-outdir') + outpath=os.path.abspath(args[i+1]) +if not os.path.exists(outpath): + os.mkdir(outpath) + +#bam=os.path.basename(bampath) +#sample=bam[:-4] +i=args.index('-step') +step=args[i+1] +i=args.index('-tag') +tag=args[i+1] + +prada_path=os.path.dirname(os.path.abspath(__file__)) #### +ref_search_path=[prada_path,os.getcwd()] #search path for ref file if not specified in command line + +if '-conf' in args: + i=args.index('-conf') + reffile=args[i+1] + if os.path.exists(reffile): + pass + else: + for pth in ref_search_path: + new_reffile='%s/%s'%(pth, os.path.basename(reffile)) + if os.path.exists(new_reffile): + reffile=new_reffile + break + else: + sys.exit('ERROR: conf file %s not found'%reffile) +else: + reffile='%s/conf.txt'%prada_path + if not os.path.exists(reffile): + sys.exit('ERROR: No default conf.txt found and none specified') + +if '-platform' in args: + i=args.index('-platform') + plat=args[i+1] +else: + plat='illumina' +if '-submit' in args: + i=args.index('-submit') + submit=args[i+1] +else: + submit='no' +if '-intermediate' in args: + i=args.index('-intermediate') + keepmed=args[i+1] +else: + keepmed='False' + +if keepmed in ['False','FALSE','false','F','NO','No','no','n']: + keepmed_flag='no' +elif keepmed in ['True','TRUE','true','T','YES','Yes','yes','y']: + keepmed_flag='yes' +else: + sys.exit('ERROR: -intermediate value not recognized') + +if '-pbs' in args: + i=args.index('-pbs') + docstr=args[i+1] +else: + a=time.ctime().split() + b=time.time() + timestamp='_'.join([a[-1],a[1],a[2]])+'.'+str(b) + docstr='prada_prep_'+timestamp +logfilename=docstr+'.log' +pbsfilename=docstr+'.pbs' +pbspath=outpath+'/'+pbsfilename +logpath=outpath+'/'+logfilename +######################################################################################## + +######################################################################################## +#underlying utilities, automatically detected +samtools='%s/tools/samtools-0.1.16/samtools'%prada_path +bwa='%s/tools/bwa-0.5.7-mh/bwa'%prada_path +gatk='%s/tools/GATK/'%prada_path +picard='%s/tools/Picard/'%prada_path +seqc='%s/tools/RNA-SeQC_v1.1.7.jar'%prada_path +sam2fastq='%s/tools/ubu-1.2-jar-with-dependencies.jar'%prada_path +#Default uses 12 nodes in HPC +######################################################################################### + +######################################################################################### +#reference files +refdict=ioprada.read_conf(reffile) +genome_gtf=refdict['--REF--']['genome_gtf'] +compdb_fasta=refdict['--REF--']['compdb_fasta'] +compdb_map=refdict['--REF--']['compdb_map'] +genome_fasta=refdict['--REF--']['genome_fasta'] +dbsnp_vcf=refdict['--REF--']['dbsnp_vcf'] +select_tx=refdict['--REF--']['select_tx'] +pat=re.compile('ppn=(\d*)') +parallel_n=pat.search(refdict['--PBS--']['-l']).groups()[0] +######################################################################################### + +######################################################################################### +#pipeline command lines. +##Cleaning up steps: if -intermediate is yes, none will be executed. +step_1_1_cmd=['%s sort -n -m 1000000000 %s %s.sorted'%(samtools,bampath,sample)] +post_1_1_clean=[] +step_1_2_cmd=['java -Xmx8g -jar %s INPUT=%s.sorted.bam FASTQ=%s.end1.fastq SECOND_END_FASTQ=%s.end2.fastq INCLUDE_NON_PF_READS=true VALIDATION_STRINGENCY=SILENT TMP_DIR=tmp/'%(sam2fastq,sample,sample,sample)] +post_1_2_clean=['rm -f %s.sorted.bam'%sample] +alnparams=' '.join([' '.join(x) for x in refdict['--BWA aln--'].items()]) +samseparams=' '.join([' '.join(x) for x in refdict['--BWA samse--'].items()]) +if step == '2_e1_1' or step == '2_e2_1': + step_2_e1_1_cmd=['%s aln %s %s %s > %s.end1.sai'%(bwa,alnparams,compdb_fasta,fq1path,sample)] + post_2_e1_1_clean=[] + step_2_e1_2_cmd=['%s samse -s %s %s %s.end1.sai %s > %s.end1.sam'%(bwa,samseparams,compdb_fasta,sample,fq1path,sample)] + post_2_e1_2_clean=['rm -f %s.end1.sai'%sample] + step_2_e2_1_cmd=['%s aln %s %s %s > %s.end2.sai'%(bwa,alnparams,compdb_fasta,fq2path,sample)] + post_2_e2_1_clean=[] + step_2_e2_2_cmd=['%s samse -s %s %s %s.end2.sai %s > %s.end2.sam'%(bwa,samseparams,compdb_fasta,sample,fq2path,sample)] + post_2_e2_2_clean=['rm -f %s.end2.sai'%sample] +else: + step_2_e1_1_cmd=['%s aln %s %s %s.end1.fastq > %s.end1.sai'%(bwa,alnparams,compdb_fasta,sample,sample)] + post_2_e1_1_clean=[] + step_2_e1_2_cmd=['%s samse -s %s %s %s.end1.sai %s.end1.fastq > %s.end1.sam'%(bwa,samseparams,compdb_fasta,sample,sample,sample)] + post_2_e1_2_clean=['rm -f %s.end1.sai'%sample,'rm -f %s.end1.fastq'%sample] + step_2_e2_1_cmd=['%s aln %s %s %s.end2.fastq > %s.end2.sai'%(bwa,alnparams,compdb_fasta,sample,sample)] + post_2_e2_1_clean=[] + step_2_e2_2_cmd=['%s samse -s %s %s %s.end2.sai %s.end2.fastq > %s.end2.sam'%(bwa,samseparams,compdb_fasta,sample,sample,sample)] + post_2_e2_2_clean=['rm -f %s.end2.sai'%sample,'rm -f %s.end2.fastq'%sample] +step_2_e1_3_cmd=['%s view -bS -o %s.end1.bam %s.end1.sam'%(samtools,sample,sample)] +post_2_e1_3_clean=['rm -f %s.end1.sam'%sample] +step_2_e1_4_cmd=['%s sort -n -m 1000000000 %s.end1.bam %s.end1.sorted'%(samtools,sample,sample)] +post_2_e1_4_clean=['rm -f %s.end1.bam'%sample] +step_2_e2_3_cmd=['%s view -bS -o %s.end2.bam %s.end2.sam'%(samtools,sample,sample)] +post_2_e2_3_clean=['rm -f %s.end2.sam'%sample] +step_2_e2_4_cmd=['%s sort -n -m 1000000000 %s.end2.bam %s.end2.sorted'%(samtools,sample,sample)] +post_2_e2_4_clean=['rm -f %s.end2.bam'%sample] +step_3_e1_1_cmd=['java -Djava.io.tmpdir=tmp/ -cp %s/RemapAlignments.jar -Xmx8g org.broadinstitute.cga.tools.gatk.rna.RemapAlignments M=%s IN=%s.end1.sorted.bam OUT=%s.end1.remapped.bam R=%s REDUCE=TRUE'%(gatk,compdb_map,sample,sample,genome_fasta)] +post_3_e1_1_clean=['rm -f %s.end1.sorted.bam'%sample] +step_3_e1_2_cmd=['%s sort -n -m 1000000000 %s.end1.remapped.bam %s.end1.remapped.sorted'%(samtools,sample,sample)] +post_3_e1_2_clean=['rm -f %s.end1.remapped.bam'%sample] +step_3_e2_1_cmd=['java -Djava.io.tmpdir=tmp/ -cp %s/RemapAlignments.jar -Xmx8g org.broadinstitute.cga.tools.gatk.rna.RemapAlignments M=%s IN=%s.end2.sorted.bam OUT=%s.end2.remapped.bam R=%s REDUCE=TRUE'%(gatk,compdb_map,sample,sample,genome_fasta)] +post_3_e2_1_clean=['rm -f %s.end2.sorted.bam'%sample] +step_3_e2_2_cmd=['%s sort -n -m 1000000000 %s.end2.remapped.bam %s.end2.remapped.sorted'%(samtools,sample,sample)] +post_3_e2_2_clean=['rm -f %s.end2.remapped.bam'%sample] +step_4_1_cmd=['java -Djava.io.tmpdir=tmp/ -Xmx8g -jar %s/PairMaker.jar IN1=%s.end1.remapped.sorted.bam IN2=%s.end2.remapped.sorted.bam OUTPUT=%s.paired.bam TMP_DIR=tmp/'%(gatk,sample,sample,sample)] +post_4_1_clean=['rm -f %s.end1.remapped.sorted.bam'%sample,'rm -f %s.end2.remapped.sorted.bam'%sample] +step_4_2_cmd=['%s sort -m 1000000000 %s.paired.bam %s.paired.sorted'%(samtools,sample,sample)] +post_4_2_clean=['rm -f %s.paired.bam'%sample] +step_5_cmd=['java -Xmx8g -jar %s/AddOrReplaceReadGroups.jar I=%s.paired.sorted.bam O=%s.withRG.paired.sorted.bam RGLB=%s RGPL=%s RGPU=%s RGSM=%s'%(picard,sample,sample,tag,plat,tag,tag)] +post_5_clean=['rm -f %s.paired.sorted.bam'%sample] +step_6_1_cmd=['%s index %s.withRG.paired.sorted.bam'%(samtools,sample),'java -Xmx8g -jar %s/GenomeAnalysisTK.jar -l INFO -R %s --default_platform %s --knownSites %s -I %s.withRG.paired.sorted.bam --downsample_to_coverage 10000 -T CountCovariates -cov ReadGroupCovariate -cov QualityScoreCovariate -cov CycleCovariate -cov DinucCovariate -nt %s -recalFile %s.orig.csv'%(gatk,genome_fasta,plat,dbsnp_vcf,sample,parallel_n,sample)] +post_6_1_clean=[] +step_6_2_cmd=['java -Xmx8g -jar %s/GenomeAnalysisTK.jar -l INFO -R %s --default_platform %s -I %s.withRG.paired.sorted.bam -T TableRecalibration --out %s.withRG.GATKRecalibrated.bam -recalFile %s.orig.csv'%(gatk,genome_fasta,plat,sample,sample,sample)] +post_6_2_clean=['rm -f %s.withRG.paired.sorted.bam'%sample,'rm -f %s.withRG.paired.sorted.bam.bai'%sample,'rm -f %s.orig.csv'%sample] +step_7_cmd=['java -Xmx8g -jar %s/MarkDuplicates.jar I=%s.withRG.GATKRecalibrated.bam O=%s.withRG.GATKRecalibrated.flagged.bam METRICS_FILE=%s.Duplicates_metrics.txt VALIDATION_STRINGENCY=SILENT TMP_DIR=tmp/'%(picard,sample,sample,sample),'%s index %s.withRG.GATKRecalibrated.flagged.bam'%(samtools,sample)] +post_7_clean=['rm -f %s.withRG.GATKRecalibrated.bam'%sample,'rm -f %s.withRG.GATKRecalibrated.bai'%sample,'rm -f %s.Duplicates_metrics.txt'%sample] +step_8_cmd=["java -Xmx8g -jar %s -ttype 2 -t %s -r %s -s '%s|%s.withRG.GATKRecalibrated.flagged.bam|Disc' -o %s/"%(seqc,genome_gtf,genome_fasta,sample,sample,sample)] +post_8_clean=[] + +cmdset=[] +for item in globals().keys(): + if item.endswith('_cmd'): + cmdset.append(item) +cmdset.sort() + +######################################################################################### +#write PBS file + +###############Entry Point +try: + cmd_entry=cmdset.index('step_'+step+'_cmd') ##entry point +except ValueError: + sys.exit('ERROR: STEP not recognized') + +def _parsecmd(cmd): + '''pase cmd str for step information''' + info=cmd.split('_') + cstep='_'.join(info[1:-1]) + return cstep + +########################### +##headers +outfile=open(pbspath,'w') +outfile.write('#! /bin/sh\n') +outfile.write('#PBS -V\n') +outfile.write('#PBS -N %s\n'%tag) +outfile.write('#PBS -j oe\n') +outfile.write('#PBS -o %s\n'%logpath) +for item in refdict['--PBS--']: + outfile.write('#PBS %s %s\n'%(item,refdict['--PBS--'][item])) +outfile.write('#PBS -d %s\n'%outpath) + +#commands +outfile.write('echo "Job start: `date`"\n') + +for i in range(cmd_entry,len(cmdset)): + cmd=cmdset[i] + cstep=_parsecmd(cmd) + clean_flag=1 + outfile.write('echo "step %s start: `date`"\n'%cstep) + outfile.write('if\n') + outfile.write('\t%s\n'%('\n'.join(eval(cmd)))) + outfile.write('then\n') + outfile.write('\techo "step %s done: `date`"\n'%cstep) + outfile.write('else\n') + outfile.write('\techo "step %s ERROR"\n'%cstep) + outfile.write('\texit\n') + outfile.write('fi\n') + + if keepmed_flag=='yes': #if so, keep files by force + clean_flag=0 + + if clean_flag==1: + outfile.write('\n'.join(eval('post_%s_clean'%cstep))) + outfile.write('\n') + +outfile.write('echo "PIPELINE FINISHED"\n') +outfile.close() +###################################################################### + +if submit in ['False','FALSE','false','F','NO','No','no','n']: + jid='Not_Submitted' + logpath='None' +elif submit in ['True','TRUE','true','T','YES','Yes','yes','y']: + cmdstr='qsub %s'%pbspath + cmd=cmdstr.split() + cmdout=subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.STDOUT) + jid=cmdout.stdout.read().strip() ##JOB ID +else: + sys.exit('ERROR: submit parameter not recognized') + +print '#!#%s'%tag +print 'BAM\t%s'%bampath +print 'Entry\t%s'%step +print 'PBS\t%s'%pbspath +print 'JOB\t%s'%jid +print 'LOG\t%s'%logpath +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/privutils.py Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,165 @@ +#This module collects functions used in homology comparison and frame prediction + +import subprocess + +def maptranscript(gene,exon_end,part=''): + """ + Find all transcripts of the gene having the fusion boundary. + "gene" is a Gene object. + "exon_end" is the exon boundary that to be searched. + "part" has to be '5' or '3'. + Return a list of Transcript objects that has "exon_end" boundary. + """ + if part not in ['5','3']: + raise Exception('part must be "5" or "3"') + txuse=[] ## + g=gene.name + strand=gene.strand + if part=='5': + tag='big' if strand=='1' else 'small' + else: + tag='small' if strand=='1' else 'big' + txs=gene.transcript + if tag=='small': + for tx in txs: + e_pos=[x.start for x in tx.exon] + if exon_end in e_pos: + txuse.append(tx) + elif tag=='big': + for tx in txs: + e_pos=[x.end for x in tx.exon] + if exon_end in e_pos: + txuse.append(tx) + return txuse + + +def overlap(r1,r2): + """compare two ranges, return the overlapped range""" + if r1[0] <= r2[0]: + ra,rb=r1[:],r2[:] + else: + ra,rb=r2[:],r1[:] + if rb[0] > ra[1]: + return [] + else: + if rb[1] <= ra[1]: + return rb + else: + return [rb[0],ra[1]] + +def br_front_len(tx,br,part): + '''No matter it is 5'/3' partner,calculate the ORF length before the break''' + txname=tx.name + strand=tx.strand + cds_start=tx.cds_start + cds_end=tx.cds_end + e_pos=[[x.start,x.end] for x in tx.exon] + if part=='5' and strand=='1': + posset=[x.end for x in tx.exon] + if br not in posset: + raise Exception('Br is not exon boundary') + if br < cds_start: + return '5UTR' + elif br > cds_end: + return '3UTR' + else: + chim_r=[cds_start,br] + ol=[overlap(x,chim_r) for x in e_pos] + L=sum([x[1]-x[0]+1 for x in ol if len(x)>0]) + return L + if part=='5' and strand=='-1': + posset=[x.start for x in tx.exon] + if br not in posset: + raise Exception('Br is not exon boundary') + if br > cds_end: + return '5UTR' + elif br < cds_start: + return '3UTR' + else: + chim_r=[br,cds_end] + ol=[overlap(x,chim_r) for x in e_pos] + L=sum([x[1]-x[0]+1 for x in ol if len(x)>0]) + return L + if part=='3' and strand=='1': + posset=[x.start for x in tx.exon] + if br not in posset: + raise Exception('Br is not exon boundary') + if br < cds_start: + return '5UTR' + elif br > cds_end: + return '3UTR' + else: + chim_r=[cds_start,br-1] + ol=[overlap(x,chim_r) for x in e_pos] + L=sum([x[1]-x[0]+1 for x in ol if len(x)>0]) + return L + if part=='3' and strand=='-1': + posset=[x.end for x in tx.exon] + if br not in posset: + raise Exception('Br is not exon boundary') + if br > cds_end: + return '5UTR' + elif br < cds_start: + return '3UTR' + else: + chim_r=[br+1,cds_end] + ol=[overlap(x,chim_r) for x in e_pos] + L=sum([x[1]-x[0]+1 for x in ol if len(x)>0]) + return L + +def fusion_frame(gene_a,ga_br,gene_b,gb_br): + """gene_a:FGFR3,gene_b:TACC3,ga_br:1808661,gb_br:1741429 + or chr4.1808661.chr4.1741429 + gene_a, gene_b are Gene objects. + """ + ga_br=int(ga_br) + gb_br=int(gb_br) + ga_txs=maptranscript(gene_a,ga_br,part='5') + gb_txs=maptranscript(gene_b,gb_br,part='3') + res=[] + for ta in ga_txs: + for tb in gb_txs: + s1=br_front_len(ta,ga_br,'5') + s2=br_front_len(tb,gb_br,'3') + fusion_conseq='Unknown' + if isinstance(s1,int) and isinstance(s2,int): #both br in CDS region + if s1%3==s2%3: + fusion_conseq='In-frame' + else: + fusion_conseq='Out-of-frame' + elif isinstance(s1,int) and not isinstance(s2,int): + fusion_conseq='CDS'+'-'+s2 + elif isinstance(s2,int) and not isinstance(s1,int): + fusion_conseq=s1+'-'+'CDS' + else: + fusion_conseq=s1+'-'+s2 + res.append((ta.name,tb.name,fusion_conseq)) + if ga_txs==[] and gb_txs==[]: + res.append(['NA','NA','NA']) + elif ga_txs==[]: + for tb in gb_txs: + res.append(['NA',tb.name,'NA']) + elif gb_txs==[]: + for ta in ga_txs: + res.append([ta.name,'NA','NA']) + return res + + +def seqblast(seqA,seqB,blastn=None): + '''seqA,seqB:fasta files''' + if blastn==None: blastn='blastn' + cmdstr='%s -task=blastn -subject %s -query %s -outfmt 6'%(blastn,seqA,seqB) + cmdout=subprocess.Popen(cmdstr.split(),stdout=subprocess.PIPE,stderr=subprocess.STDOUT) + result=cmdout.stdout.read() + best_align=result.split('\n')[0] + if best_align=='': + return None + else: + info=best_align.split('\t') + identity=info[2].strip() + align_len=info[3].strip() + evalue=info[10].strip() + bit_score=info[11].strip() + return [identity,align_len,evalue,bit_score] + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/release_note Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,28 @@ +PRADA: Pipeline for RnAseq Data Analysis + +AUTHOR: Siyuan Zheng, Wandaliz-Torres Garcia, Rahul Vegesna +CONTACT: Siyuan Zheng (szheng2@mdanderson.org), Roel Verhaak (rverhaak@mdanderson.org) +COPY RIGHT: Verhaak Lab,Department of Bioinformatics and Computational Biology + The University of Texas MD Anderson Cancer Center +VERSION: 1.2 +DATE: 02/16/2014 +REQUIRE: Python v2.6 or v2.7; +Python Libs: pysam, Biopython +PLATFORM: Linux, tested with PBS, B-shell and TC-shell + +CITATION +PRADA: Pipeline for RNA sequencing Data Analysis +Bioinformatics. Coming soon. + +TOOLS INCLUDED: +prada-fusion genome-widely identify gene fusions +prada-preprocess preprocess paired end RNAseq data +prada-frame predict functional consequences of gene fusions +prada-homology calculate gene sequence similarity +prada-guess-ft supervised search of a gene fusion +prada-guess-if supervised search of intragenic fusions (normal splicing excluded) + +WHAT'S NEW +1. New configur allows more user customization to bwa alignment and PBS script. +2. Reorganized preprocess module for better control of BAM an FASTQ as input. +3. A test data set is added.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/testdata/frame_test.txt Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,7 @@ +FGFR3 1808661 TACC3 1739325 +FGFR3 1808661 TACC3 1741429 +EGFR 55268106 SEPT14 55863785 +PGD 10459761 CAMTA1 7309551 +YEATS4 69756687 EP400 132527849 +FAKE 69756687 EP400 132527849 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/testdata/homology_test.txt Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,5 @@ +CAND1 CPM +HLA-C HLA-B +ALDOA ALDOC +BAI2 HS3ST4 +FAKEG HLA-E
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/testdata/readme.txt Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,24 @@ +TEST EXAMPLES +To run these examples, set your PBS queue to short, walltime to 1:00:00 and ppn to 2 +For the following exmaples, I assume the current location is the PRADA directory +Please use "tar xzvf U87_chr17p13.2.end1.fastq.tar.gz" to unzip the fastq file. +Please see manual how to add PRADA to system path. + +1. Run PRADA from BAM +./prada-preprocess-bi -inputdir testdata -sample U87_chr17p13.2 -tag U87 -step 1_1 -pbs frombam -outdir testdata/test1 -submit yes + +2. Run PRADA from FASTQ +./prada-preprocess-bi -inputdir testdata -sample U87_chr17p13.2 -tag U87 -step 2_e1_1 -pbs fromfq -outdir testdata/test2 -submit yes + +3. Run Fusion Module +./prada-fusion -bam testdata/test1/U87_chr17p13.2.withRG.GATKRecalibrated.flagged.bam -junL 50 -outdir testdata/fusion + +4. Run frame prediction +./prada-frame -conf conf.txt -i testdata/frame_test.txt -docstr frame_test_result -outdir testdata/ + +5. Run homology prediction +./prada-homology -i testdata/homology_test.txt -o testdata/homology_test_result.txt -tmpdir testdata/tmp + +6. Run GUESS-ft +./prada-guess-ft SPAG7 CAMTA2 -inputbam testdata/test1/U87_chr17p13.2.withRG.GATKRecalibrated.flagged.bam -junL 50 -outdir testdata/SPAG7_CAMTA2 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/COPYING Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/ChangeLog Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,3545 @@ +------------------------------------------------------------------------ +r1309 | lh3 | 2010-02-26 21:42:22 -0500 (Fri, 26 Feb 2010) | 4 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + + * bwa-0.5.6-2 (r1309) + * fixed an unfixed bug (by Carol Scott) + * fixed some tiny formatting + +------------------------------------------------------------------------ +r1305 | lh3 | 2010-02-25 13:47:58 -0500 (Thu, 25 Feb 2010) | 3 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + + * bwa-0.5.6-1 (r1304) + * optionally write output to a file (by Tim Fennel) + +------------------------------------------------------------------------ +r1303 | lh3 | 2010-02-10 23:43:48 -0500 (Wed, 10 Feb 2010) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + +Release bwa-0.5.6 + +------------------------------------------------------------------------ +r1302 | lh3 | 2010-02-10 11:11:49 -0500 (Wed, 10 Feb 2010) | 3 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/main.c + + * bwa-0.5.5-10 (r1302) + * improve max insert size estimate (method suggested by Gerton Lunter) + +------------------------------------------------------------------------ +r1301 | lh3 | 2010-02-09 16:15:28 -0500 (Tue, 09 Feb 2010) | 5 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/main.c + + * bwa-0.5.5-9 (r1301) + * improve mapping quality calculation for abnomalous pairs + * fixed a bug in multiple hits + * SOLiD multiple hits should work now + +------------------------------------------------------------------------ +r1300 | lh3 | 2010-02-09 12:50:02 -0500 (Tue, 09 Feb 2010) | 3 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/main.c + + * bwa-0.5.5-8 (r1300) + * output kurtosis + +------------------------------------------------------------------------ +r1299 | lh3 | 2010-02-09 12:33:34 -0500 (Tue, 09 Feb 2010) | 5 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/main.c + + * bwa-0.5.5-7 (r1299) + * calculate skewness in sampe + * increase min_len in SW to 20 + * perform more SW to fix discordant pairs + +------------------------------------------------------------------------ +r1298 | lh3 | 2010-02-08 12:40:31 -0500 (Mon, 08 Feb 2010) | 3 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/cs2nt.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/stdaln.h + + * bwa-0.5.5-6 (r1297) + * prepare to replace all 16-bit CIGAR (patches by Rodrigo Goya) + +------------------------------------------------------------------------ +r1297 | lh3 | 2010-02-05 22:26:11 -0500 (Fri, 05 Feb 2010) | 2 lines +Changed paths: + M /branches/prog/bwa/solid2fastq.pl + +the old fix seems not working! + +------------------------------------------------------------------------ +r1296 | lh3 | 2010-02-05 21:51:03 -0500 (Fri, 05 Feb 2010) | 3 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/main.c + + * bwa-0.5.5-5 (r1296) + * fixed a minor issue that the lower bound of insert size is not correctly set. + +------------------------------------------------------------------------ +r1295 | lh3 | 2010-02-05 21:01:10 -0500 (Fri, 05 Feb 2010) | 5 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwaseqio.c + M /branches/prog/bwa/main.c + + * bwa-0.5.5-4 (r1295) + * fixed a memory leak + * change the behaviour of -n (samse and sampe) + * change the default of -n + +------------------------------------------------------------------------ +r1294 | lh3 | 2010-02-05 17:24:06 -0500 (Fri, 05 Feb 2010) | 3 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwaseqio.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/main.c + + * bwa-0.5.5-3 (r1294) + * improved multi-hit report + +------------------------------------------------------------------------ +r1293 | lh3 | 2010-02-05 12:57:38 -0500 (Fri, 05 Feb 2010) | 5 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/cs2nt.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/solid2fastq.pl + + * bwa-0.5.5-2 (r1293) + * bugfix: truncated quality string + * bugfix: quality -1 in solid->fastq conversion + * bugfix: color reads on the reverse strand is not complemented + +------------------------------------------------------------------------ +r1279 | lh3 | 2009-11-23 22:42:34 -0500 (Mon, 23 Nov 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bntseq.c + M /branches/prog/bwa/bntseq.h + M /branches/prog/bwa/bwase.c + A /branches/prog/bwa/bwase.h + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/main.c + + * bwa-0.5.5-1 (r1279) + * incorporate changes from Matt Hanna for Java bindings. + +------------------------------------------------------------------------ +r1275 | lh3 | 2009-11-10 22:13:10 -0500 (Tue, 10 Nov 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + +update ChangeLog + +------------------------------------------------------------------------ +r1273 | lh3 | 2009-11-10 22:08:16 -0500 (Tue, 10 Nov 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/main.c + A /branches/prog/bwa/qualfa2fq.pl + +Release bwa-0.5.5 (r1273) + +------------------------------------------------------------------------ +r1272 | lh3 | 2009-11-10 22:02:50 -0500 (Tue, 10 Nov 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/main.c + + * bwa-0.5.4-3 (r1272) + * fixed another typo which may lead to incorrect single-end mapping quality + +------------------------------------------------------------------------ +r1271 | lh3 | 2009-11-10 21:59:47 -0500 (Tue, 10 Nov 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + + * bwa-0.5.4-2 (r1271) + * fixed a serious typo/bug which does not hurt if we allow one gap open + and work with <200bp reads, but causes segfault for long reads. + +------------------------------------------------------------------------ +r1270 | lh3 | 2009-11-09 23:12:42 -0500 (Mon, 09 Nov 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/cs2nt.c + M /branches/prog/bwa/main.c + + * bwa-0.5.4-1 (r1270) + * fixed a bug in color alignment + +------------------------------------------------------------------------ +r1245 | lh3 | 2009-10-09 07:42:52 -0400 (Fri, 09 Oct 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwaseqio.c + M /branches/prog/bwa/main.c + +Release bwa-0.5.4 + +------------------------------------------------------------------------ +r1244 | lh3 | 2009-10-09 05:53:52 -0400 (Fri, 09 Oct 2009) | 5 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwaseqio.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/main.c + M /branches/prog/bwa/stdaln.c + + * bwa-0.5.3-4 (r1244) + * output the clipped length in XC:i: tag + * skip mate alignment when stdaln is buggy + * fixed a bug in NM:i: tag + +------------------------------------------------------------------------ +r1243 | lh3 | 2009-10-07 08:15:04 -0400 (Wed, 07 Oct 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/main.c + + * bwa-0.5.3-3 (r1243) + * sampe: fixed a bug when a read sequence is identical its reverse complement. + +------------------------------------------------------------------------ +r1242 | lh3 | 2009-10-07 07:49:13 -0400 (Wed, 07 Oct 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bntseq.c + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/main.c + + * bwa-0.5.3-2 (r1242) + * sampe: optionall preload the full index into memory + * aln: change the default seed length to 32bp + +------------------------------------------------------------------------ +r1238 | lh3 | 2009-09-26 18:38:15 -0400 (Sat, 26 Sep 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/khash.h + +Improve portability of khash.h + +------------------------------------------------------------------------ +r1228 | lh3 | 2009-09-15 09:20:22 -0400 (Tue, 15 Sep 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/main.c + +fixed a typo + +------------------------------------------------------------------------ +r1227 | lh3 | 2009-09-15 09:19:35 -0400 (Tue, 15 Sep 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + + * bwa-0.5.3-1 (r1226) + * in dBWT-SW, optionall use hard clipping instead of soft clipping + +------------------------------------------------------------------------ +r1225 | lh3 | 2009-09-15 08:32:30 -0400 (Tue, 15 Sep 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/main.c + +Release bwa-0.5.3 (r1225) + +------------------------------------------------------------------------ +r1223 | lh3 | 2009-09-13 07:30:41 -0400 (Sun, 13 Sep 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/main.c + +Release bwa-0.5.2 + +------------------------------------------------------------------------ +r1222 | lh3 | 2009-09-11 09:11:39 -0400 (Fri, 11 Sep 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + + * bwa-0.5.1-5 (r1222) + * fixed a typo. No real change + +------------------------------------------------------------------------ +r1221 | lh3 | 2009-09-11 09:09:44 -0400 (Fri, 11 Sep 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwaseqio.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/main.c + + * bwa-0.5.1-4 (r1221) + * trim reads before alignment + +------------------------------------------------------------------------ +r1216 | lh3 | 2009-09-08 17:50:15 -0400 (Tue, 08 Sep 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/main.c + + * bwa-0.5.1-3 (r1216) + * fixed a bug about NM tags for gapped alignment + * print SAM header + +------------------------------------------------------------------------ +r1215 | lh3 | 2009-09-08 17:14:42 -0400 (Tue, 08 Sep 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + + * bwa-0.5.1-2 (r1215) + * fixed a bug when read lengths vary (by John Marshall) + +------------------------------------------------------------------------ +r1213 | lh3 | 2009-09-06 18:58:15 -0400 (Sun, 06 Sep 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/main.c + + * bwa-0.5.1-1 (r1213) + * change default -T to 30 + +------------------------------------------------------------------------ +r1209 | lh3 | 2009-09-02 06:06:02 -0400 (Wed, 02 Sep 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/main.c + +Release bwa-0.5.1 + +------------------------------------------------------------------------ +r1208 | lh3 | 2009-09-02 05:56:33 -0400 (Wed, 02 Sep 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + + * ChangeLog + +------------------------------------------------------------------------ +r1206 | lh3 | 2009-08-30 18:27:30 -0400 (Sun, 30 Aug 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/main.c + + * bwa-0.5.0-6 (r1206) + * fixed two bugs caused by previous modification + +------------------------------------------------------------------------ +r1205 | lh3 | 2009-08-30 17:28:36 -0400 (Sun, 30 Aug 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/main.c + + * bwa-0.5.0-4 (r1205) + * reduce false coordinates and CIGAR when a query bridges two reference + sequences, although some very rare cases may fail bwa. + +------------------------------------------------------------------------ +r1204 | lh3 | 2009-08-30 06:06:16 -0400 (Sun, 30 Aug 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/main.c + + * bwa-0.5.0-3 (r1204) + * choose one repetitive hit to extend + +------------------------------------------------------------------------ +r1203 | lh3 | 2009-08-29 18:11:51 -0400 (Sat, 29 Aug 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/main.c + + * bwa-0.5.0-2 (r1203) + * dBWT-SW: change a parameter in calculating mapping quality + * fixed a bug in samse + +------------------------------------------------------------------------ +r1202 | lh3 | 2009-08-28 19:48:41 -0400 (Fri, 28 Aug 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/main.c + + * bwa-0.5.0-1 (r1202) + * change default band width to 50 + * improve mapping quality a bit + +------------------------------------------------------------------------ +r1200 | lh3 | 2009-08-20 06:21:24 -0400 (Thu, 20 Aug 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/main.c + +Release bwa-0.5.0 (r1200) + +------------------------------------------------------------------------ +r1199 | lh3 | 2009-08-20 04:49:15 -0400 (Thu, 20 Aug 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/bwa.1 + +Updated ChangeLog and the manual + +------------------------------------------------------------------------ +r1198 | lh3 | 2009-08-19 11:09:15 -0400 (Wed, 19 Aug 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-36 (r1198) + * simplify duphits removal. The accuracy is changed a tiny bit, sometimes better, sometimes worse. + +------------------------------------------------------------------------ +r1197 | lh3 | 2009-08-19 08:15:05 -0400 (Wed, 19 Aug 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwtsw2_aux.c + A /branches/prog/bwa/bwtsw2_chain.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-35 (r1197) + * further heuristic acceleration for long queries + +------------------------------------------------------------------------ +r1196 | lh3 | 2009-08-18 06:54:03 -0400 (Tue, 18 Aug 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-34 (r1196) + * updated the manual page + * output base quality if the input is fastq + +------------------------------------------------------------------------ +r1195 | lh3 | 2009-08-18 06:23:00 -0400 (Tue, 18 Aug 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/simple_dp.c + + * bwa-0.4.9-33 (r1191) + * fixed a bug in sampe/samse when gaps occur to the 5'-end in SW alignment + * in dbwtsw adjust -T and -c according to -a + +------------------------------------------------------------------------ +r1192 | lh3 | 2009-08-13 05:37:28 -0400 (Thu, 13 Aug 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + +update manual + +------------------------------------------------------------------------ +r1191 | lh3 | 2009-08-12 19:40:51 -0400 (Wed, 12 Aug 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/bwtsw2_main.c + +update documentation + +------------------------------------------------------------------------ +r1190 | lh3 | 2009-08-12 08:56:10 -0400 (Wed, 12 Aug 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-32 (r1190) + * only help messages are changed + +------------------------------------------------------------------------ +r1189 | lh3 | 2009-08-11 09:28:55 -0400 (Tue, 11 Aug 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-31 (r1189) + * in bwape/bwase, print CIGAR "*" if the read is unmapped + * improved the calculation of mapping quality + +------------------------------------------------------------------------ +r1181 | lh3 | 2009-08-03 12:09:41 -0400 (Mon, 03 Aug 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_aux.c + +fflush() + +------------------------------------------------------------------------ +r1180 | lh3 | 2009-08-03 12:08:46 -0400 (Mon, 03 Aug 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-30 (r1180) + * fixed a memory problem + * multi-threading sometimes does not work... + +------------------------------------------------------------------------ +r1179 | lh3 | 2009-08-03 11:04:39 -0400 (Mon, 03 Aug 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-29 (r1179) + * preliminary mutli-threading support in dbwtsw + +------------------------------------------------------------------------ +r1178 | lh3 | 2009-08-03 09:14:54 -0400 (Mon, 03 Aug 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-28 (r1178) + * fixed a bug in printing repetitive hits + +------------------------------------------------------------------------ +r1177 | lh3 | 2009-08-03 05:03:42 -0400 (Mon, 03 Aug 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-27 (r1177) + * bwtsw2: fixed a hidden memory leak + +------------------------------------------------------------------------ +r1176 | lh3 | 2009-07-31 10:58:24 -0400 (Fri, 31 Jul 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-26 + * change the way mapping quality is calculated + +------------------------------------------------------------------------ +r1175 | lh3 | 2009-07-31 09:15:54 -0400 (Fri, 31 Jul 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-25 + * code clean up + * automatically adjust ->t and ->is_rev based on input + +------------------------------------------------------------------------ +r1174 | lh3 | 2009-07-30 08:50:25 -0400 (Thu, 30 Jul 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-24 + * fixed a bug in printing the hits + +------------------------------------------------------------------------ +r1173 | lh3 | 2009-07-29 18:32:43 -0400 (Wed, 29 Jul 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-23 + * allow to skip reverse alignment + * increase opt->t to 37 + +------------------------------------------------------------------------ +r1172 | lh3 | 2009-07-29 17:22:39 -0400 (Wed, 29 Jul 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-22 + * report if the hit is found in both directions + +------------------------------------------------------------------------ +r1171 | lh3 | 2009-07-29 17:12:02 -0400 (Wed, 29 Jul 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-21 + * dbwtsw: map to both forward and reverse BWT to reduce false alignment + +------------------------------------------------------------------------ +r1170 | lh3 | 2009-07-29 15:25:14 -0400 (Wed, 29 Jul 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/main.c + +save hits before cut_tail() + +------------------------------------------------------------------------ +r1169 | lh3 | 2009-07-29 08:06:01 -0400 (Wed, 29 Jul 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/stdaln.c + M /branches/prog/bwa/stdaln.h + + * bwa-0.4.9-19 + * use a global memory pool to reduce the CPU time spent on malloc/free(). + +------------------------------------------------------------------------ +r1168 | lh3 | 2009-07-29 06:13:29 -0400 (Wed, 29 Jul 2009) | 5 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-18 + * reduce unnecessary extension to the 5'-end + * allow to use different interval size for the 2 rounds + * change default parameters + +------------------------------------------------------------------------ +r1167 | lh3 | 2009-07-28 19:06:17 -0400 (Tue, 28 Jul 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-17 + * dbwtsw: fixed THE memory leak. + +------------------------------------------------------------------------ +r1166 | lh3 | 2009-07-28 16:31:41 -0400 (Tue, 28 Jul 2009) | 5 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/stdaln.c + + * bwa-0.4.9-16 + * fixed a memory leak + * a small memory leak still occurs to bwtsw2_core(). I will work on that later. + * changed the default parameters + +------------------------------------------------------------------------ +r1165 | lh3 | 2009-07-28 10:15:40 -0400 (Tue, 28 Jul 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/stdaln.c + + * bwa-0.4.9-15 + * generate CIGAR right before output. This saves unnecessary computation. + * this version may be buggy as I have not tested it. + +------------------------------------------------------------------------ +r1164 | lh3 | 2009-07-28 09:04:14 -0400 (Tue, 28 Jul 2009) | 11 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/stdaln.c + M /branches/prog/bwa/stdaln.h + + * bwa-0.4.9-14 + + * deplete unique hits in dbwtsw and postprocess them with standard sw + + * in principle, this stratgy should be faster and more accurate, but I + have not tested this point. I may switch back to the old method if + this does not work. + + * the code looks quite nasty now. it needs clean up... + + +------------------------------------------------------------------------ +r1163 | lh3 | 2009-07-27 17:41:10 -0400 (Mon, 27 Jul 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_aux.c + +change a default parameter + +------------------------------------------------------------------------ +r1162 | lh3 | 2009-07-27 17:04:35 -0400 (Mon, 27 Jul 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-13 + * dbwtsw: switch between small and large Z-best + +------------------------------------------------------------------------ +r1161 | lh3 | 2009-07-27 12:17:41 -0400 (Mon, 27 Jul 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-12 + * changed the default -z to 100 + * heuristically speed up alignments for polyA reads + +------------------------------------------------------------------------ +r1160 | lh3 | 2009-07-27 07:50:57 -0400 (Mon, 27 Jul 2009) | 6 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-11 + + * dbwtsw potentially generates less false alignments, although in + practice, the modification brings no improvement. + + +------------------------------------------------------------------------ +r1159 | lh3 | 2009-07-27 04:37:02 -0400 (Mon, 27 Jul 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-10 + * disabled debugging code + * add "BAM_FMU" if both ends are unmapped + +------------------------------------------------------------------------ +r1158 | lh3 | 2009-07-24 09:36:52 -0400 (Fri, 24 Jul 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/main.c + +nothing, really + +------------------------------------------------------------------------ +r1157 | lh3 | 2009-07-24 09:05:44 -0400 (Fri, 24 Jul 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-9 + * bwtsw2: generate SAM output + +------------------------------------------------------------------------ +r1156 | lh3 | 2009-07-24 05:42:47 -0400 (Fri, 24 Jul 2009) | 6 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-8 + + * fixed a weird deadloop which only happens to icc -O3. Thanks John + Marshall for the fix. + + +------------------------------------------------------------------------ +r1155 | lh3 | 2009-07-24 05:28:40 -0400 (Fri, 24 Jul 2009) | 8 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-7 + + * fixed a typo in bwtsw2 alignment. Now score from the standard SW + seems to agree with score from bwtsw2, except that in reporting + alignments, bwtsw2 may report non-optimal segments. This is expected, + though. I will improve in future. + + +------------------------------------------------------------------------ +r1154 | lh3 | 2009-07-23 17:40:20 -0400 (Thu, 23 Jul 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/stdaln.c + M /branches/prog/bwa/stdaln.h + + * aln_left_core() seems to work properly + * aln_local_core() has a bug... AN EVER EXISTING BUG!!!!!!!!!!! + +------------------------------------------------------------------------ +r1153 | lh3 | 2009-07-23 17:06:09 -0400 (Thu, 23 Jul 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/stdaln.c + +removed debugging code... + +------------------------------------------------------------------------ +r1152 | lh3 | 2009-07-23 17:01:00 -0400 (Thu, 23 Jul 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/stdaln.c + + * radical changes failed... + * fixed a bug + +------------------------------------------------------------------------ +r1151 | lh3 | 2009-07-23 14:46:35 -0400 (Thu, 23 Jul 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/stdaln.c + +temporary changes. Will apply some radical changes to this file... + +------------------------------------------------------------------------ +r1150 | lh3 | 2009-07-23 10:09:56 -0400 (Thu, 23 Jul 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/stdaln.c + +fixed a long-existing bug in Smith-Waterman alignment + +------------------------------------------------------------------------ +r1149 | lh3 | 2009-07-23 08:50:52 -0400 (Thu, 23 Jul 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/simple_dp.c + M /branches/prog/bwa/stdaln.c + M /branches/prog/bwa/stdaln.h + + * bwa-0.4.9-6 + * unexplained inconsistency still occurs, but the results largely look reasonable. + +------------------------------------------------------------------------ +r1148 | lh3 | 2009-07-23 08:07:29 -0400 (Thu, 23 Jul 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/stdaln.c + +half DP + +------------------------------------------------------------------------ +r1147 | lh3 | 2009-07-22 08:03:06 -0400 (Wed, 22 Jul 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/bwtsw2_main.c + +a bit code clean up + +------------------------------------------------------------------------ +r1145 | lh3 | 2009-07-21 15:52:05 -0400 (Tue, 21 Jul 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-5 + * fixed a bug in determining sub-optimal hits + * removed some debugging codes + +------------------------------------------------------------------------ +r1144 | lh3 | 2009-07-21 10:17:29 -0400 (Tue, 21 Jul 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-4 + * better cmd interface + * faster speed + +------------------------------------------------------------------------ +r1143 | lh3 | 2009-07-20 16:38:18 -0400 (Mon, 20 Jul 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + +bwtsw2 (dBWT-SW) is working apparently... + + +------------------------------------------------------------------------ +r1139 | lh3 | 2009-07-15 05:52:18 -0400 (Wed, 15 Jul 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/main.c + + * bwa-0.4.9-2 + * bwtsw2: change cut_tail() such that it is faster but more likely to + miss true hits + +------------------------------------------------------------------------ +r1138 | lh3 | 2009-07-15 05:18:42 -0400 (Wed, 15 Jul 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/Makefile + A /branches/prog/bwa/bwt_lite.c + A /branches/prog/bwa/bwt_lite.h + A /branches/prog/bwa/bwtsw2.h + A /branches/prog/bwa/bwtsw2_aux.c + A /branches/prog/bwa/bwtsw2_core.c + A /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/main.h + + * bwa-0.4.9-1 + * added back bwtsw2 + +------------------------------------------------------------------------ +r1075 | lh3 | 2009-05-19 05:14:50 -0400 (Tue, 19 May 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/main.c + +Release bwa-0.4.9 + +------------------------------------------------------------------------ +r1073 | lh3 | 2009-05-18 17:13:19 -0400 (Mon, 18 May 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/main.c + +Release bwa-0.4.8 + +------------------------------------------------------------------------ +r1069 | lh3 | 2009-05-14 09:54:54 -0400 (Thu, 14 May 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + + * bwa-0.4.7-2 + * change the default of "aln -R" to 30 + +------------------------------------------------------------------------ +r1068 | lh3 | 2009-05-14 09:27:55 -0400 (Thu, 14 May 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/main.c + + * bwa-0.4.7-1 + * search for suboptimal hits if the top hit is not so repetitive + +------------------------------------------------------------------------ +r1066 | lh3 | 2009-05-12 15:31:31 -0400 (Tue, 12 May 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/main.c + +Release bwa-0.4.7 + +------------------------------------------------------------------------ +r1065 | lh3 | 2009-05-12 15:20:40 -0400 (Tue, 12 May 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/main.c + + * bwa-0.4.6-9 + * fixed compiling errors on some Linux machines + +------------------------------------------------------------------------ +r1064 | lh3 | 2009-05-12 07:30:46 -0400 (Tue, 12 May 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + + * bwa-0.4.6-8 + * avoid compilation error on some systems. + +------------------------------------------------------------------------ +r1035 | lh3 | 2009-05-09 05:41:33 -0400 (Sat, 09 May 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/main.c + + * bwa-0.4.6-7 + * fixed an integer overflow caused by previous modifications + * made insert size estimation more robust + +------------------------------------------------------------------------ +r1008 | lh3 | 2009-04-29 05:41:58 -0400 (Wed, 29 Apr 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/main.c + + * bwa-0.4.6-5 + * fixed a integer overflow problem which may cause seg fault in very rare cases + * made XN tags more accurate + +------------------------------------------------------------------------ +r1005 | lh3 | 2009-04-27 07:37:23 -0400 (Mon, 27 Apr 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/simple_dp.c + M /branches/prog/bwa/stdaln.c + M /branches/prog/bwa/stdaln.h + + * bwa-0.4.6-4 + * heuristic rules to detect suboptimal alignment + * stdsw: support double-strand and protein alignment + +------------------------------------------------------------------------ +r1003 | lh3 | 2009-04-26 12:48:19 -0400 (Sun, 26 Apr 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/main.c + M /branches/prog/bwa/simple_dp.c + M /branches/prog/bwa/stdaln.c + M /branches/prog/bwa/stdaln.h + + * bwa-0.4.6-2 + * improve the functionality of stdsw + * allow to add a threshold on SW alignment. Hope this does not incur new bugs... + +------------------------------------------------------------------------ +r1002 | lh3 | 2009-04-22 03:56:15 -0400 (Wed, 22 Apr 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/main.c + + * bwa-0.4.6-1 + * output SM and AM tag + +------------------------------------------------------------------------ +r914 | lh3 | 2009-03-09 17:53:50 -0400 (Mon, 09 Mar 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/main.c + +Release bwa-0.4.6 + +------------------------------------------------------------------------ +r913 | lh3 | 2009-03-09 17:23:24 -0400 (Mon, 09 Mar 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/bwape.c + A /branches/prog/bwa/solid2fastq.pl + + * added notes to bwa + * added a script to convert SOLiD reads + * updated documentations + +------------------------------------------------------------------------ +r912 | lh3 | 2009-03-09 16:57:05 -0400 (Mon, 09 Mar 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/kstring.c + M /branches/prog/bwa/main.c + +fixed a bug in kstring + +------------------------------------------------------------------------ +r881 | lh3 | 2009-03-02 15:36:06 -0500 (Mon, 02 Mar 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtmisc.c + M /branches/prog/bwa/main.c + + * bwa-0.4.5-7 + * fixed a bug in pac2cspac + +------------------------------------------------------------------------ +r880 | lh3 | 2009-03-01 16:34:08 -0500 (Sun, 01 Mar 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/Makefile + +disable debugging + +------------------------------------------------------------------------ +r879 | lh3 | 2009-03-01 16:28:04 -0500 (Sun, 01 Mar 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/cs2nt.c + M /branches/prog/bwa/main.c + + * bwa-0.4.5-6 + * fixed problems with coordinates for color gapped alignment + +------------------------------------------------------------------------ +r878 | lh3 | 2009-03-01 13:43:09 -0500 (Sun, 01 Mar 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/cs2nt.c + M /branches/prog/bwa/main.c + + * bwa-0.4.5-5 + * added support for gapped color alignment + +------------------------------------------------------------------------ +r877 | lh3 | 2009-03-01 10:27:52 -0500 (Sun, 01 Mar 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/cs2nt.c + M /branches/prog/bwa/main.c + + * convert cs read to nt read (for ungapped alignment only) + +------------------------------------------------------------------------ +r860 | lh3 | 2009-02-27 08:58:39 -0500 (Fri, 27 Feb 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwase.c + A /branches/prog/bwa/cs2nt.c + +prepare to implement cs->nt conversion (have not yet...) + +------------------------------------------------------------------------ +r859 | lh3 | 2009-02-27 07:00:03 -0500 (Fri, 27 Feb 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bntseq.c + M /branches/prog/bwa/bntseq.h + M /branches/prog/bwa/bwtindex.c + M /branches/prog/bwa/bwtmisc.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/main.h + + * bwa-0.4.5-3 + * generate color index from nucleotide fasta reference + +------------------------------------------------------------------------ +r857 | lh3 | 2009-02-26 10:22:58 -0500 (Thu, 26 Feb 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/main.c + + * bwa-0.4.5-2 + * improved mapping quality a bit if one end falls in a tandem repeat + but the mate is unique. + +------------------------------------------------------------------------ +r856 | lh3 | 2009-02-26 10:02:29 -0500 (Thu, 26 Feb 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/main.c + + * bwa-0.4.5-1 + * make bwa work for SOLiD reads + +------------------------------------------------------------------------ +r828 | lh3 | 2009-02-18 17:36:41 -0500 (Wed, 18 Feb 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/main.c + +Release bwa-0.4.5 + +------------------------------------------------------------------------ +r827 | lh3 | 2009-02-18 16:48:48 -0500 (Wed, 18 Feb 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/main.c + M /branches/prog/bwa/stdaln.c + M /branches/prog/bwa/stdaln.h + + * bwa-0.4.4-6 + * fixed a bug in SW alignment when no residue matches + +------------------------------------------------------------------------ +r824 | lh3 | 2009-02-17 05:33:07 -0500 (Tue, 17 Feb 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/main.c + + * bwa-0.4.4-5 + * fixed that bounary bug + +------------------------------------------------------------------------ +r823 | lh3 | 2009-02-17 04:54:18 -0500 (Tue, 17 Feb 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/bwape.c + +just change some logging information + +------------------------------------------------------------------------ +r822 | lh3 | 2009-02-17 04:20:39 -0500 (Tue, 17 Feb 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + +update manual + +------------------------------------------------------------------------ +r821 | lh3 | 2009-02-17 04:11:14 -0500 (Tue, 17 Feb 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/main.c + + * bwa-0.4.4-4 + * fixed a bug on boundary check in pair_sw + +------------------------------------------------------------------------ +r820 | lh3 | 2009-02-16 17:43:37 -0500 (Mon, 16 Feb 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + + * bwa-0.4.4-3 + * allow to change mismatch penalty + +------------------------------------------------------------------------ +r819 | lh3 | 2009-02-16 17:40:28 -0500 (Mon, 16 Feb 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + + * bwa-0.4.4-2 + * remove timer + * allow to change default gapo and gape penalty at the command line + +------------------------------------------------------------------------ +r818 | lh3 | 2009-02-16 09:30:51 -0500 (Mon, 16 Feb 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + +update benchmark + +------------------------------------------------------------------------ +r817 | lh3 | 2009-02-16 08:44:40 -0500 (Mon, 16 Feb 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/kvec.h + M /branches/prog/bwa/main.c + + * bwa-0.4.4-1 + * automatically detect insert size + * use insert size in pairing. This may potentially improve accuracy (untested!) + +------------------------------------------------------------------------ +r814 | lh3 | 2009-02-15 11:10:23 -0500 (Sun, 15 Feb 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/main.c + +Release bwa-0.4.4 + +------------------------------------------------------------------------ +r813 | lh3 | 2009-02-15 10:22:50 -0500 (Sun, 15 Feb 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/main.c + + * bwa-0.4.3-5 + * impose boundary check in refine_gapped + +------------------------------------------------------------------------ +r811 | lh3 | 2009-02-14 09:46:13 -0500 (Sat, 14 Feb 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/main.c + + * bwa-0.4.3-4 + * change MD tag to match the latest SAM specification + +------------------------------------------------------------------------ +r810 | lh3 | 2009-02-13 04:46:04 -0500 (Fri, 13 Feb 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + +update ChangeLog + +------------------------------------------------------------------------ +r799 | lh3 | 2009-02-05 12:01:17 -0500 (Thu, 05 Feb 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/main.c + +change MD tag to meet the latest SAM specification + +------------------------------------------------------------------------ +r796 | lh3 | 2009-02-05 08:35:13 -0500 (Thu, 05 Feb 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bntseq.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/main.c + + * bwa-0.4.3-2 + * fixed a bug on counting 'N' + +------------------------------------------------------------------------ +r795 | lh3 | 2009-02-05 07:41:27 -0500 (Thu, 05 Feb 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/main.c + + * bwa-0.4.3-1 + * fixed potential boundary problems + * update benchmark result + +------------------------------------------------------------------------ +r791 | lh3 | 2009-01-25 05:20:47 -0500 (Sun, 25 Jan 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + +update some numbers + +------------------------------------------------------------------------ +r790 | lh3 | 2009-01-24 15:13:03 -0500 (Sat, 24 Jan 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + +update benchmark + +------------------------------------------------------------------------ +r789 | lh3 | 2009-01-22 10:18:44 -0500 (Thu, 22 Jan 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtindex.c + +a warning message for index + +------------------------------------------------------------------------ +r788 | lh3 | 2009-01-22 09:54:06 -0500 (Thu, 22 Jan 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/main.c + +forget to change release number + +------------------------------------------------------------------------ +r786 | lh3 | 2009-01-22 06:27:39 -0500 (Thu, 22 Jan 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/NEWS + +Release bwa-0.4.3 + +------------------------------------------------------------------------ +r785 | lh3 | 2009-01-22 06:27:16 -0500 (Thu, 22 Jan 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/NEWS + +Release bwa-0.4.3 + +------------------------------------------------------------------------ +r784 | lh3 | 2009-01-22 06:19:59 -0500 (Thu, 22 Jan 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/main.c + + * bwa-0.4.2-10 + * update documentation + * fixed a bug on generating MD tags for SW alignment + +------------------------------------------------------------------------ +r782 | lh3 | 2009-01-19 12:08:38 -0500 (Mon, 19 Jan 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/main.c + + * bwa-0.4.2-9 + * fixed a bug in samse -n... + +------------------------------------------------------------------------ +r781 | lh3 | 2009-01-19 11:26:37 -0500 (Mon, 19 Jan 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + + * bwa-0.4.2-8 + * given -N, the previous version would stop if the top hit is a repeat. Now changed. + +------------------------------------------------------------------------ +r780 | lh3 | 2009-01-19 11:20:18 -0500 (Mon, 19 Jan 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/main.c + + * bwa-0.4.2-7 + * use a bit-wise flag to replace some member variables in the option struct + * allow to switch off the iterative strategy + +------------------------------------------------------------------------ +r779 | lh3 | 2009-01-19 10:45:57 -0500 (Mon, 19 Jan 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/main.c + + * bwa-0.4.2-6 + * allow to dump multiple hits from samse, in another format, though + +------------------------------------------------------------------------ +r778 | lh3 | 2009-01-19 06:24:29 -0500 (Mon, 19 Jan 2009) | 5 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwaseqio.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/kseq.h + A /branches/prog/bwa/kstring.c + A /branches/prog/bwa/kstring.h + M /branches/prog/bwa/main.c + M /branches/prog/bwa/simple_dp.c + + * bwa-0.4.2-5 + * update kseq.h to the latest version + * generate MD tag + * print mate coordinate if only one end is unmapped + +------------------------------------------------------------------------ +r775 | lh3 | 2009-01-18 05:40:35 -0500 (Sun, 18 Jan 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/main.c + + * bwa-0.4.2-4 + * fixed a bug for SAM format + +------------------------------------------------------------------------ +r774 | lh3 | 2009-01-17 13:48:52 -0500 (Sat, 17 Jan 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + + * bwa-0.4.2-3 + * change default fnr to 0.04 + * print max_diff for valid fnr + +------------------------------------------------------------------------ +r773 | lh3 | 2009-01-17 05:54:37 -0500 (Sat, 17 Jan 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/main.c + + * bwa-0.4.2-2 + * automatically choose max_diff + +------------------------------------------------------------------------ +r772 | lh3 | 2009-01-16 18:16:14 -0500 (Fri, 16 Jan 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwaseqio.c + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/main.c + + * bwa-0.4.2-1 + * take N as a mismatch + +------------------------------------------------------------------------ +r768 | lh3 | 2009-01-09 11:57:23 -0500 (Fri, 09 Jan 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/bntseq.c + M /branches/prog/bwa/main.c + +Release bwa-0.4.2 + +------------------------------------------------------------------------ +r759 | lh3 | 2009-01-07 09:55:43 -0500 (Wed, 07 Jan 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/main.c + +Release bwa-0.4.1 + +------------------------------------------------------------------------ +r758 | lh3 | 2009-01-07 05:36:06 -0500 (Wed, 07 Jan 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/main.c + + * bwa-0.4.0-2 + * make mate_sw fully working + +------------------------------------------------------------------------ +r757 | lh3 | 2009-01-06 18:04:29 -0500 (Tue, 06 Jan 2009) | 5 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwaseqio.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/main.c + + * bwa-0.4.0-1 + * do SW alignment for unmapped mate. It is working. + * I still need to do some extra work for SW alignment, but it is too late + and I am getting tired... I will do tomorrow. + +------------------------------------------------------------------------ +r755 | lh3 | 2009-01-06 10:23:29 -0500 (Tue, 06 Jan 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/main.c + +Release bwa-0.4.0 + +------------------------------------------------------------------------ +r754 | lh3 | 2009-01-06 07:45:02 -0500 (Tue, 06 Jan 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/bwtgap.h + M /branches/prog/bwa/main.c + + * bwa-0.3.0-12 + * better lock + +------------------------------------------------------------------------ +r753 | lh3 | 2009-01-06 06:17:21 -0500 (Tue, 06 Jan 2009) | 5 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwaseqio.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/main.c + + * bwa-0.3.0-11 + * fixed a small memory leak in bwa_seq_close() + * fixed "uninitialized memory" from bwt_aln1_t + * multithreading for "aln" command + +------------------------------------------------------------------------ +r752 | lh3 | 2009-01-05 17:34:13 -0500 (Mon, 05 Jan 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/Makefile + D /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwt_gen/bwt_gen.c + A /branches/prog/bwa/bwtmisc.c (from /branches/prog/bwa/pac2bwt.c:748) + M /branches/prog/bwa/main.c + M /branches/prog/bwa/main.h + D /branches/prog/bwa/pac2bwt.c + + * bwa-0.3.0-10 + * a little bit code clean up + +------------------------------------------------------------------------ +r751 | lh3 | 2009-01-05 17:19:04 -0500 (Mon, 05 Jan 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/main.c + + * bwa-0.3.0-9 + * use 64-bit integer to speed up Occ calculate, although just a little bit + +------------------------------------------------------------------------ +r750 | lh3 | 2009-01-05 16:44:26 -0500 (Mon, 05 Jan 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/main.c + + * bwa-0.3.0-8 + * a little bit code cleanup + +------------------------------------------------------------------------ +r749 | lh3 | 2009-01-05 16:37:28 -0500 (Mon, 05 Jan 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/main.c + + * bwa-0.1.0-7 + * accelerate Occ calculation + +------------------------------------------------------------------------ +r748 | lh3 | 2009-01-05 16:12:28 -0500 (Mon, 05 Jan 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt.h + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtindex.c + M /branches/prog/bwa/bwtio.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/main.h + M /branches/prog/bwa/pac2bwt.c + + * bwa-0.3.0-6 + * put occ table along with bwt to save another cache miss + * this version is already faster than the previous and I can still improve it... + +------------------------------------------------------------------------ +r747 | lh3 | 2009-01-05 10:16:18 -0500 (Mon, 05 Jan 2009) | 5 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt.h + M /branches/prog/bwa/bwtio.c + M /branches/prog/bwa/main.c + + * bwa-0.3.0-5 + * remove occ_major to save a cache miss; however, OCC_INTERVAL has to be + increased to keep the same memory. As a result, the speed is a little + slower in fact. + +------------------------------------------------------------------------ +r746 | lh3 | 2009-01-05 09:50:53 -0500 (Mon, 05 Jan 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/main.c + + * bwa-0.3.0-4 + * added back optimization codes (it is a pain...) + +------------------------------------------------------------------------ +r745 | lh3 | 2009-01-05 08:23:00 -0500 (Mon, 05 Jan 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + + * bwa-0.3.0-3 + * faster bit operations + +------------------------------------------------------------------------ +r744 | lh3 | 2009-01-05 05:58:46 -0500 (Mon, 05 Jan 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/main.c + + * bwa-0.3.0-2 + * removed optimization codes again... + * use a new method to count the bits + +------------------------------------------------------------------------ +r743 | lh3 | 2009-01-04 17:18:38 -0500 (Sun, 04 Jan 2009) | 5 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/main.c + + * bwa-0.3.0-1 + * added back the optimization codes + * added a new option to aln: max_entries, although this is disabled by default + * updated benchmark + +------------------------------------------------------------------------ +r742 | lh3 | 2009-01-04 07:56:12 -0500 (Sun, 04 Jan 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + +add URL + +------------------------------------------------------------------------ +r740 | lh3 | 2009-01-04 07:39:43 -0500 (Sun, 04 Jan 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/main.c + +Release bwa-0.3.0 + +------------------------------------------------------------------------ +r739 | lh3 | 2009-01-04 06:55:06 -0500 (Sun, 04 Jan 2009) | 2 lines +Changed paths: + A /branches/prog/bwa/COPYING + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/bntseq.c + M /branches/prog/bwa/bntseq.h + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt.h + M /branches/prog/bwa/bwtindex.c + M /branches/prog/bwa/utils.c + M /branches/prog/bwa/utils.h + +added licensing information + +------------------------------------------------------------------------ +r738 | lh3 | 2009-01-04 06:18:25 -0500 (Sun, 04 Jan 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/main.c + + * bwa-0.2.0-31 + * better mapping quality + * update benchmark + +------------------------------------------------------------------------ +r737 | lh3 | 2009-01-03 16:00:58 -0500 (Sat, 03 Jan 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/bwa.1 + +update documentation + +------------------------------------------------------------------------ +r736 | lh3 | 2009-01-02 10:26:38 -0500 (Fri, 02 Jan 2009) | 2 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + +update documentation + +------------------------------------------------------------------------ +r735 | lh3 | 2009-01-02 07:10:20 -0500 (Fri, 02 Jan 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + + * bwa-0.2.0-30 + * reduce memory a little bit + * update documentation + +------------------------------------------------------------------------ +r734 | lh3 | 2009-01-01 13:45:45 -0500 (Thu, 01 Jan 2009) | 8 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/main.c + + * bwa-0.2.0-29 + * sampe: removed -O option; changed default -o to 100000 + * sampe: fixed a bug in calculating paired mapping quality + * aln: added an option to search for suboptimal hits even if the best is a repeat. + This option will make sampe MUCH SLOWER. + * sampe: set isize as zero if mapped to two different chr + * update manual (unfinished) + +------------------------------------------------------------------------ +r733 | lh3 | 2009-01-01 11:01:20 -0500 (Thu, 01 Jan 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/main.c + + * bwa-0.2.0-28 + * fixed a bug in calculating paired mapping quality + +------------------------------------------------------------------------ +r732 | lh3 | 2009-01-01 09:27:46 -0500 (Thu, 01 Jan 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwape.c + A /branches/prog/bwa/khash.h (from /branches/prog/sclib/khash/khash.h:675) + M /branches/prog/bwa/main.c + + * bwa-0.2.0-27 + * accelerate sampe by storing visited large intervals + +------------------------------------------------------------------------ +r731 | lh3 | 2009-01-01 06:51:21 -0500 (Thu, 01 Jan 2009) | 3 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/main.c + + * bwa-0.2.0-26 + * remove the optimation codes + +------------------------------------------------------------------------ +r730 | lh3 | 2009-01-01 06:48:59 -0500 (Thu, 01 Jan 2009) | 4 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/main.c + + * bwa-0.2.0-25 + * accelerate OCC calculation by ~7%. However, it seems not worth doing + this by complicate the codes. I will change back later. + +------------------------------------------------------------------------ +r729 | lh3 | 2008-12-31 16:43:56 -0500 (Wed, 31 Dec 2008) | 6 lines +Changed paths: + M /branches/prog/bwa/bntseq.c + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/main.c + + * bwa-0.2.0-24 + * change command "sai2sam_pe" to "sampe" + * print usage for sampe command + * in sampe: change default max_occ to 1000 + * fixed a few compiling warnings in bntseq.c + +------------------------------------------------------------------------ +r728 | lh3 | 2008-12-27 07:14:59 -0500 (Sat, 27 Dec 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/main.c + + * bwa-0.2.0-22 + * mating information can be printed to SAM + +------------------------------------------------------------------------ +r727 | lh3 | 2008-12-26 18:10:59 -0500 (Fri, 26 Dec 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwaseqio.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/main.c + + * bwa-0.2.0-21 + * implement pairing (still UNFINISHED) + * output all reads even if full of N + +------------------------------------------------------------------------ +r726 | lh3 | 2008-12-26 13:31:27 -0500 (Fri, 26 Dec 2008) | 5 lines +Changed paths: + M /branches/prog/bwa/Makefile + A /branches/prog/bwa/bwape.c + M /branches/prog/bwa/bwase.c + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/main.h + + * bwa-0.2.0-20 + * remove "-t" from aln cmd + * code clean up: move some functions in bwt2fmv.c to other source files + * added sai2sam_pe cmd: *UNFINISHED* + +------------------------------------------------------------------------ +r725 | lh3 | 2008-12-26 07:04:11 -0500 (Fri, 26 Dec 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/Makefile + A /branches/prog/bwa/bwase.c + A /branches/prog/bwa/bwaseqio.c + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/kseq.h + A /branches/prog/bwa/ksort.h (from /branches/prog/sclib/ksort/ksort.h:712) + A /branches/prog/bwa/kvec.h (from /branches/prog/sclib/kvec/kvec.h:537) + M /branches/prog/bwa/main.c + + * bwa-0.2.0-19 + * considerable code cleanup; no actual changes + +------------------------------------------------------------------------ +r724 | lh3 | 2008-12-25 11:32:11 -0500 (Thu, 25 Dec 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/main.c + + * bwa-0.2.0-18 + * generate SAM output + +------------------------------------------------------------------------ +r723 | lh3 | 2008-12-25 10:48:31 -0500 (Thu, 25 Dec 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/main.h + + * bwa-0.2.0-17 + * remove bwtsw2 related codes + * separate searching for SA interval from generating alignments + +------------------------------------------------------------------------ +r722 | lh3 | 2008-12-25 08:57:13 -0500 (Thu, 25 Dec 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwt2fmv.c + D /branches/prog/bwa/bwt_lite.c + D /branches/prog/bwa/bwt_lite.h + M /branches/prog/bwa/bwtgap.c + D /branches/prog/bwa/bwtsw2.h + D /branches/prog/bwa/bwtsw2_aux.c + D /branches/prog/bwa/bwtsw2_core.c + D /branches/prog/bwa/bwtsw2_main.c + D /branches/prog/bwa/khash.h + D /branches/prog/bwa/ksort.h + D /branches/prog/bwa/kvec.h + M /branches/prog/bwa/main.c + + * added interface to "aln -t" + * remove bwtsw2 related codes + +------------------------------------------------------------------------ +r666 | lh3 | 2008-11-18 18:34:29 -0500 (Tue, 18 Nov 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/main.c + + * bwa-0.2.0-16 + * allow to set max mismatches based on read length, but I do not know + whether this really works + +------------------------------------------------------------------------ +r665 | lh3 | 2008-11-18 08:34:03 -0500 (Tue, 18 Nov 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + + * bwa-0.2.0-15 + * fixed a bug in sequence parser. + +------------------------------------------------------------------------ +r612 | lh3 | 2008-10-28 06:50:53 -0400 (Tue, 28 Oct 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bntseq.c + M /branches/prog/bwa/bwtindex.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/utils.c + + * bwa-0.2.0-14 + * fixed a bug caused by the change of the FASTA/Q parser + +------------------------------------------------------------------------ +r611 | lh3 | 2008-10-28 06:24:56 -0400 (Tue, 28 Oct 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bntseq.c + M /branches/prog/bwa/bntseq.h + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtsw2_core.c + A /branches/prog/bwa/kseq.h + D /branches/prog/bwa/seq.c + D /branches/prog/bwa/seq.h + M /branches/prog/bwa/simple_dp.c + M /branches/prog/bwa/utils.c + M /branches/prog/bwa/utils.h + +replace seq.* with kseq.h + +------------------------------------------------------------------------ +r610 | lh3 | 2008-10-27 13:00:04 -0400 (Mon, 27 Oct 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/main.c + + * bwa-0.2.0-13 + * make bwtsw2 output sub-optimal hits. not completed + +------------------------------------------------------------------------ +r609 | lh3 | 2008-10-24 16:52:00 -0400 (Fri, 24 Oct 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/kvec.h + +little... + +------------------------------------------------------------------------ +r532 | lh3 | 2008-09-19 05:28:45 -0400 (Fri, 19 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/khash.h + +improve interface of khash + +------------------------------------------------------------------------ +r531 | lh3 | 2008-09-18 06:52:59 -0400 (Thu, 18 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + +improve minor things, which make bwtsw2 slower, but should miss less true hits + +------------------------------------------------------------------------ +r530 | lh3 | 2008-09-17 18:19:26 -0400 (Wed, 17 Sep 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + + * fixed a bug in calculating ->D + * enforce band-width checking + +------------------------------------------------------------------------ +r529 | lh3 | 2008-09-17 18:06:49 -0400 (Wed, 17 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + +delete a line of code that is never visited + +------------------------------------------------------------------------ +r528 | lh3 | 2008-09-17 17:58:51 -0400 (Wed, 17 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + +a bit code clean up + +------------------------------------------------------------------------ +r527 | lh3 | 2008-09-17 10:55:45 -0400 (Wed, 17 Sep 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + + * bwa-0.2.0-12 + * max-depth can be set, although it does not help the speed at all + +------------------------------------------------------------------------ +r526 | lh3 | 2008-09-16 17:59:36 -0400 (Tue, 16 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + +cut_tail after remove duplicate + +------------------------------------------------------------------------ +r525 | lh3 | 2008-09-16 17:56:11 -0400 (Tue, 16 Sep 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/khash.h + M /branches/prog/bwa/main.c + + * bwa-0.2.0-11 + * improved cut_tail() + +------------------------------------------------------------------------ +r524 | lh3 | 2008-09-15 16:53:22 -0400 (Mon, 15 Sep 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + + * bwa-0.2.0-10 + * fixed a bug in cut_tail() + +------------------------------------------------------------------------ +r518 | lh3 | 2008-09-15 04:35:59 -0400 (Mon, 15 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + +a bit code clean up + +------------------------------------------------------------------------ +r517 | lh3 | 2008-09-14 18:18:11 -0400 (Sun, 14 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + +improve speed (<1%) + +------------------------------------------------------------------------ +r516 | lh3 | 2008-09-14 18:08:55 -0400 (Sun, 14 Sep 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + + * fixed two potential bugs, although I have not seen their effects + * improve speed a bit (<2%) + +------------------------------------------------------------------------ +r515 | lh3 | 2008-09-14 17:26:49 -0400 (Sun, 14 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/bwtsw2_main.c + +nothing, really + +------------------------------------------------------------------------ +r514 | lh3 | 2008-09-14 17:10:13 -0400 (Sun, 14 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + +disable X-drop, which has to be reimplemented in the current algorithm + +------------------------------------------------------------------------ +r513 | lh3 | 2008-09-14 16:49:42 -0400 (Sun, 14 Sep 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bwt_lite.c + M /branches/prog/bwa/bwt_lite.h + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/bwtsw2_main.c + + * temporarily disable cut_tail() + * calculate SA in bwt_lite.c + * fixed a bug in reversing the sequence + +------------------------------------------------------------------------ +r512 | lh3 | 2008-09-13 17:35:40 -0400 (Sat, 13 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/bwtsw2_main.c + A /branches/prog/bwa/ksort.h + +n-best method + +------------------------------------------------------------------------ +r507 | lh3 | 2008-09-13 09:06:54 -0400 (Sat, 13 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwtsw2_core.c + +give correct result again + +------------------------------------------------------------------------ +r506 | lh3 | 2008-09-13 08:12:07 -0400 (Sat, 13 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + +I think I know the reason. It needs more work... + +------------------------------------------------------------------------ +r505 | lh3 | 2008-09-13 06:20:43 -0400 (Sat, 13 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwtsw2_core.c + +fixed another bug, but still have + +------------------------------------------------------------------------ +r504 | lh3 | 2008-09-12 18:13:37 -0400 (Fri, 12 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + +fixed another bug + +------------------------------------------------------------------------ +r503 | lh3 | 2008-09-12 17:15:56 -0400 (Fri, 12 Sep 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/khash.h + + * do not segfault, but the result is WRONG! + * prepare to remove bsw2_connectivity_check() + +------------------------------------------------------------------------ +r502 | lh3 | 2008-09-12 15:52:41 -0400 (Fri, 12 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/kvec.h + +more revisions + +------------------------------------------------------------------------ +r501 | lh3 | 2008-09-11 18:06:15 -0400 (Thu, 11 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + +further simply codes with kvec.h + +------------------------------------------------------------------------ +r500 | lh3 | 2008-09-11 17:42:15 -0400 (Thu, 11 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + +part of revisions... have not finished + +------------------------------------------------------------------------ +r499 | lh3 | 2008-09-11 17:24:15 -0400 (Thu, 11 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/khash.h + A /branches/prog/bwa/kvec.h + +prepare for abrupt change + +------------------------------------------------------------------------ +r496 | lh3 | 2008-09-11 10:34:38 -0400 (Thu, 11 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + +fixed a bug; now "bwtsw2 -d" is useless + +------------------------------------------------------------------------ +r495 | lh3 | 2008-09-11 09:22:03 -0400 (Thu, 11 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/simple_dp.c + M /branches/prog/bwa/stdaln.c + M /branches/prog/bwa/stdaln.h + +improve speed a little bit + +------------------------------------------------------------------------ +r494 | lh3 | 2008-09-11 08:28:08 -0400 (Thu, 11 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + +remove debug codes + +------------------------------------------------------------------------ +r493 | lh3 | 2008-09-11 07:49:53 -0400 (Thu, 11 Sep 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + + * improve the speed a little bit (<5%) + * prepare to remove BSW_DEBUG + +------------------------------------------------------------------------ +r492 | lh3 | 2008-09-11 06:15:56 -0400 (Thu, 11 Sep 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + + * bwa-0.2.0-9 + * support reverse strand + * fixed a bug that causes missing hits + +------------------------------------------------------------------------ +r491 | lh3 | 2008-09-11 05:46:16 -0400 (Thu, 11 Sep 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/main.c + + * bwa-0.2.0-8 + * better progress report + +------------------------------------------------------------------------ +r490 | lh3 | 2008-09-10 17:04:49 -0400 (Wed, 10 Sep 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + + * bwa-0.2.0-7 + * avoid some missing hits + * add maximum depth + +------------------------------------------------------------------------ +r489 | lh3 | 2008-09-10 11:51:13 -0400 (Wed, 10 Sep 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/main.c + + * bwa-0.2.0-6 + * bwtsw2 works although on the forward strand only for now + * better progress information + +------------------------------------------------------------------------ +r488 | lh3 | 2008-09-10 10:21:53 -0400 (Wed, 10 Sep 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + + * implement memory pool + * avoid some rehashing + +------------------------------------------------------------------------ +r487 | lh3 | 2008-09-10 09:23:38 -0400 (Wed, 10 Sep 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_main.c + + * fixed a memory leak + * prepare to implement mempool + +------------------------------------------------------------------------ +r486 | lh3 | 2008-09-10 09:10:09 -0400 (Wed, 10 Sep 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/khash.h + + * add X-dropoff + * remove duplicated results + * switch to simple stack + +------------------------------------------------------------------------ +r485 | lh3 | 2008-09-10 06:31:20 -0400 (Wed, 10 Sep 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/bwtsw2_main.c + + * check whether t-node has been visited + * prepare to remove two-level stack + +------------------------------------------------------------------------ +r484 | lh3 | 2008-09-10 05:00:57 -0400 (Wed, 10 Sep 2008) | 2 lines +Changed paths: + A /branches/prog/bwa/khash.h + +khash library + +------------------------------------------------------------------------ +r483 | lh3 | 2008-09-10 04:22:53 -0400 (Wed, 10 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + +add inline + +------------------------------------------------------------------------ +r482 | lh3 | 2008-09-09 16:34:57 -0400 (Tue, 09 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + +improve speed + +------------------------------------------------------------------------ +r481 | lh3 | 2008-09-09 13:13:00 -0400 (Tue, 09 Sep 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bwtsw2_core.c + +Use a 128bit hash table to keep all (tk,tl,qk,ql). This is slow. Just +keep a copy in case I may need this in future. + + +------------------------------------------------------------------------ +r480 | lh3 | 2008-09-09 12:53:32 -0400 (Tue, 09 Sep 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_core.c + + * no principal modification + +------------------------------------------------------------------------ +r479 | lh3 | 2008-09-09 11:01:45 -0400 (Tue, 09 Sep 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwtsw2_core.c + + * fixed a bug which may cause duplicated matching + * accelerate the speed a bit, although using hash in avoiding duplications + slows the speed down in the end + +------------------------------------------------------------------------ +r474 | lh3 | 2008-09-03 17:22:57 -0400 (Wed, 03 Sep 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwtsw2.h + M /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + + * bwa-0.2.0-5 + * indel seems to work on toy example + * add band + +------------------------------------------------------------------------ +r469 | lh3 | 2008-09-01 09:18:45 -0400 (Mon, 01 Sep 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwt_lite.c + M /branches/prog/bwa/bwt_lite.h + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/bwtsw2.h + A /branches/prog/bwa/bwtsw2_aux.c + M /branches/prog/bwa/bwtsw2_core.c + M /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/is.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/main.h + M /branches/prog/bwa/simple_dp.c + + * bwa-0.2.0-4 + * updated bwtsw2, which seems to work properly on toy examples + +------------------------------------------------------------------------ +r447 | lh3 | 2008-08-27 10:05:09 -0400 (Wed, 27 Aug 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/main.c + + * bwa-0.2.0-3 + * tune for longer gaps, but it does not really work with kilo-bp gaps... + +------------------------------------------------------------------------ +r446 | lh3 | 2008-08-26 13:30:41 -0400 (Tue, 26 Aug 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/main.c + + * bwa-0.2.0-2 + * changed the way to extend long deletions. Now use max_del_occ. + +------------------------------------------------------------------------ +r445 | lh3 | 2008-08-26 13:05:58 -0400 (Tue, 26 Aug 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwt_lite.c + M /branches/prog/bwa/bwt_lite.h + +updated from bwtsw2_lite + +------------------------------------------------------------------------ +r436 | lh3 | 2008-08-23 12:28:44 -0400 (Sat, 23 Aug 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwt.h + A /branches/prog/bwa/bwt_lite.c + A /branches/prog/bwa/bwt_lite.h + A /branches/prog/bwa/bwtsw2.h + A /branches/prog/bwa/bwtsw2_core.c + A /branches/prog/bwa/bwtsw2_main.c + M /branches/prog/bwa/main.c + + * bwa-0.2.0-1 + * add bwt_lite: a light-weighted version of bwt (NOT TESTED!) + * add core codes for bwtsw2: NOT TESTED!!! + +------------------------------------------------------------------------ +r427 | lh3 | 2008-08-15 05:38:12 -0400 (Fri, 15 Aug 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + +Release bwa-0.2.0 + +------------------------------------------------------------------------ +r426 | lh3 | 2008-08-14 11:26:19 -0400 (Thu, 14 Aug 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/main.c + + * bwa-0.1.6-7 + * change default seed length to 31 + * add incomplete support to color sequences (not tested yet!) + +------------------------------------------------------------------------ +r425 | lh3 | 2008-08-14 06:23:11 -0400 (Thu, 14 Aug 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + + * bwa-0.1.6-6 + * change default seed length to 33bp + +------------------------------------------------------------------------ +r424 | lh3 | 2008-08-14 05:55:33 -0400 (Thu, 14 Aug 2008) | 6 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/main.c + + * bwa-0.1.6-5 + * fixed a bug that may miss true alignments. this bugs exists in most + early versions. + * fixed a bug that yields wrong coordinates for reads mapped on the forward + strands with gaps. + +------------------------------------------------------------------------ +r423 | lh3 | 2008-08-14 04:07:28 -0400 (Thu, 14 Aug 2008) | 2 lines +Changed paths: + D /branches/prog/bwa/Makefile.div + +useless + +------------------------------------------------------------------------ +r422 | lh3 | 2008-08-13 19:21:14 -0400 (Wed, 13 Aug 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + + * bwa-0.1.6-4 + * fixed one bug + * there is another one... + +------------------------------------------------------------------------ +r421 | lh3 | 2008-08-13 18:23:33 -0400 (Wed, 13 Aug 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/bwtgap.h + M /branches/prog/bwa/bwtindex.c + M /branches/prog/bwa/main.c + + * bwa-0.1.6-3 + * almost there, but not quite right + +------------------------------------------------------------------------ +r419 | lh3 | 2008-08-13 17:27:02 -0400 (Wed, 13 Aug 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/bwtgap.h + M /branches/prog/bwa/main.c + + * improve the seeding method + * prepare to load two BWTs into memory. A BIG change! + +------------------------------------------------------------------------ +r418 | lh3 | 2008-08-13 10:56:54 -0400 (Wed, 13 Aug 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/bwtgap.h + M /branches/prog/bwa/main.c + + * added seeding + * unfinished yet + +------------------------------------------------------------------------ +r413 | lh3 | 2008-08-08 11:48:35 -0400 (Fri, 08 Aug 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/main.c + +Release bwa-0.1.6 + +------------------------------------------------------------------------ +r410 | lh3 | 2008-08-06 15:48:22 -0400 (Wed, 06 Aug 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/simple_dp.c + +sw: output alignment score + +------------------------------------------------------------------------ +r407 | lh3 | 2008-08-04 10:01:20 -0400 (Mon, 04 Aug 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/main.c + M /branches/prog/bwa/main.h + A /branches/prog/bwa/simple_dp.c + M /branches/prog/bwa/stdaln.c + M /branches/prog/bwa/stdaln.h + + * bwa-0.1.5-3 + * added a simple interface to SW/NW alignment + * stdaln-0.9.8 (see header for more details) + +------------------------------------------------------------------------ +r406 | lh3 | 2008-08-01 19:21:59 -0400 (Fri, 01 Aug 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/main.c + A /branches/prog/bwa/stdaln.c + A /branches/prog/bwa/stdaln.h + + * bwa-0.1.5-2 + * give accurate gap positions + +------------------------------------------------------------------------ +r405 | lh3 | 2008-08-01 19:06:19 -0400 (Fri, 01 Aug 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + +unfinished, but I am tired... + +------------------------------------------------------------------------ +r401 | lh3 | 2008-07-30 05:59:24 -0400 (Wed, 30 Jul 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bntseq.c + M /branches/prog/bwa/main.c + + * bwa-0.1.5-1 + * fixed a potential bug which may produce an alignment in N regions, + although extremely rare. + +------------------------------------------------------------------------ +r399 | lh3 | 2008-07-27 11:41:52 -0400 (Sun, 27 Jul 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/main.c + +Release bwa-0.1.5 + +------------------------------------------------------------------------ +r398 | lh3 | 2008-07-25 12:14:47 -0400 (Fri, 25 Jul 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + +update documentation + +------------------------------------------------------------------------ +r397 | lh3 | 2008-07-25 09:58:56 -0400 (Fri, 25 Jul 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + + * + +------------------------------------------------------------------------ +r396 | lh3 | 2008-07-25 06:42:01 -0400 (Fri, 25 Jul 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + + * bwa-0.1.4-4 + * add timer for debugging + +------------------------------------------------------------------------ +r395 | lh3 | 2008-07-24 05:46:21 -0400 (Thu, 24 Jul 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/main.c + + * bwa-0.1.4-3 + * fixed a bug in the previous code + * this version gives identical result to bwa-0.1.4, just 10% faster + +------------------------------------------------------------------------ +r394 | lh3 | 2008-07-24 05:18:53 -0400 (Thu, 24 Jul 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/bwtgap.h + M /branches/prog/bwa/main.c + + * bwa-0.1.4-2 + * further improve the speed + * The result is slightly different from bwa-0.1.4 now. I need to check... + +------------------------------------------------------------------------ +r393 | lh3 | 2008-07-23 12:04:16 -0400 (Wed, 23 Jul 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwt.c + +comments only + +------------------------------------------------------------------------ +r392 | lh3 | 2008-07-23 10:34:03 -0400 (Wed, 23 Jul 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/main.c + +further improve the speed in Occ functions + +------------------------------------------------------------------------ +r386 | lh3 | 2008-07-22 10:03:54 -0400 (Tue, 22 Jul 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/main.c + +Release bwa-0.1.4 + +------------------------------------------------------------------------ +r385 | lh3 | 2008-07-22 09:44:50 -0400 (Tue, 22 Jul 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/bwa.1 + +update documentation and ChangeLog + +------------------------------------------------------------------------ +r384 | lh3 | 2008-07-22 08:50:03 -0400 (Tue, 22 Jul 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/main.c + + * bwa-0.1.3-2 + * fixed the bug in the last modification + * now the alignment should be more clearly defined + +------------------------------------------------------------------------ +r383 | lh3 | 2008-07-21 18:32:21 -0400 (Mon, 21 Jul 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/main.c + + * bwa-0.1.3-1 + * this is a buggy verion! + * i will fix the bug tomorrow. It is late... + +------------------------------------------------------------------------ +r381 | lh3 | 2008-07-21 06:45:32 -0400 (Mon, 21 Jul 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/main.c + +Release bwa-0.1.3 + +------------------------------------------------------------------------ +r380 | lh3 | 2008-07-21 06:07:43 -0400 (Mon, 21 Jul 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/main.c + + * bwa-0.1.2-3 + * improve the speed for gcc on Intel Mac OS X, but not really on icc on Linux + * aln: more command-line options + +------------------------------------------------------------------------ +r373 | lh3 | 2008-07-17 09:09:46 -0400 (Thu, 17 Jul 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt.h + M /branches/prog/bwa/bwtio.c + M /branches/prog/bwa/main.c + + * bwa-0.1.2-2 + * further improve the speed + * this version gives exactly the same result as bwa-0.1.2 + +------------------------------------------------------------------------ +r372 | lh3 | 2008-07-17 07:51:08 -0400 (Thu, 17 Jul 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/main.c + + * bwa-0.1.2-1 + * speed up by about 5% + +------------------------------------------------------------------------ +r370 | lh3 | 2008-07-17 05:12:00 -0400 (Thu, 17 Jul 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/NEWS + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/main.c + +Release bwa-0.1.2 + +------------------------------------------------------------------------ +r368 | lh3 | 2008-07-16 08:51:25 -0400 (Wed, 16 Jul 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/Makefile + D /branches/prog/bwa/bwt1away.c + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/bwtgap.h + D /branches/prog/bwa/bwttop2.c + M /branches/prog/bwa/main.c + + * bwa-0.1.1-9 + * some code cleanup + * remove 1away and top2 + +------------------------------------------------------------------------ +r367 | lh3 | 2008-07-16 08:24:34 -0400 (Wed, 16 Jul 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/is.c + +Yuta Mori's implementation of IS algorithm. + +------------------------------------------------------------------------ +r365 | lh3 | 2008-07-16 06:58:04 -0400 (Wed, 16 Jul 2008) | 6 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/bwtgap.h + M /branches/prog/bwa/main.c + + * bwa-0.1.1-8 + * improve gapped alignment + * this version will miss more gapped alignments, but the speed is much faster + * prepare to remove top2 and 1away algorithms + * prepare to add SAIS algorithm for bwt construction + +------------------------------------------------------------------------ +r358 | lh3 | 2008-06-09 06:03:04 -0400 (Mon, 09 Jun 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/main.c + + * bwa-0.1.1-7 + * change END_SKIP from 3 to 5, but still gaps may be wrongly added + * change default '-g' from 5 to 3 + +------------------------------------------------------------------------ +r357 | lh3 | 2008-06-09 05:18:36 -0400 (Mon, 09 Jun 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bntseq.c + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/main.c + + * bwa-0.1.1-6 + * fix a bug in nested stack + +------------------------------------------------------------------------ +r356 | lh3 | 2008-06-08 18:43:13 -0400 (Sun, 08 Jun 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwtgap.c + A /branches/prog/bwa/bwtgap.h + M /branches/prog/bwa/main.c + + * bwa-0.1.1-5 + * replace heap with nested stacks + * there are still obvious bugs... + +------------------------------------------------------------------------ +r355 | lh3 | 2008-06-08 17:13:44 -0400 (Sun, 08 Jun 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/main.h + + * bwa-0.1.1-4 + * add interface to affine gap alignment + * there are obvious bugs and I will fix them later + +------------------------------------------------------------------------ +r354 | lh3 | 2008-06-08 15:39:05 -0400 (Sun, 08 Jun 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/main.c + + * bwa-0.1.1-3 + * affine gap seems to work, at least partially + +------------------------------------------------------------------------ +r353 | lh3 | 2008-06-08 09:27:18 -0400 (Sun, 08 Jun 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + A /branches/prog/bwa/bwtgap.c + M /branches/prog/bwa/bwttop2.c + M /branches/prog/bwa/main.c + + * bwa-0.1.1-2 + * initial gapped alignment. not work at the moment + +------------------------------------------------------------------------ +r352 | lh3 | 2008-06-06 04:37:34 -0400 (Fri, 06 Jun 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwttop2.c + M /branches/prog/bwa/main.c + + * bwa-0.1.1-1 + * ungap: remove a useless varible in top2_entry_t + +------------------------------------------------------------------------ +r348 | lh3 | 2008-06-03 09:04:12 -0400 (Tue, 03 Jun 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/ChangeLog + A /branches/prog/bwa/NEWS + M /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/main.c + +Release bwa-0.1.1 + +------------------------------------------------------------------------ +r347 | lh3 | 2008-06-03 05:45:08 -0400 (Tue, 03 Jun 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwa.1 + +update documentation + +------------------------------------------------------------------------ +r346 | lh3 | 2008-06-02 18:59:50 -0400 (Mon, 02 Jun 2008) | 5 lines +Changed paths: + A /branches/prog/bwa/ChangeLog + A /branches/prog/bwa/bwa.1 + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + + * bwa-0.1.0-11 + * improve approximating mapping qualities + * add documentation + * add ChangeLog + +------------------------------------------------------------------------ +r345 | lh3 | 2008-06-02 16:04:39 -0400 (Mon, 02 Jun 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwttop2.c + M /branches/prog/bwa/main.c + + * bwa-0.1.0-10 + * output a random position for repetitive reads + +------------------------------------------------------------------------ +r344 | lh3 | 2008-06-02 15:03:54 -0400 (Mon, 02 Jun 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bntseq.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/pac2bwt.c + + * bwa-0.1.0-9 + * fix memory leaks + * fix a potential bug in coverting to the real coordinate + +------------------------------------------------------------------------ +r343 | lh3 | 2008-06-02 13:44:51 -0400 (Mon, 02 Jun 2008) | 5 lines +Changed paths: + M /branches/prog/bwa/Makefile.div + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt.h + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwttop2.c + M /branches/prog/bwa/main.c + + * bwa-0.1.0-8 + * fix a bug about strand + * update Makefile.div + * change top2b as the default method + +------------------------------------------------------------------------ +r342 | lh3 | 2008-06-02 11:23:26 -0400 (Mon, 02 Jun 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt1away.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + + * bwa-0.1.0-7 + * use bwt_2occ() and bwt_2occ4() in other functions + +------------------------------------------------------------------------ +r341 | lh3 | 2008-06-02 09:31:39 -0400 (Mon, 02 Jun 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwttop2.c + M /branches/prog/bwa/main.c + + * bwa-0.1.0-6 + * fix a bug for missing hits + +------------------------------------------------------------------------ +r340 | lh3 | 2008-06-02 09:10:18 -0400 (Mon, 02 Jun 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwttop2.c + M /branches/prog/bwa/main.c + + * bwa-0.1.0-5 + * accelerate comparisons in heap, a bit + +------------------------------------------------------------------------ +r339 | lh3 | 2008-06-02 08:41:31 -0400 (Mon, 02 Jun 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt.h + M /branches/prog/bwa/bwttop2.c + M /branches/prog/bwa/main.c + + * bwa-0.1.0-4 + * avoid marginal repeated calculation in occ + +------------------------------------------------------------------------ +r338 | lh3 | 2008-06-02 06:46:51 -0400 (Mon, 02 Jun 2008) | 5 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwttop2.c + M /branches/prog/bwa/main.c + + * bwa-0.1.0-3 + * fix a bug caused by previours change + * fix a bug in heap + * order the heap by more criteria + +------------------------------------------------------------------------ +r337 | lh3 | 2008-06-01 19:11:15 -0400 (Sun, 01 Jun 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bwttop2.c + M /branches/prog/bwa/main.c + + * bwa-0.1.0-2 + * also sort sa range in heapsort, in attempt to improve cache performance. + Unfortunately, it does not work well at all. + +------------------------------------------------------------------------ +r336 | lh3 | 2008-06-01 17:45:23 -0400 (Sun, 01 Jun 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/Makefile.div + M /branches/prog/bwa/bntseq.c + M /branches/prog/bwa/main.c + + * 0.1.0-1 + * fix a bug in calculating the real coordinate + +------------------------------------------------------------------------ +r335 | lh3 | 2008-06-01 16:03:09 -0400 (Sun, 01 Jun 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/Makefile + +nothing, really + +------------------------------------------------------------------------ +r334 | lh3 | 2008-06-01 15:59:13 -0400 (Sun, 01 Jun 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/Makefile + A /branches/prog/bwa/Makefile.div + M /branches/prog/bwa/bwtindex.c + M /branches/prog/bwa/pac2bwt.c + +use IS algorithm by default + +------------------------------------------------------------------------ +r333 | lh3 | 2008-06-01 15:05:15 -0400 (Sun, 01 Jun 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwtindex.c + M /branches/prog/bwa/is.c + M /branches/prog/bwa/pac2bwt.c + + * a bit code clean up in is.c + * add IS algorithm for constructing BWT, albeit slower + +------------------------------------------------------------------------ +r332 | lh3 | 2008-06-01 13:23:08 -0400 (Sun, 01 Jun 2008) | 2 lines +Changed paths: + A /branches/prog/bwa/is.c + +IS linear-time algorithm for constructing SA/BWT + +------------------------------------------------------------------------ +r331 | lh3 | 2008-06-01 10:35:26 -0400 (Sun, 01 Jun 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bntseq.c + A /branches/prog/bwa/bwtindex.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/main.h + + * fix a bug in generating .pac + * index in one go + +------------------------------------------------------------------------ +r330 | lh3 | 2008-06-01 09:17:05 -0400 (Sun, 01 Jun 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bntseq.c + M /branches/prog/bwa/bntseq.h + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwttop2.c + +real coordinates can be ouput + +------------------------------------------------------------------------ +r329 | lh3 | 2008-05-31 19:21:02 -0400 (Sat, 31 May 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwttop2.c + +add top2e which is similar to 1away + +------------------------------------------------------------------------ +r328 | lh3 | 2008-05-31 18:46:12 -0400 (Sat, 31 May 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwttop2.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/main.h + + * unified cmd-line interface for ungapped alignment + * add two alternatives to top2 algorithm + +------------------------------------------------------------------------ +r327 | lh3 | 2008-05-31 18:14:46 -0400 (Sat, 31 May 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/main.c + M /branches/prog/bwa/main.h + +add cmd-line interface to alntop2 + +------------------------------------------------------------------------ +r326 | lh3 | 2008-05-31 17:59:31 -0400 (Sat, 31 May 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwt1away.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + A /branches/prog/bwa/bwttop2.c + +top2 algorithm seems to work. I need to change interface, though + +------------------------------------------------------------------------ +r325 | lh3 | 2008-05-31 15:11:49 -0400 (Sat, 31 May 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwt1away.c + +change the variable in the structure + +------------------------------------------------------------------------ +r324 | lh3 | 2008-05-31 14:52:13 -0400 (Sat, 31 May 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwt1away.c + +set a slightly better bound on the maximum allowed mismatches + +------------------------------------------------------------------------ +r323 | lh3 | 2008-05-30 18:40:21 -0400 (Fri, 30 May 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + + * output time statistics + +------------------------------------------------------------------------ +r322 | lh3 | 2008-05-30 17:58:25 -0400 (Fri, 30 May 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt.h + A /branches/prog/bwa/bwt1away.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + + * presumably better way to make use of prefix. But for the moment I do + not know whether it is correct or not. + * a bit code clean up: separate alignment part + +------------------------------------------------------------------------ +r321 | lh3 | 2008-05-30 13:57:43 -0400 (Fri, 30 May 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt.h + M /branches/prog/bwa/bwt_gen/Makefile + M /branches/prog/bwa/bwt_gen/bwt_gen.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/main.h + M /branches/prog/bwa/pac2bwt.c + + * a bit code clean up + * put bwt_gen in bwa + +------------------------------------------------------------------------ +r320 | lh3 | 2008-05-30 11:40:11 -0400 (Fri, 30 May 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwtio.c + + * improve cmd-line interface + * fix a bug in loading .sa + * change default sa interval to 32 + +------------------------------------------------------------------------ +r319 | lh3 | 2008-05-30 10:31:37 -0400 (Fri, 30 May 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwtaln.c + + * fix memory leak (I know that. Just a bit lazy) + * change to another method to do 1-away alignment + +------------------------------------------------------------------------ +r318 | lh3 | 2008-05-30 09:21:49 -0400 (Fri, 30 May 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt.h + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/main.c + M /branches/prog/bwa/main.h + +best unique match is partially finished + +------------------------------------------------------------------------ +r317 | lh3 | 2008-05-30 06:33:28 -0400 (Fri, 30 May 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/main.c + M /branches/prog/bwa/main.h + +remove "ungapped" command and related codes + +------------------------------------------------------------------------ +r316 | lh3 | 2008-05-30 06:05:20 -0400 (Fri, 30 May 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + +change variable name thick to width + +------------------------------------------------------------------------ +r315 | lh3 | 2008-05-29 19:06:13 -0400 (Thu, 29 May 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bntseq.c + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt.h + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwtio.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/main.h + M /branches/prog/bwa/pac2bwt.c + +revised algorithm for ungapped alignment. the old one can still be used. + +------------------------------------------------------------------------ +r314 | lh3 | 2008-05-29 16:36:11 -0400 (Thu, 29 May 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwt_gen/bwt_gen.c + M /branches/prog/bwa/bwtio.c + M /branches/prog/bwa/pac2bwt.c + + * make commands more independent, but ungapped does not work at the moment + +------------------------------------------------------------------------ +r313 | lh3 | 2008-05-29 15:56:14 -0400 (Thu, 29 May 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwt_gen/bwt_gen.c + +little... + +------------------------------------------------------------------------ +r312 | lh3 | 2008-05-29 15:54:01 -0400 (Thu, 29 May 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwt_gen/bwt_gen.c + M /branches/prog/bwa/bwt_gen/bwt_gen.h + + * add CopyRight information from the original codes + * do not dump .fmv files + +------------------------------------------------------------------------ +r311 | lh3 | 2008-05-29 15:44:36 -0400 (Thu, 29 May 2008) | 2 lines +Changed paths: + A /branches/prog/bwa/bwt_gen + A /branches/prog/bwa/bwt_gen/Makefile + A /branches/prog/bwa/bwt_gen/QSufSort.c + A /branches/prog/bwa/bwt_gen/QSufSort.h + A /branches/prog/bwa/bwt_gen/bwt_gen.c + A /branches/prog/bwa/bwt_gen/bwt_gen.h + +codes from BWT-SW, for building BWT from packed file + +------------------------------------------------------------------------ +r310 | lh3 | 2008-05-28 17:03:35 -0400 (Wed, 28 May 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt.h + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtio.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/main.h + + * change OCC_INTERVAL to 0x40, which makes bwa twice as fast. + * write Occ file as ".occ" as it is using a different interval from + .fmv, the BWT-SW correspondance of .occ + +------------------------------------------------------------------------ +r309 | lh3 | 2008-05-28 11:39:37 -0400 (Wed, 28 May 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt2fmv.c + +fix a bug + +------------------------------------------------------------------------ +r308 | lh3 | 2008-05-28 09:56:16 -0400 (Wed, 28 May 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt2fmv.c + +add heuristics to improve the speed, but I have not tested whether the +results are correct or not. + + +------------------------------------------------------------------------ +r307 | lh3 | 2008-05-28 06:31:34 -0400 (Wed, 28 May 2008) | 5 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/bwtaln.c + M /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/main.c + M /branches/prog/bwa/main.h + + * make ungapped alignment basically works... + * but it is very slow in comparison to others... + * also I need to improve the interface... + * a lot of things to keep me busy today... + +------------------------------------------------------------------------ +r306 | lh3 | 2008-05-27 18:41:27 -0400 (Tue, 27 May 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt.h + M /branches/prog/bwa/bwtaln.c + + * remove recursion + * fixed a bug in bwt_occ() + +------------------------------------------------------------------------ +r305 | lh3 | 2008-05-27 16:59:44 -0400 (Tue, 27 May 2008) | 5 lines +Changed paths: + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt.h + M /branches/prog/bwa/bwtaln.c + + * bwa now tells whether a sequenced can be mapped with maximum allowed + mismatches. ONLY ungapped. + * this is a recursive version. I will remove recursion later. + + +------------------------------------------------------------------------ +r304 | lh3 | 2008-05-27 09:12:17 -0400 (Tue, 27 May 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt.h + M /branches/prog/bwa/bwt2fmv.c + A /branches/prog/bwa/bwtaln.c + A /branches/prog/bwa/bwtaln.h + M /branches/prog/bwa/bwtio.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/main.h + M /branches/prog/bwa/utils.c + + * load .sa and .fmv files + * exact alignment now works + +------------------------------------------------------------------------ +r303 | lh3 | 2008-05-27 06:33:38 -0400 (Tue, 27 May 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/bntseq.c + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwtio.c + M /branches/prog/bwa/utils.c + M /branches/prog/bwa/utils.h + +add xassert and fix a bug + +------------------------------------------------------------------------ +r302 | lh3 | 2008-05-27 06:23:20 -0400 (Tue, 27 May 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bntseq.c + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwtio.c + A /branches/prog/bwa/utils.c + A /branches/prog/bwa/utils.h + +improve error message and error handling + +------------------------------------------------------------------------ +r301 | lh3 | 2008-05-27 05:37:51 -0400 (Tue, 27 May 2008) | 4 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt.h + M /branches/prog/bwa/bwt2fmv.c + A /branches/prog/bwa/bwtio.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/main.h + + * move I/O codes to bwtio.c + * SA can be dumped and interestingly, it is identical to BWTSW + * now, .fmv is still different from BWTSW + +------------------------------------------------------------------------ +r299 | lh3 | 2008-05-26 18:07:44 -0400 (Mon, 26 May 2008) | 2 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt.h + M /branches/prog/bwa/bwt2fmv.c + +generate/retrieve SA and Occ + +------------------------------------------------------------------------ +r298 | lh3 | 2008-05-26 13:16:49 -0400 (Mon, 26 May 2008) | 3 lines +Changed paths: + M /branches/prog/bwa/bntseq.h + M /branches/prog/bwa/bwt.c + M /branches/prog/bwa/bwt.h + M /branches/prog/bwa/bwt2fmv.c + + * retrieve occ value at any position + * move bwt_cal_occ() to bwt.c + +------------------------------------------------------------------------ +r297 | lh3 | 2008-05-25 17:43:58 -0400 (Sun, 25 May 2008) | 6 lines +Changed paths: + M /branches/prog/bwa/Makefile + A /branches/prog/bwa/bwt.c + A /branches/prog/bwa/bwt.h + A /branches/prog/bwa/bwt2fmv.c + M /branches/prog/bwa/main.c + M /branches/prog/bwa/main.h + M /branches/prog/bwa/pac2bwt.c + + * add bwt2fmv. It works to some extend. However, I do not understand + the purpose of some weird codes in BWT-SW. As a consequence, bwt2fmv + could generate a file almost identical, but not exactly identical, to + the .fmv file from BWT-SW. + + +------------------------------------------------------------------------ +r296 | lh3 | 2008-05-24 18:35:02 -0400 (Sat, 24 May 2008) | 5 lines +Changed paths: + M /branches/prog/bwa/Makefile + M /branches/prog/bwa/bntseq.c + M /branches/prog/bwa/bntseq.h + M /branches/prog/bwa/main.c + M /branches/prog/bwa/main.h + A /branches/prog/bwa/pac2bwt.c + +Burrows-Wheeler Transform now works. At least on one example, the +current code generates the same BWT as BWT-SW. Kind of magical, I would +say. :) + + +------------------------------------------------------------------------ +r295 | lh3 | 2008-05-24 11:25:31 -0400 (Sat, 24 May 2008) | 3 lines +Changed paths: + A /branches/prog/bwa/Makefile + M /branches/prog/bwa/bntseq.c + A /branches/prog/bwa/main.c + A /branches/prog/bwa/main.h + + * add Makefile and main.* + * improve interface to fa2bns, a bit + +------------------------------------------------------------------------ +r293 | lh3 | 2008-05-24 10:57:03 -0400 (Sat, 24 May 2008) | 3 lines +Changed paths: + A /branches/prog/bwa + A /branches/prog/bwa/bntseq.c + A /branches/prog/bwa/bntseq.h + A /branches/prog/bwa/seq.c + A /branches/prog/bwa/seq.h + + * Burrow-Wheeler Alignment + * initial codes + +------------------------------------------------------------------------
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/INSTALL Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,9 @@ +Simply type `make' to compile and copy the resulting executable `bwa' +anywhere you want. You may also like to copy `solid2fastq.pl' and +`qualfa2fq.pl' for format conversion. + +On 32-bit system, you should compile bwa with `make CFLAGS=-O2'. + +The GNU building system is also supported, which is necessary for +building Java binding. Nonetheless, directly runing `make' is +recommended in most other cases. \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/Makefile Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,55 @@ +CC= gcc +CXX= g++ +CFLAGS= -g -Wall -O2 -m64 +CXXFLAGS= $(CFLAGS) +DFLAGS= -DHAVE_PTHREAD #-D_FILE_OFFSET_BITS=64 +OBJS= utils.o bwt.o bwtio.o bwtaln.o bwtgap.o is.o \ + bntseq.o bwtmisc.o bwtindex.o stdaln.o simple_dp.o \ + bwaseqio.o bwase.o bwape.o kstring.o cs2nt.o \ + bwtsw2_core.o bwtsw2_main.o bwtsw2_aux.o bwt_lite.o \ + bwtsw2_chain.o +PROG= bwa +INCLUDES= +LIBS= -lm -lz -lpthread -Lbwt_gen -lbwtgen +SUBDIRS= . bwt_gen + +.SUFFIXES:.c .o .cc + +.c.o: + $(CC) -c $(CFLAGS) $(DFLAGS) $(INCLUDES) $< -o $@ +.cc.o: + $(CXX) -c $(CXXFLAGS) $(DFLAGS) $(INCLUDES) $< -o $@ + +all:$(PROG) + +lib-recur all-recur clean-recur cleanlocal-recur install-recur: + @target=`echo $@ | sed s/-recur//`; \ + wdir=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + cd $$subdir; \ + $(MAKE) CC="$(CC)" CXX="$(CXX)" DFLAGS="$(DFLAGS)" CFLAGS="$(CFLAGS)" \ + INCLUDES="$(INCLUDES)" $$target || exit 1; \ + cd $$wdir; \ + done; + +lib: + +bwa:lib-recur $(OBJS) main.o + $(CC) $(CFLAGS) $(DFLAGS) $(OBJS) main.o -o $@ $(LIBS) + +bwt.o:bwt.h +bwtio.o:bwt.h +bwtaln.o:bwt.h bwtaln.h kseq.h +bwt1away.o:bwt.h bwtaln.h +bwt2fmv.o:bwt.h +bntseq.o:bntseq.h +bwtgap.o:bwtgap.h bwtaln.h bwt.h + +bwtsw2_core.o:bwtsw2.h bwt.h bwt_lite.h stdaln.h +bwtsw2_aux.o:bwtsw2.h bwt.h bwt_lite.h stdaln.h +bwtsw2_main.o:bwtsw2.h + +cleanlocal: + rm -f gmon.out *.o a.out $(PROG) *~ *.a + +clean:cleanlocal-recur
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/Makefile.am Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,13 @@ +## Makefile.am -- Process this file with automake to produce Makefile.in +ACLOCAL_AMFLAGS=-I m4 +AM_CFLAGS = -Wall -m64 -fPIC +bin_PROGRAMS = bwa +noinst_LIBRARIES = libbwacore.a +libbwacore_a_SOURCES = utils.c bwt.c bwtio.c bwtaln.c bwtgap.c bntseq.c \ + stdaln.c bwaseqio.c bwase.c kstring.c cs2nt.c +bwa_SOURCES = is.c bwtmisc.c bwtindex.c simple_dp.c bwape.c \ + bwtsw2_core.c bwtsw2_main.c bwtsw2_aux.c bwt_lite.c bwtsw2_chain.c \ + main.c +bwa_LDADD = bwt_gen/libbwtgen.a libbwacore.a +man_MANS= bwa.1 +SUBDIRS= bwt_gen .
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/NEWS Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,469 @@ +Beta Release 0.5.7 (1 March, 2010) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This release only has an effect on paired-end data with fat insert-size +distribution. Users are still recommended to update as the new release +improves the robustness to poor data. + + * The fix for `weird pairing' was not working in version 0.5.6, pointed + out by Carol Scott. It should work now. + + * Optionally output to a normal file rather than to stdout (by Tim + Fennel). + +(0.5.7: 1 March 2010, r1310) + + + +Beta Release 0.5.6 (10 Feburary, 2010) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Notable changes in bwa-short: + + * Report multiple hits in the SAM format at a new tag XA encoded as: + (chr,pos,CIGAR,NM;)*. By default, if a paired or single-end read has + 4 or fewer hits, they will all be reported; if a read in a anomalous + pair has 11 or fewer hits, all of them will be reported. + + * Perform Smith-Waterman alignment also for anomalous read pairs when + both ends have quality higher than 17. This reduces false positives + for some SV discovery algorithms. + + * Do not report "weird pairing" when the insert size distribution is + too fat or has a mean close to zero. + + * If a read is bridging two adjacent chromsomes, flag it as unmapped. + + * Fixed a small but long existing memory leak in paired-end mapping. + + * Multiple bug fixes in SOLiD mapping: a) quality "-1" can be correctly + parsed by solid2fastq.pl; b) truncated quality string is resolved; c) + SOLiD read mapped to the reverse strand is complemented. + + * Bwa now calculates skewness and kurtosis of the insert size + distribution. + + * Deploy a Bayesian method to estimate the maximum distance for a read + pair considered to be paired properly. The method is proposed by + Gerton Lunter, but bwa only implements a simplified version. + + * Export more functions for Java bindings, by Matt Hanna (See: + http://www.broadinstitute.org/gsa/wiki/index.php/Sting_BWA/C_bindings) + + * Abstract bwa CIGAR for further extension, by Rodrigo Goya. + +(0.5.6: 10 Feburary 2010, r1303) + + + +Beta Release 0.5.5 (10 November, 2009) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is a bug fix release: + + * Fixed a serious bug/typo in aln which does not occur given short + reads, but will lead to segfault for >500bp reads. Of course, the aln + command is not recommended for reads longer than 200bp, but this is a + bug anyway. + + * Fixed a minor bug/typo which leads to incorrect single-end mapping + quality when one end is moved to meet the mate-pair requirement. + + * Fixed a bug in samse for mapping in the color space. This bug is + caused by quality filtration added since 0.5.1. + +(0.5.5: 10 November 2009, r1273) + + + +Beta Release 0.5.4 (9 October, 2009) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Since this version, the default seed length used in the "aln" command is +changed to 32. + +Notable changes in bwa-short: + + * Added a new tag "XC:i" which gives the length of clipped reads. + + * In sampe, skip alignments in case of a bug in the Smith-Waterman + alignment module. + + * In sampe, fixed a bug in pairing when the read sequence is identical + to its reverse complement. + + * In sampe, optionally preload the entire FM-index into memory to + reduce disk operations. + +Notable changes in dBWT-SW/BWA-SW: + + * Changed name dBWT-SW to BWA-SW. + + * Optionally use "hard clipping" in the SAM output. + +(0.5.4: 9 October 2009, r1245) + + + +Beta Release 0.5.3 (15 September, 2009) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Fixed a critical bug in bwa-short: reads mapped to the reverse strand +are not complemented. + +(0.5.3: 15 September 2009, r1225) + + + +Beta Release 0.5.2 (13 September, 2009) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Notable changes in bwa-short: + + * Optionally trim reads before alignment. See the manual page on `aln + -q' for detailed description. + + * Fixed a bug in calculating the NM tag for a gapped alignment. + + * Fixed a bug given a mixture of reads with some longer than the seed + length and some shorter. + + * Print SAM header. + +Notable changes in dBWT-SW: + + * Changed the default value of -T to 30. As a result, the accuracy is a + little higher for short reads at the cost of speed. + +(0.5.2: 13 September 2009, r1223) + + + +Beta Release 0.5.1 (2 September, 2009) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Notable changes in the short read alignment component: + + * Fixed a bug in samse: do not write mate coordinates. + +Notable changes in dBWT-SW: + + * Randomly choose one alignment if the read is a repetitive. + + * Fixed a flaw when a read is mapped across two adjacent reference + sequences. However, wrong alignment reports may still occur rarely in + this case. + + * Changed the default band width to 50. The speed is slower due to this + change. + + * Improved the mapping quality a little given long query sequences. + +(0.5.1: 2 September 2009, r1209) + + + +Beta Release 0.5.0 (20 August, 2009) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This release implements a novel algorithm, dBWT-SW, specifically +designed for long reads. It is 10-50 times faster than SSAHA2, depending +on the characteristics of the input data, and achieves comparable +alignment accuracy while allowing chimera detection. In comparison to +BLAT, dBWT-SW is several times faster and much more accurate especially +when the error rate is high. Please read the manual page for more +information. + +The dBWT-SW algorithm is kind of developed for future sequencing +technologies which produce much longer reads with a little higher error +rate. It is still at its early development stage. Some features are +missing and it may be buggy although I have evaluated on several +simulated and real data sets. But following the "release early" +paradigm, I would like the users to try it first. + +Other notable changes in BWA are: + + * Fixed a rare bug in the Smith-Waterman alignment module. + + * Fixed a rare bug about the wrong alignment coordinate when a read is + poorly aligned. + + * Fixed a bug in generating the "mate-unmap" SAM tag when both ends in + a pair are unmapped. + +(0.5.0: 20 August 2009, r1200) + + + +Beta Release 0.4.9 (19 May, 2009) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Interestingly, the integer overflow bug claimed to be fixed in 0.4.7 has +not in fact. Now I have fixed the bug. Sorry for this and thank Quan +Long for pointing out the bug (again). + +(0.4.9: 19 May 2009, r1075) + + + +Beta Release 0.4.8 (18 May, 2009) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +One change to "aln -R". Now by default, if there are no more than `-R' +equally best hits, bwa will search for suboptimal hits. This change +affects the ability in finding SNPs in segmental duplications. + +I have not tested this option thoroughly, but this simple change is less +likely to cause new bugs. Hope I am right. + +(0.4.8: 18 May 2009, r1073) + + + +Beta Release 0.4.7 (12 May, 2009) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Notable changes: + + * Output SM (single-end mapping quality) and AM (smaller mapping + quality among the two ends) tag from sam output. + + * Improved the functionality of stdsw. + + * Made the XN tag more accurate. + + * Fixed a very rare segfault caused by integer overflow. + + * Improve the insert size estimation. + + * Fixed compiling errors for some Linux systems. + +(0.4.7: 12 May 2009, r1066) + + + +Beta Release 0.4.6 (9 March, 2009) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This release improves the SOLiD support. First, a script for converting +SOLiD raw data is provided. This script is adapted from solid2fastq.pl +in the MAQ package. Second, a nucleotide reference file can be directly +used with `bwa index'. Third, SOLiD paired-end support is +completed. Fourth, color-space reads will be converted to nucleotides +when SAM output is generated. Color errors are corrected in this +process. Please note that like MAQ, BWA cannot make use of the primer +base and the first color. + +In addition, the calculation of mapping quality is also improved a +little bit, although end-users may barely observe the difference. + +(0.4.6: 9 March 2009, r915) + + + +Beta Release 0.4.5 (18 Feburary, 2009) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Not much happened, but I think it would be good to let the users use the +latest version. + +Notable changes (Thank Bob Handsaker for catching the two bugs): + + * Improved bounary check. Previous version may still give incorrect + alignment coordinates in rare cases. + + * Fixed a bug in SW alignment when no residue matches. This only + affects the `sampe' command. + + * Robustly estimate insert size without setting the maximum on the + command line. Since this release `sampe -a' only has an effect if + there are not enough good pairs to infer the insert size + distribution. + + * Reduced false PE alignments a little bit by using the inferred insert + size distribution. This fix may be more important for long insert + size libraries. + +(0.4.5: 18 Feburary 2009, r829) + + + +Beta Release 0.4.4 (15 Feburary, 2009) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is mainly a bug fix release. Notable changes are: + + * Imposed boundary check for extracting subsequence from the + genome. Previously this causes memory problem in rare cases. + + * Fixed a bug in failing to find whether an alignment overlapping with + N on the genome. + + * Changed MD tag to meet the latest SAM specification. + +(0.4.4: 15 Feburary 2009, r815) + + + +Beta Release 0.4.3 (22 January, 2009) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Notable changes: + + * Treat an ambiguous base N as a mismatch. Previous versions will not + map reads containing any N. + + * Automatically choose the maximum allowed number of differences. This + is important when reads of different lengths are mixed together. + + * Print mate coordinate if only one end is unmapped. + + * Generate MD tag. This tag encodes the mismatching positions and the + reference bases at these positions. Deletions from the reference will + also be printed. + + * Optionally dump multiple hits from samse, in another concise format + rather than SAM. + + * Optionally disable iterative search. This is VERY SLOOOOW, though. + + * Fixed a bug in generate SAM. + +(0.4.3: 22 January 2009, r787) + + + +Beta Release 0.4.2 (9 January, 2009) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Aaron Quinlan found a bug in the indexer: the bwa indexer segfaults if +there are no comment texts in the FASTA header. This is a critical +bug. Nothing else was changed. + +(0.4.2: 9 January 2009, r769) + + + +Beta Release 0.4.1 (7 January, 2009) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +I am sorry for the quick updates these days. I like to set a milestone +for BWA and this release seems to be. For paired end reads, BWA also +does Smith-Waterman alignment for an unmapped read whose mate can be +mapped confidently. With this strategy BWA achieves similar accuracy to +maq. Benchmark is also updated accordingly. + +(0.4.1: 7 January 2009, r760) + + + +Beta Release 0.4.0 (6 January, 2009) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In comparison to the release two days ago, this release is mainly tuned +for performance with some tricks I learnt from Bowtie. However, as the +indexing format has also been changed, I have to increase the version +number to 0.4.0 to emphasize that *DATABASE MUST BE RE-INDEXED* with +`bwa index'. + + * Improved the speed by about 20%. + + * Added multi-threading to `bwa aln'. + +(0.4.0: 6 January 2009, r756) + + + +Beta Release 0.3.0 (4 January, 2009) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + * Added paired-end support by separating SA calculation and alignment + output. + + * Added SAM output. + + * Added evaluation to the documentation. + +(0.3.0: 4 January 2009, r741) + + + +Beta Release 0.2.0 (15 Augusst, 2008) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + * Take the subsequence at the 5'-end as seed. Seeding strategy greatly + improves the speed for long reads, at the cost of missing a few true + hits that contain many differences in the seed. Seeding also increase + the memory by 800MB. + + * Fixed a bug which may miss some gapped alignments. Fixing the bug + also slows the speed a little. + +(0.2.0: 15 August 2008, r428) + + + +Beta Release 0.1.6 (08 Augusst, 2008) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + * Give accurate CIGAR string. + + * Add a simple interface to SW/NW alignment + +(0.1.6: 08 August 2008, r414) + + + +Beta Release 0.1.5 (27 July, 2008) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + * Improve the speed. This version is expected to give the same results. + +(0.1.5: 27 July 2008, r400) + + + +Beta Release 0.1.4 (22 July, 2008) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + * Fixed a bug which may cause missing gapped alignments. + + * More clearly define what alignments can be found by BWA (See + manual). Now BWA runs a little slower because it will visit more + potential gapped alignments. + + * A bit code clean up. + +(0.1.4: 22 July 2008, r387) + + + +Beta Release 0.1.3 (21 July, 2008) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Improve the speed with some tricks on retrieving occurences. The results +should be exactly the same as that of 0.1.2. + +(0.1.3: 21 July 2008, r382) + + + +Beta Release 0.1.2 (17 July, 2008) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Support gapped alignment. Codes for ungapped alignment has been removed. + +(0.1.2: 17 July 2008, r371) + + + +Beta Release 0.1.1 (03 June, 2008) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is the first release of BWA, Burrows-Wheeler Alignment tool. Please +read man page for more information about this software. + +(0.1.1: 03 June 2008, r349) + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/autogen.sh Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,2 @@ +#!/bin/sh +autoreconf -vi
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bntseq.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,303 @@ +/* The MIT License + + Copyright (c) 2008 Genome Research Ltd (GRL). + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* Contact: Heng Li <lh3@sanger.ac.uk> */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <zlib.h> +#include "bntseq.h" +#include "main.h" +#include "utils.h" + +#include "kseq.h" +KSEQ_INIT(gzFile, gzread) + +unsigned char nst_nt4_table[256] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5 /*'-'*/, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 0, 4, 1, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 0, 4, 1, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 +}; + +void bns_dump(const bntseq_t *bns, const char *prefix) +{ + char str[1024]; + FILE *fp; + int i; + { // dump .ann + strcpy(str, prefix); strcat(str, ".ann"); + fp = xopen(str, "w"); + fprintf(fp, "%lld %d %u\n", (long long)bns->l_pac, bns->n_seqs, bns->seed); + for (i = 0; i != bns->n_seqs; ++i) { + bntann1_t *p = bns->anns + i; + fprintf(fp, "%d %s", p->gi, p->name); + if (p->anno[0]) fprintf(fp, " %s\n", p->anno); + else fprintf(fp, "\n"); + fprintf(fp, "%lld %d %d\n", (long long)p->offset, p->len, p->n_ambs); + } + fclose(fp); + } + { // dump .amb + strcpy(str, prefix); strcat(str, ".amb"); + fp = xopen(str, "w"); + fprintf(fp, "%lld %d %u\n", (long long)bns->l_pac, bns->n_seqs, bns->n_holes); + for (i = 0; i != bns->n_holes; ++i) { + bntamb1_t *p = bns->ambs + i; + fprintf(fp, "%lld %d %c\n", (long long)p->offset, p->len, p->amb); + } + fclose(fp); + } +} + +bntseq_t *bns_restore_core(const char *ann_filename, const char* amb_filename, const char* pac_filename) +{ + char str[1024]; + FILE *fp; + bntseq_t *bns; + long long xx; + int i; + bns = (bntseq_t*)calloc(1, sizeof(bntseq_t)); + { // read .ann + fp = xopen(ann_filename, "r"); + fscanf(fp, "%lld%d%u", &xx, &bns->n_seqs, &bns->seed); + bns->l_pac = xx; + bns->anns = (bntann1_t*)calloc(bns->n_seqs, sizeof(bntann1_t)); + for (i = 0; i < bns->n_seqs; ++i) { + bntann1_t *p = bns->anns + i; + char *q = str; + int c; + // read gi and sequence name + fscanf(fp, "%u%s", &p->gi, str); + p->name = strdup(str); + // read fasta comments + while ((c = fgetc(fp)) != '\n' && c != EOF) *q++ = c; + *q = 0; + if (q - str > 1) p->anno = strdup(str + 1); // skip leading space + else p->anno = strdup(""); + // read the rest + fscanf(fp, "%lld%d%d", &xx, &p->len, &p->n_ambs); + p->offset = xx; + } + fclose(fp); + } + { // read .amb + int64_t l_pac; + int32_t n_seqs; + fp = xopen(amb_filename, "r"); + fscanf(fp, "%lld%d%d", &xx, &n_seqs, &bns->n_holes); + l_pac = xx; + xassert(l_pac == bns->l_pac && n_seqs == bns->n_seqs, "inconsistent .ann and .amb files."); + bns->ambs = (bntamb1_t*)calloc(bns->n_holes, sizeof(bntamb1_t)); + for (i = 0; i < bns->n_holes; ++i) { + bntamb1_t *p = bns->ambs + i; + fscanf(fp, "%lld%d%s", &xx, &p->len, str); + p->offset = xx; + p->amb = str[0]; + } + fclose(fp); + } + { // open .pac + bns->fp_pac = xopen(pac_filename, "rb"); + } + return bns; +} + +bntseq_t *bns_restore(const char *prefix) +{ + char ann_filename[1024], amb_filename[1024], pac_filename[1024]; + strcat(strcpy(ann_filename, prefix), ".ann"); + strcat(strcpy(amb_filename, prefix), ".amb"); + strcat(strcpy(pac_filename, prefix), ".pac"); + return bns_restore_core(ann_filename, amb_filename, pac_filename); +} + +void bns_destroy(bntseq_t *bns) +{ + if (bns == 0) return; + else { + int i; + if (bns->fp_pac) fclose(bns->fp_pac); + free(bns->ambs); + for (i = 0; i < bns->n_seqs; ++i) { + free(bns->anns[i].name); + free(bns->anns[i].anno); + } + free(bns->anns); + free(bns); + } +} + +void bns_fasta2bntseq(gzFile fp_fa, const char *prefix) +{ + kseq_t *seq; + char name[1024]; + bntseq_t *bns; + bntamb1_t *q; + int l_buf; + unsigned char buf[0x10000]; + int32_t m_seqs, m_holes, l, i; + FILE *fp; + + // initialization + seq = kseq_init(fp_fa); + bns = (bntseq_t*)calloc(1, sizeof(bntseq_t)); + bns->seed = 11; // fixed seed for random generator + srand48(bns->seed); + m_seqs = m_holes = 8; + bns->anns = (bntann1_t*)calloc(m_seqs, sizeof(bntann1_t)); + bns->ambs = (bntamb1_t*)calloc(m_holes, sizeof(bntamb1_t)); + q = bns->ambs; + l_buf = 0; + strcpy(name, prefix); strcat(name, ".pac"); + fp = xopen(name, "wb"); + memset(buf, 0, 0x10000); + // read sequences + while ((l = kseq_read(seq)) >= 0) { + bntann1_t *p; + int lasts; + if (bns->n_seqs == m_seqs) { + m_seqs <<= 1; + bns->anns = (bntann1_t*)realloc(bns->anns, m_seqs * sizeof(bntann1_t)); + } + p = bns->anns + bns->n_seqs; + p->name = strdup((char*)seq->name.s); + p->anno = seq->comment.s? strdup((char*)seq->comment.s) : strdup("(null)"); + p->gi = 0; p->len = l; + p->offset = (bns->n_seqs == 0)? 0 : (p-1)->offset + (p-1)->len; + p->n_ambs = 0; + for (i = 0, lasts = 0; i < l; ++i) { + int c = nst_nt4_table[(int)seq->seq.s[i]]; + if (c >= 4) { // N + if (lasts == seq->seq.s[i]) { // contiguous N + ++q->len; + } else { + if (bns->n_holes == m_holes) { + m_holes <<= 1; + bns->ambs = (bntamb1_t*)realloc(bns->ambs, m_holes * sizeof(bntamb1_t)); + } + q = bns->ambs + bns->n_holes; + q->len = 1; + q->offset = p->offset + i; + q->amb = seq->seq.s[i]; + ++p->n_ambs; + ++bns->n_holes; + } + } + lasts = seq->seq.s[i]; + { // fill buffer + if (c >= 4) c = lrand48()&0x3; + if (l_buf == 0x40000) { + fwrite(buf, 1, 0x10000, fp); + memset(buf, 0, 0x10000); + l_buf = 0; + } + buf[l_buf>>2] |= c << ((3 - (l_buf&3)) << 1); + ++l_buf; + } + } + ++bns->n_seqs; + bns->l_pac += seq->seq.l; + } + xassert(bns->l_pac, "zero length sequence."); + { // finalize .pac file + ubyte_t ct; + fwrite(buf, 1, (l_buf>>2) + ((l_buf&3) == 0? 0 : 1), fp); + // the following codes make the pac file size always (l_pac/4+1+1) + if (bns->l_pac % 4 == 0) { + ct = 0; + fwrite(&ct, 1, 1, fp); + } + ct = bns->l_pac % 4; + fwrite(&ct, 1, 1, fp); + // close .pac file + fclose(fp); + } + bns_dump(bns, prefix); + bns_destroy(bns); + kseq_destroy(seq); +} + +int bwa_fa2pac(int argc, char *argv[]) +{ + gzFile fp; + if (argc < 2) { + fprintf(stderr, "Usage: bwa fa2pac <in.fasta> [<out.prefix>]\n"); + return 1; + } + fp = xzopen(argv[1], "r"); + bns_fasta2bntseq(fp, (argc < 3)? argv[1] : argv[2]); + gzclose(fp); + return 0; +} + +int bns_coor_pac2real(const bntseq_t *bns, int64_t pac_coor, int len, int32_t *real_seq) +{ + int left, mid, right, nn; + if (pac_coor >= bns->l_pac) + err_fatal("bns_coor_pac2real", "bug! Coordinate is longer than sequence (%lld>=%lld).", pac_coor, bns->l_pac); + // binary search for the sequence ID. Note that this is a bit different from the following one... + left = 0; mid = 0; right = bns->n_seqs; + while (left < right) { + mid = (left + right) >> 1; + if (pac_coor >= bns->anns[mid].offset) { + if (mid == bns->n_seqs - 1) break; + if (pac_coor < bns->anns[mid+1].offset) break; + left = mid + 1; + } else right = mid; + } + *real_seq = mid; + // binary search for holes + left = 0; right = bns->n_holes; nn = 0; + while (left < right) { + int64_t mid = (left + right) >> 1; + if (pac_coor >= bns->ambs[mid].offset + bns->ambs[mid].len) left = mid + 1; + else if (pac_coor + len <= bns->ambs[mid].offset) right = mid; + else { // overlap + if (pac_coor >= bns->ambs[mid].offset) { + nn += bns->ambs[mid].offset + bns->ambs[mid].len < pac_coor + len? + bns->ambs[mid].offset + bns->ambs[mid].len - pac_coor : len; + } else { + nn += bns->ambs[mid].offset + bns->ambs[mid].len < pac_coor + len? + bns->ambs[mid].len : len - (bns->ambs[mid].offset - pac_coor); + } + break; + } + } + return nn; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bntseq.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,80 @@ +/* The MIT License + + Copyright (c) 2008 Genome Research Ltd (GRL). + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* Contact: Heng Li <lh3@sanger.ac.uk> */ + +#ifndef BWT_BNTSEQ_H +#define BWT_BNTSEQ_H + +#include <stdint.h> +#include <zlib.h> + +#ifndef BWA_UBYTE +#define BWA_UBYTE +typedef uint8_t ubyte_t; +#endif + +typedef struct { + int64_t offset; + int32_t len; + int32_t n_ambs; + uint32_t gi; + char *name, *anno; +} bntann1_t; + +typedef struct { + int64_t offset; + int32_t len; + char amb; +} bntamb1_t; + +typedef struct { + int64_t l_pac; + int32_t n_seqs; + uint32_t seed; + bntann1_t *anns; // n_seqs elements + int32_t n_holes; + bntamb1_t *ambs; // n_holes elements + FILE *fp_pac; +} bntseq_t; + +extern unsigned char nst_nt4_table[256]; + +#ifdef __cplusplus +extern "C" { +#endif + + void bns_dump(const bntseq_t *bns, const char *prefix); + bntseq_t *bns_restore(const char *prefix); + bntseq_t *bns_restore_core(const char *ann_filename, const char* amb_filename, const char* pac_filename); + void bns_destroy(bntseq_t *bns); + void bns_fasta2bntseq(gzFile fp_fa, const char *prefix); + int bns_coor_pac2real(const bntseq_t *bns, int64_t pac_coor, int len, int32_t *real_seq); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwa.1 Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,514 @@ +.TH bwa 1 "10 Feburuary 2010" "bwa-0.5.6" "Bioinformatics tools" +.SH NAME +.PP +bwa - Burrows-Wheeler Alignment Tool +.SH SYNOPSIS +.PP +bwa index -a bwtsw database.fasta +.PP +bwa aln database.fasta short_read.fastq > aln_sa.sai +.PP +bwa samse database.fasta aln_sa.sai short_read.fastq > aln.sam +.PP +bwa sampe database.fasta aln_sa1.sai aln_sa2.sai read1.fq read2.fq > aln.sam +.PP +bwa bwasw database.fasta long_read.fastq > aln.sam + +.SH DESCRIPTION +.PP +BWA is a fast light-weighted tool that aligns relatively short sequences +(queries) to a sequence database (targe), such as the human reference +genome. It implements two different algorithms, both based on +Burrows-Wheeler Transform (BWT). The first algorithm is designed for +short queries up to ~200bp with low error rate (<3%). It does gapped +global alignment w.r.t. queries, supports paired-end reads, and is one +of the fastest short read alignment algorithms to date while also +visiting suboptimal hits. The second algorithm, BWA-SW, is designed for +long reads with more errors. It performs heuristic Smith-Waterman-like +alignment to find high-scoring local hits (and thus chimera). On +low-error short queries, BWA-SW is slower and less accurate than the +first algorithm, but on long queries, it is better. +.PP +For both algorithms, the database file in the FASTA format must be +first indexed with the +.B `index' +command, which typically takes a few hours. The first algorithm is +implemented via the +.B `aln' +command, which finds the suffix array (SA) coordinates of good hits of +each individual read, and the +.B `samse/sampe' +command, which converts SA coordinates to chromosomal coordinate and +pairs reads (for `sampe'). The second algorithm is invoked by the +.B `dbtwsw' +command. It works for single-end reads only. + +.SH COMMANDS AND OPTIONS +.TP +.B index +bwa index [-p prefix] [-a algoType] [-c] <in.db.fasta> + +Index database sequences in the FASTA format. + +.B OPTIONS: +.RS +.TP 10 +.B -c +Build color-space index. The input fast should be in nucleotide space. +.TP +.B -p STR +Prefix of the output database [same as db filename] +.TP +.B -a STR +Algorithm for constructing BWT index. Available options are: +.RS +.TP +.B is +IS linear-time algorithm for constructing suffix array. It requires +5.37N memory where N is the size of the database. IS is moderately fast, +but does not work with database larger than 2GB. IS is the default +algorithm due to its simplicity. The current codes for IS algorithm are +reimplemented by Yuta Mori. +.TP +.B bwtsw +Algorithm implemented in BWT-SW. This method works with the whole human +genome, but it does not work with database smaller than 10MB and it is +usually slower than IS. +.RE +.RE + +.TP +.B aln +bwa aln [-n maxDiff] [-o maxGapO] [-e maxGapE] [-d nDelTail] [-i +nIndelEnd] [-k maxSeedDiff] [-l seedLen] [-t nThrds] [-cRN] [-M misMsc] +[-O gapOsc] [-E gapEsc] [-q trimQual] <in.db.fasta> <in.query.fq> > +<out.sai> + +Find the SA coordinates of the input reads. Maximum +.I maxSeedDiff +differences are allowed in the first +.I seedLen +subsequence and maximum +.I maxDiff +differences are allowed in the whole sequence. + +.B OPTIONS: +.RS +.TP 10 +.B -n NUM +Maximum edit distance if the value is INT, or the fraction of missing +alignments given 2% uniform base error rate if FLOAT. In the latter +case, the maximum edit distance is automatically chosen for different +read lengths. [0.04] +.TP +.B -o INT +Maximum number of gap opens [1] +.TP +.B -e INT +Maximum number of gap extensions, -1 for k-difference mode (disallowing +long gaps) [-1] +.TP +.B -d INT +Disallow a long deletion within INT bp towards the 3'-end [16] +.TP +.B -i INT +Disallow an indel within INT bp towards the ends [5] +.TP +.B -l INT +Take the first INT subsequence as seed. If INT is larger than the query +sequence, seeding will be disabled. For long reads, this option is +typically ranged from 25 to 35 for `-k 2'. [inf] +.TP +.B -k INT +Maximum edit distance in the seed [2] +.TP +.B -t INT +Number of threads (multi-threading mode) [1] +.TP +.B -M INT +Mismatch penalty. BWA will not search for suboptimal hits with a score +lower than (bestScore-misMsc). [3] +.TP +.B -O INT +Gap open penalty [11] +.TP +.B -E INT +Gap extension penalty [4] +.TP +.B -R INT +Proceed with suboptimal alignments if there are no more than INT equally +best hits. This option only affects paired-end mapping. Increasing this +threshold helps to improve the pairing accuracy at the cost of speed, +especially for short reads (~32bp). +.TP +.B -c +Reverse query but not complement it, which is required for alignment in +the color space. +.TP +.B -N +Disable iterative search. All hits with no more than +.I maxDiff +differences will be found. This mode is much slower than the default. +.TP +.B -q INT +Parameter for read trimming. BWA trims a read down to +argmax_x{\\sum_{i=x+1}^l(INT-q_i)} if q_l<INT where l is the original +read length. [0] +.RE + +.TP +.B samse +bwa samse [-n maxOcc] <in.db.fasta> <in.sai> <in.fq> > <out.sam> + +Generate alignments in the SAM format given single-end reads. Repetitive +hits will be randomly chosen. + +.B OPTIONS: +.RS +.TP 10 +.B -n INT +Maximum number of alignments to output in the XA tag for reads paired +properly. If a read has more than INT hits, the XA tag will not be +written. [3] +.RE + +.TP +.B sampe +bwa sampe [-a maxInsSize] [-o maxOcc] [-n maxHitPaired] [-N maxHitDis] +[-P] <in.db.fasta> <in1.sai> <in2.sai> <in1.fq> <in2.fq> > <out.sam> + +Generate alignments in the SAM format given paired-end reads. Repetitive +read pairs will be placed randomly. + +.B OPTIONS: +.RS +.TP 8 +.B -a INT +Maximum insert size for a read pair to be considered being mapped +properly. Since 0.4.5, this option is only used when there are not +enough good alignment to infer the distribution of insert sizes. [500] +.TP +.B -o INT +Maximum occurrences of a read for pairing. A read with more occurrneces +will be treated as a single-end read. Reducing this parameter helps +faster pairing. [100000] +.TP +.B -P +Load the entire FM-index into memory to reduce disk operations +(base-space reads only). With this option, at least 1.25N bytes of +memory are required, where N is the length of the genome. +.TP +.B -n INT +Maximum number of alignments to output in the XA tag for reads paired +properly. If a read has more than INT hits, the XA tag will not be +written. [3] +.TP +.B -N INT +Maximum number of alignments to output in the XA tag for disconcordant +read pairs (excluding singletons). If a read has more than INT hits, the +XA tag will not be written. [10] +.RE + +.TP +.B bwasw +bwa bwasw [-a matchScore] [-b mmPen] [-q gapOpenPen] [-r gapExtPen] [-t +nThreads] [-w bandWidth] [-T thres] [-s hspIntv] [-z zBest] [-N +nHspRev] [-c thresCoef] <in.db.fasta> <in.fq> + +Align query sequences in the <in.fq> file. + +.B OPTIONS: +.RS +.TP 10 +.B -a INT +Score of a match [1] +.TP +.B -b INT +Mismatch penalty [3] +.TP +.B -q INT +Gap open penalty [5] +.TP +.B -r INT +Gap extension penalty. The penalty for a contiguous gap of size k is +q+k*r. [2] +.TP +.B -t INT +Number of threads in the multi-threading mode [1] +.TP +.B -w INT +Band width in the banded alignment [33] +.TP +.B -T INT +Minimum score threshold divided by a [37] +.TP +.B -c FLOAT +Coefficient for threshold adjustment according to query length. Given an +l-long query, the threshold for a hit to be retained is +a*max{T,c*log(l)}. [5.5] +.TP +.B -z INT +Z-best heuristics. Higher -z increases accuracy at the cost of speed. [1] +.TP +.B -s INT +Maximum SA interval size for initiating a seed. Higher -s increases +accuracy at the cost of speed. [3] +.TP +.B -N INT +Minimum number of seeds supporting the resultant alignment to skip +reverse alignment. [5] +.RE + +.SH SAM ALIGNMENT FORMAT +.PP +The output of the +.B `aln' +command is binary and designed for BWA use only. BWA outputs the final +alignment in the SAM (Sequence Alignment/Map) format. Each line consists +of: + +.TS +center box; +cb | cb | cb +n | l | l . +Col Field Description +_ +1 QNAME Query (pair) NAME +2 FLAG bitwise FLAG +3 RNAME Reference sequence NAME +4 POS 1-based leftmost POSition/coordinate of clipped sequence +5 MAPQ MAPping Quality (Phred-scaled) +6 CIAGR extended CIGAR string +7 MRNM Mate Reference sequence NaMe (`=' if same as RNAME) +8 MPOS 1-based Mate POSistion +9 ISIZE Inferred insert SIZE +10 SEQ query SEQuence on the same strand as the reference +11 QUAL query QUALity (ASCII-33 gives the Phred base quality) +12 OPT variable OPTional fields in the format TAG:VTYPE:VALUE +.TE + +.PP +Each bit in the FLAG field is defined as: + +.TS +center box; +cb | cb | cb +c | l | l . +Chr Flag Description +_ +p 0x0001 the read is paired in sequencing +P 0x0002 the read is mapped in a proper pair +u 0x0004 the query sequence itself is unmapped +U 0x0008 the mate is unmapped +r 0x0010 strand of the query (1 for reverse) +R 0x0020 strand of the mate +1 0x0040 the read is the first read in a pair +2 0x0080 the read is the second read in a pair +s 0x0100 the alignment is not primary +f 0x0200 QC failure +d 0x0400 optical or PCR duplicate +.TE + +.PP +The Please check <http://samtools.sourceforge.net> for the format +specification and the tools for post-processing the alignment. + +BWA generates the following optional fields. Tags starting with `X' are +specific to BWA. + +.TS +center box; +cb | cb +cB | l . +Tag Meaning +_ +NM Edit distance +MD Mismatching positions/bases +AS Alignment score +_ +X0 Number of best hits +X1 Number of suboptimal hits found by BWA +XN Number of ambiguous bases in the referenece +XM Number of mismatches in the alignment +XO Number of gap opens +XG Number of gap extentions +XT Type: Unique/Repeat/N/Mate-sw +XA Alternative hits; format: (chr,pos,CIGAR,NM;)* +_ +XS Suboptimal alignment score +XF Support from forward/reverse alignment +XE Number of supporting seeds +.TE + +.PP +Note that XO and XG are generated by BWT search while the CIGAR string +by Smith-Waterman alignment. These two tags may be inconsistent with the +CIGAR string. This is not a bug. + +.SH NOTES ON SHORT-READ ALIGNMENT +.SS Alignment Accuracy +.PP +When seeding is disabled, BWA guarantees to find an alignment +containing maximum +.I maxDiff +differences including +.I maxGapO +gap opens which do not occur within +.I nIndelEnd +bp towards either end of the query. Longer gaps may be found if +.I maxGapE +is positive, but it is not guaranteed to find all hits. When seeding is +enabled, BWA further requires that the first +.I seedLen +subsequence contains no more than +.I maxSeedDiff +differences. +.PP +When gapped alignment is disabled, BWA is expected to generate the same +alignment as Eland, the Illumina alignment program. However, as BWA +change `N' in the database sequence to random nucleotides, hits to these +random sequences will also be counted. As a consequence, BWA may mark a +unique hit as a repeat, if the random sequences happen to be identical +to the sequences which should be unqiue in the database. This random +behaviour will be avoided in future releases. +.PP +By default, if the best hit is no so repetitive (controlled by -R), BWA +also finds all hits contains one more mismatch; otherwise, BWA finds all +equally best hits only. Base quality is NOT considered in evaluating +hits. In paired-end alignment, BWA pairs all hits it found. It further +performs Smith-Waterman alignment for unmapped reads with mates mapped +to rescue mapped mates, and for high-quality anomalous pairs to fix +potential alignment errors. + +.SS Estimating Insert Size Distribution +.PP +BWA estimates the insert size distribution per 256*1024 read pairs. It +first collects pairs of reads with both ends mapped with a single-end +quality 20 or higher and then calculates median (Q2), lower and higher +quartile (Q1 and Q3). It estimates the mean and the variance of the +insert size distribution from pairs whose insert sizes are within +interval [Q1-2(Q3-Q1), Q3+2(Q3-Q1)]. The maximum distance x for a pair +considered to be properly paired (SAM flag 0x2) is calculated by solving +equation Phi((x-mu)/sigma)=x/L*p0, where mu is the mean, sigma is the +standard error of the insert size distribution, L is the length of the +genome, p0 is prior of anomalous pair and Phi() is the standard +cumulative distribution function. For mapping Illumina short-insert +reads to the human genome, x is about 6-7 sigma away from the +mean. Quartiles, mean, variance and x will be printed to the standard +error output. + +.SS Memory Requirement +.PP +With bwtsw algorithm, 2.5GB memory is required for indexing the complete +human genome sequences. For short reads, the +.B `aln' +command uses ~2.3GB memory and the +.B `sampe' +command uses ~3.5GB. + +.SS Speed +.PP +Indexing the human genome sequences takes 3 hours with bwtsw +algorithm. Indexing smaller genomes with IS or divsufsort algorithms is +several times faster, but requires more memory. +.PP +Speed of alignment is largely determined by the error rate of the query +sequences (r). Firstly, BWA runs much faster for near perfect hits than +for hits with many differences, and it stops searching for a hit with +l+2 differences if a l-difference hit is found. This means BWA will be +very slow if r is high because in this case BWA has to visit hits with +many differences and looking for these hits is expensive. Secondly, the +alignment algorithm behind makes the speed sensitive to [k log(N)/m], +where k is the maximum allowed differences, N the size of database and m +the length of a query. In practice, we choose k w.r.t. r and therefore r +is the leading factor. I would not recommend to use BWA on data with +r>0.02. +.PP +Pairing is slower for shorter reads. This is mainly because shorter +reads have more spurious hits and converting SA coordinates to +chromosomal coordinates are very costly. +.PP +In a practical experiment, BWA is able to map 2 million 32bp reads to a +bacterial genome in several minutes, map the same amount of reads to +human X chromosome in 8-15 minutes and to the human genome in 15-25 +minutes. This result implies that the speed of BWA is insensitive to the +size of database and therefore BWA is more efficient when the database +is sufficiently large. On smaller genomes, hash based algorithms are +usually much faster. + +.SH NOTES ON LONG-READ ALIGNMENT +.PP +Command +.B `bwasw' +is designed for long-read alignment. The algorithm behind, BWA-SW, is +similar to BWT-SW, but does not guarantee to find all local hits due to +the heuristic acceleration. It tends to be faster and more accurate if +the resultant alignment is supported by more seeds, and therefore +BWA-SW usually performs better on long queries than on short ones. + +On 350-1000bp reads, BWA-SW is several to tens of times faster than the +existing programs. Its accuracy is comparable to SSAHA2, more accurate +than BLAT. Like BLAT, BWA-SW also finds chimera which may pose a +challenge to SSAHA2. On 10-100kbp queries where chimera detection is +important, BWA-SW is over 10X faster than BLAT while being more +sensitive. + +BWA-SW can also be used to align ~100bp reads, but it is slower than +the short-read algorithm. Its sensitivity and accuracy is lower than +SSAHA2 especially when the sequencing error rate is above 2%. This is +the trade-off of the 30X speed up in comparison to SSAHA2's -454 mode. + +.SH SEE ALSO +BWA website <http://bio-bwa.sourceforge.net>, Samtools website +<http://samtools.sourceforge.net> + +.SH AUTHOR +Heng Li at the Sanger Institute wrote the key source codes and +integrated the following codes for BWT construction: bwtsw +<http://i.cs.hku.hk/~ckwong3/bwtsw/>, implemented by Chi-Kwong Wong at +the University of Hong Kong and IS +<http://yuta.256.googlepages.com/sais> originally proposed by Nong Ge +<http://www.cs.sysu.edu.cn/nong/> at the Sun Yat-Sen University and +implemented by Yuta Mori. + +.SH LICENSE AND CITATION +.PP +The full BWA package is distributed under GPLv3 as it uses source codes +from BWT-SW which is covered by GPL. Sorting, hash table, BWT and IS +libraries are distributed under the MIT license. +.PP +If you use the short-read alignment component, please cite the following +paper: +.PP +Li H. and Durbin R. (2009) Fast and accurate short read alignment with +Burrows-Wheeler transform. Bioinformatics, 25, 1754-60. [PMID: 19451168] +.PP +If you use the long-read component (BWA-SW), please cite: +.PP +Li H. and Durbin R. (2010) Fast and accurate long-read alignment with +Burrows-Wheeler transform. Bioinformatics. [PMID: 20080505] + +.SH HISTORY +BWA is largely influenced by BWT-SW. It uses source codes from BWT-SW +and mimics its binary file formats; BWA-SW resembles BWT-SW in several +ways. The initial idea about BWT-based alignment also came from the +group who developed BWT-SW. At the same time, BWA is different enough +from BWT-SW. The short-read alignment algorithm bears no similarity to +Smith-Waterman algorithm any more. While BWA-SW learns from BWT-SW, it +introduces heuristics that can hardly be applied to the original +algorithm. In all, BWA does not guarantee to find all local hits as what +BWT-SW is designed to do, but it is much faster than BWT-SW on both +short and long query sequences. + +I started to write the first piece of codes on 24 May 2008 and got the +initial stable version on 02 June 2008. During this period, I was +acquainted that Professor Tak-Wah Lam, the first author of BWT-SW paper, +was collaborating with Beijing Genomics Institute on SOAP2, the successor +to SOAP (Short Oligonucleotide Analysis Package). SOAP2 has come out in +November 2008. According to the SourceForge download page, the third +BWT-based short read aligner, bowtie, was first released in August +2008. At the time of writing this manual, at least three more BWT-based +short-read aligners are being implemented. + +The BWA-SW algorithm is a new component of BWA. It was conceived in +November 2008 and implemented ten months later.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwape.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,747 @@ +#include <unistd.h> +#include <math.h> +#include <stdlib.h> +#include <time.h> +#include <stdio.h> +#include <string.h> +#include "bwtaln.h" +#include "kvec.h" +#include "bntseq.h" +#include "utils.h" +#include "stdaln.h" + +typedef struct { + int n; + bwtint_t *a; +} poslist_t; + +typedef struct { + double avg, std; + bwtint_t low, high, high_bayesian; +} isize_info_t; + +#include "khash.h" +KHASH_MAP_INIT_INT64(64, poslist_t) + +#include "ksort.h" +KSORT_INIT_GENERIC(uint64_t) + +typedef struct { + kvec_t(uint64_t) arr; + kvec_t(uint64_t) pos[2]; + kvec_t(bwt_aln1_t) aln[2]; +} pe_data_t; + +#define MIN_HASH_WIDTH 1000 + +static int g_log_n[256]; +static kh_64_t *g_hash; + +void bwa_aln2seq_core(int n_aln, const bwt_aln1_t *aln, bwa_seq_t *s, int set_main, int n_multi); +void bwa_aln2seq(int n_aln, const bwt_aln1_t *aln, bwa_seq_t *s); +void bwa_refine_gapped(const bntseq_t *bns, int n_seqs, bwa_seq_t *seqs, ubyte_t *_pacseq, bntseq_t *ntbns); +int bwa_approx_mapQ(const bwa_seq_t *p, int mm); +void bwa_print_sam1(const bntseq_t *bns, bwa_seq_t *p, const bwa_seq_t *mate, int mode, int max_top2); +bntseq_t *bwa_open_nt(const char *prefix); +void bwa_print_sam_SQ(const bntseq_t *bns); + +pe_opt_t *bwa_init_pe_opt() +{ + pe_opt_t *po; + po = (pe_opt_t*)calloc(1, sizeof(pe_opt_t)); + po->max_isize = 500; + po->max_occ = 100000; + po->n_multi = 3; + po->N_multi = 10; + po->type = BWA_PET_STD; + po->is_sw = 1; + po->ap_prior = 1e-5; + return po; +} + +static inline uint64_t hash_64(uint64_t key) +{ + key += ~(key << 32); + key ^= (key >> 22); + key += ~(key << 13); + key ^= (key >> 8); + key += (key << 3); + key ^= (key >> 15); + key += ~(key << 27); + key ^= (key >> 31); + return key; +} +/* +static double ierfc(double x) // inverse erfc(); iphi(x) = M_SQRT2 *ierfc(2 * x); +{ + const double a = 0.140012; + double b, c; + b = log(x * (2 - x)); + c = 2./M_PI/a + b / 2.; + return sqrt(sqrt(c * c - b / a) - c); +} +*/ + +// for normal distribution, this is about 3std +#define OUTLIER_BOUND 2.0 + +static int infer_isize(int n_seqs, bwa_seq_t *seqs[2], isize_info_t *ii, double ap_prior, int64_t L) +{ + uint64_t x, *isizes; + int n, i, tot, p25, p75, p50, max_len = 1, tmp; + double skewness = 0.0, kurtosis = 0.0, y; + + ii->avg = ii->std = -1.0; + ii->low = ii->high = ii->high_bayesian = 0; + isizes = (uint64_t*)calloc(n_seqs, 8); + for (i = 0, tot = 0; i != n_seqs; ++i) { + bwa_seq_t *p[2]; + p[0] = seqs[0] + i; p[1] = seqs[1] + i; + if (p[0]->mapQ >= 20 && p[1]->mapQ >= 20) + isizes[tot++] = (p[0]->pos < p[1]->pos)? p[1]->pos + p[1]->len - p[0]->pos : p[0]->pos + p[0]->len - p[1]->pos; + if (p[0]->len > max_len) max_len = p[0]->len; + if (p[1]->len > max_len) max_len = p[1]->len; + } + if (tot < 20) { + fprintf(stderr, "[infer_isize] fail to infer insert size: too few good pairs\n"); + free(isizes); + return -1; + } + ks_introsort(uint64_t, tot, isizes); + p25 = isizes[(int)(tot*0.25 + 0.5)]; + p50 = isizes[(int)(tot*0.50 + 0.5)]; + p75 = isizes[(int)(tot*0.75 + 0.5)]; + tmp = (int)(p25 - OUTLIER_BOUND * (p75 - p25) + .499); + ii->low = tmp > max_len? tmp : max_len; // ii->low is unsigned + ii->high = (int)(p75 + OUTLIER_BOUND * (p75 - p25) + .499); + for (i = 0, x = n = 0; i < tot; ++i) + if (isizes[i] >= ii->low && isizes[i] <= ii->high) + ++n, x += isizes[i]; + ii->avg = (double)x / n; + for (i = 0; i < tot; ++i) { + if (isizes[i] >= ii->low && isizes[i] <= ii->high) { + double tmp = (isizes[i] - ii->avg) * (isizes[i] - ii->avg); + ii->std += tmp; + skewness += tmp * (isizes[i] - ii->avg); + kurtosis += tmp * tmp; + } + } + kurtosis = kurtosis/n / (ii->std / n * ii->std / n) - 3; + ii->std = sqrt(ii->std / n); // it would be better as n-1, but n is usually very large + skewness = skewness / n / (ii->std * ii->std * ii->std); + free(isizes); + if (isnan(ii->std)) { + ii->low = ii->high = 0; ii->avg = ii->std = -1.0; + fprintf(stderr, "[infer_isize] fail to infer insert size: weird pairing\n"); + return -1; + } + for (y = 1.0; y < 10.0; y += 0.01) + if (.5 * erfc(y / M_SQRT2) < ap_prior / L * (y * ii->std + ii->avg)) break; + ii->high_bayesian = (bwtint_t)(y * ii->std + ii->avg + .499); + fprintf(stderr, "[infer_isize] (25, 50, 75) percentile: (%d, %d, %d)\n", p25, p50, p75); + fprintf(stderr, "[infer_isize] low and high boundaries: %d and %d for estimating avg and std\n", ii->low, ii->high); + fprintf(stderr, "[infer_isize] inferred external isize from %d pairs: %.3lf +/- %.3lf\n", n, ii->avg, ii->std); + fprintf(stderr, "[infer_isize] skewness: %.3lf; kurtosis: %.3lf\n", skewness, kurtosis); + fprintf(stderr, "[infer_isize] inferred maximum insert size: %d (%.2lf sigma)\n", ii->high_bayesian, y); + return 0; +} + +static int pairing(bwa_seq_t *p[2], pe_data_t *d, const pe_opt_t *opt, int s_mm, const isize_info_t *ii) +{ + int i, j, o_n, subo_n, cnt_chg = 0, low_bound = ii->low, max_len; + uint64_t last_pos[2][2], o_pos[2], subo_score, o_score; + max_len = p[0]->full_len; + if (max_len < p[1]->full_len) max_len = p[1]->full_len; + if (low_bound < max_len) low_bound = max_len; + + // here v>=u. When ii is set, we check insert size with ii; otherwise with opt->max_isize +#define __pairing_aux(u,v) do { \ + bwtint_t l = ((v)>>32) + p[(v)&1]->len - ((u)>>32); \ + if ((u) != (uint64_t)-1 && (v)>>32 > (u)>>32 && l >= max_len \ + && ((ii->high && l <= ii->high_bayesian) || (ii->high == 0 && l <= opt->max_isize))) \ + { \ + uint64_t s = d->aln[(v)&1].a[(uint32_t)(v)>>1].score + d->aln[(u)&1].a[(uint32_t)(u)>>1].score; \ + s *= 10; \ + if (ii->high) s += (int)(-4.343 * log(.5 * erfc(M_SQRT1_2 * fabs(l - ii->avg) / ii->std)) + .499); \ + s = s<<32 | (uint32_t)hash_64((u)>>32<<32 | (v)>>32); \ + if (s>>32 == o_score>>32) ++o_n; \ + else if (s>>32 < o_score>>32) { subo_n += o_n; o_n = 1; } \ + else ++subo_n; \ + if (s < o_score) subo_score = o_score, o_score = s, o_pos[(u)&1] = (u), o_pos[(v)&1] = (v); \ + else if (s < subo_score) subo_score = s; \ + } \ + } while (0) + +#define __pairing_aux2(q, w) do { \ + const bwt_aln1_t *r = d->aln[(w)&1].a + ((uint32_t)(w)>>1); \ + (q)->extra_flag |= SAM_FPP; \ + if ((q)->pos != (w)>>32 || (q)->strand != r->a) { \ + (q)->n_mm = r->n_mm; (q)->n_gapo = r->n_gapo; (q)->n_gape = r->n_gape; (q)->strand = r->a; \ + (q)->score = r->score; (q)->mapQ = mapQ_p; \ + (q)->pos = (w)>>32; \ + if ((q)->mapQ > 0) ++cnt_chg; \ + } \ + } while (0) + + o_score = subo_score = (uint64_t)-1; + o_n = subo_n = 0; + ks_introsort(uint64_t, d->arr.n, d->arr.a); + for (j = 0; j < 2; ++j) last_pos[j][0] = last_pos[j][1] = (uint64_t)-1; + if (opt->type == BWA_PET_STD) { + for (i = 0; i < d->arr.n; ++i) { + uint64_t x = d->arr.a[i]; + int strand = d->aln[x&1].a[(uint32_t)x>>1].a; + if (strand == 1) { // reverse strand, then check + int y = 1 - (x&1); + __pairing_aux(last_pos[y][1], x); + __pairing_aux(last_pos[y][0], x); + } else { // forward strand, then push + last_pos[x&1][0] = last_pos[x&1][1]; + last_pos[x&1][1] = x; + } + } + } else if (opt->type == BWA_PET_SOLID) { + for (i = 0; i < d->arr.n; ++i) { + uint64_t x = d->arr.a[i]; + int strand = d->aln[x&1].a[(uint32_t)x>>1].a; + if ((strand^x)&1) { // push + int y = 1 - (x&1); + __pairing_aux(last_pos[y][1], x); + __pairing_aux(last_pos[y][0], x); + } else { // check + last_pos[x&1][0] = last_pos[x&1][1]; + last_pos[x&1][1] = x; + } + } + } else { + fprintf(stderr, "[paring] not implemented yet!\n"); + exit(1); + } + // set pairing + //fprintf(stderr, "[%d, %d, %d, %d]\n", d->arr.n, (int)(o_score>>32), (int)(subo_score>>32), o_n); + if (o_score != (uint64_t)-1) { + int mapQ_p = 0; // this is the maximum mapping quality when one end is moved + //fprintf(stderr, "%d, %d\n", o_n, subo_n); + if (o_n == 1) { + if (subo_score == (uint64_t)-1) mapQ_p = 29; // no sub-optimal pair + else if ((subo_score>>32) - (o_score>>32) > s_mm * 10) mapQ_p = 23; // poor sub-optimal pair + else { + int n = subo_n > 255? 255 : subo_n; + mapQ_p = ((subo_score>>32) - (o_score>>32)) / 2 - g_log_n[n]; + if (mapQ_p < 0) mapQ_p = 0; + } + } + if (p[0]->pos == o_pos[0]>>32 && p[1]->pos == o_pos[1]>>32) { // both ends not moved + if (p[0]->mapQ > 0 && p[1]->mapQ > 0) { + int mapQ = p[0]->mapQ + p[1]->mapQ; + if (mapQ > 60) mapQ = 60; + p[0]->mapQ = p[1]->mapQ = mapQ; + } else { + if (p[0]->mapQ == 0) p[0]->mapQ = (mapQ_p + 7 < p[1]->mapQ)? mapQ_p + 7 : p[1]->mapQ; + if (p[1]->mapQ == 0) p[1]->mapQ = (mapQ_p + 7 < p[0]->mapQ)? mapQ_p + 7 : p[0]->mapQ; + } + } else if (p[0]->pos == o_pos[0]>>32) { // [1] moved + p[1]->seQ = 0; p[1]->mapQ = p[0]->mapQ; + if (p[1]->mapQ > mapQ_p) p[1]->mapQ = mapQ_p; + } else if (p[1]->pos == o_pos[1]>>32) { // [0] moved + p[0]->seQ = 0; p[0]->mapQ = p[1]->mapQ; + if (p[0]->mapQ > mapQ_p) p[0]->mapQ = mapQ_p; + } else { // both ends moved + p[0]->seQ = p[1]->seQ = 0; + mapQ_p -= 20; + if (mapQ_p < 0) mapQ_p = 0; + p[0]->mapQ = p[1]->mapQ = mapQ_p; + } + __pairing_aux2(p[0], o_pos[0]); + __pairing_aux2(p[1], o_pos[1]); + } + return cnt_chg; +} + +typedef struct { + kvec_t(bwt_aln1_t) aln; +} aln_buf_t; + +int bwa_cal_pac_pos_pe(const char *prefix, bwt_t *const _bwt[2], int n_seqs, bwa_seq_t *seqs[2], FILE *fp_sa[2], isize_info_t *ii, + const pe_opt_t *opt, const gap_opt_t *gopt, const isize_info_t *last_ii) +{ + int i, j, cnt_chg = 0; + char str[1024]; + bwt_t *bwt[2]; + pe_data_t *d; + aln_buf_t *buf[2]; + + d = (pe_data_t*)calloc(1, sizeof(pe_data_t)); + buf[0] = (aln_buf_t*)calloc(n_seqs, sizeof(aln_buf_t)); + buf[1] = (aln_buf_t*)calloc(n_seqs, sizeof(aln_buf_t)); + + if (_bwt[0] == 0) { // load forward SA + strcpy(str, prefix); strcat(str, ".bwt"); bwt[0] = bwt_restore_bwt(str); + strcpy(str, prefix); strcat(str, ".sa"); bwt_restore_sa(str, bwt[0]); + strcpy(str, prefix); strcat(str, ".rbwt"); bwt[1] = bwt_restore_bwt(str); + strcpy(str, prefix); strcat(str, ".rsa"); bwt_restore_sa(str, bwt[1]); + } else bwt[0] = _bwt[0], bwt[1] = _bwt[1]; + + // SE + for (i = 0; i != n_seqs; ++i) { + bwa_seq_t *p[2]; + for (j = 0; j < 2; ++j) { + int n_aln; + p[j] = seqs[j] + i; + p[j]->n_multi = 0; + p[j]->extra_flag |= SAM_FPD | (j == 0? SAM_FR1 : SAM_FR2); + fread(&n_aln, 4, 1, fp_sa[j]); + if (n_aln > kv_max(d->aln[j])) + kv_resize(bwt_aln1_t, d->aln[j], n_aln); + d->aln[j].n = n_aln; + fread(d->aln[j].a, sizeof(bwt_aln1_t), n_aln, fp_sa[j]); + kv_copy(bwt_aln1_t, buf[j][i].aln, d->aln[j]); // backup d->aln[j] + // generate SE alignment and mapping quality + bwa_aln2seq(n_aln, d->aln[j].a, p[j]); + if (p[j]->type == BWA_TYPE_UNIQUE || p[j]->type == BWA_TYPE_REPEAT) { + int max_diff = gopt->fnr > 0.0? bwa_cal_maxdiff(p[j]->len, BWA_AVG_ERR, gopt->fnr) : gopt->max_diff; + p[j]->pos = p[j]->strand? bwt_sa(bwt[0], p[j]->sa) + : bwt[1]->seq_len - (bwt_sa(bwt[1], p[j]->sa) + p[j]->len); + p[j]->seQ = p[j]->mapQ = bwa_approx_mapQ(p[j], max_diff); + } + } + } + + // infer isize + infer_isize(n_seqs, seqs, ii, opt->ap_prior, bwt[0]->seq_len); + if (ii->avg < 0.0 && last_ii->avg > 0.0) *ii = *last_ii; + + // PE + for (i = 0; i != n_seqs; ++i) { + bwa_seq_t *p[2]; + for (j = 0; j < 2; ++j) { + p[j] = seqs[j] + i; + kv_copy(bwt_aln1_t, d->aln[j], buf[j][i].aln); + } + if ((p[0]->type == BWA_TYPE_UNIQUE || p[0]->type == BWA_TYPE_REPEAT) + && (p[1]->type == BWA_TYPE_UNIQUE || p[1]->type == BWA_TYPE_REPEAT)) + { // only when both ends mapped + uint64_t x; + int j, k, n_occ[2]; + for (j = 0; j < 2; ++j) { + n_occ[j] = 0; + for (k = 0; k < d->aln[j].n; ++k) + n_occ[j] += d->aln[j].a[k].l - d->aln[j].a[k].k + 1; + } + if (n_occ[0] > opt->max_occ || n_occ[1] > opt->max_occ) continue; + d->arr.n = 0; + for (j = 0; j < 2; ++j) { + for (k = 0; k < d->aln[j].n; ++k) { + bwt_aln1_t *r = d->aln[j].a + k; + bwtint_t l; + if (r->l - r->k + 1 >= MIN_HASH_WIDTH) { // then check hash table + uint64_t key = (uint64_t)r->k<<32 | r->l; + int ret; + khint_t iter = kh_put(64, g_hash, key, &ret); + if (ret) { // not in the hash table; ret must equal 1 as we never remove elements + poslist_t *z = &kh_val(g_hash, iter); + z->n = r->l - r->k + 1; + z->a = (bwtint_t*)malloc(sizeof(bwtint_t) * z->n); + for (l = r->k; l <= r->l; ++l) + z->a[l - r->k] = r->a? bwt_sa(bwt[0], l) : bwt[1]->seq_len - (bwt_sa(bwt[1], l) + p[j]->len); + } + for (l = 0; l < kh_val(g_hash, iter).n; ++l) { + x = kh_val(g_hash, iter).a[l]; + x = x<<32 | k<<1 | j; + kv_push(uint64_t, d->arr, x); + } + } else { // then calculate on the fly + for (l = r->k; l <= r->l; ++l) { + x = r->a? bwt_sa(bwt[0], l) : bwt[1]->seq_len - (bwt_sa(bwt[1], l) + p[j]->len); + x = x<<32 | k<<1 | j; + kv_push(uint64_t, d->arr, x); + } + } + } + } + cnt_chg += pairing(p, d, opt, gopt->s_mm, ii); + } + + if (opt->N_multi || opt->n_multi) { + for (j = 0; j < 2; ++j) { + if (p[j]->type != BWA_TYPE_NO_MATCH) { + int k; + if (!(p[j]->extra_flag&SAM_FPP) && p[1-j]->type != BWA_TYPE_NO_MATCH) { + bwa_aln2seq_core(d->aln[j].n, d->aln[j].a, p[j], 0, p[j]->c1+p[j]->c2-1 > opt->N_multi? opt->n_multi : opt->N_multi); + } else bwa_aln2seq_core(d->aln[j].n, d->aln[j].a, p[j], 0, opt->n_multi); + for (k = 0; k < p[j]->n_multi; ++k) { + bwt_multi1_t *q = p[j]->multi + k; + q->pos = q->strand? bwt_sa(bwt[0], q->pos) : bwt[1]->seq_len - (bwt_sa(bwt[1], q->pos) + p[j]->len); + } + } + } + } + } + + // free + for (i = 0; i < n_seqs; ++i) { + kv_destroy(buf[0][i].aln); + kv_destroy(buf[1][i].aln); + } + free(buf[0]); free(buf[1]); + if (_bwt[0] == 0) { + bwt_destroy(bwt[0]); bwt_destroy(bwt[1]); + } + kv_destroy(d->arr); + kv_destroy(d->pos[0]); kv_destroy(d->pos[1]); + kv_destroy(d->aln[0]); kv_destroy(d->aln[1]); + free(d); + return cnt_chg; +} + +#define SW_MIN_MATCH_LEN 20 +#define SW_MIN_MAPQ 17 + +// cnt = n_mm<<16 | n_gapo<<8 | n_gape +bwa_cigar_t *bwa_sw_core(bwtint_t l_pac, const ubyte_t *pacseq, int len, const ubyte_t *seq, int64_t *beg, int reglen, + int *n_cigar, uint32_t *_cnt) +{ + bwa_cigar_t *cigar = 0; + ubyte_t *ref_seq; + bwtint_t k, x, y, l; + int path_len, ret; + AlnParam ap = aln_param_bwa; + path_t *path, *p; + + // check whether there are too many N's + if (reglen < SW_MIN_MATCH_LEN || (int64_t)l_pac - *beg < len) return 0; + for (k = 0, x = 0; k < len; ++k) + if (seq[k] >= 4) ++x; + if ((float)x/len >= 0.25 || len - x < SW_MIN_MATCH_LEN) return 0; + + // get reference subsequence + ref_seq = (ubyte_t*)calloc(reglen, 1); + for (k = *beg, l = 0; l < reglen && k < l_pac; ++k) + ref_seq[l++] = pacseq[k>>2] >> ((~k&3)<<1) & 3; + path = (path_t*)calloc(l+len, sizeof(path_t)); + + // do alignment + ret = aln_local_core(ref_seq, l, (ubyte_t*)seq, len, &ap, path, &path_len, 1, 0); + if (ret < 0) { + free(path); free(cigar); free(ref_seq); *n_cigar = 0; + return 0; + } + cigar = bwa_aln_path2cigar(path, path_len, n_cigar); + + // check whether the alignment is good enough + for (k = 0, x = y = 0; k < *n_cigar; ++k) { + bwa_cigar_t c = cigar[k]; + if (__cigar_op(c) == FROM_M) x += __cigar_len(c), y += __cigar_len(c); + else if (__cigar_op(c) == FROM_D) x += __cigar_len(c); + else y += __cigar_len(c); + } + if (x < SW_MIN_MATCH_LEN || y < SW_MIN_MATCH_LEN) { // not good enough + free(path); free(cigar); free(ref_seq); + *n_cigar = 0; + return 0; + } + + { // update cigar and coordinate; + int start, end; + p = path + path_len - 1; + *beg += (p->i? p->i : 1) - 1; + start = (p->j? p->j : 1) - 1; + end = path->j; + cigar = (bwa_cigar_t*)realloc(cigar, sizeof(bwa_cigar_t) * (*n_cigar + 2)); + if (start) { + memmove(cigar + 1, cigar, sizeof(bwa_cigar_t) * (*n_cigar)); + cigar[0] = __cigar_create(3, start); + ++(*n_cigar); + } + if (end < len) { + /*cigar[*n_cigar] = 3<<14 | (len - end);*/ + cigar[*n_cigar] = __cigar_create(3, (len - end)); + ++(*n_cigar); + } + } + + { // set *cnt + int n_mm, n_gapo, n_gape; + n_mm = n_gapo = n_gape = 0; + p = path + path_len - 1; + x = p->i? p->i - 1 : 0; y = p->j? p->j - 1 : 0; + for (k = 0; k < *n_cigar; ++k) { + bwa_cigar_t c = cigar[k]; + if (__cigar_op(c) == FROM_M) { + for (l = 0; l < (__cigar_len(c)); ++l) + if (ref_seq[x+l] < 4 && seq[y+l] < 4 && ref_seq[x+l] != seq[y+l]) ++n_mm; + x += __cigar_len(c), y += __cigar_len(c); + } else if (__cigar_op(c) == FROM_D) { + x += __cigar_len(c), ++n_gapo, n_gape += (__cigar_len(c)) - 1; + } else if (__cigar_op(c) == FROM_I) { + y += __cigar_len(c), ++n_gapo, n_gape += (__cigar_len(c)) - 1; + } + } + *_cnt = (uint32_t)n_mm<<16 | n_gapo<<8 | n_gape; + } + + free(ref_seq); free(path); + return cigar; +} + +ubyte_t *bwa_paired_sw(const bntseq_t *bns, const ubyte_t *_pacseq, int n_seqs, bwa_seq_t *seqs[2], const pe_opt_t *popt, const isize_info_t *ii) +{ + ubyte_t *pacseq; + int i; + uint64_t n_tot[2], n_mapped[2]; + + // load reference sequence + if (_pacseq == 0) { + pacseq = (ubyte_t*)calloc(bns->l_pac/4+1, 1); + rewind(bns->fp_pac); + fread(pacseq, 1, bns->l_pac/4+1, bns->fp_pac); + } else pacseq = (ubyte_t*)_pacseq; + if (!popt->is_sw || ii->avg < 0.0) return pacseq; + + // perform mate alignment + n_tot[0] = n_tot[1] = n_mapped[0] = n_mapped[1] = 0; + for (i = 0; i != n_seqs; ++i) { + bwa_seq_t *p[2]; + p[0] = seqs[0] + i; p[1] = seqs[1] + i; + if ((p[0]->mapQ >= SW_MIN_MAPQ || p[1]->mapQ >= SW_MIN_MAPQ) && (p[0]->extra_flag&SAM_FPP) == 0) { // unpaired and one read has high mapQ + int k, n_cigar[2], is_singleton, mapQ = 0; + int64_t beg[2], end[2]; + bwa_cigar_t *cigar[2]; + uint32_t cnt[2]; + + /* In the following, _pref points to the reference read + * which must be aligned; _pmate points to its mate which is + * considered to be modified. */ + +#define __set_rght_coor(_a, _b, _pref, _pmate) do { \ + (_a) = _pref->pos + ii->avg - 3 * ii->std - _pmate->len * 1.5; \ + (_b) = (_a) + 6 * ii->std + 2 * _pmate->len; \ + if ((_a) < _pref->pos + _pref->len) (_a) = _pref->pos + _pref->len; \ + if ((_b) > bns->l_pac) (_b) = bns->l_pac; \ + } while (0) + +#define __set_left_coor(_a, _b, _pref, _pmate) do { \ + (_a) = _pref->pos + _pref->len - ii->avg - 3 * ii->std - _pmate->len * 0.5; \ + (_b) = (_a) + 6 * ii->std + 2 * _pmate->len; \ + if ((_a) < 0) (_a) = 0; \ + if ((_b) > _pref->pos) (_b) = _pref->pos; \ + } while (0) + +#define __set_fixed(_pref, _pmate, _beg, _cnt) do { \ + _pmate->type = BWA_TYPE_MATESW; \ + _pmate->pos = _beg; \ + _pmate->seQ = _pref->seQ; \ + _pmate->strand = (popt->type == BWA_PET_STD)? 1 - _pref->strand : _pref->strand; \ + _pmate->n_mm = _cnt>>16; _pmate->n_gapo = _cnt>>8&0xff; _pmate->n_gape = _cnt&0xff; \ + _pmate->extra_flag |= SAM_FPP; \ + _pref->extra_flag |= SAM_FPP; \ + } while (0) + + is_singleton = (p[0]->type == BWA_TYPE_NO_MATCH || p[1]->type == BWA_TYPE_NO_MATCH)? 1 : 0; + + ++n_tot[is_singleton]; + cigar[0] = cigar[1] = 0; + n_cigar[0] = n_cigar[1] = 0; + if (popt->type != BWA_PET_STD && popt->type != BWA_PET_SOLID) continue; // other types of pairing is not considered + for (k = 0; k < 2; ++k) { // p[1-k] is the reference read and p[k] is the read considered to be modified + ubyte_t *seq; + if (p[1-k]->type == BWA_TYPE_NO_MATCH) continue; // if p[1-k] is unmapped, skip + if (popt->type == BWA_PET_STD) { + if (p[1-k]->strand == 0) { // then the mate is on the reverse strand and has larger coordinate + __set_rght_coor(beg[k], end[k], p[1-k], p[k]); + seq = p[k]->rseq; + } else { // then the mate is on forward stand and has smaller coordinate + __set_left_coor(beg[k], end[k], p[1-k], p[k]); + seq = p[k]->seq; + seq_reverse(p[k]->len, seq, 0); // because ->seq is reversed; this will reversed back shortly + } + } else { // BWA_PET_SOLID + if (p[1-k]->strand == 0) { // R3-F3 pairing + if (k == 0) __set_left_coor(beg[k], end[k], p[1-k], p[k]); // p[k] is R3 + else __set_rght_coor(beg[k], end[k], p[1-k], p[k]); // p[k] is F3 + seq = p[k]->rseq; + seq_reverse(p[k]->len, seq, 0); // because ->seq is reversed + } else { // F3-R3 pairing + if (k == 0) __set_rght_coor(beg[k], end[k], p[1-k], p[k]); // p[k] is R3 + else __set_left_coor(beg[k], end[k], p[1-k], p[k]); // p[k] is F3 + seq = p[k]->seq; + } + } + // perform SW alignment + cigar[k] = bwa_sw_core(bns->l_pac, pacseq, p[k]->len, seq, &beg[k], end[k] - beg[k], &n_cigar[k], &cnt[k]); + // now revserse sequence back such that p[*]->seq looks untouched + if (popt->type == BWA_PET_STD) { + if (p[1-k]->strand == 1) seq_reverse(p[k]->len, seq, 0); + } else { + if (p[1-k]->strand == 0) seq_reverse(p[k]->len, seq, 0); + } + } + k = -1; // no read to be changed + if (cigar[0] && cigar[1]) { + k = p[0]->mapQ < p[1]->mapQ? 0 : 1; // p[k] to be fixed + mapQ = abs(p[1]->mapQ - p[0]->mapQ); + } else if (cigar[0]) k = 0, mapQ = p[1]->mapQ; + else if (cigar[1]) k = 1, mapQ = p[0]->mapQ; + if (k >= 0 && p[k]->pos != beg[k]) { + ++n_mapped[is_singleton]; + { // recalculate mapping quality + int tmp = (int)p[1-k]->mapQ - p[k]->mapQ/2 - 8; + if (tmp <= 0) tmp = 1; + if (mapQ > tmp) mapQ = tmp; + p[k]->mapQ = p[1-k]->mapQ = mapQ; + p[k]->seQ = p[1-k]->seQ = p[1-k]->seQ < mapQ? p[1-k]->seQ : mapQ; + } + // update CIGAR + free(p[k]->cigar); p[k]->cigar = cigar[k]; cigar[k] = 0; + p[k]->n_cigar = n_cigar[k]; + // update the rest of information + __set_fixed(p[1-k], p[k], beg[k], cnt[k]); + } + free(cigar[0]); free(cigar[1]); + } + } + fprintf(stderr, "[bwa_paired_sw] %lld out of %lld Q%d singletons are mated.\n", + (long long)n_mapped[1], (long long)n_tot[1], SW_MIN_MAPQ); + fprintf(stderr, "[bwa_paired_sw] %lld out of %lld Q%d discordant pairs are fixed.\n", + (long long)n_mapped[0], (long long)n_tot[0], SW_MIN_MAPQ); + return pacseq; +} + +void bwa_sai2sam_pe_core(const char *prefix, char *const fn_sa[2], char *const fn_fa[2], pe_opt_t *popt) +{ + int i, j, n_seqs, tot_seqs = 0; + bwa_seq_t *seqs[2]; + bwa_seqio_t *ks[2]; + clock_t t; + bntseq_t *bns, *ntbns = 0; + FILE *fp_sa[2]; + gap_opt_t opt; + khint_t iter; + isize_info_t last_ii; // this is for the last batch of reads + char str[1024]; + bwt_t *bwt[2]; + uint8_t *pac; + + // initialization + pac = 0; bwt[0] = bwt[1] = 0; + for (i = 1; i != 256; ++i) g_log_n[i] = (int)(4.343 * log(i) + 0.5); + bns = bns_restore(prefix); + srand48(bns->seed); + for (i = 0; i < 2; ++i) { + ks[i] = bwa_seq_open(fn_fa[i]); + fp_sa[i] = xopen(fn_sa[i], "r"); + } + g_hash = kh_init(64); + last_ii.avg = -1.0; + + fread(&opt, sizeof(gap_opt_t), 1, fp_sa[0]); + fread(&opt, sizeof(gap_opt_t), 1, fp_sa[1]); + if (!(opt.mode & BWA_MODE_COMPREAD)) { + popt->type = BWA_PET_SOLID; + ntbns = bwa_open_nt(prefix); + } else { // for Illumina alignment only + if (popt->is_preload) { + strcpy(str, prefix); strcat(str, ".bwt"); bwt[0] = bwt_restore_bwt(str); + strcpy(str, prefix); strcat(str, ".sa"); bwt_restore_sa(str, bwt[0]); + strcpy(str, prefix); strcat(str, ".rbwt"); bwt[1] = bwt_restore_bwt(str); + strcpy(str, prefix); strcat(str, ".rsa"); bwt_restore_sa(str, bwt[1]); + pac = (ubyte_t*)calloc(bns->l_pac/4+1, 1); + rewind(bns->fp_pac); + fread(pac, 1, bns->l_pac/4+1, bns->fp_pac); + } + } + + // core loop + bwa_print_sam_SQ(bns); + while ((seqs[0] = bwa_read_seq(ks[0], 0x40000, &n_seqs, opt.mode & BWA_MODE_COMPREAD, opt.trim_qual)) != 0) { + int cnt_chg; + isize_info_t ii; + ubyte_t *pacseq; + + seqs[1] = bwa_read_seq(ks[1], 0x40000, &n_seqs, opt.mode & BWA_MODE_COMPREAD, opt.trim_qual); + tot_seqs += n_seqs; + t = clock(); + + fprintf(stderr, "[bwa_sai2sam_pe_core] convert to sequence coordinate... \n"); + cnt_chg = bwa_cal_pac_pos_pe(prefix, bwt, n_seqs, seqs, fp_sa, &ii, popt, &opt, &last_ii); + fprintf(stderr, "[bwa_sai2sam_pe_core] time elapses: %.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); t = clock(); + fprintf(stderr, "[bwa_sai2sam_pe_core] changing coordinates of %d alignments.\n", cnt_chg); + + fprintf(stderr, "[bwa_sai2sam_pe_core] align unmapped mate...\n"); + pacseq = bwa_paired_sw(bns, pac, n_seqs, seqs, popt, &ii); + fprintf(stderr, "[bwa_sai2sam_pe_core] time elapses: %.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); t = clock(); + + fprintf(stderr, "[bwa_sai2sam_pe_core] refine gapped alignments... "); + for (j = 0; j < 2; ++j) + bwa_refine_gapped(bns, n_seqs, seqs[j], pacseq, ntbns); + fprintf(stderr, "%.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); t = clock(); + if (pac == 0) free(pacseq); + + fprintf(stderr, "[bwa_sai2sam_pe_core] print alignments... "); + for (i = 0; i < n_seqs; ++i) { + bwa_print_sam1(bns, seqs[0] + i, seqs[1] + i, opt.mode, opt.max_top2); + bwa_print_sam1(bns, seqs[1] + i, seqs[0] + i, opt.mode, opt.max_top2); + } + fprintf(stderr, "%.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); t = clock(); + + for (j = 0; j < 2; ++j) + bwa_free_read_seq(n_seqs, seqs[j]); + fprintf(stderr, "[bwa_sai2sam_pe_core] %d sequences have been processed.\n", tot_seqs); + last_ii = ii; + } + + // destroy + bns_destroy(bns); + if (ntbns) bns_destroy(ntbns); + for (i = 0; i < 2; ++i) { + bwa_seq_close(ks[i]); + fclose(fp_sa[i]); + } + for (iter = kh_begin(g_hash); iter != kh_end(g_hash); ++iter) + if (kh_exist(g_hash, iter)) free(kh_val(g_hash, iter).a); + kh_destroy(64, g_hash); + if (pac) { + free(pac); bwt_destroy(bwt[0]); bwt_destroy(bwt[1]); + } +} + +int bwa_sai2sam_pe(int argc, char *argv[]) +{ + int c; + pe_opt_t *popt; + popt = bwa_init_pe_opt(); + while ((c = getopt(argc, argv, "a:o:sPn:N:c:f:")) >= 0) { + switch (c) { + case 'a': popt->max_isize = atoi(optarg); break; + case 'o': popt->max_occ = atoi(optarg); break; + case 's': popt->is_sw = 0; break; + case 'P': popt->is_preload = 1; break; + case 'n': popt->n_multi = atoi(optarg); break; + case 'N': popt->N_multi = atoi(optarg); break; + case 'c': popt->ap_prior = atof(optarg); break; + case 'f': freopen(optarg, "w", stdout); break; + default: return 1; + } + } + + if (optind + 5 > argc) { + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: bwa sampe [options] <prefix> <in1.sai> <in2.sai> <in1.fq> <in2.fq>\n\n"); + fprintf(stderr, "Options: -a INT maximum insert size [%d]\n", popt->max_isize); + fprintf(stderr, " -o INT maximum occurrences for one end [%d]\n", popt->max_occ); + fprintf(stderr, " -n INT maximum hits to output for paired reads [%d]\n", popt->n_multi); + fprintf(stderr, " -N INT maximum hits to output for discordant pairs [%d]\n", popt->N_multi); + fprintf(stderr, " -c FLOAT prior of chimeric rate [%.1le]\n", popt->ap_prior); + fprintf(stderr, " -P preload index into memory (for base-space reads only)\n"); + fprintf(stderr, " -s disable Smith-Waterman for the unmapped mate\n"); + fprintf(stderr, " -f FILE sam file to output results to instead of stdout\n\n"); + fprintf(stderr, "Notes: 1. For SOLiD reads, <in1.fq> corresponds R3 reads and <in2.fq> to F3.\n"); + fprintf(stderr, " 2. For reads shorter than 30bp, applying a smaller -o is recommended to\n"); + fprintf(stderr, " to get a sensible speed at the cost of pairing accuracy.\n"); + fprintf(stderr, "\n"); + return 1; + } + bwa_sai2sam_pe_core(argv[optind], argv + optind + 1, argv + optind+3, popt); + free(popt); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwase.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,995 @@ +#include <unistd.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <time.h> +#include "stdaln.h" +#include "bwase.h" +#include "bwtaln.h" +#include "bntseq.h" +#include "utils.h" +#include "kstring.h" + +static int g_log_n[256]; + +void bwa_aln2seq_core(int n_aln, const bwt_aln1_t *aln, bwa_seq_t *s, int set_main, int n_multi) +{ + int i, cnt, best; + if (n_aln == 0) { + s->type = BWA_TYPE_NO_MATCH; + s->c1 = s->c2 = 0; + return; + } + + if (set_main) { + best = aln[0].score; + for (i = cnt = 0; i < n_aln; ++i) { + const bwt_aln1_t *p = aln + i; + if (p->score > best) break; + if (drand48() * (p->l - p->k + 1) > (double)cnt) { + s->n_mm = p->n_mm; s->n_gapo = p->n_gapo; s->n_gape = p->n_gape; s->strand = p->a; + s->score = p->score; + s->sa = p->k + (bwtint_t)((p->l - p->k + 1) * drand48()); + } + cnt += p->l - p->k + 1; + } + s->c1 = cnt; + for (; i < n_aln; ++i) cnt += aln[i].l - aln[i].k + 1; + s->c2 = cnt - s->c1; + s->type = s->c1 > 1? BWA_TYPE_REPEAT : BWA_TYPE_UNIQUE; + } + + if (n_multi) { + int k, rest, n_occ, z = 0; + for (k = n_occ = 0; k < n_aln; ++k) { + const bwt_aln1_t *q = aln + k; + n_occ += q->l - q->k + 1; + } + if (s->multi) free(s->multi); + if (n_occ > n_multi + 1) { // if there are too many hits, generate none of them + s->multi = 0; s->n_multi = 0; + return; + } + /* The following code is more flexible than what is required + * here. In principle, due to the requirement above, we can + * simply output all hits, but the following samples "rest" + * number of random hits. */ + rest = n_occ > n_multi + 1? n_multi + 1 : n_occ; // find one additional for ->sa + s->multi = calloc(rest, rest * sizeof(bwt_multi1_t)); + for (k = 0; k < n_aln; ++k) { + const bwt_aln1_t *q = aln + k; + if (q->l - q->k + 1 <= rest) { + bwtint_t l; + for (l = q->k; l <= q->l; ++l) { + s->multi[z].pos = l; + s->multi[z].gap = q->n_gapo + q->n_gape; + s->multi[z].mm = q->n_mm; + s->multi[z++].strand = q->a; + } + rest -= q->l - q->k + 1; + } else { // Random sampling (http://code.activestate.com/recipes/272884/). In fact, we never come here. + int j, i, k; + for (j = rest, i = q->l - q->k + 1, k = 0; j > 0; --j) { + double p = 1.0, x = drand48(); + while (x < p) p -= p * j / (i--); + s->multi[z].pos = q->l - i; + s->multi[z].gap = q->n_gapo + q->n_gape; + s->multi[z].mm = q->n_mm; + s->multi[z++].strand = q->a; + } + rest = 0; + break; + } + } + s->n_multi = z; + for (k = z = 0; k < s->n_multi; ++k) + if (s->multi[k].pos != s->sa) + s->multi[z++] = s->multi[k]; + s->n_multi = z < n_multi? z : n_multi; + } +} + +void bwa_aln2seq(int n_aln, const bwt_aln1_t *aln, bwa_seq_t *s) +{ + bwa_aln2seq_core(n_aln, aln, s, 1, 0); +} + +/* *aln points to alignments found for the current sequence, n_aln is the + size of the array pointed to by *aln. Array *s of size n_seq is a collection + of SAM records that must be replicas, i.e. initialized with the same current sequence. + This method updates sequence records in *s with placements recorded in *aln, + until all n_seq replicas are updated. For each separate alignment record in array *aln, + each placement corresponding to this record will be assigned to a separate record in *s + if there are enough elements remaining in *s, otherwise a random subset of the placements will + be assigned to the remaining elements in *s. The total number of best placements and total + number of non-best placements will be computed from the whole array *aln (regardless of whether it + fits completely into *s or not) and assigned to each updated record in *s. +*/ +void bwa_aln2seq_all(int n_aln, const bwt_aln1_t *aln, int n_seq, bwa_seq_t *s) +{ + int i, cnt1, cnt2, j, best, N; + if (n_aln == 0) { + /* there is no match found for *s */ + s->type = BWA_TYPE_NO_MATCH; + s->c1 = s->c2 = 0; + return; + } + + N = n_seq; // remember the size of the array + best = aln[0].score; + + cnt1 = 0; // total number of already processed alignments (i.e. distinct placements, NOT alignment records) with best score + cnt2 = 0; // total number of already processed alignments with inferior score(s) + for (i = 0; i < n_aln && n_seq > 0 ; ++i) { + const bwt_aln1_t *p_aln = aln + i; + + int N_aligns = p_aln->l-p_aln->k +1 ; // number of placements (alignments) in the current alignment record p_aln + + if (N_aligns <= n_seq) { /* we have space to save all the alignments stored in 'p_aln' */ + + for ( j = 0 ; j < N_aligns ; j++ ) { + + bwa_seq_t * seq = s + cnt1+ cnt2+j ; + seq->n_mm = p_aln->n_mm; seq->n_gapo = p_aln->n_gapo; seq->n_gape = p_aln->n_gape; seq->strand = p_aln->a; + seq->score = p_aln->score; + seq->sa = p_aln->k + j; + } + n_seq -= N_aligns; // we have n_seq slots remaining to store more alignments + } else { // See also: http://code.activestate.com/recipes/272884/ + // we have to truncate, so let's select few remaining alignments randomly: + int xj, xi, xk; + for (xj = n_seq, xi = N_aligns, xk = 0; xj > 0; --xj, ++xk) { + double p = 1.0, x = drand48(); + while (x < p) p -= p * xj / (xi--); + + bwa_seq_t * seq = s+cnt1+cnt2+xk ; + seq->n_mm = p_aln->n_mm; seq->n_gapo = p_aln->n_gapo; seq->n_gape = p_aln->n_gape; seq->strand = p_aln->a; + seq->score = p_aln->score; + seq->sa = p_aln->l - xi; + + } + n_seq = 0; + } + // cnt1 + cnt2 is the total count of hits processed so far: + if ( p_aln->score == best ) cnt1 += N_aligns; // we found N_aligns more placements with best score + else cnt2 += N_aligns; // N_aligns more placements with inferior score + } + + // we filled all available slots in the array *s, but there can be more alignments + // left; we need to count them: + for (; i < n_aln; ++i) { + if ( aln[i].score == best ) cnt1 += aln[i].l-aln[i].k+1; + else cnt2 += aln[i].l-aln[i].k+1; + } + + // now cnt1 is the total number of found alignments (placements) with best score + // and cnt2 is the total number of found placements with worse score + + /* set counts and flags for all hits: */ + for (i = 0; i < N ; ++i) { + bwa_seq_t * seq = s+i ; + + seq->c1 = cnt1; + seq->c2 = cnt2; + seq->type = seq->c1 > 1? BWA_TYPE_REPEAT : BWA_TYPE_UNIQUE; + } +} + + + +int bwa_approx_mapQ(const bwa_seq_t *p, int mm) +{ + int n; + if (p->c1 == 0) return 23; + if (p->c1 > 1) return 0; + if (p->n_mm == mm) return 25; + if (p->c2 == 0) return 37; + n = (p->c2 >= 255)? 255 : p->c2; + return (23 < g_log_n[n])? 0 : 23 - g_log_n[n]; +} + +/** + * Derive the actual position in the read from the given suffix array + * coordinates. Note that the position will be approximate based on + * whether indels appear in the read and whether calculations are + * performed from the start or end of the read. + */ +void bwa_cal_pac_pos_core(const bwt_t *forward_bwt, const bwt_t *reverse_bwt, int n_seqs, bwa_seq_t *s, const int max_mm, const float fnr) +{ + int max_diff; + bwa_seq_t *seq; + int i; + + for ( i = 0 ; i < n_seqs ; i++ ) { + seq = s + i; + if (seq->type != BWA_TYPE_UNIQUE && seq->type != BWA_TYPE_REPEAT) continue; + + max_diff = fnr > 0.0? bwa_cal_maxdiff(seq->len, BWA_AVG_ERR, fnr) : max_mm; + if (seq->strand) { // reverse strand only + seq->pos = bwt_sa(forward_bwt, seq->sa); + seq->seQ = seq->mapQ = bwa_approx_mapQ(seq, max_diff); + } else { // forward strand only + /* NB: For gapped alignment, p->pos may not be correct, which + * will be fixed in refine_gapped_core(). This line also + * determines the way "x" is calculated in + * refine_gapped_core() when (ext < 0 && is_end == 0). */ + seq->pos = reverse_bwt->seq_len - (bwt_sa(reverse_bwt, seq->sa) + seq->len); + seq->seQ = seq->mapQ = bwa_approx_mapQ(seq, max_diff); + } + } +} + +void bwa_cal_pac_pos(const char *prefix, int n_seqs, bwa_seq_t *seqs, int max_mm, float fnr) +{ + int i, j; + char str[1024]; + bwt_t *bwt; + // load forward SA + strcpy(str, prefix); strcat(str, ".bwt"); bwt = bwt_restore_bwt(str); + strcpy(str, prefix); strcat(str, ".sa"); bwt_restore_sa(str, bwt); + for (i = 0; i != n_seqs; ++i) { + if (seqs[i].strand) bwa_cal_pac_pos_core(bwt, 0, 1, &seqs[i], max_mm, fnr); + for (j = 0; j < seqs[i].n_multi; ++j) { + bwt_multi1_t *p = seqs[i].multi + j; + if (p->strand) p->pos = bwt_sa(bwt, p->pos); + } + } + bwt_destroy(bwt); + // load reverse BWT and SA + strcpy(str, prefix); strcat(str, ".rbwt"); bwt = bwt_restore_bwt(str); + strcpy(str, prefix); strcat(str, ".rsa"); bwt_restore_sa(str, bwt); + for (i = 0; i != n_seqs; ++i) { + if (!seqs[i].strand) bwa_cal_pac_pos_core(0, bwt, 1, &seqs[i], max_mm, fnr); + for (j = 0; j < seqs[i].n_multi; ++j) { + bwt_multi1_t *p = seqs[i].multi + j; + if (!p->strand) p->pos = bwt->seq_len - (bwt_sa(bwt, p->pos) + seqs[i].len); + } + } + bwt_destroy(bwt); +} + +/* is_end_correct == 1 if (*pos+len) gives the correct coordinate on + * forward strand. This happens when p->pos is calculated by + * bwa_cal_pac_pos(). is_end_correct==0 if (*pos) gives the correct + * coordinate. This happens only for color-converted alignment. */ +static bwa_cigar_t *refine_gapped_core(bwtint_t l_pac, const ubyte_t *pacseq, int len, const ubyte_t *seq, bwtint_t *_pos, + int ext, int *n_cigar, int is_end_correct) +{ + bwa_cigar_t *cigar = 0; + ubyte_t *ref_seq; + int l = 0, path_len, ref_len; + AlnParam ap = aln_param_bwa; + path_t *path; + int64_t k, __pos = *_pos > l_pac? (int64_t)((int32_t)*_pos) : *_pos; + + ref_len = len + abs(ext); + if (ext > 0) { + ref_seq = (ubyte_t*)calloc(ref_len, 1); + for (k = __pos; k < __pos + ref_len && k < l_pac; ++k) + ref_seq[l++] = pacseq[k>>2] >> ((~k&3)<<1) & 3; + } else { + int64_t x = __pos + (is_end_correct? len : ref_len); + ref_seq = (ubyte_t*)calloc(ref_len, 1); + for (l = 0, k = x - ref_len > 0? x - ref_len : 0; k < x && k < l_pac; ++k) + ref_seq[l++] = pacseq[k>>2] >> ((~k&3)<<1) & 3; + } + path = (path_t*)calloc(l+len, sizeof(path_t)); + + aln_global_core(ref_seq, l, (ubyte_t*)seq, len, &ap, path, &path_len); + cigar = bwa_aln_path2cigar(path, path_len, n_cigar); + + if (ext < 0 && is_end_correct) { // fix coordinate for reads mapped on the forward strand + for (l = k = 0; k < *n_cigar; ++k) { + if (__cigar_op(cigar[k]) == FROM_D) l -= __cigar_len(cigar[k]); + else if (__cigar_op(cigar[k]) == FROM_I) l += __cigar_len(cigar[k]); + } + __pos += l; + } + + if (__cigar_op(cigar[0]) == FROM_D) { // deletion at the 5'-end + __pos += __cigar_len(cigar[0]); + for (k = 0; k < *n_cigar - 1; ++k) cigar[k] = cigar[k+1]; + --(*n_cigar); + } + if (__cigar_op(cigar[*n_cigar-1]) == FROM_D) --(*n_cigar); // deletion at the 3'-end + + // change "I" at either end of the read to S. just in case. This should rarely happen... + if (__cigar_op(cigar[*n_cigar-1]) == FROM_I) cigar[*n_cigar-1] = __cigar_create(3, (__cigar_len(cigar[*n_cigar-1]))); + if (__cigar_op(cigar[0]) == FROM_I) cigar[0] = __cigar_create(3, (__cigar_len(cigar[0]))); + + *_pos = (bwtint_t)__pos; + free(ref_seq); free(path); + return cigar; +} + +char *bwa_cal_md1(int n_cigar, bwa_cigar_t *cigar, int len, bwtint_t pos, ubyte_t *seq, + bwtint_t l_pac, ubyte_t *pacseq, kstring_t *str, int *_nm) +{ + bwtint_t x, y; + int z, u, c, nm = 0; + str->l = 0; // reset + x = pos; y = 0; + if (cigar) { + int k, l; + for (k = u = 0; k < n_cigar; ++k) { + l = __cigar_len(cigar[k]); + if (__cigar_op(cigar[k]) == FROM_M) { + for (z = 0; z < l && x+z < l_pac; ++z) { + c = pacseq[(x+z)>>2] >> ((~(x+z)&3)<<1) & 3; + if (c > 3 || seq[y+z] > 3 || c != seq[y+z]) { + ksprintf(str, "%d", u); + kputc("ACGTN"[c], str); + ++nm; + u = 0; + } else ++u; + } + x += l; y += l; +/* } else if (cigar[k]>>14 == FROM_I || cigar[k]>>14 == 3) { */ + } else if (__cigar_op(cigar[k]) == FROM_I || __cigar_op(cigar[k]) == FROM_S) { + y += l; + if (__cigar_op(cigar[k]) == FROM_I) nm += l; + } else if (__cigar_op(cigar[k]) == FROM_D) { + ksprintf(str, "%d", u); + kputc('^', str); + for (z = 0; z < l && x+z < l_pac; ++z) + kputc("ACGT"[pacseq[(x+z)>>2] >> ((~(x+z)&3)<<1) & 3], str); + u = 0; + x += l; nm += l; + } + } + } else { // no gaps + for (z = u = 0; z < (bwtint_t)len; ++z) { + c = pacseq[(x+z)>>2] >> ((~(x+z)&3)<<1) & 3; + if (c > 3 || seq[y+z] > 3 || c != seq[y+z]) { + ksprintf(str, "%d", u); + kputc("ACGTN"[c], str); + ++nm; + u = 0; + } else ++u; + } + } + ksprintf(str, "%d", u); + *_nm = nm; + return strdup(str->s); +} + +void bwa_correct_trimmed(bwa_seq_t *s) +{ + if (s->len == s->full_len) return; + if (s->strand == 0) { // forward + if (s->cigar && __cigar_op(s->cigar[s->n_cigar-1]) == FROM_S) { // the last is S + s->cigar[s->n_cigar-1] += s->full_len - s->len; + } else { + if (s->cigar == 0) { + s->n_cigar = 2; + s->cigar = calloc(s->n_cigar, sizeof(bwa_cigar_t)); + s->cigar[0] = __cigar_create(0, s->len); + } else { + ++s->n_cigar; + s->cigar = realloc(s->cigar, s->n_cigar * sizeof(bwa_cigar_t)); + } + s->cigar[s->n_cigar-1] = __cigar_create(3, (s->full_len - s->len)); + } + } else { // reverse + if (s->cigar && __cigar_op(s->cigar[0]) == FROM_S) { // the first is S + s->cigar[0] += s->full_len - s->len; + } else { + if (s->cigar == 0) { + s->n_cigar = 2; + s->cigar = calloc(s->n_cigar, sizeof(bwa_cigar_t)); + s->cigar[1] = __cigar_create(0, s->len); + } else { + ++s->n_cigar; + s->cigar = realloc(s->cigar, s->n_cigar * sizeof(bwa_cigar_t)); + memmove(s->cigar + 1, s->cigar, (s->n_cigar-1) * sizeof(bwa_cigar_t)); + } + s->cigar[0] = __cigar_create(3, (s->full_len - s->len)); + } + } + s->len = s->full_len; +} + +void bwa_refine_gapped(const bntseq_t *bns, int n_seqs, bwa_seq_t *seqs, ubyte_t *_pacseq, bntseq_t *ntbns) +{ + ubyte_t *pacseq, *ntpac = 0; + int i, j; + kstring_t *str; + + if (ntbns) { // in color space + ntpac = (ubyte_t*)calloc(ntbns->l_pac/4+1, 1); + rewind(ntbns->fp_pac); + fread(ntpac, 1, ntbns->l_pac/4 + 1, ntbns->fp_pac); + } + + if (!_pacseq) { + pacseq = (ubyte_t*)calloc(bns->l_pac/4+1, 1); + rewind(bns->fp_pac); + fread(pacseq, 1, bns->l_pac/4+1, bns->fp_pac); + } else pacseq = _pacseq; + for (i = 0; i != n_seqs; ++i) { + bwa_seq_t *s = seqs + i; + for (j = 0; j < s->n_multi; ++j) { + bwt_multi1_t *q = s->multi + j; + int n_cigar; + if (q->gap == 0) continue; + q->cigar = refine_gapped_core(bns->l_pac, pacseq, s->len, q->strand? s->rseq : s->seq, &q->pos, + (q->strand? 1 : -1) * q->gap, &n_cigar, 1); + q->n_cigar = n_cigar; + } + if (s->type == BWA_TYPE_NO_MATCH || s->type == BWA_TYPE_MATESW || s->n_gapo == 0) continue; + s->cigar = refine_gapped_core(bns->l_pac, pacseq, s->len, s->strand? s->rseq : s->seq, &s->pos, + (s->strand? 1 : -1) * (s->n_gapo + s->n_gape), &s->n_cigar, 1); + } + + if (ntbns) { // in color space + for (i = 0; i < n_seqs; ++i) { + bwa_seq_t *s = seqs + i; + bwa_cs2nt_core(s, bns->l_pac, ntpac); + for (j = 0; j < s->n_multi; ++j) { + bwt_multi1_t *q = s->multi + j; + int n_cigar; + if (q->gap == 0) continue; + free(q->cigar); + q->cigar = refine_gapped_core(bns->l_pac, ntpac, s->len, q->strand? s->rseq : s->seq, &q->pos, + (q->strand? 1 : -1) * q->gap, &n_cigar, 0); + q->n_cigar = n_cigar; + } + if (s->type != BWA_TYPE_NO_MATCH && s->cigar) { // update cigar again + free(s->cigar); + s->cigar = refine_gapped_core(bns->l_pac, ntpac, s->len, s->strand? s->rseq : s->seq, &s->pos, + (s->strand? 1 : -1) * (s->n_gapo + s->n_gape), &s->n_cigar, 0); + } + } + } + + // generate MD tag + str = (kstring_t*)calloc(1, sizeof(kstring_t)); + for (i = 0; i != n_seqs; ++i) { + bwa_seq_t *s = seqs + i; + if (s->type != BWA_TYPE_NO_MATCH) { + int nm; + s->md = bwa_cal_md1(s->n_cigar, s->cigar, s->len, s->pos, s->strand? s->rseq : s->seq, + bns->l_pac, ntbns? ntpac : pacseq, str, &nm); + s->nm = nm; + } + } + free(str->s); free(str); + + // correct for trimmed reads + if (!ntbns) // trimming is only enabled for Illumina reads + for (i = 0; i < n_seqs; ++i) bwa_correct_trimmed(seqs + i); + + if (!_pacseq) free(pacseq); + free(ntpac); +} + +int64_t pos_end(const bwa_seq_t *p) +{ + if (p->cigar) { + int j; + int64_t x = p->pos; + for (j = 0; j != p->n_cigar; ++j) { + int op = __cigar_op(p->cigar[j]); + if (op == 0 || op == 2) x += __cigar_len(p->cigar[j]); + } + return x; + } else return p->pos + p->len; +} + +int64_t pos_end_multi(const bwt_multi1_t *p, int len) // analogy to pos_end() +{ + if (p->cigar) { + int j; + int64_t x = p->pos; + for (j = 0; j != p->n_cigar; ++j) { + int op = __cigar_op(p->cigar[j]); + if (op == 0 || op == 2) x += __cigar_len(p->cigar[j]); + } + return x; + } else return p->pos + len; +} + +static int64_t pos_5(const bwa_seq_t *p) +{ + if (p->type != BWA_TYPE_NO_MATCH) + return p->strand? pos_end(p) : p->pos; + return -1; +} + +/* Prints <bases>\t<quals> of the sequence *p into STDOUT; +*/ +void bwa_print_seq_and_qual(bwa_seq_t *p) { + int j; + ubyte_t * char_ptr; + + if (p->strand == 0) + for (j = 0; j != p->full_len; ++j) putchar("ACGTN"[(int)p->seq[j]]); + else for (j = 0; j != p->full_len; ++j) putchar("TGCAN"[p->seq[p->full_len - 1 - j]]); + putchar('\t'); + if (p->qual) { + if (p->strand) { + // seq_reverse(p->len, p->qual, 0); // reverse quality + for ( char_ptr = p->qual + p->len - 1 ; char_ptr >= p->qual ; char_ptr-- ) putchar( *char_ptr ); + } else { + printf("%s", p->qual); + } + } else printf("*"); + +} + + + +void bwa_print_sam1(const bntseq_t *bns, bwa_seq_t *p, const bwa_seq_t *mate, int mode, int max_top2) +{ + int j; + if (p->type != BWA_TYPE_NO_MATCH || (mate && mate->type != BWA_TYPE_NO_MATCH)) { + int seqid, nn, am = 0, flag = p->extra_flag; + char XT; + + if (p->type == BWA_TYPE_NO_MATCH) { + p->pos = mate->pos; + p->strand = mate->strand; + flag |= SAM_FSU; + j = 1; + } else j = pos_end(p) - p->pos; // j is the length of the reference in the alignment + + // get seqid + nn = bns_coor_pac2real(bns, p->pos, j, &seqid); + if (p->type != BWA_TYPE_NO_MATCH && p->pos + j - bns->anns[seqid].offset > bns->anns[seqid].len) + flag |= SAM_FSU; // flag UNMAP as this alignment bridges two adjacent reference sequences + + // update flag and print it + if (p->strand) flag |= SAM_FSR; + if (mate) { + if (mate->type != BWA_TYPE_NO_MATCH) { + if (mate->strand) flag |= SAM_FMR; + } else flag |= SAM_FMU; + } + printf("%s\t%d\t%s\t", p->name, flag, bns->anns[seqid].name); + printf("%d\t%d\t", (int)(p->pos - bns->anns[seqid].offset + 1), p->mapQ); + + // print CIGAR + if (p->cigar) { + for (j = 0; j != p->n_cigar; ++j) + printf("%d%c", __cigar_len(p->cigar[j]), "MIDS"[__cigar_op(p->cigar[j])]); + } else if (p->type == BWA_TYPE_NO_MATCH) printf("*"); + else printf("%dM", p->len); + + // print mate coordinate + if (mate && mate->type != BWA_TYPE_NO_MATCH) { + int m_seqid, m_is_N; + long long isize; + am = mate->seQ < p->seQ? mate->seQ : p->seQ; // smaller single-end mapping quality + // redundant calculation here, but should not matter too much + m_is_N = bns_coor_pac2real(bns, mate->pos, mate->len, &m_seqid); + printf("\t%s\t", (seqid == m_seqid)? "=" : bns->anns[m_seqid].name); + isize = (seqid == m_seqid)? pos_5(mate) - pos_5(p) : 0; + if (p->type == BWA_TYPE_NO_MATCH) isize = 0; + printf("%d\t%lld\t", (int)(mate->pos - bns->anns[m_seqid].offset + 1), isize); + } else if (mate) printf("\t=\t%d\t0\t", (int)(p->pos - bns->anns[seqid].offset + 1)); + else printf("\t*\t0\t0\t"); + + // print sequence and quality + bwa_print_seq_and_qual(p); + + if (p->clip_len < p->full_len) printf("\tXC:i:%d", p->clip_len); + if (p->type != BWA_TYPE_NO_MATCH) { + int i; + // calculate XT tag + XT = "NURM"[p->type]; + if (nn > 10) XT = 'N'; + // print tags + printf("\tXT:A:%c\t%s:i:%d", XT, (mode & BWA_MODE_COMPREAD)? "NM" : "CM", p->nm); + if (nn) printf("\tXN:i:%d", nn); + if (mate) printf("\tSM:i:%d\tAM:i:%d", p->seQ, am); + if (p->type != BWA_TYPE_MATESW) { // X0 and X1 are not available for this type of alignment + printf("\tX0:i:%d", p->c1); + if (p->c1 <= max_top2) printf("\tX1:i:%d", p->c2); + } + printf("\tXM:i:%d\tXO:i:%d\tXG:i:%d", p->n_mm, p->n_gapo, p->n_gapo+p->n_gape); + if (p->md) printf("\tMD:Z:%s", p->md); + // print multiple hits + if (p->n_multi) { + printf("\tXA:Z:"); + for (i = 0; i < p->n_multi; ++i) { + bwt_multi1_t *q = p->multi + i; + int k; + j = pos_end_multi(q, p->len) - q->pos; + nn = bns_coor_pac2real(bns, q->pos, j, &seqid); + printf("%s,%c%d,", bns->anns[seqid].name, q->strand? '-' : '+', + (int)(q->pos - bns->anns[seqid].offset + 1)); + if (q->cigar) { + for (k = 0; k < q->n_cigar; ++k) + printf("%d%c", __cigar_len(q->cigar[k]), "MIDS"[__cigar_op(q->cigar[k])]); + } else printf("%dM", p->len); + printf(",%d;", q->gap + q->mm); + } + } + } + putchar('\n'); + } else { // this read has no match + ubyte_t *s = p->strand? p->rseq : p->seq; + int flag = p->extra_flag | SAM_FSU; + if (mate && mate->type == BWA_TYPE_NO_MATCH) flag |= SAM_FMU; + printf("%s\t%d\t*\t0\t0\t*\t*\t0\t0\t", p->name, flag); + for (j = 0; j != p->len; ++j) putchar("ACGTN"[(int)s[j]]); + putchar('\t'); + if (p->qual) { + if (p->strand) { + // seq_reverse(p->len, p->qual, 0); // reverse quality + for ( s = p->qual + p->len - 1 ; s >= p->qual ; s-- ) putchar( *s ); + + } else { + printf("%s", p->qual); + } + } else printf("*"); + if (p->clip_len < p->full_len) printf("\tXC:i:%d", p->clip_len); + putchar('\n'); + } +} + +/* UNUSED +void bwa_print_partial_sam1(const bntseq_t *bns, bwa_seq_t *p, const bwa_seq_t *mate, int mode, int max_top2) +{ + int j; + if (p->type != BWA_TYPE_NO_MATCH || (mate && mate->type != BWA_TYPE_NO_MATCH)) { + int seqid, nn, am = 0, flag = p->extra_flag; + char XT; + + if (p->type == BWA_TYPE_NO_MATCH) { + p->pos = mate->pos; + p->strand = mate->strand; + flag |= SAM_FSU; + j = 1; + } else j = pos_end(p) - p->pos; // j is the length of the reference in the alignment + + // get seqid + nn = bns_coor_pac2real(bns, p->pos, j, &seqid); + if (p->type != BWA_TYPE_NO_MATCH && p->pos + j - bns->anns[seqid].offset > bns->anns[seqid].len) + flag |= SAM_FSU; // flag UNMAP as this alignment bridges two adjacent reference sequences + + // update flag and print it + if (p->strand) flag |= SAM_FSR; + if (mate) { + if (mate->type != BWA_TYPE_NO_MATCH) { + if (mate->strand) flag |= SAM_FMR; + } else flag |= SAM_FMU; + } + printf("%s\t%d\t%s\t", p->name, flag, bns->anns[seqid].name); + printf("%d\t%d\t", (int)(p->pos - bns->anns[seqid].offset + 1), p->mapQ); + + // print CIGAR + if (p->cigar) { + for (j = 0; j != p->n_cigar; ++j) + printf("%d%c", __cigar_len(p->cigar[j]), "MIDS"[__cigar_op(p->cigar[j])]); + } else if (p->type == BWA_TYPE_NO_MATCH) printf("*"); + else printf("%dM", p->len); + + // print mate coordinate + if (mate && mate->type != BWA_TYPE_NO_MATCH) { + int m_seqid, m_is_N; + long long isize; + am = mate->seQ < p->seQ? mate->seQ : p->seQ; // smaller single-end mapping quality + // redundant calculation here, but should not matter too much + m_is_N = bns_coor_pac2real(bns, mate->pos, mate->len, &m_seqid); + printf("\t%s\t", (seqid == m_seqid)? "=" : bns->anns[m_seqid].name); + isize = (seqid == m_seqid)? pos_5(mate) - pos_5(p) : 0; + if (p->type == BWA_TYPE_NO_MATCH) isize = 0; + printf("%d\t%lld\t", (int)(mate->pos - bns->anns[m_seqid].offset + 1), isize); + } else if (mate) printf("\t=\t%d\t0\t", (int)(p->pos - bns->anns[seqid].offset + 1)); + else printf("\t*\t0\t0\t"); + + + if (p->clip_len < p->full_len) printf("\tXC:i:%d", p->clip_len); + if (p->type != BWA_TYPE_NO_MATCH) { + int i; + // calculate XT tag + XT = "NURM"[p->type]; + if (nn > 10) XT = 'N'; + // print tags + printf("\tXT:A:%c\t%s:i:%d", XT, (mode & BWA_MODE_COMPREAD)? "NM" : "CM", p->nm); + if (nn) printf("\tXN:i:%d", nn); + if (mate) printf("\tSM:i:%d\tAM:i:%d", p->seQ, am); + printf("\tXM:i:%d\tXO:i:%d\tXG:i:%d", p->n_mm, p->n_gapo, p->n_gapo+p->n_gape); + if (p->md) printf("\tMD:Z:%s", p->md); + } + putchar('\n'); + } else { // this read has no match + ubyte_t *s = p->strand? p->rseq : p->seq; + int flag = p->extra_flag | SAM_FSU; + if (mate && mate->type == BWA_TYPE_NO_MATCH) flag |= SAM_FMU; + printf("%d\t*\t0\t0\t*\t*\t0\t0\t", flag); + if (p->clip_len < p->full_len) printf("\tXC:i:%d", p->clip_len); + putchar('\n'); + } +} + +*/ + +bntseq_t *bwa_open_nt(const char *prefix) +{ + bntseq_t *ntbns; + char *str; + str = (char*)calloc(strlen(prefix) + 10, 1); + strcat(strcpy(str, prefix), ".nt"); + ntbns = bns_restore(str); + free(str); + return ntbns; +} + +void bwa_print_sam_SQ(const bntseq_t *bns) +{ + int i; + for (i = 0; i < bns->n_seqs; ++i) + printf("@SQ\tSN:%s\tLN:%d\n", bns->anns[i].name, bns->anns[i].len); +} + +void bwase_initialize() +{ + int i; + for (i = 1; i != 256; ++i) g_log_n[i] = (int)(4.343 * log(i) + 0.5); +} + +void bwa_sai2sam_se_core(const char *prefix, const char *fn_sa, const char *fn_fa, int n_occ) +{ + int i, n_seqs, tot_seqs = 0, m_aln; + bwt_aln1_t *aln = 0; + bwa_seq_t *seqs; + bwa_seqio_t *ks; + clock_t t; + bntseq_t *bns, *ntbns = 0; + FILE *fp_sa; + gap_opt_t opt; + + // initialization + bwase_initialize(); + bns = bns_restore(prefix); + srand48(bns->seed); + ks = bwa_seq_open(fn_fa); + fp_sa = xopen(fn_sa, "r"); + + // core loop + m_aln = 0; + fread(&opt, sizeof(gap_opt_t), 1, fp_sa); + if (!(opt.mode & BWA_MODE_COMPREAD)) // in color space; initialize ntpac + ntbns = bwa_open_nt(prefix); + bwa_print_sam_SQ(bns); + while ((seqs = bwa_read_seq(ks, 0x40000, &n_seqs, opt.mode & BWA_MODE_COMPREAD, opt.trim_qual)) != 0) { + tot_seqs += n_seqs; + t = clock(); + + // read alignment + for (i = 0; i < n_seqs; ++i) { + bwa_seq_t *p = seqs + i; + int n_aln; + fread(&n_aln, 4, 1, fp_sa); + if (n_aln > m_aln) { + m_aln = n_aln; + aln = (bwt_aln1_t*)realloc(aln, sizeof(bwt_aln1_t) * m_aln); + } + fread(aln, sizeof(bwt_aln1_t), n_aln, fp_sa); + bwa_aln2seq_core(n_aln, aln, p, 1, n_occ); + // seq_reverse(p->len, p->seq, 0); + } + + fprintf(stderr, "[bwa_aln_core] convert to sequence coordinate... "); + bwa_cal_pac_pos(prefix, n_seqs, seqs, opt.max_diff, opt.fnr); // forward bwt will be destroyed here + fprintf(stderr, "%.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); t = clock(); + + for (i = 0; i < n_seqs; ++i) { + bwa_seq_t *p = seqs + i; + seq_reverse(p->len, p->seq, 0); + } + + fprintf(stderr, "[bwa_aln_core] refine gapped alignments... "); + bwa_refine_gapped(bns, n_seqs, seqs, 0, ntbns); + fprintf(stderr, "%.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); t = clock(); + + fprintf(stderr, "[bwa_aln_core] print alignments... "); + for (i = 0; i < n_seqs; ++i) + bwa_print_sam1(bns, seqs + i, 0, opt.mode, opt.max_top2); + fprintf(stderr, "%.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); t = clock(); + + bwa_free_read_seq(n_seqs, seqs); + fprintf(stderr, "[bwa_aln_core] %d sequences have been processed.\n", tot_seqs); + } + + // destroy + bwa_seq_close(ks); + if (ntbns) bns_destroy(ntbns); + bns_destroy(bns); + fclose(fp_sa); + free(aln); +} + +void bwa_print_all_hits(const char *prefix, const char *fn_sa, const char *fn_fa, int max_extra_occ) +{ + int i, n_seqs, tot_seqs = 0, m_aln, m_rest; + bwt_aln1_t *aln = 0; + bwa_seq_t *seqs; + bwa_seqio_t *ks; + clock_t t,t_convert, t_refine, t_write;; + bntseq_t *bns, *ntbns = 0; + FILE *fp_sa; + gap_opt_t opt; + + //****** below modified (added) for multiple hit printout: + + bwa_seq_t * rest_seqs = 0; // this array will keep (shallow) replicas of the current sequence; + // each of the replicas will be updated with its own alignment + // selected from all the (multiple) alignmens available for the current seq. + + bwt_t *bwt[2]; + char str[1024]; + ubyte_t *pacseq; + + t = clock(); + fprintf(stderr, "[bwa_aln_core] Data structures initialized: "); + + + strcpy(str, prefix); strcat(str, ".bwt"); bwt[0] = bwt_restore_bwt(str); + strcpy(str, prefix); strcat(str, ".sa"); bwt_restore_sa(str, bwt[0]); + + // load reverse BWT and SA + strcpy(str, prefix); strcat(str, ".rbwt"); bwt[1] = bwt_restore_bwt(str); + strcpy(str, prefix); strcat(str, ".rsa"); bwt_restore_sa(str, bwt[1]); + //*************** + + // initialization + bwase_initialize(); + bns = bns_restore(prefix); + srand48(bns->seed); + ks = bwa_seq_open(fn_fa); + fp_sa = xopen(fn_sa, "r"); + + pacseq = (ubyte_t*)calloc(bns->l_pac/4+1, 1); + rewind(bns->fp_pac); + fread(pacseq, 1, bns->l_pac/4+1, bns->fp_pac); + + + // core loop + m_aln = 0; + m_rest = 0; + + fread(&opt, sizeof(gap_opt_t), 1, fp_sa); + if (!(opt.mode & BWA_MODE_COMPREAD)) // in color space; initialize ntpac + ntbns = bwa_open_nt(prefix); + bwa_print_sam_SQ(bns); + + fprintf(stderr, "%.2f sec\n", (float)(clock()-t) / CLOCKS_PER_SEC); + + t = clock(); + + max_extra_occ++; // now this variable holds TOTAL number of alignments we want to print (1+requested extra). + + while ((seqs = bwa_read_seq(ks, 0x40000, &n_seqs, opt.mode & BWA_MODE_COMPREAD, opt.trim_qual)) != 0) { + tot_seqs += n_seqs; + t_convert = 0; + t_refine = 0; + t_write = 0; + + fprintf(stderr, "[bwa_aln_core] %d sequences loaded: ",n_seqs); + fprintf(stderr, "%.2f sec\n", (float)(clock()-t) / CLOCKS_PER_SEC); + + + // read alignment + for (i = 0; i < n_seqs; ++i) { + + bwa_seq_t *p = seqs + i; + int n_aln, n_occ, k, rest; + fread(&n_aln, 4, 1, fp_sa); + if (n_aln > m_aln) { + m_aln = n_aln; + aln = (bwt_aln1_t*)realloc(aln, sizeof(bwt_aln1_t) * m_aln); + } + + fread(aln, sizeof(bwt_aln1_t), n_aln, fp_sa); + for ( k = n_occ = 0 ; k < n_aln; ++k ) { + const bwt_aln1_t *q = aln + k; + n_occ += q->l - q->k + 1; + } /* n_occ is now keeping total number of available alignments to the reference + (i.e. placements, NOT bwa records, each of which can describe few placements) + */ + + // we are going to keep and print 'rest' alignments: + rest = ((n_occ > max_extra_occ)? max_extra_occ : n_occ); + + if ( rest == 0 ) rest++; /* we need at least one record, even if it is going to say "UNMAPPED" */ + + if ( rest > m_rest ) { + // reallocate rest_seqs array (only if needed) to ensure it can keep 'rest' records + m_rest = rest; + rest_seqs = (bwa_seq_t*)realloc(rest_seqs,sizeof(bwa_seq_t)*m_rest); + } + // initialize 'rest' replicas of the current sequence record + for ( k = 0 ; k < rest ; k++ ) { + rest_seqs[k] = *p; /* clone current sequence p; IMPORTANT: it's a shallow copy */ + } + + bwa_aln2seq_all(n_aln, aln, rest,rest_seqs); + // now each of the replicas carries its own bwa alignment selected from all alignments + // available for the current sequence *p. + + /* compute positions of the alignments on the ref: */ + t = clock(); + + bwa_cal_pac_pos_core(bwt[0],bwt[1], rest, rest_seqs, opt.max_diff, opt.fnr ); + t_convert += ( clock() - t ); + *p = rest_seqs[0]; // copy first selected alignment back into p; + + seq_reverse(p->len, p->seq,0); + + /* compute positions of the alignments on the ref: */ + t = clock(); + + bwa_cal_pac_pos_core(bwt[0],bwt[1], rest, rest_seqs, opt.max_diff, opt.fnr ); + t_convert += ( clock() - t ); + + t = clock(); + + bwa_refine_gapped(bns,rest,rest_seqs,pacseq,ntbns); // refine all gapped aligns in our replicas; + // side effect: cigars will be allocated for each replica + t_refine += ( clock() - t ); + + t = clock(); + // for ( k = 0 ; k < n_seqs ; k++ ) { + for ( k = 0 ; k < rest ; k++ ) { + + bwa_print_sam1(bns, rest_seqs + k, 0, opt.mode, opt.max_top2); + // cigar was allocated for us in every replica as a side effect, free it now: + free ( (rest_seqs+k)->cigar ); + } + t_write+= ( clock()-t); + + } + + bwa_free_read_seq(n_seqs, seqs); + + fprintf(stderr, "[bwa_aln_core] convert %d sequences to sequence coordinate: ",n_seqs); + fprintf(stderr, "%.2f sec\n", (float)t_convert / CLOCKS_PER_SEC); + fprintf(stderr, "[bwa_aln_core] refine gapped alignments for %d sequences: ", n_seqs); + fprintf(stderr, "%.2f sec\n", (float)t_refine / CLOCKS_PER_SEC); + fprintf(stderr, "[bwa_aln_core] print alignments for %d sequences: ", n_seqs); + fprintf(stderr, "%.2f sec\n", (float)t_write/ CLOCKS_PER_SEC); + fprintf(stderr, "[bwa_aln_core] %d sequences have been processed.\n", tot_seqs); + + t = clock(); + } + + // destroy + bwt_destroy(bwt[0]); + bwt_destroy(bwt[1]); + + free(rest_seqs); + free(pacseq); + + bwa_seq_close(ks); + if (ntbns) bns_destroy(ntbns); + bns_destroy(bns); + fclose(fp_sa); + free(aln); +} + +int bwa_sai2sam_se(int argc, char *argv[]) +{ + int c, n_occ = 3; + int do_full_sam = 0; + while ((c = getopt(argc, argv, "hsn:f:")) >= 0) { + switch (c) { + case 'h': break; + case 's': do_full_sam = 1; break; + case 'n': n_occ = atoi(optarg); break; + case 'f': freopen(optarg, "w", stdout); break; + default: return 1; + } + } + + if (optind + 3 > argc) { + fprintf(stderr, "Usage: bwa samse [-n max_occ [-s] ] [-f out.sam] <prefix> <in.sai> <in.fq>\n"); + return 1; + } + if ( do_full_sam ) bwa_print_all_hits(argv[optind], argv[optind+1], argv[optind+2], n_occ); + else bwa_sai2sam_se_core(argv[optind], argv[optind+1], argv[optind+2], n_occ); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwase.c~ Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,977 @@ +#include <unistd.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <time.h> +#include "stdaln.h" +#include "bwase.h" +#include "bwtaln.h" +#include "bntseq.h" +#include "utils.h" +#include "kstring.h" + +static int g_log_n[256]; + +void bwa_aln2seq_core(int n_aln, const bwt_aln1_t *aln, bwa_seq_t *s, int set_main, int n_multi) +{ + int i, cnt, best; + if (n_aln == 0) { + s->type = BWA_TYPE_NO_MATCH; + s->c1 = s->c2 = 0; + return; + } + + if (set_main) { + best = aln[0].score; + for (i = cnt = 0; i < n_aln; ++i) { + const bwt_aln1_t *p = aln + i; + if (p->score > best) break; + if (drand48() * (p->l - p->k + 1) > (double)cnt) { + s->n_mm = p->n_mm; s->n_gapo = p->n_gapo; s->n_gape = p->n_gape; s->strand = p->a; + s->score = p->score; + s->sa = p->k + (bwtint_t)((p->l - p->k + 1) * drand48()); + } + cnt += p->l - p->k + 1; + } + s->c1 = cnt; + for (; i < n_aln; ++i) cnt += aln[i].l - aln[i].k + 1; + s->c2 = cnt - s->c1; + s->type = s->c1 > 1? BWA_TYPE_REPEAT : BWA_TYPE_UNIQUE; + } + + if (n_multi) { + int k, rest, n_occ, z = 0; + for (k = n_occ = 0; k < n_aln; ++k) { + const bwt_aln1_t *q = aln + k; + n_occ += q->l - q->k + 1; + } + if (s->multi) free(s->multi); + if (n_occ > n_multi + 1) { // if there are too many hits, generate none of them + s->multi = 0; s->n_multi = 0; + return; + } + /* The following code is more flexible than what is required + * here. In principle, due to the requirement above, we can + * simply output all hits, but the following samples "rest" + * number of random hits. */ + rest = n_occ > n_multi + 1? n_multi + 1 : n_occ; // find one additional for ->sa + s->multi = calloc(rest, rest * sizeof(bwt_multi1_t)); + for (k = 0; k < n_aln; ++k) { + const bwt_aln1_t *q = aln + k; + if (q->l - q->k + 1 <= rest) { + bwtint_t l; + for (l = q->k; l <= q->l; ++l) { + s->multi[z].pos = l; + s->multi[z].gap = q->n_gapo + q->n_gape; + s->multi[z].mm = q->n_mm; + s->multi[z++].strand = q->a; + } + rest -= q->l - q->k + 1; + } else { // Random sampling (http://code.activestate.com/recipes/272884/). In fact, we never come here. + int j, i, k; + for (j = rest, i = q->l - q->k + 1, k = 0; j > 0; --j) { + double p = 1.0, x = drand48(); + while (x < p) p -= p * j / (i--); + s->multi[z].pos = q->l - i; + s->multi[z].gap = q->n_gapo + q->n_gape; + s->multi[z].mm = q->n_mm; + s->multi[z++].strand = q->a; + } + rest = 0; + break; + } + } + s->n_multi = z; + for (k = z = 0; k < s->n_multi; ++k) + if (s->multi[k].pos != s->sa) + s->multi[z++] = s->multi[k]; + s->n_multi = z < n_multi? z : n_multi; + } +} + +void bwa_aln2seq(int n_aln, const bwt_aln1_t *aln, bwa_seq_t *s) +{ + bwa_aln2seq_core(n_aln, aln, s, 1, 0); +} + +/* *aln points to alignments found for the current sequence, n_aln is the + size of the array pointed to by *aln. Array *s of size n_seq is a collection + of SAM records that must be replicas, i.e. initialized with the same current sequence. + This method updates sequence records in *s with placements recorded in *aln, + until all n_seq replicas are updated. For each separate alignment record in array *aln, + each placement corresponding to this record will be assigned to a separate record in *s + if there are enough elements remaining in *s, otherwise a random subset of the placements will + be assigned to the remaining elements in *s. The total number of best placements and total + number of non-best placements will be computed from the whole array *aln (regardless of whether it + fits completely into *s or not) and assigned to each updated record in *s. +*/ +void bwa_aln2seq_all(int n_aln, const bwt_aln1_t *aln, int n_seq, bwa_seq_t *s) +{ + int i, cnt1, cnt2, j, best, N; + if (n_aln == 0) { + /* there is no match found for *s */ + s->type = BWA_TYPE_NO_MATCH; + s->c1 = s->c2 = 0; + return; + } + + N = n_seq; // remember the size of the array + best = aln[0].score; + + cnt1 = 0; // total number of already processed alignments (i.e. distinct placements, NOT alignment records) with best score + cnt2 = 0; // total number of already processed alignments with inferior score(s) + for (i = 0; i < n_aln && n_seq > 0 ; ++i) { + const bwt_aln1_t *p_aln = aln + i; + + int N_aligns = p_aln->l-p_aln->k +1 ; // number of placements (alignments) in the current alignment record p_aln + + if (N_aligns <= n_seq) { /* we have space to save all the alignments stored in 'p_aln' */ + + for ( j = 0 ; j < N_aligns ; j++ ) { + + bwa_seq_t * seq = s + cnt1+ cnt2+j ; + seq->n_mm = p_aln->n_mm; seq->n_gapo = p_aln->n_gapo; seq->n_gape = p_aln->n_gape; seq->strand = p_aln->a; + seq->score = p_aln->score; + seq->sa = p_aln->k + j; + } + n_seq -= N_aligns; // we have n_seq slots remaining to store more alignments + } else { // See also: http://code.activestate.com/recipes/272884/ + // we have to truncate, so let's select few remaining alignments randomly: + int xj, xi, xk; + for (xj = n_seq, xi = N_aligns, xk = 0; xj > 0; --xj, ++xk) { + double p = 1.0, x = drand48(); + while (x < p) p -= p * xj / (xi--); + + bwa_seq_t * seq = s+cnt1+cnt2+xk ; + seq->n_mm = p_aln->n_mm; seq->n_gapo = p_aln->n_gapo; seq->n_gape = p_aln->n_gape; seq->strand = p_aln->a; + seq->score = p_aln->score; + seq->sa = p_aln->l - xi; + + } + n_seq = 0; + } + // cnt1 + cnt2 is the total count of hits processed so far: + if ( p_aln->score == best ) cnt1 += N_aligns; // we found N_aligns more placements with best score + else cnt2 += N_aligns; // N_aligns more placements with inferior score + } + + // we filled all available slots in the array *s, but there can be more alignments + // left; we need to count them: + for (; i < n_aln; ++i) { + if ( aln[i].score == best ) cnt1 += aln[i].l-aln[i].k+1; + else cnt2 += aln[i].l-aln[i].k+1; + } + + // now cnt1 is the total number of found alignments (placements) with best score + // and cnt2 is the total number of found placements with worse score + + /* set counts and flags for all hits: */ + for (i = 0; i < N ; ++i) { + bwa_seq_t * seq = s+i ; + + seq->c1 = cnt1; + seq->c2 = cnt2; + seq->type = seq->c1 > 1? BWA_TYPE_REPEAT : BWA_TYPE_UNIQUE; + } +} + + + +int bwa_approx_mapQ(const bwa_seq_t *p, int mm) +{ + int n; + if (p->c1 == 0) return 23; + if (p->c1 > 1) return 0; + if (p->n_mm == mm) return 25; + if (p->c2 == 0) return 37; + n = (p->c2 >= 255)? 255 : p->c2; + return (23 < g_log_n[n])? 0 : 23 - g_log_n[n]; +} + +/** + * Derive the actual position in the read from the given suffix array + * coordinates. Note that the position will be approximate based on + * whether indels appear in the read and whether calculations are + * performed from the start or end of the read. + */ +void bwa_cal_pac_pos_core(const bwt_t *forward_bwt, const bwt_t *reverse_bwt, int n_seqs, bwa_seq_t *s, const int max_mm, const float fnr) +{ + int max_diff; + bwa_seq_t *seq; + int i; + + for ( i = 0 ; i < n_seqs ; i++ ) { + seq = s + i; + if (seq->type != BWA_TYPE_UNIQUE && seq->type != BWA_TYPE_REPEAT) continue; + + max_diff = fnr > 0.0? bwa_cal_maxdiff(seq->len, BWA_AVG_ERR, fnr) : max_mm; + if (seq->strand) { // reverse strand only + seq->pos = bwt_sa(forward_bwt, seq->sa); + seq->seQ = seq->mapQ = bwa_approx_mapQ(seq, max_diff); + } else { // forward strand only + /* NB: For gapped alignment, p->pos may not be correct, which + * will be fixed in refine_gapped_core(). This line also + * determines the way "x" is calculated in + * refine_gapped_core() when (ext < 0 && is_end == 0). */ + seq->pos = reverse_bwt->seq_len - (bwt_sa(reverse_bwt, seq->sa) + seq->len); + seq->seQ = seq->mapQ = bwa_approx_mapQ(seq, max_diff); + } + } +} + +void bwa_cal_pac_pos(const char *prefix, int n_seqs, bwa_seq_t *seqs, int max_mm, float fnr) +{ + int i, j; + char str[1024]; + bwt_t *bwt; + // load forward SA + strcpy(str, prefix); strcat(str, ".bwt"); bwt = bwt_restore_bwt(str); + strcpy(str, prefix); strcat(str, ".sa"); bwt_restore_sa(str, bwt); + for (i = 0; i != n_seqs; ++i) { + if (seqs[i].strand) bwa_cal_pac_pos_core(bwt, 0, 1, &seqs[i], max_mm, fnr); + for (j = 0; j < seqs[i].n_multi; ++j) { + bwt_multi1_t *p = seqs[i].multi + j; + if (p->strand) p->pos = bwt_sa(bwt, p->pos); + } + } + bwt_destroy(bwt); + // load reverse BWT and SA + strcpy(str, prefix); strcat(str, ".rbwt"); bwt = bwt_restore_bwt(str); + strcpy(str, prefix); strcat(str, ".rsa"); bwt_restore_sa(str, bwt); + for (i = 0; i != n_seqs; ++i) { + if (!seqs[i].strand) bwa_cal_pac_pos_core(0, bwt, 1, &seqs[i], max_mm, fnr); + for (j = 0; j < seqs[i].n_multi; ++j) { + bwt_multi1_t *p = seqs[i].multi + j; + if (!p->strand) p->pos = bwt->seq_len - (bwt_sa(bwt, p->pos) + seqs[i].len); + } + } + bwt_destroy(bwt); +} + +/* is_end_correct == 1 if (*pos+len) gives the correct coordinate on + * forward strand. This happens when p->pos is calculated by + * bwa_cal_pac_pos(). is_end_correct==0 if (*pos) gives the correct + * coordinate. This happens only for color-converted alignment. */ +static bwa_cigar_t *refine_gapped_core(bwtint_t l_pac, const ubyte_t *pacseq, int len, const ubyte_t *seq, bwtint_t *_pos, + int ext, int *n_cigar, int is_end_correct) +{ + bwa_cigar_t *cigar = 0; + ubyte_t *ref_seq; + int l = 0, path_len, ref_len; + AlnParam ap = aln_param_bwa; + path_t *path; + int64_t k, __pos = *_pos > l_pac? (int64_t)((int32_t)*_pos) : *_pos; + + ref_len = len + abs(ext); + if (ext > 0) { + ref_seq = (ubyte_t*)calloc(ref_len, 1); + for (k = __pos; k < __pos + ref_len && k < l_pac; ++k) + ref_seq[l++] = pacseq[k>>2] >> ((~k&3)<<1) & 3; + } else { + int64_t x = __pos + (is_end_correct? len : ref_len); + ref_seq = (ubyte_t*)calloc(ref_len, 1); + for (l = 0, k = x - ref_len > 0? x - ref_len : 0; k < x && k < l_pac; ++k) + ref_seq[l++] = pacseq[k>>2] >> ((~k&3)<<1) & 3; + } + path = (path_t*)calloc(l+len, sizeof(path_t)); + + aln_global_core(ref_seq, l, (ubyte_t*)seq, len, &ap, path, &path_len); + cigar = bwa_aln_path2cigar(path, path_len, n_cigar); + + if (ext < 0 && is_end_correct) { // fix coordinate for reads mapped on the forward strand + for (l = k = 0; k < *n_cigar; ++k) { + if (__cigar_op(cigar[k]) == FROM_D) l -= __cigar_len(cigar[k]); + else if (__cigar_op(cigar[k]) == FROM_I) l += __cigar_len(cigar[k]); + } + __pos += l; + } + + if (__cigar_op(cigar[0]) == FROM_D) { // deletion at the 5'-end + __pos += __cigar_len(cigar[0]); + for (k = 0; k < *n_cigar - 1; ++k) cigar[k] = cigar[k+1]; + --(*n_cigar); + } + if (__cigar_op(cigar[*n_cigar-1]) == FROM_D) --(*n_cigar); // deletion at the 3'-end + + // change "I" at either end of the read to S. just in case. This should rarely happen... + if (__cigar_op(cigar[*n_cigar-1]) == FROM_I) cigar[*n_cigar-1] = __cigar_create(3, (__cigar_len(cigar[*n_cigar-1]))); + if (__cigar_op(cigar[0]) == FROM_I) cigar[0] = __cigar_create(3, (__cigar_len(cigar[0]))); + + *_pos = (bwtint_t)__pos; + free(ref_seq); free(path); + return cigar; +} + +char *bwa_cal_md1(int n_cigar, bwa_cigar_t *cigar, int len, bwtint_t pos, ubyte_t *seq, + bwtint_t l_pac, ubyte_t *pacseq, kstring_t *str, int *_nm) +{ + bwtint_t x, y; + int z, u, c, nm = 0; + str->l = 0; // reset + x = pos; y = 0; + if (cigar) { + int k, l; + for (k = u = 0; k < n_cigar; ++k) { + l = __cigar_len(cigar[k]); + if (__cigar_op(cigar[k]) == FROM_M) { + for (z = 0; z < l && x+z < l_pac; ++z) { + c = pacseq[(x+z)>>2] >> ((~(x+z)&3)<<1) & 3; + if (c > 3 || seq[y+z] > 3 || c != seq[y+z]) { + ksprintf(str, "%d", u); + kputc("ACGTN"[c], str); + ++nm; + u = 0; + } else ++u; + } + x += l; y += l; +/* } else if (cigar[k]>>14 == FROM_I || cigar[k]>>14 == 3) { */ + } else if (__cigar_op(cigar[k]) == FROM_I || __cigar_op(cigar[k]) == FROM_S) { + y += l; + if (__cigar_op(cigar[k]) == FROM_I) nm += l; + } else if (__cigar_op(cigar[k]) == FROM_D) { + ksprintf(str, "%d", u); + kputc('^', str); + for (z = 0; z < l && x+z < l_pac; ++z) + kputc("ACGT"[pacseq[(x+z)>>2] >> ((~(x+z)&3)<<1) & 3], str); + u = 0; + x += l; nm += l; + } + } + } else { // no gaps + for (z = u = 0; z < (bwtint_t)len; ++z) { + c = pacseq[(x+z)>>2] >> ((~(x+z)&3)<<1) & 3; + if (c > 3 || seq[y+z] > 3 || c != seq[y+z]) { + ksprintf(str, "%d", u); + kputc("ACGTN"[c], str); + ++nm; + u = 0; + } else ++u; + } + } + ksprintf(str, "%d", u); + *_nm = nm; + return strdup(str->s); +} + +void bwa_correct_trimmed(bwa_seq_t *s) +{ + if (s->len == s->full_len) return; + if (s->strand == 0) { // forward + if (s->cigar && __cigar_op(s->cigar[s->n_cigar-1]) == FROM_S) { // the last is S + s->cigar[s->n_cigar-1] += s->full_len - s->len; + } else { + if (s->cigar == 0) { + s->n_cigar = 2; + s->cigar = calloc(s->n_cigar, sizeof(bwa_cigar_t)); + s->cigar[0] = __cigar_create(0, s->len); + } else { + ++s->n_cigar; + s->cigar = realloc(s->cigar, s->n_cigar * sizeof(bwa_cigar_t)); + } + s->cigar[s->n_cigar-1] = __cigar_create(3, (s->full_len - s->len)); + } + } else { // reverse + if (s->cigar && __cigar_op(s->cigar[0]) == FROM_S) { // the first is S + s->cigar[0] += s->full_len - s->len; + } else { + if (s->cigar == 0) { + s->n_cigar = 2; + s->cigar = calloc(s->n_cigar, sizeof(bwa_cigar_t)); + s->cigar[1] = __cigar_create(0, s->len); + } else { + ++s->n_cigar; + s->cigar = realloc(s->cigar, s->n_cigar * sizeof(bwa_cigar_t)); + memmove(s->cigar + 1, s->cigar, (s->n_cigar-1) * sizeof(bwa_cigar_t)); + } + s->cigar[0] = __cigar_create(3, (s->full_len - s->len)); + } + } + s->len = s->full_len; +} + +void bwa_refine_gapped(const bntseq_t *bns, int n_seqs, bwa_seq_t *seqs, ubyte_t *_pacseq, bntseq_t *ntbns) +{ + ubyte_t *pacseq, *ntpac = 0; + int i, j; + kstring_t *str; + + if (ntbns) { // in color space + ntpac = (ubyte_t*)calloc(ntbns->l_pac/4+1, 1); + rewind(ntbns->fp_pac); + fread(ntpac, 1, ntbns->l_pac/4 + 1, ntbns->fp_pac); + } + + if (!_pacseq) { + pacseq = (ubyte_t*)calloc(bns->l_pac/4+1, 1); + rewind(bns->fp_pac); + fread(pacseq, 1, bns->l_pac/4+1, bns->fp_pac); + } else pacseq = _pacseq; + for (i = 0; i != n_seqs; ++i) { + bwa_seq_t *s = seqs + i; + seq_reverse(s->len, s->seq, 0); // IMPORTANT: s->seq is reversed here!!! + for (j = 0; j < s->n_multi; ++j) { + bwt_multi1_t *q = s->multi + j; + int n_cigar; + if (q->gap == 0) continue; + q->cigar = refine_gapped_core(bns->l_pac, pacseq, s->len, q->strand? s->rseq : s->seq, &q->pos, + (q->strand? 1 : -1) * q->gap, &n_cigar, 1); + q->n_cigar = n_cigar; + } + if (s->type == BWA_TYPE_NO_MATCH || s->type == BWA_TYPE_MATESW || s->n_gapo == 0) continue; + s->cigar = refine_gapped_core(bns->l_pac, pacseq, s->len, s->strand? s->rseq : s->seq, &s->pos, + (s->strand? 1 : -1) * (s->n_gapo + s->n_gape), &s->n_cigar, 1); + } + + if (ntbns) { // in color space + for (i = 0; i < n_seqs; ++i) { + bwa_seq_t *s = seqs + i; + bwa_cs2nt_core(s, bns->l_pac, ntpac); + for (j = 0; j < s->n_multi; ++j) { + bwt_multi1_t *q = s->multi + j; + int n_cigar; + if (q->gap == 0) continue; + free(q->cigar); + q->cigar = refine_gapped_core(bns->l_pac, ntpac, s->len, q->strand? s->rseq : s->seq, &q->pos, + (q->strand? 1 : -1) * q->gap, &n_cigar, 0); + q->n_cigar = n_cigar; + } + if (s->type != BWA_TYPE_NO_MATCH && s->cigar) { // update cigar again + free(s->cigar); + s->cigar = refine_gapped_core(bns->l_pac, ntpac, s->len, s->strand? s->rseq : s->seq, &s->pos, + (s->strand? 1 : -1) * (s->n_gapo + s->n_gape), &s->n_cigar, 0); + } + } + } + + // generate MD tag + str = (kstring_t*)calloc(1, sizeof(kstring_t)); + for (i = 0; i != n_seqs; ++i) { + bwa_seq_t *s = seqs + i; + if (s->type != BWA_TYPE_NO_MATCH) { + int nm; + s->md = bwa_cal_md1(s->n_cigar, s->cigar, s->len, s->pos, s->strand? s->rseq : s->seq, + bns->l_pac, ntbns? ntpac : pacseq, str, &nm); + s->nm = nm; + } + } + free(str->s); free(str); + + // correct for trimmed reads + if (!ntbns) // trimming is only enabled for Illumina reads + for (i = 0; i < n_seqs; ++i) bwa_correct_trimmed(seqs + i); + + if (!_pacseq) free(pacseq); + free(ntpac); +} + +int64_t pos_end(const bwa_seq_t *p) +{ + if (p->cigar) { + int j; + int64_t x = p->pos; + for (j = 0; j != p->n_cigar; ++j) { + int op = __cigar_op(p->cigar[j]); + if (op == 0 || op == 2) x += __cigar_len(p->cigar[j]); + } + return x; + } else return p->pos + p->len; +} + +int64_t pos_end_multi(const bwt_multi1_t *p, int len) // analogy to pos_end() +{ + if (p->cigar) { + int j; + int64_t x = p->pos; + for (j = 0; j != p->n_cigar; ++j) { + int op = __cigar_op(p->cigar[j]); + if (op == 0 || op == 2) x += __cigar_len(p->cigar[j]); + } + return x; + } else return p->pos + len; +} + +static int64_t pos_5(const bwa_seq_t *p) +{ + if (p->type != BWA_TYPE_NO_MATCH) + return p->strand? pos_end(p) : p->pos; + return -1; +} + +/* Prints <bases>\t<quals> of the sequence *p into STDOUT; +*/ +void bwa_print_seq_and_qual(bwa_seq_t *p) { + int j; + + if (p->strand == 0) + for (j = 0; j != p->full_len; ++j) putchar("ACGTN"[(int)p->seq[j]]); + else for (j = 0; j != p->full_len; ++j) putchar("TGCAN"[p->seq[p->full_len - 1 - j]]); + putchar('\t'); + if (p->qual) { + if (p->strand) seq_reverse(p->len, p->qual, 0); // reverse quality + printf("%s", p->qual); + } else printf("*"); + +} + + + +void bwa_print_sam1(const bntseq_t *bns, bwa_seq_t *p, const bwa_seq_t *mate, int mode, int max_top2) +{ + int j; + if (p->type != BWA_TYPE_NO_MATCH || (mate && mate->type != BWA_TYPE_NO_MATCH)) { + int seqid, nn, am = 0, flag = p->extra_flag; + char XT; + + if (p->type == BWA_TYPE_NO_MATCH) { + p->pos = mate->pos; + p->strand = mate->strand; + flag |= SAM_FSU; + j = 1; + } else j = pos_end(p) - p->pos; // j is the length of the reference in the alignment + + // get seqid + nn = bns_coor_pac2real(bns, p->pos, j, &seqid); + if (p->type != BWA_TYPE_NO_MATCH && p->pos + j - bns->anns[seqid].offset > bns->anns[seqid].len) + flag |= SAM_FSU; // flag UNMAP as this alignment bridges two adjacent reference sequences + + // update flag and print it + if (p->strand) flag |= SAM_FSR; + if (mate) { + if (mate->type != BWA_TYPE_NO_MATCH) { + if (mate->strand) flag |= SAM_FMR; + } else flag |= SAM_FMU; + } + printf("%s\t%d\t%s\t", p->name, flag, bns->anns[seqid].name); + printf("%d\t%d\t", (int)(p->pos - bns->anns[seqid].offset + 1), p->mapQ); + + // print CIGAR + if (p->cigar) { + for (j = 0; j != p->n_cigar; ++j) + printf("%d%c", __cigar_len(p->cigar[j]), "MIDS"[__cigar_op(p->cigar[j])]); + } else if (p->type == BWA_TYPE_NO_MATCH) printf("*"); + else printf("%dM", p->len); + + // print mate coordinate + if (mate && mate->type != BWA_TYPE_NO_MATCH) { + int m_seqid, m_is_N; + long long isize; + am = mate->seQ < p->seQ? mate->seQ : p->seQ; // smaller single-end mapping quality + // redundant calculation here, but should not matter too much + m_is_N = bns_coor_pac2real(bns, mate->pos, mate->len, &m_seqid); + printf("\t%s\t", (seqid == m_seqid)? "=" : bns->anns[m_seqid].name); + isize = (seqid == m_seqid)? pos_5(mate) - pos_5(p) : 0; + if (p->type == BWA_TYPE_NO_MATCH) isize = 0; + printf("%d\t%lld\t", (int)(mate->pos - bns->anns[m_seqid].offset + 1), isize); + } else if (mate) printf("\t=\t%d\t0\t", (int)(p->pos - bns->anns[seqid].offset + 1)); + else printf("\t*\t0\t0\t"); + + // print sequence and quality + bwa_print_seq_and_qual(p); + + if (p->clip_len < p->full_len) printf("\tXC:i:%d", p->clip_len); + if (p->type != BWA_TYPE_NO_MATCH) { + int i; + // calculate XT tag + XT = "NURM"[p->type]; + if (nn > 10) XT = 'N'; + // print tags + printf("\tXT:A:%c\t%s:i:%d", XT, (mode & BWA_MODE_COMPREAD)? "NM" : "CM", p->nm); + if (nn) printf("\tXN:i:%d", nn); + if (mate) printf("\tSM:i:%d\tAM:i:%d", p->seQ, am); + if (p->type != BWA_TYPE_MATESW) { // X0 and X1 are not available for this type of alignment + printf("\tX0:i:%d", p->c1); + if (p->c1 <= max_top2) printf("\tX1:i:%d", p->c2); + } + printf("\tXM:i:%d\tXO:i:%d\tXG:i:%d", p->n_mm, p->n_gapo, p->n_gapo+p->n_gape); + if (p->md) printf("\tMD:Z:%s", p->md); + // print multiple hits + if (p->n_multi) { + printf("\tXA:Z:"); + for (i = 0; i < p->n_multi; ++i) { + bwt_multi1_t *q = p->multi + i; + int k; + j = pos_end_multi(q, p->len) - q->pos; + nn = bns_coor_pac2real(bns, q->pos, j, &seqid); + printf("%s,%c%d,", bns->anns[seqid].name, q->strand? '-' : '+', + (int)(q->pos - bns->anns[seqid].offset + 1)); + if (q->cigar) { + for (k = 0; k < q->n_cigar; ++k) + printf("%d%c", __cigar_len(q->cigar[k]), "MIDS"[__cigar_op(q->cigar[k])]); + } else printf("%dM", p->len); + printf(",%d;", q->gap + q->mm); + } + } + } + putchar('\n'); + } else { // this read has no match + ubyte_t *s = p->strand? p->rseq : p->seq; + int flag = p->extra_flag | SAM_FSU; + if (mate && mate->type == BWA_TYPE_NO_MATCH) flag |= SAM_FMU; + printf("%s\t%d\t*\t0\t0\t*\t*\t0\t0\t", p->name, flag); + for (j = 0; j != p->len; ++j) putchar("ACGTN"[(int)s[j]]); + putchar('\t'); + if (p->qual) { + if (p->strand) seq_reverse(p->len, p->qual, 0); // reverse quality + printf("%s", p->qual); + } else printf("*"); + if (p->clip_len < p->full_len) printf("\tXC:i:%d", p->clip_len); + putchar('\n'); + } +} + +/* UNUSED +void bwa_print_partial_sam1(const bntseq_t *bns, bwa_seq_t *p, const bwa_seq_t *mate, int mode, int max_top2) +{ + int j; + if (p->type != BWA_TYPE_NO_MATCH || (mate && mate->type != BWA_TYPE_NO_MATCH)) { + int seqid, nn, am = 0, flag = p->extra_flag; + char XT; + + if (p->type == BWA_TYPE_NO_MATCH) { + p->pos = mate->pos; + p->strand = mate->strand; + flag |= SAM_FSU; + j = 1; + } else j = pos_end(p) - p->pos; // j is the length of the reference in the alignment + + // get seqid + nn = bns_coor_pac2real(bns, p->pos, j, &seqid); + if (p->type != BWA_TYPE_NO_MATCH && p->pos + j - bns->anns[seqid].offset > bns->anns[seqid].len) + flag |= SAM_FSU; // flag UNMAP as this alignment bridges two adjacent reference sequences + + // update flag and print it + if (p->strand) flag |= SAM_FSR; + if (mate) { + if (mate->type != BWA_TYPE_NO_MATCH) { + if (mate->strand) flag |= SAM_FMR; + } else flag |= SAM_FMU; + } + printf("%s\t%d\t%s\t", p->name, flag, bns->anns[seqid].name); + printf("%d\t%d\t", (int)(p->pos - bns->anns[seqid].offset + 1), p->mapQ); + + // print CIGAR + if (p->cigar) { + for (j = 0; j != p->n_cigar; ++j) + printf("%d%c", __cigar_len(p->cigar[j]), "MIDS"[__cigar_op(p->cigar[j])]); + } else if (p->type == BWA_TYPE_NO_MATCH) printf("*"); + else printf("%dM", p->len); + + // print mate coordinate + if (mate && mate->type != BWA_TYPE_NO_MATCH) { + int m_seqid, m_is_N; + long long isize; + am = mate->seQ < p->seQ? mate->seQ : p->seQ; // smaller single-end mapping quality + // redundant calculation here, but should not matter too much + m_is_N = bns_coor_pac2real(bns, mate->pos, mate->len, &m_seqid); + printf("\t%s\t", (seqid == m_seqid)? "=" : bns->anns[m_seqid].name); + isize = (seqid == m_seqid)? pos_5(mate) - pos_5(p) : 0; + if (p->type == BWA_TYPE_NO_MATCH) isize = 0; + printf("%d\t%lld\t", (int)(mate->pos - bns->anns[m_seqid].offset + 1), isize); + } else if (mate) printf("\t=\t%d\t0\t", (int)(p->pos - bns->anns[seqid].offset + 1)); + else printf("\t*\t0\t0\t"); + + + if (p->clip_len < p->full_len) printf("\tXC:i:%d", p->clip_len); + if (p->type != BWA_TYPE_NO_MATCH) { + int i; + // calculate XT tag + XT = "NURM"[p->type]; + if (nn > 10) XT = 'N'; + // print tags + printf("\tXT:A:%c\t%s:i:%d", XT, (mode & BWA_MODE_COMPREAD)? "NM" : "CM", p->nm); + if (nn) printf("\tXN:i:%d", nn); + if (mate) printf("\tSM:i:%d\tAM:i:%d", p->seQ, am); + printf("\tXM:i:%d\tXO:i:%d\tXG:i:%d", p->n_mm, p->n_gapo, p->n_gapo+p->n_gape); + if (p->md) printf("\tMD:Z:%s", p->md); + } + putchar('\n'); + } else { // this read has no match + ubyte_t *s = p->strand? p->rseq : p->seq; + int flag = p->extra_flag | SAM_FSU; + if (mate && mate->type == BWA_TYPE_NO_MATCH) flag |= SAM_FMU; + printf("%d\t*\t0\t0\t*\t*\t0\t0\t", flag); + if (p->clip_len < p->full_len) printf("\tXC:i:%d", p->clip_len); + putchar('\n'); + } +} + +*/ + +bntseq_t *bwa_open_nt(const char *prefix) +{ + bntseq_t *ntbns; + char *str; + str = (char*)calloc(strlen(prefix) + 10, 1); + strcat(strcpy(str, prefix), ".nt"); + ntbns = bns_restore(str); + free(str); + return ntbns; +} + +void bwa_print_sam_SQ(const bntseq_t *bns) +{ + int i; + for (i = 0; i < bns->n_seqs; ++i) + printf("@SQ\tSN:%s\tLN:%d\n", bns->anns[i].name, bns->anns[i].len); +} + +void bwase_initialize() +{ + int i; + for (i = 1; i != 256; ++i) g_log_n[i] = (int)(4.343 * log(i) + 0.5); +} + +void bwa_sai2sam_se_core(const char *prefix, const char *fn_sa, const char *fn_fa, int n_occ) +{ + int i, n_seqs, tot_seqs = 0, m_aln; + bwt_aln1_t *aln = 0; + bwa_seq_t *seqs; + bwa_seqio_t *ks; + clock_t t; + bntseq_t *bns, *ntbns = 0; + FILE *fp_sa; + gap_opt_t opt; + + // initialization + bwase_initialize(); + bns = bns_restore(prefix); + srand48(bns->seed); + ks = bwa_seq_open(fn_fa); + fp_sa = xopen(fn_sa, "r"); + + // core loop + m_aln = 0; + fread(&opt, sizeof(gap_opt_t), 1, fp_sa); + if (!(opt.mode & BWA_MODE_COMPREAD)) // in color space; initialize ntpac + ntbns = bwa_open_nt(prefix); + bwa_print_sam_SQ(bns); + while ((seqs = bwa_read_seq(ks, 0x40000, &n_seqs, opt.mode & BWA_MODE_COMPREAD, opt.trim_qual)) != 0) { + tot_seqs += n_seqs; + t = clock(); + + // read alignment + for (i = 0; i < n_seqs; ++i) { + bwa_seq_t *p = seqs + i; + int n_aln; + fread(&n_aln, 4, 1, fp_sa); + if (n_aln > m_aln) { + m_aln = n_aln; + aln = (bwt_aln1_t*)realloc(aln, sizeof(bwt_aln1_t) * m_aln); + } + fread(aln, sizeof(bwt_aln1_t), n_aln, fp_sa); + bwa_aln2seq_core(n_aln, aln, p, 1, n_occ); + } + + fprintf(stderr, "[bwa_aln_core] convert to sequence coordinate... "); + bwa_cal_pac_pos(prefix, n_seqs, seqs, opt.max_diff, opt.fnr); // forward bwt will be destroyed here + fprintf(stderr, "%.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); t = clock(); + + fprintf(stderr, "[bwa_aln_core] refine gapped alignments... "); + bwa_refine_gapped(bns, n_seqs, seqs, 0, ntbns); + fprintf(stderr, "%.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); t = clock(); + + fprintf(stderr, "[bwa_aln_core] print alignments... "); + for (i = 0; i < n_seqs; ++i) + bwa_print_sam1(bns, seqs + i, 0, opt.mode, opt.max_top2); + fprintf(stderr, "%.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); t = clock(); + + bwa_free_read_seq(n_seqs, seqs); + fprintf(stderr, "[bwa_aln_core] %d sequences have been processed.\n", tot_seqs); + } + + // destroy + bwa_seq_close(ks); + if (ntbns) bns_destroy(ntbns); + bns_destroy(bns); + fclose(fp_sa); + free(aln); +} + +void bwa_print_all_hits(const char *prefix, const char *fn_sa, const char *fn_fa, int max_extra_occ) +{ + int i, n_seqs, tot_seqs = 0, m_aln, m_rest; + bwt_aln1_t *aln = 0; + bwa_seq_t *seqs; + bwa_seqio_t *ks; + clock_t t,t_convert, t_refine, t_write;; + bntseq_t *bns, *ntbns = 0; + FILE *fp_sa; + gap_opt_t opt; + + //****** below modified (added) for multiple hit printout: + + bwa_seq_t * rest_seqs = 0; // this array will keep (shallow) replicas of the current sequence; + // each of the replicas will be updated with its own alignment + // selected from all the (multiple) alignmens available for the current seq. + + bwt_t *bwt[2]; + char str[1024]; + ubyte_t *pacseq; + + t = clock(); + fprintf(stderr, "[bwa_aln_core] Data structures initialized: "); + + + strcpy(str, prefix); strcat(str, ".bwt"); bwt[0] = bwt_restore_bwt(str); + strcpy(str, prefix); strcat(str, ".sa"); bwt_restore_sa(str, bwt[0]); + + // load reverse BWT and SA + strcpy(str, prefix); strcat(str, ".rbwt"); bwt[1] = bwt_restore_bwt(str); + strcpy(str, prefix); strcat(str, ".rsa"); bwt_restore_sa(str, bwt[1]); + //*************** + + // initialization + bwase_initialize(); + bns = bns_restore(prefix); + srand48(bns->seed); + ks = bwa_seq_open(fn_fa); + fp_sa = xopen(fn_sa, "r"); + + pacseq = (ubyte_t*)calloc(bns->l_pac/4+1, 1); + rewind(bns->fp_pac); + fread(pacseq, 1, bns->l_pac/4+1, bns->fp_pac); + + + // core loop + m_aln = 0; + m_rest = 0; + + fread(&opt, sizeof(gap_opt_t), 1, fp_sa); + if (!(opt.mode & BWA_MODE_COMPREAD)) // in color space; initialize ntpac + ntbns = bwa_open_nt(prefix); + bwa_print_sam_SQ(bns); + + fprintf(stderr, "%.2f sec\n", (float)(clock()-t) / CLOCKS_PER_SEC); + + t = clock(); + + max_extra_occ++; // now this variable holds TOTAL number of alignments we want to print (1+requested extra). + + while ((seqs = bwa_read_seq(ks, 0x40000, &n_seqs, opt.mode & BWA_MODE_COMPREAD, opt.trim_qual)) != 0) { + tot_seqs += n_seqs; + t_convert = 0; + t_refine = 0; + t_write = 0; + + fprintf(stderr, "[bwa_aln_core] %d sequences loaded: ",n_seqs); + fprintf(stderr, "%.2f sec\n", (float)(clock()-t) / CLOCKS_PER_SEC); + + + // read alignment + for (i = 0; i < n_seqs; ++i) { + + bwa_seq_t *p = seqs + i; + int n_aln, n_occ, k, rest; + fread(&n_aln, 4, 1, fp_sa); + if (n_aln > m_aln) { + m_aln = n_aln; + aln = (bwt_aln1_t*)realloc(aln, sizeof(bwt_aln1_t) * m_aln); + } + + fread(aln, sizeof(bwt_aln1_t), n_aln, fp_sa); + for ( k = n_occ = 0 ; k < n_aln; ++k ) { + const bwt_aln1_t *q = aln + k; + n_occ += q->l - q->k + 1; + } /* n_occ is now keeping total number of available alignments to the reference + (i.e. placements, NOT bwa records, each of which can describe few placements) + */ + + // we are going to keep and print 'rest' alignments: + rest = ((n_occ > max_extra_occ)? max_extra_occ : n_occ); + + if ( rest == 0 ) rest++; /* we need at least one record, even if it is going to say "UNMAPPED" */ + + if ( rest > m_rest ) { + // reallocate rest_seqs array (only if needed) to ensure it can keep 'rest' records + m_rest = rest; + rest_seqs = (bwa_seq_t*)realloc(rest_seqs,sizeof(bwa_seq_t)*m_rest); + } + // initialize 'rest' replicas of the current sequence record + for ( k = 0 ; k < rest ; k++ ) { + rest_seqs[k] = *p; /* clone current sequence p; IMPORTANT: it's a shallow copy */ + } + + bwa_aln2seq_all(n_aln, aln, rest,rest_seqs); + // now each of the replicas carries its own bwa alignment selected from all alignments + // available for the current sequence *p. + + /* compute positions of the alignments on the ref: */ + t = clock(); + + bwa_cal_pac_pos_core(bwt[0],bwt[1], rest, rest_seqs, opt.max_diff, opt.fnr ); + t_convert += ( clock() - t ); + + /* compute positions of the alignments on the ref: */ + t = clock(); + + bwa_cal_pac_pos_core(bwt[0],bwt[1], rest, rest_seqs, opt.max_diff, opt.fnr ); + t_convert += ( clock() - t ); + + t = clock(); + + bwa_refine_gapped(bns,rest,rest_seqs,pacseq,ntbns); // refine all gapped aligns in our replicas; + // side effect: cigars will be allocated for each replica + t_refine += ( clock() - t ); + + t = clock(); + // for ( k = 0 ; k < n_seqs ; k++ ) { + for ( k = 0 ; k < rest ; k++ ) { + + bwa_print_sam1(bns, rest_seqs + k, 0, opt.mode, opt.max_top2); + // cigar was allocated for us in every replica as a side effect, free it now: + free ( (rest_seqs+k)->cigar ); + } + t_write+= ( clock()-t); + + } + + bwa_free_read_seq(n_seqs, seqs); + + fprintf(stderr, "[bwa_aln_core] convert %d sequences to sequence coordinate: ",n_seqs); + fprintf(stderr, "%.2f sec\n", (float)t_convert / CLOCKS_PER_SEC); + fprintf(stderr, "[bwa_aln_core] refine gapped alignments for %d sequences: ", n_seqs); + fprintf(stderr, "%.2f sec\n", (float)t_refine / CLOCKS_PER_SEC); + fprintf(stderr, "[bwa_aln_core] print alignments for %d sequences: ", n_seqs); + fprintf(stderr, "%.2f sec\n", (float)t_write/ CLOCKS_PER_SEC); + fprintf(stderr, "[bwa_aln_core] %d sequences have been processed.\n", tot_seqs); + + t = clock(); + } + + // destroy + bwt_destroy(bwt[0]); + bwt_destroy(bwt[1]); + + free(rest_seqs); + free(pacseq); + + bwa_seq_close(ks); + if (ntbns) bns_destroy(ntbns); + bns_destroy(bns); + fclose(fp_sa); + free(aln); +} + +int bwa_sai2sam_se(int argc, char *argv[]) +{ + int c, n_occ = 3; + int do_full_sam = 0; + while ((c = getopt(argc, argv, "hsn:f:")) >= 0) { + switch (c) { + case 'h': break; + case 's': do_full_sam = 1; break; + case 'n': n_occ = atoi(optarg); break; + case 'f': freopen(optarg, "w", stdout); break; + default: return 1; + } + } + + if (optind + 3 > argc) { + fprintf(stderr, "Usage: bwa samse [-n max_occ [-s] ] [-f out.sam] <prefix> <in.sai> <in.fq>\n"); + return 1; + } + if ( do_full_sam ) bwa_print_all_hits(argv[optind], argv[optind+1], argv[optind+2], n_occ); + else bwa_sai2sam_se_core(argv[optind], argv[optind+1], argv[optind+2], n_occ); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwase.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,27 @@ +#ifndef BWASE_H +#define BWASE_H + +#include "bntseq.h" +#include "bwt.h" +#include "bwtaln.h" + +#ifdef __cplusplus +extern "C" { +#endif + + // Initialize mapping tables in the bwa single-end mapper. + void bwase_initialize(); + // Calculate the approximate position of the sequence from the specified bwt with loaded suffix array. + void bwa_cal_pac_pos_core(const bwt_t* forward_bwt, const bwt_t* reverse_bwt, int n_seqs, bwa_seq_t* seq, const int max_mm, const float fnr); + // Refine the approximate position of the sequence to an actual placement for the sequence. + void bwa_refine_gapped(const bntseq_t *bns, int n_seqs, bwa_seq_t *seqs, ubyte_t *_pacseq, bntseq_t *ntbns); + // Backfill certain alignment properties mainly centering around number of matches. + void bwa_aln2seq(int n_aln, const bwt_aln1_t *aln, bwa_seq_t *s); + // Calculate the end position of a read given a certain sequence. + int64_t pos_end(const bwa_seq_t *p); + +#ifdef __cplusplus +} +#endif + +#endif // BWASE_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwase.h~ Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,27 @@ +#ifndef BWASE_H +#define BWASE_H + +#include "bntseq.h" +#include "bwt.h" +#include "bwtaln.h" + +#ifdef __cplusplus +extern "C" { +#endif + + // Initialize mapping tables in the bwa single-end mapper. + void bwase_initialize(); + // Calculate the approximate position of the sequence from the specified bwt with loaded suffix array. + void bwa_cal_pac_pos_core(const bwt_t* forward_bwt, const bwt_t* reverse_bwt, bwa_seq_t* seq, const int max_mm, const float fnr); + // Refine the approximate position of the sequence to an actual placement for the sequence. + void bwa_refine_gapped(const bntseq_t *bns, int n_seqs, bwa_seq_t *seqs, ubyte_t *_pacseq, bntseq_t *ntbns); + // Backfill certain alignment properties mainly centering around number of matches. + void bwa_aln2seq(int n_aln, const bwt_aln1_t *aln, bwa_seq_t *s); + // Calculate the end position of a read given a certain sequence. + int64_t pos_end(const bwa_seq_t *p); + +#ifdef __cplusplus +} +#endif + +#endif // BWASE_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwaseqio.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,121 @@ +#include <zlib.h> +#include "bwtaln.h" +#include "utils.h" + +#include "kseq.h" +KSEQ_INIT(gzFile, gzread) + +extern unsigned char nst_nt4_table[256]; + +struct __bwa_seqio_t { + kseq_t *ks; +}; + +bwa_seqio_t *bwa_seq_open(const char *fn) +{ + gzFile fp; + bwa_seqio_t *bs; + bs = (bwa_seqio_t*)calloc(1, sizeof(bwa_seqio_t)); + fp = xzopen(fn, "r"); + bs->ks = kseq_init(fp); + return bs; +} + +void bwa_seq_close(bwa_seqio_t *bs) +{ + if (bs == 0) return; + gzclose(bs->ks->f->f); + kseq_destroy(bs->ks); + free(bs); +} + +void seq_reverse(int len, ubyte_t *seq, int is_comp) +{ + int i; + if (is_comp) { + for (i = 0; i < len>>1; ++i) { + char tmp = seq[len-1-i]; + if (tmp < 4) tmp = 3 - tmp; + seq[len-1-i] = (seq[i] >= 4)? seq[i] : 3 - seq[i]; + seq[i] = tmp; + } + if (len&1) seq[i] = (seq[i] >= 4)? seq[i] : 3 - seq[i]; + } else { + for (i = 0; i < len>>1; ++i) { + char tmp = seq[len-1-i]; + seq[len-1-i] = seq[i]; seq[i] = tmp; + } + } +} + +int bwa_trim_read(int trim_qual, bwa_seq_t *p) +{ + int s = 0, l, max = 0, max_l = p->len - 1; + if (trim_qual < 1 || p->qual == 0) return 0; + for (l = p->len - 1; l >= BWA_MIN_RDLEN - 1; --l) { + s += trim_qual - (p->qual[l] - 33); + if (s < 0) break; + if (s > max) { + max = s; max_l = l; + } + } + p->clip_len = p->len = max_l + 1; + return p->full_len - p->len; +} + +bwa_seq_t *bwa_read_seq(bwa_seqio_t *bs, int n_needed, int *n, int is_comp, int trim_qual) +{ + bwa_seq_t *seqs, *p; + kseq_t *seq = bs->ks; + int n_seqs, l, i; + long n_trimmed = 0, n_tot = 0; + + n_seqs = 0; + seqs = (bwa_seq_t*)calloc(n_needed, sizeof(bwa_seq_t)); + while ((l = kseq_read(seq)) >= 0) { + p = &seqs[n_seqs++]; + p->tid = -1; // no assigned to a thread + p->qual = 0; + p->full_len = p->clip_len = p->len = l; + n_tot += p->full_len; + p->seq = (ubyte_t*)calloc(p->len, 1); + for (i = 0; i != p->full_len; ++i) + p->seq[i] = nst_nt4_table[(int)seq->seq.s[i]]; + if (seq->qual.l) { // copy quality + p->qual = (ubyte_t*)strdup((char*)seq->qual.s); + if (trim_qual >= 1) n_trimmed += bwa_trim_read(trim_qual, p); + } + p->rseq = (ubyte_t*)calloc(p->full_len, 1); + memcpy(p->rseq, p->seq, p->len); + seq_reverse(p->len, p->seq, 0); // *IMPORTANT*: will be reversed back in bwa_refine_gapped() + seq_reverse(p->len, p->rseq, is_comp); + p->name = strdup((const char*)seq->name.s); + { // trim /[12]$ + int t = strlen(p->name); + if (t > 2 && p->name[t-2] == '/' && (p->name[t-1] == '1' || p->name[t-1] == '2')) p->name[t-2] = '\0'; + } + if (n_seqs == n_needed) break; + } + *n = n_seqs; + if (n_seqs && trim_qual >= 1) + fprintf(stderr, "[bwa_read_seq] %.1f%% bases are trimmed.\n", 100.0f * n_trimmed/n_tot); + if (n_seqs == 0) { + free(seqs); + return 0; + } + return seqs; +} + +void bwa_free_read_seq(int n_seqs, bwa_seq_t *seqs) +{ + int i, j; + for (i = 0; i != n_seqs; ++i) { + bwa_seq_t *p = seqs + i; + for (j = 0; j < p->n_multi; ++j) + if (p->multi[j].cigar) free(p->multi[j].cigar); + free(p->name); + free(p->seq); free(p->rseq); free(p->qual); free(p->aln); free(p->md); free(p->multi); + free(p->cigar); + } + free(seqs); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwt.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,250 @@ +/* The MIT License + + Copyright (c) 2008 Genome Research Ltd (GRL). + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* Contact: Heng Li <lh3@sanger.ac.uk> */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include <stdint.h> +#include "utils.h" +#include "bwt.h" + +void bwt_gen_cnt_table(bwt_t *bwt) +{ + int i, j; + for (i = 0; i != 256; ++i) { + uint32_t x = 0; + for (j = 0; j != 4; ++j) + x |= (((i&3) == j) + ((i>>2&3) == j) + ((i>>4&3) == j) + (i>>6 == j)) << (j<<3); + bwt->cnt_table[i] = x; + } +} + +// bwt->bwt and bwt->occ must be precalculated +void bwt_cal_sa(bwt_t *bwt, int intv) +{ + bwtint_t isa, sa, i; // S(isa) = sa + + xassert(bwt->bwt, "bwt_t::bwt is not initialized."); + + if (bwt->sa) free(bwt->sa); + bwt->sa_intv = intv; + bwt->n_sa = (bwt->seq_len + intv) / intv; + bwt->sa = (bwtint_t*)calloc(bwt->n_sa, sizeof(bwtint_t)); + // calculate SA value + isa = 0; sa = bwt->seq_len; + for (i = 0; i < bwt->seq_len; ++i) { + if (isa % intv == 0) bwt->sa[isa/intv] = sa; + --sa; + isa = bwt_invPsi(bwt, isa); + } + if (isa % intv == 0) bwt->sa[isa/intv] = sa; + bwt->sa[0] = (bwtint_t)-1; // before this line, bwt->sa[0] = bwt->seq_len +} + +bwtint_t bwt_sa(const bwt_t *bwt, bwtint_t k) +{ + bwtint_t sa = 0; + while (k % bwt->sa_intv != 0) { + ++sa; + k = bwt_invPsi(bwt, k); + } + /* without setting bwt->sa[0] = -1, the following line should be + changed to (sa + bwt->sa[k/bwt->sa_intv]) % (bwt->seq_len + 1) */ + return sa + bwt->sa[k/bwt->sa_intv]; +} + +static inline int __occ_aux(uint64_t y, int c) +{ + // reduce nucleotide counting to bits counting + y = ((c&2)? y : ~y) >> 1 & ((c&1)? y : ~y) & 0x5555555555555555ull; + // count the number of 1s in y + y = (y & 0x3333333333333333ull) + (y >> 2 & 0x3333333333333333ull); + return ((y + (y >> 4)) & 0xf0f0f0f0f0f0f0full) * 0x101010101010101ull >> 56; +} + +inline bwtint_t bwt_occ(const bwt_t *bwt, bwtint_t k, ubyte_t c) +{ + bwtint_t n, l, j; + uint32_t *p; + + if (k == bwt->seq_len) return bwt->L2[c+1] - bwt->L2[c]; + if (k == (bwtint_t)(-1)) return 0; + if (k >= bwt->primary) --k; // because $ is not in bwt + + // retrieve Occ at k/OCC_INTERVAL + n = (p = bwt_occ_intv(bwt, k))[c]; + p += 4; // jump to the start of the first BWT cell + + // calculate Occ up to the last k/32 + j = k >> 5 << 5; + for (l = k/OCC_INTERVAL*OCC_INTERVAL; l < j; l += 32, p += 2) + n += __occ_aux((uint64_t)p[0]<<32 | p[1], c); + + // calculate Occ + n += __occ_aux(((uint64_t)p[0]<<32 | p[1]) & ~((1ull<<((~k&31)<<1)) - 1), c); + if (c == 0) n -= ~k&31; // corrected for the masked bits + + return n; +} + +// an analogy to bwt_occ() but more efficient, requiring k <= l +inline void bwt_2occ(const bwt_t *bwt, bwtint_t k, bwtint_t l, ubyte_t c, bwtint_t *ok, bwtint_t *ol) +{ + bwtint_t _k, _l; + if (k == l) { + *ok = *ol = bwt_occ(bwt, k, c); + return; + } + _k = (k >= bwt->primary)? k-1 : k; + _l = (l >= bwt->primary)? l-1 : l; + if (_l/OCC_INTERVAL != _k/OCC_INTERVAL || k == (bwtint_t)(-1) || l == (bwtint_t)(-1)) { + *ok = bwt_occ(bwt, k, c); + *ol = bwt_occ(bwt, l, c); + } else { + bwtint_t m, n, i, j; + uint32_t *p; + if (k >= bwt->primary) --k; + if (l >= bwt->primary) --l; + n = (p = bwt_occ_intv(bwt, k))[c]; + p += 4; + // calculate *ok + j = k >> 5 << 5; + for (i = k/OCC_INTERVAL*OCC_INTERVAL; i < j; i += 32, p += 2) + n += __occ_aux((uint64_t)p[0]<<32 | p[1], c); + m = n; + n += __occ_aux(((uint64_t)p[0]<<32 | p[1]) & ~((1ull<<((~k&31)<<1)) - 1), c); + if (c == 0) n -= ~k&31; // corrected for the masked bits + *ok = n; + // calculate *ol + j = l >> 5 << 5; + for (; i < j; i += 32, p += 2) + m += __occ_aux((uint64_t)p[0]<<32 | p[1], c); + m += __occ_aux(((uint64_t)p[0]<<32 | p[1]) & ~((1ull<<((~l&31)<<1)) - 1), c); + if (c == 0) m -= ~l&31; // corrected for the masked bits + *ol = m; + } +} + +#define __occ_aux4(bwt, b) \ + ((bwt)->cnt_table[(b)&0xff] + (bwt)->cnt_table[(b)>>8&0xff] \ + + (bwt)->cnt_table[(b)>>16&0xff] + (bwt)->cnt_table[(b)>>24]) + +inline void bwt_occ4(const bwt_t *bwt, bwtint_t k, bwtint_t cnt[4]) +{ + bwtint_t l, j, x; + uint32_t *p; + if (k == (bwtint_t)(-1)) { + memset(cnt, 0, 4 * sizeof(bwtint_t)); + return; + } + if (k >= bwt->primary) --k; // because $ is not in bwt + p = bwt_occ_intv(bwt, k); + memcpy(cnt, p, 16); + p += 4; + j = k >> 4 << 4; + for (l = k / OCC_INTERVAL * OCC_INTERVAL, x = 0; l < j; l += 16, ++p) + x += __occ_aux4(bwt, *p); + x += __occ_aux4(bwt, *p & ~((1U<<((~k&15)<<1)) - 1)) - (~k&15); + cnt[0] += x&0xff; cnt[1] += x>>8&0xff; cnt[2] += x>>16&0xff; cnt[3] += x>>24; +} + +// an analogy to bwt_occ4() but more efficient, requiring k <= l +inline void bwt_2occ4(const bwt_t *bwt, bwtint_t k, bwtint_t l, bwtint_t cntk[4], bwtint_t cntl[4]) +{ + bwtint_t _k, _l; + if (k == l) { + bwt_occ4(bwt, k, cntk); + memcpy(cntl, cntk, 4 * sizeof(bwtint_t)); + return; + } + _k = (k >= bwt->primary)? k-1 : k; + _l = (l >= bwt->primary)? l-1 : l; + if (_l/OCC_INTERVAL != _k/OCC_INTERVAL || k == (bwtint_t)(-1) || l == (bwtint_t)(-1)) { + bwt_occ4(bwt, k, cntk); + bwt_occ4(bwt, l, cntl); + } else { + bwtint_t i, j, x, y; + uint32_t *p; + int cl[4]; + if (k >= bwt->primary) --k; // because $ is not in bwt + if (l >= bwt->primary) --l; + cl[0] = cl[1] = cl[2] = cl[3] = 0; + p = bwt_occ_intv(bwt, k); + memcpy(cntk, p, 4 * sizeof(bwtint_t)); + p += 4; + // prepare cntk[] + j = k >> 4 << 4; + for (i = k / OCC_INTERVAL * OCC_INTERVAL, x = 0; i < j; i += 16, ++p) + x += __occ_aux4(bwt, *p); + y = x; + x += __occ_aux4(bwt, *p & ~((1U<<((~k&15)<<1)) - 1)) - (~k&15); + // calculate cntl[] and finalize cntk[] + j = l >> 4 << 4; + for (; i < j; i += 16, ++p) y += __occ_aux4(bwt, *p); + y += __occ_aux4(bwt, *p & ~((1U<<((~l&15)<<1)) - 1)) - (~l&15); + memcpy(cntl, cntk, 16); + cntk[0] += x&0xff; cntk[1] += x>>8&0xff; cntk[2] += x>>16&0xff; cntk[3] += x>>24; + cntl[0] += y&0xff; cntl[1] += y>>8&0xff; cntl[2] += y>>16&0xff; cntl[3] += y>>24; + } +} + +int bwt_match_exact(const bwt_t *bwt, int len, const ubyte_t *str, bwtint_t *sa_begin, bwtint_t *sa_end) +{ + bwtint_t k, l, ok, ol; + int i; + k = 0; l = bwt->seq_len; + for (i = len - 1; i >= 0; --i) { + ubyte_t c = str[i]; + if (c > 3) return 0; // no match + bwt_2occ(bwt, k - 1, l, c, &ok, &ol); + k = bwt->L2[c] + ok + 1; + l = bwt->L2[c] + ol; + if (k > l) break; // no match + } + if (k > l) return 0; // no match + if (sa_begin) *sa_begin = k; + if (sa_end) *sa_end = l; + return l - k + 1; +} + +int bwt_match_exact_alt(const bwt_t *bwt, int len, const ubyte_t *str, bwtint_t *k0, bwtint_t *l0) +{ + int i; + bwtint_t k, l, ok, ol; + k = *k0; l = *l0; + for (i = len - 1; i >= 0; --i) { + ubyte_t c = str[i]; + if (c > 3) return 0; // there is an N here. no match + bwt_2occ(bwt, k - 1, l, c, &ok, &ol); + k = bwt->L2[c] + ok + 1; + l = bwt->L2[c] + ol; + if (k > l) return 0; // no match + } + *k0 = k; *l0 = l; + return l - k + 1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwt.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,105 @@ +/* The MIT License + + Copyright (c) 2008 Genome Research Ltd (GRL). + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* Contact: Heng Li <lh3@sanger.ac.uk> */ + +#ifndef BWA_BWT_H +#define BWA_BWT_H + +#include <stdint.h> + +// requirement: (OCC_INTERVAL%16 == 0) +#define OCC_INTERVAL 0x80 + +#ifndef BWA_UBYTE +#define BWA_UBYTE +typedef unsigned char ubyte_t; +#endif +typedef uint32_t bwtint_t; + +typedef struct { + bwtint_t primary; // S^{-1}(0), or the primary index of BWT + bwtint_t L2[5]; // C(), cumulative count + bwtint_t seq_len; // sequence length + bwtint_t bwt_size; // size of bwt, about seq_len/4 + uint32_t *bwt; // BWT + // occurance array, separated to two parts + uint32_t cnt_table[256]; + // suffix array + int sa_intv; + bwtint_t n_sa; + bwtint_t *sa; +} bwt_t; + +#define bwt_bwt(b, k) ((b)->bwt[(k)/OCC_INTERVAL*12 + 4 + (k)%OCC_INTERVAL/16]) + +/* retrieve a character from the $-removed BWT string. Note that + * bwt_t::bwt is not exactly the BWT string and therefore this macro is + * called bwt_B0 instead of bwt_B */ +#define bwt_B0(b, k) (bwt_bwt(b, k)>>((~(k)&0xf)<<1)&3) + +#define bwt_occ_intv(b, k) ((b)->bwt + (k)/OCC_INTERVAL*12) + +// inverse Psi function +#define bwt_invPsi(bwt, k) \ + (((k) == (bwt)->primary)? 0 : \ + ((k) < (bwt)->primary)? \ + (bwt)->L2[bwt_B0(bwt, k)] + bwt_occ(bwt, k, bwt_B0(bwt, k)) \ + : (bwt)->L2[bwt_B0(bwt, (k)-1)] + bwt_occ(bwt, k, bwt_B0(bwt, (k)-1))) + +#ifdef __cplusplus +extern "C" { +#endif + + void bwt_dump_bwt(const char *fn, const bwt_t *bwt); + void bwt_dump_sa(const char *fn, const bwt_t *bwt); + + bwt_t *bwt_restore_bwt(const char *fn); + void bwt_restore_sa(const char *fn, bwt_t *bwt); + + void bwt_destroy(bwt_t *bwt); + + void bwt_bwtgen(const char *fn_pac, const char *fn_bwt); // from BWT-SW + void bwt_cal_sa(bwt_t *bwt, int intv); + + void bwt_bwtupdate_core(bwt_t *bwt); + + inline bwtint_t bwt_occ(const bwt_t *bwt, bwtint_t k, ubyte_t c); + inline void bwt_occ4(const bwt_t *bwt, bwtint_t k, bwtint_t cnt[4]); + bwtint_t bwt_sa(const bwt_t *bwt, bwtint_t k); + + // more efficient version of bwt_occ/bwt_occ4 for retrieving two close Occ values + void bwt_gen_cnt_table(bwt_t *bwt); + inline void bwt_2occ(const bwt_t *bwt, bwtint_t k, bwtint_t l, ubyte_t c, bwtint_t *ok, bwtint_t *ol); + inline void bwt_2occ4(const bwt_t *bwt, bwtint_t k, bwtint_t l, bwtint_t cntk[4], bwtint_t cntl[4]); + + int bwt_match_exact(const bwt_t *bwt, int len, const ubyte_t *str, bwtint_t *sa_begin, bwtint_t *sa_end); + int bwt_match_exact_alt(const bwt_t *bwt, int len, const ubyte_t *str, bwtint_t *k0, bwtint_t *l0); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwt_gen/Makefile Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,23 @@ +CC= gcc +CFLAGS= -g -Wall -O2 -m64 # comment out `-m64' for 32-bit compilation +DFLAGS= -D_FILE_OFFSET_BITS=64 +OBJS= bwt_gen.o QSufSort.o +INCLUDES= +VERSION= 0.1.0 +LIBS= +SUBDIRS= + +.SUFFIXES:.c .o + +.c.o: + $(CC) -c $(CFLAGS) $(DFLAGS) $(INCLUDES) $< -o $@ + +lib:libbwtgen.a + +libbwtgen.a:$(OBJS) + $(AR) -cru $@ $(OBJS) + +cleanlocal: + rm -f gmon.out *.o a.out $(PROG) *~ *.a + +clean:cleanlocal
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwt_gen/Makefile.am Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,4 @@ +## Makefile.am -- Process this file with automake to produce Makefile.in +AM_CFLAGS = -g -Wall -O2 -m64 +noinst_LIBRARIES = libbwtgen.a +libbwtgen_a_SOURCES = QSufSort.c bwt_gen.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwt_gen/QSufSort.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,496 @@ +/* QSufSort.c + + Original source from qsufsort.c + + Copyright 1999, N. Jesper Larsson, all rights reserved. + + This file contains an implementation of the algorithm presented in "Faster + Suffix Sorting" by N. Jesper Larsson (jesper@cs.lth.se) and Kunihiko + Sadakane (sada@is.s.u-tokyo.ac.jp). + + This software may be used freely for any purpose. However, when distributed, + the original source must be clearly stated, and, when the source code is + distributed, the copyright notice must be retained and any alterations in + the code must be clearly marked. No warranty is given regarding the quality + of this software. + + Modified by Wong Chi-Kwong, 2004 + + Changes summary: - Used long variable and function names + - Removed global variables + - Replace pointer references with array references + - Used insertion sort in place of selection sort and increased insertion sort threshold + - Reconstructing suffix array from inverse becomes an option + - Add handling where end-of-text symbol is not necessary < all characters + - Removed codes for supporting alphabet size > number of characters + + No warrenty is given regarding the quality of the modifications. + +*/ + + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> +#include "bwt_gen.h" +#include "QSufSort.h" + +// Static functions +static void QSufSortSortSplit(int* __restrict V, int* __restrict I, const int lowestPos, + const int highestPos, const int numSortedChar); +static int QSufSortChoosePivot(int* __restrict V, int* __restrict I, const int lowestPos, + const int highestPos, const int numSortedChar); +static void QSufSortInsertSortSplit(int* __restrict V, int* __restrict I, const int lowestPos, + const int highestPos, const int numSortedChar); +static void QSufSortBucketSort(int* __restrict V, int* __restrict I, const int numChar, const int alphabetSize); +static int QSufSortTransform(int* __restrict V, int* __restrict I, const int numChar, const int largestInputSymbol, + const int smallestInputSymbol, const int maxNewAlphabetSize, int *numSymbolAggregated); + +// from MiscUtilities.c +static unsigned int leadingZero(const unsigned int input) { + + unsigned int l; + const static unsigned int leadingZero8bit[256] = {8,7,6,6,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + + if (input & 0xFFFF0000) { + if (input & 0xFF000000) { + l = leadingZero8bit[input >> 24]; + } else { + l = 8 + leadingZero8bit[input >> 16]; + } + } else { + if (input & 0x0000FF00) { + l = 16 + leadingZero8bit[input >> 8]; + } else { + l = 24 + leadingZero8bit[input]; + } + } + return l; + +} + +/* Makes suffix array p of x. x becomes inverse of p. p and x are both of size + n+1. Contents of x[0...n-1] are integers in the range l...k-1. Original + contents of x[n] is disregarded, the n-th symbol being regarded as + end-of-string smaller than all other symbols.*/ +void QSufSortSuffixSort(int* __restrict V, int* __restrict I, const int numChar, const int largestInputSymbol, + const int smallestInputSymbol, const int skipTransform) { + + int i, j; + int s, negatedSortedGroupLength; + int numSymbolAggregated; + int maxNumInputSymbol; + int numSortedPos = 1; + int newAlphabetSize; + + maxNumInputSymbol = largestInputSymbol - smallestInputSymbol + 1; + + if (!skipTransform) { + /* bucketing possible*/ + newAlphabetSize = QSufSortTransform(V, I, numChar, largestInputSymbol, smallestInputSymbol, + numChar, &numSymbolAggregated); + QSufSortBucketSort(V, I, numChar, newAlphabetSize); + I[0] = -1; + V[numChar] = 0; + numSortedPos = numSymbolAggregated; + } + + while ((int)(I[0]) >= -(int)numChar) { + i = 0; + negatedSortedGroupLength = 0; + do { + s = I[i]; + if (s < 0) { + i -= s; /* skip over sorted group.*/ + negatedSortedGroupLength += s; + } else { + if (negatedSortedGroupLength) { + I[i+negatedSortedGroupLength] = negatedSortedGroupLength; /* combine preceding sorted groups */ + negatedSortedGroupLength = 0; + } + j = V[s] + 1; + QSufSortSortSplit(V, I, i, j - 1, numSortedPos); + i = j; + } + } while (i <= numChar); + if (negatedSortedGroupLength) { + /* array ends with a sorted group.*/ + I[i+negatedSortedGroupLength] = negatedSortedGroupLength; /* combine sorted groups at end of I.*/ + } + numSortedPos *= 2; /* double sorted-depth.*/ + } + +} + +void QSufSortGenerateSaFromInverse(const int* V, int* __restrict I, const int numChar) { + + int i; + for (i=0; i<=numChar; i++) { + I[V[i]] = i + 1; + } + +} + +/* Sorting routine called for each unsorted group. Sorts the array of integers + (suffix numbers) of length n starting at p. The algorithm is a ternary-split + quicksort taken from Bentley & McIlroy, "Engineering a Sort Function", + Software -- Practice and Experience 23(11), 1249-1265 (November 1993). This + function is based on Program 7.*/ +static void QSufSortSortSplit(int* __restrict V, int* __restrict I, const int lowestPos, + const int highestPos, const int numSortedChar) { + + int a, b, c, d; + int l, m; + int f, v, s, t; + int tmp; + int numItem; + + #ifdef DEBUG + if (lowestPos > highestPos) { + fprintf(stderr, "QSufSortSortSplit(): lowestPos > highestPos!\n"); + exit(1); + } + #endif + + numItem = highestPos - lowestPos + 1; + + if (numItem <= INSERT_SORT_NUM_ITEM) { + QSufSortInsertSortSplit(V, I, lowestPos, highestPos, numSortedChar); + return; + } + + v = QSufSortChoosePivot(V, I, lowestPos, highestPos, numSortedChar); + + a = b = lowestPos; + c = d = highestPos; + + while (TRUE) { + while (c >= b && (f = KEY(V, I, b, numSortedChar)) <= v) { + if (f == v) { + swap(I[a], I[b], tmp); + a++; + } + b++; + } + while (c >= b && (f = KEY(V, I, c, numSortedChar)) >= v) { + if (f == v) { + swap(I[c], I[d], tmp); + d--; + } + c--; + } + if (b > c) { + break; + } + swap(I[b], I[c], tmp); + b++; + c--; + } + + s = a - lowestPos; + t = b - a; + s = min(s, t); + for (l = lowestPos, m = b - s; m < b; l++, m++) { + swap(I[l], I[m], tmp); + } + + s = d - c; + t = highestPos - d; + s = min(s, t); + for (l = b, m = highestPos - s + 1; m <= highestPos; l++, m++) { + swap(I[l], I[m], tmp); + } + + s = b - a; + t = d - c; + if (s > 0) { + QSufSortSortSplit(V, I, lowestPos, lowestPos + s - 1, numSortedChar); + } + + // Update group number for equal portion + a = lowestPos + s; + b = highestPos - t; + if (a == b) { + // Sorted group + V[I[a]] = a; + I[a] = -1; + } else { + // Unsorted group + for (c=a; c<=b; c++) { + V[I[c]] = b; + } + } + + if (t > 0) { + QSufSortSortSplit(V, I, highestPos - t + 1, highestPos, numSortedChar); + } + +} + +/* Algorithm by Bentley & McIlroy.*/ +static int QSufSortChoosePivot(int* __restrict V, int* __restrict I, const int lowestPos, + const int highestPos, const int numSortedChar) { + + int m; + int keyl, keym, keyn; + int key1, key2, key3; + int s; + int numItem; + + #ifdef DEBUG + if (lowestPos > highestPos) { + fprintf(stderr, "QSufSortChoosePivot(): lowestPos > highestPos!\n"); + exit(1); + } + #endif + + numItem = highestPos - lowestPos + 1; + + #ifdef DEBUG + if (numItem <= INSERT_SORT_NUM_ITEM) { + fprintf(stderr, "QSufSortChoosePivot(): number of items <= INSERT_SORT_NUM_ITEM!\n"); + exit(1); + } + #endif + + m = lowestPos + numItem / 2; + + s = numItem / 8; + key1 = KEY(V, I, lowestPos, numSortedChar); + key2 = KEY(V, I, lowestPos+s, numSortedChar); + key3 = KEY(V, I, lowestPos+2*s, numSortedChar); + keyl = med3(key1, key2, key3); + key1 = KEY(V, I, m-s, numSortedChar); + key2 = KEY(V, I, m, numSortedChar); + key3 = KEY(V, I, m+s, numSortedChar); + keym = med3(key1, key2, key3); + key1 = KEY(V, I, highestPos-2*s, numSortedChar); + key2 = KEY(V, I, highestPos-s, numSortedChar); + key3 = KEY(V, I, highestPos, numSortedChar); + keyn = med3(key1, key2, key3); + + return med3(keyl, keym, keyn); + + +} + +/* Quadratic sorting method to use for small subarrays. */ +static void QSufSortInsertSortSplit(int* __restrict V, int* __restrict I, const int lowestPos, + const int highestPos, const int numSortedChar) { + + int i, j; + int tmpKey, tmpPos; + int numItem; + int key[INSERT_SORT_NUM_ITEM], pos[INSERT_SORT_NUM_ITEM]; + int negativeSortedLength; + int groupNum; + + #ifdef DEBUG + if (lowestPos > highestPos) { + fprintf(stderr, "QSufSortInsertSortSplit(): lowestPos > highestPos!\n"); + exit(1); + } + #endif + + numItem = highestPos - lowestPos + 1; + + #ifdef DEBUG + if (numItem > INSERT_SORT_NUM_ITEM) { + fprintf(stderr, "QSufSortInsertSortSplit(): number of items > INSERT_SORT_NUM_ITEM!\n"); + exit(1); + } + #endif + + for (i=0; i<numItem; i++) { + #ifdef DEBUG + if (I[lowestPos + i] < 0) { + fprintf(stderr, "QSufSortInsertSortSplit(): I < 0 in unsorted region!\n"); + exit(1); + } + #endif + pos[i] = I[lowestPos + i]; + key[i] = V[pos[i] + numSortedChar]; + } + + for (i=1; i<numItem; i++) { + tmpKey = key[i]; + tmpPos = pos[i]; + for (j=i; j>0 && key[j-1] > tmpKey; j--) { + key[j] = key[j-1]; + pos[j] = pos[j-1]; + } + key[j] = tmpKey; + pos[j] = tmpPos; + } + + negativeSortedLength = -1; + + i = numItem - 1; + groupNum = highestPos; + while (i > 0) { + I[i+lowestPos] = pos[i]; + V[I[i+lowestPos]] = groupNum; + if (key[i-1] == key[i]) { + negativeSortedLength = 0; + } else { + if (negativeSortedLength < 0) { + I[i+lowestPos] = negativeSortedLength; + } + groupNum = i + lowestPos - 1; + negativeSortedLength--; + } + i--; + } + + I[lowestPos] = pos[0]; + V[I[lowestPos]] = groupNum; + if (negativeSortedLength < 0) { + I[lowestPos] = negativeSortedLength; + } + +} + +/* Bucketsort for first iteration. + + Input: x[0...n-1] holds integers in the range 1...k-1, all of which appear + at least once. x[n] is 0. (This is the corresponding output of transform.) k + must be at most n+1. p is array of size n+1 whose contents are disregarded. + + Output: x is V and p is I after the initial sorting stage of the refined + suffix sorting algorithm.*/ + +static void QSufSortBucketSort(int* __restrict V, int* __restrict I, const int numChar, const int alphabetSize) { + + int i, c; + int d; + int groupNum; + int currentIndex; + + // mark linked list empty + for (i=0; i<alphabetSize; i++) { + I[i] = -1; + } + + // insert to linked list + for (i=0; i<=numChar; i++) { + c = V[i]; + V[i] = (int)(I[c]); + I[c] = i; + } + + currentIndex = numChar; + for (i=alphabetSize; i>0; i--) { + c = I[i-1]; + d = (int)(V[c]); + groupNum = currentIndex; + V[c] = groupNum; + if (d >= 0) { + I[currentIndex] = c; + while (d >= 0) { + c = d; + d = V[c]; + V[c] = groupNum; + currentIndex--; + I[currentIndex] = c; + } + } else { + // sorted group + I[currentIndex] = -1; + } + currentIndex--; + } + +} + +/* Transforms the alphabet of x by attempting to aggregate several symbols into + one, while preserving the suffix order of x. The alphabet may also be + compacted, so that x on output comprises all integers of the new alphabet + with no skipped numbers. + + Input: x is an array of size n+1 whose first n elements are positive + integers in the range l...k-1. p is array of size n+1, used for temporary + storage. q controls aggregation and compaction by defining the maximum intue + for any symbol during transformation: q must be at least k-l; if q<=n, + compaction is guaranteed; if k-l>n, compaction is never done; if q is + INT_MAX, the maximum number of symbols are aggregated into one. + + Output: Returns an integer j in the range 1...q representing the size of the + new alphabet. If j<=n+1, the alphabet is compacted. The global variable r is + set to the number of old symbols grouped into one. Only x[n] is 0.*/ +static int QSufSortTransform(int* __restrict V, int* __restrict I, const int numChar, const int largestInputSymbol, + const int smallestInputSymbol, const int maxNewAlphabetSize, int *numSymbolAggregated) { + + int c, i, j; + int a; // numSymbolAggregated + int mask; + int minSymbolInChunk = 0, maxSymbolInChunk = 0; + int newAlphabetSize; + int maxNumInputSymbol, maxNumBit, maxSymbol; + + maxNumInputSymbol = largestInputSymbol - smallestInputSymbol + 1; + + maxNumBit = BITS_IN_WORD - leadingZero(maxNumInputSymbol); + maxSymbol = INT_MAX >> maxNumBit; + + c = maxNumInputSymbol; + for (a = 0; a < numChar && maxSymbolInChunk <= maxSymbol && c <= maxNewAlphabetSize; a++) { + minSymbolInChunk = (minSymbolInChunk << maxNumBit) | (V[a] - smallestInputSymbol + 1); + maxSymbolInChunk = c; + c = (maxSymbolInChunk << maxNumBit) | maxNumInputSymbol; + } + + mask = (1 << (a-1) * maxNumBit) - 1; /* mask masks off top old symbol from chunk.*/ + V[numChar] = smallestInputSymbol - 1; /* emulate zero terminator.*/ + + #ifdef DEBUG + // Section of code for maxSymbolInChunk > numChar removed! + if (maxSymbolInChunk > numChar) { + fprintf(stderr, "QSufSortTransform(): maxSymbolInChunk > numChar!\n"); + exit(1); + } + #endif + + /* bucketing possible, compact alphabet.*/ + for (i=0; i<=maxSymbolInChunk; i++) { + I[i] = 0; /* zero transformation table.*/ + } + c = minSymbolInChunk; + for (i=a; i<=numChar; i++) { + I[c] = 1; /* mark used chunk symbol.*/ + c = ((c & mask) << maxNumBit) | (V[i] - smallestInputSymbol + 1); /* shift in next old symbol in chunk.*/ + } + for (i=1; i<a; i++) { /* handle last r-1 positions.*/ + I[c] = 1; /* mark used chunk symbol.*/ + c = (c & mask) << maxNumBit; /* shift in next old symbol in chunk.*/ + } + newAlphabetSize = 1; + for (i=0; i<=maxSymbolInChunk; i++) { + if (I[i]) { + I[i] = newAlphabetSize; + newAlphabetSize++; + } + } + c = minSymbolInChunk; + for (i=0, j=a; j<=numChar; i++, j++) { + V[i] = I[c]; /* transform to new alphabet.*/ + c = ((c & mask) << maxNumBit) | (V[j] - smallestInputSymbol + 1); /* shift in next old symbol in chunk.*/ + } + for (; i<numChar; i++) { /* handle last a-1 positions.*/ + V[i] = I[c]; /* transform to new alphabet.*/ + c = (c & mask) << maxNumBit; /* shift right-end zero in chunk.*/ + } + + V[numChar] = 0; /* end-of-string symbol is zero.*/ + + *numSymbolAggregated = a; + return newAlphabetSize; + +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwt_gen/QSufSort.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,40 @@ +/* QSufSort.h + + Header file for QSufSort.c + + This file contains an implementation of the algorithm presented in "Faster + Suffix Sorting" by N. Jesper Larsson (jesper@cs.lth.se) and Kunihiko + Sadakane (sada@is.s.u-tokyo.ac.jp). + + This software may be used freely for any purpose. However, when distributed, + the original source must be clearly stated, and, when the source code is + distributed, the copyright notice must be retained and any alterations in + the code must be clearly marked. No warranty is given regarding the quality + of this software. + + Modified by Wong Chi-Kwong, 2004 + + Changes summary: - Used long variable and function names + - Removed global variables + - Replace pointer references with array references + - Used insertion sort in place of selection sort and increased insertion sort threshold + - Reconstructing suffix array from inverse becomes an option + - Add handling where end-of-text symbol is not necessary < all characters + - Removed codes for supporting alphabet size > number of characters + + No warrenty is given regarding the quality of the modifications. + +*/ + +#ifndef __QSUFSORT_H__ +#define __QSUFSORT_H__ + +#define KEY(V, I, p, h) ( V[ I[p] + h ] ) +#define INSERT_SORT_NUM_ITEM 16 + +void QSufSortSuffixSort(int* __restrict V, int* __restrict I, const int numChar, const int largestInputSymbol, + const int smallestInputSymbol, const int skipTransform); +void QSufSortGenerateSaFromInverse(const int *V, int* __restrict I, const int numChar); + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwt_gen/bwt_gen.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,1547 @@ +/* + + BWTConstruct.c BWT-Index Construction + + This module constructs BWT and auxiliary data structures. + + Copyright (C) 2004, Wong Chi Kwong. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "bwt_gen.h" +#include "QSufSort.h" + +static unsigned int TextLengthFromBytePacked(unsigned int bytePackedLength, unsigned int bitPerChar, + unsigned int lastByteLength) +{ + if (bytePackedLength > ALL_ONE_MASK / (BITS_IN_BYTE / bitPerChar)) { + fprintf(stderr, "TextLengthFromBytePacked(): text length > 2^32!\n"); + exit(1); + } + return (bytePackedLength - 1) * (BITS_IN_BYTE / bitPerChar) + lastByteLength; +} + +static void initializeVAL(unsigned int *startAddr, const unsigned int length, const unsigned int initValue) +{ + unsigned int i; + for (i=0; i<length; i++) startAddr[i] = initValue; +} + +static void GenerateDNAOccCountTable(unsigned int *dnaDecodeTable) +{ + unsigned int i, j, c, t; + + for (i=0; i<DNA_OCC_CNT_TABLE_SIZE_IN_WORD; i++) { + dnaDecodeTable[i] = 0; + c = i; + for (j=0; j<8; j++) { + t = c & 0x00000003; + dnaDecodeTable[i] += 1 << (t * 8); + c >>= 2; + } + } + +} +// for BWTIncCreate() +static unsigned int BWTOccValueMajorSizeInWord(const unsigned int numChar) +{ + unsigned int numOfOccValue; + unsigned int numOfOccIntervalPerMajor; + numOfOccValue = (numChar + OCC_INTERVAL - 1) / OCC_INTERVAL + 1; // Value at both end for bi-directional encoding + numOfOccIntervalPerMajor = OCC_INTERVAL_MAJOR / OCC_INTERVAL; + return (numOfOccValue + numOfOccIntervalPerMajor - 1) / numOfOccIntervalPerMajor * ALPHABET_SIZE; +} +// for BWTIncCreate() +static unsigned int BWTOccValueMinorSizeInWord(const unsigned int numChar) +{ + unsigned int numOfOccValue; + numOfOccValue = (numChar + OCC_INTERVAL - 1) / OCC_INTERVAL + 1; // Value at both end for bi-directional encoding + return (numOfOccValue + OCC_VALUE_PER_WORD - 1) / OCC_VALUE_PER_WORD * ALPHABET_SIZE; +} +// for BWTIncCreate() +static unsigned int BWTResidentSizeInWord(const unsigned int numChar) { + + unsigned int numCharRoundUpToOccInterval; + + // The $ in BWT at the position of inverseSa0 is not encoded + numCharRoundUpToOccInterval = (numChar + OCC_INTERVAL - 1) / OCC_INTERVAL * OCC_INTERVAL; + + return (numCharRoundUpToOccInterval + CHAR_PER_WORD - 1) / CHAR_PER_WORD; + +} + +static void BWTIncSetBuildSizeAndTextAddr(BWTInc *bwtInc) +{ + unsigned int maxBuildSize; + + if (bwtInc->bwt->textLength == 0) { + // initial build + // Minus 2 because n+1 entries of seq and rank needed for n char + maxBuildSize = (bwtInc->availableWord - 2 - OCC_INTERVAL / CHAR_PER_WORD) + / (2 * CHAR_PER_WORD + 1) * CHAR_PER_WORD; + if (bwtInc->initialMaxBuildSize > 0) { + bwtInc->buildSize = min(bwtInc->initialMaxBuildSize, maxBuildSize); + } else { + bwtInc->buildSize = maxBuildSize; + } + } else { + // Minus 3 because n+1 entries of sorted rank, seq and rank needed for n char + // Minus numberOfIterationDone because bwt slightly shift to left in each iteration + maxBuildSize = (bwtInc->availableWord - bwtInc->bwt->bwtSizeInWord - bwtInc->bwt->occSizeInWord - 3 + - bwtInc->numberOfIterationDone * OCC_INTERVAL / BIT_PER_CHAR) + / 3; + if (maxBuildSize < CHAR_PER_WORD) { + fprintf(stderr, "BWTIncSetBuildSizeAndTextAddr(): Not enough space allocated to continue construction!\n"); + exit(1); + } + if (bwtInc->incMaxBuildSize > 0) { + bwtInc->buildSize = min(bwtInc->incMaxBuildSize, maxBuildSize); + } else { + bwtInc->buildSize = maxBuildSize; + } + if (bwtInc->buildSize < CHAR_PER_WORD) { + bwtInc->buildSize = CHAR_PER_WORD; + } + } + + if (bwtInc->buildSize < CHAR_PER_WORD) { + fprintf(stderr, "BWTIncSetBuildSizeAndTextAddr(): Not enough space allocated to continue construction!\n"); + exit(1); + } + + bwtInc->buildSize = bwtInc->buildSize / CHAR_PER_WORD * CHAR_PER_WORD; + + bwtInc->packedText = bwtInc->workingMemory + 2 * (bwtInc->buildSize + 1); + bwtInc->textBuffer = (unsigned char*)(bwtInc->workingMemory + bwtInc->buildSize + 1); + +} + +// for ceilLog2() +unsigned int leadingZero(const unsigned int input) +{ + unsigned int l; + const static unsigned int leadingZero8bit[256] = {8,7,6,6,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + + if (input & 0xFFFF0000) { + if (input & 0xFF000000) { + l = leadingZero8bit[input >> 24]; + } else { + l = 8 + leadingZero8bit[input >> 16]; + } + } else { + if (input & 0x0000FF00) { + l = 16 + leadingZero8bit[input >> 8]; + } else { + l = 24 + leadingZero8bit[input]; + } + } + return l; + +} +// for BitPerBytePackedChar() +static unsigned int ceilLog2(const unsigned int input) +{ + if (input <= 1) return 0; + return BITS_IN_WORD - leadingZero(input - 1); + +} +// for ConvertBytePackedToWordPacked() +static unsigned int BitPerBytePackedChar(const unsigned int alphabetSize) +{ + unsigned int bitPerChar; + bitPerChar = ceilLog2(alphabetSize); + // Return the largest number of bit that does not affect packing efficiency + if (BITS_IN_BYTE / (BITS_IN_BYTE / bitPerChar) > bitPerChar) + bitPerChar = BITS_IN_BYTE / (BITS_IN_BYTE / bitPerChar); + return bitPerChar; +} +// for ConvertBytePackedToWordPacked() +static unsigned int BitPerWordPackedChar(const unsigned int alphabetSize) +{ + return ceilLog2(alphabetSize); +} + +static void ConvertBytePackedToWordPacked(const unsigned char *input, unsigned int *output, const unsigned int alphabetSize, + const unsigned int textLength) +{ + unsigned int i, j, k; + unsigned int c; + unsigned int bitPerBytePackedChar; + unsigned int bitPerWordPackedChar; + unsigned int charPerWord; + unsigned int charPerByte; + unsigned int bytePerIteration; + unsigned int byteProcessed = 0; + unsigned int wordProcessed = 0; + unsigned int mask, shift; + + unsigned int buffer[BITS_IN_WORD]; + + bitPerBytePackedChar = BitPerBytePackedChar(alphabetSize); + bitPerWordPackedChar = BitPerWordPackedChar(alphabetSize); + charPerByte = BITS_IN_BYTE / bitPerBytePackedChar; + charPerWord = BITS_IN_WORD / bitPerWordPackedChar; + + bytePerIteration = charPerWord / charPerByte; + mask = truncateRight(ALL_ONE_MASK, BITS_IN_WORD - bitPerWordPackedChar); + shift = BITS_IN_WORD - BITS_IN_BYTE + bitPerBytePackedChar - bitPerWordPackedChar; + + while ((wordProcessed + 1) * charPerWord < textLength) { + + k = 0; + for (i=0; i<bytePerIteration; i++) { + c = (unsigned int)input[byteProcessed] << shift; + for (j=0; j<charPerByte; j++) { + buffer[k] = c & mask; + c <<= bitPerBytePackedChar; + k++; + } + byteProcessed++; + } + + c = 0; + for (i=0; i<charPerWord; i++) { + c |= buffer[i] >> bitPerWordPackedChar * i; + } + output[wordProcessed] = c; + wordProcessed++; + + } + + k = 0; + for (i=0; i < (textLength - wordProcessed * charPerWord - 1) / charPerByte + 1; i++) { + c = (unsigned int)input[byteProcessed] << shift; + for (j=0; j<charPerByte; j++) { + buffer[k] = c & mask; + c <<= bitPerBytePackedChar; + k++; + } + byteProcessed++; + } + + c = 0; + for (i=0; i<textLength - wordProcessed * charPerWord; i++) { + c |= buffer[i] >> bitPerWordPackedChar * i; + } + output[wordProcessed] = c; +} + +BWT *BWTCreate(const unsigned int textLength, unsigned int *decodeTable) +{ + BWT *bwt; + + bwt = (BWT*)calloc(1, sizeof(BWT)); + + bwt->textLength = 0; + bwt->inverseSa = 0; + + bwt->cumulativeFreq = (unsigned*)calloc((ALPHABET_SIZE + 1), sizeof(unsigned int*)); + initializeVAL(bwt->cumulativeFreq, ALPHABET_SIZE + 1, 0); + + bwt->bwtSizeInWord = 0; + bwt->saValueOnBoundary = NULL; + + // Generate decode tables + if (decodeTable == NULL) { + bwt->decodeTable = (unsigned*)calloc(DNA_OCC_CNT_TABLE_SIZE_IN_WORD, sizeof(unsigned int)); + GenerateDNAOccCountTable(bwt->decodeTable); + } else { + bwt->decodeTable = decodeTable; + } + + bwt->occMajorSizeInWord = BWTOccValueMajorSizeInWord(textLength); + bwt->occValueMajor = (unsigned*)calloc(bwt->occMajorSizeInWord, sizeof(unsigned int)); + + bwt->occSizeInWord = 0; + bwt->occValue = NULL; + + bwt->saInterval = ALL_ONE_MASK; + bwt->saValueSize = 0; + bwt->saValue = NULL; + + bwt->inverseSaInterval = ALL_ONE_MASK; + bwt->inverseSaSize = 0; + bwt->inverseSa = NULL; + + return bwt; +} + +BWTInc *BWTIncCreate(const unsigned int textLength, const float targetNBit, + const unsigned int initialMaxBuildSize, const unsigned int incMaxBuildSize) +{ + BWTInc *bwtInc; + unsigned int i; + + if (targetNBit == 0) { + fprintf(stderr, "BWTIncCreate() : targetNBit = 0!\n"); + exit(1); + } + + bwtInc = (BWTInc*)calloc(1, sizeof(BWTInc)); + bwtInc->numberOfIterationDone = 0; + bwtInc->bwt = BWTCreate(textLength, NULL); + bwtInc->initialMaxBuildSize = initialMaxBuildSize; + bwtInc->incMaxBuildSize = incMaxBuildSize; + bwtInc->targetNBit = targetNBit; + bwtInc->cumulativeCountInCurrentBuild = (unsigned*)calloc((ALPHABET_SIZE + 1), sizeof(unsigned int)); + initializeVAL(bwtInc->cumulativeCountInCurrentBuild, ALPHABET_SIZE + 1, 0); + + // Build frequently accessed data + bwtInc->packedShift = (unsigned*)calloc(CHAR_PER_WORD, sizeof(unsigned int)); + for (i=0; i<CHAR_PER_WORD; i++) { + bwtInc->packedShift[i] = BITS_IN_WORD - (i+1) * BIT_PER_CHAR; + } + + bwtInc->targetTextLength = textLength; + bwtInc->availableWord = (unsigned int)((textLength + OCC_INTERVAL - 1) / OCC_INTERVAL * OCC_INTERVAL / BITS_IN_WORD * bwtInc->targetNBit); + if (bwtInc->availableWord < BWTResidentSizeInWord(textLength) + BWTOccValueMinorSizeInWord(textLength)) { + fprintf(stderr, "BWTIncCreate() : targetNBit is too low!\n"); + exit(1); + } + bwtInc->workingMemory = (unsigned*)calloc(bwtInc->availableWord, BYTES_IN_WORD); + + return bwtInc; + +} +// for BWTIncConstruct() +static void BWTIncPutPackedTextToRank(const unsigned int *packedText, unsigned int* __restrict rank, + unsigned int* __restrict cumulativeCount, const unsigned int numChar) +{ + unsigned int i, j; + unsigned int c, t; + unsigned int packedMask; + unsigned int rankIndex; + unsigned int lastWord, numCharInLastWord; + + lastWord = (numChar - 1) / CHAR_PER_WORD; + numCharInLastWord = numChar - lastWord * CHAR_PER_WORD; + + packedMask = ALL_ONE_MASK >> (BITS_IN_WORD - BIT_PER_CHAR); + rankIndex = numChar - 1; + + t = packedText[lastWord] >> (BITS_IN_WORD - numCharInLastWord * BIT_PER_CHAR); + for (i=0; i<numCharInLastWord; i++) { + c = t & packedMask; + cumulativeCount[c+1]++; + rank[rankIndex] = c; + rankIndex--; + t >>= BIT_PER_CHAR; + } + + for (i=lastWord; i--;) { // loop from lastWord - 1 to 0 + t = packedText[i]; + for (j=0; j<CHAR_PER_WORD; j++) { + c = t & packedMask; + cumulativeCount[c+1]++; + rank[rankIndex] = c; + rankIndex--; + t >>= BIT_PER_CHAR; + } + } + + // Convert occurrence to cumulativeCount + cumulativeCount[2] += cumulativeCount[1]; + cumulativeCount[3] += cumulativeCount[2]; + cumulativeCount[4] += cumulativeCount[3]; +} + + +static void ForwardDNAAllOccCountNoLimit(const unsigned int* dna, const unsigned int index, + unsigned int* __restrict occCount, const unsigned int* dnaDecodeTable) +{ + static const unsigned int truncateRightMask[16] = { 0x00000000, 0xC0000000, 0xF0000000, 0xFC000000, + 0xFF000000, 0xFFC00000, 0xFFF00000, 0xFFFC0000, + 0xFFFF0000, 0xFFFFC000, 0xFFFFF000, 0xFFFFFC00, + 0xFFFFFF00, 0xFFFFFFC0, 0xFFFFFFF0, 0xFFFFFFFC }; + + unsigned int iteration, wordToCount, charToCount; + unsigned int i, j, c; + unsigned int sum; + + occCount[0] = 0; + occCount[1] = 0; + occCount[2] = 0; + occCount[3] = 0; + + iteration = index / 256; + wordToCount = (index - iteration * 256) / 16; + charToCount = index - iteration * 256 - wordToCount * 16; + + for (i=0; i<iteration; i++) { + + sum = 0; + for (j=0; j<16; j++) { + sum += dnaDecodeTable[*dna >> 16]; + sum += dnaDecodeTable[*dna & 0x0000FFFF]; + dna++; + } + if (!DNA_OCC_SUM_EXCEPTION(sum)) { + occCount[0] += sum & 0x000000FF; sum >>= 8; + occCount[1] += sum & 0x000000FF; sum >>= 8; + occCount[2] += sum & 0x000000FF; sum >>= 8; + occCount[3] += sum; + } else { + // only some or all of the 3 bits are on + // in reality, only one of the four cases are possible + if (sum == 0x00000100) { + occCount[0] += 256; + } else if (sum == 0x00010000) { + occCount[1] += 256; + } else if (sum == 0x01000000) { + occCount[2] += 256; + } else if (sum == 0x00000000) { + occCount[3] += 256; + } else { + fprintf(stderr, "ForwardDNAAllOccCountNoLimit(): DNA occ sum exception!\n"); + exit(1); + } + } + + } + + sum = 0; + for (j=0; j<wordToCount; j++) { + sum += dnaDecodeTable[*dna >> 16]; + sum += dnaDecodeTable[*dna & 0x0000FFFF]; + dna++; + } + + if (charToCount > 0) { + c = *dna & truncateRightMask[charToCount]; // increase count of 'a' by 16 - c; + sum += dnaDecodeTable[c >> 16]; + sum += dnaDecodeTable[c & 0xFFFF]; + sum += charToCount - 16; // decrease count of 'a' by 16 - positionToProcess + } + + occCount[0] += sum & 0x000000FF; sum >>= 8; + occCount[1] += sum & 0x000000FF; sum >>= 8; + occCount[2] += sum & 0x000000FF; sum >>= 8; + occCount[3] += sum; +} + +static void BWTIncBuildPackedBwt(const unsigned int *relativeRank, unsigned int* __restrict bwt, const unsigned int numChar, + const unsigned int *cumulativeCount, const unsigned int *packedShift) { + + unsigned int i, c, r; + unsigned int previousRank, currentRank; + unsigned int wordIndex, charIndex; + unsigned int inverseSa0; + + inverseSa0 = previousRank = relativeRank[0]; + + for (i=1; i<=numChar; i++) { + currentRank = relativeRank[i]; + // previousRank > cumulativeCount[c] because $ is one of the char + c = (previousRank > cumulativeCount[1]) + (previousRank > cumulativeCount[2]) + + (previousRank > cumulativeCount[3]); + // set bwt for currentRank + if (c > 0) { + // c <> 'a' + r = currentRank; + if (r > inverseSa0) { + // - 1 because $ at inverseSa0 is not encoded + r--; + } + wordIndex = r / CHAR_PER_WORD; + charIndex = r - wordIndex * CHAR_PER_WORD; + bwt[wordIndex] |= c << packedShift[charIndex]; + } + previousRank = currentRank; + } +} + +static inline unsigned int BWTOccValueExplicit(const BWT *bwt, const unsigned int occIndexExplicit, + const unsigned int character) +{ + unsigned int occIndexMajor; + + occIndexMajor = occIndexExplicit * OCC_INTERVAL / OCC_INTERVAL_MAJOR; + + if (occIndexExplicit % OCC_VALUE_PER_WORD == 0) { + return bwt->occValueMajor[occIndexMajor * ALPHABET_SIZE + character] + + (bwt->occValue[occIndexExplicit / OCC_VALUE_PER_WORD * ALPHABET_SIZE + character] >> 16); + + } else { + return bwt->occValueMajor[occIndexMajor * ALPHABET_SIZE + character] + + (bwt->occValue[occIndexExplicit / OCC_VALUE_PER_WORD * ALPHABET_SIZE + character] & 0x0000FFFF); + } +} + + +static unsigned int ForwardDNAOccCount(const unsigned int* dna, const unsigned int index, const unsigned int character, + const unsigned int* dnaDecodeTable) +{ + static const unsigned int truncateRightMask[16] = { 0x00000000, 0xC0000000, 0xF0000000, 0xFC000000, + 0xFF000000, 0xFFC00000, 0xFFF00000, 0xFFFC0000, + 0xFFFF0000, 0xFFFFC000, 0xFFFFF000, 0xFFFFFC00, + 0xFFFFFF00, 0xFFFFFFC0, 0xFFFFFFF0, 0xFFFFFFFC }; + + unsigned int wordToCount, charToCount; + unsigned int i, c; + unsigned int sum = 0; + + wordToCount = index / 16; + charToCount = index - wordToCount * 16; + + for (i=0; i<wordToCount; i++) { + sum += dnaDecodeTable[dna[i] >> 16]; + sum += dnaDecodeTable[dna[i] & 0x0000FFFF]; + } + + if (charToCount > 0) { + c = dna[i] & truncateRightMask[charToCount]; // increase count of 'a' by 16 - c; + sum += dnaDecodeTable[c >> 16]; + sum += dnaDecodeTable[c & 0xFFFF]; + sum += charToCount - 16; // decrease count of 'a' by 16 - positionToProcess + } + + return (sum >> (character * 8)) & 0x000000FF; + +} + +static unsigned int BackwardDNAOccCount(const unsigned int* dna, const unsigned int index, const unsigned int character, + const unsigned int* dnaDecodeTable) +{ + static const unsigned int truncateLeftMask[16] = { 0x00000000, 0x00000003, 0x0000000F, 0x0000003F, + 0x000000FF, 0x000003FF, 0x00000FFF, 0x00003FFF, + 0x0000FFFF, 0x0003FFFF, 0x000FFFFF, 0x003FFFFF, + 0x00FFFFFF, 0x03FFFFFF, 0x0FFFFFFF, 0x3FFFFFFF }; + + unsigned int wordToCount, charToCount; + unsigned int i, c; + unsigned int sum = 0; + + wordToCount = index / 16; + charToCount = index - wordToCount * 16; + + dna -= wordToCount + 1; + + if (charToCount > 0) { + c = *dna & truncateLeftMask[charToCount]; // increase count of 'a' by 16 - c; + sum += dnaDecodeTable[c >> 16]; + sum += dnaDecodeTable[c & 0xFFFF]; + sum += charToCount - 16; // decrease count of 'a' by 16 - positionToProcess + } + + for (i=0; i<wordToCount; i++) { + dna++; + sum += dnaDecodeTable[*dna >> 16]; + sum += dnaDecodeTable[*dna & 0x0000FFFF]; + } + + return (sum >> (character * 8)) & 0x000000FF; + +} + +unsigned int BWTOccValue(const BWT *bwt, unsigned int index, const unsigned int character) { + + unsigned int occValue; + unsigned int occExplicitIndex, occIndex; + + // $ is supposed to be positioned at inverseSa0 but it is not encoded + // therefore index is subtracted by 1 for adjustment + if (index > bwt->inverseSa0) { + index--; + } + + occExplicitIndex = (index + OCC_INTERVAL / 2 - 1) / OCC_INTERVAL; // Bidirectional encoding + occIndex = occExplicitIndex * OCC_INTERVAL; + occValue = BWTOccValueExplicit(bwt, occExplicitIndex, character); + + if (occIndex == index) { + return occValue; + } + + if (occIndex < index) { + return occValue + ForwardDNAOccCount(bwt->bwtCode + occIndex / CHAR_PER_WORD, index - occIndex, character, bwt->decodeTable); + } else { + return occValue - BackwardDNAOccCount(bwt->bwtCode + occIndex / CHAR_PER_WORD, occIndex - index, character, bwt->decodeTable); + } + +} + +static unsigned int BWTIncGetAbsoluteRank(BWT *bwt, unsigned int* __restrict absoluteRank, unsigned int* __restrict seq, + const unsigned int *packedText, const unsigned int numChar, + const unsigned int* cumulativeCount, const unsigned int firstCharInLastIteration) +{ + unsigned int saIndex; + unsigned int lastWord; + unsigned int packedMask; + unsigned int i, j; + unsigned int c, t; + unsigned int rankIndex; + unsigned int shift; + unsigned int seqIndexFromStart[ALPHABET_SIZE]; + unsigned int seqIndexFromEnd[ALPHABET_SIZE]; + + for (i=0; i<ALPHABET_SIZE; i++) { + seqIndexFromStart[i] = cumulativeCount[i]; + seqIndexFromEnd[i] = cumulativeCount[i+1] - 1; + } + + shift = BITS_IN_WORD - BIT_PER_CHAR; + packedMask = ALL_ONE_MASK >> shift; + saIndex = bwt->inverseSa0; + rankIndex = numChar - 1; + + lastWord = numChar / CHAR_PER_WORD; + for (i=lastWord; i--;) { // loop from lastWord - 1 to 0 + t = packedText[i]; + for (j=0; j<CHAR_PER_WORD; j++) { + c = t & packedMask; + saIndex = bwt->cumulativeFreq[c] + BWTOccValue(bwt, saIndex, c) + 1; + // A counting sort using the first character of suffix is done here + // If rank > inverseSa0 -> fill seq from end, otherwise fill seq from start -> to leave the right entry for inverseSa0 + if (saIndex > bwt->inverseSa0) { + seq[seqIndexFromEnd[c]] = rankIndex; + absoluteRank[seqIndexFromEnd[c]] = saIndex; + seqIndexFromEnd[c]--; + } else { + seq[seqIndexFromStart[c]] = rankIndex; + absoluteRank[seqIndexFromStart[c]] = saIndex; + seqIndexFromStart[c]++; + } + rankIndex--; + t >>= BIT_PER_CHAR; + } + } + + absoluteRank[seqIndexFromStart[firstCharInLastIteration]] = bwt->inverseSa0; // representing the substring of all preceding characters + seq[seqIndexFromStart[firstCharInLastIteration]] = numChar; + + return seqIndexFromStart[firstCharInLastIteration]; +} + +static void BWTIncSortKey(unsigned int* __restrict key, unsigned int* __restrict seq, const unsigned int numItem) +{ + #define EQUAL_KEY_THRESHOLD 4 // Partition for equal key if data array size / the number of data with equal value with pivot < EQUAL_KEY_THRESHOLD + + int lowIndex, highIndex, midIndex; + int lowPartitionIndex, highPartitionIndex; + int lowStack[32], highStack[32]; + int stackDepth; + int i, j; + unsigned int tempSeq, tempKey; + int numberOfEqualKey; + + if (numItem < 2) return; + + stackDepth = 0; + + lowIndex = 0; + highIndex = numItem - 1; + + for (;;) { + + for (;;) { + + // Sort small array of data + if (highIndex - lowIndex < BWTINC_INSERT_SORT_NUM_ITEM) { // Insertion sort on smallest arrays + for (i=lowIndex+1; i<=highIndex; i++) { + tempSeq = seq[i]; + tempKey = key[i]; + for (j = i; j > lowIndex && key[j-1] > tempKey; j--) { + seq[j] = seq[j-1]; + key[j] = key[j-1]; + } + if (j != i) { + seq[j] = tempSeq; + key[j] = tempKey; + } + } + break; + } + + // Choose pivot as median of the lowest, middle, and highest data; sort the three data + + midIndex = average(lowIndex, highIndex); + if (key[lowIndex] > key[midIndex]) { + tempSeq = seq[lowIndex]; + tempKey = key[lowIndex]; + seq[lowIndex] = seq[midIndex]; + key[lowIndex] = key[midIndex]; + seq[midIndex] = tempSeq; + key[midIndex] = tempKey; + } + if (key[lowIndex] > key[highIndex]) { + tempSeq = seq[lowIndex]; + tempKey = key[lowIndex]; + seq[lowIndex] = seq[highIndex]; + key[lowIndex] = key[highIndex]; + seq[highIndex] = tempSeq; + key[highIndex] = tempKey; + } + if (key[midIndex] > key[highIndex]) { + tempSeq = seq[midIndex]; + tempKey = key[midIndex]; + seq[midIndex] = seq[highIndex]; + key[midIndex] = key[highIndex]; + seq[highIndex] = tempSeq; + key[highIndex] = tempKey; + } + + // Partition data + + numberOfEqualKey = 0; + + lowPartitionIndex = lowIndex + 1; + highPartitionIndex = highIndex - 1; + + for (;;) { + while (lowPartitionIndex <= highPartitionIndex && key[lowPartitionIndex] <= key[midIndex]) { + numberOfEqualKey += (key[lowPartitionIndex] == key[midIndex]); + lowPartitionIndex++; + } + while (lowPartitionIndex < highPartitionIndex) { + if (key[midIndex] >= key[highPartitionIndex]) { + numberOfEqualKey += (key[midIndex] == key[highPartitionIndex]); + break; + } + highPartitionIndex--; + } + if (lowPartitionIndex >= highPartitionIndex) { + break; + } + tempSeq = seq[lowPartitionIndex]; + tempKey = key[lowPartitionIndex]; + seq[lowPartitionIndex] = seq[highPartitionIndex]; + key[lowPartitionIndex] = key[highPartitionIndex]; + seq[highPartitionIndex] = tempSeq; + key[highPartitionIndex] = tempKey; + if (highPartitionIndex == midIndex) { + // partition key has been moved + midIndex = lowPartitionIndex; + } + lowPartitionIndex++; + highPartitionIndex--; + } + + // Adjust the partition index + highPartitionIndex = lowPartitionIndex; + lowPartitionIndex--; + + // move the partition key to end of low partition + tempSeq = seq[midIndex]; + tempKey = key[midIndex]; + seq[midIndex] = seq[lowPartitionIndex]; + key[midIndex] = key[lowPartitionIndex]; + seq[lowPartitionIndex] = tempSeq; + key[lowPartitionIndex] = tempKey; + + if (highIndex - lowIndex + BWTINC_INSERT_SORT_NUM_ITEM <= EQUAL_KEY_THRESHOLD * numberOfEqualKey) { + + // Many keys = partition key; separate the equal key data from the lower partition + + midIndex = lowIndex; + + for (;;) { + while (midIndex < lowPartitionIndex && key[midIndex] < key[lowPartitionIndex]) { + midIndex++; + } + while (midIndex < lowPartitionIndex && key[lowPartitionIndex] == key[lowPartitionIndex - 1]) { + lowPartitionIndex--; + } + if (midIndex >= lowPartitionIndex) { + break; + } + tempSeq = seq[midIndex]; + tempKey = key[midIndex]; + seq[midIndex] = seq[lowPartitionIndex - 1]; + key[midIndex] = key[lowPartitionIndex - 1]; + seq[lowPartitionIndex - 1] = tempSeq; + key[lowPartitionIndex - 1] = tempKey; + midIndex++; + lowPartitionIndex--; + } + + } + + if (lowPartitionIndex - lowIndex > highIndex - highPartitionIndex) { + // put the larger partition to stack + lowStack[stackDepth] = lowIndex; + highStack[stackDepth] = lowPartitionIndex - 1; + stackDepth++; + // sort the smaller partition first + lowIndex = highPartitionIndex; + } else { + // put the larger partition to stack + lowStack[stackDepth] = highPartitionIndex; + highStack[stackDepth] = highIndex; + stackDepth++; + // sort the smaller partition first + if (lowPartitionIndex > lowIndex) { + highIndex = lowPartitionIndex - 1; + } else { + // all keys in the partition equals to the partition key + break; + } + } + continue; + } + + // Pop a range from stack + if (stackDepth > 0) { + stackDepth--; + lowIndex = lowStack[stackDepth]; + highIndex = highStack[stackDepth]; + continue; + } else return; + } +} + + +static void BWTIncBuildRelativeRank(unsigned int* __restrict sortedRank, unsigned int* __restrict seq, + unsigned int* __restrict relativeRank, const unsigned int numItem, + unsigned int oldInverseSa0, const unsigned int *cumulativeCount) +{ + unsigned int i, c; + unsigned int s, r; + unsigned int lastRank, lastIndex; + unsigned int oldInverseSa0RelativeRank = 0; + unsigned int freq; + + lastIndex = numItem; + lastRank = sortedRank[numItem]; + if (lastRank > oldInverseSa0) { + sortedRank[numItem]--; // to prepare for merging; $ is not encoded in bwt + } + s = seq[numItem]; + relativeRank[s] = numItem; + if (lastRank == oldInverseSa0) { + oldInverseSa0RelativeRank = numItem; + oldInverseSa0++; // so that this segment of code is not run again + lastRank++; // so that oldInverseSa0 become a sorted group with 1 item + } + + c = ALPHABET_SIZE - 1; + freq = cumulativeCount[c]; + + for (i=numItem; i--;) { // from numItem - 1 to 0 + r = sortedRank[i]; + if (r > oldInverseSa0) { + sortedRank[i]--; // to prepare for merging; $ is not encoded in bwt + } + s = seq[i]; + if (i < freq) { + if (lastIndex >= freq) { + lastRank++; // to trigger the group across alphabet boundary to be split + } + c--; + freq = cumulativeCount[c]; + } + if (r == lastRank) { + relativeRank[s] = lastIndex; + } else { + if (i == lastIndex - 1) { + if (lastIndex < numItem && (int)seq[lastIndex + 1] < 0) { + seq[lastIndex] = seq[lastIndex + 1] - 1; + } else { + seq[lastIndex] = (unsigned int)-1; + } + } + lastIndex = i; + lastRank = r; + relativeRank[s] = i; + if (r == oldInverseSa0) { + oldInverseSa0RelativeRank = i; + oldInverseSa0++; // so that this segment of code is not run again + lastRank++; // so that oldInverseSa0 become a sorted group with 1 item + } + } + } + +} + +static void BWTIncBuildBwt(unsigned int* seq, const unsigned int *relativeRank, const unsigned int numChar, + const unsigned int *cumulativeCount) +{ + unsigned int i, c; + unsigned int previousRank, currentRank; + + previousRank = relativeRank[0]; + + for (i=1; i<=numChar; i++) { + currentRank = relativeRank[i]; + c = (previousRank >= cumulativeCount[1]) + (previousRank >= cumulativeCount[2]) + + (previousRank >= cumulativeCount[3]); + seq[currentRank] = c; + previousRank = currentRank; + } +} + +static void BWTIncMergeBwt(const unsigned int *sortedRank, const unsigned int* oldBwt, const unsigned int *insertBwt, + unsigned int* __restrict mergedBwt, const unsigned int numOldBwt, const unsigned int numInsertBwt) +{ + unsigned int bitsInWordMinusBitPerChar; + unsigned int leftShift, rightShift; + unsigned int o; + unsigned int oIndex, iIndex, mIndex; + unsigned int mWord, mChar, oWord, oChar; + unsigned int numInsert; + + bitsInWordMinusBitPerChar = BITS_IN_WORD - BIT_PER_CHAR; + + oIndex = 0; + iIndex = 0; + mIndex = 0; + + mWord = 0; + mChar = 0; + + mergedBwt[0] = 0; // this can be cleared as merged Bwt slightly shift to the left in each iteration + + while (oIndex < numOldBwt) { + + // copy from insertBwt + while (iIndex <= numInsertBwt && sortedRank[iIndex] <= oIndex) { + if (sortedRank[iIndex] != 0) { // special value to indicate that this is for new inverseSa0 + mergedBwt[mWord] |= insertBwt[iIndex] << (BITS_IN_WORD - (mChar + 1) * BIT_PER_CHAR); + mIndex++; + mChar++; + if (mChar == CHAR_PER_WORD) { + mChar = 0; + mWord++; + mergedBwt[mWord] = 0; // no need to worry about crossing mergedBwt boundary + } + } + iIndex++; + } + + // Copy from oldBwt to mergedBwt + if (iIndex <= numInsertBwt) { + o = sortedRank[iIndex]; + } else { + o = numOldBwt; + } + numInsert = o - oIndex; + + oWord = oIndex / CHAR_PER_WORD; + oChar = oIndex - oWord * CHAR_PER_WORD; + if (oChar > mChar) { + leftShift = (oChar - mChar) * BIT_PER_CHAR; + rightShift = (CHAR_PER_WORD + mChar - oChar) * BIT_PER_CHAR; + mergedBwt[mWord] = mergedBwt[mWord] + | (oldBwt[oWord] << (oChar * BIT_PER_CHAR) >> (mChar * BIT_PER_CHAR)) + | (oldBwt[oWord+1] >> rightShift); + oIndex += min(numInsert, CHAR_PER_WORD - mChar); + while (o > oIndex) { + oWord++; + mWord++; + mergedBwt[mWord] = (oldBwt[oWord] << leftShift) | (oldBwt[oWord+1] >> rightShift); + oIndex += CHAR_PER_WORD; + } + } else if (oChar < mChar) { + rightShift = (mChar - oChar) * BIT_PER_CHAR; + leftShift = (CHAR_PER_WORD + oChar - mChar) * BIT_PER_CHAR; + mergedBwt[mWord] = mergedBwt[mWord] + | (oldBwt[oWord] << (oChar * BIT_PER_CHAR) >> (mChar * BIT_PER_CHAR)); + oIndex += min(numInsert, CHAR_PER_WORD - mChar); + while (o > oIndex) { + oWord++; + mWord++; + mergedBwt[mWord] = (oldBwt[oWord-1] << leftShift) | (oldBwt[oWord] >> rightShift); + oIndex += CHAR_PER_WORD; + } + } else { // oChar == mChar + mergedBwt[mWord] = mergedBwt[mWord] | truncateLeft(oldBwt[oWord], mChar * BIT_PER_CHAR); + oIndex += min(numInsert, CHAR_PER_WORD - mChar); + while (o > oIndex) { + oWord++; + mWord++; + mergedBwt[mWord] = oldBwt[oWord]; + oIndex += CHAR_PER_WORD; + } + } + oIndex = o; + mIndex += numInsert; + + // Clear the trailing garbage in mergedBwt + mWord = mIndex / CHAR_PER_WORD; + mChar = mIndex - mWord * CHAR_PER_WORD; + if (mChar == 0) { + mergedBwt[mWord] = 0; + } else { + mergedBwt[mWord] = truncateRight(mergedBwt[mWord], (BITS_IN_WORD - mChar * BIT_PER_CHAR)); + } + + } + + // copy from insertBwt + while (iIndex <= numInsertBwt) { + if (sortedRank[iIndex] != 0) { + mergedBwt[mWord] |= insertBwt[iIndex] << (BITS_IN_WORD - (mChar + 1) * BIT_PER_CHAR); + mIndex++; + mChar++; + if (mChar == CHAR_PER_WORD) { + mChar = 0; + mWord++; + mergedBwt[mWord] = 0; // no need to worry about crossing mergedBwt boundary + } + } + iIndex++; + } +} + +void BWTClearTrailingBwtCode(BWT *bwt) +{ + unsigned int bwtResidentSizeInWord; + unsigned int wordIndex, offset; + unsigned int i; + + bwtResidentSizeInWord = BWTResidentSizeInWord(bwt->textLength); + + wordIndex = bwt->textLength / CHAR_PER_WORD; + offset = (bwt->textLength - wordIndex * CHAR_PER_WORD) * BIT_PER_CHAR; + if (offset > 0) { + bwt->bwtCode[wordIndex] = truncateRight(bwt->bwtCode[wordIndex], BITS_IN_WORD - offset); + } else { + if (wordIndex < bwtResidentSizeInWord) { + bwt->bwtCode[wordIndex] = 0; + } + } + + for (i=wordIndex+1; i<bwtResidentSizeInWord; i++) { + bwt->bwtCode[i] = 0; + } +} + + +void BWTGenerateOccValueFromBwt(const unsigned int* bwt, unsigned int* __restrict occValue, + unsigned int* __restrict occValueMajor, + const unsigned int textLength, const unsigned int* decodeTable) +{ + unsigned int numberOfOccValueMajor, numberOfOccValue; + unsigned int wordBetweenOccValue; + unsigned int numberOfOccIntervalPerMajor; + unsigned int c; + unsigned int i, j; + unsigned int occMajorIndex; + unsigned int occIndex, bwtIndex; + unsigned int sum; + unsigned int tempOccValue0[ALPHABET_SIZE], tempOccValue1[ALPHABET_SIZE]; + + wordBetweenOccValue = OCC_INTERVAL / CHAR_PER_WORD; + + // Calculate occValue + // [lh3] by default: OCC_INTERVAL_MAJOR=65536, OCC_INTERVAL=256 + numberOfOccValue = (textLength + OCC_INTERVAL - 1) / OCC_INTERVAL + 1; // Value at both end for bi-directional encoding + numberOfOccIntervalPerMajor = OCC_INTERVAL_MAJOR / OCC_INTERVAL; + numberOfOccValueMajor = (numberOfOccValue + numberOfOccIntervalPerMajor - 1) / numberOfOccIntervalPerMajor; + + tempOccValue0[0] = 0; + tempOccValue0[1] = 0; + tempOccValue0[2] = 0; + tempOccValue0[3] = 0; + occValueMajor[0] = 0; + occValueMajor[1] = 0; + occValueMajor[2] = 0; + occValueMajor[3] = 0; + + occIndex = 0; + bwtIndex = 0; + for (occMajorIndex=1; occMajorIndex<numberOfOccValueMajor; occMajorIndex++) { + + for (i=0; i<numberOfOccIntervalPerMajor/2; i++) { + + sum = 0; + tempOccValue1[0] = tempOccValue0[0]; + tempOccValue1[1] = tempOccValue0[1]; + tempOccValue1[2] = tempOccValue0[2]; + tempOccValue1[3] = tempOccValue0[3]; + + for (j=0; j<wordBetweenOccValue; j++) { + c = bwt[bwtIndex]; + sum += decodeTable[c >> 16]; + sum += decodeTable[c & 0x0000FFFF]; + bwtIndex++; + } + if (!DNA_OCC_SUM_EXCEPTION(sum)) { + tempOccValue1[0] += (sum & 0x000000FF); sum >>= 8; + tempOccValue1[1] += (sum & 0x000000FF); sum >>= 8; + tempOccValue1[2] += (sum & 0x000000FF); sum >>= 8; + tempOccValue1[3] += sum; + } else { + if (sum == 0x00000100) { + tempOccValue1[0] += 256; + } else if (sum == 0x00010000) { + tempOccValue1[1] += 256; + } else if (sum == 0x01000000) { + tempOccValue1[2] += 256; + } else { + tempOccValue1[3] += 256; + } + } + occValue[occIndex * 4 + 0] = (tempOccValue0[0] << 16) | tempOccValue1[0]; + occValue[occIndex * 4 + 1] = (tempOccValue0[1] << 16) | tempOccValue1[1]; + occValue[occIndex * 4 + 2] = (tempOccValue0[2] << 16) | tempOccValue1[2]; + occValue[occIndex * 4 + 3] = (tempOccValue0[3] << 16) | tempOccValue1[3]; + tempOccValue0[0] = tempOccValue1[0]; + tempOccValue0[1] = tempOccValue1[1]; + tempOccValue0[2] = tempOccValue1[2]; + tempOccValue0[3] = tempOccValue1[3]; + sum = 0; + + occIndex++; + + for (j=0; j<wordBetweenOccValue; j++) { + c = bwt[bwtIndex]; + sum += decodeTable[c >> 16]; + sum += decodeTable[c & 0x0000FFFF]; + bwtIndex++; + } + if (!DNA_OCC_SUM_EXCEPTION(sum)) { + tempOccValue0[0] += (sum & 0x000000FF); sum >>= 8; + tempOccValue0[1] += (sum & 0x000000FF); sum >>= 8; + tempOccValue0[2] += (sum & 0x000000FF); sum >>= 8; + tempOccValue0[3] += sum; + } else { + if (sum == 0x00000100) { + tempOccValue0[0] += 256; + } else if (sum == 0x00010000) { + tempOccValue0[1] += 256; + } else if (sum == 0x01000000) { + tempOccValue0[2] += 256; + } else { + tempOccValue0[3] += 256; + } + } + } + + occValueMajor[occMajorIndex * 4 + 0] = occValueMajor[(occMajorIndex - 1) * 4 + 0] + tempOccValue0[0]; + occValueMajor[occMajorIndex * 4 + 1] = occValueMajor[(occMajorIndex - 1) * 4 + 1] + tempOccValue0[1]; + occValueMajor[occMajorIndex * 4 + 2] = occValueMajor[(occMajorIndex - 1) * 4 + 2] + tempOccValue0[2]; + occValueMajor[occMajorIndex * 4 + 3] = occValueMajor[(occMajorIndex - 1) * 4 + 3] + tempOccValue0[3]; + tempOccValue0[0] = 0; + tempOccValue0[1] = 0; + tempOccValue0[2] = 0; + tempOccValue0[3] = 0; + + } + + while (occIndex < (numberOfOccValue-1)/2) { + sum = 0; + tempOccValue1[0] = tempOccValue0[0]; + tempOccValue1[1] = tempOccValue0[1]; + tempOccValue1[2] = tempOccValue0[2]; + tempOccValue1[3] = tempOccValue0[3]; + for (j=0; j<wordBetweenOccValue; j++) { + c = bwt[bwtIndex]; + sum += decodeTable[c >> 16]; + sum += decodeTable[c & 0x0000FFFF]; + bwtIndex++; + } + if (!DNA_OCC_SUM_EXCEPTION(sum)) { + tempOccValue1[0] += (sum & 0x000000FF); sum >>= 8; + tempOccValue1[1] += (sum & 0x000000FF); sum >>= 8; + tempOccValue1[2] += (sum & 0x000000FF); sum >>= 8; + tempOccValue1[3] += sum; + } else { + if (sum == 0x00000100) { + tempOccValue1[0] += 256; + } else if (sum == 0x00010000) { + tempOccValue1[1] += 256; + } else if (sum == 0x01000000) { + tempOccValue1[2] += 256; + } else { + tempOccValue1[3] += 256; + } + } + occValue[occIndex * 4 + 0] = (tempOccValue0[0] << 16) | tempOccValue1[0]; + occValue[occIndex * 4 + 1] = (tempOccValue0[1] << 16) | tempOccValue1[1]; + occValue[occIndex * 4 + 2] = (tempOccValue0[2] << 16) | tempOccValue1[2]; + occValue[occIndex * 4 + 3] = (tempOccValue0[3] << 16) | tempOccValue1[3]; + tempOccValue0[0] = tempOccValue1[0]; + tempOccValue0[1] = tempOccValue1[1]; + tempOccValue0[2] = tempOccValue1[2]; + tempOccValue0[3] = tempOccValue1[3]; + sum = 0; + occIndex++; + + for (j=0; j<wordBetweenOccValue; j++) { + c = bwt[bwtIndex]; + sum += decodeTable[c >> 16]; + sum += decodeTable[c & 0x0000FFFF]; + bwtIndex++; + } + if (!DNA_OCC_SUM_EXCEPTION(sum)) { + tempOccValue0[0] += (sum & 0x000000FF); sum >>= 8; + tempOccValue0[1] += (sum & 0x000000FF); sum >>= 8; + tempOccValue0[2] += (sum & 0x000000FF); sum >>= 8; + tempOccValue0[3] += sum; + } else { + if (sum == 0x00000100) { + tempOccValue0[0] += 256; + } else if (sum == 0x00010000) { + tempOccValue0[1] += 256; + } else if (sum == 0x01000000) { + tempOccValue0[2] += 256; + } else { + tempOccValue0[3] += 256; + } + } + } + + sum = 0; + tempOccValue1[0] = tempOccValue0[0]; + tempOccValue1[1] = tempOccValue0[1]; + tempOccValue1[2] = tempOccValue0[2]; + tempOccValue1[3] = tempOccValue0[3]; + + if (occIndex * 2 < numberOfOccValue - 1) { + for (j=0; j<wordBetweenOccValue; j++) { + c = bwt[bwtIndex]; + sum += decodeTable[c >> 16]; + sum += decodeTable[c & 0x0000FFFF]; + bwtIndex++; + } + if (!DNA_OCC_SUM_EXCEPTION(sum)) { + tempOccValue1[0] += (sum & 0x000000FF); sum >>= 8; + tempOccValue1[1] += (sum & 0x000000FF); sum >>= 8; + tempOccValue1[2] += (sum & 0x000000FF); sum >>= 8; + tempOccValue1[3] += sum; + } else { + if (sum == 0x00000100) { + tempOccValue1[0] += 256; + } else if (sum == 0x00010000) { + tempOccValue1[1] += 256; + } else if (sum == 0x01000000) { + tempOccValue1[2] += 256; + } else { + tempOccValue1[3] += 256; + } + } + } + + occValue[occIndex * 4 + 0] = (tempOccValue0[0] << 16) | tempOccValue1[0]; + occValue[occIndex * 4 + 1] = (tempOccValue0[1] << 16) | tempOccValue1[1]; + occValue[occIndex * 4 + 2] = (tempOccValue0[2] << 16) | tempOccValue1[2]; + occValue[occIndex * 4 + 3] = (tempOccValue0[3] << 16) | tempOccValue1[3]; + +} + +static void BWTIncConstruct(BWTInc *bwtInc, const unsigned int numChar) +{ + unsigned int i; + unsigned int mergedBwtSizeInWord, mergedOccSizeInWord; + unsigned int firstCharInThisIteration; + + unsigned int *relativeRank, *seq, *sortedRank, *insertBwt, *mergedBwt; + unsigned int newInverseSa0RelativeRank, oldInverseSa0RelativeRank, newInverseSa0; + + #ifdef DEBUG + if (numChar > bwtInc->buildSize) { + fprintf(stderr, "BWTIncConstruct(): numChar > buildSize!\n"); + exit(1); + } + #endif + + mergedBwtSizeInWord = BWTResidentSizeInWord(bwtInc->bwt->textLength + numChar); + mergedOccSizeInWord = BWTOccValueMinorSizeInWord(bwtInc->bwt->textLength + numChar); + + initializeVAL(bwtInc->cumulativeCountInCurrentBuild, ALPHABET_SIZE + 1, 0); + + if (bwtInc->bwt->textLength == 0) { // Initial build + + // Set address + seq = bwtInc->workingMemory; + relativeRank = seq + bwtInc->buildSize + 1; + mergedBwt = insertBwt = bwtInc->workingMemory + bwtInc->availableWord - mergedBwtSizeInWord; // build in place + + BWTIncPutPackedTextToRank(bwtInc->packedText, relativeRank, bwtInc->cumulativeCountInCurrentBuild, numChar); + + firstCharInThisIteration = relativeRank[0]; + relativeRank[numChar] = 0; + + // Sort suffix + QSufSortSuffixSort((int*)relativeRank, (int*)seq, (int)numChar, (int)ALPHABET_SIZE - 1, 0, FALSE); + newInverseSa0 = relativeRank[0]; + + // Clear BWT area + initializeVAL(insertBwt, mergedBwtSizeInWord, 0); + + // Build BWT + BWTIncBuildPackedBwt(relativeRank, insertBwt, numChar, bwtInc->cumulativeCountInCurrentBuild, bwtInc->packedShift); + + // so that the cumulativeCount is not deducted + bwtInc->firstCharInLastIteration = ALPHABET_SIZE; + + } else { // Incremental build + // Set address + sortedRank = bwtInc->workingMemory; + seq = sortedRank + bwtInc->buildSize + 1; + insertBwt = seq; + relativeRank = seq + bwtInc->buildSize + 1; + + // Store the first character of this iteration + firstCharInThisIteration = bwtInc->packedText[0] >> (BITS_IN_WORD - BIT_PER_CHAR); + + // Count occurrence of input text + ForwardDNAAllOccCountNoLimit(bwtInc->packedText, numChar, bwtInc->cumulativeCountInCurrentBuild + 1, bwtInc->bwt->decodeTable); + // Add the first character of the previous iteration to represent the inverseSa0 of the previous iteration + bwtInc->cumulativeCountInCurrentBuild[bwtInc->firstCharInLastIteration + 1]++; + bwtInc->cumulativeCountInCurrentBuild[2] += bwtInc->cumulativeCountInCurrentBuild[1]; + bwtInc->cumulativeCountInCurrentBuild[3] += bwtInc->cumulativeCountInCurrentBuild[2]; + bwtInc->cumulativeCountInCurrentBuild[4] += bwtInc->cumulativeCountInCurrentBuild[3]; + + // Get rank of new suffix among processed suffix + // The seq array is built into ALPHABET_SIZE + 2 groups; ALPHABET_SIZE groups + 1 group divided into 2 by inverseSa0 + inverseSa0 as 1 group + oldInverseSa0RelativeRank = BWTIncGetAbsoluteRank(bwtInc->bwt, sortedRank, seq, bwtInc->packedText, + numChar, bwtInc->cumulativeCountInCurrentBuild, bwtInc->firstCharInLastIteration); + + // Sort rank by ALPHABET_SIZE + 2 groups (or ALPHABET_SIZE + 1 groups when inverseSa0 sit on the border of a group) + for (i=0; i<ALPHABET_SIZE; i++) { + if (bwtInc->cumulativeCountInCurrentBuild[i] > oldInverseSa0RelativeRank || + bwtInc->cumulativeCountInCurrentBuild[i+1] <= oldInverseSa0RelativeRank) { + BWTIncSortKey(sortedRank + bwtInc->cumulativeCountInCurrentBuild[i], seq + bwtInc->cumulativeCountInCurrentBuild[i], bwtInc->cumulativeCountInCurrentBuild[i+1] - bwtInc->cumulativeCountInCurrentBuild[i]); + } else { + if (bwtInc->cumulativeCountInCurrentBuild[i] < oldInverseSa0RelativeRank) { + BWTIncSortKey(sortedRank + bwtInc->cumulativeCountInCurrentBuild[i], seq + bwtInc->cumulativeCountInCurrentBuild[i], oldInverseSa0RelativeRank - bwtInc->cumulativeCountInCurrentBuild[i]); + } + if (bwtInc->cumulativeCountInCurrentBuild[i+1] > oldInverseSa0RelativeRank + 1) { + BWTIncSortKey(sortedRank + oldInverseSa0RelativeRank + 1, seq + oldInverseSa0RelativeRank + 1, bwtInc->cumulativeCountInCurrentBuild[i+1] - oldInverseSa0RelativeRank - 1); + } + } + } + + // build relative rank; sortedRank is updated for merging to cater for the fact that $ is not encoded in bwt + // the cumulative freq information is used to make sure that inverseSa0 and suffix beginning with different characters are kept in different unsorted groups) + BWTIncBuildRelativeRank(sortedRank, seq, relativeRank, numChar, bwtInc->bwt->inverseSa0, bwtInc->cumulativeCountInCurrentBuild); +#ifdef DEBUG + if (relativeRank[numChar] != oldInverseSa0RelativeRank) { + fprintf(stderr, "BWTIncConstruct(): relativeRank[numChar] != oldInverseSa0RelativeRank!\n"); + exit(1); + } +#endif + + // Sort suffix + QSufSortSuffixSort((int*)relativeRank, (int*)seq, (int)numChar, (int)numChar, 1, TRUE); + + newInverseSa0RelativeRank = relativeRank[0]; + newInverseSa0 = sortedRank[newInverseSa0RelativeRank] + newInverseSa0RelativeRank; + + sortedRank[newInverseSa0RelativeRank] = 0; // a special value so that this is skipped in the merged bwt + + // Build BWT + BWTIncBuildBwt(seq, relativeRank, numChar, bwtInc->cumulativeCountInCurrentBuild); + + // Merge BWT + mergedBwt = bwtInc->workingMemory + bwtInc->availableWord - mergedBwtSizeInWord + - bwtInc->numberOfIterationDone * OCC_INTERVAL / BIT_PER_CHAR; + // minus numberOfIteration * occInterval to create a buffer for merging + BWTIncMergeBwt(sortedRank, bwtInc->bwt->bwtCode, insertBwt, mergedBwt, bwtInc->bwt->textLength, numChar); + + } + + // Build auxiliary structure and update info and pointers in BWT + bwtInc->bwt->textLength += numChar; + bwtInc->bwt->bwtCode = mergedBwt; + bwtInc->bwt->bwtSizeInWord = mergedBwtSizeInWord; + bwtInc->bwt->occSizeInWord = mergedOccSizeInWord; + if (mergedBwt < bwtInc->workingMemory + mergedOccSizeInWord) { + fprintf(stderr, "BWTIncConstruct() : Not enough memory allocated!\n"); + exit(1); + } + + bwtInc->bwt->occValue = mergedBwt - mergedOccSizeInWord; + + BWTClearTrailingBwtCode(bwtInc->bwt); + BWTGenerateOccValueFromBwt(bwtInc->bwt->bwtCode, bwtInc->bwt->occValue, bwtInc->bwt->occValueMajor, + bwtInc->bwt->textLength, bwtInc->bwt->decodeTable); + + bwtInc->bwt->inverseSa0 = newInverseSa0; + + bwtInc->bwt->cumulativeFreq[1] += bwtInc->cumulativeCountInCurrentBuild[1] - (bwtInc->firstCharInLastIteration <= 0); + bwtInc->bwt->cumulativeFreq[2] += bwtInc->cumulativeCountInCurrentBuild[2] - (bwtInc->firstCharInLastIteration <= 1); + bwtInc->bwt->cumulativeFreq[3] += bwtInc->cumulativeCountInCurrentBuild[3] - (bwtInc->firstCharInLastIteration <= 2); + bwtInc->bwt->cumulativeFreq[4] += bwtInc->cumulativeCountInCurrentBuild[4] - (bwtInc->firstCharInLastIteration <= 3); + + bwtInc->firstCharInLastIteration = firstCharInThisIteration; + + // Set build size and text address for the next build + BWTIncSetBuildSizeAndTextAddr(bwtInc); + bwtInc->numberOfIterationDone++; + +} + +BWTInc *BWTIncConstructFromPacked(const char *inputFileName, const float targetNBit, + const unsigned int initialMaxBuildSize, const unsigned int incMaxBuildSize) +{ + + FILE *packedFile; + unsigned int packedFileLen; + unsigned int totalTextLength; + unsigned int textToLoad, textSizeInByte; + unsigned int processedTextLength; + unsigned char lastByteLength; + + BWTInc *bwtInc; + + packedFile = (FILE*)fopen(inputFileName, "rb"); + + if (packedFile == NULL) { + fprintf(stderr, "BWTIncConstructFromPacked() : Cannot open inputFileName!\n"); + exit(1); + } + + fseek(packedFile, -1, SEEK_END); + packedFileLen = ftell(packedFile); + if ((int)packedFileLen < 0) { + fprintf(stderr, "BWTIncConstructFromPacked: Cannot determine file length!\n"); + exit(1); + } + fread(&lastByteLength, sizeof(unsigned char), 1, packedFile); + totalTextLength = TextLengthFromBytePacked(packedFileLen, BIT_PER_CHAR, lastByteLength); + + bwtInc = BWTIncCreate(totalTextLength, targetNBit, initialMaxBuildSize, incMaxBuildSize); + + BWTIncSetBuildSizeAndTextAddr(bwtInc); + + if (bwtInc->buildSize > totalTextLength) { + textToLoad = totalTextLength; + } else { + textToLoad = totalTextLength - ((totalTextLength - bwtInc->buildSize + CHAR_PER_WORD - 1) / CHAR_PER_WORD * CHAR_PER_WORD); + } + textSizeInByte = textToLoad / CHAR_PER_BYTE; // excluded the odd byte + + fseek(packedFile, -2, SEEK_CUR); + fseek(packedFile, -((int)textSizeInByte), SEEK_CUR); + fread(bwtInc->textBuffer, sizeof(unsigned char), textSizeInByte + 1, packedFile); + fseek(packedFile, -((int)textSizeInByte + 1), SEEK_CUR); + + ConvertBytePackedToWordPacked(bwtInc->textBuffer, bwtInc->packedText, ALPHABET_SIZE, textToLoad); + BWTIncConstruct(bwtInc, textToLoad); + + processedTextLength = textToLoad; + + while (processedTextLength < totalTextLength) { + textToLoad = bwtInc->buildSize / CHAR_PER_WORD * CHAR_PER_WORD; + if (textToLoad > totalTextLength - processedTextLength) { + textToLoad = totalTextLength - processedTextLength; + } + textSizeInByte = textToLoad / CHAR_PER_BYTE; + fseek(packedFile, -((int)textSizeInByte), SEEK_CUR); + fread(bwtInc->textBuffer, sizeof(unsigned char), textSizeInByte, packedFile); + fseek(packedFile, -((int)textSizeInByte), SEEK_CUR); + ConvertBytePackedToWordPacked(bwtInc->textBuffer, bwtInc->packedText, ALPHABET_SIZE, textToLoad); + BWTIncConstruct(bwtInc, textToLoad); + processedTextLength += textToLoad; + if (bwtInc->numberOfIterationDone % 10 == 0) { + printf("[BWTIncConstructFromPacked] %u iterations done. %u characters processed.\n", + bwtInc->numberOfIterationDone, processedTextLength); + } + } + return bwtInc; +} + +void BWTFree(BWT *bwt) +{ + if (bwt == 0) return; + free(bwt->cumulativeFreq); + free(bwt->bwtCode); + free(bwt->occValue); + free(bwt->occValueMajor); + free(bwt->saValue); + free(bwt->inverseSa); + free(bwt->decodeTable); + free(bwt->saIndexRange); + free(bwt->saValueOnBoundary); + free(bwt); +} + +void BWTIncFree(BWTInc *bwtInc) +{ + if (bwtInc == 0) return; + free(bwtInc->bwt); + free(bwtInc->workingMemory); + free(bwtInc); +} + +static unsigned int BWTFileSizeInWord(const unsigned int numChar) +{ + // The $ in BWT at the position of inverseSa0 is not encoded + return (numChar + CHAR_PER_WORD - 1) / CHAR_PER_WORD; +} + +void BWTSaveBwtCodeAndOcc(const BWT *bwt, const char *bwtFileName, const char *occValueFileName) +{ + FILE *bwtFile; +/* FILE *occValueFile; */ + unsigned int bwtLength; + + bwtFile = (FILE*)fopen(bwtFileName, "wb"); + if (bwtFile == NULL) { + fprintf(stderr, "BWTSaveBwtCodeAndOcc(): Cannot open BWT code file!\n"); + exit(1); + } + + fwrite(&bwt->inverseSa0, sizeof(unsigned int), 1, bwtFile); + fwrite(bwt->cumulativeFreq + 1, sizeof(unsigned int), ALPHABET_SIZE, bwtFile); + bwtLength = BWTFileSizeInWord(bwt->textLength); + fwrite(bwt->bwtCode, sizeof(unsigned int), bwtLength, bwtFile); + fclose(bwtFile); +/* + occValueFile = (FILE*)fopen(occValueFileName, "wb"); + if (occValueFile == NULL) { + fprintf(stderr, "BWTSaveBwtCodeAndOcc(): Cannot open occ value file!\n"); + exit(1); + } + + fwrite(&bwt->inverseSa0, sizeof(unsigned int), 1, occValueFile); + fwrite(bwt->cumulativeFreq + 1, sizeof(unsigned int), ALPHABET_SIZE, occValueFile); + fwrite(bwt->occValue, sizeof(unsigned int), bwt->occSizeInWord, occValueFile); + fwrite(bwt->occValueMajor, sizeof(unsigned int), bwt->occMajorSizeInWord, occValueFile); + fclose(occValueFile); +*/ +} + +void bwt_bwtgen(const char *fn_pac, const char *fn_bwt) +{ + BWTInc *bwtInc; + bwtInc = BWTIncConstructFromPacked(fn_pac, 2.5, 10000000, 10000000); + printf("[bwt_gen] Finished constructing BWT in %u iterations.\n", bwtInc->numberOfIterationDone); + BWTSaveBwtCodeAndOcc(bwtInc->bwt, fn_bwt, 0); + BWTIncFree(bwtInc); +} + +int bwt_bwtgen_main(int argc, char *argv[]) +{ + if (argc < 3) { + fprintf(stderr, "Usage: bwtgen <in.pac> <out.bwt>\n"); + return 1; + } + bwt_bwtgen(argv[1], argv[2]); + return 0; +} + +#ifdef MAIN_BWT_GEN + +int main(int argc, char *argv[]) +{ + return bwt_bwtgen_main(argc, argv); +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwt_gen/bwt_gen.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,105 @@ +/* + + BWTConstruct.h BWT-Index Construction + + This module constructs BWT and auxiliary data structures. + + Copyright (C) 2004, Wong Chi Kwong. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#ifndef BWT_GEN_H +#define BWT_GEN_H + +#define ALPHABET_SIZE 4 +#define BIT_PER_CHAR 2 +#define CHAR_PER_WORD 16 +#define CHAR_PER_BYTE 4 + +#define BITS_IN_WORD 32 +#define BITS_IN_BYTE 8 +#define BYTES_IN_WORD 4 + +#define ALL_ONE_MASK 0xFFFFFFFF +#define DNA_OCC_CNT_TABLE_SIZE_IN_WORD 65536 + +#define BITS_PER_OCC_VALUE 16 +#define OCC_VALUE_PER_WORD 2 +#define OCC_INTERVAL 256 +#define OCC_INTERVAL_MAJOR 65536 + +#define TRUE 1 +#define FALSE 0 + +#define BWTINC_INSERT_SORT_NUM_ITEM 7 + +#define average(value1, value2) ( ((value1) & (value2)) + ((value1) ^ (value2)) / 2 ) +#define min(value1, value2) ( ((value1) < (value2)) ? (value1) : (value2) ) +#define max(value1, value2) ( ((value1) > (value2)) ? (value1) : (value2) ) +#define med3(a, b, c) ( a<b ? (b<c ? b : a<c ? c : a) : (b>c ? b : a>c ? c : a)) +#define swap(a, b, t); t = a; a = b; b = t; +#define truncateLeft(value, offset) ( (value) << (offset) >> (offset) ) +#define truncateRight(value, offset) ( (value) >> (offset) << (offset) ) +#define DNA_OCC_SUM_EXCEPTION(sum) ((sum & 0xfefefeff) == 0) + +typedef struct SaIndexRange { + unsigned int startSaIndex; + unsigned int endSaIndex; +} SaIndexRange; + +typedef struct BWT { + unsigned int textLength; // length of the text + unsigned int saInterval; // interval between two SA values stored explicitly + unsigned int inverseSaInterval; // interval between two inverse SA stored explicitly + unsigned int inverseSa0; // SA-1[0] + unsigned int *cumulativeFreq; // cumulative frequency + unsigned int *bwtCode; // BWT code + unsigned int *occValue; // Occurrence values stored explicitly + unsigned int *occValueMajor; // Occurrence values stored explicitly + unsigned int *saValue; // SA values stored explicitly + unsigned int *inverseSa; // Inverse SA stored explicitly + SaIndexRange *saIndexRange; // SA index range + int saIndexRangeNumOfChar; // Number of characters indexed in SA index range + unsigned int *saValueOnBoundary; // Pre-calculated frequently referred data + unsigned int *decodeTable; // For decoding BWT by table lookup + unsigned int decodeTableGenerated; // == TRUE if decode table is generated on load and will be freed + unsigned int bwtSizeInWord; // Temporary variable to hold the memory allocated + unsigned int occSizeInWord; // Temporary variable to hold the memory allocated + unsigned int occMajorSizeInWord; // Temporary variable to hold the memory allocated + unsigned int saValueSize; // Temporary variable to hold the memory allocated + unsigned int inverseSaSize; // Temporary variable to hold the memory allocated + unsigned int saIndexRangeSize; // Temporary variable to hold the memory allocated +} BWT; + +typedef struct BWTInc { + BWT *bwt; + unsigned int numberOfIterationDone; + unsigned int *cumulativeCountInCurrentBuild; + unsigned int availableWord; + unsigned int targetTextLength; + float targetNBit; + unsigned int buildSize; + unsigned int initialMaxBuildSize; + unsigned int incMaxBuildSize; + unsigned int firstCharInLastIteration; + unsigned int *workingMemory; + unsigned int *packedText; + unsigned char *textBuffer; + unsigned int *packedShift; +} BWTInc; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwt_lite.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,94 @@ +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include "bwt_lite.h" + +int is_sa(const uint8_t *T, uint32_t *SA, int n); +int is_bwt(uint8_t *T, int n); + +bwtl_t *bwtl_seq2bwtl(int len, const uint8_t *seq) +{ + bwtl_t *b; + int i; + b = (bwtl_t*)calloc(1, sizeof(bwtl_t)); + b->seq_len = len; + + { // calculate b->bwt + uint8_t *s; + b->sa = (uint32_t*)calloc(len + 1, 4); + is_sa(seq, b->sa, len); + s = (uint8_t*)calloc(len + 1, 1); + for (i = 0; i <= len; ++i) { + if (b->sa[i] == 0) b->primary = i; + else s[i] = seq[b->sa[i] - 1]; + } + for (i = b->primary; i < len; ++i) s[i] = s[i + 1]; + b->bwt_size = (len + 15) / 16; + b->bwt = (uint32_t*)calloc(b->bwt_size, 4); + for (i = 0; i < len; ++i) + b->bwt[i>>4] |= s[i] << ((15 - (i&15)) << 1); + free(s); + } + { // calculate b->occ + uint32_t c[4]; + b->n_occ = (len + 15) / 16 * 4; + b->occ = (uint32_t*)calloc(b->n_occ, 4); + memset(c, 0, 16); + for (i = 0; i < len; ++i) { + if (i % 16 == 0) + memcpy(b->occ + (i/16) * 4, c, 16); + ++c[bwtl_B0(b, i)]; + } + memcpy(b->L2+1, c, 16); + for (i = 2; i < 5; ++i) b->L2[i] += b->L2[i-1]; + } + { // generate cnt_table + for (i = 0; i != 256; ++i) { + u_int32_t j, x = 0; + for (j = 0; j != 4; ++j) + x |= (((i&3) == j) + ((i>>2&3) == j) + ((i>>4&3) == j) + (i>>6 == j)) << (j<<3); + b->cnt_table[i] = x; + } + } + return b; +} +inline uint32_t bwtl_occ(const bwtl_t *bwt, uint32_t k, uint8_t c) +{ + uint32_t n, b; + if (k == bwt->seq_len) return bwt->L2[c+1] - bwt->L2[c]; + if (k == (uint32_t)(-1)) return 0; + if (k >= bwt->primary) --k; // because $ is not in bwt + n = bwt->occ[k/16<<2|c]; + b = bwt->bwt[k/16] & ~((1U<<((15-(k&15))<<1)) - 1); + n += (bwt->cnt_table[b&0xff] + bwt->cnt_table[b>>8&0xff] + + bwt->cnt_table[b>>16&0xff] + bwt->cnt_table[b>>24]) >> (c<<3) & 0xff; + if (c == 0) n -= 15 - (k&15); // corrected for the masked bits + return n; +} +inline void bwtl_occ4(const bwtl_t *bwt, uint32_t k, uint32_t cnt[4]) +{ + uint32_t x, b; + if (k == (uint32_t)(-1)) { + memset(cnt, 0, 16); + return; + } + if (k >= bwt->primary) --k; // because $ is not in bwt + memcpy(cnt, bwt->occ + (k>>4<<2), 16); + b = bwt->bwt[k>>4] & ~((1U<<((~k&15)<<1)) - 1); + x = bwt->cnt_table[b&0xff] + bwt->cnt_table[b>>8&0xff] + + bwt->cnt_table[b>>16&0xff] + bwt->cnt_table[b>>24]; + x -= 15 - (k&15); + cnt[0] += x&0xff; cnt[1] += x>>8&0xff; cnt[2] += x>>16&0xff; cnt[3] += x>>24; +} +inline void bwtl_2occ4(const bwtl_t *bwt, uint32_t k, uint32_t l, uint32_t cntk[4], uint32_t cntl[4]) +{ + bwtl_occ4(bwt, k, cntk); + bwtl_occ4(bwt, l, cntl); +} +void bwtl_destroy(bwtl_t *bwt) +{ + if (bwt) { + free(bwt->occ); free(bwt->bwt); free(bwt->sa); + free(bwt); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwt_lite.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,29 @@ +#ifndef BWT_LITE_H_ +#define BWT_LITE_H_ + +#include <stdint.h> + +typedef struct { + uint32_t seq_len, bwt_size, n_occ; + uint32_t primary; + uint32_t *bwt, *occ, *sa, L2[5]; + uint32_t cnt_table[256]; +} bwtl_t; + +#define bwtl_B0(b, k) ((b)->bwt[(k)>>4]>>((~(k)&0xf)<<1)&3) + +#ifdef __cplusplus +extern "C" { +#endif + + bwtl_t *bwtl_seq2bwtl(int len, const uint8_t *seq); + inline uint32_t bwtl_occ(const bwtl_t *bwt, uint32_t k, uint8_t c); + inline void bwtl_occ4(const bwtl_t *bwt, uint32_t k, uint32_t cnt[4]); + inline void bwtl_2occ4(const bwtl_t *bwt, uint32_t k, uint32_t l, uint32_t cntk[4], uint32_t cntl[4]); + void bwtl_destroy(bwtl_t *bwt); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwtaln.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,315 @@ +#include <stdio.h> +#include <unistd.h> +#include <math.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <stdint.h> +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "bwtaln.h" +#include "bwtgap.h" +#include "utils.h" + +#ifdef HAVE_PTHREAD +#define THREAD_BLOCK_SIZE 1024 +#include <pthread.h> +static pthread_mutex_t g_seq_lock = PTHREAD_MUTEX_INITIALIZER; +#endif + +gap_opt_t *gap_init_opt() +{ + gap_opt_t *o; + o = (gap_opt_t*)calloc(1, sizeof(gap_opt_t)); + /* IMPORTANT: s_mm*10 should be about the average base error + rate. Voilating this requirement will break pairing! */ + o->s_mm = 3; o->s_gapo = 11; o->s_gape = 4; + o->max_diff = -1; o->max_gapo = 1; o->max_gape = 6; + o->indel_end_skip = 5; o->max_del_occ = 10; o->max_entries = 2000000; + o->mode = BWA_MODE_GAPE | BWA_MODE_COMPREAD; + o->seed_len = 32; o->max_seed_diff = 2; + o->fnr = 0.04; + o->n_threads = 1; + o->max_top2 = 30; + o->trim_qual = 0; + return o; +} + +int bwa_cal_maxdiff(int l, double err, double thres) +{ + double elambda = exp(-l * err); + double sum, y = 1.0; + int k, x = 1; + for (k = 1, sum = elambda; k < 1000; ++k) { + y *= l * err; + x *= k; + sum += elambda * y / x; + if (1.0 - sum < thres) return k; + } + return 2; +} + +// width must be filled as zero +static int bwt_cal_width(const bwt_t *rbwt, int len, const ubyte_t *str, bwt_width_t *width) +{ + bwtint_t k, l, ok, ol; + int i, bid; + bid = 0; + k = 0; l = rbwt->seq_len; + for (i = 0; i < len; ++i) { + ubyte_t c = str[i]; + if (c < 4) { + bwt_2occ(rbwt, k - 1, l, c, &ok, &ol); + k = rbwt->L2[c] + ok + 1; + l = rbwt->L2[c] + ol; + } + if (k > l || c > 3) { // then restart + k = 0; + l = rbwt->seq_len; + ++bid; + } + width[i].w = l - k + 1; + width[i].bid = bid; + } + width[len].w = 0; + width[len].bid = ++bid; + return bid; +} + +void bwa_cal_sa_reg_gap(int tid, bwt_t *const bwt[2], int n_seqs, bwa_seq_t *seqs, const gap_opt_t *opt) +{ + int i, max_l = 0, max_len; + gap_stack_t *stack; + bwt_width_t *w[2], *seed_w[2]; + const ubyte_t *seq[2]; + gap_opt_t local_opt = *opt; + + // initiate priority stack + for (i = max_len = 0; i != n_seqs; ++i) + if (seqs[i].len > max_len) max_len = seqs[i].len; + if (opt->fnr > 0.0) local_opt.max_diff = bwa_cal_maxdiff(max_len, BWA_AVG_ERR, opt->fnr); + if (local_opt.max_diff < local_opt.max_gapo) local_opt.max_gapo = local_opt.max_diff; + stack = gap_init_stack(local_opt.max_diff, local_opt.max_gapo, local_opt.max_gape, &local_opt); + + seed_w[0] = (bwt_width_t*)calloc(opt->seed_len+1, sizeof(bwt_width_t)); + seed_w[1] = (bwt_width_t*)calloc(opt->seed_len+1, sizeof(bwt_width_t)); + w[0] = w[1] = 0; + for (i = 0; i != n_seqs; ++i) { + bwa_seq_t *p = seqs + i; +#ifdef HAVE_PTHREAD + if (opt->n_threads > 1) { + pthread_mutex_lock(&g_seq_lock); + if (p->tid < 0) { // unassigned + int j; + for (j = i; j < n_seqs && j < i + THREAD_BLOCK_SIZE; ++j) + seqs[j].tid = tid; + } else if (p->tid != tid) { + pthread_mutex_unlock(&g_seq_lock); + continue; + } + pthread_mutex_unlock(&g_seq_lock); + } +#endif + p->sa = 0; p->type = BWA_TYPE_NO_MATCH; p->c1 = p->c2 = 0; p->n_aln = 0; p->aln = 0; + seq[0] = p->seq; seq[1] = p->rseq; + if (max_l < p->len) { + max_l = p->len; + w[0] = (bwt_width_t*)calloc(max_l + 1, sizeof(bwt_width_t)); + w[1] = (bwt_width_t*)calloc(max_l + 1, sizeof(bwt_width_t)); + } + bwt_cal_width(bwt[0], p->len, seq[0], w[0]); + bwt_cal_width(bwt[1], p->len, seq[1], w[1]); + if (opt->fnr > 0.0) local_opt.max_diff = bwa_cal_maxdiff(p->len, BWA_AVG_ERR, opt->fnr); + local_opt.seed_len = opt->seed_len < p->len? opt->seed_len : 0x7fffffff; + if (p->len > opt->seed_len) { + bwt_cal_width(bwt[0], opt->seed_len, seq[0] + (p->len - opt->seed_len), seed_w[0]); + bwt_cal_width(bwt[1], opt->seed_len, seq[1] + (p->len - opt->seed_len), seed_w[1]); + } + // core function + p->aln = bwt_match_gap(bwt, p->len, seq, w, p->len <= opt->seed_len? 0 : seed_w, &local_opt, &p->n_aln, stack); + // store the alignment + free(p->name); free(p->seq); free(p->rseq); free(p->qual); + p->name = 0; p->seq = p->rseq = p->qual = 0; + } + free(seed_w[0]); free(seed_w[1]); + free(w[0]); free(w[1]); + gap_destroy_stack(stack); +} + +#ifdef HAVE_PTHREAD +typedef struct { + int tid; + bwt_t *bwt[2]; + int n_seqs; + bwa_seq_t *seqs; + const gap_opt_t *opt; +} thread_aux_t; + +static void *worker(void *data) +{ + thread_aux_t *d = (thread_aux_t*)data; + bwa_cal_sa_reg_gap(d->tid, d->bwt, d->n_seqs, d->seqs, d->opt); + return 0; +} +#endif + +void bwa_aln_core(const char *prefix, const char *fn_fa, const gap_opt_t *opt) +{ + int i, n_seqs, tot_seqs = 0; + bwa_seq_t *seqs; + bwa_seqio_t *ks; + clock_t t; + bwt_t *bwt[2]; + + // initialization + ks = bwa_seq_open(fn_fa); + + { // load BWT + char *str = (char*)calloc(strlen(prefix) + 10, 1); + strcpy(str, prefix); strcat(str, ".bwt"); bwt[0] = bwt_restore_bwt(str); + strcpy(str, prefix); strcat(str, ".rbwt"); bwt[1] = bwt_restore_bwt(str); + free(str); + } + + // core loop + fwrite(opt, sizeof(gap_opt_t), 1, stdout); + while ((seqs = bwa_read_seq(ks, 0x40000, &n_seqs, opt->mode & BWA_MODE_COMPREAD, opt->trim_qual)) != 0) { + tot_seqs += n_seqs; + t = clock(); + + fprintf(stderr, "[bwa_aln_core] calculate SA coordinate... "); + +#ifdef HAVE_PTHREAD + if (opt->n_threads <= 1) { // no multi-threading at all + bwa_cal_sa_reg_gap(0, bwt, n_seqs, seqs, opt); + } else { + pthread_t *tid; + pthread_attr_t attr; + thread_aux_t *data; + int j; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + data = (thread_aux_t*)calloc(opt->n_threads, sizeof(thread_aux_t)); + tid = (pthread_t*)calloc(opt->n_threads, sizeof(pthread_t)); + for (j = 0; j < opt->n_threads; ++j) { + data[j].tid = j; data[j].bwt[0] = bwt[0]; data[j].bwt[1] = bwt[1]; + data[j].n_seqs = n_seqs; data[j].seqs = seqs; data[j].opt = opt; + pthread_create(&tid[j], &attr, worker, data + j); + } + for (j = 0; j < opt->n_threads; ++j) pthread_join(tid[j], 0); + free(data); free(tid); + } +#else + bwa_cal_sa_reg_gap(0, bwt, n_seqs, seqs, opt); +#endif + + fprintf(stderr, "%.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); t = clock(); + + t = clock(); + fprintf(stderr, "[bwa_aln_core] write to the disk... "); + for (i = 0; i < n_seqs; ++i) { + bwa_seq_t *p = seqs + i; + fwrite(&p->n_aln, 4, 1, stdout); + if (p->n_aln) fwrite(p->aln, sizeof(bwt_aln1_t), p->n_aln, stdout); + } + fprintf(stderr, "%.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); t = clock(); + + bwa_free_read_seq(n_seqs, seqs); + fprintf(stderr, "[bwa_aln_core] %d sequences have been processed.\n", tot_seqs); + } + + // destroy + bwt_destroy(bwt[0]); bwt_destroy(bwt[1]); + bwa_seq_close(ks); +} + +int bwa_aln(int argc, char *argv[]) +{ + int c, opte = -1; + gap_opt_t *opt; + + opt = gap_init_opt(); + while ((c = getopt(argc, argv, "n:o:e:i:d:l:k:cLR:m:t:NM:O:E:q:f:")) >= 0) { + switch (c) { + case 'n': + if (strstr(optarg, ".")) opt->fnr = atof(optarg), opt->max_diff = -1; + else opt->max_diff = atoi(optarg), opt->fnr = -1.0; + break; + case 'o': opt->max_gapo = atoi(optarg); break; + case 'e': opte = atoi(optarg); break; + case 'M': opt->s_mm = atoi(optarg); break; + case 'O': opt->s_gapo = atoi(optarg); break; + case 'E': opt->s_gape = atoi(optarg); break; + case 'd': opt->max_del_occ = atoi(optarg); break; + case 'i': opt->indel_end_skip = atoi(optarg); break; + case 'l': opt->seed_len = atoi(optarg); break; + case 'k': opt->max_seed_diff = atoi(optarg); break; + case 'm': opt->max_entries = atoi(optarg); break; + case 't': opt->n_threads = atoi(optarg); break; + case 'L': opt->mode |= BWA_MODE_LOGGAP; break; + case 'R': opt->max_top2 = atoi(optarg); break; + case 'q': opt->trim_qual = atoi(optarg); break; + case 'c': opt->mode &= ~BWA_MODE_COMPREAD; break; + case 'N': opt->mode |= BWA_MODE_NONSTOP; opt->max_top2 = 0x7fffffff; break; + case 'f': freopen(optarg, "wb", stdout); break; + default: return 1; + } + } + if (opte > 0) { + opt->max_gape = opte; + opt->mode &= ~BWA_MODE_GAPE; + } + + if (optind + 2 > argc) { + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: bwa aln [options] <prefix> <in.fq>\n\n"); + fprintf(stderr, "Options: -n NUM max #diff (int) or missing prob under %.2f err rate (float) [%.2f]\n", + BWA_AVG_ERR, opt->fnr); + fprintf(stderr, " -o INT maximum number or fraction of gap opens [%d]\n", opt->max_gapo); + fprintf(stderr, " -e INT maximum number of gap extensions, -1 for disabling long gaps [-1]\n"); + fprintf(stderr, " -i INT do not put an indel within INT bp towards the ends [%d]\n", opt->indel_end_skip); + fprintf(stderr, " -d INT maximum occurrences for extending a long deletion [%d]\n", opt->max_del_occ); + fprintf(stderr, " -l INT seed length [%d]\n", opt->seed_len); + fprintf(stderr, " -k INT maximum differences in the seed [%d]\n", opt->max_seed_diff); + fprintf(stderr, " -m INT maximum entries in the queue [%d]\n", opt->max_entries); + fprintf(stderr, " -t INT number of threads [%d]\n", opt->n_threads); + fprintf(stderr, " -M INT mismatch penalty [%d]\n", opt->s_mm); + fprintf(stderr, " -O INT gap open penalty [%d]\n", opt->s_gapo); + fprintf(stderr, " -E INT gap extension penalty [%d]\n", opt->s_gape); + fprintf(stderr, " -R INT stop searching when there are >INT equally best hits [%d]\n", opt->max_top2); + fprintf(stderr, " -q INT quality threshold for read trimming down to %dbp [%d]\n", BWA_MIN_RDLEN, opt->trim_qual); + fprintf(stderr, " -c input sequences are in the color space\n"); + fprintf(stderr, " -L log-scaled gap penalty for long deletions\n"); + fprintf(stderr, " -N non-iterative mode: search for all n-difference hits (slooow)\n"); + fprintf(stderr, " -f FILE file to write output to instead of stdout\n"); + fprintf(stderr, "\n"); + return 1; + } + if (opt->fnr > 0.0) { + int i, k; + for (i = 17, k = 0; i <= 250; ++i) { + int l = bwa_cal_maxdiff(i, BWA_AVG_ERR, opt->fnr); + if (l != k) fprintf(stderr, "[bwa_aln] %dbp reads: max_diff = %d\n", i, l); + k = l; + } + } + bwa_aln_core(argv[optind], argv[optind+1], opt); + free(opt); + return 0; +} + +/* rgoya: Temporary clone of aln_path2cigar to accomodate for bwa_cigar_t, +__cigar_op and __cigar_len while keeping stdaln stand alone */ +bwa_cigar_t *bwa_aln_path2cigar(const path_t *path, int path_len, int *n_cigar) +{ + uint32_t *cigar32; + bwa_cigar_t *cigar; + int i; + cigar32 = aln_path2cigar32((path_t*) path, path_len, n_cigar); + cigar = (bwa_cigar_t*)cigar32; + for (i = 0; i < *n_cigar; ++i) + cigar[i] = __cigar_create( (cigar32[i]&0xf), (cigar32[i]>>4) ); + return cigar; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwtaln.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,142 @@ +#ifndef BWTALN_H +#define BWTALN_H + +#include <stdint.h> +#include "bwt.h" + +#define BWA_TYPE_NO_MATCH 0 +#define BWA_TYPE_UNIQUE 1 +#define BWA_TYPE_REPEAT 2 +#define BWA_TYPE_MATESW 3 + +#define SAM_FPD 1 // paired +#define SAM_FPP 2 // properly paired +#define SAM_FSU 4 // self-unmapped +#define SAM_FMU 8 // mate-unmapped +#define SAM_FSR 16 // self on the reverse strand +#define SAM_FMR 32 // mate on the reverse strand +#define SAM_FR1 64 // this is read one +#define SAM_FR2 128 // this is read two +#define SAM_FSC 256 // secondary alignment + +#define BWA_AVG_ERR 0.02 +#define BWA_MIN_RDLEN 35 // for read trimming + +#ifndef bns_pac +#define bns_pac(pac, k) ((pac)[(k)>>2] >> ((~(k)&3)<<1) & 3) +#endif + +typedef struct { + bwtint_t w; + int bid; +} bwt_width_t; + +typedef struct { + uint32_t n_mm:8, n_gapo:8, n_gape:8, a:1; + bwtint_t k, l; + int score; +} bwt_aln1_t; + +typedef uint16_t bwa_cigar_t; +/* rgoya: If changing order of bytes, beware of operations like: + * s->cigar[0] += s->full_len - s->len; + */ +#define CIGAR_OP_SHIFT 14 +#define CIGAR_LN_MASK 0x3fff + +#define __cigar_op(__cigar) ((__cigar)>>CIGAR_OP_SHIFT) +#define __cigar_len(__cigar) ((__cigar)&CIGAR_LN_MASK) +#define __cigar_create(__op, __len) ((__op)<<CIGAR_OP_SHIFT | (__len)) + +typedef struct { + uint32_t pos; + uint32_t n_cigar:15, gap:8, mm:8, strand:1; + bwa_cigar_t *cigar; +} bwt_multi1_t; + +typedef struct { + char *name; + ubyte_t *seq, *rseq, *qual; + uint32_t len:20, strand:1, type:2, dummy:1, extra_flag:8; + uint32_t n_mm:8, n_gapo:8, n_gape:8, mapQ:8; + int score; + int clip_len; + // alignments in SA coordinates + int n_aln; + bwt_aln1_t *aln; + // multiple hits + int n_multi; + bwt_multi1_t *multi; + // alignment information + bwtint_t sa, pos; + uint64_t c1:28, c2:28, seQ:8; // number of top1 and top2 hits; single-end mapQ + int n_cigar; + bwa_cigar_t *cigar; + // for multi-threading only + int tid; + // NM and MD tags + uint32_t full_len:20, nm:12; + char *md; +} bwa_seq_t; + +#define BWA_MODE_GAPE 0x01 +#define BWA_MODE_COMPREAD 0x02 +#define BWA_MODE_LOGGAP 0x04 +#define BWA_MODE_NONSTOP 0x10 + +typedef struct { + int s_mm, s_gapo, s_gape; + int mode; + int indel_end_skip, max_del_occ, max_entries; + float fnr; + int max_diff, max_gapo, max_gape; + int max_seed_diff, seed_len; + int n_threads; + int max_top2; + int trim_qual; +} gap_opt_t; + +#define BWA_PET_STD 1 +#define BWA_PET_SOLID 2 + +typedef struct { + int max_isize; + int max_occ; + int n_multi, N_multi; + int type, is_sw, is_preload; + double ap_prior; +} pe_opt_t; + +struct __bwa_seqio_t; +typedef struct __bwa_seqio_t bwa_seqio_t; + +#ifdef __cplusplus +extern "C" { +#endif + + gap_opt_t *gap_init_opt(); + void bwa_aln_core(const char *prefix, const char *fn_fa, const gap_opt_t *opt); + + bwa_seqio_t *bwa_seq_open(const char *fn); + void bwa_seq_close(bwa_seqio_t *bs); + void seq_reverse(int len, ubyte_t *seq, int is_comp); + bwa_seq_t *bwa_read_seq(bwa_seqio_t *seq, int n_needed, int *n, int is_comp, int trim_qual); + void bwa_free_read_seq(int n_seqs, bwa_seq_t *seqs); + + int bwa_cal_maxdiff(int l, double err, double thres); + void bwa_cal_sa_reg_gap(int tid, bwt_t *const bwt[2], int n_seqs, bwa_seq_t *seqs, const gap_opt_t *opt); + + void bwa_cs2nt_core(bwa_seq_t *p, bwtint_t l_pac, ubyte_t *pac); + + + /* rgoya: Temporary clone of aln_path2cigar to accomodate for bwa_cigar_t, + __cigar_op and __cigar_len while keeping stdaln stand alone */ +#include "stdaln.h" + + bwa_cigar_t *bwa_aln_path2cigar(const path_t *path, int path_len, int *n_cigar); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwtgap.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,264 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "bwtgap.h" +#include "bwtaln.h" + +#define STATE_M 0 +#define STATE_I 1 +#define STATE_D 2 + +#define aln_score(m,o,e,p) ((m)*(p)->s_mm + (o)*(p)->s_gapo + (e)*(p)->s_gape) + +gap_stack_t *gap_init_stack(int max_mm, int max_gapo, int max_gape, const gap_opt_t *opt) +{ + int i; + gap_stack_t *stack; + stack = (gap_stack_t*)calloc(1, sizeof(gap_stack_t)); + stack->n_stacks = aln_score(max_mm+1, max_gapo+1, max_gape+1, opt); + stack->stacks = (gap_stack1_t*)calloc(stack->n_stacks, sizeof(gap_stack1_t)); + for (i = 0; i != stack->n_stacks; ++i) { + gap_stack1_t *p = stack->stacks + i; + p->m_entries = 4; + p->stack = (gap_entry_t*)calloc(p->m_entries, sizeof(gap_entry_t)); + } + return stack; +} + +void gap_destroy_stack(gap_stack_t *stack) +{ + int i; + for (i = 0; i != stack->n_stacks; ++i) free(stack->stacks[i].stack); + free(stack->stacks); + free(stack); +} + +static void gap_reset_stack(gap_stack_t *stack) +{ + int i; + for (i = 0; i != stack->n_stacks; ++i) + stack->stacks[i].n_entries = 0; + stack->best = stack->n_stacks; + stack->n_entries = 0; +} + +static inline void gap_push(gap_stack_t *stack, int a, int i, bwtint_t k, bwtint_t l, int n_mm, int n_gapo, int n_gape, + int state, int is_diff, const gap_opt_t *opt) +{ + int score; + gap_entry_t *p; + gap_stack1_t *q; + score = aln_score(n_mm, n_gapo, n_gape, opt); + q = stack->stacks + score; + if (q->n_entries == q->m_entries) { + q->m_entries <<= 1; + q->stack = (gap_entry_t*)realloc(q->stack, sizeof(gap_entry_t) * q->m_entries); + } + p = q->stack + q->n_entries; + p->info = (u_int32_t)score<<21 | a<<20 | i; p->k = k; p->l = l; + p->n_mm = n_mm; p->n_gapo = n_gapo; p->n_gape = n_gape; p->state = state; + if (is_diff) p->last_diff_pos = i; + ++(q->n_entries); + ++(stack->n_entries); + if (stack->best > score) stack->best = score; +} + +static inline void gap_pop(gap_stack_t *stack, gap_entry_t *e) +{ + gap_stack1_t *q; + q = stack->stacks + stack->best; + *e = q->stack[q->n_entries - 1]; + --(q->n_entries); + --(stack->n_entries); + if (q->n_entries == 0 && stack->n_entries) { // reset best + int i; + for (i = stack->best + 1; i < stack->n_stacks; ++i) + if (stack->stacks[i].n_entries != 0) break; + stack->best = i; + } else if (stack->n_entries == 0) stack->best = stack->n_stacks; +} + +static inline void gap_shadow(int x, int len, bwtint_t max, int last_diff_pos, bwt_width_t *w) +{ + int i, j; + for (i = j = 0; i < last_diff_pos; ++i) { + if (w[i].w > x) w[i].w -= x; + else if (w[i].w == x) { + w[i].bid = 1; + w[i].w = max - (++j); + } // else should not happen + } +} + +static inline int int_log2(uint32_t v) +{ + int c = 0; + if (v & 0xffff0000u) { v >>= 16; c |= 16; } + if (v & 0xff00) { v >>= 8; c |= 8; } + if (v & 0xf0) { v >>= 4; c |= 4; } + if (v & 0xc) { v >>= 2; c |= 2; } + if (v & 0x2) c |= 1; + return c; +} + +bwt_aln1_t *bwt_match_gap(bwt_t *const bwts[2], int len, const ubyte_t *seq[2], bwt_width_t *w[2], + bwt_width_t *seed_w[2], const gap_opt_t *opt, int *_n_aln, gap_stack_t *stack) +{ + int best_score = aln_score(opt->max_diff+1, opt->max_gapo+1, opt->max_gape+1, opt); + int best_diff = opt->max_diff + 1, max_diff = opt->max_diff; + int best_cnt = 0; + int max_entries = 0, j, _j, n_aln, m_aln; + bwt_aln1_t *aln; + + m_aln = 4; n_aln = 0; + aln = (bwt_aln1_t*)calloc(m_aln, sizeof(bwt_aln1_t)); + + // check whether there are too many N + for (j = _j = 0; j < len; ++j) + if (seq[0][j] > 3) ++_j; + if (_j > max_diff) { + *_n_aln = n_aln; + return aln; + } + + //for (j = 0; j != len; ++j) printf("#0 %d: [%d,%u]\t[%d,%u]\n", j, w[0][j].bid, w[0][j].w, w[1][j].bid, w[1][j].w); + gap_reset_stack(stack); // reset stack + gap_push(stack, 0, len, 0, bwts[0]->seq_len, 0, 0, 0, 0, 0, opt); + gap_push(stack, 1, len, 0, bwts[0]->seq_len, 0, 0, 0, 0, 0, opt); + + while (stack->n_entries) { + gap_entry_t e; + int a, i, m, m_seed = 0, hit_found, allow_diff, allow_M, tmp; + bwtint_t k, l, cnt_k[4], cnt_l[4], occ; + const bwt_t *bwt; + const ubyte_t *str; + const bwt_width_t *seed_width = 0; + bwt_width_t *width; + + if (max_entries < stack->n_entries) max_entries = stack->n_entries; + if (stack->n_entries > opt->max_entries) break; + gap_pop(stack, &e); // get the best entry + k = e.k; l = e.l; // SA interval + a = e.info>>20&1; i = e.info&0xffff; // strand, length + if (!(opt->mode & BWA_MODE_NONSTOP) && e.info>>21 > best_score + opt->s_mm) break; // no need to proceed + + m = max_diff - (e.n_mm + e.n_gapo); + if (opt->mode & BWA_MODE_GAPE) m -= e.n_gape; + if (m < 0) continue; + bwt = bwts[1-a]; str = seq[a]; width = w[a]; + if (seed_w) { // apply seeding + seed_width = seed_w[a]; + m_seed = opt->max_seed_diff - (e.n_mm + e.n_gapo); + if (opt->mode & BWA_MODE_GAPE) m_seed -= e.n_gape; + } + //printf("#1\t[%d,%d,%d,%c]\t[%d,%d,%d]\t[%u,%u]\t[%u,%u]\t%d\n", stack->n_entries, a, i, "MID"[e.state], e.n_mm, e.n_gapo, e.n_gape, width[i-1].bid, width[i-1].w, k, l, e.last_diff_pos); + if (i > 0 && m < width[i-1].bid) continue; + + // check whether a hit is found + hit_found = 0; + if (i == 0) hit_found = 1; + else if (m == 0 && (e.state == STATE_M || (opt->mode&BWA_MODE_GAPE) || e.n_gape == opt->max_gape)) { // no diff allowed + if (bwt_match_exact_alt(bwt, i, str, &k, &l)) hit_found = 1; + else continue; // no hit, skip + } + + if (hit_found) { // action for found hits + int score = aln_score(e.n_mm, e.n_gapo, e.n_gape, opt); + int do_add = 1; + //printf("#2 hits found: %d:(%u,%u)\n", e.n_mm+e.n_gapo, k, l); + if (n_aln == 0) { + best_score = score; + best_diff = e.n_mm + e.n_gapo; + if (opt->mode & BWA_MODE_GAPE) best_diff += e.n_gape; + if (!(opt->mode & BWA_MODE_NONSTOP)) + max_diff = (best_diff + 1 > opt->max_diff)? opt->max_diff : best_diff + 1; // top2 behaviour + } + if (score == best_score) best_cnt += l - k + 1; + else if (best_cnt > opt->max_top2) break; // top2b behaviour + if (e.n_gapo) { // check whether the hit has been found. this may happen when a gap occurs in a tandem repeat + for (j = 0; j != n_aln; ++j) + if (aln[j].k == k && aln[j].l == l) break; + if (j < n_aln) do_add = 0; + } + if (do_add) { // append + bwt_aln1_t *p; + gap_shadow(l - k + 1, len, bwt->seq_len, e.last_diff_pos, width); + if (n_aln == m_aln) { + m_aln <<= 1; + aln = (bwt_aln1_t*)realloc(aln, m_aln * sizeof(bwt_aln1_t)); + memset(aln + m_aln/2, 0, m_aln/2*sizeof(bwt_aln1_t)); + } + p = aln + n_aln; + p->n_mm = e.n_mm; p->n_gapo = e.n_gapo; p->n_gape = e.n_gape; p->a = a; + p->k = k; p->l = l; + p->score = score; + ++n_aln; + } + continue; + } + + --i; + bwt_2occ4(bwt, k - 1, l, cnt_k, cnt_l); // retrieve Occ values + occ = l - k + 1; + // test whether diff is allowed + allow_diff = allow_M = 1; + if (i > 0) { + int ii = i - (len - opt->seed_len); + if (width[i-1].bid > m-1) allow_diff = 0; + else if (width[i-1].bid == m-1 && width[i].bid == m-1 && width[i-1].w == width[i].w) allow_M = 0; + if (seed_w && ii > 0) { + if (seed_width[ii-1].bid > m_seed-1) allow_diff = 0; + else if (seed_width[ii-1].bid == m_seed-1 && seed_width[ii].bid == m_seed-1 + && seed_width[ii-1].w == seed_width[ii].w) allow_M = 0; + } + } + // indels + tmp = (opt->mode & BWA_MODE_LOGGAP)? int_log2(e.n_gape + e.n_gapo)/2+1 : e.n_gapo + e.n_gape; + if (allow_diff && i >= opt->indel_end_skip + tmp && len - i >= opt->indel_end_skip + tmp) { + if (e.state == STATE_M) { // gap open + if (e.n_gapo < opt->max_gapo) { // gap open is allowed + // insertion + gap_push(stack, a, i, k, l, e.n_mm, e.n_gapo + 1, e.n_gape, STATE_I, 1, opt); + // deletion + for (j = 0; j != 4; ++j) { + k = bwt->L2[j] + cnt_k[j] + 1; + l = bwt->L2[j] + cnt_l[j]; + if (k <= l) gap_push(stack, a, i + 1, k, l, e.n_mm, e.n_gapo + 1, e.n_gape, STATE_D, 1, opt); + } + } + } else if (e.state == STATE_I) { // extention of an insertion + if (e.n_gape < opt->max_gape) // gap extention is allowed + gap_push(stack, a, i, k, l, e.n_mm, e.n_gapo, e.n_gape + 1, STATE_I, 1, opt); + } else if (e.state == STATE_D) { // extention of a deletion + if (e.n_gape < opt->max_gape) { // gap extention is allowed + if (e.n_gape + e.n_gapo < max_diff || occ < opt->max_del_occ) { + for (j = 0; j != 4; ++j) { + k = bwt->L2[j] + cnt_k[j] + 1; + l = bwt->L2[j] + cnt_l[j]; + if (k <= l) gap_push(stack, a, i + 1, k, l, e.n_mm, e.n_gapo, e.n_gape + 1, STATE_D, 1, opt); + } + } + } + } + } + // mismatches + if (allow_diff && allow_M) { // mismatch is allowed + for (j = 1; j <= 4; ++j) { + int c = (str[i] + j) & 3; + int is_mm = (j != 4 || str[i] > 3); + k = bwt->L2[c] + cnt_k[c] + 1; + l = bwt->L2[c] + cnt_l[c]; + if (k <= l) gap_push(stack, a, i, k, l, e.n_mm + is_mm, e.n_gapo, e.n_gape, STATE_M, is_mm, opt); + } + } else if (str[i] < 4) { // try exact match only + int c = str[i] & 3; + k = bwt->L2[c] + cnt_k[c] + 1; + l = bwt->L2[c] + cnt_l[c]; + if (k <= l) gap_push(stack, a, i, k, l, e.n_mm, e.n_gapo, e.n_gape, STATE_M, 0, opt); + } + } + + *_n_aln = n_aln; + //fprintf(stderr, "max_entries = %d\n", max_entries); + return aln; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwtgap.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,38 @@ +#ifndef BWTGAP_H_ +#define BWTGAP_H_ + +#include "bwt.h" +#include "bwtaln.h" + +typedef struct { // recursion stack + u_int32_t info; // score<<21 | a<<20 | i + u_int32_t n_mm:8, n_gapo:8, n_gape:8, state:2, n_seed_mm:6; + bwtint_t k, l; // (k,l) is the SA region of [i,n-1] + int last_diff_pos; +} gap_entry_t; + +typedef struct { + int n_entries, m_entries; + gap_entry_t *stack; +} gap_stack1_t; + +typedef struct { + int n_stacks, best, n_entries; + gap_stack1_t *stacks; +} gap_stack_t; + +#ifdef __cplusplus +extern "C" { +#endif + + gap_stack_t *gap_init_stack(int max_mm, int max_gapo, int max_gape, const gap_opt_t *opt); + void gap_destroy_stack(gap_stack_t *stack); + bwt_aln1_t *bwt_match_gap(bwt_t *const bwt[2], int len, const ubyte_t *seq[2], bwt_width_t *w[2], + bwt_width_t *seed_w[2], const gap_opt_t *opt, int *_n_aln, gap_stack_t *stack); + void bwa_aln2seq(int n_aln, const bwt_aln1_t *aln, bwa_seq_t *s); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwtindex.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,186 @@ +/* The MIT License + + Copyright (c) 2008 Genome Research Ltd (GRL). + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* Contact: Heng Li <lh3@sanger.ac.uk> */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <time.h> +#include <zlib.h> +#include "bntseq.h" +#include "bwt.h" +#include "main.h" +#include "utils.h" + +bwt_t *bwt_pac2bwt(const char *fn_pac, int use_is); +void bwa_pac_rev_core(const char *fn, const char *fn_rev); + +int bwa_index(int argc, char *argv[]) +{ + char *prefix = 0, *str, *str2, *str3; + int c, algo_type = 3, is_color = 0; + clock_t t; + + while ((c = getopt(argc, argv, "ca:p:")) >= 0) { + switch (c) { + case 'a': + if (strcmp(optarg, "div") == 0) algo_type = 1; + else if (strcmp(optarg, "bwtsw") == 0) algo_type = 2; + else if (strcmp(optarg, "is") == 0) algo_type = 3; + else err_fatal(__func__, "unknown algorithm: '%s'.", optarg); + break; + case 'p': prefix = strdup(optarg); break; + case 'c': is_color = 1; break; + default: return 1; + } + } + + if (optind + 1 > argc) { + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: bwa index [-a bwtsw|div|is] [-c] <in.fasta>\n\n"); + fprintf(stderr, "Options: -a STR BWT construction algorithm: bwtsw or is [is]\n"); + fprintf(stderr, " -p STR prefix of the index [same as fasta name]\n"); + fprintf(stderr, " -c build color-space index\n\n"); + fprintf(stderr, "Warning: `-a bwtsw' does not work for short genomes, while `-a is' and\n"); + fprintf(stderr, " `-a div' do not work not for long genomes. Please choose `-a'\n"); + fprintf(stderr, " according to the length of the genome.\n\n"); + return 1; + } + if (prefix == 0) prefix = strdup(argv[optind]); + str = (char*)calloc(strlen(prefix) + 10, 1); + str2 = (char*)calloc(strlen(prefix) + 10, 1); + str3 = (char*)calloc(strlen(prefix) + 10, 1); + + if (is_color == 0) { // nucleotide indexing + gzFile fp = xzopen(argv[optind], "r"); + t = clock(); + fprintf(stderr, "[bwa_index] Pack FASTA... "); + bns_fasta2bntseq(fp, prefix); + fprintf(stderr, "%.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); + gzclose(fp); + } else { // color indexing + gzFile fp = xzopen(argv[optind], "r"); + strcat(strcpy(str, prefix), ".nt"); + t = clock(); + fprintf(stderr, "[bwa_index] Pack nucleotide FASTA... "); + bns_fasta2bntseq(fp, str); + fprintf(stderr, "%.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); + gzclose(fp); + { + char *tmp_argv[3]; + tmp_argv[0] = argv[0]; tmp_argv[1] = str; tmp_argv[2] = prefix; + t = clock(); + fprintf(stderr, "[bwa_index] Convert nucleotide PAC to color PAC... "); + bwa_pac2cspac(3, tmp_argv); + fprintf(stderr, "%.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); + } + } + { + strcpy(str, prefix); strcat(str, ".pac"); + strcpy(str2, prefix); strcat(str2, ".rpac"); + t = clock(); + fprintf(stderr, "[bwa_index] Reverse the packed sequence... "); + bwa_pac_rev_core(str, str2); + fprintf(stderr, "%.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); + } + { + strcpy(str, prefix); strcat(str, ".pac"); + strcpy(str2, prefix); strcat(str2, ".bwt"); + t = clock(); + fprintf(stderr, "[bwa_index] Construct BWT for the packed sequence...\n"); + if (algo_type == 2) bwt_bwtgen(str, str2); + else if (algo_type == 1 || algo_type == 3) { + bwt_t *bwt; + bwt = bwt_pac2bwt(str, algo_type == 3); + bwt_dump_bwt(str2, bwt); + bwt_destroy(bwt); + } + fprintf(stderr, "[bwa_index] %.2f seconds elapse.\n", (float)(clock() - t) / CLOCKS_PER_SEC); + } + { + strcpy(str, prefix); strcat(str, ".rpac"); + strcpy(str2, prefix); strcat(str2, ".rbwt"); + t = clock(); + fprintf(stderr, "[bwa_index] Construct BWT for the reverse packed sequence...\n"); + if (algo_type == 2) bwt_bwtgen(str, str2); + else if (algo_type == 1 || algo_type == 3) { + bwt_t *bwt; + bwt = bwt_pac2bwt(str, algo_type == 3); + bwt_dump_bwt(str2, bwt); + bwt_destroy(bwt); + } + fprintf(stderr, "[bwa_index] %.2f seconds elapse.\n", (float)(clock() - t) / CLOCKS_PER_SEC); + } + { + bwt_t *bwt; + strcpy(str, prefix); strcat(str, ".bwt"); + t = clock(); + fprintf(stderr, "[bwa_index] Update BWT... "); + bwt = bwt_restore_bwt(str); + bwt_bwtupdate_core(bwt); + bwt_dump_bwt(str, bwt); + bwt_destroy(bwt); + fprintf(stderr, "%.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); + } + { + bwt_t *bwt; + strcpy(str, prefix); strcat(str, ".rbwt"); + t = clock(); + fprintf(stderr, "[bwa_index] Update reverse BWT... "); + bwt = bwt_restore_bwt(str); + bwt_bwtupdate_core(bwt); + bwt_dump_bwt(str, bwt); + bwt_destroy(bwt); + fprintf(stderr, "%.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); + } + { + bwt_t *bwt; + strcpy(str, prefix); strcat(str, ".bwt"); + strcpy(str3, prefix); strcat(str3, ".sa"); + t = clock(); + fprintf(stderr, "[bwa_index] Construct SA from BWT and Occ... "); + bwt = bwt_restore_bwt(str); + bwt_cal_sa(bwt, 32); + bwt_dump_sa(str3, bwt); + bwt_destroy(bwt); + fprintf(stderr, "%.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); + } + { + bwt_t *bwt; + strcpy(str, prefix); strcat(str, ".rbwt"); + strcpy(str3, prefix); strcat(str3, ".rsa"); + t = clock(); + fprintf(stderr, "[bwa_index] Construct SA from reverse BWT and Occ... "); + bwt = bwt_restore_bwt(str); + bwt_cal_sa(bwt, 32); + bwt_dump_sa(str3, bwt); + bwt_destroy(bwt); + fprintf(stderr, "%.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC); + } + free(str3); free(str2); free(str); free(prefix); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwtio.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,77 @@ +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include "bwt.h" +#include "utils.h" + +void bwt_dump_bwt(const char *fn, const bwt_t *bwt) +{ + FILE *fp; + fp = xopen(fn, "wb"); + fwrite(&bwt->primary, sizeof(bwtint_t), 1, fp); + fwrite(bwt->L2+1, sizeof(bwtint_t), 4, fp); + fwrite(bwt->bwt, sizeof(bwtint_t), bwt->bwt_size, fp); + fclose(fp); +} + +void bwt_dump_sa(const char *fn, const bwt_t *bwt) +{ + FILE *fp; + fp = xopen(fn, "wb"); + fwrite(&bwt->primary, sizeof(bwtint_t), 1, fp); + fwrite(bwt->L2+1, sizeof(bwtint_t), 4, fp); + fwrite(&bwt->sa_intv, sizeof(bwtint_t), 1, fp); + fwrite(&bwt->seq_len, sizeof(bwtint_t), 1, fp); + fwrite(bwt->sa + 1, sizeof(bwtint_t), bwt->n_sa - 1, fp); + fclose(fp); +} + +void bwt_restore_sa(const char *fn, bwt_t *bwt) +{ + char skipped[256]; + FILE *fp; + bwtint_t primary; + + fp = xopen(fn, "rb"); + fread(&primary, sizeof(bwtint_t), 1, fp); + xassert(primary == bwt->primary, "SA-BWT inconsistency: primary is not the same."); + fread(skipped, sizeof(bwtint_t), 4, fp); // skip + fread(&bwt->sa_intv, sizeof(bwtint_t), 1, fp); + fread(&primary, sizeof(bwtint_t), 1, fp); + xassert(primary == bwt->seq_len, "SA-BWT inconsistency: seq_len is not the same."); + + bwt->n_sa = (bwt->seq_len + bwt->sa_intv) / bwt->sa_intv; + bwt->sa = (bwtint_t*)calloc(bwt->n_sa, sizeof(bwtint_t)); + bwt->sa[0] = -1; + + fread(bwt->sa + 1, sizeof(bwtint_t), bwt->n_sa - 1, fp); + fclose(fp); +} + +bwt_t *bwt_restore_bwt(const char *fn) +{ + bwt_t *bwt; + FILE *fp; + + bwt = (bwt_t*)calloc(1, sizeof(bwt_t)); + fp = xopen(fn, "rb"); + fseek(fp, 0, SEEK_END); + bwt->bwt_size = (ftell(fp) - sizeof(bwtint_t) * 5) >> 2; + bwt->bwt = (uint32_t*)calloc(bwt->bwt_size, 4); + fseek(fp, 0, SEEK_SET); + fread(&bwt->primary, sizeof(bwtint_t), 1, fp); + fread(bwt->L2+1, sizeof(bwtint_t), 4, fp); + fread(bwt->bwt, 4, bwt->bwt_size, fp); + bwt->seq_len = bwt->L2[4]; + fclose(fp); + bwt_gen_cnt_table(bwt); + + return bwt; +} + +void bwt_destroy(bwt_t *bwt) +{ + if (bwt == 0) return; + free(bwt->sa); free(bwt->bwt); + free(bwt); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwtmisc.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,267 @@ +/* The MIT License + + Copyright (c) 2008 Genome Research Ltd (GRL). + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* Contact: Heng Li <lh3@sanger.ac.uk> */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include "bntseq.h" +#include "utils.h" +#include "main.h" +#include "bwt.h" + +#ifdef _DIVBWT +#include "divsufsort.h" +#endif + +int is_bwt(ubyte_t *T, int n); + +int64_t bwa_seq_len(const char *fn_pac) +{ + FILE *fp; + int64_t pac_len; + ubyte_t c; + fp = xopen(fn_pac, "rb"); + fseek(fp, -1, SEEK_END); + pac_len = ftell(fp); + fread(&c, 1, 1, fp); + fclose(fp); + return (pac_len - 1) * 4 + (int)c; +} + +bwt_t *bwt_pac2bwt(const char *fn_pac, int use_is) +{ + bwt_t *bwt; + ubyte_t *buf, *buf2; + int i, pac_size; + FILE *fp; + + // initialization + bwt = (bwt_t*)calloc(1, sizeof(bwt_t)); + bwt->seq_len = bwa_seq_len(fn_pac); + bwt->bwt_size = (bwt->seq_len + 15) >> 4; + fp = xopen(fn_pac, "rb"); + + // prepare sequence + pac_size = (bwt->seq_len>>2) + ((bwt->seq_len&3) == 0? 0 : 1); + buf2 = (ubyte_t*)calloc(pac_size, 1); + fread(buf2, 1, pac_size, fp); + fclose(fp); + memset(bwt->L2, 0, 5 * 4); + buf = (ubyte_t*)calloc(bwt->seq_len + 1, 1); + for (i = 0; i < bwt->seq_len; ++i) { + buf[i] = buf2[i>>2] >> ((3 - (i&3)) << 1) & 3; + ++bwt->L2[1+buf[i]]; + } + for (i = 2; i <= 4; ++i) bwt->L2[i] += bwt->L2[i-1]; + free(buf2); + + // Burrows-Wheeler Transform + if (use_is) { + bwt->primary = is_bwt(buf, bwt->seq_len); + } else { +#ifdef _DIVBWT + bwt->primary = divbwt(buf, buf, 0, bwt->seq_len); +#else + err_fatal_simple("libdivsufsort is not compiled in."); +#endif + } + bwt->bwt = (u_int32_t*)calloc(bwt->bwt_size, 4); + for (i = 0; i < bwt->seq_len; ++i) + bwt->bwt[i>>4] |= buf[i] << ((15 - (i&15)) << 1); + free(buf); + return bwt; +} + +int bwa_pac2bwt(int argc, char *argv[]) +{ + bwt_t *bwt; + int c, use_is = 1; + while ((c = getopt(argc, argv, "d")) >= 0) { + switch (c) { + case 'd': use_is = 0; break; + default: return 1; + } + } + if (optind + 2 > argc) { + fprintf(stderr, "Usage: bwa pac2bwt [-d] <in.pac> <out.bwt>\n"); + return 1; + } + bwt = bwt_pac2bwt(argv[optind], use_is); + bwt_dump_bwt(argv[optind+1], bwt); + bwt_destroy(bwt); + return 0; +} + +#define bwt_B00(b, k) ((b)->bwt[(k)>>4]>>((~(k)&0xf)<<1)&3) + +void bwt_bwtupdate_core(bwt_t *bwt) +{ + bwtint_t i, k, c[4], n_occ; + uint32_t *buf; + + n_occ = (bwt->seq_len + OCC_INTERVAL - 1) / OCC_INTERVAL + 1; + bwt->bwt_size += n_occ * 4; // the new size + buf = (uint32_t*)calloc(bwt->bwt_size, 4); // will be the new bwt + c[0] = c[1] = c[2] = c[3] = 0; + for (i = k = 0; i < bwt->seq_len; ++i) { + if (i % OCC_INTERVAL == 0) { + memcpy(buf + k, c, sizeof(bwtint_t) * 4); + k += 4; + } + if (i % 16 == 0) buf[k++] = bwt->bwt[i/16]; + ++c[bwt_B00(bwt, i)]; + } + // the last element + memcpy(buf + k, c, sizeof(bwtint_t) * 4); + xassert(k + 4 == bwt->bwt_size, "inconsistent bwt_size"); + // update bwt + free(bwt->bwt); bwt->bwt = buf; +} + +int bwa_bwtupdate(int argc, char *argv[]) +{ + bwt_t *bwt; + if (argc < 2) { + fprintf(stderr, "Usage: bwa bwtupdate <the.bwt>\n"); + return 1; + } + bwt = bwt_restore_bwt(argv[1]); + bwt_bwtupdate_core(bwt); + bwt_dump_bwt(argv[1], bwt); + bwt_destroy(bwt); + return 0; +} + +void bwa_pac_rev_core(const char *fn, const char *fn_rev) +{ + int64_t seq_len, i; + bwtint_t pac_len, j; + ubyte_t *bufin, *bufout, ct; + FILE *fp; + seq_len = bwa_seq_len(fn); + pac_len = (seq_len >> 2) + 1; + bufin = (ubyte_t*)calloc(pac_len, 1); + bufout = (ubyte_t*)calloc(pac_len, 1); + fp = xopen(fn, "rb"); + fread(bufin, 1, pac_len, fp); + fclose(fp); + for (i = seq_len - 1, j = 0; i >= 0; --i) { + int c = bufin[i>>2] >> ((~i&3)<<1) & 3; + bwtint_t j = seq_len - 1 - i; + bufout[j>>2] |= c << ((~j&3)<<1); + } + free(bufin); + fp = xopen(fn_rev, "wb"); + fwrite(bufout, 1, pac_len, fp); + ct = seq_len % 4; + fwrite(&ct, 1, 1, fp); + fclose(fp); + free(bufout); +} + +int bwa_pac_rev(int argc, char *argv[]) +{ + if (argc < 3) { + fprintf(stderr, "Usage: bwa pac_rev <in.pac> <out.pac>\n"); + return 1; + } + bwa_pac_rev_core(argv[1], argv[2]); + return 0; +} + +const int nst_color_space_table[] = { 4, 0, 0, 1, 0, 2, 3, 4, 0, 3, 2, 4, 1, 4, 4, 4}; + +/* this function is not memory efficient, but this will make life easier + Ideally we should also change .amb files as one 'N' in the nucleotide + sequence leads to two ambiguous colors. I may do this later... */ +uint8_t *bwa_pac2cspac_core(const bntseq_t *bns) +{ + uint8_t *pac, *cspac; + bwtint_t i; + int c1, c2; + pac = (uint8_t*)calloc(bns->l_pac/4 + 1, 1); + cspac = (uint8_t*)calloc(bns->l_pac/4 + 1, 1); + fread(pac, 1, bns->l_pac/4+1, bns->fp_pac); + rewind(bns->fp_pac); + c1 = pac[0]>>6; cspac[0] = c1<<6; + for (i = 1; i < bns->l_pac; ++i) { + c2 = pac[i>>2] >> (~i&3)*2 & 3; + cspac[i>>2] |= nst_color_space_table[(1<<c1)|(1<<c2)] << (~i&3)*2; + c1 = c2; + } + free(pac); + return cspac; +} + +int bwa_pac2cspac(int argc, char *argv[]) +{ + bntseq_t *bns; + uint8_t *cspac, ct; + char *str; + FILE *fp; + + if (argc < 3) { + fprintf(stderr, "Usage: bwa pac2cspac <in.nt.prefix> <out.cs.prefix>\n"); + return 1; + } + bns = bns_restore(argv[1]); + cspac = bwa_pac2cspac_core(bns); + bns_dump(bns, argv[2]); + // now write cspac + str = (char*)calloc(strlen(argv[2]) + 5, 1); + strcat(strcpy(str, argv[2]), ".pac"); + fp = xopen(str, "wb"); + fwrite(cspac, 1, bns->l_pac/4 + 1, fp); + ct = bns->l_pac % 4; + fwrite(&ct, 1, 1, fp); + fclose(fp); + bns_destroy(bns); + free(cspac); + return 0; +} + +int bwa_bwt2sa(int argc, char *argv[]) +{ + bwt_t *bwt; + int c, sa_intv = 32; + while ((c = getopt(argc, argv, "i:")) >= 0) { + switch (c) { + case 'i': sa_intv = atoi(optarg); break; + default: return 1; + } + } + if (optind + 2 > argc) { + fprintf(stderr, "Usage: bwa bwt2sa [-i %d] <in.bwt> <out.sa>\n", sa_intv); + return 1; + } + bwt = bwt_restore_bwt(argv[optind]); + bwt_cal_sa(bwt, sa_intv); + bwt_dump_sa(argv[optind+1], bwt); + bwt_destroy(bwt); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwtsw2.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,51 @@ +#ifndef LH3_BWTSW2_H +#define LH3_BWTSW2_H + +#include <stdint.h> +#include "bntseq.h" +#include "bwt_lite.h" +#include "bwt.h" + +typedef struct { + int a, b, q, r, t, qr, bw; + int z, is, t_seeds, hard_clip; + float yita, mask_level, coef; + int n_threads, chunk_size; +} bsw2opt_t; + +typedef struct { + uint32_t k, l, flag:18, n_seeds:14; + int len, G, G2; + int beg, end; +} bsw2hit_t; + +typedef struct { + int n, max; + bsw2hit_t *hits; + int *n_cigar; + uint32_t **cigar; +} bwtsw2_t; + +typedef struct { + void *stack; + int max_l; + uint8_t *aln_mem; +} bsw2global_t; + +#ifdef __cplusplus +extern "C" { +#endif + + bsw2opt_t *bsw2_init_opt(); + bwtsw2_t **bsw2_core(const bsw2opt_t *opt, const bwtl_t *target, const bwt_t *query, bsw2global_t *pool); + void bsw2_aln(const bsw2opt_t *opt, const bntseq_t *bns, bwt_t * const target[2], const char *fn); + void bsw2_destroy(bwtsw2_t *b); + + bsw2global_t *bsw2_global_init(); + void bsw2_global_destroy(bsw2global_t *_pool); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwtsw2_aux.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,639 @@ +#include <stdlib.h> +#include <stdio.h> +#include <math.h> +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#ifdef HAVE_PTHREAD +#include <pthread.h> +#endif +#include "bntseq.h" +#include "bwt_lite.h" +#include "utils.h" +#include "bwtsw2.h" +#include "stdaln.h" +#include "kstring.h" + +#include "kseq.h" +KSEQ_INIT(gzFile, gzread) + +#include "ksort.h" +#define __left_lt(a, b) ((a).end > (b).end) +KSORT_INIT(hit, bsw2hit_t, __left_lt) + +extern unsigned char nst_nt4_table[256]; + +unsigned char nt_comp_table[256] = { + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', + 'N','T','V','G', 'H','N','N','C', 'D','N','N','M', 'N','K','N','N', + 'N','N','Y','S', 'A','N','B','W', 'X','R','N','N', 'N','N','N','N', + 'n','t','v','g', 'h','n','n','c', 'd','n','n','m', 'n','k','n','n', + 'n','n','y','s', 'a','n','b','w', 'x','r','n','N', 'N','N','N','N', + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N' +}; + +extern int bsw2_resolve_duphits(const bwt_t *bwt, bwtsw2_t *b, int IS); +extern int bsw2_resolve_query_overlaps(bwtsw2_t *b, float mask_level); + +bsw2opt_t *bsw2_init_opt() +{ + bsw2opt_t *o = (bsw2opt_t*)calloc(1, sizeof(bsw2opt_t)); + o->a = 1; o->b = 3; o->q = 5; o->r = 2; o->t = 30; + o->bw = 50; + o->z = 1; o->is = 3; o->t_seeds = 5; o->hard_clip = 0; + o->mask_level = 0.50f; o->yita = 5.5f; o->coef = 5.5f; + o->qr = o->q + o->r; o->n_threads = 1; o->chunk_size = 10000000; + return o; +} + +void bsw2_destroy(bwtsw2_t *b) +{ + int i; + if (b == 0) return; + if (b->cigar) + for (i = 0; i < b->n; ++i) free(b->cigar[i]); + free(b->cigar); free(b->n_cigar); free(b->hits); + free(b); +} + +#define __gen_ap(par, opt) do { \ + int i; \ + for (i = 0; i < 25; ++i) (par).matrix[i] = -(opt)->b; \ + for (i = 0; i < 4; ++i) (par).matrix[i*5+i] = (opt)->a; \ + (par).gap_open = (opt)->q; (par).gap_ext = (opt)->r; \ + (par).gap_end = (opt)->r; \ + (par).row = 5; (par).band_width = opt->bw; \ + } while (0) + +#define __rpac(pac, l, i) (pac[(l-i-1)>>2] >> (~(l-i-1)&3)*2 & 0x3) + +void bsw2_extend_left(const bsw2opt_t *opt, bwtsw2_t *b, uint8_t *_query, int lq, uint8_t *pac, uint32_t l_pac, int is_rev, uint8_t *_mem) +{ + int i, matrix[25]; + bwtint_t k; + uint8_t *target = 0, *query; + AlnParam par; + + par.matrix = matrix; + __gen_ap(par, opt); + query = calloc(lq, 1); + // sort according to the descending order of query end + ks_introsort(hit, b->n, b->hits); + target = calloc(((lq + 1) / 2 * opt->a + opt->r) / opt->r + lq, 1); + // reverse _query + for (i = 0; i < lq; ++i) query[lq - i - 1] = _query[i]; + // core loop + for (i = 0; i < b->n; ++i) { + bsw2hit_t *p = b->hits + i; + int lt = ((p->beg + 1) / 2 * opt->a + opt->r) / opt->r + lq; + int score, j; + path_t path; + p->n_seeds = 1; + if (p->l || p->k == 0) continue; + for (j = score = 0; j < i; ++j) { + bsw2hit_t *q = b->hits + j; + if (q->beg <= p->beg && q->k <= p->k && q->k + q->len >= p->k + p->len) { + if (q->n_seeds < (1<<14) - 2) ++q->n_seeds; + ++score; + } + } + if (score) continue; + if (lt > p->k) lt = p->k; + if (is_rev) { + for (k = p->k - 1, j = 0; k > 0 && j < lt; --k) // FIXME: k=0 not considered! + target[j++] = __rpac(pac, l_pac, k); + } else { + for (k = p->k - 1, j = 0; k > 0 && j < lt; --k) // FIXME: k=0 not considered! + target[j++] = pac[k>>2] >> (~k&3)*2 & 0x3; + } + lt = j; + score = aln_extend_core(target, lt, query + lq - p->beg, p->beg, &par, &path, 0, p->G, _mem); + if (score > p->G) { // extensible + p->G = score; + p->len += path.i; + p->beg -= path.j; + p->k -= path.i; + } + } + free(query); free(target); +} + +void bsw2_extend_rght(const bsw2opt_t *opt, bwtsw2_t *b, uint8_t *query, int lq, uint8_t *pac, uint32_t l_pac, int is_rev, uint8_t *_mem) +{ + int i, matrix[25]; + uint32_t k; + uint8_t *target; + AlnParam par; + + par.matrix = matrix; + __gen_ap(par, opt); + target = calloc(((lq + 1) / 2 * opt->a + opt->r) / opt->r + lq, 1); + for (i = 0; i < b->n; ++i) { + bsw2hit_t *p = b->hits + i; + int lt = ((lq - p->beg + 1) / 2 * opt->a + opt->r) / opt->r + lq; + int j, score; + path_t path; + if (p->l) continue; + if (is_rev) { + for (k = p->k, j = 0; k < p->k + lt && k < l_pac; ++k) + target[j++] = __rpac(pac, l_pac, k); + } else { + for (k = p->k, j = 0; k < p->k + lt && k < l_pac; ++k) + target[j++] = pac[k>>2] >> (~k&3)*2 & 0x3; + } + lt = j; + score = aln_extend_core(target, lt, query + p->beg, lq - p->beg, &par, &path, 0, 1, _mem); +// if (score < p->G) fprintf(stderr, "[bsw2_extend_hits] %d < %d\n", score, p->G); + if (score >= p->G) { + p->G = score; + p->len = path.i; + p->end = path.j + p->beg; + } + } + free(target); +} + +/* generate CIGAR array(s) in b->cigar[] */ +static void gen_cigar(const bsw2opt_t *opt, int lq, uint8_t *seq[2], uint8_t *pac, bwtsw2_t *b) +{ + uint8_t *target; + int i, matrix[25]; + AlnParam par; + path_t *path; + + par.matrix = matrix; + __gen_ap(par, opt); + i = ((lq + 1) / 2 * opt->a + opt->r) / opt->r + lq; // maximum possible target length + target = calloc(i, 1); + path = calloc(i + lq, sizeof(path_t)); + // memory clean up for b + if (b->n < b->max) { + b->max = b->n; + b->hits = realloc(b->hits, b->n * sizeof(bsw2hit_t)); + } + if (b->cigar) free(b->cigar); + if (b->n_cigar) free(b->n_cigar); + b->cigar = (uint32_t**)calloc(b->max, sizeof(void*)); + b->n_cigar = (int*)calloc(b->max, sizeof(int)); + // generate CIGAR + for (i = 0; i < b->n; ++i) { + bsw2hit_t *p = b->hits + i; + uint8_t *query; + uint32_t k; + int score, path_len, beg, end; + if (p->l) continue; + beg = (p->flag & 0x10)? lq - p->end : p->beg; + end = (p->flag & 0x10)? lq - p->beg : p->end; + query = seq[(p->flag & 0x10)? 1 : 0] + beg; + for (k = p->k; k < p->k + p->len; ++k) // in principle, no out-of-boundary here + target[k - p->k] = pac[k>>2] >> (~k&3)*2 & 0x3; + score = aln_global_core(target, p->len, query, end - beg, &par, path, &path_len); + b->cigar[i] = aln_path2cigar32(path, path_len, &b->n_cigar[i]); + if (beg != 0 || end < lq) { // write soft clipping + b->cigar[i] = realloc(b->cigar[i], 4 * (b->n_cigar[i] + 2)); + if (beg != 0) { + memmove(b->cigar[i] + 1, b->cigar[i], b->n_cigar[i] * 4); + b->cigar[i][0] = beg<<4 | 4; + ++b->n_cigar[i]; + } + if (end < lq) { + b->cigar[i][b->n_cigar[i]] = (lq - end)<<4 | 4; + ++b->n_cigar[i]; + } + } + } + free(target); free(path); +} + +/* this is for the debugging purpose only */ +void bsw2_debug_hits(const bwtsw2_t *b) +{ + int i; + printf("# raw hits: %d\n", b->n); + for (i = 0; i < b->n; ++i) { + bsw2hit_t *p = b->hits + i; + if (p->l == 0) + printf("%d, %d, %d, %u, %u\n", p->G, p->beg, p->end, p->k, p->l); + } +} + +static void merge_hits(bwtsw2_t *b[2], int l, int is_reverse) +{ + int i; + if (b[0]->n + b[1]->n > b[0]->max) { + b[0]->max = b[0]->n + b[1]->n; + b[0]->hits = realloc(b[0]->hits, b[0]->max * sizeof(bsw2hit_t)); + } + for (i = 0; i < b[1]->n; ++i) { + bsw2hit_t *p = b[0]->hits + b[0]->n + i; + *p = b[1]->hits[i]; + if (is_reverse) { + int x = p->beg; + p->beg = l - p->end; + p->end = l - x; + p->flag |= 0x10; + } + } + b[0]->n += b[1]->n; + bsw2_destroy(b[1]); + b[1] = 0; +} + +static bwtsw2_t *bsw2_aln1_core(const bsw2opt_t *opt, const bntseq_t *bns, uint8_t *pac, const bwt_t *target, int l, uint8_t *seq[2], int is_rev, bsw2global_t *pool) +{ + extern void bsw2_chain_filter(const bsw2opt_t *opt, int len, bwtsw2_t *b[2]); + bwtsw2_t *b[2], **bb[2]; + int k; + for (k = 0; k < 2; ++k) { + bwtl_t *query = bwtl_seq2bwtl(l, seq[k]); + bb[k] = bsw2_core(opt, query, target, pool); + bwtl_destroy(query); + } + b[0] = bb[0][1]; b[1] = bb[1][1]; + bsw2_chain_filter(opt, l, b); + for (k = 0; k < 2; ++k) { + bsw2_extend_left(opt, bb[k][1], seq[k], l, pac, bns->l_pac, is_rev, pool->aln_mem); + merge_hits(bb[k], l, 0); + bsw2_resolve_duphits(0, bb[k][0], 0); + bsw2_extend_rght(opt, bb[k][0], seq[k], l, pac, bns->l_pac, is_rev, pool->aln_mem); + b[k] = bb[k][0]; + free(bb[k]); + } + merge_hits(b, l, 1); + bsw2_resolve_query_overlaps(b[0], opt->mask_level); + return b[0]; +} + +/* set ->flag to records the origin of the hit (to forward bwt or reverse bwt) */ +static void flag_fr(bwtsw2_t *b[2]) +{ + int i, j; + for (i = 0; i < b[0]->n; ++i) { + bsw2hit_t *p = b[0]->hits + i; + p->flag |= 0x10000; + } + for (i = 0; i < b[1]->n; ++i) { + bsw2hit_t *p = b[1]->hits + i; + p->flag |= 0x20000; + } + for (i = 0; i < b[0]->n; ++i) { + bsw2hit_t *p = b[0]->hits + i; + for (j = 0; j < b[1]->n; ++j) { + bsw2hit_t *q = b[1]->hits + i; + if (q->beg == p->beg && q->end == p->end && q->k == p->k && q->len == p->len && q->G == p->G) { + q->flag |= 0x30000; p->flag |= 0x30000; + break; + } + } + } +} + +typedef struct { + int l, tid; + char *name, *seq, *qual, *sam; +} bsw2seq1_t; + +typedef struct { + int n, max; + bsw2seq1_t *seq; +} bsw2seq_t; + +#ifdef HAVE_PTHREAD +static pthread_mutex_t g_dbwtsw_lock = PTHREAD_MUTEX_INITIALIZER; +#endif + +static int fix_cigar(const char *qname, const bntseq_t *bns, bsw2hit_t *p, int n_cigar, uint32_t *cigar) +{ + // FIXME: this routine does not work if the query bridge three reference sequences + int32_t coor, refl, lq; + int x, y, i, seqid; + bns_coor_pac2real(bns, p->k, p->len, &seqid); + coor = p->k - bns->anns[seqid].offset; + refl = bns->anns[seqid].len; + x = coor; y = 0; + // test if the alignment goes beyond the boundary + for (i = 0; i < n_cigar; ++i) { + int op = cigar[i]&0xf, ln = cigar[i]>>4; + if (op == 1 || op == 4 || op == 5) y += ln; + else if (op == 2) x += ln; + else x += ln, y += ln; + } + lq = y; // length of the query sequence + if (x > refl) { // then fix it + int j, nc, mq[2], nlen[2]; + uint32_t *cn, kk = 0; + nc = mq[0] = mq[1] = nlen[0] = nlen[1] = 0; + cn = calloc(n_cigar + 3, 4); + x = coor; y = 0; + for (i = j = 0; i < n_cigar; ++i) { + int op = cigar[i]&0xf, ln = cigar[i]>>4; + if (op == 4 || op == 5 || op == 1) { // ins or clipping + y += ln; + cn[j++] = cigar[i]; + } else if (op == 2) { // del + if (x + ln >= refl && nc == 0) { + cn[j++] = (uint32_t)(lq - y)<<4 | 4; + nc = j; + cn[j++] = (uint32_t)y<<4 | 4; + kk = p->k + (x + ln - refl); + nlen[0] = x - coor; + nlen[1] = p->len - nlen[0] - ln; + } else cn[j++] = cigar[i]; + x += ln; + } else if (op == 0) { // match + if (x + ln >= refl && nc == 0) { + // FIXME: not consider a special case where a split right between M and I + cn[j++] = (uint32_t)(refl - x)<<4 | 0; // write M + cn[j++] = (uint32_t)(lq - y - (refl - x))<<4 | 4; // write S + nc = j; + mq[0] += refl - x; + cn[j++] = (uint32_t)(y + (refl - x))<<4 | 4; + if (x + ln - refl) cn[j++] = (uint32_t)(x + ln - refl)<<4 | 0; + mq[1] += x + ln - refl; + kk = bns->anns[seqid].offset + refl; + nlen[0] = refl - coor; + nlen[1] = p->len - nlen[0]; + } else { + cn[j++] = cigar[i]; + mq[nc?1:0] += ln; + } + x += ln; y += ln; + } + } + if (mq[0] > mq[1]) { // then take the first alignment + n_cigar = nc; + memcpy(cigar, cn, 4 * nc); + p->len = nlen[0]; + } else { + p->k = kk; p->len = nlen[1]; + n_cigar = j - nc; + memcpy(cigar, cn + nc, 4 * (j - nc)); + } + free(cn); + } + return n_cigar; +} + +/* generate SAM lines for a sequence in ks with alignment stored in + * b. ks->name and ks->seq will be freed and set to NULL in the end. */ +static void print_hits(const bntseq_t *bns, const bsw2opt_t *opt, bsw2seq1_t *ks, bwtsw2_t *b) +{ + int i, k; + kstring_t str; + memset(&str, 0, sizeof(kstring_t)); + for (i = 0; i < b->n; ++i) { + bsw2hit_t *p = b->hits + i; + int32_t seqid = -1, coor = -1; + int j, qual, nn = 0; + int beg, end; + if (p->l == 0) { + b->n_cigar[i] = fix_cigar(ks->name, bns, p, b->n_cigar[i], b->cigar[i]); + nn = bns_coor_pac2real(bns, p->k, p->len, &seqid); + coor = p->k - bns->anns[seqid].offset; + } + ksprintf(&str, "%s\t%d", ks->name, p->flag&0x10); + ksprintf(&str, "\t%s\t%d", seqid>=0? bns->anns[seqid].name : "*", coor + 1); + if (p->l == 0) { + { // estimate mapping quality + float c = 1.0; + int subo = p->G2 > opt->t? p->G2 : opt->t; + if (p->flag>>16 == 1 || p->flag>>16 == 2) c *= .5; + if (p->n_seeds < 2) c *= .2; + qual = (int)(c * (p->G - subo) * (250.0 / p->G + 0.03 / opt->a) + .499); + if (qual > 250) qual = 250; + if (p->flag&1) qual = 0; + } + ksprintf(&str, "\t%d\t", qual); + for (k = 0; k < b->n_cigar[i]; ++k) + ksprintf(&str, "%d%c", b->cigar[i][k]>>4, (opt->hard_clip? "MIDNHHP" : "MIDNSHP")[b->cigar[i][k]&0xf]); + } else ksprintf(&str, "\t0\t*"); + ksprintf(&str, "\t*\t0\t0\t"); + beg = 0; end = ks->l; + if (opt->hard_clip) { + if ((b->cigar[i][0]&0xf) == 4) beg += b->cigar[i][0]>>4; + if ((b->cigar[i][b->n_cigar[i]-1]&0xf) == 4) end -= b->cigar[i][b->n_cigar[i]-1]>>4; + } + for (j = beg; j < end; ++j) { + if (p->flag&0x10) kputc(nt_comp_table[(int)ks->seq[ks->l - 1 - j]], &str); + else kputc(ks->seq[j], &str); + } + if (ks->qual) { + kputc('\t', &str); + for (j = beg; j < end; ++j) { + if (p->flag&0x10) kputc(ks->qual[ks->l - 1 - j], &str); + else kputc(ks->qual[j], &str); + } + } else ksprintf(&str, "\t*"); + ksprintf(&str, "\tAS:i:%d\tXS:i:%d\tXF:i:%d\tXE:i:%d\tXN:i:%d", p->G, p->G2, p->flag>>16, p->n_seeds, nn); + if (p->l) ksprintf(&str, "\tXI:i:%d", p->l - p->k + 1); + kputc('\n', &str); + } + ks->sam = str.s; + free(ks->seq); ks->seq = 0; + free(ks->qual); ks->qual = 0; + free(ks->name); ks->name = 0; +} + +/* Core routine to align reads in _seq. It is separated from + * process_seqs() to realize multi-threading */ +static void bsw2_aln_core(int tid, bsw2seq_t *_seq, const bsw2opt_t *_opt, const bntseq_t *bns, uint8_t *pac, bwt_t * const target[2]) +{ + int x; + bsw2opt_t opt = *_opt; + bsw2global_t *pool = bsw2_global_init(); + for (x = 0; x < _seq->n; ++x) { + bsw2seq1_t *p = _seq->seq + x; + uint8_t *seq[2], *rseq[2]; + int i, l, k; + bwtsw2_t *b[2]; + l = p->l; + +#ifdef HAVE_PTHREAD + if (_opt->n_threads > 1) { + pthread_mutex_lock(&g_dbwtsw_lock); + if (p->tid < 0) p->tid = tid; + else if (p->tid != tid) { + pthread_mutex_unlock(&g_dbwtsw_lock); + continue; + } // in pinciple else should not happen + pthread_mutex_unlock(&g_dbwtsw_lock); + } +#endif + + // set opt->t + opt.t = _opt->t; + if (opt.t < log(l) * opt.coef) opt.t = (int)(log(l) * opt.coef + .499); + if (pool->max_l < l) { // then enlarge working space for aln_extend_core() + int tmp = ((l + 1) / 2 * opt.a + opt.r) / opt.r + l; + pool->max_l = l; + pool->aln_mem = realloc(pool->aln_mem, (tmp + 2) * 24); + } + // set opt->bw + opt.bw = _opt->bw; + k = (l * opt.a - 2 * opt.q) / (2 * opt.r + opt.a); + i = (l * opt.a - opt.a - opt.t) / opt.r; + if (k > i) k = i; + if (k < 1) k = 1; // I do not know if k==0 causes troubles + opt.bw = _opt->bw < k? _opt->bw : k; + // set seq[2] and rseq[2] + seq[0] = calloc(l * 4, 1); + seq[1] = seq[0] + l; + rseq[0] = seq[1] + l; rseq[1] = rseq[0] + l; + // convert sequences to 2-bit representation + for (i = k = 0; i < l; ++i) { + int c = nst_nt4_table[(int)p->seq[i]]; + if (c >= 4) { c = (int)(drand48() * 4); ++k; } // FIXME: ambiguous bases are not properly handled + seq[0][i] = c; + seq[1][l-1-i] = 3 - c; + rseq[0][l-1-i] = c; + rseq[1][i] = 3 - c; + } + if (l - k < opt.t) { + free(seq[0]); continue; + } + // alignment + b[0] = bsw2_aln1_core(&opt, bns, pac, target[0], l, seq, 0, pool); + for (k = 0; k < b[0]->n; ++k) + if (b[0]->hits[k].n_seeds < opt.t_seeds) break; + if (k < b[0]->n) { + b[1] = bsw2_aln1_core(&opt, bns, pac, target[1], l, rseq, 1, pool); + for (i = 0; i < b[1]->n; ++i) { + bsw2hit_t *p = b[1]->hits + i; + int x = p->beg; + p->beg = l - p->end; + p->end = l - x; + if (p->l == 0) p->k = bns->l_pac - (p->k + p->len); + } + flag_fr(b); + merge_hits(b, l, 0); + bsw2_resolve_duphits(0, b[0], 0); + bsw2_resolve_query_overlaps(b[0], opt.mask_level); + } else b[1] = 0; + // generate CIGAR and print SAM + gen_cigar(&opt, l, seq, pac, b[0]); + print_hits(bns, &opt, p, b[0]); + // free + free(seq[0]); + bsw2_destroy(b[0]); + } + bsw2_global_destroy(pool); +} + +#ifdef HAVE_PTHREAD +typedef struct { + int tid; + bsw2seq_t *_seq; + const bsw2opt_t *_opt; + const bntseq_t *bns; + uint8_t *pac; + bwt_t *target[2]; +} thread_aux_t; + +/* another interface to bsw2_aln_core() to facilitate pthread_create() */ +static void *worker(void *data) +{ + thread_aux_t *p = (thread_aux_t*)data; + bsw2_aln_core(p->tid, p->_seq, p->_opt, p->bns, p->pac, p->target); + return 0; +} +#endif + +/* process sequences stored in _seq, generate SAM lines for these + * sequences and reset _seq afterwards. */ +static void process_seqs(bsw2seq_t *_seq, const bsw2opt_t *opt, const bntseq_t *bns, uint8_t *pac, bwt_t * const target[2]) +{ + int i; + +#ifdef HAVE_PTHREAD + if (opt->n_threads <= 1) { + bsw2_aln_core(0, _seq, opt, bns, pac, target); + } else { + pthread_t *tid; + pthread_attr_t attr; + thread_aux_t *data; + int j; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + data = (thread_aux_t*)calloc(opt->n_threads, sizeof(thread_aux_t)); + tid = (pthread_t*)calloc(opt->n_threads, sizeof(pthread_t)); + for (j = 0; j < opt->n_threads; ++j) { + thread_aux_t *p = data + j; + p->tid = j; p->_seq = _seq; p->_opt = opt; p->bns = bns; + p->pac = pac; p->target[0] = target[0]; p->target[1] = target[1]; + pthread_create(&tid[j], &attr, worker, p); + } + for (j = 0; j < opt->n_threads; ++j) pthread_join(tid[j], 0); + free(data); free(tid); + } +#else + bsw2_aln_core(0, _seq, opt, bns, pac, target); +#endif + + // print and reset + for (i = 0; i < _seq->n; ++i) { + bsw2seq1_t *p = _seq->seq + i; + if (p->sam) printf("%s", p->sam); + free(p->name); free(p->seq); free(p->qual); free(p->sam); + p->tid = -1; p->l = 0; + p->name = p->seq = p->qual = p->sam = 0; + } + fflush(stdout); + _seq->n = 0; +} + +void bsw2_aln(const bsw2opt_t *opt, const bntseq_t *bns, bwt_t * const target[2], const char *fn) +{ + gzFile fp; + kseq_t *ks; + int l, size = 0; + uint8_t *pac; + bsw2seq_t *_seq; + + pac = calloc(bns->l_pac/4+1, 1); + if (pac == 0) { + fprintf(stderr, "[bsw2_aln] insufficient memory!\n"); + return; + } + for (l = 0; l < bns->n_seqs; ++l) + printf("@SQ\tSN:%s\tLN:%d\n", bns->anns[l].name, bns->anns[l].len); + fread(pac, 1, bns->l_pac/4+1, bns->fp_pac); + fp = xzopen(fn, "r"); + ks = kseq_init(fp); + _seq = calloc(1, sizeof(bsw2seq_t)); + while ((l = kseq_read(ks)) >= 0) { + bsw2seq1_t *p; + if (_seq->n == _seq->max) { + _seq->max = _seq->max? _seq->max<<1 : 1024; + _seq->seq = realloc(_seq->seq, _seq->max * sizeof(bsw2seq1_t)); + } + p = &_seq->seq[_seq->n++]; + p->tid = -1; + p->l = l; + p->name = strdup(ks->name.s); + p->seq = strdup(ks->seq.s); + p->qual = ks->qual.l? strdup(ks->qual.s) : 0; + p->sam = 0; + size += l; + if (size > opt->chunk_size) { + fprintf(stderr, "[bsw2_aln] read %d sequences (%d bp)...\n", _seq->n, size); + process_seqs(_seq, opt, bns, pac, target); + size = 0; + } + } + fprintf(stderr, "[bsw2_aln] read %d sequences (%d bp)...\n", _seq->n, size); + process_seqs(_seq, opt, bns, pac, target); + free(_seq->seq); free(_seq); + kseq_destroy(ks); + gzclose(fp); + free(pac); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwtsw2_chain.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,107 @@ +#include <stdio.h> +#include "bwtsw2.h" + +typedef struct { + uint32_t tbeg, tend; + int qbeg, qend; + uint32_t flag:1, idx:31; + int chain; // also reuse as a counter +} hsaip_t; + +#define _hsaip_lt(a, b) ((a).qbeg < (b).qbeg) + +#include "ksort.h" +KSORT_INIT(hsaip, hsaip_t, _hsaip_lt) + +static int chaining(const bsw2opt_t *opt, int shift, int n, hsaip_t *z, hsaip_t *chain) +{ + int j, k, m = 0; + ks_introsort(hsaip, n, z); + for (j = 0; j < n; ++j) { + hsaip_t *p = z + j; + for (k = m - 1; k >= 0; --k) { + hsaip_t *q = chain + k; + int x = p->qbeg - q->qbeg; // always positive + int y = p->tbeg - q->tbeg; + if (y > 0 && x - y <= opt->bw && y - x <= opt->bw) { + if (p->qend > q->qend) q->qend = p->qend; + if (p->tend > q->tend) q->tend = p->tend; + ++q->chain; + p->chain = shift + k; + break; + } + } + if (k < 0) { + chain[m] = *p; + chain[m].chain = 1; + chain[m].idx = p->chain = shift + m; + ++m; + } + } + return m; +} + +void bsw2_chain_filter(const bsw2opt_t *opt, int len, bwtsw2_t *b[2]) +{ + hsaip_t *z[2], *chain[2]; + int i, j, k, n[2], m[2]; + char *flag; + // initialization + n[0] = b[0]->n; n[1] = b[1]->n; + z[0] = calloc(n[0] + n[1], sizeof(hsaip_t)); + z[1] = z[0] + n[0]; + chain[0] = calloc(n[0] + n[1], sizeof(hsaip_t)); + for (k = j = 0; k < 2; ++k) { + for (i = 0; i < b[k]->n; ++i) { + bsw2hit_t *p = b[k]->hits + i; + hsaip_t *q = z[k] + i; + q->flag = k; q->idx = i; + q->tbeg = p->k; q->tend = p->k + p->len; + q->chain = -1; + q->qbeg = p->beg; q->qend = p->end; + } + } + // chaining + m[0] = chaining(opt, 0, n[0], z[0], chain[0]); + chain[1] = chain[0] + m[0]; + m[1] = chaining(opt, m[0], n[1], z[1], chain[1]); + // change query coordinate on the reverse strand + for (k = 0; k < m[1]; ++k) { + hsaip_t *p = chain[1] + k; + int tmp = p->qbeg; + p->qbeg = len - p->qend; p->qend = len - tmp; + } + // filtering + flag = calloc(m[0] + m[1], 1); + ks_introsort(hsaip, m[0] + m[1], chain[0]); + for (k = 1; k < m[0] + m[1]; ++k) { + hsaip_t *p = chain[0] + k; + for (j = 0; j < k; ++j) { + hsaip_t *q = chain[0] + j; + if (flag[q->idx]) continue; + if (q->qend >= p->qend && q->chain > p->chain * opt->t_seeds * 2) { + flag[p->idx] = 1; + break; + } + } + } + for (k = 0; k < n[0] + n[1]; ++k) { + hsaip_t *p = z[0] + k; + if (flag[p->chain]) + b[p->flag]->hits[p->idx].G = 0; + } + free(flag); + // squeeze out filtered elements in b[2] + for (k = 0; k < 2; ++k) { + for (j = i = 0; j < n[k]; ++j) { + bsw2hit_t *p = b[k]->hits + j; + if (p->G) { + if (i != j) b[k]->hits[i++] = *p; + else ++i; + } + } + b[k]->n = i; + } + // free + free(z[0]); free(chain[0]); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwtsw2_core.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,575 @@ +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <sys/resource.h> +#include <assert.h> +#include "bwt_lite.h" +#include "bwtsw2.h" +#include "bwt.h" +#include "kvec.h" + +#include "khash.h" +KHASH_MAP_INIT_INT64(64, uint64_t) + +#define MINUS_INF -0x3fffffff +#define MASK_LEVEL 0.90f + +struct __mempool_t; +static void mp_destroy(struct __mempool_t*); +typedef struct { + uint32_t qk, ql; + int I, D, G; + uint32_t pj:2, qlen:30; + int tlen; + int ppos, upos; + int cpos[4]; +} bsw2cell_t; + +#include "ksort.h" +KSORT_INIT_GENERIC(int) +#define __hitG_lt(a, b) ((a).G > (b).G) +KSORT_INIT(hitG, bsw2hit_t, __hitG_lt) + +static const bsw2cell_t g_default_cell = { 0, 0, MINUS_INF, MINUS_INF, MINUS_INF, 0, 0, 0, -1, -1, {-1, -1, -1, -1} }; + +typedef struct { + int n, max; + uint32_t tk, tl; + bsw2cell_t *array; +} bsw2entry_t, *bsw2entry_p; + +/* --- BEGIN: Stack operations --- */ +typedef struct { + int n_pending; + kvec_t(bsw2entry_p) stack0, pending; + struct __mempool_t *pool; +} bsw2stack_t; + +#define stack_isempty(s) (kv_size(s->stack0) == 0 && s->n_pending == 0) +static void stack_destroy(bsw2stack_t *s) { mp_destroy(s->pool); kv_destroy(s->stack0); kv_destroy(s->pending); free(s); } +inline static void stack_push0(bsw2stack_t *s, bsw2entry_p e) { kv_push(bsw2entry_p, s->stack0, e); } +inline static bsw2entry_p stack_pop(bsw2stack_t *s) +{ + assert(!(kv_size(s->stack0) == 0 && s->n_pending != 0)); + return kv_pop(s->stack0); +} +/* --- END: Stack operations --- */ + +/* --- BEGIN: memory pool --- */ +typedef struct __mempool_t { + int cnt; // if cnt!=0, then there must be memory leak + kvec_t(bsw2entry_p) pool; +} mempool_t; +inline static bsw2entry_p mp_alloc(mempool_t *mp) +{ + ++mp->cnt; + if (kv_size(mp->pool) == 0) return (bsw2entry_t*)calloc(1, sizeof(bsw2entry_t)); + else return kv_pop(mp->pool); +} +inline static void mp_free(mempool_t *mp, bsw2entry_p e) +{ + --mp->cnt; e->n = 0; + kv_push(bsw2entry_p, mp->pool, e); +} +static void mp_destroy(struct __mempool_t *mp) +{ + int i; + for (i = 0; i != kv_size(mp->pool); ++i) { + free(kv_A(mp->pool, i)->array); + free(kv_A(mp->pool, i)); + } + kv_destroy(mp->pool); + free(mp); +} +/* --- END: memory pool --- */ + +/* --- BEGIN: utilities --- */ +static khash_t(64) *bsw2_connectivity(const bwtl_t *b) +{ + khash_t(64) *h; + uint32_t k, l, cntk[4], cntl[4]; + uint64_t x; + khiter_t iter; + int j, ret; + kvec_t(uint64_t) stack; + + kv_init(stack); + h = kh_init(64); + kh_resize(64, h, b->seq_len * 4); + x = b->seq_len; + kv_push(uint64_t, stack, x); + while (kv_size(stack)) { + x = kv_pop(stack); + k = x>>32; l = (uint32_t)x; + bwtl_2occ4(b, k-1, l, cntk, cntl); + for (j = 0; j != 4; ++j) { + k = b->L2[j] + cntk[j] + 1; + l = b->L2[j] + cntl[j]; + if (k > l) continue; + x = (uint64_t)k << 32 | l; + iter = kh_put(64, h, x, &ret); + if (ret) { // if not present + kh_value(h, iter) = 1; + kv_push(uint64_t, stack, x); + } else ++kh_value(h, iter); + } + } + kv_destroy(stack); + //fprintf(stderr, "[bsw2_connectivity] %u nodes in the DAG\n", kh_size(h)); + return h; +} +// pick up top T matches at a node +static void cut_tail(bsw2entry_t *u, int T, bsw2entry_t *aux) +{ + int i, *a, n, x; + if (u->n <= T) return; + if (aux->max < u->n) { + aux->max = u->n; + aux->array = (bsw2cell_t*)realloc(aux->array, aux->max * sizeof(bsw2cell_t)); + } + a = (int*)aux->array; + for (i = n = 0; i != u->n; ++i) + if (u->array[i].ql && u->array[i].G > 0) + a[n++] = -u->array[i].G; + if (n <= T) return; + x = -ks_ksmall(int, n, a, T); + n = 0; + for (i = 0; i < u->n; ++i) { + bsw2cell_t *p = u->array + i; + if (p->G == x) ++n; + if (p->G < x || (p->G == x && n >= T)) { + p->qk = p->ql = 0; p->G = 0; + if (p->ppos >= 0) u->array[p->ppos].cpos[p->pj] = -1; + } + } +} +// remove duplicated cells +static inline void remove_duplicate(bsw2entry_t *u, khash_t(64) *hash) +{ + int i, ret, j; + khiter_t k; + uint64_t key; + kh_clear(64, hash); + for (i = 0; i != u->n; ++i) { + bsw2cell_t *p = u->array + i; + if (p->ql == 0) continue; + key = (uint64_t)p->qk << 32 | p->ql; + k = kh_put(64, hash, key, &ret); + j = -1; + if (ret == 0) { + if ((uint32_t)kh_value(hash, k) >= p->G) j = i; + else { + j = kh_value(hash, k)>>32; + kh_value(hash, k) = (uint64_t)i<<32 | p->G; + } + } else kh_value(hash, k) = (uint64_t)i<<32 | p->G; + if (j >= 0) { + p = u->array + j; + p->qk = p->ql = 0; p->G = 0; + if (p->ppos >= 0) u->array[p->ppos].cpos[p->pj] = -3; + } + } +} +// merge two entries +static void merge_entry(const bsw2opt_t * __restrict opt, bsw2entry_t *u, bsw2entry_t *v, bwtsw2_t *b) +{ + int i; + if (u->n + v->n >= u->max) { + u->max = u->n + v->n; + u->array = (bsw2cell_t*)realloc(u->array, u->max * sizeof(bsw2cell_t)); + } + for (i = 0; i != v->n; ++i) { + bsw2cell_t *p = v->array + i; + if (p->ppos >= 0) p->ppos += u->n; + if (p->cpos[0] >= 0) p->cpos[0] += u->n; + if (p->cpos[1] >= 0) p->cpos[1] += u->n; + if (p->cpos[2] >= 0) p->cpos[2] += u->n; + if (p->cpos[3] >= 0) p->cpos[3] += u->n; + } + memcpy(u->array + u->n, v->array, v->n * sizeof(bsw2cell_t)); + u->n += v->n; +} + +static inline bsw2cell_t *push_array_p(bsw2entry_t *e) +{ + if (e->n == e->max) { + e->max = e->max? e->max<<1 : 256; + e->array = (bsw2cell_t*)realloc(e->array, sizeof(bsw2cell_t) * e->max); + } + return e->array + e->n; +} + +static inline double time_elapse(const struct rusage *curr, const struct rusage *last) +{ + long t1 = (curr->ru_utime.tv_sec - last->ru_utime.tv_sec) + (curr->ru_stime.tv_sec - last->ru_stime.tv_sec); + long t2 = (curr->ru_utime.tv_usec - last->ru_utime.tv_usec) + (curr->ru_stime.tv_usec - last->ru_stime.tv_usec); + return (double)t1 + t2 * 1e-6; +} +/* --- END: utilities --- */ + +/* --- BEGIN: processing partial hits --- */ +static void save_hits(const bwtl_t *bwt, int thres, bsw2hit_t *hits, bsw2entry_t *u) +{ + int i; + uint32_t k; + for (i = 0; i < u->n; ++i) { + bsw2cell_t *p = u->array + i; + if (p->G < thres) continue; + for (k = u->tk; k <= u->tl; ++k) { + int beg, end; + bsw2hit_t *q = 0; + beg = bwt->sa[k]; end = beg + p->tlen; + if (p->G > hits[beg*2].G) { + hits[beg*2+1] = hits[beg*2]; + q = hits + beg * 2; + } else if (p->G > hits[beg*2+1].G) q = hits + beg * 2 + 1; + if (q) { + q->k = p->qk; q->l = p->ql; q->len = p->qlen; q->G = p->G; + q->beg = beg; q->end = end; q->G2 = q->k == q->l? 0 : q->G; + q->flag = q->n_seeds = 0; + } + } + } +} + +static void save_narrow_hits(const bwtl_t *bwtl, bsw2entry_t *u, bwtsw2_t *b1, int t, int IS) +{ + int i; + for (i = 0; i < u->n; ++i) { + bsw2hit_t *q; + bsw2cell_t *p = u->array + i; + if (p->G >= t && p->ql - p->qk + 1 <= IS) { // good narrow hit + if (b1->max == b1->n) { + b1->max = b1->max? b1->max<<1 : 4; + b1->hits = realloc(b1->hits, b1->max * sizeof(bsw2hit_t)); + } + q = &b1->hits[b1->n++]; + q->k = p->qk; q->l = p->ql; + q->len = p->qlen; + q->G = p->G; q->G2 = 0; + q->beg = bwtl->sa[u->tk]; q->end = q->beg + p->tlen; + q->flag = 0; + // delete p + p->qk = p->ql = 0; p->G = 0; + if (p->ppos >= 0) u->array[p->ppos].cpos[p->pj] = -3; + } + } +} + +int bsw2_resolve_duphits(const bwt_t *bwt, bwtsw2_t *b, int IS) +{ + int i, j, n; + if (b->n == 0) return 0; + if (bwt) { // convert to chromosomal coordinates if suitable + int old_n = b->n; + bsw2hit_t *old_hits = b->hits; + for (i = n = 0; i < b->n; ++i) { + bsw2hit_t *p = old_hits + i; + if (p->l - p->k + 1 <= IS) n += p->l - p->k + 1; + else if (p->G > 0) ++n; + } + b->n = b->max = n; + b->hits = calloc(b->max, sizeof(bsw2hit_t)); + for (i = j = 0; i < old_n; ++i) { + bsw2hit_t *p = old_hits + i; + if (p->l - p->k + 1 <= IS) { + bwtint_t k; + for (k = p->k; k <= p->l; ++k) { + b->hits[j] = *p; + b->hits[j].k = bwt_sa(bwt, k); + b->hits[j].l = 0; + ++j; + } + } else if (p->G > 0) { + b->hits[j] = *p; + b->hits[j].k = bwt_sa(bwt, p->k); + b->hits[j].l = 0; + b->hits[j].flag |= 1; + ++j; + } + } + free(old_hits); + } + ks_introsort(hitG, b->n, b->hits); + for (i = 1; i < b->n; ++i) { + bsw2hit_t *p = b->hits + i; + if (p->G == 0) break; + for (j = 0; j < i; ++j) { + bsw2hit_t *q = b->hits + j; + int compatible = 1; + if (q->G == 0) continue; + if (p->l == 0 && q->l == 0) { + int qol = (p->end < q->end? p->end : q->end) - (p->beg > q->beg? p->beg : q->beg); + if (qol < 0) qol = 0; + if ((float)qol / (p->end - p->beg) > MASK_LEVEL || (float)qol / (q->end - q->beg) > MASK_LEVEL) { + int64_t tol = (int64_t)(p->k + p->len < q->k + q->len? p->k + p->len : q->k + q->len) + - (int64_t)(p->k > q->k? p->k : q->k); + if ((double)tol / p->len > MASK_LEVEL || (double)tol / q->len > MASK_LEVEL) + compatible = 0; + } + } + if (!compatible) { + p->G = 0; + break; + } + } + } + n = i; + for (i = j = 0; i < n; ++i) { + if (b->hits[i].G == 0) continue; + if (i != j) b->hits[j++] = b->hits[i]; + else ++j; + } + b->n = j; + return b->n; +} + +int bsw2_resolve_query_overlaps(bwtsw2_t *b, float mask_level) +{ + int i, j, n; + if (b->n == 0) return 0; + ks_introsort(hitG, b->n, b->hits); + for (i = 1; i < b->n; ++i) { + bsw2hit_t *p = b->hits + i; + int all_compatible = 1; + if (p->G == 0) break; + for (j = 0; j < i; ++j) { + bsw2hit_t *q = b->hits + j; + int qol, compatible = 0; + if (q->G == 0) continue; + qol = (p->end < q->end? p->end : q->end) - (p->beg > q->beg? p->beg : q->beg); + if (qol < 0) qol = 0; + if ((float)qol / (p->end - p->beg) < mask_level + && (float)qol / (q->end - q->beg) < mask_level) compatible = 1; + if (!compatible) { + if (q->G2 < p->G) q->G2 = p->G; + all_compatible = 0; + } + } + if (!all_compatible) p->G = 0; + } + n = i; + for (i = j = 0; i < n; ++i) { + if (b->hits[i].G == 0) continue; + if (i != j) b->hits[j++] = b->hits[i]; + else ++j; + } + b->n = j; + return j; +} +/* --- END: processing partial hits --- */ + +/* --- BEGIN: global mem pool --- */ +bsw2global_t *bsw2_global_init() +{ + bsw2global_t *pool; + bsw2stack_t *stack; + pool = calloc(1, sizeof(bsw2global_t)); + stack = calloc(1, sizeof(bsw2stack_t)); + stack->pool = (mempool_t*)calloc(1, sizeof(mempool_t)); + pool->stack = (void*)stack; + return pool; +} + +void bsw2_global_destroy(bsw2global_t *pool) +{ + stack_destroy((bsw2stack_t*)pool->stack); + free(pool->aln_mem); + free(pool); +} +/* --- END: global mem pool --- */ + +static inline int fill_cell(const bsw2opt_t *o, int match_score, bsw2cell_t *c[4]) +{ + int G = c[3]? c[3]->G + match_score : MINUS_INF; + if (c[1]) { + c[0]->I = c[1]->I > c[1]->G - o->q? c[1]->I - o->r : c[1]->G - o->qr; + if (c[0]->I > G) G = c[0]->I; + } else c[0]->I = MINUS_INF; + if (c[2]) { + c[0]->D = c[2]->D > c[2]->G - o->q? c[2]->D - o->r : c[2]->G - o->qr; + if (c[0]->D > G) G = c[0]->D; + } else c[0]->D = MINUS_INF; + return(c[0]->G = G); +} + +static void init_bwtsw2(const bwtl_t *target, const bwt_t *query, bsw2stack_t *s) +{ + bsw2entry_t *u; + bsw2cell_t *x; + + u = mp_alloc(s->pool); + u->tk = 0; u->tl = target->seq_len; + x = push_array_p(u); + *x = g_default_cell; + x->G = 0; x->qk = 0; x->ql = query->seq_len; + u->n++; + stack_push0(s, u); +} + +bwtsw2_t **bsw2_core(const bsw2opt_t *opt, const bwtl_t *target, const bwt_t *query, bsw2global_t *pool) +{ + bsw2stack_t *stack = (bsw2stack_t*)pool->stack; + bwtsw2_t *b, *b1, **b_ret; + int i, j, score_mat[16], *heap, heap_size, n_tot = 0; + struct rusage curr, last; + khash_t(64) *rhash, *chash; + + // initialize connectivity hash (chash) + chash = bsw2_connectivity(target); + // calculate score matrix + for (i = 0; i != 4; ++i) + for (j = 0; j != 4; ++j) + score_mat[i<<2|j] = (i == j)? opt->a : -opt->b; + // initialize other variables + rhash = kh_init(64); + init_bwtsw2(target, query, stack); + heap_size = opt->z; + heap = calloc(heap_size, sizeof(int)); + // initialize the return struct + b = (bwtsw2_t*)calloc(1, sizeof(bwtsw2_t)); + b->n = b->max = target->seq_len * 2; + b->hits = calloc(b->max, sizeof(bsw2hit_t)); + b1 = (bwtsw2_t*)calloc(1, sizeof(bwtsw2_t)); + b_ret = calloc(2, sizeof(void*)); + b_ret[0] = b; b_ret[1] = b1; + // initialize timer + getrusage(0, &last); + // the main loop: traversal of the DAG + while (!stack_isempty(stack)) { + int old_n, tj; + bsw2entry_t *v; + uint32_t k, l, tcntk[4], tcntl[4]; + + v = stack_pop(stack); old_n = v->n; + n_tot += v->n; + + for (i = 0; i < v->n; ++i) { // test max depth and band width + bsw2cell_t *p = v->array + i; + if (p->ql == 0) continue; + if (p->tlen - (int)p->qlen > opt->bw || (int)p->qlen - p->tlen > opt->bw) { + p->qk = p->ql = 0; + if (p->ppos >= 0) v->array[p->ppos].cpos[p->pj] = -5; + } + } + + // get Occ for the DAG + bwtl_2occ4(target, v->tk - 1, v->tl, tcntk, tcntl); + for (tj = 0; tj != 4; ++tj) { // descend to the children + uint32_t qcntk[4], qcntl[4]; + int qj, *curr_score_mat = score_mat + tj * 4; + khiter_t iter; + bsw2entry_t *u; + + k = target->L2[tj] + tcntk[tj] + 1; + l = target->L2[tj] + tcntl[tj]; + if (k > l) continue; + // update counter + iter = kh_get(64, chash, (uint64_t)k<<32 | l); + --kh_value(chash, iter); + // initialization + u = mp_alloc(stack->pool); + u->tk = k; u->tl = l; + memset(heap, 0, sizeof(int) * opt->z); + // loop through all the nodes in v + for (i = 0; i < v->n; ++i) { + bsw2cell_t *p = v->array + i, *x, *c[4]; // c[0]=>current, c[1]=>I, c[2]=>D, c[3]=>G + int is_added = 0; + if (p->ql == 0) continue; // deleted node + c[0] = x = push_array_p(u); + x->G = MINUS_INF; + p->upos = x->upos = -1; + if (p->ppos >= 0) { // parent has been visited + c[1] = (v->array[p->ppos].upos >= 0)? u->array + v->array[p->ppos].upos : 0; + c[3] = v->array + p->ppos; c[2] = p; + if (fill_cell(opt, curr_score_mat[p->pj], c) > 0) { // then update topology at p and x + x->ppos = v->array[p->ppos].upos; // the parent pos in u + p->upos = u->n++; // the current pos in u + if (x->ppos >= 0) u->array[x->ppos].cpos[p->pj] = p->upos; // the child pos of its parent in u + is_added = 1; + } + } else { + x->D = p->D > p->G - opt->q? p->D - opt->r : p->G - opt->qr; + if (x->D > 0) { + x->G = x->D; + x->I = MINUS_INF; x->ppos = -1; + p->upos = u->n++; + is_added = 1; + } + } + if (is_added) { // x has been added to u->array. fill the remaining variables + x->cpos[0] = x->cpos[1] = x->cpos[2] = x->cpos[3] = -1; + x->pj = p->pj; x->qk = p->qk; x->ql = p->ql; x->qlen = p->qlen; x->tlen = p->tlen + 1; + if (x->G > -heap[0]) { + heap[0] = -x->G; + ks_heapadjust(int, 0, heap_size, heap); + } + } + if ((x->G > opt->qr && x->G >= -heap[0]) || i < old_n) { // good node in u, or in v + if (p->cpos[0] == -1 || p->cpos[1] == -1 || p->cpos[2] == -1 || p->cpos[3] == -1) { + bwt_2occ4(query, p->qk - 1, p->ql, qcntk, qcntl); + for (qj = 0; qj != 4; ++qj) { // descend to the prefix trie + if (p->cpos[qj] != -1) continue; // this node will be visited later + k = query->L2[qj] + qcntk[qj] + 1; + l = query->L2[qj] + qcntl[qj]; + if (k > l) { p->cpos[qj] = -2; continue; } + x = push_array_p(v); + p = v->array + i; // p may not point to the correct position after realloc + x->G = x->I = x->D = MINUS_INF; + x->qk = k; x->ql = l; x->pj = qj; x->qlen = p->qlen + 1; x->ppos = i; x->tlen = p->tlen; + x->cpos[0] = x->cpos[1] = x->cpos[2] = x->cpos[3] = -1; + p->cpos[qj] = v->n++; + } // ~for(qj) + } // ~if(p->cpos[]) + } // ~if + } // ~for(i) + if (u->n) save_hits(target, opt->t, b->hits, u); + { // push u to the stack (or to the pending array) + uint32_t cnt, pos; + cnt = (uint32_t)kh_value(chash, iter); + pos = kh_value(chash, iter)>>32; + if (pos) { // something in the pending array, then merge + bsw2entry_t *w = kv_A(stack->pending, pos-1); + if (u->n) { + if (w->n < u->n) { // swap + w = u; u = kv_A(stack->pending, pos-1); kv_A(stack->pending, pos-1) = w; + } + merge_entry(opt, w, u, b); + } + if (cnt == 0) { // move from pending to stack0 + remove_duplicate(w, rhash); + save_narrow_hits(target, w, b1, opt->t, opt->is); + cut_tail(w, opt->z, u); + stack_push0(stack, w); + kv_A(stack->pending, pos-1) = 0; + --stack->n_pending; + } + mp_free(stack->pool, u); + } else if (cnt) { // the first time + if (u->n) { // push to the pending queue + ++stack->n_pending; + kv_push(bsw2entry_p, stack->pending, u); + kh_value(chash, iter) = (uint64_t)kv_size(stack->pending)<<32 | cnt; + } else mp_free(stack->pool, u); + } else { // cnt == 0, then push to the stack + bsw2entry_t *w = mp_alloc(stack->pool); + save_narrow_hits(target, u, b1, opt->t, opt->is); + cut_tail(u, opt->z, w); + mp_free(stack->pool, w); + stack_push0(stack, u); + } + } + } // ~for(tj) + mp_free(stack->pool, v); + } // while(top) + getrusage(0, &curr); + bsw2_resolve_duphits(query, b, opt->is); + bsw2_resolve_duphits(query, b1, opt->is); + //fprintf(stderr, "stats: %.3lf sec; %d elems\n", time_elapse(&curr, &last), n_tot); + // free + free(heap); + kh_destroy(64, rhash); + kh_destroy(64, chash); + stack->pending.n = stack->stack0.n = 0; + return b_ret; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/bwtsw2_main.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,93 @@ +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <math.h> +#include "bwt.h" +#include "bwtsw2.h" + +int bwa_bwtsw2(int argc, char *argv[]) +{ + bsw2opt_t *opt; + bwt_t *target[2]; + char buf[1024]; + bntseq_t *bns; + int c; + + opt = bsw2_init_opt(); + srand48(11); + while ((c = getopt(argc, argv, "q:r:a:b:t:T:w:d:z:m:y:s:c:N:H:f:")) >= 0) { + switch (c) { + case 'q': opt->q = atoi(optarg); break; + case 'r': opt->r = atoi(optarg); break; + case 'a': opt->a = atoi(optarg); break; + case 'b': opt->b = atoi(optarg); break; + case 'w': opt->bw = atoi(optarg); break; + case 'T': opt->t = atoi(optarg); break; + case 't': opt->n_threads = atoi(optarg); break; + case 'z': opt->z = atoi(optarg); break; + case 'y': opt->yita = atof(optarg); break; + case 's': opt->is = atoi(optarg); break; + case 'm': opt->mask_level = atof(optarg); break; + case 'c': opt->coef = atof(optarg); break; + case 'N': opt->t_seeds = atoi(optarg); break; + case 'H': opt->hard_clip = 1; break; + case 'f': freopen(optarg, "w", stdout); + } + } + opt->qr = opt->q + opt->r; + + if (optind + 2 > argc) { + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: bwa bwasw [options] <target.prefix> <query.fa>\n\n"); + fprintf(stderr, "Options: -a INT score for a match [%d]\n", opt->a); + fprintf(stderr, " -b INT mismatch penalty [%d]\n", opt->b); + fprintf(stderr, " -q INT gap open penalty [%d]\n", opt->q); + fprintf(stderr, " -r INT gap extension penalty [%d]\n", opt->r); +// fprintf(stderr, " -y FLOAT error recurrence coef. (4..16) [%.1f]\n", opt->yita); + fprintf(stderr, "\n"); + fprintf(stderr, " -t INT nmber of threads [%d]\n", opt->n_threads); + fprintf(stderr, " -s INT size of a chunk of reads [%d]\n", opt->chunk_size); + fprintf(stderr, "\n"); + fprintf(stderr, " -w INT band width [%d]\n", opt->bw); + fprintf(stderr, " -m FLOAT mask level [%.2f]\n", opt->mask_level); + fprintf(stderr, "\n"); + fprintf(stderr, " -T INT score threshold divided by a [%d]\n", opt->t); + fprintf(stderr, " -s INT maximum seeding interval size [%d]\n", opt->is); + fprintf(stderr, " -z INT Z-best [%d]\n", opt->z); + fprintf(stderr, " -N INT # seeds to trigger reverse alignment [%d]\n", opt->t_seeds); + fprintf(stderr, " -c FLOAT coefficient of length-threshold adjustment [%.1f]\n", opt->coef); + fprintf(stderr, " -H in SAM output, use hard clipping rather than soft\n"); + fprintf(stderr, " -f FILE file to output results to instead of stdout\n"); + fprintf(stderr, "\n"); + + { + double c, theta, eps, delta; + c = opt->a / log(opt->yita); + theta = exp(-opt->b / c) / opt->yita; + eps = exp(-opt->q / c); + delta = exp(-opt->r / c); + fprintf(stderr, "mismatch: %lf, gap_open: %lf, gap_ext: %lf\n\n", + theta, eps, delta); + } + return 1; + } + + // adjust opt for opt->a + opt->t *= opt->a; + opt->coef *= opt->a; + + strcpy(buf, argv[optind]); target[0] = bwt_restore_bwt(strcat(buf, ".bwt")); + strcpy(buf, argv[optind]); bwt_restore_sa(strcat(buf, ".sa"), target[0]); + strcpy(buf, argv[optind]); target[1] = bwt_restore_bwt(strcat(buf, ".rbwt")); + strcpy(buf, argv[optind]); bwt_restore_sa(strcat(buf, ".rsa"), target[1]); + bns = bns_restore(argv[optind]); + + bsw2_aln(opt, bns, target, argv[optind+1]); + + bns_destroy(bns); + bwt_destroy(target[0]); bwt_destroy(target[1]); + free(opt); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/cleanup.sh Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,1 @@ +rm -fr autom4te.cache Makefile.in depcomp configure config.guess config.sub missing aclocal.m4 install-sh bwt_gen/Makefile.in \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/config.h.in Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,157 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +#undef HAVE_DOPRNT + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `m' library (-lm). */ +#undef HAVE_LIBM + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +#undef HAVE_LIBPTHREAD + +/* Define to 1 if you have the `z' library (-lz). */ +#undef HAVE_LIBZ + +/* Define to 1 if you have the <limits.h> header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if your system has a GNU libc compatible `malloc' function, and + to 0 otherwise. */ +#undef HAVE_MALLOC + +/* Define to 1 if you have the `memmove' function. */ +#undef HAVE_MEMMOVE + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `memset' function. */ +#undef HAVE_MEMSET + +/* Define if you have POSIX threads libraries and header files. */ +#undef HAVE_PTHREAD + +/* Define to 1 if your system has a GNU libc compatible `realloc' function, + and to 0 otherwise. */ +#undef HAVE_REALLOC + +/* Define to 1 if you have the `sqrt' function. */ +#undef HAVE_SQRT + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strstr' function. */ +#undef HAVE_STRSTR + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vprintf' function. */ +#undef HAVE_VPRINTF + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +#undef PTHREAD_CREATE_JOINABLE + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>, + <pthread.h>, or <semaphore.h> is not used. If the typedef was allowed, the + #define below would cause a syntax error. */ +#undef _UINT32_T + +/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>, + <pthread.h>, or <semaphore.h> is not used. If the typedef was allowed, the + #define below would cause a syntax error. */ +#undef _UINT64_T + +/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>, + <pthread.h>, or <semaphore.h> is not used. If the typedef was allowed, the + #define below would cause a syntax error. */ +#undef _UINT8_T + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to the type of a signed integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +#undef int32_t + +/* Define to the type of a signed integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +#undef int64_t + +/* Define to rpl_malloc if the replacement function should be used. */ +#undef malloc + +/* Define to rpl_realloc if the replacement function should be used. */ +#undef realloc + +/* Define to `unsigned int' if <sys/types.h> does not define. */ +#undef size_t + +/* Define to the type of an unsigned integer type of width exactly 16 bits if + such a type exists and the standard includes do not define it. */ +#undef uint16_t + +/* Define to the type of an unsigned integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +#undef uint32_t + +/* Define to the type of an unsigned integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +#undef uint64_t + +/* Define to the type of an unsigned integer type of width exactly 8 bits if + such a type exists and the standard includes do not define it. */ +#undef uint8_t
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/configure.in Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,49 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.61) +AC_INIT([bwa], [0.5.5]) +AC_CONFIG_SRCDIR([bntseq.c]) +AC_CONFIG_HEADER([config.h]) +AC_CONFIG_MACRO_DIR([m4]) +AM_INIT_AUTOMAKE() + +# Checks for programs. +AC_PROG_CC([gcc]) +AC_PROG_CXX([g++]) +AC_PROG_INSTALL +AC_PROG_AWK +AC_PROG_MKDIR_P +AC_PROG_RANLIB + +# Checks for libraries. + +# Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS([limits.h stdint.h stdlib.h string.h unistd.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE +AC_TYPE_INT32_T +AC_TYPE_INT64_T +AC_TYPE_SIZE_T +AC_TYPE_UINT16_T +AC_TYPE_UINT32_T +AC_TYPE_UINT64_T +AC_TYPE_UINT8_T + +# Checks for library functions. +AC_FUNC_MALLOC +AC_FUNC_REALLOC +AC_FUNC_VPRINTF +AC_CHECK_FUNCS([memmove memset sqrt strdup strstr]) +AC_CHECK_LIB([m],[log]) +AC_CHECK_LIB([z],[gzopen]) +AC_CHECK_LIB([pthread],[pthread_create]) + +ACX_PTHREAD + +AC_CONFIG_FILES([Makefile + bwt_gen/Makefile]) +AC_OUTPUT
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/cs2nt.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,191 @@ +#include <string.h> +#include <stdint.h> +#include <stdlib.h> +#include "bwtaln.h" +#include "stdaln.h" + +/* + Here is a delicate example. ref_nt=ATTAAC(RBRBG), read_cs=RBBOG. If we + decode as ATTGAC(RBGOG), there are one color change and one nt change; + if we decode as ATTAAC(RBRBG), there are two color changes. + + In DP, if color quality is smaller than COLOR_MM, we will use COLOR_MM + as the penalty; otherwise, we will use color quality as the + penalty. This means we always prefer two consistent color changes over + a nt change, but if a color has high quality, we may prefer one nt + change. + + In the above example, the penalties of the two types of decoding are + q(B)+25 and q(B)+q(O), respectively. If q(O)>25, we prefer the first; + otherwise the second. Note that no matter what we choose, the fourth + base will get a low nt quality. + */ + +#define COLOR_MM 19 +#define NUCL_MM 25 + +static const int nst_ntnt2cs_table[] = { 4, 0, 0, 1, 0, 2, 3, 4, 0, 3, 2, 4, 1, 4, 4, 4 }; + +/* + {A,C,G,T,N} -> {0,1,2,3,4} + nt_ref[0..size]: nucleotide reference: 0/1/2/3/4 + cs_read[0..size-1]: color read+qual sequence: base<<6|qual; qual==63 for N + nt_read[0..size]: nucleotide read sequence: 0/1/2/3 (returned) + btarray[0..4*size]: backtrack array (working space) + */ +void cs2nt_DP(int size, const uint8_t *nt_ref, const uint8_t *cs_read, uint8_t *nt_read, uint8_t *btarray) +{ + int h[8], curr, last; + int x, y, xmin, hmin, k; + + // h[0..3] and h[4..7] are the current and last best score array, depending on curr and last + + // recursion: initial value + if (nt_ref[0] >= 4) memset(h, 0, sizeof(int) << 2); + else { + for (x = 0; x != 4; ++x) h[x] = NUCL_MM; + h[nt_ref[0]] = 0; + } + // recursion: main loop + curr = 1; last = 0; + for (k = 1; k <= size; ++k) { + for (x = 0; x != 4; ++x) { + int min = 0x7fffffff, ymin = 0; + for (y = 0; y != 4; ++y) { + int s = h[last<<2|y]; + if ((cs_read[k-1]&0x3f) != 63 && cs_read[k-1]>>6 != nst_ntnt2cs_table[1<<x|1<<y]) + s += ((cs_read[k-1]&0x3f) < COLOR_MM)? COLOR_MM : (cs_read[k-1]&0x3f); // color mismatch + if (nt_ref[k] < 4 && nt_ref[k] != x) s += NUCL_MM; // nt mismatch + if (s < min) { + min = s; ymin = y; + } + } + h[curr<<2|x] = min; btarray[k<<2|x] = ymin; + } + last = curr; curr = 1 - curr; // swap + } + // back trace + hmin = 0x7fffffff; xmin = 0; + for (x = 0; x != 4; ++x) { + if (h[last<<2|x] < hmin) { + hmin = h[last<<2|x]; xmin = x; + } + } + nt_read[size] = xmin; + for (k = size - 1; k >= 0; --k) + nt_read[k] = btarray[(k+1)<<2 | nt_read[k+1]]; +} +/* + nt_read[0..size]: nucleotide read sequence: 0/1/2/3 + cs_read[0..size-1]: color read+qual sequence: base<<6|qual; qual==63 for N + tarray[0..size*2-1]: temporary array + */ +uint8_t *cs2nt_nt_qual(int size, const uint8_t *nt_read, const uint8_t *cs_read, uint8_t *tarray) +{ + int k, c1, c2; + uint8_t *t2array = tarray + size; + // get the color sequence of nt_read + c1 = nt_read[0]; + for (k = 1; k <= size; ++k) { + c2 = nt_read[k]; // in principle, there is no 'N' in nt_read[]; just in case + tarray[k-1] = (c1 >= 4 || c2 >= 4)? 4 : nst_ntnt2cs_table[1<<c1 | 1<<c2]; + c1 = c2; + } + for (k = 1; k != size; ++k) { + int q = 0; + if (tarray[k-1] == cs_read[k-1]>>6 && tarray[k] == cs_read[k]>>6) { + q = (int)(cs_read[k-1]&0x3f) + (int)(cs_read[k]&0x3f) + 10; + } else if (tarray[k-1] == cs_read[k-1]>>6) { + q = (int)(cs_read[k-1]&0x3f) - (int)(cs_read[k]&0x3f); + } else if (tarray[k] == cs_read[k]>>6) { + q = (int)(cs_read[k]&0x3f) - (int)(cs_read[k-1]&0x3f); + } // else, q = 0 + if (q < 0) q = 0; + if (q > 60) q = 60; + t2array[k] = nt_read[k]<<6 | q; + if ((cs_read[k-1]&0x3f) == 63 || (cs_read[k]&0x3f) == 63) t2array[k] = 0; + } + return t2array + 1; // of size-2 +} + +// this function will be called when p->seq has been reversed by refine_gapped() +void bwa_cs2nt_core(bwa_seq_t *p, bwtint_t l_pac, ubyte_t *pac) +{ + uint8_t *ta, *nt_read, *btarray, *tarray, *nt_ref, *cs_read, *new_nt_read; + int i, len; + uint8_t *seq; + + // set temporary arrays + if (p->type == BWA_TYPE_NO_MATCH) return; + len = p->len + p->n_gapo + p->n_gape + 100; // leave enough space + ta = (uint8_t*)malloc(len * 7); + nt_ref = ta; + cs_read = nt_ref + len; + nt_read = cs_read + len; + btarray = nt_read + len; + tarray = nt_read + len; + +#define __gen_csbase(_cs, _i, _seq) do { \ + int q = p->qual[p->strand? p->len - 1 - (_i) : (_i)] - 33; \ + if (q > 60) q = 60; \ + if (_seq[_i] > 3) q = 63; \ + (_cs) = _seq[_i]<<6 | q; \ + } while (0) + + // generate len, nt_ref[] and cs_read + seq = p->strand? p->rseq : p->seq; + nt_ref[0] = p->pos? bns_pac(pac, p->pos-1) : 4; + if (p->cigar == 0) { // no gap or clipping + len = p->len; + for (i = 0; i < p->len; ++i) { + __gen_csbase(cs_read[i], i, seq); + nt_ref[i+1] = bns_pac(pac, p->pos + i); + } + } else { + int k, z; + bwtint_t x, y; + x = p->pos; y = 0; + for (k = z = 0; k < p->n_cigar; ++k) { + int l = __cigar_len(p->cigar[k]); + if (__cigar_op(p->cigar[k]) == FROM_M) { + for (i = 0; i < l; ++i, ++x, ++y) { + __gen_csbase(cs_read[z], y, seq); + nt_ref[z+1] = bns_pac(pac, x); + ++z; + } + } else if (__cigar_op(p->cigar[k]) == FROM_I) { + for (i = 0; i < l; ++i, ++y) { + __gen_csbase(cs_read[z], y, seq); + nt_ref[z+1] = 4; + ++z; + } + } else if (__cigar_op(p->cigar[k]) == FROM_S) y += l; + else x += l; + } + len = z; + } + + cs2nt_DP(len, nt_ref, cs_read, nt_read, btarray); + new_nt_read = cs2nt_nt_qual(len, nt_read, cs_read, tarray); + + // update p + p->len = p->full_len = len - 1; + for (i = 0; i < p->len; ++i) { + if ((new_nt_read[i]&0x3f) == 63) { + p->qual[i] = 33; seq[i] = 4; + } else { + p->qual[i] = (new_nt_read[i]&0x3f) + 33; + seq[i] = new_nt_read[i]>>6; + } + } + p->qual[p->len] = seq[p->len] = 0; + if (p->strand) { + memcpy(p->seq, seq, p->len); + seq_reverse(p->len, p->seq, 1); + seq_reverse(p->len, p->qual, 0); + } else { + memcpy(p->rseq, seq, p->len); + seq_reverse(p->len, p->rseq, 1); + } + free(ta); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/is.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,218 @@ +/* + * sais.c for sais-lite + * Copyright (c) 2008 Yuta Mori All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <stdlib.h> + +typedef unsigned char ubyte_t; +#define chr(i) (cs == sizeof(int) ? ((const int *)T)[i]:((const unsigned char *)T)[i]) + +/* find the start or end of each bucket */ +static void getCounts(const unsigned char *T, int *C, int n, int k, int cs) +{ + int i; + for (i = 0; i < k; ++i) C[i] = 0; + for (i = 0; i < n; ++i) ++C[chr(i)]; +} +static void getBuckets(const int *C, int *B, int k, int end) +{ + int i, sum = 0; + if (end) { + for (i = 0; i < k; ++i) { + sum += C[i]; + B[i] = sum; + } + } else { + for (i = 0; i < k; ++i) { + sum += C[i]; + B[i] = sum - C[i]; + } + } +} + +/* compute SA */ +static void induceSA(const unsigned char *T, int *SA, int *C, int *B, int n, int k, int cs) +{ + int *b, i, j; + int c0, c1; + /* compute SAl */ + if (C == B) getCounts(T, C, n, k, cs); + getBuckets(C, B, k, 0); /* find starts of buckets */ + j = n - 1; + b = SA + B[c1 = chr(j)]; + *b++ = ((0 < j) && (chr(j - 1) < c1)) ? ~j : j; + for (i = 0; i < n; ++i) { + j = SA[i], SA[i] = ~j; + if (0 < j) { + --j; + if ((c0 = chr(j)) != c1) { + B[c1] = b - SA; + b = SA + B[c1 = c0]; + } + *b++ = ((0 < j) && (chr(j - 1) < c1)) ? ~j : j; + } + } + /* compute SAs */ + if (C == B) getCounts(T, C, n, k, cs); + getBuckets(C, B, k, 1); /* find ends of buckets */ + for (i = n - 1, b = SA + B[c1 = 0]; 0 <= i; --i) { + if (0 < (j = SA[i])) { + --j; + if ((c0 = chr(j)) != c1) { + B[c1] = b - SA; + b = SA + B[c1 = c0]; + } + *--b = ((j == 0) || (chr(j - 1) > c1)) ? ~j : j; + } else SA[i] = ~j; + } +} + +/* + * find the suffix array SA of T[0..n-1] in {0..k-1}^n use a working + * space (excluding T and SA) of at most 2n+O(1) for a constant alphabet + */ +static int sais_main(const unsigned char *T, int *SA, int fs, int n, int k, int cs) +{ + int *C, *B, *RA; + int i, j, c, m, p, q, plen, qlen, name; + int c0, c1; + int diff; + + /* stage 1: reduce the problem by at least 1/2 sort all the + * S-substrings */ + if (k <= fs) { + C = SA + n; + B = (k <= (fs - k)) ? C + k : C; + } else if ((C = B = (int *) malloc(k * sizeof(int))) == NULL) return -2; + getCounts(T, C, n, k, cs); + getBuckets(C, B, k, 1); /* find ends of buckets */ + for (i = 0; i < n; ++i) SA[i] = 0; + for (i = n - 2, c = 0, c1 = chr(n - 1); 0 <= i; --i, c1 = c0) { + if ((c0 = chr(i)) < (c1 + c)) c = 1; + else if (c != 0) SA[--B[c1]] = i + 1, c = 0; + } + induceSA(T, SA, C, B, n, k, cs); + if (fs < k) free(C); + /* compact all the sorted substrings into the first m items of SA + * 2*m must be not larger than n (proveable) */ + for (i = 0, m = 0; i < n; ++i) { + p = SA[i]; + if ((0 < p) && (chr(p - 1) > (c0 = chr(p)))) { + for (j = p + 1; (j < n) && (c0 == (c1 = chr(j))); ++j); + if ((j < n) && (c0 < c1)) SA[m++] = p; + } + } + for (i = m; i < n; ++i) SA[i] = 0; /* init the name array buffer */ + /* store the length of all substrings */ + for (i = n - 2, j = n, c = 0, c1 = chr(n - 1); 0 <= i; --i, c1 = c0) { + if ((c0 = chr(i)) < (c1 + c)) c = 1; + else if (c != 0) { + SA[m + ((i + 1) >> 1)] = j - i - 1; + j = i + 1; + c = 0; + } + } + /* find the lexicographic names of all substrings */ + for (i = 0, name = 0, q = n, qlen = 0; i < m; ++i) { + p = SA[i], plen = SA[m + (p >> 1)], diff = 1; + if (plen == qlen) { + for (j = 0; (j < plen) && (chr(p + j) == chr(q + j)); j++); + if (j == plen) diff = 0; + } + if (diff != 0) ++name, q = p, qlen = plen; + SA[m + (p >> 1)] = name; + } + + /* stage 2: solve the reduced problem recurse if names are not yet + * unique */ + if (name < m) { + RA = SA + n + fs - m; + for (i = n - 1, j = m - 1; m <= i; --i) { + if (SA[i] != 0) RA[j--] = SA[i] - 1; + } + if (sais_main((unsigned char *) RA, SA, fs + n - m * 2, m, name, sizeof(int)) != 0) return -2; + for (i = n - 2, j = m - 1, c = 0, c1 = chr(n - 1); 0 <= i; --i, c1 = c0) { + if ((c0 = chr(i)) < (c1 + c)) c = 1; + else if (c != 0) RA[j--] = i + 1, c = 0; /* get p1 */ + } + for (i = 0; i < m; ++i) SA[i] = RA[SA[i]]; /* get index */ + } + /* stage 3: induce the result for the original problem */ + if (k <= fs) { + C = SA + n; + B = (k <= (fs - k)) ? C + k : C; + } else if ((C = B = (int *) malloc(k * sizeof(int))) == NULL) return -2; + /* put all left-most S characters into their buckets */ + getCounts(T, C, n, k, cs); + getBuckets(C, B, k, 1); /* find ends of buckets */ + for (i = m; i < n; ++i) SA[i] = 0; /* init SA[m..n-1] */ + for (i = m - 1; 0 <= i; --i) { + j = SA[i], SA[i] = 0; + SA[--B[chr(j)]] = j; + } + induceSA(T, SA, C, B, n, k, cs); + if (fs < k) free(C); + return 0; +} + +/** + * Constructs the suffix array of a given string. + * @param T[0..n-1] The input string. + * @param SA[0..n] The output array of suffixes. + * @param n The length of the given string. + * @return 0 if no error occurred + */ +int is_sa(const ubyte_t *T, int *SA, int n) +{ + if ((T == NULL) || (SA == NULL) || (n < 0)) return -1; + SA[0] = n; + if (n <= 1) { + if (n == 1) SA[1] = 0; + return 0; + } + return sais_main(T, SA+1, 0, n, 256, 1); +} + +/** + * Constructs the burrows-wheeler transformed string of a given string. + * @param T[0..n-1] The input string. + * @param n The length of the given string. + * @return The primary index if no error occurred, -1 or -2 otherwise. + */ +int is_bwt(ubyte_t *T, int n) +{ + int *SA, i, primary = 0; + SA = (int*)calloc(n+1, sizeof(int)); + is_sa(T, SA, n); + + for (i = 0; i <= n; ++i) { + if (SA[i] == 0) primary = i; + else SA[i] = T[SA[i] - 1]; + } + for (i = 0; i < primary; ++i) T[i] = SA[i]; + for (; i < n; ++i) T[i] = SA[i + 1]; + free(SA); + return primary; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/khash.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,506 @@ +/* The MIT License + + Copyright (c) 2008, 2009 by attractor <attractor@live.co.uk> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* + An example: + +#include "khash.h" +KHASH_MAP_INIT_INT(32, char) +int main() { + int ret, is_missing; + khiter_t k; + khash_t(32) *h = kh_init(32); + k = kh_put(32, h, 5, &ret); + if (!ret) kh_del(32, h, k); + kh_value(h, k) = 10; + k = kh_get(32, h, 10); + is_missing = (k == kh_end(h)); + k = kh_get(32, h, 5); + kh_del(32, h, k); + for (k = kh_begin(h); k != kh_end(h); ++k) + if (kh_exist(h, k)) kh_value(h, k) = 1; + kh_destroy(32, h); + return 0; +} +*/ + +/* + 2009-09-26 (0.2.4): + + * Improve portability + + 2008-09-19 (0.2.3): + + * Corrected the example + * Improved interfaces + + 2008-09-11 (0.2.2): + + * Improved speed a little in kh_put() + + 2008-09-10 (0.2.1): + + * Added kh_clear() + * Fixed a compiling error + + 2008-09-02 (0.2.0): + + * Changed to token concatenation which increases flexibility. + + 2008-08-31 (0.1.2): + + * Fixed a bug in kh_get(), which has not been tested previously. + + 2008-08-31 (0.1.1): + + * Added destructor +*/ + + +#ifndef __AC_KHASH_H +#define __AC_KHASH_H + +/*! + @header + + Generic hash table library. + + @copyright Heng Li + */ + +#define AC_VERSION_KHASH_H "0.2.4" + +#include <stdlib.h> +#include <string.h> +#include <limits.h> + +/* compipler specific configuration */ + +#if UINT_MAX == 0xffffffffu +typedef unsigned int khint32_t; +#elif ULONG_MAX == 0xffffffffu +typedef unsigned long khint32_t; +#endif + +#if ULONG_MAX == ULLONG_MAX +typedef unsigned long khint64_t; +#else +typedef unsigned long long khint64_t; +#endif + +#ifdef _MSC_VER +#define inline __inline +#endif + +typedef khint32_t khint_t; +typedef khint_t khiter_t; + +#define __ac_HASH_PRIME_SIZE 32 +static const khint32_t __ac_prime_list[__ac_HASH_PRIME_SIZE] = +{ + 0ul, 3ul, 11ul, 23ul, 53ul, + 97ul, 193ul, 389ul, 769ul, 1543ul, + 3079ul, 6151ul, 12289ul, 24593ul, 49157ul, + 98317ul, 196613ul, 393241ul, 786433ul, 1572869ul, + 3145739ul, 6291469ul, 12582917ul, 25165843ul, 50331653ul, + 100663319ul, 201326611ul, 402653189ul, 805306457ul, 1610612741ul, + 3221225473ul, 4294967291ul +}; + +#define __ac_isempty(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&2) +#define __ac_isdel(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&1) +#define __ac_iseither(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&3) +#define __ac_set_isdel_false(flag, i) (flag[i>>4]&=~(1ul<<((i&0xfU)<<1))) +#define __ac_set_isempty_false(flag, i) (flag[i>>4]&=~(2ul<<((i&0xfU)<<1))) +#define __ac_set_isboth_false(flag, i) (flag[i>>4]&=~(3ul<<((i&0xfU)<<1))) +#define __ac_set_isdel_true(flag, i) (flag[i>>4]|=1ul<<((i&0xfU)<<1)) + +static const double __ac_HASH_UPPER = 0.77; + +#define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ + typedef struct { \ + khint_t n_buckets, size, n_occupied, upper_bound; \ + khint32_t *flags; \ + khkey_t *keys; \ + khval_t *vals; \ + } kh_##name##_t; \ + static inline kh_##name##_t *kh_init_##name() { \ + return (kh_##name##_t*)calloc(1, sizeof(kh_##name##_t)); \ + } \ + static inline void kh_destroy_##name(kh_##name##_t *h) \ + { \ + if (h) { \ + free(h->keys); free(h->flags); \ + free(h->vals); \ + free(h); \ + } \ + } \ + static inline void kh_clear_##name(kh_##name##_t *h) \ + { \ + if (h && h->flags) { \ + memset(h->flags, 0xaa, ((h->n_buckets>>4) + 1) * sizeof(khint32_t)); \ + h->size = h->n_occupied = 0; \ + } \ + } \ + static inline khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \ + { \ + if (h->n_buckets) { \ + khint_t inc, k, i, last; \ + k = __hash_func(key); i = k % h->n_buckets; \ + inc = 1 + k % (h->n_buckets - 1); last = i; \ + while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \ + if (i + inc >= h->n_buckets) i = i + inc - h->n_buckets; \ + else i += inc; \ + if (i == last) return h->n_buckets; \ + } \ + return __ac_iseither(h->flags, i)? h->n_buckets : i; \ + } else return 0; \ + } \ + static inline void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \ + { \ + khint32_t *new_flags = 0; \ + khint_t j = 1; \ + { \ + khint_t t = __ac_HASH_PRIME_SIZE - 1; \ + while (__ac_prime_list[t] > new_n_buckets) --t; \ + new_n_buckets = __ac_prime_list[t+1]; \ + if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) j = 0; \ + else { \ + new_flags = (khint32_t*)malloc(((new_n_buckets>>4) + 1) * sizeof(khint32_t)); \ + memset(new_flags, 0xaa, ((new_n_buckets>>4) + 1) * sizeof(khint32_t)); \ + if (h->n_buckets < new_n_buckets) { \ + h->keys = (khkey_t*)realloc(h->keys, new_n_buckets * sizeof(khkey_t)); \ + if (kh_is_map) \ + h->vals = (khval_t*)realloc(h->vals, new_n_buckets * sizeof(khval_t)); \ + } \ + } \ + } \ + if (j) { \ + for (j = 0; j != h->n_buckets; ++j) { \ + if (__ac_iseither(h->flags, j) == 0) { \ + khkey_t key = h->keys[j]; \ + khval_t val; \ + if (kh_is_map) val = h->vals[j]; \ + __ac_set_isdel_true(h->flags, j); \ + while (1) { \ + khint_t inc, k, i; \ + k = __hash_func(key); \ + i = k % new_n_buckets; \ + inc = 1 + k % (new_n_buckets - 1); \ + while (!__ac_isempty(new_flags, i)) { \ + if (i + inc >= new_n_buckets) i = i + inc - new_n_buckets; \ + else i += inc; \ + } \ + __ac_set_isempty_false(new_flags, i); \ + if (i < h->n_buckets && __ac_iseither(h->flags, i) == 0) { \ + { khkey_t tmp = h->keys[i]; h->keys[i] = key; key = tmp; } \ + if (kh_is_map) { khval_t tmp = h->vals[i]; h->vals[i] = val; val = tmp; } \ + __ac_set_isdel_true(h->flags, i); \ + } else { \ + h->keys[i] = key; \ + if (kh_is_map) h->vals[i] = val; \ + break; \ + } \ + } \ + } \ + } \ + if (h->n_buckets > new_n_buckets) { \ + h->keys = (khkey_t*)realloc(h->keys, new_n_buckets * sizeof(khkey_t)); \ + if (kh_is_map) \ + h->vals = (khval_t*)realloc(h->vals, new_n_buckets * sizeof(khval_t)); \ + } \ + free(h->flags); \ + h->flags = new_flags; \ + h->n_buckets = new_n_buckets; \ + h->n_occupied = h->size; \ + h->upper_bound = (khint_t)(h->n_buckets * __ac_HASH_UPPER + 0.5); \ + } \ + } \ + static inline khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \ + { \ + khint_t x; \ + if (h->n_occupied >= h->upper_bound) { \ + if (h->n_buckets > (h->size<<1)) kh_resize_##name(h, h->n_buckets - 1); \ + else kh_resize_##name(h, h->n_buckets + 1); \ + } \ + { \ + khint_t inc, k, i, site, last; \ + x = site = h->n_buckets; k = __hash_func(key); i = k % h->n_buckets; \ + if (__ac_isempty(h->flags, i)) x = i; \ + else { \ + inc = 1 + k % (h->n_buckets - 1); last = i; \ + while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \ + if (__ac_isdel(h->flags, i)) site = i; \ + if (i + inc >= h->n_buckets) i = i + inc - h->n_buckets; \ + else i += inc; \ + if (i == last) { x = site; break; } \ + } \ + if (x == h->n_buckets) { \ + if (__ac_isempty(h->flags, i) && site != h->n_buckets) x = site; \ + else x = i; \ + } \ + } \ + } \ + if (__ac_isempty(h->flags, x)) { \ + h->keys[x] = key; \ + __ac_set_isboth_false(h->flags, x); \ + ++h->size; ++h->n_occupied; \ + *ret = 1; \ + } else if (__ac_isdel(h->flags, x)) { \ + h->keys[x] = key; \ + __ac_set_isboth_false(h->flags, x); \ + ++h->size; \ + *ret = 2; \ + } else *ret = 0; \ + return x; \ + } \ + static inline void kh_del_##name(kh_##name##_t *h, khint_t x) \ + { \ + if (x != h->n_buckets && !__ac_iseither(h->flags, x)) { \ + __ac_set_isdel_true(h->flags, x); \ + --h->size; \ + } \ + } + +/* --- BEGIN OF HASH FUNCTIONS --- */ + +/*! @function + @abstract Integer hash function + @param key The integer [khint32_t] + @return The hash value [khint_t] + */ +#define kh_int_hash_func(key) (khint32_t)(key) +/*! @function + @abstract Integer comparison function + */ +#define kh_int_hash_equal(a, b) ((a) == (b)) +/*! @function + @abstract 64-bit integer hash function + @param key The integer [khint64_t] + @return The hash value [khint_t] + */ +#define kh_int64_hash_func(key) (khint32_t)((key)>>33^(key)^(key)<<11) +/*! @function + @abstract 64-bit integer comparison function + */ +#define kh_int64_hash_equal(a, b) ((a) == (b)) +/*! @function + @abstract const char* hash function + @param s Pointer to a null terminated string + @return The hash value + */ +static inline khint_t __ac_X31_hash_string(const char *s) +{ + khint_t h = *s; + if (h) for (++s ; *s; ++s) h = (h << 5) - h + *s; + return h; +} +/*! @function + @abstract Another interface to const char* hash function + @param key Pointer to a null terminated string [const char*] + @return The hash value [khint_t] + */ +#define kh_str_hash_func(key) __ac_X31_hash_string(key) +/*! @function + @abstract Const char* comparison function + */ +#define kh_str_hash_equal(a, b) (strcmp(a, b) == 0) + +/* --- END OF HASH FUNCTIONS --- */ + +/* Other necessary macros... */ + +/*! + @abstract Type of the hash table. + @param name Name of the hash table [symbol] + */ +#define khash_t(name) kh_##name##_t + +/*! @function + @abstract Initiate a hash table. + @param name Name of the hash table [symbol] + @return Pointer to the hash table [khash_t(name)*] + */ +#define kh_init(name) kh_init_##name() + +/*! @function + @abstract Destroy a hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + */ +#define kh_destroy(name, h) kh_destroy_##name(h) + +/*! @function + @abstract Reset a hash table without deallocating memory. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + */ +#define kh_clear(name, h) kh_clear_##name(h) + +/*! @function + @abstract Resize a hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param s New size [khint_t] + */ +#define kh_resize(name, h, s) kh_resize_##name(h, s) + +/*! @function + @abstract Insert a key to the hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param k Key [type of keys] + @param r Extra return code: 0 if the key is present in the hash table; + 1 if the bucket is empty (never used); 2 if the element in + the bucket has been deleted [int*] + @return Iterator to the inserted element [khint_t] + */ +#define kh_put(name, h, k, r) kh_put_##name(h, k, r) + +/*! @function + @abstract Retrieve a key from the hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param k Key [type of keys] + @return Iterator to the found element, or kh_end(h) is the element is absent [khint_t] + */ +#define kh_get(name, h, k) kh_get_##name(h, k) + +/*! @function + @abstract Remove a key from the hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param k Iterator to the element to be deleted [khint_t] + */ +#define kh_del(name, h, k) kh_del_##name(h, k) + + +/*! @function + @abstract Test whether a bucket contains data. + @param h Pointer to the hash table [khash_t(name)*] + @param x Iterator to the bucket [khint_t] + @return 1 if containing data; 0 otherwise [int] + */ +#define kh_exist(h, x) (!__ac_iseither((h)->flags, (x))) + +/*! @function + @abstract Get key given an iterator + @param h Pointer to the hash table [khash_t(name)*] + @param x Iterator to the bucket [khint_t] + @return Key [type of keys] + */ +#define kh_key(h, x) ((h)->keys[x]) + +/*! @function + @abstract Get value given an iterator + @param h Pointer to the hash table [khash_t(name)*] + @param x Iterator to the bucket [khint_t] + @return Value [type of values] + @discussion For hash sets, calling this results in segfault. + */ +#define kh_val(h, x) ((h)->vals[x]) + +/*! @function + @abstract Alias of kh_val() + */ +#define kh_value(h, x) ((h)->vals[x]) + +/*! @function + @abstract Get the start iterator + @param h Pointer to the hash table [khash_t(name)*] + @return The start iterator [khint_t] + */ +#define kh_begin(h) (khint_t)(0) + +/*! @function + @abstract Get the end iterator + @param h Pointer to the hash table [khash_t(name)*] + @return The end iterator [khint_t] + */ +#define kh_end(h) ((h)->n_buckets) + +/*! @function + @abstract Get the number of elements in the hash table + @param h Pointer to the hash table [khash_t(name)*] + @return Number of elements in the hash table [khint_t] + */ +#define kh_size(h) ((h)->size) + +/*! @function + @abstract Get the number of buckets in the hash table + @param h Pointer to the hash table [khash_t(name)*] + @return Number of buckets in the hash table [khint_t] + */ +#define kh_n_buckets(h) ((h)->n_buckets) + +/* More conenient interfaces */ + +/*! @function + @abstract Instantiate a hash set containing integer keys + @param name Name of the hash table [symbol] + */ +#define KHASH_SET_INIT_INT(name) \ + KHASH_INIT(name, khint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal) + +/*! @function + @abstract Instantiate a hash map containing integer keys + @param name Name of the hash table [symbol] + @param khval_t Type of values [type] + */ +#define KHASH_MAP_INIT_INT(name, khval_t) \ + KHASH_INIT(name, khint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal) + +/*! @function + @abstract Instantiate a hash map containing 64-bit integer keys + @param name Name of the hash table [symbol] + */ +#define KHASH_SET_INIT_INT64(name) \ + KHASH_INIT(name, khint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal) + +/*! @function + @abstract Instantiate a hash map containing 64-bit integer keys + @param name Name of the hash table [symbol] + @param khval_t Type of values [type] + */ +#define KHASH_MAP_INIT_INT64(name, khval_t) \ + KHASH_INIT(name, khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal) + +typedef const char *kh_cstr_t; +/*! @function + @abstract Instantiate a hash map containing const char* keys + @param name Name of the hash table [symbol] + */ +#define KHASH_SET_INIT_STR(name) \ + KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal) + +/*! @function + @abstract Instantiate a hash map containing const char* keys + @param name Name of the hash table [symbol] + @param khval_t Type of values [type] + */ +#define KHASH_MAP_INIT_STR(name, khval_t) \ + KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal) + +#endif /* __AC_KHASH_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/kseq.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,208 @@ +/* The MIT License + + Copyright (c) 2008, by Heng Li <lh3@sanger.ac.uk> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#ifndef AC_KSEQ_H +#define AC_KSEQ_H + +#include <ctype.h> +#include <string.h> +#include <stdlib.h> + +#define __KS_TYPE(type_t) \ + typedef struct __kstream_t { \ + char *buf; \ + int begin, end, is_eof; \ + type_t f; \ + } kstream_t; + +#define ks_eof(ks) ((ks)->is_eof && (ks)->begin >= (ks)->end) +#define ks_rewind(ks) ((ks)->is_eof = (ks)->begin = (ks)->end = 0) + +#define __KS_BASIC(type_t, __bufsize) \ + static inline kstream_t *ks_init(type_t f) \ + { \ + kstream_t *ks = (kstream_t*)calloc(1, sizeof(kstream_t)); \ + ks->f = f; \ + ks->buf = (char*)malloc(__bufsize); \ + return ks; \ + } \ + static inline void ks_destroy(kstream_t *ks) \ + { \ + if (ks) { \ + free(ks->buf); \ + free(ks); \ + } \ + } + +#define __KS_GETC(__read, __bufsize) \ + static inline int ks_getc(kstream_t *ks) \ + { \ + if (ks->is_eof && ks->begin >= ks->end) return -1; \ + if (ks->begin >= ks->end) { \ + ks->begin = 0; \ + ks->end = __read(ks->f, ks->buf, __bufsize); \ + if (ks->end < __bufsize) ks->is_eof = 1; \ + if (ks->end == 0) return -1; \ + } \ + return (int)ks->buf[ks->begin++]; \ + } + +#ifndef KSTRING_T +#define KSTRING_T kstring_t +typedef struct __kstring_t { + size_t l, m; + char *s; +} kstring_t; +#endif + +#ifndef kroundup32 +#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) +#endif + +#define __KS_GETUNTIL(__read, __bufsize) \ + static int ks_getuntil(kstream_t *ks, int delimiter, kstring_t *str, int *dret) \ + { \ + if (dret) *dret = 0; \ + str->l = 0; \ + if (ks->begin >= ks->end && ks->is_eof) return -1; \ + for (;;) { \ + int i; \ + if (ks->begin >= ks->end) { \ + if (!ks->is_eof) { \ + ks->begin = 0; \ + ks->end = __read(ks->f, ks->buf, __bufsize); \ + if (ks->end < __bufsize) ks->is_eof = 1; \ + if (ks->end == 0) break; \ + } else break; \ + } \ + if (delimiter) { \ + for (i = ks->begin; i < ks->end; ++i) \ + if (ks->buf[i] == delimiter) break; \ + } else { \ + for (i = ks->begin; i < ks->end; ++i) \ + if (isspace(ks->buf[i])) break; \ + } \ + if (str->m - str->l < i - ks->begin + 1) { \ + str->m = str->l + (i - ks->begin) + 1; \ + kroundup32(str->m); \ + str->s = (char*)realloc(str->s, str->m); \ + } \ + memcpy(str->s + str->l, ks->buf + ks->begin, i - ks->begin); \ + str->l = str->l + (i - ks->begin); \ + ks->begin = i + 1; \ + if (i < ks->end) { \ + if (dret) *dret = ks->buf[i]; \ + break; \ + } \ + } \ + str->s[str->l] = '\0'; \ + return str->l; \ + } + +#define KSTREAM_INIT(type_t, __read, __bufsize) \ + __KS_TYPE(type_t) \ + __KS_BASIC(type_t, __bufsize) \ + __KS_GETC(__read, __bufsize) \ + __KS_GETUNTIL(__read, __bufsize) + +#define __KSEQ_BASIC(type_t) \ + static inline kseq_t *kseq_init(type_t fd) \ + { \ + kseq_t *s = (kseq_t*)calloc(1, sizeof(kseq_t)); \ + s->f = ks_init(fd); \ + return s; \ + } \ + static inline void kseq_rewind(kseq_t *ks) \ + { \ + ks->last_char = 0; \ + ks->f->is_eof = ks->f->begin = ks->f->end = 0; \ + } \ + static inline void kseq_destroy(kseq_t *ks) \ + { \ + if (!ks) return; \ + free(ks->name.s); free(ks->comment.s); free(ks->seq.s); free(ks->qual.s); \ + ks_destroy(ks->f); \ + free(ks); \ + } + +/* Return value: + >=0 length of the sequence (normal) + -1 end-of-file + -2 truncated quality string + */ +#define __KSEQ_READ \ + static int kseq_read(kseq_t *seq) \ + { \ + int c; \ + kstream_t *ks = seq->f; \ + if (seq->last_char == 0) { /* then jump to the next header line */ \ + while ((c = ks_getc(ks)) != -1 && c != '>' && c != '@'); \ + if (c == -1) return -1; /* end of file */ \ + seq->last_char = c; \ + } /* the first header char has been read */ \ + seq->comment.l = seq->seq.l = seq->qual.l = 0; \ + if (ks_getuntil(ks, 0, &seq->name, &c) < 0) return -1; \ + if (c != '\n') ks_getuntil(ks, '\n', &seq->comment, 0); \ + while ((c = ks_getc(ks)) != -1 && c != '>' && c != '+' && c != '@') { \ + if (isgraph(c)) { /* printable non-space character */ \ + if (seq->seq.l + 1 >= seq->seq.m) { /* double the memory */ \ + seq->seq.m = seq->seq.l + 2; \ + kroundup32(seq->seq.m); /* rounded to next closest 2^k */ \ + seq->seq.s = (char*)realloc(seq->seq.s, seq->seq.m); \ + } \ + seq->seq.s[seq->seq.l++] = (char)c; \ + } \ + } \ + if (c == '>' || c == '@') seq->last_char = c; /* the first header char has been read */ \ + seq->seq.s[seq->seq.l] = 0; /* null terminated string */ \ + if (c != '+') return seq->seq.l; /* FASTA */ \ + if (seq->qual.m < seq->seq.m) { /* allocate enough memory */ \ + seq->qual.m = seq->seq.m; \ + seq->qual.s = (char*)realloc(seq->qual.s, seq->qual.m); \ + } \ + while ((c = ks_getc(ks)) != -1 && c != '\n'); /* skip the rest of '+' line */ \ + if (c == -1) return -2; /* we should not stop here */ \ + while ((c = ks_getc(ks)) != -1 && seq->qual.l < seq->seq.l) \ + if (c >= 33 && c <= 127) seq->qual.s[seq->qual.l++] = (unsigned char)c; \ + seq->qual.s[seq->qual.l] = 0; /* null terminated string */ \ + seq->last_char = 0; /* we have not come to the next header line */ \ + if (seq->seq.l != seq->qual.l) return -2; /* qual string is shorter than seq string */ \ + return seq->seq.l; \ + } + +#define __KSEQ_TYPE(type_t) \ + typedef struct { \ + kstring_t name, comment, seq, qual; \ + int last_char; \ + kstream_t *f; \ + } kseq_t; + +#define KSEQ_INIT(type_t, __read) \ + KSTREAM_INIT(type_t, __read, 4096) \ + __KSEQ_TYPE(type_t) \ + __KSEQ_BASIC(type_t) \ + __KSEQ_READ + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/ksort.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,269 @@ +/* The MIT License + + Copyright (c) 2008, by Attractive Chaos <attractivechaos@aol.co.uk> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* + 2008-11-16 (0.1.4): + + * Fixed a bug in introsort() that happens in rare cases. + + 2008-11-05 (0.1.3): + + * Fixed a bug in introsort() for complex comparisons. + + * Fixed a bug in mergesort(). The previous version is not stable. + + 2008-09-15 (0.1.2): + + * Accelerated introsort. On my Mac (not on another Linux machine), + my implementation is as fast as std::sort on random input. + + * Added combsort and in introsort, switch to combsort if the + recursion is too deep. + + 2008-09-13 (0.1.1): + + * Added k-small algorithm + + 2008-09-05 (0.1.0): + + * Initial version + +*/ + +#ifndef AC_KSORT_H +#define AC_KSORT_H + +#include <stdlib.h> +#include <string.h> + +typedef struct { + void *left, *right; + int depth; +} ks_isort_stack_t; + +#define KSORT_SWAP(type_t, a, b) { register type_t t=(a); (a)=(b); (b)=t; } + +#define KSORT_INIT(name, type_t, __sort_lt) \ + void ks_mergesort_##name(size_t n, type_t array[], type_t temp[]) \ + { \ + type_t *a2[2], *a, *b; \ + int curr, shift; \ + \ + a2[0] = array; \ + a2[1] = temp? temp : (type_t*)malloc(sizeof(type_t) * n); \ + for (curr = 0, shift = 0; (1ul<<shift) < n; ++shift) { \ + a = a2[curr]; b = a2[1-curr]; \ + if (shift == 0) { \ + type_t *p = b, *i, *eb = a + n; \ + for (i = a; i < eb; i += 2) { \ + if (i == eb - 1) *p++ = *i; \ + else { \ + if (__sort_lt(*(i+1), *i)) { \ + *p++ = *(i+1); *p++ = *i; \ + } else { \ + *p++ = *i; *p++ = *(i+1); \ + } \ + } \ + } \ + } else { \ + size_t i, step = 1ul<<shift; \ + for (i = 0; i < n; i += step<<1) { \ + type_t *p, *j, *k, *ea, *eb; \ + if (n < i + step) { \ + ea = a + n; eb = a; \ + } else { \ + ea = a + i + step; \ + eb = a + (n < i + (step<<1)? n : i + (step<<1)); \ + } \ + j = a + i; k = a + i + step; p = b + i; \ + while (j < ea && k < eb) { \ + if (__sort_lt(*k, *j)) *p++ = *k++; \ + else *p++ = *j++; \ + } \ + while (j < ea) *p++ = *j++; \ + while (k < eb) *p++ = *k++; \ + } \ + } \ + curr = 1 - curr; \ + } \ + if (curr == 1) { \ + type_t *p = a2[0], *i = a2[1], *eb = array + n; \ + for (; p < eb; ++i) *p++ = *i; \ + } \ + if (temp == 0) free(a2[1]); \ + } \ + void ks_heapadjust_##name(size_t i, size_t n, type_t l[]) \ + { \ + size_t k = i; \ + type_t tmp = l[i]; \ + while ((k = (k << 1) + 1) < n) { \ + if (k != n - 1 && __sort_lt(l[k], l[k+1])) ++k; \ + if (__sort_lt(l[k], tmp)) break; \ + l[i] = l[k]; i = k; \ + } \ + l[i] = tmp; \ + } \ + void ks_heapmake_##name(size_t lsize, type_t l[]) \ + { \ + size_t i; \ + for (i = (lsize >> 1) - 1; i != (size_t)(-1); --i) \ + ks_heapadjust_##name(i, lsize, l); \ + } \ + void ks_heapsort_##name(size_t lsize, type_t l[]) \ + { \ + size_t i; \ + for (i = lsize - 1; i > 0; --i) { \ + type_t tmp; \ + tmp = *l; *l = l[i]; l[i] = tmp; ks_heapadjust_##name(0, i, l); \ + } \ + } \ + inline void __ks_insertsort_##name(type_t *s, type_t *t) \ + { \ + type_t *i, *j, swap_tmp; \ + for (i = s + 1; i < t; ++i) \ + for (j = i; j > s && __sort_lt(*j, *(j-1)); --j) { \ + swap_tmp = *j; *j = *(j-1); *(j-1) = swap_tmp; \ + } \ + } \ + void ks_combsort_##name(size_t n, type_t a[]) \ + { \ + const double shrink_factor = 1.2473309501039786540366528676643; \ + int do_swap; \ + size_t gap = n; \ + type_t tmp, *i, *j; \ + do { \ + if (gap > 2) { \ + gap = (size_t)(gap / shrink_factor); \ + if (gap == 9 || gap == 10) gap = 11; \ + } \ + do_swap = 0; \ + for (i = a; i < a + n - gap; ++i) { \ + j = i + gap; \ + if (__sort_lt(*j, *i)) { \ + tmp = *i; *i = *j; *j = tmp; \ + do_swap = 1; \ + } \ + } \ + } while (do_swap || gap > 2); \ + if (gap != 1) __ks_insertsort_##name(a, a + n); \ + } \ + void ks_introsort_##name(size_t n, type_t a[]) \ + { \ + int d; \ + ks_isort_stack_t *top, *stack; \ + type_t rp, swap_tmp; \ + type_t *s, *t, *i, *j, *k; \ + \ + if (n < 1) return; \ + else if (n == 2) { \ + if (__sort_lt(a[1], a[0])) { swap_tmp = a[0]; a[0] = a[1]; a[1] = swap_tmp; } \ + return; \ + } \ + for (d = 2; 1ul<<d < n; ++d); \ + stack = (ks_isort_stack_t*)malloc(sizeof(ks_isort_stack_t) * ((sizeof(size_t)*d)+2)); \ + top = stack; s = a; t = a + (n-1); d <<= 1; \ + while (1) { \ + if (s < t) { \ + if (--d == 0) { \ + ks_combsort_##name(t - s + 1, s); \ + t = s; \ + continue; \ + } \ + i = s; j = t; k = i + ((j-i)>>1) + 1; \ + if (__sort_lt(*k, *i)) { \ + if (__sort_lt(*k, *j)) k = j; \ + } else k = __sort_lt(*j, *i)? i : j; \ + rp = *k; \ + if (k != t) { swap_tmp = *k; *k = *t; *t = swap_tmp; } \ + for (;;) { \ + do ++i; while (__sort_lt(*i, rp)); \ + do --j; while (i <= j && __sort_lt(rp, *j)); \ + if (j <= i) break; \ + swap_tmp = *i; *i = *j; *j = swap_tmp; \ + } \ + swap_tmp = *i; *i = *t; *t = swap_tmp; \ + if (i-s > t-i) { \ + if (i-s > 16) { top->left = s; top->right = i-1; top->depth = d; ++top; } \ + s = t-i > 16? i+1 : t; \ + } else { \ + if (t-i > 16) { top->left = i+1; top->right = t; top->depth = d; ++top; } \ + t = i-s > 16? i-1 : s; \ + } \ + } else { \ + if (top == stack) { \ + free(stack); \ + __ks_insertsort_##name(a, a+n); \ + return; \ + } else { --top; s = (type_t*)top->left; t = (type_t*)top->right; d = top->depth; } \ + } \ + } \ + } \ + /* This function is adapted from: http://ndevilla.free.fr/median/ */ \ + /* 0 <= kk < n */ \ + type_t ks_ksmall_##name(size_t n, type_t arr[], size_t kk) \ + { \ + type_t *low, *high, *k, *ll, *hh, *mid; \ + low = arr; high = arr + n - 1; k = arr + kk; \ + for (;;) { \ + if (high <= low) return *k; \ + if (high == low + 1) { \ + if (__sort_lt(*high, *low)) KSORT_SWAP(type_t, *low, *high); \ + return *k; \ + } \ + mid = low + (high - low) / 2; \ + if (__sort_lt(*high, *mid)) KSORT_SWAP(type_t, *mid, *high); \ + if (__sort_lt(*high, *low)) KSORT_SWAP(type_t, *low, *high); \ + if (__sort_lt(*low, *mid)) KSORT_SWAP(type_t, *mid, *low); \ + KSORT_SWAP(type_t, *mid, *(low+1)); \ + ll = low + 1; hh = high; \ + for (;;) { \ + do ++ll; while (__sort_lt(*ll, *low)); \ + do --hh; while (__sort_lt(*low, *hh)); \ + if (hh < ll) break; \ + KSORT_SWAP(type_t, *ll, *hh); \ + } \ + KSORT_SWAP(type_t, *low, *hh); \ + if (hh <= k) low = ll; \ + if (hh >= k) high = hh - 1; \ + } \ + } + +#define ks_mergesort(name, n, a, t) ks_mergesort_##name(n, a, t) +#define ks_introsort(name, n, a) ks_introsort_##name(n, a) +#define ks_combsort(name, n, a) ks_combsort_##name(n, a) +#define ks_heapsort(name, n, a) ks_heapsort_##name(n, a) +#define ks_heapmake(name, n, a) ks_heapmake_##name(n, a) +#define ks_heapadjust(name, i, n, a) ks_heapadjust_##name(i, n, a) +#define ks_ksmall(name, n, a, k) ks_ksmall_##name(n, a, k) + +#define ks_lt_generic(a, b) ((a) < (b)) +#define ks_lt_str(a, b) (strcmp((a), (b)) < 0) + +typedef const char *ksstr_t; + +#define KSORT_INIT_GENERIC(type_t) KSORT_INIT(type_t, type_t, ks_lt_generic) +#define KSORT_INIT_STR KSORT_INIT(str, ksstr_t, ks_lt_str) + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/kstring.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,35 @@ +#include <stdarg.h> +#include <stdio.h> +#include "kstring.h" + +int ksprintf(kstring_t *s, const char *fmt, ...) +{ + va_list ap; + int l; + va_start(ap, fmt); + l = vsnprintf(s->s + s->l, s->m - s->l, fmt, ap); + va_end(ap); + if (l + 1 > s->m - s->l) { + s->m = s->l + l + 2; + kroundup32(s->m); + s->s = (char*)realloc(s->s, s->m); + va_start(ap, fmt); + l = vsnprintf(s->s + s->l, s->m - s->l, fmt, ap); + } + va_end(ap); + s->l += l; + return l; +} + +#ifdef KSTRING_MAIN +#include <stdio.h> +int main() +{ + kstring_t *s; + s = (kstring_t*)calloc(1, sizeof(kstring_t)); + ksprintf(s, "abcdefg: %d", 100); + printf("%s\n", s->s); + free(s); + return 0; +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/kstring.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,46 @@ +#ifndef KSTRING_H +#define KSTRING_H + +#include <stdlib.h> +#include <string.h> + +#ifndef kroundup32 +#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) +#endif + +#ifndef KSTRING_T +#define KSTRING_T kstring_t +typedef struct __kstring_t { + size_t l, m; + char *s; +} kstring_t; +#endif + +static inline int kputs(const char *p, kstring_t *s) +{ + int l = strlen(p); + if (s->l + l + 1 >= s->m) { + s->m = s->l + l + 2; + kroundup32(s->m); + s->s = (char*)realloc(s->s, s->m); + } + strcpy(s->s + s->l, p); + s->l += l; + return l; +} + +static inline int kputc(int c, kstring_t *s) +{ + if (s->l + 1 >= s->m) { + s->m = s->l + 2; + kroundup32(s->m); + s->s = (char*)realloc(s->s, s->m); + } + s->s[s->l++] = c; + s->s[s->l] = 0; + return c; +} + +int ksprintf(kstring_t *s, const char *fmt, ...); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/kvec.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,90 @@ +/* The MIT License + + Copyright (c) 2008, by Attractive Chaos <attractivechaos@aol.co.uk> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* + An example: + +#include "kvec.h" +int main() { + kvec_t(int) array; + kv_init(array); + kv_push(int, array, 10); // append + kv_a(int, array, 20) = 5; // dynamic + kv_A(array, 20) = 4; // static + kv_destroy(array); + return 0; +} +*/ + +/* + 2008-09-22 (0.1.0): + + * The initial version. + +*/ + +#ifndef AC_KVEC_H +#define AC_KVEC_H + +#include <stdlib.h> + +#define kv_roundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) + +#define kvec_t(type) struct { size_t n, m; type *a; } +#define kv_init(v) ((v).n = (v).m = 0, (v).a = 0) +#define kv_destroy(v) free((v).a) +#define kv_A(v, i) ((v).a[(i)]) +#define kv_pop(v) ((v).a[--(v).n]) +#define kv_size(v) ((v).n) +#define kv_max(v) ((v).m) + +#define kv_resize(type, v, s) ((v).m = (s), (v).a = (type*)realloc((v).a, sizeof(type) * (v).m)) + +#define kv_copy(type, v1, v0) do { \ + if ((v1).m < (v0).n) kv_resize(type, v1, (v0).n); \ + (v1).n = (v0).n; \ + memcpy((v1).a, (v0).a, sizeof(type) * (v0).n); \ + } while (0) \ + +#define kv_push(type, v, x) do { \ + if ((v).n == (v).m) { \ + (v).m = (v).m? (v).m<<1 : 2; \ + (v).a = (type*)realloc((v).a, sizeof(type) * (v).m); \ + } \ + (v).a[(v).n++] = (x); \ + } while (0) + +#define kv_pushp(type, v) (((v).n == (v).m)? \ + ((v).m = ((v).m? (v).m<<1 : 2), \ + (v).a = (type*)realloc((v).a, sizeof(type) * (v).m), 0) \ + : 0), ((v).a + ((v).n++)) + +#define kv_a(type, v, i) ((v).m <= (size_t)(i)? \ + ((v).m = (v).n = (i) + 1, kv_roundup32((v).m), \ + (v).a = (type*)realloc((v).a, sizeof(type) * (v).m), 0) \ + : (v).n <= (size_t)(i)? (v).n = (i) \ + : 0), (v).a[(i)] + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/m4/acx_pthread.m4 Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,271 @@ +# =========================================================================== +# http://autoconf-archive.cryp.to/acx_pthread.html +# =========================================================================== +# +# SYNOPSIS +# +# ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro figures out how to build C programs using POSIX threads. It +# sets the PTHREAD_LIBS output variable to the threads library and linker +# flags, and the PTHREAD_CFLAGS output variable to any special C compiler +# flags that are needed. (The user can also force certain compiler +# flags/libs to be tested by setting these environment variables.) +# +# Also sets PTHREAD_CC to any special C compiler that is needed for +# multi-threaded programs (defaults to the value of CC otherwise). (This +# is necessary on AIX to use the special cc_r compiler alias.) +# +# NOTE: You are assumed to not only compile your program with these flags, +# but also link it with them as well. e.g. you should link with +# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# +# If you are only building threads programs, you may wish to use these +# variables in your default LIBS, CFLAGS, and CC: +# +# LIBS="$PTHREAD_LIBS $LIBS" +# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CC="$PTHREAD_CC" +# +# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant +# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name +# (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# +# ACTION-IF-FOUND is a list of shell commands to run if a threads library +# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it +# is not found. If ACTION-IF-FOUND is not specified, the default action +# will define HAVE_PTHREAD. +# +# Please let the authors know if this macro fails on any platform, or if +# you have any other suggestions or comments. This macro was based on work +# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help +# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by +# Alejandro Forero Cuervo to the autoconf macro repository. We are also +# grateful for the helpful feedback of numerous users. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu> +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <http://www.gnu.org/licenses/>. +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +AC_DEFUN([ACX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_SAVE +AC_LANG_C +acx_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) + AC_MSG_RESULT($acx_pthread_ok) + if test x"$acx_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case "${host_cpu}-${host_os}" in + *solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" + ;; +esac + +if test x"$acx_pthread_ok" = xno; then +for flag in $acx_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) + if test x"$acx_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_TRY_LINK([#include <pthread.h>], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [acx_pthread_ok=yes]) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT($acx_pthread_ok) + if test "x$acx_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$acx_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_MSG_CHECKING([for joinable pthread attribute]) + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;], + [attr_name=$attr; break]) + done + AC_MSG_RESULT($attr_name) + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case "${host_cpu}-${host_os}" in + *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; + *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; + esac + AC_MSG_RESULT(${flag}) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: must compile with xlc_r or cc_r + if test x"$GCC" != xyes; then + AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) + else + PTHREAD_CC=$CC + fi +else + PTHREAD_CC="$CC" +fi + +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_CC) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$acx_pthread_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) + : +else + acx_pthread_ok=no + $2 +fi +AC_LANG_RESTORE +])dnl ACX_PTHREAD
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/main.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,58 @@ +#include <stdio.h> +#include <string.h> +#include "main.h" + +#ifndef PACKAGE_VERSION +#define PACKAGE_VERSION "0.5.7 (r1310)" +#endif + +static int usage() +{ + fprintf(stderr, "\n"); + fprintf(stderr, "Program: bwa (alignment via Burrows-Wheeler transformation)\n"); + fprintf(stderr, "Version: %s\n", PACKAGE_VERSION); + fprintf(stderr, "Contact: Heng Li <lh3@sanger.ac.uk>\n\n"); + fprintf(stderr, "Usage: bwa <command> [options]\n\n"); + fprintf(stderr, "Command: index index sequences in the FASTA format\n"); + fprintf(stderr, " aln gapped/ungapped alignment\n"); + fprintf(stderr, " samse generate alignment (single ended)\n"); + fprintf(stderr, " sampe generate alignment (paired ended)\n"); + fprintf(stderr, " bwasw BWA-SW for long queries\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " fa2pac convert FASTA to PAC format\n"); + fprintf(stderr, " pac2bwt generate BWT from PAC\n"); + fprintf(stderr, " pac2bwtgen alternative algorithm for generating BWT\n"); + fprintf(stderr, " bwtupdate update .bwt to the new format\n"); + fprintf(stderr, " pac_rev generate reverse PAC\n"); + fprintf(stderr, " bwt2sa generate SA from BWT and Occ\n"); + fprintf(stderr, " pac2cspac convert PAC to color-space PAC\n"); + fprintf(stderr, " stdsw standard SW/NW alignment\n"); + fprintf(stderr, "\n"); + return 1; +} + +int main(int argc, char *argv[]) +{ + if (argc < 2) return usage(); + if (strcmp(argv[1], "fa2pac") == 0) return bwa_fa2pac(argc-1, argv+1); + else if (strcmp(argv[1], "pac2bwt") == 0) return bwa_pac2bwt(argc-1, argv+1); + else if (strcmp(argv[1], "pac2bwtgen") == 0) return bwt_bwtgen_main(argc-1, argv+1); + else if (strcmp(argv[1], "bwtupdate") == 0) return bwa_bwtupdate(argc-1, argv+1); + else if (strcmp(argv[1], "pac_rev") == 0) return bwa_pac_rev(argc-1, argv+1); + else if (strcmp(argv[1], "bwt2sa") == 0) return bwa_bwt2sa(argc-1, argv+1); + else if (strcmp(argv[1], "index") == 0) return bwa_index(argc-1, argv+1); + else if (strcmp(argv[1], "aln") == 0) return bwa_aln(argc-1, argv+1); + else if (strcmp(argv[1], "sw") == 0) return bwa_stdsw(argc-1, argv+1); + else if (strcmp(argv[1], "samse") == 0) return bwa_sai2sam_se(argc-1, argv+1); + else if (strcmp(argv[1], "sampe") == 0) return bwa_sai2sam_pe(argc-1, argv+1); + else if (strcmp(argv[1], "pac2cspac") == 0) return bwa_pac2cspac(argc-1, argv+1); + else if (strcmp(argv[1], "stdsw") == 0) return bwa_stdsw(argc-1, argv+1); + else if (strcmp(argv[1], "bwtsw2") == 0) return bwa_bwtsw2(argc-1, argv+1); + else if (strcmp(argv[1], "dbwtsw") == 0) return bwa_bwtsw2(argc-1, argv+1); + else if (strcmp(argv[1], "bwasw") == 0) return bwa_bwtsw2(argc-1, argv+1); + else { + fprintf(stderr, "[main] unrecognized command '%s'\n", argv[1]); + return 1; + } + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/main.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,29 @@ +#ifndef BWA_MAIN_H +#define BWA_MAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + + int bwa_fa2pac(int argc, char *argv[]); + int bwa_pac_rev(int argc, char *argv[]); + int bwa_pac2cspac(int argc, char *argv[]); + int bwa_pac2bwt(int argc, char *argv[]); + int bwa_bwtupdate(int argc, char *argv[]); + int bwa_bwt2sa(int argc, char *argv[]); + int bwa_index(int argc, char *argv[]); + int bwa_aln(int argc, char *argv[]); + int bwt_bwtgen_main(int argc, char *argv[]); + + int bwa_sai2sam_se(int argc, char *argv[]); + int bwa_sai2sam_pe(int argc, char *argv[]); + + int bwa_stdsw(int argc, char *argv[]); + + int bwa_bwtsw2(int argc, char *argv[]); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/qualfa2fq.pl Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,27 @@ +#!/usr/bin/perl -w + +use strict; +use warnings; + +die("Usage: qualfa2fq.pl <in.fasta> <in.qual>\n") if (@ARGV != 2); + +my ($fhs, $fhq, $q); +open($fhs, ($ARGV[0] =~ /\.gz$/)? "gzip -dc $ARGV[0] |" : $ARGV[0]) || die; +open($fhq, ($ARGV[1] =~ /\.gz$/)? "gzip -dc $ARGV[1] |" : $ARGV[1]) || die; + +$/ = ">"; <$fhs>; <$fhq>; $/ = "\n"; +while (<$fhs>) { + $q = <$fhq>; + print "\@$_"; + $/ = ">"; + $_ = <$fhs>; $q = <$fhq>; + chomp; chomp($q); + $q =~ s/\s*(\d+)\s*/chr($1+33)/eg; + print $_, "+\n"; + for (my $i = 0; $i < length($q); $i += 60) { + print substr($q, $i, 60), "\n"; + } + $/ = "\n"; +} + +close($fhs); close($fhq);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/simple_dp.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,162 @@ +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <zlib.h> +#include <stdint.h> +#include "stdaln.h" +#include "utils.h" + +#include "kseq.h" +KSEQ_INIT(gzFile, gzread) + +typedef struct { + int l; + unsigned char *s; + char *n; +} seq1_t; + +typedef struct { + int n_seqs, m_seqs; + seq1_t *seqs; +} seqs_t; + +unsigned char aln_rev_table[256] = { + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', + 'N','T','V','G', 'H','N','N','C', 'D','N','N','M', 'N','K','N','N', + 'N','N','Y','S', 'A','N','B','W', 'X','R','N','N', 'N','N','N','N', + 'N','t','v','g', 'h','N','N','c', 'd','N','N','m', 'N','k','N','N', + 'N','N','y','s', 'a','N','b','w', 'x','r','N','N', 'N','N','N','N', + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', + 'N','N','N','N', 'N','N','N','N', 'N','N','N','N', 'N','N','N','N' +}; + +static int g_is_global = 0, g_thres = 1, g_strand = 0, g_aa = 0; +static AlnParam g_aln_param; + +static void revseq(int len, uint8_t *seq) +{ + int i; + for (i = 0; i < len>>1; ++i) { + uint8_t tmp = aln_rev_table[seq[len-1-i]]; + seq[len-1-i] = aln_rev_table[seq[i]]; + seq[i] = tmp; + } + if (len&1) seq[i] = aln_rev_table[seq[i]]; +} + +static seqs_t *load_seqs(const char *fn) +{ + seqs_t *s; + seq1_t *p; + gzFile fp; + int l; + kseq_t *seq; + + fp = xzopen(fn, "r"); + seq = kseq_init(fp); + s = (seqs_t*)calloc(1, sizeof(seqs_t)); + s->m_seqs = 256; + s->seqs = (seq1_t*)calloc(s->m_seqs, sizeof(seq1_t)); + while ((l = kseq_read(seq)) >= 0) { + if (s->n_seqs == s->m_seqs) { + s->m_seqs <<= 1; + s->seqs = (seq1_t*)realloc(s->seqs, s->m_seqs * sizeof(seq1_t)); + } + p = s->seqs + (s->n_seqs++); + p->l = seq->seq.l; + p->s = (unsigned char*)malloc(p->l + 1); + memcpy(p->s, seq->seq.s, p->l); + p->s[p->l] = 0; + p->n = strdup((const char*)seq->name.s); + } + kseq_destroy(seq); + gzclose(fp); + fprintf(stderr, "[load_seqs] %d sequences are loaded.\n", s->n_seqs); + return s; +} + +static void aln_1seq(const seqs_t *ss, const char *name, int l, const char *s, char strand) +{ + int i; + for (i = 0; i < ss->n_seqs; ++i) { + AlnAln *aa; + seq1_t *p = ss->seqs + i; + g_aln_param.band_width = l + p->l; + aa = aln_stdaln_aux(s, (const char*)p->s, &g_aln_param, g_is_global, g_thres, l, p->l); + if (aa->score >= g_thres || g_is_global) { + printf(">%s\t%d\t%d\t%s\t%c\t%d\t%d\t%d\t%d\t", p->n, aa->start1? aa->start1 : 1, aa->end1, name, strand, + aa->start2? aa->start2 : 1, aa->end2, aa->score, aa->subo); + // NB: I put the short sequence as the first sequence in SW, an insertion to + // the reference becomes a deletion from the short sequence. Therefore, I use + // "MDI" here rather than "MID", and print ->out2 first rather than ->out1. + for (i = 0; i != aa->n_cigar; ++i) + printf("%d%c", aa->cigar32[i]>>4, "MDI"[aa->cigar32[i]&0xf]); + printf("\n%s\n%s\n%s\n", aa->out2, aa->outm, aa->out1); + } + aln_free_AlnAln(aa); + } +} + +static void aln_seqs(const seqs_t *ss, const char *fn) +{ + gzFile fp; + kseq_t *seq; + int l; + + fp = xzopen(fn, "r"); + seq = kseq_init(fp); + while ((l = kseq_read(seq)) >= 0) { + if (g_strand&1) aln_1seq(ss, (char*)seq->name.s, l, seq->seq.s, '+'); + if (g_strand&2) { + revseq(l, (uint8_t*)seq->seq.s); + aln_1seq(ss, (char*)seq->name.s, l, seq->seq.s, '-'); + } + } + kseq_destroy(seq); + gzclose(fp); +} + +int bwa_stdsw(int argc, char *argv[]) +{ + int c; + seqs_t *ss; + + while ((c = getopt(argc, argv, "gT:frp")) >= 0) { + switch (c) { + case 'g': g_is_global = 1; break; + case 'T': g_thres = atoi(optarg); break; + case 'f': g_strand |= 1; break; + case 'r': g_strand |= 2; break; + case 'p': g_aa = 1; break; + } + } + if (g_strand == 0) g_strand = 3; + if (g_aa) g_strand = 1; + if (optind + 1 >= argc) { + fprintf(stderr, "\nUsage: bwa stdsw [options] <seq1.long.fa> <seq2.short.fa>\n\n"); + fprintf(stderr, "Options: -T INT minimum score [%d]\n", g_thres); + fprintf(stderr, " -p protein alignment (suppressing -r)\n"); + fprintf(stderr, " -f forward strand only\n"); + fprintf(stderr, " -r reverse strand only\n"); + fprintf(stderr, " -g global alignment\n\n"); + fprintf(stderr, "Note: This program is specifically designed for alignment between multiple short\n"); + fprintf(stderr, " sequences and ONE long sequence. It outputs the suboptimal score on the long\n"); + fprintf(stderr, " sequence.\n\n"); + return 1; + } + g_aln_param = g_aa? aln_param_aa2aa : aln_param_blast; + g_aln_param.gap_end = 0; + ss = load_seqs(argv[optind]); + aln_seqs(ss, argv[optind+1]); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/solid2fastq.pl Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,111 @@ +#!/usr/bin/perl -w + +# Author: lh3 +# Note: Ideally, this script should be written in C. It is a bit slow at present. +# Also note that this script is different from the one contained in MAQ. + +use strict; +use warnings; +use Getopt::Std; + +my %opts; +my $version = '0.1.3'; +my $usage = qq{ +Usage: solid2fastq.pl <in.title> <out.prefix> + +Note: <in.title> is the string showed in the `# Title:' line of a + ".csfasta" read file. Then <in.title>F3.csfasta is read sequence + file and <in.title>F3_QV.qual is the quality file. If + <in.title>R3.csfasta is present, this script assumes reads are + paired; otherwise reads will be regarded as single-end. + + The read name will be <out.prefix>:panel_x_y/[12] with `1' for R3 + tag and `2' for F3. Usually you may want to use short <out.prefix> + to save diskspace. Long <out.prefix> also causes troubles to maq. + +}; + +getopts('', \%opts); +die($usage) if (@ARGV != 2); +my ($title, $pre) = @ARGV; +my (@fhr, @fhw); +my @fn_suff = ('F3.csfasta', 'F3_QV.qual', 'R3.csfasta', 'R3_QV.qual'); +my $is_paired = (-f "$title$fn_suff[2]" || -f "$title$fn_suff[2].gz")? 1 : 0; +if ($is_paired) { # paired end + for (0 .. 3) { + my $fn = "$title$fn_suff[$_]"; + $fn = "gzip -dc $fn.gz |" if (!-f $fn && -f "$fn.gz"); + open($fhr[$_], $fn) || die("** Fail to open '$fn'.\n"); + } + open($fhw[0], "|gzip >$pre.read2.fastq.gz") || die; # this is NOT a typo + open($fhw[1], "|gzip >$pre.read1.fastq.gz") || die; + open($fhw[2], "|gzip >$pre.single.fastq.gz") || die; + my (@df, @dr); + @df = &read1(1); @dr = &read1(2); + while (@df && @dr) { + if ($df[0] eq $dr[0]) { # mate pair + print {$fhw[0]} $df[1]; print {$fhw[1]} $dr[1]; + @df = &read1(1); @dr = &read1(2); + } else { + if ($df[0] le $dr[0]) { + print {$fhw[2]} $df[1]; + @df = &read1(1); + } else { + print {$fhw[2]} $dr[1]; + @dr = &read1(2); + } + } + } + if (@df) { + print {$fhw[2]} $df[1]; + while (@df = &read1(1, $fhr[0], $fhr[1])) { + print {$fhw[2]} $df[1]; + } + } + if (@dr) { + print {$fhw[2]} $dr[1]; + while (@dr = &read1(2, $fhr[2], $fhr[3])) { + print {$fhw[2]} $dr[1]; + } + } + close($fhr[$_]) for (0 .. $#fhr); + close($fhw[$_]) for (0 .. $#fhw); +} else { # single end + for (0 .. 1) { + my $fn = "$title$fn_suff[$_]"; + $fn = "gzip -dc $fn.gz |" if (!-f $fn && -f "$fn.gz"); + open($fhr[$_], $fn) || die("** Fail to open '$fn'.\n"); + } + open($fhw[2], "|gzip >$pre.single.fastq.gz") || die; + my @df; + while (@df = &read1(1, $fhr[0], $fhr[1])) { + print {$fhw[2]} $df[1]; + } + close($fhr[$_]) for (0 .. $#fhr); + close($fhw[2]); +} + +sub read1 { + my $i = shift(@_); + my $j = ($i-1)<<1; + my ($key, $seq); + my ($fhs, $fhq) = ($fhr[$j], $fhr[$j|1]); + while (<$fhs>) { + my $t = <$fhq>; + if (/^>(\d+)_(\d+)_(\d+)_[FR]3/) { + $key = sprintf("%.4d_%.4d_%.4d", $1, $2, $3); # this line could be improved on 64-bit machines + die(qq/** unmatched read name: '$_' != '$_'\n/) unless ($_ eq $t); + my $name = "$pre:$1_$2_$3/$i"; + $_ = substr(<$fhs>, 2); + tr/0123./ACGTN/; + my $s = $_; + $_ = <$fhq>; + s/^(\d+)\s*//; + s/-1\b/0/eg; + s/(\d+)\s*/chr($1+33)/eg; + $seq = qq/\@$name\n$s+\n$_\n/; + last; + } + } + return defined($seq)? ($key, $seq) : (); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/stdaln.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,1072 @@ +/* The MIT License + + Copyright (c) 2003-2006, 2008, 2009, by Heng Li <lh3lh3@gmail.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> +#include "stdaln.h" + +/* char -> 17 (=16+1) nucleotides */ +unsigned char aln_nt16_table[256] = { + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,16 /*'-'*/,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15, 1,14, 4, 11,15,15, 2, 13,15,15,10, 15, 5,15,15, + 15,15, 3, 6, 8,15, 7, 9, 0,12,15,15, 15,15,15,15, + 15, 1,14, 4, 11,15,15, 2, 13,15,15,10, 15, 5,15,15, + 15,15, 3, 6, 8,15, 7, 9, 0,12,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15 +}; +char *aln_nt16_rev_table = "XAGRCMSVTWKDYHBN-"; + +/* char -> 5 (=4+1) nucleotides */ +unsigned char aln_nt4_table[256] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5 /*'-'*/, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 0, 4, 2, 4, 4, 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 0, 4, 2, 4, 4, 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 +}; +char *aln_nt4_rev_table = "AGCTN-"; + +/* char -> 22 (=20+1+1) amino acids */ +unsigned char aln_aa_table[256] = { + 21,21,21,21, 21,21,21,21, 21,21,21,21, 21,21,21,21, + 21,21,21,21, 21,21,21,21, 21,21,21,21, 21,21,21,21, + 21,21,21,21, 21,21,21,21, 21,21,20,21, 21,22 /*'-'*/,21,21, + 21,21,21,21, 21,21,21,21, 21,21,21,21, 21,21,21,21, + 21, 0,21, 4, 3, 6,13, 7, 8, 9,21,11, 10,12, 2,21, + 14, 5, 1,15, 16,21,19,17, 21,18,21,21, 21,21,21,21, + 21, 0,21, 4, 3, 6,13, 7, 8, 9,21,11, 10,12, 2,21, + 14, 5, 1,15, 16,21,19,17, 21,18,21,21, 21,21,21,21, + 21,21,21,21, 21,21,21,21, 21,21,21,21, 21,21,21,21, + 21,21,21,21, 21,21,21,21, 21,21,21,21, 21,21,21,21, + 21,21,21,21, 21,21,21,21, 21,21,21,21, 21,21,21,21, + 21,21,21,21, 21,21,21,21, 21,21,21,21, 21,21,21,21, + 21,21,21,21, 21,21,21,21, 21,21,21,21, 21,21,21,21, + 21,21,21,21, 21,21,21,21, 21,21,21,21, 21,21,21,21, + 21,21,21,21, 21,21,21,21, 21,21,21,21, 21,21,21,21, + 21,21,21,21, 21,21,21,21, 21,21,21,21, 21,21,21,21 +}; +char *aln_aa_rev_table = "ARNDCQEGHILKMFPSTWYV*X-"; + /* 01234567890123456789012 */ + +/* translation table. They are useless in stdaln.c, but when you realize you need it, you need not write the table again. */ +unsigned char aln_trans_table_eu[66] = { + 11,11, 2, 2, 1, 1,15,15, 16,16,16,16, 9,12, 9, 9, + 6, 6, 3, 3, 7, 7, 7, 7, 0, 0, 0, 0, 19,19,19,19, + 5, 5, 8, 8, 1, 1, 1, 1, 14,14,14,14, 10,10,10,10, + 20,20,18,18, 20,17, 4, 4, 15,15,15,15, 10,10,13,13, 21, 22 +}; +char *aln_trans_table_eu_char = "KKNNRRSSTTTTIMIIEEDDGGGGAAAAVVVVQQHHRRRRPPPPLLLL**YY*WCCSSSSLLFFX"; + /* 01234567890123456789012345678901234567890123456789012345678901234 */ +int aln_sm_blosum62[] = { +/* A R N D C Q E G H I L K M F P S T W Y V * X */ + 4,-1,-2,-2, 0,-1,-1, 0,-2,-1,-1,-1,-1,-2,-1, 1, 0,-3,-2, 0,-4, 0, + -1, 5, 0,-2,-3, 1, 0,-2, 0,-3,-2, 2,-1,-3,-2,-1,-1,-3,-2,-3,-4,-1, + -2, 0, 6, 1,-3, 0, 0, 0, 1,-3,-3, 0,-2,-3,-2, 1, 0,-4,-2,-3,-4,-1, + -2,-2, 1, 6,-3, 0, 2,-1,-1,-3,-4,-1,-3,-3,-1, 0,-1,-4,-3,-3,-4,-1, + 0,-3,-3,-3, 9,-3,-4,-3,-3,-1,-1,-3,-1,-2,-3,-1,-1,-2,-2,-1,-4,-2, + -1, 1, 0, 0,-3, 5, 2,-2, 0,-3,-2, 1, 0,-3,-1, 0,-1,-2,-1,-2,-4,-1, + -1, 0, 0, 2,-4, 2, 5,-2, 0,-3,-3, 1,-2,-3,-1, 0,-1,-3,-2,-2,-4,-1, + 0,-2, 0,-1,-3,-2,-2, 6,-2,-4,-4,-2,-3,-3,-2, 0,-2,-2,-3,-3,-4,-1, + -2, 0, 1,-1,-3, 0, 0,-2, 8,-3,-3,-1,-2,-1,-2,-1,-2,-2, 2,-3,-4,-1, + -1,-3,-3,-3,-1,-3,-3,-4,-3, 4, 2,-3, 1, 0,-3,-2,-1,-3,-1, 3,-4,-1, + -1,-2,-3,-4,-1,-2,-3,-4,-3, 2, 4,-2, 2, 0,-3,-2,-1,-2,-1, 1,-4,-1, + -1, 2, 0,-1,-3, 1, 1,-2,-1,-3,-2, 5,-1,-3,-1, 0,-1,-3,-2,-2,-4,-1, + -1,-1,-2,-3,-1, 0,-2,-3,-2, 1, 2,-1, 5, 0,-2,-1,-1,-1,-1, 1,-4,-1, + -2,-3,-3,-3,-2,-3,-3,-3,-1, 0, 0,-3, 0, 6,-4,-2,-2, 1, 3,-1,-4,-1, + -1,-2,-2,-1,-3,-1,-1,-2,-2,-3,-3,-1,-2,-4, 7,-1,-1,-4,-3,-2,-4,-2, + 1,-1, 1, 0,-1, 0, 0, 0,-1,-2,-2, 0,-1,-2,-1, 4, 1,-3,-2,-2,-4, 0, + 0,-1, 0,-1,-1,-1,-1,-2,-2,-1,-1,-1,-1,-2,-1, 1, 5,-2,-2, 0,-4, 0, + -3,-3,-4,-4,-2,-2,-3,-2,-2,-3,-2,-3,-1, 1,-4,-3,-2,11, 2,-3,-4,-2, + -2,-2,-2,-3,-2,-1,-2,-3, 2,-1,-1,-2,-1, 3,-3,-2,-2, 2, 7,-1,-4,-1, + 0,-3,-3,-3,-1,-2,-2,-3,-3, 3, 1,-2, 1,-1,-2,-2, 0,-3,-1, 4,-4,-1, + -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, 1,-4, + 0,-1,-1,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-2, 0, 0,-2,-1,-1,-4,-1 +}; + +int aln_sm_blosum45[] = { +/* A R N D C Q E G H I L K M F P S T W Y V * X */ + 5,-2,-1,-2,-1,-1,-1, 0,-2,-1,-1,-1,-1,-2,-1, 1, 0,-2,-2, 0,-5, 0, + -2, 7, 0,-1,-3, 1, 0,-2, 0,-3,-2, 3,-1,-2,-2,-1,-1,-2,-1,-2,-5,-1, + -1, 0, 6, 2,-2, 0, 0, 0, 1,-2,-3, 0,-2,-2,-2, 1, 0,-4,-2,-3,-5,-1, + -2,-1, 2, 7,-3, 0, 2,-1, 0,-4,-3, 0,-3,-4,-1, 0,-1,-4,-2,-3,-5,-1, + -1,-3,-2,-3,12,-3,-3,-3,-3,-3,-2,-3,-2,-2,-4,-1,-1,-5,-3,-1,-5,-2, + -1, 1, 0, 0,-3, 6, 2,-2, 1,-2,-2, 1, 0,-4,-1, 0,-1,-2,-1,-3,-5,-1, + -1, 0, 0, 2,-3, 2, 6,-2, 0,-3,-2, 1,-2,-3, 0, 0,-1,-3,-2,-3,-5,-1, + 0,-2, 0,-1,-3,-2,-2, 7,-2,-4,-3,-2,-2,-3,-2, 0,-2,-2,-3,-3,-5,-1, + -2, 0, 1, 0,-3, 1, 0,-2,10,-3,-2,-1, 0,-2,-2,-1,-2,-3, 2,-3,-5,-1, + -1,-3,-2,-4,-3,-2,-3,-4,-3, 5, 2,-3, 2, 0,-2,-2,-1,-2, 0, 3,-5,-1, + -1,-2,-3,-3,-2,-2,-2,-3,-2, 2, 5,-3, 2, 1,-3,-3,-1,-2, 0, 1,-5,-1, + -1, 3, 0, 0,-3, 1, 1,-2,-1,-3,-3, 5,-1,-3,-1,-1,-1,-2,-1,-2,-5,-1, + -1,-1,-2,-3,-2, 0,-2,-2, 0, 2, 2,-1, 6, 0,-2,-2,-1,-2, 0, 1,-5,-1, + -2,-2,-2,-4,-2,-4,-3,-3,-2, 0, 1,-3, 0, 8,-3,-2,-1, 1, 3, 0,-5,-1, + -1,-2,-2,-1,-4,-1, 0,-2,-2,-2,-3,-1,-2,-3, 9,-1,-1,-3,-3,-3,-5,-1, + 1,-1, 1, 0,-1, 0, 0, 0,-1,-2,-3,-1,-2,-2,-1, 4, 2,-4,-2,-1,-5, 0, + 0,-1, 0,-1,-1,-1,-1,-2,-2,-1,-1,-1,-1,-1,-1, 2, 5,-3,-1, 0,-5, 0, + -2,-2,-4,-4,-5,-2,-3,-2,-3,-2,-2,-2,-2, 1,-3,-4,-3,15, 3,-3,-5,-2, + -2,-1,-2,-2,-3,-1,-2,-3, 2, 0, 0,-1, 0, 3,-3,-2,-1, 3, 8,-1,-5,-1, + 0,-2,-3,-3,-1,-3,-3,-3,-3, 3, 1,-2, 1, 0,-3,-1, 0,-3,-1, 5,-5,-1, + -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5, 1,-5, + 0,-1,-1,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0,-2,-1,-1,-5,-1 +}; + +int aln_sm_nt[] = { +/* X A G R C M S V T W K D Y H B N */ + -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, + -2, 2,-1, 1,-2, 1,-2, 0,-2, 1,-2, 0,-2, 0,-2, 0, + -2,-1, 2, 1,-2,-2, 1, 0,-2,-2, 1, 0,-2,-2, 0, 0, + -2, 1, 1, 1,-2,-1,-1, 0,-2,-1,-1, 0,-2, 0, 0, 0, + -2,-2,-2,-2, 2, 1, 1, 0,-1,-2,-2,-2, 1, 0, 0, 0, + -2, 1,-2,-1, 1, 1,-1, 0,-2,-1,-2, 0,-1, 0, 0, 0, + -2,-2, 1,-1, 1,-1, 1, 0,-2,-2,-1, 0,-1, 0, 0, 0, + -2, 0, 0, 0, 0, 0, 0, 0,-2, 0, 0, 0, 0, 0, 0, 0, + -2,-2,-2,-2,-1,-2,-2,-2, 2, 1, 1, 0, 1, 0, 0, 0, + -2, 1,-2,-1,-2,-1,-2, 0, 1, 1,-1, 0,-1, 0, 0, 0, + -2,-2, 1,-1,-2,-2,-1, 0, 1,-1, 1, 0,-1, 0, 0, 0, + -2, 0, 0, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -2,-2,-2,-2, 1,-1,-1, 0, 1,-1,-1, 0, 1, 0, 0, 0, + -2, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -2,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +int aln_sm_read[] = { +/* X A G R C M S V T W K D Y H B N */ + -17,-17,-17,-17,-17,-17,-17,-17,-17,-17,-17,-17,-17,-17,-17,-17, + -17, 2,-17, 1,-17, 1,-17, 0,-17, 1,-17, 0,-17, 0,-17, 0, + -17,-17, 2, 1,-17,-17, 1, 0,-17,-17, 1, 0,-17,-17, 0, 0, + -17, 1, 1, 1,-17,-17,-17, 0,-17,-17,-17, 0,-17, 0, 0, 0, + -17,-17,-17,-17, 2, 1, 1, 0,-17,-17,-17,-17, 1, 0, 0, 0, + -17, 1,-17,-17, 1, 1,-17, 0,-17,-17,-17, 0,-17, 0, 0, 0, + -17,-17, 1,-17, 1,-17, 1, 0,-17,-17,-17, 0,-17, 0, 0, 0, + -17, 0, 0, 0, 0, 0, 0, 0,-17, 0, 0, 0, 0, 0, 0, 0, + -17,-17,-17,-17,-17,-17,-17,-17, 2, 1, 1, 0, 1, 0, 0, 0, + -17, 1,-17,-17,-17,-17,-17, 0, 1, 1,-17, 0,-17, 0, 0, 0, + -17,-17, 1,-17,-17,-17,-17, 0, 1,-17, 1, 0,-17, 0, 0, 0, + -17, 0, 0, 0,-17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -17,-17,-17,-17, 1,-17,-17, 0, 1,-17,-17, 0, 1, 0, 0, 0, + -17, 0,-17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -17,-17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +int aln_sm_hs[] = { +/* A G C T N */ + 91, -31,-114,-123, -44, + -31, 100,-125,-114, -42, + -123,-125, 100, -31, -42, + -114,-114, -31, 91, -42, + -44, -42, -42, -42, -43 +}; + +int aln_sm_maq[] = { + 11, -19, -19, -19, -13, + -19, 11, -19, -19, -13, + -19, -19, 11, -19, -13, + -19, -19, -19, 11, -13, + -13, -13, -13, -13, -13 +}; + +int aln_sm_blast[] = { + 1, -3, -3, -3, -2, + -3, 1, -3, -3, -2, + -3, -3, 1, -3, -2, + -3, -3, -3, 1, -2, + -2, -2, -2, -2, -2 +}; + +/********************/ +/* START OF align.c */ +/********************/ + +AlnParam aln_param_blast = { 5, 2, 2, aln_sm_blast, 5, 50 }; +AlnParam aln_param_bwa = { 26, 9, 5, aln_sm_maq, 5, 50 }; +AlnParam aln_param_nt2nt = { 8, 2, 2, aln_sm_nt, 16, 75 }; +AlnParam aln_param_rd2rd = { 1, 19, 19, aln_sm_read, 16, 75 }; +AlnParam aln_param_aa2aa = { 10, 2, 2, aln_sm_blosum62, 22, 50 }; + +AlnAln *aln_init_AlnAln() +{ + AlnAln *aa; + aa = (AlnAln*)malloc(sizeof(AlnAln)); + aa->path = 0; + aa->out1 = aa->out2 = aa->outm = 0; + aa->path_len = 0; + return aa; +} +void aln_free_AlnAln(AlnAln *aa) +{ + free(aa->path); free(aa->cigar32); + free(aa->out1); free(aa->out2); free(aa->outm); + free(aa); +} + +/***************************/ +/* START OF common_align.c */ +/***************************/ + +#define LOCAL_OVERFLOW_THRESHOLD 32000 +#define LOCAL_OVERFLOW_REDUCE 16000 +#define NT_LOCAL_SCORE int +#define NT_LOCAL_SHIFT 16 +#define NT_LOCAL_MASK 0xffff + +#define SET_INF(s) (s).M = (s).I = (s).D = MINOR_INF; + +#define set_M(MM, cur, p, sc) \ +{ \ + if ((p)->M >= (p)->I) { \ + if ((p)->M >= (p)->D) { \ + (MM) = (p)->M + (sc); (cur)->Mt = FROM_M; \ + } else { \ + (MM) = (p)->D + (sc); (cur)->Mt = FROM_D; \ + } \ + } else { \ + if ((p)->I > (p)->D) { \ + (MM) = (p)->I + (sc); (cur)->Mt = FROM_I; \ + } else { \ + (MM) = (p)->D + (sc); (cur)->Mt = FROM_D; \ + } \ + } \ +} +#define set_I(II, cur, p) \ +{ \ + if ((p)->M - gap_open > (p)->I) { \ + (cur)->It = FROM_M; \ + (II) = (p)->M - gap_open - gap_ext; \ + } else { \ + (cur)->It = FROM_I; \ + (II) = (p)->I - gap_ext; \ + } \ +} +#define set_end_I(II, cur, p) \ +{ \ + if (gap_end >= 0) { \ + if ((p)->M - gap_open > (p)->I) { \ + (cur)->It = FROM_M; \ + (II) = (p)->M - gap_open - gap_end; \ + } else { \ + (cur)->It = FROM_I; \ + (II) = (p)->I - gap_end; \ + } \ + } else set_I(II, cur, p); \ +} +#define set_D(DD, cur, p) \ +{ \ + if ((p)->M - gap_open > (p)->D) { \ + (cur)->Dt = FROM_M; \ + (DD) = (p)->M - gap_open - gap_ext; \ + } else { \ + (cur)->Dt = FROM_D; \ + (DD) = (p)->D - gap_ext; \ + } \ +} +#define set_end_D(DD, cur, p) \ +{ \ + if (gap_end >= 0) { \ + if ((p)->M - gap_open > (p)->D) { \ + (cur)->Dt = FROM_M; \ + (DD) = (p)->M - gap_open - gap_end; \ + } else { \ + (cur)->Dt = FROM_D; \ + (DD) = (p)->D - gap_end; \ + } \ + } else set_D(DD, cur, p); \ +} + +typedef struct +{ + unsigned char Mt:3, It:2, Dt:2; +} dpcell_t; + +typedef struct +{ + int M, I, D; +} dpscore_t; + +/* build score profile for accelerating alignment, in theory */ +void aln_init_score_array(unsigned char *seq, int len, int row, int *score_matrix, int **s_array) +{ + int *tmp, *tmp2, i, k; + for (i = 0; i != row; ++i) { + tmp = score_matrix + i * row; + tmp2 = s_array[i]; + for (k = 0; k != len; ++k) + tmp2[k] = tmp[seq[k]]; + } +} +/*************************** + * banded global alignment * + ***************************/ +int aln_global_core(unsigned char *seq1, int len1, unsigned char *seq2, int len2, const AlnParam *ap, + path_t *path, int *path_len) +{ + register int i, j; + dpcell_t **dpcell, *q; + dpscore_t *curr, *last, *s; + path_t *p; + int b1, b2, tmp_end; + int *mat, end, max; + unsigned char type, ctype; + + int gap_open, gap_ext, gap_end, b; + int *score_matrix, N_MATRIX_ROW; + + /* initialize some align-related parameters. just for compatibility */ + gap_open = ap->gap_open; + gap_ext = ap->gap_ext; + gap_end = ap->gap_end; + b = ap->band_width; + score_matrix = ap->matrix; + N_MATRIX_ROW = ap->row; + + if (len1 == 0 || len2 == 0) { + *path_len = 0; + return 0; + } + /* calculate b1 and b2 */ + if (len1 > len2) { + b1 = len1 - len2 + b; + b2 = b; + } else { + b1 = b; + b2 = len2 - len1 + b; + } + if (b1 > len1) b1 = len1; + if (b2 > len2) b2 = len2; + --seq1; --seq2; + + /* allocate memory */ + end = (b1 + b2 <= len1)? (b1 + b2 + 1) : (len1 + 1); + dpcell = (dpcell_t**)malloc(sizeof(dpcell_t*) * (len2 + 1)); + for (j = 0; j <= len2; ++j) + dpcell[j] = (dpcell_t*)malloc(sizeof(dpcell_t) * end); + for (j = b2 + 1; j <= len2; ++j) + dpcell[j] -= j - b2; + curr = (dpscore_t*)malloc(sizeof(dpscore_t) * (len1 + 1)); + last = (dpscore_t*)malloc(sizeof(dpscore_t) * (len1 + 1)); + + /* set first row */ + SET_INF(*curr); curr->M = 0; + for (i = 1, s = curr + 1; i < b1; ++i, ++s) { + SET_INF(*s); + set_end_D(s->D, dpcell[0] + i, s - 1); + } + s = curr; curr = last; last = s; + + /* core dynamic programming, part 1 */ + tmp_end = (b2 < len2)? b2 : len2 - 1; + for (j = 1; j <= tmp_end; ++j) { + q = dpcell[j]; s = curr; SET_INF(*s); + set_end_I(s->I, q, last); + end = (j + b1 <= len1 + 1)? (j + b1 - 1) : len1; + mat = score_matrix + seq2[j] * N_MATRIX_ROW; + ++s; ++q; + for (i = 1; i != end; ++i, ++s, ++q) { + set_M(s->M, q, last + i - 1, mat[seq1[i]]); /* this will change s->M ! */ + set_I(s->I, q, last + i); + set_D(s->D, q, s - 1); + } + set_M(s->M, q, last + i - 1, mat[seq1[i]]); + set_D(s->D, q, s - 1); + if (j + b1 - 1 > len1) { /* bug fixed, 040227 */ + set_end_I(s->I, q, last + i); + } else s->I = MINOR_INF; + s = curr; curr = last; last = s; + } + /* last row for part 1, use set_end_D() instead of set_D() */ + if (j == len2 && b2 != len2 - 1) { + q = dpcell[j]; s = curr; SET_INF(*s); + set_end_I(s->I, q, last); + end = (j + b1 <= len1 + 1)? (j + b1 - 1) : len1; + mat = score_matrix + seq2[j] * N_MATRIX_ROW; + ++s; ++q; + for (i = 1; i != end; ++i, ++s, ++q) { + set_M(s->M, q, last + i - 1, mat[seq1[i]]); /* this will change s->M ! */ + set_I(s->I, q, last + i); + set_end_D(s->D, q, s - 1); + } + set_M(s->M, q, last + i - 1, mat[seq1[i]]); + set_end_D(s->D, q, s - 1); + if (j + b1 - 1 > len1) { /* bug fixed, 040227 */ + set_end_I(s->I, q, last + i); + } else s->I = MINOR_INF; + s = curr; curr = last; last = s; + ++j; + } + + /* core dynamic programming, part 2 */ + for (; j <= len2 - b2 + 1; ++j) { + SET_INF(curr[j - b2]); + mat = score_matrix + seq2[j] * N_MATRIX_ROW; + end = j + b1 - 1; + for (i = j - b2 + 1, q = dpcell[j] + i, s = curr + i; i != end; ++i, ++s, ++q) { + set_M(s->M, q, last + i - 1, mat[seq1[i]]); + set_I(s->I, q, last + i); + set_D(s->D, q, s - 1); + } + set_M(s->M, q, last + i - 1, mat[seq1[i]]); + set_D(s->D, q, s - 1); + s->I = MINOR_INF; + s = curr; curr = last; last = s; + } + + /* core dynamic programming, part 3 */ + for (; j < len2; ++j) { + SET_INF(curr[j - b2]); + mat = score_matrix + seq2[j] * N_MATRIX_ROW; + for (i = j - b2 + 1, q = dpcell[j] + i, s = curr + i; i < len1; ++i, ++s, ++q) { + set_M(s->M, q, last + i - 1, mat[seq1[i]]); + set_I(s->I, q, last + i); + set_D(s->D, q, s - 1); + } + set_M(s->M, q, last + len1 - 1, mat[seq1[i]]); + set_end_I(s->I, q, last + i); + set_D(s->D, q, s - 1); + s = curr; curr = last; last = s; + } + /* last row */ + if (j == len2) { + SET_INF(curr[j - b2]); + mat = score_matrix + seq2[j] * N_MATRIX_ROW; + for (i = j - b2 + 1, q = dpcell[j] + i, s = curr + i; i < len1; ++i, ++s, ++q) { + set_M(s->M, q, last + i - 1, mat[seq1[i]]); + set_I(s->I, q, last + i); + set_end_D(s->D, q, s - 1); + } + set_M(s->M, q, last + len1 - 1, mat[seq1[i]]); + set_end_I(s->I, q, last + i); + set_end_D(s->D, q, s - 1); + s = curr; curr = last; last = s; + } + + /* backtrace */ + i = len1; j = len2; + q = dpcell[j] + i; + s = last + len1; + max = s->M; type = q->Mt; ctype = FROM_M; + if (s->I > max) { max = s->I; type = q->It; ctype = FROM_I; } + if (s->D > max) { max = s->D; type = q->Dt; ctype = FROM_D; } + + p = path; + p->ctype = ctype; p->i = i; p->j = j; /* bug fixed 040408 */ + ++p; + do { + switch (ctype) { + case FROM_M: --i; --j; break; + case FROM_I: --j; break; + case FROM_D: --i; break; + } + q = dpcell[j] + i; + ctype = type; + switch (type) { + case FROM_M: type = q->Mt; break; + case FROM_I: type = q->It; break; + case FROM_D: type = q->Dt; break; + } + p->ctype = ctype; p->i = i; p->j = j; + ++p; + } while (i || j); + *path_len = p - path - 1; + + /* free memory */ + for (j = b2 + 1; j <= len2; ++j) + dpcell[j] += j - b2; + for (j = 0; j <= len2; ++j) + free(dpcell[j]); + free(dpcell); + free(curr); free(last); + + return max; +} +/************************************************* + * local alignment combined with banded strategy * + *************************************************/ +int aln_local_core(unsigned char *seq1, int len1, unsigned char *seq2, int len2, const AlnParam *ap, + path_t *path, int *path_len, int _thres, int *_subo) +{ + register NT_LOCAL_SCORE *s; + register int i; + int q, r, qr, tmp_len, qr_shift; + int **s_array, *score_array; + int e, f; + int is_overflow, of_base; + NT_LOCAL_SCORE *eh, curr_h, last_h, curr_last_h; + int j, start_i, start_j, end_i, end_j; + path_t *p; + int score_f, score_r, score_g; + int start, end, max_score; + int thres, *suba, *ss; + + int gap_open, gap_ext, b; + int *score_matrix, N_MATRIX_ROW; + + /* initialize some align-related parameters. just for compatibility */ + gap_open = ap->gap_open; + gap_ext = ap->gap_ext; + b = ap->band_width; + score_matrix = ap->matrix; + N_MATRIX_ROW = ap->row; + thres = _thres > 0? _thres : -_thres; + + if (len1 == 0 || len2 == 0) return -1; + + /* allocate memory */ + suba = (int*)malloc(sizeof(int) * (len2 + 1)); + eh = (NT_LOCAL_SCORE*)malloc(sizeof(NT_LOCAL_SCORE) * (len1 + 1)); + s_array = (int**)malloc(sizeof(int*) * N_MATRIX_ROW); + for (i = 0; i != N_MATRIX_ROW; ++i) + s_array[i] = (int*)malloc(sizeof(int) * len1); + /* initialization */ + aln_init_score_array(seq1, len1, N_MATRIX_ROW, score_matrix, s_array); + q = gap_open; + r = gap_ext; + qr = q + r; + qr_shift = (qr+1) << NT_LOCAL_SHIFT; + tmp_len = len1 + 1; + start_i = start_j = end_i = end_j = 0; + for (i = 0, max_score = 0; i != N_MATRIX_ROW * N_MATRIX_ROW; ++i) + if (max_score < score_matrix[i]) max_score = score_matrix[i]; + /* convert the coordinate */ + --seq1; --seq2; + for (i = 0; i != N_MATRIX_ROW; ++i) --s_array[i]; + + /* forward dynamic programming */ + for (i = 0, s = eh; i != tmp_len; ++i, ++s) *s = 0; + score_f = 0; + is_overflow = of_base = 0; + suba[0] = 0; + for (j = 1, ss = suba + 1; j <= len2; ++j, ++ss) { + int subo = 0; + last_h = f = 0; + score_array = s_array[seq2[j]]; + if (is_overflow) { /* adjust eh[] array if overflow occurs. */ + /* If LOCAL_OVERFLOW_REDUCE is too small, optimal alignment might be missed. + * If it is too large, this block will be excuted frequently and therefore + * slow down the whole program. + * Acually, smaller LOCAL_OVERFLOW_REDUCE might also help to reduce the + * number of assignments because it sets some cells to zero when overflow + * happens. */ + int tmp, tmp2; + score_f -= LOCAL_OVERFLOW_REDUCE; + of_base += LOCAL_OVERFLOW_REDUCE; + is_overflow = 0; + for (i = 1, s = eh; i <= tmp_len; ++i, ++s) { + tmp = *s >> NT_LOCAL_SHIFT; tmp2 = *s & NT_LOCAL_MASK; + if (tmp2 < LOCAL_OVERFLOW_REDUCE) tmp2 = 0; + else tmp2 -= LOCAL_OVERFLOW_REDUCE; + if (tmp < LOCAL_OVERFLOW_REDUCE) tmp = 0; + else tmp -= LOCAL_OVERFLOW_REDUCE; + *s = (tmp << NT_LOCAL_SHIFT) | tmp2; + } + } + for (i = 1, s = eh; i != tmp_len; ++i, ++s) { + /* prepare for calculate current h */ + curr_h = (*s >> NT_LOCAL_SHIFT) + score_array[i]; + if (curr_h < 0) curr_h = 0; + if (last_h > 0) { /* initialize f */ + f = (f > last_h - q)? f - r : last_h - qr; + if (curr_h < f) curr_h = f; + } + if (*(s+1) >= qr_shift) { /* initialize e */ + curr_last_h = *(s+1) >> NT_LOCAL_SHIFT; + e = ((*s & NT_LOCAL_MASK) > curr_last_h - q)? (*s & NT_LOCAL_MASK) - r : curr_last_h - qr; + if (curr_h < e) curr_h = e; + *s = (last_h << NT_LOCAL_SHIFT) | e; + } else *s = last_h << NT_LOCAL_SHIFT; /* e = 0 */ + last_h = curr_h; + if (subo < curr_h) subo = curr_h; + if (score_f < curr_h) { + score_f = curr_h; end_i = i; end_j = j; + if (score_f > LOCAL_OVERFLOW_THRESHOLD) is_overflow = 1; + } + } + *s = last_h << NT_LOCAL_SHIFT; + *ss = subo + of_base; + } + score_f += of_base; + + if (score_f < thres) { /* no matching residue at all, 090218 */ + *path_len = 0; + goto end_func; + } + if (path == 0) goto end_func; /* skip path-filling */ + + /* reverse dynamic programming */ + for (i = end_i, s = eh + end_i; i >= 0; --i, --s) *s = 0; + if (end_i == 0 || end_j == 0) goto end_func; /* no local match */ + score_r = score_matrix[seq1[end_i] * N_MATRIX_ROW + seq2[end_j]]; + is_overflow = of_base = 0; + start_i = end_i; start_j = end_j; + eh[end_i] = ((NT_LOCAL_SCORE)(qr + score_r)) << NT_LOCAL_SHIFT; /* in order to initialize f and e, 040408 */ + start = end_i - 1; + end = end_i - 3; + if (end <= 0) end = 0; + + /* second pass DP can be done in a band, speed will thus be enhanced */ + for (j = end_j - 1; j != 0; --j) { + last_h = f = 0; + score_array = s_array[seq2[j]]; + if (is_overflow) { /* adjust eh[] array if overflow occurs. */ + int tmp, tmp2; + score_r -= LOCAL_OVERFLOW_REDUCE; + of_base += LOCAL_OVERFLOW_REDUCE; + is_overflow = 0; + for (i = start, s = eh + start + 1; i >= end; --i, --s) { + tmp = *s >> NT_LOCAL_SHIFT; tmp2 = *s & NT_LOCAL_MASK; + if (tmp2 < LOCAL_OVERFLOW_REDUCE) tmp2 = 0; + else tmp2 -= LOCAL_OVERFLOW_REDUCE; + if (tmp < LOCAL_OVERFLOW_REDUCE) tmp = 0; + else tmp -= LOCAL_OVERFLOW_REDUCE; + *s = (tmp << NT_LOCAL_SHIFT) | tmp2; + } + } + for (i = start, s = eh + start + 1; i != end; --i, --s) { + /* prepare for calculate current h */ + curr_h = (*s >> NT_LOCAL_SHIFT) + score_array[i]; + if (curr_h < 0) curr_h = 0; + if (last_h > 0) { /* initialize f */ + f = (f > last_h - q)? f - r : last_h - qr; + if (curr_h < f) curr_h = f; + } + curr_last_h = *(s-1) >> NT_LOCAL_SHIFT; + e = ((*s & NT_LOCAL_MASK) > curr_last_h - q)? (*s & NT_LOCAL_MASK) - r : curr_last_h - qr; + if (e < 0) e = 0; + if (curr_h < e) curr_h = e; + *s = (last_h << NT_LOCAL_SHIFT) | e; + last_h = curr_h; + if (score_r < curr_h) { + score_r = curr_h; start_i = i; start_j = j; + if (score_r + of_base - qr == score_f) { + j = 1; break; + } + if (score_r > LOCAL_OVERFLOW_THRESHOLD) is_overflow = 1; + } + } + *s = last_h << NT_LOCAL_SHIFT; + /* recalculate start and end, the boundaries of the band */ + if ((eh[start] >> NT_LOCAL_SHIFT) <= qr) --start; + if (start <= 0) start = 0; + end = start_i - (start_j - j) - (score_r + of_base + (start_j - j) * max_score) / r - 1; + if (end <= 0) end = 0; + } + + if (_subo) { + int tmp2 = 0, tmp = (int)(start_j - .33 * (end_j - start_j) + .499); + for (j = 1; j <= tmp; ++j) + if (tmp2 < suba[j]) tmp2 = suba[j]; + tmp = (int)(end_j + .33 * (end_j - start_j) + .499); + for (j = tmp; j <= len2; ++j) + if (tmp2 < suba[j]) tmp2 = suba[j]; + *_subo = tmp2; + } + + if (path_len == 0) { + path[0].i = start_i; path[0].j = start_j; + path[1].i = end_i; path[1].j = end_j; + goto end_func; + } + + score_r += of_base; + score_r -= qr; + +#ifdef DEBUG + /* this seems not a bug */ + if (score_f != score_r) + fprintf(stderr, "[aln_local_core] unknown flaw occurs: score_f(%d) != score_r(%d)\n", score_f, score_r); +#endif + + if (_thres > 0) { /* call global alignment to fill the path */ + score_g = 0; + j = (end_i - start_i > end_j - start_j)? end_i - start_i : end_j - start_j; + ++j; /* j is the maximum band_width */ + for (i = ap->band_width;; i <<= 1) { + AlnParam ap_real = *ap; + ap_real.gap_end = -1; + ap_real.band_width = i; + score_g = aln_global_core(seq1 + start_i, end_i - start_i + 1, seq2 + start_j, + end_j - start_j + 1, &ap_real, path, path_len); + if (score_g == score_r || score_f == score_g) break; + if (i > j) break; + } + if (score_r > score_g && score_f > score_g) { + fprintf(stderr, "[aln_local_core] Potential bug: (%d,%d) > %d\n", score_f, score_r, score_g); + score_f = score_r = -1; + } else score_f = score_g; + + /* convert coordinate */ + for (p = path + *path_len - 1; p >= path; --p) { + p->i += start_i - 1; + p->j += start_j - 1; + } + } else { /* just store the start and end */ + *path_len = 2; + path[1].i = start_i; path[1].j = start_j; + path->i = end_i; path->j = end_j; + } + +end_func: + /* free */ + free(eh); free(suba); + for (i = 0; i != N_MATRIX_ROW; ++i) { + ++s_array[i]; + free(s_array[i]); + } + free(s_array); + return score_f; +} +AlnAln *aln_stdaln_aux(const char *seq1, const char *seq2, const AlnParam *ap, + int type, int thres, int len1, int len2) +{ + unsigned char *seq11, *seq22; + int score; + int i, j, l; + path_t *p; + char *out1, *out2, *outm; + AlnAln *aa; + + if (len1 < 0) len1 = strlen(seq1); + if (len2 < 0) len2 = strlen(seq2); + + aa = aln_init_AlnAln(); + seq11 = (unsigned char*)malloc(sizeof(unsigned char) * len1); + seq22 = (unsigned char*)malloc(sizeof(unsigned char) * len2); + aa->path = (path_t*)malloc(sizeof(path_t) * (len1 + len2 + 1)); + + if (ap->row < 10) { /* 4-nucleotide alignment */ + for (i = 0; i < len1; ++i) + seq11[i] = aln_nt4_table[(int)seq1[i]]; + for (j = 0; j < len2; ++j) + seq22[j] = aln_nt4_table[(int)seq2[j]]; + } else if (ap->row < 20) { /* 16-nucleotide alignment */ + for (i = 0; i < len1; ++i) + seq11[i] = aln_nt16_table[(int)seq1[i]]; + for (j = 0; j < len2; ++j) + seq22[j] = aln_nt16_table[(int)seq2[j]]; + } else { /* amino acids */ + for (i = 0; i < len1; ++i) + seq11[i] = aln_aa_table[(int)seq1[i]]; + for (j = 0; j < len2; ++j) + seq22[j] = aln_aa_table[(int)seq2[j]]; + } + + if (type == ALN_TYPE_GLOBAL) score = aln_global_core(seq11, len1, seq22, len2, ap, aa->path, &aa->path_len); + else if (type == ALN_TYPE_LOCAL) score = aln_local_core(seq11, len1, seq22, len2, ap, aa->path, &aa->path_len, thres, &aa->subo); + else if (type == ALN_TYPE_EXTEND) score = aln_extend_core(seq11, len1, seq22, len2, ap, aa->path, &aa->path_len, 1, 0); + else { + free(seq11); free(seq22); free(aa->path); + aln_free_AlnAln(aa); + return 0; + } + aa->score = score; + + if (thres > 0) { + out1 = aa->out1 = (char*)malloc(sizeof(char) * (aa->path_len + 1)); + out2 = aa->out2 = (char*)malloc(sizeof(char) * (aa->path_len + 1)); + outm = aa->outm = (char*)malloc(sizeof(char) * (aa->path_len + 1)); + + --seq1; --seq2; + --seq11; --seq22; + + p = aa->path + aa->path_len - 1; + + for (l = 0; p >= aa->path; --p, ++l) { + switch (p->ctype) { + case FROM_M: out1[l] = seq1[p->i]; out2[l] = seq2[p->j]; + outm[l] = (seq11[p->i] == seq22[p->j] && seq11[p->i] != ap->row)? '|' : ' '; + break; + case FROM_I: out1[l] = '-'; out2[l] = seq2[p->j]; outm[l] = ' '; break; + case FROM_D: out1[l] = seq1[p->i]; out2[l] = '-'; outm[l] = ' '; break; + } + } + out1[l] = out2[l] = outm[l] = '\0'; + ++seq11; ++seq22; + } + + free(seq11); + free(seq22); + + p = aa->path + aa->path_len - 1; + aa->start1 = p->i? p->i : 1; + aa->end1 = aa->path->i; + aa->start2 = p->j? p->j : 1; + aa->end2 = aa->path->j; + aa->cigar32 = aln_path2cigar32(aa->path, aa->path_len, &aa->n_cigar); + + return aa; +} +AlnAln *aln_stdaln(const char *seq1, const char *seq2, const AlnParam *ap, int type, int thres) +{ + return aln_stdaln_aux(seq1, seq2, ap, type, thres, -1, -1); +} + +/* for backward compatibility */ +uint16_t *aln_path2cigar(const path_t *path, int path_len, int *n_cigar) +{ + uint32_t *cigar32; + uint16_t *cigar; + int i; + cigar32 = aln_path2cigar32(path, path_len, n_cigar); + cigar = (uint16_t*)cigar32; + for (i = 0; i < *n_cigar; ++i) + cigar[i] = (cigar32[i]&0xf)<<14 | (cigar32[i]>>4&0x3fff); + return cigar; +} + +/* newly added functions (2009-07-21) */ + +int aln_extend_core(unsigned char *seq1, int len1, unsigned char *seq2, int len2, const AlnParam *ap, + path_t *path, int *path_len, int G0, uint8_t *_mem) +{ + int q, r, qr, tmp_len; + int32_t **s_array, *score_array; + int is_overflow, of_base; + uint32_t *eh; + int i, j, end_i, end_j; + int score, start, end; + int *score_matrix, N_MATRIX_ROW; + uint8_t *mem, *_p; + + /* initialize some align-related parameters. just for compatibility */ + q = ap->gap_open; + r = ap->gap_ext; + qr = q + r; + score_matrix = ap->matrix; + N_MATRIX_ROW = ap->row; + + if (len1 == 0 || len2 == 0) return -1; + + /* allocate memory */ + mem = _mem? _mem : calloc((len1 + 2) * (N_MATRIX_ROW + 1), 4); + _p = mem; + eh = (uint32_t*)_p, _p += 4 * (len1 + 2); + s_array = calloc(N_MATRIX_ROW, sizeof(void*)); + for (i = 0; i != N_MATRIX_ROW; ++i) + s_array[i] = (int32_t*)_p, _p += 4 * len1; + /* initialization */ + aln_init_score_array(seq1, len1, N_MATRIX_ROW, score_matrix, s_array); + tmp_len = len1 + 1; + start = 1; end = 2; + end_i = end_j = 0; + score = 0; + is_overflow = of_base = 0; + /* convert the coordinate */ + --seq1; --seq2; + for (i = 0; i != N_MATRIX_ROW; ++i) --s_array[i]; + + /* dynamic programming */ + memset(eh, 0, 4 * (len1 + 2)); + eh[1] = (uint32_t)G0<<16; + for (j = 1; j <= len2; ++j) { + int _start, _end; + int h1 = 0, f = 0; + score_array = s_array[seq2[j]]; + /* set start and end */ + _start = j - ap->band_width; + if (_start < 1) _start = 1; + if (_start > start) start = _start; + _end = j + ap->band_width; + if (_end > len1 + 1) _end = len1 + 1; + if (_end < end) end = _end; + if (start == end) break; + /* adjust eh[] array if overflow occurs. */ + if (is_overflow) { + int tmp, tmp2; + score -= LOCAL_OVERFLOW_REDUCE; + of_base += LOCAL_OVERFLOW_REDUCE; + is_overflow = 0; + for (i = start; i <= end; ++i) { + uint32_t *s = &eh[i]; + tmp = *s >> 16; tmp2 = *s & 0xffff; + if (tmp2 < LOCAL_OVERFLOW_REDUCE) tmp2 = 0; + else tmp2 -= LOCAL_OVERFLOW_REDUCE; + if (tmp < LOCAL_OVERFLOW_REDUCE) tmp = 0; + else tmp -= LOCAL_OVERFLOW_REDUCE; + *s = (tmp << 16) | tmp2; + } + } + _start = _end = 0; + /* the inner loop */ + for (i = start; i < end; ++i) { + /* At the beginning of each cycle: + eh[i] -> h[j-1,i-1]<<16 | e[j,i] + f -> f[j,i] + h1 -> h[j,i-1] + */ + uint32_t *s = &eh[i]; + int h = (int)(*s >> 16); + int e = *s & 0xffff; /* this is e[j,i] */ + *s = (uint32_t)h1 << 16; /* eh[i] now stores h[j,i-1]<<16 */ + h += h? score_array[i] : 0; /* this is left_core() specific */ + /* calculate h[j,i]; don't need to test 0, as {e,f}>=0 */ + h = h > e? h : e; + h = h > f? h : f; /* h now is h[j,i] */ + h1 = h; + if (h > 0) { + if (_start == 0) _start = i; + _end = i; + if (score < h) { + score = h; end_i = i; end_j = j; + if (score > LOCAL_OVERFLOW_THRESHOLD) is_overflow = 1; + } + } + /* calculate e[j+1,i] and f[j,i+1] */ + h -= qr; + h = h > 0? h : 0; + e -= r; + e = e > h? e : h; + f -= r; + f = f > h? f : h; + *s |= e; + } + eh[end] = h1 << 16; + /* recalculate start and end, the boundaries of the band */ + if (_end <= 0) break; /* no cell in this row has a positive score */ + start = _start; + end = _end + 3; + } + + score += of_base - 1; + if (score <= 0) { + if (path_len) *path_len = 0; + goto end_left_func; + } + + if (path == 0) goto end_left_func; + + if (path_len == 0) { + path[0].i = end_i; path[0].j = end_j; + goto end_left_func; + } + + { /* call global alignment to fill the path */ + int score_g = 0; + j = (end_i - 1 > end_j - 1)? end_i - 1 : end_j - 1; + ++j; /* j is the maximum band_width */ + for (i = ap->band_width;; i <<= 1) { + AlnParam ap_real = *ap; + ap_real.gap_end = -1; + ap_real.band_width = i; + score_g = aln_global_core(seq1 + 1, end_i, seq2 + 1, end_j, &ap_real, path, path_len); + if (score == score_g) break; + if (i > j) break; + } + if (score > score_g) + fprintf(stderr, "[aln_left_core] no suitable bandwidth: %d < %d\n", score_g, score); + score = score_g; + } + +end_left_func: + /* free */ + free(s_array); + if (!_mem) free(mem); + return score; +} + +uint32_t *aln_path2cigar32(const path_t *path, int path_len, int *n_cigar) +{ + int i, n; + uint32_t *cigar; + unsigned char last_type; + + if (path_len == 0 || path == 0) { + *n_cigar = 0; + return 0; + } + + last_type = path->ctype; + for (i = n = 1; i < path_len; ++i) { + if (last_type != path[i].ctype) ++n; + last_type = path[i].ctype; + } + *n_cigar = n; + cigar = (uint32_t*)malloc(*n_cigar * 4); + + cigar[0] = 1u << 4 | path[path_len-1].ctype; + last_type = path[path_len-1].ctype; + for (i = path_len - 2, n = 0; i >= 0; --i) { + if (path[i].ctype == last_type) cigar[n] += 1u << 4; + else { + cigar[++n] = 1u << 4 | path[i].ctype; + last_type = path[i].ctype; + } + } + + return cigar; +} + +#ifdef STDALN_MAIN +int main() +{ + AlnAln *aln_local, *aln_global, *aln_left; + int i; + + aln_local = aln_stdaln("CGTGCGATGCactgCATACGGCTCGCCTAGATCA", "AAGGGATGCTCTGCATCgCTCGGCTAGCTGT", &aln_param_blast, 0, 1); + aln_global = aln_stdaln("CGTGCGATGCactgCATACGGCTCGCCTAGATCA", "AAGGGATGCTCTGCATCGgCTCGGCTAGCTGT", &aln_param_blast, 1, 1); +// aln_left = aln_stdaln( "GATGCACTGCATACGGCTCGCCTAGATCA", "GATGCTCTGCATCGgCTCGGCTAGCTGT", &aln_param_blast, 2, 1); + aln_left = aln_stdaln("CACCTTCGACTCACGTCTCATTCTCGGAGTCGAGTGGACGGTCCCTCATACACGAACAGGTTC", + "CACCTTCGACTTTCACCTCTCATTCTCGGACTCGAGTGGACGGTCCCTCATCCAAGAACAGGGTCTGTGAAA", &aln_param_blast, 2, 1); + + printf(">%d,%d\t%d,%d\n", aln_local->start1, aln_local->end1, aln_local->start2, aln_local->end2); + printf("%s\n%s\n%s\n", aln_local->out1, aln_local->outm, aln_local->out2); + + printf(">%d,%d\t%d,%d\t", aln_global->start1, aln_global->end1, aln_global->start2, aln_global->end2); + for (i = 0; i != aln_global->n_cigar; ++i) + printf("%d%c", aln_global->cigar32[i]>>4, "MID"[aln_global->cigar32[i]&0xf]); + printf("\n%s\n%s\n%s\n", aln_global->out1, aln_global->outm, aln_global->out2); + + printf(">%d\t%d,%d\t%d,%d\t", aln_left->score, aln_left->start1, aln_left->end1, aln_left->start2, aln_left->end2); + for (i = 0; i != aln_left->n_cigar; ++i) + printf("%d%c", aln_left->cigar32[i]>>4, "MID"[aln_left->cigar32[i]&0xf]); + printf("\n%s\n%s\n%s\n", aln_left->out1, aln_left->outm, aln_left->out2); + + aln_free_AlnAln(aln_local); + aln_free_AlnAln(aln_global); + aln_free_AlnAln(aln_left); + return 0; +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/stdaln.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,162 @@ +/* The MIT License + + Copyright (c) 2003-2006, 2008, by Heng Li <lh3lh3@gmail.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* + 2009-07-23, 0.10.0 + + - Use 32-bit to store CIGAR + + - Report suboptimal aligments + + - Implemented half-fixed-half-open DP + + 2009-04-26, 0.9.10 + + - Allow to set a threshold for local alignment + + 2009-02-18, 0.9.9 + + - Fixed a bug when no residue matches + + 2008-08-04, 0.9.8 + + - Fixed the wrong declaration of aln_stdaln_aux() + + - Avoid 0 coordinate for global alignment + + 2008-08-01, 0.9.7 + + - Change gap_end penalty to 5 in aln_param_bwa + + - Add function to convert path_t to the CIGAR format + + 2008-08-01, 0.9.6 + + - The first gap now costs (gap_open+gap_ext), instead of + gap_open. Scoring systems are modified accordingly. + + - Gap end is now correctly handled. Previously it is not correct. + + - Change license to MIT. + + */ + +#ifndef LH3_STDALN_H_ +#define LH3_STDALN_H_ + + +#define STDALN_VERSION 0.11.0 + +#include <stdint.h> + +#define FROM_M 0 +#define FROM_I 1 +#define FROM_D 2 +#define FROM_S 3 + +#define ALN_TYPE_LOCAL 0 +#define ALN_TYPE_GLOBAL 1 +#define ALN_TYPE_EXTEND 2 + +/* This is the smallest integer. It might be CPU-dependent in very RARE cases. */ +#define MINOR_INF -1073741823 + +typedef struct +{ + int gap_open; + int gap_ext; + int gap_end; + + int *matrix; + int row; + int band_width; +} AlnParam; + +typedef struct +{ + int i, j; + unsigned char ctype; +} path_t; + +typedef struct +{ + path_t *path; /* for advanced users... :-) */ + int path_len; /* for advanced users... :-) */ + int start1, end1; /* start and end of the first sequence, coordinations are 1-based */ + int start2, end2; /* start and end of the second sequence, coordinations are 1-based */ + int score, subo; /* score */ + + char *out1, *out2; /* print them, and then you will know */ + char *outm; + + int n_cigar; + uint32_t *cigar32; +} AlnAln; + +#ifdef __cplusplus +extern "C" { +#endif + + AlnAln *aln_stdaln_aux(const char *seq1, const char *seq2, const AlnParam *ap, + int type, int do_align, int len1, int len2); + AlnAln *aln_stdaln(const char *seq1, const char *seq2, const AlnParam *ap, int type, int do_align); + void aln_free_AlnAln(AlnAln *aa); + + int aln_global_core(unsigned char *seq1, int len1, unsigned char *seq2, int len2, const AlnParam *ap, + path_t *path, int *path_len); + int aln_local_core(unsigned char *seq1, int len1, unsigned char *seq2, int len2, const AlnParam *ap, + path_t *path, int *path_len, int _thres, int *_subo); + int aln_extend_core(unsigned char *seq1, int len1, unsigned char *seq2, int len2, const AlnParam *ap, + path_t *path, int *path_len, int G0, uint8_t *_mem); + uint16_t *aln_path2cigar(const path_t *path, int path_len, int *n_cigar); + uint32_t *aln_path2cigar32(const path_t *path, int path_len, int *n_cigar); + +#ifdef __cplusplus +} +#endif + +/******************** + * global variables * + ********************/ + +extern AlnParam aln_param_bwa; /* = { 37, 9, 0, aln_sm_maq, 5, 50 }; */ +extern AlnParam aln_param_blast; /* = { 5, 2, 2, aln_sm_blast, 5, 50 }; */ +extern AlnParam aln_param_nt2nt; /* = { 10, 2, 2, aln_sm_nt, 16, 75 }; */ +extern AlnParam aln_param_aa2aa; /* = { 20, 19, 19, aln_sm_read, 16, 75 }; */ +extern AlnParam aln_param_rd2rd; /* = { 12, 2, 2, aln_sm_blosum62, 22, 50 }; */ + +/* common nucleotide score matrix for 16 bases */ +extern int aln_sm_nt[]; + +/* BLOSUM62 and BLOSUM45 */ +extern int aln_sm_blosum62[], aln_sm_blosum45[]; + +/* common read for 16 bases. note that read alignment is quite different from common nucleotide alignment */ +extern int aln_sm_read[]; + +/* human-mouse score matrix for 4 bases */ +extern int aln_sm_hs[]; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/utils.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,72 @@ +/* The MIT License + + Copyright (c) 2008 Genome Research Ltd (GRL). + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* Contact: Heng Li <lh3@sanger.ac.uk> */ + +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <zlib.h> +#include "utils.h" + +FILE *err_xopen_core(const char *func, const char *fn, const char *mode) +{ + FILE *fp = 0; + if (strcmp(fn, "-") == 0) + return (strstr(mode, "r"))? stdin : stdout; + if ((fp = fopen(fn, mode)) == 0) { + fprintf(stderr, "[%s] fail to open file '%s'. Abort!\n", func, fn); + abort(); + } + return fp; +} +gzFile err_xzopen_core(const char *func, const char *fn, const char *mode) +{ + gzFile fp; + if (strcmp(fn, "-") == 0) + return gzdopen(fileno((strstr(mode, "r"))? stdin : stdout), mode); + if ((fp = gzopen(fn, mode)) == 0) { + fprintf(stderr, "[%s] fail to open file '%s'. Abort!\n", func, fn); + abort(); + } + return fp; +} +void err_fatal(const char *header, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + fprintf(stderr, "[%s] ", header); + vfprintf(stderr, fmt, args); + fprintf(stderr, " Abort!\n"); + va_end(args); + abort(); +} + +void err_fatal_simple_core(const char *func, const char *msg) +{ + fprintf(stderr, "[%s] %s Abort!\n", func, msg); + abort(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/bwa-0.5.7-mh/utils.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,52 @@ +/* The MIT License + + Copyright (c) 2008 Genome Research Ltd (GRL). + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* Contact: Heng Li <lh3@sanger.ac.uk> */ + +#ifndef LH3_UTILS_H +#define LH3_UTILS_H + +#include <stdio.h> +#include <zlib.h> + +#define err_fatal_simple(msg) err_fatal_simple_core(__func__, msg) +#define xopen(fn, mode) err_xopen_core(__func__, fn, mode) +#define xzopen(fn, mode) err_xzopen_core(__func__, fn, mode) +#define xassert(cond, msg) if ((cond) == 0) err_fatal_simple_core(__func__, msg) + +#ifdef __cplusplus +extern "C" { +#endif + + void err_fatal(const char *header, const char *fmt, ...); + void err_fatal_simple_core(const char *func, const char *msg); + FILE *err_xopen_core(const char *func, const char *fn, const char *mode); + gzFile err_xzopen_core(const char *func, const char *fn, const char *mode); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/AUTHORS Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,20 @@ +Heng Li from the Sanger Institute wrote most of the initial source codes +of SAMtools and various converters. + +Bob Handsaker from the Broad Institute is a major contributor to the +SAM/BAM specification. He designed and implemented the BGZF format, the +underlying indexable compression format for the BAM format. BGZF does +not support arithmetic between file offsets. + +Jue Ruan for the Beijing Genome Institute designed and implemented the +RAZF format, an alternative indexable compression format. RAZF supports +arithmetic between file offsets, at the cost of increased index file +size and the full compatibility with gzip. RAZF is optional and only +used in `faidx' for indexing RAZF compressed fasta files. + +Colin Hercus updated novo2sam.pl to support gapped alignment by +novoalign. + +Petr Danecek contributed the header parsing library sam_header.c and +sam2vcf.pl script and added knet support to the RAZF library. +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/COPYING Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2008-2009 Genome Research Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/ChangeLog Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,5948 @@ +------------------------------------------------------------------------ +r925 | lh3lh3 | 2011-02-28 15:45:17 -0500 (Mon, 28 Feb 2011) | 2 lines +Changed paths: + M /trunk/samtools/phase.c + +minor changes to a heuristic rule + +------------------------------------------------------------------------ +r924 | lh3lh3 | 2011-02-28 15:24:04 -0500 (Mon, 28 Feb 2011) | 4 lines +Changed paths: + M /trunk/samtools/bam.h + M /trunk/samtools/bcftools/vcfutils.pl + M /trunk/samtools/phase.c + + * 0.1.12-r924:126 + * fixed a bug in phase (due to recent changes) + * fixed a bug in vcf2fq + +------------------------------------------------------------------------ +r923 | lh3lh3 | 2011-02-28 12:57:39 -0500 (Mon, 28 Feb 2011) | 5 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/bam.h + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/phase.c + + * put version number in bam.h + * write version to BCF + * in phase, change the default -q to 37 + * output a little more information during phasing + +------------------------------------------------------------------------ +r922 | lh3lh3 | 2011-02-25 16:40:09 -0500 (Fri, 25 Feb 2011) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/bcftools/bcf.c + M /trunk/samtools/bcftools/bcf.tex + M /trunk/samtools/bcftools/bcf2qcall.c + M /trunk/samtools/bcftools/bcfutils.c + M /trunk/samtools/bcftools/ld.c + M /trunk/samtools/bcftools/prob1.c + M /trunk/samtools/bcftools/vcf.c + M /trunk/samtools/cut_target.c + + * change the order of PL/GL according to the latest VCF spec + * change the type of SP to int32_t + +------------------------------------------------------------------------ +r921 | lh3lh3 | 2011-02-25 14:40:56 -0500 (Fri, 25 Feb 2011) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/bcf.tex + +update the BCF spec + +------------------------------------------------------------------------ +r920 | lh3lh3 | 2011-02-25 00:59:27 -0500 (Fri, 25 Feb 2011) | 2 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/bam_md.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bam_sort.c + M /trunk/samtools/bamtk.c + A /trunk/samtools/cut_target.c + M /trunk/samtools/errmod.h + M /trunk/samtools/faidx.c + M /trunk/samtools/khash.h + M /trunk/samtools/kstring.c + M /trunk/samtools/kstring.h + A /trunk/samtools/phase.c + M /trunk/samtools/samtools.1 + +added the phase command + +------------------------------------------------------------------------ +r918 | lh3lh3 | 2011-02-24 10:05:54 -0500 (Thu, 24 Feb 2011) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/prob1.c + M /trunk/samtools/bcftools/prob1.h + +added "const" to bcf_p1_cal() + +------------------------------------------------------------------------ +r917 | lh3lh3 | 2011-02-24 09:36:30 -0500 (Thu, 24 Feb 2011) | 2 lines +Changed paths: + M /trunk/samtools/bam.c + +more meaningful BAM truncation message + +------------------------------------------------------------------------ +r916 | lh3lh3 | 2011-02-24 09:35:06 -0500 (Thu, 24 Feb 2011) | 3 lines +Changed paths: + M /trunk/samtools/bcftools/bcf.c + M /trunk/samtools/bcftools/vcf.c + + * automatically fix errors in GL + * output unrecognized FORMAT as "." + +------------------------------------------------------------------------ +r913 | lh3lh3 | 2011-02-10 22:59:47 -0500 (Thu, 10 Feb 2011) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/bcf.h + M /trunk/samtools/bcftools/call1.c + M /trunk/samtools/bcftools/vcf.c + +finished VCF->BCF conversion + +------------------------------------------------------------------------ +r910 | petulda | 2011-02-03 03:13:48 -0500 (Thu, 03 Feb 2011) | 1 line +Changed paths: + M /trunk/samtools/bcftools/vcfutils.pl + +Prevent division by zero +------------------------------------------------------------------------ +r909 | lh3lh3 | 2011-02-02 11:29:20 -0500 (Wed, 02 Feb 2011) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/call1.c + +fixed a typo in the VCF header + +------------------------------------------------------------------------ +r908 | lh3lh3 | 2011-02-02 11:28:24 -0500 (Wed, 02 Feb 2011) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam_index.c + + * fixed an out-of-boundary bug + * improved sorting order checking in index + +------------------------------------------------------------------------ +r907 | lh3lh3 | 2011-01-29 22:59:20 -0500 (Sat, 29 Jan 2011) | 4 lines +Changed paths: + M /trunk/samtools/INSTALL + M /trunk/samtools/bam_tview.c + M /trunk/samtools/knetfile.c + + * avoid a segfault when network connect fails + * update INSTALL + * fixed a bug in tview on big-endian by Nathan Weeks + +------------------------------------------------------------------------ +r903 | lh3lh3 | 2011-01-27 14:50:02 -0500 (Thu, 27 Jan 2011) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bam_md.c + + * fixed a rare memory issue in bam_md.c + * fixed a bug in indel calling related to unmapped and refskip reads + +------------------------------------------------------------------------ +r902 | lh3lh3 | 2011-01-23 21:46:18 -0500 (Sun, 23 Jan 2011) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/fet.c + +fixed two minor bugs in Fisher's exact test + +------------------------------------------------------------------------ +r899 | petulda | 2011-01-19 09:28:02 -0500 (Wed, 19 Jan 2011) | 1 line +Changed paths: + M /trunk/samtools/bcftools/vcfutils.pl + +Skip sites with unknown ref +------------------------------------------------------------------------ +r898 | lh3lh3 | 2011-01-15 12:56:05 -0500 (Sat, 15 Jan 2011) | 2 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bam_md.c + +move bam_nt16_nt4_table[] from bam_maqcns.c to bam_md.c + +------------------------------------------------------------------------ +r896 | lh3lh3 | 2011-01-06 10:52:15 -0500 (Thu, 06 Jan 2011) | 3 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/bcftools/bcf.h + M /trunk/samtools/bcftools/bcfutils.c + M /trunk/samtools/bcftools/call1.c + + * samtools-0.1.12-10 (r896) + * allow to exclude read groups in mpileup + +------------------------------------------------------------------------ +r895 | lh3lh3 | 2011-01-04 11:31:29 -0500 (Tue, 04 Jan 2011) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/bcf.tex + +sorry. It is SP not ST + +------------------------------------------------------------------------ +r894 | lh3lh3 | 2011-01-04 11:29:06 -0500 (Tue, 04 Jan 2011) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/bcf.tex + +added ST + +------------------------------------------------------------------------ +r893 | petulda | 2011-01-04 06:55:56 -0500 (Tue, 04 Jan 2011) | 1 line +Changed paths: + M /trunk/samtools/bcftools/call1.c + +Fixed a typo in read_samples +------------------------------------------------------------------------ +r892 | jmarshall | 2010-12-28 08:06:49 -0500 (Tue, 28 Dec 2010) | 9 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/bcftools/Makefile + M /trunk/samtools/examples/Makefile + +System libraries go *after* user libraries in link commands, because +the user libraries may themselves have dependencies that are satisfied +by the system libraries. It's not rocket science! + +This makes a difference with some linkers; or with -static or --as-needed. + +The examples/Makefile fix is from Charles Plessy. +See also http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=606004 + +------------------------------------------------------------------------ +r891 | lh3lh3 | 2010-12-21 12:16:33 -0500 (Tue, 21 Dec 2010) | 3 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/bcftools/bcf.h + M /trunk/samtools/bcftools/bcfutils.c + M /trunk/samtools/bcftools/call1.c + + * samtools-0.1.12-9 (r891) + * allow to call SNPs from a subset of samples + +------------------------------------------------------------------------ +r889 | lh3lh3 | 2010-12-15 11:28:16 -0500 (Wed, 15 Dec 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.12-12 (r889) + * set mapQ as 20 if it equals 255 + +------------------------------------------------------------------------ +r888 | lh3lh3 | 2010-12-14 22:41:09 -0500 (Tue, 14 Dec 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + +When -B is applied to mpileup, still use paired reads only unless -A is flagged. + +------------------------------------------------------------------------ +r887 | lh3lh3 | 2010-12-14 22:37:05 -0500 (Tue, 14 Dec 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam_md.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.12-6 (r887) + * added a hidden option -E to mpileup/calmd. -E triggers an alternative way to apply BAQ. + +------------------------------------------------------------------------ +r886 | lh3lh3 | 2010-12-14 12:51:03 -0500 (Tue, 14 Dec 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bamtk.c + +(Arguably) improved the indel caller a tiny bit for lowCov data. + +------------------------------------------------------------------------ +r885 | petulda | 2010-12-14 04:55:46 -0500 (Tue, 14 Dec 2010) | 1 line +Changed paths: + M /trunk/samtools/bcftools/call1.c + +Fixed the VCF header to pass validation +------------------------------------------------------------------------ +r884 | lh3lh3 | 2010-12-12 23:02:19 -0500 (Sun, 12 Dec 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/bcftools/vcfutils.pl + + * samtools-0.1.12-4 (r884) + * fixed a long-existing flaw in the INDEL calling model + +------------------------------------------------------------------------ +r883 | lh3lh3 | 2010-12-11 20:05:42 -0500 (Sat, 11 Dec 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/bcfutils.c + M /trunk/samtools/bcftools/call1.c + M /trunk/samtools/bcftools/vcfutils.pl + +compute max SP and max GQ from sample genotypes + +------------------------------------------------------------------------ +r880 | lh3lh3 | 2010-12-10 10:50:54 -0500 (Fri, 10 Dec 2010) | 2 lines +Changed paths: + D /trunk/samtools/bcftools/bcf-fix.pl + +drop bcf-fix.pl as it is redundant by the latest changes + +------------------------------------------------------------------------ +r879 | lh3lh3 | 2010-12-10 10:50:29 -0500 (Fri, 10 Dec 2010) | 3 lines +Changed paths: + M /trunk/samtools/bcftools/call1.c + M /trunk/samtools/bcftools/vcf.c + + * fixed a minor issue in printing VCFs + * write bcftools specific INFO and FORMAT in the header + +------------------------------------------------------------------------ +r878 | lh3lh3 | 2010-12-10 10:09:14 -0500 (Fri, 10 Dec 2010) | 2 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/bcftools/bcfutils.c + M /trunk/samtools/bcftools/call1.c + +Make sure that the GT genotype field is the first + +------------------------------------------------------------------------ +r877 | lh3lh3 | 2010-12-08 17:27:05 -0500 (Wed, 08 Dec 2010) | 7 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf.h + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.12-2 (r877) + + * allow to fine control the selection of indel candidates. The current + setting is okay for lowCov and highCov with ~100 samples, but it + skips too many indels for highCov with >250 samples. + + +------------------------------------------------------------------------ +r874 | lh3lh3 | 2010-12-07 22:40:35 -0500 (Tue, 07 Dec 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + +a spelling error.. + +------------------------------------------------------------------------ +r873 | lh3lh3 | 2010-12-07 22:39:57 -0500 (Tue, 07 Dec 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.12-1 (r873) + * added a switch to allow anomalous read pairs in calling + +------------------------------------------------------------------------ +r872 | lh3lh3 | 2010-12-07 14:43:54 -0500 (Tue, 07 Dec 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/vcfutils.pl + +fixed a bug in vcf2fq + +------------------------------------------------------------------------ +r869 | lh3lh3 | 2010-12-05 01:18:06 -0500 (Sun, 05 Dec 2010) | 2 lines +Changed paths: + M /trunk/samtools/bamtk.c + +added a warning for the Windows version + +------------------------------------------------------------------------ +r868 | lh3lh3 | 2010-12-05 01:05:51 -0500 (Sun, 05 Dec 2010) | 4 lines +Changed paths: + M /trunk/samtools/bcftools/call1.c + +In ksprintf(), change "%lf" and "%lg" to "%f" and "%g", respectively. +According to the manual page, this change is valid. However, MinGW seems +to interpret "%lf" as "%Lf". + +------------------------------------------------------------------------ +r867 | lh3lh3 | 2010-12-05 00:35:43 -0500 (Sun, 05 Dec 2010) | 2 lines +Changed paths: + M /trunk/samtools/Makefile.mingw + M /trunk/samtools/bam_aux.c + +bring back the windows support + +------------------------------------------------------------------------ +r866 | lh3lh3 | 2010-12-04 23:33:51 -0500 (Sat, 04 Dec 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_reheader.c + M /trunk/samtools/bcftools/vcfutils.pl + +Fixed a compiling error when knetfile is not used. + +------------------------------------------------------------------------ +r865 | lh3lh3 | 2010-12-04 00:13:22 -0500 (Sat, 04 Dec 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/vcfutils.pl + +vcf->fastq + +------------------------------------------------------------------------ +r864 | lh3lh3 | 2010-12-03 17:12:30 -0500 (Fri, 03 Dec 2010) | 3 lines +Changed paths: + M /trunk/samtools/bcftools/call1.c + M /trunk/samtools/bcftools/prob1.c + M /trunk/samtools/bcftools/prob1.h + + * remove "-f". Instead always compute consensus quality + * increase the upper limit of quality + +------------------------------------------------------------------------ +r863 | lh3lh3 | 2010-12-03 15:28:15 -0500 (Fri, 03 Dec 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/bcf.c + +more informative error message + +------------------------------------------------------------------------ +r862 | lh3lh3 | 2010-12-02 16:16:08 -0500 (Thu, 02 Dec 2010) | 2 lines +Changed paths: + M /trunk/samtools/NEWS + M /trunk/samtools/bamtk.c + +Release samtools-0.1.12a + +------------------------------------------------------------------------ +r861 | lh3lh3 | 2010-12-02 15:55:06 -0500 (Thu, 02 Dec 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/call1.c + +a possible fix to DP4=0,0,0,0; have not tested, but should have no side-effect + +------------------------------------------------------------------------ +r859 | lh3lh3 | 2010-12-02 11:39:57 -0500 (Thu, 02 Dec 2010) | 2 lines +Changed paths: + M /trunk/samtools/NEWS + M /trunk/samtools/bam_index.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/samtools.1 + +Release samtools-0.1.12 + +------------------------------------------------------------------------ +r858 | lh3lh3 | 2010-12-02 11:24:41 -0500 (Thu, 02 Dec 2010) | 4 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/bcftools/bcf.c + + * samtools-0.1.11-1 (r858) + * fixed a bug in mpileup which causes segfaults + * bcftools: do not segfault when BCF contains errors + +------------------------------------------------------------------------ +r857 | lh3lh3 | 2010-11-30 23:52:50 -0500 (Tue, 30 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_index.c + +fixed a memory leak in bam_fetch() + +------------------------------------------------------------------------ +r856 | lh3lh3 | 2010-11-26 00:07:31 -0500 (Fri, 26 Nov 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bcftools/vcfutils.pl + + * fixed a memory violation + * added splitchr to vcfutils.pl + +------------------------------------------------------------------------ +r854 | lh3lh3 | 2010-11-23 09:05:08 -0500 (Tue, 23 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/ld.c + +fixed a typo/bug in r^2 computation + +------------------------------------------------------------------------ +r852 | lh3lh3 | 2010-11-21 22:20:20 -0500 (Sun, 21 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/bamtk.c + +forget to change the version information + +------------------------------------------------------------------------ +r851 | lh3lh3 | 2010-11-21 22:16:52 -0500 (Sun, 21 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/NEWS + M /trunk/samtools/bcftools/bcftools.1 + M /trunk/samtools/samtools.1 + +Release samtools-0.1.11 + +------------------------------------------------------------------------ +r844 | lh3lh3 | 2010-11-19 23:16:08 -0500 (Fri, 19 Nov 2010) | 3 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/bcftools/call1.c + M /trunk/samtools/bcftools/prob1.c + M /trunk/samtools/bcftools/prob1.h + + * samtools-0.1.10-9 (r844) + * added the "folded" or reference-free mode for variant calling + +------------------------------------------------------------------------ +r843 | lh3lh3 | 2010-11-19 22:26:36 -0500 (Fri, 19 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/NEWS + M /trunk/samtools/bam_sort.c + +In merging, if -R is specified, do not abort if the sequence dictionary is different. + +------------------------------------------------------------------------ +r842 | jmarshall | 2010-11-19 21:24:28 -0500 (Fri, 19 Nov 2010) | 5 lines +Changed paths: + M /trunk/samtools/bam_sort.c + +When merging BAM headers, compare the list of target reference sequences +strictly (and fail/abort if there is a mismatch), but allow one list to be a +prefix of the other. (i.e., check that the lists are identical up until the +shorter runs out, and add the excess targets from the longer to the output.) + +------------------------------------------------------------------------ +r841 | lh3lh3 | 2010-11-19 14:49:27 -0500 (Fri, 19 Nov 2010) | 4 lines +Changed paths: + M /trunk/samtools/bam_index.c + M /trunk/samtools/bam_pileup.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.10 (r841) + * fixed a bug in pileup when the first CIGAR operation is D + * fixed a bug in view with range query + +------------------------------------------------------------------------ +r840 | lh3lh3 | 2010-11-19 13:45:51 -0500 (Fri, 19 Nov 2010) | 10 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf.h + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.10-4 (r840) + + * drop the MNP caller. It is slow while does not diliver too much + benefit. Possibly I will work on it in future given more time. + + * there is a segfault in pileup + + * someone has reported segfault from view/index/sort + + +------------------------------------------------------------------------ +r839 | lh3lh3 | 2010-11-18 17:30:11 -0500 (Thu, 18 Nov 2010) | 9 lines +Changed paths: + M /trunk/samtools/bam2bcf.h + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.10-6 (r839) + + * call MNPs without realignment because it seems to me that it is not + worthwhile to significantly slow down SNP calling. + + * the result looks quite different from the previous version. I have + work to do... + + +------------------------------------------------------------------------ +r838 | lh3lh3 | 2010-11-18 11:26:09 -0500 (Thu, 18 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/knetfile.c + +Apply a patch by Rob Davis, which improves fault detection. + +------------------------------------------------------------------------ +r836 | lh3lh3 | 2010-11-18 11:09:23 -0500 (Thu, 18 Nov 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bamtk.c + + * samtools-r836 + * initiate MNP realignment when the MNP has at least 0.2% frequency (otherwise too slow) + +------------------------------------------------------------------------ +r835 | lh3lh3 | 2010-11-18 00:25:13 -0500 (Thu, 18 Nov 2010) | 3 lines +Changed paths: + M /trunk/samtools/bcftools/vcfutils.pl + + * modify the filtering rule: also filter SNPs around filtered indels + * added MNP filter + +------------------------------------------------------------------------ +r834 | lh3lh3 | 2010-11-17 23:13:52 -0500 (Wed, 17 Nov 2010) | 4 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.10-4 (r834) + * fixed a silly bug in printing MNP + * restrict to at most 1 alternative allele + +------------------------------------------------------------------------ +r833 | lh3lh3 | 2010-11-17 21:58:58 -0500 (Wed, 17 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bamtk.c + +fixed a bug in printing MNPs + +------------------------------------------------------------------------ +r832 | lh3lh3 | 2010-11-17 21:47:20 -0500 (Wed, 17 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bamtk.c + +minor change to how seqQ is applied + +------------------------------------------------------------------------ +r831 | lh3lh3 | 2010-11-17 21:41:12 -0500 (Wed, 17 Nov 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf.h + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.10 (r831) + * initial MNP caller + +------------------------------------------------------------------------ +r829 | lh3lh3 | 2010-11-16 23:14:15 -0500 (Tue, 16 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/NEWS + M /trunk/samtools/bamtk.c + +Release samtools-0.1.10 (r829) + +------------------------------------------------------------------------ +r828 | lh3lh3 | 2010-11-16 20:48:49 -0500 (Tue, 16 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/bamtk.c + +update version information: samtools-0.1.9-20 (r828) + +------------------------------------------------------------------------ +r827 | lh3lh3 | 2010-11-16 15:32:50 -0500 (Tue, 16 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/call1.c + +bcftools: allow to skip indels + +------------------------------------------------------------------------ +r826 | lh3lh3 | 2010-11-16 14:11:58 -0500 (Tue, 16 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_md.c + +remove ZQ if both BQ and ZQ are present + +------------------------------------------------------------------------ +r825 | lh3lh3 | 2010-11-16 13:51:33 -0500 (Tue, 16 Nov 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bam_md.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/samtools.1 + + * samtools-0.1.9-18 (r825) + * change the behaviour of calmd such that by default it does not change the base quality + +------------------------------------------------------------------------ +r824 | lh3lh3 | 2010-11-15 23:31:53 -0500 (Mon, 15 Nov 2010) | 4 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/bcftools/call1.c + M /trunk/samtools/samtools.1 + + * samtools-0.1.9-17 (r824) + * added command line options to change the default parameters in indel calling + * update the manual + +------------------------------------------------------------------------ +r823 | lh3lh3 | 2010-11-15 12:20:13 -0500 (Mon, 15 Nov 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bam_md.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.9-r823 + * the BQ tag is now 64 shifted, not 33 shifted + +------------------------------------------------------------------------ +r822 | lh3lh3 | 2010-11-15 00:30:18 -0500 (Mon, 15 Nov 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf.h + M /trunk/samtools/bamtk.c + M /trunk/samtools/bcftools/vcfutils.pl + M /trunk/samtools/misc/samtools.pl + + * samtools-0.1.9-16 (r822) + * keep the raw depth because in indel calling, DP4 may be way off the true depth + +------------------------------------------------------------------------ +r821 | lh3lh3 | 2010-11-13 01:18:31 -0500 (Sat, 13 Nov 2010) | 4 lines +Changed paths: + M /trunk/samtools/bam_md.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.9-15 (r821) + * calmd: write BQ + * skip realignment if BQ is present + +------------------------------------------------------------------------ +r820 | lh3lh3 | 2010-11-13 01:08:26 -0500 (Sat, 13 Nov 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.9-14 (r820) + * penalize reads with excessive differences in indel calling + +------------------------------------------------------------------------ +r819 | lh3lh3 | 2010-11-12 21:36:27 -0500 (Fri, 12 Nov 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.9-13 (r819) + * fixed a bug in pileup given refskip + +------------------------------------------------------------------------ +r818 | lh3lh3 | 2010-11-12 13:04:53 -0500 (Fri, 12 Nov 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bamtk.c + + * samtools-r818 + * for indel calling, do two rounds of probabilistic realignments + +------------------------------------------------------------------------ +r817 | lh3lh3 | 2010-11-11 20:04:07 -0500 (Thu, 11 Nov 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/bcftools/vcfutils.pl + + * samtools-0.1.19-11 (r817) + * only initiate indel calling when 0.2% of reads contain a gap + +------------------------------------------------------------------------ +r816 | lh3lh3 | 2010-11-11 01:22:59 -0500 (Thu, 11 Nov 2010) | 7 lines +Changed paths: + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.9-10 (r816) + + * I know why the forward method fails. it is because of zero base + qualities. when that is fixed, the forward method seems to give + better results than Viterbi, as it should be. I am tired... + + +------------------------------------------------------------------------ +r815 | lh3lh3 | 2010-11-11 00:57:15 -0500 (Thu, 11 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/bam2bcf_indel.c + +effectively revert to the viterbi version. The forward realignment gives too many false positives. + +------------------------------------------------------------------------ +r814 | lh3lh3 | 2010-11-11 00:18:02 -0500 (Thu, 11 Nov 2010) | 4 lines +Changed paths: + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bam_md.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.9-9 (r810) + * use forward, instead of viterbi, for realignment + * realignment is now quality aware + +------------------------------------------------------------------------ +r813 | lh3lh3 | 2010-11-10 22:45:24 -0500 (Wed, 10 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/kprobaln.c + M /trunk/samtools/kprobaln.h + + * prepare to replace kaln with kprobaln in realignment + +------------------------------------------------------------------------ +r812 | lh3lh3 | 2010-11-10 17:28:50 -0500 (Wed, 10 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/bcf.c + +fixed a typo + +------------------------------------------------------------------------ +r811 | lh3lh3 | 2010-11-10 16:54:46 -0500 (Wed, 10 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/bcf.c + M /trunk/samtools/bcftools/bcf.h + +use zlib for direct reading when BCF_LITE is in use + +------------------------------------------------------------------------ +r810 | lh3lh3 | 2010-11-10 16:32:13 -0500 (Wed, 10 Nov 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf_indel.c + + * do not use reads containing too many mismatches for indel calling + * fixed a trivial bug in case of multi-allelic indels + +------------------------------------------------------------------------ +r809 | lh3lh3 | 2010-11-10 13:23:02 -0500 (Wed, 10 Nov 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.9-8 (r809) + * fixed a bug in the indel caller + +------------------------------------------------------------------------ +r808 | lh3lh3 | 2010-11-10 12:24:10 -0500 (Wed, 10 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/Makefile + +minor change to makefile + +------------------------------------------------------------------------ +r807 | lh3lh3 | 2010-11-10 12:10:21 -0500 (Wed, 10 Nov 2010) | 4 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/bam2bcf.h + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/bcftools/vcfutils.pl + + * samtools-0.1.9-8 (r807) + * collect indel candidates only from specified platforms (@RG-PL) + * merge varFilter and filter4vcf in vcfutils.pl + +------------------------------------------------------------------------ +r806 | lh3lh3 | 2010-11-09 22:05:46 -0500 (Tue, 09 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/call1.c + M /trunk/samtools/bcftools/prob1.c + M /trunk/samtools/bcftools/prob1.h + +bcftools: compute equal-tail (Bayesian) credible interval + +------------------------------------------------------------------------ +r805 | lh3lh3 | 2010-11-09 16:28:39 -0500 (Tue, 09 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/vcfutils.pl + +added a double-hit filter to avoid overestimated indel likelihood + +------------------------------------------------------------------------ +r804 | lh3lh3 | 2010-11-09 14:12:06 -0500 (Tue, 09 Nov 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.9-7 (r804) + * fixed a bug in the gap caller + +------------------------------------------------------------------------ +r803 | lh3lh3 | 2010-11-09 10:45:33 -0500 (Tue, 09 Nov 2010) | 4 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/bcftools/bcf.c + M /trunk/samtools/bcftools/bcf.h + M /trunk/samtools/bcftools/prob1.c + + * samtools-0.1.9-6 (r803) + * mpileup: apply homopolymer correction when calculating GL, instead of before + * bcftools: apply a different prior to indels + +------------------------------------------------------------------------ +r802 | lh3lh3 | 2010-11-08 23:53:15 -0500 (Mon, 08 Nov 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.9-5 (r802) + * relax tandem penalty. this will be made a command-line option in future. + +------------------------------------------------------------------------ +r801 | lh3lh3 | 2010-11-08 23:35:52 -0500 (Mon, 08 Nov 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.9-4 (r801) + * fixed a minor issue in printing indel VCF + +------------------------------------------------------------------------ +r800 | lh3lh3 | 2010-11-08 15:28:14 -0500 (Mon, 08 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bcftools/vcfutils.pl + +fixed another silly bug in mpileup's indel caller + +------------------------------------------------------------------------ +r799 | lh3lh3 | 2010-11-08 14:28:27 -0500 (Mon, 08 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + +fixed a silly bug in the indel caller + +------------------------------------------------------------------------ +r798 | lh3lh3 | 2010-11-08 14:07:33 -0500 (Mon, 08 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/sam_view.c + M /trunk/samtools/samtools.1 + +Incorporate patches by Marcel Martin for read counting. + +------------------------------------------------------------------------ +r797 | lh3lh3 | 2010-11-08 13:39:52 -0500 (Mon, 08 Nov 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf.h + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.9-2 (r797) + * mpileup: indel calling seems to be working + +------------------------------------------------------------------------ +r796 | lh3lh3 | 2010-11-08 10:54:46 -0500 (Mon, 08 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf.h + M /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/kaln.c + +indel calling is apparently working, but more information needs to be collected + +------------------------------------------------------------------------ +r795 | lh3lh3 | 2010-11-08 00:39:18 -0500 (Mon, 08 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf_indel.c + +fixed a few bugs in the indel caller. Probably there are more. + +------------------------------------------------------------------------ +r794 | lh3lh3 | 2010-11-07 22:23:16 -0500 (Sun, 07 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/bam.h + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf.h + A /trunk/samtools/bam2bcf_indel.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/kaln.c + M /trunk/samtools/kaln.h + +prepare for the indel caller. It is not ready yet. + +------------------------------------------------------------------------ +r793 | lh3lh3 | 2010-11-05 11:28:23 -0400 (Fri, 05 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf.h + M /trunk/samtools/bam_plcmd.c + +Revert to r790. The recent changes are not good... + +------------------------------------------------------------------------ +r792 | lh3lh3 | 2010-11-05 00:19:14 -0400 (Fri, 05 Nov 2010) | 6 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf.h + M /trunk/samtools/bam_plcmd.c + + * this revision is UNSTABLE + + * indel caller seems working, but it is very insensitive and has + several things I do not quite understand. + + +------------------------------------------------------------------------ +r791 | lh3lh3 | 2010-11-04 22:58:43 -0400 (Thu, 04 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf.h + M /trunk/samtools/bam_plcmd.c + +for backup. no effective changes + +------------------------------------------------------------------------ +r790 | lh3lh3 | 2010-11-03 15:51:24 -0400 (Wed, 03 Nov 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/vcfutils.pl + M /trunk/samtools/kprobaln.c + +fixed a minor problem in the example coming with kprobaln.c + +------------------------------------------------------------------------ +r789 | lh3lh3 | 2010-11-02 15:41:27 -0400 (Tue, 02 Nov 2010) | 4 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/bam_md.c + M /trunk/samtools/kaln.c + M /trunk/samtools/kaln.h + A /trunk/samtools/kprobaln.c + A /trunk/samtools/kprobaln.h + +Separate kaln and kprobaln as I am preparing further changes. At +present, the results should be identical to the previous. + + +------------------------------------------------------------------------ +r788 | petulda | 2010-11-02 12:19:04 -0400 (Tue, 02 Nov 2010) | 1 line +Changed paths: + M /trunk/samtools/bam_plcmd.c + +Added -b option: read file names from a file +------------------------------------------------------------------------ +r787 | lh3lh3 | 2010-10-29 23:17:22 -0400 (Fri, 29 Oct 2010) | 7 lines +Changed paths: + M /trunk/samtools/bam.h + M /trunk/samtools/bam_pileup.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.9-2 (r787) + + * Allow to set a maximum per-sample depth to reduce memory. However, + BAQ computation is still applied to every read. The speed is not + improved. + + +------------------------------------------------------------------------ +r786 | lh3lh3 | 2010-10-29 12:10:40 -0400 (Fri, 29 Oct 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf.h + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/bcftools/bcf.c + M /trunk/samtools/bcftools/vcf.c + + * samtools-0.1.9-1 (r786) + * samtools: optionally perform exact test for each sample + +------------------------------------------------------------------------ +r785 | lh3lh3 | 2010-10-29 09:42:25 -0400 (Fri, 29 Oct 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf.h + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bcftools/bcf.c + +Optionally output "DP", the individual read depth + +------------------------------------------------------------------------ +r784 | lh3lh3 | 2010-10-27 23:10:27 -0400 (Wed, 27 Oct 2010) | 2 lines +Changed paths: + M /trunk/samtools/samtools.1 + +acknowledge Petr and John who have greatly contributed to the project. + +------------------------------------------------------------------------ +r783 | lh3lh3 | 2010-10-27 22:47:47 -0400 (Wed, 27 Oct 2010) | 2 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/NEWS + M /trunk/samtools/bamtk.c + M /trunk/samtools/samtools.1 + +Release samtools-0.1.9 (r783) + +------------------------------------------------------------------------ +r782 | lh3lh3 | 2010-10-27 19:58:54 -0400 (Wed, 27 Oct 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + +fixed a silly bug in pileup + +------------------------------------------------------------------------ +r781 | lh3lh3 | 2010-10-27 14:39:48 -0400 (Wed, 27 Oct 2010) | 5 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bam_sort.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/samtools.1 + + * samtools-0.1.8-22 (r781) + * made BAQ the default behavior of mpileup + * updated manual + * in merge, force to exit given inconsistent header when "-R" is not in use. + +------------------------------------------------------------------------ +r780 | lh3lh3 | 2010-10-27 11:01:11 -0400 (Wed, 27 Oct 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam.h + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.8-21 (r780) + * minor speedup to pileup + +------------------------------------------------------------------------ +r779 | lh3lh3 | 2010-10-27 09:58:56 -0400 (Wed, 27 Oct 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_pileup.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/examples/toy.sam + +improve pileup a little bit + +------------------------------------------------------------------------ +r778 | lh3lh3 | 2010-10-27 00:14:43 -0400 (Wed, 27 Oct 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam.h + M /trunk/samtools/bam_pileup.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bam_tview.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.8-20 (r778) + * speed up pileup, although I do not know how much is the improvement + +------------------------------------------------------------------------ +r777 | lh3lh3 | 2010-10-26 17:26:04 -0400 (Tue, 26 Oct 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bam_maqcns.h + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/examples/Makefile + + * samtools-0.1.8-19 (r777) + * integrate mpileup features to pileup: min_baseQ, capQ, prob_realn, paired-only and biased prior + +------------------------------------------------------------------------ +r776 | lh3lh3 | 2010-10-26 15:27:46 -0400 (Tue, 26 Oct 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_md.c + +remove local realignment (probabilistic realignment is still there) + +------------------------------------------------------------------------ +r774 | jmarshall | 2010-10-21 06:52:38 -0400 (Thu, 21 Oct 2010) | 3 lines +Changed paths: + M /trunk/samtools/sam_view.c + +Add the relevant filename or region to error messages, and cause a failure +exit status where appropriate. Based on a patch provided by Marcel Martin. + +------------------------------------------------------------------------ +r773 | lh3lh3 | 2010-10-19 19:44:31 -0400 (Tue, 19 Oct 2010) | 3 lines +Changed paths: + M /trunk/samtools/examples/toy.sam + M /trunk/samtools/kaln.c + + * Minor code changes. No real effect. + * change quality to 30 in toy.sam + +------------------------------------------------------------------------ +r772 | lh3lh3 | 2010-10-18 23:40:13 -0400 (Mon, 18 Oct 2010) | 2 lines +Changed paths: + M /trunk/samtools/examples/toy.fa + M /trunk/samtools/examples/toy.sam + +added another toy example + +------------------------------------------------------------------------ +r771 | lh3lh3 | 2010-10-13 23:32:12 -0400 (Wed, 13 Oct 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/call1.c + M /trunk/samtools/bcftools/ld.c + M /trunk/samtools/bcftools/vcfutils.pl + +improve the LD statistics + +------------------------------------------------------------------------ +r770 | lh3lh3 | 2010-10-12 23:49:26 -0400 (Tue, 12 Oct 2010) | 3 lines +Changed paths: + M /trunk/samtools/bcftools/call1.c + M /trunk/samtools/bcftools/vcfutils.pl + + * a minor fix to the -L option + * add ldstats to vcfutils.pl + +------------------------------------------------------------------------ +r769 | lh3lh3 | 2010-10-12 15:51:57 -0400 (Tue, 12 Oct 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/bcf.c + +a minor change + +------------------------------------------------------------------------ +r768 | lh3lh3 | 2010-10-12 15:49:06 -0400 (Tue, 12 Oct 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/Makefile + A /trunk/samtools/bcftools/ld.c + +forget to add the key file + +------------------------------------------------------------------------ +r767 | lh3lh3 | 2010-10-12 15:48:46 -0400 (Tue, 12 Oct 2010) | 4 lines +Changed paths: + M /trunk/samtools/bcftools/Makefile + M /trunk/samtools/bcftools/bcf.c + M /trunk/samtools/bcftools/bcf.h + M /trunk/samtools/bcftools/call1.c + M /trunk/samtools/bcftools/prob1.c + M /trunk/samtools/bcftools/vcfutils.pl + + * vcfutils.pl: fixed a typo in help message + * added APIs: bcf_append_info() and bcf_cpy() + * calculate adjacent LD + +------------------------------------------------------------------------ +r766 | lh3lh3 | 2010-10-11 11:06:40 -0400 (Mon, 11 Oct 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/vcfutils.pl + +added filter for samtools/bcftools genetated VCFs + +------------------------------------------------------------------------ +r765 | lh3lh3 | 2010-10-05 14:05:18 -0400 (Tue, 05 Oct 2010) | 3 lines +Changed paths: + M /trunk/samtools/bcftools/vcfutils.pl + M /trunk/samtools/kaln.c + + * removed a comment line in kaln.c + * vcfutils.pl fillac works when GT is not the first field + +------------------------------------------------------------------------ +r764 | petulda | 2010-10-05 08:59:36 -0400 (Tue, 05 Oct 2010) | 1 line +Changed paths: + A /trunk/samtools/bcftools/bcf-fix.pl + +Convert VCF output of "bcftools view -bgcv" to a valid VCF file +------------------------------------------------------------------------ +r763 | lh3lh3 | 2010-10-02 22:51:03 -0400 (Sat, 02 Oct 2010) | 4 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + A /trunk/samtools/bcftools/bcftools.1 + M /trunk/samtools/bcftools/call1.c + M /trunk/samtools/samtools.1 + + * samtools-0.1.8-18 (r763) + * added bcftools manual page + * minor fix to mpileup and view command lines + +------------------------------------------------------------------------ +r762 | lh3lh3 | 2010-10-02 21:46:25 -0400 (Sat, 02 Oct 2010) | 3 lines +Changed paths: + M /trunk/samtools/bcftools/bcf.c + M /trunk/samtools/bcftools/call1.c + M /trunk/samtools/bcftools/vcfutils.pl + + * vcfutils.pl qstats: calculate marginal ts/tv + * allow to call genotypes at variant sites + +------------------------------------------------------------------------ +r761 | lh3lh3 | 2010-10-01 00:29:55 -0400 (Fri, 01 Oct 2010) | 3 lines +Changed paths: + M /trunk/samtools/kaln.c + M /trunk/samtools/misc/HmmGlocal.java + +I am changing the gap open probability back to 0.001. It seems that +being conservative here is a good thing... + +------------------------------------------------------------------------ +r760 | lh3lh3 | 2010-10-01 00:11:27 -0400 (Fri, 01 Oct 2010) | 5 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/kaln.c + A /trunk/samtools/misc/HmmGlocal.java + + * samtools-0.1.8-17 (r760) + * the default gap open penalty is too small (a typo) + * added comments on hmm_realn + * Java implementation + +------------------------------------------------------------------------ +r759 | lh3lh3 | 2010-09-30 10:12:54 -0400 (Thu, 30 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/bamtk.c + +mark samtools-0.1.8-16 (r759) + +------------------------------------------------------------------------ +r758 | lh3lh3 | 2010-09-30 10:12:02 -0400 (Thu, 30 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/kaln.c + +round to the nearest integer + +------------------------------------------------------------------------ +r757 | lh3lh3 | 2010-09-28 17:16:43 -0400 (Tue, 28 Sep 2010) | 4 lines +Changed paths: + M /trunk/samtools/kaln.c + +I was trying to accelerate ka_prob_glocal() as this will be the +bottleneck. After an hour, the only gain is to change division to +multiplication. OK. I will stop. + +------------------------------------------------------------------------ +r756 | lh3lh3 | 2010-09-28 16:57:49 -0400 (Tue, 28 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/kaln.c + +this is interesting. multiplication is much faster than division, at least on my Mac + +------------------------------------------------------------------------ +r755 | lh3lh3 | 2010-09-28 16:19:13 -0400 (Tue, 28 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/kaln.c + +minor changes + +------------------------------------------------------------------------ +r754 | lh3lh3 | 2010-09-28 15:44:16 -0400 (Tue, 28 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_md.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/kaln.c + +prob_realn() seems working! + +------------------------------------------------------------------------ +r753 | lh3lh3 | 2010-09-28 12:48:23 -0400 (Tue, 28 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/kaln.c + +minor + +------------------------------------------------------------------------ +r752 | lh3lh3 | 2010-09-28 12:47:41 -0400 (Tue, 28 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/kaln.c + M /trunk/samtools/kaln.h + +Convert phredQ to probabilities + +------------------------------------------------------------------------ +r751 | lh3lh3 | 2010-09-28 12:32:08 -0400 (Tue, 28 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/kaln.c + M /trunk/samtools/kaln.h + +Implement the glocal HMM; discard the extention HMM + +------------------------------------------------------------------------ +r750 | lh3lh3 | 2010-09-28 00:06:11 -0400 (Tue, 28 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/kaln.c + +improve numerical stability + +------------------------------------------------------------------------ +r749 | lh3lh3 | 2010-09-27 23:27:54 -0400 (Mon, 27 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/kaln.c + +more comments + +------------------------------------------------------------------------ +r748 | lh3lh3 | 2010-09-27 23:17:16 -0400 (Mon, 27 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/kaln.c + +fixed a bug in banded DP + +------------------------------------------------------------------------ +r747 | lh3lh3 | 2010-09-27 23:05:12 -0400 (Mon, 27 Sep 2010) | 3 lines +Changed paths: + M /trunk/samtools/kaln.c + + * fixed that weird issue. + * the banded version is NOT working + +------------------------------------------------------------------------ +r746 | lh3lh3 | 2010-09-27 22:57:05 -0400 (Mon, 27 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/kaln.c + +More comments. This version seems working, but something is a little weird... + +------------------------------------------------------------------------ +r745 | lh3lh3 | 2010-09-27 17:21:40 -0400 (Mon, 27 Sep 2010) | 6 lines +Changed paths: + M /trunk/samtools/kaln.c + +A little code cleanup. Now the forward and backback algorithms give +nearly identical P(x), which means both are close to the correct +forms. However, I have only tested on toy examples. Minor errors in +the implementation may not be obvious. + + +------------------------------------------------------------------------ +r744 | lh3lh3 | 2010-09-27 16:55:15 -0400 (Mon, 27 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bam_sort.c + M /trunk/samtools/kaln.c + M /trunk/samtools/kaln.h + +... + +------------------------------------------------------------------------ +r743 | jmarshall | 2010-09-27 08:19:06 -0400 (Mon, 27 Sep 2010) | 6 lines +Changed paths: + M /trunk/samtools/bam_sort.c + +Abort if merge -h's INH.SAM cannot be opened, just as we abort +if any of the IN#.BAM input files cannot be opened. + +Also propagate any error indication returned by bam_merge_core() +to samtools merge's exit status. + +------------------------------------------------------------------------ +r741 | jmarshall | 2010-09-24 11:08:24 -0400 (Fri, 24 Sep 2010) | 5 lines +Changed paths: + M /trunk/samtools/bam_index.c + +Use bam_validate1() to detect garbage records in the event of a corrupt +BAI index file that causes a bam_seek() to an invalid position. At most +one record (namely, the bam_iter_read terminator) is tested per bam_fetch() +call, so the cost is insignificant in the normal case. + +------------------------------------------------------------------------ +r740 | jmarshall | 2010-09-24 11:00:19 -0400 (Fri, 24 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam.c + M /trunk/samtools/bam.h + +Add bam_validate1(). + +------------------------------------------------------------------------ +r739 | lh3lh3 | 2010-09-22 12:07:50 -0400 (Wed, 22 Sep 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam_md.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.8-15 (r379) + * allow to change capQ parameter in calmd + +------------------------------------------------------------------------ +r738 | jmarshall | 2010-09-22 11:15:33 -0400 (Wed, 22 Sep 2010) | 13 lines +Changed paths: + M /trunk/samtools/bam_index.c + M /trunk/samtools/sam_view.c + +When bam_read1() returns an error (return value <= -2), propagate that error +to bam_iter_read()'s own return value. Similarly, also propagate it up to +bam_fetch()'s return value. Previously bam_fetch() always returned 0, and +callers ignored its return value anyway. With this change, 0 continues to +indicate success, while <= -2 (which can be written as < 0, as -1 is never +returned) indicates corrupted input. + +bam_iter_read() ought also to propagate errors returned by bam_seek(). + +main_samview() can now print an error message and fail when bam_fetch() +detects that a .bai index file is corrupted or otherwise does not correspond +to the .bam file it is being used with. + +------------------------------------------------------------------------ +r737 | jmarshall | 2010-09-22 10:47:42 -0400 (Wed, 22 Sep 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam_index.c + +0 is a successful return value from bam_read1(). (In practice, it never +returns 0 anyway; but all the other callers treat 0 as successful.) + +------------------------------------------------------------------------ +r736 | lh3lh3 | 2010-09-20 17:43:08 -0400 (Mon, 20 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam.h + M /trunk/samtools/bam_index.c + M /trunk/samtools/bam_sort.c + + * merge files region-by-region. work on small examples but more tests are needed. + +------------------------------------------------------------------------ +r735 | lh3lh3 | 2010-09-20 16:56:24 -0400 (Mon, 20 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/vcfutils.pl + +improve qstats by checking the alleles as well + +------------------------------------------------------------------------ +r734 | lh3lh3 | 2010-09-17 18:12:13 -0400 (Fri, 17 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/vcfutils.pl + +convert UCSC SNP SQL dump to VCF + +------------------------------------------------------------------------ +r733 | lh3lh3 | 2010-09-17 13:02:11 -0400 (Fri, 17 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/vcfutils.pl + +hapmap2vcf convertor + +------------------------------------------------------------------------ +r732 | lh3lh3 | 2010-09-17 10:11:37 -0400 (Fri, 17 Sep 2010) | 3 lines +Changed paths: + M /trunk/samtools/bcftools/Makefile + M /trunk/samtools/bcftools/bcf.c + M /trunk/samtools/bcftools/bcf.h + M /trunk/samtools/bcftools/vcf.c + + * added comments + * VCF->BCF is not possible without knowing the sequence dictionary before hand... + +------------------------------------------------------------------------ +r731 | lh3lh3 | 2010-09-17 09:15:53 -0400 (Fri, 17 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bcftools/bcf.c + M /trunk/samtools/bcftools/bcf.h + M /trunk/samtools/bcftools/bcfutils.c + M /trunk/samtools/bcftools/call1.c + M /trunk/samtools/bcftools/vcf.c + + * put n_smpl to "bcf1_t" to simplify API a little + +------------------------------------------------------------------------ +r730 | lh3lh3 | 2010-09-16 21:36:01 -0400 (Thu, 16 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/bcf.h + M /trunk/samtools/bcftools/call1.c + M /trunk/samtools/bcftools/index.c + +fixed a bug in indexing + +------------------------------------------------------------------------ +r729 | lh3lh3 | 2010-09-16 16:54:48 -0400 (Thu, 16 Sep 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam.c + M /trunk/samtools/bam_md.c + M /trunk/samtools/bam_pileup.c + + * fixed a bug in capQ + * valgrind identifies a use of uninitialised value, but I have not fixed it. + +------------------------------------------------------------------------ +r728 | lh3lh3 | 2010-09-16 15:03:59 -0400 (Thu, 16 Sep 2010) | 3 lines +Changed paths: + M /trunk/samtools/bgzip.c + M /trunk/samtools/razip.c + + * fixed a bug in razip: -c will delete the input file + * copy tabix/bgzip to here + +------------------------------------------------------------------------ +r727 | lh3lh3 | 2010-09-16 13:45:49 -0400 (Thu, 16 Sep 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam_md.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.8-14 (r727) + * allow to change the capQ parameter at the command line + +------------------------------------------------------------------------ +r726 | lh3lh3 | 2010-09-16 13:38:43 -0400 (Thu, 16 Sep 2010) | 4 lines +Changed paths: + M /trunk/samtools/bam_md.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bcftools/vcfutils.pl + M /trunk/samtools/misc/samtools.pl + + * added varFilter to vcfutils.pl + * reimplement realn(). now it performs a local alignment + * added cap_mapQ() to cap mapping quality when there are many substitutions + +------------------------------------------------------------------------ +r724 | lh3lh3 | 2010-09-15 00:18:31 -0400 (Wed, 15 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/Makefile + A /trunk/samtools/bcftools/bcf2qcall.c + M /trunk/samtools/bcftools/call1.c + + * convert BCF to QCALL input + +------------------------------------------------------------------------ +r723 | lh3lh3 | 2010-09-14 22:41:50 -0400 (Tue, 14 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_md.c + +dynamic band width in realignment + +------------------------------------------------------------------------ +r722 | lh3lh3 | 2010-09-14 22:05:32 -0400 (Tue, 14 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_md.c + M /trunk/samtools/bam_plcmd.c + +fixed a bug in realignment + +------------------------------------------------------------------------ +r721 | lh3lh3 | 2010-09-14 20:54:09 -0400 (Tue, 14 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/prob1.c + +fixed a minor issue + +------------------------------------------------------------------------ +r720 | lh3lh3 | 2010-09-14 19:25:10 -0400 (Tue, 14 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bam_md.c + +fixed a bug in realignment + +------------------------------------------------------------------------ +r719 | lh3lh3 | 2010-09-14 19:18:24 -0400 (Tue, 14 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + +minor changes. It is BUGGY now! + +------------------------------------------------------------------------ +r718 | lh3lh3 | 2010-09-14 16:32:33 -0400 (Tue, 14 Sep 2010) | 4 lines +Changed paths: + M /trunk/samtools/bam_md.c + M /trunk/samtools/bam_pileup.c + M /trunk/samtools/kaln.c + M /trunk/samtools/kaln.h + + * aggressive gapped aligner is implemented in calmd. + * distinguish gap_open and gap_end_open in banded alignment + * make tview accepts alignment with heading and tailing D + +------------------------------------------------------------------------ +r717 | jmarshall | 2010-09-14 09:04:28 -0400 (Tue, 14 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools + +Add svn:ignore properties for generated files that don't appear in "make all". + +------------------------------------------------------------------------ +r716 | jmarshall | 2010-09-13 08:37:53 -0400 (Mon, 13 Sep 2010) | 3 lines +Changed paths: + M /trunk/samtools + M /trunk/samtools/bcftools + M /trunk/samtools/misc + +Add svn:ignore properties listing the generated files. +(Except for *.o, which we'll assume is in global-ignores.) + +------------------------------------------------------------------------ +r715 | lh3lh3 | 2010-09-08 12:53:55 -0400 (Wed, 08 Sep 2010) | 5 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/bcftools/call1.c + M /trunk/samtools/bcftools/prob1.c + M /trunk/samtools/sample.c + M /trunk/samtools/sample.h + + * samtools-0.1.8-13 (r715) + * fixed a bug in identifying SM across files + * bcftools: estimate heterozygosity + * bcftools: allow to skip sites without reference bases + +------------------------------------------------------------------------ +r713 | lh3lh3 | 2010-09-03 17:19:12 -0400 (Fri, 03 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/Makefile + M /trunk/samtools/bcftools/call1.c + M /trunk/samtools/bcftools/prob1.c + M /trunk/samtools/bcftools/prob1.h + +quite a lot changes to the contrast caller, but I still feel something is missing... + +------------------------------------------------------------------------ +r711 | lh3lh3 | 2010-09-03 00:30:48 -0400 (Fri, 03 Sep 2010) | 4 lines +Changed paths: + M /trunk/samtools/bcftools/Makefile + M /trunk/samtools/bcftools/call1.c + M /trunk/samtools/bcftools/prob1.c + M /trunk/samtools/bcftools/vcfutils.pl + + * changed 3.434 to 4.343 (typo!) + * fixed a bug in the contrast caller + * calculate heterozygosity + +------------------------------------------------------------------------ +r710 | lh3lh3 | 2010-09-01 23:24:47 -0400 (Wed, 01 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/bcf.h + M /trunk/samtools/bcftools/bcfutils.c + M /trunk/samtools/bcftools/call1.c + +SNP calling from the GL field + +------------------------------------------------------------------------ +r709 | lh3lh3 | 2010-09-01 18:52:30 -0400 (Wed, 01 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/vcf.c + +fixed another problem + +------------------------------------------------------------------------ +r708 | lh3lh3 | 2010-09-01 18:31:17 -0400 (Wed, 01 Sep 2010) | 3 lines +Changed paths: + M /trunk/samtools/bcftools/bcf.c + M /trunk/samtools/bcftools/vcf.c + + * fixed bugs in parsing VCF + * parser now works with GT/GQ/DP/PL/GL + +------------------------------------------------------------------------ +r707 | lh3lh3 | 2010-09-01 15:28:29 -0400 (Wed, 01 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/Makefile + M /trunk/samtools/bcftools/prob1.c + +Do not compile _BCF_QUAD by default + +------------------------------------------------------------------------ +r706 | lh3lh3 | 2010-09-01 15:21:41 -0400 (Wed, 01 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/bcf.c + M /trunk/samtools/bcftools/bcf.h + M /trunk/samtools/bcftools/bcfutils.c + M /trunk/samtools/bcftools/call1.c + +Write the correct ALT and PL in the SNP calling mode. + +------------------------------------------------------------------------ +r705 | lh3lh3 | 2010-09-01 12:50:33 -0400 (Wed, 01 Sep 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/vcfutils.pl + +more commands for my own uses + +------------------------------------------------------------------------ +r704 | lh3lh3 | 2010-09-01 09:26:10 -0400 (Wed, 01 Sep 2010) | 2 lines +Changed paths: + A /trunk/samtools/bcftools/vcfutils.pl + +Utilities for processing VCF + +------------------------------------------------------------------------ +r703 | lh3lh3 | 2010-08-31 16:44:57 -0400 (Tue, 31 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/Makefile + M /trunk/samtools/bcftools/call1.c + M /trunk/samtools/bcftools/prob1.c + M /trunk/samtools/bcftools/prob1.h + +preliminary contrast variant caller + +------------------------------------------------------------------------ +r702 | lh3lh3 | 2010-08-31 12:28:39 -0400 (Tue, 31 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/call1.c + M /trunk/samtools/bcftools/prob1.c + M /trunk/samtools/bcftools/prob1.h + +z' and z'' can be calculated + +------------------------------------------------------------------------ +r701 | lh3lh3 | 2010-08-31 10:20:57 -0400 (Tue, 31 Aug 2010) | 3 lines +Changed paths: + M /trunk/samtools/bcftools/Makefile + A /trunk/samtools/bcftools/call1.c (from /trunk/samtools/bcftools/vcfout.c:699) + M /trunk/samtools/bcftools/prob1.c + D /trunk/samtools/bcftools/vcfout.c + + * rename vcfout.c as call1.c + * prepare to add two-sample comparison + +------------------------------------------------------------------------ +r699 | lh3lh3 | 2010-08-24 15:28:16 -0400 (Tue, 24 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/vcfout.c + +fixed a bug in calculating the t statistics + +------------------------------------------------------------------------ +r698 | lh3lh3 | 2010-08-24 14:05:50 -0400 (Tue, 24 Aug 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf.h + M /trunk/samtools/bamtk.c + M /trunk/samtools/bcftools/kfunc.c + M /trunk/samtools/bcftools/vcfout.c + + * samtools-0.1.8-13 (r698) + * perform one-tailed t-test for baseQ, mapQ and endDist + +------------------------------------------------------------------------ +r697 | lh3lh3 | 2010-08-24 12:30:13 -0400 (Tue, 24 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/kfunc.c + +added regularized incomplete beta function + +------------------------------------------------------------------------ +r695 | lh3lh3 | 2010-08-23 17:36:17 -0400 (Mon, 23 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bam_plcmd.c + +change the default correlation coefficient + +------------------------------------------------------------------------ +r694 | lh3lh3 | 2010-08-23 14:46:52 -0400 (Mon, 23 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/bcf.c + M /trunk/samtools/bcftools/vcfout.c + +print QUAL as floating numbers + +------------------------------------------------------------------------ +r693 | lh3lh3 | 2010-08-23 14:06:07 -0400 (Mon, 23 Aug 2010) | 3 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/examples/Makefile + A /trunk/samtools/sample.c + A /trunk/samtools/sample.h + + * samtools-0.1.8-12 (r692) + * group data by samples in "mpileup -g" + +------------------------------------------------------------------------ +r692 | lh3lh3 | 2010-08-23 10:58:53 -0400 (Mon, 23 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/Makefile + D /trunk/samtools/bam_mcns.c + D /trunk/samtools/bam_mcns.h + M /trunk/samtools/bam_plcmd.c + +remove VCF output in mpileup + +------------------------------------------------------------------------ +r691 | lh3lh3 | 2010-08-23 10:48:20 -0400 (Mon, 23 Aug 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf.h + + * use the revised MAQ error model for mpileup + * prepare to remove the independent model from mpileup + +------------------------------------------------------------------------ +r690 | lh3lh3 | 2010-08-20 15:46:40 -0400 (Fri, 20 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bam_maqcns.h + M /trunk/samtools/bam_plcmd.c + A /trunk/samtools/errmod.c + A /trunk/samtools/errmod.h + M /trunk/samtools/ksort.h + +added revised MAQ error model + +------------------------------------------------------------------------ +r689 | lh3lh3 | 2010-08-18 09:55:20 -0400 (Wed, 18 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/prob1.c + M /trunk/samtools/bcftools/prob1.h + M /trunk/samtools/bcftools/vcfout.c + +allow to read the prior from the error output. EM iteration is working. + +------------------------------------------------------------------------ +r688 | lh3lh3 | 2010-08-17 12:12:20 -0400 (Tue, 17 Aug 2010) | 3 lines +Changed paths: + M /trunk/samtools/bcftools/main.c + M /trunk/samtools/bcftools/vcf.c + + * write a little more VCF header + * concatenate BCFs + +------------------------------------------------------------------------ +r687 | lh3lh3 | 2010-08-16 20:53:16 -0400 (Mon, 16 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/bcf.c + M /trunk/samtools/bcftools/bcf.h + M /trunk/samtools/bcftools/bcf.tex + +use float for QUAL + +------------------------------------------------------------------------ +r686 | lh3lh3 | 2010-08-14 00:11:13 -0400 (Sat, 14 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/bcf.c + M /trunk/samtools/bcftools/prob1.c + +faster for large sample size (in principle) + +------------------------------------------------------------------------ +r685 | lh3lh3 | 2010-08-13 23:28:31 -0400 (Fri, 13 Aug 2010) | 4 lines +Changed paths: + M /trunk/samtools/bcftools/prob1.c + + * a numerically stable method to calculate z_{jk} + * currently slower than the old method but will be important for large sample size + * in principle, we can speed up for large n, but have not tried + +------------------------------------------------------------------------ +r684 | lh3lh3 | 2010-08-11 21:58:31 -0400 (Wed, 11 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/vcfout.c + +fixed an issue in parsing integer + +------------------------------------------------------------------------ +r683 | lh3lh3 | 2010-08-09 13:05:07 -0400 (Mon, 09 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/bcf.c + +do not print refname if file is converted from VCF + +------------------------------------------------------------------------ +r682 | lh3lh3 | 2010-08-09 12:59:47 -0400 (Mon, 09 Aug 2010) | 3 lines +Changed paths: + M /trunk/samtools/bcftools/vcf.c + + * parse PL + * fixed a bug in parsing VCF + +------------------------------------------------------------------------ +r681 | lh3lh3 | 2010-08-09 12:49:23 -0400 (Mon, 09 Aug 2010) | 4 lines +Changed paths: + M /trunk/samtools/bcftools/bcf.c + M /trunk/samtools/bcftools/bcf.h + M /trunk/samtools/bcftools/bcfutils.c + M /trunk/samtools/bcftools/main.c + M /trunk/samtools/bcftools/vcf.c + M /trunk/samtools/bcftools/vcfout.c + M /trunk/samtools/bgzf.c + M /trunk/samtools/kstring.c + + * fixed a bug in kstrtok@kstring.c + * preliminary VCF parser (not parse everything for now) + * improved view interface + +------------------------------------------------------------------------ +r680 | lh3lh3 | 2010-08-09 10:43:13 -0400 (Mon, 09 Aug 2010) | 4 lines +Changed paths: + M /trunk/samtools/bcftools/bcf.c + M /trunk/samtools/bcftools/bcf.h + M /trunk/samtools/bcftools/vcfout.c + M /trunk/samtools/kstring.c + M /trunk/samtools/kstring.h + + * improved kstring (added kstrtok) + * removed the limit on the format string length in bcftools + * use kstrtok to parse format which fixed a bug in the old code + +------------------------------------------------------------------------ +r679 | lh3lh3 | 2010-08-09 01:12:05 -0400 (Mon, 09 Aug 2010) | 2 lines +Changed paths: + A /trunk/samtools/bcftools/README + M /trunk/samtools/bcftools/vcfout.c + +help messages + +------------------------------------------------------------------------ +r678 | lh3lh3 | 2010-08-09 00:01:52 -0400 (Mon, 09 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/vcfout.c + +perform single-tail test for ED4 + +------------------------------------------------------------------------ +r677 | lh3lh3 | 2010-08-08 23:48:35 -0400 (Sun, 08 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/Makefile + M /trunk/samtools/bcftools/kfunc.c + M /trunk/samtools/bcftools/vcfout.c + + * test depth, end distance and HWE + +------------------------------------------------------------------------ +r676 | lh3lh3 | 2010-08-08 02:04:15 -0400 (Sun, 08 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/kfunc.c + +reimplement incomplete gamma functions. no copy-paste + +------------------------------------------------------------------------ +r675 | lh3lh3 | 2010-08-06 22:42:54 -0400 (Fri, 06 Aug 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf.h + M /trunk/samtools/bcftools/fet.c + M /trunk/samtools/bcftools/prob1.c + M /trunk/samtools/bcftools/prob1.h + M /trunk/samtools/bcftools/vcfout.c + + * bcftools: add HWE (no testing for now) + * record end dist in a 2x2 table, not avg, std any more + +------------------------------------------------------------------------ +r674 | lh3lh3 | 2010-08-06 17:30:16 -0400 (Fri, 06 Aug 2010) | 3 lines +Changed paths: + A /trunk/samtools/bcftools/kfunc.c + + * Special functions: log(gamma()), erfc(), P(a,x) (incomplete gamma) + * Not using Numerical Recipe due to licensing issues + +------------------------------------------------------------------------ +r673 | lh3lh3 | 2010-08-05 23:46:53 -0400 (Thu, 05 Aug 2010) | 2 lines +Changed paths: + A /trunk/samtools/bcftools/fet.c + +Fisher's exact test + +------------------------------------------------------------------------ +r672 | lh3lh3 | 2010-08-05 21:48:33 -0400 (Thu, 05 Aug 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf.h + M /trunk/samtools/bamtk.c + M /trunk/samtools/examples/Makefile + + * samtools-0.1.8-11 (r672) + * collect more stats for allele balance test in bcftools (not yet) + +------------------------------------------------------------------------ +r671 | lh3lh3 | 2010-08-05 16:17:58 -0400 (Thu, 05 Aug 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bcftools/bcf.c + M /trunk/samtools/bcftools/main.c + + * the code base is stablized again. + * I will delay the vcf parser, which is quite complicated but with little value for now + +------------------------------------------------------------------------ +r670 | lh3lh3 | 2010-08-05 16:03:23 -0400 (Thu, 05 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/examples/Makefile + +minor + +------------------------------------------------------------------------ +r669 | lh3lh3 | 2010-08-05 16:03:08 -0400 (Thu, 05 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcftools/vcf.c + +unfinished vcf parser + +------------------------------------------------------------------------ +r668 | lh3lh3 | 2010-08-05 15:46:40 -0400 (Thu, 05 Aug 2010) | 3 lines +Changed paths: + M /trunk/samtools/bcftools/Makefile + M /trunk/samtools/bcftools/bcf.c + M /trunk/samtools/bcftools/bcf.h + M /trunk/samtools/bcftools/bcfutils.c + M /trunk/samtools/bcftools/index.c + M /trunk/samtools/bcftools/main.c + A /trunk/samtools/bcftools/vcf.c + M /trunk/samtools/bcftools/vcfout.c + + * added prelimiary VCF parser (not finished) + * change struct a bit + +------------------------------------------------------------------------ +r667 | lh3lh3 | 2010-08-03 22:35:27 -0400 (Tue, 03 Aug 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf.h + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bcftools/bcf.c + + * allow to set min base q + * fixed a bug in mpileup -u + +------------------------------------------------------------------------ +r666 | lh3lh3 | 2010-08-03 22:08:44 -0400 (Tue, 03 Aug 2010) | 2 lines +Changed paths: + A /trunk/samtools/bcftools/bcf.tex + +spec + +------------------------------------------------------------------------ +r665 | lh3lh3 | 2010-08-03 21:18:57 -0400 (Tue, 03 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/examples/Makefile + +added more examples + +------------------------------------------------------------------------ +r664 | lh3lh3 | 2010-08-03 21:13:00 -0400 (Tue, 03 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf.h + M /trunk/samtools/bcftools/Makefile + +fixed compilation error + +------------------------------------------------------------------------ +r662 | lh3lh3 | 2010-08-03 21:04:00 -0400 (Tue, 03 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/Makefile + D /trunk/samtools/bcf.c + D /trunk/samtools/bcf.h + A /trunk/samtools/bcftools + A /trunk/samtools/bcftools/Makefile + A /trunk/samtools/bcftools/bcf.c + A /trunk/samtools/bcftools/bcf.h + A /trunk/samtools/bcftools/bcfutils.c + A /trunk/samtools/bcftools/index.c + A /trunk/samtools/bcftools/main.c + A /trunk/samtools/bcftools/prob1.c + A /trunk/samtools/bcftools/prob1.h + A /trunk/samtools/bcftools/vcfout.c + +move bcftools to samtools + +------------------------------------------------------------------------ +r660 | lh3lh3 | 2010-08-03 15:58:32 -0400 (Tue, 03 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + +fixed another minor bug + +------------------------------------------------------------------------ +r658 | lh3lh3 | 2010-08-03 15:06:45 -0400 (Tue, 03 Aug 2010) | 3 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/bcf.c + + * samtools-0.1.8-10 (r658) + * fixed a bug in bam2bcf when the reference is N + +------------------------------------------------------------------------ +r657 | lh3lh3 | 2010-08-03 14:50:23 -0400 (Tue, 03 Aug 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf.h + + * fixed a bug + * treat ambiguous ref base as the fifth base + +------------------------------------------------------------------------ +r654 | lh3lh3 | 2010-08-02 17:38:27 -0400 (Mon, 02 Aug 2010) | 2 lines +Changed paths: + M /trunk/bcftools/bcf.c + M /trunk/samtools/bcf.c + +missing a column in VCF output... + +------------------------------------------------------------------------ +r653 | lh3lh3 | 2010-08-02 17:31:33 -0400 (Mon, 02 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcf.c + +fixed a memory leak + +------------------------------------------------------------------------ +r651 | lh3lh3 | 2010-08-02 17:27:31 -0400 (Mon, 02 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/bcf.c + +fixed a bug in bcf reader + +------------------------------------------------------------------------ +r650 | lh3lh3 | 2010-08-02 17:00:41 -0400 (Mon, 02 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam2bcf.c + +fixed a bug + +------------------------------------------------------------------------ +r649 | lh3lh3 | 2010-08-02 16:49:35 -0400 (Mon, 02 Aug 2010) | 3 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/bam2bcf.c + M /trunk/samtools/bam2bcf.h + M /trunk/samtools/bamtk.c + + * samtools-0.1.8-9 (r649) + * lossless representation of PL in BCF output + +------------------------------------------------------------------------ +r648 | lh3lh3 | 2010-08-02 16:07:25 -0400 (Mon, 02 Aug 2010) | 2 lines +Changed paths: + M /trunk/samtools/Makefile + A /trunk/samtools/bam2bcf.c + A /trunk/samtools/bam2bcf.h + M /trunk/samtools/bam_plcmd.c + A /trunk/samtools/bcf.c + A /trunk/samtools/bcf.h + +Generate binary VCF + +------------------------------------------------------------------------ +r644 | lh3lh3 | 2010-07-28 11:59:19 -0400 (Wed, 28 Jul 2010) | 5 lines +Changed paths: + M /trunk/samtools/bam_mcns.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.8-8 (r644) + * mpileup becomes a little stable again + * the method is slightly different, but is more theoretically correct + * snp calling is O(n^2) instead of O(n^3) + +------------------------------------------------------------------------ +r643 | lh3lh3 | 2010-07-28 11:54:15 -0400 (Wed, 28 Jul 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam_mcns.c + + * fixed a STUPID bug, which cost me a lot of time. + * I am going to clean up mcns a little bit + +------------------------------------------------------------------------ +r642 | lh3lh3 | 2010-07-27 23:23:07 -0400 (Tue, 27 Jul 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_mcns.c + M /trunk/samtools/bam_mcns.h + M /trunk/samtools/bam_plcmd.c + +supposedly this is THE correct implementation, but more testing is needed + +------------------------------------------------------------------------ +r641 | lh3lh3 | 2010-07-27 22:43:39 -0400 (Tue, 27 Jul 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_mcns.c + +NOT ready yet. Going to make further changes... + +------------------------------------------------------------------------ +r639 | lh3lh3 | 2010-07-25 22:18:38 -0400 (Sun, 25 Jul 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam_mcns.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.8-7 (r639) + * fixed the reference allele assignment + +------------------------------------------------------------------------ +r638 | lh3lh3 | 2010-07-25 12:01:26 -0400 (Sun, 25 Jul 2010) | 5 lines +Changed paths: + M /trunk/samtools/bam_mcns.c + M /trunk/samtools/bam_mcns.h + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.8-6 (r638) + * skip isnan/isinf in case of float underflow + * added the flat prior + * fixed an issue where there are no reads supporting the reference + +------------------------------------------------------------------------ +r637 | lh3lh3 | 2010-07-24 14:16:27 -0400 (Sat, 24 Jul 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + +minor changes + +------------------------------------------------------------------------ +r636 | lh3lh3 | 2010-07-24 14:07:27 -0400 (Sat, 24 Jul 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_mcns.c + M /trunk/samtools/bam_mcns.h + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + +minor tweaks + +------------------------------------------------------------------------ +r635 | lh3lh3 | 2010-07-24 01:49:49 -0400 (Sat, 24 Jul 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_mcns.c + M /trunk/samtools/bam_mcns.h + M /trunk/samtools/bam_plcmd.c + +posterior expectation FINALLY working. I am so tired... + +------------------------------------------------------------------------ +r633 | lh3lh3 | 2010-07-23 13:50:48 -0400 (Fri, 23 Jul 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + +another minor fix to mpileup + +------------------------------------------------------------------------ +r632 | lh3lh3 | 2010-07-23 13:43:31 -0400 (Fri, 23 Jul 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + +added the format column + +------------------------------------------------------------------------ +r631 | lh3lh3 | 2010-07-23 13:25:44 -0400 (Fri, 23 Jul 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_mcns.c + M /trunk/samtools/bam_mcns.h + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + +added an alternative prior + +------------------------------------------------------------------------ +r628 | lh3lh3 | 2010-07-23 11:48:51 -0400 (Fri, 23 Jul 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_mcns.c + M /trunk/samtools/bam_mcns.h + M /trunk/samtools/bam_plcmd.c + +calculate posterior allele frequency + +------------------------------------------------------------------------ +r627 | lh3lh3 | 2010-07-22 21:39:13 -0400 (Thu, 22 Jul 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam_mcns.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.8-3 (r627) + * multi-sample snp calling appears to work. More tests needed. + +------------------------------------------------------------------------ +r626 | lh3lh3 | 2010-07-22 16:37:56 -0400 (Thu, 22 Jul 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam_mcns.c + M /trunk/samtools/bam_mcns.h + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bam_tview.c + + * preliminary multisample SNP caller. + * something looks not so right, but it largely works + +------------------------------------------------------------------------ +r617 | lh3lh3 | 2010-07-14 16:26:27 -0400 (Wed, 14 Jul 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam_mcns.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.8-2 (r617) + * allele frequency calculation apparently works... + +------------------------------------------------------------------------ +r616 | lh3lh3 | 2010-07-14 13:33:51 -0400 (Wed, 14 Jul 2010) | 3 lines +Changed paths: + M /trunk/samtools/Makefile + A /trunk/samtools/bam_mcns.c + A /trunk/samtools/bam_mcns.h + M /trunk/samtools/bam_plcmd.c + + * added mutli-sample framework. It is not working, yet. + * improved the mpileup interface + +------------------------------------------------------------------------ +r615 | lh3lh3 | 2010-07-13 14:50:12 -0400 (Tue, 13 Jul 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/misc/Makefile + + * samtools-0.1.8-1 (r615) + * allow to get mpileup at required sites + +------------------------------------------------------------------------ +r613 | lh3lh3 | 2010-07-11 22:40:56 -0400 (Sun, 11 Jul 2010) | 2 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/NEWS + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/samtools.1 + +Release samtools-0.1.8 + +------------------------------------------------------------------------ +r612 | lh3lh3 | 2010-07-11 21:08:56 -0400 (Sun, 11 Jul 2010) | 2 lines +Changed paths: + M /trunk/samtools/knetfile.c + +fixed a compiling issue for Windows + +------------------------------------------------------------------------ +r611 | lh3lh3 | 2010-07-11 20:59:15 -0400 (Sun, 11 Jul 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_sort.c + +fixed a bug in sorting when output to stdout (by Peter Chines) + +------------------------------------------------------------------------ +r610 | lh3lh3 | 2010-07-09 17:05:10 -0400 (Fri, 09 Jul 2010) | 2 lines +Changed paths: + M /trunk/samtools/NEWS + M /trunk/samtools/bam_plcmd.c + +change the command line option of pileup + +------------------------------------------------------------------------ +r609 | lh3lh3 | 2010-07-09 00:39:34 -0400 (Fri, 09 Jul 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_pileup.c + A /trunk/samtools/examples/toy.fa + A /trunk/samtools/examples/toy.sam + +make pileup work with CIGAR with I/D at the beginning or in the end + +------------------------------------------------------------------------ +r608 | lh3lh3 | 2010-07-08 22:36:12 -0400 (Thu, 08 Jul 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bam_maqcns.h + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bam_tview.c + + * make tview more friendly + * a temporary remedy for an issue in indel calling + +------------------------------------------------------------------------ +r607 | lh3lh3 | 2010-07-08 14:43:52 -0400 (Thu, 08 Jul 2010) | 4 lines +Changed paths: + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.7-r607 + * improved the genotype accuracy for indels + * use the SOAPsnp model for SNP calling by default. + +------------------------------------------------------------------------ +r606 | lh3lh3 | 2010-07-08 01:05:19 -0400 (Thu, 08 Jul 2010) | 2 lines +Changed paths: + M /trunk/samtools/misc/Makefile + +removed a debugging example + +------------------------------------------------------------------------ +r605 | lh3lh3 | 2010-07-08 01:04:09 -0400 (Thu, 08 Jul 2010) | 4 lines +Changed paths: + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bamtk.c + + * samtools-.1.7-18 (r605) + * fixed an issue when a deletion and mismatch occur at the same time + and the base quality is higher than 40 (if -I40). + +------------------------------------------------------------------------ +r604 | lh3lh3 | 2010-07-02 19:32:24 -0400 (Fri, 02 Jul 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam.h + M /trunk/samtools/bam_index.c + M /trunk/samtools/misc/Makefile + +fixed a minor bug in idxstats + +------------------------------------------------------------------------ +r601 | lh3lh3 | 2010-06-16 09:03:59 -0400 (Wed, 16 Jun 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_index.c + +fixed a minor bug in indexing + +------------------------------------------------------------------------ +r600 | lh3lh3 | 2010-06-15 10:17:53 -0400 (Tue, 15 Jun 2010) | 2 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/bam.c + +change printf() to puts in exporting + +------------------------------------------------------------------------ +r599 | lh3lh3 | 2010-06-13 21:41:11 -0400 (Sun, 13 Jun 2010) | 2 lines +Changed paths: + M /trunk/samtools/bamtk.c + +minor fix. No actual effect. + +------------------------------------------------------------------------ +r598 | lh3lh3 | 2010-06-13 21:32:45 -0400 (Sun, 13 Jun 2010) | 2 lines +Changed paths: + M /trunk/samtools/Makefile + +added Makefile targets to compile shared/dynamic library + +------------------------------------------------------------------------ +r596 | lh3lh3 | 2010-06-13 19:48:07 -0400 (Sun, 13 Jun 2010) | 3 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/bam_index.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.7-17 (r596) + * also keep the number of coor-less reads in the index file + +------------------------------------------------------------------------ +r595 | lh3lh3 | 2010-06-13 18:54:26 -0400 (Sun, 13 Jun 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam_index.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.7-16 (r595) + * write additional information to bam index + +------------------------------------------------------------------------ +r594 | lh3lh3 | 2010-06-13 17:29:52 -0400 (Sun, 13 Jun 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_index.c + +fixed a bug for unmapped sequences in indexing + +------------------------------------------------------------------------ +r593 | lh3lh3 | 2010-06-12 18:11:32 -0400 (Sat, 12 Jun 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam.h + M /trunk/samtools/bam_index.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/samtools.1 + +rename iterf as iter + +------------------------------------------------------------------------ +r592 | lh3lh3 | 2010-06-12 18:02:38 -0400 (Sat, 12 Jun 2010) | 4 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/bam_aux.c + M /trunk/samtools/bam_index.c + M /trunk/samtools/bam_pileup.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.7-15 (r592) + * fixed a few minor memory leaks in the new pileup code + * improved the functionality of mpileup + +------------------------------------------------------------------------ +r591 | lh3lh3 | 2010-06-12 14:09:22 -0400 (Sat, 12 Jun 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam.h + M /trunk/samtools/bam_pileup.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.7-14 (r591) + * elementary multi-way pileup. More testing and more functionality to be done. + +------------------------------------------------------------------------ +r590 | lh3lh3 | 2010-06-12 01:00:24 -0400 (Sat, 12 Jun 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam.h + M /trunk/samtools/bam_pileup.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.7-13 (r590) + * added mpileup APIs. No compiling errors, but not tested at all. It is late. + +------------------------------------------------------------------------ +r589 | lh3lh3 | 2010-06-11 22:37:09 -0400 (Fri, 11 Jun 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam.h + M /trunk/samtools/bam_pileup.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.7-12 (r589) + * added iterator-like APIs for pileup + +------------------------------------------------------------------------ +r588 | lh3lh3 | 2010-06-11 17:41:13 -0400 (Fri, 11 Jun 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam_index.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.7-11 (r588) + * ported a few improvements from tabix back to samtools + +------------------------------------------------------------------------ +r587 | lh3lh3 | 2010-06-11 17:33:16 -0400 (Fri, 11 Jun 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam.h + M /trunk/samtools/bam_index.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.7-10 (r587) + * added iterator interface for bam_fetch (ported back from tabix) + +------------------------------------------------------------------------ +r586 | lh3lh3 | 2010-06-11 13:23:53 -0400 (Fri, 11 Jun 2010) | 3 lines +Changed paths: + M /trunk/samtools/Makefile + A /trunk/samtools/bam_reheader.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/bgzf.c + + * samtools-0.1.7-9 (r586) + * added "reheader" to replace the BAM header + +------------------------------------------------------------------------ +r585 | lh3lh3 | 2010-06-11 12:22:06 -0400 (Fri, 11 Jun 2010) | 3 lines +Changed paths: + M /trunk/samtools/bam.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/kstring.h + + * samtools-0.1.7-8 (r585) + * speed up "view" + +------------------------------------------------------------------------ +r584 | lh3lh3 | 2010-06-11 12:00:41 -0400 (Fri, 11 Jun 2010) | 4 lines +Changed paths: + M /trunk/samtools/bam.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/bgzf.c + M /trunk/samtools/bgzf.h + M /trunk/samtools/kstring.h + M /trunk/samtools/misc/wgsim_eval.pl + + * samtools-0.1.7-7 (r584) + * ported tabix BGZF to samtools + * flush BGZF after writing the BAM header and between alignment boundaries + +------------------------------------------------------------------------ +r583 | petulda | 2010-06-11 11:58:20 -0400 (Fri, 11 Jun 2010) | 1 line +Changed paths: + A /trunk/samtools/misc/varfilter.py + +Initial release on behalf of Aylwyn Scally +------------------------------------------------------------------------ +r561 | petulda | 2010-05-07 08:41:56 -0400 (Fri, 07 May 2010) | 1 line +Changed paths: + M /trunk/samtools/samtools.1 + +Added a note about the indels coordinates +------------------------------------------------------------------------ +r551 | petulda | 2010-04-23 09:42:13 -0400 (Fri, 23 Apr 2010) | 1 line +Changed paths: + M /trunk/samtools/misc/sam2vcf.pl + +Added the possibility to print or not to print the reference allele +------------------------------------------------------------------------ +r546 | petulda | 2010-04-15 04:33:55 -0400 (Thu, 15 Apr 2010) | 1 line +Changed paths: + M /trunk/samtools/sam_header.c + +More descriptive message for space separated tags +------------------------------------------------------------------------ +r545 | petulda | 2010-04-14 11:44:50 -0400 (Wed, 14 Apr 2010) | 1 line +Changed paths: + M /trunk/samtools/misc/sam2vcf.pl + +Speedup with -i, no need to query the reference all the time +------------------------------------------------------------------------ +r541 | petulda | 2010-03-15 10:03:51 -0400 (Mon, 15 Mar 2010) | 1 line +Changed paths: + M /trunk/samtools/sam_header.c + +Fixed the order of sequences in the header +------------------------------------------------------------------------ +r540 | petulda | 2010-03-04 06:28:35 -0500 (Thu, 04 Mar 2010) | 1 line +Changed paths: + M /trunk/samtools/misc/sam2vcf.pl + +Added possibility to select indels only and fixed a bug in reporting homozygous indels. +------------------------------------------------------------------------ +r539 | jmarshall | 2010-02-27 06:48:17 -0500 (Sat, 27 Feb 2010) | 4 lines +Changed paths: + M /trunk/samtools/bam.c + +Improve the invalid 'BAM\1' magic number error message, and also print it +when no bytes can be read from the alleged BAM file, e.g., in the common +user error case when a SAM file has accidentally been supplied. + +------------------------------------------------------------------------ +r538 | petulda | 2010-02-26 10:51:40 -0500 (Fri, 26 Feb 2010) | 1 line +Changed paths: + M /trunk/samtools/AUTHORS + M /trunk/samtools/bam.h + M /trunk/samtools/bam_import.c + M /trunk/samtools/sam_header.c + +Improved efficiency of header parsing +------------------------------------------------------------------------ +r537 | lh3lh3 | 2010-02-23 21:08:48 -0500 (Tue, 23 Feb 2010) | 3 lines +Changed paths: + M /trunk/samtools/misc/export2sam.pl + +Updated export2sam.pl by Chris Saunders from Illumina. + + +------------------------------------------------------------------------ +r536 | petulda | 2010-02-17 08:32:53 -0500 (Wed, 17 Feb 2010) | 1 line +Changed paths: + M /trunk/samtools/misc/samtools.pl + +Fixed filtering of SNPs near indels. Added min indel and SNP quality filter. +------------------------------------------------------------------------ +r535 | petulda | 2010-02-12 04:52:37 -0500 (Fri, 12 Feb 2010) | 1 line +Changed paths: + M /trunk/samtools/misc/sam2vcf.pl + +Print an error for pileups in simple format +------------------------------------------------------------------------ +r534 | lh3lh3 | 2010-02-11 14:01:41 -0500 (Thu, 11 Feb 2010) | 2 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + +added a hidden option in pileup to output the base position (for Erin) + +------------------------------------------------------------------------ +r533 | petulda | 2010-02-09 10:12:14 -0500 (Tue, 09 Feb 2010) | 1 line +Changed paths: + M /trunk/samtools/misc/sam2vcf.pl + +Added possibility to specify a custom column title for the data column +------------------------------------------------------------------------ +r532 | petulda | 2010-02-09 09:46:09 -0500 (Tue, 09 Feb 2010) | 1 line +Changed paths: + M /trunk/samtools/bam_plcmd.c + +Added the -d option to limit maximum depth for indels. +------------------------------------------------------------------------ +r531 | petulda | 2010-02-03 07:57:27 -0500 (Wed, 03 Feb 2010) | 1 line +Changed paths: + M /trunk/samtools/misc/sam2vcf.pl + +Added VCF header +------------------------------------------------------------------------ +r530 | lh3lh3 | 2010-02-01 09:13:19 -0500 (Mon, 01 Feb 2010) | 3 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/misc/samtools.pl + M /trunk/samtools/misc/wgsim.c + + * samtools-0.1.7-6 + * fixed a bug in faidx + +------------------------------------------------------------------------ +r529 | jmarshall | 2010-01-11 18:51:49 -0500 (Mon, 11 Jan 2010) | 2 lines +Changed paths: + M /trunk/samtools/faidx.c + +Put the right filename in the error message. + +------------------------------------------------------------------------ +r528 | lh3lh3 | 2009-12-14 11:26:47 -0500 (Mon, 14 Dec 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.7-5 (r528) + * further add new consensus generation strategy + +------------------------------------------------------------------------ +r527 | petulda | 2009-12-11 12:31:05 -0500 (Fri, 11 Dec 2009) | 1 line +Changed paths: + M /trunk/samtools/knetfile.c + +Fixed a bug in knet_seek +------------------------------------------------------------------------ +r526 | petulda | 2009-12-11 07:51:18 -0500 (Fri, 11 Dec 2009) | 1 line +Changed paths: + M /trunk/samtools/misc/sam2vcf.pl + +Small fix in VCF format: dot for the empty INFO field +------------------------------------------------------------------------ +r525 | petulda | 2009-12-11 04:36:18 -0500 (Fri, 11 Dec 2009) | 1 line +Changed paths: + M /trunk/samtools/sam_header.c + +Allow tabs in the CO header field +------------------------------------------------------------------------ +r524 | jmarshall | 2009-12-10 10:03:58 -0500 (Thu, 10 Dec 2009) | 3 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/Makefile.mingw + +Depend on libbam.a rather than the phony target, so that samtools is not +unnecessarily rebuilt every time. Also clean bgzip. + +------------------------------------------------------------------------ +r523 | jmarshall | 2009-12-10 09:45:32 -0500 (Thu, 10 Dec 2009) | 4 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/Makefile.mingw + +Fix a bug in compiling bgzip: this also needs knetfile.o when _USE_KNETFILE +is defined. Also introduce $(KNETFILE_O) which can be set to empty to +facilitate non-knet builds. + +------------------------------------------------------------------------ +r522 | lh3lh3 | 2009-12-01 13:02:36 -0500 (Tue, 01 Dec 2009) | 4 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/sam_view.c + + * samtools-0.1.7-4 (r522) + * fixed a bug in "view -r" + * added a new option "view -R" to read required read groups from a file + +------------------------------------------------------------------------ +r521 | lh3lh3 | 2009-12-01 10:00:12 -0500 (Tue, 01 Dec 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_md.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.7-3 (r521) + * calmd: optionally mask matching bases as N + +------------------------------------------------------------------------ +r520 | lh3lh3 | 2009-12-01 09:37:17 -0500 (Tue, 01 Dec 2009) | 4 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/misc/samtools.pl + + * samtools-0.1.7-2 (r520) + * fixed a few issues with compilation in Windows (on behalf of John) + * choose a random base as the consensus (for population genetics studies) + +------------------------------------------------------------------------ +r519 | jmarshall | 2009-11-30 10:53:02 -0500 (Mon, 30 Nov 2009) | 6 lines +Changed paths: + M /trunk/samtools/Makefile + +Put libraries at the end, so they can resolve references from libbam.a +as well, even with old-fashioned linkers. + +Also use libbam.a explicitly rather than "-L. -lbam" to ensure that we get +the freshly built library, not some other libbam.a lying around the system. + +------------------------------------------------------------------------ +r518 | jmarshall | 2009-11-30 08:44:56 -0500 (Mon, 30 Nov 2009) | 2 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/misc/Makefile + +Also clean *.exe (for Cygwin users using this makefile). + +------------------------------------------------------------------------ +r517 | jmarshall | 2009-11-30 07:09:04 -0500 (Mon, 30 Nov 2009) | 2 lines +Changed paths: + M /trunk/samtools/bam_index.c + +Index files should be opened in binary mode, not text mode. + +------------------------------------------------------------------------ +r516 | lh3lh3 | 2009-11-27 15:18:59 -0500 (Fri, 27 Nov 2009) | 2 lines +Changed paths: + A /trunk/samtools/examples/bam2bed.c + +another example program + +------------------------------------------------------------------------ +r515 | lh3lh3 | 2009-11-27 10:44:56 -0500 (Fri, 27 Nov 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_import.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/misc/wgsim_eval.pl + M /trunk/samtools/sam.c + + * samtools-0.1.7-1 (r515) + * report an error when .fai contains duplicated names, instead of segfault + +------------------------------------------------------------------------ +r514 | jmarshall | 2009-11-24 09:45:35 -0500 (Tue, 24 Nov 2009) | 2 lines +Changed paths: + M /trunk/samtools/bam.c + +Format 'c'-encoded auxiliary fields correctly, as *signed* integers. + +------------------------------------------------------------------------ +r513 | lh3lh3 | 2009-11-16 10:13:07 -0500 (Mon, 16 Nov 2009) | 2 lines +Changed paths: + M /trunk/samtools/Makefile.mingw + +Update Makefile.mingw for the same reason + +------------------------------------------------------------------------ +r512 | lh3lh3 | 2009-11-16 10:00:08 -0500 (Mon, 16 Nov 2009) | 2 lines +Changed paths: + M /trunk/samtools/Makefile + +Fixed a bug in compiling razip + +------------------------------------------------------------------------ +r510 | lh3lh3 | 2009-11-10 10:55:41 -0500 (Tue, 10 Nov 2009) | 2 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/NEWS + M /trunk/samtools/bamtk.c + M /trunk/samtools/samtools.1 + +Release samtools-0.1.7 (r510) + +------------------------------------------------------------------------ +r509 | lh3lh3 | 2009-11-06 09:17:09 -0500 (Fri, 06 Nov 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.6-22 (r509) + * forget to fix a similar problem in glfgen + +------------------------------------------------------------------------ +r508 | lh3lh3 | 2009-11-06 09:06:40 -0500 (Fri, 06 Nov 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/sam_view.c + + * samtools-0.1.6-21 (r508) + * fixed a potential bug in the indel caller towards the end of a chromosome + +------------------------------------------------------------------------ +r494 | lh3lh3 | 2009-10-26 11:38:00 -0400 (Mon, 26 Oct 2009) | 3 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/sam_view.c + + * samtools-0.1.6-19 (r494) + * allow to convert Illumina quality (64 based) to the BAM quality + +------------------------------------------------------------------------ +r493 | lh3lh3 | 2009-10-26 10:24:39 -0400 (Mon, 26 Oct 2009) | 4 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/bam.c + M /trunk/samtools/bam_import.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/sam.c + M /trunk/samtools/sam_header.c + + * samtools-0.1.6-18 (r493) + * fixed the bugs due to improperly incorporating Petr's header parser + * a little code clean up in sam_header.c + +------------------------------------------------------------------------ +r492 | petulda | 2009-10-24 09:43:25 -0400 (Sat, 24 Oct 2009) | 1 line +Changed paths: + M /trunk/samtools/sam_header.c + +Added sam_header_line_free call for sam_header_parse2 +------------------------------------------------------------------------ +r491 | lh3lh3 | 2009-10-24 00:50:16 -0400 (Sat, 24 Oct 2009) | 3 lines +Changed paths: + M /trunk/samtools/sam_view.c + + * BUGGY VERSION + * fixed a minor bug + +------------------------------------------------------------------------ +r490 | lh3lh3 | 2009-10-24 00:45:12 -0400 (Sat, 24 Oct 2009) | 4 lines +Changed paths: + M /trunk/samtools/bam.c + M /trunk/samtools/bam.h + M /trunk/samtools/bam_import.c + M /trunk/samtools/sam.c + + * BUGGY VERSION + * improved the interface a bit + * bug unfixed + +------------------------------------------------------------------------ +r489 | lh3lh3 | 2009-10-24 00:41:50 -0400 (Sat, 24 Oct 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_import.c + M /trunk/samtools/sam_header.c + M /trunk/samtools/sam_header.h + + * BUGGY VERSION. Please NOT use it. + * Fixed a minor bug, but the major bug is still there. + +------------------------------------------------------------------------ +r488 | lh3lh3 | 2009-10-24 00:17:10 -0400 (Sat, 24 Oct 2009) | 3 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/bam.c + M /trunk/samtools/bam.h + M /trunk/samtools/bam_aux.c + M /trunk/samtools/bam_import.c + M /trunk/samtools/bam_rmdup.c + M /trunk/samtools/bam_rmdupse.c + M /trunk/samtools/kaln.c + M /trunk/samtools/sam.c + M /trunk/samtools/sam_header.c + M /trunk/samtools/sam_header.h + M /trunk/samtools/sam_view.c + + * This revision is SERIOUSLY BUGGY. Please NOT use it. + * Start to incorporate header parsing from Petr Danecek + +------------------------------------------------------------------------ +r487 | petulda | 2009-10-23 11:44:32 -0400 (Fri, 23 Oct 2009) | 1 line +Changed paths: + M /trunk/samtools/sam_header.c + M /trunk/samtools/sam_header.h + +Now possible to merge multiple HeaderDict dictionaries +------------------------------------------------------------------------ +r486 | petulda | 2009-10-22 11:46:58 -0400 (Thu, 22 Oct 2009) | 1 line +Changed paths: + M /trunk/samtools/sam_header.c + + +------------------------------------------------------------------------ +r485 | petulda | 2009-10-22 11:41:56 -0400 (Thu, 22 Oct 2009) | 1 line +Changed paths: + A /trunk/samtools/sam_header.c + A /trunk/samtools/sam_header.h + + +------------------------------------------------------------------------ +r484 | lh3lh3 | 2009-10-19 14:31:32 -0400 (Mon, 19 Oct 2009) | 5 lines +Changed paths: + M /trunk/samtools/bam_import.c + M /trunk/samtools/bam_rmdupse.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/examples/Makefile + + * samtools-0.1.6-17 (r484) + * fixed a memory leak in rmdupse + * fixed a bug in parsing @RG header lines + * test rmdup in examples/ + +------------------------------------------------------------------------ +r483 | lh3lh3 | 2009-10-19 13:22:48 -0400 (Mon, 19 Oct 2009) | 4 lines +Changed paths: + M /trunk/samtools/bam_rmdup.c + M /trunk/samtools/bam_rmdupse.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.6-16 (r483) + * unify the interface of rmdup and rmdupse + * a new bug found in rg2lib(). Have not been fixed yet. + +------------------------------------------------------------------------ +r482 | lh3lh3 | 2009-10-19 13:03:34 -0400 (Mon, 19 Oct 2009) | 4 lines +Changed paths: + M /trunk/samtools/bam.h + M /trunk/samtools/bam_rmdup.c + M /trunk/samtools/bam_rmdupse.c + M /trunk/samtools/bamtk.c + A /trunk/samtools/klist.h + + * samtools-0.1.6-15 (r482) + * rewrite rmdupse + * rmdupse is now library aware + +------------------------------------------------------------------------ +r481 | lh3lh3 | 2009-10-18 00:07:21 -0400 (Sun, 18 Oct 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_rmdup.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.6-14 (r480) + * rmdup is now RG aware + +------------------------------------------------------------------------ +r480 | lh3lh3 | 2009-10-17 22:05:20 -0400 (Sat, 17 Oct 2009) | 2 lines +Changed paths: + M /trunk/samtools/misc/samtools.pl + +added a small unitity to parse SRA XML files + +------------------------------------------------------------------------ +r479 | lh3lh3 | 2009-10-17 20:57:26 -0400 (Sat, 17 Oct 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bam_maqcns.h + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bam_sort.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.6-13 (r479) + * merge: optionally use file names as RG tags + +------------------------------------------------------------------------ +r478 | lh3lh3 | 2009-10-14 14:18:12 -0400 (Wed, 14 Oct 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam.c + M /trunk/samtools/bam.h + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/kaln.c + + * samtools-0.1.6-12 (r478) + * fixed a bug in the indel caller + +------------------------------------------------------------------------ +r477 | lh3lh3 | 2009-10-10 06:12:26 -0400 (Sat, 10 Oct 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_index.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.6-11 (r477) + * fixed a bug due to recent change in bam_index.c (thank Nicole Washington for the patch) + +------------------------------------------------------------------------ +r476 | petulda | 2009-10-09 11:45:36 -0400 (Fri, 09 Oct 2009) | 1 line +Changed paths: + A /trunk/samtools/misc/sam2vcf.pl + +Added the sam2vcf.pl script. +------------------------------------------------------------------------ +r475 | lh3lh3 | 2009-10-08 10:19:16 -0400 (Thu, 08 Oct 2009) | 2 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/bam.c + M /trunk/samtools/bam.h + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bamtk.c + A /trunk/samtools/kaln.c + A /trunk/samtools/kaln.h + +Unfinished modification. Please do not use this revision... + +------------------------------------------------------------------------ +r474 | petulda | 2009-10-08 06:39:54 -0400 (Thu, 08 Oct 2009) | 1 line +Changed paths: + M /trunk/samtools/knetfile.c + +Removed the offending knet_seek message. +------------------------------------------------------------------------ +r473 | petulda | 2009-10-06 09:26:35 -0400 (Tue, 06 Oct 2009) | 1 line +Changed paths: + M /trunk/samtools/knetfile.c + M /trunk/samtools/razf.c + +Bug fix - faidx on RAZF compressed files now working. +------------------------------------------------------------------------ +r472 | lh3lh3 | 2009-10-02 08:42:57 -0400 (Fri, 02 Oct 2009) | 2 lines +Changed paths: + M /trunk/samtools/samtools.1 + +Clarify the meaning of a region like "chr2:1,000,000". + +------------------------------------------------------------------------ +r471 | lh3lh3 | 2009-10-02 05:42:19 -0400 (Fri, 02 Oct 2009) | 2 lines +Changed paths: + M /trunk/samtools/misc/novo2sam.pl + +Fixed minor bugs in novo2sam.pl (on behalf of Ken Chen and Colin Hercus) + +------------------------------------------------------------------------ +r470 | lh3lh3 | 2009-09-29 15:01:27 -0400 (Tue, 29 Sep 2009) | 3 lines +Changed paths: + M /trunk/samtools/Makefile.mingw + M /trunk/samtools/bamtk.c + M /trunk/samtools/knetfile.c + M /trunk/samtools/knetfile.h + + * samtools-0.1.6-9 (r470) + * make knetfile.c compatible with MinGW (thank Martin Morgan for the patch) + +------------------------------------------------------------------------ +r469 | lh3lh3 | 2009-09-29 08:07:44 -0400 (Tue, 29 Sep 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_index.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.6-9 (r469) + * refactor bam_fetch() for Python binding. On behalf of Leo Goodstadt. + +------------------------------------------------------------------------ +r468 | lh3lh3 | 2009-09-28 05:18:29 -0400 (Mon, 28 Sep 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_sort.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/misc/samtools.pl + + * samtools-0.1.6-7 (r468) + * make merge stable + +------------------------------------------------------------------------ +r467 | petulda | 2009-09-28 04:51:29 -0400 (Mon, 28 Sep 2009) | 1 line +Changed paths: + M /trunk/samtools/bgzf.c + M /trunk/samtools/bgzip.c + M /trunk/samtools/razf.c + M /trunk/samtools/razip.c + +Changed the mode for newly created files to 0666. This allows less strict permissions with umask properly set (e.g. 0002 vs. 0022). +------------------------------------------------------------------------ +r466 | lh3lh3 | 2009-09-24 06:29:19 -0400 (Thu, 24 Sep 2009) | 3 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/bam_md.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.6-6 (r466) + * do not crash calmd when some sequences are absent from the reference. + +------------------------------------------------------------------------ +r464 | jmarshall | 2009-09-23 06:14:32 -0400 (Wed, 23 Sep 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam.c + M /trunk/samtools/knetfile.c + +Suppress bgzf_check_EOF() messages when reading from a pipe, as there is +no way to seek on a pipe and the messages always appear. + +------------------------------------------------------------------------ +r463 | petulda | 2009-09-16 07:05:41 -0400 (Wed, 16 Sep 2009) | 1 line +Changed paths: + M /trunk/samtools/knetfile.c + M /trunk/samtools/razf.c + +A bug fix, "samtools view" is now working again. +------------------------------------------------------------------------ +r462 | lh3lh3 | 2009-09-16 04:51:07 -0400 (Wed, 16 Sep 2009) | 3 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/faidx.c + M /trunk/samtools/knetfile.c + M /trunk/samtools/knetfile.h + M /trunk/samtools/razf.c + M /trunk/samtools/razf.h + + * samtools-0.1.6-5 (r462) + * Added knetfile support in razf and faidx (on behalf of Petr Danecek) + +------------------------------------------------------------------------ +r460 | lh3lh3 | 2009-09-09 07:06:22 -0400 (Wed, 09 Sep 2009) | 2 lines +Changed paths: + M /trunk/samtools/samtools.1 + +fixed a formatting issue + +------------------------------------------------------------------------ +r459 | lh3lh3 | 2009-09-08 18:14:08 -0400 (Tue, 08 Sep 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_sort.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.6-4 (r459) + * make sort output the result to stdout when -o is in use + +------------------------------------------------------------------------ +r458 | lh3lh3 | 2009-09-07 05:10:28 -0400 (Mon, 07 Sep 2009) | 4 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/faidx.c + M /trunk/samtools/faidx.h + M /trunk/samtools/samtools.1 + + * samtools-0.1.6-2 (r458) + * added more interface to faidx (by Nils) + * updated documentation + +------------------------------------------------------------------------ +r457 | lh3lh3 | 2009-09-05 16:12:04 -0400 (Sat, 05 Sep 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_sort.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.6-2 (r457) + * get rid of three assert() in bam_sort.c + +------------------------------------------------------------------------ +r456 | jmarshall | 2009-09-04 12:46:25 -0400 (Fri, 04 Sep 2009) | 3 lines +Changed paths: + M /trunk/samtools/razf.c + +Return NULL from _razf_open() (and hence razf_open()/razf_open2()) +when opening the file fails. + +------------------------------------------------------------------------ +r453 | lh3lh3 | 2009-09-02 08:56:33 -0400 (Wed, 02 Sep 2009) | 2 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/NEWS + M /trunk/samtools/bamtk.c + M /trunk/samtools/samtools.1 + D /trunk/samtools/source.dot + +Release samtools-0.1.6 + +------------------------------------------------------------------------ +r451 | lh3lh3 | 2009-09-02 05:44:48 -0400 (Wed, 02 Sep 2009) | 4 lines +Changed paths: + M /trunk/samtools/bam_md.c + M /trunk/samtools/bam_rmdup.c + M /trunk/samtools/bam_rmdupse.c + M /trunk/samtools/bam_sort.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/samtools.1 + + * samtools-0.1.5-34 (r451) + * applied the patch by John + * improved the help message a little bit + +------------------------------------------------------------------------ +r450 | lh3lh3 | 2009-09-02 04:55:55 -0400 (Wed, 02 Sep 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_color.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.5-33 (r450) + * fixed a bug in bam_color.c (on behalf of Nils Homer) + +------------------------------------------------------------------------ +r449 | lh3lh3 | 2009-08-29 15:36:41 -0400 (Sat, 29 Aug 2009) | 4 lines +Changed paths: + M /trunk/samtools/bam_import.c + M /trunk/samtools/bam_md.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/misc/samtools.pl + + * samtools-0.1.5-32 (r449) + * fillmd: fixed a bug in modifying MD/NM tags + * in import, give a warning if the read is aligned but there is no CIGAR. + +------------------------------------------------------------------------ +r448 | lh3lh3 | 2009-08-19 04:44:28 -0400 (Wed, 19 Aug 2009) | 3 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/bam_pileup.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/misc/wgsim_eval.pl + + * samtools-0.1.5-31 (r448) + * fixed an issue when the last CIGAR is I or D + +------------------------------------------------------------------------ +r447 | lh3lh3 | 2009-08-17 04:34:57 -0400 (Mon, 17 Aug 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_aux.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.5-30 (r447) + * fixed a bug in bam_aux_get(): 'A' is not checked + +------------------------------------------------------------------------ +r446 | lh3lh3 | 2009-08-17 04:33:17 -0400 (Mon, 17 Aug 2009) | 2 lines +Changed paths: + M /trunk/samtools/bam_aux.c + M /trunk/samtools/bamtk.c + + * + +------------------------------------------------------------------------ +r444 | lh3lh3 | 2009-08-11 05:02:36 -0400 (Tue, 11 Aug 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_sort.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.5-28 (r444) + * bug in "merge -n" + +------------------------------------------------------------------------ +r443 | lh3lh3 | 2009-08-11 04:29:11 -0400 (Tue, 11 Aug 2009) | 4 lines +Changed paths: + M /trunk/samtools/bam.c + M /trunk/samtools/bam_import.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.5-27 (r443) + * SEQ and QUAL can be "*" + * parse CIGAR "=" and "X" as "M" + +------------------------------------------------------------------------ +r442 | lh3lh3 | 2009-08-07 16:56:38 -0400 (Fri, 07 Aug 2009) | 4 lines +Changed paths: + M /trunk/samtools/bam_pileup.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/misc/md5.c + M /trunk/samtools/misc/md5.h + M /trunk/samtools/misc/md5fa.c + + * samtools-0.1.5-26 (r442) + * replace RSA Inc md5.* with ones under permissive lincense + * fixed a bug in detecting unsorted bam in pileup + +------------------------------------------------------------------------ +r441 | bhandsaker | 2009-08-05 09:41:28 -0400 (Wed, 05 Aug 2009) | 2 lines +Changed paths: + M /trunk/samtools/bgzf.c + M /trunk/samtools/bgzf.h + M /trunk/samtools/bgzip.c + +Change copyright notices now that MIT has approved open source distribution. + +------------------------------------------------------------------------ +r440 | lh3lh3 | 2009-08-05 05:44:24 -0400 (Wed, 05 Aug 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_stat.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.5-25 (r436) + * in flagstats, do not report singletons if both ends are unmapped + +------------------------------------------------------------------------ +r439 | lh3lh3 | 2009-08-04 17:16:51 -0400 (Tue, 04 Aug 2009) | 2 lines +Changed paths: + M /trunk/samtools/misc/maq2sam.c + +fixed a SERIOUS bug in setting 0x20 flag + +------------------------------------------------------------------------ +r438 | lh3lh3 | 2009-08-04 16:50:43 -0400 (Tue, 04 Aug 2009) | 2 lines +Changed paths: + M /trunk/samtools/misc/samtools.pl + +fixed two minor bugs (suggested by Tim M Storm) + +------------------------------------------------------------------------ +r437 | lh3lh3 | 2009-08-04 04:13:24 -0400 (Tue, 04 Aug 2009) | 3 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/misc/samtools.pl + M /trunk/samtools/sam_view.c + + * samtools-0.1.5-24 (r435) + * fixed a typo + +------------------------------------------------------------------------ +r434 | lh3lh3 | 2009-08-03 05:40:42 -0400 (Mon, 03 Aug 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_tview.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.5-23 (r434) + * in tview, press 'r' to show read names rather than sequences + +------------------------------------------------------------------------ +r433 | lh3lh3 | 2009-08-02 14:13:35 -0400 (Sun, 02 Aug 2009) | 3 lines +Changed paths: + M /trunk/samtools/knetfile.c + + * tried to fixed the buggy FTP random access in Windows. FAILED. + * anyway, MinGW seems to have problem with "%lld". + +------------------------------------------------------------------------ +r432 | lh3lh3 | 2009-08-01 19:32:07 -0400 (Sat, 01 Aug 2009) | 5 lines +Changed paths: + M /trunk/samtools/Makefile.mingw + M /trunk/samtools/bamtk.c + M /trunk/samtools/faidx.c + M /trunk/samtools/razf.c + A /trunk/samtools/win32/libcurses.a + A /trunk/samtools/win32/xcurses.h + + * samtools-0.1.5-22 (r432) + * faidx: fixed compitability issue with _WIN32 + * razf: fixed potential compitability issue with _WIN32 + * PDCurses support in Windows + +------------------------------------------------------------------------ +r431 | lh3lh3 | 2009-08-01 18:34:54 -0400 (Sat, 01 Aug 2009) | 2 lines +Changed paths: + M /trunk/samtools/win32/libz.a + +replace the GnuWin32 version of libz.a with my own build with MinGW. + +------------------------------------------------------------------------ +r430 | lh3lh3 | 2009-08-01 18:21:07 -0400 (Sat, 01 Aug 2009) | 2 lines +Changed paths: + M /trunk/samtools/knetfile.c + +add comments + +------------------------------------------------------------------------ +r429 | lh3lh3 | 2009-08-01 17:41:19 -0400 (Sat, 01 Aug 2009) | 3 lines +Changed paths: + M /trunk/samtools/Makefile.mingw + M /trunk/samtools/bamtk.c + M /trunk/samtools/knetfile.c + M /trunk/samtools/knetfile.h + + * samtools-0.1.5-21 (r428) + * knetfile.c is now compatible with mingw-winsock + +------------------------------------------------------------------------ +r428 | lh3lh3 | 2009-07-31 19:39:07 -0400 (Fri, 31 Jul 2009) | 2 lines +Changed paths: + M /trunk/samtools/Makefile.mingw + +simplify MinGW Makefile + +------------------------------------------------------------------------ +r427 | lh3lh3 | 2009-07-31 19:30:54 -0400 (Fri, 31 Jul 2009) | 5 lines +Changed paths: + A /trunk/samtools/Makefile.mingw + M /trunk/samtools/bam_import.c + M /trunk/samtools/bamtk.c + A /trunk/samtools/win32 + A /trunk/samtools/win32/libz.a + A /trunk/samtools/win32/zconf.h + A /trunk/samtools/win32/zlib.h + + * samtools-0.1.5-20 (r427) + * MinGW support. At least SAM<->BAM conversion is working. Other + functionality are not tested at the moment. + * zlib headers and Windows version of libz.a are included in win32/ + +------------------------------------------------------------------------ +r426 | lh3lh3 | 2009-07-31 18:32:09 -0400 (Fri, 31 Jul 2009) | 3 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/sam_view.c + + * samtools-0.1.5-19 (r426) + * fixed a bug caused by recent modifications. Sorry. + +------------------------------------------------------------------------ +r425 | lh3lh3 | 2009-07-31 18:23:51 -0400 (Fri, 31 Jul 2009) | 2 lines +Changed paths: + M /trunk/samtools/bgzf.c + +compatible with Windows binary files + +------------------------------------------------------------------------ +r424 | lh3lh3 | 2009-07-31 05:19:59 -0400 (Fri, 31 Jul 2009) | 5 lines +Changed paths: + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bam_maqcns.h + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bam_tview.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/misc/samtools.pl + + * samtools-0.1.5-18 (r423) + * output additional information in pileup indel lines, for the purepose + of debugging at the moment + * in tview, optionally allow to treat reference skip as deletion + +------------------------------------------------------------------------ +r423 | lh3lh3 | 2009-07-30 17:00:36 -0400 (Thu, 30 Jul 2009) | 2 lines +Changed paths: + A /trunk/samtools/misc/psl2sam.pl + +convert BLAT psl to SAM. + +------------------------------------------------------------------------ +r422 | lh3lh3 | 2009-07-30 06:24:39 -0400 (Thu, 30 Jul 2009) | 6 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/bam.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/bgzf.c + M /trunk/samtools/bgzf.h + M /trunk/samtools/knetfile.c + M /trunk/samtools/sam.c + M /trunk/samtools/sam_view.c + + * samtools-0.1.5-17 (r422) + * fixed a but in knetfile.c when seek type is not SEEK_SET + * write an empty BGZF block to every BGZF file + * check BGZF EOF marker in bam_header_read() + * update ChangeLog + +------------------------------------------------------------------------ +r421 | lh3lh3 | 2009-07-30 05:03:39 -0400 (Thu, 30 Jul 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_import.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/misc/samtools.pl + M /trunk/samtools/sam.c + M /trunk/samtools/sam.h + M /trunk/samtools/sam_view.c + + * samtools-0.1.5-16 (r421) + * in view and pileup, load header from FASTA index if the input is SAM. + +------------------------------------------------------------------------ +r420 | lh3lh3 | 2009-07-29 04:18:55 -0400 (Wed, 29 Jul 2009) | 2 lines +Changed paths: + M /trunk/samtools/misc/maq2sam.c + +do not set "read 1" if reads are not mapped in the PE mode of maq + +------------------------------------------------------------------------ +r419 | lh3lh3 | 2009-07-28 04:52:33 -0400 (Tue, 28 Jul 2009) | 5 lines +Changed paths: + M /trunk/samtools/bam_import.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/misc/samtools.pl + M /trunk/samtools/misc/wgsim_eval.pl + + * samtools-0.1.5-15 (r419) + * in sam_open(), return NULL when the file cannot be opened. + * make wgsim_eval.pl more robust to imperfect SAM + * add "unique" command to samtools.pl + +------------------------------------------------------------------------ +r418 | lh3lh3 | 2009-07-24 09:04:19 -0400 (Fri, 24 Jul 2009) | 2 lines +Changed paths: + M /trunk/samtools/misc/wgsim_eval.pl + +skip @header lines in SAM + +------------------------------------------------------------------------ +r417 | lh3lh3 | 2009-07-24 07:42:38 -0400 (Fri, 24 Jul 2009) | 3 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/sam_view.c + + * samtools-0.1.5-14 (r417) + * more help in "samtools view" due to the recent changes. + +------------------------------------------------------------------------ +r416 | lh3lh3 | 2009-07-24 07:34:30 -0400 (Fri, 24 Jul 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam.c + M /trunk/samtools/bam.h + M /trunk/samtools/bam_import.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/sam.c + M /trunk/samtools/sam.h + M /trunk/samtools/sam_view.c + + * samtools-0.1.5-17 (r416) + * support import/export SAM with string tags + +------------------------------------------------------------------------ +r415 | lh3lh3 | 2009-07-24 06:39:26 -0400 (Fri, 24 Jul 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam.c + M /trunk/samtools/bam.h + M /trunk/samtools/bam_import.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/sam.c + M /trunk/samtools/sam.h + M /trunk/samtools/sam_view.c + + * samtools-0.1.5-12 (r415) + * FLAG now can be in HEX + +------------------------------------------------------------------------ +r414 | lh3lh3 | 2009-07-22 17:03:49 -0400 (Wed, 22 Jul 2009) | 2 lines +Changed paths: + M /trunk/samtools/kstring.h + +fixed a compiling error (thank Ken for fixing it) + +------------------------------------------------------------------------ +r412 | lh3lh3 | 2009-07-21 17:19:40 -0400 (Tue, 21 Jul 2009) | 2 lines +Changed paths: + M /trunk/samtools/kstring.c + M /trunk/samtools/kstring.h + +Implemented Boyer-Moore search in the kstring library. + +------------------------------------------------------------------------ +r409 | lh3lh3 | 2009-07-17 12:10:20 -0400 (Fri, 17 Jul 2009) | 2 lines +Changed paths: + M /trunk/samtools/bam_index.c + +do not include knetfile.h when _USE_KNETFILE is not defined + +------------------------------------------------------------------------ +r408 | lh3lh3 | 2009-07-17 10:29:21 -0400 (Fri, 17 Jul 2009) | 5 lines +Changed paths: + M /trunk/samtools/bam_md.c + M /trunk/samtools/bam_tview.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/bgzf.c + + * samtools-0.1.5-11 (r408) + * force to overwirte existing MD if it is different from the one calculated + from fillmd. + * bgzf.c: improved the compatibility with Windows headers + +------------------------------------------------------------------------ +r407 | lh3lh3 | 2009-07-17 09:46:56 -0400 (Fri, 17 Jul 2009) | 5 lines +Changed paths: + M /trunk/samtools/bam.h + M /trunk/samtools/bam_aux.c + M /trunk/samtools/bam_md.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/sam.h + + * samtools-0.1.5-10 (r407) + * implemented bam_aux_del() to remove a tag + * fillmd: generate the NM tag + * fillmd: cmd interface improvement + +------------------------------------------------------------------------ +r406 | lh3lh3 | 2009-07-16 18:30:40 -0400 (Thu, 16 Jul 2009) | 2 lines +Changed paths: + M /trunk/samtools/Makefile + +Sorry. The old Makefile is for PDCurses... + +------------------------------------------------------------------------ +r405 | lh3lh3 | 2009-07-16 18:30:11 -0400 (Thu, 16 Jul 2009) | 3 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/bam_tview.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.5-9 (r405) + * improved the compatibility with PDCurses a little bit + +------------------------------------------------------------------------ +r404 | lh3lh3 | 2009-07-16 18:23:52 -0400 (Thu, 16 Jul 2009) | 3 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/bam_tview.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.5-8 (r404) + * compatible with PDCurses + +------------------------------------------------------------------------ +r403 | lh3lh3 | 2009-07-16 17:39:39 -0400 (Thu, 16 Jul 2009) | 3 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/kseq.h + + * samtools-0.1.5-7 (r403) + * fixed a bug in kseq.h for binary files (text files are fine) + +------------------------------------------------------------------------ +r402 | lh3lh3 | 2009-07-16 06:49:53 -0400 (Thu, 16 Jul 2009) | 4 lines +Changed paths: + M /trunk/samtools/bam_import.c + M /trunk/samtools/bam_index.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/bgzf.c + + * samtools-0.1.5-6 (r402) + * fixed compiling error when "-D_USE_NETFILE" is not applied + * improve portability to MinGW + +------------------------------------------------------------------------ +r398 | lh3lh3 | 2009-07-13 05:21:36 -0400 (Mon, 13 Jul 2009) | 3 lines +Changed paths: + A /trunk/bam-lite/bam.h (from /trunk/samtools/bam.h:395) + A /trunk/bam-lite/bam_lite.c (from /trunk/samtools/bam_lite.c:395) + D /trunk/samtools/bam_lite.c + + * move bam_lite.c to bam-lite + * copy bam.h to bam-lite + +------------------------------------------------------------------------ +r395 | lh3lh3 | 2009-07-13 05:12:57 -0400 (Mon, 13 Jul 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam.h + M /trunk/samtools/bam_lite.c + M /trunk/samtools/bam_lpileup.c + M /trunk/samtools/bam_pileup.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.5-5 (r395) + * added bam_pileup_file() and removed bam_lpileup_file() + +------------------------------------------------------------------------ +r394 | lh3lh3 | 2009-07-12 19:35:10 -0400 (Sun, 12 Jul 2009) | 3 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/knetfile.c + M /trunk/samtools/knetfile.h + + * samtools-0.1.5-4 (r394) + * http_proxy support in knetfile library (check http_proxy ENV) + +------------------------------------------------------------------------ +r393 | lh3lh3 | 2009-07-12 18:57:07 -0400 (Sun, 12 Jul 2009) | 5 lines +Changed paths: + M /trunk/samtools/bam_index.c + M /trunk/samtools/bam_tview.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/knetfile.c + M /trunk/samtools/knetfile.h + + * samtools-0.1.5-3 (r393) + * knetfile now supports HTTP (no proxy at the moment) + * fixed a potential issue in knetfile on opening ordinary file, although I have + not seen the sideeffect so far. + +------------------------------------------------------------------------ +r392 | lh3lh3 | 2009-07-12 13:50:55 -0400 (Sun, 12 Jul 2009) | 2 lines +Changed paths: + M /trunk/samtools/samtools.1 + +Remove the warning in tview + +------------------------------------------------------------------------ +r391 | lh3lh3 | 2009-07-12 13:42:43 -0400 (Sun, 12 Jul 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_tview.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.5-2 (r391) + * do not show a blank screen when no reads mapped + +------------------------------------------------------------------------ +r390 | lh3lh3 | 2009-07-09 09:01:42 -0400 (Thu, 09 Jul 2009) | 4 lines +Changed paths: + M /trunk/samtools/bam.h + A /trunk/samtools/bam_lite.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.5-1 (r390) + * removed useless _IOLIB in bam.h. This should cause no change at all. + * added bam_lite.c for light-weight BAM reading + +------------------------------------------------------------------------ +r385 | lh3lh3 | 2009-07-07 11:53:29 -0400 (Tue, 07 Jul 2009) | 2 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/knetfile.c + +Release samtools-0.1.5c (fixed a bug in piping) + +------------------------------------------------------------------------ +r383 | lh3lh3 | 2009-07-07 06:39:55 -0400 (Tue, 07 Jul 2009) | 2 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/sam.c + +Release samtools-0.1.5b (BUG! so embarrassing!) + +------------------------------------------------------------------------ +r381 | lh3lh3 | 2009-07-07 06:20:06 -0400 (Tue, 07 Jul 2009) | 2 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/bam.h + M /trunk/samtools/bam_aux.c + M /trunk/samtools/bamtk.c + +Release samtools-0.1.5a (for compatibility with Bio::DB::Sam) + +------------------------------------------------------------------------ +r373 | lh3lh3 | 2009-07-07 05:26:57 -0400 (Tue, 07 Jul 2009) | 2 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/NEWS + M /trunk/samtools/bamtk.c + M /trunk/samtools/samtools.1 + +Release samtools-0.1.5 + +------------------------------------------------------------------------ +r372 | lh3lh3 | 2009-07-07 04:49:27 -0400 (Tue, 07 Jul 2009) | 3 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/sam.c + + * samtools-0.1.4-23 (r372) + * keep header text if "view -t" is used (by Gerton) + +------------------------------------------------------------------------ +r371 | lh3lh3 | 2009-07-06 20:13:32 -0400 (Mon, 06 Jul 2009) | 2 lines +Changed paths: + M /trunk/samtools/samtools.1 + +update documentation + +------------------------------------------------------------------------ +r370 | bhandsaker | 2009-07-02 17:24:34 -0400 (Thu, 02 Jul 2009) | 2 lines +Changed paths: + M /trunk/samtools/Makefile + +Introduced LIBPATH variable so this could be overridden to allow samtools to build correct at the Broad. + +------------------------------------------------------------------------ +r369 | lh3lh3 | 2009-07-02 08:36:53 -0400 (Thu, 02 Jul 2009) | 4 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/bam_aux.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.4-22 (r369) + * in pileup, optionally print E2 and U2 + * remove the debugging code in bam_aux_get() (Drat!) + +------------------------------------------------------------------------ +r368 | lh3lh3 | 2009-07-02 06:32:26 -0400 (Thu, 02 Jul 2009) | 6 lines +Changed paths: + M /trunk/samtools/bam.c + M /trunk/samtools/bam.h + M /trunk/samtools/bam_aux.c + M /trunk/samtools/bam_index.c + M /trunk/samtools/bam_lpileup.c + M /trunk/samtools/bam_md.c + M /trunk/samtools/bam_pileup.c + M /trunk/samtools/bam_rmdup.c + M /trunk/samtools/bam_stat.c + M /trunk/samtools/bam_tview.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/faidx.c + M /trunk/samtools/faidx.h + M /trunk/samtools/glf.c + + * samtools-0.1.4-21 (r368) + * propagate errors rather than exit or complain assertion failure. Assertion + should be only used for checking internal bugs, but not for external input + inconsistency. I was just a bit lazy. + * small memory leak may be present on failure, though + +------------------------------------------------------------------------ +r367 | lh3lh3 | 2009-06-30 11:18:42 -0400 (Tue, 30 Jun 2009) | 2 lines +Changed paths: + M /trunk/samtools/knetfile.c + +reduce the chance of blocking in FTP connection + +------------------------------------------------------------------------ +r366 | lh3lh3 | 2009-06-30 10:35:21 -0400 (Tue, 30 Jun 2009) | 2 lines +Changed paths: + M /trunk/samtools/knetfile.c + +minor changes to knetfile: invalid fd equals -1 rather than 0 + +------------------------------------------------------------------------ +r365 | lh3lh3 | 2009-06-30 09:04:30 -0400 (Tue, 30 Jun 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_index.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/knetfile.c + M /trunk/samtools/knetfile.h + + * samtools-0.1.4-20 (r365) + * download the BAM index file if it is not found in the current working directory. + +------------------------------------------------------------------------ +r364 | lh3lh3 | 2009-06-30 07:39:07 -0400 (Tue, 30 Jun 2009) | 3 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/knetfile.c + + * samtools-0.1.4-19 (r364) + * knetfile: report error when the file is not present on FTP + +------------------------------------------------------------------------ +r363 | lh3lh3 | 2009-06-29 18:23:32 -0400 (Mon, 29 Jun 2009) | 4 lines +Changed paths: + M /trunk/samtools/bam_tview.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/bgzf.c + M /trunk/samtools/bgzf.h + M /trunk/samtools/knetfile.c + M /trunk/samtools/knetfile.h + + * samtools-0.1.4-18 (r363) + * knetfile: do not trigger network communication in FTP seek (lazy seek) + * bgzf: cache recent blocks (disabled by default) + +------------------------------------------------------------------------ +r362 | lh3lh3 | 2009-06-25 16:04:34 -0400 (Thu, 25 Jun 2009) | 2 lines +Changed paths: + M /trunk/samtools/bgzf.c + +write changelog + +------------------------------------------------------------------------ +r361 | lh3lh3 | 2009-06-25 16:03:10 -0400 (Thu, 25 Jun 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_index.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.4-17 (r361) + * if a file is given on FTP, search locally for the BAM index + +------------------------------------------------------------------------ +r360 | lh3lh3 | 2009-06-25 15:44:52 -0400 (Thu, 25 Jun 2009) | 5 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/bam_import.c + M /trunk/samtools/bam_index.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/bgzf.c + M /trunk/samtools/bgzf.h + M /trunk/samtools/knetfile.c + M /trunk/samtools/knetfile.h + + * samtools-0.1.4-16 (r360) + * report more information in index when the input is not sorted + * change the behaviour of knet_seek() such that it returns 0 on success + * support knetfile library in BGZF + +------------------------------------------------------------------------ +r359 | lh3lh3 | 2009-06-25 12:10:55 -0400 (Thu, 25 Jun 2009) | 2 lines +Changed paths: + M /trunk/samtools/knetfile.c + M /trunk/samtools/knetfile.h + +fixed bugs in knetfile.* + +------------------------------------------------------------------------ +r358 | lh3lh3 | 2009-06-25 08:53:19 -0400 (Thu, 25 Jun 2009) | 2 lines +Changed paths: + A /trunk/samtools/knetfile.h + +this is the header file + +------------------------------------------------------------------------ +r357 | lh3lh3 | 2009-06-25 08:52:03 -0400 (Thu, 25 Jun 2009) | 3 lines +Changed paths: + A /trunk/samtools/knetfile.c + + * open a file at FTP + * preliminary version + +------------------------------------------------------------------------ +r354 | lh3lh3 | 2009-06-24 09:02:25 -0400 (Wed, 24 Jun 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.4-15 (r354) + * fixed a memory leak in bam_view1(), although samtools is not using this routine. + +------------------------------------------------------------------------ +r351 | lh3lh3 | 2009-06-17 19:16:26 -0400 (Wed, 17 Jun 2009) | 4 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/faidx.c + + * samtools-0.1.4-13 (r351) + * make faidx more tolerant to empty lines right before or after > lines + * hope this does not introduce new bugs... + +------------------------------------------------------------------------ +r350 | lh3lh3 | 2009-06-16 09:37:01 -0400 (Tue, 16 Jun 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.4-13 (r350) + * fixed a small memory leak in pileup, caused by recent modifications + +------------------------------------------------------------------------ +r347 | lh3lh3 | 2009-06-13 16:20:49 -0400 (Sat, 13 Jun 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/sam_view.c + + * samtools-0.1.4-12 (r347) + * added `-S' to pileup, similar to `view -S' + +------------------------------------------------------------------------ +r346 | lh3lh3 | 2009-06-13 12:52:31 -0400 (Sat, 13 Jun 2009) | 3 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/bamtk.c + M /trunk/samtools/sam_view.c + M /trunk/samtools/samtools.1 + + * samtools-0.1.4-11 (r346) + * allow to select a read group at view command-line + +------------------------------------------------------------------------ +r344 | lh3lh3 | 2009-06-13 09:06:24 -0400 (Sat, 13 Jun 2009) | 2 lines +Changed paths: + M /trunk/samtools/examples/calDepth.c + +added more comments + +------------------------------------------------------------------------ +r343 | lh3lh3 | 2009-06-13 09:01:22 -0400 (Sat, 13 Jun 2009) | 2 lines +Changed paths: + M /trunk/samtools/examples/calDepth.c + +nothing really + +------------------------------------------------------------------------ +r342 | lh3lh3 | 2009-06-13 08:58:48 -0400 (Sat, 13 Jun 2009) | 2 lines +Changed paths: + M /trunk/samtools/examples/Makefile + A /trunk/samtools/examples/calDepth.c + +added an example of calculating read depth + +------------------------------------------------------------------------ +r341 | lh3lh3 | 2009-06-13 08:00:08 -0400 (Sat, 13 Jun 2009) | 6 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/bam.h + M /trunk/samtools/bam_aux.c + A /trunk/samtools/bam_color.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bam_sort.c + M /trunk/samtools/bam_tview.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/sam.c + M /trunk/samtools/sam.h + + * samtools-0.1.4-10 (r341) + * only include key APIs in libbam.a + * move color-specific routines to bam_color.c + * update documentations + * remove the support of -q in pileup + +------------------------------------------------------------------------ +r340 | lh3lh3 | 2009-06-13 06:17:14 -0400 (Sat, 13 Jun 2009) | 6 lines +Changed paths: + M /trunk/samtools/INSTALL + M /trunk/samtools/Makefile + M /trunk/samtools/bam_aux.c + M /trunk/samtools/bam_import.c + M /trunk/samtools/bam_tview.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/razf.c + M /trunk/samtools/sam_view.c + + * samtools-0.1.4-9 (r340) + * added a warning to razf.c if zlib<1.2.2.1 + * fixed a compilation warning + * fixed a segfault caused by @RG parsing + * detect NCURSES in bam_tview.c + +------------------------------------------------------------------------ +r339 | lh3lh3 | 2009-06-13 05:35:19 -0400 (Sat, 13 Jun 2009) | 2 lines +Changed paths: + M /trunk/samtools/INSTALL + +update INSTALL + +------------------------------------------------------------------------ +r338 | lh3lh3 | 2009-06-12 19:15:24 -0400 (Fri, 12 Jun 2009) | 4 lines +Changed paths: + M /trunk/samtools/bam.c + M /trunk/samtools/bam.h + M /trunk/samtools/bam_aux.c + M /trunk/samtools/bam_import.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/kstring.h + M /trunk/samtools/sam.c + M /trunk/samtools/sam_view.c + + * samtools-0.1.4-8 (r338) + * parse the @RG header lines and allow to choose library at the "samtools view" + command line + +------------------------------------------------------------------------ +r337 | lh3lh3 | 2009-06-12 16:25:50 -0400 (Fri, 12 Jun 2009) | 4 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/bgzf.c + M /trunk/samtools/bgzf.h + M /trunk/samtools/sam.c + M /trunk/samtools/sam_view.c + + * samtools-0.1.4-7 (r337) + * bgzf.c: support mode string "wu": uncompressed output + * "samtools view" support "-u" command-line option + +------------------------------------------------------------------------ +r336 | lh3lh3 | 2009-06-12 12:20:12 -0400 (Fri, 12 Jun 2009) | 5 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/misc/Makefile + M /trunk/samtools/razf.c + M /trunk/samtools/razf.h + M /trunk/samtools/razip.c + + * no changes to samtools itself + * remove zlib source codes + * make RAZF reading compatible with old version of zlib + * on old version of zlib, writing is not available + +------------------------------------------------------------------------ +r335 | lh3lh3 | 2009-06-12 11:47:33 -0400 (Fri, 12 Jun 2009) | 2 lines +Changed paths: + D /trunk/samtools/zlib + +remove zlib for simplification... + +------------------------------------------------------------------------ +r334 | lh3lh3 | 2009-06-12 10:43:36 -0400 (Fri, 12 Jun 2009) | 5 lines +Changed paths: + M /trunk/samtools/bam.h + M /trunk/samtools/bam_aux.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.4-6 (r334) + * do not export bam_aux_get_core() for Bio::DB::Sam because it has already + been implemented in that. + * this version works with the latest Bio::DB::Sam (20090612) + +------------------------------------------------------------------------ +r333 | lh3lh3 | 2009-06-12 10:33:42 -0400 (Fri, 12 Jun 2009) | 2 lines +Changed paths: + M /trunk/samtools/ChangeLog + +update ChangeLog + +------------------------------------------------------------------------ +r332 | lh3lh3 | 2009-06-12 10:21:21 -0400 (Fri, 12 Jun 2009) | 2 lines +Changed paths: + M /trunk/samtools/AUTHORS + M /trunk/samtools/Makefile + M /trunk/samtools/misc/Makefile + +fixed minor things in Makefile + +------------------------------------------------------------------------ +r331 | lh3lh3 | 2009-06-12 10:07:05 -0400 (Fri, 12 Jun 2009) | 4 lines +Changed paths: + M /trunk/samtools/bamtk.c + + * samtools-0.1.4-5 (r3310 + * no change to samtools itself. Version number is increased to reflect the + changes in the Makefile building system. + +------------------------------------------------------------------------ +r330 | lh3lh3 | 2009-06-12 10:03:38 -0400 (Fri, 12 Jun 2009) | 2 lines +Changed paths: + M /trunk/samtools/AUTHORS + D /trunk/samtools/README + +update information... + +------------------------------------------------------------------------ +r329 | lh3lh3 | 2009-06-12 09:52:21 -0400 (Fri, 12 Jun 2009) | 3 lines +Changed paths: + M /trunk/samtools/misc/novo2sam.pl + + * updated novoalign converter by Colin Hercus et al. + * this version works with indels + +------------------------------------------------------------------------ +r328 | lh3lh3 | 2009-06-12 09:50:53 -0400 (Fri, 12 Jun 2009) | 3 lines +Changed paths: + M /trunk/samtools/INSTALL + M /trunk/samtools/Makefile + M /trunk/samtools/misc/Makefile + M /trunk/samtools/zlib/Makefile + + * update Makefile + * update INSTALL instruction + +------------------------------------------------------------------------ +r327 | lh3lh3 | 2009-06-12 09:18:29 -0400 (Fri, 12 Jun 2009) | 4 lines +Changed paths: + A /trunk/samtools/Makefile (from /trunk/samtools/Makefile.generic:325) + D /trunk/samtools/Makefile.am + D /trunk/samtools/Makefile.generic + D /trunk/samtools/Makefile.lite + D /trunk/samtools/autogen.sh + D /trunk/samtools/cleanup.sh + D /trunk/samtools/configure.ac + A /trunk/samtools/misc/Makefile (from /trunk/samtools/misc/Makefile.generic:305) + D /trunk/samtools/misc/Makefile.am + D /trunk/samtools/misc/Makefile.generic + M /trunk/samtools/razf.c + A /trunk/samtools/zlib + A /trunk/samtools/zlib/Makefile + A /trunk/samtools/zlib/adler32.c + A /trunk/samtools/zlib/compress.c + A /trunk/samtools/zlib/crc32.c + A /trunk/samtools/zlib/crc32.h + A /trunk/samtools/zlib/deflate.c + A /trunk/samtools/zlib/deflate.h + A /trunk/samtools/zlib/gzio.c + A /trunk/samtools/zlib/infback.c + A /trunk/samtools/zlib/inffast.c + A /trunk/samtools/zlib/inffast.h + A /trunk/samtools/zlib/inffixed.h + A /trunk/samtools/zlib/inflate.c + A /trunk/samtools/zlib/inflate.h + A /trunk/samtools/zlib/inftrees.c + A /trunk/samtools/zlib/inftrees.h + A /trunk/samtools/zlib/trees.c + A /trunk/samtools/zlib/trees.h + A /trunk/samtools/zlib/uncompr.c + A /trunk/samtools/zlib/zconf.h + A /trunk/samtools/zlib/zlib.h + A /trunk/samtools/zlib/zutil.c + A /trunk/samtools/zlib/zutil.h + D /trunk/samtools/zutil.h + + * added zlib-1.2.3 as razip requires that + * prepare to changed back to the Makefile building system + * unfinished! (will be soon) + +------------------------------------------------------------------------ +r326 | lh3lh3 | 2009-06-12 09:12:03 -0400 (Fri, 12 Jun 2009) | 2 lines +Changed paths: + M /trunk/samtools/misc/samtools.pl + +Unfinished + +------------------------------------------------------------------------ +r325 | lh3lh3 | 2009-06-10 11:27:59 -0400 (Wed, 10 Jun 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.4-4 (r325) + * further avoid wrong consensus calls in repetitive regions. + +------------------------------------------------------------------------ +r324 | lh3lh3 | 2009-06-10 10:56:17 -0400 (Wed, 10 Jun 2009) | 4 lines +Changed paths: + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/sam.c + M /trunk/samtools/sam.h + + * samtools-0.1.4-3 (r324) + * make maqcns generate the correct call in repetitive regions. + * allow filtering on mapQ at the pileup command line + +------------------------------------------------------------------------ +r323 | lh3lh3 | 2009-06-10 05:04:21 -0400 (Wed, 10 Jun 2009) | 3 lines +Changed paths: + M /trunk/samtools/misc/samtools.pl + + * samtools.pl-0.3.2 (r322) + * indels and SNPs use different mapping quality threshold + +------------------------------------------------------------------------ +r322 | lh3lh3 | 2009-06-10 05:03:22 -0400 (Wed, 10 Jun 2009) | 2 lines +Changed paths: + M /trunk/samtools/misc/export2sam.pl + +fixed a typo + +------------------------------------------------------------------------ +r321 | lh3lh3 | 2009-06-09 04:21:48 -0400 (Tue, 09 Jun 2009) | 2 lines +Changed paths: + M /trunk/samtools/misc/samtools.pl + +just typo. no real change + +------------------------------------------------------------------------ +r320 | lh3lh3 | 2009-06-08 09:32:51 -0400 (Mon, 08 Jun 2009) | 2 lines +Changed paths: + M /trunk/samtools/misc/samtools.pl + +a little bit code cleanup + +------------------------------------------------------------------------ +r319 | lh3lh3 | 2009-06-08 09:22:33 -0400 (Mon, 08 Jun 2009) | 4 lines +Changed paths: + M /trunk/samtools/misc/samtools.pl + + * samtools.pl-0.3.1 + * change default parameters + * optionally print filtered variants + +------------------------------------------------------------------------ +r318 | lh3lh3 | 2009-06-08 09:14:26 -0400 (Mon, 08 Jun 2009) | 3 lines +Changed paths: + M /trunk/samtools/misc/samtools.pl + + * samtools.pl-0.3.0 + * combine snpFilter and indelFilter + +------------------------------------------------------------------------ +r317 | lh3lh3 | 2009-06-08 06:31:42 -0400 (Mon, 08 Jun 2009) | 3 lines +Changed paths: + M /trunk/samtools/misc/samtools.pl + + * samtools.pl-0.2.3 + * change a default parameter + +------------------------------------------------------------------------ +r316 | lh3lh3 | 2009-06-08 06:11:06 -0400 (Mon, 08 Jun 2009) | 5 lines +Changed paths: + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bam_maqcns.h + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/sam.c + + * samtools-0.1.4-2 (r316) + * pileup: cap mapping quality at 60 (by default) + * pileup: always calculate RMS mapq + * pileup: allow to output variant sites only + +------------------------------------------------------------------------ +r312 | lh3lh3 | 2009-06-04 08:01:10 -0400 (Thu, 04 Jun 2009) | 3 lines +Changed paths: + M /trunk/samtools/misc/samtools.pl + + * samtools.pl-0.2.2 + * added pileup2fq + +------------------------------------------------------------------------ +r311 | lh3lh3 | 2009-06-03 04:40:40 -0400 (Wed, 03 Jun 2009) | 2 lines +Changed paths: + M /trunk/samtools/misc/samtools.pl + + * in snpFilter, suppress non-SNP sites + +------------------------------------------------------------------------ +r310 | lh3lh3 | 2009-06-01 09:35:13 -0400 (Mon, 01 Jun 2009) | 3 lines +Changed paths: + M /trunk/samtools/misc/samtools.pl + + * samtools.pl-0.2.1 + * fixed a typo + +------------------------------------------------------------------------ +r309 | lh3lh3 | 2009-06-01 09:04:39 -0400 (Mon, 01 Jun 2009) | 3 lines +Changed paths: + M /trunk/samtools/misc/samtools.pl + + * samtools.pl-0.2.0 + * snpFilter + +------------------------------------------------------------------------ +r306 | lh3lh3 | 2009-05-28 06:49:35 -0400 (Thu, 28 May 2009) | 3 lines +Changed paths: + M /trunk/samtools/bgzf.c + + * minor changes to bgzf: return NULL if fd == -1 + * suggested by {kdj,jm18}@sanger.ac.uk + +------------------------------------------------------------------------ +r305 | lh3lh3 | 2009-05-28 06:16:08 -0400 (Thu, 28 May 2009) | 2 lines +Changed paths: + A /trunk/samtools/misc/interpolate_sam.pl + +Script for paired-end pileup, contributed by Stephen Montgomery. + +------------------------------------------------------------------------ +r304 | lh3lh3 | 2009-05-28 06:08:49 -0400 (Thu, 28 May 2009) | 3 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/sam.c + + * samtools-0.1.4-1 (r304) + * fixed a minor bug in printing headers + +------------------------------------------------------------------------ +r297 | lh3lh3 | 2009-05-21 11:06:16 -0400 (Thu, 21 May 2009) | 2 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/NEWS + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/misc/maq2sam.c + M /trunk/samtools/samtools.1 + +Release samtools-0.1.4 + +------------------------------------------------------------------------ +r296 | lh3lh3 | 2009-05-21 07:53:14 -0400 (Thu, 21 May 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.3-24 (r296) + * another similar bug in the indel caller + +------------------------------------------------------------------------ +r295 | lh3lh3 | 2009-05-21 07:50:28 -0400 (Thu, 21 May 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.3-23 (r295) + * fixed a critical bug in the indel caller + +------------------------------------------------------------------------ +r294 | lh3lh3 | 2009-05-20 08:00:20 -0400 (Wed, 20 May 2009) | 2 lines +Changed paths: + M /trunk/samtools/bam_stat.c + +added a missing header file + +------------------------------------------------------------------------ +r293 | lh3lh3 | 2009-05-19 18:44:25 -0400 (Tue, 19 May 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_tview.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.3-22 (r293) + * open tview in the dot-view mode by default + +------------------------------------------------------------------------ +r292 | lh3lh3 | 2009-05-18 16:01:23 -0400 (Mon, 18 May 2009) | 6 lines +Changed paths: + M /trunk/samtools/samtools.1 + +Added a note to the manual. Currently SAMtools used unaligned words in +several places. Although this does not cause bus errors to me, it may +affect portability. Please see the "Bus error" wiki page for more +information. Also thank James Bonfields for pointing this out. + + +------------------------------------------------------------------------ +r286 | lh3lh3 | 2009-05-14 10:23:13 -0400 (Thu, 14 May 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam.h + M /trunk/samtools/bam_aux.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.3-21 (286) + * declare bam_aux_get_core() in bam.h + +------------------------------------------------------------------------ +r276 | lh3lh3 | 2009-05-13 05:07:55 -0400 (Wed, 13 May 2009) | 5 lines +Changed paths: + M /trunk/samtools/bam.h + M /trunk/samtools/bam_index.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.3-20 (r276) + * remove bam1_t::hash again. We need to modify the Perl API anyway to + make it work with the latest SVN. + * As is suggested by Tim, scan "{base}.bai" and "{base}.bam.bai" for index + +------------------------------------------------------------------------ +r275 | lh3lh3 | 2009-05-12 16:14:10 -0400 (Tue, 12 May 2009) | 4 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/bam.h + M /trunk/samtools/bamtk.c + + * samtools-0.1.3-19 (r275) + * a minor change to the bam1_t struct: added back "void *hash" for the + backward compatibility with Bio::DB::Sam + +------------------------------------------------------------------------ +r273 | lh3lh3 | 2009-05-12 09:28:39 -0400 (Tue, 12 May 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_rmdupse.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.3-18 (r273) + * rmdupse: do not remove unmapped reads + +------------------------------------------------------------------------ +r272 | lh3lh3 | 2009-05-12 09:20:00 -0400 (Tue, 12 May 2009) | 2 lines +Changed paths: + M /trunk/samtools/bam_rmdupse.c + +change a parameter. It does nothing + +------------------------------------------------------------------------ +r271 | lh3lh3 | 2009-05-12 09:17:58 -0400 (Tue, 12 May 2009) | 3 lines +Changed paths: + M /trunk/samtools/Makefile.am + M /trunk/samtools/Makefile.generic + M /trunk/samtools/Makefile.lite + A /trunk/samtools/bam_rmdupse.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/configure.ac + + * samtools-0.1.3-17 (r271) + * added 'rmdupse' command + +------------------------------------------------------------------------ +r267 | lh3lh3 | 2009-05-05 17:31:41 -0400 (Tue, 05 May 2009) | 3 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/sam_view.c + + * samtools-0.1.3-16 (r267) + * in sam_view.c, changed g_flag_on based on the suggestion by Angie Hinrichs + +------------------------------------------------------------------------ +r266 | lh3lh3 | 2009-05-05 17:23:27 -0400 (Tue, 05 May 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_import.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.3-15 (r266) + * report an error if a non-* reference is present while @SQ is absent + +------------------------------------------------------------------------ +r265 | lh3lh3 | 2009-05-05 17:09:00 -0400 (Tue, 05 May 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam.h + M /trunk/samtools/bam_import.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/sam.c + M /trunk/samtools/sam_view.c + + * samtools-0.1.3-14 (r262) + * make samopen() recognize @SQ header lines + +------------------------------------------------------------------------ +r261 | lh3lh3 | 2009-05-05 10:10:30 -0400 (Tue, 05 May 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/bgzf.c + M /trunk/samtools/sam.c + M /trunk/samtools/sam_view.c + + * samtools-0.1.3-13 (r260) + * report error for file I/O error + +------------------------------------------------------------------------ +r260 | lh3lh3 | 2009-05-05 10:01:16 -0400 (Tue, 05 May 2009) | 2 lines +Changed paths: + M /trunk/samtools/Makefile.am + +update Makefile.am + +------------------------------------------------------------------------ +r259 | lh3lh3 | 2009-05-05 09:52:25 -0400 (Tue, 05 May 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam.h + M /trunk/samtools/bam_pileup.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/sam.c + M /trunk/samtools/sam.h + + * samtools-0.1.3-12 (r259) + * use the new I/O interface in pileup + +------------------------------------------------------------------------ +r258 | lh3lh3 | 2009-05-05 09:33:22 -0400 (Tue, 05 May 2009) | 3 lines +Changed paths: + M /trunk/samtools/Makefile.generic + M /trunk/samtools/Makefile.lite + M /trunk/samtools/bam.c + M /trunk/samtools/bam.h + M /trunk/samtools/bam_import.c + M /trunk/samtools/bamtk.c + A /trunk/samtools/sam.c + A /trunk/samtools/sam.h + A /trunk/samtools/sam_view.c + + * samtools-0.1.3-11 (r258) + * unify the interface to BAM and SAM I/O + +------------------------------------------------------------------------ +r257 | lh3lh3 | 2009-05-05 04:53:35 -0400 (Tue, 05 May 2009) | 3 lines +Changed paths: + M /trunk/samtools/Makefile.lite + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.3-10 (r257) + * allow hex with "pileup -m" + +------------------------------------------------------------------------ +r256 | lh3lh3 | 2009-05-04 14:16:50 -0400 (Mon, 04 May 2009) | 4 lines +Changed paths: + M /trunk/samtools/bam_lpileup.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.3-9 (r256) + * fixed a bug in bam_lpileup.c + * I do not know if this also fixes the bug causing assertion failure in the tview + +------------------------------------------------------------------------ +r251 | lh3lh3 | 2009-04-28 08:53:23 -0400 (Tue, 28 Apr 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_pileup.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.3-8 (r251) + * fixed a bug when there are reads without coordinates + +------------------------------------------------------------------------ +r250 | lh3lh3 | 2009-04-28 08:43:33 -0400 (Tue, 28 Apr 2009) | 2 lines +Changed paths: + A /trunk/samtools/AUTHORS + A /trunk/samtools/README + M /trunk/samtools/cleanup.sh + +added missing files + +------------------------------------------------------------------------ +r249 | lh3lh3 | 2009-04-28 08:37:16 -0400 (Tue, 28 Apr 2009) | 2 lines +Changed paths: + M /trunk/samtools/Makefile.generic + M /trunk/samtools/Makefile.lite + M /trunk/samtools/configure.ac + M /trunk/samtools/misc/Makefile.generic + +improve large file support in compilation + +------------------------------------------------------------------------ +r248 | lh3lh3 | 2009-04-28 08:33:24 -0400 (Tue, 28 Apr 2009) | 2 lines +Changed paths: + M /trunk/samtools/INSTALL + +update INSTALL + +------------------------------------------------------------------------ +r247 | lh3lh3 | 2009-04-28 08:28:50 -0400 (Tue, 28 Apr 2009) | 2 lines +Changed paths: + M /trunk/samtools/Makefile.am + M /trunk/samtools/autogen.sh + M /trunk/samtools/cleanup.sh + M /trunk/samtools/configure.ac + A /trunk/samtools/misc/Makefile.am + +fixed various issues about the GNU building scripts + +------------------------------------------------------------------------ +r246 | lh3lh3 | 2009-04-28 08:10:23 -0400 (Tue, 28 Apr 2009) | 4 lines +Changed paths: + M /trunk/samtools/ChangeLog + D /trunk/samtools/Makefile + A /trunk/samtools/Makefile.am + A /trunk/samtools/Makefile.generic + A /trunk/samtools/autogen.sh + M /trunk/samtools/bam.h + M /trunk/samtools/bam_aux.c + M /trunk/samtools/bam_tview.c + M /trunk/samtools/bamtk.c + A /trunk/samtools/cleanup.sh + A /trunk/samtools/configure.ac + D /trunk/samtools/misc/Makefile + A /trunk/samtools/misc/Makefile.generic (from /trunk/samtools/misc/Makefile:245) + + * samtools-0.1.3-7 (r246) + * incorporated revisions from Nils Homer + * enhanced support of displaying color-space reads + +------------------------------------------------------------------------ +r244 | lh3lh3 | 2009-04-25 06:49:40 -0400 (Sat, 25 Apr 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_md.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.3-6 (r244) + * fixed segfault for unmapped reads + +------------------------------------------------------------------------ +r243 | lh3lh3 | 2009-04-24 16:27:26 -0400 (Fri, 24 Apr 2009) | 5 lines +Changed paths: + M /trunk/samtools/bam.h + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bam_md.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.3-5 (r243) + * fixed a long existing bug which may cause memory leak + * check MD + * consensus calling now works with "=", but indel calling not + +------------------------------------------------------------------------ +r242 | lh3lh3 | 2009-04-24 15:44:46 -0400 (Fri, 24 Apr 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_md.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.3-4 (r242) + * fixed a memory leak + +------------------------------------------------------------------------ +r240 | lh3lh3 | 2009-04-24 11:40:18 -0400 (Fri, 24 Apr 2009) | 5 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/Makefile.lite + M /trunk/samtools/bam.h + M /trunk/samtools/bam_aux.c + A /trunk/samtools/bam_md.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.3-3 (r240) + * generate MD tag + * generate "=" bases + * the plain pileup now support "=" bases, but consensus calling and glfgen may fail + +------------------------------------------------------------------------ +r239 | lh3lh3 | 2009-04-24 07:08:20 -0400 (Fri, 24 Apr 2009) | 5 lines +Changed paths: + M /trunk/samtools/bam.h + M /trunk/samtools/bam_aux.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.3-2 (r239) + * fixed bugs in bam_aux.c (these functions nevered used by samtools) + * removed bam_aux_init()/bam_aux_destroy() + * added tagview for testing bam_aux + +------------------------------------------------------------------------ +r235 | lh3lh3 | 2009-04-21 18:17:39 -0400 (Tue, 21 Apr 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_pileup.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.3-1 + * fixed a bug in pileup: the first read in a chromosome may not be printed + +------------------------------------------------------------------------ +r232 | lh3lh3 | 2009-04-16 10:25:43 -0400 (Thu, 16 Apr 2009) | 2 lines +Changed paths: + M /trunk/samtools/Makefile.lite + +a missing file in Makefile.lite + +------------------------------------------------------------------------ +r227 | lh3lh3 | 2009-04-15 17:02:53 -0400 (Wed, 15 Apr 2009) | 2 lines +Changed paths: + M /trunk/samtools/NEWS + M /trunk/samtools/bamtk.c + +Release samtools-0.1.3 + +------------------------------------------------------------------------ +r223 | lh3lh3 | 2009-04-15 09:31:32 -0400 (Wed, 15 Apr 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.2-28 + * make samtools more robust to weird input such as empty file + +------------------------------------------------------------------------ +r222 | lh3lh3 | 2009-04-15 09:05:33 -0400 (Wed, 15 Apr 2009) | 2 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/NEWS + M /trunk/samtools/samtools.1 + +prepare for release 0.1.3 + +------------------------------------------------------------------------ +r221 | lh3lh3 | 2009-04-15 08:32:14 -0400 (Wed, 15 Apr 2009) | 2 lines +Changed paths: + A /trunk/samtools/misc/blast2sam.pl + +convert NCBI-BLASTN to SAM + +------------------------------------------------------------------------ +r220 | lh3lh3 | 2009-04-15 08:18:19 -0400 (Wed, 15 Apr 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_lpileup.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.2-27 + * fixed a small memory leak in tview + +------------------------------------------------------------------------ +r219 | lh3lh3 | 2009-04-15 08:00:08 -0400 (Wed, 15 Apr 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_rmdup.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.2-26 + * fixed a bug in rmdup when there are unmapped reads + +------------------------------------------------------------------------ +r218 | lh3lh3 | 2009-04-14 17:28:58 -0400 (Tue, 14 Apr 2009) | 2 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/NEWS + +proposed NEWS for the new release (have not yet) + +------------------------------------------------------------------------ +r216 | lh3lh3 | 2009-04-14 17:10:46 -0400 (Tue, 14 Apr 2009) | 4 lines +Changed paths: + M /trunk/samtools/misc/samtools.pl + + * samtools.pl-0.1.1 + * improve indelFilter to avoid filtering true indels. The new filter relies + on the new pileup indel line implemented in samtools-0.1.2-25 + +------------------------------------------------------------------------ +r215 | lh3lh3 | 2009-04-14 17:04:19 -0400 (Tue, 14 Apr 2009) | 4 lines +Changed paths: + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/samtools.1 + + * samtools-0.1.2-25 + * change the pileup indel line to shows the number of alignments actually + containing indels + +------------------------------------------------------------------------ +r211 | lh3lh3 | 2009-04-13 07:07:13 -0400 (Mon, 13 Apr 2009) | 2 lines +Changed paths: + M /trunk/samtools/ChangeLog + +update ChangeLog from "svn log" + +------------------------------------------------------------------------ +r210 | lh3lh3 | 2009-04-12 15:57:05 -0400 (Sun, 12 Apr 2009) | 4 lines +Changed paths: + M /trunk/samtools/bam.c + M /trunk/samtools/bam_import.c + M /trunk/samtools/bam_sort.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/kseq.h + + * samtools-0.1.2-24 + * in merge, gives a warning rather than error if the target sequence length is different + * allow empty header + +------------------------------------------------------------------------ +r209 | lh3lh3 | 2009-04-12 15:32:44 -0400 (Sun, 12 Apr 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam.c + M /trunk/samtools/bam_import.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.2-23 + * recognize '*' at the QUAL field + +------------------------------------------------------------------------ +r208 | lh3lh3 | 2009-04-12 15:08:02 -0400 (Sun, 12 Apr 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_import.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/kseq.h + + * samtools-0.1.2-22 + * the field separater is TAB only, now + +------------------------------------------------------------------------ +r207 | lh3lh3 | 2009-04-08 10:18:03 -0400 (Wed, 08 Apr 2009) | 2 lines +Changed paths: + M /trunk/samtools/examples/ex1.sam.gz + + * fixed the problem in the example alignment due to the bug in fixmate + +------------------------------------------------------------------------ +r206 | lh3lh3 | 2009-04-08 10:15:05 -0400 (Wed, 08 Apr 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_mate.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/misc/soap2sam.pl + + * samtools-0.1.2-21 + * fixed a nasty bug in `fixmate' + +------------------------------------------------------------------------ +r205 | lh3lh3 | 2009-04-08 05:57:08 -0400 (Wed, 08 Apr 2009) | 2 lines +Changed paths: + M /trunk/samtools/misc/bowtie2sam.pl + M /trunk/samtools/misc/soap2sam.pl + M /trunk/samtools/misc/wgsim_eval.pl + +make the script robust to the bugs in SOAP-2.1.7 + +------------------------------------------------------------------------ +r200 | lh3lh3 | 2009-04-02 10:14:56 -0400 (Thu, 02 Apr 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_stat.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.2-20 + * check if file is truncated in flagstat + +------------------------------------------------------------------------ +r199 | lh3lh3 | 2009-04-02 10:09:10 -0400 (Thu, 02 Apr 2009) | 3 lines +Changed paths: + M /trunk/samtools/bamtk.c + + * samtools-0.1.2-19 + * print the header if requested + +------------------------------------------------------------------------ +r193 | lh3lh3 | 2009-03-27 11:09:50 -0400 (Fri, 27 Mar 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.2-18 + * fixed a minor bug reported by Nils Homer + +------------------------------------------------------------------------ +r185 | lh3lh3 | 2009-03-24 07:50:32 -0400 (Tue, 24 Mar 2009) | 2 lines +Changed paths: + A /trunk/samtools/Makefile (from /trunk/samtools/Makefile.std:184) + D /trunk/samtools/Makefile.std + A /trunk/samtools/misc/Makefile (from /trunk/samtools/misc/Makefile.std:184) + D /trunk/samtools/misc/Makefile.std + +rename Makefile.std as Makefile. GNU building systerm is not ready and may take some time... + +------------------------------------------------------------------------ +r184 | lh3lh3 | 2009-03-24 06:36:38 -0400 (Tue, 24 Mar 2009) | 4 lines +Changed paths: + D /trunk/samtools/Makefile + A /trunk/samtools/Makefile.std (from /trunk/samtools/Makefile:183) + M /trunk/samtools/bam_sort.c + M /trunk/samtools/bam_tview.c + M /trunk/samtools/bamtk.c + D /trunk/samtools/misc/Makefile + A /trunk/samtools/misc/Makefile.std (from /trunk/samtools/misc/Makefile:182) + M /trunk/samtools/samtools.1 + + * samtools-0.1.2-17 + * incorporating Nils' changes + * rename Makefile to Makefile.std and prepare to add the GNU building systerms (also by Nils) + +------------------------------------------------------------------------ +r183 | lh3lh3 | 2009-03-24 06:30:23 -0400 (Tue, 24 Mar 2009) | 4 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/bam_import.c + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bam_maqcns.h + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/kseq.h + A /trunk/samtools/kstring.c + A /trunk/samtools/kstring.h + + * samtools-0.1.2-16 + * made pileup take a list of proposed indels. An insertion is N at the moment. + * added my kstring library for a bit complex parsing of the position list. + +------------------------------------------------------------------------ +r169 | lh3lh3 | 2009-03-12 09:40:14 -0400 (Thu, 12 Mar 2009) | 3 lines +Changed paths: + M /trunk/samtools/misc/soap2sam.pl + + * soap2sam.pl-0.1.2 + * more robust to truncated soap output + +------------------------------------------------------------------------ +r168 | lh3lh3 | 2009-03-11 06:49:00 -0400 (Wed, 11 Mar 2009) | 2 lines +Changed paths: + M /trunk/samtools/Makefile.lite + +added bam_stat.o to Makefile.lite + +------------------------------------------------------------------------ +r167 | lh3lh3 | 2009-03-10 18:11:31 -0400 (Tue, 10 Mar 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.2-15 + * generate RMS of mapQ instead of max mapQ + +------------------------------------------------------------------------ +r166 | lh3lh3 | 2009-03-10 18:06:45 -0400 (Tue, 10 Mar 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/glf.c + M /trunk/samtools/glf.h + M /trunk/samtools/misc/Makefile + + * samtools-0.1.2-14 + * implemented GLFv3 + +------------------------------------------------------------------------ +r159 | lh3lh3 | 2009-03-03 06:26:08 -0500 (Tue, 03 Mar 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.2-13 + * fixed a minor bug in displaying pileup + +------------------------------------------------------------------------ +r158 | lh3lh3 | 2009-03-03 06:24:16 -0500 (Tue, 03 Mar 2009) | 3 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/bamtk.c + + * samtools-0.1.2-12 + * optionally print SAM header + +------------------------------------------------------------------------ +r153 | lh3lh3 | 2009-03-02 05:45:28 -0500 (Mon, 02 Mar 2009) | 3 lines +Changed paths: + M /trunk/samtools/bamtk.c + M /trunk/samtools/glf.c + + * samtools-0.1.2-11 + * use "GLF\3" as the magic for GLFv3 files + +------------------------------------------------------------------------ +r152 | lh3lh3 | 2009-03-02 05:39:09 -0500 (Mon, 02 Mar 2009) | 5 lines +Changed paths: + M /trunk/samtools/Makefile + M /trunk/samtools/bam_import.c + M /trunk/samtools/bam_index.c + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/glf.c + M /trunk/samtools/glf.h + + * samtools-0.1.2-10 + * fixed a bug in import: core.bin is undefined for unmapped reads + * this bug can be alleviated (not completely solved) in bam_index.c + * update to GLFv3: pos is changed to offset for better compression + +------------------------------------------------------------------------ +r151 | lh3lh3 | 2009-03-01 10:18:43 -0500 (Sun, 01 Mar 2009) | 3 lines +Changed paths: + M /trunk/samtools/misc/wgsim.c + + * wgsim-0.2.3 + * fixed a bug in simulating indels + +------------------------------------------------------------------------ +r145 | lh3lh3 | 2009-02-26 14:43:57 -0500 (Thu, 26 Feb 2009) | 4 lines +Changed paths: + M /trunk/samtools/misc/wgsim.c + + * wgsim-0.2.2 + * allow to print mismatch information as fastq comment. MAQ does + not like long read names. + +------------------------------------------------------------------------ +r141 | lh3lh3 | 2009-02-26 09:53:03 -0500 (Thu, 26 Feb 2009) | 6 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/misc/wgsim.c + M /trunk/samtools/misc/wgsim_eval.pl + + * wgsim-0.2.1 + * fixed a bug about color read coordinates + * fixed a bug in read names + * wgsim_eval.pl-0.1.3 + * make the script work with color reads + +------------------------------------------------------------------------ +r140 | lh3lh3 | 2009-02-26 09:02:57 -0500 (Thu, 26 Feb 2009) | 2 lines +Changed paths: + M /trunk/samtools/misc/Makefile + M /trunk/samtools/misc/wgsim.c + + * wgsim: added a note + +------------------------------------------------------------------------ +r139 | lh3lh3 | 2009-02-26 06:39:08 -0500 (Thu, 26 Feb 2009) | 7 lines +Changed paths: + M /trunk/samtools/misc/wgsim.c + M /trunk/samtools/misc/wgsim_eval.pl + + * wgsim-0.2.0 + * considerable code clean up + * print number of substitutions/indels/errors on each read + * potentially support SOLiD simulation, though not tested at the moment + * wgsim_eval.pl-0.1.2 + * change in accordant with wgsim + +------------------------------------------------------------------------ +r129 | lh3lh3 | 2009-02-18 17:23:27 -0500 (Wed, 18 Feb 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_index.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.2-9 + * fixed a bug in bam_fetch, caused by completely contained adjacent chunks + +------------------------------------------------------------------------ +r128 | bhandsaker | 2009-02-18 14:06:57 -0500 (Wed, 18 Feb 2009) | 2 lines +Changed paths: + M /trunk/samtools/bamtk.c + +Fix annoying segv when invalid region specified. + +------------------------------------------------------------------------ +r127 | lh3lh3 | 2009-02-17 05:49:55 -0500 (Tue, 17 Feb 2009) | 2 lines +Changed paths: + D /trunk/samtools/misc/indel_filter.pl + A /trunk/samtools/misc/samtools.pl + + * move indel_filter.pl to samtools.pl + +------------------------------------------------------------------------ +r126 | lh3lh3 | 2009-02-14 16:22:30 -0500 (Sat, 14 Feb 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_mate.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.2-7 + * fixed a bug in fixmate: SE reads are flagged as BAM_FMUNMAP + +------------------------------------------------------------------------ +r125 | lh3lh3 | 2009-02-13 04:54:45 -0500 (Fri, 13 Feb 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_stat.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.2-7 + * fixed a minor bug in flagstat + +------------------------------------------------------------------------ +r124 | lh3lh3 | 2009-02-12 06:15:32 -0500 (Thu, 12 Feb 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/misc/indel_filter.pl + + * samtools-0.1.2-6 + * improve indel caller by setting maximum window size + +------------------------------------------------------------------------ +r123 | lh3lh3 | 2009-02-12 05:30:29 -0500 (Thu, 12 Feb 2009) | 2 lines +Changed paths: + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bamtk.c + + * output max mapping quality in indel line + +------------------------------------------------------------------------ +r122 | lh3lh3 | 2009-02-11 05:59:10 -0500 (Wed, 11 Feb 2009) | 2 lines +Changed paths: + M /trunk/samtools/misc/maq2sam.c + +fixed a bug in generating tag AM + +------------------------------------------------------------------------ +r121 | lh3lh3 | 2009-02-03 05:43:11 -0500 (Tue, 03 Feb 2009) | 2 lines +Changed paths: + M /trunk/samtools/bam_index.c + M /trunk/samtools/bamtk.c + +fixed a potential memory problem in indexing + +------------------------------------------------------------------------ +r120 | bhandsaker | 2009-02-02 10:52:52 -0500 (Mon, 02 Feb 2009) | 2 lines +Changed paths: + M /trunk/samtools/Makefile + +Pass LIBS to recursive targets to facilitate building at Broad. + +------------------------------------------------------------------------ +r119 | lh3lh3 | 2009-02-02 05:12:15 -0500 (Mon, 02 Feb 2009) | 4 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/bam_plcmd.c + M /trunk/samtools/bam_stat.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.2-3 + * fixed a bug in generating GLFv2 for indels + * improve flagstat report a little bit + +------------------------------------------------------------------------ +r118 | lh3lh3 | 2009-01-29 07:33:23 -0500 (Thu, 29 Jan 2009) | 3 lines +Changed paths: + M /trunk/samtools/Makefile + A /trunk/samtools/bam_stat.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.2-1 + * added flagstat command + +------------------------------------------------------------------------ +r116 | lh3lh3 | 2009-01-28 08:31:12 -0500 (Wed, 28 Jan 2009) | 2 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/NEWS + M /trunk/samtools/bamtk.c + M /trunk/samtools/samtools.1 + +Release SAMtools-0.1.2 + +------------------------------------------------------------------------ +r115 | lh3lh3 | 2009-01-28 07:54:08 -0500 (Wed, 28 Jan 2009) | 2 lines +Changed paths: + A /trunk/samtools/misc/indel_filter.pl + +Script for filtering indel results + +------------------------------------------------------------------------ +r114 | lh3lh3 | 2009-01-25 06:45:37 -0500 (Sun, 25 Jan 2009) | 2 lines +Changed paths: + A /trunk/samtools/misc/zoom2sam.pl + +convert ZOOM to SAM + +------------------------------------------------------------------------ +r113 | lh3lh3 | 2009-01-24 09:25:07 -0500 (Sat, 24 Jan 2009) | 2 lines +Changed paths: + A /trunk/samtools/misc/novo2sam.pl + +add a script to convert novo alignment to SAM + +------------------------------------------------------------------------ +r112 | lh3lh3 | 2009-01-23 15:57:39 -0500 (Fri, 23 Jan 2009) | 2 lines +Changed paths: + M /trunk/samtools/ChangeLog + M /trunk/samtools/ChangeLog.old + M /trunk/samtools/samtools.1 + +update documentation and ChangeLog + +------------------------------------------------------------------------ +r111 | lh3lh3 | 2009-01-23 14:22:59 -0500 (Fri, 23 Jan 2009) | 3 lines +Changed paths: + M /trunk/samtools/bam_sort.c + M /trunk/samtools/bamtk.c + + * samtools-0.1.1-19 + * fixed a bug in "merge" command line + +------------------------------------------------------------------------ +r110 | lh3lh3 | 2009-01-22 10:36:48 -0500 (Thu, 22 Jan 2009) | 3 lines +Changed paths: + M /trunk/samtools/misc/Makefile + A /trunk/samtools/misc/bowtie2sam.pl (from /branches/dev/samtools/misc/bowtie2sam.pl:108) + M /trunk/samtools/misc/export2sam.pl + A /trunk/samtools/misc/soap2sam.pl (from /branches/dev/samtools/misc/soap2sam.pl:108) + A /trunk/samtools/misc/wgsim.c (from /branches/dev/samtools/misc/wgsim.c:108) + A /trunk/samtools/misc/wgsim_eval.pl (from /branches/dev/samtools/misc/wgsim_eval.pl:108) + + * merge from branches/dev/ + * all future development will happen here + +------------------------------------------------------------------------ +r109 | lh3lh3 | 2009-01-22 10:14:27 -0500 (Thu, 22 Jan 2009) | 3 lines +Changed paths: + M /trunk/samtools/COPYING + M /trunk/samtools/ChangeLog + A /trunk/samtools/INSTALL (from /branches/dev/samtools/INSTALL:108) + M /trunk/samtools/Makefile + A /trunk/samtools/Makefile.lite (from /branches/dev/samtools/Makefile.lite:108) + M /trunk/samtools/bam.c + M /trunk/samtools/bam.h + M /trunk/samtools/bam_import.c + M /trunk/samtools/bam_index.c + M /trunk/samtools/bam_lpileup.c + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bam_maqcns.h + A /trunk/samtools/bam_mate.c (from /branches/dev/samtools/bam_mate.c:108) + M /trunk/samtools/bam_pileup.c + M /trunk/samtools/bam_plcmd.c + A /trunk/samtools/bam_rmdup.c (from /branches/dev/samtools/bam_rmdup.c:108) + M /trunk/samtools/bam_sort.c + M /trunk/samtools/bamtk.c + M /trunk/samtools/bgzf.h + M /trunk/samtools/examples/00README.txt + A /trunk/samtools/examples/Makefile (from /branches/dev/samtools/examples/Makefile:108) + D /trunk/samtools/examples/ex1.fa.fai + M /trunk/samtools/examples/ex1.sam.gz + M /trunk/samtools/faidx.c + A /trunk/samtools/glf.c (from /branches/dev/samtools/glf.c:108) + M /trunk/samtools/glf.h + M /trunk/samtools/misc/Makefile + M /trunk/samtools/misc/maq2sam.c + M /trunk/samtools/razf.c + M /trunk/samtools/source.dot + + * Merge from branches/dev/ + * all future development will happen here at trunk/ + +------------------------------------------------------------------------ +r79 | bhandsaker | 2009-01-07 16:42:15 -0500 (Wed, 07 Jan 2009) | 2 lines +Changed paths: + M /trunk/samtools/bam_maqcns.c + M /trunk/samtools/bam_tview.c + +Fix problem with compiling without curses. + +------------------------------------------------------------------------ +r63 | lh3lh3 | 2008-12-22 10:58:02 -0500 (Mon, 22 Dec 2008) | 2 lines +Changed paths: + A /trunk/samtools (from /branches/dev/samtools:62) + +Create trunk copy + +------------------------------------------------------------------------ +r62 | lh3lh3 | 2008-12-22 10:55:13 -0500 (Mon, 22 Dec 2008) | 2 lines +Changed paths: + A /branches/dev/samtools/NEWS + M /branches/dev/samtools/bamtk.c + M /branches/dev/samtools/samtools.1 + +Release samtools-0.1.1 + +------------------------------------------------------------------------ +r61 | lh3lh3 | 2008-12-22 10:46:08 -0500 (Mon, 22 Dec 2008) | 10 lines +Changed paths: + M /branches/dev/samtools/bam_aux.c + M /branches/dev/samtools/bam_index.c + M /branches/dev/samtools/bam_plcmd.c + M /branches/dev/samtools/bam_tview.c + M /branches/dev/samtools/bamtk.c + M /branches/dev/samtools/razf.c + M /branches/dev/samtools/samtools.1 + + * samtools-0.1.0-66 + * fixed a bug in razf.c: reset z_eof when razf_seek() is called + * fixed a memory leak in parsing a region + * changed pileup a little bit when -s is in use: output ^ and $ + * when a bam is not indexed, output more meaningful error message + * fixed a bug in indexing for small alignment + * fixed a bug in the viewer when we come to the end of a reference file + * updated documentation + * prepare to release 0.1.1 + +------------------------------------------------------------------------ +r60 | lh3lh3 | 2008-12-22 10:10:16 -0500 (Mon, 22 Dec 2008) | 2 lines +Changed paths: + A /branches/dev/samtools/examples + A /branches/dev/samtools/examples/00README.txt + A /branches/dev/samtools/examples/ex1.fa + A /branches/dev/samtools/examples/ex1.fa.fai + A /branches/dev/samtools/examples/ex1.sam.gz + +example + +------------------------------------------------------------------------ +r59 | lh3lh3 | 2008-12-22 04:38:15 -0500 (Mon, 22 Dec 2008) | 2 lines +Changed paths: + M /branches/dev/samtools/ChangeLog + +update ChangeLog + +------------------------------------------------------------------------ +r58 | lh3lh3 | 2008-12-20 18:06:00 -0500 (Sat, 20 Dec 2008) | 3 lines +Changed paths: + M /branches/dev/samtools/misc/export2sam.pl + + * added comments + * fixed several bugs + +------------------------------------------------------------------------ +r57 | lh3lh3 | 2008-12-20 10:44:20 -0500 (Sat, 20 Dec 2008) | 2 lines +Changed paths: + A /branches/dev/samtools/misc/export2sam.pl + +convert Export format to SAM; not thoroughly tested + +------------------------------------------------------------------------ +r56 | lh3lh3 | 2008-12-19 17:13:28 -0500 (Fri, 19 Dec 2008) | 6 lines +Changed paths: + M /branches/dev/samtools/bam_import.c + M /branches/dev/samtools/bam_plcmd.c + M /branches/dev/samtools/bam_tview.c + M /branches/dev/samtools/bamtk.c + A /branches/dev/samtools/source.dot + + * samtools-0.1.0-65 + * pileup: generate maq-like simple output + * pileup: allow to output pileup at required sites + * source.dot: source file relationship graph + * tview: fixed a minor bug + +------------------------------------------------------------------------ +r55 | lh3lh3 | 2008-12-19 15:10:26 -0500 (Fri, 19 Dec 2008) | 2 lines +Changed paths: + D /branches/dev/samtools/misc/all2sam.pl + +remove all2sam.pl + +------------------------------------------------------------------------ +r54 | lh3lh3 | 2008-12-16 17:34:25 -0500 (Tue, 16 Dec 2008) | 2 lines +Changed paths: + A /branches/dev/samtools/COPYING + M /branches/dev/samtools/bam.h + M /branches/dev/samtools/faidx.h + M /branches/dev/samtools/khash.h + M /branches/dev/samtools/kseq.h + M /branches/dev/samtools/ksort.h + M /branches/dev/samtools/samtools.1 + +Added copyright information and a bit more documentation. No code change. + +------------------------------------------------------------------------ +r53 | lh3lh3 | 2008-12-16 08:40:18 -0500 (Tue, 16 Dec 2008) | 3 lines +Changed paths: + M /branches/dev/samtools/bam.c + M /branches/dev/samtools/bam.h + M /branches/dev/samtools/bam_index.c + M /branches/dev/samtools/bam_maqcns.c + M /branches/dev/samtools/bamtk.c + + * samtools-0.1.0-64 + * improved efficiency of the indel caller for spliced alignments + +------------------------------------------------------------------------ +r52 | lh3lh3 | 2008-12-16 05:28:20 -0500 (Tue, 16 Dec 2008) | 3 lines +Changed paths: + M /branches/dev/samtools/bam.c + M /branches/dev/samtools/bam.h + M /branches/dev/samtools/bam_aux.c + M /branches/dev/samtools/bam_index.c + M /branches/dev/samtools/bamtk.c + + * samtools-0.1.0-63 + * a bit code cleanup: reduce the dependency between source files + +------------------------------------------------------------------------ +r51 | lh3lh3 | 2008-12-15 09:29:32 -0500 (Mon, 15 Dec 2008) | 3 lines +Changed paths: + M /branches/dev/samtools/bam_maqcns.c + M /branches/dev/samtools/bam_plcmd.c + M /branches/dev/samtools/bamtk.c + + * samtools-0.1.0-62 + * fixed a memory leak + +------------------------------------------------------------------------ +r50 | lh3lh3 | 2008-12-15 09:00:13 -0500 (Mon, 15 Dec 2008) | 2 lines +Changed paths: + M /branches/dev/samtools/ChangeLog + M /branches/dev/samtools/bam.h + M /branches/dev/samtools/samtools.1 + +update documentation, ChangeLog and a comment + +------------------------------------------------------------------------ +r49 | lh3lh3 | 2008-12-15 08:36:43 -0500 (Mon, 15 Dec 2008) | 6 lines +Changed paths: + M /branches/dev/samtools/Makefile + M /branches/dev/samtools/bam.h + M /branches/dev/samtools/bam_maqcns.c + M /branches/dev/samtools/bam_maqcns.h + M /branches/dev/samtools/bam_pileup.c + A /branches/dev/samtools/bam_plcmd.c + M /branches/dev/samtools/bamtk.c + M /branches/dev/samtools/samtools.1 + + * samtools-0.1.0-61 + * moved pileup command to a separate source file + * added indel caller + * added bam_cal_segend(). (NOT WORKING for spliced alignment!!!) + * updated documentation + +------------------------------------------------------------------------ +r48 | lh3lh3 | 2008-12-12 08:55:36 -0500 (Fri, 12 Dec 2008) | 3 lines +Changed paths: + M /branches/dev/samtools/bam_maqcns.c + M /branches/dev/samtools/bamtk.c + + * samtools-0.1.0-60 + * fixed another bug in maqcns when there is a nearby deletion + +------------------------------------------------------------------------ +r47 | lh3lh3 | 2008-12-12 08:42:16 -0500 (Fri, 12 Dec 2008) | 5 lines +Changed paths: + M /branches/dev/samtools/bam_maqcns.c + M /branches/dev/samtools/bam_pileup.c + M /branches/dev/samtools/bamtk.c + + * samtools-0.1.0-59 + * pileup: outputing consensus is now optional + * fixed a bug in glfgen. This bug also exists in maq's glfgen. However, + I am not quite sure why the previous version may have problem. + +------------------------------------------------------------------------ +r46 | lh3lh3 | 2008-12-12 06:44:56 -0500 (Fri, 12 Dec 2008) | 6 lines +Changed paths: + M /branches/dev/samtools/bam_pileup.c + M /branches/dev/samtools/bamtk.c + + * samtools-0.1.0-58 + * add maq consensus to pileup. However, I will move this part to a new + command as strictly speaking, consensus callin is not part of pileup, + and imposing it would make it harder to generate for other language + bindings. + +------------------------------------------------------------------------ +r45 | bhandsaker | 2008-12-11 15:43:56 -0500 (Thu, 11 Dec 2008) | 2 lines +Changed paths: + M /branches/dev/samtools/bgzf.c + +Fix bug in tell() after reads that consume to the exact end of a block. + +------------------------------------------------------------------------ +r44 | lh3lh3 | 2008-12-11 04:36:53 -0500 (Thu, 11 Dec 2008) | 2 lines +Changed paths: + M /branches/dev/samtools/samtools.1 + +update manual + +------------------------------------------------------------------------ +r43 | lh3lh3 | 2008-12-11 04:25:36 -0500 (Thu, 11 Dec 2008) | 4 lines +Changed paths: + M /branches/dev/samtools/bam_import.c + M /branches/dev/samtools/bamtk.c + + * samtools-0.1.0-57 + * fixed a bug in parser when there is auxiliary fields + * made the parser a bit more robust + +------------------------------------------------------------------------ +r42 | lh3lh3 | 2008-12-10 09:57:29 -0500 (Wed, 10 Dec 2008) | 5 lines +Changed paths: + M /branches/dev/samtools/bam_index.c + M /branches/dev/samtools/bamtk.c + M /branches/dev/samtools/bgzf.c + + * samtools-0.1.0-56 + * fixed a bug in bgzf (only reading is affected) + * fixed a typo in bam_index.c + * in bam_index.c, check potential bugs in the underlying I/O library + +------------------------------------------------------------------------ +r41 | lh3lh3 | 2008-12-10 07:53:08 -0500 (Wed, 10 Dec 2008) | 2 lines +Changed paths: + M /branches/dev/samtools/samtools.1 + +update manual + +------------------------------------------------------------------------ +r40 | lh3lh3 | 2008-12-10 06:52:10 -0500 (Wed, 10 Dec 2008) | 5 lines +Changed paths: + M /branches/dev/samtools/bam.h + M /branches/dev/samtools/bam_pileup.c + M /branches/dev/samtools/bamtk.c + + * samtools-0.1.0-55 + * tried to make pileup work with clipping (previously not), though NOT tested + * removed -v from pileup + * made pileup take the reference sequence + +------------------------------------------------------------------------ +r39 | lh3lh3 | 2008-12-09 06:59:28 -0500 (Tue, 09 Dec 2008) | 4 lines +Changed paths: + M /branches/dev/samtools/bam_import.c + M /branches/dev/samtools/bamtk.c + M /branches/dev/samtools/samtools.1 + + * samtools-0.1.0-54 + * in parser, recognize "=", rather than ",", as a match + * in parser, correctl parse "=" at the MRNM field. + +------------------------------------------------------------------------ +r38 | lh3lh3 | 2008-12-09 06:39:07 -0500 (Tue, 09 Dec 2008) | 2 lines +Changed paths: + M /branches/dev/samtools/misc/maq2sam.c + +fixed a bug in handling maq flag 64 and 192 + +------------------------------------------------------------------------ +r37 | lh3lh3 | 2008-12-09 04:53:46 -0500 (Tue, 09 Dec 2008) | 2 lines +Changed paths: + M /branches/dev/samtools/misc/md5fa.c + +also calculate unordered md5sum check + +------------------------------------------------------------------------ +r36 | lh3lh3 | 2008-12-09 04:46:21 -0500 (Tue, 09 Dec 2008) | 2 lines +Changed paths: + M /branches/dev/samtools/misc/md5fa.c + +fixed a minor bug when there are space in the sequence + +------------------------------------------------------------------------ +r35 | lh3lh3 | 2008-12-09 04:40:45 -0500 (Tue, 09 Dec 2008) | 2 lines +Changed paths: + M /branches/dev/samtools/misc/md5fa.c + +fixed a potential memory leak + +------------------------------------------------------------------------ +r34 | lh3lh3 | 2008-12-08 09:52:17 -0500 (Mon, 08 Dec 2008) | 2 lines +Changed paths: + M /branches/dev/samtools/bam_import.c + M /branches/dev/samtools/bam_index.c + M /branches/dev/samtools/bamtk.c + + * fixed a bug in import: bin is wrongly calculated + +------------------------------------------------------------------------ +r33 | lh3lh3 | 2008-12-08 09:08:01 -0500 (Mon, 08 Dec 2008) | 2 lines +Changed paths: + M /branches/dev/samtools/misc/all2sam.pl + +nothing, really + +------------------------------------------------------------------------ +r32 | lh3lh3 | 2008-12-08 07:56:02 -0500 (Mon, 08 Dec 2008) | 3 lines +Changed paths: + M /branches/dev/samtools/Makefile + M /branches/dev/samtools/kseq.h + M /branches/dev/samtools/misc/Makefile + A /branches/dev/samtools/misc/md5.c + A /branches/dev/samtools/misc/md5.h + A /branches/dev/samtools/misc/md5fa.c + + * fixed two warnings in kseq.h + * added md5sum utilities + +------------------------------------------------------------------------ +r31 | lh3lh3 | 2008-12-08 06:35:29 -0500 (Mon, 08 Dec 2008) | 5 lines +Changed paths: + M /branches/dev/samtools/Makefile + M /branches/dev/samtools/bam_import.c + M /branches/dev/samtools/bamtk.c + A /branches/dev/samtools/kseq.h + D /branches/dev/samtools/kstream.h + + * samtools-0.1.0-52 + * replace kstream with kseq. kseq is a superset of kstream. I need the + extra functions in kseq.h. + * also compile stand-alone faidx + +------------------------------------------------------------------------ +r30 | lh3lh3 | 2008-12-08 06:17:04 -0500 (Mon, 08 Dec 2008) | 3 lines +Changed paths: + M /branches/dev/samtools/bam.h + M /branches/dev/samtools/bam_sort.c + M /branches/dev/samtools/bamtk.c + + * samtools-0.1.0-51 + * sorting by read names is available + +------------------------------------------------------------------------ +r29 | lh3lh3 | 2008-12-08 05:29:02 -0500 (Mon, 08 Dec 2008) | 3 lines +Changed paths: + M /branches/dev/samtools/bam.c + M /branches/dev/samtools/bam.h + M /branches/dev/samtools/bam_import.c + M /branches/dev/samtools/bam_maqcns.c + M /branches/dev/samtools/bam_pileup.c + M /branches/dev/samtools/bam_sort.c + M /branches/dev/samtools/bam_tview.c + M /branches/dev/samtools/bamtk.c + M /branches/dev/samtools/misc/maq2sam.c + + * samtools-0.1.0-50 + * format change to meet the latest specification + +------------------------------------------------------------------------ +r28 | lh3lh3 | 2008-12-04 11:09:21 -0500 (Thu, 04 Dec 2008) | 3 lines +Changed paths: + M /branches/dev/samtools/bam_maqcns.c + M /branches/dev/samtools/misc/maq2sam.c + + * minor change in maqcns: special care when n==0 + * change maq2sam to meet the latest specification + +------------------------------------------------------------------------ +r27 | lh3lh3 | 2008-12-04 10:55:44 -0500 (Thu, 04 Dec 2008) | 2 lines +Changed paths: + M /branches/dev/samtools/razf.c + M /branches/dev/samtools/razf.h + +considerable code clean up in razf + +------------------------------------------------------------------------ +r26 | lh3lh3 | 2008-12-04 10:08:18 -0500 (Thu, 04 Dec 2008) | 2 lines +Changed paths: + M /branches/dev/samtools/ChangeLog + M /branches/dev/samtools/Makefile + M /branches/dev/samtools/faidx.c + +make RAZF optional in faidx.c + +------------------------------------------------------------------------ +r25 | lh3lh3 | 2008-12-01 10:27:22 -0500 (Mon, 01 Dec 2008) | 3 lines +Changed paths: + M /branches/dev/samtools/Makefile + M /branches/dev/samtools/bam.h + M /branches/dev/samtools/bam_aux.c + M /branches/dev/samtools/bamtk.c + M /branches/dev/samtools/samtools.1 + + * samtools-0.1.0-49 + * added routines for retrieving aux data, NOT TESTED YET! + +------------------------------------------------------------------------ +r24 | lh3lh3 | 2008-12-01 09:29:43 -0500 (Mon, 01 Dec 2008) | 5 lines +Changed paths: + M /branches/dev/samtools/bam.c + M /branches/dev/samtools/bam_import.c + M /branches/dev/samtools/bam_maqcns.c + M /branches/dev/samtools/bamtk.c + M /branches/dev/samtools/bgzf.c + M /branches/dev/samtools/samtools.1 + + * samtools-0.1.0-48 + * bgzf: fixed a potential integer overflow on 32-it machines + * maqcns: set the minimum combined quality as 0 + * supporting hex strings + +------------------------------------------------------------------------ +r23 | lh3lh3 | 2008-11-27 12:14:37 -0500 (Thu, 27 Nov 2008) | 3 lines +Changed paths: + M /branches/dev/samtools/bam_maqcns.c + M /branches/dev/samtools/bamtk.c + + * samtools-0.1.0-47 + * fixed the bug in maqcns + +------------------------------------------------------------------------ +r22 | lh3lh3 | 2008-11-27 12:08:11 -0500 (Thu, 27 Nov 2008) | 3 lines +Changed paths: + M /branches/dev/samtools/Makefile + M /branches/dev/samtools/bam.h + A /branches/dev/samtools/bam_maqcns.c + A /branches/dev/samtools/bam_maqcns.h + M /branches/dev/samtools/bam_tview.c + M /branches/dev/samtools/bamtk.c + A /branches/dev/samtools/glf.h + + * samtools-0.1.0-46 + * add MAQ consensus caller, currently BUGGY! + +------------------------------------------------------------------------ +r21 | lh3lh3 | 2008-11-27 08:51:28 -0500 (Thu, 27 Nov 2008) | 4 lines +Changed paths: + M /branches/dev/samtools/bam_pileup.c + M /branches/dev/samtools/bam_tview.c + M /branches/dev/samtools/bamtk.c + + * samtools-0.1.0-45 + * tview: display padded alignment (but not P operation) + * better coordinates and reference sequence + +------------------------------------------------------------------------ +r19 | lh3lh3 | 2008-11-27 04:26:05 -0500 (Thu, 27 Nov 2008) | 2 lines +Changed paths: + A /branches/dev/samtools/ChangeLog + +new ChangeLog + +------------------------------------------------------------------------ +r18 | lh3lh3 | 2008-11-27 04:24:45 -0500 (Thu, 27 Nov 2008) | 3 lines +Changed paths: + D /branches/dev/samtools/ChangeLog + A /branches/dev/samtools/ChangeLog.old (from /branches/dev/samtools/ChangeLog:6) + +Rename ChangeLog to ChangeLog.old. This old ChangeLog is generated from +the log of my personal SVN repository. + +------------------------------------------------------------------------ +r17 | lh3lh3 | 2008-11-27 04:22:55 -0500 (Thu, 27 Nov 2008) | 6 lines +Changed paths: + M /branches/dev/samtools/Makefile + M /branches/dev/samtools/bamtk.c + M /branches/dev/samtools/bgzf.c + + * samtools-0.1.0-44 + * declare fseeko and ftello as some Linux may not do this by default and + missing these declarations will make bgzf buggy + * get rid of some harmless warings + * use BGZF by default, now + +------------------------------------------------------------------------ +r16 | lh3lh3 | 2008-11-26 16:19:11 -0500 (Wed, 26 Nov 2008) | 4 lines +Changed paths: + M /branches/dev/samtools/bam_index.c + M /branches/dev/samtools/bamtk.c + M /branches/dev/samtools/razf.c + + * samtools-0.1.0-43 + * fixed a bug in razf_read() + * give more warnings when the file is truncated (or due to bugs in I/O library) + +------------------------------------------------------------------------ +r15 | lh3lh3 | 2008-11-26 15:41:39 -0500 (Wed, 26 Nov 2008) | 2 lines +Changed paths: + M /branches/dev/samtools/bgzf.c + +fixed a bug in bgzf.c at the end of the file + +------------------------------------------------------------------------ +r14 | lh3lh3 | 2008-11-26 12:05:18 -0500 (Wed, 26 Nov 2008) | 4 lines +Changed paths: + M /branches/dev/samtools/bamtk.c + + * samtools-0.1.0-42 + * a lot happened to RAZF, although samtools itself is untouched. Better + also update the version number anyway to avoid confusion + +------------------------------------------------------------------------ +r13 | lh3lh3 | 2008-11-26 12:03:48 -0500 (Wed, 26 Nov 2008) | 2 lines +Changed paths: + M /branches/dev/samtools/razf.c + +a change from Jue, but I think it should not matter + +------------------------------------------------------------------------ +r12 | lh3lh3 | 2008-11-26 11:48:14 -0500 (Wed, 26 Nov 2008) | 3 lines +Changed paths: + M /branches/dev/samtools/razf.c + +fixed a potential bug in razf. However, it seems still buggy, just +rarely happens, very rarely. + +------------------------------------------------------------------------ +r11 | lh3lh3 | 2008-11-26 09:02:56 -0500 (Wed, 26 Nov 2008) | 2 lines +Changed paths: + M /branches/dev/samtools/razf.c + +fixed a bug in razf, with the help of Jue + +------------------------------------------------------------------------ +r10 | lh3lh3 | 2008-11-26 06:55:32 -0500 (Wed, 26 Nov 2008) | 2 lines +Changed paths: + M /branches/dev/samtools/bam_index.c + +remove a comment + +------------------------------------------------------------------------ +r9 | lh3lh3 | 2008-11-26 06:37:05 -0500 (Wed, 26 Nov 2008) | 2 lines +Changed paths: + M /branches/dev/samtools/Makefile + M /branches/dev/samtools/bam.h + M /branches/dev/samtools/razf.c + M /branches/dev/samtools/razf.h + + * Jue has updated razf to realize Bob's scheme + +------------------------------------------------------------------------ +r7 | lh3lh3 | 2008-11-25 15:37:37 -0500 (Tue, 25 Nov 2008) | 2 lines +Changed paths: + A /branches/dev/samtools/samtools.1 + +the manual page + +------------------------------------------------------------------------ +r6 | lh3lh3 | 2008-11-25 15:37:16 -0500 (Tue, 25 Nov 2008) | 3 lines +Changed paths: + A /branches/dev/samtools/ChangeLog + A /branches/dev/samtools/Makefile + A /branches/dev/samtools/bam.c + A /branches/dev/samtools/bam.h + A /branches/dev/samtools/bam_aux.c + A /branches/dev/samtools/bam_endian.h + A /branches/dev/samtools/bam_import.c + A /branches/dev/samtools/bam_index.c + A /branches/dev/samtools/bam_lpileup.c + A /branches/dev/samtools/bam_pileup.c + A /branches/dev/samtools/bam_sort.c + A /branches/dev/samtools/bam_tview.c + A /branches/dev/samtools/bamtk.c + A /branches/dev/samtools/bgzf.c + A /branches/dev/samtools/bgzf.h + A /branches/dev/samtools/bgzip.c + A /branches/dev/samtools/faidx.c + A /branches/dev/samtools/faidx.h + A /branches/dev/samtools/khash.h + A /branches/dev/samtools/ksort.h + A /branches/dev/samtools/kstream.h + A /branches/dev/samtools/misc + A /branches/dev/samtools/misc/Makefile + A /branches/dev/samtools/misc/all2sam.pl + A /branches/dev/samtools/misc/maq2sam.c + A /branches/dev/samtools/razf.c + A /branches/dev/samtools/razf.h + A /branches/dev/samtools/razip.c + A /branches/dev/samtools/zutil.h + +The initial version of samtools, replicated from my local SVN repository. +The current version is: 0.1.0-42. All future development will happen here. + +------------------------------------------------------------------------ +r5 | lh3lh3 | 2008-11-25 15:30:49 -0500 (Tue, 25 Nov 2008) | 2 lines +Changed paths: + A /branches/dev/samtools + +samtools (C version) + +------------------------------------------------------------------------
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/INSTALL Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,30 @@ +System Requirements +=================== + +SAMtools depends on the zlib library <http://www.zlib.net>. Version 1.2.3+ is +preferred and with 1.2.3+ you can compile razip and use it to compress a FASTA +file. SAMtools' faidx is able to index a razip-compressed FASTA file to save +diskspace. Older zlib also works with SAMtools, but razip cannot be compiled. + +The text-based viewer (tview) requires the GNU ncurses library +<http://www.gnu.org/software/ncurses/>, which comes with Mac OS X and most of +the modern Linux/Unix distributions. If you do not have this library installed, +you can still compile the rest of SAMtools by manually changing: +`-D_CURSES_LIB=1' to `-D_CURSES_LIB=0' at the line starting with `DFLAGS=', and +comment out the line starting with `LIBCURSES='. + + +Compilation +=========== + +Type `make' to compile samtools. If you have zlib >= 1.2.2.1, you can compile +razip with `make razip'. + + +Installation +============ + +Copy `samtools', `bcftools/bcftools' and other executables/scripts in `misc' to +a location you want (e.g. a directory in your $PATH). You may also copy +`samtools.1' and `bcftools/bcftools.1' to a directory in your $MANPATH such +that the `man' command may find the manual.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/Makefile Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,95 @@ +CC= gcc +CFLAGS= -g -Wall -O2 #-m64 #-arch ppc +DFLAGS= -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -D_USE_KNETFILE -D_CURSES_LIB=1 +KNETFILE_O= knetfile.o +LOBJS= bgzf.o kstring.o bam_aux.o bam.o bam_import.o sam.o bam_index.o \ + bam_pileup.o bam_lpileup.o bam_md.o glf.o razf.o faidx.o bedidx.o \ + $(KNETFILE_O) bam_sort.o sam_header.o bam_reheader.o kprobaln.o bam_cat.o +AOBJS= bam_tview.o bam_maqcns.o bam_plcmd.o sam_view.o \ + bam_rmdup.o bam_rmdupse.o bam_mate.o bam_stat.o bam_color.o \ + bamtk.o kaln.o bam2bcf.o bam2bcf_indel.o errmod.o sample.o \ + cut_target.o phase.o bam2depth.o +PROG= samtools +INCLUDES= -I. +SUBDIRS= . bcftools misc +LIBPATH= +LIBCURSES= -lcurses # -lXCurses + +.SUFFIXES:.c .o + +.c.o: + $(CC) -c $(CFLAGS) $(DFLAGS) $(INCLUDES) $< -o $@ + +all-recur lib-recur clean-recur cleanlocal-recur install-recur: + @target=`echo $@ | sed s/-recur//`; \ + wdir=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + cd $$subdir; \ + $(MAKE) CC="$(CC)" DFLAGS="$(DFLAGS)" CFLAGS="$(CFLAGS)" \ + INCLUDES="$(INCLUDES)" LIBPATH="$(LIBPATH)" $$target || exit 1; \ + cd $$wdir; \ + done; + +all:$(PROG) + +.PHONY:all lib clean cleanlocal +.PHONY:all-recur lib-recur clean-recur cleanlocal-recur install-recur + +lib:libbam.a + +libbam.a:$(LOBJS) + $(AR) -cru $@ $(LOBJS) + +samtools:lib-recur $(AOBJS) + $(CC) $(CFLAGS) -o $@ $(AOBJS) -Lbcftools $(LIBPATH) libbam.a -lbcf $(LIBCURSES) -lm -lz + +razip:razip.o razf.o $(KNETFILE_O) + $(CC) $(CFLAGS) -o $@ razf.o razip.o $(KNETFILE_O) -lz + +bgzip:bgzip.o bgzf.o $(KNETFILE_O) + $(CC) $(CFLAGS) -o $@ bgzf.o bgzip.o $(KNETFILE_O) -lz + +razip.o:razf.h +bam.o:bam.h razf.h bam_endian.h kstring.h sam_header.h +sam.o:sam.h bam.h +bam_import.o:bam.h kseq.h khash.h razf.h +bam_pileup.o:bam.h razf.h ksort.h +bam_plcmd.o:bam.h faidx.h bam_maqcns.h glf.h bcftools/bcf.h bam2bcf.h +bam_index.o:bam.h khash.h ksort.h razf.h bam_endian.h +bam_lpileup.o:bam.h ksort.h +bam_tview.o:bam.h faidx.h bam_maqcns.h +bam_maqcns.o:bam.h ksort.h bam_maqcns.h kaln.h +bam_sort.o:bam.h ksort.h razf.h +bam_md.o:bam.h faidx.h +glf.o:glf.h +sam_header.o:sam_header.h khash.h +bcf.o:bcftools/bcf.h +bam2bcf.o:bam2bcf.h errmod.h bcftools/bcf.h +bam2bcf_indel.o:bam2bcf.h +errmod.o:errmod.h +phase.o:bam.h khash.h ksort.h +bamtk.o:bam.h + +faidx.o:faidx.h razf.h khash.h +faidx_main.o:faidx.h razf.h + + +libbam.1.dylib-local:$(LOBJS) + libtool -dynamic $(LOBJS) -o libbam.1.dylib -lc -lz + +libbam.so.1-local:$(LOBJS) + $(CC) -shared -Wl,-soname,libbam.so -o libbam.so.1 $(LOBJS) -lc -lz + +dylib: + @$(MAKE) cleanlocal; \ + case `uname` in \ + Linux) $(MAKE) CFLAGS="$(CFLAGS) -fPIC" libbam.so.1-local;; \ + Darwin) $(MAKE) CFLAGS="$(CFLAGS) -fPIC" libbam.1.dylib-local;; \ + *) echo 'Unknown OS';; \ + esac + + +cleanlocal: + rm -fr gmon.out *.o a.out *.exe *.dSYM razip bgzip $(PROG) *~ *.a *.so.* *.so *.dylib + +clean:cleanlocal-recur
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/Makefile.mingw Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,64 @@ +CC= gcc.exe +AR= ar.exe +CFLAGS= -g -Wall -O2 +DFLAGS= -D_USE_KNETFILE -D_CURSES_LIB=2 +KNETFILE_O= knetfile.o +LOBJS= bgzf.o kstring.o bam_aux.o bam.o bam_import.o sam.o bam_index.o \ + bam_pileup.o bam_lpileup.o bam_md.o glf.o razf.o faidx.o \ + $(KNETFILE_O) bam_sort.o sam_header.o bam_reheader.o kprobaln.o +AOBJS= bam_tview.o bam_maqcns.o bam_plcmd.o sam_view.o \ + bam_rmdup.o bam_rmdupse.o bam_mate.o bam_stat.o bam_color.o \ + bamtk.o kaln.o bam2bcf.o bam2bcf_indel.o errmod.o sample.o +BCFOBJS= bcftools/bcf.o bcftools/fet.o bcftools/bcf2qcall.o bcftools/bcfutils.o \ + bcftools/call1.o bcftools/index.o bcftools/kfunc.o bcftools/ld.o \ + bcftools/prob1.o bcftools/vcf.o +PROG= samtools.exe bcftools.exe +INCLUDES= -I. -Iwin32 +SUBDIRS= . +LIBPATH= + +.SUFFIXES:.c .o + +.c.o: + $(CC) -c $(CFLAGS) $(DFLAGS) $(INCLUDES) $< -o $@ + +all:$(PROG) + +.PHONY:all lib clean cleanlocal +.PHONY:all-recur lib-recur clean-recur cleanlocal-recur install-recur + +lib:libbam.a + +libbam.a:$(LOBJS) + $(AR) -cru $@ $(LOBJS) + +samtools.exe:$(AOBJS) libbam.a $(BCFOBJS) + $(CC) $(CFLAGS) -o $@ $(AOBJS) $(BCFOBJS) $(LIBPATH) -lm -L. -lbam -Lwin32 -lz -lcurses -lws2_32 + +bcftools.exe:$(BCFOBJS) bcftools/main.o kstring.o bgzf.o knetfile.o + $(CC) $(CFLAGS) -o $@ $(BCFOBJS) bcftools/main.o kstring.o bgzf.o knetfile.o -lm -Lwin32 -lz -lws2_32 + +razip.o:razf.h +bam.o:bam.h razf.h bam_endian.h kstring.h sam_header.h +sam.o:sam.h bam.h +bam_import.o:bam.h kseq.h khash.h razf.h +bam_pileup.o:bam.h razf.h ksort.h +bam_plcmd.o:bam.h faidx.h bam_maqcns.h glf.h bcftools/bcf.h bam2bcf.h +bam_index.o:bam.h khash.h ksort.h razf.h bam_endian.h +bam_lpileup.o:bam.h ksort.h +bam_tview.o:bam.h faidx.h bam_maqcns.h +bam_maqcns.o:bam.h ksort.h bam_maqcns.h kaln.h +bam_sort.o:bam.h ksort.h razf.h +bam_md.o:bam.h faidx.h +glf.o:glf.h +sam_header.o:sam_header.h khash.h +bcf.o:bcftools/bcf.h +bam2bcf.o:bam2bcf.h errmod.h bcftools/bcf.h +bam2bcf_indel.o:bam2bcf.h +errmod.o:errmod.h + +faidx.o:faidx.h razf.h khash.h +faidx_main.o:faidx.h razf.h + +clean: + rm -fr gmon.out *.o a.out *.exe *.dSYM razip bgzip $(PROG) *~ *.a *.so.* *.so *.dylib
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/NEWS Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,735 @@ +Beta Release 0.1.16 (21 April, 2011) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Notable changes in samtools: + + * Support the new SAM/BAM type `B' in the latest SAM spec v1.4. + + * When the output file of `samtools merge' exists, do not overwrite it unless + a new command-line option `-f' is applied. + + * Bugfix: BED support is not working when the input BED is not sorted. + + * Bugfix: some reads without coordinates but given on the reverse strand are + lost in merging. + +Notable changes in bcftools: + + * Code cleanup: separated max-likelihood inference and Bayesian inference. + + * Test Hardy-Weinberg equilibrium with a likelihood-ratio test. + + * Provided another association test P-value by likelihood-ratio test. + + * Use Brent's method to estimate the site allele frequency when EM converges + slowly. The resulting ML estimate of allele frequnecy is more accurate. + + * Added the `ldpair' command, which computes r^2 between SNP pairs given in + an input file. + +Also, the `pileup' command, which has been deprecated by `mpileup' since +version 0.1.10, will be dropped in the next release. The old `pileup' command +is substandard and causing a lot of confusion. + +(0.1.16: 21 April 2011, r963:234) + + + +Beta Release 0.1.15 (10 April, 2011) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Noteable changes: + + * Allow to perform variant calling or to extract information in multiple + regions specified by a BED file (`samtools mpileup -l', `samtools view -L' + and `bcftools view -l'). + + * Added the `depth' command to samtools to compute the per-base depth with a + simpler interface. File `bam2depth.c', which implements this command, is the + recommended example on how to use the mpileup APIs. + + * Estimate genotype frequencies with ML; perform chi^2 based Hardy-Weinberg + test using this estimate. + + * For `samtools view', when `-R' is specified, drop read groups in the header + that are not contained in the specified file. + + * For `samtools flagstat', separate QC-pass and QC-fail reads. + + * Improved the command line help of `samtools mpileup' and `bcftools view'. + + * Use a global variable to control the verbose level of samtools stderr + output. Nonetheless, it has not been full utilized. + + * Fixed an issue in association test which may report false associations, + possibly due to floating point underflow. + +(0.1.15: 10 April 2011, r949:203) + + + +Beta release 0.1.14 (21 March, 2011) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This release implements a method for testing associations for case-control +data. The method does not call genotypes but instead sums over all genotype +configurations to compute a chi^2 based test statistics. It can be potentially +applied to comparing a pair of samples (e.g. a tumor-normal pair), but this +has not been evaluated on real data. + +Another new feature is to make X chromosome variant calls when female and male +samples are both present. The user needs to provide a file indicating the +ploidy of each sample (see also manual bcftools/bcftools.1). + +Other notable changes: + + * Added `bcftools view -F' to parse BCF files generated by samtools r921 or + older which encodes PL in a different way. + + * Changed the behavior of `bcftools view -s'. Now when a list of samples is + provided, the samples in the output will be reordered to match the ordering + in the sample list. This change is mainly designed for association test. + + * Sped up `bcftools view -v' for target sequencing given thousands of samples. + Also added a new option `view -d' to skip loci where only a few samples are + covered by reads. + + * Dropped HWE test. This feature has never been implemented properly. An EM + should be much better. To be implemented in future. + + * Added the `cat' command to samtools. This command concatenate BAMs with + identical sequence dictionaries in an efficient way. Modified from bam_cat.c + written by Chris Saunders. + + * Added `samtools view -1' to write BAMs at a low compression level but twice + faster to create. The `sort' command generates temporary files at a low + compression level as well. + + * Added `samtools mpileup -6' to accept "BAM" with Illumina 1.3+ quality + strings (strictly speaking, such a file is not BAM). + + * Added `samtools mpileup -L' to skip INDEL calling in regions with + excessively high coverage. Such regions dramatically slow down mpileup. + + * Updated `misc/export2sam.pl', provided by Chris Saunders from Illumina Inc. + +(0.1.14: 21 March 2011, r933:170) + + + +Beta release 0.1.13 (1 March, 2011) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The most important though largely invisible modification is the change of the +order of genotypes in the PL VCF/BCF tag. This is to conform the upcoming VCF +spec v4.1. The change means that 0.1.13 is not backward compatible with VCF/BCF +generated by samtools older than r921 inclusive. VCF/BCF generated by the new +samtools will contain a line `##fileformat=VCFv4.1' as well as the samtools +version number. + +Single Individual Haplotyping (SIH) is added as an experimental feature. It +originally aims to produce haploid consensus from fosmid pool sequencing, but +also works with short-read data. For short reads, phased blocks are usually too +short to be useful in many applications, but they can help to rule out part of +SNPs close to INDELs or between copies of CNVs. + + +Other notable changes in samtools: + + * Construct per-sample consensus to reduce the effect of nearby SNPs in INDEL + calling. This reduces the power but improves specificity. + + * Improved sorting order checking in indexing. Now indexing is the preferred way + to check if a BAM is sorted. + + * Added a switch `-E' to mpileup and calmd. This option uses an alternative way + to apply BAQ, which increases sensistivity, especially to MNPs, at the cost of + a little loss in specificity. + + * Added `mpileup -A' to allow to use reads in anomalous pairs in SNP calling. + + * Added `mpileup -m' to allow fine control of the collection of INDEL candidates. + + * Added `mpileup -S' to compute per-sample strand bias P-value. + + * Added `mpileup -G' to exclude read groups in variant calling. + + * Fixed segfault in indel calling related to unmapped and refskip reads. + + * Fixed an integer overflow in INDEL calling. This bug produces wrong INDEL + genotypes for longer short INDELs, typically over 10bp. + + * Fixed a bug in tview on big-endian machines. + + * Fixed a very rare memory issue in bam_md.c + + * Fixed an out-of-boundary bug in mpileup when the read base is `N'. + + * Fixed a compiling error when the knetfile library is not used. Fixed a + library compiling error due to the lack of bam_nt16_nt4_table[] table. + Suppress a compiling warning related to the latest zlib. + + +Other notable changes in bcftools: + + * Updated the BCF spec. + + * Added the `FQ' VCF INFO field, which gives the phred-scaled probability + of all samples being the same (identical to the reference or all homozygous + variants). Option `view -f' has been dropped. + + * Implementated of "vcfutils.pl vcf2fq" to generate a consensus sequence + similar to "samtools.pl pileup2fq". + + * Make sure the GT FORMAT field is always the first FORMAT to conform the VCF + spec. Drop bcf-fix.pl. + + * Output bcftools specific INFO and FORMAT in the VCF header. + + * Added `view -s' to call variants from a subset of samples. + + * Properly convert VCF to BCF with a user provided sequence dictionary. Nonetheless, + custom fields are still unparsed and will be stored as a missing value. + + * Fixed a minor bug in Fisher's exact test; the results are rarely changed. + + +(0.1.13: 1 March 2011, r926:134) + + + +Beta release 0.1.12a (2 December, 2010) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is another bug fix release: + + * Fixed a memory violation in mpileup, which causes segfault. Release + 0.1.9 and above are affected. + + * Fixed a memory violation in the indel caller, which does not causes + segfault, but may potentially affect deletion calls in an unexpected + way. Release 0.1.10 and above are affected. + + * Fixed a bug in computing r-square in bcftools. Few are using this + functionality and it only has minor effect. + + * Fixed a memory leak in bam_fetch(). + + * Fixed a bug in writing meta information to the BAM index for the last + sequence. This bug is invisible to most users, but it is a bug anyway. + + * Fixed a bug in bcftools which causes false "DP4=0,0,0,0" annotations. + +(0.1.12: 2 December 2010, r862) + + + +Beta release 0.1.11 (21 November, 2010) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is mainly a bug fix release: + + * Fixed a bug in random retrieval (since 0.1.8). It occurs when reads + are retrieved from a small region containing no reads. + + * Fixed a bug in pileup (since 0.1.9). The bug causes an assertion + failure when the first CIGAR operation is a deletion. + + * Improved fault tolerence in remote access. + +One minor feature has been implemented in bcftools: + + * Added a reference-free variant calling mode. In this mode, a site is + regarded as a variat iff the sample(s) contains two or more alleles; + the meaning of the QUAL field in the VCF output is changed + accordingly. Effectively, the reference allele is irrelevant to the + result in the new mode, although the reference sequence has to be + used in realignment when SAMtools computes genotype likelihoods. + +In addition, since 0.1.10, the `pileup' command has been deprecated by +`mpileup' which is more powerful and more accurate. The `pileup' command +will not be removed in the next few releases, but new features will not +be added. + +(0.1.11: 21 November 2010, r851) + + + +Beta Release 0.1.10 (16 November, 2010) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This release is featured as the first major improvement to the indel +caller. The method is similar to the old one implemented in the pileup +command, but the details are handled more carefully both in theory and +in practice. As a result, the new indel caller usually gives more +accurate indel calls, though at the cost of sensitivity. The caller is +implemented in the mpileup command and is invoked by default. It works +with multiple samples. + +Other notable changes: + + * With the -r option, the calmd command writes the difference between + the original base quality and the BAQ capped base quality at the BQ + tag but does not modify the base quality. Please use -Ar to overwrite + the original base quality (the 0.1.9 behavior). + + * Allow to set a maximum per-sample read depth to reduce memory. In + 0.1.9, most of memory is wasted for the ultra high read depth in some + regions (e.g. the chr1 centromere). + + * Optionally write per-sample read depth and per-sample strand bias + P-value. + + * Compute equal-tail (Bayesian) credible interval of site allele + frequency at the CI95 VCF annotation. + + * Merged the vcfutils.pl varFilter and filter4vcf for better SNP/indel + filtering. + +(0.1.10: 16 November 2010, r829) + + + +Beta Release 0.1.9 (27 October, 2010) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This release is featured as the first major improvement to the samtools' +SNP caller. It comes with a revised MAQ error model, the support of +multi-sample SNP calling and the computation of base alignment quality +(BAQ). + +The revised MAQ error model is based on the original model. It solves an +issue of miscalling SNPs in repetitive regions. Althought such SNPs can +usually be filtered at a later step, they mess up unfiltered calls. This +is a theoretical flaw in the original model. The revised MAQ model +deprecates the orginal MAQ model and the simplified SOAPsnp model. + +Multi-sample SNP calling is separated in two steps. The first is done by +samtools mpileup and the second by a new program, bcftools, which is +included in the samtools source code tree. Multi-sample SNP calling also +works for single sample and has the advantage of enabling more powerful +filtration. It is likely to deprecate pileup in future once a proper +indel calling method is implemented. + +BAQ is the Phred-scaled probability of a read base being wrongly +aligned. Capping base quality by BAQ has been shown to be very effective +in suppressing false SNPs caused by misalignments around indels or in +low-complexity regions with acceptable compromise on computation +time. This strategy is highly recommended and can be used with other SNP +callers as well. + +In addition to the three major improvements, other notable changes are: + + * Changes to the pileup format. A reference skip (the N CIGAR operator) + is shown as '<' or '>' depending on the strand. Tview is also changed + accordingly. + + * Accelerated pileup. The plain pileup is about 50% faster. + + * Regional merge. The merge command now accepts a new option to merge + files in a specified region. + + * Fixed a bug in bgzip and razip which causes source files to be + deleted even if option -c is applied. + + * In APIs, propogate errors to downstream callers and make samtools + return non-zero values once errors occur. + +(0.1.9: 27 October 2010, r783) + + + +Beta Release 0.1.8 (11 July, 2010) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Notable functional changes: + + * Added the `reheader' command which replaces a BAM header with a new + header. This command is much faster than replacing header by + BAM->SAM->BAM conversions. + + * Added the `mpileup' command which computes the pileup of multiple + alignments. + + * The `index' command now stores the number of mapped and unmapped + reads in the index file. This information can be retrieved quickly by + the new `idxstats' command. + + * By default, pileup used the SOAPsnp model for SNP calling. This + avoids the floating overflow in the MAQ model which leads to spurious + calls in repetitive regions, although these calls will be immediately + filtered by varFilter. + + * The `tview' command now correctly handles CIGARs like 7I10M and + 10M1P1I10M which cause assertion failure in earlier versions. + + * Tview accepts a region like `=10,000' where `=' stands for the + current sequence name. This saves typing for long sequence names. + + * Added the `-d' option to `pileup' which avoids slow indel calling + in ultradeep regions by subsampling reads locally. + + * Added the `-R' option to `view' which retrieves alignments in read + groups listed in the specified file. + +Performance improvements: + + * The BAM->SAM conversion is up to twice faster, depending on the + characteristic of the input. + + * Parsing SAM headers with a lot of reference sequences is now much + faster. + + * The number of lseek() calls per query is reduced when the query + region contains no read alignments. + +Bug fixes: + + * Fixed an issue in the indel caller that leads to miscall of indels. + Note that this solution may not work well when the sequencing indel + error rate is higher than the rate of SNPs. + + * Fixed another issue in the indel caller which may lead to incorrect + genotype. + + * Fixed a bug in `sort' when option `-o' is applied. + + * Fixed a bug in `view -r'. + +APIs and other changes: + + * Added iterator interfaces to random access and pileup. The callback + interfaces directly call the iterator interfaces. + + * The BGZF blocks holding the BAM header are indepedent of alignment + BGZF blocks. Alignment records shorter than 64kB is guaranteed to be + fully contained in one BGZF block. This change is fully compatible + with the old version of samtools/picard. + +Changes in other utilities: + + * Updated export2sam.pl by Chris Saunders. + + * Improved the sam2vcf.pl script. + + * Added a Python version of varfilter.py by Aylwyn Scally. + +(0.1.8: 11 July 2010, r613) + + + +Beta Release 0.1.7 (10 November, 2009) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Notable changes: + + * Improved the indel caller in complex scenariors, in particular for + long reads. The indel caller is now able to make reasonable indel + calls from Craig Venter capillary reads. + + * Rewrote single-end duplicate removal with improved + performance. Paired-end reads are not touched. + + * Duplicate removal is now library aware. Samtools remove potential + PCR/optical dupliates inside a library rather than across libraries. + + * SAM header is now fully parsed, although this functionality is not + used in merging and so on. + + * In samtools merge, optionally take the input file name as RG-ID and + attach the RG tag to each alignment. + + * Added FTP support in the RAZF library. RAZF-compressed reference + sequence can be retrieved remotely. + + * Improved network support for Win32. + + * Samtools sort and merge are now stable. + +Changes in other utilities: + + * Implemented sam2vcf.pl that converts the pileup format to the VCF + format. + + * This release of samtools is known to work with the latest + Bio-Samtools Perl module. + +(0.1.7: 10 November 2009, r510) + + + +Beta Release 0.1.6 (2 September, 2009) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Notable changes: + + * In tview, do not show a blank screen when no reads mapped to the + corresponding region. + + * Implemented native HTTP support in the BGZF library. Samtools is now + able to directly open a BAM file on HTTP. HTTP proxy is also + supported via the "http_proxy" environmental variable. + + * Samtools is now compitable with the MinGW (win32) compiler and the + PDCurses library. + + * The calmd (or fillmd) command now calculates the NM tag and replaces + MD tags if they are wrong. + + * The view command now recognizes and optionally prints FLAG in HEXs or + strings to make a SAM file more friendly to human eyes. This is a + samtools-C extension, not implemented in Picard for the time + being. Please type `samtools view -?' for more information. + + * BAM files now have an end-of-file (EOF) marker to facilitate + truncation detection. A warning will be given if an on-disk BAM file + does not have this marker. The warning will be seen on BAM files + generated by an older version of samtools. It does NO harm. + + * New key bindings in tview: `r' to show read names and `s' to show + reference skip (N operation) as deletions. + + * Fixed a bug in `samtools merge -n'. + + * Samtools merge now optionally copies the header of a user specified + SAM file to the resultant BAM output. + + * Samtools pileup/tview works with a CIGAR with the first or the last + operation is an indel. + + * Fixed a bug in bam_aux_get(). + + +Changes in other utilies: + + * Fixed wrong FLAG in maq2sam. + + +(0.1.6: 2 September 2009, r453) + + + +Beta Release 0.1.5 (7 July, 2009) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Notable changes: + + * Support opening a BAM alignment on FTP. Users can now use "tview" to + view alignments at the NCBI ftp site. Please read manual for more + information. + + * In library, propagate errors rather than exit or complain assertion + failure. + + * Simplified the building system and fixed compiling errors caused by + zlib<1.2.2.1. + + * Fixed an issue about lost header information when a SAM is imported + with "view -t". + + * Implemented "samtool.pl varFilter" which filters both SNPs and short + indels. This command replaces "indelFilter". + + * Implemented "samtools.pl pileup2fq" to generate FASTQ consensus from + pileup output. + + * In pileup, cap mapping quality at 60. This helps filtering when + different aligners are in use. + + * In pileup, allow to output variant sites only. + + * Made pileup generate correct calls in repetitive region. At the same + time, I am considering to implement a simplified model in SOAPsnp, + although this has not happened yet. + + * In view, added '-u' option to output BAM without compression. This + option is preferred when the output is piped to other commands. + + * In view, added '-l' and '-r' to get the alignments for one library or + read group. The "@RG" header lines are now partially parsed. + + * Do not include command line utilities to libbam.a. + + * Fixed memory leaks in pileup and bam_view1(). + + * Made faidx more tolerant to empty lines right before or after FASTA > + lines. + + +Changes in other utilities: + + * Updated novo2sam.pl by Colin Hercus, the key developer of novoalign. + + +This release involves several modifications to the key code base which +may potentially introduce new bugs even though we have tried to minimize +this by testing on several examples. Please let us know if you catch +bugs. + +(0.1.5: 7 July 2009, r373) + + + +Beta Release 0.1.4 (21 May, 2009) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Notable changes: + + * Added the 'rmdupse' command: removing duplicates for SE reads. + + * Fixed a critical bug in the indel caller: clipped alignments are not + processed correctly. + + * Fixed a bug in the tview: gapped alignment may be incorrectly + displayed. + + * Unified the interface to BAM and SAM I/O. This is done by + implementing a wrapper on top of the old APIs and therefore old APIs + are still valid. The new I/O APIs also recognize the @SQ header + lines. + + * Generate the MD tag. + + * Generate "=" bases. However, the indel caller will not work when "=" + bases are present. + + * Enhanced support of color-read display (by Nils Homer). + + * Implemented the GNU building system. However, currently the building + system does not generate libbam.a. We will improve this later. For + the time being, `make -f Makefile.generic' is preferred. + + * Fixed a minor bug in pileup: the first read in a chromosome may be + skipped. + + * Fixed bugs in bam_aux.c. These bugs do not affect other components as + they were not used previously. + + * Output the 'SM' tag from maq2sam. + +(0.1.4: 21 May 2009, r297) + + + +Beta Release 0.1.3 (15 April, 2009) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Notable changes in SAMtools: + + * SAMtools is more consistent with the specification: a) '*' in the + QUAL field is allowed; b) the field separator is TAB only and SPACE + is treated as a character in a field; c) empty header is allowed. + + * Implemented GLFv3 support in pileup. + + * Fixed a severe bug in fixmate: strand information is wrongly + overwritten. + + * Fixed a bug in alignment retrieval: alignments bridging n*16384bp are + not correctly retrieved sometimes. + + * Fixed a bug in rmdup: segfault if unmapped reads are present. + + * Move indel_filter.pl to samtools.pl and improved the filtering by + checking the actual number of alignments containing indels. The indel + pileup line is also changed a little to make this filtration easier. + + * Fixed a minor bug in indexing: the bin number of an unmapped read is + wrongly calculated. + + * Added `flagstat' command to show statistics on the FLAG field. + + * Improved indel caller by setting the maximum window size in local + realignment. + +Changes in other utilities: + + * Fixed a bug in maq2sam: a tag name is obsolete. + + * Improvement to wgsim: a) added support for SOLiD read simulation; b) + show the number of substitutions/indels/errors in read name; c) + considerable code clean up. + + * Various converters: improved functionality in general. + + * Updated the example SAM due to the previous bug in fixmate. + +(0.1.3: 15 April 2009, r227) + + + +Beta Release 0.1.2 (28 January, 2008) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Notable changes in SAMtools: + + * Implemented a Bayesian indel caller. The new caller generate scores + and genotype and is potentially more accurate than Maq's indel + caller. The pileup format is also changed accordingly. + + * Implemented rmdup command: remove potential PCR duplicates. Note that + this command ONLY works for FR orientation and requires ISIZE is + correctly set. + + * Added fixmate command: fill in mate coordinates, ISIZE and mate + related flags from a name-sorted alignment. + + * Fixed a bug in indexing: reads bridging 16x kbp were not retrieved. + + * Allow to select reads shown in the pileup output with a mask. + + * Generate GLFv2 from pileup. + + * Added two more flags for flagging PCR/optical duplicates and for QC + failure. + + * Fixed a bug in sort command: name sorting for large alignment did not + work. + + * Allow to completely disable RAZF (using Makefile.lite) as some people + have problem to compile it. + + * Fixed a bug in import command when there are reads without + coordinates. + + * Fixed a bug in tview: clipping broke the alignment viewer. + + * Fixed a compiling error when _NO_CURSES is applied. + + * Fixed a bug in merge command. + +Changes in other utilities: + + * Added wgsim, a paired-end reads simulator. Wgsim was adapted from + maq's reads simulator. Colin Hercus further improved it to allow + longer indels. + + * Added wgsim_eval.pl, a script that evaluates the accuracy of + alignment on reads generated by wgsim. + + * Added soap2sam.pl, a SOAP2->SAM converter. This converter does not + work properly when multiple hits are output. + + * Added bowtie2sam.pl, a Bowtie->SAM converter. Only the top hit will + be retained when multiple hits are present. + + * Fixed a bug in export2sam.pl for QC reads. + + * Support RG tag at MAQ->SAM converter. + + * Added novo2sam.pl, a NovoAlign->SAM converter. Multiple hits and + indel are not properly handled, though. + + * Added zoom2sam.pl, a ZOOM->SAM converter. It only works with the + default Illumina output. + +(0.1.2: 28 January 2008; r116) + + + +Beta Release 0.1.1 (22 December, 2008) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The is the first public release of samtools. For more information, +please check the manual page `samtools.1' and the samtools website +http://samtools.sourceforge.net
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,362 @@ +#include <stdio.h> +#include <ctype.h> +#include <errno.h> +#include <assert.h> +#include "bam.h" +#include "bam_endian.h" +#include "kstring.h" +#include "sam_header.h" + +int bam_is_be = 0, bam_verbose = 2; +char *bam_flag2char_table = "pPuUrR12sfd\0\0\0\0\0"; + +/************************** + * CIGAR related routines * + **************************/ + +uint32_t bam_calend(const bam1_core_t *c, const uint32_t *cigar) +{ + uint32_t k, end; + end = c->pos; + for (k = 0; k < c->n_cigar; ++k) { + int op = cigar[k] & BAM_CIGAR_MASK; + if (op == BAM_CMATCH || op == BAM_CDEL || op == BAM_CREF_SKIP) + end += cigar[k] >> BAM_CIGAR_SHIFT; + } + return end; +} + +int32_t bam_cigar2qlen(const bam1_core_t *c, const uint32_t *cigar) +{ + uint32_t k; + int32_t l = 0; + for (k = 0; k < c->n_cigar; ++k) { + int op = cigar[k] & BAM_CIGAR_MASK; + if (op == BAM_CMATCH || op == BAM_CINS || op == BAM_CSOFT_CLIP) + l += cigar[k] >> BAM_CIGAR_SHIFT; + } + return l; +} + +/******************** + * BAM I/O routines * + ********************/ + +bam_header_t *bam_header_init() +{ + bam_is_be = bam_is_big_endian(); + return (bam_header_t*)calloc(1, sizeof(bam_header_t)); +} + +void bam_header_destroy(bam_header_t *header) +{ + int32_t i; + extern void bam_destroy_header_hash(bam_header_t *header); + if (header == 0) return; + if (header->target_name) { + for (i = 0; i < header->n_targets; ++i) + free(header->target_name[i]); + free(header->target_name); + free(header->target_len); + } + free(header->text); + if (header->dict) sam_header_free(header->dict); + if (header->rg2lib) sam_tbl_destroy(header->rg2lib); + bam_destroy_header_hash(header); + free(header); +} + +bam_header_t *bam_header_read(bamFile fp) +{ + bam_header_t *header; + char buf[4]; + int magic_len; + int32_t i = 1, name_len; + // check EOF + i = bgzf_check_EOF(fp); + if (i < 0) { + // If the file is a pipe, checking the EOF marker will *always* fail + // with ESPIPE. Suppress the error message in this case. + if (errno != ESPIPE) perror("[bam_header_read] bgzf_check_EOF"); + } + else if (i == 0) fprintf(stderr, "[bam_header_read] EOF marker is absent. The input is probably truncated.\n"); + // read "BAM1" + magic_len = bam_read(fp, buf, 4); + if (magic_len != 4 || strncmp(buf, "BAM\001", 4) != 0) { + fprintf(stderr, "[bam_header_read] invalid BAM binary header (this is not a BAM file).\n"); + return 0; + } + header = bam_header_init(); + // read plain text and the number of reference sequences + bam_read(fp, &header->l_text, 4); + if (bam_is_be) bam_swap_endian_4p(&header->l_text); + header->text = (char*)calloc(header->l_text + 1, 1); + bam_read(fp, header->text, header->l_text); + bam_read(fp, &header->n_targets, 4); + if (bam_is_be) bam_swap_endian_4p(&header->n_targets); + // read reference sequence names and lengths + header->target_name = (char**)calloc(header->n_targets, sizeof(char*)); + header->target_len = (uint32_t*)calloc(header->n_targets, 4); + for (i = 0; i != header->n_targets; ++i) { + bam_read(fp, &name_len, 4); + if (bam_is_be) bam_swap_endian_4p(&name_len); + header->target_name[i] = (char*)calloc(name_len, 1); + bam_read(fp, header->target_name[i], name_len); + bam_read(fp, &header->target_len[i], 4); + if (bam_is_be) bam_swap_endian_4p(&header->target_len[i]); + } + return header; +} + +int bam_header_write(bamFile fp, const bam_header_t *header) +{ + char buf[4]; + int32_t i, name_len, x; + // write "BAM1" + strncpy(buf, "BAM\001", 4); + bam_write(fp, buf, 4); + // write plain text and the number of reference sequences + if (bam_is_be) { + x = bam_swap_endian_4(header->l_text); + bam_write(fp, &x, 4); + if (header->l_text) bam_write(fp, header->text, header->l_text); + x = bam_swap_endian_4(header->n_targets); + bam_write(fp, &x, 4); + } else { + bam_write(fp, &header->l_text, 4); + if (header->l_text) bam_write(fp, header->text, header->l_text); + bam_write(fp, &header->n_targets, 4); + } + // write sequence names and lengths + for (i = 0; i != header->n_targets; ++i) { + char *p = header->target_name[i]; + name_len = strlen(p) + 1; + if (bam_is_be) { + x = bam_swap_endian_4(name_len); + bam_write(fp, &x, 4); + } else bam_write(fp, &name_len, 4); + bam_write(fp, p, name_len); + if (bam_is_be) { + x = bam_swap_endian_4(header->target_len[i]); + bam_write(fp, &x, 4); + } else bam_write(fp, &header->target_len[i], 4); + } + bgzf_flush(fp); + return 0; +} + +static void swap_endian_data(const bam1_core_t *c, int data_len, uint8_t *data) +{ + uint8_t *s; + uint32_t i, *cigar = (uint32_t*)(data + c->l_qname); + s = data + c->n_cigar*4 + c->l_qname + c->l_qseq + (c->l_qseq + 1)/2; + for (i = 0; i < c->n_cigar; ++i) bam_swap_endian_4p(&cigar[i]); + while (s < data + data_len) { + uint8_t type; + s += 2; // skip key + type = toupper(*s); ++s; // skip type + if (type == 'C' || type == 'A') ++s; + else if (type == 'S') { bam_swap_endian_2p(s); s += 2; } + else if (type == 'I' || type == 'F') { bam_swap_endian_4p(s); s += 4; } + else if (type == 'D') { bam_swap_endian_8p(s); s += 8; } + else if (type == 'Z' || type == 'H') { while (*s) ++s; ++s; } + else if (type == 'B') { + int32_t n, Bsize = bam_aux_type2size(*s); + memcpy(&n, s + 1, 4); + if (1 == Bsize) { + } else if (2 == Bsize) { + for (i = 0; i < n; i += 2) + bam_swap_endian_2p(s + 5 + i); + } else if (4 == Bsize) { + for (i = 0; i < n; i += 4) + bam_swap_endian_4p(s + 5 + i); + } + bam_swap_endian_4p(s+1); + } + } +} + +int bam_read1(bamFile fp, bam1_t *b) +{ + bam1_core_t *c = &b->core; + int32_t block_len, ret, i; + uint32_t x[8]; + + assert(BAM_CORE_SIZE == 32); + if ((ret = bam_read(fp, &block_len, 4)) != 4) { + if (ret == 0) return -1; // normal end-of-file + else return -2; // truncated + } + if (bam_read(fp, x, BAM_CORE_SIZE) != BAM_CORE_SIZE) return -3; + if (bam_is_be) { + bam_swap_endian_4p(&block_len); + for (i = 0; i < 8; ++i) bam_swap_endian_4p(x + i); + } + c->tid = x[0]; c->pos = x[1]; + c->bin = x[2]>>16; c->qual = x[2]>>8&0xff; c->l_qname = x[2]&0xff; + c->flag = x[3]>>16; c->n_cigar = x[3]&0xffff; + c->l_qseq = x[4]; + c->mtid = x[5]; c->mpos = x[6]; c->isize = x[7]; + b->data_len = block_len - BAM_CORE_SIZE; + if (b->m_data < b->data_len) { + b->m_data = b->data_len; + kroundup32(b->m_data); + b->data = (uint8_t*)realloc(b->data, b->m_data); + } + if (bam_read(fp, b->data, b->data_len) != b->data_len) return -4; + b->l_aux = b->data_len - c->n_cigar * 4 - c->l_qname - c->l_qseq - (c->l_qseq+1)/2; + if (bam_is_be) swap_endian_data(c, b->data_len, b->data); + return 4 + block_len; +} + +inline int bam_write1_core(bamFile fp, const bam1_core_t *c, int data_len, uint8_t *data) +{ + uint32_t x[8], block_len = data_len + BAM_CORE_SIZE, y; + int i; + assert(BAM_CORE_SIZE == 32); + x[0] = c->tid; + x[1] = c->pos; + x[2] = (uint32_t)c->bin<<16 | c->qual<<8 | c->l_qname; + x[3] = (uint32_t)c->flag<<16 | c->n_cigar; + x[4] = c->l_qseq; + x[5] = c->mtid; + x[6] = c->mpos; + x[7] = c->isize; + bgzf_flush_try(fp, 4 + block_len); + if (bam_is_be) { + for (i = 0; i < 8; ++i) bam_swap_endian_4p(x + i); + y = block_len; + bam_write(fp, bam_swap_endian_4p(&y), 4); + swap_endian_data(c, data_len, data); + } else bam_write(fp, &block_len, 4); + bam_write(fp, x, BAM_CORE_SIZE); + bam_write(fp, data, data_len); + if (bam_is_be) swap_endian_data(c, data_len, data); + return 4 + block_len; +} + +int bam_write1(bamFile fp, const bam1_t *b) +{ + return bam_write1_core(fp, &b->core, b->data_len, b->data); +} + +char *bam_format1_core(const bam_header_t *header, const bam1_t *b, int of) +{ + uint8_t *s = bam1_seq(b), *t = bam1_qual(b); + int i; + const bam1_core_t *c = &b->core; + kstring_t str; + str.l = str.m = 0; str.s = 0; + + kputsn(bam1_qname(b), c->l_qname-1, &str); kputc('\t', &str); + if (of == BAM_OFDEC) { kputw(c->flag, &str); kputc('\t', &str); } + else if (of == BAM_OFHEX) ksprintf(&str, "0x%x\t", c->flag); + else { // BAM_OFSTR + for (i = 0; i < 16; ++i) + if ((c->flag & 1<<i) && bam_flag2char_table[i]) + kputc(bam_flag2char_table[i], &str); + kputc('\t', &str); + } + if (c->tid < 0) kputsn("*\t", 2, &str); + else { + if (header) kputs(header->target_name[c->tid] , &str); + else kputw(c->tid, &str); + kputc('\t', &str); + } + kputw(c->pos + 1, &str); kputc('\t', &str); kputw(c->qual, &str); kputc('\t', &str); + if (c->n_cigar == 0) kputc('*', &str); + else { + for (i = 0; i < c->n_cigar; ++i) { + kputw(bam1_cigar(b)[i]>>BAM_CIGAR_SHIFT, &str); + kputc("MIDNSHP"[bam1_cigar(b)[i]&BAM_CIGAR_MASK], &str); + } + } + kputc('\t', &str); + if (c->mtid < 0) kputsn("*\t", 2, &str); + else if (c->mtid == c->tid) kputsn("=\t", 2, &str); + else { + if (header) kputs(header->target_name[c->mtid], &str); + else kputw(c->mtid, &str); + kputc('\t', &str); + } + kputw(c->mpos + 1, &str); kputc('\t', &str); kputw(c->isize, &str); kputc('\t', &str); + if (c->l_qseq) { + for (i = 0; i < c->l_qseq; ++i) kputc(bam_nt16_rev_table[bam1_seqi(s, i)], &str); + kputc('\t', &str); + if (t[0] == 0xff) kputc('*', &str); + else for (i = 0; i < c->l_qseq; ++i) kputc(t[i] + 33, &str); + } else kputsn("*\t*", 3, &str); + s = bam1_aux(b); + while (s < b->data + b->data_len) { + uint8_t type, key[2]; + key[0] = s[0]; key[1] = s[1]; + s += 2; type = *s; ++s; + kputc('\t', &str); kputsn((char*)key, 2, &str); kputc(':', &str); + if (type == 'A') { kputsn("A:", 2, &str); kputc(*s, &str); ++s; } + else if (type == 'C') { kputsn("i:", 2, &str); kputw(*s, &str); ++s; } + else if (type == 'c') { kputsn("i:", 2, &str); kputw(*(int8_t*)s, &str); ++s; } + else if (type == 'S') { kputsn("i:", 2, &str); kputw(*(uint16_t*)s, &str); s += 2; } + else if (type == 's') { kputsn("i:", 2, &str); kputw(*(int16_t*)s, &str); s += 2; } + else if (type == 'I') { kputsn("i:", 2, &str); kputuw(*(uint32_t*)s, &str); s += 4; } + else if (type == 'i') { kputsn("i:", 2, &str); kputw(*(int32_t*)s, &str); s += 4; } + else if (type == 'f') { ksprintf(&str, "f:%g", *(float*)s); s += 4; } + else if (type == 'd') { ksprintf(&str, "d:%lg", *(double*)s); s += 8; } + else if (type == 'Z' || type == 'H') { kputc(type, &str); kputc(':', &str); while (*s) kputc(*s++, &str); ++s; } + else if (type == 'B') { + uint8_t sub_type = *(s++); + int32_t n; + memcpy(&n, s, 4); + s += 4; // no point to the start of the array + kputc(type, &str); kputc(':', &str); kputc(sub_type, &str); // write the typing + for (i = 0; i < n; ++i) { + kputc(',', &str); + if ('c' == sub_type || 'c' == sub_type) { kputw(*(int8_t*)s, &str); ++s; } + else if ('C' == sub_type) { kputw(*(uint8_t*)s, &str); ++s; } + else if ('s' == sub_type) { kputw(*(int16_t*)s, &str); s += 2; } + else if ('S' == sub_type) { kputw(*(uint16_t*)s, &str); s += 2; } + else if ('i' == sub_type) { kputw(*(int32_t*)s, &str); s += 4; } + else if ('I' == sub_type) { kputuw(*(uint32_t*)s, &str); s += 4; } + else if ('f' == sub_type) { ksprintf(&str, "%g", *(float*)s); s += 4; } + } + } + } + return str.s; +} + +char *bam_format1(const bam_header_t *header, const bam1_t *b) +{ + return bam_format1_core(header, b, BAM_OFDEC); +} + +void bam_view1(const bam_header_t *header, const bam1_t *b) +{ + char *s = bam_format1(header, b); + puts(s); + free(s); +} + +int bam_validate1(const bam_header_t *header, const bam1_t *b) +{ + char *s; + + if (b->core.tid < -1 || b->core.mtid < -1) return 0; + if (header && (b->core.tid >= header->n_targets || b->core.mtid >= header->n_targets)) return 0; + + if (b->data_len < b->core.l_qname) return 0; + s = memchr(bam1_qname(b), '\0', b->core.l_qname); + if (s != &bam1_qname(b)[b->core.l_qname-1]) return 0; + + // FIXME: Other fields could also be checked, especially the auxiliary data + + return 1; +} + +// FIXME: we should also check the LB tag associated with each alignment +const char *bam_get_library(bam_header_t *h, const bam1_t *b) +{ + const uint8_t *rg; + if (h->dict == 0) h->dict = sam_header_parse2(h->text); + if (h->rg2lib == 0) h->rg2lib = sam_header2tbl(h->dict, "RG", "ID", "LB"); + rg = bam_aux_get(b, "RG"); + return (rg == 0)? 0 : sam_tbl_get(h->rg2lib, (const char*)(rg + 1)); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,758 @@ +/* The MIT License + + Copyright (c) 2008-2010 Genome Research Ltd (GRL). + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* Contact: Heng Li <lh3@sanger.ac.uk> */ + +#ifndef BAM_BAM_H +#define BAM_BAM_H + +/*! + @header + + BAM library provides I/O and various operations on manipulating files + in the BAM (Binary Alignment/Mapping) or SAM (Sequence Alignment/Map) + format. It now supports importing from or exporting to SAM, sorting, + merging, generating pileup, and quickly retrieval of reads overlapped + with a specified region. + + @copyright Genome Research Ltd. + */ + +#define BAM_VERSION "0.1.16 (r963:234)" + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#ifndef BAM_LITE +#define BAM_VIRTUAL_OFFSET16 +#include "bgzf.h" +/*! @abstract BAM file handler */ +typedef BGZF *bamFile; +#define bam_open(fn, mode) bgzf_open(fn, mode) +#define bam_dopen(fd, mode) bgzf_fdopen(fd, mode) +#define bam_close(fp) bgzf_close(fp) +#define bam_read(fp, buf, size) bgzf_read(fp, buf, size) +#define bam_write(fp, buf, size) bgzf_write(fp, buf, size) +#define bam_tell(fp) bgzf_tell(fp) +#define bam_seek(fp, pos, dir) bgzf_seek(fp, pos, dir) +#else +#define BAM_TRUE_OFFSET +#include <zlib.h> +typedef gzFile bamFile; +#define bam_open(fn, mode) gzopen(fn, mode) +#define bam_dopen(fd, mode) gzdopen(fd, mode) +#define bam_close(fp) gzclose(fp) +#define bam_read(fp, buf, size) gzread(fp, buf, size) +/* no bam_write/bam_tell/bam_seek() here */ +#endif + +/*! @typedef + @abstract Structure for the alignment header. + @field n_targets number of reference sequences + @field target_name names of the reference sequences + @field target_len lengths of the referene sequences + @field dict header dictionary + @field hash hash table for fast name lookup + @field rg2lib hash table for @RG-ID -> LB lookup + @field l_text length of the plain text in the header + @field text plain text + + @discussion Field hash points to null by default. It is a private + member. + */ +typedef struct { + int32_t n_targets; + char **target_name; + uint32_t *target_len; + void *dict, *hash, *rg2lib; + size_t l_text, n_text; + char *text; +} bam_header_t; + +/*! @abstract the read is paired in sequencing, no matter whether it is mapped in a pair */ +#define BAM_FPAIRED 1 +/*! @abstract the read is mapped in a proper pair */ +#define BAM_FPROPER_PAIR 2 +/*! @abstract the read itself is unmapped; conflictive with BAM_FPROPER_PAIR */ +#define BAM_FUNMAP 4 +/*! @abstract the mate is unmapped */ +#define BAM_FMUNMAP 8 +/*! @abstract the read is mapped to the reverse strand */ +#define BAM_FREVERSE 16 +/*! @abstract the mate is mapped to the reverse strand */ +#define BAM_FMREVERSE 32 +/*! @abstract this is read1 */ +#define BAM_FREAD1 64 +/*! @abstract this is read2 */ +#define BAM_FREAD2 128 +/*! @abstract not primary alignment */ +#define BAM_FSECONDARY 256 +/*! @abstract QC failure */ +#define BAM_FQCFAIL 512 +/*! @abstract optical or PCR duplicate */ +#define BAM_FDUP 1024 + +#define BAM_OFDEC 0 +#define BAM_OFHEX 1 +#define BAM_OFSTR 2 + +/*! @abstract defautl mask for pileup */ +#define BAM_DEF_MASK (BAM_FUNMAP | BAM_FSECONDARY | BAM_FQCFAIL | BAM_FDUP) + +#define BAM_CORE_SIZE sizeof(bam1_core_t) + +/** + * Describing how CIGAR operation/length is packed in a 32-bit integer. + */ +#define BAM_CIGAR_SHIFT 4 +#define BAM_CIGAR_MASK ((1 << BAM_CIGAR_SHIFT) - 1) + +/* + CIGAR operations. + */ +/*! @abstract CIGAR: match */ +#define BAM_CMATCH 0 +/*! @abstract CIGAR: insertion to the reference */ +#define BAM_CINS 1 +/*! @abstract CIGAR: deletion from the reference */ +#define BAM_CDEL 2 +/*! @abstract CIGAR: skip on the reference (e.g. spliced alignment) */ +#define BAM_CREF_SKIP 3 +/*! @abstract CIGAR: clip on the read with clipped sequence present in qseq */ +#define BAM_CSOFT_CLIP 4 +/*! @abstract CIGAR: clip on the read with clipped sequence trimmed off */ +#define BAM_CHARD_CLIP 5 +/*! @abstract CIGAR: padding */ +#define BAM_CPAD 6 + +/*! @typedef + @abstract Structure for core alignment information. + @field tid chromosome ID, defined by bam_header_t + @field pos 0-based leftmost coordinate + @field strand strand; 0 for forward and 1 otherwise + @field bin bin calculated by bam_reg2bin() + @field qual mapping quality + @field l_qname length of the query name + @field flag bitwise flag + @field n_cigar number of CIGAR operations + @field l_qseq length of the query sequence (read) + */ +typedef struct { + int32_t tid; + int32_t pos; + uint32_t bin:16, qual:8, l_qname:8; + uint32_t flag:16, n_cigar:16; + int32_t l_qseq; + int32_t mtid; + int32_t mpos; + int32_t isize; +} bam1_core_t; + +/*! @typedef + @abstract Structure for one alignment. + @field core core information about the alignment + @field l_aux length of auxiliary data + @field data_len current length of bam1_t::data + @field m_data maximum length of bam1_t::data + @field data all variable-length data, concatenated; structure: cigar-qname-seq-qual-aux + + @discussion Notes: + + 1. qname is zero tailing and core.l_qname includes the tailing '\0'. + 2. l_qseq is calculated from the total length of an alignment block + on reading or from CIGAR. + */ +typedef struct { + bam1_core_t core; + int l_aux, data_len, m_data; + uint8_t *data; +} bam1_t; + +typedef struct __bam_iter_t *bam_iter_t; + +#define bam1_strand(b) (((b)->core.flag&BAM_FREVERSE) != 0) +#define bam1_mstrand(b) (((b)->core.flag&BAM_FMREVERSE) != 0) + +/*! @function + @abstract Get the CIGAR array + @param b pointer to an alignment + @return pointer to the CIGAR array + + @discussion In the CIGAR array, each element is a 32-bit integer. The + lower 4 bits gives a CIGAR operation and the higher 28 bits keep the + length of a CIGAR. + */ +#define bam1_cigar(b) ((uint32_t*)((b)->data + (b)->core.l_qname)) + +/*! @function + @abstract Get the name of the query + @param b pointer to an alignment + @return pointer to the name string, null terminated + */ +#define bam1_qname(b) ((char*)((b)->data)) + +/*! @function + @abstract Get query sequence + @param b pointer to an alignment + @return pointer to sequence + + @discussion Each base is encoded in 4 bits: 1 for A, 2 for C, 4 for G, + 8 for T and 15 for N. Two bases are packed in one byte with the base + at the higher 4 bits having smaller coordinate on the read. It is + recommended to use bam1_seqi() macro to get the base. + */ +#define bam1_seq(b) ((b)->data + (b)->core.n_cigar*4 + (b)->core.l_qname) + +/*! @function + @abstract Get query quality + @param b pointer to an alignment + @return pointer to quality string + */ +#define bam1_qual(b) ((b)->data + (b)->core.n_cigar*4 + (b)->core.l_qname + (((b)->core.l_qseq + 1)>>1)) + +/*! @function + @abstract Get a base on read + @param s Query sequence returned by bam1_seq() + @param i The i-th position, 0-based + @return 4-bit integer representing the base. + */ +#define bam1_seqi(s, i) ((s)[(i)/2] >> 4*(1-(i)%2) & 0xf) + +/*! @function + @abstract Get query sequence and quality + @param b pointer to an alignment + @return pointer to the concatenated auxiliary data + */ +#define bam1_aux(b) ((b)->data + (b)->core.n_cigar*4 + (b)->core.l_qname + (b)->core.l_qseq + ((b)->core.l_qseq + 1)/2) + +#ifndef kroundup32 +/*! @function + @abstract Round an integer to the next closest power-2 integer. + @param x integer to be rounded (in place) + @discussion x will be modified. + */ +#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) +#endif + +/*! + @abstract Whether the machine is big-endian; modified only in + bam_header_init(). + */ +extern int bam_is_be; + +/*! + @abstract Verbose level between 0 and 3; 0 is supposed to disable all + debugging information, though this may not have been implemented. + */ +extern int bam_verbose; + +/*! @abstract Table for converting a nucleotide character to the 4-bit encoding. */ +extern unsigned char bam_nt16_table[256]; + +/*! @abstract Table for converting a 4-bit encoded nucleotide to a letter. */ +extern char *bam_nt16_rev_table; + +extern char bam_nt16_nt4_table[]; + +#ifdef __cplusplus +extern "C" { +#endif + + /********************* + * Low-level SAM I/O * + *********************/ + + /*! @abstract TAM file handler */ + typedef struct __tamFile_t *tamFile; + + /*! + @abstract Open a SAM file for reading, either uncompressed or compressed by gzip/zlib. + @param fn SAM file name + @return SAM file handler + */ + tamFile sam_open(const char *fn); + + /*! + @abstract Close a SAM file handler + @param fp SAM file handler + */ + void sam_close(tamFile fp); + + /*! + @abstract Read one alignment from a SAM file handler + @param fp SAM file handler + @param header header information (ordered names of chromosomes) + @param b read alignment; all members in b will be updated + @return 0 if successful; otherwise negative + */ + int sam_read1(tamFile fp, bam_header_t *header, bam1_t *b); + + /*! + @abstract Read header information from a TAB-delimited list file. + @param fn_list file name for the list + @return a pointer to the header structure + + @discussion Each line in this file consists of chromosome name and + the length of chromosome. + */ + bam_header_t *sam_header_read2(const char *fn_list); + + /*! + @abstract Read header from a SAM file (if present) + @param fp SAM file handler + @return pointer to header struct; 0 if no @SQ lines available + */ + bam_header_t *sam_header_read(tamFile fp); + + /*! + @abstract Parse @SQ lines a update a header struct + @param h pointer to the header struct to be updated + @return number of target sequences + + @discussion bam_header_t::{n_targets,target_len,target_name} will + be destroyed in the first place. + */ + int sam_header_parse(bam_header_t *h); + int32_t bam_get_tid(const bam_header_t *header, const char *seq_name); + + /*! + @abstract Parse @RG lines a update a header struct + @param h pointer to the header struct to be updated + @return number of @RG lines + + @discussion bam_header_t::rg2lib will be destroyed in the first + place. + */ + int sam_header_parse_rg(bam_header_t *h); + +#define sam_write1(header, b) bam_view1(header, b) + + + /******************************** + * APIs for string dictionaries * + ********************************/ + + int bam_strmap_put(void *strmap, const char *rg, const char *lib); + const char *bam_strmap_get(const void *strmap, const char *rg); + void *bam_strmap_dup(const void*); + void *bam_strmap_init(); + void bam_strmap_destroy(void *strmap); + + + /********************* + * Low-level BAM I/O * + *********************/ + + /*! + @abstract Initialize a header structure. + @return the pointer to the header structure + + @discussion This function also modifies the global variable + bam_is_be. + */ + bam_header_t *bam_header_init(); + + /*! + @abstract Destroy a header structure. + @param header pointer to the header + */ + void bam_header_destroy(bam_header_t *header); + + /*! + @abstract Read a header structure from BAM. + @param fp BAM file handler, opened by bam_open() + @return pointer to the header structure + + @discussion The file position indicator must be placed at the + beginning of the file. Upon success, the position indicator will + be set at the start of the first alignment. + */ + bam_header_t *bam_header_read(bamFile fp); + + /*! + @abstract Write a header structure to BAM. + @param fp BAM file handler + @param header pointer to the header structure + @return always 0 currently + */ + int bam_header_write(bamFile fp, const bam_header_t *header); + + /*! + @abstract Read an alignment from BAM. + @param fp BAM file handler + @param b read alignment; all members are updated. + @return number of bytes read from the file + + @discussion The file position indicator must be + placed right before an alignment. Upon success, this function + will set the position indicator to the start of the next + alignment. This function is not affected by the machine + endianness. + */ + int bam_read1(bamFile fp, bam1_t *b); + + /*! + @abstract Write an alignment to BAM. + @param fp BAM file handler + @param c pointer to the bam1_core_t structure + @param data_len total length of variable size data related to + the alignment + @param data pointer to the concatenated data + @return number of bytes written to the file + + @discussion This function is not affected by the machine + endianness. + */ + int bam_write1_core(bamFile fp, const bam1_core_t *c, int data_len, uint8_t *data); + + /*! + @abstract Write an alignment to BAM. + @param fp BAM file handler + @param b alignment to write + @return number of bytes written to the file + + @abstract It is equivalent to: + bam_write1_core(fp, &b->core, b->data_len, b->data) + */ + int bam_write1(bamFile fp, const bam1_t *b); + + /*! @function + @abstract Initiate a pointer to bam1_t struct + */ +#define bam_init1() ((bam1_t*)calloc(1, sizeof(bam1_t))) + + /*! @function + @abstract Free the memory allocated for an alignment. + @param b pointer to an alignment + */ +#define bam_destroy1(b) do { \ + if (b) { free((b)->data); free(b); } \ + } while (0) + + /*! + @abstract Format a BAM record in the SAM format + @param header pointer to the header structure + @param b alignment to print + @return a pointer to the SAM string + */ + char *bam_format1(const bam_header_t *header, const bam1_t *b); + + char *bam_format1_core(const bam_header_t *header, const bam1_t *b, int of); + + /*! + @abstract Check whether a BAM record is plausibly valid + @param header associated header structure, or NULL if unavailable + @param b alignment to validate + @return 0 if the alignment is invalid; non-zero otherwise + + @discussion Simple consistency check of some of the fields of the + alignment record. If the header is provided, several additional checks + are made. Not all fields are checked, so a non-zero result is not a + guarantee that the record is valid. However it is usually good enough + to detect when bam_seek() has been called with a virtual file offset + that is not the offset of an alignment record. + */ + int bam_validate1(const bam_header_t *header, const bam1_t *b); + + const char *bam_get_library(bam_header_t *header, const bam1_t *b); + + + /*************** + * pileup APIs * + ***************/ + + /*! @typedef + @abstract Structure for one alignment covering the pileup position. + @field b pointer to the alignment + @field qpos position of the read base at the pileup site, 0-based + @field indel indel length; 0 for no indel, positive for ins and negative for del + @field is_del 1 iff the base on the padded read is a deletion + @field level the level of the read in the "viewer" mode + + @discussion See also bam_plbuf_push() and bam_lplbuf_push(). The + difference between the two functions is that the former does not + set bam_pileup1_t::level, while the later does. Level helps the + implementation of alignment viewers, but calculating this has some + overhead. + */ + typedef struct { + bam1_t *b; + int32_t qpos; + int indel, level; + uint32_t is_del:1, is_head:1, is_tail:1, is_refskip:1, aux:28; + } bam_pileup1_t; + + typedef int (*bam_plp_auto_f)(void *data, bam1_t *b); + + struct __bam_plp_t; + typedef struct __bam_plp_t *bam_plp_t; + + bam_plp_t bam_plp_init(bam_plp_auto_f func, void *data); + int bam_plp_push(bam_plp_t iter, const bam1_t *b); + const bam_pileup1_t *bam_plp_next(bam_plp_t iter, int *_tid, int *_pos, int *_n_plp); + const bam_pileup1_t *bam_plp_auto(bam_plp_t iter, int *_tid, int *_pos, int *_n_plp); + void bam_plp_set_mask(bam_plp_t iter, int mask); + void bam_plp_set_maxcnt(bam_plp_t iter, int maxcnt); + void bam_plp_reset(bam_plp_t iter); + void bam_plp_destroy(bam_plp_t iter); + + struct __bam_mplp_t; + typedef struct __bam_mplp_t *bam_mplp_t; + + bam_mplp_t bam_mplp_init(int n, bam_plp_auto_f func, void **data); + void bam_mplp_destroy(bam_mplp_t iter); + void bam_mplp_set_maxcnt(bam_mplp_t iter, int maxcnt); + int bam_mplp_auto(bam_mplp_t iter, int *_tid, int *_pos, int *n_plp, const bam_pileup1_t **plp); + + /*! @typedef + @abstract Type of function to be called by bam_plbuf_push(). + @param tid chromosome ID as is defined in the header + @param pos start coordinate of the alignment, 0-based + @param n number of elements in pl array + @param pl array of alignments + @param data user provided data + @discussion See also bam_plbuf_push(), bam_plbuf_init() and bam_pileup1_t. + */ + typedef int (*bam_pileup_f)(uint32_t tid, uint32_t pos, int n, const bam_pileup1_t *pl, void *data); + + typedef struct { + bam_plp_t iter; + bam_pileup_f func; + void *data; + } bam_plbuf_t; + + void bam_plbuf_set_mask(bam_plbuf_t *buf, int mask); + void bam_plbuf_reset(bam_plbuf_t *buf); + bam_plbuf_t *bam_plbuf_init(bam_pileup_f func, void *data); + void bam_plbuf_destroy(bam_plbuf_t *buf); + int bam_plbuf_push(const bam1_t *b, bam_plbuf_t *buf); + + int bam_pileup_file(bamFile fp, int mask, bam_pileup_f func, void *func_data); + + struct __bam_lplbuf_t; + typedef struct __bam_lplbuf_t bam_lplbuf_t; + + void bam_lplbuf_reset(bam_lplbuf_t *buf); + + /*! @abstract bam_plbuf_init() equivalent with level calculated. */ + bam_lplbuf_t *bam_lplbuf_init(bam_pileup_f func, void *data); + + /*! @abstract bam_plbuf_destroy() equivalent with level calculated. */ + void bam_lplbuf_destroy(bam_lplbuf_t *tv); + + /*! @abstract bam_plbuf_push() equivalent with level calculated. */ + int bam_lplbuf_push(const bam1_t *b, bam_lplbuf_t *buf); + + + /********************* + * BAM indexing APIs * + *********************/ + + struct __bam_index_t; + typedef struct __bam_index_t bam_index_t; + + /*! + @abstract Build index for a BAM file. + @discussion Index file "fn.bai" will be created. + @param fn name of the BAM file + @return always 0 currently + */ + int bam_index_build(const char *fn); + + /*! + @abstract Load index from file "fn.bai". + @param fn name of the BAM file (NOT the index file) + @return pointer to the index structure + */ + bam_index_t *bam_index_load(const char *fn); + + /*! + @abstract Destroy an index structure. + @param idx pointer to the index structure + */ + void bam_index_destroy(bam_index_t *idx); + + /*! @typedef + @abstract Type of function to be called by bam_fetch(). + @param b the alignment + @param data user provided data + */ + typedef int (*bam_fetch_f)(const bam1_t *b, void *data); + + /*! + @abstract Retrieve the alignments that are overlapped with the + specified region. + + @discussion A user defined function will be called for each + retrieved alignment ordered by its start position. + + @param fp BAM file handler + @param idx pointer to the alignment index + @param tid chromosome ID as is defined in the header + @param beg start coordinate, 0-based + @param end end coordinate, 0-based + @param data user provided data (will be transferred to func) + @param func user defined function + */ + int bam_fetch(bamFile fp, const bam_index_t *idx, int tid, int beg, int end, void *data, bam_fetch_f func); + + bam_iter_t bam_iter_query(const bam_index_t *idx, int tid, int beg, int end); + int bam_iter_read(bamFile fp, bam_iter_t iter, bam1_t *b); + void bam_iter_destroy(bam_iter_t iter); + + /*! + @abstract Parse a region in the format: "chr2:100,000-200,000". + @discussion bam_header_t::hash will be initialized if empty. + @param header pointer to the header structure + @param str string to be parsed + @param ref_id the returned chromosome ID + @param begin the returned start coordinate + @param end the returned end coordinate + @return 0 on success; -1 on failure + */ + int bam_parse_region(bam_header_t *header, const char *str, int *ref_id, int *begin, int *end); + + + /************************** + * APIs for optional tags * + **************************/ + + /*! + @abstract Retrieve data of a tag + @param b pointer to an alignment struct + @param tag two-character tag to be retrieved + + @return pointer to the type and data. The first character is the + type that can be 'iIsScCdfAZH'. + + @discussion Use bam_aux2?() series to convert the returned data to + the corresponding type. + */ + uint8_t *bam_aux_get(const bam1_t *b, const char tag[2]); + + int32_t bam_aux2i(const uint8_t *s); + float bam_aux2f(const uint8_t *s); + double bam_aux2d(const uint8_t *s); + char bam_aux2A(const uint8_t *s); + char *bam_aux2Z(const uint8_t *s); + + int bam_aux_del(bam1_t *b, uint8_t *s); + void bam_aux_append(bam1_t *b, const char tag[2], char type, int len, uint8_t *data); + uint8_t *bam_aux_get_core(bam1_t *b, const char tag[2]); // an alias of bam_aux_get() + + + /***************** + * Miscellaneous * + *****************/ + + /*! + @abstract Calculate the rightmost coordinate of an alignment on the + reference genome. + + @param c pointer to the bam1_core_t structure + @param cigar the corresponding CIGAR array (from bam1_t::cigar) + @return the rightmost coordinate, 0-based + */ + uint32_t bam_calend(const bam1_core_t *c, const uint32_t *cigar); + + /*! + @abstract Calculate the length of the query sequence from CIGAR. + @param c pointer to the bam1_core_t structure + @param cigar the corresponding CIGAR array (from bam1_t::cigar) + @return length of the query sequence + */ + int32_t bam_cigar2qlen(const bam1_core_t *c, const uint32_t *cigar); + +#ifdef __cplusplus +} +#endif + +/*! + @abstract Calculate the minimum bin that contains a region [beg,end). + @param beg start of the region, 0-based + @param end end of the region, 0-based + @return bin + */ +static inline int bam_reg2bin(uint32_t beg, uint32_t end) +{ + --end; + if (beg>>14 == end>>14) return 4681 + (beg>>14); + if (beg>>17 == end>>17) return 585 + (beg>>17); + if (beg>>20 == end>>20) return 73 + (beg>>20); + if (beg>>23 == end>>23) return 9 + (beg>>23); + if (beg>>26 == end>>26) return 1 + (beg>>26); + return 0; +} + +/*! + @abstract Copy an alignment + @param bdst destination alignment struct + @param bsrc source alignment struct + @return pointer to the destination alignment struct + */ +static inline bam1_t *bam_copy1(bam1_t *bdst, const bam1_t *bsrc) +{ + uint8_t *data = bdst->data; + int m_data = bdst->m_data; // backup data and m_data + if (m_data < bsrc->data_len) { // double the capacity + m_data = bsrc->data_len; kroundup32(m_data); + data = (uint8_t*)realloc(data, m_data); + } + memcpy(data, bsrc->data, bsrc->data_len); // copy var-len data + *bdst = *bsrc; // copy the rest + // restore the backup + bdst->m_data = m_data; + bdst->data = data; + return bdst; +} + +/*! + @abstract Duplicate an alignment + @param src source alignment struct + @return pointer to the destination alignment struct + */ +static inline bam1_t *bam_dup1(const bam1_t *src) +{ + bam1_t *b; + b = bam_init1(); + *b = *src; + b->m_data = b->data_len; + b->data = (uint8_t*)calloc(b->data_len, 1); + memcpy(b->data, src->data, b->data_len); + return b; +} + +static inline int bam_aux_type2size(int x) +{ + if (x == 'C' || x == 'c' || x == 'A') return 1; + else if (x == 'S' || x == 's') return 2; + else if (x == 'I' || x == 'i' || x == 'f') return 4; + else return 0; +} + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam2bcf.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,260 @@ +#include <math.h> +#include <stdint.h> +#include "bam.h" +#include "kstring.h" +#include "bam2bcf.h" +#include "errmod.h" +#include "bcftools/bcf.h" + +extern void ks_introsort_uint32_t(size_t n, uint32_t a[]); + +#define CALL_ETA 0.03f +#define CALL_MAX 256 +#define CALL_DEFTHETA 0.83f +#define DEF_MAPQ 20 + +#define CAP_DIST 25 + +bcf_callaux_t *bcf_call_init(double theta, int min_baseQ) +{ + bcf_callaux_t *bca; + if (theta <= 0.) theta = CALL_DEFTHETA; + bca = calloc(1, sizeof(bcf_callaux_t)); + bca->capQ = 60; + bca->openQ = 40; bca->extQ = 20; bca->tandemQ = 100; + bca->min_baseQ = min_baseQ; + bca->e = errmod_init(1. - theta); + bca->min_frac = 0.002; + bca->min_support = 1; + return bca; +} + +void bcf_call_destroy(bcf_callaux_t *bca) +{ + if (bca == 0) return; + errmod_destroy(bca->e); + free(bca->bases); free(bca->inscns); free(bca); +} +/* ref_base is the 4-bit representation of the reference base. It is + * negative if we are looking at an indel. */ +int bcf_call_glfgen(int _n, const bam_pileup1_t *pl, int ref_base, bcf_callaux_t *bca, bcf_callret1_t *r) +{ + int i, n, ref4, is_indel, ori_depth = 0; + memset(r, 0, sizeof(bcf_callret1_t)); + if (ref_base >= 0) { + ref4 = bam_nt16_nt4_table[ref_base]; + is_indel = 0; + } else ref4 = 4, is_indel = 1; + if (_n == 0) return -1; + // enlarge the bases array if necessary + if (bca->max_bases < _n) { + bca->max_bases = _n; + kroundup32(bca->max_bases); + bca->bases = (uint16_t*)realloc(bca->bases, 2 * bca->max_bases); + } + // fill the bases array + memset(r, 0, sizeof(bcf_callret1_t)); + for (i = n = 0; i < _n; ++i) { + const bam_pileup1_t *p = pl + i; + int q, b, mapQ, baseQ, is_diff, min_dist, seqQ; + // set base + if (p->is_del || p->is_refskip || (p->b->core.flag&BAM_FUNMAP)) continue; + ++ori_depth; + baseQ = q = is_indel? p->aux&0xff : (int)bam1_qual(p->b)[p->qpos]; // base/indel quality + seqQ = is_indel? (p->aux>>8&0xff) : 99; + if (q < bca->min_baseQ) continue; + if (q > seqQ) q = seqQ; + mapQ = p->b->core.qual < 255? p->b->core.qual : DEF_MAPQ; // special case for mapQ==255 + mapQ = mapQ < bca->capQ? mapQ : bca->capQ; + if (q > mapQ) q = mapQ; + if (q > 63) q = 63; + if (q < 4) q = 4; + if (!is_indel) { + b = bam1_seqi(bam1_seq(p->b), p->qpos); // base + b = bam_nt16_nt4_table[b? b : ref_base]; // b is the 2-bit base + is_diff = (ref4 < 4 && b == ref4)? 0 : 1; + } else { + b = p->aux>>16&0x3f; + is_diff = (b != 0); + } + bca->bases[n++] = q<<5 | (int)bam1_strand(p->b)<<4 | b; + // collect annotations + if (b < 4) r->qsum[b] += q; + ++r->anno[0<<2|is_diff<<1|bam1_strand(p->b)]; + min_dist = p->b->core.l_qseq - 1 - p->qpos; + if (min_dist > p->qpos) min_dist = p->qpos; + if (min_dist > CAP_DIST) min_dist = CAP_DIST; + r->anno[1<<2|is_diff<<1|0] += baseQ; + r->anno[1<<2|is_diff<<1|1] += baseQ * baseQ; + r->anno[2<<2|is_diff<<1|0] += mapQ; + r->anno[2<<2|is_diff<<1|1] += mapQ * mapQ; + r->anno[3<<2|is_diff<<1|0] += min_dist; + r->anno[3<<2|is_diff<<1|1] += min_dist * min_dist; + } + r->depth = n; r->ori_depth = ori_depth; + // glfgen + errmod_cal(bca->e, n, 5, bca->bases, r->p); + return r->depth; +} + +int bcf_call_combine(int n, const bcf_callret1_t *calls, int ref_base /*4-bit*/, bcf_call_t *call) +{ + int ref4, i, j, qsum[4]; + int64_t tmp; + if (ref_base >= 0) { + call->ori_ref = ref4 = bam_nt16_nt4_table[ref_base]; + if (ref4 > 4) ref4 = 4; + } else call->ori_ref = -1, ref4 = 0; + // calculate qsum + memset(qsum, 0, 4 * sizeof(int)); + for (i = 0; i < n; ++i) + for (j = 0; j < 4; ++j) + qsum[j] += calls[i].qsum[j]; + for (j = 0; j < 4; ++j) qsum[j] = qsum[j] << 2 | j; + // find the top 2 alleles + for (i = 1; i < 4; ++i) // insertion sort + for (j = i; j > 0 && qsum[j] < qsum[j-1]; --j) + tmp = qsum[j], qsum[j] = qsum[j-1], qsum[j-1] = tmp; + // set the reference allele and alternative allele(s) + for (i = 0; i < 5; ++i) call->a[i] = -1; + call->unseen = -1; + call->a[0] = ref4; + for (i = 3, j = 1; i >= 0; --i) { + if ((qsum[i]&3) != ref4) { + if (qsum[i]>>2 != 0) call->a[j++] = qsum[i]&3; + else break; + } + } + if (ref_base >= 0) { // for SNPs, find the "unseen" base + if (((ref4 < 4 && j < 4) || (ref4 == 4 && j < 5)) && i >= 0) + call->unseen = j, call->a[j++] = qsum[i]&3; + call->n_alleles = j; + } else { + call->n_alleles = j; + if (call->n_alleles == 1) return -1; // no reliable supporting read. stop doing anything + } + // set the PL array + if (call->n < n) { + call->n = n; + call->PL = realloc(call->PL, 15 * n); + } + { + int x, g[15], z; + double sum_min = 0.; + x = call->n_alleles * (call->n_alleles + 1) / 2; + // get the possible genotypes + for (i = z = 0; i < call->n_alleles; ++i) + for (j = 0; j <= i; ++j) + g[z++] = call->a[j] * 5 + call->a[i]; + for (i = 0; i < n; ++i) { + uint8_t *PL = call->PL + x * i; + const bcf_callret1_t *r = calls + i; + float min = 1e37; + for (j = 0; j < x; ++j) + if (min > r->p[g[j]]) min = r->p[g[j]]; + sum_min += min; + for (j = 0; j < x; ++j) { + int y; + y = (int)(r->p[g[j]] - min + .499); + if (y > 255) y = 255; + PL[j] = y; + } + } +// if (ref_base < 0) fprintf(stderr, "%d,%d,%f,%d\n", call->n_alleles, x, sum_min, call->unseen); + call->shift = (int)(sum_min + .499); + } + // combine annotations + memset(call->anno, 0, 16 * sizeof(int)); + for (i = call->depth = call->ori_depth = 0, tmp = 0; i < n; ++i) { + call->depth += calls[i].depth; + call->ori_depth += calls[i].ori_depth; + for (j = 0; j < 16; ++j) call->anno[j] += calls[i].anno[j]; + } + return 0; +} + +int bcf_call2bcf(int tid, int pos, bcf_call_t *bc, bcf1_t *b, bcf_callret1_t *bcr, int is_SP, + const bcf_callaux_t *bca, const char *ref) +{ + extern double kt_fisher_exact(int n11, int n12, int n21, int n22, double *_left, double *_right, double *two); + kstring_t s; + int i, j; + b->n_smpl = bc->n; + b->tid = tid; b->pos = pos; b->qual = 0; + s.s = b->str; s.m = b->m_str; s.l = 0; + kputc('\0', &s); + if (bc->ori_ref < 0) { // an indel + // write REF + kputc(ref[pos], &s); + for (j = 0; j < bca->indelreg; ++j) kputc(ref[pos+1+j], &s); + kputc('\0', &s); + // write ALT + kputc(ref[pos], &s); + for (i = 1; i < 4; ++i) { + if (bc->a[i] < 0) break; + if (i > 1) { + kputc(',', &s); kputc(ref[pos], &s); + } + if (bca->indel_types[bc->a[i]] < 0) { // deletion + for (j = -bca->indel_types[bc->a[i]]; j < bca->indelreg; ++j) + kputc(ref[pos+1+j], &s); + } else { // insertion; cannot be a reference unless a bug + char *inscns = &bca->inscns[bc->a[i] * bca->maxins]; + for (j = 0; j < bca->indel_types[bc->a[i]]; ++j) + kputc("ACGTN"[(int)inscns[j]], &s); + for (j = 0; j < bca->indelreg; ++j) kputc(ref[pos+1+j], &s); + } + } + kputc('\0', &s); + } else { // a SNP + kputc("ACGTN"[bc->ori_ref], &s); kputc('\0', &s); + for (i = 1; i < 5; ++i) { + if (bc->a[i] < 0) break; + if (i > 1) kputc(',', &s); + kputc(bc->unseen == i? 'X' : "ACGT"[bc->a[i]], &s); + } + kputc('\0', &s); + } + kputc('\0', &s); + // INFO + if (bc->ori_ref < 0) kputs("INDEL;", &s); + kputs("DP=", &s); kputw(bc->ori_depth, &s); kputs(";I16=", &s); + for (i = 0; i < 16; ++i) { + if (i) kputc(',', &s); + kputw(bc->anno[i], &s); + } + kputc('\0', &s); + // FMT + kputs("PL", &s); + if (bcr) { + kputs(":DP", &s); + if (is_SP) kputs(":SP", &s); + } + kputc('\0', &s); + b->m_str = s.m; b->str = s.s; b->l_str = s.l; + bcf_sync(b); + memcpy(b->gi[0].data, bc->PL, b->gi[0].len * bc->n); + if (bcr) { + uint16_t *dp = (uint16_t*)b->gi[1].data; + uint8_t *sp = is_SP? b->gi[2].data : 0; + for (i = 0; i < bc->n; ++i) { + bcf_callret1_t *p = bcr + i; + dp[i] = p->depth < 0xffff? p->depth : 0xffff; + if (is_SP) { + if (p->anno[0] + p->anno[1] < 2 || p->anno[2] + p->anno[3] < 2 + || p->anno[0] + p->anno[2] < 2 || p->anno[1] + p->anno[3] < 2) + { + sp[i] = 0; + } else { + double left, right, two; + int x; + kt_fisher_exact(p->anno[0], p->anno[1], p->anno[2], p->anno[3], &left, &right, &two); + x = (int)(-4.343 * log(two) + .499); + if (x > 255) x = 255; + sp[i] = x; + } + } + } + } + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam2bcf.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,55 @@ +#ifndef BAM2BCF_H +#define BAM2BCF_H + +#include <stdint.h> +#include "errmod.h" +#include "bcftools/bcf.h" + +#define B2B_INDEL_NULL 10000 + +typedef struct __bcf_callaux_t { + int capQ, min_baseQ; + int openQ, extQ, tandemQ; // for indels + int min_support; // for collecting indel candidates + double min_frac; // for collecting indel candidates + // for internal uses + int max_bases; + int indel_types[4]; + int maxins, indelreg; + char *inscns; + uint16_t *bases; + errmod_t *e; + void *rghash; +} bcf_callaux_t; + +typedef struct { + int depth, ori_depth, qsum[4]; + int anno[16]; + float p[25]; +} bcf_callret1_t; + +typedef struct { + int a[5]; // alleles: ref, alt, alt2, alt3 + int n, n_alleles, shift, ori_ref, unseen; + int anno[16], depth, ori_depth; + uint8_t *PL; +} bcf_call_t; + +#ifdef __cplusplus +extern "C" { +#endif + + bcf_callaux_t *bcf_call_init(double theta, int min_baseQ); + void bcf_call_destroy(bcf_callaux_t *bca); + int bcf_call_glfgen(int _n, const bam_pileup1_t *pl, int ref_base, bcf_callaux_t *bca, bcf_callret1_t *r); + int bcf_call_combine(int n, const bcf_callret1_t *calls, int ref_base /*4-bit*/, bcf_call_t *call); + int bcf_call2bcf(int tid, int pos, bcf_call_t *bc, bcf1_t *b, bcf_callret1_t *bcr, int is_SP, + const bcf_callaux_t *bca, const char *ref); + int bcf_call_gap_prep(int n, int *n_plp, bam_pileup1_t **plp, int pos, bcf_callaux_t *bca, const char *ref, + const void *rghash); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam2bcf_indel.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,469 @@ +#include <assert.h> +#include <ctype.h> +#include <string.h> +#include "bam.h" +#include "bam2bcf.h" +#include "ksort.h" +#include "kaln.h" +#include "kprobaln.h" +#include "khash.h" +KHASH_SET_INIT_STR(rg) + +#define MINUS_CONST 0x10000000 +#define INDEL_WINDOW_SIZE 50 + +void *bcf_call_add_rg(void *_hash, const char *hdtext, const char *list) +{ + const char *s, *p, *q, *r, *t; + khash_t(rg) *hash; + if (list == 0 || hdtext == 0) return _hash; + if (_hash == 0) _hash = kh_init(rg); + hash = (khash_t(rg)*)_hash; + if ((s = strstr(hdtext, "@RG\t")) == 0) return hash; + do { + t = strstr(s + 4, "@RG\t"); // the next @RG + if ((p = strstr(s, "\tID:")) != 0) p += 4; + if ((q = strstr(s, "\tPL:")) != 0) q += 4; + if (p && q && (t == 0 || (p < t && q < t))) { // ID and PL are both present + int lp, lq; + char *x; + for (r = p; *r && *r != '\t' && *r != '\n'; ++r); lp = r - p; + for (r = q; *r && *r != '\t' && *r != '\n'; ++r); lq = r - q; + x = calloc((lp > lq? lp : lq) + 1, 1); + for (r = q; *r && *r != '\t' && *r != '\n'; ++r) x[r-q] = *r; + if (strstr(list, x)) { // insert ID to the hash table + khint_t k; + int ret; + for (r = p; *r && *r != '\t' && *r != '\n'; ++r) x[r-p] = *r; + x[r-p] = 0; + k = kh_get(rg, hash, x); + if (k == kh_end(hash)) k = kh_put(rg, hash, x, &ret); + else free(x); + } else free(x); + } + s = t; + } while (s); + return hash; +} + +void bcf_call_del_rghash(void *_hash) +{ + khint_t k; + khash_t(rg) *hash = (khash_t(rg)*)_hash; + if (hash == 0) return; + for (k = kh_begin(hash); k < kh_end(hash); ++k) + if (kh_exist(hash, k)) + free((char*)kh_key(hash, k)); + kh_destroy(rg, hash); +} + +static int tpos2qpos(const bam1_core_t *c, const uint32_t *cigar, int32_t tpos, int is_left, int32_t *_tpos) +{ + int k, x = c->pos, y = 0, last_y = 0; + *_tpos = c->pos; + for (k = 0; k < c->n_cigar; ++k) { + int op = cigar[k] & BAM_CIGAR_MASK; + int l = cigar[k] >> BAM_CIGAR_SHIFT; + if (op == BAM_CMATCH) { + if (c->pos > tpos) return y; + if (x + l > tpos) { + *_tpos = tpos; + return y + (tpos - x); + } + x += l; y += l; + last_y = y; + } else if (op == BAM_CINS || op == BAM_CSOFT_CLIP) y += l; + else if (op == BAM_CDEL || op == BAM_CREF_SKIP) { + if (x + l > tpos) { + *_tpos = is_left? x : x + l; + return y; + } + x += l; + } + } + *_tpos = x; + return last_y; +} +// FIXME: check if the inserted sequence is consistent with the homopolymer run +// l is the relative gap length and l_run is the length of the homopolymer on the reference +static inline int est_seqQ(const bcf_callaux_t *bca, int l, int l_run) +{ + int q, qh; + q = bca->openQ + bca->extQ * (abs(l) - 1); + qh = l_run >= 3? (int)(bca->tandemQ * (double)abs(l) / l_run + .499) : 1000; + return q < qh? q : qh; +} + +static inline int est_indelreg(int pos, const char *ref, int l, char *ins4) +{ + int i, j, max = 0, max_i = pos, score = 0; + l = abs(l); + for (i = pos + 1, j = 0; ref[i]; ++i, ++j) { + if (ins4) score += (toupper(ref[i]) != "ACGTN"[(int)ins4[j%l]])? -10 : 1; + else score += (toupper(ref[i]) != toupper(ref[pos+1+j%l]))? -10 : 1; + if (score < 0) break; + if (max < score) max = score, max_i = i; + } + return max_i - pos; +} + +int bcf_call_gap_prep(int n, int *n_plp, bam_pileup1_t **plp, int pos, bcf_callaux_t *bca, const char *ref, + const void *rghash) +{ + extern void ks_introsort_uint32_t(int, uint32_t*); + int i, s, j, k, t, n_types, *types, max_rd_len, left, right, max_ins, *score1, *score2, max_ref2; + int N, K, l_run, ref_type, n_alt; + char *inscns = 0, *ref2, *query, **ref_sample; + khash_t(rg) *hash = (khash_t(rg)*)rghash; + if (ref == 0 || bca == 0) return -1; + // mark filtered reads + if (rghash) { + N = 0; + for (s = N = 0; s < n; ++s) { + for (i = 0; i < n_plp[s]; ++i) { + bam_pileup1_t *p = plp[s] + i; + const uint8_t *rg = bam_aux_get(p->b, "RG"); + p->aux = 1; // filtered by default + if (rg) { + khint_t k = kh_get(rg, hash, (const char*)(rg + 1)); + if (k != kh_end(hash)) p->aux = 0, ++N; // not filtered + } + } + } + if (N == 0) return -1; // no reads left + } + // determine if there is a gap + for (s = N = 0; s < n; ++s) { + for (i = 0; i < n_plp[s]; ++i) + if (plp[s][i].indel != 0) break; + if (i < n_plp[s]) break; + } + if (s == n) return -1; // there is no indel at this position. + for (s = N = 0; s < n; ++s) N += n_plp[s]; // N is the total number of reads + { // find out how many types of indels are present + int m, n_alt = 0, n_tot = 0; + uint32_t *aux; + aux = calloc(N + 1, 4); + m = max_rd_len = 0; + aux[m++] = MINUS_CONST; // zero indel is always a type + for (s = 0; s < n; ++s) { + for (i = 0; i < n_plp[s]; ++i) { + const bam_pileup1_t *p = plp[s] + i; + if (rghash == 0 || p->aux == 0) { + ++n_tot; + if (p->indel != 0) { + ++n_alt; + aux[m++] = MINUS_CONST + p->indel; + } + } + j = bam_cigar2qlen(&p->b->core, bam1_cigar(p->b)); + if (j > max_rd_len) max_rd_len = j; + } + } + ks_introsort(uint32_t, m, aux); + // squeeze out identical types + for (i = 1, n_types = 1; i < m; ++i) + if (aux[i] != aux[i-1]) ++n_types; + if (n_types == 1 || (double)n_alt / n_tot < bca->min_frac || n_alt < bca->min_support) { // then skip + free(aux); return -1; + } + types = (int*)calloc(n_types, sizeof(int)); + t = 0; + types[t++] = aux[0] - MINUS_CONST; + for (i = 1; i < m; ++i) + if (aux[i] != aux[i-1]) + types[t++] = aux[i] - MINUS_CONST; + free(aux); + for (t = 0; t < n_types; ++t) + if (types[t] == 0) break; + ref_type = t; // the index of the reference type (0) + assert(n_types < 64); + } + { // calculate left and right boundary + left = pos > INDEL_WINDOW_SIZE? pos - INDEL_WINDOW_SIZE : 0; + right = pos + INDEL_WINDOW_SIZE; + if (types[0] < 0) right -= types[0]; + // in case the alignments stand out the reference + for (i = pos; i < right; ++i) + if (ref[i] == 0) break; + right = i; + } + /* The following block fixes a long-existing flaw in the INDEL + * calling model: the interference of nearby SNPs. However, it also + * reduces the power because sometimes, substitutions caused by + * indels are not distinguishable from true mutations. Multiple + * sequence realignment helps to increase the power. + */ + { // construct per-sample consensus + int L = right - left + 1, max_i, max2_i; + uint32_t *cns, max, max2; + char *ref0, *r; + ref_sample = calloc(n, sizeof(void*)); + cns = calloc(L, 4); + ref0 = calloc(L, 1); + for (i = 0; i < right - left; ++i) + ref0[i] = bam_nt16_table[(int)ref[i+left]]; + for (s = 0; s < n; ++s) { + r = ref_sample[s] = calloc(L, 1); + memset(cns, 0, sizeof(int) * L); + // collect ref and non-ref counts + for (i = 0; i < n_plp[s]; ++i) { + bam_pileup1_t *p = plp[s] + i; + bam1_t *b = p->b; + uint32_t *cigar = bam1_cigar(b); + uint8_t *seq = bam1_seq(b); + int x = b->core.pos, y = 0; + for (k = 0; k < b->core.n_cigar; ++k) { + int op = cigar[k]&0xf; + int j, l = cigar[k]>>4; + if (op == BAM_CMATCH) { + for (j = 0; j < l; ++j) + if (x + j >= left && x + j < right) + cns[x+j-left] += (bam1_seqi(seq, y+j) == ref0[x+j-left])? 1 : 0x10000; + x += l; y += l; + } else if (op == BAM_CDEL || op == BAM_CREF_SKIP) x += l; + else if (op == BAM_CINS || op == BAM_CSOFT_CLIP) y += l; + } + } + // determine the consensus + for (i = 0; i < right - left; ++i) r[i] = ref0[i]; + max = max2 = 0; max_i = max2_i = -1; + for (i = 0; i < right - left; ++i) { + if (cns[i]>>16 >= max>>16) max2 = max, max2_i = max_i, max = cns[i], max_i = i; + else if (cns[i]>>16 >= max2>>16) max2 = cns[i], max2_i = i; + } + if ((double)(max&0xffff) / ((max&0xffff) + (max>>16)) >= 0.7) max_i = -1; + if ((double)(max2&0xffff) / ((max2&0xffff) + (max2>>16)) >= 0.7) max2_i = -1; + if (max_i >= 0) r[max_i] = 15; + if (max2_i >= 0) r[max2_i] = 15; +// for (i = 0; i < right - left; ++i) fputc("=ACMGRSVTWYHKDBN"[(int)r[i]], stderr); fputc('\n', stderr); + } + free(ref0); free(cns); + } + { // the length of the homopolymer run around the current position + int c = bam_nt16_table[(int)ref[pos + 1]]; + if (c == 15) l_run = 1; + else { + for (i = pos + 2; ref[i]; ++i) + if (bam_nt16_table[(int)ref[i]] != c) break; + l_run = i; + for (i = pos; i >= 0; --i) + if (bam_nt16_table[(int)ref[i]] != c) break; + l_run -= i + 1; + } + } + // construct the consensus sequence + max_ins = types[n_types - 1]; // max_ins is at least 0 + if (max_ins > 0) { + int *inscns_aux = calloc(4 * n_types * max_ins, sizeof(int)); + // count the number of occurrences of each base at each position for each type of insertion + for (t = 0; t < n_types; ++t) { + if (types[t] > 0) { + for (s = 0; s < n; ++s) { + for (i = 0; i < n_plp[s]; ++i) { + bam_pileup1_t *p = plp[s] + i; + if (p->indel == types[t]) { + uint8_t *seq = bam1_seq(p->b); + for (k = 1; k <= p->indel; ++k) { + int c = bam_nt16_nt4_table[bam1_seqi(seq, p->qpos + k)]; + if (c < 4) ++inscns_aux[(t*max_ins+(k-1))*4 + c]; + } + } + } + } + } + } + // use the majority rule to construct the consensus + inscns = calloc(n_types * max_ins, 1); + for (t = 0; t < n_types; ++t) { + for (j = 0; j < types[t]; ++j) { + int max = 0, max_k = -1, *ia = &inscns_aux[(t*max_ins+j)*4]; + for (k = 0; k < 4; ++k) + if (ia[k] > max) + max = ia[k], max_k = k; + inscns[t*max_ins + j] = max? max_k : 4; + } + } + free(inscns_aux); + } + // compute the likelihood given each type of indel for each read + max_ref2 = right - left + 2 + 2 * (max_ins > -types[0]? max_ins : -types[0]); + ref2 = calloc(max_ref2, 1); + query = calloc(right - left + max_rd_len + max_ins + 2, 1); + score1 = calloc(N * n_types, sizeof(int)); + score2 = calloc(N * n_types, sizeof(int)); + bca->indelreg = 0; + for (t = 0; t < n_types; ++t) { + int l, ir; + kpa_par_t apf1 = { 1e-4, 1e-2, 10 }, apf2 = { 1e-6, 1e-3, 10 }; + apf1.bw = apf2.bw = abs(types[t]) + 3; + // compute indelreg + if (types[t] == 0) ir = 0; + else if (types[t] > 0) ir = est_indelreg(pos, ref, types[t], &inscns[t*max_ins]); + else ir = est_indelreg(pos, ref, -types[t], 0); + if (ir > bca->indelreg) bca->indelreg = ir; +// fprintf(stderr, "%d, %d, %d\n", pos, types[t], ir); + // realignment + for (s = K = 0; s < n; ++s) { + // write ref2 + for (k = 0, j = left; j <= pos; ++j) + ref2[k++] = bam_nt16_nt4_table[(int)ref_sample[s][j-left]]; + if (types[t] <= 0) j += -types[t]; + else for (l = 0; l < types[t]; ++l) + ref2[k++] = inscns[t*max_ins + l]; + for (; j < right && ref[j]; ++j) + ref2[k++] = bam_nt16_nt4_table[(int)ref_sample[s][j-left]]; + for (; k < max_ref2; ++k) ref2[k] = 4; + if (j < right) right = j; + // align each read to ref2 + for (i = 0; i < n_plp[s]; ++i, ++K) { + bam_pileup1_t *p = plp[s] + i; + int qbeg, qend, tbeg, tend, sc, kk; + uint8_t *seq = bam1_seq(p->b); + uint32_t *cigar = bam1_cigar(p->b); + if (p->b->core.flag&4) continue; // unmapped reads + // FIXME: the following loop should be better moved outside; nonetheless, realignment should be much slower anyway. + for (kk = 0; kk < p->b->core.n_cigar; ++kk) + if ((cigar[kk]&BAM_CIGAR_MASK) == BAM_CREF_SKIP) break; + if (kk < p->b->core.n_cigar) continue; + // FIXME: the following skips soft clips, but using them may be more sensitive. + // determine the start and end of sequences for alignment + qbeg = tpos2qpos(&p->b->core, bam1_cigar(p->b), left, 0, &tbeg); + qend = tpos2qpos(&p->b->core, bam1_cigar(p->b), right, 1, &tend); + if (types[t] < 0) { + int l = -types[t]; + tbeg = tbeg - l > left? tbeg - l : left; + } + // write the query sequence + for (l = qbeg; l < qend; ++l) + query[l - qbeg] = bam_nt16_nt4_table[bam1_seqi(seq, l)]; + { // do realignment; this is the bottleneck + const uint8_t *qual = bam1_qual(p->b), *bq; + uint8_t *qq; + qq = calloc(qend - qbeg, 1); + bq = (uint8_t*)bam_aux_get(p->b, "ZQ"); + if (bq) ++bq; // skip type + for (l = qbeg; l < qend; ++l) { + qq[l - qbeg] = bq? qual[l] + (bq[l] - 64) : qual[l]; + if (qq[l - qbeg] > 30) qq[l - qbeg] = 30; + if (qq[l - qbeg] < 7) qq[l - qbeg] = 7; + } + sc = kpa_glocal((uint8_t*)ref2 + tbeg - left, tend - tbeg + abs(types[t]), + (uint8_t*)query, qend - qbeg, qq, &apf1, 0, 0); + l = (int)(100. * sc / (qend - qbeg) + .499); // used for adjusting indelQ below + if (l > 255) l = 255; + score1[K*n_types + t] = score2[K*n_types + t] = sc<<8 | l; + if (sc > 5) { + sc = kpa_glocal((uint8_t*)ref2 + tbeg - left, tend - tbeg + abs(types[t]), + (uint8_t*)query, qend - qbeg, qq, &apf2, 0, 0); + l = (int)(100. * sc / (qend - qbeg) + .499); + if (l > 255) l = 255; + score2[K*n_types + t] = sc<<8 | l; + } + free(qq); + } +/* + for (l = 0; l < tend - tbeg + abs(types[t]); ++l) + fputc("ACGTN"[(int)ref2[tbeg-left+l]], stderr); + fputc('\n', stderr); + for (l = 0; l < qend - qbeg; ++l) fputc("ACGTN"[(int)query[l]], stderr); + fputc('\n', stderr); + fprintf(stderr, "pos=%d type=%d read=%d:%d name=%s qbeg=%d tbeg=%d score=%d\n", pos, types[t], s, i, bam1_qname(p->b), qbeg, tbeg, sc); +*/ + } + } + } + free(ref2); free(query); + { // compute indelQ + int *sc, tmp, *sumq; + sc = alloca(n_types * sizeof(int)); + sumq = alloca(n_types * sizeof(int)); + memset(sumq, 0, sizeof(int) * n_types); + for (s = K = 0; s < n; ++s) { + for (i = 0; i < n_plp[s]; ++i, ++K) { + bam_pileup1_t *p = plp[s] + i; + int *sct = &score1[K*n_types], indelQ1, indelQ2, seqQ, indelQ; + for (t = 0; t < n_types; ++t) sc[t] = sct[t]<<6 | t; + for (t = 1; t < n_types; ++t) // insertion sort + for (j = t; j > 0 && sc[j] < sc[j-1]; --j) + tmp = sc[j], sc[j] = sc[j-1], sc[j-1] = tmp; + /* errmod_cal() assumes that if the call is wrong, the + * likelihoods of other events are equal. This is about + * right for substitutions, but is not desired for + * indels. To reuse errmod_cal(), I have to make + * compromise for multi-allelic indels. + */ + if ((sc[0]&0x3f) == ref_type) { + indelQ1 = (sc[1]>>14) - (sc[0]>>14); + seqQ = est_seqQ(bca, types[sc[1]&0x3f], l_run); + } else { + for (t = 0; t < n_types; ++t) // look for the reference type + if ((sc[t]&0x3f) == ref_type) break; + indelQ1 = (sc[t]>>14) - (sc[0]>>14); + seqQ = est_seqQ(bca, types[sc[0]&0x3f], l_run); + } + tmp = sc[0]>>6 & 0xff; + indelQ1 = tmp > 111? 0 : (int)((1. - tmp/111.) * indelQ1 + .499); // reduce indelQ + sct = &score2[K*n_types]; + for (t = 0; t < n_types; ++t) sc[t] = sct[t]<<6 | t; + for (t = 1; t < n_types; ++t) // insertion sort + for (j = t; j > 0 && sc[j] < sc[j-1]; --j) + tmp = sc[j], sc[j] = sc[j-1], sc[j-1] = tmp; + if ((sc[0]&0x3f) == ref_type) { + indelQ2 = (sc[1]>>14) - (sc[0]>>14); + } else { + for (t = 0; t < n_types; ++t) // look for the reference type + if ((sc[t]&0x3f) == ref_type) break; + indelQ2 = (sc[t]>>14) - (sc[0]>>14); + } + tmp = sc[0]>>6 & 0xff; + indelQ2 = tmp > 111? 0 : (int)((1. - tmp/111.) * indelQ2 + .499); + // pick the smaller between indelQ1 and indelQ2 + indelQ = indelQ1 < indelQ2? indelQ1 : indelQ2; + if (indelQ > 255) indelQ = 255; + if (seqQ > 255) seqQ = 255; + p->aux = (sc[0]&0x3f)<<16 | seqQ<<8 | indelQ; // use 22 bits in total + sumq[sc[0]&0x3f] += indelQ < seqQ? indelQ : seqQ; +// fprintf(stderr, "pos=%d read=%d:%d name=%s call=%d indelQ=%d seqQ=%d\n", pos, s, i, bam1_qname(p->b), types[sc[0]&0x3f], indelQ, seqQ); + } + } + // determine bca->indel_types[] and bca->inscns + bca->maxins = max_ins; + bca->inscns = realloc(bca->inscns, bca->maxins * 4); + for (t = 0; t < n_types; ++t) + sumq[t] = sumq[t]<<6 | t; + for (t = 1; t < n_types; ++t) // insertion sort + for (j = t; j > 0 && sumq[j] > sumq[j-1]; --j) + tmp = sumq[j], sumq[j] = sumq[j-1], sumq[j-1] = tmp; + for (t = 0; t < n_types; ++t) // look for the reference type + if ((sumq[t]&0x3f) == ref_type) break; + if (t) { // then move the reference type to the first + tmp = sumq[t]; + for (; t > 0; --t) sumq[t] = sumq[t-1]; + sumq[0] = tmp; + } + for (t = 0; t < 4; ++t) bca->indel_types[t] = B2B_INDEL_NULL; + for (t = 0; t < 4 && t < n_types; ++t) { + bca->indel_types[t] = types[sumq[t]&0x3f]; + memcpy(&bca->inscns[t * bca->maxins], &inscns[(sumq[t]&0x3f) * max_ins], bca->maxins); + } + // update p->aux + for (s = n_alt = 0; s < n; ++s) { + for (i = 0; i < n_plp[s]; ++i) { + bam_pileup1_t *p = plp[s] + i; + int x = types[p->aux>>16&0x3f]; + for (j = 0; j < 4; ++j) + if (x == bca->indel_types[j]) break; + p->aux = j<<16 | (j == 4? 0 : (p->aux&0xffff)); + if ((p->aux>>16&0x3f) > 0) ++n_alt; +// fprintf(stderr, "X pos=%d read=%d:%d name=%s call=%d type=%d q=%d seqQ=%d\n", pos, s, i, bam1_qname(p->b), p->aux>>16&63, bca->indel_types[p->aux>>16&63], p->aux&0xff, p->aux>>8&0xff); + } + } + } + free(score1); free(score2); + // free + for (i = 0; i < n; ++i) free(ref_sample[i]); + free(ref_sample); + free(types); free(inscns); + return n_alt > 0? 0 : -1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam2depth.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,112 @@ +/* This program demonstrates how to generate pileup from multiple BAMs + * simutaneously, to achieve random access and to use the BED interface. + * To compile this program separately, you may: + * + * gcc -g -O2 -Wall -o bam2depth -D_MAIN_BAM2DEPTH bam2depth.c -L. -lbam -lz + */ +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <unistd.h> +#include "bam.h" + +typedef struct { // auxiliary data structure + bamFile fp; // the file handler + bam_iter_t iter; // NULL if a region not specified + int min_mapQ; // mapQ filter +} aux_t; + +void *bed_read(const char *fn); // read a BED or position list file +void bed_destroy(void *_h); // destroy the BED data structure +int bed_overlap(const void *_h, const char *chr, int beg, int end); // test if chr:beg-end overlaps + +// This function reads a BAM alignment from one BAM file. +static int read_bam(void *data, bam1_t *b) // read level filters better go here to avoid pileup +{ + aux_t *aux = (aux_t*)data; // data in fact is a pointer to an auxiliary structure + int ret = aux->iter? bam_iter_read(aux->fp, aux->iter, b) : bam_read1(aux->fp, b); + if ((int)b->core.qual < aux->min_mapQ) b->core.flag |= BAM_FUNMAP; + return ret; +} + +#ifdef _MAIN_BAM2DEPTH +int main(int argc, char *argv[]) +#else +int main_depth(int argc, char *argv[]) +#endif +{ + int i, n, tid, beg, end, pos, *n_plp, baseQ = 0, mapQ = 0; + const bam_pileup1_t **plp; + char *reg = 0; // specified region + void *bed = 0; // BED data structure + bam_header_t *h = 0; // BAM header of the 1st input + aux_t **data; + bam_mplp_t mplp; + + // parse the command line + while ((n = getopt(argc, argv, "r:b:q:Q:")) >= 0) { + switch (n) { + case 'r': reg = strdup(optarg); break; // parsing a region requires a BAM header + case 'b': bed = bed_read(optarg); break; // BED or position list file can be parsed now + case 'q': baseQ = atoi(optarg); break; // base quality threshold + case 'Q': mapQ = atoi(optarg); break; // mapping quality threshold + } + } + if (optind == argc) { + fprintf(stderr, "Usage: bam2depth [-r reg] [-q baseQthres] [-Q mapQthres] [-b in.bed] <in1.bam> [...]\n"); + return 1; + } + + // initialize the auxiliary data structures + n = argc - optind; // the number of BAMs on the command line + data = calloc(n, sizeof(void*)); // data[i] for the i-th input + beg = 0; end = 1<<30; tid = -1; // set the default region + for (i = 0; i < n; ++i) { + bam_header_t *htmp; + data[i] = calloc(1, sizeof(aux_t)); + data[i]->fp = bam_open(argv[optind+i], "r"); // open BAM + data[i]->min_mapQ = mapQ; // set the mapQ filter + htmp = bam_header_read(data[i]->fp); // read the BAM header + if (i == 0) { + h = htmp; // keep the header of the 1st BAM + if (reg) bam_parse_region(h, reg, &tid, &beg, &end); // also parse the region + } else bam_header_destroy(htmp); // if not the 1st BAM, trash the header + if (tid >= 0) { // if a region is specified and parsed successfully + bam_index_t *idx = bam_index_load(argv[optind+i]); // load the index + data[i]->iter = bam_iter_query(idx, tid, beg, end); // set the iterator + bam_index_destroy(idx); // the index is not needed any more; phase out of the memory + } + } + + // the core multi-pileup loop + mplp = bam_mplp_init(n, read_bam, (void**)data); // initialization + n_plp = calloc(n, sizeof(int)); // n_plp[i] is the number of covering reads from the i-th BAM + plp = calloc(n, sizeof(void*)); // plp[i] points to the array of covering reads (internal in mplp) + while (bam_mplp_auto(mplp, &tid, &pos, n_plp, plp) > 0) { // come to the next covered position + if (pos < beg || pos >= end) continue; // out of range; skip + if (bed && bed_overlap(bed, h->target_name[tid], pos, pos + 1) == 0) continue; // not in BED; skip + fputs(h->target_name[tid], stdout); printf("\t%d", pos+1); // a customized printf() would be faster + for (i = 0; i < n; ++i) { // base level filters have to go here + int j, m = 0; + for (j = 0; j < n_plp[i]; ++j) { + const bam_pileup1_t *p = plp[i] + j; // DON'T modfity plp[][] unless you really know + if (p->is_del || p->is_refskip) ++m; // having dels or refskips at tid:pos + else if (bam1_qual(p->b)[p->qpos] < baseQ) ++m; // low base quality + } + printf("\t%d", n_plp[i] - m); // this the depth to output + } + putchar('\n'); + } + free(n_plp); free(plp); + bam_mplp_destroy(mplp); + + bam_header_destroy(h); + for (i = 0; i < n; ++i) { + bam_close(data[i]->fp); + if (data[i]->iter) bam_iter_destroy(data[i]->iter); + free(data[i]); + } + free(data); free(reg); + if (bed) bed_destroy(bed); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam_aux.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,187 @@ +#include <ctype.h> +#include "bam.h" +#include "khash.h" +typedef char *str_p; +KHASH_MAP_INIT_STR(s, int) +KHASH_MAP_INIT_STR(r2l, str_p) + +void bam_aux_append(bam1_t *b, const char tag[2], char type, int len, uint8_t *data) +{ + int ori_len = b->data_len; + b->data_len += 3 + len; + b->l_aux += 3 + len; + if (b->m_data < b->data_len) { + b->m_data = b->data_len; + kroundup32(b->m_data); + b->data = (uint8_t*)realloc(b->data, b->m_data); + } + b->data[ori_len] = tag[0]; b->data[ori_len + 1] = tag[1]; + b->data[ori_len + 2] = type; + memcpy(b->data + ori_len + 3, data, len); +} + +uint8_t *bam_aux_get_core(bam1_t *b, const char tag[2]) +{ + return bam_aux_get(b, tag); +} + +#define __skip_tag(s) do { \ + int type = toupper(*(s)); \ + ++(s); \ + if (type == 'Z' || type == 'H') { while (*(s)) ++(s); ++(s); } \ + else if (type == 'B') (s) += 5 + bam_aux_type2size(*(s)) * (*(int32_t*)((s)+1)); \ + else (s) += bam_aux_type2size(type); \ + } while(0) + +uint8_t *bam_aux_get(const bam1_t *b, const char tag[2]) +{ + uint8_t *s; + int y = tag[0]<<8 | tag[1]; + s = bam1_aux(b); + while (s < b->data + b->data_len) { + int x = (int)s[0]<<8 | s[1]; + s += 2; + if (x == y) return s; + __skip_tag(s); + } + return 0; +} +// s MUST BE returned by bam_aux_get() +int bam_aux_del(bam1_t *b, uint8_t *s) +{ + uint8_t *p, *aux; + aux = bam1_aux(b); + p = s - 2; + __skip_tag(s); + memmove(p, s, b->l_aux - (s - aux)); + b->data_len -= s - p; + b->l_aux -= s - p; + return 0; +} + +void bam_init_header_hash(bam_header_t *header) +{ + if (header->hash == 0) { + int ret, i; + khiter_t iter; + khash_t(s) *h; + header->hash = h = kh_init(s); + for (i = 0; i < header->n_targets; ++i) { + iter = kh_put(s, h, header->target_name[i], &ret); + kh_value(h, iter) = i; + } + } +} + +void bam_destroy_header_hash(bam_header_t *header) +{ + if (header->hash) + kh_destroy(s, (khash_t(s)*)header->hash); +} + +int32_t bam_get_tid(const bam_header_t *header, const char *seq_name) +{ + khint_t k; + khash_t(s) *h = (khash_t(s)*)header->hash; + k = kh_get(s, h, seq_name); + return k == kh_end(h)? -1 : kh_value(h, k); +} + +int bam_parse_region(bam_header_t *header, const char *str, int *ref_id, int *begin, int *end) +{ + char *s, *p; + int i, l, k; + khiter_t iter; + khash_t(s) *h; + + bam_init_header_hash(header); + h = (khash_t(s)*)header->hash; + + l = strlen(str); + p = s = (char*)malloc(l+1); + /* squeeze out "," */ + for (i = k = 0; i != l; ++i) + if (str[i] != ',' && !isspace(str[i])) s[k++] = str[i]; + s[k] = 0; + for (i = 0; i != k; ++i) if (s[i] == ':') break; + s[i] = 0; + iter = kh_get(s, h, s); /* get the ref_id */ + if (iter == kh_end(h)) { // name not found + *ref_id = -1; free(s); + return -1; + } + *ref_id = kh_value(h, iter); + if (i == k) { /* dump the whole sequence */ + *begin = 0; *end = 1<<29; free(s); + return 0; + } + for (p = s + i + 1; i != k; ++i) if (s[i] == '-') break; + *begin = atoi(p); + if (i < k) { + p = s + i + 1; + *end = atoi(p); + } else *end = 1<<29; + if (*begin > 0) --*begin; + free(s); + if (*begin > *end) { + fprintf(stderr, "[bam_parse_region] invalid region.\n"); + return -1; + } + return 0; +} + +int32_t bam_aux2i(const uint8_t *s) +{ + int type; + if (s == 0) return 0; + type = *s++; + if (type == 'c') return (int32_t)*(int8_t*)s; + else if (type == 'C') return (int32_t)*(uint8_t*)s; + else if (type == 's') return (int32_t)*(int16_t*)s; + else if (type == 'S') return (int32_t)*(uint16_t*)s; + else if (type == 'i' || type == 'I') return *(int32_t*)s; + else return 0; +} + +float bam_aux2f(const uint8_t *s) +{ + int type; + type = *s++; + if (s == 0) return 0.0; + if (type == 'f') return *(float*)s; + else return 0.0; +} + +double bam_aux2d(const uint8_t *s) +{ + int type; + type = *s++; + if (s == 0) return 0.0; + if (type == 'd') return *(double*)s; + else return 0.0; +} + +char bam_aux2A(const uint8_t *s) +{ + int type; + type = *s++; + if (s == 0) return 0; + if (type == 'A') return *(char*)s; + else return 0; +} + +char *bam_aux2Z(const uint8_t *s) +{ + int type; + type = *s++; + if (s == 0) return 0; + if (type == 'Z' || type == 'H') return (char*)s; + else return 0; +} + +#ifdef _WIN32 +double drand48() +{ + return (double)rand() / RAND_MAX; +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam_cat.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,184 @@ +/* + +bam_cat -- efficiently concatenates bam files + +bam_cat can be used to concatenate BAM files. Under special +circumstances, it can be used as an alternative to 'samtools merge' to +concatenate multiple sorted files into a single sorted file. For this +to work each file must be sorted, and the sorted files must be given +as command line arguments in order such that the final read in file i +is less than or equal to the first read in file i+1. + +This code is derived from the bam_reheader function in samtools 0.1.8 +and modified to perform concatenation by Chris Saunders on behalf of +Illumina. + + +########## License: + +The MIT License + +Original SAMtools work copyright (c) 2008-2009 Genome Research Ltd. +Modified SAMtools work copyright (c) 2010 Illumina, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + + +/* +makefile: +""" +CC=gcc +CFLAGS+=-g -Wall -O2 -D_FILE_OFFSET_BITS=64 -D_USE_KNETFILE -I$(SAMTOOLS_DIR) +LDFLAGS+=-L$(SAMTOOLS_DIR) +LDLIBS+=-lbam -lz + +all:bam_cat +""" +*/ + + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include "bgzf.h" +#include "bam.h" + +#define BUF_SIZE 0x10000 + +#define GZIPID1 31 +#define GZIPID2 139 + +#define BGZF_EMPTY_BLOCK_SIZE 28 + + +int bam_cat(int nfn, char * const *fn, const bam_header_t *h, const char* outbam) +{ + BGZF *fp; + FILE* fp_file; + uint8_t *buf; + uint8_t ebuf[BGZF_EMPTY_BLOCK_SIZE]; + const int es=BGZF_EMPTY_BLOCK_SIZE; + int i; + + fp = strcmp(outbam, "-")? bgzf_open(outbam, "w") : bgzf_fdopen(fileno(stdout), "w"); + if (fp == 0) { + fprintf(stderr, "[%s] ERROR: fail to open output file '%s'.\n", __func__, outbam); + return 1; + } + if (h) bam_header_write(fp, h); + + buf = (uint8_t*) malloc(BUF_SIZE); + for(i = 0; i < nfn; ++i){ + BGZF *in; + bam_header_t *old; + int len,j; + + in = strcmp(fn[i], "-")? bam_open(fn[i], "r") : bam_dopen(fileno(stdin), "r"); + if (in == 0) { + fprintf(stderr, "[%s] ERROR: fail to open file '%s'.\n", __func__, fn[i]); + return -1; + } + if (in->open_mode != 'r') return -1; + + old = bam_header_read(in); + if (h == 0 && i == 0) bam_header_write(fp, old); + + if (in->block_offset < in->block_length) { + bgzf_write(fp, in->uncompressed_block + in->block_offset, in->block_length - in->block_offset); + bgzf_flush(fp); + } + + j=0; +#ifdef _USE_KNETFILE + fp_file=fp->x.fpw; + while ((len = knet_read(in->x.fpr, buf, BUF_SIZE)) > 0) { +#else + fp_file=fp->file; + while (!feof(in->file) && (len = fread(buf, 1, BUF_SIZE, in->file)) > 0) { +#endif + if(len<es){ + int diff=es-len; + if(j==0) { + fprintf(stderr, "[%s] ERROR: truncated file?: '%s'.\n", __func__, fn[i]); + return -1; + } + fwrite(ebuf, 1, len, fp_file); + memcpy(ebuf,ebuf+len,diff); + memcpy(ebuf+diff,buf,len); + } else { + if(j!=0) fwrite(ebuf, 1, es, fp_file); + len-= es; + memcpy(ebuf,buf+len,es); + fwrite(buf, 1, len, fp_file); + } + j=1; + } + + /* check final gzip block */ + { + const uint8_t gzip1=ebuf[0]; + const uint8_t gzip2=ebuf[1]; + const uint32_t isize=*((uint32_t*)(ebuf+es-4)); + if(((gzip1!=GZIPID1) || (gzip2!=GZIPID2)) || (isize!=0)) { + fprintf(stderr, "[%s] WARNING: Unexpected block structure in file '%s'.", __func__, fn[i]); + fprintf(stderr, " Possible output corruption.\n"); + fwrite(ebuf, 1, es, fp_file); + } + } + bam_header_destroy(old); + bgzf_close(in); + } + free(buf); + bgzf_close(fp); + return 0; +} + + + +int main_cat(int argc, char *argv[]) +{ + bam_header_t *h = 0; + char *outfn = 0; + int c, ret; + while ((c = getopt(argc, argv, "h:o:")) >= 0) { + switch (c) { + case 'h': { + tamFile fph = sam_open(optarg); + if (fph == 0) { + fprintf(stderr, "[%s] ERROR: fail to read the header from '%s'.\n", __func__, argv[1]); + return 1; + } + h = sam_header_read(fph); + sam_close(fph); + break; + } + case 'o': outfn = strdup(optarg); break; + } + } + if (argc - optind < 2) { + fprintf(stderr, "Usage: samtools cat [-h header.sam] [-o out.bam] <in1.bam> <in2.bam> [...]\n"); + return 1; + } + ret = bam_cat(argc - optind, argv + optind, h, outfn? outfn : "-"); + free(outfn); + return ret; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam_color.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,127 @@ +#include <ctype.h> +#include "bam.h" + +/*! + @abstract Get the color encoding the previous and current base + @param b pointer to an alignment + @param i The i-th position, 0-based + @return color + + @discussion Returns 0 no color information is found. + */ +char bam_aux_getCSi(bam1_t *b, int i) +{ + uint8_t *c = bam_aux_get(b, "CS"); + char *cs = NULL; + + // return the base if the tag was not found + if(0 == c) return 0; + + cs = bam_aux2Z(c); + // adjust for strandedness and leading adaptor + if(bam1_strand(b)) i = strlen(cs) - 1 - i; + else i++; + return cs[i]; +} + +/*! + @abstract Get the color quality of the color encoding the previous and current base + @param b pointer to an alignment + @param i The i-th position, 0-based + @return color quality + + @discussion Returns 0 no color information is found. + */ +char bam_aux_getCQi(bam1_t *b, int i) +{ + uint8_t *c = bam_aux_get(b, "CQ"); + char *cq = NULL; + + // return the base if the tag was not found + if(0 == c) return 0; + + cq = bam_aux2Z(c); + // adjust for strandedness + if(bam1_strand(b)) i = strlen(cq) - 1 - i; + return cq[i]; +} + +char bam_aux_nt2int(char a) +{ + switch(toupper(a)) { + case 'A': + return 0; + break; + case 'C': + return 1; + break; + case 'G': + return 2; + break; + case 'T': + return 3; + break; + default: + return 4; + break; + } +} + +char bam_aux_ntnt2cs(char a, char b) +{ + a = bam_aux_nt2int(a); + b = bam_aux_nt2int(b); + if(4 == a || 4 == b) return '4'; + return "0123"[(int)(a ^ b)]; +} + +/*! + @abstract Get the color error profile at the give position + @param b pointer to an alignment + @return the original color if the color was an error, '-' (dash) otherwise + + @discussion Returns 0 no color information is found. + */ +char bam_aux_getCEi(bam1_t *b, int i) +{ + int cs_i; + uint8_t *c = bam_aux_get(b, "CS"); + char *cs = NULL; + char prev_b, cur_b; + char cur_color, cor_color; + + // return the base if the tag was not found + if(0 == c) return 0; + + cs = bam_aux2Z(c); + + // adjust for strandedness and leading adaptor + if(bam1_strand(b)) { //reverse strand + cs_i = strlen(cs) - 1 - i; + // get current color + cur_color = cs[cs_i]; + // get previous base. Note: must rc adaptor + prev_b = (cs_i == 1) ? "TGCAN"[(int)bam_aux_nt2int(cs[0])] : bam_nt16_rev_table[bam1_seqi(bam1_seq(b), i+1)]; + // get current base + cur_b = bam_nt16_rev_table[bam1_seqi(bam1_seq(b), i)]; + } + else { + cs_i=i+1; + // get current color + cur_color = cs[cs_i]; + // get previous base + prev_b = (0 == i) ? cs[0] : bam_nt16_rev_table[bam1_seqi(bam1_seq(b), i-1)]; + // get current base + cur_b = bam_nt16_rev_table[bam1_seqi(bam1_seq(b), i)]; + } + + // corrected color + cor_color = bam_aux_ntnt2cs(prev_b, cur_b); + + if(cur_color == cor_color) { + return '-'; + } + else { + return cur_color; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam_endian.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,42 @@ +#ifndef BAM_ENDIAN_H +#define BAM_ENDIAN_H + +#include <stdint.h> + +static inline int bam_is_big_endian() +{ + long one= 1; + return !(*((char *)(&one))); +} +static inline uint16_t bam_swap_endian_2(uint16_t v) +{ + return (uint16_t)(((v & 0x00FF00FFU) << 8) | ((v & 0xFF00FF00U) >> 8)); +} +static inline void *bam_swap_endian_2p(void *x) +{ + *(uint16_t*)x = bam_swap_endian_2(*(uint16_t*)x); + return x; +} +static inline uint32_t bam_swap_endian_4(uint32_t v) +{ + v = ((v & 0x0000FFFFU) << 16) | (v >> 16); + return ((v & 0x00FF00FFU) << 8) | ((v & 0xFF00FF00U) >> 8); +} +static inline void *bam_swap_endian_4p(void *x) +{ + *(uint32_t*)x = bam_swap_endian_4(*(uint32_t*)x); + return x; +} +static inline uint64_t bam_swap_endian_8(uint64_t v) +{ + v = ((v & 0x00000000FFFFFFFFLLU) << 32) | (v >> 32); + v = ((v & 0x0000FFFF0000FFFFLLU) << 16) | ((v & 0xFFFF0000FFFF0000LLU) >> 16); + return ((v & 0x00FF00FF00FF00FFLLU) << 8) | ((v & 0xFF00FF00FF00FF00LLU) >> 8); +} +static inline void *bam_swap_endian_8p(void *x) +{ + *(uint64_t*)x = bam_swap_endian_8(*(uint64_t*)x); + return x; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam_import.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,480 @@ +#include <zlib.h> +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <assert.h> +#ifdef _WIN32 +#include <fcntl.h> +#endif +#include "kstring.h" +#include "bam.h" +#include "sam_header.h" +#include "kseq.h" +#include "khash.h" + +KSTREAM_INIT(gzFile, gzread, 8192) +KHASH_MAP_INIT_STR(ref, uint64_t) + +void bam_init_header_hash(bam_header_t *header); +void bam_destroy_header_hash(bam_header_t *header); +int32_t bam_get_tid(const bam_header_t *header, const char *seq_name); + +unsigned char bam_nt16_table[256] = { + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 1, 2, 4, 8, 15,15,15,15, 15,15,15,15, 15, 0 /*=*/,15,15, + 15, 1,14, 2, 13,15,15, 4, 11,15,15,12, 15, 3,15,15, + 15,15, 5, 6, 8,15, 7, 9, 15,10,15,15, 15,15,15,15, + 15, 1,14, 2, 13,15,15, 4, 11,15,15,12, 15, 3,15,15, + 15,15, 5, 6, 8,15, 7, 9, 15,10,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, + 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15 +}; + +unsigned short bam_char2flag_table[256] = { + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + 0,BAM_FREAD1,BAM_FREAD2,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + BAM_FPROPER_PAIR,0,BAM_FMREVERSE,0, 0,BAM_FMUNMAP,0,0, 0,0,0,0, 0,0,0,0, + 0,0,0,0, BAM_FDUP,0,BAM_FQCFAIL,0, 0,0,0,0, 0,0,0,0, + BAM_FPAIRED,0,BAM_FREVERSE,BAM_FSECONDARY, 0,BAM_FUNMAP,0,0, 0,0,0,0, 0,0,0,0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 +}; + +char *bam_nt16_rev_table = "=ACMGRSVTWYHKDBN"; + +struct __tamFile_t { + gzFile fp; + kstream_t *ks; + kstring_t *str; + uint64_t n_lines; + int is_first; +}; + +char **__bam_get_lines(const char *fn, int *_n) // for bam_plcmd.c only +{ + char **list = 0, *s; + int n = 0, dret, m = 0; + gzFile fp = (strcmp(fn, "-") == 0)? gzdopen(fileno(stdin), "r") : gzopen(fn, "r"); + kstream_t *ks; + kstring_t *str; + str = (kstring_t*)calloc(1, sizeof(kstring_t)); + ks = ks_init(fp); + while (ks_getuntil(ks, '\n', str, &dret) > 0) { + if (n == m) { + m = m? m << 1 : 16; + list = (char**)realloc(list, m * sizeof(char*)); + } + if (str->s[str->l-1] == '\r') + str->s[--str->l] = '\0'; + s = list[n++] = (char*)calloc(str->l + 1, 1); + strcpy(s, str->s); + } + ks_destroy(ks); + gzclose(fp); + free(str->s); free(str); + *_n = n; + return list; +} + +static bam_header_t *hash2header(const kh_ref_t *hash) +{ + bam_header_t *header; + khiter_t k; + header = bam_header_init(); + header->n_targets = kh_size(hash); + header->target_name = (char**)calloc(kh_size(hash), sizeof(char*)); + header->target_len = (uint32_t*)calloc(kh_size(hash), 4); + for (k = kh_begin(hash); k != kh_end(hash); ++k) { + if (kh_exist(hash, k)) { + int i = (int)kh_value(hash, k); + header->target_name[i] = (char*)kh_key(hash, k); + header->target_len[i] = kh_value(hash, k)>>32; + } + } + bam_init_header_hash(header); + return header; +} +bam_header_t *sam_header_read2(const char *fn) +{ + bam_header_t *header; + int c, dret, ret, error = 0; + gzFile fp; + kstream_t *ks; + kstring_t *str; + kh_ref_t *hash; + khiter_t k; + if (fn == 0) return 0; + fp = (strcmp(fn, "-") == 0)? gzdopen(fileno(stdin), "r") : gzopen(fn, "r"); + if (fp == 0) return 0; + hash = kh_init(ref); + ks = ks_init(fp); + str = (kstring_t*)calloc(1, sizeof(kstring_t)); + while (ks_getuntil(ks, 0, str, &dret) > 0) { + char *s = strdup(str->s); + int len, i; + i = kh_size(hash); + ks_getuntil(ks, 0, str, &dret); + len = atoi(str->s); + k = kh_put(ref, hash, s, &ret); + if (ret == 0) { + fprintf(stderr, "[sam_header_read2] duplicated sequence name: %s\n", s); + error = 1; + } + kh_value(hash, k) = (uint64_t)len<<32 | i; + if (dret != '\n') + while ((c = ks_getc(ks)) != '\n' && c != -1); + } + ks_destroy(ks); + gzclose(fp); + free(str->s); free(str); + fprintf(stderr, "[sam_header_read2] %d sequences loaded.\n", kh_size(hash)); + if (error) return 0; + header = hash2header(hash); + kh_destroy(ref, hash); + return header; +} +static inline uint8_t *alloc_data(bam1_t *b, int size) +{ + if (b->m_data < size) { + b->m_data = size; + kroundup32(b->m_data); + b->data = (uint8_t*)realloc(b->data, b->m_data); + } + return b->data; +} +static inline void parse_error(int64_t n_lines, const char * __restrict msg) +{ + fprintf(stderr, "Parse error at line %lld: %s\n", (long long)n_lines, msg); + abort(); +} +static inline void append_text(bam_header_t *header, kstring_t *str) +{ + size_t x = header->l_text, y = header->l_text + str->l + 2; // 2 = 1 byte dret + 1 byte null + kroundup32(x); kroundup32(y); + if (x < y) + { + header->n_text = y; + header->text = (char*)realloc(header->text, y); + if ( !header->text ) + { + fprintf(stderr,"realloc failed to alloc %ld bytes\n", y); + abort(); + } + } + // Sanity check + if ( header->l_text+str->l+1 >= header->n_text ) + { + fprintf(stderr,"append_text FIXME: %ld>=%ld, x=%ld,y=%ld\n", header->l_text+str->l+1,header->n_text,x,y); + abort(); + } + strncpy(header->text + header->l_text, str->s, str->l+1); // we cannot use strcpy() here. + header->l_text += str->l + 1; + header->text[header->l_text] = 0; +} + +int sam_header_parse(bam_header_t *h) +{ + char **tmp; + int i; + free(h->target_len); free(h->target_name); + h->n_targets = 0; h->target_len = 0; h->target_name = 0; + if (h->l_text < 3) return 0; + if (h->dict == 0) h->dict = sam_header_parse2(h->text); + tmp = sam_header2list(h->dict, "SQ", "SN", &h->n_targets); + if (h->n_targets == 0) return 0; + h->target_name = calloc(h->n_targets, sizeof(void*)); + for (i = 0; i < h->n_targets; ++i) + h->target_name[i] = strdup(tmp[i]); + free(tmp); + tmp = sam_header2list(h->dict, "SQ", "LN", &h->n_targets); + h->target_len = calloc(h->n_targets, 4); + for (i = 0; i < h->n_targets; ++i) + h->target_len[i] = atoi(tmp[i]); + free(tmp); + return h->n_targets; +} + +bam_header_t *sam_header_read(tamFile fp) +{ + int ret, dret; + bam_header_t *header = bam_header_init(); + kstring_t *str = fp->str; + while ((ret = ks_getuntil(fp->ks, KS_SEP_TAB, str, &dret)) >= 0 && str->s[0] == '@') { // skip header + str->s[str->l] = dret; // note that str->s is NOT null terminated!! + append_text(header, str); + if (dret != '\n') { + ret = ks_getuntil(fp->ks, '\n', str, &dret); + str->s[str->l] = '\n'; // NOT null terminated!! + append_text(header, str); + } + ++fp->n_lines; + } + sam_header_parse(header); + bam_init_header_hash(header); + fp->is_first = 1; + return header; +} + +int sam_read1(tamFile fp, bam_header_t *header, bam1_t *b) +{ + int ret, doff, doff0, dret, z = 0; + bam1_core_t *c = &b->core; + kstring_t *str = fp->str; + kstream_t *ks = fp->ks; + + if (fp->is_first) { + fp->is_first = 0; + ret = str->l; + } else { + do { // special consideration for empty lines + ret = ks_getuntil(fp->ks, KS_SEP_TAB, str, &dret); + if (ret >= 0) z += str->l + 1; + } while (ret == 0); + } + if (ret < 0) return -1; + ++fp->n_lines; + doff = 0; + + { // name + c->l_qname = strlen(str->s) + 1; + memcpy(alloc_data(b, doff + c->l_qname) + doff, str->s, c->l_qname); + doff += c->l_qname; + } + { // flag + long flag; + char *s; + ret = ks_getuntil(ks, KS_SEP_TAB, str, &dret); z += str->l + 1; + flag = strtol((char*)str->s, &s, 0); + if (*s) { // not the end of the string + flag = 0; + for (s = str->s; *s; ++s) + flag |= bam_char2flag_table[(int)*s]; + } + c->flag = flag; + } + { // tid, pos, qual + ret = ks_getuntil(ks, KS_SEP_TAB, str, &dret); z += str->l + 1; c->tid = bam_get_tid(header, str->s); + if (c->tid < 0 && strcmp(str->s, "*")) { + if (header->n_targets == 0) { + fprintf(stderr, "[sam_read1] missing header? Abort!\n"); + exit(1); + } else fprintf(stderr, "[sam_read1] reference '%s' is recognized as '*'.\n", str->s); + } + ret = ks_getuntil(ks, KS_SEP_TAB, str, &dret); z += str->l + 1; c->pos = isdigit(str->s[0])? atoi(str->s) - 1 : -1; + ret = ks_getuntil(ks, KS_SEP_TAB, str, &dret); z += str->l + 1; c->qual = isdigit(str->s[0])? atoi(str->s) : 0; + if (ret < 0) return -2; + } + { // cigar + char *s, *t; + int i, op; + long x; + c->n_cigar = 0; + if (ks_getuntil(ks, KS_SEP_TAB, str, &dret) < 0) return -3; + z += str->l + 1; + if (str->s[0] != '*') { + for (s = str->s; *s; ++s) { + if (isalpha(*s)) ++c->n_cigar; + else if (!isdigit(*s)) parse_error(fp->n_lines, "invalid CIGAR character"); + } + b->data = alloc_data(b, doff + c->n_cigar * 4); + for (i = 0, s = str->s; i != c->n_cigar; ++i) { + x = strtol(s, &t, 10); + op = toupper(*t); + if (op == 'M' || op == '=' || op == 'X') op = BAM_CMATCH; + else if (op == 'I') op = BAM_CINS; + else if (op == 'D') op = BAM_CDEL; + else if (op == 'N') op = BAM_CREF_SKIP; + else if (op == 'S') op = BAM_CSOFT_CLIP; + else if (op == 'H') op = BAM_CHARD_CLIP; + else if (op == 'P') op = BAM_CPAD; + else parse_error(fp->n_lines, "invalid CIGAR operation"); + s = t + 1; + bam1_cigar(b)[i] = x << BAM_CIGAR_SHIFT | op; + } + if (*s) parse_error(fp->n_lines, "unmatched CIGAR operation"); + c->bin = bam_reg2bin(c->pos, bam_calend(c, bam1_cigar(b))); + doff += c->n_cigar * 4; + } else { + if (!(c->flag&BAM_FUNMAP)) { + fprintf(stderr, "Parse warning at line %lld: mapped sequence without CIGAR\n", (long long)fp->n_lines); + c->flag |= BAM_FUNMAP; + } + c->bin = bam_reg2bin(c->pos, c->pos + 1); + } + } + { // mtid, mpos, isize + ret = ks_getuntil(ks, KS_SEP_TAB, str, &dret); z += str->l + 1; + c->mtid = strcmp(str->s, "=")? bam_get_tid(header, str->s) : c->tid; + ret = ks_getuntil(ks, KS_SEP_TAB, str, &dret); z += str->l + 1; + c->mpos = isdigit(str->s[0])? atoi(str->s) - 1 : -1; + ret = ks_getuntil(ks, KS_SEP_TAB, str, &dret); z += str->l + 1; + c->isize = (str->s[0] == '-' || isdigit(str->s[0]))? atoi(str->s) : 0; + if (ret < 0) return -4; + } + { // seq and qual + int i; + uint8_t *p = 0; + if (ks_getuntil(ks, KS_SEP_TAB, str, &dret) < 0) return -5; // seq + z += str->l + 1; + if (strcmp(str->s, "*")) { + c->l_qseq = strlen(str->s); + if (c->n_cigar && c->l_qseq != (int32_t)bam_cigar2qlen(c, bam1_cigar(b))) + parse_error(fp->n_lines, "CIGAR and sequence length are inconsistent"); + p = (uint8_t*)alloc_data(b, doff + c->l_qseq + (c->l_qseq+1)/2) + doff; + memset(p, 0, (c->l_qseq+1)/2); + for (i = 0; i < c->l_qseq; ++i) + p[i/2] |= bam_nt16_table[(int)str->s[i]] << 4*(1-i%2); + } else c->l_qseq = 0; + if (ks_getuntil(ks, KS_SEP_TAB, str, &dret) < 0) return -6; // qual + z += str->l + 1; + if (strcmp(str->s, "*") && c->l_qseq != strlen(str->s)) + parse_error(fp->n_lines, "sequence and quality are inconsistent"); + p += (c->l_qseq+1)/2; + if (strcmp(str->s, "*") == 0) for (i = 0; i < c->l_qseq; ++i) p[i] = 0xff; + else for (i = 0; i < c->l_qseq; ++i) p[i] = str->s[i] - 33; + doff += c->l_qseq + (c->l_qseq+1)/2; + } + doff0 = doff; + if (dret != '\n' && dret != '\r') { // aux + while (ks_getuntil(ks, KS_SEP_TAB, str, &dret) >= 0) { + uint8_t *s, type, key[2]; + z += str->l + 1; + if (str->l < 6 || str->s[2] != ':' || str->s[4] != ':') + parse_error(fp->n_lines, "missing colon in auxiliary data"); + key[0] = str->s[0]; key[1] = str->s[1]; + type = str->s[3]; + s = alloc_data(b, doff + 3) + doff; + s[0] = key[0]; s[1] = key[1]; s += 2; doff += 2; + if (type == 'A' || type == 'a' || type == 'c' || type == 'C') { // c and C for backward compatibility + s = alloc_data(b, doff + 2) + doff; + *s++ = 'A'; *s = str->s[5]; + doff += 2; + } else if (type == 'I' || type == 'i') { + long long x; + s = alloc_data(b, doff + 5) + doff; + x = (long long)atoll(str->s + 5); + if (x < 0) { + if (x >= -127) { + *s++ = 'c'; *(int8_t*)s = (int8_t)x; + s += 1; doff += 2; + } else if (x >= -32767) { + *s++ = 's'; *(int16_t*)s = (int16_t)x; + s += 2; doff += 3; + } else { + *s++ = 'i'; *(int32_t*)s = (int32_t)x; + s += 4; doff += 5; + if (x < -2147483648ll) + fprintf(stderr, "Parse warning at line %lld: integer %lld is out of range.", + (long long)fp->n_lines, x); + } + } else { + if (x <= 255) { + *s++ = 'C'; *s++ = (uint8_t)x; + doff += 2; + } else if (x <= 65535) { + *s++ = 'S'; *(uint16_t*)s = (uint16_t)x; + s += 2; doff += 3; + } else { + *s++ = 'I'; *(uint32_t*)s = (uint32_t)x; + s += 4; doff += 5; + if (x > 4294967295ll) + fprintf(stderr, "Parse warning at line %lld: integer %lld is out of range.", + (long long)fp->n_lines, x); + } + } + } else if (type == 'f') { + s = alloc_data(b, doff + 5) + doff; + *s++ = 'f'; + *(float*)s = (float)atof(str->s + 5); + s += 4; doff += 5; + } else if (type == 'd') { + s = alloc_data(b, doff + 9) + doff; + *s++ = 'd'; + *(float*)s = (float)atof(str->s + 9); + s += 8; doff += 9; + } else if (type == 'Z' || type == 'H') { + int size = 1 + (str->l - 5) + 1; + if (type == 'H') { // check whether the hex string is valid + int i; + if ((str->l - 5) % 2 == 1) parse_error(fp->n_lines, "length of the hex string not even"); + for (i = 0; i < str->l - 5; ++i) { + int c = toupper(str->s[5 + i]); + if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'))) + parse_error(fp->n_lines, "invalid hex character"); + } + } + s = alloc_data(b, doff + size) + doff; + *s++ = type; + memcpy(s, str->s + 5, str->l - 5); + s[str->l - 5] = 0; + doff += size; + } else if (type == 'B') { + int32_t n = 0, Bsize, k = 0, size; + char *p; + if (str->l < 8) parse_error(fp->n_lines, "too few values in aux type B"); + Bsize = bam_aux_type2size(str->s[5]); // the size of each element + for (p = (char*)str->s + 6; *p; ++p) // count the number of elements in the array + if (*p == ',') ++n; + p = str->s + 7; // now p points to the first number in the array + size = 6 + Bsize * n; // total number of bytes allocated to this tag + s = alloc_data(b, doff + 6 * Bsize * n) + doff; // allocate memory + *s++ = 'B'; *s++ = str->s[5]; + memcpy(s, &n, 4); s += 4; // write the number of elements + if (str->s[5] == 'c') while (p < str->s + str->l) ((int8_t*)s)[k++] = (int8_t)strtol(p, &p, 0), ++p; + else if (str->s[5] == 'C') while (p < str->s + str->l) ((uint8_t*)s)[k++] = (uint8_t)strtol(p, &p, 0), ++p; + else if (str->s[5] == 's') while (p < str->s + str->l) ((int16_t*)s)[k++] = (int16_t)strtol(p, &p, 0), ++p; // FIXME: avoid unaligned memory + else if (str->s[5] == 'S') while (p < str->s + str->l) ((uint16_t*)s)[k++] = (uint16_t)strtol(p, &p, 0), ++p; + else if (str->s[5] == 'i') while (p < str->s + str->l) ((int32_t*)s)[k++] = (int32_t)strtol(p, &p, 0), ++p; + else if (str->s[5] == 'I') while (p < str->s + str->l) ((uint32_t*)s)[k++] = (uint32_t)strtol(p, &p, 0), ++p; + else if (str->s[5] == 'f') while (p < str->s + str->l) ((float*)s)[k++] = (float)strtof(p, &p), ++p; + else parse_error(fp->n_lines, "unrecognized array type"); + s += Bsize * n; doff += size; + } else parse_error(fp->n_lines, "unrecognized type"); + if (dret == '\n' || dret == '\r') break; + } + } + b->l_aux = doff - doff0; + b->data_len = doff; + return z; +} + +tamFile sam_open(const char *fn) +{ + tamFile fp; + gzFile gzfp = (strcmp(fn, "-") == 0)? gzdopen(fileno(stdin), "rb") : gzopen(fn, "rb"); + if (gzfp == 0) return 0; + fp = (tamFile)calloc(1, sizeof(struct __tamFile_t)); + fp->str = (kstring_t*)calloc(1, sizeof(kstring_t)); + fp->fp = gzfp; + fp->ks = ks_init(fp->fp); + return fp; +} + +void sam_close(tamFile fp) +{ + if (fp) { + ks_destroy(fp->ks); + gzclose(fp->fp); + free(fp->str->s); free(fp->str); + free(fp); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam_index.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,711 @@ +#include <ctype.h> +#include <assert.h> +#include "bam.h" +#include "khash.h" +#include "ksort.h" +#include "bam_endian.h" +#ifdef _USE_KNETFILE +#include "knetfile.h" +#endif + +/*! + @header + + Alignment indexing. Before indexing, BAM must be sorted based on the + leftmost coordinate of alignments. In indexing, BAM uses two indices: + a UCSC binning index and a simple linear index. The binning index is + efficient for alignments spanning long distance, while the auxiliary + linear index helps to reduce unnecessary seek calls especially for + short alignments. + + The UCSC binning scheme was suggested by Richard Durbin and Lincoln + Stein and is explained by Kent et al. (2002). In this scheme, each bin + represents a contiguous genomic region which can be fully contained in + another bin; each alignment is associated with a bin which represents + the smallest region containing the entire alignment. The binning + scheme is essentially another representation of R-tree. A distinct bin + uniquely corresponds to a distinct internal node in a R-tree. Bin A is + a child of Bin B if region A is contained in B. + + In BAM, each bin may span 2^29, 2^26, 2^23, 2^20, 2^17 or 2^14 bp. Bin + 0 spans a 512Mbp region, bins 1-8 span 64Mbp, 9-72 8Mbp, 73-584 1Mbp, + 585-4680 128Kbp and bins 4681-37449 span 16Kbp regions. If we want to + find the alignments overlapped with a region [rbeg,rend), we need to + calculate the list of bins that may be overlapped the region and test + the alignments in the bins to confirm the overlaps. If the specified + region is short, typically only a few alignments in six bins need to + be retrieved. The overlapping alignments can be quickly fetched. + + */ + +#define BAM_MIN_CHUNK_GAP 32768 +// 1<<14 is the size of minimum bin. +#define BAM_LIDX_SHIFT 14 + +#define BAM_MAX_BIN 37450 // =(8^6-1)/7+1 + +typedef struct { + uint64_t u, v; +} pair64_t; + +#define pair64_lt(a,b) ((a).u < (b).u) +KSORT_INIT(off, pair64_t, pair64_lt) + +typedef struct { + uint32_t m, n; + pair64_t *list; +} bam_binlist_t; + +typedef struct { + int32_t n, m; + uint64_t *offset; +} bam_lidx_t; + +KHASH_MAP_INIT_INT(i, bam_binlist_t) + +struct __bam_index_t { + int32_t n; + uint64_t n_no_coor; // unmapped reads without coordinate + khash_t(i) **index; + bam_lidx_t *index2; +}; + +// requirement: len <= LEN_MASK +static inline void insert_offset(khash_t(i) *h, int bin, uint64_t beg, uint64_t end) +{ + khint_t k; + bam_binlist_t *l; + int ret; + k = kh_put(i, h, bin, &ret); + l = &kh_value(h, k); + if (ret) { // not present + l->m = 1; l->n = 0; + l->list = (pair64_t*)calloc(l->m, 16); + } + if (l->n == l->m) { + l->m <<= 1; + l->list = (pair64_t*)realloc(l->list, l->m * 16); + } + l->list[l->n].u = beg; l->list[l->n++].v = end; +} + +static inline void insert_offset2(bam_lidx_t *index2, bam1_t *b, uint64_t offset) +{ + int i, beg, end; + beg = b->core.pos >> BAM_LIDX_SHIFT; + end = (bam_calend(&b->core, bam1_cigar(b)) - 1) >> BAM_LIDX_SHIFT; + if (index2->m < end + 1) { + int old_m = index2->m; + index2->m = end + 1; + kroundup32(index2->m); + index2->offset = (uint64_t*)realloc(index2->offset, index2->m * 8); + memset(index2->offset + old_m, 0, 8 * (index2->m - old_m)); + } + if (beg == end) { + if (index2->offset[beg] == 0) index2->offset[beg] = offset; + } else { + for (i = beg; i <= end; ++i) + if (index2->offset[i] == 0) index2->offset[i] = offset; + } + index2->n = end + 1; +} + +static void merge_chunks(bam_index_t *idx) +{ +#if defined(BAM_TRUE_OFFSET) || defined(BAM_VIRTUAL_OFFSET16) + khash_t(i) *index; + int i, l, m; + khint_t k; + for (i = 0; i < idx->n; ++i) { + index = idx->index[i]; + for (k = kh_begin(index); k != kh_end(index); ++k) { + bam_binlist_t *p; + if (!kh_exist(index, k) || kh_key(index, k) == BAM_MAX_BIN) continue; + p = &kh_value(index, k); + m = 0; + for (l = 1; l < p->n; ++l) { +#ifdef BAM_TRUE_OFFSET + if (p->list[m].v + BAM_MIN_CHUNK_GAP > p->list[l].u) p->list[m].v = p->list[l].v; +#else + if (p->list[m].v>>16 == p->list[l].u>>16) p->list[m].v = p->list[l].v; +#endif + else p->list[++m] = p->list[l]; + } // ~for(l) + p->n = m + 1; + } // ~for(k) + } // ~for(i) +#endif // defined(BAM_TRUE_OFFSET) || defined(BAM_BGZF) +} + +static void fill_missing(bam_index_t *idx) +{ + int i, j; + for (i = 0; i < idx->n; ++i) { + bam_lidx_t *idx2 = &idx->index2[i]; + for (j = 1; j < idx2->n; ++j) + if (idx2->offset[j] == 0) + idx2->offset[j] = idx2->offset[j-1]; + } +} + +bam_index_t *bam_index_core(bamFile fp) +{ + bam1_t *b; + bam_header_t *h; + int i, ret; + bam_index_t *idx; + uint32_t last_bin, save_bin; + int32_t last_coor, last_tid, save_tid; + bam1_core_t *c; + uint64_t save_off, last_off, n_mapped, n_unmapped, off_beg, off_end, n_no_coor; + + idx = (bam_index_t*)calloc(1, sizeof(bam_index_t)); + b = (bam1_t*)calloc(1, sizeof(bam1_t)); + h = bam_header_read(fp); + c = &b->core; + + idx->n = h->n_targets; + bam_header_destroy(h); + idx->index = (khash_t(i)**)calloc(idx->n, sizeof(void*)); + for (i = 0; i < idx->n; ++i) idx->index[i] = kh_init(i); + idx->index2 = (bam_lidx_t*)calloc(idx->n, sizeof(bam_lidx_t)); + + save_bin = save_tid = last_tid = last_bin = 0xffffffffu; + save_off = last_off = bam_tell(fp); last_coor = 0xffffffffu; + n_mapped = n_unmapped = n_no_coor = off_end = 0; + off_beg = off_end = bam_tell(fp); + while ((ret = bam_read1(fp, b)) >= 0) { + if (c->tid < 0) ++n_no_coor; + if (last_tid != c->tid) { // change of chromosomes + last_tid = c->tid; + last_bin = 0xffffffffu; + } else if (last_coor > c->pos) { + fprintf(stderr, "[bam_index_core] the alignment is not sorted (%s): %u > %u in %d-th chr\n", + bam1_qname(b), last_coor, c->pos, c->tid+1); + exit(1); + } + if (c->tid >= 0) insert_offset2(&idx->index2[b->core.tid], b, last_off); + if (c->bin != last_bin) { // then possibly write the binning index + if (save_bin != 0xffffffffu) // save_bin==0xffffffffu only happens to the first record + insert_offset(idx->index[save_tid], save_bin, save_off, last_off); + if (last_bin == 0xffffffffu && save_tid != 0xffffffffu) { // write the meta element + off_end = last_off; + insert_offset(idx->index[save_tid], BAM_MAX_BIN, off_beg, off_end); + insert_offset(idx->index[save_tid], BAM_MAX_BIN, n_mapped, n_unmapped); + n_mapped = n_unmapped = 0; + off_beg = off_end; + } + save_off = last_off; + save_bin = last_bin = c->bin; + save_tid = c->tid; + if (save_tid < 0) break; + } + if (bam_tell(fp) <= last_off) { + fprintf(stderr, "[bam_index_core] bug in BGZF/RAZF: %llx < %llx\n", + (unsigned long long)bam_tell(fp), (unsigned long long)last_off); + exit(1); + } + if (c->flag & BAM_FUNMAP) ++n_unmapped; + else ++n_mapped; + last_off = bam_tell(fp); + last_coor = b->core.pos; + } + if (save_tid >= 0) { + insert_offset(idx->index[save_tid], save_bin, save_off, bam_tell(fp)); + insert_offset(idx->index[save_tid], BAM_MAX_BIN, off_beg, bam_tell(fp)); + insert_offset(idx->index[save_tid], BAM_MAX_BIN, n_mapped, n_unmapped); + } + merge_chunks(idx); + fill_missing(idx); + if (ret >= 0) { + while ((ret = bam_read1(fp, b)) >= 0) { + ++n_no_coor; + if (c->tid >= 0 && n_no_coor) { + fprintf(stderr, "[bam_index_core] the alignment is not sorted: reads without coordinates prior to reads with coordinates.\n"); + exit(1); + } + } + } + if (ret < -1) fprintf(stderr, "[bam_index_core] truncated file? Continue anyway. (%d)\n", ret); + free(b->data); free(b); + idx->n_no_coor = n_no_coor; + return idx; +} + +void bam_index_destroy(bam_index_t *idx) +{ + khint_t k; + int i; + if (idx == 0) return; + for (i = 0; i < idx->n; ++i) { + khash_t(i) *index = idx->index[i]; + bam_lidx_t *index2 = idx->index2 + i; + for (k = kh_begin(index); k != kh_end(index); ++k) { + if (kh_exist(index, k)) + free(kh_value(index, k).list); + } + kh_destroy(i, index); + free(index2->offset); + } + free(idx->index); free(idx->index2); + free(idx); +} + +void bam_index_save(const bam_index_t *idx, FILE *fp) +{ + int32_t i, size; + khint_t k; + fwrite("BAI\1", 1, 4, fp); + if (bam_is_be) { + uint32_t x = idx->n; + fwrite(bam_swap_endian_4p(&x), 4, 1, fp); + } else fwrite(&idx->n, 4, 1, fp); + for (i = 0; i < idx->n; ++i) { + khash_t(i) *index = idx->index[i]; + bam_lidx_t *index2 = idx->index2 + i; + // write binning index + size = kh_size(index); + if (bam_is_be) { // big endian + uint32_t x = size; + fwrite(bam_swap_endian_4p(&x), 4, 1, fp); + } else fwrite(&size, 4, 1, fp); + for (k = kh_begin(index); k != kh_end(index); ++k) { + if (kh_exist(index, k)) { + bam_binlist_t *p = &kh_value(index, k); + if (bam_is_be) { // big endian + uint32_t x; + x = kh_key(index, k); fwrite(bam_swap_endian_4p(&x), 4, 1, fp); + x = p->n; fwrite(bam_swap_endian_4p(&x), 4, 1, fp); + for (x = 0; (int)x < p->n; ++x) { + bam_swap_endian_8p(&p->list[x].u); + bam_swap_endian_8p(&p->list[x].v); + } + fwrite(p->list, 16, p->n, fp); + for (x = 0; (int)x < p->n; ++x) { + bam_swap_endian_8p(&p->list[x].u); + bam_swap_endian_8p(&p->list[x].v); + } + } else { + fwrite(&kh_key(index, k), 4, 1, fp); + fwrite(&p->n, 4, 1, fp); + fwrite(p->list, 16, p->n, fp); + } + } + } + // write linear index (index2) + if (bam_is_be) { + int x = index2->n; + fwrite(bam_swap_endian_4p(&x), 4, 1, fp); + } else fwrite(&index2->n, 4, 1, fp); + if (bam_is_be) { // big endian + int x; + for (x = 0; (int)x < index2->n; ++x) + bam_swap_endian_8p(&index2->offset[x]); + fwrite(index2->offset, 8, index2->n, fp); + for (x = 0; (int)x < index2->n; ++x) + bam_swap_endian_8p(&index2->offset[x]); + } else fwrite(index2->offset, 8, index2->n, fp); + } + { // write the number of reads coor-less records. + uint64_t x = idx->n_no_coor; + if (bam_is_be) bam_swap_endian_8p(&x); + fwrite(&x, 8, 1, fp); + } + fflush(fp); +} + +static bam_index_t *bam_index_load_core(FILE *fp) +{ + int i; + char magic[4]; + bam_index_t *idx; + if (fp == 0) { + fprintf(stderr, "[bam_index_load_core] fail to load index.\n"); + return 0; + } + fread(magic, 1, 4, fp); + if (strncmp(magic, "BAI\1", 4)) { + fprintf(stderr, "[bam_index_load] wrong magic number.\n"); + fclose(fp); + return 0; + } + idx = (bam_index_t*)calloc(1, sizeof(bam_index_t)); + fread(&idx->n, 4, 1, fp); + if (bam_is_be) bam_swap_endian_4p(&idx->n); + idx->index = (khash_t(i)**)calloc(idx->n, sizeof(void*)); + idx->index2 = (bam_lidx_t*)calloc(idx->n, sizeof(bam_lidx_t)); + for (i = 0; i < idx->n; ++i) { + khash_t(i) *index; + bam_lidx_t *index2 = idx->index2 + i; + uint32_t key, size; + khint_t k; + int j, ret; + bam_binlist_t *p; + index = idx->index[i] = kh_init(i); + // load binning index + fread(&size, 4, 1, fp); + if (bam_is_be) bam_swap_endian_4p(&size); + for (j = 0; j < (int)size; ++j) { + fread(&key, 4, 1, fp); + if (bam_is_be) bam_swap_endian_4p(&key); + k = kh_put(i, index, key, &ret); + p = &kh_value(index, k); + fread(&p->n, 4, 1, fp); + if (bam_is_be) bam_swap_endian_4p(&p->n); + p->m = p->n; + p->list = (pair64_t*)malloc(p->m * 16); + fread(p->list, 16, p->n, fp); + if (bam_is_be) { + int x; + for (x = 0; x < p->n; ++x) { + bam_swap_endian_8p(&p->list[x].u); + bam_swap_endian_8p(&p->list[x].v); + } + } + } + // load linear index + fread(&index2->n, 4, 1, fp); + if (bam_is_be) bam_swap_endian_4p(&index2->n); + index2->m = index2->n; + index2->offset = (uint64_t*)calloc(index2->m, 8); + fread(index2->offset, index2->n, 8, fp); + if (bam_is_be) + for (j = 0; j < index2->n; ++j) bam_swap_endian_8p(&index2->offset[j]); + } + if (fread(&idx->n_no_coor, 8, 1, fp) == 0) idx->n_no_coor = 0; + if (bam_is_be) bam_swap_endian_8p(&idx->n_no_coor); + return idx; +} + +bam_index_t *bam_index_load_local(const char *_fn) +{ + FILE *fp; + char *fnidx, *fn; + + if (strstr(_fn, "ftp://") == _fn || strstr(_fn, "http://") == _fn) { + const char *p; + int l = strlen(_fn); + for (p = _fn + l - 1; p >= _fn; --p) + if (*p == '/') break; + fn = strdup(p + 1); + } else fn = strdup(_fn); + fnidx = (char*)calloc(strlen(fn) + 5, 1); + strcpy(fnidx, fn); strcat(fnidx, ".bai"); + fp = fopen(fnidx, "rb"); + if (fp == 0) { // try "{base}.bai" + char *s = strstr(fn, "bam"); + if (s == fn + strlen(fn) - 3) { + strcpy(fnidx, fn); + fnidx[strlen(fn)-1] = 'i'; + fp = fopen(fnidx, "rb"); + } + } + free(fnidx); free(fn); + if (fp) { + bam_index_t *idx = bam_index_load_core(fp); + fclose(fp); + return idx; + } else return 0; +} + +#ifdef _USE_KNETFILE +static void download_from_remote(const char *url) +{ + const int buf_size = 1 * 1024 * 1024; + char *fn; + FILE *fp; + uint8_t *buf; + knetFile *fp_remote; + int l; + if (strstr(url, "ftp://") != url && strstr(url, "http://") != url) return; + l = strlen(url); + for (fn = (char*)url + l - 1; fn >= url; --fn) + if (*fn == '/') break; + ++fn; // fn now points to the file name + fp_remote = knet_open(url, "r"); + if (fp_remote == 0) { + fprintf(stderr, "[download_from_remote] fail to open remote file.\n"); + return; + } + if ((fp = fopen(fn, "wb")) == 0) { + fprintf(stderr, "[download_from_remote] fail to create file in the working directory.\n"); + knet_close(fp_remote); + return; + } + buf = (uint8_t*)calloc(buf_size, 1); + while ((l = knet_read(fp_remote, buf, buf_size)) != 0) + fwrite(buf, 1, l, fp); + free(buf); + fclose(fp); + knet_close(fp_remote); +} +#else +static void download_from_remote(const char *url) +{ + return; +} +#endif + +bam_index_t *bam_index_load(const char *fn) +{ + bam_index_t *idx; + idx = bam_index_load_local(fn); + if (idx == 0 && (strstr(fn, "ftp://") == fn || strstr(fn, "http://") == fn)) { + char *fnidx = calloc(strlen(fn) + 5, 1); + strcat(strcpy(fnidx, fn), ".bai"); + fprintf(stderr, "[bam_index_load] attempting to download the remote index file.\n"); + download_from_remote(fnidx); + idx = bam_index_load_local(fn); + } + if (idx == 0) fprintf(stderr, "[bam_index_load] fail to load BAM index.\n"); + return idx; +} + +int bam_index_build2(const char *fn, const char *_fnidx) +{ + char *fnidx; + FILE *fpidx; + bamFile fp; + bam_index_t *idx; + if ((fp = bam_open(fn, "r")) == 0) { + fprintf(stderr, "[bam_index_build2] fail to open the BAM file.\n"); + return -1; + } + idx = bam_index_core(fp); + bam_close(fp); + if (_fnidx == 0) { + fnidx = (char*)calloc(strlen(fn) + 5, 1); + strcpy(fnidx, fn); strcat(fnidx, ".bai"); + } else fnidx = strdup(_fnidx); + fpidx = fopen(fnidx, "wb"); + if (fpidx == 0) { + fprintf(stderr, "[bam_index_build2] fail to create the index file.\n"); + free(fnidx); + return -1; + } + bam_index_save(idx, fpidx); + bam_index_destroy(idx); + fclose(fpidx); + free(fnidx); + return 0; +} + +int bam_index_build(const char *fn) +{ + return bam_index_build2(fn, 0); +} + +int bam_index(int argc, char *argv[]) +{ + if (argc < 2) { + fprintf(stderr, "Usage: samtools index <in.bam> [out.index]\n"); + return 1; + } + if (argc >= 3) bam_index_build2(argv[1], argv[2]); + else bam_index_build(argv[1]); + return 0; +} + +int bam_idxstats(int argc, char *argv[]) +{ + bam_index_t *idx; + bam_header_t *header; + bamFile fp; + int i; + if (argc < 2) { + fprintf(stderr, "Usage: samtools idxstats <in.bam>\n"); + return 1; + } + fp = bam_open(argv[1], "r"); + if (fp == 0) { fprintf(stderr, "[%s] fail to open BAM.\n", __func__); return 1; } + header = bam_header_read(fp); + bam_close(fp); + idx = bam_index_load(argv[1]); + if (idx == 0) { fprintf(stderr, "[%s] fail to load the index.\n", __func__); return 1; } + for (i = 0; i < idx->n; ++i) { + khint_t k; + khash_t(i) *h = idx->index[i]; + printf("%s\t%d", header->target_name[i], header->target_len[i]); + k = kh_get(i, h, BAM_MAX_BIN); + if (k != kh_end(h)) + printf("\t%llu\t%llu", (long long)kh_val(h, k).list[1].u, (long long)kh_val(h, k).list[1].v); + else printf("\t0\t0"); + putchar('\n'); + } + printf("*\t0\t0\t%llu\n", (long long)idx->n_no_coor); + bam_header_destroy(header); + bam_index_destroy(idx); + return 0; +} + +static inline int reg2bins(uint32_t beg, uint32_t end, uint16_t list[BAM_MAX_BIN]) +{ + int i = 0, k; + if (beg >= end) return 0; + if (end >= 1u<<29) end = 1u<<29; + --end; + list[i++] = 0; + for (k = 1 + (beg>>26); k <= 1 + (end>>26); ++k) list[i++] = k; + for (k = 9 + (beg>>23); k <= 9 + (end>>23); ++k) list[i++] = k; + for (k = 73 + (beg>>20); k <= 73 + (end>>20); ++k) list[i++] = k; + for (k = 585 + (beg>>17); k <= 585 + (end>>17); ++k) list[i++] = k; + for (k = 4681 + (beg>>14); k <= 4681 + (end>>14); ++k) list[i++] = k; + return i; +} + +static inline int is_overlap(uint32_t beg, uint32_t end, const bam1_t *b) +{ + uint32_t rbeg = b->core.pos; + uint32_t rend = b->core.n_cigar? bam_calend(&b->core, bam1_cigar(b)) : b->core.pos + 1; + return (rend > beg && rbeg < end); +} + +struct __bam_iter_t { + int from_first; // read from the first record; no random access + int tid, beg, end, n_off, i, finished; + uint64_t curr_off; + pair64_t *off; +}; + +// bam_fetch helper function retrieves +bam_iter_t bam_iter_query(const bam_index_t *idx, int tid, int beg, int end) +{ + uint16_t *bins; + int i, n_bins, n_off; + pair64_t *off; + khint_t k; + khash_t(i) *index; + uint64_t min_off; + bam_iter_t iter = 0; + + if (beg < 0) beg = 0; + if (end < beg) return 0; + // initialize iter + iter = calloc(1, sizeof(struct __bam_iter_t)); + iter->tid = tid, iter->beg = beg, iter->end = end; iter->i = -1; + // + bins = (uint16_t*)calloc(BAM_MAX_BIN, 2); + n_bins = reg2bins(beg, end, bins); + index = idx->index[tid]; + if (idx->index2[tid].n > 0) { + min_off = (beg>>BAM_LIDX_SHIFT >= idx->index2[tid].n)? idx->index2[tid].offset[idx->index2[tid].n-1] + : idx->index2[tid].offset[beg>>BAM_LIDX_SHIFT]; + if (min_off == 0) { // improvement for index files built by tabix prior to 0.1.4 + int n = beg>>BAM_LIDX_SHIFT; + if (n > idx->index2[tid].n) n = idx->index2[tid].n; + for (i = n - 1; i >= 0; --i) + if (idx->index2[tid].offset[i] != 0) break; + if (i >= 0) min_off = idx->index2[tid].offset[i]; + } + } else min_off = 0; // tabix 0.1.2 may produce such index files + for (i = n_off = 0; i < n_bins; ++i) { + if ((k = kh_get(i, index, bins[i])) != kh_end(index)) + n_off += kh_value(index, k).n; + } + if (n_off == 0) { + free(bins); return iter; + } + off = (pair64_t*)calloc(n_off, 16); + for (i = n_off = 0; i < n_bins; ++i) { + if ((k = kh_get(i, index, bins[i])) != kh_end(index)) { + int j; + bam_binlist_t *p = &kh_value(index, k); + for (j = 0; j < p->n; ++j) + if (p->list[j].v > min_off) off[n_off++] = p->list[j]; + } + } + free(bins); + if (n_off == 0) { + free(off); return iter; + } + { + bam1_t *b = (bam1_t*)calloc(1, sizeof(bam1_t)); + int l; + ks_introsort(off, n_off, off); + // resolve completely contained adjacent blocks + for (i = 1, l = 0; i < n_off; ++i) + if (off[l].v < off[i].v) + off[++l] = off[i]; + n_off = l + 1; + // resolve overlaps between adjacent blocks; this may happen due to the merge in indexing + for (i = 1; i < n_off; ++i) + if (off[i-1].v >= off[i].u) off[i-1].v = off[i].u; + { // merge adjacent blocks +#if defined(BAM_TRUE_OFFSET) || defined(BAM_VIRTUAL_OFFSET16) + for (i = 1, l = 0; i < n_off; ++i) { +#ifdef BAM_TRUE_OFFSET + if (off[l].v + BAM_MIN_CHUNK_GAP > off[i].u) off[l].v = off[i].v; +#else + if (off[l].v>>16 == off[i].u>>16) off[l].v = off[i].v; +#endif + else off[++l] = off[i]; + } + n_off = l + 1; +#endif + } + bam_destroy1(b); + } + iter->n_off = n_off; iter->off = off; + return iter; +} + +pair64_t *get_chunk_coordinates(const bam_index_t *idx, int tid, int beg, int end, int *cnt_off) +{ // for pysam compatibility + bam_iter_t iter; + pair64_t *off; + iter = bam_iter_query(idx, tid, beg, end); + off = iter->off; *cnt_off = iter->n_off; + free(iter); + return off; +} + +void bam_iter_destroy(bam_iter_t iter) +{ + if (iter) { free(iter->off); free(iter); } +} + +int bam_iter_read(bamFile fp, bam_iter_t iter, bam1_t *b) +{ + int ret; + if (iter && iter->finished) return -1; + if (iter == 0 || iter->from_first) { + ret = bam_read1(fp, b); + if (ret < 0 && iter) iter->finished = 1; + return ret; + } + if (iter->off == 0) return -1; + for (;;) { + if (iter->curr_off == 0 || iter->curr_off >= iter->off[iter->i].v) { // then jump to the next chunk + if (iter->i == iter->n_off - 1) { ret = -1; break; } // no more chunks + if (iter->i >= 0) assert(iter->curr_off == iter->off[iter->i].v); // otherwise bug + if (iter->i < 0 || iter->off[iter->i].v != iter->off[iter->i+1].u) { // not adjacent chunks; then seek + bam_seek(fp, iter->off[iter->i+1].u, SEEK_SET); + iter->curr_off = bam_tell(fp); + } + ++iter->i; + } + if ((ret = bam_read1(fp, b)) >= 0) { + iter->curr_off = bam_tell(fp); + if (b->core.tid != iter->tid || b->core.pos >= iter->end) { // no need to proceed + ret = bam_validate1(NULL, b)? -1 : -5; // determine whether end of region or error + break; + } + else if (is_overlap(iter->beg, iter->end, b)) return ret; + } else break; // end of file or error + } + iter->finished = 1; + return ret; +} + +int bam_fetch(bamFile fp, const bam_index_t *idx, int tid, int beg, int end, void *data, bam_fetch_f func) +{ + int ret; + bam_iter_t iter; + bam1_t *b; + b = bam_init1(); + iter = bam_iter_query(idx, tid, beg, end); + while ((ret = bam_iter_read(fp, iter, b)) >= 0) func(b, data); + bam_iter_destroy(iter); + bam_destroy1(b); + return (ret == -1)? 0 : ret; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam_lpileup.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,198 @@ +#include <stdlib.h> +#include <stdio.h> +#include <assert.h> +#include "bam.h" +#include "ksort.h" + +#define TV_GAP 2 + +typedef struct __freenode_t { + uint32_t level:28, cnt:4; + struct __freenode_t *next; +} freenode_t, *freenode_p; + +#define freenode_lt(a,b) ((a)->cnt < (b)->cnt || ((a)->cnt == (b)->cnt && (a)->level < (b)->level)) +KSORT_INIT(node, freenode_p, freenode_lt) + +/* Memory pool, similar to the one in bam_pileup.c */ +typedef struct { + int cnt, n, max; + freenode_t **buf; +} mempool_t; + +static mempool_t *mp_init() +{ + return (mempool_t*)calloc(1, sizeof(mempool_t)); +} +static void mp_destroy(mempool_t *mp) +{ + int k; + for (k = 0; k < mp->n; ++k) free(mp->buf[k]); + free(mp->buf); free(mp); +} +static inline freenode_t *mp_alloc(mempool_t *mp) +{ + ++mp->cnt; + if (mp->n == 0) return (freenode_t*)calloc(1, sizeof(freenode_t)); + else return mp->buf[--mp->n]; +} +static inline void mp_free(mempool_t *mp, freenode_t *p) +{ + --mp->cnt; p->next = 0; p->cnt = TV_GAP; + if (mp->n == mp->max) { + mp->max = mp->max? mp->max<<1 : 256; + mp->buf = (freenode_t**)realloc(mp->buf, sizeof(freenode_t*) * mp->max); + } + mp->buf[mp->n++] = p; +} + +/* core part */ +struct __bam_lplbuf_t { + int max, n_cur, n_pre; + int max_level, *cur_level, *pre_level; + mempool_t *mp; + freenode_t **aux, *head, *tail; + int n_nodes, m_aux; + bam_pileup_f func; + void *user_data; + bam_plbuf_t *plbuf; +}; + +void bam_lplbuf_reset(bam_lplbuf_t *buf) +{ + freenode_t *p, *q; + bam_plbuf_reset(buf->plbuf); + for (p = buf->head; p->next;) { + q = p->next; + mp_free(buf->mp, p); + p = q; + } + buf->head = buf->tail; + buf->max_level = 0; + buf->n_cur = buf->n_pre = 0; + buf->n_nodes = 0; +} + +static int tview_func(uint32_t tid, uint32_t pos, int n, const bam_pileup1_t *pl, void *data) +{ + bam_lplbuf_t *tv = (bam_lplbuf_t*)data; + freenode_t *p; + int i, l, max_level; + // allocate memory if necessary + if (tv->max < n) { // enlarge + tv->max = n; + kroundup32(tv->max); + tv->cur_level = (int*)realloc(tv->cur_level, sizeof(int) * tv->max); + tv->pre_level = (int*)realloc(tv->pre_level, sizeof(int) * tv->max); + } + tv->n_cur = n; + // update cnt + for (p = tv->head; p->next; p = p->next) + if (p->cnt > 0) --p->cnt; + // calculate cur_level[] + max_level = 0; + for (i = l = 0; i < n; ++i) { + const bam_pileup1_t *p = pl + i; + if (p->is_head) { + if (tv->head->next && tv->head->cnt == 0) { // then take a free slot + freenode_t *p = tv->head->next; + tv->cur_level[i] = tv->head->level; + mp_free(tv->mp, tv->head); + tv->head = p; + --tv->n_nodes; + } else tv->cur_level[i] = ++tv->max_level; + } else { + tv->cur_level[i] = tv->pre_level[l++]; + if (p->is_tail) { // then return a free slot + tv->tail->level = tv->cur_level[i]; + tv->tail->next = mp_alloc(tv->mp); + tv->tail = tv->tail->next; + ++tv->n_nodes; + } + } + if (tv->cur_level[i] > max_level) max_level = tv->cur_level[i]; + ((bam_pileup1_t*)p)->level = tv->cur_level[i]; + } + assert(l == tv->n_pre); + tv->func(tid, pos, n, pl, tv->user_data); + // sort the linked list + if (tv->n_nodes) { + freenode_t *q; + if (tv->n_nodes + 1 > tv->m_aux) { // enlarge + tv->m_aux = tv->n_nodes + 1; + kroundup32(tv->m_aux); + tv->aux = (freenode_t**)realloc(tv->aux, sizeof(void*) * tv->m_aux); + } + for (p = tv->head, i = l = 0; p->next;) { + if (p->level > max_level) { // then discard this entry + q = p->next; + mp_free(tv->mp, p); + p = q; + } else { + tv->aux[i++] = p; + p = p->next; + } + } + tv->aux[i] = tv->tail; // add a proper tail for the loop below + tv->n_nodes = i; + if (tv->n_nodes) { + ks_introsort(node, tv->n_nodes, tv->aux); + for (i = 0; i < tv->n_nodes; ++i) tv->aux[i]->next = tv->aux[i+1]; + tv->head = tv->aux[0]; + } else tv->head = tv->tail; + } + // clean up + tv->max_level = max_level; + memcpy(tv->pre_level, tv->cur_level, tv->n_cur * 4); + // squeeze out terminated levels + for (i = l = 0; i < n; ++i) { + const bam_pileup1_t *p = pl + i; + if (!p->is_tail) + tv->pre_level[l++] = tv->pre_level[i]; + } + tv->n_pre = l; +/* + fprintf(stderr, "%d\t", pos+1); + for (i = 0; i < n; ++i) { + const bam_pileup1_t *p = pl + i; + if (p->is_head) fprintf(stderr, "^"); + if (p->is_tail) fprintf(stderr, "$"); + fprintf(stderr, "%d,", p->level); + } + fprintf(stderr, "\n"); +*/ + return 0; +} + +bam_lplbuf_t *bam_lplbuf_init(bam_pileup_f func, void *data) +{ + bam_lplbuf_t *tv; + tv = (bam_lplbuf_t*)calloc(1, sizeof(bam_lplbuf_t)); + tv->mp = mp_init(); + tv->head = tv->tail = mp_alloc(tv->mp); + tv->func = func; + tv->user_data = data; + tv->plbuf = bam_plbuf_init(tview_func, tv); + return (bam_lplbuf_t*)tv; +} + +void bam_lplbuf_destroy(bam_lplbuf_t *tv) +{ + freenode_t *p, *q; + free(tv->cur_level); free(tv->pre_level); + bam_plbuf_destroy(tv->plbuf); + free(tv->aux); + for (p = tv->head; p->next;) { + q = p->next; + mp_free(tv->mp, p); p = q; + } + mp_free(tv->mp, p); + assert(tv->mp->cnt == 0); + mp_destroy(tv->mp); + free(tv); +} + +int bam_lplbuf_push(const bam1_t *b, bam_lplbuf_t *tv) +{ + return bam_plbuf_push(b, tv->plbuf); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam_maqcns.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,626 @@ +#include <math.h> +#include <assert.h> +#include "bam.h" +#include "bam_maqcns.h" +#include "ksort.h" +#include "errmod.h" +#include "kaln.h" +KSORT_INIT_GENERIC(uint32_t) + +#define INDEL_WINDOW_SIZE 50 +#define INDEL_EXT_DEP 0.9 + +typedef struct __bmc_aux_t { + int max; + uint32_t *info; + uint16_t *info16; + errmod_t *em; +} bmc_aux_t; + +typedef struct { + float esum[4], fsum[4]; + uint32_t c[4]; +} glf_call_aux_t; + +/* + P(<b1,b2>) = \theta \sum_{i=1}^{N-1} 1/i + P(D|<b1,b2>) = \sum_{k=1}^{N-1} p_k 1/2 [(k/N)^n_2(1-k/N)^n_1 + (k/N)^n1(1-k/N)^n_2] + p_k = 1/k / \sum_{i=1}^{N-1} 1/i + */ +static void cal_het(bam_maqcns_t *aa) +{ + int k, n1, n2; + double sum_harmo; // harmonic sum + double poly_rate; + + free(aa->lhet); + aa->lhet = (double*)calloc(256 * 256, sizeof(double)); + sum_harmo = 0.0; + for (k = 1; k <= aa->n_hap - 1; ++k) + sum_harmo += 1.0 / k; + for (n1 = 0; n1 < 256; ++n1) { + for (n2 = 0; n2 < 256; ++n2) { + long double sum = 0.0; + double lC = aa->errmod == BAM_ERRMOD_SOAP? 0 : lgamma(n1+n2+1) - lgamma(n1+1) - lgamma(n2+1); + for (k = 1; k <= aa->n_hap - 1; ++k) { + double pk = 1.0 / k / sum_harmo; + double log1 = log((double)k/aa->n_hap); + double log2 = log(1.0 - (double)k/aa->n_hap); + sum += pk * 0.5 * (expl(log1*n2) * expl(log2*n1) + expl(log1*n1) * expl(log2*n2)); + } + aa->lhet[n1<<8|n2] = lC + logl(sum); + } + } + poly_rate = aa->het_rate * sum_harmo; + aa->q_r = -4.343 * log(2.0 * poly_rate / (1.0 - poly_rate)); +} + +/** initialize the helper structure */ +static void cal_coef(bam_maqcns_t *aa) +{ + int k, n, q; + long double sum_a[257], b[256], q_c[256], tmp[256], fk2[256]; + double *lC; + + if (aa->errmod == BAM_ERRMOD_MAQ2) return; // no need to do the following + // aa->lhet will be allocated and initialized + free(aa->fk); free(aa->coef); + aa->coef = 0; + aa->fk = (double*)calloc(256, sizeof(double)); + aa->fk[0] = fk2[0] = 1.0; + for (n = 1; n != 256; ++n) { + aa->fk[n] = pow(aa->theta, n) * (1.0 - aa->eta) + aa->eta; + fk2[n] = aa->fk[n>>1]; // this is an approximation, assuming reads equally likely come from both strands + } + if (aa->errmod == BAM_ERRMOD_SOAP) return; + aa->coef = (double*)calloc(256*256*64, sizeof(double)); + lC = (double*)calloc(256 * 256, sizeof(double)); + for (n = 1; n != 256; ++n) + for (k = 1; k <= n; ++k) + lC[n<<8|k] = lgamma(n+1) - lgamma(k+1) - lgamma(n-k+1); + for (q = 1; q != 64; ++q) { + double e = pow(10.0, -q/10.0); + double le = log(e); + double le1 = log(1.0-e); + for (n = 1; n != 256; ++n) { + double *coef = aa->coef + (q<<16|n<<8); + sum_a[n+1] = 0.0; + for (k = n; k >= 0; --k) { // a_k = \sum_{i=k}^n C^n_k \epsilon^k (1-\epsilon)^{n-k} + sum_a[k] = sum_a[k+1] + expl(lC[n<<8|k] + k*le + (n-k)*le1); + b[k] = sum_a[k+1] / sum_a[k]; + if (b[k] > 0.99) b[k] = 0.99; + } + for (k = 0; k != n; ++k) // log(\bar\beta_{nk}(\bar\epsilon)^{f_k}) + q_c[k] = -4.343 * fk2[k] * logl(b[k] / e); + for (k = 1; k != n; ++k) q_c[k] += q_c[k-1]; // \prod_{i=0}^k c_i + for (k = 0; k <= n; ++k) { // powl() in 64-bit mode seems broken on my Mac OS X 10.4.9 + tmp[k] = -4.343 * logl(1.0 - expl(fk2[k] * logl(b[k]))); + coef[k] = (k? q_c[k-1] : 0) + tmp[k]; // this is the final c_{nk} + } + } + } + free(lC); +} + +bam_maqcns_t *bam_maqcns_init() +{ + bam_maqcns_t *bm; + bm = (bam_maqcns_t*)calloc(1, sizeof(bam_maqcns_t)); + bm->aux = (bmc_aux_t*)calloc(1, sizeof(bmc_aux_t)); + bm->het_rate = 0.001; + bm->theta = 0.83f; + bm->n_hap = 2; + bm->eta = 0.03; + bm->cap_mapQ = 60; + bm->min_baseQ = 13; + return bm; +} + +void bam_maqcns_prepare(bam_maqcns_t *bm) +{ + if (bm->errmod == BAM_ERRMOD_MAQ2) bm->aux->em = errmod_init(1. - bm->theta); + cal_coef(bm); cal_het(bm); +} + +void bam_maqcns_destroy(bam_maqcns_t *bm) +{ + if (bm == 0) return; + free(bm->lhet); free(bm->fk); free(bm->coef); free(bm->aux->info); free(bm->aux->info16); + if (bm->aux->em) errmod_destroy(bm->aux->em); + free(bm->aux); free(bm); +} + +glf1_t *bam_maqcns_glfgen(int _n, const bam_pileup1_t *pl, uint8_t ref_base, bam_maqcns_t *bm) +{ + glf_call_aux_t *b = 0; + int i, j, k, w[8], c, n; + glf1_t *g = (glf1_t*)calloc(1, sizeof(glf1_t)); + float p[16], min_p = 1e30; + uint64_t rms; + + g->ref_base = ref_base; + if (_n == 0) return g; + + // construct aux array + if (bm->aux->max < _n) { + bm->aux->max = _n; + kroundup32(bm->aux->max); + bm->aux->info = (uint32_t*)realloc(bm->aux->info, 4 * bm->aux->max); + bm->aux->info16 = (uint16_t*)realloc(bm->aux->info16, 2 * bm->aux->max); + } + for (i = n = 0, rms = 0; i < _n; ++i) { + const bam_pileup1_t *p = pl + i; + uint32_t q, x = 0, qq; + uint16_t y = 0; + if (p->is_del || p->is_refskip || (p->b->core.flag&BAM_FUNMAP)) continue; + q = (uint32_t)bam1_qual(p->b)[p->qpos]; + if (q < bm->min_baseQ) continue; + x |= (uint32_t)bam1_strand(p->b) << 18 | q << 8 | p->b->core.qual; + y |= bam1_strand(p->b)<<4; + if (p->b->core.qual < q) q = p->b->core.qual; + c = p->b->core.qual < bm->cap_mapQ? p->b->core.qual : bm->cap_mapQ; + rms += c * c; + x |= q << 24; + y |= q << 5; + qq = bam1_seqi(bam1_seq(p->b), p->qpos); + q = bam_nt16_nt4_table[qq? qq : ref_base]; + if (!p->is_del && !p->is_refskip && q < 4) x |= 1 << 21 | q << 16, y |= q; + bm->aux->info16[n] = y; + bm->aux->info[n++] = x; + } + rms = (uint8_t)(sqrt((double)rms / n) + .499); + if (bm->errmod == BAM_ERRMOD_MAQ2) { + errmod_cal(bm->aux->em, n, 4, bm->aux->info16, p); + goto goto_glf; + } + ks_introsort(uint32_t, n, bm->aux->info); + // generate esum and fsum + b = (glf_call_aux_t*)calloc(1, sizeof(glf_call_aux_t)); + for (k = 0; k != 8; ++k) w[k] = 0; + for (j = n - 1; j >= 0; --j) { // calculate esum and fsum + uint32_t info = bm->aux->info[j]; + if (info>>24 < 4 && (info>>8&0x3f) != 0) info = 4<<24 | (info&0xffffff); + k = info>>16&7; + if (info>>24 > 0) { + b->esum[k&3] += bm->fk[w[k]] * (info>>24); + b->fsum[k&3] += bm->fk[w[k]]; + if (w[k] < 0xff) ++w[k]; + ++b->c[k&3]; + } + } + // rescale ->c[] + for (j = c = 0; j != 4; ++j) c += b->c[j]; + if (c > 255) { + for (j = 0; j != 4; ++j) b->c[j] = (int)(254.0 * b->c[j] / c + 0.5); + for (j = c = 0; j != 4; ++j) c += b->c[j]; + } + if (bm->errmod == BAM_ERRMOD_MAQ) { + // generate likelihood + for (j = 0; j != 4; ++j) { + // homozygous + float tmp1, tmp3; + int tmp2, bar_e; + for (k = 0, tmp1 = tmp3 = 0.0, tmp2 = 0; k != 4; ++k) { + if (j == k) continue; + tmp1 += b->esum[k]; tmp2 += b->c[k]; tmp3 += b->fsum[k]; + } + if (tmp2) { + bar_e = (int)(tmp1 / tmp3 + 0.5); + if (bar_e < 4) bar_e = 4; // should not happen + if (bar_e > 63) bar_e = 63; + p[j<<2|j] = tmp1 + bm->coef[bar_e<<16|c<<8|tmp2]; + } else p[j<<2|j] = 0.0; // all the bases are j + // heterozygous + for (k = j + 1; k < 4; ++k) { + for (i = 0, tmp2 = 0, tmp1 = tmp3 = 0.0; i != 4; ++i) { + if (i == j || i == k) continue; + tmp1 += b->esum[i]; tmp2 += b->c[i]; tmp3 += b->fsum[i]; + } + if (tmp2) { + bar_e = (int)(tmp1 / tmp3 + 0.5); + if (bar_e < 4) bar_e = 4; + if (bar_e > 63) bar_e = 63; + p[j<<2|k] = p[k<<2|j] = -4.343 * bm->lhet[b->c[j]<<8|b->c[k]] + tmp1 + bm->coef[bar_e<<16|c<<8|tmp2]; + } else p[j<<2|k] = p[k<<2|j] = -4.343 * bm->lhet[b->c[j]<<8|b->c[k]]; // all the bases are either j or k + } + // + for (k = 0; k != 4; ++k) + if (p[j<<2|k] < 0.0) p[j<<2|k] = 0.0; + } + + { // fix p[k<<2|k] + float max1, max2, min1, min2; + int max_k, min_k; + max_k = min_k = -1; + max1 = max2 = -1.0; min1 = min2 = 1e30; + for (k = 0; k < 4; ++k) { + if (b->esum[k] > max1) { + max2 = max1; max1 = b->esum[k]; max_k = k; + } else if (b->esum[k] > max2) max2 = b->esum[k]; + } + for (k = 0; k < 4; ++k) { + if (p[k<<2|k] < min1) { + min2 = min1; min1 = p[k<<2|k]; min_k = k; + } else if (p[k<<2|k] < min2) min2 = p[k<<2|k]; + } + if (max1 > max2 && (min_k != max_k || min1 + 1.0 > min2)) + p[max_k<<2|max_k] = min1 > 1.0? min1 - 1.0 : 0.0; + } + } else if (bm->errmod == BAM_ERRMOD_SOAP) { // apply the SOAP model + // generate likelihood + for (j = 0; j != 4; ++j) { + float tmp; + // homozygous + for (k = 0, tmp = 0.0; k != 4; ++k) + if (j != k) tmp += b->esum[k]; + p[j<<2|j] = tmp; + // heterozygous + for (k = j + 1; k < 4; ++k) { + for (i = 0, tmp = 0.0; i != 4; ++i) + if (i != j && i != k) tmp += b->esum[i]; + p[j<<2|k] = p[k<<2|j] = -4.343 * bm->lhet[b->c[j]<<8|b->c[k]] + tmp; + } + } + } + +goto_glf: + // convert necessary information to glf1_t + g->ref_base = ref_base; g->max_mapQ = rms; + g->depth = n > 16777215? 16777215 : n; + for (j = 0; j != 4; ++j) + for (k = j; k < 4; ++k) + if (p[j<<2|k] < min_p) min_p = p[j<<2|k]; + g->min_lk = min_p > 255.0? 255 : (int)(min_p + 0.5); + for (j = c = 0; j != 4; ++j) + for (k = j; k < 4; ++k) + g->lk[c++] = p[j<<2|k]-min_p > 255.0? 255 : (int)(p[j<<2|k]-min_p + 0.5); + + free(b); + return g; +} + +uint32_t glf2cns(const glf1_t *g, int q_r) +{ + int i, j, k, p[10], ref4; + uint32_t x = 0; + ref4 = bam_nt16_nt4_table[g->ref_base]; + for (i = k = 0; i < 4; ++i) + for (j = i; j < 4; ++j) { + int prior = (i == ref4 && j == ref4? 0 : i == ref4 || j == ref4? q_r : q_r + 3); + p[k] = (g->lk[k] + prior)<<4 | i<<2 | j; + ++k; + } + for (i = 1; i < 10; ++i) // insertion sort + for (j = i; j > 0 && p[j] < p[j-1]; --j) + k = p[j], p[j] = p[j-1], p[j-1] = k; + x = (1u<<(p[0]&3) | 1u<<(p[0]>>2&3)) << 28; // the best genotype + x |= (uint32_t)g->max_mapQ << 16; // rms mapQ + x |= ((p[1]>>4) - (p[0]>>4) < 256? (p[1]>>4) - (p[0]>>4) : 255) << 8; // consensus Q + for (k = 0; k < 10; ++k) + if ((p[k]&0xf) == (ref4<<2|ref4)) break; + if (k == 10) k = 9; + x |= (p[k]>>4) - (p[0]>>4) < 256? (p[k]>>4) - (p[0]>>4) : 255; // snp Q + return x; +} + +uint32_t bam_maqcns_call(int n, const bam_pileup1_t *pl, bam_maqcns_t *bm) +{ + glf1_t *g; + uint32_t x; + if (n) { + g = bam_maqcns_glfgen(n, pl, 0xf, bm); + x = g->depth == 0? (0xfU<<28 | 0xfU<<24) : glf2cns(g, (int)(bm->q_r + 0.5)); + free(g); + } else x = 0xfU<<28 | 0xfU<<24; + return x; +} + +/************** *****************/ + +bam_maqindel_opt_t *bam_maqindel_opt_init() +{ + bam_maqindel_opt_t *mi = (bam_maqindel_opt_t*)calloc(1, sizeof(bam_maqindel_opt_t)); + mi->q_indel = 40; + mi->r_indel = 0.00015; + mi->r_snp = 0.001; + // + mi->mm_penalty = 3; + mi->indel_err = 4; + mi->ambi_thres = 10; + return mi; +} + +void bam_maqindel_ret_destroy(bam_maqindel_ret_t *mir) +{ + if (mir == 0) return; + free(mir->s[0]); free(mir->s[1]); free(mir); +} + +int bam_tpos2qpos(const bam1_core_t *c, const uint32_t *cigar, int32_t tpos, int is_left, int32_t *_tpos) +{ + int k, x = c->pos, y = 0, last_y = 0; + *_tpos = c->pos; + for (k = 0; k < c->n_cigar; ++k) { + int op = cigar[k] & BAM_CIGAR_MASK; + int l = cigar[k] >> BAM_CIGAR_SHIFT; + if (op == BAM_CMATCH) { + if (c->pos > tpos) return y; + if (x + l > tpos) { + *_tpos = tpos; + return y + (tpos - x); + } + x += l; y += l; + last_y = y; + } else if (op == BAM_CINS || op == BAM_CSOFT_CLIP) y += l; + else if (op == BAM_CDEL || op == BAM_CREF_SKIP) { + if (x + l > tpos) { + *_tpos = is_left? x : x + l; + return y; + } + x += l; + } + } + *_tpos = x; + return last_y; +} + +#define MINUS_CONST 0x10000000 + +bam_maqindel_ret_t *bam_maqindel(int n, int pos, const bam_maqindel_opt_t *mi, const bam_pileup1_t *pl, const char *ref, + int _n_types, int *_types) +{ + int i, j, n_types, *types, left, right, max_rd_len = 0; + bam_maqindel_ret_t *ret = 0; + // if there is no proposed indel, check if there is an indel from the alignment + if (_n_types == 0) { + for (i = 0; i < n; ++i) { + const bam_pileup1_t *p = pl + i; + if (!(p->b->core.flag&BAM_FUNMAP) && p->indel != 0) break; + } + if (i == n) return 0; // no indel + } + { // calculate how many types of indels are available (set n_types and types) + int m; + uint32_t *aux; + aux = (uint32_t*)calloc(n + _n_types + 1, 4); + m = 0; + aux[m++] = MINUS_CONST; // zero indel is always a type + for (i = 0; i < n; ++i) { + const bam_pileup1_t *p = pl + i; + if (!(p->b->core.flag&BAM_FUNMAP) && p->indel != 0) + aux[m++] = MINUS_CONST + p->indel; + j = bam_cigar2qlen(&p->b->core, bam1_cigar(p->b)); + if (j > max_rd_len) max_rd_len = j; + } + if (_n_types) // then also add this to aux[] + for (i = 0; i < _n_types; ++i) + if (_types[i]) aux[m++] = MINUS_CONST + _types[i]; + ks_introsort(uint32_t, m, aux); + // squeeze out identical types + for (i = 1, n_types = 1; i < m; ++i) + if (aux[i] != aux[i-1]) ++n_types; + types = (int*)calloc(n_types, sizeof(int)); + j = 0; + types[j++] = aux[0] - MINUS_CONST; + for (i = 1; i < m; ++i) { + if (aux[i] != aux[i-1]) + types[j++] = aux[i] - MINUS_CONST; + } + free(aux); + } + { // calculate left and right boundary + left = pos > INDEL_WINDOW_SIZE? pos - INDEL_WINDOW_SIZE : 0; + right = pos + INDEL_WINDOW_SIZE; + if (types[0] < 0) right -= types[0]; + // in case the alignments stand out the reference + for (i = pos; i < right; ++i) + if (ref[i] == 0) break; + right = i; + } + { // the core part + char *ref2, *rs, *inscns = 0; + int qr_snp, k, l, *score, *pscore, max_ins = types[n_types-1]; + qr_snp = (int)(-4.343 * log(mi->r_snp) + .499); + if (max_ins > 0) { // get the consensus of inserted sequences + int *inscns_aux = (int*)calloc(4 * n_types * max_ins, sizeof(int)); + // count occurrences + for (i = 0; i < n_types; ++i) { + if (types[i] <= 0) continue; // not insertion + for (j = 0; j < n; ++j) { + const bam_pileup1_t *p = pl + j; + if (!(p->b->core.flag&BAM_FUNMAP) && p->indel == types[i]) { + for (k = 1; k <= p->indel; ++k) { + int c = bam_nt16_nt4_table[bam1_seqi(bam1_seq(p->b), p->qpos + k)]; + if (c < 4) ++inscns_aux[i*max_ins*4 + (k-1)*4 + c]; + } + } + } + } + // construct the consensus of inserted sequence + inscns = (char*)calloc(n_types * max_ins, sizeof(char)); + for (i = 0; i < n_types; ++i) { + for (j = 0; j < types[i]; ++j) { + int max = 0, max_k = -1, *ia = inscns_aux + i*max_ins*4 + j*4; + for (k = 0; k < 4; ++k) { + if (ia[k] > max) { + max = ia[k]; + max_k = k; + } + } + inscns[i*max_ins + j] = max? 1<<max_k : 15; + } + } + free(inscns_aux); + } + // calculate score + ref2 = (char*)calloc(right - left + types[n_types-1] + 2, 1); + rs = (char*)calloc(right - left + max_rd_len + types[n_types-1] + 2, 1); + score = (int*)calloc(n_types * n, sizeof(int)); + pscore = (int*)calloc(n_types * n, sizeof(int)); + for (i = 0; i < n_types; ++i) { + ka_param_t ap = ka_param_blast; + ap.band_width = 2 * types[n_types - 1] + 2; + ap.gap_end_ext = 0; + // write ref2 + for (k = 0, j = left; j <= pos; ++j) + ref2[k++] = bam_nt16_nt4_table[bam_nt16_table[(int)ref[j]]]; + if (types[i] <= 0) j += -types[i]; + else for (l = 0; l < types[i]; ++l) + ref2[k++] = bam_nt16_nt4_table[(int)inscns[i*max_ins + l]]; + if (types[0] < 0) { // mask deleted sequences + int jj, tmp = types[i] >= 0? -types[0] : -types[0] + types[i]; + for (jj = 0; jj < tmp && j < right && ref[j]; ++jj, ++j) + ref2[k++] = 4; + } + for (; j < right && ref[j]; ++j) + ref2[k++] = bam_nt16_nt4_table[bam_nt16_table[(int)ref[j]]]; + if (j < right) right = j; + // calculate score for each read + for (j = 0; j < n; ++j) { + const bam_pileup1_t *p = pl + j; + int qbeg, qend, tbeg, tend; + if (p->b->core.flag & BAM_FUNMAP) continue; + qbeg = bam_tpos2qpos(&p->b->core, bam1_cigar(p->b), left, 0, &tbeg); + qend = bam_tpos2qpos(&p->b->core, bam1_cigar(p->b), right, 1, &tend); + assert(tbeg >= left); + for (l = qbeg; l < qend; ++l) + rs[l - qbeg] = bam_nt16_nt4_table[bam1_seqi(bam1_seq(p->b), l)]; + { + int x, y, n_acigar, ps; + uint32_t *acigar; + ps = 0; + if (tend - tbeg + types[i] <= 0) { + score[i*n+j] = -(1<<20); + pscore[i*n+j] = 1<<20; + continue; + } + acigar = ka_global_core((uint8_t*)ref2 + tbeg - left, tend - tbeg + types[i], (uint8_t*)rs, qend - qbeg, &ap, &score[i*n+j], &n_acigar); + x = tbeg - left; y = 0; + for (l = 0; l < n_acigar; ++l) { + int op = acigar[l]&0xf; + int len = acigar[l]>>4; + if (op == BAM_CMATCH) { + int k; + for (k = 0; k < len; ++k) + if (ref2[x+k] != rs[y+k] && ref2[x+k] < 4) + ps += bam1_qual(p->b)[y+k] < qr_snp? bam1_qual(p->b)[y+k] : qr_snp; + x += len; y += len; + } else if (op == BAM_CINS || op == BAM_CSOFT_CLIP) { + if (op == BAM_CINS && l > 0 && l < n_acigar - 1) ps += mi->q_indel * len; + y += len; + } else if (op == BAM_CDEL) { + if (l > 0 && l < n_acigar - 1) ps += mi->q_indel * len; + x += len; + } + } + pscore[i*n+j] = ps; + /*if (1) { // for debugging only + fprintf(stderr, "id=%d, pos=%d, type=%d, j=%d, score=%d, psore=%d, %d, %d, %d, %d, %d, ", + j, pos+1, types[i], j, score[i*n+j], pscore[i*n+j], tbeg, tend, qbeg, qend, mi->q_indel); + for (l = 0; l < n_acigar; ++l) fprintf(stderr, "%d%c", acigar[l]>>4, "MIDS"[acigar[l]&0xf]); + fprintf(stderr, "\n"); + for (l = 0; l < tend - tbeg + types[i]; ++l) fputc("ACGTN"[ref2[l+tbeg-left]], stderr); + fputc('\n', stderr); + for (l = 0; l < qend - qbeg; ++l) fputc("ACGTN"[rs[l]], stderr); + fputc('\n', stderr); + }*/ + free(acigar); + } + } + } + { // get final result + int *sum, max1, max2, max1_i, max2_i; + // pick up the best two score + sum = (int*)calloc(n_types, sizeof(int)); + for (i = 0; i < n_types; ++i) + for (j = 0; j < n; ++j) + sum[i] += -pscore[i*n+j]; + max1 = max2 = -0x7fffffff; max1_i = max2_i = -1; + for (i = 0; i < n_types; ++i) { + if (sum[i] > max1) { + max2 = max1; max2_i = max1_i; max1 = sum[i]; max1_i = i; + } else if (sum[i] > max2) { + max2 = sum[i]; max2_i = i; + } + } + free(sum); + // write ret + ret = (bam_maqindel_ret_t*)calloc(1, sizeof(bam_maqindel_ret_t)); + ret->indel1 = types[max1_i]; ret->indel2 = types[max2_i]; + ret->s[0] = (char*)calloc(abs(ret->indel1) + 2, 1); + ret->s[1] = (char*)calloc(abs(ret->indel2) + 2, 1); + // write indel sequence + if (ret->indel1 > 0) { + ret->s[0][0] = '+'; + for (k = 0; k < ret->indel1; ++k) + ret->s[0][k+1] = bam_nt16_rev_table[(int)inscns[max1_i*max_ins + k]]; + } else if (ret->indel1 < 0) { + ret->s[0][0] = '-'; + for (k = 0; k < -ret->indel1 && ref[pos + k + 1]; ++k) + ret->s[0][k+1] = ref[pos + k + 1]; + } else ret->s[0][0] = '*'; + if (ret->indel2 > 0) { + ret->s[1][0] = '+'; + for (k = 0; k < ret->indel2; ++k) + ret->s[1][k+1] = bam_nt16_rev_table[(int)inscns[max2_i*max_ins + k]]; + } else if (ret->indel2 < 0) { + ret->s[1][0] = '-'; + for (k = 0; k < -ret->indel2 && ref[pos + k + 1]; ++k) + ret->s[1][k+1] = ref[pos + k + 1]; + } else ret->s[1][0] = '*'; + // write count + for (i = 0; i < n; ++i) { + const bam_pileup1_t *p = pl + i; + if (p->indel == ret->indel1) ++ret->cnt1; + else if (p->indel == ret->indel2) ++ret->cnt2; + else ++ret->cnt_anti; + } + { // write gl[] + int tmp, seq_err = 0; + double x = 1.0; + tmp = max1_i - max2_i; + if (tmp < 0) tmp = -tmp; + for (j = 0; j < tmp + 1; ++j) x *= INDEL_EXT_DEP; + seq_err = mi->q_indel * (1.0 - x) / (1.0 - INDEL_EXT_DEP); + ret->gl[0] = ret->gl[1] = 0; + for (j = 0; j < n; ++j) { + int s1 = pscore[max1_i*n + j], s2 = pscore[max2_i*n + j]; + //fprintf(stderr, "id=%d, %d, %d, %d, %d, %d\n", j, pl[j].b->core.pos+1, types[max1_i], types[max2_i], s1, s2); + if (s1 > s2) ret->gl[0] += s1 - s2 < seq_err? s1 - s2 : seq_err; + else ret->gl[1] += s2 - s1 < seq_err? s2 - s1 : seq_err; + } + } + // write cnt_ref and cnt_ambi + if (max1_i != 0 && max2_i != 0) { + for (j = 0; j < n; ++j) { + int diff1 = score[j] - score[max1_i * n + j]; + int diff2 = score[j] - score[max2_i * n + j]; + if (diff1 > 0 && diff2 > 0) ++ret->cnt_ref; + else if (diff1 == 0 || diff2 == 0) ++ret->cnt_ambi; + } + } + } + free(score); free(pscore); free(ref2); free(rs); free(inscns); + } + { // call genotype + int q[3], qr_indel = (int)(-4.343 * log(mi->r_indel) + 0.5); + int min1, min2, min1_i; + q[0] = ret->gl[0] + (ret->s[0][0] != '*'? 0 : 0) * qr_indel; + q[1] = ret->gl[1] + (ret->s[1][0] != '*'? 0 : 0) * qr_indel; + q[2] = n * 3 + (ret->s[0][0] == '*' || ret->s[1][0] == '*'? 1 : 1) * qr_indel; + min1 = min2 = 0x7fffffff; min1_i = -1; + for (i = 0; i < 3; ++i) { + if (q[i] < min1) { + min2 = min1; min1 = q[i]; min1_i = i; + } else if (q[i] < min2) min2 = q[i]; + } + ret->gt = min1_i; + ret->q_cns = min2 - min1; + // set q_ref + if (ret->gt < 2) ret->q_ref = (ret->s[ret->gt][0] == '*')? 0 : q[1-ret->gt] - q[ret->gt] - qr_indel - 3; + else ret->q_ref = (ret->s[0][0] == '*')? q[0] - q[2] : q[1] - q[2]; + if (ret->q_ref < 0) ret->q_ref = 0; + } + free(types); + return ret; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam_maqcns.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,61 @@ +#ifndef BAM_MAQCNS_H +#define BAM_MAQCNS_H + +#include "glf.h" + +#define BAM_ERRMOD_MAQ2 0 +#define BAM_ERRMOD_MAQ 1 +#define BAM_ERRMOD_SOAP 2 + +struct __bmc_aux_t; + +typedef struct { + float het_rate, theta; + int n_hap, cap_mapQ, errmod, min_baseQ; + + float eta, q_r; + double *fk, *coef; + double *lhet; + struct __bmc_aux_t *aux; +} bam_maqcns_t; + +typedef struct { + int q_indel; // indel sequencing error, phred scaled + float r_indel; // indel prior + float r_snp; // snp prior + // hidden parameters, unchangeable from command line + int mm_penalty, indel_err, ambi_thres; +} bam_maqindel_opt_t; + +typedef struct { + int indel1, indel2; + int cnt1, cnt2, cnt_anti; + int cnt_ref, cnt_ambi; + char *s[2]; + // + int gt, gl[2]; + int q_cns, q_ref; +} bam_maqindel_ret_t; + +#ifdef __cplusplus +extern "C" { +#endif + + bam_maqcns_t *bam_maqcns_init(); + void bam_maqcns_prepare(bam_maqcns_t *bm); + void bam_maqcns_destroy(bam_maqcns_t *bm); + glf1_t *bam_maqcns_glfgen(int n, const bam_pileup1_t *pl, uint8_t ref_base, bam_maqcns_t *bm); + uint32_t bam_maqcns_call(int n, const bam_pileup1_t *pl, bam_maqcns_t *bm); + // return: cns<<28 | cns2<<24 | mapQ<<16 | cnsQ<<8 | cnsQ2 + uint32_t glf2cns(const glf1_t *g, int q_r); + + bam_maqindel_opt_t *bam_maqindel_opt_init(); + bam_maqindel_ret_t *bam_maqindel(int n, int pos, const bam_maqindel_opt_t *mi, const bam_pileup1_t *pl, const char *ref, + int _n_types, int *_types); + void bam_maqindel_ret_destroy(bam_maqindel_ret_t*); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam_mate.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,70 @@ +#include <stdlib.h> +#include <string.h> +#include "bam.h" + +// currently, this function ONLY works if each read has one hit +void bam_mating_core(bamFile in, bamFile out) +{ + bam_header_t *header; + bam1_t *b[2]; + int curr, has_prev; + + header = bam_header_read(in); + bam_header_write(out, header); + + b[0] = bam_init1(); + b[1] = bam_init1(); + curr = 0; has_prev = 0; + while (bam_read1(in, b[curr]) >= 0) { + bam1_t *cur = b[curr], *pre = b[1-curr]; + if (has_prev) { + if (strcmp(bam1_qname(cur), bam1_qname(pre)) == 0) { // identical pair name + cur->core.mtid = pre->core.tid; cur->core.mpos = pre->core.pos; + pre->core.mtid = cur->core.tid; pre->core.mpos = cur->core.pos; + if (pre->core.tid == cur->core.tid && !(cur->core.flag&(BAM_FUNMAP|BAM_FMUNMAP)) + && !(pre->core.flag&(BAM_FUNMAP|BAM_FMUNMAP))) + { + uint32_t cur5, pre5; + cur5 = (cur->core.flag&BAM_FREVERSE)? bam_calend(&cur->core, bam1_cigar(cur)) : cur->core.pos; + pre5 = (pre->core.flag&BAM_FREVERSE)? bam_calend(&pre->core, bam1_cigar(pre)) : pre->core.pos; + cur->core.isize = pre5 - cur5; pre->core.isize = cur5 - pre5; + } else cur->core.isize = pre->core.isize = 0; + if (pre->core.flag&BAM_FREVERSE) cur->core.flag |= BAM_FMREVERSE; + else cur->core.flag &= ~BAM_FMREVERSE; + if (cur->core.flag&BAM_FREVERSE) pre->core.flag |= BAM_FMREVERSE; + else pre->core.flag &= ~BAM_FMREVERSE; + if (cur->core.flag & BAM_FUNMAP) { pre->core.flag |= BAM_FMUNMAP; pre->core.flag &= ~BAM_FPROPER_PAIR; } + if (pre->core.flag & BAM_FUNMAP) { cur->core.flag |= BAM_FMUNMAP; cur->core.flag &= ~BAM_FPROPER_PAIR; } + bam_write1(out, pre); + bam_write1(out, cur); + has_prev = 0; + } else { // unpaired or singleton + pre->core.mtid = -1; pre->core.mpos = -1; pre->core.isize = 0; + if (pre->core.flag & BAM_FPAIRED) { + pre->core.flag |= BAM_FMUNMAP; + pre->core.flag &= ~BAM_FMREVERSE & ~BAM_FPROPER_PAIR; + } + bam_write1(out, pre); + } + } else has_prev = 1; + curr = 1 - curr; + } + if (has_prev) bam_write1(out, b[1-curr]); + bam_header_destroy(header); + bam_destroy1(b[0]); + bam_destroy1(b[1]); +} + +int bam_mating(int argc, char *argv[]) +{ + bamFile in, out; + if (argc < 3) { + fprintf(stderr, "samtools fixmate <in.nameSrt.bam> <out.nameSrt.bam>\n"); + return 1; + } + in = (strcmp(argv[1], "-") == 0)? bam_dopen(fileno(stdin), "r") : bam_open(argv[1], "r"); + out = (strcmp(argv[2], "-") == 0)? bam_dopen(fileno(stdout), "w") : bam_open(argv[2], "w"); + bam_mating_core(in, out); + bam_close(in); bam_close(out); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam_md.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,357 @@ +#include <unistd.h> +#include <assert.h> +#include <string.h> +#include <ctype.h> +#include <math.h> +#include "faidx.h" +#include "sam.h" +#include "kstring.h" +#include "kaln.h" +#include "kprobaln.h" + +char bam_nt16_nt4_table[] = { 4, 0, 1, 4, 2, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4 }; + +void bam_fillmd1_core(bam1_t *b, char *ref, int is_equal, int max_nm) +{ + uint8_t *seq = bam1_seq(b); + uint32_t *cigar = bam1_cigar(b); + bam1_core_t *c = &b->core; + int i, x, y, u = 0; + kstring_t *str; + uint8_t *old_md, *old_nm; + int32_t old_nm_i = -1, nm = 0; + + str = (kstring_t*)calloc(1, sizeof(kstring_t)); + for (i = y = 0, x = c->pos; i < c->n_cigar; ++i) { + int j, l = cigar[i]>>4, op = cigar[i]&0xf; + if (op == BAM_CMATCH) { + for (j = 0; j < l; ++j) { + int z = y + j; + int c1 = bam1_seqi(seq, z), c2 = bam_nt16_table[(int)ref[x+j]]; + if (ref[x+j] == 0) break; // out of boundary + if ((c1 == c2 && c1 != 15 && c2 != 15) || c1 == 0) { // a match + if (is_equal) seq[z/2] &= (z&1)? 0xf0 : 0x0f; + ++u; + } else { + ksprintf(str, "%d", u); + kputc(ref[x+j], str); + u = 0; ++nm; + } + } + if (j < l) break; + x += l; y += l; + } else if (op == BAM_CDEL) { + ksprintf(str, "%d", u); + kputc('^', str); + for (j = 0; j < l; ++j) { + if (ref[x+j] == 0) break; + kputc(ref[x+j], str); + } + u = 0; + if (j < l) break; + x += l; nm += l; + } else if (op == BAM_CINS || op == BAM_CSOFT_CLIP) { + y += l; + if (op == BAM_CINS) nm += l; + } else if (op == BAM_CREF_SKIP) { + x += l; + } + } + ksprintf(str, "%d", u); + // apply max_nm + if (max_nm > 0 && nm >= max_nm) { + for (i = y = 0, x = c->pos; i < c->n_cigar; ++i) { + int j, l = cigar[i]>>4, op = cigar[i]&0xf; + if (op == BAM_CMATCH) { + for (j = 0; j < l; ++j) { + int z = y + j; + int c1 = bam1_seqi(seq, z), c2 = bam_nt16_table[(int)ref[x+j]]; + if (ref[x+j] == 0) break; // out of boundary + if ((c1 == c2 && c1 != 15 && c2 != 15) || c1 == 0) { // a match + seq[z/2] |= (z&1)? 0x0f : 0xf0; + bam1_qual(b)[z] = 0; + } + } + if (j < l) break; + x += l; y += l; + } else if (op == BAM_CDEL || op == BAM_CREF_SKIP) x += l; + else if (op == BAM_CINS || op == BAM_CSOFT_CLIP) y += l; + } + } + // update NM + old_nm = bam_aux_get(b, "NM"); + if (c->flag & BAM_FUNMAP) return; + if (old_nm) old_nm_i = bam_aux2i(old_nm); + if (!old_nm) bam_aux_append(b, "NM", 'i', 4, (uint8_t*)&nm); + else if (nm != old_nm_i) { + fprintf(stderr, "[bam_fillmd1] different NM for read '%s': %d -> %d\n", bam1_qname(b), old_nm_i, nm); + bam_aux_del(b, old_nm); + bam_aux_append(b, "NM", 'i', 4, (uint8_t*)&nm); + } + // update MD + old_md = bam_aux_get(b, "MD"); + if (!old_md) bam_aux_append(b, "MD", 'Z', str->l + 1, (uint8_t*)str->s); + else { + int is_diff = 0; + if (strlen((char*)old_md+1) == str->l) { + for (i = 0; i < str->l; ++i) + if (toupper(old_md[i+1]) != toupper(str->s[i])) + break; + if (i < str->l) is_diff = 1; + } else is_diff = 1; + if (is_diff) { + fprintf(stderr, "[bam_fillmd1] different MD for read '%s': '%s' -> '%s'\n", bam1_qname(b), old_md+1, str->s); + bam_aux_del(b, old_md); + bam_aux_append(b, "MD", 'Z', str->l + 1, (uint8_t*)str->s); + } + } + free(str->s); free(str); +} + +void bam_fillmd1(bam1_t *b, char *ref, int is_equal) +{ + bam_fillmd1_core(b, ref, is_equal, 0); +} + +int bam_cap_mapQ(bam1_t *b, char *ref, int thres) +{ + uint8_t *seq = bam1_seq(b), *qual = bam1_qual(b); + uint32_t *cigar = bam1_cigar(b); + bam1_core_t *c = &b->core; + int i, x, y, mm, q, len, clip_l, clip_q; + double t; + if (thres < 0) thres = 40; // set the default + mm = q = len = clip_l = clip_q = 0; + for (i = y = 0, x = c->pos; i < c->n_cigar; ++i) { + int j, l = cigar[i]>>4, op = cigar[i]&0xf; + if (op == BAM_CMATCH) { + for (j = 0; j < l; ++j) { + int z = y + j; + int c1 = bam1_seqi(seq, z), c2 = bam_nt16_table[(int)ref[x+j]]; + if (ref[x+j] == 0) break; // out of boundary + if (c2 != 15 && c1 != 15 && qual[z] >= 13) { // not ambiguous + ++len; + if (c1 && c1 != c2 && qual[z] >= 13) { // mismatch + ++mm; + q += qual[z] > 33? 33 : qual[z]; + } + } + } + if (j < l) break; + x += l; y += l; len += l; + } else if (op == BAM_CDEL) { + for (j = 0; j < l; ++j) + if (ref[x+j] == 0) break; + if (j < l) break; + x += l; + } else if (op == BAM_CSOFT_CLIP) { + for (j = 0; j < l; ++j) clip_q += qual[y+j]; + clip_l += l; + y += l; + } else if (op == BAM_CHARD_CLIP) { + clip_q += 13 * l; + clip_l += l; + } else if (op == BAM_CINS) y += l; + else if (op == BAM_CREF_SKIP) x += l; + } + for (i = 0, t = 1; i < mm; ++i) + t *= (double)len / (i+1); + t = q - 4.343 * log(t) + clip_q / 5.; + if (t > thres) return -1; + if (t < 0) t = 0; + t = sqrt((thres - t) / thres) * thres; +// fprintf(stderr, "%s %lf %d\n", bam1_qname(b), t, q); + return (int)(t + .499); +} + +int bam_prob_realn_core(bam1_t *b, const char *ref, int flag) +{ + int k, i, bw, x, y, yb, ye, xb, xe, apply_baq = flag&1, extend_baq = flag>>1&1; + uint32_t *cigar = bam1_cigar(b); + bam1_core_t *c = &b->core; + kpa_par_t conf = kpa_par_def; + uint8_t *bq = 0, *zq = 0, *qual = bam1_qual(b); + if ((c->flag & BAM_FUNMAP) || b->core.l_qseq == 0) return -1; // do nothing + // test if BQ or ZQ is present + if ((bq = bam_aux_get(b, "BQ")) != 0) ++bq; + if ((zq = bam_aux_get(b, "ZQ")) != 0 && *zq == 'Z') ++zq; + if (bq && zq) { // remove the ZQ tag + bam_aux_del(b, zq-1); + zq = 0; + } + if (bq || zq) { + if ((apply_baq && zq) || (!apply_baq && bq)) return -3; // in both cases, do nothing + if (bq && apply_baq) { // then convert BQ to ZQ + for (i = 0; i < c->l_qseq; ++i) + qual[i] = qual[i] + 64 < bq[i]? 0 : qual[i] - ((int)bq[i] - 64); + *(bq - 3) = 'Z'; + } else if (zq && !apply_baq) { // then convert ZQ to BQ + for (i = 0; i < c->l_qseq; ++i) + qual[i] += (int)zq[i] - 64; + *(zq - 3) = 'B'; + } + return 0; + } + // find the start and end of the alignment + x = c->pos, y = 0, yb = ye = xb = xe = -1; + for (k = 0; k < c->n_cigar; ++k) { + int op, l; + op = cigar[k]&0xf; l = cigar[k]>>4; + if (op == BAM_CMATCH) { + if (yb < 0) yb = y; + if (xb < 0) xb = x; + ye = y + l; xe = x + l; + x += l; y += l; + } else if (op == BAM_CSOFT_CLIP || op == BAM_CINS) y += l; + else if (op == BAM_CDEL) x += l; + else if (op == BAM_CREF_SKIP) return -1; // do nothing if there is a reference skip + } + // set bandwidth and the start and the end + bw = 7; + if (abs((xe - xb) - (ye - yb)) > bw) + bw = abs((xe - xb) - (ye - yb)) + 3; + conf.bw = bw; + xb -= yb + bw/2; if (xb < 0) xb = 0; + xe += c->l_qseq - ye + bw/2; + if (xe - xb - c->l_qseq > bw) + xb += (xe - xb - c->l_qseq - bw) / 2, xe -= (xe - xb - c->l_qseq - bw) / 2; + { // glocal + uint8_t *s, *r, *q, *seq = bam1_seq(b), *bq; + int *state; + bq = calloc(c->l_qseq + 1, 1); + memcpy(bq, qual, c->l_qseq); + s = calloc(c->l_qseq, 1); + for (i = 0; i < c->l_qseq; ++i) s[i] = bam_nt16_nt4_table[bam1_seqi(seq, i)]; + r = calloc(xe - xb, 1); + for (i = xb; i < xe; ++i) { + if (ref[i] == 0) { xe = i; break; } + r[i-xb] = bam_nt16_nt4_table[bam_nt16_table[(int)ref[i]]]; + } + state = calloc(c->l_qseq, sizeof(int)); + q = calloc(c->l_qseq, 1); + kpa_glocal(r, xe-xb, s, c->l_qseq, qual, &conf, state, q); + if (!extend_baq) { // in this block, bq[] is capped by base quality qual[] + for (k = 0, x = c->pos, y = 0; k < c->n_cigar; ++k) { + int op = cigar[k]&0xf, l = cigar[k]>>4; + if (op == BAM_CMATCH) { + for (i = y; i < y + l; ++i) { + if ((state[i]&3) != 0 || state[i]>>2 != x - xb + (i - y)) bq[i] = 0; + else bq[i] = bq[i] < q[i]? bq[i] : q[i]; + } + x += l; y += l; + } else if (op == BAM_CSOFT_CLIP || op == BAM_CINS) y += l; + else if (op == BAM_CDEL) x += l; + } + for (i = 0; i < c->l_qseq; ++i) bq[i] = qual[i] - bq[i] + 64; // finalize BQ + } else { // in this block, bq[] is BAQ that can be larger than qual[] (different from the above!) + uint8_t *left, *rght; + left = calloc(c->l_qseq, 1); rght = calloc(c->l_qseq, 1); + for (k = 0, x = c->pos, y = 0; k < c->n_cigar; ++k) { + int op = cigar[k]&0xf, l = cigar[k]>>4; + if (op == BAM_CMATCH) { + for (i = y; i < y + l; ++i) + bq[i] = ((state[i]&3) != 0 || state[i]>>2 != x - xb + (i - y))? 0 : q[i]; + for (left[y] = bq[y], i = y + 1; i < y + l; ++i) + left[i] = bq[i] > left[i-1]? bq[i] : left[i-1]; + for (rght[y+l-1] = bq[y+l-1], i = y + l - 2; i >= y; --i) + rght[i] = bq[i] > rght[i+1]? bq[i] : rght[i+1]; + for (i = y; i < y + l; ++i) + bq[i] = left[i] < rght[i]? left[i] : rght[i]; + x += l; y += l; + } else if (op == BAM_CSOFT_CLIP || op == BAM_CINS) y += l; + else if (op == BAM_CDEL) x += l; + } + for (i = 0; i < c->l_qseq; ++i) bq[i] = 64 + (qual[i] <= bq[i]? 0 : qual[i] - bq[i]); // finalize BQ + free(left); free(rght); + } + if (apply_baq) { + for (i = 0; i < c->l_qseq; ++i) qual[i] -= bq[i] - 64; // modify qual + bam_aux_append(b, "ZQ", 'Z', c->l_qseq + 1, bq); + } else bam_aux_append(b, "BQ", 'Z', c->l_qseq + 1, bq); + free(bq); free(s); free(r); free(q); free(state); + } + return 0; +} + +int bam_prob_realn(bam1_t *b, const char *ref) +{ + return bam_prob_realn_core(b, ref, 1); +} + +int bam_fillmd(int argc, char *argv[]) +{ + int c, is_equal, tid = -2, ret, len, is_bam_out, is_sam_in, is_uncompressed, max_nm, is_realn, capQ, baq_flag; + samfile_t *fp, *fpout = 0; + faidx_t *fai; + char *ref = 0, mode_w[8], mode_r[8]; + bam1_t *b; + + is_equal = is_bam_out = is_sam_in = is_uncompressed = is_realn = max_nm = capQ = baq_flag = 0; + mode_w[0] = mode_r[0] = 0; + strcpy(mode_r, "r"); strcpy(mode_w, "w"); + while ((c = getopt(argc, argv, "EreubSC:n:A")) >= 0) { + switch (c) { + case 'r': is_realn = 1; break; + case 'e': is_equal = 1; break; + case 'b': is_bam_out = 1; break; + case 'u': is_uncompressed = is_bam_out = 1; break; + case 'S': is_sam_in = 1; break; + case 'n': max_nm = atoi(optarg); break; + case 'C': capQ = atoi(optarg); break; + case 'A': baq_flag |= 1; break; + case 'E': baq_flag |= 2; break; + default: fprintf(stderr, "[bam_fillmd] unrecognized option '-%c'\n", c); return 1; + } + } + if (!is_sam_in) strcat(mode_r, "b"); + if (is_bam_out) strcat(mode_w, "b"); + else strcat(mode_w, "h"); + if (is_uncompressed) strcat(mode_w, "u"); + if (optind + 1 >= argc) { + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: samtools fillmd [-eubrS] <aln.bam> <ref.fasta>\n\n"); + fprintf(stderr, "Options: -e change identical bases to '='\n"); + fprintf(stderr, " -u uncompressed BAM output (for piping)\n"); + fprintf(stderr, " -b compressed BAM output\n"); + fprintf(stderr, " -S the input is SAM with header\n"); + fprintf(stderr, " -A modify the quality string\n"); + fprintf(stderr, " -r compute the BQ tag (without -A) or cap baseQ by BAQ (with -A)\n"); + fprintf(stderr, " -E extended BAQ for better sensitivity but lower specificity\n\n"); + return 1; + } + fp = samopen(argv[optind], mode_r, 0); + if (fp == 0) return 1; + if (is_sam_in && (fp->header == 0 || fp->header->n_targets == 0)) { + fprintf(stderr, "[bam_fillmd] input SAM does not have header. Abort!\n"); + return 1; + } + fpout = samopen("-", mode_w, fp->header); + fai = fai_load(argv[optind+1]); + + b = bam_init1(); + while ((ret = samread(fp, b)) >= 0) { + if (b->core.tid >= 0) { + if (tid != b->core.tid) { + free(ref); + ref = fai_fetch(fai, fp->header->target_name[b->core.tid], &len); + tid = b->core.tid; + if (ref == 0) + fprintf(stderr, "[bam_fillmd] fail to find sequence '%s' in the reference.\n", + fp->header->target_name[tid]); + } + if (is_realn) bam_prob_realn_core(b, ref, baq_flag); + if (capQ > 10) { + int q = bam_cap_mapQ(b, ref, capQ); + if (b->core.qual > q) b->core.qual = q; + } + if (ref) bam_fillmd1_core(b, ref, is_equal, max_nm); + } + samwrite(fpout, b); + } + bam_destroy1(b); + + free(ref); + fai_destroy(fai); + samclose(fp); samclose(fpout); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam_pileup.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,437 @@ +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <assert.h> +#include "sam.h" + +typedef struct { + int k, x, y, end; +} cstate_t; + +static cstate_t g_cstate_null = { -1, 0, 0, 0 }; + +typedef struct __linkbuf_t { + bam1_t b; + uint32_t beg, end; + cstate_t s; + struct __linkbuf_t *next; +} lbnode_t; + +/* --- BEGIN: Memory pool */ + +typedef struct { + int cnt, n, max; + lbnode_t **buf; +} mempool_t; + +static mempool_t *mp_init() +{ + mempool_t *mp; + mp = (mempool_t*)calloc(1, sizeof(mempool_t)); + return mp; +} +static void mp_destroy(mempool_t *mp) +{ + int k; + for (k = 0; k < mp->n; ++k) { + free(mp->buf[k]->b.data); + free(mp->buf[k]); + } + free(mp->buf); + free(mp); +} +static inline lbnode_t *mp_alloc(mempool_t *mp) +{ + ++mp->cnt; + if (mp->n == 0) return (lbnode_t*)calloc(1, sizeof(lbnode_t)); + else return mp->buf[--mp->n]; +} +static inline void mp_free(mempool_t *mp, lbnode_t *p) +{ + --mp->cnt; p->next = 0; // clear lbnode_t::next here + if (mp->n == mp->max) { + mp->max = mp->max? mp->max<<1 : 256; + mp->buf = (lbnode_t**)realloc(mp->buf, sizeof(lbnode_t*) * mp->max); + } + mp->buf[mp->n++] = p; +} + +/* --- END: Memory pool */ + +/* --- BEGIN: Auxiliary functions */ + +/* s->k: the index of the CIGAR operator that has just been processed. + s->x: the reference coordinate of the start of s->k + s->y: the query coordiante of the start of s->k + */ +static inline int resolve_cigar2(bam_pileup1_t *p, uint32_t pos, cstate_t *s) +{ +#define _cop(c) ((c)&BAM_CIGAR_MASK) +#define _cln(c) ((c)>>BAM_CIGAR_SHIFT) + + bam1_t *b = p->b; + bam1_core_t *c = &b->core; + uint32_t *cigar = bam1_cigar(b); + int k, is_head = 0; + // determine the current CIGAR operation +// fprintf(stderr, "%s\tpos=%d\tend=%d\t(%d,%d,%d)\n", bam1_qname(b), pos, s->end, s->k, s->x, s->y); + if (s->k == -1) { // never processed + is_head = 1; + if (c->n_cigar == 1) { // just one operation, save a loop + if (_cop(cigar[0]) == BAM_CMATCH) s->k = 0, s->x = c->pos, s->y = 0; + } else { // find the first match or deletion + for (k = 0, s->x = c->pos, s->y = 0; k < c->n_cigar; ++k) { + int op = _cop(cigar[k]); + int l = _cln(cigar[k]); + if (op == BAM_CMATCH || op == BAM_CDEL) break; + else if (op == BAM_CREF_SKIP) s->x += l; + else if (op == BAM_CINS || op == BAM_CSOFT_CLIP) s->y += l; + } + assert(k < c->n_cigar); + s->k = k; + } + } else { // the read has been processed before + int op, l = _cln(cigar[s->k]); + if (pos - s->x >= l) { // jump to the next operation + assert(s->k < c->n_cigar); // otherwise a bug: this function should not be called in this case + op = _cop(cigar[s->k+1]); + if (op == BAM_CMATCH || op == BAM_CDEL || op == BAM_CREF_SKIP) { // jump to the next without a loop + if (_cop(cigar[s->k]) == BAM_CMATCH) s->y += l; + s->x += l; + ++s->k; + } else { // find the next M/D/N + if (_cop(cigar[s->k]) == BAM_CMATCH) s->y += l; + s->x += l; + for (k = s->k + 1; k < c->n_cigar; ++k) { + op = _cop(cigar[k]), l = _cln(cigar[k]); + if (op == BAM_CMATCH || op == BAM_CDEL || op == BAM_CREF_SKIP) break; + else if (op == BAM_CINS || op == BAM_CSOFT_CLIP) s->y += l; + } + s->k = k; + } + assert(s->k < c->n_cigar); // otherwise a bug + } // else, do nothing + } + { // collect pileup information + int op, l; + op = _cop(cigar[s->k]); l = _cln(cigar[s->k]); + p->is_del = p->indel = p->is_refskip = 0; + if (s->x + l - 1 == pos && s->k + 1 < c->n_cigar) { // peek the next operation + int op2 = _cop(cigar[s->k+1]); + int l2 = _cln(cigar[s->k+1]); + if (op2 == BAM_CDEL) p->indel = -(int)l2; + else if (op2 == BAM_CINS) p->indel = l2; + else if (op2 == BAM_CPAD && s->k + 2 < c->n_cigar) { // no working for adjacent padding + int l3 = 0; + for (k = s->k + 2; k < c->n_cigar; ++k) { + op2 = _cop(cigar[k]); l2 = _cln(cigar[k]); + if (op2 == BAM_CINS) l3 += l2; + else if (op2 == BAM_CDEL || op2 == BAM_CMATCH || op2 == BAM_CREF_SKIP) break; + } + if (l3 > 0) p->indel = l3; + } + } + if (op == BAM_CMATCH) { + p->qpos = s->y + (pos - s->x); + } else if (op == BAM_CDEL || op == BAM_CREF_SKIP) { + p->is_del = 1; p->qpos = s->y; // FIXME: distinguish D and N!!!!! + p->is_refskip = (op == BAM_CREF_SKIP); + } // cannot be other operations; otherwise a bug + p->is_head = (pos == c->pos); p->is_tail = (pos == s->end); + } + return 1; +} + +/* --- END: Auxiliary functions */ + +/******************* + * pileup iterator * + *******************/ + +struct __bam_plp_t { + mempool_t *mp; + lbnode_t *head, *tail, *dummy; + int32_t tid, pos, max_tid, max_pos; + int is_eof, flag_mask, max_plp, error, maxcnt; + bam_pileup1_t *plp; + // for the "auto" interface only + bam1_t *b; + bam_plp_auto_f func; + void *data; +}; + +bam_plp_t bam_plp_init(bam_plp_auto_f func, void *data) +{ + bam_plp_t iter; + iter = calloc(1, sizeof(struct __bam_plp_t)); + iter->mp = mp_init(); + iter->head = iter->tail = mp_alloc(iter->mp); + iter->dummy = mp_alloc(iter->mp); + iter->max_tid = iter->max_pos = -1; + iter->flag_mask = BAM_DEF_MASK; + iter->maxcnt = 8000; + if (func) { + iter->func = func; + iter->data = data; + iter->b = bam_init1(); + } + return iter; +} + +void bam_plp_destroy(bam_plp_t iter) +{ + mp_free(iter->mp, iter->dummy); + mp_free(iter->mp, iter->head); + if (iter->mp->cnt != 0) + fprintf(stderr, "[bam_plp_destroy] memory leak: %d. Continue anyway.\n", iter->mp->cnt); + mp_destroy(iter->mp); + if (iter->b) bam_destroy1(iter->b); + free(iter->plp); + free(iter); +} + +const bam_pileup1_t *bam_plp_next(bam_plp_t iter, int *_tid, int *_pos, int *_n_plp) +{ + if (iter->error) { *_n_plp = -1; return 0; } + *_n_plp = 0; + if (iter->is_eof && iter->head->next == 0) return 0; + while (iter->is_eof || iter->max_tid > iter->tid || (iter->max_tid == iter->tid && iter->max_pos > iter->pos)) { + int n_plp = 0; + lbnode_t *p, *q; + // write iter->plp at iter->pos + iter->dummy->next = iter->head; + for (p = iter->head, q = iter->dummy; p->next; q = p, p = p->next) { + if (p->b.core.tid < iter->tid || (p->b.core.tid == iter->tid && p->end <= iter->pos)) { // then remove + q->next = p->next; mp_free(iter->mp, p); p = q; + } else if (p->b.core.tid == iter->tid && p->beg <= iter->pos) { // here: p->end > pos; then add to pileup + if (n_plp == iter->max_plp) { // then double the capacity + iter->max_plp = iter->max_plp? iter->max_plp<<1 : 256; + iter->plp = (bam_pileup1_t*)realloc(iter->plp, sizeof(bam_pileup1_t) * iter->max_plp); + } + iter->plp[n_plp].b = &p->b; + if (resolve_cigar2(iter->plp + n_plp, iter->pos, &p->s)) ++n_plp; // actually always true... + } + } + iter->head = iter->dummy->next; // dummy->next may be changed + *_n_plp = n_plp; *_tid = iter->tid; *_pos = iter->pos; + // update iter->tid and iter->pos + if (iter->head->next) { + if (iter->tid > iter->head->b.core.tid) { + fprintf(stderr, "[%s] unsorted input. Pileup aborts.\n", __func__); + iter->error = 1; + *_n_plp = -1; + return 0; + } + } + if (iter->tid < iter->head->b.core.tid) { // come to a new reference sequence + iter->tid = iter->head->b.core.tid; iter->pos = iter->head->beg; // jump to the next reference + } else if (iter->pos < iter->head->beg) { // here: tid == head->b.core.tid + iter->pos = iter->head->beg; // jump to the next position + } else ++iter->pos; // scan contiguously + // return + if (n_plp) return iter->plp; + if (iter->is_eof && iter->head->next == 0) break; + } + return 0; +} + +int bam_plp_push(bam_plp_t iter, const bam1_t *b) +{ + if (iter->error) return -1; + if (b) { + if (b->core.tid < 0) return 0; + if (b->core.flag & iter->flag_mask) return 0; + if (iter->tid == b->core.tid && iter->pos == b->core.pos && iter->mp->cnt > iter->maxcnt) return 0; + bam_copy1(&iter->tail->b, b); + iter->tail->beg = b->core.pos; iter->tail->end = bam_calend(&b->core, bam1_cigar(b)); + iter->tail->s = g_cstate_null; iter->tail->s.end = iter->tail->end - 1; // initialize cstate_t + if (b->core.tid < iter->max_tid) { + fprintf(stderr, "[bam_pileup_core] the input is not sorted (chromosomes out of order)\n"); + iter->error = 1; + return -1; + } + if ((b->core.tid == iter->max_tid) && (iter->tail->beg < iter->max_pos)) { + fprintf(stderr, "[bam_pileup_core] the input is not sorted (reads out of order)\n"); + iter->error = 1; + return -1; + } + iter->max_tid = b->core.tid; iter->max_pos = iter->tail->beg; + if (iter->tail->end > iter->pos || iter->tail->b.core.tid > iter->tid) { + iter->tail->next = mp_alloc(iter->mp); + iter->tail = iter->tail->next; + } + } else iter->is_eof = 1; + return 0; +} + +const bam_pileup1_t *bam_plp_auto(bam_plp_t iter, int *_tid, int *_pos, int *_n_plp) +{ + const bam_pileup1_t *plp; + if (iter->func == 0 || iter->error) { *_n_plp = -1; return 0; } + if ((plp = bam_plp_next(iter, _tid, _pos, _n_plp)) != 0) return plp; + else { // no pileup line can be obtained; read alignments + *_n_plp = 0; + if (iter->is_eof) return 0; + while (iter->func(iter->data, iter->b) >= 0) { + if (bam_plp_push(iter, iter->b) < 0) { + *_n_plp = -1; + return 0; + } + if ((plp = bam_plp_next(iter, _tid, _pos, _n_plp)) != 0) return plp; + // otherwise no pileup line can be returned; read the next alignment. + } + bam_plp_push(iter, 0); + if ((plp = bam_plp_next(iter, _tid, _pos, _n_plp)) != 0) return plp; + return 0; + } +} + +void bam_plp_reset(bam_plp_t iter) +{ + lbnode_t *p, *q; + iter->max_tid = iter->max_pos = -1; + iter->tid = iter->pos = 0; + iter->is_eof = 0; + for (p = iter->head; p->next;) { + q = p->next; + mp_free(iter->mp, p); + p = q; + } + iter->head = iter->tail; +} + +void bam_plp_set_mask(bam_plp_t iter, int mask) +{ + iter->flag_mask = mask < 0? BAM_DEF_MASK : (BAM_FUNMAP | mask); +} + +void bam_plp_set_maxcnt(bam_plp_t iter, int maxcnt) +{ + iter->maxcnt = maxcnt; +} + +/***************** + * callback APIs * + *****************/ + +int bam_pileup_file(bamFile fp, int mask, bam_pileup_f func, void *func_data) +{ + bam_plbuf_t *buf; + int ret; + bam1_t *b; + b = bam_init1(); + buf = bam_plbuf_init(func, func_data); + bam_plbuf_set_mask(buf, mask); + while ((ret = bam_read1(fp, b)) >= 0) + bam_plbuf_push(b, buf); + bam_plbuf_push(0, buf); + bam_plbuf_destroy(buf); + bam_destroy1(b); + return 0; +} + +void bam_plbuf_set_mask(bam_plbuf_t *buf, int mask) +{ + bam_plp_set_mask(buf->iter, mask); +} + +void bam_plbuf_reset(bam_plbuf_t *buf) +{ + bam_plp_reset(buf->iter); +} + +bam_plbuf_t *bam_plbuf_init(bam_pileup_f func, void *data) +{ + bam_plbuf_t *buf; + buf = calloc(1, sizeof(bam_plbuf_t)); + buf->iter = bam_plp_init(0, 0); + buf->func = func; + buf->data = data; + return buf; +} + +void bam_plbuf_destroy(bam_plbuf_t *buf) +{ + bam_plp_destroy(buf->iter); + free(buf); +} + +int bam_plbuf_push(const bam1_t *b, bam_plbuf_t *buf) +{ + int ret, n_plp, tid, pos; + const bam_pileup1_t *plp; + ret = bam_plp_push(buf->iter, b); + if (ret < 0) return ret; + while ((plp = bam_plp_next(buf->iter, &tid, &pos, &n_plp)) != 0) + buf->func(tid, pos, n_plp, plp, buf->data); + return 0; +} + +/*********** + * mpileup * + ***********/ + +struct __bam_mplp_t { + int n; + uint64_t min, *pos; + bam_plp_t *iter; + int *n_plp; + const bam_pileup1_t **plp; +}; + +bam_mplp_t bam_mplp_init(int n, bam_plp_auto_f func, void **data) +{ + int i; + bam_mplp_t iter; + iter = calloc(1, sizeof(struct __bam_mplp_t)); + iter->pos = calloc(n, 8); + iter->n_plp = calloc(n, sizeof(int)); + iter->plp = calloc(n, sizeof(void*)); + iter->iter = calloc(n, sizeof(void*)); + iter->n = n; + iter->min = (uint64_t)-1; + for (i = 0; i < n; ++i) { + iter->iter[i] = bam_plp_init(func, data[i]); + iter->pos[i] = iter->min; + } + return iter; +} + +void bam_mplp_set_maxcnt(bam_mplp_t iter, int maxcnt) +{ + int i; + for (i = 0; i < iter->n; ++i) + iter->iter[i]->maxcnt = maxcnt; +} + +void bam_mplp_destroy(bam_mplp_t iter) +{ + int i; + for (i = 0; i < iter->n; ++i) bam_plp_destroy(iter->iter[i]); + free(iter->iter); free(iter->pos); free(iter->n_plp); free(iter->plp); + free(iter); +} + +int bam_mplp_auto(bam_mplp_t iter, int *_tid, int *_pos, int *n_plp, const bam_pileup1_t **plp) +{ + int i, ret = 0; + uint64_t new_min = (uint64_t)-1; + for (i = 0; i < iter->n; ++i) { + if (iter->pos[i] == iter->min) { + int tid, pos; + iter->plp[i] = bam_plp_auto(iter->iter[i], &tid, &pos, &iter->n_plp[i]); + iter->pos[i] = (uint64_t)tid<<32 | pos; + } + if (iter->plp[i] && iter->pos[i] < new_min) new_min = iter->pos[i]; + } + iter->min = new_min; + if (new_min == (uint64_t)-1) return 0; + *_tid = new_min>>32; *_pos = (uint32_t)new_min; + for (i = 0; i < iter->n; ++i) { + if (iter->pos[i] == iter->min) { // FIXME: valgrind reports "uninitialised value(s) at this line" + n_plp[i] = iter->n_plp[i], plp[i] = iter->plp[i]; + ++ret; + } else n_plp[i] = 0, plp[i] = 0; + } + return ret; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam_plcmd.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,980 @@ +#include <math.h> +#include <stdio.h> +#include <unistd.h> +#include <ctype.h> +#include <string.h> +#include <errno.h> +#include "sam.h" +#include "faidx.h" +#include "bam_maqcns.h" +#include "khash.h" +#include "glf.h" +#include "kstring.h" + +typedef int *indel_list_t; +KHASH_MAP_INIT_INT64(64, indel_list_t) + +#define BAM_PLF_SIMPLE 0x01 +#define BAM_PLF_CNS 0x02 +#define BAM_PLF_INDEL_ONLY 0x04 +#define BAM_PLF_GLF 0x08 +#define BAM_PLF_VAR_ONLY 0x10 +#define BAM_PLF_2ND 0x20 +#define BAM_PLF_RANBASE 0x40 +#define BAM_PLF_1STBASE 0x80 +#define BAM_PLF_ALLBASE 0x100 +#define BAM_PLF_READPOS 0x200 +#define BAM_PLF_NOBAQ 0x400 + +typedef struct { + bam_header_t *h; + bam_maqcns_t *c; + bam_maqindel_opt_t *ido; + faidx_t *fai; + khash_t(64) *hash; + uint32_t format; + int tid, len, last_pos; + int mask; + int capQ_thres, min_baseQ; + int max_depth; // for indel calling, ignore reads with the depth too high. 0 for unlimited + char *ref; + glfFile fp_glf; // for glf output only +} pu_data_t; + +char **__bam_get_lines(const char *fn, int *_n); +void bam_init_header_hash(bam_header_t *header); +int32_t bam_get_tid(const bam_header_t *header, const char *seq_name); + +static khash_t(64) *load_pos(const char *fn, bam_header_t *h) +{ + char **list; + int i, j, n, *fields, max_fields; + khash_t(64) *hash; + bam_init_header_hash(h); + list = __bam_get_lines(fn, &n); + hash = kh_init(64); + max_fields = 0; fields = 0; + for (i = 0; i < n; ++i) { + char *str = list[i]; + int chr, n_fields, ret; + khint_t k; + uint64_t x; + n_fields = ksplit_core(str, 0, &max_fields, &fields); + if (n_fields < 2) continue; + chr = bam_get_tid(h, str + fields[0]); + if (chr < 0) { + fprintf(stderr, "[load_pos] unknown reference sequence name: %s\n", str + fields[0]); + continue; + } + x = (uint64_t)chr << 32 | (atoi(str + fields[1]) - 1); + k = kh_put(64, hash, x, &ret); + if (ret == 0) { + fprintf(stderr, "[load_pos] position %s:%s has been loaded.\n", str+fields[0], str+fields[1]); + continue; + } + kh_val(hash, k) = 0; + if (n_fields > 2) { + // count + for (j = 2; j < n_fields; ++j) { + char *s = str + fields[j]; + if ((*s != '+' && *s != '-') || !isdigit(s[1])) break; + } + if (j > 2) { // update kh_val() + int *q, y, z; + q = kh_val(hash, k) = (int*)calloc(j - 1, sizeof(int)); + q[0] = j - 2; z = j; y = 1; + for (j = 2; j < z; ++j) + q[y++] = atoi(str + fields[j]); + } + } + free(str); + } + free(list); free(fields); + return hash; +} + +static inline int printw(int c, FILE *fp) +{ + char buf[16]; + int l, x; + if (c == 0) return fputc('0', fp); + for (l = 0, x = c < 0? -c : c; x > 0; x /= 10) buf[l++] = x%10 + '0'; + if (c < 0) buf[l++] = '-'; + buf[l] = 0; + for (x = 0; x < l/2; ++x) { + int y = buf[x]; buf[x] = buf[l-1-x]; buf[l-1-x] = y; + } + fputs(buf, fp); + return 0; +} + +// an analogy to pileup_func() below +static int glt3_func(uint32_t tid, uint32_t pos, int n, const bam_pileup1_t *pu, void *data) +{ + pu_data_t *d = (pu_data_t*)data; + bam_maqindel_ret_t *r = 0; + int rb, *proposed_indels = 0; + glf1_t *g; + glf3_t *g3; + + if (d->fai == 0) { + fprintf(stderr, "[glt3_func] reference sequence is required for generating GLT. Abort!\n"); + exit(1); + } + if (d->hash) { // only output a list of sites + khint_t k = kh_get(64, d->hash, (uint64_t)tid<<32|pos); + if (k == kh_end(d->hash)) return 0; + proposed_indels = kh_val(d->hash, k); + } + g3 = glf3_init1(); + if (d->fai && (int)tid != d->tid) { + if (d->ref) { // then write the end mark + g3->rtype = GLF3_RTYPE_END; + glf3_write1(d->fp_glf, g3); + } + glf3_ref_write(d->fp_glf, d->h->target_name[tid], d->h->target_len[tid]); // write reference + free(d->ref); + d->ref = fai_fetch(d->fai, d->h->target_name[tid], &d->len); + d->tid = tid; + d->last_pos = 0; + } + rb = (d->ref && (int)pos < d->len)? d->ref[pos] : 'N'; + g = bam_maqcns_glfgen(n, pu, bam_nt16_table[rb], d->c); + memcpy(g3, g, sizeof(glf1_t)); + g3->rtype = GLF3_RTYPE_SUB; + g3->offset = pos - d->last_pos; + d->last_pos = pos; + glf3_write1(d->fp_glf, g3); + if (pos < d->len) { + int m = (!d->max_depth || d->max_depth>n) ? n : d->max_depth; + if (proposed_indels) + r = bam_maqindel(m, pos, d->ido, pu, d->ref, proposed_indels[0], proposed_indels+1); + else r = bam_maqindel(m, pos, d->ido, pu, d->ref, 0, 0); + } + if (r) { // then write indel line + int het = 3 * n, min; + min = het; + if (min > r->gl[0]) min = r->gl[0]; + if (min > r->gl[1]) min = r->gl[1]; + g3->ref_base = 0; + g3->rtype = GLF3_RTYPE_INDEL; + memset(g3->lk, 0, 10); + g3->lk[0] = r->gl[0] - min < 255? r->gl[0] - min : 255; + g3->lk[1] = r->gl[1] - min < 255? r->gl[1] - min : 255; + g3->lk[2] = het - min < 255? het - min : 255; + g3->offset = 0; + g3->indel_len[0] = r->indel1; + g3->indel_len[1] = r->indel2; + g3->min_lk = min < 255? min : 255; + g3->max_len = (abs(r->indel1) > abs(r->indel2)? abs(r->indel1) : abs(r->indel2)) + 1; + g3->indel_seq[0] = strdup(r->s[0]+1); + g3->indel_seq[1] = strdup(r->s[1]+1); + glf3_write1(d->fp_glf, g3); + bam_maqindel_ret_destroy(r); + } + free(g); + glf3_destroy1(g3); + return 0; +} + +static inline void pileup_seq(const bam_pileup1_t *p, int pos, int ref_len, const char *ref) +{ + int j; + if (p->is_head) { + putchar('^'); + putchar(p->b->core.qual > 93? 126 : p->b->core.qual + 33); + } + if (!p->is_del) { + int c = bam_nt16_rev_table[bam1_seqi(bam1_seq(p->b), p->qpos)]; + if (ref) { + int rb = pos < ref_len? ref[pos] : 'N'; + if (c == '=' || bam_nt16_table[c] == bam_nt16_table[rb]) c = bam1_strand(p->b)? ',' : '.'; + else c = bam1_strand(p->b)? tolower(c) : toupper(c); + } else { + if (c == '=') c = bam1_strand(p->b)? ',' : '.'; + else c = bam1_strand(p->b)? tolower(c) : toupper(c); + } + putchar(c); + } else putchar(p->is_refskip? (bam1_strand(p->b)? '<' : '>') : '*'); + if (p->indel > 0) { + putchar('+'); printw(p->indel, stdout); + for (j = 1; j <= p->indel; ++j) { + int c = bam_nt16_rev_table[bam1_seqi(bam1_seq(p->b), p->qpos + j)]; + putchar(bam1_strand(p->b)? tolower(c) : toupper(c)); + } + } else if (p->indel < 0) { + printw(p->indel, stdout); + for (j = 1; j <= -p->indel; ++j) { + int c = (ref && (int)pos+j < ref_len)? ref[pos+j] : 'N'; + putchar(bam1_strand(p->b)? tolower(c) : toupper(c)); + } + } + if (p->is_tail) putchar('$'); +} + +static int pileup_func(uint32_t tid, uint32_t pos, int n, const bam_pileup1_t *pu, void *data) +{ + pu_data_t *d = (pu_data_t*)data; + bam_maqindel_ret_t *r = 0; + int i, rb, rms_mapq = -1, *proposed_indels = 0; + uint64_t rms_aux; + uint32_t cns = 0; + + // if GLF is required, suppress -c completely + if (d->format & BAM_PLF_GLF) return glt3_func(tid, pos, n, pu, data); + // if d->hash is initialized, only output the sites in the hash table + if (d->hash) { + khint_t k = kh_get(64, d->hash, (uint64_t)tid<<32|pos); + if (k == kh_end(d->hash)) return 0; + proposed_indels = kh_val(d->hash, k); + } + // update d->ref if necessary + if (d->fai && (int)tid != d->tid) { + free(d->ref); + d->ref = faidx_fetch_seq(d->fai, d->h->target_name[tid], 0, 0x7fffffff, &d->len); + d->tid = tid; + } + rb = (d->ref && (int)pos < d->len)? d->ref[pos] : 'N'; + // when the indel-only mode is asked for, return if no reads mapped with indels + if (d->format & BAM_PLF_INDEL_ONLY) { + for (i = 0; i < n; ++i) + if (pu[i].indel != 0) break; + if (i == n) return 0; + } + // call the consensus and indel + if (d->format & BAM_PLF_CNS) { // call consensus + if (d->format & (BAM_PLF_RANBASE|BAM_PLF_1STBASE)) { // use a random base or the 1st base as the consensus call + const bam_pileup1_t *p = (d->format & BAM_PLF_1STBASE)? pu : pu + (int)(drand48() * n); + int q = bam1_qual(p->b)[p->qpos]; + int mapQ = p->b->core.qual < d->c->cap_mapQ? p->b->core.qual : d->c->cap_mapQ; + uint32_t b = bam1_seqi(bam1_seq(p->b), p->qpos); + cns = b<<28 | 0xf<<24 | mapQ<<16 | q<<8; + } else if (d->format & BAM_PLF_ALLBASE) { // collapse all bases + uint64_t rmsQ = 0; + uint32_t b = 0; + for (i = 0; i < n; ++i) { + const bam_pileup1_t *p = pu + i; + int q = p->b->core.qual < d->c->cap_mapQ? p->b->core.qual : d->c->cap_mapQ; + b |= bam1_seqi(bam1_seq(p->b), p->qpos); + rmsQ += q * q; + } + rmsQ = (uint64_t)(sqrt((double)rmsQ / n) + .499); + cns = b<<28 | 0xf<<24 | rmsQ<<16 | 60<<8; + } else { + glf1_t *g = bam_maqcns_glfgen(n, pu, bam_nt16_table[rb], d->c); + cns = g->depth == 0? (0xfu<<28 | 0xf<<24) : glf2cns(g, (int)(d->c->q_r + .499)); + free(g); + } + } + if ((d->format & (BAM_PLF_CNS|BAM_PLF_INDEL_ONLY)) && d->ref && pos < d->len) { // call indels + int m = (!d->max_depth || d->max_depth>n) ? n : d->max_depth; + if (proposed_indels) // the first element gives the size of the array + r = bam_maqindel(m, pos, d->ido, pu, d->ref, proposed_indels[0], proposed_indels+1); + else r = bam_maqindel(m, pos, d->ido, pu, d->ref, 0, 0); + } + // when only variant sites are asked for, test if the site is a variant + if ((d->format & BAM_PLF_CNS) && (d->format & BAM_PLF_VAR_ONLY)) { + if (!(bam_nt16_table[rb] != 15 && cns>>28 != 15 && cns>>28 != bam_nt16_table[rb])) { // not a SNP + if (!(r && (r->gt == 2 || strcmp(r->s[r->gt], "*")))) { // not an indel + if (r) bam_maqindel_ret_destroy(r); + return 0; + } + } + } + // print the first 3 columns + fputs(d->h->target_name[tid], stdout); putchar('\t'); + printw(pos+1, stdout); putchar('\t'); putchar(rb); putchar('\t'); + // print consensus information if required + if (d->format & BAM_PLF_CNS) { + putchar(bam_nt16_rev_table[cns>>28]); putchar('\t'); + printw(cns>>8&0xff, stdout); putchar('\t'); + printw(cns&0xff, stdout); putchar('\t'); + printw(cns>>16&0xff, stdout); putchar('\t'); + } + // print pileup sequences + printw(n, stdout); putchar('\t'); + for (i = 0; i < n; ++i) + pileup_seq(pu + i, pos, d->len, d->ref); + // finalize rms_mapq + if (d->format & BAM_PLF_CNS) { + for (i = rms_aux = 0; i < n; ++i) { + const bam_pileup1_t *p = pu + i; + int tmp = p->b->core.qual < d->c->cap_mapQ? p->b->core.qual : d->c->cap_mapQ; + rms_aux += tmp * tmp; + } + rms_aux = (uint64_t)(sqrt((double)rms_aux / n) + .499); + if (rms_mapq < 0) rms_mapq = rms_aux; + } + putchar('\t'); + // print quality + for (i = 0; i < n; ++i) { + const bam_pileup1_t *p = pu + i; + int c = bam1_qual(p->b)[p->qpos] + 33; + if (c > 126) c = 126; + putchar(c); + } + if (d->format & BAM_PLF_2ND) { // print 2nd calls and qualities + const unsigned char *q; + putchar('\t'); + for (i = 0; i < n; ++i) { + const bam_pileup1_t *p = pu + i; + q = bam_aux_get(p->b, "E2"); + putchar(q? q[p->qpos + 1] : 'N'); + } + putchar('\t'); + for (i = 0; i < n; ++i) { + const bam_pileup1_t *p = pu + i; + q = bam_aux_get(p->b, "U2"); + putchar(q? q[p->qpos + 1] : '!'); + } + } + // print mapping quality if -s is flagged on the command line + if (d->format & BAM_PLF_SIMPLE) { + putchar('\t'); + for (i = 0; i < n; ++i) { + int c = pu[i].b->core.qual + 33; + if (c > 126) c = 126; + putchar(c); + } + } + // print read position + if (d->format & BAM_PLF_READPOS) { + putchar('\t'); + for (i = 0; i < n; ++i) { + int x = pu[i].qpos; + int l = pu[i].b->core.l_qseq; + printw(x < l/2? x+1 : -((l-1)-x+1), stdout); putchar(','); + } + } + putchar('\n'); + // print the indel line if r has been calculated. This only happens if: + // a) -c or -i are flagged, AND b) the reference sequence is available + if (r) { + printf("%s\t%d\t*\t", d->h->target_name[tid], pos + 1); + if (r->gt < 2) printf("%s/%s\t", r->s[r->gt], r->s[r->gt]); + else printf("%s/%s\t", r->s[0], r->s[1]); + printf("%d\t%d\t", r->q_cns, r->q_ref); + printf("%d\t%d\t", rms_mapq, n); + printf("%s\t%s\t", r->s[0], r->s[1]); + //printf("%d\t%d\t", r->gl[0], r->gl[1]); + printf("%d\t%d\t%d\t", r->cnt1, r->cnt2, r->cnt_anti); + printf("%d\t%d\n", r->cnt_ref, r->cnt_ambi); + bam_maqindel_ret_destroy(r); + } + return 0; +} + +int bam_pileup(int argc, char *argv[]) +{ + int c, is_SAM = 0; + char *fn_list = 0, *fn_fa = 0, *fn_pos = 0; + pu_data_t *d = (pu_data_t*)calloc(1, sizeof(pu_data_t)); + d->max_depth = 1024; d->tid = -1; d->mask = BAM_DEF_MASK; d->min_baseQ = 13; + d->c = bam_maqcns_init(); + d->c->errmod = BAM_ERRMOD_MAQ2; // change the default model + d->ido = bam_maqindel_opt_init(); + while ((c = getopt(argc, argv, "st:f:cT:N:r:l:d:im:gI:G:vM:S2aR:PAQ:C:B")) >= 0) { + switch (c) { + case 'Q': d->c->min_baseQ = atoi(optarg); break; + case 'C': d->capQ_thres = atoi(optarg); break; + case 'B': d->format |= BAM_PLF_NOBAQ; break; + case 'a': d->c->errmod = BAM_ERRMOD_SOAP; break; + case 'A': d->c->errmod = BAM_ERRMOD_MAQ; break; + case 's': d->format |= BAM_PLF_SIMPLE; break; + case 't': fn_list = strdup(optarg); break; + case 'l': fn_pos = strdup(optarg); break; + case 'f': fn_fa = strdup(optarg); break; + case 'T': d->c->theta = atof(optarg); break; + case 'N': d->c->n_hap = atoi(optarg); break; + case 'r': d->c->het_rate = atof(optarg); d->ido->r_snp = d->c->het_rate; break; + case 'M': d->c->cap_mapQ = atoi(optarg); break; + case 'd': d->max_depth = atoi(optarg); break; + case 'c': d->format |= BAM_PLF_CNS; break; + case 'i': d->format |= BAM_PLF_INDEL_ONLY; break; + case 'v': d->format |= BAM_PLF_VAR_ONLY; break; + case 'm': d->mask = strtol(optarg, 0, 0); break; + case 'g': d->format |= BAM_PLF_GLF; break; + case '2': d->format |= BAM_PLF_2ND; break; + case 'P': d->format |= BAM_PLF_READPOS; break; + case 'I': d->ido->q_indel = atoi(optarg); break; + case 'G': d->ido->r_indel = atof(optarg); break; + case 'S': is_SAM = 1; break; + case 'R': + if (strcmp(optarg, "random") == 0) d->format |= BAM_PLF_RANBASE; + else if (strcmp(optarg, "first") == 0) d->format |= BAM_PLF_1STBASE; + else if (strcmp(optarg, "all") == 0) d->format |= BAM_PLF_ALLBASE; + else fprintf(stderr, "[bam_pileup] unrecognized -R\n"); + break; + default: fprintf(stderr, "Unrecognizd option '-%c'.\n", c); return 1; + } + } + if (d->c->errmod != BAM_ERRMOD_MAQ2) d->c->theta += 0.02; + if (d->c->theta > 1.0) d->c->theta = 1.0; + if (fn_list) is_SAM = 1; + if (optind == argc) { + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: samtools pileup [options] <in.bam>|<in.sam>\n\n"); + fprintf(stderr, "Option: -s simple (yet incomplete) pileup format\n"); + fprintf(stderr, " -S the input is in SAM\n"); + fprintf(stderr, " -B disable BAQ computation\n"); + fprintf(stderr, " -A use the original MAQ model for SNP calling (DEPRECATED)\n"); + fprintf(stderr, " -2 output the 2nd best call and quality\n"); + fprintf(stderr, " -i only show lines/consensus with indels\n"); + fprintf(stderr, " -Q INT min base quality (possibly capped by BAQ) [%d]\n", d->c->min_baseQ); + fprintf(stderr, " -C INT coefficient for adjusting mapQ of poor mappings [%d]\n", d->capQ_thres); + fprintf(stderr, " -m INT filtering reads with bits in INT [0x%x]\n", d->mask); + fprintf(stderr, " -M INT cap mapping quality at INT [%d]\n", d->c->cap_mapQ); + fprintf(stderr, " -d INT limit maximum depth for indels [%d]\n", d->max_depth); + fprintf(stderr, " -t FILE list of reference sequences (force -S)\n"); + fprintf(stderr, " -l FILE list of sites at which pileup is output\n"); + fprintf(stderr, " -f FILE reference sequence in the FASTA format\n\n"); + fprintf(stderr, " -c compute the consensus sequence\n"); + fprintf(stderr, " -v print variants only (for -c)\n"); + fprintf(stderr, " -g output in the GLFv3 format (DEPRECATED)\n"); + fprintf(stderr, " -T FLOAT theta in maq consensus calling model (for -c) [%.4g]\n", d->c->theta); + fprintf(stderr, " -N INT number of haplotypes in the sample (for -c) [%d]\n", d->c->n_hap); + fprintf(stderr, " -r FLOAT prior of a difference between two haplotypes (for -c) [%.4g]\n", d->c->het_rate); + fprintf(stderr, " -G FLOAT prior of an indel between two haplotypes (for -c) [%.4g]\n", d->ido->r_indel); + fprintf(stderr, " -I INT phred prob. of an indel in sequencing/prep. (for -c) [%d]\n", d->ido->q_indel); + fprintf(stderr, "\n"); + fprintf(stderr, "Warning: Please use the `mpileup' command instead `pileup'. `Pileup' is deprecated!\n\n"); + free(fn_list); free(fn_fa); free(d); + return 1; + } + if (d->format & (BAM_PLF_RANBASE|BAM_PLF_1STBASE|BAM_PLF_ALLBASE)) d->format |= BAM_PLF_CNS; + if (fn_fa) d->fai = fai_load(fn_fa); + if (d->format & (BAM_PLF_CNS|BAM_PLF_GLF)) bam_maqcns_prepare(d->c); // consensus calling + if (d->format & BAM_PLF_GLF) { // for glf output + glf3_header_t *h; + h = glf3_header_init(); + d->fp_glf = bgzf_fdopen(fileno(stdout), "w"); + glf3_header_write(d->fp_glf, h); + glf3_header_destroy(h); + } + if (d->fai == 0 && (d->format & (BAM_PLF_CNS|BAM_PLF_INDEL_ONLY))) + fprintf(stderr, "[bam_pileup] indels will not be called when -f is absent.\n"); + if (fn_fa && is_SAM && fn_list == 0) fn_list = samfaipath(fn_fa); + + { + samfile_t *fp; + fp = is_SAM? samopen(argv[optind], "r", fn_list) : samopen(argv[optind], "rb", 0); + if (fp == 0 || fp->header == 0) { + fprintf(stderr, "[bam_pileup] fail to read the header: non-exisiting file or wrong format.\n"); + return 1; + } + d->h = fp->header; + if (fn_pos) d->hash = load_pos(fn_pos, d->h); + { // run pileup + extern int bam_prob_realn(bam1_t *b, const char *ref); + extern int bam_cap_mapQ(bam1_t *b, char *ref, int thres); + bam1_t *b; + int ret, tid, pos, n_plp; + bam_plp_t iter; + const bam_pileup1_t *plp; + b = bam_init1(); + iter = bam_plp_init(0, 0); + bam_plp_set_mask(iter, d->mask); + while ((ret = samread(fp, b)) >= 0) { + int skip = 0; + if ((int)b->core.tid < 0) break; + // update d->ref if necessary + if (d->fai && (int)b->core.tid != d->tid) { + free(d->ref); + d->ref = faidx_fetch_seq(d->fai, d->h->target_name[b->core.tid], 0, 0x7fffffff, &d->len); + d->tid = b->core.tid; + } + if (d->ref && (d->format&BAM_PLF_CNS) && !(d->format&BAM_PLF_NOBAQ)) bam_prob_realn(b, d->ref); + if (d->ref && (d->format&BAM_PLF_CNS) && d->capQ_thres > 10) { + int q = bam_cap_mapQ(b, d->ref, d->capQ_thres); + if (q < 0) skip = 1; + else if (b->core.qual > q) b->core.qual = q; + } else if (b->core.flag&BAM_FUNMAP) skip = 1; + else if ((d->format&BAM_PLF_CNS) && (b->core.flag&1) && !(b->core.flag&2)) skip = 1; + if (skip) continue; + bam_plp_push(iter, b); + while ((plp = bam_plp_next(iter, &tid, &pos, &n_plp)) != 0) + pileup_func(tid, pos, n_plp, plp, d); + } + bam_plp_push(iter, 0); + while ((plp = bam_plp_next(iter, &tid, &pos, &n_plp)) != 0) + pileup_func(tid, pos, n_plp, plp, d); + bam_plp_destroy(iter); + bam_destroy1(b); + } + samclose(fp); // d->h will be destroyed here + } + + // free + if (d->format & BAM_PLF_GLF) bgzf_close(d->fp_glf); + if (fn_pos) { // free the hash table + khint_t k; + for (k = kh_begin(d->hash); k < kh_end(d->hash); ++k) + if (kh_exist(d->hash, k)) free(kh_val(d->hash, k)); + kh_destroy(64, d->hash); + } + free(fn_pos); free(fn_list); free(fn_fa); + if (d->fai) fai_destroy(d->fai); + bam_maqcns_destroy(d->c); + free(d->ido); free(d->ref); free(d); + return 0; +} + +/*********** + * mpileup * + ***********/ + +#include <assert.h> +#include "bam2bcf.h" +#include "sample.h" + +#define MPLP_GLF 0x10 +#define MPLP_NO_COMP 0x20 +#define MPLP_NO_ORPHAN 0x40 +#define MPLP_REALN 0x80 +#define MPLP_FMT_DP 0x100 +#define MPLP_FMT_SP 0x200 +#define MPLP_NO_INDEL 0x400 +#define MPLP_EXT_BAQ 0x800 +#define MPLP_ILLUMINA13 0x1000 + +void *bed_read(const char *fn); +void bed_destroy(void *_h); +int bed_overlap(const void *_h, const char *chr, int beg, int end); + +typedef struct { + int max_mq, min_mq, flag, min_baseQ, capQ_thres, max_depth, max_indel_depth; + int openQ, extQ, tandemQ, min_support; // for indels + double min_frac; // for indels + char *reg, *pl_list; + faidx_t *fai; + void *bed, *rghash; +} mplp_conf_t; + +typedef struct { + bamFile fp; + bam_iter_t iter; + bam_header_t *h; + int ref_id; + char *ref; + const mplp_conf_t *conf; +} mplp_aux_t; + +typedef struct { + int n; + int *n_plp, *m_plp; + bam_pileup1_t **plp; +} mplp_pileup_t; + +static int mplp_func(void *data, bam1_t *b) +{ + extern int bam_realn(bam1_t *b, const char *ref); + extern int bam_prob_realn_core(bam1_t *b, const char *ref, int); + extern int bam_cap_mapQ(bam1_t *b, char *ref, int thres); + mplp_aux_t *ma = (mplp_aux_t*)data; + int ret, skip = 0; + do { + int has_ref; + ret = ma->iter? bam_iter_read(ma->fp, ma->iter, b) : bam_read1(ma->fp, b); + if (ret < 0) break; + if (b->core.tid < 0 || (b->core.flag&BAM_FUNMAP)) { // exclude unmapped reads + skip = 1; + continue; + } + if (ma->conf->bed) { // test overlap + skip = !bed_overlap(ma->conf->bed, ma->h->target_name[b->core.tid], b->core.pos, bam_calend(&b->core, bam1_cigar(b))); + if (skip) continue; + } + if (ma->conf->rghash) { // exclude read groups + uint8_t *rg = bam_aux_get(b, "RG"); + skip = (rg && bcf_str2id(ma->conf->rghash, (const char*)(rg+1)) >= 0); + if (skip) continue; + } + if (ma->conf->flag & MPLP_ILLUMINA13) { + int i; + uint8_t *qual = bam1_qual(b); + for (i = 0; i < b->core.l_qseq; ++i) + qual[i] = qual[i] > 31? qual[i] - 31 : 0; + } + has_ref = (ma->ref && ma->ref_id == b->core.tid)? 1 : 0; + skip = 0; + if (has_ref && (ma->conf->flag&MPLP_REALN)) bam_prob_realn_core(b, ma->ref, (ma->conf->flag & MPLP_EXT_BAQ)? 3 : 1); + if (has_ref && ma->conf->capQ_thres > 10) { + int q = bam_cap_mapQ(b, ma->ref, ma->conf->capQ_thres); + if (q < 0) skip = 1; + else if (b->core.qual > q) b->core.qual = q; + } + else if (b->core.qual < ma->conf->min_mq) skip = 1; + else if ((ma->conf->flag&MPLP_NO_ORPHAN) && (b->core.flag&1) && !(b->core.flag&2)) skip = 1; + } while (skip); + return ret; +} + +static void group_smpl(mplp_pileup_t *m, bam_sample_t *sm, kstring_t *buf, + int n, char *const*fn, int *n_plp, const bam_pileup1_t **plp) +{ + int i, j; + memset(m->n_plp, 0, m->n * sizeof(int)); + for (i = 0; i < n; ++i) { + for (j = 0; j < n_plp[i]; ++j) { + const bam_pileup1_t *p = plp[i] + j; + uint8_t *q; + int id = -1; + q = bam_aux_get(p->b, "RG"); + if (q) id = bam_smpl_rg2smid(sm, fn[i], (char*)q+1, buf); + if (id < 0) id = bam_smpl_rg2smid(sm, fn[i], 0, buf); + if (id < 0 || id >= m->n) { + assert(q); // otherwise a bug + fprintf(stderr, "[%s] Read group %s used in file %s but absent from the header or an alignment missing read group.\n", __func__, (char*)q+1, fn[i]); + exit(1); + } + if (m->n_plp[id] == m->m_plp[id]) { + m->m_plp[id] = m->m_plp[id]? m->m_plp[id]<<1 : 8; + m->plp[id] = realloc(m->plp[id], sizeof(bam_pileup1_t) * m->m_plp[id]); + } + m->plp[id][m->n_plp[id]++] = *p; + } + } +} + +static int mpileup(mplp_conf_t *conf, int n, char **fn) +{ + extern void *bcf_call_add_rg(void *rghash, const char *hdtext, const char *list); + extern void bcf_call_del_rghash(void *rghash); + mplp_aux_t **data; + int i, tid, pos, *n_plp, beg0 = 0, end0 = 1u<<29, ref_len, ref_tid, max_depth, max_indel_depth; + const bam_pileup1_t **plp; + bam_mplp_t iter; + bam_header_t *h = 0; + char *ref; + void *rghash = 0; + + bcf_callaux_t *bca = 0; + bcf_callret1_t *bcr = 0; + bcf_call_t bc; + bcf_t *bp = 0; + bcf_hdr_t *bh = 0; + + bam_sample_t *sm = 0; + kstring_t buf; + mplp_pileup_t gplp; + + memset(&gplp, 0, sizeof(mplp_pileup_t)); + memset(&buf, 0, sizeof(kstring_t)); + memset(&bc, 0, sizeof(bcf_call_t)); + data = calloc(n, sizeof(void*)); + plp = calloc(n, sizeof(void*)); + n_plp = calloc(n, sizeof(int*)); + sm = bam_smpl_init(); + + // read the header and initialize data + for (i = 0; i < n; ++i) { + bam_header_t *h_tmp; + data[i] = calloc(1, sizeof(mplp_aux_t)); + data[i]->fp = strcmp(fn[i], "-") == 0? bam_dopen(fileno(stdin), "r") : bam_open(fn[i], "r"); + data[i]->conf = conf; + h_tmp = bam_header_read(data[i]->fp); + data[i]->h = i? h : h_tmp; // for i==0, "h" has not been set yet + bam_smpl_add(sm, fn[i], h_tmp->text); + rghash = bcf_call_add_rg(rghash, h_tmp->text, conf->pl_list); + if (conf->reg) { + int beg, end; + bam_index_t *idx; + idx = bam_index_load(fn[i]); + if (idx == 0) { + fprintf(stderr, "[%s] fail to load index for %d-th input.\n", __func__, i+1); + exit(1); + } + if (bam_parse_region(h_tmp, conf->reg, &tid, &beg, &end) < 0) { + fprintf(stderr, "[%s] malformatted region or wrong seqname for %d-th input.\n", __func__, i+1); + exit(1); + } + if (i == 0) beg0 = beg, end0 = end; + data[i]->iter = bam_iter_query(idx, tid, beg, end); + bam_index_destroy(idx); + } + if (i == 0) h = h_tmp; + else { + // FIXME: to check consistency + bam_header_destroy(h_tmp); + } + } + gplp.n = sm->n; + gplp.n_plp = calloc(sm->n, sizeof(int)); + gplp.m_plp = calloc(sm->n, sizeof(int)); + gplp.plp = calloc(sm->n, sizeof(void*)); + + fprintf(stderr, "[%s] %d samples in %d input files\n", __func__, sm->n, n); + // write the VCF header + if (conf->flag & MPLP_GLF) { + kstring_t s; + bh = calloc(1, sizeof(bcf_hdr_t)); + s.l = s.m = 0; s.s = 0; + bp = bcf_open("-", (conf->flag&MPLP_NO_COMP)? "wu" : "w"); + for (i = 0; i < h->n_targets; ++i) { + kputs(h->target_name[i], &s); + kputc('\0', &s); + } + bh->l_nm = s.l; + bh->name = malloc(s.l); + memcpy(bh->name, s.s, s.l); + s.l = 0; + for (i = 0; i < sm->n; ++i) { + kputs(sm->smpl[i], &s); kputc('\0', &s); + } + bh->l_smpl = s.l; + bh->sname = malloc(s.l); + memcpy(bh->sname, s.s, s.l); + bh->txt = malloc(strlen(BAM_VERSION) + 64); + bh->l_txt = 1 + sprintf(bh->txt, "##samtoolsVersion=%s\n", BAM_VERSION); + free(s.s); + bcf_hdr_sync(bh); + bcf_hdr_write(bp, bh); + bca = bcf_call_init(-1., conf->min_baseQ); + bcr = calloc(sm->n, sizeof(bcf_callret1_t)); + bca->rghash = rghash; + bca->openQ = conf->openQ, bca->extQ = conf->extQ, bca->tandemQ = conf->tandemQ; + bca->min_frac = conf->min_frac; + bca->min_support = conf->min_support; + } + ref_tid = -1; ref = 0; + iter = bam_mplp_init(n, mplp_func, (void**)data); + max_depth = conf->max_depth; + if (max_depth * sm->n > 1<<20) + fprintf(stderr, "(%s) Max depth is above 1M. Potential memory hog!\n", __func__); + if (max_depth * sm->n < 8000) { + max_depth = 8000 / sm->n; + fprintf(stderr, "<%s> Set max per-file depth to %d\n", __func__, max_depth); + } + max_indel_depth = conf->max_indel_depth * sm->n; + bam_mplp_set_maxcnt(iter, max_depth); + while (bam_mplp_auto(iter, &tid, &pos, n_plp, plp) > 0) { + if (conf->reg && (pos < beg0 || pos >= end0)) continue; // out of the region requested + if (conf->bed && tid >= 0 && !bed_overlap(conf->bed, h->target_name[tid], pos, pos+1)) continue; + if (tid != ref_tid) { + free(ref); ref = 0; + if (conf->fai) ref = fai_fetch(conf->fai, h->target_name[tid], &ref_len); + for (i = 0; i < n; ++i) data[i]->ref = ref, data[i]->ref_id = tid; + ref_tid = tid; + } + if (conf->flag & MPLP_GLF) { + int total_depth, _ref0, ref16; + bcf1_t *b = calloc(1, sizeof(bcf1_t)); + for (i = total_depth = 0; i < n; ++i) total_depth += n_plp[i]; + group_smpl(&gplp, sm, &buf, n, fn, n_plp, plp); + _ref0 = (ref && pos < ref_len)? ref[pos] : 'N'; + ref16 = bam_nt16_table[_ref0]; + for (i = 0; i < gplp.n; ++i) + bcf_call_glfgen(gplp.n_plp[i], gplp.plp[i], ref16, bca, bcr + i); + bcf_call_combine(gplp.n, bcr, ref16, &bc); + bcf_call2bcf(tid, pos, &bc, b, (conf->flag&(MPLP_FMT_DP|MPLP_FMT_SP))? bcr : 0, + (conf->flag&MPLP_FMT_SP), 0, 0); + bcf_write(bp, bh, b); + bcf_destroy(b); + // call indels + if (!(conf->flag&MPLP_NO_INDEL) && total_depth < max_indel_depth && bcf_call_gap_prep(gplp.n, gplp.n_plp, gplp.plp, pos, bca, ref, rghash) >= 0) { + for (i = 0; i < gplp.n; ++i) + bcf_call_glfgen(gplp.n_plp[i], gplp.plp[i], -1, bca, bcr + i); + if (bcf_call_combine(gplp.n, bcr, -1, &bc) >= 0) { + b = calloc(1, sizeof(bcf1_t)); + bcf_call2bcf(tid, pos, &bc, b, (conf->flag&(MPLP_FMT_DP|MPLP_FMT_SP))? bcr : 0, + (conf->flag&MPLP_FMT_SP), bca, ref); + bcf_write(bp, bh, b); + bcf_destroy(b); + } + } + } else { + printf("%s\t%d\t%c", h->target_name[tid], pos + 1, (ref && pos < ref_len)? ref[pos] : 'N'); + for (i = 0; i < n; ++i) { + int j; + printf("\t%d\t", n_plp[i]); + if (n_plp[i] == 0) printf("*\t*"); + else { + for (j = 0; j < n_plp[i]; ++j) + pileup_seq(plp[i] + j, pos, ref_len, ref); + putchar('\t'); + for (j = 0; j < n_plp[i]; ++j) { + const bam_pileup1_t *p = plp[i] + j; + int c = bam1_qual(p->b)[p->qpos] + 33; + if (c > 126) c = 126; + putchar(c); + } + } + } + putchar('\n'); + } + } + + bcf_close(bp); + bam_smpl_destroy(sm); free(buf.s); + for (i = 0; i < gplp.n; ++i) free(gplp.plp[i]); + free(gplp.plp); free(gplp.n_plp); free(gplp.m_plp); + bcf_call_del_rghash(rghash); + bcf_hdr_destroy(bh); bcf_call_destroy(bca); free(bc.PL); free(bcr); + bam_mplp_destroy(iter); + bam_header_destroy(h); + for (i = 0; i < n; ++i) { + bam_close(data[i]->fp); + if (data[i]->iter) bam_iter_destroy(data[i]->iter); + free(data[i]); + } + free(data); free(plp); free(ref); free(n_plp); + return 0; +} + +#define MAX_PATH_LEN 1024 +static int read_file_list(const char *file_list,int *n,char **argv[]) +{ + char buf[MAX_PATH_LEN]; + int len, nfiles; + char **files; + + FILE *fh = fopen(file_list,"r"); + if ( !fh ) + { + fprintf(stderr,"%s: %s\n", file_list,strerror(errno)); + return 1; + } + + // Speed is not an issue here, determine the number of files by reading the file twice + nfiles = 0; + while ( fgets(buf,MAX_PATH_LEN,fh) ) nfiles++; + + if ( fseek(fh, 0L, SEEK_SET) ) + { + fprintf(stderr,"%s: %s\n", file_list,strerror(errno)); + return 1; + } + + files = calloc(nfiles,sizeof(char*)); + nfiles = 0; + while ( fgets(buf,MAX_PATH_LEN,fh) ) + { + len = strlen(buf); + while ( len>0 && isspace(buf[len-1]) ) len--; + if ( !len ) continue; + + files[nfiles] = malloc(sizeof(char)*(len+1)); + strncpy(files[nfiles],buf,len); + files[nfiles][len] = 0; + nfiles++; + } + fclose(fh); + if ( !nfiles ) + { + fprintf(stderr,"No files read from %s\n", file_list); + return 1; + } + *argv = files; + *n = nfiles; + return 0; +} +#undef MAX_PATH_LEN + +int bam_mpileup(int argc, char *argv[]) +{ + int c; + const char *file_list = NULL; + char **fn = NULL; + int nfiles = 0, use_orphan = 0; + mplp_conf_t mplp; + memset(&mplp, 0, sizeof(mplp_conf_t)); + mplp.max_mq = 60; + mplp.min_baseQ = 13; + mplp.capQ_thres = 0; + mplp.max_depth = 250; mplp.max_indel_depth = 250; + mplp.openQ = 40; mplp.extQ = 20; mplp.tandemQ = 100; + mplp.min_frac = 0.002; mplp.min_support = 1; + mplp.flag = MPLP_NO_ORPHAN | MPLP_REALN; + while ((c = getopt(argc, argv, "Agf:r:l:M:q:Q:uaRC:BDSd:L:b:P:o:e:h:Im:F:EG:6")) >= 0) { + switch (c) { + case 'f': + mplp.fai = fai_load(optarg); + if (mplp.fai == 0) return 1; + break; + case 'd': mplp.max_depth = atoi(optarg); break; + case 'r': mplp.reg = strdup(optarg); break; + case 'l': mplp.bed = bed_read(optarg); break; + case 'P': mplp.pl_list = strdup(optarg); break; + case 'g': mplp.flag |= MPLP_GLF; break; + case 'u': mplp.flag |= MPLP_NO_COMP | MPLP_GLF; break; + case 'a': mplp.flag |= MPLP_NO_ORPHAN | MPLP_REALN; break; + case 'B': mplp.flag &= ~MPLP_REALN; break; + case 'R': mplp.flag |= MPLP_REALN; break; + case 'D': mplp.flag |= MPLP_FMT_DP; break; + case 'S': mplp.flag |= MPLP_FMT_SP; break; + case 'I': mplp.flag |= MPLP_NO_INDEL; break; + case 'E': mplp.flag |= MPLP_EXT_BAQ; break; + case '6': mplp.flag |= MPLP_ILLUMINA13; break; + case 'C': mplp.capQ_thres = atoi(optarg); break; + case 'M': mplp.max_mq = atoi(optarg); break; + case 'q': mplp.min_mq = atoi(optarg); break; + case 'Q': mplp.min_baseQ = atoi(optarg); break; + case 'b': file_list = optarg; break; + case 'o': mplp.openQ = atoi(optarg); break; + case 'e': mplp.extQ = atoi(optarg); break; + case 'h': mplp.tandemQ = atoi(optarg); break; + case 'A': use_orphan = 1; break; + case 'F': mplp.min_frac = atof(optarg); break; + case 'm': mplp.min_support = atoi(optarg); break; + case 'L': mplp.max_indel_depth = atoi(optarg); break; + case 'G': { + FILE *fp_rg; + char buf[1024]; + mplp.rghash = bcf_str2id_init(); + if ((fp_rg = fopen(optarg, "r")) == 0) + fprintf(stderr, "(%s) Fail to open file %s. Continue anyway.\n", __func__, optarg); + while (!feof(fp_rg) && fscanf(fp_rg, "%s", buf) > 0) // this is not a good style, but forgive me... + bcf_str2id_add(mplp.rghash, strdup(buf)); + fclose(fp_rg); + } + break; + } + } + if (use_orphan) mplp.flag &= ~MPLP_NO_ORPHAN; + if (argc == 1) { + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: samtools mpileup [options] in1.bam [in2.bam [...]]\n\n"); + fprintf(stderr, "Input options:\n\n"); + fprintf(stderr, " -6 assume the quality is in the Illumina-1.3+ encoding\n"); + fprintf(stderr, " -A count anomalous read pairs\n"); + fprintf(stderr, " -B disable BAQ computation\n"); + fprintf(stderr, " -b FILE list of input BAM files [null]\n"); + fprintf(stderr, " -d INT max per-BAM depth to avoid excessive memory usage [%d]\n", mplp.max_depth); + fprintf(stderr, " -E extended BAQ for higher sensitivity but lower specificity\n"); + fprintf(stderr, " -f FILE faidx indexed reference sequence file [null]\n"); + fprintf(stderr, " -G FILE exclude read groups listed in FILE [null]\n"); + fprintf(stderr, " -l FILE list of positions (chr pos) or regions (BED) [null]\n"); + fprintf(stderr, " -M INT cap mapping quality at INT [%d]\n", mplp.max_mq); + fprintf(stderr, " -r STR region in which pileup is generated [null]\n"); + fprintf(stderr, " -q INT skip alignments with mapQ smaller than INT [%d]\n", mplp.min_mq); + fprintf(stderr, " -Q INT skip bases with baseQ/BAQ smaller than INT [%d]\n", mplp.min_baseQ); + fprintf(stderr, "\nOutput options:\n\n"); + fprintf(stderr, " -D output per-sample DP in BCF (require -g/-u)\n"); + fprintf(stderr, " -g generate BCF output (genotype likelihoods)\n"); + fprintf(stderr, " -S output per-sample strand bias P-value in BCF (require -g/-u)\n"); + fprintf(stderr, " -u generate uncompress BCF output\n"); + fprintf(stderr, "\nSNP/INDEL genotype likelihoods options (effective with `-g' or `-u'):\n\n"); + fprintf(stderr, " -e INT Phred-scaled gap extension seq error probability [%d]\n", mplp.extQ); + fprintf(stderr, " -F FLOAT minimum fraction of gapped reads for candidates [%g]\n", mplp.min_frac); + fprintf(stderr, " -h INT coefficient for homopolymer errors [%d]\n", mplp.tandemQ); + fprintf(stderr, " -I do not perform indel calling\n"); + fprintf(stderr, " -L INT max per-sample depth for INDEL calling [%d]\n", mplp.max_indel_depth); + fprintf(stderr, " -m INT minimum gapped reads for indel candidates [%d]\n", mplp.min_support); + fprintf(stderr, " -o INT Phred-scaled gap open sequencing error probability [%d]\n", mplp.openQ); + fprintf(stderr, " -P STR comma separated list of platforms for indels [all]\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "Notes: Assuming diploid individuals.\n\n"); + return 1; + } + if (file_list) { + if ( read_file_list(file_list,&nfiles,&fn) ) return 1; + mpileup(&mplp,nfiles,fn); + for (c=0; c<nfiles; c++) free(fn[c]); + free(fn); + } else mpileup(&mplp, argc - optind, argv + optind); + if (mplp.rghash) bcf_str2id_thorough_destroy(mplp.rghash); + free(mplp.reg); free(mplp.pl_list); + if (mplp.fai) fai_destroy(mplp.fai); + if (mplp.bed) bed_destroy(mplp.bed); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam_reheader.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,61 @@ +#include <stdio.h> +#include <stdlib.h> +#include "bgzf.h" +#include "bam.h" + +#define BUF_SIZE 0x10000 + +int bam_reheader(BGZF *in, const bam_header_t *h, int fd) +{ + BGZF *fp; + bam_header_t *old; + int len; + uint8_t *buf; + if (in->open_mode != 'r') return -1; + buf = malloc(BUF_SIZE); + old = bam_header_read(in); + fp = bgzf_fdopen(fd, "w"); + bam_header_write(fp, h); + if (in->block_offset < in->block_length) { + bgzf_write(fp, in->uncompressed_block + in->block_offset, in->block_length - in->block_offset); + bgzf_flush(fp); + } +#ifdef _USE_KNETFILE + while ((len = knet_read(in->x.fpr, buf, BUF_SIZE)) > 0) + fwrite(buf, 1, len, fp->x.fpw); +#else + while (!feof(in->file) && (len = fread(buf, 1, BUF_SIZE, in->file)) > 0) + fwrite(buf, 1, len, fp->file); +#endif + free(buf); + fp->block_offset = in->block_offset = 0; + bgzf_close(fp); + return 0; +} + +int main_reheader(int argc, char *argv[]) +{ + bam_header_t *h; + BGZF *in; + if (argc != 3) { + fprintf(stderr, "Usage: samtools reheader <in.header.sam> <in.bam>\n"); + return 1; + } + { // read the header + tamFile fph = sam_open(argv[1]); + if (fph == 0) { + fprintf(stderr, "[%s] fail to read the header from %s.\n", __func__, argv[1]); + return 1; + } + h = sam_header_read(fph); + sam_close(fph); + } + in = strcmp(argv[2], "-")? bam_open(argv[2], "r") : bam_dopen(fileno(stdin), "r"); + if (in == 0) { + fprintf(stderr, "[%s] fail to open file %s.\n", __func__, argv[2]); + return 1; + } + bam_reheader(in, h, fileno(stdout)); + bgzf_close(in); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam_rmdup.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,206 @@ +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <zlib.h> +#include <unistd.h> +#include "sam.h" + +typedef bam1_t *bam1_p; + +#include "khash.h" +KHASH_SET_INIT_STR(name) +KHASH_MAP_INIT_INT64(pos, bam1_p) + +#define BUFFER_SIZE 0x40000 + +typedef struct { + uint64_t n_checked, n_removed; + khash_t(pos) *best_hash; +} lib_aux_t; +KHASH_MAP_INIT_STR(lib, lib_aux_t) + +typedef struct { + int n, max; + bam1_t **a; +} tmp_stack_t; + +static inline void stack_insert(tmp_stack_t *stack, bam1_t *b) +{ + if (stack->n == stack->max) { + stack->max = stack->max? stack->max<<1 : 0x10000; + stack->a = (bam1_t**)realloc(stack->a, sizeof(bam1_t*) * stack->max); + } + stack->a[stack->n++] = b; +} + +static inline void dump_best(tmp_stack_t *stack, samfile_t *out) +{ + int i; + for (i = 0; i != stack->n; ++i) { + samwrite(out, stack->a[i]); + bam_destroy1(stack->a[i]); + } + stack->n = 0; +} + +static void clear_del_set(khash_t(name) *del_set) +{ + khint_t k; + for (k = kh_begin(del_set); k < kh_end(del_set); ++k) + if (kh_exist(del_set, k)) + free((char*)kh_key(del_set, k)); + kh_clear(name, del_set); +} + +static lib_aux_t *get_aux(khash_t(lib) *aux, const char *lib) +{ + khint_t k = kh_get(lib, aux, lib); + if (k == kh_end(aux)) { + int ret; + char *p = strdup(lib); + lib_aux_t *q; + k = kh_put(lib, aux, p, &ret); + q = &kh_val(aux, k); + q->n_checked = q->n_removed = 0; + q->best_hash = kh_init(pos); + return q; + } else return &kh_val(aux, k); +} + +static void clear_best(khash_t(lib) *aux, int max) +{ + khint_t k; + for (k = kh_begin(aux); k != kh_end(aux); ++k) { + if (kh_exist(aux, k)) { + lib_aux_t *q = &kh_val(aux, k); + if (kh_size(q->best_hash) >= max) + kh_clear(pos, q->best_hash); + } + } +} + +static inline int sum_qual(const bam1_t *b) +{ + int i, q; + uint8_t *qual = bam1_qual(b); + for (i = q = 0; i < b->core.l_qseq; ++i) q += qual[i]; + return q; +} + +void bam_rmdup_core(samfile_t *in, samfile_t *out) +{ + bam1_t *b; + int last_tid = -1, last_pos = -1; + tmp_stack_t stack; + khint_t k; + khash_t(lib) *aux; + khash_t(name) *del_set; + + aux = kh_init(lib); + del_set = kh_init(name); + b = bam_init1(); + memset(&stack, 0, sizeof(tmp_stack_t)); + + kh_resize(name, del_set, 4 * BUFFER_SIZE); + while (samread(in, b) >= 0) { + bam1_core_t *c = &b->core; + if (c->tid != last_tid || last_pos != c->pos) { + dump_best(&stack, out); // write the result + clear_best(aux, BUFFER_SIZE); + if (c->tid != last_tid) { + clear_best(aux, 0); + if (kh_size(del_set)) { // check + fprintf(stderr, "[bam_rmdup_core] %llu unmatched pairs\n", (long long)kh_size(del_set)); + clear_del_set(del_set); + } + if ((int)c->tid == -1) { // append unmapped reads + samwrite(out, b); + while (samread(in, b) >= 0) samwrite(out, b); + break; + } + last_tid = c->tid; + fprintf(stderr, "[bam_rmdup_core] processing reference %s...\n", in->header->target_name[c->tid]); + } + } + if (!(c->flag&BAM_FPAIRED) || (c->flag&(BAM_FUNMAP|BAM_FMUNMAP)) || (c->mtid >= 0 && c->tid != c->mtid)) { + samwrite(out, b); + } else if (c->isize > 0) { // paired, head + uint64_t key = (uint64_t)c->pos<<32 | c->isize; + const char *lib; + lib_aux_t *q; + int ret; + lib = bam_get_library(in->header, b); + q = lib? get_aux(aux, lib) : get_aux(aux, "\t"); + ++q->n_checked; + k = kh_put(pos, q->best_hash, key, &ret); + if (ret == 0) { // found in best_hash + bam1_t *p = kh_val(q->best_hash, k); + ++q->n_removed; + if (sum_qual(p) < sum_qual(b)) { // the current alignment is better; this can be accelerated in principle + kh_put(name, del_set, strdup(bam1_qname(p)), &ret); // p will be removed + bam_copy1(p, b); // replaced as b + } else kh_put(name, del_set, strdup(bam1_qname(b)), &ret); // b will be removed + if (ret == 0) + fprintf(stderr, "[bam_rmdup_core] inconsistent BAM file for pair '%s'. Continue anyway.\n", bam1_qname(b)); + } else { // not found in best_hash + kh_val(q->best_hash, k) = bam_dup1(b); + stack_insert(&stack, kh_val(q->best_hash, k)); + } + } else { // paired, tail + k = kh_get(name, del_set, bam1_qname(b)); + if (k != kh_end(del_set)) { + free((char*)kh_key(del_set, k)); + kh_del(name, del_set, k); + } else samwrite(out, b); + } + last_pos = c->pos; + } + + for (k = kh_begin(aux); k != kh_end(aux); ++k) { + if (kh_exist(aux, k)) { + lib_aux_t *q = &kh_val(aux, k); + dump_best(&stack, out); + fprintf(stderr, "[bam_rmdup_core] %lld / %lld = %.4lf in library '%s'\n", (long long)q->n_removed, + (long long)q->n_checked, (double)q->n_removed/q->n_checked, kh_key(aux, k)); + kh_destroy(pos, q->best_hash); + free((char*)kh_key(aux, k)); + } + } + kh_destroy(lib, aux); + + clear_del_set(del_set); + kh_destroy(name, del_set); + free(stack.a); + bam_destroy1(b); +} + +void bam_rmdupse_core(samfile_t *in, samfile_t *out, int force_se); + +int bam_rmdup(int argc, char *argv[]) +{ + int c, is_se = 0, force_se = 0; + samfile_t *in, *out; + while ((c = getopt(argc, argv, "sS")) >= 0) { + switch (c) { + case 's': is_se = 1; break; + case 'S': force_se = is_se = 1; break; + } + } + if (optind + 2 > argc) { + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: samtools rmdup [-sS] <input.srt.bam> <output.bam>\n\n"); + fprintf(stderr, "Option: -s rmdup for SE reads\n"); + fprintf(stderr, " -S treat PE reads as SE in rmdup (force -s)\n\n"); + return 1; + } + in = samopen(argv[optind], "rb", 0); + out = samopen(argv[optind+1], "wb", in->header); + if (in == 0 || out == 0) { + fprintf(stderr, "[bam_rmdup] fail to read/write input files\n"); + return 1; + } + if (is_se) bam_rmdupse_core(in, out, force_se); + else bam_rmdup_core(in, out); + samclose(in); samclose(out); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam_rmdupse.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,159 @@ +#include <math.h> +#include "sam.h" +#include "khash.h" +#include "klist.h" + +#define QUEUE_CLEAR_SIZE 0x100000 +#define MAX_POS 0x7fffffff + +typedef struct { + int endpos; + uint32_t score:31, discarded:1; + bam1_t *b; +} elem_t, *elem_p; +#define __free_elem(p) bam_destroy1((p)->data.b) +KLIST_INIT(q, elem_t, __free_elem) +typedef klist_t(q) queue_t; + +KHASH_MAP_INIT_INT(best, elem_p) +typedef khash_t(best) besthash_t; + +typedef struct { + uint64_t n_checked, n_removed; + besthash_t *left, *rght; +} lib_aux_t; +KHASH_MAP_INIT_STR(lib, lib_aux_t) + +static lib_aux_t *get_aux(khash_t(lib) *aux, const char *lib) +{ + khint_t k = kh_get(lib, aux, lib); + if (k == kh_end(aux)) { + int ret; + char *p = strdup(lib); + lib_aux_t *q; + k = kh_put(lib, aux, p, &ret); + q = &kh_val(aux, k); + q->left = kh_init(best); + q->rght = kh_init(best); + q->n_checked = q->n_removed = 0; + return q; + } else return &kh_val(aux, k); +} + +static inline int sum_qual(const bam1_t *b) +{ + int i, q; + uint8_t *qual = bam1_qual(b); + for (i = q = 0; i < b->core.l_qseq; ++i) q += qual[i]; + return q; +} + +static inline elem_t *push_queue(queue_t *queue, const bam1_t *b, int endpos, int score) +{ + elem_t *p = kl_pushp(q, queue); + p->discarded = 0; + p->endpos = endpos; p->score = score; + if (p->b == 0) p->b = bam_init1(); + bam_copy1(p->b, b); + return p; +} + +static void clear_besthash(besthash_t *h, int32_t pos) +{ + khint_t k; + for (k = kh_begin(h); k != kh_end(h); ++k) + if (kh_exist(h, k) && kh_val(h, k)->endpos <= pos) + kh_del(best, h, k); +} + +static void dump_alignment(samfile_t *out, queue_t *queue, int32_t pos, khash_t(lib) *h) +{ + if (queue->size > QUEUE_CLEAR_SIZE || pos == MAX_POS) { + khint_t k; + while (1) { + elem_t *q; + if (queue->head == queue->tail) break; + q = &kl_val(queue->head); + if (q->discarded) { + q->b->data_len = 0; + kl_shift(q, queue, 0); + continue; + } + if ((q->b->core.flag&BAM_FREVERSE) && q->endpos > pos) break; + samwrite(out, q->b); + q->b->data_len = 0; + kl_shift(q, queue, 0); + } + for (k = kh_begin(h); k != kh_end(h); ++k) { + if (kh_exist(h, k)) { + clear_besthash(kh_val(h, k).left, pos); + clear_besthash(kh_val(h, k).rght, pos); + } + } + } +} + +void bam_rmdupse_core(samfile_t *in, samfile_t *out, int force_se) +{ + bam1_t *b; + queue_t *queue; + khint_t k; + int last_tid = -2; + khash_t(lib) *aux; + + aux = kh_init(lib); + b = bam_init1(); + queue = kl_init(q); + while (samread(in, b) >= 0) { + bam1_core_t *c = &b->core; + int endpos = bam_calend(c, bam1_cigar(b)); + int score = sum_qual(b); + + if (last_tid != c->tid) { + if (last_tid >= 0) dump_alignment(out, queue, MAX_POS, aux); + last_tid = c->tid; + } else dump_alignment(out, queue, c->pos, aux); + if ((c->flag&BAM_FUNMAP) || ((c->flag&BAM_FPAIRED) && !force_se)) { + push_queue(queue, b, endpos, score); + } else { + const char *lib; + lib_aux_t *q; + besthash_t *h; + uint32_t key; + int ret; + lib = bam_get_library(in->header, b); + q = lib? get_aux(aux, lib) : get_aux(aux, "\t"); + ++q->n_checked; + h = (c->flag&BAM_FREVERSE)? q->rght : q->left; + key = (c->flag&BAM_FREVERSE)? endpos : c->pos; + k = kh_put(best, h, key, &ret); + if (ret == 0) { // in the hash table + elem_t *p = kh_val(h, k); + ++q->n_removed; + if (p->score < score) { + if (c->flag&BAM_FREVERSE) { // mark "discarded" and push the queue + p->discarded = 1; + kh_val(h, k) = push_queue(queue, b, endpos, score); + } else { // replace + p->score = score; p->endpos = endpos; + bam_copy1(p->b, b); + } + } // otherwise, discard the alignment + } else kh_val(h, k) = push_queue(queue, b, endpos, score); + } + } + dump_alignment(out, queue, MAX_POS, aux); + + for (k = kh_begin(aux); k != kh_end(aux); ++k) { + if (kh_exist(aux, k)) { + lib_aux_t *q = &kh_val(aux, k); + fprintf(stderr, "[bam_rmdupse_core] %lld / %lld = %.4lf in library '%s'\n", (long long)q->n_removed, + (long long)q->n_checked, (double)q->n_removed/q->n_checked, kh_key(aux, k)); + kh_destroy(best, q->left); kh_destroy(best, q->rght); + free((char*)kh_key(aux, k)); + } + } + kh_destroy(lib, aux); + bam_destroy1(b); + kl_destroy(q, queue); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam_sort.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,438 @@ +#include <stdlib.h> +#include <ctype.h> +#include <assert.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include "bam.h" +#include "ksort.h" + +static int g_is_by_qname = 0; + +static inline int strnum_cmp(const char *a, const char *b) +{ + char *pa, *pb; + pa = (char*)a; pb = (char*)b; + while (*pa && *pb) { + if (isdigit(*pa) && isdigit(*pb)) { + long ai, bi; + ai = strtol(pa, &pa, 10); + bi = strtol(pb, &pb, 10); + if (ai != bi) return ai<bi? -1 : ai>bi? 1 : 0; + } else { + if (*pa != *pb) break; + ++pa; ++pb; + } + } + if (*pa == *pb) + return (pa-a) < (pb-b)? -1 : (pa-a) > (pb-b)? 1 : 0; + return *pa<*pb? -1 : *pa>*pb? 1 : 0; +} + +#define HEAP_EMPTY 0xffffffffffffffffull + +typedef struct { + int i; + uint64_t pos, idx; + bam1_t *b; +} heap1_t; + +#define __pos_cmp(a, b) ((a).pos > (b).pos || ((a).pos == (b).pos && ((a).i > (b).i || ((a).i == (b).i && (a).idx > (b).idx)))) + +static inline int heap_lt(const heap1_t a, const heap1_t b) +{ + if (g_is_by_qname) { + int t; + if (a.b == 0 || b.b == 0) return a.b == 0? 1 : 0; + t = strnum_cmp(bam1_qname(a.b), bam1_qname(b.b)); + return (t > 0 || (t == 0 && __pos_cmp(a, b))); + } else return __pos_cmp(a, b); +} + +KSORT_INIT(heap, heap1_t, heap_lt) + +static void swap_header_targets(bam_header_t *h1, bam_header_t *h2) +{ + bam_header_t t; + t.n_targets = h1->n_targets, h1->n_targets = h2->n_targets, h2->n_targets = t.n_targets; + t.target_name = h1->target_name, h1->target_name = h2->target_name, h2->target_name = t.target_name; + t.target_len = h1->target_len, h1->target_len = h2->target_len, h2->target_len = t.target_len; +} + +static void swap_header_text(bam_header_t *h1, bam_header_t *h2) +{ + int tempi; + char *temps; + tempi = h1->l_text, h1->l_text = h2->l_text, h2->l_text = tempi; + temps = h1->text, h1->text = h2->text, h2->text = temps; +} + +#define MERGE_RG 1 +#define MERGE_UNCOMP 2 +#define MERGE_LEVEL1 4 +#define MERGE_FORCE 8 + +/*! + @abstract Merge multiple sorted BAM. + @param is_by_qname whether to sort by query name + @param out output BAM file name + @param headers name of SAM file from which to copy '@' header lines, + or NULL to copy them from the first file to be merged + @param n number of files to be merged + @param fn names of files to be merged + + @discussion Padding information may NOT correctly maintained. This + function is NOT thread safe. + */ +int bam_merge_core(int by_qname, const char *out, const char *headers, int n, char * const *fn, + int flag, const char *reg) +{ + bamFile fpout, *fp; + heap1_t *heap; + bam_header_t *hout = 0; + bam_header_t *hheaders = NULL; + int i, j, *RG_len = 0; + uint64_t idx = 0; + char **RG = 0; + bam_iter_t *iter = 0; + + if (headers) { + tamFile fpheaders = sam_open(headers); + if (fpheaders == 0) { + const char *message = strerror(errno); + fprintf(stderr, "[bam_merge_core] cannot open '%s': %s\n", headers, message); + return -1; + } + hheaders = sam_header_read(fpheaders); + sam_close(fpheaders); + } + + g_is_by_qname = by_qname; + fp = (bamFile*)calloc(n, sizeof(bamFile)); + heap = (heap1_t*)calloc(n, sizeof(heap1_t)); + iter = (bam_iter_t*)calloc(n, sizeof(bam_iter_t)); + // prepare RG tag + if (flag & MERGE_RG) { + RG = (char**)calloc(n, sizeof(void*)); + RG_len = (int*)calloc(n, sizeof(int)); + for (i = 0; i != n; ++i) { + int l = strlen(fn[i]); + const char *s = fn[i]; + if (l > 4 && strcmp(s + l - 4, ".bam") == 0) l -= 4; + for (j = l - 1; j >= 0; --j) if (s[j] == '/') break; + ++j; l -= j; + RG[i] = calloc(l + 1, 1); + RG_len[i] = l; + strncpy(RG[i], s + j, l); + } + } + // read the first + for (i = 0; i != n; ++i) { + bam_header_t *hin; + fp[i] = bam_open(fn[i], "r"); + if (fp[i] == 0) { + int j; + fprintf(stderr, "[bam_merge_core] fail to open file %s\n", fn[i]); + for (j = 0; j < i; ++j) bam_close(fp[j]); + free(fp); free(heap); + // FIXME: possible memory leak + return -1; + } + hin = bam_header_read(fp[i]); + if (i == 0) { // the first BAM + hout = hin; + } else { // validate multiple baf + int min_n_targets = hout->n_targets; + if (hin->n_targets < min_n_targets) min_n_targets = hin->n_targets; + + for (j = 0; j < min_n_targets; ++j) + if (strcmp(hout->target_name[j], hin->target_name[j]) != 0) { + fprintf(stderr, "[bam_merge_core] different target sequence name: '%s' != '%s' in file '%s'\n", + hout->target_name[j], hin->target_name[j], fn[i]); + return -1; + } + + // If this input file has additional target reference sequences, + // add them to the headers to be output + if (hin->n_targets > hout->n_targets) { + swap_header_targets(hout, hin); + // FIXME Possibly we should also create @SQ text headers + // for the newly added reference sequences + } + + bam_header_destroy(hin); + } + } + + if (hheaders) { + // If the text headers to be swapped in include any @SQ headers, + // check that they are consistent with the existing binary list + // of reference information. + if (hheaders->n_targets > 0) { + if (hout->n_targets != hheaders->n_targets) { + fprintf(stderr, "[bam_merge_core] number of @SQ headers in '%s' differs from number of target sequences\n", headers); + if (!reg) return -1; + } + for (j = 0; j < hout->n_targets; ++j) + if (strcmp(hout->target_name[j], hheaders->target_name[j]) != 0) { + fprintf(stderr, "[bam_merge_core] @SQ header '%s' in '%s' differs from target sequence\n", hheaders->target_name[j], headers); + if (!reg) return -1; + } + } + + swap_header_text(hout, hheaders); + bam_header_destroy(hheaders); + } + + if (reg) { + int tid, beg, end; + if (bam_parse_region(hout, reg, &tid, &beg, &end) < 0) { + fprintf(stderr, "[%s] Malformated region string or undefined reference name\n", __func__); + return -1; + } + for (i = 0; i < n; ++i) { + bam_index_t *idx; + idx = bam_index_load(fn[i]); + iter[i] = bam_iter_query(idx, tid, beg, end); + bam_index_destroy(idx); + } + } + + for (i = 0; i < n; ++i) { + heap1_t *h = heap + i; + h->i = i; + h->b = (bam1_t*)calloc(1, sizeof(bam1_t)); + if (bam_iter_read(fp[i], iter[i], h->b) >= 0) { + h->pos = ((uint64_t)h->b->core.tid<<32) | (uint32_t)((int32_t)h->b->core.pos+1)<<1 | bam1_strand(h->b); + h->idx = idx++; + } + else h->pos = HEAP_EMPTY; + } + if (flag & MERGE_UNCOMP) fpout = strcmp(out, "-")? bam_open(out, "wu") : bam_dopen(fileno(stdout), "wu"); + else if (flag & MERGE_LEVEL1) fpout = strcmp(out, "-")? bam_open(out, "w1") : bam_dopen(fileno(stdout), "w1"); + else fpout = strcmp(out, "-")? bam_open(out, "w") : bam_dopen(fileno(stdout), "w"); + if (fpout == 0) { + fprintf(stderr, "[%s] fail to create the output file.\n", __func__); + return -1; + } + bam_header_write(fpout, hout); + bam_header_destroy(hout); + + ks_heapmake(heap, n, heap); + while (heap->pos != HEAP_EMPTY) { + bam1_t *b = heap->b; + if (flag & MERGE_RG) { + uint8_t *rg = bam_aux_get(b, "RG"); + if (rg) bam_aux_del(b, rg); + bam_aux_append(b, "RG", 'Z', RG_len[heap->i] + 1, (uint8_t*)RG[heap->i]); + } + bam_write1_core(fpout, &b->core, b->data_len, b->data); + if ((j = bam_iter_read(fp[heap->i], iter[heap->i], b)) >= 0) { + heap->pos = ((uint64_t)b->core.tid<<32) | (uint32_t)((int)b->core.pos+1)<<1 | bam1_strand(b); + heap->idx = idx++; + } else if (j == -1) { + heap->pos = HEAP_EMPTY; + free(heap->b->data); free(heap->b); + heap->b = 0; + } else fprintf(stderr, "[bam_merge_core] '%s' is truncated. Continue anyway.\n", fn[heap->i]); + ks_heapadjust(heap, 0, n, heap); + } + + if (flag & MERGE_RG) { + for (i = 0; i != n; ++i) free(RG[i]); + free(RG); free(RG_len); + } + for (i = 0; i != n; ++i) { + bam_iter_destroy(iter[i]); + bam_close(fp[i]); + } + bam_close(fpout); + free(fp); free(heap); free(iter); + return 0; +} + +int bam_merge(int argc, char *argv[]) +{ + int c, is_by_qname = 0, flag = 0, ret = 0; + char *fn_headers = NULL, *reg = 0; + + while ((c = getopt(argc, argv, "h:nru1R:f")) >= 0) { + switch (c) { + case 'r': flag |= MERGE_RG; break; + case 'f': flag |= MERGE_FORCE; break; + case 'h': fn_headers = strdup(optarg); break; + case 'n': is_by_qname = 1; break; + case '1': flag |= MERGE_LEVEL1; break; + case 'u': flag |= MERGE_UNCOMP; break; + case 'R': reg = strdup(optarg); break; + } + } + if (optind + 2 >= argc) { + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: samtools merge [-nr] [-h inh.sam] <out.bam> <in1.bam> <in2.bam> [...]\n\n"); + fprintf(stderr, "Options: -n sort by read names\n"); + fprintf(stderr, " -r attach RG tag (inferred from file names)\n"); + fprintf(stderr, " -u uncompressed BAM output\n"); + fprintf(stderr, " -f overwrite the output BAM if exist\n"); + fprintf(stderr, " -1 compress level 1\n"); + fprintf(stderr, " -R STR merge file in the specified region STR [all]\n"); + fprintf(stderr, " -h FILE copy the header in FILE to <out.bam> [in1.bam]\n\n"); + fprintf(stderr, "Note: Samtools' merge does not reconstruct the @RG dictionary in the header. Users\n"); + fprintf(stderr, " must provide the correct header with -h, or uses Picard which properly maintains\n"); + fprintf(stderr, " the header dictionary in merging.\n\n"); + return 1; + } + if (!(flag & MERGE_FORCE) && strcmp(argv[optind], "-")) { + FILE *fp = fopen(argv[optind], "rb"); + if (fp != NULL) { + fclose(fp); + fprintf(stderr, "[%s] File '%s' exists. Please apply '-f' to overwrite. Abort.\n", __func__, argv[optind]); + return 1; + } + } + if (bam_merge_core(is_by_qname, argv[optind], fn_headers, argc - optind - 1, argv + optind + 1, flag, reg) < 0) ret = 1; + free(reg); + free(fn_headers); + return ret; +} + +typedef bam1_t *bam1_p; + +static inline int bam1_lt(const bam1_p a, const bam1_p b) +{ + if (g_is_by_qname) { + int t = strnum_cmp(bam1_qname(a), bam1_qname(b)); + return (t < 0 || (t == 0 && (((uint64_t)a->core.tid<<32|(a->core.pos+1)) < ((uint64_t)b->core.tid<<32|(b->core.pos+1))))); + } else return (((uint64_t)a->core.tid<<32|(a->core.pos+1)) < ((uint64_t)b->core.tid<<32|(b->core.pos+1))); +} +KSORT_INIT(sort, bam1_p, bam1_lt) + +static void sort_blocks(int n, int k, bam1_p *buf, const char *prefix, const bam_header_t *h, int is_stdout) +{ + char *name, mode[3]; + int i; + bamFile fp; + ks_mergesort(sort, k, buf, 0); + name = (char*)calloc(strlen(prefix) + 20, 1); + if (n >= 0) { + sprintf(name, "%s.%.4d.bam", prefix, n); + strcpy(mode, "w1"); + } else { + sprintf(name, "%s.bam", prefix); + strcpy(mode, "w"); + } + fp = is_stdout? bam_dopen(fileno(stdout), mode) : bam_open(name, mode); + if (fp == 0) { + fprintf(stderr, "[sort_blocks] fail to create file %s.\n", name); + free(name); + // FIXME: possible memory leak + return; + } + free(name); + bam_header_write(fp, h); + for (i = 0; i < k; ++i) + bam_write1_core(fp, &buf[i]->core, buf[i]->data_len, buf[i]->data); + bam_close(fp); +} + +/*! + @abstract Sort an unsorted BAM file based on the chromosome order + and the leftmost position of an alignment + + @param is_by_qname whether to sort by query name + @param fn name of the file to be sorted + @param prefix prefix of the output and the temporary files; upon + sucessess, prefix.bam will be written. + @param max_mem approxiate maximum memory (very inaccurate) + + @discussion It may create multiple temporary subalignment files + and then merge them by calling bam_merge_core(). This function is + NOT thread safe. + */ +void bam_sort_core_ext(int is_by_qname, const char *fn, const char *prefix, size_t max_mem, int is_stdout) +{ + int n, ret, k, i; + size_t mem; + bam_header_t *header; + bamFile fp; + bam1_t *b, **buf; + + g_is_by_qname = is_by_qname; + n = k = 0; mem = 0; + fp = strcmp(fn, "-")? bam_open(fn, "r") : bam_dopen(fileno(stdin), "r"); + if (fp == 0) { + fprintf(stderr, "[bam_sort_core] fail to open file %s\n", fn); + return; + } + header = bam_header_read(fp); + buf = (bam1_t**)calloc(max_mem / BAM_CORE_SIZE, sizeof(bam1_t*)); + // write sub files + for (;;) { + if (buf[k] == 0) buf[k] = (bam1_t*)calloc(1, sizeof(bam1_t)); + b = buf[k]; + if ((ret = bam_read1(fp, b)) < 0) break; + mem += ret; + ++k; + if (mem >= max_mem) { + sort_blocks(n++, k, buf, prefix, header, 0); + mem = 0; k = 0; + } + } + if (ret != -1) + fprintf(stderr, "[bam_sort_core] truncated file. Continue anyway.\n"); + if (n == 0) sort_blocks(-1, k, buf, prefix, header, is_stdout); + else { // then merge + char **fns, *fnout; + fprintf(stderr, "[bam_sort_core] merging from %d files...\n", n+1); + sort_blocks(n++, k, buf, prefix, header, 0); + fnout = (char*)calloc(strlen(prefix) + 20, 1); + if (is_stdout) sprintf(fnout, "-"); + else sprintf(fnout, "%s.bam", prefix); + fns = (char**)calloc(n, sizeof(char*)); + for (i = 0; i < n; ++i) { + fns[i] = (char*)calloc(strlen(prefix) + 20, 1); + sprintf(fns[i], "%s.%.4d.bam", prefix, i); + } + bam_merge_core(is_by_qname, fnout, 0, n, fns, 0, 0); + free(fnout); + for (i = 0; i < n; ++i) { + unlink(fns[i]); + free(fns[i]); + } + free(fns); + } + for (k = 0; k < max_mem / BAM_CORE_SIZE; ++k) { + if (buf[k]) { + free(buf[k]->data); + free(buf[k]); + } + } + free(buf); + bam_header_destroy(header); + bam_close(fp); +} + +void bam_sort_core(int is_by_qname, const char *fn, const char *prefix, size_t max_mem) +{ + bam_sort_core_ext(is_by_qname, fn, prefix, max_mem, 0); +} + +int bam_sort(int argc, char *argv[]) +{ + size_t max_mem = 500000000; + int c, is_by_qname = 0, is_stdout = 0; + while ((c = getopt(argc, argv, "nom:")) >= 0) { + switch (c) { + case 'o': is_stdout = 1; break; + case 'n': is_by_qname = 1; break; + case 'm': max_mem = atol(optarg); break; + } + } + if (optind + 2 > argc) { + fprintf(stderr, "Usage: samtools sort [-on] [-m <maxMem>] <in.bam> <out.prefix>\n"); + return 1; + } + bam_sort_core_ext(is_by_qname, argv[optind], argv[optind+1], max_mem, is_stdout); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam_stat.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,77 @@ +#include <unistd.h> +#include <assert.h> +#include "bam.h" + +typedef struct { + long long n_reads[2], n_mapped[2], n_pair_all[2], n_pair_map[2], n_pair_good[2]; + long long n_sgltn[2], n_read1[2], n_read2[2]; + long long n_dup[2]; + long long n_diffchr[2], n_diffhigh[2]; +} bam_flagstat_t; + +#define flagstat_loop(s, c) do { \ + int w = ((c)->flag & BAM_FQCFAIL)? 1 : 0; \ + ++(s)->n_reads[w]; \ + if ((c)->flag & BAM_FPAIRED) { \ + ++(s)->n_pair_all[w]; \ + if ((c)->flag & BAM_FPROPER_PAIR) ++(s)->n_pair_good[w]; \ + if ((c)->flag & BAM_FREAD1) ++(s)->n_read1[w]; \ + if ((c)->flag & BAM_FREAD2) ++(s)->n_read2[w]; \ + if (((c)->flag & BAM_FMUNMAP) && !((c)->flag & BAM_FUNMAP)) ++(s)->n_sgltn[w]; \ + if (!((c)->flag & BAM_FUNMAP) && !((c)->flag & BAM_FMUNMAP)) { \ + ++(s)->n_pair_map[w]; \ + if ((c)->mtid != (c)->tid) { \ + ++(s)->n_diffchr[w]; \ + if ((c)->qual >= 5) ++(s)->n_diffhigh[w]; \ + } \ + } \ + } \ + if (!((c)->flag & BAM_FUNMAP)) ++(s)->n_mapped[w]; \ + if ((c)->flag & BAM_FDUP) ++(s)->n_dup[w]; \ + } while (0) + +bam_flagstat_t *bam_flagstat_core(bamFile fp) +{ + bam_flagstat_t *s; + bam1_t *b; + bam1_core_t *c; + int ret; + s = (bam_flagstat_t*)calloc(1, sizeof(bam_flagstat_t)); + b = bam_init1(); + c = &b->core; + while ((ret = bam_read1(fp, b)) >= 0) + flagstat_loop(s, c); + bam_destroy1(b); + if (ret != -1) + fprintf(stderr, "[bam_flagstat_core] Truncated file? Continue anyway.\n"); + return s; +} +int bam_flagstat(int argc, char *argv[]) +{ + bamFile fp; + bam_header_t *header; + bam_flagstat_t *s; + if (argc == optind) { + fprintf(stderr, "Usage: samtools flagstat <in.bam>\n"); + return 1; + } + fp = strcmp(argv[optind], "-")? bam_open(argv[optind], "r") : bam_dopen(fileno(stdin), "r"); + assert(fp); + header = bam_header_read(fp); + s = bam_flagstat_core(fp); + printf("%lld + %lld in total (QC-passed reads + QC-failed reads)\n", s->n_reads[0], s->n_reads[1]); + printf("%lld + %lld duplicates\n", s->n_dup[0], s->n_dup[1]); + printf("%lld + %lld mapped (%.2f%%:%.2f%%)\n", s->n_mapped[0], s->n_mapped[1], (float)s->n_mapped[0] / s->n_reads[0] * 100.0, (float)s->n_mapped[1] / s->n_reads[1] * 100.0); + printf("%lld + %lld paired in sequencing\n", s->n_pair_all[0], s->n_pair_all[1]); + printf("%lld + %lld read1\n", s->n_read1[0], s->n_read1[1]); + printf("%lld + %lld read2\n", s->n_read2[0], s->n_read2[1]); + printf("%lld + %lld properly paired (%.2f%%:%.2f%%)\n", s->n_pair_good[0], s->n_pair_good[1], (float)s->n_pair_good[0] / s->n_pair_all[0] * 100.0, (float)s->n_pair_good[1] / s->n_pair_all[1] * 100.0); + printf("%lld + %lld with itself and mate mapped\n", s->n_pair_map[0], s->n_pair_map[1]); + printf("%lld + %lld singletons (%.2f%%:%.2f%%)\n", s->n_sgltn[0], s->n_sgltn[1], (float)s->n_sgltn[0] / s->n_pair_all[0] * 100.0, (float)s->n_sgltn[1] / s->n_pair_all[1] * 100.0); + printf("%lld + %lld with mate mapped to a different chr\n", s->n_diffchr[0], s->n_diffchr[1]); + printf("%lld + %lld with mate mapped to a different chr (mapQ>=5)\n", s->n_diffhigh[0], s->n_diffhigh[1]); + free(s); + bam_header_destroy(header); + bam_close(fp); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bam_tview.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,424 @@ +#undef _HAVE_CURSES + +#if _CURSES_LIB == 0 +#elif _CURSES_LIB == 1 +#include <curses.h> +#ifndef NCURSES_VERSION +#warning "_CURSES_LIB=1 but NCURSES_VERSION not defined; tview is NOT compiled" +#else +#define _HAVE_CURSES +#endif +#elif _CURSES_LIB == 2 +#include <xcurses.h> +#define _HAVE_CURSES +#else +#warning "_CURSES_LIB is not 0, 1 or 2; tview is NOT compiled" +#endif + +#ifdef _HAVE_CURSES +#include <ctype.h> +#include <assert.h> +#include <string.h> +#include "bam.h" +#include "faidx.h" +#include "bam_maqcns.h" + +char bam_aux_getCEi(bam1_t *b, int i); +char bam_aux_getCSi(bam1_t *b, int i); +char bam_aux_getCQi(bam1_t *b, int i); + +#define TV_MIN_ALNROW 2 +#define TV_MAX_GOTO 40 +#define TV_LOW_MAPQ 10 + +#define TV_COLOR_MAPQ 0 +#define TV_COLOR_BASEQ 1 +#define TV_COLOR_NUCL 2 +#define TV_COLOR_COL 3 +#define TV_COLOR_COLQ 4 + +#define TV_BASE_NUCL 0 +#define TV_BASE_COLOR_SPACE 1 + +typedef struct { + int mrow, mcol; + WINDOW *wgoto, *whelp; + + bam_index_t *idx; + bam_lplbuf_t *lplbuf; + bam_header_t *header; + bamFile fp; + int curr_tid, left_pos; + faidx_t *fai; + bam_maqcns_t *bmc; + + int ccol, last_pos, row_shift, base_for, color_for, is_dot, l_ref, ins, no_skip, show_name; + char *ref; +} tview_t; + +int tv_pl_func(uint32_t tid, uint32_t pos, int n, const bam_pileup1_t *pl, void *data) +{ + tview_t *tv = (tview_t*)data; + int i, j, c, rb, attr, max_ins = 0; + uint32_t call = 0; + if (pos < tv->left_pos || tv->ccol > tv->mcol) return 0; // out of screen + // print referece + rb = (tv->ref && pos - tv->left_pos < tv->l_ref)? tv->ref[pos - tv->left_pos] : 'N'; + for (i = tv->last_pos + 1; i < pos; ++i) { + if (i%10 == 0 && tv->mcol - tv->ccol >= 10) mvprintw(0, tv->ccol, "%-d", i+1); + c = tv->ref? tv->ref[i - tv->left_pos] : 'N'; + mvaddch(1, tv->ccol++, c); + } + if (pos%10 == 0 && tv->mcol - tv->ccol >= 10) mvprintw(0, tv->ccol, "%-d", pos+1); + // print consensus + call = bam_maqcns_call(n, pl, tv->bmc); + attr = A_UNDERLINE; + c = ",ACMGRSVTWYHKDBN"[call>>28&0xf]; + i = (call>>8&0xff)/10+1; + if (i > 4) i = 4; + attr |= COLOR_PAIR(i); + if (c == toupper(rb)) c = '.'; + attron(attr); + mvaddch(2, tv->ccol, c); + attroff(attr); + if(tv->ins) { + // calculate maximum insert + for (i = 0; i < n; ++i) { + const bam_pileup1_t *p = pl + i; + if (p->indel > 0 && max_ins < p->indel) max_ins = p->indel; + } + } + // core loop + for (j = 0; j <= max_ins; ++j) { + for (i = 0; i < n; ++i) { + const bam_pileup1_t *p = pl + i; + int row = TV_MIN_ALNROW + p->level - tv->row_shift; + if (j == 0) { + if (!p->is_del) { + if (tv->base_for == TV_BASE_COLOR_SPACE && + (c = bam_aux_getCSi(p->b, p->qpos))) { + c = bam_aux_getCSi(p->b, p->qpos); + // assume that if we found one color, we will be able to get the color error + if (tv->is_dot && '-' == bam_aux_getCEi(p->b, p->qpos)) c = bam1_strand(p->b)? ',' : '.'; + } else { + if (tv->show_name) { + char *name = bam1_qname(p->b); + c = (p->qpos + 1 >= p->b->core.l_qname)? ' ' : name[p->qpos]; + } else { + c = bam_nt16_rev_table[bam1_seqi(bam1_seq(p->b), p->qpos)]; + if (tv->is_dot && toupper(c) == toupper(rb)) c = bam1_strand(p->b)? ',' : '.'; + } + } + } else c = p->is_refskip? (bam1_strand(p->b)? '<' : '>') : '*'; + } else { // padding + if (j > p->indel) c = '*'; + else { // insertion + if (tv->base_for == TV_BASE_NUCL) { + if (tv->show_name) { + char *name = bam1_qname(p->b); + c = (p->qpos + j + 1 >= p->b->core.l_qname)? ' ' : name[p->qpos + j]; + } else { + c = bam_nt16_rev_table[bam1_seqi(bam1_seq(p->b), p->qpos + j)]; + if (j == 0 && tv->is_dot && toupper(c) == toupper(rb)) c = bam1_strand(p->b)? ',' : '.'; + } + } else { + c = bam_aux_getCSi(p->b, p->qpos + j); + if (tv->is_dot && '-' == bam_aux_getCEi(p->b, p->qpos + j)) c = bam1_strand(p->b)? ',' : '.'; + } + } + } + if (row > TV_MIN_ALNROW && row < tv->mrow) { + int x; + attr = 0; + if (((p->b->core.flag&BAM_FPAIRED) && !(p->b->core.flag&BAM_FPROPER_PAIR)) + || (p->b->core.flag & BAM_FSECONDARY)) attr |= A_UNDERLINE; + if (tv->color_for == TV_COLOR_BASEQ) { + x = bam1_qual(p->b)[p->qpos]/10 + 1; + if (x > 4) x = 4; + attr |= COLOR_PAIR(x); + } else if (tv->color_for == TV_COLOR_MAPQ) { + x = p->b->core.qual/10 + 1; + if (x > 4) x = 4; + attr |= COLOR_PAIR(x); + } else if (tv->color_for == TV_COLOR_NUCL) { + x = bam_nt16_nt4_table[bam1_seqi(bam1_seq(p->b), p->qpos)] + 5; + attr |= COLOR_PAIR(x); + } else if(tv->color_for == TV_COLOR_COL) { + x = 0; + switch(bam_aux_getCSi(p->b, p->qpos)) { + case '0': x = 0; break; + case '1': x = 1; break; + case '2': x = 2; break; + case '3': x = 3; break; + case '4': x = 4; break; + default: x = bam_nt16_nt4_table[bam1_seqi(bam1_seq(p->b), p->qpos)]; break; + } + x+=5; + attr |= COLOR_PAIR(x); + } else if(tv->color_for == TV_COLOR_COLQ) { + x = bam_aux_getCQi(p->b, p->qpos); + if(0 == x) x = bam1_qual(p->b)[p->qpos]; + x = x/10 + 1; + if (x > 4) x = 4; + attr |= COLOR_PAIR(x); + } + attron(attr); + mvaddch(row, tv->ccol, bam1_strand(p->b)? tolower(c) : toupper(c)); + attroff(attr); + } + } + c = j? '*' : rb; + if (c == '*') { + attr = COLOR_PAIR(8); + attron(attr); + mvaddch(1, tv->ccol++, c); + attroff(attr); + } else mvaddch(1, tv->ccol++, c); + } + tv->last_pos = pos; + return 0; +} + +tview_t *tv_init(const char *fn, const char *fn_fa) +{ + tview_t *tv = (tview_t*)calloc(1, sizeof(tview_t)); + tv->is_dot = 1; + tv->fp = bam_open(fn, "r"); + bgzf_set_cache_size(tv->fp, 8 * 1024 *1024); + assert(tv->fp); + tv->header = bam_header_read(tv->fp); + tv->idx = bam_index_load(fn); + if (tv->idx == 0) exit(1); + tv->lplbuf = bam_lplbuf_init(tv_pl_func, tv); + if (fn_fa) tv->fai = fai_load(fn_fa); + tv->bmc = bam_maqcns_init(); + tv->ins = 1; + bam_maqcns_prepare(tv->bmc); + + initscr(); + keypad(stdscr, TRUE); + clear(); + noecho(); + cbreak(); + tv->mrow = 24; tv->mcol = 80; + getmaxyx(stdscr, tv->mrow, tv->mcol); + tv->wgoto = newwin(3, TV_MAX_GOTO + 10, 10, 5); + tv->whelp = newwin(29, 40, 5, 5); + tv->color_for = TV_COLOR_MAPQ; + start_color(); + init_pair(1, COLOR_BLUE, COLOR_BLACK); + init_pair(2, COLOR_GREEN, COLOR_BLACK); + init_pair(3, COLOR_YELLOW, COLOR_BLACK); + init_pair(4, COLOR_WHITE, COLOR_BLACK); + init_pair(5, COLOR_GREEN, COLOR_BLACK); + init_pair(6, COLOR_CYAN, COLOR_BLACK); + init_pair(7, COLOR_YELLOW, COLOR_BLACK); + init_pair(8, COLOR_RED, COLOR_BLACK); + init_pair(9, COLOR_BLUE, COLOR_BLACK); + return tv; +} + +void tv_destroy(tview_t *tv) +{ + delwin(tv->wgoto); delwin(tv->whelp); + endwin(); + + bam_lplbuf_destroy(tv->lplbuf); + bam_maqcns_destroy(tv->bmc); + bam_index_destroy(tv->idx); + if (tv->fai) fai_destroy(tv->fai); + free(tv->ref); + bam_header_destroy(tv->header); + bam_close(tv->fp); + free(tv); +} + +int tv_fetch_func(const bam1_t *b, void *data) +{ + tview_t *tv = (tview_t*)data; + if (tv->no_skip) { + uint32_t *cigar = bam1_cigar(b); // this is cheating... + int i; + for (i = 0; i <b->core.n_cigar; ++i) { + if ((cigar[i]&0xf) == BAM_CREF_SKIP) + cigar[i] = cigar[i]>>4<<4 | BAM_CDEL; + } + } + bam_lplbuf_push(b, tv->lplbuf); + return 0; +} + +int tv_draw_aln(tview_t *tv, int tid, int pos) +{ + // reset + clear(); + tv->curr_tid = tid; tv->left_pos = pos; + tv->last_pos = tv->left_pos - 1; + tv->ccol = 0; + // print ref and consensus + if (tv->fai) { + char *str; + if (tv->ref) free(tv->ref); + str = (char*)calloc(strlen(tv->header->target_name[tv->curr_tid]) + 30, 1); + sprintf(str, "%s:%d-%d", tv->header->target_name[tv->curr_tid], tv->left_pos + 1, tv->left_pos + tv->mcol); + tv->ref = fai_fetch(tv->fai, str, &tv->l_ref); + free(str); + } + // draw aln + bam_lplbuf_reset(tv->lplbuf); + bam_fetch(tv->fp, tv->idx, tv->curr_tid, tv->left_pos, tv->left_pos + tv->mcol, tv, tv_fetch_func); + bam_lplbuf_push(0, tv->lplbuf); + + while (tv->ccol < tv->mcol) { + int pos = tv->last_pos + 1; + if (pos%10 == 0 && tv->mcol - tv->ccol >= 10) mvprintw(0, tv->ccol, "%-d", pos+1); + mvaddch(1, tv->ccol++, (tv->ref && pos < tv->l_ref)? tv->ref[pos - tv->left_pos] : 'N'); + ++tv->last_pos; + } + return 0; +} + +static void tv_win_goto(tview_t *tv, int *tid, int *pos) +{ + char str[256], *p; + int i, l = 0; + wborder(tv->wgoto, '|', '|', '-', '-', '+', '+', '+', '+'); + mvwprintw(tv->wgoto, 1, 2, "Goto: "); + for (;;) { + int c = wgetch(tv->wgoto); + wrefresh(tv->wgoto); + if (c == KEY_BACKSPACE || c == '\010' || c == '\177') { + --l; + } else if (c == KEY_ENTER || c == '\012' || c == '\015') { + int _tid = -1, _beg, _end; + if (str[0] == '=') { + _beg = strtol(str+1, &p, 10) - 1; + if (_beg > 0) { + *pos = _beg; + return; + } + } else { + bam_parse_region(tv->header, str, &_tid, &_beg, &_end); + if (_tid >= 0) { + *tid = _tid; *pos = _beg; + return; + } + } + } else if (isgraph(c)) { + if (l < TV_MAX_GOTO) str[l++] = c; + } else if (c == '\027') l = 0; + else if (c == '\033') return; + str[l] = '\0'; + for (i = 0; i < TV_MAX_GOTO; ++i) mvwaddch(tv->wgoto, 1, 8 + i, ' '); + mvwprintw(tv->wgoto, 1, 8, "%s", str); + } +} + +static void tv_win_help(tview_t *tv) { + int r = 1; + WINDOW *win = tv->whelp; + wborder(win, '|', '|', '-', '-', '+', '+', '+', '+'); + mvwprintw(win, r++, 2, " -=- Help -=- "); + r++; + mvwprintw(win, r++, 2, "? This window"); + mvwprintw(win, r++, 2, "Arrows Small scroll movement"); + mvwprintw(win, r++, 2, "h,j,k,l Small scroll movement"); + mvwprintw(win, r++, 2, "H,J,K,L Large scroll movement"); + mvwprintw(win, r++, 2, "ctrl-H Scroll 1k left"); + mvwprintw(win, r++, 2, "ctrl-L Scroll 1k right"); + mvwprintw(win, r++, 2, "space Scroll one screen"); + mvwprintw(win, r++, 2, "backspace Scroll back one screen"); + mvwprintw(win, r++, 2, "g Go to specific location"); + mvwprintw(win, r++, 2, "m Color for mapping qual"); + mvwprintw(win, r++, 2, "n Color for nucleotide"); + mvwprintw(win, r++, 2, "b Color for base quality"); + mvwprintw(win, r++, 2, "c Color for cs color"); + mvwprintw(win, r++, 2, "z Color for cs qual"); + mvwprintw(win, r++, 2, ". Toggle on/off dot view"); + mvwprintw(win, r++, 2, "s Toggle on/off ref skip"); + mvwprintw(win, r++, 2, "r Toggle on/off rd name"); + mvwprintw(win, r++, 2, "N Turn on nt view"); + mvwprintw(win, r++, 2, "C Turn on cs view"); + mvwprintw(win, r++, 2, "i Toggle on/off ins"); + mvwprintw(win, r++, 2, "q Exit"); + r++; + mvwprintw(win, r++, 2, "Underline: Secondary or orphan"); + mvwprintw(win, r++, 2, "Blue: 0-9 Green: 10-19"); + mvwprintw(win, r++, 2, "Yellow: 20-29 White: >=30"); + wrefresh(win); + wgetch(win); +} + +void tv_loop(tview_t *tv) +{ + int tid, pos; + tid = tv->curr_tid; pos = tv->left_pos; + while (1) { + int c = getch(); + switch (c) { + case '?': tv_win_help(tv); break; + case '\033': + case 'q': goto end_loop; + case '/': + case 'g': tv_win_goto(tv, &tid, &pos); break; + case 'm': tv->color_for = TV_COLOR_MAPQ; break; + case 'b': tv->color_for = TV_COLOR_BASEQ; break; + case 'n': tv->color_for = TV_COLOR_NUCL; break; + case 'c': tv->color_for = TV_COLOR_COL; break; + case 'z': tv->color_for = TV_COLOR_COLQ; break; + case 's': tv->no_skip = !tv->no_skip; break; + case 'r': tv->show_name = !tv->show_name; break; + case KEY_LEFT: + case 'h': --pos; break; + case KEY_RIGHT: + case 'l': ++pos; break; + case KEY_SLEFT: + case 'H': pos -= 20; break; + case KEY_SRIGHT: + case 'L': pos += 20; break; + case '.': tv->is_dot = !tv->is_dot; break; + case 'N': tv->base_for = TV_BASE_NUCL; break; + case 'C': tv->base_for = TV_BASE_COLOR_SPACE; break; + case 'i': tv->ins = !tv->ins; break; + case '\010': pos -= 1000; break; + case '\014': pos += 1000; break; + case ' ': pos += tv->mcol; break; + case KEY_UP: + case 'j': --tv->row_shift; break; + case KEY_DOWN: + case 'k': ++tv->row_shift; break; + case KEY_BACKSPACE: + case '\177': pos -= tv->mcol; break; + case KEY_RESIZE: getmaxyx(stdscr, tv->mrow, tv->mcol); break; + default: continue; + } + if (pos < 0) pos = 0; + if (tv->row_shift < 0) tv->row_shift = 0; + tv_draw_aln(tv, tid, pos); + } +end_loop: + return; +} + +int bam_tview_main(int argc, char *argv[]) +{ + tview_t *tv; + if (argc == 1) { + fprintf(stderr, "Usage: bamtk tview <aln.bam> [ref.fasta]\n"); + return 1; + } + tv = tv_init(argv[1], (argc == 2)? 0 : argv[2]); + tv_draw_aln(tv, 0, 0); + tv_loop(tv); + tv_destroy(tv); + return 0; +} +#else // #ifdef _HAVE_CURSES +#include <stdio.h> +#warning "No curses library is available; tview is disabled." +int bam_tview_main(int argc, char *argv[]) +{ + fprintf(stderr, "[bam_tview_main] The ncurses library is unavailable; tview is not compiled.\n"); + return 1; +} +#endif // #ifdef _HAVE_CURSES
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bamtk.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,109 @@ +#include <stdio.h> +#include <unistd.h> +#include <assert.h> +#include <fcntl.h> +#include "bam.h" + +#ifdef _USE_KNETFILE +#include "knetfile.h" +#endif + +int bam_taf2baf(int argc, char *argv[]); +int bam_pileup(int argc, char *argv[]); +int bam_mpileup(int argc, char *argv[]); +int bam_merge(int argc, char *argv[]); +int bam_index(int argc, char *argv[]); +int bam_sort(int argc, char *argv[]); +int bam_tview_main(int argc, char *argv[]); +int bam_mating(int argc, char *argv[]); +int bam_rmdup(int argc, char *argv[]); +int bam_flagstat(int argc, char *argv[]); +int bam_fillmd(int argc, char *argv[]); +int bam_idxstats(int argc, char *argv[]); +int main_samview(int argc, char *argv[]); +int main_import(int argc, char *argv[]); +int main_reheader(int argc, char *argv[]); +int main_cut_target(int argc, char *argv[]); +int main_phase(int argc, char *argv[]); +int main_cat(int argc, char *argv[]); +int main_depth(int argc, char *argv[]); + +int faidx_main(int argc, char *argv[]); +int glf3_view_main(int argc, char *argv[]); + +static int usage() +{ + fprintf(stderr, "\n"); + fprintf(stderr, "Program: samtools (Tools for alignments in the SAM format)\n"); + fprintf(stderr, "Version: %s\n\n", BAM_VERSION); + fprintf(stderr, "Usage: samtools <command> [options]\n\n"); + fprintf(stderr, "Command: view SAM<->BAM conversion\n"); + fprintf(stderr, " sort sort alignment file\n"); + fprintf(stderr, " pileup generate pileup output\n"); + fprintf(stderr, " mpileup multi-way pileup\n"); + fprintf(stderr, " depth compute the depth\n"); + fprintf(stderr, " faidx index/extract FASTA\n"); +#if _CURSES_LIB != 0 + fprintf(stderr, " tview text alignment viewer\n"); +#endif + fprintf(stderr, " index index alignment\n"); + fprintf(stderr, " idxstats BAM index stats (r595 or later)\n"); + fprintf(stderr, " fixmate fix mate information\n"); + fprintf(stderr, " glfview print GLFv3 file\n"); + fprintf(stderr, " flagstat simple stats\n"); + fprintf(stderr, " calmd recalculate MD/NM tags and '=' bases\n"); + fprintf(stderr, " merge merge sorted alignments\n"); + fprintf(stderr, " rmdup remove PCR duplicates\n"); + fprintf(stderr, " reheader replace BAM header\n"); + fprintf(stderr, " cat concatenate BAMs\n"); + fprintf(stderr, " targetcut cut fosmid regions (for fosmid pool only)\n"); + fprintf(stderr, " phase phase heterozygotes\n"); + fprintf(stderr, "\n"); +#ifdef _WIN32 + fprintf(stderr, "\ +Note: The Windows version of SAMtools is mainly designed for read-only\n\ + operations, such as viewing the alignments and generating the pileup.\n\ + Binary files generated by the Windows version may be buggy.\n\n"); +#endif + return 1; +} + +int main(int argc, char *argv[]) +{ +#ifdef _WIN32 + setmode(fileno(stdout), O_BINARY); + setmode(fileno(stdin), O_BINARY); +#ifdef _USE_KNETFILE + knet_win32_init(); +#endif +#endif + if (argc < 2) return usage(); + if (strcmp(argv[1], "view") == 0) return main_samview(argc-1, argv+1); + else if (strcmp(argv[1], "import") == 0) return main_import(argc-1, argv+1); + else if (strcmp(argv[1], "pileup") == 0) return bam_pileup(argc-1, argv+1); + else if (strcmp(argv[1], "mpileup") == 0) return bam_mpileup(argc-1, argv+1); + else if (strcmp(argv[1], "merge") == 0) return bam_merge(argc-1, argv+1); + else if (strcmp(argv[1], "sort") == 0) return bam_sort(argc-1, argv+1); + else if (strcmp(argv[1], "index") == 0) return bam_index(argc-1, argv+1); + else if (strcmp(argv[1], "idxstats") == 0) return bam_idxstats(argc-1, argv+1); + else if (strcmp(argv[1], "faidx") == 0) return faidx_main(argc-1, argv+1); + else if (strcmp(argv[1], "fixmate") == 0) return bam_mating(argc-1, argv+1); + else if (strcmp(argv[1], "rmdup") == 0) return bam_rmdup(argc-1, argv+1); + else if (strcmp(argv[1], "glfview") == 0) return glf3_view_main(argc-1, argv+1); + else if (strcmp(argv[1], "flagstat") == 0) return bam_flagstat(argc-1, argv+1); + else if (strcmp(argv[1], "calmd") == 0) return bam_fillmd(argc-1, argv+1); + else if (strcmp(argv[1], "fillmd") == 0) return bam_fillmd(argc-1, argv+1); + else if (strcmp(argv[1], "reheader") == 0) return main_reheader(argc-1, argv+1); + else if (strcmp(argv[1], "cat") == 0) return main_cat(argc-1, argv+1); + else if (strcmp(argv[1], "targetcut") == 0) return main_cut_target(argc-1, argv+1); + else if (strcmp(argv[1], "phase") == 0) return main_phase(argc-1, argv+1); + else if (strcmp(argv[1], "depth") == 0) return main_depth(argc-1, argv+1); +#if _CURSES_LIB != 0 + else if (strcmp(argv[1], "tview") == 0) return bam_tview_main(argc-1, argv+1); +#endif + else { + fprintf(stderr, "[main] unrecognized command '%s'\n", argv[1]); + return 1; + } + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bcftools/Makefile Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,51 @@ +CC= gcc +CFLAGS= -g -Wall -O2 #-m64 #-arch ppc +DFLAGS= -D_FILE_OFFSET_BITS=64 -D_USE_KNETFILE +LOBJS= bcf.o vcf.o bcfutils.o prob1.o em.o kfunc.o kmin.o index.o fet.o bcf2qcall.o +OMISC= .. +AOBJS= call1.o main.o $(OMISC)/kstring.o $(OMISC)/bgzf.o $(OMISC)/knetfile.o $(OMISC)/bedidx.o +PROG= bcftools +INCLUDES= +SUBDIRS= . + +.SUFFIXES:.c .o + +.c.o: + $(CC) -c $(CFLAGS) $(DFLAGS) -I.. $(INCLUDES) $< -o $@ + +all-recur lib-recur clean-recur cleanlocal-recur install-recur: + @target=`echo $@ | sed s/-recur//`; \ + wdir=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + cd $$subdir; \ + $(MAKE) CC="$(CC)" DFLAGS="$(DFLAGS)" CFLAGS="$(CFLAGS)" \ + INCLUDES="$(INCLUDES)" LIBPATH="$(LIBPATH)" $$target || exit 1; \ + cd $$wdir; \ + done; + +all:$(PROG) + +lib:libbcf.a + +libbcf.a:$(LOBJS) + $(AR) -cru $@ $(LOBJS) + +bcftools:lib $(AOBJS) + $(CC) $(CFLAGS) -o $@ $(AOBJS) -L. $(LIBPATH) -lbcf -lm -lz + +bcf.o:bcf.h +vcf.o:bcf.h +index.o:bcf.h +bcfutils.o:bcf.h +prob1.o:prob1.h bcf.h +call1.o:prob1.h bcf.h +bcf2qcall.o:bcf.h +main.o:bcf.h + +bcf.pdf:bcf.tex + pdflatex bcf + +cleanlocal: + rm -fr gmon.out *.o a.out *.dSYM $(PROG) *~ *.a bcf.aux bcf.log bcf.pdf *.class libbcf.*.dylib libbcf.so* + +clean:cleanlocal-recur
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bcftools/README Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,36 @@ +The view command of bcftools calls variants, tests Hardy-Weinberg +equilibrium (HWE), tests allele balances and estimates allele frequency. + +This command calls a site as a potential variant if P(ref|D,F) is below +0.9 (controlled by the -p option), where D is data and F is the prior +allele frequency spectrum (AFS). + +The view command performs two types of allele balance tests, both based +on Fisher's exact test for 2x2 contingency tables with the row variable +being reference allele or not. In the first table, the column variable +is strand. Two-tail P-value is taken. We test if variant bases tend to +come from one strand. In the second table, the column variable is +whether a base appears in the first or the last 11bp of the read. +One-tail P-value is taken. We test if variant bases tend to occur +towards the end of reads, which is usually an indication of +misalignment. + +Site allele frequency is estimated in two ways. In the first way, the +frequency is esimated as \argmax_f P(D|f) under the assumption of +HWE. Prior AFS is not used. In the second way, the frequency is +estimated as the posterior expectation of allele counts \sum_k +kP(k|D,F), dividied by the total number of haplotypes. HWE is not +assumed, but the estimate depends on the prior AFS. The two estimates +largely agree when the signal is strong, but may differ greatly on weak +sites as in this case, the prior plays an important role. + +To test HWE, we calculate the posterior distribution of genotypes +(ref-hom, het and alt-hom). Chi-square test is performed. It is worth +noting that the model used here is prior dependent and assumes HWE, +which is different from both models for allele frequency estimate. The +new model actually yields a third estimate of site allele frequency. + +The estimate allele frequency spectrum is printed to stderr per 64k +sites. The estimate is in fact only the first round of a EM +procedure. The second model (not the model for HWE testing) is used to +estimate the AFS. \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bcftools/bcf.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,328 @@ +#include <string.h> +#include <ctype.h> +#include <stdio.h> +#include "kstring.h" +#include "bcf.h" + +bcf_t *bcf_open(const char *fn, const char *mode) +{ + bcf_t *b; + b = calloc(1, sizeof(bcf_t)); + if (strchr(mode, 'w')) { + b->fp = strcmp(fn, "-")? bgzf_open(fn, mode) : bgzf_fdopen(fileno(stdout), mode); + } else { + b->fp = strcmp(fn, "-")? bgzf_open(fn, mode) : bgzf_fdopen(fileno(stdin), mode); + } +#ifndef BCF_LITE + b->fp->owned_file = 1; +#endif + return b; +} + +int bcf_close(bcf_t *b) +{ + int ret; + if (b == 0) return 0; + ret = bgzf_close(b->fp); + free(b); + return ret; +} + +int bcf_hdr_write(bcf_t *b, const bcf_hdr_t *h) +{ + if (b == 0 || h == 0) return -1; + bgzf_write(b->fp, "BCF\4", 4); + bgzf_write(b->fp, &h->l_nm, 4); + bgzf_write(b->fp, h->name, h->l_nm); + bgzf_write(b->fp, &h->l_smpl, 4); + bgzf_write(b->fp, h->sname, h->l_smpl); + bgzf_write(b->fp, &h->l_txt, 4); + bgzf_write(b->fp, h->txt, h->l_txt); + bgzf_flush(b->fp); + return 16 + h->l_nm + h->l_smpl + h->l_txt; +} + +bcf_hdr_t *bcf_hdr_read(bcf_t *b) +{ + uint8_t magic[4]; + bcf_hdr_t *h; + if (b == 0) return 0; + h = calloc(1, sizeof(bcf_hdr_t)); + bgzf_read(b->fp, magic, 4); + bgzf_read(b->fp, &h->l_nm, 4); + h->name = malloc(h->l_nm); + bgzf_read(b->fp, h->name, h->l_nm); + bgzf_read(b->fp, &h->l_smpl, 4); + h->sname = malloc(h->l_smpl); + bgzf_read(b->fp, h->sname, h->l_smpl); + bgzf_read(b->fp, &h->l_txt, 4); + h->txt = malloc(h->l_txt); + bgzf_read(b->fp, h->txt, h->l_txt); + bcf_hdr_sync(h); + return h; +} + +void bcf_hdr_destroy(bcf_hdr_t *h) +{ + if (h == 0) return; + free(h->name); free(h->sname); free(h->txt); free(h->ns); free(h->sns); + free(h); +} + +static inline char **cnt_null(int l, char *str, int *_n) +{ + int n = 0; + char *p, **list; + *_n = 0; + if (l == 0 || str == 0) return 0; + for (p = str; p != str + l; ++p) + if (*p == 0) ++n; + *_n = n; + list = calloc(n, sizeof(void*)); + list[0] = str; + for (p = str, n = 1; p < str + l - 1; ++p) + if (*p == 0) list[n++] = p + 1; + return list; +} + +int bcf_hdr_sync(bcf_hdr_t *b) +{ + if (b == 0) return -1; + if (b->ns) free(b->ns); + if (b->sns) free(b->sns); + if (b->l_nm) b->ns = cnt_null(b->l_nm, b->name, &b->n_ref); + else b->ns = 0, b->n_ref = 0; + b->sns = cnt_null(b->l_smpl, b->sname, &b->n_smpl); + return 0; +} + +int bcf_sync(bcf1_t *b) +{ + char *p, *tmp[5]; + int i, n, n_smpl = b->n_smpl; + ks_tokaux_t aux; + // set ref, alt, flt, info, fmt + b->ref = b->alt = b->flt = b->info = b->fmt = 0; + for (p = b->str, n = 0; p < b->str + b->l_str; ++p) { + if (*p == 0 && p+1 != b->str + b->l_str) { + if (n == 5) { + ++n; + break; + } else tmp[n++] = p + 1; + } + } + if (n != 5) { + fprintf(stderr, "[%s] incorrect number of fields (%d != 5) at %d:%d\n", __func__, n, b->tid, b->pos); + return -1; + } + b->ref = tmp[0]; b->alt = tmp[1]; b->flt = tmp[2]; b->info = tmp[3]; b->fmt = tmp[4]; + // set n_alleles + if (*b->alt == 0) b->n_alleles = 1; + else { + for (p = b->alt, n = 1; *p; ++p) + if (*p == ',') ++n; + b->n_alleles = n + 1; + } + // set n_gi and gi[i].fmt + for (p = b->fmt, n = 1; *p; ++p) + if (*p == ':') ++n; + if (n > b->m_gi) { + int old_m = b->m_gi; + b->m_gi = n; + kroundup32(b->m_gi); + b->gi = realloc(b->gi, b->m_gi * sizeof(bcf_ginfo_t)); + memset(b->gi + old_m, 0, (b->m_gi - old_m) * sizeof(bcf_ginfo_t)); + } + b->n_gi = n; + for (p = kstrtok(b->fmt, ":", &aux), n = 0; p; p = kstrtok(0, 0, &aux)) + b->gi[n++].fmt = bcf_str2int(p, aux.p - p); + // set gi[i].len + for (i = 0; i < b->n_gi; ++i) { + if (b->gi[i].fmt == bcf_str2int("PL", 2)) { + b->gi[i].len = b->n_alleles * (b->n_alleles + 1) / 2; + } else if (b->gi[i].fmt == bcf_str2int("DP", 2) || b->gi[i].fmt == bcf_str2int("HQ", 2)) { + b->gi[i].len = 2; + } else if (b->gi[i].fmt == bcf_str2int("GQ", 2) || b->gi[i].fmt == bcf_str2int("GT", 2)) { + b->gi[i].len = 1; + } else if (b->gi[i].fmt == bcf_str2int("SP", 2)) { + b->gi[i].len = 4; + } else if (b->gi[i].fmt == bcf_str2int("GL", 2)) { + b->gi[i].len = b->n_alleles * (b->n_alleles + 1) / 2 * 4; + } + b->gi[i].data = realloc(b->gi[i].data, n_smpl * b->gi[i].len); + } + return 0; +} + +int bcf_write(bcf_t *bp, const bcf_hdr_t *h, const bcf1_t *b) +{ + int i, l = 0; + if (b == 0) return -1; + bgzf_write(bp->fp, &b->tid, 4); + bgzf_write(bp->fp, &b->pos, 4); + bgzf_write(bp->fp, &b->qual, 4); + bgzf_write(bp->fp, &b->l_str, 4); + bgzf_write(bp->fp, b->str, b->l_str); + l = 12 + b->l_str; + for (i = 0; i < b->n_gi; ++i) { + bgzf_write(bp->fp, b->gi[i].data, b->gi[i].len * h->n_smpl); + l += b->gi[i].len * h->n_smpl; + } + return l; +} + +int bcf_read(bcf_t *bp, const bcf_hdr_t *h, bcf1_t *b) +{ + int i, l = 0; + if (b == 0) return -1; + if (bgzf_read(bp->fp, &b->tid, 4) == 0) return -1; + b->n_smpl = h->n_smpl; + bgzf_read(bp->fp, &b->pos, 4); + bgzf_read(bp->fp, &b->qual, 4); + bgzf_read(bp->fp, &b->l_str, 4); + if (b->l_str > b->m_str) { + b->m_str = b->l_str; + kroundup32(b->m_str); + b->str = realloc(b->str, b->m_str); + } + bgzf_read(bp->fp, b->str, b->l_str); + l = 12 + b->l_str; + if (bcf_sync(b) < 0) return -2; + for (i = 0; i < b->n_gi; ++i) { + bgzf_read(bp->fp, b->gi[i].data, b->gi[i].len * h->n_smpl); + l += b->gi[i].len * h->n_smpl; + } + return l; +} + +int bcf_destroy(bcf1_t *b) +{ + int i; + if (b == 0) return -1; + free(b->str); + for (i = 0; i < b->m_gi; ++i) + free(b->gi[i].data); + free(b->gi); + free(b); + return 0; +} + +static inline void fmt_str(const char *p, kstring_t *s) +{ + if (*p == 0) kputc('.', s); + else kputs(p, s); +} + +void bcf_fmt_core(const bcf_hdr_t *h, bcf1_t *b, kstring_t *s) +{ + int i, j, x; + s->l = 0; + if (h->n_ref) kputs(h->ns[b->tid], s); + else kputw(b->tid, s); + kputc('\t', s); + kputw(b->pos + 1, s); kputc('\t', s); + fmt_str(b->str, s); kputc('\t', s); + fmt_str(b->ref, s); kputc('\t', s); + fmt_str(b->alt, s); kputc('\t', s); + ksprintf(s, "%.3g", b->qual); kputc('\t', s); + fmt_str(b->flt, s); kputc('\t', s); + fmt_str(b->info, s); + if (b->fmt[0]) { + kputc('\t', s); + fmt_str(b->fmt, s); + } + x = b->n_alleles * (b->n_alleles + 1) / 2; + if (b->n_gi == 0) return; + for (j = 0; j < h->n_smpl; ++j) { + kputc('\t', s); + for (i = 0; i < b->n_gi; ++i) { + if (i) kputc(':', s); + if (b->gi[i].fmt == bcf_str2int("PL", 2)) { + uint8_t *d = (uint8_t*)b->gi[i].data + j * x; + int k; + for (k = 0; k < x; ++k) { + if (k > 0) kputc(',', s); + kputw(d[k], s); + } + } else if (b->gi[i].fmt == bcf_str2int("DP", 2)) { + kputw(((uint16_t*)b->gi[i].data)[j], s); + } else if (b->gi[i].fmt == bcf_str2int("GQ", 2)) { + kputw(((uint8_t*)b->gi[i].data)[j], s); + } else if (b->gi[i].fmt == bcf_str2int("SP", 2)) { + kputw(((int32_t*)b->gi[i].data)[j], s); + } else if (b->gi[i].fmt == bcf_str2int("GT", 2)) { + int y = ((uint8_t*)b->gi[i].data)[j]; + if (y>>7&1) { + kputsn("./.", 3, s); + } else { + kputc('0' + (y>>3&7), s); + kputc("/|"[y>>6&1], s); + kputc('0' + (y&7), s); + } + } else if (b->gi[i].fmt == bcf_str2int("GL", 2)) { + float *d = (float*)b->gi[i].data + j * x; + int k; + //printf("- %lx\n", d); + for (k = 0; k < x; ++k) { + if (k > 0) kputc(',', s); + ksprintf(s, "%.2f", d[k]); + } + } else kputc('.', s); // custom fields + } + } +} + +char *bcf_fmt(const bcf_hdr_t *h, bcf1_t *b) +{ + kstring_t s; + s.l = s.m = 0; s.s = 0; + bcf_fmt_core(h, b, &s); + return s.s; +} + +int bcf_append_info(bcf1_t *b, const char *info, int l) +{ + int shift = b->fmt - b->str; + int l_fmt = b->l_str - shift; + char *ori = b->str; + if (b->l_str + l > b->m_str) { // enlarge if necessary + b->m_str = b->l_str + l; + kroundup32(b->m_str); + b->str = realloc(b->str, b->m_str); + } + memmove(b->str + shift + l, b->str + shift, l_fmt); // move the FORMAT field + memcpy(b->str + shift - 1, info, l); // append to the INFO field + b->str[shift + l - 1] = '\0'; + b->fmt = b->str + shift + l; + b->l_str += l; + if (ori != b->str) bcf_sync(b); // synchronize when realloc changes the pointer + return 0; +} + +int bcf_cpy(bcf1_t *r, const bcf1_t *b) +{ + char *t1 = r->str; + bcf_ginfo_t *t2 = r->gi; + int i, t3 = r->m_str, t4 = r->m_gi; + *r = *b; + r->str = t1; r->gi = t2; r->m_str = t3; r->m_gi = t4; + if (r->m_str < b->m_str) { + r->m_str = b->m_str; + r->str = realloc(r->str, r->m_str); + } + memcpy(r->str, b->str, r->m_str); + bcf_sync(r); // calling bcf_sync() is simple but inefficient + for (i = 0; i < r->n_gi; ++i) + memcpy(r->gi[i].data, b->gi[i].data, r->n_smpl * r->gi[i].len); + return 0; +} + +int bcf_is_indel(const bcf1_t *b) +{ + char *p; + if (strlen(b->ref) > 1) return 1; + for (p = b->alt; *p; ++p) + if (*p != ',' && p[1] != ',' && p[1] != '\0') + return 1; + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bcftools/bcf.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,184 @@ +/* The MIT License + + Copyright (c) 2010 Broad Institute + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* Contact: Heng Li <lh3@live.co.uk> */ + +#ifndef BCF_H +#define BCF_H + +#include <stdint.h> +#include <zlib.h> + +#ifndef BCF_LITE +#include "bgzf.h" +typedef BGZF *bcfFile; +#else +typedef gzFile bcfFile; +#define bgzf_open(fn, mode) gzopen(fn, mode) +#define bgzf_fdopen(fd, mode) gzdopen(fd, mode) +#define bgzf_close(fp) gzclose(fp) +#define bgzf_read(fp, buf, len) gzread(fp, buf, len) +#define bgzf_write(fp, buf, len) +#define bgzf_flush(fp) +#endif + +/* + A member in the structs below is said to "primary" if its content + cannot be inferred from other members in any of structs below; a + member is said to be "derived" if its content can be derived from + other members. For example, bcf1_t::str is primary as this comes from + the input data, while bcf1_t::info is derived as it can always be + correctly set if we know bcf1_t::str. Derived members are for quick + access to the content and must be synchronized with the primary data. + */ + +typedef struct { + uint32_t fmt; // format of the block, set by bcf_str2int(). + int len; // length of data for each individual + void *data; // concatenated data + // derived info: fmt, len (<-bcf1_t::fmt) +} bcf_ginfo_t; + +typedef struct { + int32_t tid, pos; // refID and 0-based position + int32_t l_str, m_str; // length and the allocated size of ->str + float qual; // SNP quality + char *str; // concatenated string of variable length strings in VCF (from col.2 to col.7) + char *ref, *alt, *flt, *info, *fmt; // they all point to ->str; no memory allocation + int n_gi, m_gi; // number and the allocated size of geno fields + bcf_ginfo_t *gi; // array of geno fields + int n_alleles, n_smpl; // number of alleles and samples + // derived info: ref, alt, flt, info, fmt (<-str), n_gi (<-fmt), n_alleles (<-alt), n_smpl (<-bcf_hdr_t::n_smpl) +} bcf1_t; + +typedef struct { + int32_t n_ref, n_smpl; // number of reference sequences and samples + int32_t l_nm; // length of concatenated sequence names; 0 padded + int32_t l_smpl; // length of concatenated sample names; 0 padded + int32_t l_txt; // length of header text (lines started with ##) + char *name, *sname, *txt; // concatenated sequence names, sample names and header text + char **ns, **sns; // array of sequence and sample names; point to name and sname, respectively + // derived info: n_ref (<-name), n_smpl (<-sname), ns (<-name), sns (<-sname) +} bcf_hdr_t; + +typedef struct { + int is_vcf; // if the file in operation is a VCF + void *v; // auxillary data structure for VCF + bcfFile fp; // file handler for BCF +} bcf_t; + +struct __bcf_idx_t; +typedef struct __bcf_idx_t bcf_idx_t; + +#ifdef __cplusplus +extern "C" { +#endif + + // open a BCF file; for BCF file only + bcf_t *bcf_open(const char *fn, const char *mode); + // close file + int bcf_close(bcf_t *b); + // read one record from BCF; return -1 on end-of-file, and <-1 for errors + int bcf_read(bcf_t *bp, const bcf_hdr_t *h, bcf1_t *b); + // call this function if b->str is changed + int bcf_sync(bcf1_t *b); + // write a BCF record + int bcf_write(bcf_t *bp, const bcf_hdr_t *h, const bcf1_t *b); + // read the BCF header; BCF only + bcf_hdr_t *bcf_hdr_read(bcf_t *b); + // write the BCF header + int bcf_hdr_write(bcf_t *b, const bcf_hdr_t *h); + // set bcf_hdr_t::ns and bcf_hdr_t::sns + int bcf_hdr_sync(bcf_hdr_t *b); + // destroy the header + void bcf_hdr_destroy(bcf_hdr_t *h); + // destroy a record + int bcf_destroy(bcf1_t *b); + // BCF->VCF conversion + char *bcf_fmt(const bcf_hdr_t *h, bcf1_t *b); + // append more info + int bcf_append_info(bcf1_t *b, const char *info, int l); + // copy + int bcf_cpy(bcf1_t *r, const bcf1_t *b); + + // open a VCF or BCF file if "b" is set in "mode" + bcf_t *vcf_open(const char *fn, const char *mode); + // close a VCF/BCF file + int vcf_close(bcf_t *bp); + // read the VCF/BCF header + bcf_hdr_t *vcf_hdr_read(bcf_t *bp); + // read the sequence dictionary from a separate file; required for VCF->BCF conversion + int vcf_dictread(bcf_t *bp, bcf_hdr_t *h, const char *fn); + // read a VCF/BCF record; return -1 on end-of-file and <-1 for errors + int vcf_read(bcf_t *bp, bcf_hdr_t *h, bcf1_t *b); + // write the VCF header + int vcf_hdr_write(bcf_t *bp, const bcf_hdr_t *h); + // write a VCF record + int vcf_write(bcf_t *bp, bcf_hdr_t *h, bcf1_t *b); + + // keep the first n alleles and discard the rest + int bcf_shrink_alt(bcf1_t *b, int n); + // convert GL to PL + int bcf_gl2pl(bcf1_t *b); + // if the site is an indel + int bcf_is_indel(const bcf1_t *b); + bcf_hdr_t *bcf_hdr_subsam(const bcf_hdr_t *h0, int n, char *const* samples, int *list); + int bcf_subsam(int n_smpl, int *list, bcf1_t *b); + // move GT to the first FORMAT field + int bcf_fix_gt(bcf1_t *b); + // update PL generated by old samtools + int bcf_fix_pl(bcf1_t *b); + + // string hash table + void *bcf_build_refhash(bcf_hdr_t *h); + void bcf_str2id_destroy(void *_hash); + void bcf_str2id_thorough_destroy(void *_hash); + int bcf_str2id_add(void *_hash, const char *str); + int bcf_str2id(void *_hash, const char *str); + void *bcf_str2id_init(); + + // indexing related functions + int bcf_idx_build(const char *fn); + uint64_t bcf_idx_query(const bcf_idx_t *idx, int tid, int beg); + int bcf_parse_region(void *str2id, const char *str, int *tid, int *begin, int *end); + bcf_idx_t *bcf_idx_load(const char *fn); + void bcf_idx_destroy(bcf_idx_t *idx); + +#ifdef __cplusplus +} +#endif + +static inline uint32_t bcf_str2int(const char *str, int l) +{ + int i; + uint32_t x = 0; + for (i = 0; i < l && i < 4; ++i) { + if (str[i] == 0) return x; + x = x<<8 | str[i]; + } + return x; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bcftools/bcf.tex Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,77 @@ +\documentclass[10pt,pdftex]{article} +\usepackage{color} +\definecolor{gray}{rgb}{0.7,0.7,0.7} + +\setlength{\topmargin}{0.0cm} +\setlength{\textheight}{21.5cm} +\setlength{\oddsidemargin}{0cm} +\setlength{\textwidth}{16.5cm} +\setlength{\columnsep}{0.6cm} + +\begin{document} + +\begin{center} +\begin{tabular}{|l|l|l|l|l|} +\hline +\multicolumn{2}{|c|}{\bf Field} & \multicolumn{1}{c|}{\bf Descrption} & \multicolumn{1}{c|}{\bf Type} & \multicolumn{1}{c|}{\bf Value} \\\hline\hline +\multicolumn{2}{|l|}{\sf magic} & Magic string & {\tt char[4]} & {\tt BCF\char92 4} \\\hline +\multicolumn{2}{|l|}{\sf l\_seqnm} & Length of concatenated sequence names & {\tt int32\_t} & \\\hline +\multicolumn{2}{|l|}{\sf seqnm} & Concatenated names, {\tt NULL} padded & {\tt char[{\sf l\_seqnm}]} & \\\hline +\multicolumn{2}{|l|}{\sf l\_smpl} & Length of concatenated sample names & {\tt int32\_t} & \\\hline +\multicolumn{2}{|l|}{\sf smpl} & Concatenated sample names & {\tt char[{\sf l\_smpl}]} & \\\hline +\multicolumn{2}{|l|}{\sf l\_meta} & Length of the meta text (double-hash lines)& {\tt int32\_t} & \\\hline +\multicolumn{2}{|l|}{\sf meta} & Meta text, {\tt NULL} terminated & {\tt char[{\sf l\_meta}]} & \\\hline +\multicolumn{5}{|c|}{\it \color{gray}{List of records until the end of the file}}\\\cline{2-5} +& {\sf seq\_id} & Reference sequence ID & {\tt int32\_t} & \\\cline{2-5} +& {\sf pos} & Position & {\tt int32\_t} & \\\cline{2-5} +& {\sf qual} & Variant quality & {\tt float} & \\\cline{2-5} +& {\sf l\_str} & Length of {\sf str} & {\tt int32\_t} & \\\cline{2-5} +& {\sf str} & {\tt ID+REF+ALT+FILTER+INFO+FORMAT}, {\tt NULL} padded & {\tt char[{\sf l\_str}]} &\\\cline{2-5} +& \multicolumn{4}{c|}{Blocks of data; \#blocks and formats defined by {\tt FORMAT} (table below)}\\ +\hline +\end{tabular} +\end{center} + +\begin{center} +\begin{tabular}{clp{9cm}} +\hline +\multicolumn{1}{l}{\bf Field} & \multicolumn{1}{l}{\bf Type} & \multicolumn{1}{l}{\bf Description} \\\hline +{\tt DP} & {\tt uint16\_t[n]} & Read depth \\ +{\tt GL} & {\tt float[n*G]} & Log10 likelihood of data; $G=\frac{A(A+1)}{2}$, $A=\#\{alleles\}$\\ +{\tt GT} & {\tt uint8\_t[n]} & {\tt missing\char60\char60 7 | phased\char60\char60 6 | allele1\char60\char60 3 | allele2} \\ +{\tt \_GT} & {\tt uint8\_t+uint8\_t[n*P]} & {Generic GT; the first int equals the max ploidy $P$. If the highest bit is set, + the allele is not present (e.g. due to different ploidy between samples).} \\ +{\tt GQ} & {\tt uint8\_t[n]} & {Genotype quality}\\ +{\tt HQ} & {\tt uint8\_t[n*2]} & {Haplotype quality}\\ +{\tt \_HQ} & {\tt uint8\_t+uint8\_t[n*P]} & {Generic HQ}\\ +{\tt IBD} & {\tt uint32\_t[n*2]} & {IBD}\\ +{\tt \_IBD} & {\tt uint8\_t+uint32\_t[n*P]} & {Generic IBD}\\ +{\tt PL} & {\tt uint8\_t[n*G]} & {Phred-scaled likelihood of data}\\ +{\tt PS} & {\tt uint32\_t[n]} & {Phase set}\\ +%{\tt SP} & {\tt uint8\_t[n]} & {Strand bias P-value (bcftools only)}\\ +\emph{Integer} & {\tt int32\_t[n*X]} & {Fix-sized custom Integer; $X$ defined in the header}\\ +\emph{Numeric} & {\tt double[n*X]} & {Fix-sized custom Numeric}\\ +\emph{String} & {\tt uint32\_t+char*} & {\tt NULL} padded concat. strings (int equals to the length) \\ +\hline +\end{tabular} +\end{center} + +\begin{itemize} +\item A BCF file is in the {\tt BGZF} format. +\item All multi-byte numbers are little-endian. +\item In a string, a missing value `.' is an empty C string ``{\tt + \char92 0}'' (not ``{\tt .\char92 0}'') +\item For {\tt GL} and {\tt PL}, likelihoods of genotypes appear in the + order of alleles in {\tt REF} and then {\tt ALT}. For example, if {\tt + REF=C}, {\tt ALT=T,A}, likelihoods appear in the order of {\tt + CC,CT,TT,CA,TA,AA} (NB: the ordering is different from the one in the original + BCF proposal). +\item Predefined {\tt FORMAT} fields can be missing from VCF headers, but custom {\tt FORMAT} fields + are required to be explicitly defined in the headers. +\item A {\tt FORMAT} field with its name starting with `{\tt \_}' is specific to BCF only. + It gives an alternative binary representation of the corresponding VCF field, in case + the default representation is unable to keep the genotype information, + for example, when the ploidy is not 2 or there are more than 8 alleles. +\end{itemize} + +\end{document}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bcftools/bcf2qcall.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,91 @@ +#include <errno.h> +#include <math.h> +#include <string.h> +#include <stdlib.h> +#include "bcf.h" + +static int8_t nt4_table[256] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 /*'-'*/, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 0, 4, 1, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 3, 4, 4, 4, -1, 4, 4, 4, 4, 4, 4, 4, + 4, 0, 4, 1, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 3, 4, 4, 4, -1, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 +}; + +static int read_I16(bcf1_t *b, int anno[16]) +{ + char *p; + int i; + if ((p = strstr(b->info, "I16=")) == 0) return -1; + p += 4; + for (i = 0; i < 16; ++i) { + anno[i] = strtol(p, &p, 10); + if (anno[i] == 0 && (errno == EINVAL || errno == ERANGE)) return -2; + ++p; + } + return 0; +} + +int bcf_2qcall(bcf_hdr_t *h, bcf1_t *b) +{ + int a[4], k, g[10], l, map[4], k1, j, i, i0, anno[16], dp, mq, d_rest; + char *s; + if (b->ref[1] != 0 || b->n_alleles > 4) return -1; // ref is not a single base + for (i = 0; i < b->n_gi; ++i) + if (b->gi[i].fmt == bcf_str2int("PL", 2)) break; + if (i == b->n_gi) return -1; // no PL + if (read_I16(b, anno) != 0) return -1; // no I16; FIXME: can be improved + d_rest = dp = anno[0] + anno[1] + anno[2] + anno[3]; + if (dp == 0) return -1; // depth is zero + mq = (int)(sqrt((double)(anno[9] + anno[11]) / dp) + .499); + i0 = i; + a[0] = nt4_table[(int)b->ref[0]]; + if (a[0] > 3) return -1; // ref is not A/C/G/T + a[1] = a[2] = a[3] = -2; // -1 has a special meaning + if (b->alt[0] == 0) return -1; // no alternate allele + map[0] = map[1] = map[2] = map[3] = -2; + map[a[0]] = 0; + for (k = 0, s = b->alt, k1 = -1; k < 3 && *s; ++k, s += 2) { + if (s[1] != ',' && s[1] != 0) return -1; // ALT is not single base + a[k+1] = nt4_table[(int)*s]; + if (a[k+1] >= 0) map[a[k+1]] = k+1; + else k1 = k+1; + if (s[1] == 0) break; + } + for (k = 0; k < 4; ++k) + if (map[k] < 0) map[k] = k1; + for (i = 0; i < h->n_smpl; ++i) { + int d; + uint8_t *p = b->gi[i0].data + i * b->gi[i0].len; + for (j = 0; j < b->gi[i0].len; ++j) + if (p[j]) break; + d = (int)((double)d_rest / (h->n_smpl - i) + .499); + if (d == 0) d = 1; + if (j == b->gi[i0].len) d = 0; + d_rest -= d; + for (k = j = 0; k < 4; ++k) { + for (l = k; l < 4; ++l) { + int t, x = map[k], y = map[l]; + if (x > y) t = x, x = y, y = t; // swap + g[j++] = p[y * (y+1) / 2 + x]; + } + } + printf("%s\t%d\t%c", h->ns[b->tid], b->pos+1, *b->ref); + printf("\t%d\t%d\t0", d, mq); + for (j = 0; j < 10; ++j) + printf("\t%d", g[j]); + printf("\t%s\n", h->sns[i]); + } + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bcftools/bcftools.1 Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,189 @@ +.TH bcftools 1 "16 March 2011" "bcftools" "Bioinformatics tools" +.SH NAME +.PP +bcftools - Utilities for the Binary Call Format (BCF) and VCF. +.SH SYNOPSIS +.PP +bcftools index in.bcf +.PP +bcftools view in.bcf chr2:100-200 > out.vcf +.PP +bcftools view -vc in.bcf > out.vcf 2> out.afs + +.SH DESCRIPTION +.PP +Bcftools is a toolkit for processing VCF/BCF files, calling variants and +estimating site allele frequencies and allele frequency spectrums. + +.SH COMMANDS AND OPTIONS + +.TP 10 +.B view +.B bcftools view +.RB [ \-AbFGNQSucgv ] +.RB [ \-D +.IR seqDict ] +.RB [ \-l +.IR listLoci ] +.RB [ \-s +.IR listSample ] +.RB [ \-i +.IR gapSNPratio ] +.RB [ \-t +.IR mutRate ] +.RB [ \-p +.IR varThres ] +.RB [ \-P +.IR prior ] +.RB [ \-1 +.IR nGroup1 ] +.RB [ \-d +.IR minFrac ] +.RB [ \-U +.IR nPerm ] +.RB [ \-X +.IR permThres ] +.I in.bcf +.RI [ region ] + +Convert between BCF and VCF, call variant candidates and estimate allele +frequencies. + +.RS +.TP +.B Input/Output Options: +.TP 10 +.B -A +Retain all possible alternate alleles at variant sites. By default, the view +command discards unlikely alleles. +.TP 10 +.B -b +Output in the BCF format. The default is VCF. +.TP +.BI -D \ FILE +Sequence dictionary (list of chromosome names) for VCF->BCF conversion [null] +.TP +.B -F +Indicate PL is generated by r921 or before (ordering is different). +.TP +.B -G +Suppress all individual genotype information. +.TP +.BI -l \ FILE +List of sites at which information are outputted [all sites] +.TP +.B -N +Skip sites where the REF field is not A/C/G/T +.TP +.B -Q +Output the QCALL likelihood format +.TP +.BI -s \ FILE +List of samples to use. The first column in the input gives the sample names +and the second gives the ploidy, which can only be 1 or 2. When the 2nd column +is absent, the sample ploidy is assumed to be 2. In the output, the ordering of +samples will be identical to the one in +.IR FILE . +[null] +.TP +.B -S +The input is VCF instead of BCF. +.TP +.B -u +Uncompressed BCF output (force -b). +.TP +.B Consensus/Variant Calling Options: +.TP 10 +.B -c +Call variants using Bayesian inference. This option automatically invokes option +.BR -e . +.TP +.BI -d \ FLOAT +When +.B -v +is in use, skip loci where the fraction of samples covered by reads is below FLOAT. [0] +.TP +.B -e +Perform max-likelihood inference only, including estimating the site allele frequency, +testing Hardy-Weinberg equlibrium and testing associations with LRT. +.TP +.B -g +Call per-sample genotypes at variant sites (force -c) +.TP +.BI -i \ FLOAT +Ratio of INDEL-to-SNP mutation rate [0.15] +.TP +.BI -p \ FLOAT +A site is considered to be a variant if P(ref|D)<FLOAT [0.5] +.TP +.BI -P \ STR +Prior or initial allele frequency spectrum. If STR can be +.IR full , +.IR cond2 , +.I flat +or the file consisting of error output from a previous variant calling +run. +.TP +.BI -t \ FLOAT +Scaled muttion rate for variant calling [0.001] +.TP +.B -v +Output variant sites only (force -c) +.TP +.B Contrast Calling and Association Test Options: +.TP +.BI -1 \ INT +Number of group-1 samples. This option is used for dividing the samples into +two groups for contrast SNP calling or association test. +When this option is in use, the following VCF INFO will be outputted: +PC2, PCHI2 and QCHI2. [0] +.TP +.BI -U \ INT +Number of permutations for association test (effective only with +.BR -1 ) +[0] +.TP +.BI -X \ FLOAT +Only perform permutations for P(chi^2)<FLOAT (effective only with +.BR -U ) +[0.01] +.RE + +.TP +.B index +.B bcftools index +.I in.bcf + +Index sorted BCF for random access. +.RE + +.TP +.B cat +.B bcftools cat +.I in1.bcf +.RI [ "in2.bcf " [ ... "]]]" + +Concatenate BCF files. The input files are required to be sorted and +have identical samples appearing in the same order. +.RE + +.SH BCFTOOLS SPECIFIC VCF TAGS + +.TS +center box; +cb | cb | cb +l | l | l . +Tag Format Description +_ +AF1 double Max-likelihood estimate of the site allele frequency (AF) of the first ALT allele +CI95 double[2] Equal-tail Bayesian credible interval of AF at the 95% level +DP int Raw read depth (without quality filtering) +DP4 int[4] # high-quality reference forward bases, ref reverse, alternate for and alt rev bases +FQ int Consensus quality. Positive: sample genotypes different; negative: otherwise +MQ int Root-Mean-Square mapping quality of covering reads +PC2 int[2] Phred probability of AF in group1 samples being larger (,smaller) than in group2 +PCHI2 double Posterior weighted chi^2 P-value between group1 and group2 samples +PV4 double[4] P-value for strand bias, baseQ bias, mapQ bias and tail distance bias +QCHI2 int Phred-scaled PCHI2 +RP int # permutations yielding a smaller PCHI2 +.TE
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bcftools/bcfutils.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,310 @@ +#include <string.h> +#include <math.h> +#include "bcf.h" +#include "kstring.h" +#include "khash.h" +KHASH_MAP_INIT_STR(str2id, int) + +void *bcf_build_refhash(bcf_hdr_t *h) +{ + khash_t(str2id) *hash; + int i, ret; + hash = kh_init(str2id); + for (i = 0; i < h->n_ref; ++i) { + khint_t k; + k = kh_put(str2id, hash, h->ns[i], &ret); // FIXME: check ret + kh_val(hash, k) = i; + } + return hash; +} + +void *bcf_str2id_init() +{ + return kh_init(str2id); +} + +void bcf_str2id_destroy(void *_hash) +{ + khash_t(str2id) *hash = (khash_t(str2id)*)_hash; + if (hash) kh_destroy(str2id, hash); // Note that strings are not freed. +} + +void bcf_str2id_thorough_destroy(void *_hash) +{ + khash_t(str2id) *hash = (khash_t(str2id)*)_hash; + khint_t k; + if (hash == 0) return; + for (k = 0; k < kh_end(hash); ++k) + if (kh_exist(hash, k)) free((char*)kh_key(hash, k)); + kh_destroy(str2id, hash); +} + +int bcf_str2id(void *_hash, const char *str) +{ + khash_t(str2id) *hash = (khash_t(str2id)*)_hash; + khint_t k; + if (!hash) return -1; + k = kh_get(str2id, hash, str); + return k == kh_end(hash)? -1 : kh_val(hash, k); +} + +int bcf_str2id_add(void *_hash, const char *str) +{ + khint_t k; + int ret; + khash_t(str2id) *hash = (khash_t(str2id)*)_hash; + if (!hash) return -1; + k = kh_put(str2id, hash, str, &ret); + if (ret == 0) return kh_val(hash, k); + kh_val(hash, k) = kh_size(hash) - 1; + return kh_val(hash, k); +} + +int bcf_shrink_alt(bcf1_t *b, int n) +{ + char *p; + int i, j, k, n_smpl = b->n_smpl; + if (b->n_alleles <= n) return -1; + // update ALT + if (n > 1) { + for (p = b->alt, k = 1; *p; ++p) + if (*p == ',' && ++k == n) break; + *p = '\0'; + } else p = b->alt, *p = '\0'; + ++p; + memmove(p, b->flt, b->str + b->l_str - b->flt); + b->l_str -= b->flt - p; + // update PL + for (i = 0; i < b->n_gi; ++i) { + bcf_ginfo_t *g = b->gi + i; + if (g->fmt == bcf_str2int("PL", 2)) { + int l, x = b->n_alleles * (b->n_alleles + 1) / 2; + uint8_t *d = (uint8_t*)g->data; + g->len = n * (n + 1) / 2; + for (l = k = 0; l < n_smpl; ++l) { + uint8_t *dl = d + l * x; + for (j = 0; j < g->len; ++j) d[k++] = dl[j]; + } + } // FIXME: to add GL + } + b->n_alleles = n; + bcf_sync(b); + return 0; +} + +int bcf_gl2pl(bcf1_t *b) +{ + char *p; + int i, n_smpl = b->n_smpl; + bcf_ginfo_t *g; + float *d0; + uint8_t *d1; + if (strstr(b->fmt, "PL")) return -1; + if ((p = strstr(b->fmt, "GL")) == 0) return -1; + *p = 'P'; + for (i = 0; i < b->n_gi; ++i) + if (b->gi[i].fmt == bcf_str2int("GL", 2)) + break; + g = b->gi + i; + g->fmt = bcf_str2int("PL", 2); + g->len /= 4; // 4 == sizeof(float) + d0 = (float*)g->data; d1 = (uint8_t*)g->data; + for (i = 0; i < n_smpl * g->len; ++i) { + int x = (int)(-10. * d0[i] + .499); + if (x > 255) x = 255; + if (x < 0) x = 0; + d1[i] = x; + } + return 0; +} +/* FIXME: this function will fail given AB:GTX:GT. BCFtools never + * produces such FMT, but others may do. */ +int bcf_fix_gt(bcf1_t *b) +{ + char *s; + int i; + uint32_t tmp; + bcf_ginfo_t gt; + // check the presence of the GT FMT + if ((s = strstr(b->fmt, ":GT")) == 0) return 0; // no GT or GT is already the first + if (s[3] != '\0' && s[3] != ':') return 0; // :GTX in fact + tmp = bcf_str2int("GT", 2); + for (i = 0; i < b->n_gi; ++i) + if (b->gi[i].fmt == tmp) break; + if (i == b->n_gi) return 0; // no GT in b->gi; probably a bug... + gt = b->gi[i]; + // move GT to the first + for (; i > 0; --i) b->gi[i] = b->gi[i-1]; + b->gi[0] = gt; + memmove(b->fmt + 3, b->fmt, s + 1 - b->fmt); + b->fmt[0] = 'G'; b->fmt[1] = 'T'; b->fmt[2] = ':'; + return 0; +} + +int bcf_fix_pl(bcf1_t *b) +{ + int i; + uint32_t tmp; + uint8_t *PL, *swap; + bcf_ginfo_t *gi; + // pinpoint PL + tmp = bcf_str2int("PL", 2); + for (i = 0; i < b->n_gi; ++i) + if (b->gi[i].fmt == tmp) break; + if (i == b->n_gi) return 0; + // prepare + gi = b->gi + i; + PL = (uint8_t*)gi->data; + swap = alloca(gi->len); + // loop through individuals + for (i = 0; i < b->n_smpl; ++i) { + int k, l, x; + uint8_t *PLi = PL + i * gi->len; + memcpy(swap, PLi, gi->len); + for (k = x = 0; k < b->n_alleles; ++k) + for (l = k; l < b->n_alleles; ++l) + PLi[l*(l+1)/2 + k] = swap[x++]; + } + return 0; +} + +int bcf_smpl_covered(const bcf1_t *b) +{ + int i, j, n = 0; + uint32_t tmp; + bcf_ginfo_t *gi; + // pinpoint PL + tmp = bcf_str2int("PL", 2); + for (i = 0; i < b->n_gi; ++i) + if (b->gi[i].fmt == tmp) break; + if (i == b->n_gi) return 0; + // count how many samples having PL!=[0..0] + gi = b->gi + i; + for (i = 0; i < b->n_smpl; ++i) { + uint8_t *PLi = ((uint8_t*)gi->data) + i * gi->len; + for (j = 0; j < gi->len; ++j) + if (PLi[j]) break; + if (j < gi->len) ++n; + } + return n; +} + +static void *locate_field(const bcf1_t *b, const char *fmt, int l) +{ + int i; + uint32_t tmp; + tmp = bcf_str2int(fmt, l); + for (i = 0; i < b->n_gi; ++i) + if (b->gi[i].fmt == tmp) break; + return i == b->n_gi? 0 : b->gi[i].data; +} + +int bcf_anno_max(bcf1_t *b) +{ + int k, max_gq, max_sp, n_het; + kstring_t str; + uint8_t *gt, *gq; + int32_t *sp; + max_gq = max_sp = n_het = 0; + gt = locate_field(b, "GT", 2); + if (gt == 0) return -1; + gq = locate_field(b, "GQ", 2); + sp = locate_field(b, "SP", 2); + if (sp) + for (k = 0; k < b->n_smpl; ++k) + if (gt[k]&0x3f) + max_sp = max_sp > (int)sp[k]? max_sp : sp[k]; + if (gq) + for (k = 0; k < b->n_smpl; ++k) + if (gt[k]&0x3f) + max_gq = max_gq > (int)gq[k]? max_gq : gq[k]; + for (k = 0; k < b->n_smpl; ++k) { + int a1, a2; + a1 = gt[k]&7; a2 = gt[k]>>3&7; + if ((!a1 && a2) || (!a2 && a1)) { // a het + if (gq == 0) ++n_het; + else if (gq[k] >= 20) ++n_het; + } + } + if (n_het) max_sp -= (int)(4.343 * log(n_het) + .499); + if (max_sp < 0) max_sp = 0; + memset(&str, 0, sizeof(kstring_t)); + if (*b->info) kputc(';', &str); + ksprintf(&str, "MXSP=%d;MXGQ=%d", max_sp, max_gq); + bcf_append_info(b, str.s, str.l); + free(str.s); + return 0; +} + +// FIXME: only data are shuffled; the header is NOT +int bcf_shuffle(bcf1_t *b, int seed) +{ + int i, j, *a; + if (seed > 0) srand48(seed); + a = malloc(b->n_smpl * sizeof(int)); + for (i = 0; i < b->n_smpl; ++i) a[i] = i; + for (i = b->n_smpl; i > 1; --i) { + int tmp; + j = (int)(drand48() * i); + tmp = a[j]; a[j] = a[i-1]; a[i-1] = tmp; + } + for (j = 0; j < b->n_gi; ++j) { + bcf_ginfo_t *gi = b->gi + j; + uint8_t *swap, *data = (uint8_t*)gi->data; + swap = malloc(gi->len * b->n_smpl); + for (i = 0; i < b->n_smpl; ++i) + memcpy(swap + gi->len * a[i], data + gi->len * i, gi->len); + free(gi->data); + gi->data = swap; + } + free(a); + return 0; +} + +bcf_hdr_t *bcf_hdr_subsam(const bcf_hdr_t *h0, int n, char *const* samples, int *list) +{ + int i, ret, j; + khint_t k; + bcf_hdr_t *h; + khash_t(str2id) *hash; + kstring_t s; + s.l = s.m = 0; s.s = 0; + hash = kh_init(str2id); + for (i = 0; i < h0->n_smpl; ++i) { + k = kh_put(str2id, hash, h0->sns[i], &ret); + kh_val(hash, k) = i; + } + for (i = j = 0; i < n; ++i) { + k = kh_get(str2id, hash, samples[i]); + if (k != kh_end(hash)) { + list[j++] = kh_val(hash, k); + kputs(samples[i], &s); kputc('\0', &s); + } + } + if (j < n) fprintf(stderr, "<%s> %d samples in the list but not in BCF.", __func__, n - j); + kh_destroy(str2id, hash); + h = calloc(1, sizeof(bcf_hdr_t)); + *h = *h0; + h->ns = 0; h->sns = 0; + h->name = malloc(h->l_nm); memcpy(h->name, h0->name, h->l_nm); + h->txt = calloc(1, h->l_txt + 1); memcpy(h->txt, h0->txt, h->l_txt); + h->l_smpl = s.l; h->sname = s.s; + bcf_hdr_sync(h); + return h; +} + +int bcf_subsam(int n_smpl, int *list, bcf1_t *b) +{ + int i, j; + for (j = 0; j < b->n_gi; ++j) { + bcf_ginfo_t *gi = b->gi + j; + uint8_t *swap; + swap = malloc(gi->len * b->n_smpl); + for (i = 0; i < n_smpl; ++i) + memcpy(swap + i * gi->len, (uint8_t*)gi->data + list[i] * gi->len, gi->len); + free(gi->data); + gi->data = swap; + } + b->n_smpl = n_smpl; + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bcftools/call1.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,527 @@ +#include <unistd.h> +#include <stdlib.h> +#include <math.h> +#include <zlib.h> +#include <errno.h> +#include "bcf.h" +#include "prob1.h" +#include "kstring.h" +#include "time.h" + +#include "kseq.h" +KSTREAM_INIT(gzFile, gzread, 16384) + +#define VC_NO_GENO 2 +#define VC_BCFOUT 4 +#define VC_CALL 8 +#define VC_VARONLY 16 +#define VC_VCFIN 32 +#define VC_UNCOMP 64 +#define VC_KEEPALT 256 +#define VC_ACGT_ONLY 512 +#define VC_QCALL 1024 +#define VC_CALL_GT 2048 +#define VC_ADJLD 4096 +#define VC_NO_INDEL 8192 +#define VC_ANNO_MAX 16384 +#define VC_FIX_PL 32768 +#define VC_EM 0x10000 + +typedef struct { + int flag, prior_type, n1, n_sub, *sublist, n_perm; + char *prior_file, **subsam, *fn_dict; + uint8_t *ploidy; + double theta, pref, indel_frac, min_perm_p, min_smpl_frac, min_lrt; + void *bed; +} viewconf_t; + +void *bed_read(const char *fn); +void bed_destroy(void *_h); +int bed_overlap(const void *_h, const char *chr, int beg, int end); + +typedef struct { + double p[4]; + int mq, depth, is_tested, d[4]; +} anno16_t; + +static double ttest(int n1, int n2, int a[4]) +{ + extern double kf_betai(double a, double b, double x); + double t, v, u1, u2; + if (n1 == 0 || n2 == 0 || n1 + n2 < 3) return 1.0; + u1 = (double)a[0] / n1; u2 = (double)a[2] / n2; + if (u1 <= u2) return 1.; + t = (u1 - u2) / sqrt(((a[1] - n1 * u1 * u1) + (a[3] - n2 * u2 * u2)) / (n1 + n2 - 2) * (1./n1 + 1./n2)); + v = n1 + n2 - 2; +// printf("%d,%d,%d,%d,%lf,%lf,%lf\n", a[0], a[1], a[2], a[3], t, u1, u2); + return t < 0.? 1. : .5 * kf_betai(.5*v, .5, v/(v+t*t)); +} + +static int test16_core(int anno[16], anno16_t *a) +{ + extern double kt_fisher_exact(int n11, int n12, int n21, int n22, double *_left, double *_right, double *two); + double left, right; + int i; + a->p[0] = a->p[1] = a->p[2] = a->p[3] = 1.; + memcpy(a->d, anno, 4 * sizeof(int)); + a->depth = anno[0] + anno[1] + anno[2] + anno[3]; + a->is_tested = (anno[0] + anno[1] > 0 && anno[2] + anno[3] > 0); + if (a->depth == 0) return -1; + a->mq = (int)(sqrt((anno[9] + anno[11]) / a->depth) + .499); + kt_fisher_exact(anno[0], anno[1], anno[2], anno[3], &left, &right, &a->p[0]); + for (i = 1; i < 4; ++i) + a->p[i] = ttest(anno[0] + anno[1], anno[2] + anno[3], anno+4*i); + return 0; +} + +static int test16(bcf1_t *b, anno16_t *a) +{ + char *p; + int i, anno[16]; + a->p[0] = a->p[1] = a->p[2] = a->p[3] = 1.; + a->d[0] = a->d[1] = a->d[2] = a->d[3] = 0.; + a->mq = a->depth = a->is_tested = 0; + if ((p = strstr(b->info, "I16=")) == 0) return -1; + p += 4; + for (i = 0; i < 16; ++i) { + errno = 0; anno[i] = strtol(p, &p, 10); + if (anno[i] == 0 && (errno == EINVAL || errno == ERANGE)) return -2; + ++p; + } + return test16_core(anno, a); +} + +static void rm_info(bcf1_t *b, const char *key) +{ + char *p, *q; + if ((p = strstr(b->info, key)) == 0) return; + for (q = p; *q && *q != ';'; ++q); + if (p > b->info && *(p-1) == ';') --p; + memmove(p, q, b->l_str - (q - b->str)); + b->l_str -= q - p; + bcf_sync(b); +} + +static int update_bcf1(bcf1_t *b, const bcf_p1aux_t *pa, const bcf_p1rst_t *pr, double pref, int flag, double em[9]) +{ + kstring_t s; + int has_I16, is_var; + double fq, r; + anno16_t a; + + has_I16 = test16(b, &a) >= 0? 1 : 0; + rm_info(b, "I16="); // FIXME: probably this function has a bug. If I move it below, I16 will not be removed! + + memset(&s, 0, sizeof(kstring_t)); + kputc('\0', &s); kputs(b->ref, &s); kputc('\0', &s); + kputs(b->alt, &s); kputc('\0', &s); kputc('\0', &s); + kputs(b->info, &s); + if (b->info[0]) kputc(';', &s); + { // print EM + if (em[0] >= 0) ksprintf(&s, "AF1=%.4g", 1 - em[0]); + if (em[4] >= 0 && em[4] <= 0.05) ksprintf(&s, ";G3=%.4g,%.4g,%.4g;HWE=%.3g", em[3], em[2], em[1], em[4]); + if (em[5] >= 0 && em[6] >= 0) ksprintf(&s, ";AF2=%.4g,%.4g", 1 - em[5], 1 - em[6]); + if (em[7] >= 0) ksprintf(&s, ";LRT=%.3g", em[7]); + } + if (pr == 0) { // if pr is unset, return + kputc('\0', &s); kputs(b->fmt, &s); kputc('\0', &s); + free(b->str); + b->m_str = s.m; b->l_str = s.l; b->str = s.s; + bcf_sync(b); + return 1; + } + + is_var = (pr->p_ref < pref); + r = is_var? pr->p_ref : pr->p_var; + + ksprintf(&s, ";CI95=%.4g,%.4g", pr->cil, pr->cih); // FIXME: when EM is not used, ";" should be omitted! + if (has_I16) ksprintf(&s, ";DP4=%d,%d,%d,%d;MQ=%d", a.d[0], a.d[1], a.d[2], a.d[3], a.mq); + fq = pr->p_ref_folded < 0.5? -4.343 * log(pr->p_ref_folded) : 4.343 * log(pr->p_var_folded); + if (fq < -999) fq = -999; + if (fq > 999) fq = 999; + ksprintf(&s, ";FQ=%.3g", fq); + if (pr->cmp[0] >= 0.) { // two sample groups + int i, q[3]; + for (i = 1; i < 3; ++i) { + double x = pr->cmp[i] + pr->cmp[0]/2.; + q[i] = x == 0? 255 : (int)(-4.343 * log(x) + .499); + if (q[i] > 255) q[i] = 255; + } + if (pr->perm_rank >= 0) ksprintf(&s, ";PR=%d", pr->perm_rank); + ksprintf(&s, ";PCHI2=%.3g;PC2=%d,%d", q[1], q[2], pr->p_chi2); + } + if (has_I16 && a.is_tested) ksprintf(&s, ";PV4=%.2g,%.2g,%.2g,%.2g", a.p[0], a.p[1], a.p[2], a.p[3]); + kputc('\0', &s); + kputs(b->fmt, &s); kputc('\0', &s); + free(b->str); + b->m_str = s.m; b->l_str = s.l; b->str = s.s; + b->qual = r < 1e-100? 999 : -4.343 * log(r); + if (b->qual > 999) b->qual = 999; + bcf_sync(b); + if (!is_var) bcf_shrink_alt(b, 1); + else if (!(flag&VC_KEEPALT)) + bcf_shrink_alt(b, pr->rank0 < 2? 2 : pr->rank0+1); + if (is_var && (flag&VC_CALL_GT)) { // call individual genotype + int i, x, old_n_gi = b->n_gi; + s.m = b->m_str; s.l = b->l_str - 1; s.s = b->str; + kputs(":GT:GQ", &s); kputc('\0', &s); + b->m_str = s.m; b->l_str = s.l; b->str = s.s; + bcf_sync(b); + for (i = 0; i < b->n_smpl; ++i) { + x = bcf_p1_call_gt(pa, pr->f_exp, i); + ((uint8_t*)b->gi[old_n_gi].data)[i] = (x&3) == 0? 1<<3|1 : (x&3) == 1? 1 : 0; + ((uint8_t*)b->gi[old_n_gi+1].data)[i] = x>>2; + } + } + return is_var; +} + +static char **read_samples(const char *fn, int *_n) +{ + gzFile fp; + kstream_t *ks; + kstring_t s; + int dret, n = 0, max = 0; + char **sam = 0; + *_n = 0; + s.l = s.m = 0; s.s = 0; + fp = gzopen(fn, "r"); + if (fp == 0) return 0; // fail to open file + ks = ks_init(fp); + while (ks_getuntil(ks, 0, &s, &dret) >= 0) { + int l; + if (max == n) { + max = max? max<<1 : 4; + sam = realloc(sam, sizeof(void*)*max); + } + l = s.l; + sam[n] = malloc(s.l + 2); + strcpy(sam[n], s.s); + sam[n][l+1] = 2; // by default, diploid + if (dret != '\n') { + if (ks_getuntil(ks, 0, &s, &dret) >= 0) { // read ploidy, 1 or 2 + int x = (int)s.s[0] - '0'; + if (x == 1 || x == 2) sam[n][l+1] = x; + else fprintf(stderr, "(%s) ploidy can only be 1 or 2; assume diploid\n", __func__); + } + if (dret != '\n') ks_getuntil(ks, '\n', &s, &dret); + } + ++n; + } + ks_destroy(ks); + gzclose(fp); + free(s.s); + *_n = n; + return sam; +} + +static void write_header(bcf_hdr_t *h) +{ + kstring_t str; + str.l = h->l_txt? h->l_txt - 1 : 0; + str.m = str.l + 1; str.s = h->txt; + if (!strstr(str.s, "##INFO=<ID=DP,")) + kputs("##INFO=<ID=DP,Number=1,Type=Integer,Description=\"Raw read depth\">\n", &str); + if (!strstr(str.s, "##INFO=<ID=DP4,")) + kputs("##INFO=<ID=DP4,Number=4,Type=Integer,Description=\"# high-quality ref-forward bases, ref-reverse, alt-forward and alt-reverse bases\">\n", &str); + if (!strstr(str.s, "##INFO=<ID=MQ,")) + kputs("##INFO=<ID=MQ,Number=1,Type=Integer,Description=\"Root-mean-square mapping quality of covering reads\">\n", &str); + if (!strstr(str.s, "##INFO=<ID=FQ,")) + kputs("##INFO=<ID=FQ,Number=1,Type=Float,Description=\"Phred probability of all samples being the same\">\n", &str); + if (!strstr(str.s, "##INFO=<ID=AF1,")) + kputs("##INFO=<ID=AF1,Number=1,Type=Float,Description=\"Max-likelihood estimate of the site allele frequency of the first ALT allele\">\n", &str); + if (!strstr(str.s, "##INFO=<ID=G3,")) + kputs("##INFO=<ID=G3,Number=3,Type=Float,Description=\"ML estimate of genotype frequencies\">\n", &str); + if (!strstr(str.s, "##INFO=<ID=HWE,")) + kputs("##INFO=<ID=HWE,Number=1,Type=Float,Description=\"Chi^2 based HWE test P-value based on G3\">\n", &str); + if (!strstr(str.s, "##INFO=<ID=CI95,")) + kputs("##INFO=<ID=CI95,Number=2,Type=Float,Description=\"Equal-tail Bayesian credible interval of the site allele frequency at the 95% level\">\n", &str); + if (!strstr(str.s, "##INFO=<ID=PV4,")) + kputs("##INFO=<ID=PV4,Number=4,Type=Float,Description=\"P-values for strand bias, baseQ bias, mapQ bias and tail distance bias\">\n", &str); + if (!strstr(str.s, "##INFO=<ID=INDEL,")) + kputs("##INFO=<ID=INDEL,Number=0,Type=Flag,Description=\"Indicates that the variant is an INDEL.\">\n", &str); + if (!strstr(str.s, "##INFO=<ID=PC2,")) + kputs("##INFO=<ID=PC2,Number=2,Type=Integer,Description=\"Phred probability of the nonRef allele frequency in group1 samples being larger (,smaller) than in group2.\">\n", &str); + if (!strstr(str.s, "##INFO=<ID=PCHI2,")) + kputs("##INFO=<ID=PCHI2,Number=1,Type=Float,Description=\"Posterior weighted chi^2 P-value for testing the association between group1 and group2 samples.\">\n", &str); + if (!strstr(str.s, "##INFO=<ID=QCHI2,")) + kputs("##INFO=<ID=QCHI2,Number=1,Type=Integer,Description=\"Phred scaled PCHI2.\">\n", &str); + if (!strstr(str.s, "##INFO=<ID=RP,")) + kputs("##INFO=<ID=PR,Number=1,Type=Integer,Description=\"# permutations yielding a smaller PCHI2.\">\n", &str); + if (!strstr(str.s, "##FORMAT=<ID=GT,")) + kputs("##FORMAT=<ID=GT,Number=1,Type=String,Description=\"Genotype\">\n", &str); + if (!strstr(str.s, "##FORMAT=<ID=GQ,")) + kputs("##FORMAT=<ID=GQ,Number=1,Type=Integer,Description=\"Genotype Quality\">\n", &str); + if (!strstr(str.s, "##FORMAT=<ID=GL,")) + kputs("##FORMAT=<ID=GL,Number=3,Type=Float,Description=\"Likelihoods for RR,RA,AA genotypes (R=ref,A=alt)\">\n", &str); + if (!strstr(str.s, "##FORMAT=<ID=DP,")) + kputs("##FORMAT=<ID=DP,Number=1,Type=Integer,Description=\"# high-quality bases\">\n", &str); + if (!strstr(str.s, "##FORMAT=<ID=SP,")) + kputs("##FORMAT=<ID=SP,Number=1,Type=Integer,Description=\"Phred-scaled strand bias P-value\">\n", &str); + if (!strstr(str.s, "##FORMAT=<ID=PL,")) + kputs("##FORMAT=<ID=PL,Number=-1,Type=Integer,Description=\"List of Phred-scaled genotype likelihoods, number of values is (#ALT+1)*(#ALT+2)/2\">\n", &str); + h->l_txt = str.l + 1; h->txt = str.s; +} + +double bcf_pair_freq(const bcf1_t *b0, const bcf1_t *b1, double f[4]); + +int bcfview(int argc, char *argv[]) +{ + extern int bcf_2qcall(bcf_hdr_t *h, bcf1_t *b); + extern void bcf_p1_indel_prior(bcf_p1aux_t *ma, double x); + extern int bcf_fix_gt(bcf1_t *b); + extern int bcf_anno_max(bcf1_t *b); + extern int bcf_shuffle(bcf1_t *b, int seed); + bcf_t *bp, *bout = 0; + bcf1_t *b, *blast; + int c, *seeds = 0; + uint64_t n_processed = 0; + viewconf_t vc; + bcf_p1aux_t *p1 = 0; + bcf_hdr_t *hin, *hout; + int tid, begin, end; + char moder[4], modew[4]; + + tid = begin = end = -1; + memset(&vc, 0, sizeof(viewconf_t)); + vc.prior_type = vc.n1 = -1; vc.theta = 1e-3; vc.pref = 0.5; vc.indel_frac = -1.; vc.n_perm = 0; vc.min_perm_p = 0.01; vc.min_smpl_frac = 0; vc.min_lrt = 1; + while ((c = getopt(argc, argv, "FN1:l:cC:eHAGvbSuP:t:p:QgLi:IMs:D:U:X:d:")) >= 0) { + switch (c) { + case '1': vc.n1 = atoi(optarg); break; + case 'l': vc.bed = bed_read(optarg); break; + case 'D': vc.fn_dict = strdup(optarg); break; + case 'F': vc.flag |= VC_FIX_PL; break; + case 'N': vc.flag |= VC_ACGT_ONLY; break; + case 'G': vc.flag |= VC_NO_GENO; break; + case 'A': vc.flag |= VC_KEEPALT; break; + case 'b': vc.flag |= VC_BCFOUT; break; + case 'S': vc.flag |= VC_VCFIN; break; + case 'c': vc.flag |= VC_CALL; break; + case 'e': vc.flag |= VC_EM; break; + case 'v': vc.flag |= VC_VARONLY | VC_CALL; break; + case 'u': vc.flag |= VC_UNCOMP | VC_BCFOUT; break; + case 'g': vc.flag |= VC_CALL_GT | VC_CALL; break; + case 'I': vc.flag |= VC_NO_INDEL; break; + case 'M': vc.flag |= VC_ANNO_MAX; break; + case 't': vc.theta = atof(optarg); break; + case 'p': vc.pref = atof(optarg); break; + case 'i': vc.indel_frac = atof(optarg); break; + case 'Q': vc.flag |= VC_QCALL; break; + case 'L': vc.flag |= VC_ADJLD; break; + case 'U': vc.n_perm = atoi(optarg); break; + case 'C': vc.min_lrt = atof(optarg); break; + case 'X': vc.min_perm_p = atof(optarg); break; + case 'd': vc.min_smpl_frac = atof(optarg); break; + case 's': vc.subsam = read_samples(optarg, &vc.n_sub); + vc.ploidy = calloc(vc.n_sub + 1, 1); + for (tid = 0; tid < vc.n_sub; ++tid) vc.ploidy[tid] = vc.subsam[tid][strlen(vc.subsam[tid]) + 1]; + tid = -1; + break; + case 'P': + if (strcmp(optarg, "full") == 0) vc.prior_type = MC_PTYPE_FULL; + else if (strcmp(optarg, "cond2") == 0) vc.prior_type = MC_PTYPE_COND2; + else if (strcmp(optarg, "flat") == 0) vc.prior_type = MC_PTYPE_FLAT; + else vc.prior_file = strdup(optarg); + break; + } + } + if (argc == optind) { + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: bcftools view [options] <in.bcf> [reg]\n\n"); + fprintf(stderr, "Input/output options:\n\n"); + fprintf(stderr, " -A keep all possible alternate alleles at variant sites\n"); + fprintf(stderr, " -b output BCF instead of VCF\n"); + fprintf(stderr, " -D FILE sequence dictionary for VCF->BCF conversion [null]\n"); + fprintf(stderr, " -F PL generated by r921 or before (which generate old ordering)\n"); + fprintf(stderr, " -G suppress all individual genotype information\n"); + fprintf(stderr, " -l FILE list of sites (chr pos) or regions (BED) to output [all sites]\n"); + fprintf(stderr, " -L calculate LD for adjacent sites\n"); + fprintf(stderr, " -N skip sites where REF is not A/C/G/T\n"); + fprintf(stderr, " -Q output the QCALL likelihood format\n"); + fprintf(stderr, " -s FILE list of samples to use [all samples]\n"); + fprintf(stderr, " -S input is VCF\n"); + fprintf(stderr, " -u uncompressed BCF output (force -b)\n"); + fprintf(stderr, "\nConsensus/variant calling options:\n\n"); + fprintf(stderr, " -c SNP calling (force -e)\n"); + fprintf(stderr, " -d FLOAT skip loci where less than FLOAT fraction of samples covered [0]\n"); + fprintf(stderr, " -e likelihood based analyses\n"); + fprintf(stderr, " -g call genotypes at variant sites (force -c)\n"); + fprintf(stderr, " -i FLOAT indel-to-substitution ratio [%.4g]\n", vc.indel_frac); + fprintf(stderr, " -I skip indels\n"); + fprintf(stderr, " -p FLOAT variant if P(ref|D)<FLOAT [%.3g]\n", vc.pref); + fprintf(stderr, " -P STR type of prior: full, cond2, flat [full]\n"); + fprintf(stderr, " -t FLOAT scaled substitution mutation rate [%.4g]\n", vc.theta); + fprintf(stderr, " -v output potential variant sites only (force -c)\n"); + fprintf(stderr, "\nContrast calling and association test options:\n\n"); + fprintf(stderr, " -1 INT number of group-1 samples [0]\n"); + fprintf(stderr, " -C FLOAT posterior constrast for LRT<FLOAT and P(ref|D)<0.5 [%g]\n", vc.min_lrt); + fprintf(stderr, " -U INT number of permutations for association testing (effective with -1) [0]\n"); + fprintf(stderr, " -X FLOAT only perform permutations for P(chi^2)<FLOAT [%g]\n", vc.min_perm_p); + fprintf(stderr, "\n"); + return 1; + } + + if (vc.flag & VC_CALL) vc.flag |= VC_EM; + if ((vc.flag & VC_VCFIN) && (vc.flag & VC_BCFOUT) && vc.fn_dict == 0) { + fprintf(stderr, "[%s] For VCF->BCF conversion please specify the sequence dictionary with -D\n", __func__); + return 1; + } + if (vc.n1 <= 0) vc.n_perm = 0; // TODO: give a warning here! + if (vc.n_perm > 0) { + seeds = malloc(vc.n_perm * sizeof(int)); + srand48(time(0)); + for (c = 0; c < vc.n_perm; ++c) seeds[c] = lrand48(); + } + b = calloc(1, sizeof(bcf1_t)); + blast = calloc(1, sizeof(bcf1_t)); + strcpy(moder, "r"); + if (!(vc.flag & VC_VCFIN)) strcat(moder, "b"); + strcpy(modew, "w"); + if (vc.flag & VC_BCFOUT) strcat(modew, "b"); + if (vc.flag & VC_UNCOMP) strcat(modew, "u"); + bp = vcf_open(argv[optind], moder); + hin = hout = vcf_hdr_read(bp); + if (vc.fn_dict && (vc.flag & VC_VCFIN)) + vcf_dictread(bp, hin, vc.fn_dict); + bout = vcf_open("-", modew); + if (!(vc.flag & VC_QCALL)) { + if (vc.n_sub) { + vc.sublist = calloc(vc.n_sub, sizeof(int)); + hout = bcf_hdr_subsam(hin, vc.n_sub, vc.subsam, vc.sublist); + } + if (vc.flag & VC_CALL) write_header(hout); + vcf_hdr_write(bout, hout); + } + if (vc.flag & VC_CALL) { + p1 = bcf_p1_init(hout->n_smpl, vc.ploidy); + if (vc.prior_file) { + if (bcf_p1_read_prior(p1, vc.prior_file) < 0) { + fprintf(stderr, "[%s] fail to read the prior AFS.\n", __func__); + return 1; + } + } else bcf_p1_init_prior(p1, vc.prior_type, vc.theta); + if (vc.n1 > 0 && vc.min_lrt > 0.) { // set n1 + bcf_p1_set_n1(p1, vc.n1); + bcf_p1_init_subprior(p1, vc.prior_type, vc.theta); + } + if (vc.indel_frac > 0.) bcf_p1_indel_prior(p1, vc.indel_frac); // otherwise use the default indel_frac + } + if (optind + 1 < argc && !(vc.flag&VC_VCFIN)) { + void *str2id = bcf_build_refhash(hout); + if (bcf_parse_region(str2id, argv[optind+1], &tid, &begin, &end) >= 0) { + bcf_idx_t *idx; + idx = bcf_idx_load(argv[optind]); + if (idx) { + uint64_t off; + off = bcf_idx_query(idx, tid, begin); + if (off == 0) { + fprintf(stderr, "[%s] no records in the query region.\n", __func__); + return 1; // FIXME: a lot of memory leaks... + } + bgzf_seek(bp->fp, off, SEEK_SET); + bcf_idx_destroy(idx); + } + } + } + while (vcf_read(bp, hin, b) > 0) { + int is_indel; + double em[9]; + if ((vc.flag & VC_VARONLY) && strcmp(b->alt, "X") == 0) continue; + if ((vc.flag & VC_VARONLY) && vc.min_smpl_frac > 0.) { + extern int bcf_smpl_covered(const bcf1_t *b); + int n = bcf_smpl_covered(b); + if ((double)n / b->n_smpl < vc.min_smpl_frac) continue; + } + if (vc.n_sub) bcf_subsam(vc.n_sub, vc.sublist, b); + if (vc.flag & VC_FIX_PL) bcf_fix_pl(b); + is_indel = bcf_is_indel(b); + if ((vc.flag & VC_NO_INDEL) && is_indel) continue; + if ((vc.flag & VC_ACGT_ONLY) && !is_indel) { + int x; + if (b->ref[0] == 0 || b->ref[1] != 0) continue; + x = toupper(b->ref[0]); + if (x != 'A' && x != 'C' && x != 'G' && x != 'T') continue; + } + if (vc.bed && !bed_overlap(vc.bed, hin->ns[b->tid], b->pos, b->pos + strlen(b->ref))) continue; + if (tid >= 0) { + int l = strlen(b->ref); + l = b->pos + (l > 0? l : 1); + if (b->tid != tid || b->pos >= end) break; + if (!(l > begin && end > b->pos)) continue; + } + ++n_processed; + if (vc.flag & VC_QCALL) { // output QCALL format; STOP here + bcf_2qcall(hout, b); + continue; + } + if (vc.flag & VC_EM) bcf_em1(b, vc.n1, 0xff, em); + else { + int i; + for (i = 0; i < 9; ++i) em[i] = -1.; + } + if (vc.flag & (VC_CALL|VC_ADJLD)) bcf_gl2pl(b); + if (vc.flag & VC_CALL) { // call variants + bcf_p1rst_t pr; + int calret = bcf_p1_cal(b, (em[7] >= 0 && em[7] < vc.min_lrt), p1, &pr); + if (n_processed % 100000 == 0) { + fprintf(stderr, "[%s] %ld sites processed.\n", __func__, (long)n_processed); + bcf_p1_dump_afs(p1); + } + if (pr.p_ref >= vc.pref && (vc.flag & VC_VARONLY)) continue; + if (vc.n_perm && vc.n1 > 0 && pr.p_chi2 < vc.min_perm_p) { // permutation test + bcf_p1rst_t r; + int i, n = 0; + for (i = 0; i < vc.n_perm; ++i) { +#ifdef BCF_PERM_LRT // LRT based permutation is much faster but less robust to artifacts + double x[9]; + bcf_shuffle(b, seeds[i]); + bcf_em1(b, vc.n1, 1<<7, x); + if (x[7] < em[7]) ++n; +#else + bcf_shuffle(b, seeds[i]); + bcf_p1_cal(b, 1, p1, &r); + if (pr.p_chi2 >= r.p_chi2) ++n; +#endif + } + pr.perm_rank = n; + } + if (calret >= 0) update_bcf1(b, p1, &pr, vc.pref, vc.flag, em); + } else if (vc.flag & VC_EM) update_bcf1(b, 0, 0, 0, vc.flag, em); + if (vc.flag & VC_ADJLD) { // compute LD + double f[4], r2; + if ((r2 = bcf_pair_freq(blast, b, f)) >= 0) { + kstring_t s; + s.m = s.l = 0; s.s = 0; + if (*b->info) kputc(';', &s); + ksprintf(&s, "NEIR=%.3f;NEIF4=%.3f,%.3f,%.3f,%.3f", r2, f[0], f[1], f[2], f[3]); + bcf_append_info(b, s.s, s.l); + free(s.s); + } + bcf_cpy(blast, b); + } + if (vc.flag & VC_ANNO_MAX) bcf_anno_max(b); + if (vc.flag & VC_NO_GENO) { // do not output GENO fields + b->n_gi = 0; + b->fmt[0] = '\0'; + b->l_str = b->fmt - b->str + 1; + } else bcf_fix_gt(b); + vcf_write(bout, hout, b); + } + if (vc.prior_file) free(vc.prior_file); + if (vc.flag & VC_CALL) bcf_p1_dump_afs(p1); + if (hin != hout) bcf_hdr_destroy(hout); + bcf_hdr_destroy(hin); + bcf_destroy(b); bcf_destroy(blast); + vcf_close(bp); vcf_close(bout); + if (vc.fn_dict) free(vc.fn_dict); + if (vc.ploidy) free(vc.ploidy); + if (vc.n_sub) { + int i; + for (i = 0; i < vc.n_sub; ++i) free(vc.subsam[i]); + free(vc.subsam); free(vc.sublist); + } + if (vc.bed) bed_destroy(vc.bed); + if (seeds) free(seeds); + if (p1) bcf_p1_destroy(p1); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bcftools/em.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,306 @@ +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include "bcf.h" +#include "kmin.h" + +static double g_q2p[256]; + +#define ITER_MAX 50 +#define ITER_TRY 10 +#define EPS 1e-5 + +extern double kf_gammaq(double, double); + +/* + Generic routines + */ +// get the 3 genotype likelihoods +static double *get_pdg3(const bcf1_t *b) +{ + double *pdg; + const uint8_t *PL = 0; + int i, PL_len = 0; + // initialize g_q2p if necessary + if (g_q2p[0] == 0.) + for (i = 0; i < 256; ++i) + g_q2p[i] = pow(10., -i / 10.); + // set PL and PL_len + for (i = 0; i < b->n_gi; ++i) { + if (b->gi[i].fmt == bcf_str2int("PL", 2)) { + PL = (const uint8_t*)b->gi[i].data; + PL_len = b->gi[i].len; + break; + } + } + if (i == b->n_gi) return 0; // no PL + // fill pdg + pdg = malloc(3 * b->n_smpl * sizeof(double)); + for (i = 0; i < b->n_smpl; ++i) { + const uint8_t *pi = PL + i * PL_len; + double *p = pdg + i * 3; + p[0] = g_q2p[pi[2]]; p[1] = g_q2p[pi[1]]; p[2] = g_q2p[pi[0]]; + } + return pdg; +} + +// estimate site allele frequency in a very naive and inaccurate way +static double est_freq(int n, const double *pdg) +{ + int i, gcnt[3], tmp1; + // get a rough estimate of the genotype frequency + gcnt[0] = gcnt[1] = gcnt[2] = 0; + for (i = 0; i < n; ++i) { + const double *p = pdg + i * 3; + if (p[0] != 1. || p[1] != 1. || p[2] != 1.) { + int which = p[0] > p[1]? 0 : 1; + which = p[which] > p[2]? which : 2; + ++gcnt[which]; + } + } + tmp1 = gcnt[0] + gcnt[1] + gcnt[2]; + return (tmp1 == 0)? -1.0 : (.5 * gcnt[1] + gcnt[2]) / tmp1; +} + +/* + Single-locus EM + */ + +typedef struct { + int beg, end; + const double *pdg; +} minaux1_t; + +static double prob1(double f, void *data) +{ + minaux1_t *a = (minaux1_t*)data; + double p = 1., l = 0., f3[3]; + int i; +// printf("brent %lg\n", f); + if (f < 0 || f > 1) return 1e300; + f3[0] = (1.-f)*(1.-f); f3[1] = 2.*f*(1.-f); f3[2] = f*f; + for (i = a->beg; i < a->end; ++i) { + const double *pdg = a->pdg + i * 3; + p *= pdg[0] * f3[0] + pdg[1] * f3[1] + pdg[2] * f3[2]; + if (p < 1e-200) l -= log(p), p = 1.; + } + return l - log(p); +} + +// one EM iteration for allele frequency estimate +static double freq_iter(double *f, const double *_pdg, int beg, int end) +{ + double f0 = *f, f3[3], err; + int i; +// printf("em %lg\n", *f); + f3[0] = (1.-f0)*(1.-f0); f3[1] = 2.*f0*(1.-f0); f3[2] = f0*f0; + for (i = beg, f0 = 0.; i < end; ++i) { + const double *pdg = _pdg + i * 3; + f0 += (pdg[1] * f3[1] + 2. * pdg[2] * f3[2]) + / (pdg[0] * f3[0] + pdg[1] * f3[1] + pdg[2] * f3[2]); + } + f0 /= (end - beg) * 2; + err = fabs(f0 - *f); + *f = f0; + return err; +} + +/* The following function combines EM and Brent's method. When the signal from + * the data is strong, EM is faster but sometimes, EM may converge very slowly. + * When this happens, we switch to Brent's method. The idea is learned from + * Rasmus Nielsen. + */ +static double freqml(double f0, int beg, int end, const double *pdg) +{ + int i; + double f; + for (i = 0, f = f0; i < ITER_TRY; ++i) + if (freq_iter(&f, pdg, beg, end) < EPS) break; + if (i == ITER_TRY) { // haven't converged yet; try Brent's method + minaux1_t a; + a.beg = beg; a.end = end; a.pdg = pdg; + kmin_brent(prob1, f0 == f? .5*f0 : f0, f, (void*)&a, EPS, &f); + } + return f; +} + +// one EM iteration for genotype frequency estimate +static double g3_iter(double g[3], const double *_pdg, int beg, int end) +{ + double err, gg[3]; + int i; + gg[0] = gg[1] = gg[2] = 0.; +// printf("%lg,%lg,%lg\n", g[0], g[1], g[2]); + for (i = beg; i < end; ++i) { + double sum, tmp[3]; + const double *pdg = _pdg + i * 3; + tmp[0] = pdg[0] * g[0]; tmp[1] = pdg[1] * g[1]; tmp[2] = pdg[2] * g[2]; + sum = (tmp[0] + tmp[1] + tmp[2]) * (end - beg); + gg[0] += tmp[0] / sum; gg[1] += tmp[1] / sum; gg[2] += tmp[2] / sum; + } + err = fabs(gg[0] - g[0]) > fabs(gg[1] - g[1])? fabs(gg[0] - g[0]) : fabs(gg[1] - g[1]); + err = err > fabs(gg[2] - g[2])? err : fabs(gg[2] - g[2]); + g[0] = gg[0]; g[1] = gg[1]; g[2] = gg[2]; + return err; +} + +// perform likelihood ratio test +static double lk_ratio_test(int n, int n1, const double *pdg, double f3[3][3]) +{ + double r; + int i; + for (i = 0, r = 1.; i < n1; ++i) { + const double *p = pdg + i * 3; + r *= (p[0] * f3[1][0] + p[1] * f3[1][1] + p[2] * f3[1][2]) + / (p[0] * f3[0][0] + p[1] * f3[0][1] + p[2] * f3[0][2]); + } + for (; i < n; ++i) { + const double *p = pdg + i * 3; + r *= (p[0] * f3[2][0] + p[1] * f3[2][1] + p[2] * f3[2][2]) + / (p[0] * f3[0][0] + p[1] * f3[0][1] + p[2] * f3[0][2]); + } + return r; +} + +// x[0]: ref frequency +// x[1..3]: alt-alt, alt-ref, ref-ref frequenc +// x[4]: HWE P-value +// x[5..6]: group1 freq, group2 freq +// x[7]: 1-degree P-value +// x[8]: 2-degree P-value +int bcf_em1(const bcf1_t *b, int n1, int flag, double x[9]) +{ + double *pdg; + int i, n, n2; + if (b->n_alleles < 2) return -1; // one allele only + // initialization + if (n1 < 0 || n1 > b->n_smpl) n1 = 0; + if (flag & 1<<7) flag |= 7<<5; // compute group freq if LRT is required + if (flag & 0xf<<1) flag |= 0xf<<1; + n = b->n_smpl; n2 = n - n1; + pdg = get_pdg3(b); + if (pdg == 0) return -1; + for (i = 0; i < 9; ++i) x[i] = -1.; + { + if ((x[0] = est_freq(n, pdg)) < 0.) { + free(pdg); + return -1; // no data + } + x[0] = freqml(x[0], 0, n, pdg); + } + if (flag & (0xf<<1|1<<8)) { // estimate the genotype frequency and test HWE + double *g = x + 1, f3[3], r; + f3[0] = g[0] = (1 - x[0]) * (1 - x[0]); + f3[1] = g[1] = 2 * x[0] * (1 - x[0]); + f3[2] = g[2] = x[0] * x[0]; + for (i = 0; i < ITER_MAX; ++i) + if (g3_iter(g, pdg, 0, n) < EPS) break; + // Hardy-Weinberg equilibrium (HWE) + for (i = 0, r = 1.; i < n; ++i) { + double *p = pdg + i * 3; + r *= (p[0] * g[0] + p[1] * g[1] + p[2] * g[2]) / (p[0] * f3[0] + p[1] * f3[1] + p[2] * f3[2]); + } + x[4] = kf_gammaq(.5, log(r)); + } + if ((flag & 7<<5) && n1 > 0 && n1 < n) { // group frequency + x[5] = freqml(x[0], 0, n1, pdg); + x[6] = freqml(x[0], n1, n, pdg); + } + if ((flag & 1<<7) && n1 > 0 && n1 < n) { // 1-degree P-value + double f[3], f3[3][3]; + f[0] = x[0]; f[1] = x[5]; f[2] = x[6]; + for (i = 0; i < 3; ++i) + f3[i][0] = (1-f[i])*(1-f[i]), f3[i][1] = 2*f[i]*(1-f[i]), f3[i][2] = f[i]*f[i]; + x[7] = kf_gammaq(.5, log(lk_ratio_test(n, n1, pdg, f3))); + } + if ((flag & 1<<8) && n1 > 0 && n1 < n) { // 2-degree P-value + double g[3][3]; + for (i = 0; i < 3; ++i) memcpy(g[i], x + 1, 3 * sizeof(double)); + for (i = 0; i < ITER_MAX; ++i) + if (g3_iter(g[1], pdg, 0, n1) < EPS) break; + for (i = 0; i < ITER_MAX; ++i) + if (g3_iter(g[2], pdg, n1, n) < EPS) break; + x[8] = kf_gammaq(1., log(lk_ratio_test(n, n1, pdg, g))); + } + // free + free(pdg); + return 0; +} + +/* + Two-locus EM (LD) + */ + +#define _G1(h, k) ((h>>1&1) + (k>>1&1)) +#define _G2(h, k) ((h&1) + (k&1)) + +// 0: the previous site; 1: the current site +static int pair_freq_iter(int n, double *pdg[2], double f[4]) +{ + double ff[4]; + int i, k, h; +// printf("%lf,%lf,%lf,%lf\n", f[0], f[1], f[2], f[3]); + memset(ff, 0, 4 * sizeof(double)); + for (i = 0; i < n; ++i) { + double *p[2], sum, tmp; + p[0] = pdg[0] + i * 3; p[1] = pdg[1] + i * 3; + for (k = 0, sum = 0.; k < 4; ++k) + for (h = 0; h < 4; ++h) + sum += f[k] * f[h] * p[0][_G1(k,h)] * p[1][_G2(k,h)]; + for (k = 0; k < 4; ++k) { + tmp = f[0] * (p[0][_G1(0,k)] * p[1][_G2(0,k)] + p[0][_G1(k,0)] * p[1][_G2(k,0)]) + + f[1] * (p[0][_G1(1,k)] * p[1][_G2(1,k)] + p[0][_G1(k,1)] * p[1][_G2(k,1)]) + + f[2] * (p[0][_G1(2,k)] * p[1][_G2(2,k)] + p[0][_G1(k,2)] * p[1][_G2(k,2)]) + + f[3] * (p[0][_G1(3,k)] * p[1][_G2(3,k)] + p[0][_G1(k,3)] * p[1][_G2(k,3)]); + ff[k] += f[k] * tmp / sum; + } + } + for (k = 0; k < 4; ++k) f[k] = ff[k] / (2 * n); + return 0; +} + +double bcf_pair_freq(const bcf1_t *b0, const bcf1_t *b1, double f[4]) +{ + const bcf1_t *b[2]; + int i, j, n_smpl; + double *pdg[2], flast[4], r, f0[2]; + // initialize others + if (b0->n_smpl != b1->n_smpl) return -1; // different number of samples + n_smpl = b0->n_smpl; + b[0] = b0; b[1] = b1; + f[0] = f[1] = f[2] = f[3] = -1.; + if (b[0]->n_alleles < 2 || b[1]->n_alleles < 2) return -1; // one allele only + pdg[0] = get_pdg3(b0); pdg[1] = get_pdg3(b1); + if (pdg[0] == 0 || pdg[1] == 0) { + free(pdg[0]); free(pdg[1]); + return -1; + } + // set the initial value + f0[0] = est_freq(n_smpl, pdg[0]); + f0[1] = est_freq(n_smpl, pdg[1]); + f[0] = (1 - f0[0]) * (1 - f0[1]); f[3] = f0[0] * f0[1]; + f[1] = (1 - f0[0]) * f0[1]; f[2] = f0[0] * (1 - f0[1]); + // iteration + for (j = 0; j < ITER_MAX; ++j) { + double eps = 0; + memcpy(flast, f, 4 * sizeof(double)); + pair_freq_iter(n_smpl, pdg, f); + for (i = 0; i < 4; ++i) { + double x = fabs(f[i] - flast[i]); + if (x > eps) eps = x; + } + if (eps < EPS) break; + } + // free + free(pdg[0]); free(pdg[1]); + { // calculate r^2 + double p[2], q[2], D; + p[0] = f[0] + f[1]; q[0] = 1 - p[0]; + p[1] = f[0] + f[2]; q[1] = 1 - p[1]; + D = f[0] * f[3] - f[1] * f[2]; + r = sqrt(D * D / (p[0] * p[1] * q[0] * q[1])); +// printf("R(%lf,%lf,%lf,%lf)=%lf\n", f[0], f[1], f[2], f[3], r); + if (isnan(r)) r = -1.; + } + return r; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bcftools/fet.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,112 @@ +#include <math.h> +#include <stdlib.h> + +/* This program is implemented with ideas from this web page: + * + * http://www.langsrud.com/fisher.htm + */ + +// log\binom{n}{k} +static double lbinom(int n, int k) +{ + if (k == 0 || n == k) return 0; + return lgamma(n+1) - lgamma(k+1) - lgamma(n-k+1); +} + +// n11 n12 | n1_ +// n21 n22 | n2_ +//-----------+---- +// n_1 n_2 | n + +// hypergeometric distribution +static double hypergeo(int n11, int n1_, int n_1, int n) +{ + return exp(lbinom(n1_, n11) + lbinom(n-n1_, n_1-n11) - lbinom(n, n_1)); +} + +typedef struct { + int n11, n1_, n_1, n; + double p; +} hgacc_t; + +// incremental version of hypergenometric distribution +static double hypergeo_acc(int n11, int n1_, int n_1, int n, hgacc_t *aux) +{ + if (n1_ || n_1 || n) { + aux->n11 = n11; aux->n1_ = n1_; aux->n_1 = n_1; aux->n = n; + } else { // then only n11 changed; the rest fixed + if (n11%11 && n11 + aux->n - aux->n1_ - aux->n_1) { + if (n11 == aux->n11 + 1) { // incremental + aux->p *= (double)(aux->n1_ - aux->n11) / n11 + * (aux->n_1 - aux->n11) / (n11 + aux->n - aux->n1_ - aux->n_1); + aux->n11 = n11; + return aux->p; + } + if (n11 == aux->n11 - 1) { // incremental + aux->p *= (double)aux->n11 / (aux->n1_ - n11) + * (aux->n11 + aux->n - aux->n1_ - aux->n_1) / (aux->n_1 - n11); + aux->n11 = n11; + return aux->p; + } + } + aux->n11 = n11; + } + aux->p = hypergeo(aux->n11, aux->n1_, aux->n_1, aux->n); + return aux->p; +} + +double kt_fisher_exact(int n11, int n12, int n21, int n22, double *_left, double *_right, double *two) +{ + int i, j, max, min; + double p, q, left, right; + hgacc_t aux; + int n1_, n_1, n; + + n1_ = n11 + n12; n_1 = n11 + n21; n = n11 + n12 + n21 + n22; // calculate n1_, n_1 and n + max = (n_1 < n1_) ? n_1 : n1_; // max n11, for right tail + min = n1_ + n_1 - n; + if (min < 0) min = 0; // min n11, for left tail + *two = *_left = *_right = 1.; + if (min == max) return 1.; // no need to do test + q = hypergeo_acc(n11, n1_, n_1, n, &aux); // the probability of the current table + // left tail + p = hypergeo_acc(min, 0, 0, 0, &aux); + for (left = 0., i = min + 1; p < 0.99999999 * q; ++i) // loop until underflow + left += p, p = hypergeo_acc(i, 0, 0, 0, &aux); + --i; + if (p < 1.00000001 * q) left += p; + else --i; + // right tail + p = hypergeo_acc(max, 0, 0, 0, &aux); + for (right = 0., j = max - 1; p < 0.99999999 * q; --j) // loop until underflow + right += p, p = hypergeo_acc(j, 0, 0, 0, &aux); + ++j; + if (p < 1.00000001 * q) right += p; + else ++j; + // two-tail + *two = left + right; + if (*two > 1.) *two = 1.; + // adjust left and right + if (abs(i - n11) < abs(j - n11)) right = 1. - left + q; + else left = 1.0 - right + q; + *_left = left; *_right = right; + return q; +} + +#ifdef FET_MAIN +#include <stdio.h> + +int main(int argc, char *argv[]) +{ + char id[1024]; + int n11, n12, n21, n22; + double left, right, twotail, prob; + + while (scanf("%s%d%d%d%d", id, &n11, &n12, &n21, &n22) == 5) { + prob = kt_fisher_exact(n11, n12, n21, n22, &left, &right, &twotail); + printf("%s\t%d\t%d\t%d\t%d\t%.6g\t%.6g\t%.6g\t%.6g\n", id, n11, n12, n21, n22, + prob, left, right, twotail); + } + return 0; +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bcftools/index.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,335 @@ +#include <assert.h> +#include <ctype.h> +#include <sys/stat.h> +#include "bam_endian.h" +#include "kstring.h" +#include "bcf.h" +#ifdef _USE_KNETFILE +#include "knetfile.h" +#endif + +#define TAD_LIDX_SHIFT 13 + +typedef struct { + int32_t n, m; + uint64_t *offset; +} bcf_lidx_t; + +struct __bcf_idx_t { + int32_t n; + bcf_lidx_t *index2; +}; + +/************ + * indexing * + ************/ + +static inline void insert_offset2(bcf_lidx_t *index2, int _beg, int _end, uint64_t offset) +{ + int i, beg, end; + beg = _beg >> TAD_LIDX_SHIFT; + end = (_end - 1) >> TAD_LIDX_SHIFT; + if (index2->m < end + 1) { + int old_m = index2->m; + index2->m = end + 1; + kroundup32(index2->m); + index2->offset = (uint64_t*)realloc(index2->offset, index2->m * 8); + memset(index2->offset + old_m, 0, 8 * (index2->m - old_m)); + } + if (beg == end) { + if (index2->offset[beg] == 0) index2->offset[beg] = offset; + } else { + for (i = beg; i <= end; ++i) + if (index2->offset[i] == 0) index2->offset[i] = offset; + } + if (index2->n < end + 1) index2->n = end + 1; +} + +bcf_idx_t *bcf_idx_core(bcf_t *bp, bcf_hdr_t *h) +{ + bcf_idx_t *idx; + int32_t last_coor, last_tid; + uint64_t last_off; + kstring_t *str; + BGZF *fp = bp->fp; + bcf1_t *b; + int ret; + + b = calloc(1, sizeof(bcf1_t)); + str = calloc(1, sizeof(kstring_t)); + idx = (bcf_idx_t*)calloc(1, sizeof(bcf_idx_t)); + idx->n = h->n_ref; + idx->index2 = calloc(h->n_ref, sizeof(bcf_lidx_t)); + + last_tid = 0xffffffffu; + last_off = bgzf_tell(fp); last_coor = 0xffffffffu; + while ((ret = bcf_read(bp, h, b)) > 0) { + int end, tmp; + if (last_tid != b->tid) { // change of chromosomes + last_tid = b->tid; + } else if (last_coor > b->pos) { + fprintf(stderr, "[bcf_idx_core] the input is out of order\n"); + free(str->s); free(str); free(idx); bcf_destroy(b); + return 0; + } + tmp = strlen(b->ref); + end = b->pos + (tmp > 0? tmp : 1); + insert_offset2(&idx->index2[b->tid], b->pos, end, last_off); + last_off = bgzf_tell(fp); + last_coor = b->pos; + } + free(str->s); free(str); bcf_destroy(b); + return idx; +} + +void bcf_idx_destroy(bcf_idx_t *idx) +{ + int i; + if (idx == 0) return; + for (i = 0; i < idx->n; ++i) free(idx->index2[i].offset); + free(idx->index2); + free(idx); +} + +/****************** + * index file I/O * + ******************/ + +void bcf_idx_save(const bcf_idx_t *idx, BGZF *fp) +{ + int32_t i, ti_is_be; + ti_is_be = bam_is_big_endian(); + bgzf_write(fp, "BCI\4", 4); + if (ti_is_be) { + uint32_t x = idx->n; + bgzf_write(fp, bam_swap_endian_4p(&x), 4); + } else bgzf_write(fp, &idx->n, 4); + for (i = 0; i < idx->n; ++i) { + bcf_lidx_t *index2 = idx->index2 + i; + // write linear index (index2) + if (ti_is_be) { + int x = index2->n; + bgzf_write(fp, bam_swap_endian_4p(&x), 4); + } else bgzf_write(fp, &index2->n, 4); + if (ti_is_be) { // big endian + int x; + for (x = 0; (int)x < index2->n; ++x) + bam_swap_endian_8p(&index2->offset[x]); + bgzf_write(fp, index2->offset, 8 * index2->n); + for (x = 0; (int)x < index2->n; ++x) + bam_swap_endian_8p(&index2->offset[x]); + } else bgzf_write(fp, index2->offset, 8 * index2->n); + } +} + +static bcf_idx_t *bcf_idx_load_core(BGZF *fp) +{ + int i, ti_is_be; + char magic[4]; + bcf_idx_t *idx; + ti_is_be = bam_is_big_endian(); + if (fp == 0) { + fprintf(stderr, "[%s] fail to load index.\n", __func__); + return 0; + } + bgzf_read(fp, magic, 4); + if (strncmp(magic, "BCI\4", 4)) { + fprintf(stderr, "[%s] wrong magic number.\n", __func__); + return 0; + } + idx = (bcf_idx_t*)calloc(1, sizeof(bcf_idx_t)); + bgzf_read(fp, &idx->n, 4); + if (ti_is_be) bam_swap_endian_4p(&idx->n); + idx->index2 = (bcf_lidx_t*)calloc(idx->n, sizeof(bcf_lidx_t)); + for (i = 0; i < idx->n; ++i) { + bcf_lidx_t *index2 = idx->index2 + i; + int j; + bgzf_read(fp, &index2->n, 4); + if (ti_is_be) bam_swap_endian_4p(&index2->n); + index2->m = index2->n; + index2->offset = (uint64_t*)calloc(index2->m, 8); + bgzf_read(fp, index2->offset, index2->n * 8); + if (ti_is_be) + for (j = 0; j < index2->n; ++j) bam_swap_endian_8p(&index2->offset[j]); + } + return idx; +} + +bcf_idx_t *bcf_idx_load_local(const char *fnidx) +{ + BGZF *fp; + fp = bgzf_open(fnidx, "r"); + if (fp) { + bcf_idx_t *idx = bcf_idx_load_core(fp); + bgzf_close(fp); + return idx; + } else return 0; +} + +#ifdef _USE_KNETFILE +static void download_from_remote(const char *url) +{ + const int buf_size = 1 * 1024 * 1024; + char *fn; + FILE *fp; + uint8_t *buf; + knetFile *fp_remote; + int l; + if (strstr(url, "ftp://") != url && strstr(url, "http://") != url) return; + l = strlen(url); + for (fn = (char*)url + l - 1; fn >= url; --fn) + if (*fn == '/') break; + ++fn; // fn now points to the file name + fp_remote = knet_open(url, "r"); + if (fp_remote == 0) { + fprintf(stderr, "[download_from_remote] fail to open remote file.\n"); + return; + } + if ((fp = fopen(fn, "w")) == 0) { + fprintf(stderr, "[download_from_remote] fail to create file in the working directory.\n"); + knet_close(fp_remote); + return; + } + buf = (uint8_t*)calloc(buf_size, 1); + while ((l = knet_read(fp_remote, buf, buf_size)) != 0) + fwrite(buf, 1, l, fp); + free(buf); + fclose(fp); + knet_close(fp_remote); +} +#else +static void download_from_remote(const char *url) +{ + return; +} +#endif + +static char *get_local_version(const char *fn) +{ + struct stat sbuf; + char *fnidx = (char*)calloc(strlen(fn) + 5, 1); + strcat(strcpy(fnidx, fn), ".bci"); + if ((strstr(fnidx, "ftp://") == fnidx || strstr(fnidx, "http://") == fnidx)) { + char *p, *url; + int l = strlen(fnidx); + for (p = fnidx + l - 1; p >= fnidx; --p) + if (*p == '/') break; + url = fnidx; fnidx = strdup(p + 1); + if (stat(fnidx, &sbuf) == 0) { + free(url); + return fnidx; + } + fprintf(stderr, "[%s] downloading the index file...\n", __func__); + download_from_remote(url); + free(url); + } + if (stat(fnidx, &sbuf) == 0) return fnidx; + free(fnidx); return 0; +} + +bcf_idx_t *bcf_idx_load(const char *fn) +{ + bcf_idx_t *idx; + char *fname = get_local_version(fn); + if (fname == 0) return 0; + idx = bcf_idx_load_local(fname); + free(fname); + return idx; +} + +int bcf_idx_build2(const char *fn, const char *_fnidx) +{ + char *fnidx; + BGZF *fpidx; + bcf_t *bp; + bcf_idx_t *idx; + bcf_hdr_t *h; + if ((bp = bcf_open(fn, "r")) == 0) { + fprintf(stderr, "[bcf_idx_build2] fail to open the BAM file.\n"); + return -1; + } + h = bcf_hdr_read(bp); + idx = bcf_idx_core(bp, h); + bcf_close(bp); + if (_fnidx == 0) { + fnidx = (char*)calloc(strlen(fn) + 5, 1); + strcpy(fnidx, fn); strcat(fnidx, ".bci"); + } else fnidx = strdup(_fnidx); + fpidx = bgzf_open(fnidx, "w"); + if (fpidx == 0) { + fprintf(stderr, "[bcf_idx_build2] fail to create the index file.\n"); + free(fnidx); + return -1; + } + bcf_idx_save(idx, fpidx); + bcf_idx_destroy(idx); + bgzf_close(fpidx); + free(fnidx); + return 0; +} + +int bcf_idx_build(const char *fn) +{ + return bcf_idx_build2(fn, 0); +} + +/******************************************** + * parse a region in the format chr:beg-end * + ********************************************/ + +int bcf_parse_region(void *str2id, const char *str, int *tid, int *begin, int *end) +{ + char *s, *p; + int i, l, k; + l = strlen(str); + p = s = (char*)malloc(l+1); + /* squeeze out "," */ + for (i = k = 0; i != l; ++i) + if (str[i] != ',' && !isspace(str[i])) s[k++] = str[i]; + s[k] = 0; + for (i = 0; i != k; ++i) if (s[i] == ':') break; + s[i] = 0; + if ((*tid = bcf_str2id(str2id, s)) < 0) { + free(s); + return -1; + } + if (i == k) { /* dump the whole sequence */ + *begin = 0; *end = 1<<29; free(s); + return 0; + } + for (p = s + i + 1; i != k; ++i) if (s[i] == '-') break; + *begin = atoi(p); + if (i < k) { + p = s + i + 1; + *end = atoi(p); + } else *end = 1<<29; + if (*begin > 0) --*begin; + free(s); + if (*begin > *end) return -1; + return 0; +} + +/******************************* + * retrieve a specified region * + *******************************/ + +uint64_t bcf_idx_query(const bcf_idx_t *idx, int tid, int beg) +{ + uint64_t min_off, *offset; + int i; + if (beg < 0) beg = 0; + offset = idx->index2[tid].offset; + for (i = beg>>TAD_LIDX_SHIFT; i < idx->index2[tid].n && offset[i] == 0; ++i); + min_off = (i == idx->index2[tid].n)? offset[idx->index2[tid].n-1] : offset[i]; + return min_off; +} + +int bcf_main_index(int argc, char *argv[]) +{ + if (argc == 1) { + fprintf(stderr, "Usage: bcftools index <in.bcf>\n"); + return 1; + } + bcf_idx_build(argv[1]); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bcftools/kfunc.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,162 @@ +#include <math.h> + + +/* Log gamma function + * \log{\Gamma(z)} + * AS245, 2nd algorithm, http://lib.stat.cmu.edu/apstat/245 + */ +double kf_lgamma(double z) +{ + double x = 0; + x += 0.1659470187408462e-06 / (z+7); + x += 0.9934937113930748e-05 / (z+6); + x -= 0.1385710331296526 / (z+5); + x += 12.50734324009056 / (z+4); + x -= 176.6150291498386 / (z+3); + x += 771.3234287757674 / (z+2); + x -= 1259.139216722289 / (z+1); + x += 676.5203681218835 / z; + x += 0.9999999999995183; + return log(x) - 5.58106146679532777 - z + (z-0.5) * log(z+6.5); +} + +/* complementary error function + * \frac{2}{\sqrt{\pi}} \int_x^{\infty} e^{-t^2} dt + * AS66, 2nd algorithm, http://lib.stat.cmu.edu/apstat/66 + */ +double kf_erfc(double x) +{ + const double p0 = 220.2068679123761; + const double p1 = 221.2135961699311; + const double p2 = 112.0792914978709; + const double p3 = 33.912866078383; + const double p4 = 6.37396220353165; + const double p5 = .7003830644436881; + const double p6 = .03526249659989109; + const double q0 = 440.4137358247522; + const double q1 = 793.8265125199484; + const double q2 = 637.3336333788311; + const double q3 = 296.5642487796737; + const double q4 = 86.78073220294608; + const double q5 = 16.06417757920695; + const double q6 = 1.755667163182642; + const double q7 = .08838834764831844; + double expntl, z, p; + z = fabs(x) * M_SQRT2; + if (z > 37.) return x > 0.? 0. : 2.; + expntl = exp(z * z * - .5); + if (z < 10. / M_SQRT2) // for small z + p = expntl * ((((((p6 * z + p5) * z + p4) * z + p3) * z + p2) * z + p1) * z + p0) + / (((((((q7 * z + q6) * z + q5) * z + q4) * z + q3) * z + q2) * z + q1) * z + q0); + else p = expntl / 2.506628274631001 / (z + 1. / (z + 2. / (z + 3. / (z + 4. / (z + .65))))); + return x > 0.? 2. * p : 2. * (1. - p); +} + +/* The following computes regularized incomplete gamma functions. + * Formulas are taken from Wiki, with additional input from Numerical + * Recipes in C (for modified Lentz's algorithm) and AS245 + * (http://lib.stat.cmu.edu/apstat/245). + * + * A good online calculator is available at: + * + * http://www.danielsoper.com/statcalc/calc23.aspx + * + * It calculates upper incomplete gamma function, which equals + * kf_gammaq(s,z)*tgamma(s). + */ + +#define KF_GAMMA_EPS 1e-14 +#define KF_TINY 1e-290 + +// regularized lower incomplete gamma function, by series expansion +static double _kf_gammap(double s, double z) +{ + double sum, x; + int k; + for (k = 1, sum = x = 1.; k < 100; ++k) { + sum += (x *= z / (s + k)); + if (x / sum < KF_GAMMA_EPS) break; + } + return exp(s * log(z) - z - kf_lgamma(s + 1.) + log(sum)); +} +// regularized upper incomplete gamma function, by continued fraction +static double _kf_gammaq(double s, double z) +{ + int j; + double C, D, f; + f = 1. + z - s; C = f; D = 0.; + // Modified Lentz's algorithm for computing continued fraction + // See Numerical Recipes in C, 2nd edition, section 5.2 + for (j = 1; j < 100; ++j) { + double a = j * (s - j), b = (j<<1) + 1 + z - s, d; + D = b + a * D; + if (D < KF_TINY) D = KF_TINY; + C = b + a / C; + if (C < KF_TINY) C = KF_TINY; + D = 1. / D; + d = C * D; + f *= d; + if (fabs(d - 1.) < KF_GAMMA_EPS) break; + } + return exp(s * log(z) - z - kf_lgamma(s) - log(f)); +} + +double kf_gammap(double s, double z) +{ + return z <= 1. || z < s? _kf_gammap(s, z) : 1. - _kf_gammaq(s, z); +} + +double kf_gammaq(double s, double z) +{ + return z <= 1. || z < s? 1. - _kf_gammap(s, z) : _kf_gammaq(s, z); +} + +/* Regularized incomplete beta function. The method is taken from + * Numerical Recipe in C, 2nd edition, section 6.4. The following web + * page calculates the incomplete beta function, which equals + * kf_betai(a,b,x) * gamma(a) * gamma(b) / gamma(a+b): + * + * http://www.danielsoper.com/statcalc/calc36.aspx + */ +static double kf_betai_aux(double a, double b, double x) +{ + double C, D, f; + int j; + if (x == 0.) return 0.; + if (x == 1.) return 1.; + f = 1.; C = f; D = 0.; + // Modified Lentz's algorithm for computing continued fraction + for (j = 1; j < 200; ++j) { + double aa, d; + int m = j>>1; + aa = (j&1)? -(a + m) * (a + b + m) * x / ((a + 2*m) * (a + 2*m + 1)) + : m * (b - m) * x / ((a + 2*m - 1) * (a + 2*m)); + D = 1. + aa * D; + if (D < KF_TINY) D = KF_TINY; + C = 1. + aa / C; + if (C < KF_TINY) C = KF_TINY; + D = 1. / D; + d = C * D; + f *= d; + if (fabs(d - 1.) < KF_GAMMA_EPS) break; + } + return exp(kf_lgamma(a+b) - kf_lgamma(a) - kf_lgamma(b) + a * log(x) + b * log(1.-x)) / a / f; +} +double kf_betai(double a, double b, double x) +{ + return x < (a + 1.) / (a + b + 2.)? kf_betai_aux(a, b, x) : 1. - kf_betai_aux(b, a, 1. - x); +} + +#ifdef KF_MAIN +#include <stdio.h> +int main(int argc, char *argv[]) +{ + double x = 5.5, y = 3; + double a, b; + printf("erfc(%lg): %lg, %lg\n", x, erfc(x), kf_erfc(x)); + printf("upper-gamma(%lg,%lg): %lg\n", x, y, kf_gammaq(y, x)*tgamma(y)); + a = 2; b = 2; x = 0.5; + printf("incomplete-beta(%lg,%lg,%lg): %lg\n", a, b, x, kf_betai(a, b, x) / exp(kf_lgamma(a+b) - kf_lgamma(a) - kf_lgamma(b))); + return 0; +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bcftools/kmin.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,209 @@ +/* The MIT License + + Copyright (c) 2008, 2010 by Attractive Chaos <attractor@live.co.uk> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* Hooke-Jeeves algorithm for nonlinear minimization + + Based on the pseudocodes by Bell and Pike (CACM 9(9):684-685), and + the revision by Tomlin and Smith (CACM 12(11):637-638). Both of the + papers are comments on Kaupe's Algorithm 178 "Direct Search" (ACM + 6(6):313-314). The original algorithm was designed by Hooke and + Jeeves (ACM 8:212-229). This program is further revised according to + Johnson's implementation at Netlib (opt/hooke.c). + + Hooke-Jeeves algorithm is very simple and it works quite well on a + few examples. However, it might fail to converge due to its heuristic + nature. A possible improvement, as is suggested by Johnson, may be to + choose a small r at the beginning to quickly approach to the minimum + and a large r at later step to hit the minimum. + */ + +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include "kmin.h" + +static double __kmin_hj_aux(kmin_f func, int n, double *x1, void *data, double fx1, double *dx, int *n_calls) +{ + int k, j = *n_calls; + double ftmp; + for (k = 0; k != n; ++k) { + x1[k] += dx[k]; + ftmp = func(n, x1, data); ++j; + if (ftmp < fx1) fx1 = ftmp; + else { /* search the opposite direction */ + dx[k] = 0.0 - dx[k]; + x1[k] += dx[k] + dx[k]; + ftmp = func(n, x1, data); ++j; + if (ftmp < fx1) fx1 = ftmp; + else x1[k] -= dx[k]; /* back to the original x[k] */ + } + } + *n_calls = j; + return fx1; /* here: fx1=f(n,x1) */ +} + +double kmin_hj(kmin_f func, int n, double *x, void *data, double r, double eps, int max_calls) +{ + double fx, fx1, *x1, *dx, radius; + int k, n_calls = 0; + x1 = (double*)calloc(n, sizeof(double)); + dx = (double*)calloc(n, sizeof(double)); + for (k = 0; k != n; ++k) { /* initial directions, based on MGJ */ + dx[k] = fabs(x[k]) * r; + if (dx[k] == 0) dx[k] = r; + } + radius = r; + fx1 = fx = func(n, x, data); ++n_calls; + for (;;) { + memcpy(x1, x, n * sizeof(double)); /* x1 = x */ + fx1 = __kmin_hj_aux(func, n, x1, data, fx, dx, &n_calls); + while (fx1 < fx) { + for (k = 0; k != n; ++k) { + double t = x[k]; + dx[k] = x1[k] > x[k]? fabs(dx[k]) : 0.0 - fabs(dx[k]); + x[k] = x1[k]; + x1[k] = x1[k] + x1[k] - t; + } + fx = fx1; + if (n_calls >= max_calls) break; + fx1 = func(n, x1, data); ++n_calls; + fx1 = __kmin_hj_aux(func, n, x1, data, fx1, dx, &n_calls); + if (fx1 >= fx) break; + for (k = 0; k != n; ++k) + if (fabs(x1[k] - x[k]) > .5 * fabs(dx[k])) break; + if (k == n) break; + } + if (radius >= eps) { + if (n_calls >= max_calls) break; + radius *= r; + for (k = 0; k != n; ++k) dx[k] *= r; + } else break; /* converge */ + } + free(x1); free(dx); + return fx1; +} + +// I copied this function somewhere several years ago with some of my modifications, but I forgot the source. +double kmin_brent(kmin1_f func, double a, double b, void *data, double tol, double *xmin) +{ + double bound, u, r, q, fu, tmp, fa, fb, fc, c; + const double gold1 = 1.6180339887; + const double gold2 = 0.3819660113; + const double tiny = 1e-20; + const int max_iter = 100; + + double e, d, w, v, mid, tol1, tol2, p, eold, fv, fw; + int iter; + + fa = func(a, data); fb = func(b, data); + if (fb > fa) { // swap, such that f(a) > f(b) + tmp = a; a = b; b = tmp; + tmp = fa; fa = fb; fb = tmp; + } + c = b + gold1 * (b - a), fc = func(c, data); // golden section extrapolation + while (fb > fc) { + bound = b + 100.0 * (c - b); // the farthest point where we want to go + r = (b - a) * (fb - fc); + q = (b - c) * (fb - fa); + if (fabs(q - r) < tiny) { // avoid 0 denominator + tmp = q > r? tiny : 0.0 - tiny; + } else tmp = q - r; + u = b - ((b - c) * q - (b - a) * r) / (2.0 * tmp); // u is the parabolic extrapolation point + if ((b > u && u > c) || (b < u && u < c)) { // u lies between b and c + fu = func(u, data); + if (fu < fc) { // (b,u,c) bracket the minimum + a = b; b = u; fa = fb; fb = fu; + break; + } else if (fu > fb) { // (a,b,u) bracket the minimum + c = u; fc = fu; + break; + } + u = c + gold1 * (c - b); fu = func(u, data); // golden section extrapolation + } else if ((c > u && u > bound) || (c < u && u < bound)) { // u lies between c and bound + fu = func(u, data); + if (fu < fc) { // fb > fc > fu + b = c; c = u; u = c + gold1 * (c - b); + fb = fc; fc = fu; fu = func(u, data); + } else { // (b,c,u) bracket the minimum + a = b; b = c; c = u; + fa = fb; fb = fc; fc = fu; + break; + } + } else if ((u > bound && bound > c) || (u < bound && bound < c)) { // u goes beyond the bound + u = bound; fu = func(u, data); + } else { // u goes the other way around, use golden section extrapolation + u = c + gold1 * (c - b); fu = func(u, data); + } + a = b; b = c; c = u; + fa = fb; fb = fc; fc = fu; + } + if (a > c) u = a, a = c, c = u; // swap + + // now, a<b<c, fa>fb and fb<fc, move on to Brent's algorithm + e = d = 0.0; + w = v = b; fv = fw = fb; + for (iter = 0; iter != max_iter; ++iter) { + mid = 0.5 * (a + c); + tol2 = 2.0 * (tol1 = tol * fabs(b) + tiny); + if (fabs(b - mid) <= (tol2 - 0.5 * (c - a))) { + *xmin = b; return fb; // found + } + if (fabs(e) > tol1) { + // related to parabolic interpolation + r = (b - w) * (fb - fv); + q = (b - v) * (fb - fw); + p = (b - v) * q - (b - w) * r; + q = 2.0 * (q - r); + if (q > 0.0) p = 0.0 - p; + else q = 0.0 - q; + eold = e; e = d; + if (fabs(p) >= fabs(0.5 * q * eold) || p <= q * (a - b) || p >= q * (c - b)) { + d = gold2 * (e = (b >= mid ? a - b : c - b)); + } else { + d = p / q; u = b + d; // actual parabolic interpolation happens here + if (u - a < tol2 || c - u < tol2) + d = (mid > b)? tol1 : 0.0 - tol1; + } + } else d = gold2 * (e = (b >= mid ? a - b : c - b)); // golden section interpolation + u = fabs(d) >= tol1 ? b + d : b + (d > 0.0? tol1 : -tol1); + fu = func(u, data); + if (fu <= fb) { // u is the minimum point so far + if (u >= b) a = b; + else c = b; + v = w; w = b; b = u; fv = fw; fw = fb; fb = fu; + } else { // adjust (a,c) and (u,v,w) + if (u < b) a = u; + else c = u; + if (fu <= fw || w == b) { + v = w; w = u; + fv = fw; fw = fu; + } else if (fu <= fv || v == b || v == w) { + v = u; fv = fu; + } + } + } + *xmin = b; + return fb; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bcftools/kmin.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,46 @@ +/* + Copyright (c) 2008, 2010 by Attractive Chaos <attractor@live.co.uk> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#ifndef KMIN_H +#define KMIN_H + +#define KMIN_RADIUS 0.5 +#define KMIN_EPS 1e-7 +#define KMIN_MAXCALL 50000 + +typedef double (*kmin_f)(int, double*, void*); +typedef double (*kmin1_f)(double, void*); + +#ifdef __cplusplus +extern "C" { +#endif + + double kmin_hj(kmin_f func, int n, double *x, void *data, double r, double eps, int max_calls); + double kmin_brent(kmin1_f func, double a, double b, void *data, double tol, double *xmin); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bcftools/main.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,188 @@ +#include <string.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <unistd.h> +#include "bcf.h" + +#include "kseq.h" +KSTREAM_INIT(gzFile, gzread, 0x10000) + +int bcfview(int argc, char *argv[]); +int bcf_main_index(int argc, char *argv[]); + +#define BUF_SIZE 0x10000 + +int bcf_cat(int n, char * const *fn) +{ + int i; + bcf_t *out; + uint8_t *buf; + buf = malloc(BUF_SIZE); + out = bcf_open("-", "w"); + for (i = 0; i < n; ++i) { + bcf_t *in; + bcf_hdr_t *h; + off_t end; + struct stat s; + in = bcf_open(fn[i], "r"); + h = bcf_hdr_read(in); + if (i == 0) bcf_hdr_write(out, h); + bcf_hdr_destroy(h); +#ifdef _USE_KNETFILE + fstat(knet_fileno(in->fp->x.fpr), &s); + end = s.st_size - 28; + while (knet_tell(in->fp->x.fpr) < end) { + int size = knet_tell(in->fp->x.fpr) + BUF_SIZE < end? BUF_SIZE : end - knet_tell(in->fp->x.fpr); + knet_read(in->fp->x.fpr, buf, size); + fwrite(buf, 1, size, out->fp->x.fpw); + } +#else + abort(); // FIXME: not implemented +#endif + bcf_close(in); + } + bcf_close(out); + free(buf); + return 0; +} + +extern double bcf_pair_freq(const bcf1_t *b0, const bcf1_t *b1, double f[4]); + +int bcf_main_ldpair(int argc, char *argv[]) +{ + bcf_t *fp; + bcf_hdr_t *h; + bcf1_t *b0, *b1; + bcf_idx_t *idx; + kstring_t str; + void *str2id; + gzFile fplist; + kstream_t *ks; + int dret, lineno = 0; + if (argc < 3) { + fprintf(stderr, "Usage: bcftools ldpair <in.bcf> <in.list>\n"); + return 1; + } + fplist = gzopen(argv[2], "rb"); + ks = ks_init(fplist); + memset(&str, 0, sizeof(kstring_t)); + fp = bcf_open(argv[1], "rb"); + h = bcf_hdr_read(fp); + str2id = bcf_build_refhash(h); + idx = bcf_idx_load(argv[1]); + if (idx == 0) { + fprintf(stderr, "[%s] No bcf index is found. Abort!\n", __func__); + return 1; + } + b0 = calloc(1, sizeof(bcf1_t)); + b1 = calloc(1, sizeof(bcf1_t)); + while (ks_getuntil(ks, '\n', &str, &dret) >= 0) { + char *p, *q; + int k; + int tid0 = -1, tid1 = -1, pos0 = -1, pos1 = -1; + ++lineno; + for (p = q = str.s, k = 0; *p; ++p) { + if (*p == ' ' || *p == '\t') { + *p = '\0'; + if (k == 0) tid0 = bcf_str2id(str2id, q); + else if (k == 1) pos0 = atoi(q) - 1; + else if (k == 2) tid1 = strcmp(q, "=")? bcf_str2id(str2id, q) : tid0; + else if (k == 3) pos1 = atoi(q) - 1; + q = p + 1; + ++k; + } + } + if (k == 3) pos1 = atoi(q) - 1; + if (tid0 >= 0 && tid1 >= 0 && pos0 >= 0 && pos1 >= 0) { + uint64_t off; + double r, f[4]; + off = bcf_idx_query(idx, tid0, pos0); + bgzf_seek(fp->fp, off, SEEK_SET); + while (bcf_read(fp, h, b0) >= 0 && b0->pos != pos0); + off = bcf_idx_query(idx, tid1, pos1); + bgzf_seek(fp->fp, off, SEEK_SET); + while (bcf_read(fp, h, b1) >= 0 && b1->pos != pos1); + r = bcf_pair_freq(b0, b1, f); + r *= r; + printf("%s\t%d\t%s\t%d\t%.4g\t%.4g\t%.4g\t%.4g\t%.4g\n", h->ns[tid0], pos0+1, h->ns[tid1], pos1+1, + r, f[0], f[1], f[2], f[3]); + } //else fprintf(stderr, "[%s] Parse error at line %d.\n", __func__, lineno); + } + bcf_destroy(b0); bcf_destroy(b1); + bcf_idx_destroy(idx); + bcf_str2id_destroy(str2id); + bcf_hdr_destroy(h); + bcf_close(fp); + free(str.s); + ks_destroy(ks); + gzclose(fplist); + return 0; +} + +int bcf_main_ld(int argc, char *argv[]) +{ + bcf_t *fp; + bcf_hdr_t *h; + bcf1_t **b, *b0; + int i, j, m, n; + double f[4]; + if (argc == 1) { + fprintf(stderr, "Usage: bcftools ld <in.bcf>\n"); + return 1; + } + fp = bcf_open(argv[1], "rb"); + h = bcf_hdr_read(fp); + // read the entire BCF + m = n = 0; b = 0; + b0 = calloc(1, sizeof(bcf1_t)); + while (bcf_read(fp, h, b0) >= 0) { + if (m == n) { + m = m? m<<1 : 16; + b = realloc(b, sizeof(void*) * m); + } + b[n] = calloc(1, sizeof(bcf1_t)); + bcf_cpy(b[n++], b0); + } + bcf_destroy(b0); + // compute pair-wise r^2 + printf("%d\n", n); // the number of loci + for (i = 0; i < n; ++i) { + printf("%s:%d", h->ns[b[i]->tid], b[i]->pos + 1); + for (j = 0; j < i; ++j) { + double r = bcf_pair_freq(b[i], b[j], f); + printf("\t%.3f", r*r); + } + printf("\t1.000\n"); + } + // free + for (i = 0; i < n; ++i) bcf_destroy(b[i]); + free(b); + bcf_hdr_destroy(h); + bcf_close(fp); + return 0; +} + +int main(int argc, char *argv[]) +{ + if (argc == 1) { + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: bcftools <command> <arguments>\n\n"); + fprintf(stderr, "Command: view print, extract, convert and call SNPs from BCF\n"); + fprintf(stderr, " index index BCF\n"); + fprintf(stderr, " cat concatenate BCFs\n"); + fprintf(stderr, " ld compute all-pair r^2\n"); + fprintf(stderr, " ldpair compute r^2 between requested pairs\n"); + fprintf(stderr, "\n"); + return 1; + } + if (strcmp(argv[1], "view") == 0) return bcfview(argc-1, argv+1); + else if (strcmp(argv[1], "index") == 0) return bcf_main_index(argc-1, argv+1); + else if (strcmp(argv[1], "ld") == 0) return bcf_main_ld(argc-1, argv+1); + else if (strcmp(argv[1], "ldpair") == 0) return bcf_main_ldpair(argc-1, argv+1); + else if (strcmp(argv[1], "cat") == 0) return bcf_cat(argc-2, argv+2); // cat is different ... + else { + fprintf(stderr, "[main] Unrecognized command.\n"); + return 1; + } + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bcftools/prob1.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,536 @@ +#include <math.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> +#include <assert.h> +#include "prob1.h" + +#include "kseq.h" +KSTREAM_INIT(gzFile, gzread, 16384) + +#define MC_MAX_EM_ITER 16 +#define MC_EM_EPS 1e-5 +#define MC_DEF_INDEL 0.15 + +unsigned char seq_nt4_table[256] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 /*'-'*/, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 0, 4, 1, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 0, 4, 1, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 +}; + +struct __bcf_p1aux_t { + int n, M, n1, is_indel; + uint8_t *ploidy; // haploid or diploid ONLY + double *q2p, *pdg; // pdg -> P(D|g) + double *phi, *phi_indel; + double *z, *zswap; // aux for afs + double *z1, *z2, *phi1, *phi2; // only calculated when n1 is set + double **hg; // hypergeometric distribution + double *lf; // log factorial + double t, t1, t2; + double *afs, *afs1; // afs: accumulative AFS; afs1: site posterior distribution + const uint8_t *PL; // point to PL + int PL_len; +}; + +void bcf_p1_indel_prior(bcf_p1aux_t *ma, double x) +{ + int i; + for (i = 0; i < ma->M; ++i) + ma->phi_indel[i] = ma->phi[i] * x; + ma->phi_indel[ma->M] = 1. - ma->phi[ma->M] * x; +} + +static void init_prior(int type, double theta, int M, double *phi) +{ + int i; + if (type == MC_PTYPE_COND2) { + for (i = 0; i <= M; ++i) + phi[i] = 2. * (i + 1) / (M + 1) / (M + 2); + } else if (type == MC_PTYPE_FLAT) { + for (i = 0; i <= M; ++i) + phi[i] = 1. / (M + 1); + } else { + double sum; + for (i = 0, sum = 0.; i < M; ++i) + sum += (phi[i] = theta / (M - i)); + phi[M] = 1. - sum; + } +} + +void bcf_p1_init_prior(bcf_p1aux_t *ma, int type, double theta) +{ + init_prior(type, theta, ma->M, ma->phi); + bcf_p1_indel_prior(ma, MC_DEF_INDEL); +} + +void bcf_p1_init_subprior(bcf_p1aux_t *ma, int type, double theta) +{ + if (ma->n1 <= 0 || ma->n1 >= ma->M) return; + init_prior(type, theta, 2*ma->n1, ma->phi1); + init_prior(type, theta, 2*(ma->n - ma->n1), ma->phi2); +} + +int bcf_p1_read_prior(bcf_p1aux_t *ma, const char *fn) +{ + gzFile fp; + kstring_t s; + kstream_t *ks; + long double sum; + int dret, k; + memset(&s, 0, sizeof(kstring_t)); + fp = strcmp(fn, "-")? gzopen(fn, "r") : gzdopen(fileno(stdin), "r"); + ks = ks_init(fp); + memset(ma->phi, 0, sizeof(double) * (ma->M + 1)); + while (ks_getuntil(ks, '\n', &s, &dret) >= 0) { + if (strstr(s.s, "[afs] ") == s.s) { + char *p = s.s + 6; + for (k = 0; k <= ma->M; ++k) { + int x; + double y; + x = strtol(p, &p, 10); + if (x != k && (errno == EINVAL || errno == ERANGE)) return -1; + ++p; + y = strtod(p, &p); + if (y == 0. && (errno == EINVAL || errno == ERANGE)) return -1; + ma->phi[ma->M - k] += y; + } + } + } + ks_destroy(ks); + gzclose(fp); + free(s.s); + for (sum = 0., k = 0; k <= ma->M; ++k) sum += ma->phi[k]; + fprintf(stderr, "[prior]"); + for (k = 0; k <= ma->M; ++k) ma->phi[k] /= sum; + for (k = 0; k <= ma->M; ++k) fprintf(stderr, " %d:%.3lg", k, ma->phi[ma->M - k]); + fputc('\n', stderr); + for (sum = 0., k = 1; k < ma->M; ++k) sum += ma->phi[ma->M - k] * (2.* k * (ma->M - k) / ma->M / (ma->M - 1)); + fprintf(stderr, "[%s] heterozygosity=%lf, ", __func__, (double)sum); + for (sum = 0., k = 1; k <= ma->M; ++k) sum += k * ma->phi[ma->M - k] / ma->M; + fprintf(stderr, "theta=%lf\n", (double)sum); + bcf_p1_indel_prior(ma, MC_DEF_INDEL); + return 0; +} + +bcf_p1aux_t *bcf_p1_init(int n, uint8_t *ploidy) +{ + bcf_p1aux_t *ma; + int i; + ma = calloc(1, sizeof(bcf_p1aux_t)); + ma->n1 = -1; + ma->n = n; ma->M = 2 * n; + if (ploidy) { + ma->ploidy = malloc(n); + memcpy(ma->ploidy, ploidy, n); + for (i = 0, ma->M = 0; i < n; ++i) ma->M += ploidy[i]; + if (ma->M == 2 * n) { + free(ma->ploidy); + ma->ploidy = 0; + } + } + ma->q2p = calloc(256, sizeof(double)); + ma->pdg = calloc(3 * ma->n, sizeof(double)); + ma->phi = calloc(ma->M + 1, sizeof(double)); + ma->phi_indel = calloc(ma->M + 1, sizeof(double)); + ma->phi1 = calloc(ma->M + 1, sizeof(double)); + ma->phi2 = calloc(ma->M + 1, sizeof(double)); + ma->z = calloc(ma->M + 1, sizeof(double)); + ma->zswap = calloc(ma->M + 1, sizeof(double)); + ma->z1 = calloc(ma->M + 1, sizeof(double)); // actually we do not need this large + ma->z2 = calloc(ma->M + 1, sizeof(double)); + ma->afs = calloc(ma->M + 1, sizeof(double)); + ma->afs1 = calloc(ma->M + 1, sizeof(double)); + ma->lf = calloc(ma->M + 1, sizeof(double)); + for (i = 0; i < 256; ++i) + ma->q2p[i] = pow(10., -i / 10.); + for (i = 0; i <= ma->M; ++i) ma->lf[i] = lgamma(i + 1); + bcf_p1_init_prior(ma, MC_PTYPE_FULL, 1e-3); // the simplest prior + return ma; +} + +int bcf_p1_set_n1(bcf_p1aux_t *b, int n1) +{ + if (n1 == 0 || n1 >= b->n) return -1; + if (b->M != b->n * 2) { + fprintf(stderr, "[%s] unable to set `n1' when there are haploid samples.\n", __func__); + return -1; + } + b->n1 = n1; + return 0; +} + +void bcf_p1_destroy(bcf_p1aux_t *ma) +{ + if (ma) { + int k; + free(ma->lf); + if (ma->hg && ma->n1 > 0) { + for (k = 0; k <= 2*ma->n1; ++k) free(ma->hg[k]); + free(ma->hg); + } + free(ma->ploidy); free(ma->q2p); free(ma->pdg); + free(ma->phi); free(ma->phi_indel); free(ma->phi1); free(ma->phi2); + free(ma->z); free(ma->zswap); free(ma->z1); free(ma->z2); + free(ma->afs); free(ma->afs1); + free(ma); + } +} + +static int cal_pdg(const bcf1_t *b, bcf_p1aux_t *ma) +{ + int i, j; + long *p, tmp; + p = alloca(b->n_alleles * sizeof(long)); + memset(p, 0, sizeof(long) * b->n_alleles); + for (j = 0; j < ma->n; ++j) { + const uint8_t *pi = ma->PL + j * ma->PL_len; + double *pdg = ma->pdg + j * 3; + pdg[0] = ma->q2p[pi[2]]; pdg[1] = ma->q2p[pi[1]]; pdg[2] = ma->q2p[pi[0]]; + for (i = 0; i < b->n_alleles; ++i) + p[i] += (int)pi[(i+1)*(i+2)/2-1]; + } + for (i = 0; i < b->n_alleles; ++i) p[i] = p[i]<<4 | i; + for (i = 1; i < b->n_alleles; ++i) // insertion sort + for (j = i; j > 0 && p[j] < p[j-1]; --j) + tmp = p[j], p[j] = p[j-1], p[j-1] = tmp; + for (i = b->n_alleles - 1; i >= 0; --i) + if ((p[i]&0xf) == 0) break; + return i; +} + +int bcf_p1_call_gt(const bcf_p1aux_t *ma, double f0, int k) +{ + double sum, g[3]; + double max, f3[3], *pdg = ma->pdg + k * 3; + int q, i, max_i, ploidy; + ploidy = ma->ploidy? ma->ploidy[k] : 2; + if (ploidy == 2) { + f3[0] = (1.-f0)*(1.-f0); f3[1] = 2.*f0*(1.-f0); f3[2] = f0*f0; + } else { + f3[0] = 1. - f0; f3[1] = 0; f3[2] = f0; + } + for (i = 0, sum = 0.; i < 3; ++i) + sum += (g[i] = pdg[i] * f3[i]); + for (i = 0, max = -1., max_i = 0; i < 3; ++i) { + g[i] /= sum; + if (g[i] > max) max = g[i], max_i = i; + } + max = 1. - max; + if (max < 1e-308) max = 1e-308; + q = (int)(-4.343 * log(max) + .499); + if (q > 99) q = 99; + return q<<2|max_i; +} + +#define TINY 1e-20 + +static void mc_cal_y_core(bcf_p1aux_t *ma, int beg) +{ + double *z[2], *tmp, *pdg; + int _j, last_min, last_max; + assert(beg == 0 || ma->M == ma->n*2); + z[0] = ma->z; + z[1] = ma->zswap; + pdg = ma->pdg; + memset(z[0], 0, sizeof(double) * (ma->M + 1)); + memset(z[1], 0, sizeof(double) * (ma->M + 1)); + z[0][0] = 1.; + last_min = last_max = 0; + ma->t = 0.; + if (ma->M == ma->n * 2) { + int M = 0; + for (_j = beg; _j < ma->n; ++_j) { + int k, j = _j - beg, _min = last_min, _max = last_max, M0; + double p[3], sum; + M0 = M; M += 2; + pdg = ma->pdg + _j * 3; + p[0] = pdg[0]; p[1] = 2. * pdg[1]; p[2] = pdg[2]; + for (; _min < _max && z[0][_min] < TINY; ++_min) z[0][_min] = z[1][_min] = 0.; + for (; _max > _min && z[0][_max] < TINY; --_max) z[0][_max] = z[1][_max] = 0.; + _max += 2; + if (_min == 0) k = 0, z[1][k] = (M0-k+1) * (M0-k+2) * p[0] * z[0][k]; + if (_min <= 1) k = 1, z[1][k] = (M0-k+1) * (M0-k+2) * p[0] * z[0][k] + k*(M0-k+2) * p[1] * z[0][k-1]; + for (k = _min < 2? 2 : _min; k <= _max; ++k) + z[1][k] = (M0-k+1)*(M0-k+2) * p[0] * z[0][k] + k*(M0-k+2) * p[1] * z[0][k-1] + k*(k-1)* p[2] * z[0][k-2]; + for (k = _min, sum = 0.; k <= _max; ++k) sum += z[1][k]; + ma->t += log(sum / (M * (M - 1.))); + for (k = _min; k <= _max; ++k) z[1][k] /= sum; + if (_min >= 1) z[1][_min-1] = 0.; + if (_min >= 2) z[1][_min-2] = 0.; + if (j < ma->n - 1) z[1][_max+1] = z[1][_max+2] = 0.; + if (_j == ma->n1 - 1) { // set pop1; ma->n1==-1 when unset + ma->t1 = ma->t; + memcpy(ma->z1, z[1], sizeof(double) * (ma->n1 * 2 + 1)); + } + tmp = z[0]; z[0] = z[1]; z[1] = tmp; + last_min = _min; last_max = _max; + } + //for (_j = 0; _j < last_min; ++_j) z[0][_j] = 0.; // TODO: are these necessary? + //for (_j = last_max + 1; _j < ma->M; ++_j) z[0][_j] = 0.; + } else { // this block is very similar to the block above; these two might be merged in future + int j, M = 0; + for (j = 0; j < ma->n; ++j) { + int k, M0, _min = last_min, _max = last_max; + double p[3], sum; + pdg = ma->pdg + j * 3; + for (; _min < _max && z[0][_min] < TINY; ++_min) z[0][_min] = z[1][_min] = 0.; + for (; _max > _min && z[0][_max] < TINY; --_max) z[0][_max] = z[1][_max] = 0.; + M0 = M; + M += ma->ploidy[j]; + if (ma->ploidy[j] == 1) { + p[0] = pdg[0]; p[1] = pdg[2]; + _max++; + if (_min == 0) k = 0, z[1][k] = (M0+1-k) * p[0] * z[0][k]; + for (k = _min < 1? 1 : _min; k <= _max; ++k) + z[1][k] = (M0+1-k) * p[0] * z[0][k] + k * p[1] * z[0][k-1]; + for (k = _min, sum = 0.; k <= _max; ++k) sum += z[1][k]; + ma->t += log(sum / M); + for (k = _min; k <= _max; ++k) z[1][k] /= sum; + if (_min >= 1) z[1][_min-1] = 0.; + if (j < ma->n - 1) z[1][_max+1] = 0.; + } else if (ma->ploidy[j] == 2) { + p[0] = pdg[0]; p[1] = 2 * pdg[1]; p[2] = pdg[2]; + _max += 2; + if (_min == 0) k = 0, z[1][k] = (M0-k+1) * (M0-k+2) * p[0] * z[0][k]; + if (_min <= 1) k = 1, z[1][k] = (M0-k+1) * (M0-k+2) * p[0] * z[0][k] + k*(M0-k+2) * p[1] * z[0][k-1]; + for (k = _min < 2? 2 : _min; k <= _max; ++k) + z[1][k] = (M0-k+1)*(M0-k+2) * p[0] * z[0][k] + k*(M0-k+2) * p[1] * z[0][k-1] + k*(k-1)* p[2] * z[0][k-2]; + for (k = _min, sum = 0.; k <= _max; ++k) sum += z[1][k]; + ma->t += log(sum / (M * (M - 1.))); + for (k = _min; k <= _max; ++k) z[1][k] /= sum; + if (_min >= 1) z[1][_min-1] = 0.; + if (_min >= 2) z[1][_min-2] = 0.; + if (j < ma->n - 1) z[1][_max+1] = z[1][_max+2] = 0.; + } + tmp = z[0]; z[0] = z[1]; z[1] = tmp; + last_min = _min; last_max = _max; + } + } + if (z[0] != ma->z) memcpy(ma->z, z[0], sizeof(double) * (ma->M + 1)); +} + +static void mc_cal_y(bcf_p1aux_t *ma) +{ + if (ma->n1 > 0 && ma->n1 < ma->n && ma->M == ma->n * 2) { // NB: ma->n1 is ineffective when there are haploid samples + int k; + long double x; + memset(ma->z1, 0, sizeof(double) * (2 * ma->n1 + 1)); + memset(ma->z2, 0, sizeof(double) * (2 * (ma->n - ma->n1) + 1)); + ma->t1 = ma->t2 = 0.; + mc_cal_y_core(ma, ma->n1); + ma->t2 = ma->t; + memcpy(ma->z2, ma->z, sizeof(double) * (2 * (ma->n - ma->n1) + 1)); + mc_cal_y_core(ma, 0); + // rescale z + x = expl(ma->t - (ma->t1 + ma->t2)); + for (k = 0; k <= ma->M; ++k) ma->z[k] *= x; + } else mc_cal_y_core(ma, 0); +} + +#define CONTRAST_TINY 1e-30 + +extern double kf_gammaq(double s, double z); // incomplete gamma function for chi^2 test + +static inline double chi2_test(int a, int b, int c, int d) +{ + double x, z; + x = (double)(a+b) * (c+d) * (b+d) * (a+c); + if (x == 0.) return 1; + z = a * d - b * c; + return kf_gammaq(.5, .5 * z * z * (a+b+c+d) / x); +} + +// chi2=(a+b+c+d)(ad-bc)^2/[(a+b)(c+d)(a+c)(b+d)] +static inline double contrast2_aux(const bcf_p1aux_t *p1, double sum, int k1, int k2, double x[3]) +{ + double p = p1->phi[k1+k2] * p1->z1[k1] * p1->z2[k2] / sum * p1->hg[k1][k2]; + int n1 = p1->n1, n2 = p1->n - p1->n1; + if (p < CONTRAST_TINY) return -1; + if (.5*k1/n1 < .5*k2/n2) x[1] += p; + else if (.5*k1/n1 > .5*k2/n2) x[2] += p; + else x[0] += p; + return p * chi2_test(k1, k2, (n1<<1) - k1, (n2<<1) - k2); +} + +static double contrast2(bcf_p1aux_t *p1, double ret[3]) +{ + int k, k1, k2, k10, k20, n1, n2; + double sum; + // get n1 and n2 + n1 = p1->n1; n2 = p1->n - p1->n1; + if (n1 <= 0 || n2 <= 0) return 0.; + if (p1->hg == 0) { // initialize the hypergeometric distribution + /* NB: the hg matrix may take a lot of memory when there are many samples. There is a way + to avoid precomputing this matrix, but it is slower and quite intricate. The following + computation in this block can be accelerated with a similar strategy, but perhaps this + is not a serious concern for now. */ + double tmp = lgamma(2*(n1+n2)+1) - (lgamma(2*n1+1) + lgamma(2*n2+1)); + p1->hg = calloc(2*n1+1, sizeof(void*)); + for (k1 = 0; k1 <= 2*n1; ++k1) { + p1->hg[k1] = calloc(2*n2+1, sizeof(double)); + for (k2 = 0; k2 <= 2*n2; ++k2) + p1->hg[k1][k2] = exp(lgamma(k1+k2+1) + lgamma(p1->M-k1-k2+1) - (lgamma(k1+1) + lgamma(k2+1) + lgamma(2*n1-k1+1) + lgamma(2*n2-k2+1) + tmp)); + } + } + { // compute + long double suml = 0; + for (k = 0; k <= p1->M; ++k) suml += p1->phi[k] * p1->z[k]; + sum = suml; + } + { // get the max k1 and k2 + double max; + int max_k; + for (k = 0, max = 0, max_k = -1; k <= 2*n1; ++k) { + double x = p1->phi1[k] * p1->z1[k]; + if (x > max) max = x, max_k = k; + } + k10 = max_k; + for (k = 0, max = 0, max_k = -1; k <= 2*n2; ++k) { + double x = p1->phi2[k] * p1->z2[k]; + if (x > max) max = x, max_k = k; + } + k20 = max_k; + } + { // We can do the following with one nested loop, but that is an O(N^2) thing. The following code block is much faster for large N. + double x[3], y; + long double z = 0., L[2]; + x[0] = x[1] = x[2] = 0; L[0] = L[1] = 0; + for (k1 = k10; k1 >= 0; --k1) { + for (k2 = k20; k2 >= 0; --k2) { + if ((y = contrast2_aux(p1, sum, k1, k2, x)) < 0) break; + else z += y; + } + for (k2 = k20 + 1; k2 <= 2*n2; ++k2) { + if ((y = contrast2_aux(p1, sum, k1, k2, x)) < 0) break; + else z += y; + } + } + ret[0] = x[0]; ret[1] = x[1]; ret[2] = x[2]; + x[0] = x[1] = x[2] = 0; + for (k1 = k10 + 1; k1 <= 2*n1; ++k1) { + for (k2 = k20; k2 >= 0; --k2) { + if ((y = contrast2_aux(p1, sum, k1, k2, x)) < 0) break; + else z += y; + } + for (k2 = k20 + 1; k2 <= 2*n2; ++k2) { + if ((y = contrast2_aux(p1, sum, k1, k2, x)) < 0) break; + else z += y; + } + } + ret[0] += x[0]; ret[1] += x[1]; ret[2] += x[2]; + if (ret[0] + ret[1] + ret[2] < 0.95) { // in case of bad things happened + ret[0] = ret[1] = ret[2] = 0; L[0] = L[1] = 0; + for (k1 = 0, z = 0.; k1 <= 2*n1; ++k1) + for (k2 = 0; k2 <= 2*n2; ++k2) + if ((y = contrast2_aux(p1, sum, k1, k2, ret)) >= 0) z += y; + if (ret[0] + ret[1] + ret[2] < 0.95) // It seems that this may be caused by floating point errors. I do not really understand why... + z = 1.0, ret[0] = ret[1] = ret[2] = 1./3; + } + return (double)z; + } +} + +static double mc_cal_afs(bcf_p1aux_t *ma, double *p_ref_folded, double *p_var_folded) +{ + int k; + long double sum = 0., sum2; + double *phi = ma->is_indel? ma->phi_indel : ma->phi; + memset(ma->afs1, 0, sizeof(double) * (ma->M + 1)); + mc_cal_y(ma); + // compute AFS + for (k = 0, sum = 0.; k <= ma->M; ++k) + sum += (long double)phi[k] * ma->z[k]; + for (k = 0; k <= ma->M; ++k) { + ma->afs1[k] = phi[k] * ma->z[k] / sum; + if (isnan(ma->afs1[k]) || isinf(ma->afs1[k])) return -1.; + } + // compute folded variant probability + for (k = 0, sum = 0.; k <= ma->M; ++k) + sum += (long double)(phi[k] + phi[ma->M - k]) / 2. * ma->z[k]; + for (k = 1, sum2 = 0.; k < ma->M; ++k) + sum2 += (long double)(phi[k] + phi[ma->M - k]) / 2. * ma->z[k]; + *p_var_folded = sum2 / sum; + *p_ref_folded = (phi[k] + phi[ma->M - k]) / 2. * (ma->z[ma->M] + ma->z[0]) / sum; + // the expected frequency + for (k = 0, sum = 0.; k <= ma->M; ++k) { + ma->afs[k] += ma->afs1[k]; + sum += k * ma->afs1[k]; + } + return sum / ma->M; +} + +int bcf_p1_cal(const bcf1_t *b, int do_contrast, bcf_p1aux_t *ma, bcf_p1rst_t *rst) +{ + int i, k; + long double sum = 0.; + ma->is_indel = bcf_is_indel(b); + rst->perm_rank = -1; + // set PL and PL_len + for (i = 0; i < b->n_gi; ++i) { + if (b->gi[i].fmt == bcf_str2int("PL", 2)) { + ma->PL = (uint8_t*)b->gi[i].data; + ma->PL_len = b->gi[i].len; + break; + } + } + if (i == b->n_gi) return -1; // no PL + if (b->n_alleles < 2) return -1; // FIXME: find a better solution + // + rst->rank0 = cal_pdg(b, ma); + rst->f_exp = mc_cal_afs(ma, &rst->p_ref_folded, &rst->p_var_folded); + rst->p_ref = ma->afs1[ma->M]; + for (k = 0, sum = 0.; k < ma->M; ++k) + sum += ma->afs1[k]; + rst->p_var = (double)sum; + // calculate f_flat and f_em + for (k = 0, sum = 0.; k <= ma->M; ++k) + sum += (long double)ma->z[k]; + rst->f_flat = 0.; + for (k = 0; k <= ma->M; ++k) { + double p = ma->z[k] / sum; + rst->f_flat += k * p; + } + rst->f_flat /= ma->M; + { // estimate equal-tail credible interval (95% level) + int l, h; + double p; + for (i = 0, p = 0.; i < ma->M; ++i) + if (p + ma->afs1[i] > 0.025) break; + else p += ma->afs1[i]; + l = i; + for (i = ma->M-1, p = 0.; i >= 0; --i) + if (p + ma->afs1[i] > 0.025) break; + else p += ma->afs1[i]; + h = i; + rst->cil = (double)(ma->M - h) / ma->M; rst->cih = (double)(ma->M - l) / ma->M; + } + rst->cmp[0] = rst->cmp[1] = rst->cmp[2] = rst->p_chi2 = -1.0; + if (do_contrast && rst->p_var > 0.5) // skip contrast2() if the locus is a strong non-variant + rst->p_chi2 = contrast2(ma, rst->cmp); + return 0; +} + +void bcf_p1_dump_afs(bcf_p1aux_t *ma) +{ + int k; + fprintf(stderr, "[afs]"); + for (k = 0; k <= ma->M; ++k) + fprintf(stderr, " %d:%.3lf", k, ma->afs[ma->M - k]); + fprintf(stderr, "\n"); + memset(ma->afs, 0, sizeof(double) * (ma->M + 1)); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bcftools/prob1.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,41 @@ +#ifndef BCF_PROB1_H +#define BCF_PROB1_H + +#include "bcf.h" + +struct __bcf_p1aux_t; +typedef struct __bcf_p1aux_t bcf_p1aux_t; + +typedef struct { + int rank0, perm_rank; // NB: perm_rank is always set to -1 by bcf_p1_cal() + double f_exp, f_flat, p_ref_folded, p_ref, p_var_folded, p_var; + double cil, cih; + double cmp[3], p_chi2; // used by contrast2() +} bcf_p1rst_t; + +#define MC_PTYPE_FULL 1 +#define MC_PTYPE_COND2 2 +#define MC_PTYPE_FLAT 3 + +#ifdef __cplusplus +extern "C" { +#endif + + bcf_p1aux_t *bcf_p1_init(int n, uint8_t *ploidy); + void bcf_p1_init_prior(bcf_p1aux_t *ma, int type, double theta); + void bcf_p1_init_subprior(bcf_p1aux_t *ma, int type, double theta); + void bcf_p1_destroy(bcf_p1aux_t *ma); + int bcf_p1_cal(const bcf1_t *b, int do_contrast, bcf_p1aux_t *ma, bcf_p1rst_t *rst); + int bcf_p1_call_gt(const bcf_p1aux_t *ma, double f0, int k); + void bcf_p1_dump_afs(bcf_p1aux_t *ma); + int bcf_p1_read_prior(bcf_p1aux_t *ma, const char *fn); + int bcf_p1_set_n1(bcf_p1aux_t *b, int n1); + void bcf_p1_set_folded(bcf_p1aux_t *p1a); // only effective when set_n1() is not called + + int bcf_em1(const bcf1_t *b, int n1, int flag, double x[9]); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bcftools/vcf.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,244 @@ +#include <zlib.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "bcf.h" +#include "kstring.h" +#include "kseq.h" +KSTREAM_INIT(gzFile, gzread, 4096) + +typedef struct { + gzFile fp; + FILE *fpout; + kstream_t *ks; + void *refhash; + kstring_t line; + int max_ref; +} vcf_t; + +bcf_hdr_t *vcf_hdr_read(bcf_t *bp) +{ + kstring_t meta, smpl; + int dret; + vcf_t *v; + bcf_hdr_t *h; + if (!bp->is_vcf) return bcf_hdr_read(bp); + h = calloc(1, sizeof(bcf_hdr_t)); + v = (vcf_t*)bp->v; + v->line.l = 0; + memset(&meta, 0, sizeof(kstring_t)); + memset(&smpl, 0, sizeof(kstring_t)); + while (ks_getuntil(v->ks, '\n', &v->line, &dret) >= 0) { + if (v->line.l < 2) continue; + if (v->line.s[0] != '#') return 0; // no sample line + if (v->line.s[0] == '#' && v->line.s[1] == '#') { + kputsn(v->line.s, v->line.l, &meta); kputc('\n', &meta); + } else if (v->line.s[0] == '#') { + int k; + ks_tokaux_t aux; + char *p; + for (p = kstrtok(v->line.s, "\t\n", &aux), k = 0; p; p = kstrtok(0, 0, &aux), ++k) { + if (k >= 9) { + kputsn(p, aux.p - p, &smpl); + kputc('\0', &smpl); + } + } + break; + } + } + kputc('\0', &meta); + h->name = 0; + h->sname = smpl.s; h->l_smpl = smpl.l; + h->txt = meta.s; h->l_txt = meta.l; + bcf_hdr_sync(h); + return h; +} + +bcf_t *vcf_open(const char *fn, const char *mode) +{ + bcf_t *bp; + vcf_t *v; + if (strchr(mode, 'b')) return bcf_open(fn, mode); + bp = calloc(1, sizeof(bcf_t)); + v = calloc(1, sizeof(vcf_t)); + bp->is_vcf = 1; + bp->v = v; + v->refhash = bcf_str2id_init(); + if (strchr(mode, 'r')) { + v->fp = strcmp(fn, "-")? gzopen(fn, "r") : gzdopen(fileno(stdin), "r"); + v->ks = ks_init(v->fp); + } else if (strchr(mode, 'w')) + v->fpout = strcmp(fn, "-")? fopen(fn, "w") : stdout; + return bp; +} + +int vcf_dictread(bcf_t *bp, bcf_hdr_t *h, const char *fn) +{ + vcf_t *v; + gzFile fp; + kstream_t *ks; + kstring_t s, rn; + int dret; + if (bp == 0) return -1; + if (!bp->is_vcf) return 0; + s.l = s.m = 0; s.s = 0; + rn.m = rn.l = h->l_nm; rn.s = h->name; + v = (vcf_t*)bp->v; + fp = gzopen(fn, "r"); + ks = ks_init(fp); + while (ks_getuntil(ks, 0, &s, &dret) >= 0) { + bcf_str2id_add(v->refhash, strdup(s.s)); + kputs(s.s, &rn); kputc('\0', &rn); + if (dret != '\n') ks_getuntil(ks, '\n', &s, &dret); + } + ks_destroy(ks); + gzclose(fp); + h->l_nm = rn.l; h->name = rn.s; + bcf_hdr_sync(h); + free(s.s); + return 0; +} + +int vcf_close(bcf_t *bp) +{ + vcf_t *v; + if (bp == 0) return -1; + if (!bp->is_vcf) return bcf_close(bp); + v = (vcf_t*)bp->v; + if (v->fp) { + ks_destroy(v->ks); + gzclose(v->fp); + } + if (v->fpout) fclose(v->fpout); + free(v->line.s); + bcf_str2id_thorough_destroy(v->refhash); + free(v); + free(bp); + return 0; +} + +int vcf_hdr_write(bcf_t *bp, const bcf_hdr_t *h) +{ + vcf_t *v = (vcf_t*)bp->v; + int i, has_ver = 0; + if (!bp->is_vcf) return bcf_hdr_write(bp, h); + if (h->l_txt > 0) { + if (strstr(h->txt, "##fileformat=")) has_ver = 1; + if (has_ver == 0) fprintf(v->fpout, "##fileformat=VCFv4.1\n"); + fwrite(h->txt, 1, h->l_txt - 1, v->fpout); + } + if (h->l_txt == 0) fprintf(v->fpout, "##fileformat=VCFv4.1\n"); + fprintf(v->fpout, "#CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\tINFO\tFORMAT"); + for (i = 0; i < h->n_smpl; ++i) + fprintf(v->fpout, "\t%s", h->sns[i]); + fputc('\n', v->fpout); + return 0; +} + +int vcf_write(bcf_t *bp, bcf_hdr_t *h, bcf1_t *b) +{ + vcf_t *v = (vcf_t*)bp->v; + extern void bcf_fmt_core(const bcf_hdr_t *h, bcf1_t *b, kstring_t *s); + if (!bp->is_vcf) return bcf_write(bp, h, b); + bcf_fmt_core(h, b, &v->line); + fwrite(v->line.s, 1, v->line.l, v->fpout); + fputc('\n', v->fpout); + return v->line.l + 1; +} + +int vcf_read(bcf_t *bp, bcf_hdr_t *h, bcf1_t *b) +{ + int dret, k, i, sync = 0; + vcf_t *v = (vcf_t*)bp->v; + char *p, *q; + kstring_t str, rn; + ks_tokaux_t aux, a2; + if (!bp->is_vcf) return bcf_read(bp, h, b); + v->line.l = 0; + str.l = 0; str.m = b->m_str; str.s = b->str; + rn.l = rn.m = h->l_nm; rn.s = h->name; + if (ks_getuntil(v->ks, '\n', &v->line, &dret) < 0) return -1; + b->n_smpl = h->n_smpl; + for (p = kstrtok(v->line.s, "\t", &aux), k = 0; p; p = kstrtok(0, 0, &aux), ++k) { + *(char*)aux.p = 0; + if (k == 0) { // ref + int tid = bcf_str2id(v->refhash, p); + if (tid < 0) { + tid = bcf_str2id_add(v->refhash, strdup(p)); + kputs(p, &rn); kputc('\0', &rn); + sync = 1; + } + b->tid = tid; + } else if (k == 1) { // pos + b->pos = atoi(p) - 1; + } else if (k == 5) { // qual + b->qual = (p[0] >= '0' && p[0] <= '9')? atof(p) : 0; + } else if (k <= 8) { // variable length strings + kputs(p, &str); kputc('\0', &str); + b->l_str = str.l; b->m_str = str.m; b->str = str.s; + if (k == 8) bcf_sync(b); + } else { // k > 9 + if (strncmp(p, "./.", 3) == 0) { + for (i = 0; i < b->n_gi; ++i) { + if (b->gi[i].fmt == bcf_str2int("GT", 2)) { + ((uint8_t*)b->gi[i].data)[k-9] = 1<<7; + } else if (b->gi[i].fmt == bcf_str2int("GQ", 2)) { + ((uint8_t*)b->gi[i].data)[k-9] = 0; + } else if (b->gi[i].fmt == bcf_str2int("SP", 2)) { + ((int32_t*)b->gi[i].data)[k-9] = 0; + } else if (b->gi[i].fmt == bcf_str2int("DP", 2)) { + ((uint16_t*)b->gi[i].data)[k-9] = 0; + } else if (b->gi[i].fmt == bcf_str2int("PL", 2)) { + int y = b->n_alleles * (b->n_alleles + 1) / 2; + memset((uint8_t*)b->gi[i].data + (k - 9) * y, 0, y); + } else if (b->gi[i].fmt == bcf_str2int("GL", 2)) { + int y = b->n_alleles * (b->n_alleles + 1) / 2; + memset((float*)b->gi[i].data + (k - 9) * y, 0, y * 4); + } + } + goto endblock; + } + for (q = kstrtok(p, ":", &a2), i = 0; q && i < b->n_gi; q = kstrtok(0, 0, &a2), ++i) { + if (b->gi[i].fmt == bcf_str2int("GT", 2)) { + ((uint8_t*)b->gi[i].data)[k-9] = (q[0] - '0')<<3 | (q[2] - '0') | (q[1] == '/'? 0 : 1) << 6; + } else if (b->gi[i].fmt == bcf_str2int("GQ", 2)) { + double _x = strtod(q, &q); + int x = (int)(_x + .499); + if (x > 255) x = 255; + ((uint8_t*)b->gi[i].data)[k-9] = x; + } else if (b->gi[i].fmt == bcf_str2int("SP", 2)) { + int x = strtol(q, &q, 10); + if (x > 0xffff) x = 0xffff; + ((uint32_t*)b->gi[i].data)[k-9] = x; + } else if (b->gi[i].fmt == bcf_str2int("DP", 2)) { + int x = strtol(q, &q, 10); + if (x > 0xffff) x = 0xffff; + ((uint16_t*)b->gi[i].data)[k-9] = x; + } else if (b->gi[i].fmt == bcf_str2int("PL", 2)) { + int x, y, j; + uint8_t *data = (uint8_t*)b->gi[i].data; + y = b->n_alleles * (b->n_alleles + 1) / 2; + for (j = 0; j < y; ++j) { + x = strtol(q, &q, 10); + if (x > 255) x = 255; + data[(k-9) * y + j] = x; + ++q; + } + } else if (b->gi[i].fmt == bcf_str2int("GL", 2)) { + int j, y; + float x, *data = (float*)b->gi[i].data; + y = b->n_alleles * (b->n_alleles + 1) / 2; + for (j = 0; j < y; ++j) { + x = strtod(q, &q); + data[(k-9) * y + j] = x > 0? -x/10. : x; + ++q; + } + } + } + endblock: i = i; + } + } + h->l_nm = rn.l; h->name = rn.s; + if (sync) bcf_hdr_sync(h); + return v->line.l + 1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bcftools/vcfutils.pl Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,560 @@ +#!/usr/bin/perl -w + +# Author: lh3 + +use strict; +use warnings; +use Getopt::Std; + +&main; +exit; + +sub main { + &usage if (@ARGV < 1); + my $command = shift(@ARGV); + my %func = (subsam=>\&subsam, listsam=>\&listsam, fillac=>\&fillac, qstats=>\&qstats, varFilter=>\&varFilter, + hapmap2vcf=>\&hapmap2vcf, ucscsnp2vcf=>\&ucscsnp2vcf, filter4vcf=>\&varFilter, ldstats=>\&ldstats, + gapstats=>\&gapstats, splitchr=>\&splitchr, vcf2fq=>\&vcf2fq); + die("Unknown command \"$command\".\n") if (!defined($func{$command})); + &{$func{$command}}; +} + +sub splitchr { + my %opts = (l=>5000000); + getopts('l:', \%opts); + my $l = $opts{l}; + die(qq/Usage: vcfutils.pl splitchr [-l $opts{l}] <in.fa.fai>\n/) if (@ARGV == 0 && -t STDIN); + while (<>) { + my @t = split; + my $last = 0; + for (my $i = 0; $i < $t[1];) { + my $e = ($t[1] - $i) / $l < 1.1? $t[1] : $i + $l; + print "$t[0]:".($i+1)."-$e\n"; + $i = $e; + } + } +} + +sub subsam { + die(qq/Usage: vcfutils.pl subsam <in.vcf> [samples]\n/) if (@ARGV == 0); + my ($fh, %h); + my $fn = shift(@ARGV); + my @col; + open($fh, ($fn =~ /\.gz$/)? "gzip -dc $fn |" : $fn) || die; + $h{$_} = 1 for (@ARGV); + while (<$fh>) { + if (/^##/) { + print; + } elsif (/^#/) { + my @t = split; + my @s = @t[0..8]; # all fixed fields + FORMAT + for (9 .. $#t) { + if ($h{$t[$_]}) { + push(@s, $t[$_]); + push(@col, $_); + } + } + pop(@s) if (@s == 9); # no sample selected; remove the FORMAT field + print join("\t", @s), "\n"; + } else { + my @t = split; + if (@col == 0) { + print join("\t", @t[0..7]), "\n"; + } else { + print join("\t", @t[0..8], map {$t[$_]} @col), "\n"; + } + } + } + close($fh); +} + +sub listsam { + die(qq/Usage: vcfutils.pl listsam <in.vcf>\n/) if (@ARGV == 0 && -t STDIN); + while (<>) { + if (/^#/ && !/^##/) { + my @t = split; + print join("\n", @t[9..$#t]), "\n"; + exit; + } + } +} + +sub fillac { + die(qq/Usage: vcfutils.pl fillac <in.vcf>\n\nNote: The GT field MUST BE present and always appear as the first field.\n/) if (@ARGV == 0 && -t STDIN); + while (<>) { + if (/^#/) { + print; + } else { + my @t = split; + my @c = (0); + my $n = 0; + my $s = -1; + @_ = split(":", $t[8]); + for (0 .. $#_) { + if ($_[$_] eq 'GT') { $s = $_; last; } + } + if ($s < 0) { + print join("\t", @t), "\n"; + next; + } + for (9 .. $#t) { + if ($t[$_] =~ /^0,0,0/) { + } elsif ($t[$_] =~ /^([^\s:]+:){$s}(\d+).(\d+)/) { + ++$c[$2]; ++$c[$3]; + $n += 2; + } + } + my $AC = "AC=" . join("\t", @c[1..$#c]) . ";AN=$n"; + my $info = $t[7]; + $info =~ s/(;?)AC=(\d+)//; + $info =~ s/(;?)AN=(\d+)//; + if ($info eq '.') { + $info = $AC; + } else { + $info .= ";$AC"; + } + $t[7] = $info; + print join("\t", @t), "\n"; + } + } +} + +sub ldstats { + my %opts = (t=>0.9); + getopts('t:', \%opts); + die("Usage: vcfutils.pl ldstats [-t $opts{t}] <in.vcf>\n") if (@ARGV == 0 && -t STDIN); + my $cutoff = $opts{t}; + my ($last, $lastchr) = (0x7fffffff, ''); + my ($x, $y, $n) = (0, 0, 0); + while (<>) { + if (/^([^#\s]+)\s(\d+)/) { + my ($chr, $pos) = ($1, $2); + if (/NEIR=([\d\.]+)/) { + ++$n; + ++$y, $x += $pos - $last if ($lastchr eq $chr && $pos > $last && $1 > $cutoff); + } + $last = $pos; $lastchr = $chr; + } + } + print "Number of SNP intervals in strong LD (r > $opts{t}): $y\n"; + print "Fraction: ", $y/$n, "\n"; + print "Length: $x\n"; +} + +sub qstats { + my %opts = (r=>'', s=>0.02, v=>undef); + getopts('r:s:v', \%opts); + die("Usage: vcfutils.pl qstats [-r ref.vcf] <in.vcf>\n +Note: This command discards indels. Output: QUAL #non-indel #SNPs #transitions #joint ts/tv #joint/#ref #joint/#non-indel \n") if (@ARGV == 0 && -t STDIN); + my %ts = (AG=>1, GA=>1, CT=>1, TC=>1); + my %h = (); + my $is_vcf = defined($opts{v})? 1 : 0; + if ($opts{r}) { # read the reference positions + my $fh; + open($fh, $opts{r}) || die; + while (<$fh>) { + next if (/^#/); + if ($is_vcf) { + my @t = split; + $h{$t[0],$t[1]} = $t[4]; + } else { + $h{$1,$2} = 1 if (/^(\S+)\s+(\d+)/); + } + } + close($fh); + } + my $hsize = scalar(keys %h); + my @a; + while (<>) { + next if (/^#/); + my @t = split; + next if (length($t[3]) != 1 || uc($t[3]) eq 'N'); + $t[3] = uc($t[3]); $t[4] = uc($t[4]); + my @s = split(',', $t[4]); + $t[5] = 3 if ($t[5] eq '.' || $t[5] < 0); + next if (length($s[0]) != 1); + my $hit; + if ($is_vcf) { + $hit = 0; + my $aa = $h{$t[0],$t[1]}; + if (defined($aa)) { + my @aaa = split(",", $aa); + for (@aaa) { + $hit = 1 if ($_ eq $s[0]); + } + } + } else { + $hit = defined($h{$t[0],$t[1]})? 1 : 0; + } + push(@a, [$t[5], ($t[4] eq '.' || $t[4] eq $t[3])? 0 : 1, $ts{$t[3].$s[0]}? 1 : 0, $hit]); + } + push(@a, [-1, 0, 0, 0]); # end marker + die("[qstats] No SNP data!\n") if (@a == 0); + @a = sort {$b->[0]<=>$a->[0]} @a; + my $next = $opts{s}; + my $last = $a[0]; + my @c = (0, 0, 0, 0); + my @lc; + $lc[1] = $lc[2] = 0; + for my $p (@a) { + if ($p->[0] == -1 || ($p->[0] != $last && $c[0]/@a > $next)) { + my @x; + $x[0] = sprintf("%.4f", $c[1]-$c[2]? $c[2] / ($c[1] - $c[2]) : 100); + $x[1] = sprintf("%.4f", $hsize? $c[3] / $hsize : 0); + $x[2] = sprintf("%.4f", $c[3] / $c[1]); + my $a = $c[1] - $lc[1]; + my $b = $c[2] - $lc[2]; + $x[3] = sprintf("%.4f", $a-$b? $b / ($a-$b) : 100); + print join("\t", $last, @c, @x), "\n"; + $next = $c[0]/@a + $opts{s}; + $lc[1] = $c[1]; $lc[2] = $c[2]; + } + ++$c[0]; $c[1] += $p->[1]; $c[2] += $p->[2]; $c[3] += $p->[3]; + $last = $p->[0]; + } +} + +sub varFilter { + my %opts = (d=>2, D=>10000000, a=>2, W=>10, Q=>10, w=>10, p=>undef, 1=>1e-4, 2=>1e-100, 3=>0, 4=>1e-4, G=>0, S=>1000); + getopts('pd:D:W:Q:w:a:1:2:3:4:G:S:', \%opts); + die(qq/ +Usage: vcfutils.pl varFilter [options] <in.vcf> + +Options: -Q INT minimum RMS mapping quality for SNPs [$opts{Q}] + -d INT minimum read depth [$opts{d}] + -D INT maximum read depth [$opts{D}] + -a INT minimum number of alternate bases [$opts{a}] + -w INT SNP within INT bp around a gap to be filtered [$opts{w}] + -W INT window size for filtering adjacent gaps [$opts{W}] + -1 FLOAT min P-value for strand bias (given PV4) [$opts{1}] + -2 FLOAT min P-value for baseQ bias [$opts{2}] + -3 FLOAT min P-value for mapQ bias [$opts{3}] + -4 FLOAT min P-value for end distance bias [$opts{4}] + -p print filtered variants + +Note: Some of the filters rely on annotations generated by SAMtools\/BCFtools. +\n/) if (@ARGV == 0 && -t STDIN); + + # calculate the window size + my ($ol, $ow) = ($opts{W}, $opts{w}); + my $max_dist = $ol > $ow? $ol : $ow; + # the core loop + my @staging; # (indel_filtering_score, flt_tag, indel_span; chr, pos, ...) + while (<>) { + my @t = split; + if (/^#/) { + print; next; + } + next if ($t[4] eq '.'); # skip non-var sites + next if ($t[3] eq 'N'); # skip sites with unknown ref ('N') + # check if the site is a SNP + my $type = 1; # SNP + if (length($t[3]) > 1) { + $type = 2; # MNP + my @s = split(',', $t[4]); + for (@s) { + $type = 3 if (length != length($t[3])); + } + } else { + my @s = split(',', $t[4]); + for (@s) { + $type = 3 if (length > 1); + } + } + # clear the out-of-range elements + while (@staging) { + # Still on the same chromosome and the first element's window still affects this position? + last if ($staging[0][3] eq $t[0] && $staging[0][4] + $staging[0][2] + $max_dist >= $t[1]); + varFilter_aux(shift(@staging), $opts{p}); # calling a function is a bit slower, not much + } + my $flt = 0; + # parse annotations + my ($dp, $mq, $dp_alt) = (-1, -1, -1); + if ($t[7] =~ /DP4=(\d+),(\d+),(\d+),(\d+)/i) { + $dp = $1 + $2 + $3 + $4; + $dp_alt = $3 + $4; + } + if ($t[7] =~ /DP=(\d+)/i) { + $dp = $1; + } + $mq = $1 if ($t[7] =~ /MQ=(\d+)/i); + # the depth and mapQ filter + if ($dp >= 0) { + if ($dp < $opts{d}) { + $flt = 2; + } elsif ($dp > $opts{D}) { + $flt = 3; + } + } + $flt = 4 if ($dp_alt >= 0 && $dp_alt < $opts{a}); + $flt = 1 if ($flt == 0 && $mq >= 0 && $mq < $opts{Q}); + $flt = 7 if ($flt == 0 && /PV4=([^,]+),([^,]+),([^,]+),([^,;\t]+)/ + && ($1<$opts{1} || $2<$opts{2} || $3<$opts{3} || $4<$opts{4})); + $flt = 8 if ($flt == 0 && ((/MXGQ=(\d+)/ && $1 < $opts{G}) || (/MXSP=(\d+)/ && $1 >= $opts{S}))); + + my $score = $t[5] * 100 + $dp_alt; + my $rlen = length($t[3]) - 1; # $indel_score<0 for SNPs + if ($flt == 0) { + if ($type == 3) { # an indel + # filtering SNPs and MNPs + for my $x (@staging) { + next if (($x->[0]&3) == 3 || $x->[1] || $x->[4] + $x->[2] + $ow < $t[1]); + $x->[1] = 5; + } + # check the staging list for indel filtering + for my $x (@staging) { + next if (($x->[0]&3) != 3 || $x->[1] || $x->[4] + $x->[2] + $ol < $t[1]); + if ($x->[0]>>2 < $score) { + $x->[1] = 6; + } else { + $flt = 6; last; + } + } + } else { # SNP or MNP + for my $x (@staging) { + next if (($x->[0]&3) != 3 || $x->[4] + $x->[2] + $ow < $t[1]); + if ($x->[4] + length($x->[7]) - 1 == $t[1] && substr($x->[7], -1, 1) eq substr($t[4], 0, 1) + && length($x->[7]) - length($x->[6]) == 1) { + $x->[1] = 5; + } else { $flt = 5; } + last; + } + # check MNP + for my $x (@staging) { + next if (($x->[0]&3) == 3 || $x->[4] + $x->[2] < $t[1]); + if ($x->[0]>>2 < $score) { + $x->[1] = 8; + } else { + $flt = 8; last; + } + } + } + } + push(@staging, [$score<<2|$type, $flt, $rlen, @t]); + } + # output the last few elements in the staging list + while (@staging) { + varFilter_aux(shift @staging, $opts{p}); + } +} + +sub varFilter_aux { + my ($first, $is_print) = @_; + if ($first->[1] == 0) { + print join("\t", @$first[3 .. @$first-1]), "\n"; + } elsif ($is_print) { + print STDERR join("\t", substr("UQdDaGgPMS", $first->[1], 1), @$first[3 .. @$first-1]), "\n"; + } +} + +sub gapstats { + my (@c0, @c1); + $c0[$_] = $c1[$_] = 0 for (0 .. 10000); + while (<>) { + next if (/^#/); + my @t = split; + next if (length($t[3]) == 1 && $t[4] =~ /^[A-Za-z](,[A-Za-z])*$/); # not an indel + my @s = split(',', $t[4]); + for my $x (@s) { + my $l = length($x) - length($t[3]) + 5000; + if ($x =~ /^-/) { + $l = -(length($x) - 1) + 5000; + } elsif ($x =~ /^\+/) { + $l = length($x) - 1 + 5000; + } + $c0[$l] += 1 / @s; + } + } + for (my $i = 0; $i < 10000; ++$i) { + next if ($c0[$i] == 0); + $c1[0] += $c0[$i]; + $c1[1] += $c0[$i] if (($i-5000)%3 == 0); + printf("C\t%d\t%.2f\n", ($i-5000), $c0[$i]); + } + printf("3\t%d\t%d\t%.3f\n", $c1[0], $c1[1], $c1[1]/$c1[0]); +} + +sub ucscsnp2vcf { + die("Usage: vcfutils.pl <in.ucsc.snp>\n") if (@ARGV == 0 && -t STDIN); + print "##fileformat=VCFv4.0\n"; + print join("\t", "#CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\tINFO"), "\n"; + while (<>) { + my @t = split("\t"); + my $indel = ($t[9] =~ /^[ACGT](\/[ACGT])+$/)? 0 : 1; + my $pos = $t[2] + 1; + my @alt; + push(@alt, $t[7]); + if ($t[6] eq '-') { + $t[9] = reverse($t[9]); + $t[9] =~ tr/ACGTRYMKWSNacgtrymkwsn/TGCAYRKMWSNtgcayrkmwsn/; + } + my @a = split("/", $t[9]); + for (@a) { + push(@alt, $_) if ($_ ne $alt[0]); + } + if ($indel) { + --$pos; + for (0 .. $#alt) { + $alt[$_] =~ tr/-//d; + $alt[$_] = "N$alt[$_]"; + } + } + my $ref = shift(@alt); + my $af = $t[13] > 0? ";AF=$t[13]" : ''; + my $valid = ($t[12] eq 'unknown')? '' : ";valid=$t[12]"; + my $info = "molType=$t[10];class=$t[11]$valid$af"; + print join("\t", $t[1], $pos, $t[4], $ref, join(",", @alt), 0, '.', $info), "\n"; + } +} + +sub hapmap2vcf { + die("Usage: vcfutils.pl <in.ucsc.snp> <in.hapmap>\n") if (@ARGV == 0); + my $fn = shift(@ARGV); + # parse UCSC SNP + warn("Parsing UCSC SNPs...\n"); + my ($fh, %map); + open($fh, ($fn =~ /\.gz$/)? "gzip -dc $fn |" : $fn) || die; + while (<$fh>) { + my @t = split; + next if ($t[3] - $t[2] != 1); # not SNP + @{$map{$t[4]}} = @t[1,3,7]; + } + close($fh); + # write VCF + warn("Writing VCF...\n"); + print "##fileformat=VCFv4.0\n"; + while (<>) { + my @t = split; + if ($t[0] eq 'rs#') { # the first line + print join("\t", "#CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\tINFO\tFORMAT", @t[11..$#t]), "\n"; + } else { + next unless ($map{$t[0]}); + next if (length($t[1]) != 3); # skip non-SNPs + my $a = \@{$map{$t[0]}}; + my $ref = $a->[2]; + my @u = split('/', $t[1]); + if ($u[1] eq $ref) { + $u[1] = $u[0]; $u[0] = $ref; + } elsif ($u[0] ne $ref) { next; } + my $alt = $u[1]; + my %w; + $w{$u[0]} = 0; $w{$u[1]} = 1; + my @s = (@$a[0,1], $t[0], $ref, $alt, 0, '.', '.', 'GT'); + my $is_tri = 0; + for (@t[11..$#t]) { + if ($_ eq 'NN') { + push(@s, './.'); + } else { + my @a = ($w{substr($_,0,1)}, $w{substr($_,1,1)}); + if (!defined($a[0]) || !defined($a[1])) { + $is_tri = 1; + last; + } + push(@s, "$a[0]/$a[1]"); + } + } + next if ($is_tri); + print join("\t", @s), "\n"; + } + } +} + +sub vcf2fq { + my %opts = (d=>3, D=>100000, Q=>10, l=>5); + getopts('d:D:Q:l:', \%opts); + die(qq/ +Usage: vcfutils.pl vcf2fq [options] <all-site.vcf> + +Options: -d INT minimum depth [$opts{d}] + -D INT maximum depth [$opts{D}] + -Q INT min RMS mapQ [$opts{Q}] + -l INT INDEL filtering window [$opts{l}] +\n/) if (@ARGV == 0 && -t STDIN); + + my ($last_chr, $seq, $qual, $last_pos, @gaps); + my $_Q = $opts{Q}; + my $_d = $opts{d}; + my $_D = $opts{D}; + + my %het = (AC=>'M', AG=>'R', AT=>'W', CA=>'M', CG=>'S', CT=>'Y', + GA=>'R', GC=>'S', GT=>'K', TA=>'W', TC=>'Y', TG=>'K'); + + $last_chr = ''; + while (<>) { + next if (/^#/); + my @t = split; + if ($last_chr ne $t[0]) { + &v2q_post_process($last_chr, \$seq, \$qual, \@gaps, $opts{l}) if ($last_chr); + ($last_chr, $last_pos) = ($t[0], 0); + $seq = $qual = ''; + @gaps = (); + } + die("[vcf2fq] unsorted input\n") if ($t[1] - $last_pos < 0); + if ($t[1] - $last_pos > 1) { + $seq .= 'n' x ($t[1] - $last_pos - 1); + $qual .= '!' x ($t[1] - $last_pos - 1); + } + if (length($t[3]) == 1 && $t[7] !~ /INDEL/ && $t[4] =~ /^([A-Za-z.])(,[A-Za-z])*$/) { # a SNP or reference + my ($ref, $alt) = ($t[3], $1); + my ($b, $q); + $q = $1 if ($t[7] =~ /FQ=(-?[\d\.]+)/); + if ($q < 0) { + $_ = $1 if ($t[7] =~ /AF1=([\d\.]+)/); + $b = ($_ < .5 || $alt eq '.')? $ref : $alt; + $q = -$q; + } else { + $b = $het{"$ref$alt"}; + $b ||= 'N'; + } + $b = lc($b); + $b = uc($b) if (($t[7] =~ /MQ=(\d+)/ && $1 >= $_Q) && ($t[7] =~ /DP=(\d+)/ && $1 >= $_d && $1 <= $_D)); + $q = int($q + 33 + .499); + $q = chr($q <= 126? $q : 126); + $seq .= $b; + $qual .= $q; + } elsif ($t[4] ne '.') { # an INDEL + push(@gaps, [$t[1], length($t[3])]); + } + $last_pos = $t[1]; + } + &v2q_post_process($last_chr, \$seq, \$qual, \@gaps, $opts{l}); +} + +sub v2q_post_process { + my ($chr, $seq, $qual, $gaps, $l) = @_; + for my $g (@$gaps) { + my $beg = $g->[0] > $l? $g->[0] - $l : 0; + my $end = $g->[0] + $g->[1] + $l; + $end = length($$seq) if ($end > length($$seq)); + substr($$seq, $beg, $end - $beg) = lc(substr($$seq, $beg, $end - $beg)); + } + print "\@$chr\n"; &v2q_print_str($seq); + print "+\n"; &v2q_print_str($qual); +} + +sub v2q_print_str { + my ($s) = @_; + my $l = length($$s); + for (my $i = 0; $i < $l; $i += 60) { + print substr($$s, $i, 60), "\n"; + } +} + +sub usage { + die(qq/ +Usage: vcfutils.pl <command> [<arguments>]\n +Command: subsam get a subset of samples + listsam list the samples + fillac fill the allele count field + qstats SNP stats stratified by QUAL + + hapmap2vcf convert the hapmap format to VCF + ucscsnp2vcf convert UCSC SNP SQL dump to VCF + + varFilter filtering short variants (*) + vcf2fq VCF->fastq (**) + +Notes: Commands with description endting with (*) may need bcftools + specific annotations. +\n/); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bedidx.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,156 @@ +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <stdio.h> +#include <zlib.h> + +#include "ksort.h" +KSORT_INIT_GENERIC(uint64_t) + +#include "kseq.h" +KSTREAM_INIT(gzFile, gzread, 8192) + +typedef struct { + int n, m; + uint64_t *a; + int *idx; +} bed_reglist_t; + +#include "khash.h" +KHASH_MAP_INIT_STR(reg, bed_reglist_t) + +#define LIDX_SHIFT 13 + +typedef kh_reg_t reghash_t; + +int *bed_index_core(int n, uint64_t *a, int *n_idx) +{ + int i, j, m, *idx; + m = *n_idx = 0; idx = 0; + for (i = 0; i < n; ++i) { + int beg, end; + beg = a[i]>>32 >> LIDX_SHIFT; end = ((uint32_t)a[i]) >> LIDX_SHIFT; + if (m < end + 1) { + int oldm = m; + m = end + 1; + kroundup32(m); + idx = realloc(idx, m * sizeof(int)); + for (j = oldm; j < m; ++j) idx[j] = -1; + } + if (beg == end) { + if (idx[beg] < 0) idx[beg] = i; + } else { + for (j = beg; j <= end; ++j) + if (idx[j] < 0) idx[j] = i; + } + *n_idx = end + 1; + } + return idx; +} + +void bed_index(void *_h) +{ + reghash_t *h = (reghash_t*)_h; + khint_t k; + for (k = 0; k < kh_end(h); ++k) { + if (kh_exist(h, k)) { + bed_reglist_t *p = &kh_val(h, k); + if (p->idx) free(p->idx); + ks_introsort(uint64_t, p->n, p->a); + p->idx = bed_index_core(p->n, p->a, &p->m); + } + } +} + +int bed_overlap_core(const bed_reglist_t *p, int beg, int end) +{ + int i, min_off; + if (p->n == 0) return 0; + min_off = (beg>>LIDX_SHIFT >= p->n)? p->idx[p->n-1] : p->idx[beg>>LIDX_SHIFT]; + if (min_off < 0) { // TODO: this block can be improved, but speed should not matter too much here + int n = beg>>LIDX_SHIFT; + if (n > p->n) n = p->n; + for (i = n - 1; i >= 0; --i) + if (p->idx[i] >= 0) break; + min_off = i >= 0? p->idx[i] : 0; + } + for (i = min_off; i < p->n; ++i) { + if ((int)(p->a[i]>>32) >= end) break; // out of range; no need to proceed + if ((int32_t)p->a[i] > beg && (int32_t)(p->a[i]>>32) < end) + return 1; // find the overlap; return + } + return 0; +} + +int bed_overlap(const void *_h, const char *chr, int beg, int end) +{ + const reghash_t *h = (const reghash_t*)_h; + khint_t k; + if (!h) return 0; + k = kh_get(reg, h, chr); + if (k == kh_end(h)) return 0; + return bed_overlap_core(&kh_val(h, k), beg, end); +} + +void *bed_read(const char *fn) +{ + reghash_t *h = kh_init(reg); + gzFile fp; + kstream_t *ks; + int dret; + kstring_t *str; + // read the list + fp = strcmp(fn, "-")? gzopen(fn, "r") : gzdopen(fileno(stdin), "r"); + if (fp == 0) return 0; + str = calloc(1, sizeof(kstring_t)); + ks = ks_init(fp); + while (ks_getuntil(ks, 0, str, &dret) >= 0) { // read the chr name + int beg = -1, end = -1; + bed_reglist_t *p; + khint_t k = kh_get(reg, h, str->s); + if (k == kh_end(h)) { // absent from the hash table + int ret; + char *s = strdup(str->s); + k = kh_put(reg, h, s, &ret); + memset(&kh_val(h, k), 0, sizeof(bed_reglist_t)); + } + p = &kh_val(h, k); + if (dret != '\n') { // if the lines has other characters + if (ks_getuntil(ks, 0, str, &dret) > 0 && isdigit(str->s[0])) { + beg = atoi(str->s); // begin + if (dret != '\n') { + if (ks_getuntil(ks, 0, str, &dret) > 0 && isdigit(str->s[0])) + end = atoi(str->s); // end + } + } + } + if (dret != '\n') while ((dret = ks_getc(ks)) > 0 && dret != '\n'); // skip the rest of the line + if (end < 0 && beg > 0) end = beg, beg = beg - 1; // if there is only one column + if (beg >= 0 && end > beg) { + if (p->n == p->m) { + p->m = p->m? p->m<<1 : 4; + p->a = realloc(p->a, p->m * 8); + } + p->a[p->n++] = (uint64_t)beg<<32 | end; + } + } + ks_destroy(ks); + gzclose(fp); + free(str->s); free(str); + bed_index(h); + return h; +} + +void bed_destroy(void *_h) +{ + reghash_t *h = (reghash_t*)_h; + khint_t k; + for (k = 0; k < kh_end(h); ++k) { + if (kh_exist(h, k)) { + free(kh_val(h, k).a); + free(kh_val(h, k).idx); + free((char*)kh_key(h, k)); + } + } + kh_destroy(reg, h); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bgzf.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,714 @@ +/* The MIT License + + Copyright (c) 2008 Broad Institute / Massachusetts Institute of Technology + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +/* + 2009-06-29 by lh3: cache recent uncompressed blocks. + 2009-06-25 by lh3: optionally use my knetfile library to access file on a FTP. + 2009-06-12 by lh3: support a mode string like "wu" where 'u' for uncompressed output */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "bgzf.h" + +#include "khash.h" +typedef struct { + int size; + uint8_t *block; + int64_t end_offset; +} cache_t; +KHASH_MAP_INIT_INT64(cache, cache_t) + +#if defined(_WIN32) || defined(_MSC_VER) +#define ftello(fp) ftell(fp) +#define fseeko(fp, offset, whence) fseek(fp, offset, whence) +#else +extern off_t ftello(FILE *stream); +extern int fseeko(FILE *stream, off_t offset, int whence); +#endif + +typedef int8_t bgzf_byte_t; + +static const int DEFAULT_BLOCK_SIZE = 64 * 1024; +static const int MAX_BLOCK_SIZE = 64 * 1024; + +static const int BLOCK_HEADER_LENGTH = 18; +static const int BLOCK_FOOTER_LENGTH = 8; + +static const int GZIP_ID1 = 31; +static const int GZIP_ID2 = 139; +static const int CM_DEFLATE = 8; +static const int FLG_FEXTRA = 4; +static const int OS_UNKNOWN = 255; +static const int BGZF_ID1 = 66; // 'B' +static const int BGZF_ID2 = 67; // 'C' +static const int BGZF_LEN = 2; +static const int BGZF_XLEN = 6; // BGZF_LEN+4 + +static const int GZIP_WINDOW_BITS = -15; // no zlib header +static const int Z_DEFAULT_MEM_LEVEL = 8; + + +inline +void +packInt16(uint8_t* buffer, uint16_t value) +{ + buffer[0] = value; + buffer[1] = value >> 8; +} + +inline +int +unpackInt16(const uint8_t* buffer) +{ + return (buffer[0] | (buffer[1] << 8)); +} + +inline +void +packInt32(uint8_t* buffer, uint32_t value) +{ + buffer[0] = value; + buffer[1] = value >> 8; + buffer[2] = value >> 16; + buffer[3] = value >> 24; +} + +static inline +int +bgzf_min(int x, int y) +{ + return (x < y) ? x : y; +} + +static +void +report_error(BGZF* fp, const char* message) { + fp->error = message; +} + +int bgzf_check_bgzf(const char *fn) +{ + BGZF *fp; + uint8_t buf[10],magic[10]="\037\213\010\4\0\0\0\0\0\377"; + int n; + + if ((fp = bgzf_open(fn, "r")) == 0) + { + fprintf(stderr, "[bgzf_check_bgzf] failed to open the file: %s\n",fn); + return -1; + } + +#ifdef _USE_KNETFILE + n = knet_read(fp->x.fpr, buf, 10); +#else + n = fread(buf, 1, 10, fp->file); +#endif + bgzf_close(fp); + + if ( n!=10 ) + return -1; + + if ( !memcmp(magic, buf, 10) ) return 1; + return 0; +} + +static BGZF *bgzf_read_init() +{ + BGZF *fp; + fp = calloc(1, sizeof(BGZF)); + fp->uncompressed_block_size = MAX_BLOCK_SIZE; + fp->uncompressed_block = malloc(MAX_BLOCK_SIZE); + fp->compressed_block_size = MAX_BLOCK_SIZE; + fp->compressed_block = malloc(MAX_BLOCK_SIZE); + fp->cache_size = 0; + fp->cache = kh_init(cache); + return fp; +} + +static +BGZF* +open_read(int fd) +{ +#ifdef _USE_KNETFILE + knetFile *file = knet_dopen(fd, "r"); +#else + FILE* file = fdopen(fd, "r"); +#endif + BGZF* fp; + if (file == 0) return 0; + fp = bgzf_read_init(); + fp->file_descriptor = fd; + fp->open_mode = 'r'; +#ifdef _USE_KNETFILE + fp->x.fpr = file; +#else + fp->file = file; +#endif + return fp; +} + +static +BGZF* +open_write(int fd, int compress_level) // compress_level==-1 for the default level +{ + FILE* file = fdopen(fd, "w"); + BGZF* fp; + if (file == 0) return 0; + fp = malloc(sizeof(BGZF)); + fp->file_descriptor = fd; + fp->open_mode = 'w'; + fp->owned_file = 0; + fp->compress_level = compress_level < 0? Z_DEFAULT_COMPRESSION : compress_level; // Z_DEFAULT_COMPRESSION==-1 + if (fp->compress_level > 9) fp->compress_level = Z_DEFAULT_COMPRESSION; +#ifdef _USE_KNETFILE + fp->x.fpw = file; +#else + fp->file = file; +#endif + fp->uncompressed_block_size = DEFAULT_BLOCK_SIZE; + fp->uncompressed_block = NULL; + fp->compressed_block_size = MAX_BLOCK_SIZE; + fp->compressed_block = malloc(MAX_BLOCK_SIZE); + fp->block_address = 0; + fp->block_offset = 0; + fp->block_length = 0; + fp->error = NULL; + return fp; +} + +BGZF* +bgzf_open(const char* __restrict path, const char* __restrict mode) +{ + BGZF* fp = NULL; + if (strchr(mode, 'r') || strchr(mode, 'R')) { /* The reading mode is preferred. */ +#ifdef _USE_KNETFILE + knetFile *file = knet_open(path, mode); + if (file == 0) return 0; + fp = bgzf_read_init(); + fp->file_descriptor = -1; + fp->open_mode = 'r'; + fp->x.fpr = file; +#else + int fd, oflag = O_RDONLY; +#ifdef _WIN32 + oflag |= O_BINARY; +#endif + fd = open(path, oflag); + if (fd == -1) return 0; + fp = open_read(fd); +#endif + } else if (strchr(mode, 'w') || strchr(mode, 'W')) { + int fd, compress_level = -1, oflag = O_WRONLY | O_CREAT | O_TRUNC; +#ifdef _WIN32 + oflag |= O_BINARY; +#endif + fd = open(path, oflag, 0666); + if (fd == -1) return 0; + { // set compress_level + int i; + for (i = 0; mode[i]; ++i) + if (mode[i] >= '0' && mode[i] <= '9') break; + if (mode[i]) compress_level = (int)mode[i] - '0'; + if (strchr(mode, 'u')) compress_level = 0; + } + fp = open_write(fd, compress_level); + } + if (fp != NULL) fp->owned_file = 1; + return fp; +} + +BGZF* +bgzf_fdopen(int fd, const char * __restrict mode) +{ + if (fd == -1) return 0; + if (mode[0] == 'r' || mode[0] == 'R') { + return open_read(fd); + } else if (mode[0] == 'w' || mode[0] == 'W') { + int i, compress_level = -1; + for (i = 0; mode[i]; ++i) + if (mode[i] >= '0' && mode[i] <= '9') break; + if (mode[i]) compress_level = (int)mode[i] - '0'; + if (strchr(mode, 'u')) compress_level = 0; + return open_write(fd, compress_level); + } else { + return NULL; + } +} + +static +int +deflate_block(BGZF* fp, int block_length) +{ + // Deflate the block in fp->uncompressed_block into fp->compressed_block. + // Also adds an extra field that stores the compressed block length. + + bgzf_byte_t* buffer = fp->compressed_block; + int buffer_size = fp->compressed_block_size; + + // Init gzip header + buffer[0] = GZIP_ID1; + buffer[1] = GZIP_ID2; + buffer[2] = CM_DEFLATE; + buffer[3] = FLG_FEXTRA; + buffer[4] = 0; // mtime + buffer[5] = 0; + buffer[6] = 0; + buffer[7] = 0; + buffer[8] = 0; + buffer[9] = OS_UNKNOWN; + buffer[10] = BGZF_XLEN; + buffer[11] = 0; + buffer[12] = BGZF_ID1; + buffer[13] = BGZF_ID2; + buffer[14] = BGZF_LEN; + buffer[15] = 0; + buffer[16] = 0; // placeholder for block length + buffer[17] = 0; + + // loop to retry for blocks that do not compress enough + int input_length = block_length; + int compressed_length = 0; + while (1) { + z_stream zs; + zs.zalloc = NULL; + zs.zfree = NULL; + zs.next_in = fp->uncompressed_block; + zs.avail_in = input_length; + zs.next_out = (void*)&buffer[BLOCK_HEADER_LENGTH]; + zs.avail_out = buffer_size - BLOCK_HEADER_LENGTH - BLOCK_FOOTER_LENGTH; + + int status = deflateInit2(&zs, fp->compress_level, Z_DEFLATED, + GZIP_WINDOW_BITS, Z_DEFAULT_MEM_LEVEL, Z_DEFAULT_STRATEGY); + if (status != Z_OK) { + report_error(fp, "deflate init failed"); + return -1; + } + status = deflate(&zs, Z_FINISH); + if (status != Z_STREAM_END) { + deflateEnd(&zs); + if (status == Z_OK) { + // Not enough space in buffer. + // Can happen in the rare case the input doesn't compress enough. + // Reduce the amount of input until it fits. + input_length -= 1024; + if (input_length <= 0) { + // should never happen + report_error(fp, "input reduction failed"); + return -1; + } + continue; + } + report_error(fp, "deflate failed"); + return -1; + } + status = deflateEnd(&zs); + if (status != Z_OK) { + report_error(fp, "deflate end failed"); + return -1; + } + compressed_length = zs.total_out; + compressed_length += BLOCK_HEADER_LENGTH + BLOCK_FOOTER_LENGTH; + if (compressed_length > MAX_BLOCK_SIZE) { + // should never happen + report_error(fp, "deflate overflow"); + return -1; + } + break; + } + + packInt16((uint8_t*)&buffer[16], compressed_length-1); + uint32_t crc = crc32(0L, NULL, 0L); + crc = crc32(crc, fp->uncompressed_block, input_length); + packInt32((uint8_t*)&buffer[compressed_length-8], crc); + packInt32((uint8_t*)&buffer[compressed_length-4], input_length); + + int remaining = block_length - input_length; + if (remaining > 0) { + if (remaining > input_length) { + // should never happen (check so we can use memcpy) + report_error(fp, "remainder too large"); + return -1; + } + memcpy(fp->uncompressed_block, + fp->uncompressed_block + input_length, + remaining); + } + fp->block_offset = remaining; + return compressed_length; +} + +static +int +inflate_block(BGZF* fp, int block_length) +{ + // Inflate the block in fp->compressed_block into fp->uncompressed_block + + z_stream zs; + int status; + zs.zalloc = NULL; + zs.zfree = NULL; + zs.next_in = fp->compressed_block + 18; + zs.avail_in = block_length - 16; + zs.next_out = fp->uncompressed_block; + zs.avail_out = fp->uncompressed_block_size; + + status = inflateInit2(&zs, GZIP_WINDOW_BITS); + if (status != Z_OK) { + report_error(fp, "inflate init failed"); + return -1; + } + status = inflate(&zs, Z_FINISH); + if (status != Z_STREAM_END) { + inflateEnd(&zs); + report_error(fp, "inflate failed"); + return -1; + } + status = inflateEnd(&zs); + if (status != Z_OK) { + report_error(fp, "inflate failed"); + return -1; + } + return zs.total_out; +} + +static +int +check_header(const bgzf_byte_t* header) +{ + return (header[0] == GZIP_ID1 && + header[1] == (bgzf_byte_t) GZIP_ID2 && + header[2] == Z_DEFLATED && + (header[3] & FLG_FEXTRA) != 0 && + unpackInt16((uint8_t*)&header[10]) == BGZF_XLEN && + header[12] == BGZF_ID1 && + header[13] == BGZF_ID2 && + unpackInt16((uint8_t*)&header[14]) == BGZF_LEN); +} + +static void free_cache(BGZF *fp) +{ + khint_t k; + khash_t(cache) *h = (khash_t(cache)*)fp->cache; + if (fp->open_mode != 'r') return; + for (k = kh_begin(h); k < kh_end(h); ++k) + if (kh_exist(h, k)) free(kh_val(h, k).block); + kh_destroy(cache, h); +} + +static int load_block_from_cache(BGZF *fp, int64_t block_address) +{ + khint_t k; + cache_t *p; + khash_t(cache) *h = (khash_t(cache)*)fp->cache; + k = kh_get(cache, h, block_address); + if (k == kh_end(h)) return 0; + p = &kh_val(h, k); + if (fp->block_length != 0) fp->block_offset = 0; + fp->block_address = block_address; + fp->block_length = p->size; + memcpy(fp->uncompressed_block, p->block, MAX_BLOCK_SIZE); +#ifdef _USE_KNETFILE + knet_seek(fp->x.fpr, p->end_offset, SEEK_SET); +#else + fseeko(fp->file, p->end_offset, SEEK_SET); +#endif + return p->size; +} + +static void cache_block(BGZF *fp, int size) +{ + int ret; + khint_t k; + cache_t *p; + khash_t(cache) *h = (khash_t(cache)*)fp->cache; + if (MAX_BLOCK_SIZE >= fp->cache_size) return; + if ((kh_size(h) + 1) * MAX_BLOCK_SIZE > fp->cache_size) { + /* A better way would be to remove the oldest block in the + * cache, but here we remove a random one for simplicity. This + * should not have a big impact on performance. */ + for (k = kh_begin(h); k < kh_end(h); ++k) + if (kh_exist(h, k)) break; + if (k < kh_end(h)) { + free(kh_val(h, k).block); + kh_del(cache, h, k); + } + } + k = kh_put(cache, h, fp->block_address, &ret); + if (ret == 0) return; // if this happens, a bug! + p = &kh_val(h, k); + p->size = fp->block_length; + p->end_offset = fp->block_address + size; + p->block = malloc(MAX_BLOCK_SIZE); + memcpy(kh_val(h, k).block, fp->uncompressed_block, MAX_BLOCK_SIZE); +} + +int +bgzf_read_block(BGZF* fp) +{ + bgzf_byte_t header[BLOCK_HEADER_LENGTH]; + int count, size = 0, block_length, remaining; +#ifdef _USE_KNETFILE + int64_t block_address = knet_tell(fp->x.fpr); + if (load_block_from_cache(fp, block_address)) return 0; + count = knet_read(fp->x.fpr, header, sizeof(header)); +#else + int64_t block_address = ftello(fp->file); + if (load_block_from_cache(fp, block_address)) return 0; + count = fread(header, 1, sizeof(header), fp->file); +#endif + if (count == 0) { + fp->block_length = 0; + return 0; + } + size = count; + if (count != sizeof(header)) { + report_error(fp, "read failed"); + return -1; + } + if (!check_header(header)) { + report_error(fp, "invalid block header"); + return -1; + } + block_length = unpackInt16((uint8_t*)&header[16]) + 1; + bgzf_byte_t* compressed_block = (bgzf_byte_t*) fp->compressed_block; + memcpy(compressed_block, header, BLOCK_HEADER_LENGTH); + remaining = block_length - BLOCK_HEADER_LENGTH; +#ifdef _USE_KNETFILE + count = knet_read(fp->x.fpr, &compressed_block[BLOCK_HEADER_LENGTH], remaining); +#else + count = fread(&compressed_block[BLOCK_HEADER_LENGTH], 1, remaining, fp->file); +#endif + if (count != remaining) { + report_error(fp, "read failed"); + return -1; + } + size += count; + count = inflate_block(fp, block_length); + if (count < 0) return -1; + if (fp->block_length != 0) { + // Do not reset offset if this read follows a seek. + fp->block_offset = 0; + } + fp->block_address = block_address; + fp->block_length = count; + cache_block(fp, size); + return 0; +} + +int +bgzf_read(BGZF* fp, void* data, int length) +{ + if (length <= 0) { + return 0; + } + if (fp->open_mode != 'r') { + report_error(fp, "file not open for reading"); + return -1; + } + + int bytes_read = 0; + bgzf_byte_t* output = data; + while (bytes_read < length) { + int copy_length, available = fp->block_length - fp->block_offset; + bgzf_byte_t *buffer; + if (available <= 0) { + if (bgzf_read_block(fp) != 0) { + return -1; + } + available = fp->block_length - fp->block_offset; + if (available <= 0) { + break; + } + } + copy_length = bgzf_min(length-bytes_read, available); + buffer = fp->uncompressed_block; + memcpy(output, buffer + fp->block_offset, copy_length); + fp->block_offset += copy_length; + output += copy_length; + bytes_read += copy_length; + } + if (fp->block_offset == fp->block_length) { +#ifdef _USE_KNETFILE + fp->block_address = knet_tell(fp->x.fpr); +#else + fp->block_address = ftello(fp->file); +#endif + fp->block_offset = 0; + fp->block_length = 0; + } + return bytes_read; +} + +int bgzf_flush(BGZF* fp) +{ + while (fp->block_offset > 0) { + int count, block_length; + block_length = deflate_block(fp, fp->block_offset); + if (block_length < 0) return -1; +#ifdef _USE_KNETFILE + count = fwrite(fp->compressed_block, 1, block_length, fp->x.fpw); +#else + count = fwrite(fp->compressed_block, 1, block_length, fp->file); +#endif + if (count != block_length) { + report_error(fp, "write failed"); + return -1; + } + fp->block_address += block_length; + } + return 0; +} + +int bgzf_flush_try(BGZF *fp, int size) +{ + if (fp->block_offset + size > fp->uncompressed_block_size) + return bgzf_flush(fp); + return -1; +} + +int bgzf_write(BGZF* fp, const void* data, int length) +{ + const bgzf_byte_t *input = data; + int block_length, bytes_written; + if (fp->open_mode != 'w') { + report_error(fp, "file not open for writing"); + return -1; + } + + if (fp->uncompressed_block == NULL) + fp->uncompressed_block = malloc(fp->uncompressed_block_size); + + input = data; + block_length = fp->uncompressed_block_size; + bytes_written = 0; + while (bytes_written < length) { + int copy_length = bgzf_min(block_length - fp->block_offset, length - bytes_written); + bgzf_byte_t* buffer = fp->uncompressed_block; + memcpy(buffer + fp->block_offset, input, copy_length); + fp->block_offset += copy_length; + input += copy_length; + bytes_written += copy_length; + if (fp->block_offset == block_length) { + if (bgzf_flush(fp) != 0) { + break; + } + } + } + return bytes_written; +} + +int bgzf_close(BGZF* fp) +{ + if (fp->open_mode == 'w') { + if (bgzf_flush(fp) != 0) return -1; + { // add an empty block + int count, block_length = deflate_block(fp, 0); +#ifdef _USE_KNETFILE + count = fwrite(fp->compressed_block, 1, block_length, fp->x.fpw); +#else + count = fwrite(fp->compressed_block, 1, block_length, fp->file); +#endif + } +#ifdef _USE_KNETFILE + if (fflush(fp->x.fpw) != 0) { +#else + if (fflush(fp->file) != 0) { +#endif + report_error(fp, "flush failed"); + return -1; + } + } + if (fp->owned_file) { +#ifdef _USE_KNETFILE + int ret; + if (fp->open_mode == 'w') ret = fclose(fp->x.fpw); + else ret = knet_close(fp->x.fpr); + if (ret != 0) return -1; +#else + if (fclose(fp->file) != 0) return -1; +#endif + } + free(fp->uncompressed_block); + free(fp->compressed_block); + free_cache(fp); + free(fp); + return 0; +} + +void bgzf_set_cache_size(BGZF *fp, int cache_size) +{ + if (fp) fp->cache_size = cache_size; +} + +int bgzf_check_EOF(BGZF *fp) +{ + static uint8_t magic[28] = "\037\213\010\4\0\0\0\0\0\377\6\0\102\103\2\0\033\0\3\0\0\0\0\0\0\0\0\0"; + uint8_t buf[28]; + off_t offset; +#ifdef _USE_KNETFILE + offset = knet_tell(fp->x.fpr); + if (knet_seek(fp->x.fpr, -28, SEEK_END) != 0) return -1; + knet_read(fp->x.fpr, buf, 28); + knet_seek(fp->x.fpr, offset, SEEK_SET); +#else + offset = ftello(fp->file); + if (fseeko(fp->file, -28, SEEK_END) != 0) return -1; + fread(buf, 1, 28, fp->file); + fseeko(fp->file, offset, SEEK_SET); +#endif + return (memcmp(magic, buf, 28) == 0)? 1 : 0; +} + +int64_t bgzf_seek(BGZF* fp, int64_t pos, int where) +{ + int block_offset; + int64_t block_address; + + if (fp->open_mode != 'r') { + report_error(fp, "file not open for read"); + return -1; + } + if (where != SEEK_SET) { + report_error(fp, "unimplemented seek option"); + return -1; + } + block_offset = pos & 0xFFFF; + block_address = (pos >> 16) & 0xFFFFFFFFFFFFLL; +#ifdef _USE_KNETFILE + if (knet_seek(fp->x.fpr, block_address, SEEK_SET) != 0) { +#else + if (fseeko(fp->file, block_address, SEEK_SET) != 0) { +#endif + report_error(fp, "seek failed"); + return -1; + } + fp->block_length = 0; // indicates current block is not loaded + fp->block_address = block_address; + fp->block_offset = block_offset; + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bgzf.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,157 @@ +/* The MIT License + + Copyright (c) 2008 Broad Institute / Massachusetts Institute of Technology + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef __BGZF_H +#define __BGZF_H + +#include <stdint.h> +#include <stdio.h> +#include <zlib.h> +#ifdef _USE_KNETFILE +#include "knetfile.h" +#endif + +//typedef int8_t bool; + +typedef struct { + int file_descriptor; + char open_mode; // 'r' or 'w' + int16_t owned_file, compress_level; +#ifdef _USE_KNETFILE + union { + knetFile *fpr; + FILE *fpw; + } x; +#else + FILE* file; +#endif + int uncompressed_block_size; + int compressed_block_size; + void* uncompressed_block; + void* compressed_block; + int64_t block_address; + int block_length; + int block_offset; + int cache_size; + const char* error; + void *cache; // a pointer to a hash table +} BGZF; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Open an existing file descriptor for reading or writing. + * Mode must be either "r" or "w". + * A subsequent bgzf_close will not close the file descriptor. + * Returns null on error. + */ +BGZF* bgzf_fdopen(int fd, const char* __restrict mode); + +/* + * Open the specified file for reading or writing. + * Mode must be either "r" or "w". + * Returns null on error. + */ +BGZF* bgzf_open(const char* path, const char* __restrict mode); + +/* + * Close the BGZ file and free all associated resources. + * Does not close the underlying file descriptor if created with bgzf_fdopen. + * Returns zero on success, -1 on error. + */ +int bgzf_close(BGZF* fp); + +/* + * Read up to length bytes from the file storing into data. + * Returns the number of bytes actually read. + * Returns zero on end of file. + * Returns -1 on error. + */ +int bgzf_read(BGZF* fp, void* data, int length); + +/* + * Write length bytes from data to the file. + * Returns the number of bytes written. + * Returns -1 on error. + */ +int bgzf_write(BGZF* fp, const void* data, int length); + +/* + * Return a virtual file pointer to the current location in the file. + * No interpetation of the value should be made, other than a subsequent + * call to bgzf_seek can be used to position the file at the same point. + * Return value is non-negative on success. + * Returns -1 on error. + */ +#define bgzf_tell(fp) ((fp->block_address << 16) | (fp->block_offset & 0xFFFF)) + +/* + * Set the file to read from the location specified by pos, which must + * be a value previously returned by bgzf_tell for this file (but not + * necessarily one returned by this file handle). + * The where argument must be SEEK_SET. + * Seeking on a file opened for write is not supported. + * Returns zero on success, -1 on error. + */ +int64_t bgzf_seek(BGZF* fp, int64_t pos, int where); + +/* + * Set the cache size. Zero to disable. By default, caching is + * disabled. The recommended cache size for frequent random access is + * about 8M bytes. + */ +void bgzf_set_cache_size(BGZF *fp, int cache_size); + +int bgzf_check_EOF(BGZF *fp); +int bgzf_read_block(BGZF* fp); +int bgzf_flush(BGZF* fp); +int bgzf_flush_try(BGZF *fp, int size); +int bgzf_check_bgzf(const char *fn); + +#ifdef __cplusplus +} +#endif + +static inline int bgzf_getc(BGZF *fp) +{ + int c; + if (fp->block_offset >= fp->block_length) { + if (bgzf_read_block(fp) != 0) return -2; /* error */ + if (fp->block_length == 0) return -1; /* end-of-file */ + } + c = ((unsigned char*)fp->uncompressed_block)[fp->block_offset++]; + if (fp->block_offset == fp->block_length) { +#ifdef _USE_KNETFILE + fp->block_address = knet_tell(fp->x.fpr); +#else + fp->block_address = ftello(fp->file); +#endif + fp->block_offset = 0; + fp->block_length = 0; + } + return c; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/bgzip.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,206 @@ +/* The MIT License + + Copyright (c) 2008 Broad Institute / Massachusetts Institute of Technology + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <sys/select.h> +#include <sys/stat.h> +#include "bgzf.h" + +static const int WINDOW_SIZE = 64 * 1024; + +static int bgzip_main_usage() +{ + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: bgzip [options] [file] ...\n\n"); + fprintf(stderr, "Options: -c write on standard output, keep original files unchanged\n"); + fprintf(stderr, " -d decompress\n"); + fprintf(stderr, " -f overwrite files without asking\n"); + fprintf(stderr, " -b INT decompress at virtual file pointer INT\n"); + fprintf(stderr, " -s INT decompress INT bytes in the uncompressed file\n"); + fprintf(stderr, " -h give this help\n"); + fprintf(stderr, "\n"); + return 1; +} + +static int write_open(const char *fn, int is_forced) +{ + int fd = -1; + char c; + if (!is_forced) { + if ((fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0666)) < 0 && errno == EEXIST) { + fprintf(stderr, "[bgzip] %s already exists; do you wish to overwrite (y or n)? ", fn); + scanf("%c", &c); + if (c != 'Y' && c != 'y') { + fprintf(stderr, "[bgzip] not overwritten\n"); + exit(1); + } + } + } + if (fd < 0) { + if ((fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) { + fprintf(stderr, "[bgzip] %s: Fail to write\n", fn); + exit(1); + } + } + return fd; +} + +static void fail(BGZF* fp) +{ + fprintf(stderr, "Error: %s\n", fp->error); + exit(1); +} + +int main(int argc, char **argv) +{ + int c, compress, pstdout, is_forced; + BGZF *fp; + void *buffer; + long start, end, size; + + compress = 1; pstdout = 0; start = 0; size = -1; end = -1; is_forced = 0; + while((c = getopt(argc, argv, "cdhfb:s:")) >= 0){ + switch(c){ + case 'h': return bgzip_main_usage(); + case 'd': compress = 0; break; + case 'c': pstdout = 1; break; + case 'b': start = atol(optarg); break; + case 's': size = atol(optarg); break; + case 'f': is_forced = 1; break; + } + } + if (size >= 0) end = start + size; + if (end >= 0 && end < start) { + fprintf(stderr, "[bgzip] Illegal region: [%ld, %ld]\n", start, end); + return 1; + } + if (compress == 1) { + struct stat sbuf; + int f_src = fileno(stdin); + int f_dst = fileno(stdout); + + if ( argc>optind ) + { + if ( stat(argv[optind],&sbuf)<0 ) + { + fprintf(stderr, "[bgzip] %s: %s\n", strerror(errno), argv[optind]); + return 1; + } + + if ((f_src = open(argv[optind], O_RDONLY)) < 0) { + fprintf(stderr, "[bgzip] %s: %s\n", strerror(errno), argv[optind]); + return 1; + } + + if (pstdout) + f_dst = fileno(stdout); + else + { + char *name = malloc(strlen(argv[optind]) + 5); + strcpy(name, argv[optind]); + strcat(name, ".gz"); + f_dst = write_open(name, is_forced); + if (f_dst < 0) return 1; + free(name); + } + } + else if (!pstdout && isatty(fileno((FILE *)stdout)) ) + return bgzip_main_usage(); + + fp = bgzf_fdopen(f_dst, "w"); + buffer = malloc(WINDOW_SIZE); + while ((c = read(f_src, buffer, WINDOW_SIZE)) > 0) + if (bgzf_write(fp, buffer, c) < 0) fail(fp); + // f_dst will be closed here + if (bgzf_close(fp) < 0) fail(fp); + if (argc > optind && !pstdout) unlink(argv[optind]); + free(buffer); + close(f_src); + return 0; + } else { + struct stat sbuf; + int f_dst; + + if ( argc>optind ) + { + if ( stat(argv[optind],&sbuf)<0 ) + { + fprintf(stderr, "[bgzip] %s: %s\n", strerror(errno), argv[optind]); + return 1; + } + char *name; + int len = strlen(argv[optind]); + if ( strcmp(argv[optind]+len-3,".gz") ) + { + fprintf(stderr, "[bgzip] %s: unknown suffix -- ignored\n", argv[optind]); + return 1; + } + fp = bgzf_open(argv[optind], "r"); + if (fp == NULL) { + fprintf(stderr, "[bgzip] Could not open file: %s\n", argv[optind]); + return 1; + } + + if (pstdout) { + f_dst = fileno(stdout); + } + else { + name = strdup(argv[optind]); + name[strlen(name) - 3] = '\0'; + f_dst = write_open(name, is_forced); + free(name); + } + } + else if (!pstdout && isatty(fileno((FILE *)stdin)) ) + return bgzip_main_usage(); + else + { + f_dst = fileno(stdout); + fp = bgzf_fdopen(fileno(stdin), "r"); + if (fp == NULL) { + fprintf(stderr, "[bgzip] Could not read from stdin: %s\n", strerror(errno)); + return 1; + } + } + buffer = malloc(WINDOW_SIZE); + if (bgzf_seek(fp, start, SEEK_SET) < 0) fail(fp); + while (1) { + if (end < 0) c = bgzf_read(fp, buffer, WINDOW_SIZE); + else c = bgzf_read(fp, buffer, (end - start > WINDOW_SIZE)? WINDOW_SIZE:(end - start)); + if (c == 0) break; + if (c < 0) fail(fp); + start += c; + write(f_dst, buffer, c); + if (end >= 0 && start >= end) break; + } + free(buffer); + if (bgzf_close(fp) < 0) fail(fp); + if (!pstdout) unlink(argv[optind]); + return 0; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/cut_target.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,193 @@ +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include "bam.h" +#include "errmod.h" +#include "faidx.h" + +#define ERR_DEP 0.83f + +typedef struct { + int e[2][3], p[2][2]; +} score_param_t; + +/* Note that although the two matrics have 10 parameters in total, only 4 + * (probably 3) are free. Changing the scoring matrices in a sort of symmetric + * way will not change the result. */ +static score_param_t g_param = { {{0,0,0},{-4,1,6}}, {{0,-14000}, {0,0}} }; + +typedef struct { + int min_baseQ, tid, max_bases; + uint16_t *bases; + bamFile fp; + bam_header_t *h; + char *ref; + faidx_t *fai; + errmod_t *em; +} ct_t; + +static uint16_t gencns(ct_t *g, int n, const bam_pileup1_t *plp) +{ + int i, j, ret, tmp, k, sum[4], qual; + float q[16]; + if (n > g->max_bases) { // enlarge g->bases + g->max_bases = n; + kroundup32(g->max_bases); + g->bases = realloc(g->bases, g->max_bases * 2); + } + for (i = k = 0; i < n; ++i) { + const bam_pileup1_t *p = plp + i; + uint8_t *seq; + int q, baseQ, b; + if (p->is_refskip || p->is_del) continue; + baseQ = bam1_qual(p->b)[p->qpos]; + if (baseQ < g->min_baseQ) continue; + seq = bam1_seq(p->b); + b = bam_nt16_nt4_table[bam1_seqi(seq, p->qpos)]; + if (b > 3) continue; + q = baseQ < p->b->core.qual? baseQ : p->b->core.qual; + if (q < 4) q = 4; + if (q > 63) q = 63; + g->bases[k++] = q<<5 | bam1_strand(p->b)<<4 | b; + } + if (k == 0) return 0; + errmod_cal(g->em, k, 4, g->bases, q); + for (i = 0; i < 4; ++i) sum[i] = (int)(q[i<<2|i] + .499) << 2 | i; + for (i = 1; i < 4; ++i) // insertion sort + for (j = i; j > 0 && sum[j] < sum[j-1]; --j) + tmp = sum[j], sum[j] = sum[j-1], sum[j-1] = tmp; + qual = (sum[1]>>2) - (sum[0]>>2); + k = k < 256? k : 255; + ret = (qual < 63? qual : 63) << 2 | (sum[0]&3); + return ret<<8|k; +} + +static void process_cns(bam_header_t *h, int tid, int l, uint16_t *cns) +{ + int i, f[2][2], *prev, *curr, *swap_tmp, s; + uint8_t *b; // backtrack array + b = calloc(l, 1); + f[0][0] = f[0][1] = 0; + prev = f[0]; curr = f[1]; + // fill the backtrack matrix + for (i = 0; i < l; ++i) { + int c = (cns[i] == 0)? 0 : (cns[i]>>8 == 0)? 1 : 2; + int tmp0, tmp1; + // compute f[0] + tmp0 = prev[0] + g_param.e[0][c] + g_param.p[0][0]; // (s[i+1],s[i])=(0,0) + tmp1 = prev[1] + g_param.e[0][c] + g_param.p[1][0]; // (0,1) + if (tmp0 > tmp1) curr[0] = tmp0, b[i] = 0; + else curr[0] = tmp1, b[i] = 1; + // compute f[1] + tmp0 = prev[0] + g_param.e[1][c] + g_param.p[0][1]; // (s[i+1],s[i])=(1,0) + tmp1 = prev[1] + g_param.e[1][c] + g_param.p[1][1]; // (1,1) + if (tmp0 > tmp1) curr[1] = tmp0, b[i] |= 0<<1; + else curr[1] = tmp1, b[i] |= 1<<1; + // swap + swap_tmp = prev; prev = curr; curr = swap_tmp; + } + // backtrack + s = prev[0] > prev[1]? 0 : 1; + for (i = l - 1; i > 0; --i) { + b[i] |= s<<2; + s = b[i]>>s&1; + } + // print + for (i = 0, s = -1; i <= l; ++i) { + if (i == l || ((b[i]>>2&3) == 0 && s >= 0)) { + if (s >= 0) { + int j; + printf("%s:%d-%d\t0\t%s\t%d\t60\t%dM\t*\t0\t0\t", h->target_name[tid], s+1, i, h->target_name[tid], s+1, i-s); + for (j = s; j < i; ++j) { + int c = cns[j]>>8; + if (c == 0) putchar('N'); + else putchar("ACGT"[c&3]); + } + putchar('\t'); + for (j = s; j < i; ++j) + putchar(33 + (cns[j]>>8>>2)); + putchar('\n'); + } + //if (s >= 0) printf("%s\t%d\t%d\t%d\n", h->target_name[tid], s, i, i - s); + s = -1; + } else if ((b[i]>>2&3) && s < 0) s = i; + } + free(b); +} + +static int read_aln(void *data, bam1_t *b) +{ + extern int bam_prob_realn_core(bam1_t *b, const char *ref, int flag); + ct_t *g = (ct_t*)data; + int ret, len; + ret = bam_read1(g->fp, b); + if (ret >= 0 && g->fai && b->core.tid >= 0 && (b->core.flag&4) == 0) { + if (b->core.tid != g->tid) { // then load the sequence + free(g->ref); + g->ref = fai_fetch(g->fai, g->h->target_name[b->core.tid], &len); + g->tid = b->core.tid; + } + bam_prob_realn_core(b, g->ref, 1<<1|1); + } + return ret; +} + +int main_cut_target(int argc, char *argv[]) +{ + int c, tid, pos, n, lasttid = -1, lastpos = -1, l, max_l; + const bam_pileup1_t *p; + bam_plp_t plp; + uint16_t *cns; + ct_t g; + + memset(&g, 0, sizeof(ct_t)); + g.min_baseQ = 13; g.tid = -1; + while ((c = getopt(argc, argv, "f:Q:i:o:0:1:2:")) >= 0) { + switch (c) { + case 'Q': g.min_baseQ = atoi(optarg); break; // quality cutoff + case 'i': g_param.p[0][1] = -atoi(optarg); break; // 0->1 transition (in) PENALTY + case '0': g_param.e[1][0] = atoi(optarg); break; // emission SCORE + case '1': g_param.e[1][1] = atoi(optarg); break; + case '2': g_param.e[1][2] = atoi(optarg); break; + case 'f': g.fai = fai_load(optarg); + if (g.fai == 0) fprintf(stderr, "[%s] fail to load the fasta index.\n", __func__); + break; + } + } + if (argc == optind) { + fprintf(stderr, "Usage: samtools targetcut [-Q minQ] [-i inPen] [-0 em0] [-1 em1] [-2 em2] [-f ref] <in.bam>\n"); + return 1; + } + l = max_l = 0; cns = 0; + g.fp = strcmp(argv[optind], "-")? bam_open(argv[optind], "r") : bam_dopen(fileno(stdin), "r"); + g.h = bam_header_read(g.fp); + g.em = errmod_init(1 - ERR_DEP); + plp = bam_plp_init(read_aln, &g); + while ((p = bam_plp_auto(plp, &tid, &pos, &n)) != 0) { + if (tid < 0) break; + if (tid != lasttid) { // change of chromosome + if (cns) process_cns(g.h, lasttid, l, cns); + if (max_l < g.h->target_len[tid]) { + max_l = g.h->target_len[tid]; + kroundup32(max_l); + cns = realloc(cns, max_l * 2); + } + l = g.h->target_len[tid]; + memset(cns, 0, max_l * 2); + lasttid = tid; + } + cns[pos] = gencns(&g, n, p); + lastpos = pos; + } + process_cns(g.h, lasttid, l, cns); + free(cns); + bam_header_destroy(g.h); + bam_plp_destroy(plp); + bam_close(g.fp); + if (g.fai) { + fai_destroy(g.fai); free(g.ref); + } + errmod_destroy(g.em); + free(g.bases); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/errmod.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,130 @@ +#include <math.h> +#include "errmod.h" +#include "ksort.h" +KSORT_INIT_GENERIC(uint16_t) + +typedef struct __errmod_coef_t { + double *fk, *beta, *lhet; +} errmod_coef_t; + +typedef struct { + double fsum[16], bsum[16]; + uint32_t c[16]; +} call_aux_t; + +static errmod_coef_t *cal_coef(double depcorr, double eta) +{ + int k, n, q; + long double sum, sum1; + double *lC; + errmod_coef_t *ec; + + ec = calloc(1, sizeof(errmod_coef_t)); + // initialize ->fk + ec->fk = (double*)calloc(256, sizeof(double)); + ec->fk[0] = 1.0; + for (n = 1; n != 256; ++n) + ec->fk[n] = pow(1. - depcorr, n) * (1.0 - eta) + eta; + // initialize ->coef + ec->beta = (double*)calloc(256 * 256 * 64, sizeof(double)); + lC = (double*)calloc(256 * 256, sizeof(double)); + for (n = 1; n != 256; ++n) { + double lgn = lgamma(n+1); + for (k = 1; k <= n; ++k) + lC[n<<8|k] = lgn - lgamma(k+1) - lgamma(n-k+1); + } + for (q = 1; q != 64; ++q) { + double e = pow(10.0, -q/10.0); + double le = log(e); + double le1 = log(1.0 - e); + for (n = 1; n <= 255; ++n) { + double *beta = ec->beta + (q<<16|n<<8); + sum1 = sum = 0.0; + for (k = n; k >= 0; --k, sum1 = sum) { + sum = sum1 + expl(lC[n<<8|k] + k*le + (n-k)*le1); + beta[k] = -10. / M_LN10 * logl(sum1 / sum); + } + } + } + // initialize ->lhet + ec->lhet = (double*)calloc(256 * 256, sizeof(double)); + for (n = 0; n < 256; ++n) + for (k = 0; k < 256; ++k) + ec->lhet[n<<8|k] = lC[n<<8|k] - M_LN2 * n; + free(lC); + return ec; +} + +errmod_t *errmod_init(float depcorr) +{ + errmod_t *em; + em = (errmod_t*)calloc(1, sizeof(errmod_t)); + em->depcorr = depcorr; + em->coef = cal_coef(depcorr, 0.03); + return em; +} + +void errmod_destroy(errmod_t *em) +{ + if (em == 0) return; + free(em->coef->lhet); free(em->coef->fk); free(em->coef->beta); + free(em->coef); free(em); +} +// qual:6, strand:1, base:4 +int errmod_cal(const errmod_t *em, int n, int m, uint16_t *bases, float *q) +{ + call_aux_t aux; + int i, j, k, w[32]; + + if (m > m) return -1; + memset(q, 0, m * m * sizeof(float)); + if (n == 0) return 0; + // calculate aux.esum and aux.fsum + if (n > 255) { // then sample 255 bases + ks_shuffle(uint16_t, n, bases); + n = 255; + } + ks_introsort(uint16_t, n, bases); + memset(w, 0, 32 * sizeof(int)); + memset(&aux, 0, sizeof(call_aux_t)); + for (j = n - 1; j >= 0; --j) { // calculate esum and fsum + uint16_t b = bases[j]; + int q = b>>5 < 4? 4 : b>>5; + if (q > 63) q = 63; + k = b&0x1f; + aux.fsum[k&0xf] += em->coef->fk[w[k]]; + aux.bsum[k&0xf] += em->coef->fk[w[k]] * em->coef->beta[q<<16|n<<8|aux.c[k&0xf]]; + ++aux.c[k&0xf]; + ++w[k]; + } + // generate likelihood + for (j = 0; j != m; ++j) { + float tmp1, tmp3; + int tmp2, bar_e; + // homozygous + for (k = 0, tmp1 = tmp3 = 0.0, tmp2 = 0; k != m; ++k) { + if (k == j) continue; + tmp1 += aux.bsum[k]; tmp2 += aux.c[k]; tmp3 += aux.fsum[k]; + } + if (tmp2) { + bar_e = (int)(tmp1 / tmp3 + 0.499); + if (bar_e > 63) bar_e = 63; + q[j*m+j] = tmp1; + } + // heterozygous + for (k = j + 1; k < m; ++k) { + int cjk = aux.c[j] + aux.c[k]; + for (i = 0, tmp2 = 0, tmp1 = tmp3 = 0.0; i < m; ++i) { + if (i == j || i == k) continue; + tmp1 += aux.bsum[i]; tmp2 += aux.c[i]; tmp3 += aux.fsum[i]; + } + if (tmp2) { + bar_e = (int)(tmp1 / tmp3 + 0.499); + if (bar_e > 63) bar_e = 63; + q[j*m+k] = q[k*m+j] = -4.343 * em->coef->lhet[cjk<<8|aux.c[k]] + tmp1; + } else q[j*m+k] = q[k*m+j] = -4.343 * em->coef->lhet[cjk<<8|aux.c[k]]; // all the bases are either j or k + } + for (k = 0; k != m; ++k) if (q[j*m+k] < 0.0) q[j*m+k] = 0.0; + } + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/errmod.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,24 @@ +#ifndef ERRMOD_H +#define ERRMOD_H + +#include <stdint.h> + +struct __errmod_coef_t; + +typedef struct { + double depcorr; + struct __errmod_coef_t *coef; +} errmod_t; + +errmod_t *errmod_init(float depcorr); +void errmod_destroy(errmod_t *em); + +/* + n: number of bases + m: maximum base + bases[i]: qual:6, strand:1, base:4 + q[i*m+j]: phred-scaled likelihood of (i,j) + */ +int errmod_cal(const errmod_t *em, int n, int m, uint16_t *bases, float *q); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/examples/00README.txt Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,23 @@ +File ex1.fa contains two sequences cut from the human genome +build36. They were exatracted with command: + + samtools faidx human_b36.fa 2:2043966-2045540 20:67967-69550 + +Sequence names were changed manually for simplicity. File ex1.sam.gz +contains MAQ alignments exatracted with: + + (samtools view NA18507_maq.bam 2:2044001-2045500; + samtools view NA18507_maq.bam 20:68001-69500) + +and processed with `samtools fixmate' to make it self-consistent as a +standalone alignment. + +To try samtools, you may run the following commands: + + samtools faidx ex1.fa # index the reference FASTA + samtools import ex1.fa.fai ex1.sam.gz ex1.bam # SAM->BAM + samtools index ex1.bam # index BAM + samtools tview ex1.bam ex1.fa # view alignment + samtools pileup -cf ex1.fa ex1.bam # pileup and consensus + samtools pileup -cf ex1.fa -t ex1.fa.fai ex1.sam.gz +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/examples/Makefile Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,50 @@ +all:../libbam.a ../samtools ../bcftools/bcftools \ + ex1.glf ex1.pileup.gz ex1.bam.bai ex1f-rmduppe.bam ex1f-rmdupse.bam ex1.glfview.gz ex1.bcf calDepth + @echo; echo \# You can now launch the viewer with: \'samtools tview ex1.bam ex1.fa\'; echo; + +ex1.fa.fai:ex1.fa + ../samtools faidx ex1.fa +ex1.bam:ex1.sam.gz ex1.fa.fai + ../samtools import ex1.fa.fai ex1.sam.gz ex1.bam +ex1.bam.bai:ex1.bam + ../samtools index ex1.bam +ex1.pileup.gz:ex1.bam ex1.fa + ../samtools pileup -cf ex1.fa ex1.bam | gzip > ex1.pileup.gz +ex1.glf:ex1.bam ex1.fa + ../samtools pileup -gf ex1.fa ex1.bam > ex1.glf +ex1.glfview.gz:ex1.glf + ../samtools glfview ex1.glf | gzip > ex1.glfview.gz +ex1a.bam:ex1.bam + ../samtools view -h ex1.bam | awk 'BEGIN{FS=OFS="\t"}{if(/^@/)print;else{$$1=$$1"a";print}}' | ../samtools view -bS - > $@ +ex1b.bam:ex1.bam + ../samtools view -h ex1.bam | awk 'BEGIN{FS=OFS="\t"}{if(/^@/)print;else{$$1=$$1"b";print}}' | ../samtools view -bS - > $@ +ex1f.rg: + (echo "@RG ID:ex1 LB:ex1 SM:ex1"; echo "@RG ID:ex1a LB:ex1 SM:ex1"; echo "@RG ID:ex1b LB:ex1b SM:ex1b") > $@ +ex1f.bam:ex1.bam ex1a.bam ex1b.bam ex1f.rg + ../samtools merge -rh ex1f.rg $@ ex1.bam ex1a.bam ex1b.bam +ex1f-rmduppe.bam:ex1f.bam + ../samtools rmdup ex1f.bam $@ +ex1f-rmdupse.bam:ex1f.bam + ../samtools rmdup -S ex1f.bam $@ + +ex1.bcf:ex1.bam ex1.fa.fai + ../samtools mpileup -gf ex1.fa ex1.bam > $@ + +../bcftools/bcftools: + (cd ../bcftools; make bcftools) + +../samtools: + (cd ..; make samtools) + +../libbam.a: + (cd ..; make libbam.a) + +calDepth:../libbam.a calDepth.c + gcc -g -Wall -O2 -I.. calDepth.c -o $@ -L.. -lbam -lm -lz + +clean: + rm -fr *.bam *.bai *.glf* *.fai *.pileup* *~ calDepth *.dSYM ex1*.rg ex1.bcf + +# ../samtools pileup ex1.bam|perl -ape '$_=$F[4];s/(\d+)(??{".{$1}"})|\^.//g;@_=(tr/A-Z//,tr/a-z//);$_=join("\t",@F[0,1],@_)."\n"' + +# ../samtools pileup -cf ex1.fa ex1.bam|perl -ape '$_=$F[8];s/\^.//g;s/(\d+)(??{".{$1}"})|\^.//g;@_=(tr/A-Za-z//,tr/,.//);$_=join("\t",@F[0,1],@_)."\n"'
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/examples/bam2bed.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,51 @@ +#include <stdio.h> +#include "sam.h" +static int fetch_func(const bam1_t *b, void *data) +{ + samfile_t *fp = (samfile_t*)data; + uint32_t *cigar = bam1_cigar(b); + const bam1_core_t *c = &b->core; + int i, l; + if (b->core.tid < 0) return 0; + for (i = l = 0; i < c->n_cigar; ++i) { + int op = cigar[i]&0xf; + if (op == BAM_CMATCH || op == BAM_CDEL || op == BAM_CREF_SKIP) + l += cigar[i]>>4; + } + printf("%s\t%d\t%d\t%s\t%d\t%c\n", fp->header->target_name[c->tid], + c->pos, c->pos + l, bam1_qname(b), c->qual, (c->flag&BAM_FREVERSE)? '-' : '+'); + return 0; +} +int main(int argc, char *argv[]) +{ + samfile_t *fp; + if (argc == 1) { + fprintf(stderr, "Usage: bam2bed <in.bam> [region]\n"); + return 1; + } + if ((fp = samopen(argv[1], "rb", 0)) == 0) { + fprintf(stderr, "bam2bed: Fail to open BAM file %s\n", argv[1]); + return 1; + } + if (argc == 2) { /* if a region is not specified */ + bam1_t *b = bam_init1(); + while (samread(fp, b) >= 0) fetch_func(b, fp); + bam_destroy1(b); + } else { + int ref, beg, end; + bam_index_t *idx; + if ((idx = bam_index_load(argv[1])) == 0) { + fprintf(stderr, "bam2bed: BAM indexing file is not available.\n"); + return 1; + } + bam_parse_region(fp->header, argv[2], &ref, &beg, &end); + if (ref < 0) { + fprintf(stderr, "bam2bed: Invalid region %s\n", argv[2]); + return 1; + } + bam_fetch(fp->x.bam, idx, ref, beg, end, fp, fetch_func); + bam_index_destroy(idx); + } + samclose(fp); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/examples/calDepth.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,62 @@ +#include <stdio.h> +#include "sam.h" + +typedef struct { + int beg, end; + samfile_t *in; +} tmpstruct_t; + +// callback for bam_fetch() +static int fetch_func(const bam1_t *b, void *data) +{ + bam_plbuf_t *buf = (bam_plbuf_t*)data; + bam_plbuf_push(b, buf); + return 0; +} +// callback for bam_plbuf_init() +static int pileup_func(uint32_t tid, uint32_t pos, int n, const bam_pileup1_t *pl, void *data) +{ + tmpstruct_t *tmp = (tmpstruct_t*)data; + if ((int)pos >= tmp->beg && (int)pos < tmp->end) + printf("%s\t%d\t%d\n", tmp->in->header->target_name[tid], pos + 1, n); + return 0; +} + +int main(int argc, char *argv[]) +{ + tmpstruct_t tmp; + if (argc == 1) { + fprintf(stderr, "Usage: calDepth <in.bam> [region]\n"); + return 1; + } + tmp.beg = 0; tmp.end = 0x7fffffff; + tmp.in = samopen(argv[1], "rb", 0); + if (tmp.in == 0) { + fprintf(stderr, "Fail to open BAM file %s\n", argv[1]); + return 1; + } + if (argc == 2) { // if a region is not specified + sampileup(tmp.in, -1, pileup_func, &tmp); + } else { + int ref; + bam_index_t *idx; + bam_plbuf_t *buf; + idx = bam_index_load(argv[1]); // load BAM index + if (idx == 0) { + fprintf(stderr, "BAM indexing file is not available.\n"); + return 1; + } + bam_parse_region(tmp.in->header, argv[2], &ref, &tmp.beg, &tmp.end); // parse the region + if (ref < 0) { + fprintf(stderr, "Invalid region %s\n", argv[2]); + return 1; + } + buf = bam_plbuf_init(pileup_func, &tmp); // initialize pileup + bam_fetch(tmp.in->x.bam, idx, ref, tmp.beg, tmp.end, buf, fetch_func); + bam_plbuf_push(0, buf); // finalize pileup + bam_index_destroy(idx); + bam_plbuf_destroy(buf); + } + samclose(tmp.in); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/examples/ex1.fa Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,56 @@ +>seq1 +CACTAGTGGCTCATTGTAAATGTGTGGTTTAACTCGTCCATGGCCCAGCATTAGGGAGCT +GTGGACCCTGCAGCCTGGCTGTGGGGGCCGCAGTGGCTGAGGGGTGCAGAGCCGAGTCAC +GGGGTTGCCAGCACAGGGGCTTAACCTCTGGTGACTGCCAGAGCTGCTGGCAAGCTAGAG +TCCCATTTGGAGCCCCTCTAAGCCGTTCTATTTGTAATGAAAACTATATTTATGCTATTC +AGTTCTAAATATAGAAATTGAAACAGCTGTGTTTAGTGCCTTTGTTCAACCCCCTTGCAA +CAACCTTGAGAACCCCAGGGAATTTGTCAATGTCAGGGAAGGAGCATTTTGTCAGTTACC +AAATGTGTTTATTACCAGAGGGATGGAGGGAAGAGGGACGCTGAAGAACTTTGATGCCCT +CTTCTTCCAAAGATGAAACGCGTAACTGCGCTCTCATTCACTCCAGCTCCCTGTCACCCA +ATGGACCTGTGATATCTGGATTCTGGGAAATTCTTCATCCTGGACCCTGAGAGATTCTGC +AGCCCAGCTCCAGATTGCTTGTGGTCTGACAGGCTGCAACTGTGAGCCATCACAATGAAC +AACAGGAAGAAAAGGTCTTTCAAAAGGTGATGTGTGTTCTCATCAACCTCATACACACAC +ATGGTTTAGGGGTATAATACCTCTACATGGCTGATTATGAAAACAATGTTCCCCAGATAC +CATCCCTGTCTTACTTCCAGCTCCCCAGAGGGAAAGCTTTCAACGCTTCTAGCCATTTCT +TTTGGCATTTGCCTTCAGACCCTACACGAATGCGTCTCTACCACAGGGGGCTGCGCGGTT +TCCCATCATGAAGCACTGAACTTCCACGTCTCATCTAGGGGAACAGGGAGGTGCACTAAT +GCGCTCCACGCCCAAGCCCTTCTCACAGTTTCTGCCCCCAGCATGGTTGTACTGGGCAAT +ACATGAGATTATTAGGAAATGCTTTACTGTCATAACTATGAAGAGACTATTGCCAGATGA +ACCACACATTAATACTATGTTTCTTATCTGCACATTACTACCCTGCAATTAATATAATTG +TGTCCATGTACACACGCTGTCCTATGTACTTATCATGACTCTATCCCAAATTCCCAATTA +CGTCCTATCTTCTTCTTAGGGAAGAACAGCTTAGGTATCAATTTGGTGTTCTGTGTAAAG +TCTCAGGGAGCCGTCCGTGTCCTCCCATCTGGCCTCGTCCACACTGGTTCTCTTGAAAGC +TTGGGCTGTAATGATGCCCCTTGGCCATCACCCAGTCCCTGCCCCATCTCTTGTAATCTC +TCTCCTTTTTGCTGCATCCCTGTCTTCCTCTGTCTTGATTTACTTGTTGTTGGTTTTCTG +TTTCTTTGTTTGATTTGGTGGAAGACATAATCCCACGCTTCCTATGGAAAGGTTGTTGGG +AGATTTTTAATGATTCCTCAATGTTAAAATGTCTATTTTTGTCTTGACACCCAACTAATA +TTTGTCTGAGCAAAACAGTCTAGATGAGAGAGAACTTCCCTGGAGGTCTGATGGCGTTTC +TCCCTCGTCTTCTTA +>seq2 +TTCAAATGAACTTCTGTAATTGAAAAATTCATTTAAGAAATTACAAAATATAGTTGAAAG +CTCTAACAATAGACTAAACCAAGCAGAAGAAAGAGGTTCAGAACTTGAAGACAAGTCTCT +TATGAATTAACCCAGTCAGACAAAAATAAAGAAAAAAATTTTAAAAATGAACAGAGCTTT +CAAGAAGTATGAGATTATGTAAAGTAACTGAACCTATGAGTCACAGGTATTCCTGAGGAA +AAAGAAAAAGTGAGAAGTTTGGAAAAACTATTTGAGGAAGTAATTGGGGAAAACCTCTTT +AGTCTTGCTAGAGATTTAGACATCTAAATGAAAGAGGCTCAAAGAATGCCAGGAAGATAC +ATTGCAAGACAGACTTCATCAAGATATGTAGTCATCAGACTATCTAAAGTCAACATGAAG +GAAAAAAATTCTAAAATCAGCAAGAGAAAAGCATACAGTCATCTATAAAGGAAATCCCAT +CAGAATAACAATGGGCTTCTCAGCAGAAACCTTACAAGCCAGAAGAGATTGGATCTAATT +TTTGGACTTCTTAAAGAAAAAAAAACCTGTCAAACACGAATGTTATGCCCTGCTAAACTA +AGCATCATAAATGAAGGGGAAATAAAGTCAAGTCTTTCCTGACAAGCAAATGCTAAGATA +ATTCATCATCACTAAACCAGTCCTATAAGAAATGCTCAAAAGAATTGTAAAAGTCAAAAT +TAAAGTTCAATACTCACCATCATAAATACACACAAAAGTACAAAACTCACAGGTTTTATA +AAACAATTGAGACTACAGAGCAACTAGGTAAAAAATTAACATTACAACAGGAACAAAACC +TCATATATCAATATTAACTTTGAATAAAAAGGGATTAAATTCCCCCACTTAAGAGATATA +GATTGGCAGAACAGATTTAAAAACATGAACTAACTATATGCTGTTTACAAGAAACTCATT +AATAAAGACATGAGTTCAGGTAAAGGGGTGGAAAAAGATGTTCTACGCAAACAGAAACCA +AATGAGAGAAGGAGTAGCTATACTTATATCAGATAAAGCACACTTTAAATCAACAACAGT +AAAATAAAACAAAGGAGGTCATCATACAATGATAAAAAGATCAATTCAGCAAGAAGATAT +AACCATCCTACTAAATACATATGCACCTAACACAAGACTACCCAGATTCATAAAACAAAT +ACTACTAGACCTAAGAGGGATGAGAAATTACCTAATTGGTACAATGTACAATATTCTGAT +GATGGTTACACTAAAAGCCCATACTTTACTGCTACTCAATATATCCATGTAACAAATCTG +CGCTTGTACTTCTAAATCTATAAAAAAATTAAAATTTAACAAAAGTAAATAAAACACATA +GCTAAAACTAAAAAAGCAAAAACAAAAACTATGCTAAGTATTGGTAAAGATGTGGGGAAA +AAAGTAAACTCTCAAATATTGCTAGTGGGAGTATAAATTGTTTTCCACTTTGGAAAACAA +TTTGGTAATTTCGTTTTTTTTTTTTTCTTTTCTCTTTTTTTTTTTTTTTTTTTTGCATGC +CAGAAAAAAATATTTACAGTAACT
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/examples/toy.fa Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,4 @@ +>ref +AGCATGTTAGATAAGATAGCTGTGCTAGTAGGCAGTCAGCGCCAT +>ref2 +aggttttataaaacaattaagtctacagagcaactacgcg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/examples/toy.sam Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,14 @@ +@SQ SN:ref LN:45 +@SQ SN:ref2 LN:40 +r001 163 ref 7 30 8M4I4M1D3M = 37 39 TTAGATAAAGAGGATACTG * XX:B:S,12561,2,20,112 +r002 0 ref 9 30 1S2I6M1P1I1P1I4M2I * 0 0 AAAAGATAAGGGATAAA * +r003 0 ref 9 30 5H6M * 0 0 AGCTAA * +r004 0 ref 16 30 6M14N1I5M * 0 0 ATAGCTCTCAGC * +r003 16 ref 29 30 6H5M * 0 0 TAGGC * +r001 83 ref 37 30 9M = 7 -39 CAGCGCCAT * +x1 0 ref2 1 30 20M * 0 0 aggttttataaaacaaataa ???????????????????? +x2 0 ref2 2 30 21M * 0 0 ggttttataaaacaaataatt ????????????????????? +x3 0 ref2 6 30 9M4I13M * 0 0 ttataaaacAAATaattaagtctaca ?????????????????????????? +x4 0 ref2 10 30 25M * 0 0 CaaaTaattaagtctacagagcaac ????????????????????????? +x5 0 ref2 12 30 24M * 0 0 aaTaattaagtctacagagcaact ???????????????????????? +x6 0 ref2 14 30 23M * 0 0 Taattaagtctacagagcaacta ???????????????????????
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/faidx.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,423 @@ +#include <ctype.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> +#include "faidx.h" +#include "khash.h" + +typedef struct { + uint64_t len:32, line_len:16, line_blen:16; + uint64_t offset; +} faidx1_t; +KHASH_MAP_INIT_STR(s, faidx1_t) + +#ifndef _NO_RAZF +#include "razf.h" +#else +#ifdef _WIN32 +#define ftello(fp) ftell(fp) +#define fseeko(fp, offset, whence) fseek(fp, offset, whence) +#else +extern off_t ftello(FILE *stream); +extern int fseeko(FILE *stream, off_t offset, int whence); +#endif +#define RAZF FILE +#define razf_read(fp, buf, size) fread(buf, 1, size, fp) +#define razf_open(fn, mode) fopen(fn, mode) +#define razf_close(fp) fclose(fp) +#define razf_seek(fp, offset, whence) fseeko(fp, offset, whence) +#define razf_tell(fp) ftello(fp) +#endif +#ifdef _USE_KNETFILE +#include "knetfile.h" +#endif + +struct __faidx_t { + RAZF *rz; + int n, m; + char **name; + khash_t(s) *hash; +}; + +#ifndef kroundup32 +#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) +#endif + +static inline void fai_insert_index(faidx_t *idx, const char *name, int len, int line_len, int line_blen, uint64_t offset) +{ + khint_t k; + int ret; + faidx1_t t; + if (idx->n == idx->m) { + idx->m = idx->m? idx->m<<1 : 16; + idx->name = (char**)realloc(idx->name, sizeof(void*) * idx->m); + } + idx->name[idx->n] = strdup(name); + k = kh_put(s, idx->hash, idx->name[idx->n], &ret); + t.len = len; t.line_len = line_len; t.line_blen = line_blen; t.offset = offset; + kh_value(idx->hash, k) = t; + ++idx->n; +} + +faidx_t *fai_build_core(RAZF *rz) +{ + char c, *name; + int l_name, m_name, ret; + int len, line_len, line_blen, state; + int l1, l2; + faidx_t *idx; + uint64_t offset; + + idx = (faidx_t*)calloc(1, sizeof(faidx_t)); + idx->hash = kh_init(s); + name = 0; l_name = m_name = 0; + len = line_len = line_blen = -1; state = 0; l1 = l2 = -1; offset = 0; + while (razf_read(rz, &c, 1)) { + if (c == '\n') { // an empty line + if (state == 1) { + offset = razf_tell(rz); + continue; + } else if ((state == 0 && len < 0) || state == 2) continue; + } + if (c == '>') { // fasta header + if (len >= 0) + fai_insert_index(idx, name, len, line_len, line_blen, offset); + l_name = 0; + while ((ret = razf_read(rz, &c, 1)) != 0 && !isspace(c)) { + if (m_name < l_name + 2) { + m_name = l_name + 2; + kroundup32(m_name); + name = (char*)realloc(name, m_name); + } + name[l_name++] = c; + } + name[l_name] = '\0'; + if (ret == 0) { + fprintf(stderr, "[fai_build_core] the last entry has no sequence\n"); + free(name); fai_destroy(idx); + return 0; + } + if (c != '\n') while (razf_read(rz, &c, 1) && c != '\n'); + state = 1; len = 0; + offset = razf_tell(rz); + } else { + if (state == 3) { + fprintf(stderr, "[fai_build_core] inlined empty line is not allowed in sequence '%s'.\n", name); + free(name); fai_destroy(idx); + return 0; + } + if (state == 2) state = 3; + l1 = l2 = 0; + do { + ++l1; + if (isgraph(c)) ++l2; + } while ((ret = razf_read(rz, &c, 1)) && c != '\n'); + if (state == 3 && l2) { + fprintf(stderr, "[fai_build_core] different line length in sequence '%s'.\n", name); + free(name); fai_destroy(idx); + return 0; + } + ++l1; len += l2; + if (l2 >= 0x10000) { + fprintf(stderr, "[fai_build_core] line length exceeds 65535 in sequence '%s'.\n", name); + free(name); fai_destroy(idx); + return 0; + } + if (state == 1) line_len = l1, line_blen = l2, state = 0; + else if (state == 0) { + if (l1 != line_len || l2 != line_blen) state = 2; + } + } + } + fai_insert_index(idx, name, len, line_len, line_blen, offset); + free(name); + return idx; +} + +void fai_save(const faidx_t *fai, FILE *fp) +{ + khint_t k; + int i; + for (i = 0; i < fai->n; ++i) { + faidx1_t x; + k = kh_get(s, fai->hash, fai->name[i]); + x = kh_value(fai->hash, k); +#ifdef _WIN32 + fprintf(fp, "%s\t%d\t%ld\t%d\t%d\n", fai->name[i], (int)x.len, (long)x.offset, (int)x.line_blen, (int)x.line_len); +#else + fprintf(fp, "%s\t%d\t%lld\t%d\t%d\n", fai->name[i], (int)x.len, (long long)x.offset, (int)x.line_blen, (int)x.line_len); +#endif + } +} + +faidx_t *fai_read(FILE *fp) +{ + faidx_t *fai; + char *buf, *p; + int len, line_len, line_blen; +#ifdef _WIN32 + long offset; +#else + long long offset; +#endif + fai = (faidx_t*)calloc(1, sizeof(faidx_t)); + fai->hash = kh_init(s); + buf = (char*)calloc(0x10000, 1); + while (!feof(fp) && fgets(buf, 0x10000, fp)) { + for (p = buf; *p && isgraph(*p); ++p); + *p = 0; ++p; +#ifdef _WIN32 + sscanf(p, "%d%ld%d%d", &len, &offset, &line_blen, &line_len); +#else + sscanf(p, "%d%lld%d%d", &len, &offset, &line_blen, &line_len); +#endif + fai_insert_index(fai, buf, len, line_len, line_blen, offset); + } + free(buf); + return fai; +} + +void fai_destroy(faidx_t *fai) +{ + int i; + for (i = 0; i < fai->n; ++i) free(fai->name[i]); + free(fai->name); + kh_destroy(s, fai->hash); + if (fai->rz) razf_close(fai->rz); + free(fai); +} + +int fai_build(const char *fn) +{ + char *str; + RAZF *rz; + FILE *fp; + faidx_t *fai; + str = (char*)calloc(strlen(fn) + 5, 1); + sprintf(str, "%s.fai", fn); + rz = razf_open(fn, "r"); + if (rz == 0) { + fprintf(stderr, "[fai_build] fail to open the FASTA file %s\n",fn); + free(str); + return -1; + } + fai = fai_build_core(rz); + razf_close(rz); + fp = fopen(str, "wb"); + if (fp == 0) { + fprintf(stderr, "[fai_build] fail to write FASTA index %s\n",str); + fai_destroy(fai); free(str); + return -1; + } + fai_save(fai, fp); + fclose(fp); + free(str); + fai_destroy(fai); + return 0; +} + +#ifdef _USE_KNETFILE +FILE *download_and_open(const char *fn) +{ + const int buf_size = 1 * 1024 * 1024; + uint8_t *buf; + FILE *fp; + knetFile *fp_remote; + const char *url = fn; + const char *p; + int l = strlen(fn); + for (p = fn + l - 1; p >= fn; --p) + if (*p == '/') break; + fn = p + 1; + + // First try to open a local copy + fp = fopen(fn, "r"); + if (fp) + return fp; + + // If failed, download from remote and open + fp_remote = knet_open(url, "rb"); + if (fp_remote == 0) { + fprintf(stderr, "[download_from_remote] fail to open remote file %s\n",url); + return NULL; + } + if ((fp = fopen(fn, "wb")) == 0) { + fprintf(stderr, "[download_from_remote] fail to create file in the working directory %s\n",fn); + knet_close(fp_remote); + return NULL; + } + buf = (uint8_t*)calloc(buf_size, 1); + while ((l = knet_read(fp_remote, buf, buf_size)) != 0) + fwrite(buf, 1, l, fp); + free(buf); + fclose(fp); + knet_close(fp_remote); + + return fopen(fn, "r"); +} +#endif + +faidx_t *fai_load(const char *fn) +{ + char *str; + FILE *fp; + faidx_t *fai; + str = (char*)calloc(strlen(fn) + 5, 1); + sprintf(str, "%s.fai", fn); + +#ifdef _USE_KNETFILE + if (strstr(fn, "ftp://") == fn || strstr(fn, "http://") == fn) + { + fp = download_and_open(str); + if ( !fp ) + { + fprintf(stderr, "[fai_load] failed to open remote FASTA index %s\n", str); + free(str); + return 0; + } + } + else +#endif + fp = fopen(str, "rb"); + if (fp == 0) { + fprintf(stderr, "[fai_load] build FASTA index.\n"); + fai_build(fn); + fp = fopen(str, "rb"); + if (fp == 0) { + fprintf(stderr, "[fai_load] fail to open FASTA index.\n"); + free(str); + return 0; + } + } + + fai = fai_read(fp); + fclose(fp); + + fai->rz = razf_open(fn, "rb"); + free(str); + if (fai->rz == 0) { + fprintf(stderr, "[fai_load] fail to open FASTA file.\n"); + return 0; + } + return fai; +} + +char *fai_fetch(const faidx_t *fai, const char *str, int *len) +{ + char *s, *p, c; + int i, l, k; + khiter_t iter; + faidx1_t val; + khash_t(s) *h; + int beg, end; + + beg = end = -1; + h = fai->hash; + l = strlen(str); + p = s = (char*)malloc(l+1); + /* squeeze out "," */ + for (i = k = 0; i != l; ++i) + if (str[i] != ',' && !isspace(str[i])) s[k++] = str[i]; + s[k] = 0; + for (i = 0; i != k; ++i) if (s[i] == ':') break; + s[i] = 0; + iter = kh_get(s, h, s); /* get the ref_id */ + if (iter == kh_end(h)) { + *len = 0; + free(s); return 0; + } + val = kh_value(h, iter); + if (i == k) { /* dump the whole sequence */ + beg = 0; end = val.len; + } else { + for (p = s + i + 1; i != k; ++i) if (s[i] == '-') break; + beg = atoi(p); + if (i < k) { + p = s + i + 1; + end = atoi(p); + } else end = val.len; + } + if (beg > 0) --beg; + if (beg >= val.len) beg = val.len; + if (end >= val.len) end = val.len; + if (beg > end) beg = end; + free(s); + + // now retrieve the sequence + l = 0; + s = (char*)malloc(end - beg + 2); + razf_seek(fai->rz, val.offset + beg / val.line_blen * val.line_len + beg % val.line_blen, SEEK_SET); + while (razf_read(fai->rz, &c, 1) == 1 && l < end - beg && !fai->rz->z_err) + if (isgraph(c)) s[l++] = c; + s[l] = '\0'; + *len = l; + return s; +} + +int faidx_main(int argc, char *argv[]) +{ + if (argc == 1) { + fprintf(stderr, "Usage: faidx <in.fasta> [<reg> [...]]\n"); + return 1; + } else { + if (argc == 2) fai_build(argv[1]); + else { + int i, j, k, l; + char *s; + faidx_t *fai; + fai = fai_load(argv[1]); + if (fai == 0) return 1; + for (i = 2; i != argc; ++i) { + printf(">%s\n", argv[i]); + s = fai_fetch(fai, argv[i], &l); + for (j = 0; j < l; j += 60) { + for (k = 0; k < 60 && k < l - j; ++k) + putchar(s[j + k]); + putchar('\n'); + } + free(s); + } + fai_destroy(fai); + } + } + return 0; +} + +int faidx_fetch_nseq(const faidx_t *fai) +{ + return fai->n; +} + +char *faidx_fetch_seq(const faidx_t *fai, char *c_name, int p_beg_i, int p_end_i, int *len) +{ + int l; + char c; + khiter_t iter; + faidx1_t val; + char *seq=NULL; + + // Adjust position + iter = kh_get(s, fai->hash, c_name); + if(iter == kh_end(fai->hash)) return 0; + val = kh_value(fai->hash, iter); + if(p_end_i < p_beg_i) p_beg_i = p_end_i; + if(p_beg_i < 0) p_beg_i = 0; + else if(val.len <= p_beg_i) p_beg_i = val.len - 1; + if(p_end_i < 0) p_end_i = 0; + else if(val.len <= p_end_i) p_end_i = val.len - 1; + + // Now retrieve the sequence + l = 0; + seq = (char*)malloc(p_end_i - p_beg_i + 2); + razf_seek(fai->rz, val.offset + p_beg_i / val.line_blen * val.line_len + p_beg_i % val.line_blen, SEEK_SET); + while (razf_read(fai->rz, &c, 1) == 1 && l < p_end_i - p_beg_i + 1) + if (isgraph(c)) seq[l++] = c; + seq[l] = '\0'; + *len = l; + return seq; +} + +#ifdef FAIDX_MAIN +int main(int argc, char *argv[]) { return faidx_main(argc, argv); } +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/faidx.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,103 @@ +/* The MIT License + + Copyright (c) 2008 Genome Research Ltd (GRL). + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* Contact: Heng Li <lh3@sanger.ac.uk> */ + +#ifndef FAIDX_H +#define FAIDX_H + +/*! + @header + + Index FASTA files and extract subsequence. + + @copyright The Wellcome Trust Sanger Institute. + */ + +struct __faidx_t; +typedef struct __faidx_t faidx_t; + +#ifdef __cplusplus +extern "C" { +#endif + + /*! + @abstract Build index for a FASTA or razip compressed FASTA file. + @param fn FASTA file name + @return 0 on success; or -1 on failure + @discussion File "fn.fai" will be generated. + */ + int fai_build(const char *fn); + + /*! + @abstract Distroy a faidx_t struct. + @param fai Pointer to the struct to be destroyed + */ + void fai_destroy(faidx_t *fai); + + /*! + @abstract Load index from "fn.fai". + @param fn File name of the FASTA file + */ + faidx_t *fai_load(const char *fn); + + /*! + @abstract Fetch the sequence in a region. + @param fai Pointer to the faidx_t struct + @param reg Region in the format "chr2:20,000-30,000" + @param len Length of the region + @return Pointer to the sequence; null on failure + + @discussion The returned sequence is allocated by malloc family + and should be destroyed by end users by calling free() on it. + */ + char *fai_fetch(const faidx_t *fai, const char *reg, int *len); + + /*! + @abstract Fetch the number of sequences. + @param fai Pointer to the faidx_t struct + @return The number of sequences + */ + int faidx_fetch_nseq(const faidx_t *fai); + + /*! + @abstract Fetch the sequence in a region. + @param fai Pointer to the faidx_t struct + @param c_name Region name + @param p_beg_i Beginning position number (zero-based) + @param p_end_i End position number (zero-based) + @param len Length of the region + @return Pointer to the sequence; null on failure + + @discussion The returned sequence is allocated by malloc family + and should be destroyed by end users by calling free() on it. + */ + char *faidx_fetch_seq(const faidx_t *fai, char *c_name, int p_beg_i, int p_end_i, int *len); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/glf.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,236 @@ +#include <string.h> +#include <stdlib.h> +#include "glf.h" + +#ifdef _NO_BGZF +// then alias bgzf_*() functions +#endif + +static int glf3_is_BE = 0; + +static inline uint32_t bam_swap_endian_4(uint32_t v) +{ + v = ((v & 0x0000FFFFU) << 16) | (v >> 16); + return ((v & 0x00FF00FFU) << 8) | ((v & 0xFF00FF00U) >> 8); +} + +static inline uint16_t bam_swap_endian_2(uint16_t v) +{ + return (uint16_t)(((v & 0x00FF00FFU) << 8) | ((v & 0xFF00FF00U) >> 8)); +} + +static inline int bam_is_big_endian() +{ + long one= 1; + return !(*((char *)(&one))); +} + +glf3_header_t *glf3_header_init() +{ + glf3_is_BE = bam_is_big_endian(); + return (glf3_header_t*)calloc(1, sizeof(glf3_header_t)); +} + +glf3_header_t *glf3_header_read(glfFile fp) +{ + glf3_header_t *h; + char magic[4]; + h = glf3_header_init(); + bgzf_read(fp, magic, 4); + if (strncmp(magic, "GLF\3", 4)) { + fprintf(stderr, "[glf3_header_read] invalid magic.\n"); + glf3_header_destroy(h); + return 0; + } + bgzf_read(fp, &h->l_text, 4); + if (glf3_is_BE) h->l_text = bam_swap_endian_4(h->l_text); + if (h->l_text) { + h->text = (uint8_t*)calloc(h->l_text + 1, 1); + bgzf_read(fp, h->text, h->l_text); + } + return h; +} + +void glf3_header_write(glfFile fp, const glf3_header_t *h) +{ + int32_t x; + bgzf_write(fp, "GLF\3", 4); + x = glf3_is_BE? bam_swap_endian_4(h->l_text) : h->l_text; + bgzf_write(fp, &x, 4); + if (h->l_text) bgzf_write(fp, h->text, h->l_text); +} + +void glf3_header_destroy(glf3_header_t *h) +{ + free(h->text); + free(h); +} + +char *glf3_ref_read(glfFile fp, int *len) +{ + int32_t n, x; + char *str; + *len = 0; + if (bgzf_read(fp, &n, 4) != 4) return 0; + if (glf3_is_BE) n = bam_swap_endian_4(n); + if (n < 0) { + fprintf(stderr, "[glf3_ref_read] invalid reference name length: %d.\n", n); + return 0; + } + str = (char*)calloc(n + 1, 1); // not necesarily n+1 in fact + x = bgzf_read(fp, str, n); + x += bgzf_read(fp, len, 4); + if (x != n + 4) { + free(str); *len = -1; return 0; // truncated + } + if (glf3_is_BE) *len = bam_swap_endian_4(*len); + return str; +} + +void glf3_ref_write(glfFile fp, const char *str, int len) +{ + int32_t m, n = strlen(str) + 1; + m = glf3_is_BE? bam_swap_endian_4(n) : n; + bgzf_write(fp, &m, 4); + bgzf_write(fp, str, n); + if (glf3_is_BE) len = bam_swap_endian_4(len); + bgzf_write(fp, &len, 4); +} + +void glf3_view1(const char *ref_name, const glf3_t *g3, int pos) +{ + int j; + if (g3->rtype == GLF3_RTYPE_END) return; + printf("%s\t%d\t%c\t%d\t%d\t%d", ref_name, pos + 1, + g3->rtype == GLF3_RTYPE_INDEL? '*' : "XACMGRSVTWYHKDBN"[g3->ref_base], + g3->depth, g3->rms_mapQ, g3->min_lk); + if (g3->rtype == GLF3_RTYPE_SUB) + for (j = 0; j != 10; ++j) printf("\t%d", g3->lk[j]); + else { + printf("\t%d\t%d\t%d\t%d\t%d\t%s\t%s\t", g3->lk[0], g3->lk[1], g3->lk[2], g3->indel_len[0], g3->indel_len[1], + g3->indel_len[0]? g3->indel_seq[0] : "*", g3->indel_len[1]? g3->indel_seq[1] : "*"); + } + printf("\n"); +} + +int glf3_write1(glfFile fp, const glf3_t *g3) +{ + int r; + uint8_t c; + uint32_t y[2]; + c = g3->rtype<<4 | g3->ref_base; + r = bgzf_write(fp, &c, 1); + if (g3->rtype == GLF3_RTYPE_END) return r; + y[0] = g3->offset; + y[1] = g3->min_lk<<24 | g3->depth; + if (glf3_is_BE) { + y[0] = bam_swap_endian_4(y[0]); + y[1] = bam_swap_endian_4(y[1]); + } + r += bgzf_write(fp, y, 8); + r += bgzf_write(fp, &g3->rms_mapQ, 1); + if (g3->rtype == GLF3_RTYPE_SUB) r += bgzf_write(fp, g3->lk, 10); + else { + int16_t x[2]; + r += bgzf_write(fp, g3->lk, 3); + x[0] = glf3_is_BE? bam_swap_endian_2(g3->indel_len[0]) : g3->indel_len[0]; + x[1] = glf3_is_BE? bam_swap_endian_2(g3->indel_len[1]) : g3->indel_len[1]; + r += bgzf_write(fp, x, 4); + if (g3->indel_len[0]) r += bgzf_write(fp, g3->indel_seq[0], abs(g3->indel_len[0])); + if (g3->indel_len[1]) r += bgzf_write(fp, g3->indel_seq[1], abs(g3->indel_len[1])); + } + return r; +} + +#ifndef kv_roundup32 +#define kv_roundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) +#endif + +int glf3_read1(glfFile fp, glf3_t *g3) +{ + int r; + uint8_t c; + uint32_t y[2]; + r = bgzf_read(fp, &c, 1); + if (r == 0) return 0; + g3->ref_base = c & 0xf; + g3->rtype = c>>4; + if (g3->rtype == GLF3_RTYPE_END) return r; + r += bgzf_read(fp, y, 8); + if (glf3_is_BE) { + y[0] = bam_swap_endian_4(y[0]); + y[1] = bam_swap_endian_4(y[1]); + } + g3->offset = y[0]; + g3->min_lk = y[1]>>24; + g3->depth = y[1]<<8>>8; + r += bgzf_read(fp, &g3->rms_mapQ, 1); + if (g3->rtype == GLF3_RTYPE_SUB) r += bgzf_read(fp, g3->lk, 10); + else { + int16_t x[2], max; + r += bgzf_read(fp, g3->lk, 3); + r += bgzf_read(fp, x, 4); + if (glf3_is_BE) { + x[0] = bam_swap_endian_2(x[0]); + x[1] = bam_swap_endian_2(x[1]); + } + g3->indel_len[0] = x[0]; + g3->indel_len[1] = x[1]; + x[0] = abs(x[0]); x[1] = abs(x[1]); + max = (x[0] > x[1]? x[0] : x[1]) + 1; + if (g3->max_len < max) { + g3->max_len = max; + kv_roundup32(g3->max_len); + g3->indel_seq[0] = (char*)realloc(g3->indel_seq[0], g3->max_len); + g3->indel_seq[1] = (char*)realloc(g3->indel_seq[1], g3->max_len); + } + r += bgzf_read(fp, g3->indel_seq[0], x[0]); + r += bgzf_read(fp, g3->indel_seq[1], x[1]); + g3->indel_seq[0][x[0]] = g3->indel_seq[1][x[1]] = 0; + } + return r; +} + +void glf3_view(glfFile fp) +{ + glf3_header_t *h; + char *name; + glf3_t *g3; + int len; + h = glf3_header_read(fp); + g3 = glf3_init1(); + while ((name = glf3_ref_read(fp, &len)) != 0) { + int pos = 0; + while (glf3_read1(fp, g3) && g3->rtype != GLF3_RTYPE_END) { + pos += g3->offset; + glf3_view1(name, g3, pos); + } + free(name); + } + glf3_header_destroy(h); + glf3_destroy1(g3); +} + +int glf3_view_main(int argc, char *argv[]) +{ + glfFile fp; + if (argc == 1) { + fprintf(stderr, "Usage: glfview <in.glf>\n"); + return 1; + } + fp = (strcmp(argv[1], "-") == 0)? bgzf_fdopen(fileno(stdin), "r") : bgzf_open(argv[1], "r"); + if (fp == 0) { + fprintf(stderr, "Fail to open file '%s'\n", argv[1]); + return 1; + } + glf3_view(fp); + bgzf_close(fp); + return 0; +} + +#ifdef GLFVIEW_MAIN +int main(int argc, char *argv[]) +{ + return glf3_view_main(argc, argv); +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/glf.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,56 @@ +#ifndef GLF_H_ +#define GLF_H_ + +typedef struct { + unsigned char ref_base:4, dummy:4; /** "XACMGRSVTWYHKDBN"[ref_base] gives the reference base */ + unsigned char max_mapQ; /** maximum mapping quality */ + unsigned char lk[10]; /** log likelihood ratio, capped at 255 */ + unsigned min_lk:8, depth:24; /** minimum lk capped at 255, and the number of mapped reads */ +} glf1_t; + +#include <stdint.h> +#include "bgzf.h" +typedef BGZF *glfFile; + +#define GLF3_RTYPE_END 0 +#define GLF3_RTYPE_SUB 1 +#define GLF3_RTYPE_INDEL 2 + +typedef struct { + uint8_t ref_base:4, rtype:4; /** "XACMGRSVTWYHKDBN"[ref_base] gives the reference base */ + uint8_t rms_mapQ; /** RMS mapping quality */ + uint8_t lk[10]; /** log likelihood ratio, capped at 255 */ + uint32_t min_lk:8, depth:24; /** minimum lk capped at 255, and the number of mapped reads */ + int32_t offset; /** the first base in a chromosome has offset zero. */ + // for indel (lkHom1, lkHom2 and lkHet are the first three elements in lk[10]) + int16_t indel_len[2]; + int32_t max_len; // maximum indel len; will be modified by glf3_read1() + char *indel_seq[2]; +} glf3_t; + +typedef struct { + int32_t l_text; + uint8_t *text; +} glf3_header_t; + +#ifdef __cplusplus +extern "C" { +#endif + +#define glf3_init1() ((glf3_t*)calloc(1, sizeof(glf3_t))) +#define glf3_destroy1(g3) do { free((g3)->indel_seq[0]); free((g3)->indel_seq[1]); free(g3); } while (0) + + glf3_header_t *glf3_header_init(); + glf3_header_t *glf3_header_read(glfFile fp); + void glf3_header_write(glfFile fp, const glf3_header_t *h); + void glf3_header_destroy(glf3_header_t *h); + char *glf3_ref_read(glfFile fp, int *len); + void glf3_ref_write(glfFile fp, const char *name, int len); + int glf3_write1(glfFile fp, const glf3_t *g3); + int glf3_read1(glfFile fp, glf3_t *g3); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/kaln.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,486 @@ +/* The MIT License + + Copyright (c) 2003-2006, 2008, 2009, by Heng Li <lh3lh3@gmail.com> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> +#include <math.h> +#include "kaln.h" + +#define FROM_M 0 +#define FROM_I 1 +#define FROM_D 2 + +typedef struct { + int i, j; + unsigned char ctype; +} path_t; + +int aln_sm_blosum62[] = { +/* A R N D C Q E G H I L K M F P S T W Y V * X */ + 4,-1,-2,-2, 0,-1,-1, 0,-2,-1,-1,-1,-1,-2,-1, 1, 0,-3,-2, 0,-4, 0, + -1, 5, 0,-2,-3, 1, 0,-2, 0,-3,-2, 2,-1,-3,-2,-1,-1,-3,-2,-3,-4,-1, + -2, 0, 6, 1,-3, 0, 0, 0, 1,-3,-3, 0,-2,-3,-2, 1, 0,-4,-2,-3,-4,-1, + -2,-2, 1, 6,-3, 0, 2,-1,-1,-3,-4,-1,-3,-3,-1, 0,-1,-4,-3,-3,-4,-1, + 0,-3,-3,-3, 9,-3,-4,-3,-3,-1,-1,-3,-1,-2,-3,-1,-1,-2,-2,-1,-4,-2, + -1, 1, 0, 0,-3, 5, 2,-2, 0,-3,-2, 1, 0,-3,-1, 0,-1,-2,-1,-2,-4,-1, + -1, 0, 0, 2,-4, 2, 5,-2, 0,-3,-3, 1,-2,-3,-1, 0,-1,-3,-2,-2,-4,-1, + 0,-2, 0,-1,-3,-2,-2, 6,-2,-4,-4,-2,-3,-3,-2, 0,-2,-2,-3,-3,-4,-1, + -2, 0, 1,-1,-3, 0, 0,-2, 8,-3,-3,-1,-2,-1,-2,-1,-2,-2, 2,-3,-4,-1, + -1,-3,-3,-3,-1,-3,-3,-4,-3, 4, 2,-3, 1, 0,-3,-2,-1,-3,-1, 3,-4,-1, + -1,-2,-3,-4,-1,-2,-3,-4,-3, 2, 4,-2, 2, 0,-3,-2,-1,-2,-1, 1,-4,-1, + -1, 2, 0,-1,-3, 1, 1,-2,-1,-3,-2, 5,-1,-3,-1, 0,-1,-3,-2,-2,-4,-1, + -1,-1,-2,-3,-1, 0,-2,-3,-2, 1, 2,-1, 5, 0,-2,-1,-1,-1,-1, 1,-4,-1, + -2,-3,-3,-3,-2,-3,-3,-3,-1, 0, 0,-3, 0, 6,-4,-2,-2, 1, 3,-1,-4,-1, + -1,-2,-2,-1,-3,-1,-1,-2,-2,-3,-3,-1,-2,-4, 7,-1,-1,-4,-3,-2,-4,-2, + 1,-1, 1, 0,-1, 0, 0, 0,-1,-2,-2, 0,-1,-2,-1, 4, 1,-3,-2,-2,-4, 0, + 0,-1, 0,-1,-1,-1,-1,-2,-2,-1,-1,-1,-1,-2,-1, 1, 5,-2,-2, 0,-4, 0, + -3,-3,-4,-4,-2,-2,-3,-2,-2,-3,-2,-3,-1, 1,-4,-3,-2,11, 2,-3,-4,-2, + -2,-2,-2,-3,-2,-1,-2,-3, 2,-1,-1,-2,-1, 3,-3,-2,-2, 2, 7,-1,-4,-1, + 0,-3,-3,-3,-1,-2,-2,-3,-3, 3, 1,-2, 1,-1,-2,-2, 0,-3,-1, 4,-4,-1, + -4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, 1,-4, + 0,-1,-1,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-2, 0, 0,-2,-1,-1,-4,-1 +}; + +int aln_sm_blast[] = { + 1, -3, -3, -3, -2, + -3, 1, -3, -3, -2, + -3, -3, 1, -3, -2, + -3, -3, -3, 1, -2, + -2, -2, -2, -2, -2 +}; + +int aln_sm_qual[] = { + 0, -23, -23, -23, 0, + -23, 0, -23, -23, 0, + -23, -23, 0, -23, 0, + -23, -23, -23, 0, 0, + 0, 0, 0, 0, 0 +}; + +ka_param_t ka_param_blast = { 5, 2, 5, 2, aln_sm_blast, 5, 50 }; +ka_param_t ka_param_aa2aa = { 10, 2, 10, 2, aln_sm_blosum62, 22, 50 }; + +ka_param2_t ka_param2_qual = { 37, 11, 37, 11, 37, 11, 0, 0, aln_sm_qual, 5, 50 }; + +static uint32_t *ka_path2cigar32(const path_t *path, int path_len, int *n_cigar) +{ + int i, n; + uint32_t *cigar; + unsigned char last_type; + + if (path_len == 0 || path == 0) { + *n_cigar = 0; + return 0; + } + + last_type = path->ctype; + for (i = n = 1; i < path_len; ++i) { + if (last_type != path[i].ctype) ++n; + last_type = path[i].ctype; + } + *n_cigar = n; + cigar = (uint32_t*)calloc(*n_cigar, 4); + + cigar[0] = 1u << 4 | path[path_len-1].ctype; + last_type = path[path_len-1].ctype; + for (i = path_len - 2, n = 0; i >= 0; --i) { + if (path[i].ctype == last_type) cigar[n] += 1u << 4; + else { + cigar[++n] = 1u << 4 | path[i].ctype; + last_type = path[i].ctype; + } + } + + return cigar; +} + +/***************************/ +/* START OF common_align.c */ +/***************************/ + +#define SET_INF(s) (s).M = (s).I = (s).D = MINOR_INF; + +#define set_M(MM, cur, p, sc) \ +{ \ + if ((p)->M >= (p)->I) { \ + if ((p)->M >= (p)->D) { \ + (MM) = (p)->M + (sc); (cur)->Mt = FROM_M; \ + } else { \ + (MM) = (p)->D + (sc); (cur)->Mt = FROM_D; \ + } \ + } else { \ + if ((p)->I > (p)->D) { \ + (MM) = (p)->I + (sc); (cur)->Mt = FROM_I; \ + } else { \ + (MM) = (p)->D + (sc); (cur)->Mt = FROM_D; \ + } \ + } \ +} +#define set_I(II, cur, p) \ +{ \ + if ((p)->M - gap_open > (p)->I) { \ + (cur)->It = FROM_M; \ + (II) = (p)->M - gap_open - gap_ext; \ + } else { \ + (cur)->It = FROM_I; \ + (II) = (p)->I - gap_ext; \ + } \ +} +#define set_end_I(II, cur, p) \ +{ \ + if (gap_end_ext >= 0) { \ + if ((p)->M - gap_end_open > (p)->I) { \ + (cur)->It = FROM_M; \ + (II) = (p)->M - gap_end_open - gap_end_ext; \ + } else { \ + (cur)->It = FROM_I; \ + (II) = (p)->I - gap_end_ext; \ + } \ + } else set_I(II, cur, p); \ +} +#define set_D(DD, cur, p) \ +{ \ + if ((p)->M - gap_open > (p)->D) { \ + (cur)->Dt = FROM_M; \ + (DD) = (p)->M - gap_open - gap_ext; \ + } else { \ + (cur)->Dt = FROM_D; \ + (DD) = (p)->D - gap_ext; \ + } \ +} +#define set_end_D(DD, cur, p) \ +{ \ + if (gap_end_ext >= 0) { \ + if ((p)->M - gap_end_open > (p)->D) { \ + (cur)->Dt = FROM_M; \ + (DD) = (p)->M - gap_end_open - gap_end_ext; \ + } else { \ + (cur)->Dt = FROM_D; \ + (DD) = (p)->D - gap_end_ext; \ + } \ + } else set_D(DD, cur, p); \ +} + +typedef struct { + uint8_t Mt:3, It:2, Dt:3; +} dpcell_t; + +typedef struct { + int M, I, D; +} dpscore_t; + +/*************************** + * banded global alignment * + ***************************/ +uint32_t *ka_global_core(uint8_t *seq1, int len1, uint8_t *seq2, int len2, const ka_param_t *ap, int *_score, int *n_cigar) +{ + int i, j; + dpcell_t **dpcell, *q; + dpscore_t *curr, *last, *s; + int b1, b2, tmp_end; + int *mat, end, max = 0; + uint8_t type, ctype; + uint32_t *cigar = 0; + + int gap_open, gap_ext, gap_end_open, gap_end_ext, b; + int *score_matrix, N_MATRIX_ROW; + + /* initialize some align-related parameters. just for compatibility */ + gap_open = ap->gap_open; + gap_ext = ap->gap_ext; + gap_end_open = ap->gap_end_open; + gap_end_ext = ap->gap_end_ext; + b = ap->band_width; + score_matrix = ap->matrix; + N_MATRIX_ROW = ap->row; + + if (n_cigar) *n_cigar = 0; + if (len1 == 0 || len2 == 0) return 0; + + /* calculate b1 and b2 */ + if (len1 > len2) { + b1 = len1 - len2 + b; + b2 = b; + } else { + b1 = b; + b2 = len2 - len1 + b; + } + if (b1 > len1) b1 = len1; + if (b2 > len2) b2 = len2; + --seq1; --seq2; + + /* allocate memory */ + end = (b1 + b2 <= len1)? (b1 + b2 + 1) : (len1 + 1); + dpcell = (dpcell_t**)malloc(sizeof(dpcell_t*) * (len2 + 1)); + for (j = 0; j <= len2; ++j) + dpcell[j] = (dpcell_t*)malloc(sizeof(dpcell_t) * end); + for (j = b2 + 1; j <= len2; ++j) + dpcell[j] -= j - b2; + curr = (dpscore_t*)malloc(sizeof(dpscore_t) * (len1 + 1)); + last = (dpscore_t*)malloc(sizeof(dpscore_t) * (len1 + 1)); + + /* set first row */ + SET_INF(*curr); curr->M = 0; + for (i = 1, s = curr + 1; i < b1; ++i, ++s) { + SET_INF(*s); + set_end_D(s->D, dpcell[0] + i, s - 1); + } + s = curr; curr = last; last = s; + + /* core dynamic programming, part 1 */ + tmp_end = (b2 < len2)? b2 : len2 - 1; + for (j = 1; j <= tmp_end; ++j) { + q = dpcell[j]; s = curr; SET_INF(*s); + set_end_I(s->I, q, last); + end = (j + b1 <= len1 + 1)? (j + b1 - 1) : len1; + mat = score_matrix + seq2[j] * N_MATRIX_ROW; + ++s; ++q; + for (i = 1; i != end; ++i, ++s, ++q) { + set_M(s->M, q, last + i - 1, mat[seq1[i]]); /* this will change s->M ! */ + set_I(s->I, q, last + i); + set_D(s->D, q, s - 1); + } + set_M(s->M, q, last + i - 1, mat[seq1[i]]); + set_D(s->D, q, s - 1); + if (j + b1 - 1 > len1) { /* bug fixed, 040227 */ + set_end_I(s->I, q, last + i); + } else s->I = MINOR_INF; + s = curr; curr = last; last = s; + } + /* last row for part 1, use set_end_D() instead of set_D() */ + if (j == len2 && b2 != len2 - 1) { + q = dpcell[j]; s = curr; SET_INF(*s); + set_end_I(s->I, q, last); + end = (j + b1 <= len1 + 1)? (j + b1 - 1) : len1; + mat = score_matrix + seq2[j] * N_MATRIX_ROW; + ++s; ++q; + for (i = 1; i != end; ++i, ++s, ++q) { + set_M(s->M, q, last + i - 1, mat[seq1[i]]); /* this will change s->M ! */ + set_I(s->I, q, last + i); + set_end_D(s->D, q, s - 1); + } + set_M(s->M, q, last + i - 1, mat[seq1[i]]); + set_end_D(s->D, q, s - 1); + if (j + b1 - 1 > len1) { /* bug fixed, 040227 */ + set_end_I(s->I, q, last + i); + } else s->I = MINOR_INF; + s = curr; curr = last; last = s; + ++j; + } + + /* core dynamic programming, part 2 */ + for (; j <= len2 - b2 + 1; ++j) { + SET_INF(curr[j - b2]); + mat = score_matrix + seq2[j] * N_MATRIX_ROW; + end = j + b1 - 1; + for (i = j - b2 + 1, q = dpcell[j] + i, s = curr + i; i != end; ++i, ++s, ++q) { + set_M(s->M, q, last + i - 1, mat[seq1[i]]); + set_I(s->I, q, last + i); + set_D(s->D, q, s - 1); + } + set_M(s->M, q, last + i - 1, mat[seq1[i]]); + set_D(s->D, q, s - 1); + s->I = MINOR_INF; + s = curr; curr = last; last = s; + } + + /* core dynamic programming, part 3 */ + for (; j < len2; ++j) { + SET_INF(curr[j - b2]); + mat = score_matrix + seq2[j] * N_MATRIX_ROW; + for (i = j - b2 + 1, q = dpcell[j] + i, s = curr + i; i < len1; ++i, ++s, ++q) { + set_M(s->M, q, last + i - 1, mat[seq1[i]]); + set_I(s->I, q, last + i); + set_D(s->D, q, s - 1); + } + set_M(s->M, q, last + len1 - 1, mat[seq1[i]]); + set_end_I(s->I, q, last + i); + set_D(s->D, q, s - 1); + s = curr; curr = last; last = s; + } + /* last row */ + if (j == len2) { + SET_INF(curr[j - b2]); + mat = score_matrix + seq2[j] * N_MATRIX_ROW; + for (i = j - b2 + 1, q = dpcell[j] + i, s = curr + i; i < len1; ++i, ++s, ++q) { + set_M(s->M, q, last + i - 1, mat[seq1[i]]); + set_I(s->I, q, last + i); + set_end_D(s->D, q, s - 1); + } + set_M(s->M, q, last + len1 - 1, mat[seq1[i]]); + set_end_I(s->I, q, last + i); + set_end_D(s->D, q, s - 1); + s = curr; curr = last; last = s; + } + + *_score = last[len1].M; + if (n_cigar) { /* backtrace */ + path_t *p, *path = (path_t*)malloc(sizeof(path_t) * (len1 + len2 + 2)); + i = len1; j = len2; + q = dpcell[j] + i; + s = last + len1; + max = s->M; type = q->Mt; ctype = FROM_M; + if (s->I > max) { max = s->I; type = q->It; ctype = FROM_I; } + if (s->D > max) { max = s->D; type = q->Dt; ctype = FROM_D; } + + p = path; + p->ctype = ctype; p->i = i; p->j = j; /* bug fixed 040408 */ + ++p; + do { + switch (ctype) { + case FROM_M: --i; --j; break; + case FROM_I: --j; break; + case FROM_D: --i; break; + } + q = dpcell[j] + i; + ctype = type; + switch (type) { + case FROM_M: type = q->Mt; break; + case FROM_I: type = q->It; break; + case FROM_D: type = q->Dt; break; + } + p->ctype = ctype; p->i = i; p->j = j; + ++p; + } while (i || j); + cigar = ka_path2cigar32(path, p - path - 1, n_cigar); + free(path); + } + + /* free memory */ + for (j = b2 + 1; j <= len2; ++j) + dpcell[j] += j - b2; + for (j = 0; j <= len2; ++j) + free(dpcell[j]); + free(dpcell); + free(curr); free(last); + + return cigar; +} + +typedef struct { + int M, I, D; +} score_aux_t; + +#define MINUS_INF -0x40000000 + +// matrix: len2 rows and len1 columns +int ka_global_score(const uint8_t *_seq1, int len1, const uint8_t *_seq2, int len2, const ka_param2_t *ap) +{ + +#define __score_aux(_p, _q0, _sc, _io, _ie, _do, _de) { \ + int t1, t2; \ + score_aux_t *_q; \ + _q = _q0; \ + _p->M = _q->M >= _q->I? _q->M : _q->I; \ + _p->M = _p->M >= _q->D? _p->M : _q->D; \ + _p->M += (_sc); \ + ++_q; t1 = _q->M - _io - _ie; t2 = _q->I - _ie; _p->I = t1 >= t2? t1 : t2; \ + _q = _p-1; t1 = _q->M - _do - _de; t2 = _q->D - _de; _p->D = t1 >= t2? t1 : t2; \ + } + + int i, j, bw, scmat_size = ap->row, *scmat = ap->matrix, ret; + const uint8_t *seq1, *seq2; + score_aux_t *curr, *last, *swap; + bw = abs(len1 - len2) + ap->band_width; + i = len1 > len2? len1 : len2; + if (bw > i + 1) bw = i + 1; + seq1 = _seq1 - 1; seq2 = _seq2 - 1; + curr = calloc(len1 + 2, sizeof(score_aux_t)); + last = calloc(len1 + 2, sizeof(score_aux_t)); + { // the zero-th row + int x, end = len1; + score_aux_t *p; + j = 0; + x = j + bw; end = len1 < x? len1 : x; // band end + p = curr; + p->M = 0; p->I = p->D = MINUS_INF; + for (i = 1, p = &curr[1]; i <= end; ++i, ++p) + p->M = p->I = MINUS_INF, p->D = -(ap->edo + ap->ede * i); + p->M = p->I = p->D = MINUS_INF; + swap = curr; curr = last; last = swap; + } + for (j = 1; j < len2; ++j) { + int x, beg = 0, end = len1, *scrow, col_end; + score_aux_t *p; + x = j - bw; beg = 0 > x? 0 : x; // band start + x = j + bw; end = len1 < x? len1 : x; // band end + if (beg == 0) { // from zero-th column + p = curr; + p->M = p->D = MINUS_INF; p->I = -(ap->eio + ap->eie * j); + ++beg; // then beg = 1 + } + scrow = scmat + seq2[j] * scmat_size; + if (end == len1) col_end = 1, --end; + else col_end = 0; + for (i = beg, p = &curr[beg]; i <= end; ++i, ++p) + __score_aux(p, &last[i-1], scrow[(int)seq1[i]], ap->iio, ap->iie, ap->ido, ap->ide); + if (col_end) { + __score_aux(p, &last[i-1], scrow[(int)seq1[i]], ap->eio, ap->eie, ap->ido, ap->ide); + ++p; + } + p->M = p->I = p->D = MINUS_INF; +// for (i = 0; i <= len1; ++i) printf("(%d,%d,%d) ", curr[i].M, curr[i].I, curr[i].D); putchar('\n'); + swap = curr; curr = last; last = swap; + } + { // the last row + int x, beg = 0, *scrow; + score_aux_t *p; + j = len2; + x = j - bw; beg = 0 > x? 0 : x; // band start + if (beg == 0) { // from zero-th column + p = curr; + p->M = p->D = MINUS_INF; p->I = -(ap->eio + ap->eie * j); + ++beg; // then beg = 1 + } + scrow = scmat + seq2[j] * scmat_size; + for (i = beg, p = &curr[beg]; i < len1; ++i, ++p) + __score_aux(p, &last[i-1], scrow[(int)seq1[i]], ap->iio, ap->iie, ap->edo, ap->ede); + __score_aux(p, &last[i-1], scrow[(int)seq1[i]], ap->eio, ap->eie, ap->edo, ap->ede); +// for (i = 0; i <= len1; ++i) printf("(%d,%d,%d) ", curr[i].M, curr[i].I, curr[i].D); putchar('\n'); + } + ret = curr[len1].M >= curr[len1].I? curr[len1].M : curr[len1].I; + ret = ret >= curr[len1].D? ret : curr[len1].D; + free(curr); free(last); + return ret; +} + +#ifdef _MAIN +int main(int argc, char *argv[]) +{ +// int len1 = 35, len2 = 35; +// uint8_t *seq1 = (uint8_t*)"\0\0\3\3\2\0\0\0\1\0\2\1\2\1\3\2\3\3\3\0\2\3\2\1\1\3\3\3\2\3\3\1\0\0\1"; +// uint8_t *seq2 = (uint8_t*)"\0\0\3\3\2\0\0\0\1\0\2\1\2\1\3\2\3\3\3\0\2\3\2\1\1\3\3\3\2\3\3\1\0\1\0"; + int len1 = 4, len2 = 4; + uint8_t *seq1 = (uint8_t*)"\1\0\0\1"; + uint8_t *seq2 = (uint8_t*)"\1\0\1\0"; + int sc; +// ka_global_core(seq1, 2, seq2, 1, &ka_param_qual, &sc, 0); + sc = ka_global_score(seq1, len1, seq2, len2, &ka_param2_qual); + printf("%d\n", sc); + return 0; +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/kaln.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,67 @@ +/* The MIT License + + Copyright (c) 2003-2006, 2008, 2009 by Heng Li <lh3@live.co.uk> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#ifndef LH3_KALN_H_ +#define LH3_KALN_H_ + +#include <stdint.h> + +#define MINOR_INF -1073741823 + +typedef struct { + int gap_open; + int gap_ext; + int gap_end_open; + int gap_end_ext; + + int *matrix; + int row; + int band_width; +} ka_param_t; + +typedef struct { + int iio, iie, ido, ide; + int eio, eie, edo, ede; + int *matrix; + int row; + int band_width; +} ka_param2_t; + +#ifdef __cplusplus +extern "C" { +#endif + + uint32_t *ka_global_core(uint8_t *seq1, int len1, uint8_t *seq2, int len2, const ka_param_t *ap, + int *_score, int *n_cigar); + int ka_global_score(const uint8_t *_seq1, int len1, const uint8_t *_seq2, int len2, const ka_param2_t *ap); +#ifdef __cplusplus +} +#endif + +extern ka_param_t ka_param_blast; /* = { 5, 2, 5, 2, aln_sm_blast, 5, 50 }; */ +extern ka_param_t ka_param_qual; // only use this for global alignment!!! +extern ka_param2_t ka_param2_qual; // only use this for global alignment!!! + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/khash.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,528 @@ +/* The MIT License + + Copyright (c) 2008, 2009, 2011 by Attractive Chaos <attractor@live.co.uk> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* + An example: + +#include "khash.h" +KHASH_MAP_INIT_INT(32, char) +int main() { + int ret, is_missing; + khiter_t k; + khash_t(32) *h = kh_init(32); + k = kh_put(32, h, 5, &ret); + if (!ret) kh_del(32, h, k); + kh_value(h, k) = 10; + k = kh_get(32, h, 10); + is_missing = (k == kh_end(h)); + k = kh_get(32, h, 5); + kh_del(32, h, k); + for (k = kh_begin(h); k != kh_end(h); ++k) + if (kh_exist(h, k)) kh_value(h, k) = 1; + kh_destroy(32, h); + return 0; +} +*/ + +/* + 2011-02-14 (0.2.5): + + * Allow to declare global functions. + + 2009-09-26 (0.2.4): + + * Improve portability + + 2008-09-19 (0.2.3): + + * Corrected the example + * Improved interfaces + + 2008-09-11 (0.2.2): + + * Improved speed a little in kh_put() + + 2008-09-10 (0.2.1): + + * Added kh_clear() + * Fixed a compiling error + + 2008-09-02 (0.2.0): + + * Changed to token concatenation which increases flexibility. + + 2008-08-31 (0.1.2): + + * Fixed a bug in kh_get(), which has not been tested previously. + + 2008-08-31 (0.1.1): + + * Added destructor +*/ + + +#ifndef __AC_KHASH_H +#define __AC_KHASH_H + +/*! + @header + + Generic hash table library. + + @copyright Heng Li + */ + +#define AC_VERSION_KHASH_H "0.2.5" + +#include <stdlib.h> +#include <string.h> +#include <limits.h> + +/* compipler specific configuration */ + +#if UINT_MAX == 0xffffffffu +typedef unsigned int khint32_t; +#elif ULONG_MAX == 0xffffffffu +typedef unsigned long khint32_t; +#endif + +#if ULONG_MAX == ULLONG_MAX +typedef unsigned long khint64_t; +#else +typedef unsigned long long khint64_t; +#endif + +#ifdef _MSC_VER +#define inline __inline +#endif + +typedef khint32_t khint_t; +typedef khint_t khiter_t; + +#define __ac_HASH_PRIME_SIZE 32 +static const khint32_t __ac_prime_list[__ac_HASH_PRIME_SIZE] = +{ + 0ul, 3ul, 11ul, 23ul, 53ul, + 97ul, 193ul, 389ul, 769ul, 1543ul, + 3079ul, 6151ul, 12289ul, 24593ul, 49157ul, + 98317ul, 196613ul, 393241ul, 786433ul, 1572869ul, + 3145739ul, 6291469ul, 12582917ul, 25165843ul, 50331653ul, + 100663319ul, 201326611ul, 402653189ul, 805306457ul, 1610612741ul, + 3221225473ul, 4294967291ul +}; + +#define __ac_isempty(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&2) +#define __ac_isdel(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&1) +#define __ac_iseither(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&3) +#define __ac_set_isdel_false(flag, i) (flag[i>>4]&=~(1ul<<((i&0xfU)<<1))) +#define __ac_set_isempty_false(flag, i) (flag[i>>4]&=~(2ul<<((i&0xfU)<<1))) +#define __ac_set_isboth_false(flag, i) (flag[i>>4]&=~(3ul<<((i&0xfU)<<1))) +#define __ac_set_isdel_true(flag, i) (flag[i>>4]|=1ul<<((i&0xfU)<<1)) + +static const double __ac_HASH_UPPER = 0.77; + +#define KHASH_DECLARE(name, khkey_t, khval_t) \ + typedef struct { \ + khint_t n_buckets, size, n_occupied, upper_bound; \ + khint32_t *flags; \ + khkey_t *keys; \ + khval_t *vals; \ + } kh_##name##_t; \ + extern kh_##name##_t *kh_init_##name(); \ + extern void kh_destroy_##name(kh_##name##_t *h); \ + extern void kh_clear_##name(kh_##name##_t *h); \ + extern khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key); \ + extern void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \ + extern khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret); \ + extern void kh_del_##name(kh_##name##_t *h, khint_t x); + +#define KHASH_INIT2(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ + typedef struct { \ + khint_t n_buckets, size, n_occupied, upper_bound; \ + khint32_t *flags; \ + khkey_t *keys; \ + khval_t *vals; \ + } kh_##name##_t; \ + SCOPE kh_##name##_t *kh_init_##name() { \ + return (kh_##name##_t*)calloc(1, sizeof(kh_##name##_t)); \ + } \ + SCOPE void kh_destroy_##name(kh_##name##_t *h) \ + { \ + if (h) { \ + free(h->keys); free(h->flags); \ + free(h->vals); \ + free(h); \ + } \ + } \ + SCOPE void kh_clear_##name(kh_##name##_t *h) \ + { \ + if (h && h->flags) { \ + memset(h->flags, 0xaa, ((h->n_buckets>>4) + 1) * sizeof(khint32_t)); \ + h->size = h->n_occupied = 0; \ + } \ + } \ + SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \ + { \ + if (h->n_buckets) { \ + khint_t inc, k, i, last; \ + k = __hash_func(key); i = k % h->n_buckets; \ + inc = 1 + k % (h->n_buckets - 1); last = i; \ + while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \ + if (i + inc >= h->n_buckets) i = i + inc - h->n_buckets; \ + else i += inc; \ + if (i == last) return h->n_buckets; \ + } \ + return __ac_iseither(h->flags, i)? h->n_buckets : i; \ + } else return 0; \ + } \ + SCOPE void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \ + { \ + khint32_t *new_flags = 0; \ + khint_t j = 1; \ + { \ + khint_t t = __ac_HASH_PRIME_SIZE - 1; \ + while (__ac_prime_list[t] > new_n_buckets) --t; \ + new_n_buckets = __ac_prime_list[t+1]; \ + if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) j = 0; \ + else { \ + new_flags = (khint32_t*)malloc(((new_n_buckets>>4) + 1) * sizeof(khint32_t)); \ + memset(new_flags, 0xaa, ((new_n_buckets>>4) + 1) * sizeof(khint32_t)); \ + if (h->n_buckets < new_n_buckets) { \ + h->keys = (khkey_t*)realloc(h->keys, new_n_buckets * sizeof(khkey_t)); \ + if (kh_is_map) \ + h->vals = (khval_t*)realloc(h->vals, new_n_buckets * sizeof(khval_t)); \ + } \ + } \ + } \ + if (j) { \ + for (j = 0; j != h->n_buckets; ++j) { \ + if (__ac_iseither(h->flags, j) == 0) { \ + khkey_t key = h->keys[j]; \ + khval_t val; \ + if (kh_is_map) val = h->vals[j]; \ + __ac_set_isdel_true(h->flags, j); \ + while (1) { \ + khint_t inc, k, i; \ + k = __hash_func(key); \ + i = k % new_n_buckets; \ + inc = 1 + k % (new_n_buckets - 1); \ + while (!__ac_isempty(new_flags, i)) { \ + if (i + inc >= new_n_buckets) i = i + inc - new_n_buckets; \ + else i += inc; \ + } \ + __ac_set_isempty_false(new_flags, i); \ + if (i < h->n_buckets && __ac_iseither(h->flags, i) == 0) { \ + { khkey_t tmp = h->keys[i]; h->keys[i] = key; key = tmp; } \ + if (kh_is_map) { khval_t tmp = h->vals[i]; h->vals[i] = val; val = tmp; } \ + __ac_set_isdel_true(h->flags, i); \ + } else { \ + h->keys[i] = key; \ + if (kh_is_map) h->vals[i] = val; \ + break; \ + } \ + } \ + } \ + } \ + if (h->n_buckets > new_n_buckets) { \ + h->keys = (khkey_t*)realloc(h->keys, new_n_buckets * sizeof(khkey_t)); \ + if (kh_is_map) \ + h->vals = (khval_t*)realloc(h->vals, new_n_buckets * sizeof(khval_t)); \ + } \ + free(h->flags); \ + h->flags = new_flags; \ + h->n_buckets = new_n_buckets; \ + h->n_occupied = h->size; \ + h->upper_bound = (khint_t)(h->n_buckets * __ac_HASH_UPPER + 0.5); \ + } \ + } \ + SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \ + { \ + khint_t x; \ + if (h->n_occupied >= h->upper_bound) { \ + if (h->n_buckets > (h->size<<1)) kh_resize_##name(h, h->n_buckets - 1); \ + else kh_resize_##name(h, h->n_buckets + 1); \ + } \ + { \ + khint_t inc, k, i, site, last; \ + x = site = h->n_buckets; k = __hash_func(key); i = k % h->n_buckets; \ + if (__ac_isempty(h->flags, i)) x = i; \ + else { \ + inc = 1 + k % (h->n_buckets - 1); last = i; \ + while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \ + if (__ac_isdel(h->flags, i)) site = i; \ + if (i + inc >= h->n_buckets) i = i + inc - h->n_buckets; \ + else i += inc; \ + if (i == last) { x = site; break; } \ + } \ + if (x == h->n_buckets) { \ + if (__ac_isempty(h->flags, i) && site != h->n_buckets) x = site; \ + else x = i; \ + } \ + } \ + } \ + if (__ac_isempty(h->flags, x)) { \ + h->keys[x] = key; \ + __ac_set_isboth_false(h->flags, x); \ + ++h->size; ++h->n_occupied; \ + *ret = 1; \ + } else if (__ac_isdel(h->flags, x)) { \ + h->keys[x] = key; \ + __ac_set_isboth_false(h->flags, x); \ + ++h->size; \ + *ret = 2; \ + } else *ret = 0; \ + return x; \ + } \ + SCOPE void kh_del_##name(kh_##name##_t *h, khint_t x) \ + { \ + if (x != h->n_buckets && !__ac_iseither(h->flags, x)) { \ + __ac_set_isdel_true(h->flags, x); \ + --h->size; \ + } \ + } + +#define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ + KHASH_INIT2(name, static inline, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) + +/* --- BEGIN OF HASH FUNCTIONS --- */ + +/*! @function + @abstract Integer hash function + @param key The integer [khint32_t] + @return The hash value [khint_t] + */ +#define kh_int_hash_func(key) (khint32_t)(key) +/*! @function + @abstract Integer comparison function + */ +#define kh_int_hash_equal(a, b) ((a) == (b)) +/*! @function + @abstract 64-bit integer hash function + @param key The integer [khint64_t] + @return The hash value [khint_t] + */ +#define kh_int64_hash_func(key) (khint32_t)((key)>>33^(key)^(key)<<11) +/*! @function + @abstract 64-bit integer comparison function + */ +#define kh_int64_hash_equal(a, b) ((a) == (b)) +/*! @function + @abstract const char* hash function + @param s Pointer to a null terminated string + @return The hash value + */ +static inline khint_t __ac_X31_hash_string(const char *s) +{ + khint_t h = *s; + if (h) for (++s ; *s; ++s) h = (h << 5) - h + *s; + return h; +} +/*! @function + @abstract Another interface to const char* hash function + @param key Pointer to a null terminated string [const char*] + @return The hash value [khint_t] + */ +#define kh_str_hash_func(key) __ac_X31_hash_string(key) +/*! @function + @abstract Const char* comparison function + */ +#define kh_str_hash_equal(a, b) (strcmp(a, b) == 0) + +/* --- END OF HASH FUNCTIONS --- */ + +/* Other necessary macros... */ + +/*! + @abstract Type of the hash table. + @param name Name of the hash table [symbol] + */ +#define khash_t(name) kh_##name##_t + +/*! @function + @abstract Initiate a hash table. + @param name Name of the hash table [symbol] + @return Pointer to the hash table [khash_t(name)*] + */ +#define kh_init(name) kh_init_##name() + +/*! @function + @abstract Destroy a hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + */ +#define kh_destroy(name, h) kh_destroy_##name(h) + +/*! @function + @abstract Reset a hash table without deallocating memory. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + */ +#define kh_clear(name, h) kh_clear_##name(h) + +/*! @function + @abstract Resize a hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param s New size [khint_t] + */ +#define kh_resize(name, h, s) kh_resize_##name(h, s) + +/*! @function + @abstract Insert a key to the hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param k Key [type of keys] + @param r Extra return code: 0 if the key is present in the hash table; + 1 if the bucket is empty (never used); 2 if the element in + the bucket has been deleted [int*] + @return Iterator to the inserted element [khint_t] + */ +#define kh_put(name, h, k, r) kh_put_##name(h, k, r) + +/*! @function + @abstract Retrieve a key from the hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param k Key [type of keys] + @return Iterator to the found element, or kh_end(h) is the element is absent [khint_t] + */ +#define kh_get(name, h, k) kh_get_##name(h, k) + +/*! @function + @abstract Remove a key from the hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param k Iterator to the element to be deleted [khint_t] + */ +#define kh_del(name, h, k) kh_del_##name(h, k) + + +/*! @function + @abstract Test whether a bucket contains data. + @param h Pointer to the hash table [khash_t(name)*] + @param x Iterator to the bucket [khint_t] + @return 1 if containing data; 0 otherwise [int] + */ +#define kh_exist(h, x) (!__ac_iseither((h)->flags, (x))) + +/*! @function + @abstract Get key given an iterator + @param h Pointer to the hash table [khash_t(name)*] + @param x Iterator to the bucket [khint_t] + @return Key [type of keys] + */ +#define kh_key(h, x) ((h)->keys[x]) + +/*! @function + @abstract Get value given an iterator + @param h Pointer to the hash table [khash_t(name)*] + @param x Iterator to the bucket [khint_t] + @return Value [type of values] + @discussion For hash sets, calling this results in segfault. + */ +#define kh_val(h, x) ((h)->vals[x]) + +/*! @function + @abstract Alias of kh_val() + */ +#define kh_value(h, x) ((h)->vals[x]) + +/*! @function + @abstract Get the start iterator + @param h Pointer to the hash table [khash_t(name)*] + @return The start iterator [khint_t] + */ +#define kh_begin(h) (khint_t)(0) + +/*! @function + @abstract Get the end iterator + @param h Pointer to the hash table [khash_t(name)*] + @return The end iterator [khint_t] + */ +#define kh_end(h) ((h)->n_buckets) + +/*! @function + @abstract Get the number of elements in the hash table + @param h Pointer to the hash table [khash_t(name)*] + @return Number of elements in the hash table [khint_t] + */ +#define kh_size(h) ((h)->size) + +/*! @function + @abstract Get the number of buckets in the hash table + @param h Pointer to the hash table [khash_t(name)*] + @return Number of buckets in the hash table [khint_t] + */ +#define kh_n_buckets(h) ((h)->n_buckets) + +/* More conenient interfaces */ + +/*! @function + @abstract Instantiate a hash set containing integer keys + @param name Name of the hash table [symbol] + */ +#define KHASH_SET_INIT_INT(name) \ + KHASH_INIT(name, khint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal) + +/*! @function + @abstract Instantiate a hash map containing integer keys + @param name Name of the hash table [symbol] + @param khval_t Type of values [type] + */ +#define KHASH_MAP_INIT_INT(name, khval_t) \ + KHASH_INIT(name, khint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal) + +/*! @function + @abstract Instantiate a hash map containing 64-bit integer keys + @param name Name of the hash table [symbol] + */ +#define KHASH_SET_INIT_INT64(name) \ + KHASH_INIT(name, khint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal) + +/*! @function + @abstract Instantiate a hash map containing 64-bit integer keys + @param name Name of the hash table [symbol] + @param khval_t Type of values [type] + */ +#define KHASH_MAP_INIT_INT64(name, khval_t) \ + KHASH_INIT(name, khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal) + +typedef const char *kh_cstr_t; +/*! @function + @abstract Instantiate a hash map containing const char* keys + @param name Name of the hash table [symbol] + */ +#define KHASH_SET_INIT_STR(name) \ + KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal) + +/*! @function + @abstract Instantiate a hash map containing const char* keys + @param name Name of the hash table [symbol] + @param khval_t Type of values [type] + */ +#define KHASH_MAP_INIT_STR(name, khval_t) \ + KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal) + +#endif /* __AC_KHASH_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/klist.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,96 @@ +#ifndef _LH3_KLIST_H +#define _LH3_KLIST_H + +#include <stdlib.h> + +#define KMEMPOOL_INIT(name, kmptype_t, kmpfree_f) \ + typedef struct { \ + size_t cnt, n, max; \ + kmptype_t **buf; \ + } kmp_##name##_t; \ + static inline kmp_##name##_t *kmp_init_##name() { \ + return calloc(1, sizeof(kmp_##name##_t)); \ + } \ + static inline void kmp_destroy_##name(kmp_##name##_t *mp) { \ + size_t k; \ + for (k = 0; k < mp->n; ++k) { \ + kmpfree_f(mp->buf[k]); free(mp->buf[k]); \ + } \ + free(mp->buf); free(mp); \ + } \ + static inline kmptype_t *kmp_alloc_##name(kmp_##name##_t *mp) { \ + ++mp->cnt; \ + if (mp->n == 0) return calloc(1, sizeof(kmptype_t)); \ + return mp->buf[--mp->n]; \ + } \ + static inline void kmp_free_##name(kmp_##name##_t *mp, kmptype_t *p) { \ + --mp->cnt; \ + if (mp->n == mp->max) { \ + mp->max = mp->max? mp->max<<1 : 16; \ + mp->buf = realloc(mp->buf, sizeof(void*) * mp->max); \ + } \ + mp->buf[mp->n++] = p; \ + } + +#define kmempool_t(name) kmp_##name##_t +#define kmp_init(name) kmp_init_##name() +#define kmp_destroy(name, mp) kmp_destroy_##name(mp) +#define kmp_alloc(name, mp) kmp_alloc_##name(mp) +#define kmp_free(name, mp, p) kmp_free_##name(mp, p) + +#define KLIST_INIT(name, kltype_t, kmpfree_t) \ + struct __kl1_##name { \ + kltype_t data; \ + struct __kl1_##name *next; \ + }; \ + typedef struct __kl1_##name kl1_##name; \ + KMEMPOOL_INIT(name, kl1_##name, kmpfree_t) \ + typedef struct { \ + kl1_##name *head, *tail; \ + kmp_##name##_t *mp; \ + size_t size; \ + } kl_##name##_t; \ + static inline kl_##name##_t *kl_init_##name() { \ + kl_##name##_t *kl = calloc(1, sizeof(kl_##name##_t)); \ + kl->mp = kmp_init(name); \ + kl->head = kl->tail = kmp_alloc(name, kl->mp); \ + kl->head->next = 0; \ + return kl; \ + } \ + static inline void kl_destroy_##name(kl_##name##_t *kl) { \ + kl1_##name *p; \ + for (p = kl->head; p != kl->tail; p = p->next) \ + kmp_free(name, kl->mp, p); \ + kmp_free(name, kl->mp, p); \ + kmp_destroy(name, kl->mp); \ + free(kl); \ + } \ + static inline kltype_t *kl_pushp_##name(kl_##name##_t *kl) { \ + kl1_##name *q, *p = kmp_alloc(name, kl->mp); \ + q = kl->tail; p->next = 0; kl->tail->next = p; kl->tail = p; \ + ++kl->size; \ + return &q->data; \ + } \ + static inline int kl_shift_##name(kl_##name##_t *kl, kltype_t *d) { \ + kl1_##name *p; \ + if (kl->head->next == 0) return -1; \ + --kl->size; \ + p = kl->head; kl->head = kl->head->next; \ + if (d) *d = p->data; \ + kmp_free(name, kl->mp, p); \ + return 0; \ + } + +#define kliter_t(name) kl1_##name +#define klist_t(name) kl_##name##_t +#define kl_val(iter) ((iter)->data) +#define kl_next(iter) ((iter)->next) +#define kl_begin(kl) ((kl)->head) +#define kl_end(kl) ((kl)->tail) + +#define kl_init(name) kl_init_##name() +#define kl_destroy(name, kl) kl_destroy_##name(kl) +#define kl_pushp(name, kl) kl_pushp_##name(kl) +#define kl_shift(name, kl, d) kl_shift_##name(kl, d) + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/knetfile.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,632 @@ +/* The MIT License + + Copyright (c) 2008 by Genome Research Ltd (GRL). + 2010 by Attractive Chaos <attractor@live.co.uk> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* Probably I will not do socket programming in the next few years and + therefore I decide to heavily annotate this file, for Linux and + Windows as well. -ac */ + +#include <time.h> +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> + +#ifndef _WIN32 +#include <netdb.h> +#include <arpa/inet.h> +#include <sys/socket.h> +#endif + +#include "knetfile.h" + +/* In winsock.h, the type of a socket is SOCKET, which is: "typedef + * u_int SOCKET". An invalid SOCKET is: "(SOCKET)(~0)", or signed + * integer -1. In knetfile.c, I use "int" for socket type + * throughout. This should be improved to avoid confusion. + * + * In Linux/Mac, recv() and read() do almost the same thing. You can see + * in the header file that netread() is simply an alias of read(). In + * Windows, however, they are different and using recv() is mandatory. + */ + +/* This function tests if the file handler is ready for reading (or + * writing if is_read==0). */ +static int socket_wait(int fd, int is_read) +{ + fd_set fds, *fdr = 0, *fdw = 0; + struct timeval tv; + int ret; + tv.tv_sec = 5; tv.tv_usec = 0; // 5 seconds time out + FD_ZERO(&fds); + FD_SET(fd, &fds); + if (is_read) fdr = &fds; + else fdw = &fds; + ret = select(fd+1, fdr, fdw, 0, &tv); +#ifndef _WIN32 + if (ret == -1) perror("select"); +#else + if (ret == 0) + fprintf(stderr, "select time-out\n"); + else if (ret == SOCKET_ERROR) + fprintf(stderr, "select: %d\n", WSAGetLastError()); +#endif + return ret; +} + +#ifndef _WIN32 +/* This function does not work with Windows due to the lack of + * getaddrinfo() in winsock. It is addapted from an example in "Beej's + * Guide to Network Programming" (http://beej.us/guide/bgnet/). */ +static int socket_connect(const char *host, const char *port) +{ +#define __err_connect(func) do { perror(func); freeaddrinfo(res); return -1; } while (0) + + int on = 1, fd; + struct linger lng = { 0, 0 }; + struct addrinfo hints, *res = 0; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + /* In Unix/Mac, getaddrinfo() is the most convenient way to get + * server information. */ + if (getaddrinfo(host, port, &hints, &res) != 0) __err_connect("getaddrinfo"); + if ((fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) __err_connect("socket"); + /* The following two setsockopt() are used by ftplib + * (http://nbpfaus.net/~pfau/ftplib/). I am not sure if they + * necessary. */ + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) __err_connect("setsockopt"); + if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &lng, sizeof(lng)) == -1) __err_connect("setsockopt"); + if (connect(fd, res->ai_addr, res->ai_addrlen) != 0) __err_connect("connect"); + freeaddrinfo(res); + return fd; +} +#else +/* MinGW's printf has problem with "%lld" */ +char *int64tostr(char *buf, int64_t x) +{ + int cnt; + int i = 0; + do { + buf[i++] = '0' + x % 10; + x /= 10; + } while (x); + buf[i] = 0; + for (cnt = i, i = 0; i < cnt/2; ++i) { + int c = buf[i]; buf[i] = buf[cnt-i-1]; buf[cnt-i-1] = c; + } + return buf; +} + +int64_t strtoint64(const char *buf) +{ + int64_t x; + for (x = 0; *buf != '\0'; ++buf) + x = x * 10 + ((int64_t) *buf - 48); + return x; +} +/* In windows, the first thing is to establish the TCP connection. */ +int knet_win32_init() +{ + WSADATA wsaData; + return WSAStartup(MAKEWORD(2, 2), &wsaData); +} +void knet_win32_destroy() +{ + WSACleanup(); +} +/* A slightly modfied version of the following function also works on + * Mac (and presummably Linux). However, this function is not stable on + * my Mac. It sometimes works fine but sometimes does not. Therefore for + * non-Windows OS, I do not use this one. */ +static SOCKET socket_connect(const char *host, const char *port) +{ +#define __err_connect(func) \ + do { \ + fprintf(stderr, "%s: %d\n", func, WSAGetLastError()); \ + return -1; \ + } while (0) + + int on = 1; + SOCKET fd; + struct linger lng = { 0, 0 }; + struct sockaddr_in server; + struct hostent *hp = 0; + // open socket + if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) __err_connect("socket"); + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) == -1) __err_connect("setsockopt"); + if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char*)&lng, sizeof(lng)) == -1) __err_connect("setsockopt"); + // get host info + if (isalpha(host[0])) hp = gethostbyname(host); + else { + struct in_addr addr; + addr.s_addr = inet_addr(host); + hp = gethostbyaddr((char*)&addr, 4, AF_INET); + } + if (hp == 0) __err_connect("gethost"); + // connect + server.sin_addr.s_addr = *((unsigned long*)hp->h_addr); + server.sin_family= AF_INET; + server.sin_port = htons(atoi(port)); + if (connect(fd, (struct sockaddr*)&server, sizeof(server)) != 0) __err_connect("connect"); + // freehostent(hp); // strangely in MSDN, hp is NOT freed (memory leak?!) + return fd; +} +#endif + +static off_t my_netread(int fd, void *buf, off_t len) +{ + off_t rest = len, curr, l = 0; + /* recv() and read() may not read the required length of data with + * one call. They have to be called repeatedly. */ + while (rest) { + if (socket_wait(fd, 1) <= 0) break; // socket is not ready for reading + curr = netread(fd, buf + l, rest); + /* According to the glibc manual, section 13.2, a zero returned + * value indicates end-of-file (EOF), which should mean that + * read() will not return zero if EOF has not been met but data + * are not immediately available. */ + if (curr == 0) break; + l += curr; rest -= curr; + } + return l; +} + +/************************* + * FTP specific routines * + *************************/ + +static int kftp_get_response(knetFile *ftp) +{ +#ifndef _WIN32 + unsigned char c; +#else + char c; +#endif + int n = 0; + char *p; + if (socket_wait(ftp->ctrl_fd, 1) <= 0) return 0; + while (netread(ftp->ctrl_fd, &c, 1)) { // FIXME: this is *VERY BAD* for unbuffered I/O + //fputc(c, stderr); + if (n >= ftp->max_response) { + ftp->max_response = ftp->max_response? ftp->max_response<<1 : 256; + ftp->response = realloc(ftp->response, ftp->max_response); + } + ftp->response[n++] = c; + if (c == '\n') { + if (n >= 4 && isdigit(ftp->response[0]) && isdigit(ftp->response[1]) && isdigit(ftp->response[2]) + && ftp->response[3] != '-') break; + n = 0; + continue; + } + } + if (n < 2) return -1; + ftp->response[n-2] = 0; + return strtol(ftp->response, &p, 0); +} + +static int kftp_send_cmd(knetFile *ftp, const char *cmd, int is_get) +{ + if (socket_wait(ftp->ctrl_fd, 0) <= 0) return -1; // socket is not ready for writing + netwrite(ftp->ctrl_fd, cmd, strlen(cmd)); + return is_get? kftp_get_response(ftp) : 0; +} + +static int kftp_pasv_prep(knetFile *ftp) +{ + char *p; + int v[6]; + kftp_send_cmd(ftp, "PASV\r\n", 1); + for (p = ftp->response; *p && *p != '('; ++p); + if (*p != '(') return -1; + ++p; + sscanf(p, "%d,%d,%d,%d,%d,%d", &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]); + memcpy(ftp->pasv_ip, v, 4 * sizeof(int)); + ftp->pasv_port = (v[4]<<8&0xff00) + v[5]; + return 0; +} + + +static int kftp_pasv_connect(knetFile *ftp) +{ + char host[80], port[10]; + if (ftp->pasv_port == 0) { + fprintf(stderr, "[kftp_pasv_connect] kftp_pasv_prep() is not called before hand.\n"); + return -1; + } + sprintf(host, "%d.%d.%d.%d", ftp->pasv_ip[0], ftp->pasv_ip[1], ftp->pasv_ip[2], ftp->pasv_ip[3]); + sprintf(port, "%d", ftp->pasv_port); + ftp->fd = socket_connect(host, port); + if (ftp->fd == -1) return -1; + return 0; +} + +int kftp_connect(knetFile *ftp) +{ + ftp->ctrl_fd = socket_connect(ftp->host, ftp->port); + if (ftp->ctrl_fd == -1) return -1; + kftp_get_response(ftp); + kftp_send_cmd(ftp, "USER anonymous\r\n", 1); + kftp_send_cmd(ftp, "PASS kftp@\r\n", 1); + kftp_send_cmd(ftp, "TYPE I\r\n", 1); + return 0; +} + +int kftp_reconnect(knetFile *ftp) +{ + if (ftp->ctrl_fd != -1) { + netclose(ftp->ctrl_fd); + ftp->ctrl_fd = -1; + } + netclose(ftp->fd); + ftp->fd = -1; + return kftp_connect(ftp); +} + +// initialize ->type, ->host, ->retr and ->size +knetFile *kftp_parse_url(const char *fn, const char *mode) +{ + knetFile *fp; + char *p; + int l; + if (strstr(fn, "ftp://") != fn) return 0; + for (p = (char*)fn + 6; *p && *p != '/'; ++p); + if (*p != '/') return 0; + l = p - fn - 6; + fp = calloc(1, sizeof(knetFile)); + fp->type = KNF_TYPE_FTP; + fp->fd = -1; + /* the Linux/Mac version of socket_connect() also recognizes a port + * like "ftp", but the Windows version does not. */ + fp->port = strdup("21"); + fp->host = calloc(l + 1, 1); + if (strchr(mode, 'c')) fp->no_reconnect = 1; + strncpy(fp->host, fn + 6, l); + fp->retr = calloc(strlen(p) + 8, 1); + sprintf(fp->retr, "RETR %s\r\n", p); + fp->size_cmd = calloc(strlen(p) + 8, 1); + sprintf(fp->size_cmd, "SIZE %s\r\n", p); + fp->seek_offset = 0; + return fp; +} +// place ->fd at offset off +int kftp_connect_file(knetFile *fp) +{ + int ret; + long long file_size; + if (fp->fd != -1) { + netclose(fp->fd); + if (fp->no_reconnect) kftp_get_response(fp); + } + kftp_pasv_prep(fp); + kftp_send_cmd(fp, fp->size_cmd, 1); +#ifndef _WIN32 + if ( sscanf(fp->response,"%*d %lld", &file_size) != 1 ) + { + fprintf(stderr,"[kftp_connect_file] %s\n", fp->response); + return -1; + } +#else + const char *p = fp->response; + while (*p != ' ') ++p; + while (*p < '0' || *p > '9') ++p; + file_size = strtoint64(p); +#endif + fp->file_size = file_size; + if (fp->offset>=0) { + char tmp[32]; +#ifndef _WIN32 + sprintf(tmp, "REST %lld\r\n", (long long)fp->offset); +#else + strcpy(tmp, "REST "); + int64tostr(tmp + 5, fp->offset); + strcat(tmp, "\r\n"); +#endif + kftp_send_cmd(fp, tmp, 1); + } + kftp_send_cmd(fp, fp->retr, 0); + kftp_pasv_connect(fp); + ret = kftp_get_response(fp); + if (ret != 150) { + fprintf(stderr, "[kftp_connect_file] %s\n", fp->response); + netclose(fp->fd); + fp->fd = -1; + return -1; + } + fp->is_ready = 1; + return 0; +} + + +/************************** + * HTTP specific routines * + **************************/ + +knetFile *khttp_parse_url(const char *fn, const char *mode) +{ + knetFile *fp; + char *p, *proxy, *q; + int l; + if (strstr(fn, "http://") != fn) return 0; + // set ->http_host + for (p = (char*)fn + 7; *p && *p != '/'; ++p); + l = p - fn - 7; + fp = calloc(1, sizeof(knetFile)); + fp->http_host = calloc(l + 1, 1); + strncpy(fp->http_host, fn + 7, l); + fp->http_host[l] = 0; + for (q = fp->http_host; *q && *q != ':'; ++q); + if (*q == ':') *q++ = 0; + // get http_proxy + proxy = getenv("http_proxy"); + // set ->host, ->port and ->path + if (proxy == 0) { + fp->host = strdup(fp->http_host); // when there is no proxy, server name is identical to http_host name. + fp->port = strdup(*q? q : "80"); + fp->path = strdup(*p? p : "/"); + } else { + fp->host = (strstr(proxy, "http://") == proxy)? strdup(proxy + 7) : strdup(proxy); + for (q = fp->host; *q && *q != ':'; ++q); + if (*q == ':') *q++ = 0; + fp->port = strdup(*q? q : "80"); + fp->path = strdup(fn); + } + fp->type = KNF_TYPE_HTTP; + fp->ctrl_fd = fp->fd = -1; + fp->seek_offset = 0; + return fp; +} + +int khttp_connect_file(knetFile *fp) +{ + int ret, l = 0; + char *buf, *p; + if (fp->fd != -1) netclose(fp->fd); + fp->fd = socket_connect(fp->host, fp->port); + buf = calloc(0x10000, 1); // FIXME: I am lazy... But in principle, 64KB should be large enough. + l += sprintf(buf + l, "GET %s HTTP/1.0\r\nHost: %s\r\n", fp->path, fp->http_host); + l += sprintf(buf + l, "Range: bytes=%lld-\r\n", (long long)fp->offset); + l += sprintf(buf + l, "\r\n"); + netwrite(fp->fd, buf, l); + l = 0; + while (netread(fp->fd, buf + l, 1)) { // read HTTP header; FIXME: bad efficiency + if (buf[l] == '\n' && l >= 3) + if (strncmp(buf + l - 3, "\r\n\r\n", 4) == 0) break; + ++l; + } + buf[l] = 0; + if (l < 14) { // prematured header + netclose(fp->fd); + fp->fd = -1; + return -1; + } + ret = strtol(buf + 8, &p, 0); // HTTP return code + if (ret == 200 && fp->offset>0) { // 200 (complete result); then skip beginning of the file + off_t rest = fp->offset; + while (rest) { + off_t l = rest < 0x10000? rest : 0x10000; + rest -= my_netread(fp->fd, buf, l); + } + } else if (ret != 206 && ret != 200) { + free(buf); + fprintf(stderr, "[khttp_connect_file] fail to open file (HTTP code: %d).\n", ret); + netclose(fp->fd); + fp->fd = -1; + return -1; + } + free(buf); + fp->is_ready = 1; + return 0; +} + +/******************** + * Generic routines * + ********************/ + +knetFile *knet_open(const char *fn, const char *mode) +{ + knetFile *fp = 0; + if (mode[0] != 'r') { + fprintf(stderr, "[kftp_open] only mode \"r\" is supported.\n"); + return 0; + } + if (strstr(fn, "ftp://") == fn) { + fp = kftp_parse_url(fn, mode); + if (fp == 0) return 0; + if (kftp_connect(fp) == -1) { + knet_close(fp); + return 0; + } + kftp_connect_file(fp); + } else if (strstr(fn, "http://") == fn) { + fp = khttp_parse_url(fn, mode); + if (fp == 0) return 0; + khttp_connect_file(fp); + } else { // local file +#ifdef _WIN32 + /* In windows, O_BINARY is necessary. In Linux/Mac, O_BINARY may + * be undefined on some systems, although it is defined on my + * Mac and the Linux I have tested on. */ + int fd = open(fn, O_RDONLY | O_BINARY); +#else + int fd = open(fn, O_RDONLY); +#endif + if (fd == -1) { + perror("open"); + return 0; + } + fp = (knetFile*)calloc(1, sizeof(knetFile)); + fp->type = KNF_TYPE_LOCAL; + fp->fd = fd; + fp->ctrl_fd = -1; + } + if (fp && fp->fd == -1) { + knet_close(fp); + return 0; + } + return fp; +} + +knetFile *knet_dopen(int fd, const char *mode) +{ + knetFile *fp = (knetFile*)calloc(1, sizeof(knetFile)); + fp->type = KNF_TYPE_LOCAL; + fp->fd = fd; + return fp; +} + +off_t knet_read(knetFile *fp, void *buf, off_t len) +{ + off_t l = 0; + if (fp->fd == -1) return 0; + if (fp->type == KNF_TYPE_FTP) { + if (fp->is_ready == 0) { + if (!fp->no_reconnect) kftp_reconnect(fp); + kftp_connect_file(fp); + } + } else if (fp->type == KNF_TYPE_HTTP) { + if (fp->is_ready == 0) + khttp_connect_file(fp); + } + if (fp->type == KNF_TYPE_LOCAL) { // on Windows, the following block is necessary; not on UNIX + off_t rest = len, curr; + while (rest) { + do { + curr = read(fp->fd, buf + l, rest); + } while (curr < 0 && EINTR == errno); + if (curr < 0) return -1; + if (curr == 0) break; + l += curr; rest -= curr; + } + } else l = my_netread(fp->fd, buf, len); + fp->offset += l; + return l; +} + +off_t knet_seek(knetFile *fp, int64_t off, int whence) +{ + if (whence == SEEK_SET && off == fp->offset) return 0; + if (fp->type == KNF_TYPE_LOCAL) { + /* Be aware that lseek() returns the offset after seeking, + * while fseek() returns zero on success. */ + off_t offset = lseek(fp->fd, off, whence); + if (offset == -1) { + // Be silent, it is OK for knet_seek to fail when the file is streamed + // fprintf(stderr,"[knet_seek] %s\n", strerror(errno)); + return -1; + } + fp->offset = offset; + return 0; + } + else if (fp->type == KNF_TYPE_FTP) + { + if (whence==SEEK_CUR) + fp->offset += off; + else if (whence==SEEK_SET) + fp->offset = off; + else if ( whence==SEEK_END) + fp->offset = fp->file_size+off; + fp->is_ready = 0; + return 0; + } + else if (fp->type == KNF_TYPE_HTTP) + { + if (whence == SEEK_END) { // FIXME: can we allow SEEK_END in future? + fprintf(stderr, "[knet_seek] SEEK_END is not supported for HTTP. Offset is unchanged.\n"); + errno = ESPIPE; + return -1; + } + if (whence==SEEK_CUR) + fp->offset += off; + else if (whence==SEEK_SET) + fp->offset = off; + fp->is_ready = 0; + return 0; + } + errno = EINVAL; + fprintf(stderr,"[knet_seek] %s\n", strerror(errno)); + return -1; +} + +int knet_close(knetFile *fp) +{ + if (fp == 0) return 0; + if (fp->ctrl_fd != -1) netclose(fp->ctrl_fd); // FTP specific + if (fp->fd != -1) { + /* On Linux/Mac, netclose() is an alias of close(), but on + * Windows, it is an alias of closesocket(). */ + if (fp->type == KNF_TYPE_LOCAL) close(fp->fd); + else netclose(fp->fd); + } + free(fp->host); free(fp->port); + free(fp->response); free(fp->retr); // FTP specific + free(fp->path); free(fp->http_host); // HTTP specific + free(fp); + return 0; +} + +#ifdef KNETFILE_MAIN +int main(void) +{ + char *buf; + knetFile *fp; + int type = 4, l; +#ifdef _WIN32 + knet_win32_init(); +#endif + buf = calloc(0x100000, 1); + if (type == 0) { + fp = knet_open("knetfile.c", "r"); + knet_seek(fp, 1000, SEEK_SET); + } else if (type == 1) { // NCBI FTP, large file + fp = knet_open("ftp://ftp.ncbi.nih.gov/1000genomes/ftp/data/NA12878/alignment/NA12878.chrom6.SLX.SRP000032.2009_06.bam", "r"); + knet_seek(fp, 2500000000ll, SEEK_SET); + l = knet_read(fp, buf, 255); + } else if (type == 2) { + fp = knet_open("ftp://ftp.sanger.ac.uk/pub4/treefam/tmp/index.shtml", "r"); + knet_seek(fp, 1000, SEEK_SET); + } else if (type == 3) { + fp = knet_open("http://www.sanger.ac.uk/Users/lh3/index.shtml", "r"); + knet_seek(fp, 1000, SEEK_SET); + } else if (type == 4) { + fp = knet_open("http://www.sanger.ac.uk/Users/lh3/ex1.bam", "r"); + knet_read(fp, buf, 10000); + knet_seek(fp, 20000, SEEK_SET); + knet_seek(fp, 10000, SEEK_SET); + l = knet_read(fp, buf+10000, 10000000) + 10000; + } + if (type != 4 && type != 1) { + knet_read(fp, buf, 255); + buf[255] = 0; + printf("%s\n", buf); + } else write(fileno(stdout), buf, l); + knet_close(fp); + free(buf); + return 0; +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/knetfile.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,75 @@ +#ifndef KNETFILE_H +#define KNETFILE_H + +#include <stdint.h> +#include <fcntl.h> + +#ifndef _WIN32 +#define netread(fd, ptr, len) read(fd, ptr, len) +#define netwrite(fd, ptr, len) write(fd, ptr, len) +#define netclose(fd) close(fd) +#else +#include <winsock2.h> +#define netread(fd, ptr, len) recv(fd, ptr, len, 0) +#define netwrite(fd, ptr, len) send(fd, ptr, len, 0) +#define netclose(fd) closesocket(fd) +#endif + +// FIXME: currently I/O is unbuffered + +#define KNF_TYPE_LOCAL 1 +#define KNF_TYPE_FTP 2 +#define KNF_TYPE_HTTP 3 + +typedef struct knetFile_s { + int type, fd; + int64_t offset; + char *host, *port; + + // the following are for FTP only + int ctrl_fd, pasv_ip[4], pasv_port, max_response, no_reconnect, is_ready; + char *response, *retr, *size_cmd; + int64_t seek_offset; // for lazy seek + int64_t file_size; + + // the following are for HTTP only + char *path, *http_host; +} knetFile; + +#define knet_tell(fp) ((fp)->offset) +#define knet_fileno(fp) ((fp)->fd) + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _WIN32 + int knet_win32_init(); + void knet_win32_destroy(); +#endif + + knetFile *knet_open(const char *fn, const char *mode); + + /* + This only works with local files. + */ + knetFile *knet_dopen(int fd, const char *mode); + + /* + If ->is_ready==0, this routine updates ->fd; otherwise, it simply + reads from ->fd. + */ + off_t knet_read(knetFile *fp, void *buf, off_t len); + + /* + This routine only sets ->offset and ->is_ready=0. It does not + communicate with the FTP server. + */ + off_t knet_seek(knetFile *fp, int64_t off, int whence); + int knet_close(knetFile *fp); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/kprobaln.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,278 @@ +/* The MIT License + + Copyright (c) 2003-2006, 2008-2010, by Heng Li <lh3lh3@live.co.uk> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> +#include <math.h> +#include "kprobaln.h" + +/***************************************** + * Probabilistic banded glocal alignment * + *****************************************/ + +#define EI .25 +#define EM .33333333333 + +static float g_qual2prob[256]; + +#define set_u(u, b, i, k) { int x=(i)-(b); x=x>0?x:0; (u)=((k)-x+1)*3; } + +kpa_par_t kpa_par_def = { 0.001, 0.1, 10 }; +kpa_par_t kpa_par_alt = { 0.0001, 0.01, 10 }; + +/* + The topology of the profile HMM: + + /\ /\ /\ /\ + I[1] I[k-1] I[k] I[L] + ^ \ \ ^ \ ^ \ \ ^ + | \ \ | \ | \ \ | + M[0] M[1] -> ... -> M[k-1] -> M[k] -> ... -> M[L] M[L+1] + \ \/ \/ \/ / + \ /\ /\ /\ / + -> D[k-1] -> D[k] -> + + M[0] points to every {M,I}[k] and every {M,I}[k] points M[L+1]. + + On input, _ref is the reference sequence and _query is the query + sequence. Both are sequences of 0/1/2/3/4 where 4 stands for an + ambiguous residue. iqual is the base quality. c sets the gap open + probability, gap extension probability and band width. + + On output, state and q are arrays of length l_query. The higher 30 + bits give the reference position the query base is matched to and the + lower two bits can be 0 (an alignment match) or 1 (an + insertion). q[i] gives the phred scaled posterior probability of + state[i] being wrong. + */ +int kpa_glocal(const uint8_t *_ref, int l_ref, const uint8_t *_query, int l_query, const uint8_t *iqual, + const kpa_par_t *c, int *state, uint8_t *q) +{ + double **f, **b = 0, *s, m[9], sI, sM, bI, bM, pb; + float *qual, *_qual; + const uint8_t *ref, *query; + int bw, bw2, i, k, is_diff = 0, is_backward = 1, Pr; + + /*** initialization ***/ + is_backward = state && q? 1 : 0; + ref = _ref - 1; query = _query - 1; // change to 1-based coordinate + bw = l_ref > l_query? l_ref : l_query; + if (bw > c->bw) bw = c->bw; + if (bw < abs(l_ref - l_query)) bw = abs(l_ref - l_query); + bw2 = bw * 2 + 1; + // allocate the forward and backward matrices f[][] and b[][] and the scaling array s[] + f = calloc(l_query+1, sizeof(void*)); + if (is_backward) b = calloc(l_query+1, sizeof(void*)); + for (i = 0; i <= l_query; ++i) { + f[i] = calloc(bw2 * 3 + 6, sizeof(double)); // FIXME: this is over-allocated for very short seqs + if (is_backward) b[i] = calloc(bw2 * 3 + 6, sizeof(double)); + } + s = calloc(l_query+2, sizeof(double)); // s[] is the scaling factor to avoid underflow + // initialize qual + _qual = calloc(l_query, sizeof(float)); + if (g_qual2prob[0] == 0) + for (i = 0; i < 256; ++i) + g_qual2prob[i] = pow(10, -i/10.); + for (i = 0; i < l_query; ++i) _qual[i] = g_qual2prob[iqual? iqual[i] : 30]; + qual = _qual - 1; + // initialize transition probability + sM = sI = 1. / (2 * l_query + 2); // the value here seems not to affect results; FIXME: need proof + m[0*3+0] = (1 - c->d - c->d) * (1 - sM); m[0*3+1] = m[0*3+2] = c->d * (1 - sM); + m[1*3+0] = (1 - c->e) * (1 - sI); m[1*3+1] = c->e * (1 - sI); m[1*3+2] = 0.; + m[2*3+0] = 1 - c->e; m[2*3+1] = 0.; m[2*3+2] = c->e; + bM = (1 - c->d) / l_ref; bI = c->d / l_ref; // (bM+bI)*l_ref==1 + /*** forward ***/ + // f[0] + set_u(k, bw, 0, 0); + f[0][k] = s[0] = 1.; + { // f[1] + double *fi = f[1], sum; + int beg = 1, end = l_ref < bw + 1? l_ref : bw + 1, _beg, _end; + for (k = beg, sum = 0.; k <= end; ++k) { + int u; + double e = (ref[k] > 3 || query[1] > 3)? 1. : ref[k] == query[1]? 1. - qual[1] : qual[1] * EM; + set_u(u, bw, 1, k); + fi[u+0] = e * bM; fi[u+1] = EI * bI; + sum += fi[u] + fi[u+1]; + } + // rescale + s[1] = sum; + set_u(_beg, bw, 1, beg); set_u(_end, bw, 1, end); _end += 2; + for (k = _beg; k <= _end; ++k) fi[k] /= sum; + } + // f[2..l_query] + for (i = 2; i <= l_query; ++i) { + double *fi = f[i], *fi1 = f[i-1], sum, qli = qual[i]; + int beg = 1, end = l_ref, x, _beg, _end; + uint8_t qyi = query[i]; + x = i - bw; beg = beg > x? beg : x; // band start + x = i + bw; end = end < x? end : x; // band end + for (k = beg, sum = 0.; k <= end; ++k) { + int u, v11, v01, v10; + double e; + e = (ref[k] > 3 || qyi > 3)? 1. : ref[k] == qyi? 1. - qli : qli * EM; + set_u(u, bw, i, k); set_u(v11, bw, i-1, k-1); set_u(v10, bw, i-1, k); set_u(v01, bw, i, k-1); + fi[u+0] = e * (m[0] * fi1[v11+0] + m[3] * fi1[v11+1] + m[6] * fi1[v11+2]); + fi[u+1] = EI * (m[1] * fi1[v10+0] + m[4] * fi1[v10+1]); + fi[u+2] = m[2] * fi[v01+0] + m[8] * fi[v01+2]; + sum += fi[u] + fi[u+1] + fi[u+2]; +// fprintf(stderr, "F (%d,%d;%d): %lg,%lg,%lg\n", i, k, u, fi[u], fi[u+1], fi[u+2]); // DEBUG + } + // rescale + s[i] = sum; + set_u(_beg, bw, i, beg); set_u(_end, bw, i, end); _end += 2; + for (k = _beg, sum = 1./sum; k <= _end; ++k) fi[k] *= sum; + } + { // f[l_query+1] + double sum; + for (k = 1, sum = 0.; k <= l_ref; ++k) { + int u; + set_u(u, bw, l_query, k); + if (u < 3 || u >= bw2*3+3) continue; + sum += f[l_query][u+0] * sM + f[l_query][u+1] * sI; + } + s[l_query+1] = sum; // the last scaling factor + } + { // compute likelihood + double p = 1., Pr1 = 0.; + for (i = 0; i <= l_query + 1; ++i) { + p *= s[i]; + if (p < 1e-100) Pr += -4.343 * log(p), p = 1.; + } + Pr1 += -4.343 * log(p * l_ref * l_query); + Pr = (int)(Pr1 + .499); + if (!is_backward) { // skip backward and MAP + for (i = 0; i <= l_query; ++i) free(f[i]); + free(f); free(s); free(_qual); + return Pr; + } + } + /*** backward ***/ + // b[l_query] (b[l_query+1][0]=1 and thus \tilde{b}[][]=1/s[l_query+1]; this is where s[l_query+1] comes from) + for (k = 1; k <= l_ref; ++k) { + int u; + double *bi = b[l_query]; + set_u(u, bw, l_query, k); + if (u < 3 || u >= bw2*3+3) continue; + bi[u+0] = sM / s[l_query] / s[l_query+1]; bi[u+1] = sI / s[l_query] / s[l_query+1]; + } + // b[l_query-1..1] + for (i = l_query - 1; i >= 1; --i) { + int beg = 1, end = l_ref, x, _beg, _end; + double *bi = b[i], *bi1 = b[i+1], y = (i > 1), qli1 = qual[i+1]; + uint8_t qyi1 = query[i+1]; + x = i - bw; beg = beg > x? beg : x; + x = i + bw; end = end < x? end : x; + for (k = end; k >= beg; --k) { + int u, v11, v01, v10; + double e; + set_u(u, bw, i, k); set_u(v11, bw, i+1, k+1); set_u(v10, bw, i+1, k); set_u(v01, bw, i, k+1); + e = (k >= l_ref? 0 : (ref[k+1] > 3 || qyi1 > 3)? 1. : ref[k+1] == qyi1? 1. - qli1 : qli1 * EM) * bi1[v11]; + bi[u+0] = e * m[0] + EI * m[1] * bi1[v10+1] + m[2] * bi[v01+2]; // bi1[v11] has been foled into e. + bi[u+1] = e * m[3] + EI * m[4] * bi1[v10+1]; + bi[u+2] = (e * m[6] + m[8] * bi[v01+2]) * y; +// fprintf(stderr, "B (%d,%d;%d): %lg,%lg,%lg\n", i, k, u, bi[u], bi[u+1], bi[u+2]); // DEBUG + } + // rescale + set_u(_beg, bw, i, beg); set_u(_end, bw, i, end); _end += 2; + for (k = _beg, y = 1./s[i]; k <= _end; ++k) bi[k] *= y; + } + { // b[0] + int beg = 1, end = l_ref < bw + 1? l_ref : bw + 1; + double sum = 0.; + for (k = end; k >= beg; --k) { + int u; + double e = (ref[k] > 3 || query[1] > 3)? 1. : ref[k] == query[1]? 1. - qual[1] : qual[1] * EM; + set_u(u, bw, 1, k); + if (u < 3 || u >= bw2*3+3) continue; + sum += e * b[1][u+0] * bM + EI * b[1][u+1] * bI; + } + set_u(k, bw, 0, 0); + pb = b[0][k] = sum / s[0]; // if everything works as is expected, pb == 1.0 + } + is_diff = fabs(pb - 1.) > 1e-7? 1 : 0; + /*** MAP ***/ + for (i = 1; i <= l_query; ++i) { + double sum = 0., *fi = f[i], *bi = b[i], max = 0.; + int beg = 1, end = l_ref, x, max_k = -1; + x = i - bw; beg = beg > x? beg : x; + x = i + bw; end = end < x? end : x; + for (k = beg; k <= end; ++k) { + int u; + double z; + set_u(u, bw, i, k); + z = fi[u+0] * bi[u+0]; if (z > max) max = z, max_k = (k-1)<<2 | 0; sum += z; + z = fi[u+1] * bi[u+1]; if (z > max) max = z, max_k = (k-1)<<2 | 1; sum += z; + } + max /= sum; sum *= s[i]; // if everything works as is expected, sum == 1.0 + if (state) state[i-1] = max_k; + if (q) k = (int)(-4.343 * log(1. - max) + .499), q[i-1] = k > 100? 99 : k; +#ifdef _MAIN + fprintf(stderr, "(%.10lg,%.10lg) (%d,%d:%c,%c:%d) %lg\n", pb, sum, i-1, max_k>>2, + "ACGT"[query[i]], "ACGT"[ref[(max_k>>2)+1]], max_k&3, max); // DEBUG +#endif + } + /*** free ***/ + for (i = 0; i <= l_query; ++i) { + free(f[i]); free(b[i]); + } + free(f); free(b); free(s); free(_qual); + return Pr; +} + +#ifdef _MAIN +#include <unistd.h> +int main(int argc, char *argv[]) +{ + uint8_t conv[256], *iqual, *ref, *query; + int c, l_ref, l_query, i, q = 30, b = 10, P; + while ((c = getopt(argc, argv, "b:q:")) >= 0) { + switch (c) { + case 'b': b = atoi(optarg); break; + case 'q': q = atoi(optarg); break; + } + } + if (optind + 2 > argc) { + fprintf(stderr, "Usage: %s [-q %d] [-b %d] <ref> <query>\n", argv[0], q, b); // example: acttc attc + return 1; + } + memset(conv, 4, 256); + conv['a'] = conv['A'] = 0; conv['c'] = conv['C'] = 1; + conv['g'] = conv['G'] = 2; conv['t'] = conv['T'] = 3; + ref = (uint8_t*)argv[optind]; query = (uint8_t*)argv[optind+1]; + l_ref = strlen((char*)ref); l_query = strlen((char*)query); + for (i = 0; i < l_ref; ++i) ref[i] = conv[ref[i]]; + for (i = 0; i < l_query; ++i) query[i] = conv[query[i]]; + iqual = malloc(l_query); + memset(iqual, q, l_query); + kpa_par_def.bw = b; + P = kpa_glocal(ref, l_ref, query, l_query, iqual, &kpa_par_alt, 0, 0); + fprintf(stderr, "%d\n", P); + free(iqual); + return 0; +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/kprobaln.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,49 @@ +/* The MIT License + + Copyright (c) 2003-2006, 2008, 2009 by Heng Li <lh3@live.co.uk> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#ifndef LH3_KPROBALN_H_ +#define LH3_KPROBALN_H_ + +#include <stdint.h> + +typedef struct { + float d, e; + int bw; +} kpa_par_t; + +#ifdef __cplusplus +extern "C" { +#endif + + int kpa_glocal(const uint8_t *_ref, int l_ref, const uint8_t *_query, int l_query, const uint8_t *iqual, + const kpa_par_t *c, int *state, uint8_t *q); + +#ifdef __cplusplus +} +#endif + +extern kpa_par_t kpa_par_def, kpa_par_alt; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/kseq.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,227 @@ +/* The MIT License + + Copyright (c) 2008 Genome Research Ltd (GRL). + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* Contact: Heng Li <lh3@sanger.ac.uk> */ + +/* + 2009-07-16 (lh3): in kstream_t, change "char*" to "unsigned char*" + */ + +/* Last Modified: 12APR2009 */ + +#ifndef AC_KSEQ_H +#define AC_KSEQ_H + +#include <ctype.h> +#include <string.h> +#include <stdlib.h> + +#define KS_SEP_SPACE 0 // isspace(): \t, \n, \v, \f, \r +#define KS_SEP_TAB 1 // isspace() && !' ' +#define KS_SEP_MAX 1 + +#define __KS_TYPE(type_t) \ + typedef struct __kstream_t { \ + unsigned char *buf; \ + int begin, end, is_eof; \ + type_t f; \ + } kstream_t; + +#define ks_eof(ks) ((ks)->is_eof && (ks)->begin >= (ks)->end) +#define ks_rewind(ks) ((ks)->is_eof = (ks)->begin = (ks)->end = 0) + +#define __KS_BASIC(type_t, __bufsize) \ + static inline kstream_t *ks_init(type_t f) \ + { \ + kstream_t *ks = (kstream_t*)calloc(1, sizeof(kstream_t)); \ + ks->f = f; \ + ks->buf = malloc(__bufsize); \ + return ks; \ + } \ + static inline void ks_destroy(kstream_t *ks) \ + { \ + if (ks) { \ + free(ks->buf); \ + free(ks); \ + } \ + } + +#define __KS_GETC(__read, __bufsize) \ + static inline int ks_getc(kstream_t *ks) \ + { \ + if (ks->is_eof && ks->begin >= ks->end) return -1; \ + if (ks->begin >= ks->end) { \ + ks->begin = 0; \ + ks->end = __read(ks->f, ks->buf, __bufsize); \ + if (ks->end < __bufsize) ks->is_eof = 1; \ + if (ks->end == 0) return -1; \ + } \ + return (int)ks->buf[ks->begin++]; \ + } + +#ifndef KSTRING_T +#define KSTRING_T kstring_t +typedef struct __kstring_t { + size_t l, m; + char *s; +} kstring_t; +#endif + +#ifndef kroundup32 +#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) +#endif + +#define __KS_GETUNTIL(__read, __bufsize) \ + static int ks_getuntil(kstream_t *ks, int delimiter, kstring_t *str, int *dret) \ + { \ + if (dret) *dret = 0; \ + str->l = 0; \ + if (ks->begin >= ks->end && ks->is_eof) return -1; \ + for (;;) { \ + int i; \ + if (ks->begin >= ks->end) { \ + if (!ks->is_eof) { \ + ks->begin = 0; \ + ks->end = __read(ks->f, ks->buf, __bufsize); \ + if (ks->end < __bufsize) ks->is_eof = 1; \ + if (ks->end == 0) break; \ + } else break; \ + } \ + if (delimiter > KS_SEP_MAX) { \ + for (i = ks->begin; i < ks->end; ++i) \ + if (ks->buf[i] == delimiter) break; \ + } else if (delimiter == KS_SEP_SPACE) { \ + for (i = ks->begin; i < ks->end; ++i) \ + if (isspace(ks->buf[i])) break; \ + } else if (delimiter == KS_SEP_TAB) { \ + for (i = ks->begin; i < ks->end; ++i) \ + if (isspace(ks->buf[i]) && ks->buf[i] != ' ') break; \ + } else i = 0; /* never come to here! */ \ + if (str->m - str->l < i - ks->begin + 1) { \ + str->m = str->l + (i - ks->begin) + 1; \ + kroundup32(str->m); \ + str->s = (char*)realloc(str->s, str->m); \ + } \ + memcpy(str->s + str->l, ks->buf + ks->begin, i - ks->begin); \ + str->l = str->l + (i - ks->begin); \ + ks->begin = i + 1; \ + if (i < ks->end) { \ + if (dret) *dret = ks->buf[i]; \ + break; \ + } \ + } \ + if (str->l == 0) { \ + str->m = 1; \ + str->s = (char*)calloc(1, 1); \ + } \ + str->s[str->l] = '\0'; \ + return str->l; \ + } + +#define KSTREAM_INIT(type_t, __read, __bufsize) \ + __KS_TYPE(type_t) \ + __KS_BASIC(type_t, __bufsize) \ + __KS_GETC(__read, __bufsize) \ + __KS_GETUNTIL(__read, __bufsize) + +#define __KSEQ_BASIC(type_t) \ + static inline kseq_t *kseq_init(type_t fd) \ + { \ + kseq_t *s = (kseq_t*)calloc(1, sizeof(kseq_t)); \ + s->f = ks_init(fd); \ + return s; \ + } \ + static inline void kseq_rewind(kseq_t *ks) \ + { \ + ks->last_char = 0; \ + ks->f->is_eof = ks->f->begin = ks->f->end = 0; \ + } \ + static inline void kseq_destroy(kseq_t *ks) \ + { \ + if (!ks) return; \ + free(ks->name.s); free(ks->comment.s); free(ks->seq.s); free(ks->qual.s); \ + ks_destroy(ks->f); \ + free(ks); \ + } + +/* Return value: + >=0 length of the sequence (normal) + -1 end-of-file + -2 truncated quality string + */ +#define __KSEQ_READ \ + static int kseq_read(kseq_t *seq) \ + { \ + int c; \ + kstream_t *ks = seq->f; \ + if (seq->last_char == 0) { /* then jump to the next header line */ \ + while ((c = ks_getc(ks)) != -1 && c != '>' && c != '@'); \ + if (c == -1) return -1; /* end of file */ \ + seq->last_char = c; \ + } /* the first header char has been read */ \ + seq->comment.l = seq->seq.l = seq->qual.l = 0; \ + if (ks_getuntil(ks, 0, &seq->name, &c) < 0) return -1; \ + if (c != '\n') ks_getuntil(ks, '\n', &seq->comment, 0); \ + while ((c = ks_getc(ks)) != -1 && c != '>' && c != '+' && c != '@') { \ + if (isgraph(c)) { /* printable non-space character */ \ + if (seq->seq.l + 1 >= seq->seq.m) { /* double the memory */ \ + seq->seq.m = seq->seq.l + 2; \ + kroundup32(seq->seq.m); /* rounded to next closest 2^k */ \ + seq->seq.s = (char*)realloc(seq->seq.s, seq->seq.m); \ + } \ + seq->seq.s[seq->seq.l++] = (char)c; \ + } \ + } \ + if (c == '>' || c == '@') seq->last_char = c; /* the first header char has been read */ \ + seq->seq.s[seq->seq.l] = 0; /* null terminated string */ \ + if (c != '+') return seq->seq.l; /* FASTA */ \ + if (seq->qual.m < seq->seq.m) { /* allocate enough memory */ \ + seq->qual.m = seq->seq.m; \ + seq->qual.s = (char*)realloc(seq->qual.s, seq->qual.m); \ + } \ + while ((c = ks_getc(ks)) != -1 && c != '\n'); /* skip the rest of '+' line */ \ + if (c == -1) return -2; /* we should not stop here */ \ + while ((c = ks_getc(ks)) != -1 && seq->qual.l < seq->seq.l) \ + if (c >= 33 && c <= 127) seq->qual.s[seq->qual.l++] = (unsigned char)c; \ + seq->qual.s[seq->qual.l] = 0; /* null terminated string */ \ + seq->last_char = 0; /* we have not come to the next header line */ \ + if (seq->seq.l != seq->qual.l) return -2; /* qual string is shorter than seq string */ \ + return seq->seq.l; \ + } + +#define __KSEQ_TYPE(type_t) \ + typedef struct { \ + kstring_t name, comment, seq, qual; \ + int last_char; \ + kstream_t *f; \ + } kseq_t; + +#define KSEQ_INIT(type_t, __read) \ + KSTREAM_INIT(type_t, __read, 4096) \ + __KSEQ_TYPE(type_t) \ + __KSEQ_BASIC(type_t) \ + __KSEQ_READ + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/ksort.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,281 @@ +/* The MIT License + + Copyright (c) 2008 Genome Research Ltd (GRL). + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* Contact: Heng Li <lh3@sanger.ac.uk> */ + +/* + 2008-11-16 (0.1.4): + + * Fixed a bug in introsort() that happens in rare cases. + + 2008-11-05 (0.1.3): + + * Fixed a bug in introsort() for complex comparisons. + + * Fixed a bug in mergesort(). The previous version is not stable. + + 2008-09-15 (0.1.2): + + * Accelerated introsort. On my Mac (not on another Linux machine), + my implementation is as fast as std::sort on random input. + + * Added combsort and in introsort, switch to combsort if the + recursion is too deep. + + 2008-09-13 (0.1.1): + + * Added k-small algorithm + + 2008-09-05 (0.1.0): + + * Initial version + +*/ + +#ifndef AC_KSORT_H +#define AC_KSORT_H + +#include <stdlib.h> +#include <string.h> + +typedef struct { + void *left, *right; + int depth; +} ks_isort_stack_t; + +#define KSORT_SWAP(type_t, a, b) { register type_t t=(a); (a)=(b); (b)=t; } + +#define KSORT_INIT(name, type_t, __sort_lt) \ + void ks_mergesort_##name(size_t n, type_t array[], type_t temp[]) \ + { \ + type_t *a2[2], *a, *b; \ + int curr, shift; \ + \ + a2[0] = array; \ + a2[1] = temp? temp : (type_t*)malloc(sizeof(type_t) * n); \ + for (curr = 0, shift = 0; (1ul<<shift) < n; ++shift) { \ + a = a2[curr]; b = a2[1-curr]; \ + if (shift == 0) { \ + type_t *p = b, *i, *eb = a + n; \ + for (i = a; i < eb; i += 2) { \ + if (i == eb - 1) *p++ = *i; \ + else { \ + if (__sort_lt(*(i+1), *i)) { \ + *p++ = *(i+1); *p++ = *i; \ + } else { \ + *p++ = *i; *p++ = *(i+1); \ + } \ + } \ + } \ + } else { \ + size_t i, step = 1ul<<shift; \ + for (i = 0; i < n; i += step<<1) { \ + type_t *p, *j, *k, *ea, *eb; \ + if (n < i + step) { \ + ea = a + n; eb = a; \ + } else { \ + ea = a + i + step; \ + eb = a + (n < i + (step<<1)? n : i + (step<<1)); \ + } \ + j = a + i; k = a + i + step; p = b + i; \ + while (j < ea && k < eb) { \ + if (__sort_lt(*k, *j)) *p++ = *k++; \ + else *p++ = *j++; \ + } \ + while (j < ea) *p++ = *j++; \ + while (k < eb) *p++ = *k++; \ + } \ + } \ + curr = 1 - curr; \ + } \ + if (curr == 1) { \ + type_t *p = a2[0], *i = a2[1], *eb = array + n; \ + for (; p < eb; ++i) *p++ = *i; \ + } \ + if (temp == 0) free(a2[1]); \ + } \ + void ks_heapadjust_##name(size_t i, size_t n, type_t l[]) \ + { \ + size_t k = i; \ + type_t tmp = l[i]; \ + while ((k = (k << 1) + 1) < n) { \ + if (k != n - 1 && __sort_lt(l[k], l[k+1])) ++k; \ + if (__sort_lt(l[k], tmp)) break; \ + l[i] = l[k]; i = k; \ + } \ + l[i] = tmp; \ + } \ + void ks_heapmake_##name(size_t lsize, type_t l[]) \ + { \ + size_t i; \ + for (i = (lsize >> 1) - 1; i != (size_t)(-1); --i) \ + ks_heapadjust_##name(i, lsize, l); \ + } \ + void ks_heapsort_##name(size_t lsize, type_t l[]) \ + { \ + size_t i; \ + for (i = lsize - 1; i > 0; --i) { \ + type_t tmp; \ + tmp = *l; *l = l[i]; l[i] = tmp; ks_heapadjust_##name(0, i, l); \ + } \ + } \ + inline void __ks_insertsort_##name(type_t *s, type_t *t) \ + { \ + type_t *i, *j, swap_tmp; \ + for (i = s + 1; i < t; ++i) \ + for (j = i; j > s && __sort_lt(*j, *(j-1)); --j) { \ + swap_tmp = *j; *j = *(j-1); *(j-1) = swap_tmp; \ + } \ + } \ + void ks_combsort_##name(size_t n, type_t a[]) \ + { \ + const double shrink_factor = 1.2473309501039786540366528676643; \ + int do_swap; \ + size_t gap = n; \ + type_t tmp, *i, *j; \ + do { \ + if (gap > 2) { \ + gap = (size_t)(gap / shrink_factor); \ + if (gap == 9 || gap == 10) gap = 11; \ + } \ + do_swap = 0; \ + for (i = a; i < a + n - gap; ++i) { \ + j = i + gap; \ + if (__sort_lt(*j, *i)) { \ + tmp = *i; *i = *j; *j = tmp; \ + do_swap = 1; \ + } \ + } \ + } while (do_swap || gap > 2); \ + if (gap != 1) __ks_insertsort_##name(a, a + n); \ + } \ + void ks_introsort_##name(size_t n, type_t a[]) \ + { \ + int d; \ + ks_isort_stack_t *top, *stack; \ + type_t rp, swap_tmp; \ + type_t *s, *t, *i, *j, *k; \ + \ + if (n < 1) return; \ + else if (n == 2) { \ + if (__sort_lt(a[1], a[0])) { swap_tmp = a[0]; a[0] = a[1]; a[1] = swap_tmp; } \ + return; \ + } \ + for (d = 2; 1ul<<d < n; ++d); \ + stack = (ks_isort_stack_t*)malloc(sizeof(ks_isort_stack_t) * ((sizeof(size_t)*d)+2)); \ + top = stack; s = a; t = a + (n-1); d <<= 1; \ + while (1) { \ + if (s < t) { \ + if (--d == 0) { \ + ks_combsort_##name(t - s + 1, s); \ + t = s; \ + continue; \ + } \ + i = s; j = t; k = i + ((j-i)>>1) + 1; \ + if (__sort_lt(*k, *i)) { \ + if (__sort_lt(*k, *j)) k = j; \ + } else k = __sort_lt(*j, *i)? i : j; \ + rp = *k; \ + if (k != t) { swap_tmp = *k; *k = *t; *t = swap_tmp; } \ + for (;;) { \ + do ++i; while (__sort_lt(*i, rp)); \ + do --j; while (i <= j && __sort_lt(rp, *j)); \ + if (j <= i) break; \ + swap_tmp = *i; *i = *j; *j = swap_tmp; \ + } \ + swap_tmp = *i; *i = *t; *t = swap_tmp; \ + if (i-s > t-i) { \ + if (i-s > 16) { top->left = s; top->right = i-1; top->depth = d; ++top; } \ + s = t-i > 16? i+1 : t; \ + } else { \ + if (t-i > 16) { top->left = i+1; top->right = t; top->depth = d; ++top; } \ + t = i-s > 16? i-1 : s; \ + } \ + } else { \ + if (top == stack) { \ + free(stack); \ + __ks_insertsort_##name(a, a+n); \ + return; \ + } else { --top; s = (type_t*)top->left; t = (type_t*)top->right; d = top->depth; } \ + } \ + } \ + } \ + /* This function is adapted from: http://ndevilla.free.fr/median/ */ \ + /* 0 <= kk < n */ \ + type_t ks_ksmall_##name(size_t n, type_t arr[], size_t kk) \ + { \ + type_t *low, *high, *k, *ll, *hh, *mid; \ + low = arr; high = arr + n - 1; k = arr + kk; \ + for (;;) { \ + if (high <= low) return *k; \ + if (high == low + 1) { \ + if (__sort_lt(*high, *low)) KSORT_SWAP(type_t, *low, *high); \ + return *k; \ + } \ + mid = low + (high - low) / 2; \ + if (__sort_lt(*high, *mid)) KSORT_SWAP(type_t, *mid, *high); \ + if (__sort_lt(*high, *low)) KSORT_SWAP(type_t, *low, *high); \ + if (__sort_lt(*low, *mid)) KSORT_SWAP(type_t, *mid, *low); \ + KSORT_SWAP(type_t, *mid, *(low+1)); \ + ll = low + 1; hh = high; \ + for (;;) { \ + do ++ll; while (__sort_lt(*ll, *low)); \ + do --hh; while (__sort_lt(*low, *hh)); \ + if (hh < ll) break; \ + KSORT_SWAP(type_t, *ll, *hh); \ + } \ + KSORT_SWAP(type_t, *low, *hh); \ + if (hh <= k) low = ll; \ + if (hh >= k) high = hh - 1; \ + } \ + } \ + void ks_shuffle_##name(size_t n, type_t a[]) \ + { \ + int i, j; \ + for (i = n; i > 1; --i) { \ + type_t tmp; \ + j = (int)(drand48() * i); \ + tmp = a[j]; a[j] = a[i-1]; a[i-1] = tmp; \ + } \ + } + +#define ks_mergesort(name, n, a, t) ks_mergesort_##name(n, a, t) +#define ks_introsort(name, n, a) ks_introsort_##name(n, a) +#define ks_combsort(name, n, a) ks_combsort_##name(n, a) +#define ks_heapsort(name, n, a) ks_heapsort_##name(n, a) +#define ks_heapmake(name, n, a) ks_heapmake_##name(n, a) +#define ks_heapadjust(name, i, n, a) ks_heapadjust_##name(i, n, a) +#define ks_ksmall(name, n, a, k) ks_ksmall_##name(n, a, k) +#define ks_shuffle(name, n, a) ks_shuffle_##name(n, a) + +#define ks_lt_generic(a, b) ((a) < (b)) +#define ks_lt_str(a, b) (strcmp((a), (b)) < 0) + +typedef const char *ksstr_t; + +#define KSORT_INIT_GENERIC(type_t) KSORT_INIT(type_t, type_t, ks_lt_generic) +#define KSORT_INIT_STR KSORT_INIT(str, ksstr_t, ks_lt_str) + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/kstring.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,212 @@ +#include <stdarg.h> +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <stdint.h> +#include "kstring.h" + +int ksprintf(kstring_t *s, const char *fmt, ...) +{ + va_list ap; + int l; + va_start(ap, fmt); + l = vsnprintf(s->s + s->l, s->m - s->l, fmt, ap); // This line does not work with glibc 2.0. See `man snprintf'. + va_end(ap); + if (l + 1 > s->m - s->l) { + s->m = s->l + l + 2; + kroundup32(s->m); + s->s = (char*)realloc(s->s, s->m); + va_start(ap, fmt); + l = vsnprintf(s->s + s->l, s->m - s->l, fmt, ap); + } + va_end(ap); + s->l += l; + return l; +} + +char *kstrtok(const char *str, const char *sep, ks_tokaux_t *aux) +{ + const char *p, *start; + if (sep) { // set up the table + if (str == 0 && (aux->tab[0]&1)) return 0; // no need to set up if we have finished + aux->finished = 0; + if (sep[1]) { + aux->sep = -1; + aux->tab[0] = aux->tab[1] = aux->tab[2] = aux->tab[3] = 0; + for (p = sep; *p; ++p) aux->tab[*p>>6] |= 1ull<<(*p&0x3f); + } else aux->sep = sep[0]; + } + if (aux->finished) return 0; + else if (str) aux->p = str - 1, aux->finished = 0; + if (aux->sep < 0) { + for (p = start = aux->p + 1; *p; ++p) + if (aux->tab[*p>>6]>>(*p&0x3f)&1) break; + } else { + for (p = start = aux->p + 1; *p; ++p) + if (*p == aux->sep) break; + } + aux->p = p; // end of token + if (*p == 0) aux->finished = 1; // no more tokens + return (char*)start; +} + +// s MUST BE a null terminated string; l = strlen(s) +int ksplit_core(char *s, int delimiter, int *_max, int **_offsets) +{ + int i, n, max, last_char, last_start, *offsets, l; + n = 0; max = *_max; offsets = *_offsets; + l = strlen(s); + +#define __ksplit_aux do { \ + if (_offsets) { \ + s[i] = 0; \ + if (n == max) { \ + max = max? max<<1 : 2; \ + offsets = (int*)realloc(offsets, sizeof(int) * max); \ + } \ + offsets[n++] = last_start; \ + } else ++n; \ + } while (0) + + for (i = 0, last_char = last_start = 0; i <= l; ++i) { + if (delimiter == 0) { + if (isspace(s[i]) || s[i] == 0) { + if (isgraph(last_char)) __ksplit_aux; // the end of a field + } else { + if (isspace(last_char) || last_char == 0) last_start = i; + } + } else { + if (s[i] == delimiter || s[i] == 0) { + if (last_char != 0 && last_char != delimiter) __ksplit_aux; // the end of a field + } else { + if (last_char == delimiter || last_char == 0) last_start = i; + } + } + last_char = s[i]; + } + *_max = max; *_offsets = offsets; + return n; +} + +/********************** + * Boyer-Moore search * + **********************/ + +typedef unsigned char ubyte_t; + +// reference: http://www-igm.univ-mlv.fr/~lecroq/string/node14.html +static int *ksBM_prep(const ubyte_t *pat, int m) +{ + int i, *suff, *prep, *bmGs, *bmBc; + prep = calloc(m + 256, sizeof(int)); + bmGs = prep; bmBc = prep + m; + { // preBmBc() + for (i = 0; i < 256; ++i) bmBc[i] = m; + for (i = 0; i < m - 1; ++i) bmBc[pat[i]] = m - i - 1; + } + suff = calloc(m, sizeof(int)); + { // suffixes() + int f = 0, g; + suff[m - 1] = m; + g = m - 1; + for (i = m - 2; i >= 0; --i) { + if (i > g && suff[i + m - 1 - f] < i - g) + suff[i] = suff[i + m - 1 - f]; + else { + if (i < g) g = i; + f = i; + while (g >= 0 && pat[g] == pat[g + m - 1 - f]) --g; + suff[i] = f - g; + } + } + } + { // preBmGs() + int j = 0; + for (i = 0; i < m; ++i) bmGs[i] = m; + for (i = m - 1; i >= 0; --i) + if (suff[i] == i + 1) + for (; j < m - 1 - i; ++j) + if (bmGs[j] == m) + bmGs[j] = m - 1 - i; + for (i = 0; i <= m - 2; ++i) + bmGs[m - 1 - suff[i]] = m - 1 - i; + } + free(suff); + return prep; +} + +void *kmemmem(const void *_str, int n, const void *_pat, int m, int **_prep) +{ + int i, j, *prep = 0, *bmGs, *bmBc; + const ubyte_t *str, *pat; + str = (const ubyte_t*)_str; pat = (const ubyte_t*)_pat; + prep = (_prep == 0 || *_prep == 0)? ksBM_prep(pat, m) : *_prep; + if (_prep && *_prep == 0) *_prep = prep; + bmGs = prep; bmBc = prep + m; + j = 0; + while (j <= n - m) { + for (i = m - 1; i >= 0 && pat[i] == str[i+j]; --i); + if (i >= 0) { + int max = bmBc[str[i+j]] - m + 1 + i; + if (max < bmGs[i]) max = bmGs[i]; + j += max; + } else return (void*)(str + j); + } + if (_prep == 0) free(prep); + return 0; +} + +char *kstrstr(const char *str, const char *pat, int **_prep) +{ + return (char*)kmemmem(str, strlen(str), pat, strlen(pat), _prep); +} + +char *kstrnstr(const char *str, const char *pat, int n, int **_prep) +{ + return (char*)kmemmem(str, n, pat, strlen(pat), _prep); +} + +/*********************** + * The main() function * + ***********************/ + +#ifdef KSTRING_MAIN +#include <stdio.h> +int main() +{ + kstring_t *s; + int *fields, n, i; + ks_tokaux_t aux; + char *p; + s = (kstring_t*)calloc(1, sizeof(kstring_t)); + // test ksprintf() + ksprintf(s, " abcdefg: %d ", 100); + printf("'%s'\n", s->s); + // test ksplit() + fields = ksplit(s, 0, &n); + for (i = 0; i < n; ++i) + printf("field[%d] = '%s'\n", i, s->s + fields[i]); + // test kstrtok() + s->l = 0; + for (p = kstrtok("ab:cde:fg/hij::k", ":/", &aux); p; p = kstrtok(0, 0, &aux)) { + kputsn(p, aux.p - p, s); + kputc('\n', s); + } + printf("%s", s->s); + // free + free(s->s); free(s); free(fields); + + { + static char *str = "abcdefgcdgcagtcakcdcd"; + static char *pat = "cd"; + char *ret, *s = str; + int *prep = 0; + while ((ret = kstrstr(s, pat, &prep)) != 0) { + printf("match: %s\n", ret); + s = ret + prep[0]; + } + free(prep); + } + return 0; +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/kstring.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,117 @@ +#ifndef KSTRING_H +#define KSTRING_H + +#include <stdlib.h> +#include <string.h> +#include <stdint.h> + +#ifndef kroundup32 +#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) +#endif + +#ifndef KSTRING_T +#define KSTRING_T kstring_t +typedef struct __kstring_t { + size_t l, m; + char *s; +} kstring_t; +#endif + +typedef struct { + uint64_t tab[4]; + int sep, finished; + const char *p; // end of the current token +} ks_tokaux_t; + +#ifdef __cplusplus +extern "C" { +#endif + + int ksprintf(kstring_t *s, const char *fmt, ...); + int ksplit_core(char *s, int delimiter, int *_max, int **_offsets); + char *kstrstr(const char *str, const char *pat, int **_prep); + char *kstrnstr(const char *str, const char *pat, int n, int **_prep); + void *kmemmem(const void *_str, int n, const void *_pat, int m, int **_prep); + + /* kstrtok() is similar to strtok_r() except that str is not + * modified and both str and sep can be NULL. For efficiency, it is + * actually recommended to set both to NULL in the subsequent calls + * if sep is not changed. */ + char *kstrtok(const char *str, const char *sep, ks_tokaux_t *aux); + +#ifdef __cplusplus +} +#endif + +static inline int kputsn(const char *p, int l, kstring_t *s) +{ + if (s->l + l + 1 >= s->m) { + s->m = s->l + l + 2; + kroundup32(s->m); + s->s = (char*)realloc(s->s, s->m); + } + memcpy(s->s + s->l, p, l); + s->l += l; + s->s[s->l] = 0; + return l; +} + +static inline int kputs(const char *p, kstring_t *s) +{ + return kputsn(p, strlen(p), s); +} + +static inline int kputc(int c, kstring_t *s) +{ + if (s->l + 1 >= s->m) { + s->m = s->l + 2; + kroundup32(s->m); + s->s = (char*)realloc(s->s, s->m); + } + s->s[s->l++] = c; + s->s[s->l] = 0; + return c; +} + +static inline int kputw(int c, kstring_t *s) +{ + char buf[16]; + int l, x; + if (c == 0) return kputc('0', s); + for (l = 0, x = c < 0? -c : c; x > 0; x /= 10) buf[l++] = x%10 + '0'; + if (c < 0) buf[l++] = '-'; + if (s->l + l + 1 >= s->m) { + s->m = s->l + l + 2; + kroundup32(s->m); + s->s = (char*)realloc(s->s, s->m); + } + for (x = l - 1; x >= 0; --x) s->s[s->l++] = buf[x]; + s->s[s->l] = 0; + return 0; +} + +static inline int kputuw(unsigned c, kstring_t *s) +{ + char buf[16]; + int l, i; + unsigned x; + if (c == 0) return kputc('0', s); + for (l = 0, x = c; x > 0; x /= 10) buf[l++] = x%10 + '0'; + if (s->l + l + 1 >= s->m) { + s->m = s->l + l + 2; + kroundup32(s->m); + s->s = (char*)realloc(s->s, s->m); + } + for (i = l - 1; i >= 0; --i) s->s[s->l++] = buf[i]; + s->s[s->l] = 0; + return 0; +} + +static inline int *ksplit(kstring_t *s, int delimiter, int *n) +{ + int max = 0, *offsets = 0; + *n = ksplit_core(s->s, delimiter, &max, &offsets); + return offsets; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/misc/HmmGlocal.java Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,178 @@ +import java.io.*; +import java.lang.*; + +public class HmmGlocal +{ + private double[] qual2prob; + private double cd, ce; // gap open probility [1e-3], gap extension probability [0.1] + private int cb; // band width [7] + + public HmmGlocal(final double d, final double e, final int b) { + cd = d; ce = e; cb = b; + qual2prob = new double[256]; + for (int i = 0; i < 256; ++i) + qual2prob[i] = Math.pow(10, -i/10.); + } + private static int set_u(final int b, final int i, final int k) { + int x = i - b; + x = x > 0? x : 0; + return (k + 1 - x) * 3; + } + public int hmm_glocal(final byte[] _ref, final byte[] _query, final byte[] _iqual, int[] state, byte[] q) { + int i, k; + /*** initialization ***/ + // change coordinates + int l_ref = _ref.length; + byte[] ref = new byte[l_ref+1]; + for (i = 0; i < l_ref; ++i) ref[i+1] = _ref[i]; // FIXME: this is silly... + int l_query = _query.length; + byte[] query = new byte[l_query+1]; + double[] qual = new double[l_query+1]; + for (i = 0; i < l_query; ++i) { + query[i+1] = _query[i]; + qual[i+1] = qual2prob[_iqual[i]]; + } + // set band width + int bw2, bw = l_ref > l_query? l_ref : l_query; + if (bw > cb) bw = cb; + if (bw < Math.abs(l_ref - l_query)) bw = Math.abs(l_ref - l_query); + bw2 = bw * 2 + 1; + // allocate the forward and backward matrices f[][] and b[][] and the scaling array s[] + double[][] f = new double[l_query+1][bw2*3 + 6]; + double[][] b = new double[l_query+1][bw2*3 + 6]; + double[] s = new double[l_query+2]; + // initialize transition probabilities + double sM, sI, bM, bI; + sM = sI = 1. / (2 * l_query + 2); + bM = (1 - cd) / l_query; bI = cd / l_query; // (bM+bI)*l_query==1 + double[] m = new double[9]; + m[0*3+0] = (1 - cd - cd) * (1 - sM); m[0*3+1] = m[0*3+2] = cd * (1 - sM); + m[1*3+0] = (1 - ce) * (1 - sI); m[1*3+1] = ce * (1 - sI); m[1*3+2] = 0.; + m[2*3+0] = 1 - ce; m[2*3+1] = 0.; m[2*3+2] = ce; + /*** forward ***/ + // f[0] + f[0][set_u(bw, 0, 0)] = s[0] = 1.; + { // f[1] + double[] fi = f[1]; + double sum; + int beg = 1, end = l_ref < bw + 1? l_ref : bw + 1, _beg, _end; + for (k = beg, sum = 0.; k <= end; ++k) { + int u; + double e = (ref[k] > 3 || query[1] > 3)? 1. : ref[k] == query[1]? 1. - qual[1] : qual[1] / 3.; + u = set_u(bw, 1, k); + fi[u+0] = e * bM; fi[u+1] = .25 * bI; + sum += fi[u] + fi[u+1]; + } + // rescale + s[1] = sum; + _beg = set_u(bw, 1, beg); _end = set_u(bw, 1, end); _end += 2; + for (k = _beg; k <= _end; ++k) fi[k] /= sum; + } + // f[2..l_query] + for (i = 2; i <= l_query; ++i) { + double[] fi = f[i], fi1 = f[i-1]; + double sum, qli = qual[i]; + int beg = 1, end = l_ref, x, _beg, _end; + byte qyi = query[i]; + x = i - bw; beg = beg > x? beg : x; // band start + x = i + bw; end = end < x? end : x; // band end + for (k = beg, sum = 0.; k <= end; ++k) { + int u, v11, v01, v10; + double e; + e = (ref[k] > 3 || qyi > 3)? 1. : ref[k] == qyi? 1. - qli : qli / 3.; + u = set_u(bw, i, k); v11 = set_u(bw, i-1, k-1); v10 = set_u(bw, i-1, k); v01 = set_u(bw, i, k-1); + fi[u+0] = e * (m[0] * fi1[v11+0] + m[3] * fi1[v11+1] + m[6] * fi1[v11+2]); + fi[u+1] = .25 * (m[1] * fi1[v10+0] + m[4] * fi1[v10+1]); + fi[u+2] = m[2] * fi[v01+0] + m[8] * fi[v01+2]; + sum += fi[u] + fi[u+1] + fi[u+2]; + //System.out.println("("+i+","+k+";"+u+"): "+fi[u]+","+fi[u+1]+","+fi[u+2]); + } + // rescale + s[i] = sum; + _beg = set_u(bw, i, beg); _end = set_u(bw, i, end); _end += 2; + for (k = _beg, sum = 1./sum; k <= _end; ++k) fi[k] *= sum; + } + { // f[l_query+1] + double sum; + for (k = 1, sum = 0.; k <= l_ref; ++k) { + int u = set_u(bw, l_query, k); + if (u < 3 || u >= bw2*3+3) continue; + sum += f[l_query][u+0] * sM + f[l_query][u+1] * sI; + } + s[l_query+1] = sum; // the last scaling factor + } + /*** backward ***/ + // b[l_query] (b[l_query+1][0]=1 and thus \tilde{b}[][]=1/s[l_query+1]; this is where s[l_query+1] comes from) + for (k = 1; k <= l_ref; ++k) { + int u = set_u(bw, l_query, k); + double[] bi = b[l_query]; + if (u < 3 || u >= bw2*3+3) continue; + bi[u+0] = sM / s[l_query] / s[l_query+1]; bi[u+1] = sI / s[l_query] / s[l_query+1]; + } + // b[l_query-1..1] + for (i = l_query - 1; i >= 1; --i) { + int beg = 1, end = l_ref, x, _beg, _end; + double[] bi = b[i], bi1 = b[i+1]; + double y = (i > 1)? 1. : 0., qli1 = qual[i+1]; + byte qyi1 = query[i+1]; + x = i - bw; beg = beg > x? beg : x; + x = i + bw; end = end < x? end : x; + for (k = end; k >= beg; --k) { + int u, v11, v01, v10; + double e; + u = set_u(bw, i, k); v11 = set_u(bw, i+1, k+1); v10 = set_u(bw, i+1, k); v01 = set_u(bw, i, k+1); + e = (k >= l_ref? 0 : (ref[k+1] > 3 || qyi1 > 3)? 1. : ref[k+1] == qyi1? 1. - qli1 : qli1 / 3.) * bi1[v11]; + bi[u+0] = e * m[0] + .25 * m[1] * bi1[v10+1] + m[2] * bi[v01+2]; // bi1[v11] has been foled into e. + bi[u+1] = e * m[3] + .25 * m[4] * bi1[v10+1]; + bi[u+2] = (e * m[6] + m[8] * bi[v01+2]) * y; + } + // rescale + _beg = set_u(bw, i, beg); _end = set_u(bw, i, end); _end += 2; + for (k = _beg, y = 1./s[i]; k <= _end; ++k) bi[k] *= y; + } + double pb; + { // b[0] + int beg = 1, end = l_ref < bw + 1? l_ref : bw + 1; + double sum = 0.; + for (k = end; k >= beg; --k) { + int u = set_u(bw, 1, k); + double e = (ref[k] > 3 || query[1] > 3)? 1. : ref[k] == query[1]? 1. - qual[1] : qual[1] / 3.; + if (u < 3 || u >= bw2*3+3) continue; + sum += e * b[1][u+0] * bM + .25 * b[1][u+1] * bI; + } + pb = b[0][set_u(bw, 0, 0)] = sum / s[0]; // if everything works as is expected, pb == 1.0 + } + int is_diff = Math.abs(pb - 1.) > 1e-7? 1 : 0; + /*** MAP ***/ + for (i = 1; i <= l_query; ++i) { + double sum = 0., max = 0.; + double[] fi = f[i], bi = b[i]; + int beg = 1, end = l_ref, x, max_k = -1; + x = i - bw; beg = beg > x? beg : x; + x = i + bw; end = end < x? end : x; + for (k = beg; k <= end; ++k) { + int u = set_u(bw, i, k); + double z; + sum += (z = fi[u+0] * bi[u+0]); if (z > max) { max = z; max_k = (k-1)<<2 | 0; } + sum += (z = fi[u+1] * bi[u+1]); if (z > max) { max = z; max_k = (k-1)<<2 | 1; } + } + max /= sum; sum *= s[i]; // if everything works as is expected, sum == 1.0 + if (state != null) state[i-1] = max_k; + if (q != null) { + k = (int)(-4.343 * Math.log(1. - max) + .499); + q[i-1] = (byte)(k > 100? 99 : k); + } + //System.out.println("("+pb+","+sum+")"+" ("+(i-1)+","+(max_k>>2)+","+(max_k&3)+","+max+")"); + } + return 0; + } + + public static void main(String[] args) { + byte[] ref = {'\0', '\1', '\3', '\3', '\1'}; + byte[] query = {'\0', '\3', '\3', '\1'}; + byte[] qual = new byte[4]; + qual[0] = qual[1] = qual[2] = qual[3] = (byte)20; + HmmGlocal hg = new HmmGlocal(1e-3, 0.1, 7); + hg.hmm_glocal(ref, query, qual, null, null); + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/misc/Makefile Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,60 @@ +CC= gcc +CXX= g++ +CFLAGS= -g -Wall -O2 #-m64 #-arch ppc +CXXFLAGS= $(CFLAGS) +DFLAGS= -D_FILE_OFFSET_BITS=64 +OBJS= +PROG= md5sum-lite md5fa maq2sam-short maq2sam-long wgsim +INCLUDES= -I.. +SUBDIRS= . + +.SUFFIXES:.c .o + +.c.o: + $(CC) -c $(CFLAGS) $(DFLAGS) $(INCLUDES) $< -o $@ + +all:$(PROG) + +lib-recur all-recur clean-recur cleanlocal-recur install-recur: + @target=`echo $@ | sed s/-recur//`; \ + wdir=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + cd $$subdir; \ + $(MAKE) CC="$(CC)" DFLAGS="$(DFLAGS)" CFLAGS="$(CFLAGS)" \ + INCLUDES="$(INCLUDES)" $$target || exit 1; \ + cd $$wdir; \ + done; + +lib: + +afs2:afs2.o + $(CC) $(CFLAGS) -o $@ afs2.o -lm -lz -L.. -lbam + +wgsim:wgsim.o + $(CC) $(CFLAGS) -o $@ wgsim.o -lm + +md5fa:md5.o md5fa.o md5.h ../kseq.h + $(CC) $(CFLAGS) -o $@ md5.o md5fa.o -lz + +md5sum-lite:md5sum-lite.o + $(CC) $(CFLAGS) -o $@ md5sum-lite.o + +md5sum-lite.o:md5.c md5.h + $(CC) -c $(CFLAGS) -DMD5SUM_MAIN -o $@ md5.c + +maq2sam-short:maq2sam.c + $(CC) $(CFLAGS) -o $@ maq2sam.c -lz + +maq2sam-long:maq2sam.c + $(CC) $(CFLAGS) -DMAQ_LONGREADS -o $@ maq2sam.c -lz + +md5fa.o:md5.h md5fa.c + $(CC) $(CFLAGS) -c -I.. -o $@ md5fa.c + +afs2.o:afs2.c ../bam.h + $(CC) $(CFLAGS) -c -I.. -o $@ afs2.c + +cleanlocal: + rm -fr gmon.out *.o a.out *.exe *.dSYM $(PROG) *~ *.a + +clean:cleanlocal-recur
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/misc/blast2sam.pl Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,92 @@ +#!/usr/bin/perl -w + +use strict; +use warnings; +use Getopt::Std; + +&blast2sam; + +sub blast2sam { + my %opts = (); + getopts('s', \%opts); + die("Usage: blast2sam.pl <in.blastn>\n") if (-t STDIN && @ARGV == 0); + my ($qlen, $slen, $q, $s, $qbeg, $qend, @sam, @cigar, @cmaux, $show_seq); + $show_seq = defined($opts{s}); + @sam = (); @sam[0,4,6..8,10] = ('', 255, '*', 0, 0, '*'); + while (<>) { + if (@cigar && (/^Query=/ || /Score =.*bits.*Expect/)) { # print + &blast_print_sam(\@sam, \@cigar, \@cmaux, $qlen - $qend); + @cigar = (); + } + if (/^Query= (\S+)/) { + $sam[0] = $1; + } elsif (/\((\S+)\s+letters\)/) { + $qlen = $1; $qlen =~ s/,//g; + } elsif (/^>(\S+)/) { + $sam[2] = $1; + } elsif (/Length = (\d+)/) { + $slen = $1; + } elsif (/Score =\s+(\S+) bits.+Expect(\(\d+\))? = (\S+)/) { # the start of an alignment block + my ($as, $ev) = (int($1 + .499), $3); + $ev = "1$ev" if ($ev =~ /^e/); + @sam[1,3,9,11,12] = (0, 0, '', "AS:i:$as", "EV:Z:$ev"); + @cigar = (); $qbeg = 0; + @cmaux = (0, 0, 0, ''); + } elsif (/Strand = (\S+) \/ (\S+)/) { + $sam[1] |= 0x10 if ($2 eq 'Minus'); + } elsif (/Query\:\s(\d+)\s*(\S+)\s(\d+)/) { + $q = $2; + unless ($qbeg) { + $qbeg = $1; + push(@cigar, ($1-1) . "H") if ($1 > 1); + } + $qend = $3; + if ($show_seq) { + my $x = $q; + $x =~ s/-//g; $sam[9] .= $x; + } + } elsif (/Sbjct\:\s(\d+)\s*(\S+)\s(\d+)/) { + $s = $2; + if ($sam[1] & 0x10) { + $sam[3] = $3; + } else { + $sam[3] = $1 unless ($sam[3]); + } + &aln2cm(\@cigar, \$q, \$s, \@cmaux); + } + } + &blast_print_sam(\@sam, \@cigar, \@cmaux, $qlen - $qend); +} + +sub blast_print_sam { + my ($sam, $cigar, $cmaux, $qrest) = @_; + push(@$cigar, $cmaux->[1] . substr("MDI", $cmaux->[0], 1)); + push(@$cigar, $qrest . 'H') if ($qrest); + if ($sam->[1] & 0x10) { + @$cigar = reverse(@$cigar); + $sam->[9] = reverse($sam->[9]); + $sam->[9] =~ tr/atgcrymkswATGCRYMKSW/tacgyrkmswTACGYRKMSW/; + } + $sam->[9] = '*' if (!$sam->[9]); + $sam->[5] = join('', @$cigar); + print join("\t", @$sam), "\n"; +} + +sub aln2cm { + my ($cigar, $q, $s, $cmaux) = @_; + my $l = length($$q); + for (my $i = 0; $i < $l; ++$i) { + my $op; + # set $op + if (substr($$q, $i, 1) eq '-') { $op = 2; } + elsif (substr($$s, $i, 1) eq '-') { $op = 1; } + else { $op = 0; } + # for CIGAR + if ($cmaux->[0] == $op) { + ++$cmaux->[1]; + } else { + push(@$cigar, $cmaux->[1] . substr("MDI", $cmaux->[0], 1)); + $cmaux->[0] = $op; $cmaux->[1] = 1; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/misc/bowtie2sam.pl Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,92 @@ +#!/usr/bin/perl -w + +# Contact: lh3 +# Version: 0.1.1 + +use strict; +use warnings; +use Getopt::Std; + +&bowtie2sam; +exit; + +sub bowtie2sam { + my %opts = (); + die("Usage: bowtie2sam.pl <aln.bowtie>\n") if (@ARGV == 0 && -t STDIN); + # core loop + my (@s, $last, @staging, $k, $best_s, $subbest_s, $best_k); + $last = ''; + while (<>) { + my ($name, $nm) = &bowtie2sam_aux($_, \@s); # read_name, number of mismatches + if ($name eq $last) { + # I do not know whether the multiple hits are ordered on the + # number of mismatches. I assume they are not and so I have to + # keep all these multiple hits in memory. + @{$staging[$k]} = @s; + if ($best_s > $nm) { + $subbest_s = $best_s; + $best_s = $nm; + $best_k = $k; + } elsif ($subbest_s > $nm) { + $subbest_s = $nm; + } + ++$k; + } else { + if ($last) { + if ($best_s == $subbest_s) { + $staging[$best_k][4] = 0; + } elsif ($subbest_s - $best_s == 1) { + $staging[$best_k][4] = 15 if ($staging[$best_k][4] > 15); + } + print join("\t", @{$staging[$best_k]}), "\n"; + } + $k = 1; $best_s = $nm; $subbest_s = 1000; $best_k = 0; + @{$staging[0]} = @s; + $last = $name; + } + } + print join("\t", @{$staging[$best_k]}), "\n" if ($best_k >= 0); +} + +sub bowtie2sam_aux { + my ($line, $s) = @_; + chomp($line); + my @t = split("\t", $line); + my $ret; + @$s = (); + # read name + $s->[0] = $ret = $t[0]; + $s->[0] =~ s/\/[12]$//g; + # initial flag (will be updated later) + $s->[1] = 0; + # read & quality + $s->[9] = $t[4]; $s->[10] = $t[5]; + # cigar + $s->[5] = length($s->[9]) . "M"; + # coor + $s->[2] = $t[2]; $s->[3] = $t[3] + 1; + $s->[1] |= 0x10 if ($t[1] eq '-'); + # mapQ + $s->[4] = $t[6] == 0? 25 : 0; + # mate coordinate + $s->[6] = '*'; $s->[7] = $s->[8] = 0; + # aux + my $nm = @t - 7; + push(@$s, "NM:i:" . (@t-7)); + push(@$s, "X$nm:i:" . ($t[6]+1)); + my $md = ''; + if ($t[7]) { + $_ = $t[7]; + my $a = 0; + while (/(\d+):[ACGTN]>([ACGTN])/gi) { + my ($y, $z) = ($1, $2); + $md .= (int($y)-$a) . $z; + $a += $y - $a + 1; + } + $md .= length($s->[9]) - $a; + } else { + $md = length($s->[9]); + } + push(@$s, "MD:Z:$md"); + return ($ret, $nm); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/misc/export2sam.pl Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,545 @@ +#!/usr/bin/env perl +# +# +# export2sam.pl converts GERALD export files to SAM format. +# +# +# +########## License: +# +# The MIT License +# +# Original SAMtools work copyright (c) 2008-2009 Genome Research Ltd. +# Modified SAMtools work copyright (c) 2010 Illumina, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# +# +# +# +########## ChangeLog: +# +# Version: 2.3.1 (18MAR2011) +# +# - Restore file '-' as stdin input. +# +# Version: 2.3.0 (24JAN2011) +# +# - Add support for export reserved chromosome name "CONTROL", +# which is translated to optional field "XC:Z:CONTROL". +# - Check for ".gz" file extension on export files and open +# these as gzip pipes when the extension is found. +# +# Version: 2.2.0 (16NOV2010) +# +# - Remove any leading zeros in export fields: RUNNO,LANE,TILE,X,Y +# - For export records with reserved chromosome name identifiers +# "QC" and "RM", add the optional field "XC:Z:QC" or "XC:Z:RM" +# to the SAM record, so that these cases can be distinguished +# from other unmatched reads. +# +# Version: 2.1.0 (21SEP2010) +# +# - Additional export record error checking. +# - Convert export records with chromomsome value of "RM" to unmapped +# SAM records. +# +# Version: 2.0.0 (15FEB2010) +# +# Script updated by Illumina in conjunction with CASAVA 1.7.0 +# release. +# +# Major changes are as follows: +# - The CIGAR string has been updated to include all gaps from +# ELANDv2 alignments. +# - The ELAND single read alignment score is always stored in the +# optional "SM" field and the ELAND paired read alignment score +# is stored in the optional "AS" field when it exists. +# - The MAPQ value is set to the higher of the two alignment scores, +# but no greater than 254, i.e. min(254,max(SM,AS)) +# - The SAM "proper pair" bit (0x0002) is now set for read pairs +# meeting ELAND's expected orientation and insert size criteria. +# - The default quality score translation is set for export files +# which contain Phread+64 quality values. An option, +# "--qlogodds", has been added to translate quality values from +# the Solexa+64 format used in export files prior to Pipeline +# 1.3 +# - The export match descriptor is now reverse-complemented when +# necessary such that it always corresponds to the forward +# strand of the reference, to be consistent with other +# information in the SAM record. It is now written to the +# optional 'XD' field (rather than 'MD') to acknowledge its +# minor differences from the samtools match descriptor (see +# additional detail below). +# - An option, "--nofilter", has been added to include reads which +# have failed primary analysis quality filtration. Such reads +# will have the corresponding SAM flag bit (0x0200) set. +# - Labels in the export 'contig' field are preserved by setting +# RNAME to "$export_chromosome/$export_contig" when the contig +# label exists. +# +# +# Contact: lh3 +# Version: 0.1.2 (03JAN2009) +# +# +# +########## Known Conversion Limitations: +# +# - Export records for reads that map to a position < 1 (allowed +# in export format), are converted to unmapped reads in the SAM +# record. +# - Export records contain the reserved chromosome names: "NM", +# "QC","RM" and "CONTROL". "NM" indicates that the aligner could +# not map the read to the reference sequence set. "QC" means that +# the aligner did not attempt to map the read due to some +# technical limitation. "RM" means that the read mapped to a set +# of 'contaminant' sequences specified in GERALD's RNA-seq +# workflow. "CONTROL" means that the read is a control. All of +# these alignment types are collapsed to the single unmapped +# alignment state in the SAM record, but the optional SAM "XC" +# field is used to record the original reserved chromosome name of +# the read for all but the "NM" case. +# - The export match descriptor is slightly different than the +# samtools match descriptor. For this reason it is stored in the +# optional SAM field 'XD' (and not 'MD'). Note that the export +# match descriptor differs from the samtools version in two +# respects: (1) indels are explicitly closed with the '$' +# character and (2) insertions must be enumerated in the match +# descriptor. For example a 35-base read with a two-base insertion +# is described as: 20^2$14 +# +# +# + +my $version = "2.3.1"; + +use strict; +use warnings; + +use Getopt::Long; +use File::Spec; +use List::Util qw(min max); + + +use constant { + EXPORT_MACHINE => 0, + EXPORT_RUNNO => 1, + EXPORT_LANE => 2, + EXPORT_TILE => 3, + EXPORT_X => 4, + EXPORT_Y => 5, + EXPORT_INDEX => 6, + EXPORT_READNO => 7, + EXPORT_READ => 8, + EXPORT_QUAL => 9, + EXPORT_CHROM => 10, + EXPORT_CONTIG => 11, + EXPORT_POS => 12, + EXPORT_STRAND => 13, + EXPORT_MD => 14, + EXPORT_SEMAP => 15, + EXPORT_PEMAP => 16, + EXPORT_PASSFILT => 21, + EXPORT_SIZE => 22, +}; + + +use constant { + SAM_QNAME => 0, + SAM_FLAG => 1, + SAM_RNAME => 2, + SAM_POS => 3, + SAM_MAPQ => 4, + SAM_CIGAR => 5, + SAM_MRNM => 6, + SAM_MPOS => 7, + SAM_ISIZE => 8, + SAM_SEQ => 9, + SAM_QUAL => 10, +}; + + +# function prototypes for Richard's code +sub match_desc_to_cigar($); +sub match_desc_frag_length($); +sub reverse_compl_match_descriptor($); +sub write_header($;$;$); + + +&export2sam; +exit; + + + + +sub export2sam { + + my $cmdline = $0 . " " . join(" ",@ARGV); + my $arg_count = scalar @ARGV; + my $progname = (File::Spec->splitpath($0))[2]; + + my $is_logodds_qvals = 0; # if true, assume files contain logodds (i.e. "solexa") quality values + my $is_nofilter = 0; + my $read1file; + my $read2file; + my $print_version = 0; + my $help = 0; + + my $result = GetOptions( "qlogodds" => \$is_logodds_qvals, + "nofilter" => \$is_nofilter, + "read1=s" => \$read1file, + "read2=s" => \$read2file, + "version" => \$print_version, + "help" => \$help ); + + my $usage = <<END; + +$progname converts GERALD export files to SAM format. + +Usage: $progname --read1=FILENAME [ options ] | --version | --help + + --read1=FILENAME read1 export file or '-' for stdin (mandatory) + (file may be gzipped with ".gz" extension) + --read2=FILENAME read2 export file or '-' for stdin + (file may be gzipped with ".gz" extension) + --nofilter include reads that failed the basecaller + purity filter + --qlogodds assume export file(s) use logodds quality values + as reported by OLB (Pipeline) prior to v1.3 + (default: phred quality values) + +END + + my $version_msg = <<END; + +$progname version: $version + +END + + if((not $result) or $help or ($arg_count==0)) { + die($usage); + } + + if(@ARGV) { + print STDERR "\nERROR: Unrecognized arguments: " . join(" ",@ARGV) . "\n\n"; + die($usage); + } + + if($print_version) { + die($version_msg); + } + + if(not defined($read1file)) { + print STDERR "\nERROR: read1 export file must be specified\n\n"; + die($usage); + } + + unless((-f $read1file) or ($read1file eq '-')) { + die("\nERROR: Can't find read1 export file: '$read1file'\n\n"); + } + + if (defined $read2file) { + unless((-f $read2file) or ($read2file eq '-')) { + die("\nERROR: Can't find read2 export file: '$read2file'\n\n"); + } + if($read1file eq $read2file) { + die("\nERROR: read1 and read2 export filenames are the same: '$read1file'\n\n"); + } + } + + my ($fh1, $fh2, $is_paired); + + my $read1cmd="$read1file"; + $read1cmd = "gzip -dc $read1file |" if($read1file =~ /\.gz$/); + open($fh1, $read1cmd) + or die("\nERROR: Can't open read1 process: '$read1cmd'\n\n"); + $is_paired = defined $read2file; + if ($is_paired) { + my $read2cmd="$read2file"; + $read2cmd = "gzip -dc $read2file |" if($read2file =~ /\.gz$/); + open($fh2, $read2cmd) + or die("\nERROR: Can't open read2 process: '$read2cmd'\n\n"); + } + # quality value conversion table + my @conv_table; + if($is_logodds_qvals){ # convert from solexa+64 quality values (pipeline pre-v1.3): + for (-64..64) { + $conv_table[$_+64] = int(33 + 10*log(1+10**($_/10.0))/log(10)+.499); + } + } else { # convert from phred+64 quality values (pipeline v1.3+): + for (-64..-1) { + $conv_table[$_+64] = undef; + } + for (0..64) { + $conv_table[$_+64] = int(33 + $_); + } + } + # write the header + print write_header( $progname, $version, $cmdline ); + # core loop + my $export_line_count = 0; + while (<$fh1>) { + $export_line_count++; + my (@s1, @s2); + &export2sam_aux($_, $export_line_count, \@s1, \@conv_table, $is_paired, 1, $is_nofilter); + if ($is_paired) { + my $read2line = <$fh2>; + if(not $read2line){ + die("\nERROR: read1 and read2 export files do not contain the same number of reads.\n Extra reads observed in read1 file at line no: $export_line_count.\n\n"); + } + &export2sam_aux($read2line, $export_line_count, \@s2, \@conv_table, $is_paired, 2, $is_nofilter); + + if (@s1 && @s2) { # then set mate coordinate + if($s1[SAM_QNAME] ne $s2[SAM_QNAME]){ + die("\nERROR: Non-paired reads in export files on line: $export_line_count.\n Read1: $_ Read2: $read2line\n"); + } + + my $isize = 0; + if ($s1[SAM_RNAME] ne '*' && $s1[SAM_RNAME] eq $s2[SAM_RNAME]) { # then calculate $isize + my $x1 = ($s1[SAM_FLAG] & 0x10)? $s1[SAM_POS] + length($s1[SAM_SEQ]) : $s1[SAM_POS]; + my $x2 = ($s2[SAM_FLAG] & 0x10)? $s2[SAM_POS] + length($s2[SAM_SEQ]) : $s2[SAM_POS]; + $isize = $x2 - $x1; + } + + foreach ([\@s1,\@s2,$isize],[\@s2,\@s1,-$isize]){ + my ($sa,$sb,$is) = @{$_}; + if ($sb->[SAM_RNAME] ne '*') { + $sa->[SAM_MRNM] = ($sb->[SAM_RNAME] eq $sa->[SAM_RNAME]) ? "=" : $sb->[SAM_RNAME]; + $sa->[SAM_MPOS] = $sb->[SAM_POS]; + $sa->[SAM_ISIZE] = $is; + $sa->[SAM_FLAG] |= 0x20 if ($sb->[SAM_FLAG] & 0x10); + } else { + $sa->[SAM_FLAG] |= 0x8; + } + } + } + } + print join("\t", @s1), "\n" if (@s1); + print join("\t", @s2), "\n" if (@s2 && $is_paired); + } + close($fh1); + if($is_paired) { + while(my $read2line = <$fh2>){ + $export_line_count++; + die("\nERROR: read1 and read2 export files do not contain the same number of reads.\n Extra reads observed in read2 file at line no: $export_line_count.\n\n"); + } + close($fh2); + } +} + +sub export2sam_aux { + my ($line, $line_no, $s, $ct, $is_paired, $read_no, $is_nofilter) = @_; + chomp($line); + my @t = split("\t", $line); + if(scalar(@t) < EXPORT_SIZE) { + my $msg="\nERROR: Unexpected number of fields in export record on line $line_no of read$read_no export file. Found " . scalar(@t) . " fields but expected " . EXPORT_SIZE . ".\n"; + $msg.="\t...erroneous export record:\n" . $line . "\n\n"; + die($msg); + } + @$s = (); + my $isPassFilt = ($t[EXPORT_PASSFILT] eq 'Y'); + return if(not ($isPassFilt or $is_nofilter)); + # read name + my $samQnamePrefix = $t[EXPORT_MACHINE] . (($t[EXPORT_RUNNO] ne "") ? "_" . int($t[EXPORT_RUNNO]) : ""); + $s->[SAM_QNAME] = join(':', $samQnamePrefix, int($t[EXPORT_LANE]), int($t[EXPORT_TILE]), + int($t[EXPORT_X]), int($t[EXPORT_Y])); + # initial flag (will be updated later) + $s->[SAM_FLAG] = 0; + if($is_paired) { + if($t[EXPORT_READNO] != $read_no){ + die("\nERROR: read$read_no export file contains record with read number: " .$t[EXPORT_READNO] . " on line: $line_no\n\n"); + } + $s->[SAM_FLAG] |= 1 | 1<<(5 + $read_no); + } + $s->[SAM_FLAG] |= 0x200 if (not $isPassFilt); + + # read & quality + my $is_export_rev = ($t[EXPORT_STRAND] eq 'R'); + if ($is_export_rev) { # then reverse the sequence and quality + $s->[SAM_SEQ] = reverse($t[EXPORT_READ]); + $s->[SAM_SEQ] =~ tr/ACGTacgt/TGCAtgca/; + $s->[SAM_QUAL] = reverse($t[EXPORT_QUAL]); + } else { + $s->[SAM_SEQ] = $t[EXPORT_READ]; + $s->[SAM_QUAL] = $t[EXPORT_QUAL]; + } + my @convqual = (); + foreach (unpack('C*', $s->[SAM_QUAL])){ + my $val=$ct->[$_]; + if(not defined $val){ + my $msg="\nERROR: can't interpret export quality value: " . $_ . " in read$read_no export file, line: $line_no\n"; + if( $_ < 64 ) { $msg .= " Use --qlogodds flag to translate logodds (solexa) quality values.\n"; } + die($msg . "\n"); + } + push @convqual,$val; + } + + $s->[SAM_QUAL] = pack('C*',@convqual); # change coding + + + # coor + my $has_coor = 0; + $s->[SAM_RNAME] = "*"; + if (($t[EXPORT_CHROM] eq 'NM') or + ($t[EXPORT_CHROM] eq 'QC') or + ($t[EXPORT_CHROM] eq 'RM') or + ($t[EXPORT_CHROM] eq 'CONTROL')) { + $s->[SAM_FLAG] |= 0x4; # unmapped + push(@$s,"XC:Z:".$t[EXPORT_CHROM]) if($t[EXPORT_CHROM] ne 'NM'); + } elsif ($t[EXPORT_CHROM] =~ /(\d+):(\d+):(\d+)/) { + $s->[SAM_FLAG] |= 0x4; # TODO: should I set BAM_FUNMAP in this case? + push(@$s, "H0:i:$1", "H1:i:$2", "H2:i:$3") + } elsif ($t[EXPORT_POS] < 1) { + $s->[SAM_FLAG] |= 0x4; # unmapped + } else { + $s->[SAM_RNAME] = $t[EXPORT_CHROM]; + $s->[SAM_RNAME] .= "/" . $t[EXPORT_CONTIG] if($t[EXPORT_CONTIG] ne ''); + $has_coor = 1; + } + $s->[SAM_POS] = $has_coor? $t[EXPORT_POS] : 0; + +# print STDERR "t[14] = " . $t[14] . "\n"; + my $matchDesc = ''; + $s->[SAM_CIGAR] = "*"; + if($has_coor){ + $matchDesc = ($is_export_rev) ? reverse_compl_match_descriptor($t[EXPORT_MD]) : $t[EXPORT_MD]; + + if($matchDesc =~ /\^/){ + # construct CIGAR string using Richard's function + $s->[SAM_CIGAR] = match_desc_to_cigar($matchDesc); # indel processing + } else { + $s->[SAM_CIGAR] = length($s->[SAM_SEQ]) . "M"; + } + } + +# print STDERR "cigar_string = $cigar_string\n"; + + $s->[SAM_FLAG] |= 0x10 if ($has_coor && $is_export_rev); + if($has_coor){ + my $semap = ($t[EXPORT_SEMAP] ne '') ? $t[EXPORT_SEMAP] : 0; + my $pemap = 0; + if($is_paired) { + $pemap = ($t[EXPORT_PEMAP] ne '') ? $t[EXPORT_PEMAP] : 0; + + # set `proper pair' bit if non-blank, non-zero PE alignment score: + $s->[SAM_FLAG] |= 0x02 if ($pemap > 0); + } + $s->[SAM_MAPQ] = min(254,max($semap,$pemap)); + } else { + $s->[SAM_MAPQ] = 0; + } + # mate coordinate + $s->[SAM_MRNM] = '*'; + $s->[SAM_MPOS] = 0; + $s->[SAM_ISIZE] = 0; + # aux + push(@$s, "BC:Z:$t[EXPORT_INDEX]") if ($t[EXPORT_INDEX]); + if($has_coor){ + # The export match descriptor differs slightly from the samtools match descriptor. + # In order for the converted SAM files to be as compliant as possible, + # we put the export match descriptor in optional field 'XD' rather than 'MD': + push(@$s, "XD:Z:$matchDesc"); + push(@$s, "SM:i:$t[EXPORT_SEMAP]") if ($t[EXPORT_SEMAP] ne ''); + push(@$s, "AS:i:$t[EXPORT_PEMAP]") if ($is_paired and ($t[EXPORT_PEMAP] ne '')); + } +} + + + +# +# the following code is taken from Richard Shaw's sorted2sam.pl file +# +sub reverse_compl_match_descriptor($) +{ +# print "\nREVERSING THE MATCH DESCRIPTOR!\n"; + my ($match_desc) = @_; + my $rev_compl_match_desc = reverse($match_desc); + $rev_compl_match_desc =~ tr/ACGT\^\$/TGCA\$\^/; + + # Unreverse the digits of numbers. + $rev_compl_match_desc = join('', + map {($_ =~ /\d+/) + ? join('', reverse(split('', $_))) + : $_} split(/(\d+)/, + $rev_compl_match_desc)); + + return $rev_compl_match_desc; +} + + + +sub match_desc_to_cigar($) +{ + my ($match_desc) = @_; + + my @match_desc_parts = split(/(\^.*?\$)/, $match_desc); + my $cigar_str = ''; + my $cigar_del_ch = 'D'; + my $cigar_ins_ch = 'I'; + my $cigar_match_ch = 'M'; + + foreach my $match_desc_part (@match_desc_parts) { + next if (!$match_desc_part); + + if ($match_desc_part =~ /^\^([ACGTN]+)\$$/) { + # Deletion + $cigar_str .= (length($1) . $cigar_del_ch); + } elsif ($match_desc_part =~ /^\^(\d+)\$$/) { + # Insertion + $cigar_str .= ($1 . $cigar_ins_ch); + } else { + $cigar_str .= (match_desc_frag_length($match_desc_part) + . $cigar_match_ch); + } + } + + return $cigar_str; +} + + +#------------------------------------------------------------------------------ + +sub match_desc_frag_length($) + { + my ($match_desc_str) = @_; + my $len = 0; + + my @match_desc_fields = split(/([ACGTN]+)/, $match_desc_str); + + foreach my $match_desc_field (@match_desc_fields) { + next if ($match_desc_field eq ''); + + $len += (($match_desc_field =~ /(\d+)/) + ? $1 : length($match_desc_field)); + } + + return $len; +} + + +# argument holds the command line +sub write_header($;$;$) +{ + my ($progname,$version,$cl) = @_; + my $complete_header = ""; + $complete_header .= "\@PG\tID:$progname\tVN:$version\tCL:$cl\n"; + + return $complete_header; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/misc/interpolate_sam.pl Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,125 @@ +#!/usr/bin/perl +use strict; + +###Builds interpolated pileup from SAM file +##@description counts bases between paired ends and piles up single end reads. +##@output, uses a #header for the RNAME and then the number of reads per base +##@author sm8@sanger.ac.uk, Stephen B. Montgomery + +##@caveats +##Requires RNAME to have format as per example +## chromosome:NCBI36:18:1:76117153:1 +## supercontig::NT_113883:1:137703:1 +## clone::AC138827.3:1:149397:1 +##Expects simple CIGAR characters, M, I and D +##Expects SAM file to be sorted. +##Expects 0x0010 to mark second read in PE file (as has been the observed case from MAQ output) (important for line 77) + +##Verify and read in SAM file +my $sam_file = $ARGV[0]; +if(!defined($sam_file)) { die("No sam file defined on arg 1"); } +unless(-f $sam_file) { die("Sam file does not exist: $sam_file"); } +open(SAM, $sam_file) || die("Cannot open sam file"); + +##Globals +my $current_location = ""; ##Current RNAME being processed +my $current_size = 0; ##Size of sequence region being processed +my $current_position = 1; ##Current base being processed +my $open = 0; ##Number of open reads (PE reads that have not been closed) +my %close = (); ##Hash of closing positions, when the current_position gets to this position it subtracts the + ##contained value from those open and deletes the indexed position from the hash + +while (my $line = <SAM>) { + my @tokens = split /\t/, $line; + + if ($current_location ne $tokens[2]) { ##Start a new sequence region + for (my $i = $current_position; $i <= $current_size; $i++) { ##Close the previous sequence region + if (defined($close{$i})) { + $open = $open - $close{$i}; + delete $close{$i}; + } + print $open . "\n"; + } + if ($current_location ne "") { + print "\n"; + } + + ##Initiate a new sequence region + my @location_tokens = split /:/, $tokens[2]; + $current_position = 1; + $current_location = $tokens[2]; + $current_size = $location_tokens[4]; + $open = 0; + %close = (); + print "#" . $tokens[2] . "\n"; + + ##Print pileup to just before the first read (will be 0) + for (my $current_position = 1; $current_position < $tokens[3]; $current_position++) { + print $open . "\n"; + } + $current_position = $tokens[3]; + + } else { ##Sequence region already open + if ($tokens[3] > $current_position) { ##If the new read's position is greater than the current position + ##cycle through to catch up to the current position + for (my $i = $current_position; $i < $tokens[3]; $i++) { + if (defined($close{$i})) { + $open = $open - $close{$i}; + delete $close{$i}; + } + print $open . "\n"; + } + $current_position = $tokens[3]; + } + } + $open++; ##Increment the number of open reads + + if (($tokens[1] & 0x0080 || $tokens[1] & 0x0040) && $tokens[1] & 0x0010 && $tokens[1] & 0x0002) { ##if second read of mate pair, add close condition + $open--; + my $parsed_cig = &parseCigar($tokens[5]); + my $seq_region_end = $tokens[3] + $parsed_cig->{'M'} + $parsed_cig->{'D'} - 1; + if (!defined($close{$seq_region_end + 1})) { $close{$seq_region_end + 1} = 0; } + $close{$seq_region_end + 1} = $close{$seq_region_end + 1} + 1; + } elsif (!($tokens[1] & 0x0001) || !($tokens[1] & 0x0002)) { ##if unpaired, add close condition + my $parsed_cig = &parseCigar($tokens[5]); + my $seq_region_end = $tokens[3] + $parsed_cig->{'M'} + $parsed_cig->{'D'} - 1; + if (!defined($close{$seq_region_end + 1})) { $close{$seq_region_end + 1} = 0; } + $close{$seq_region_end + 1} = $close{$seq_region_end + 1} + 1; + } else { + #do nothing + } +} +for (my $i = $current_position; $i <= $current_size; $i++) { ##Finish up the last sequence region + if (defined($close{$i})) { + $open = $open - $close{$i}; + delete $close{$i}; + } + print $open . "\n"; +} +print "\n"; +close(SAM); +exit(0); + +##reads and tokenizes simple cigarline +sub parseCigar() { + my $cigar_line = shift; + $cigar_line =~ s/([0-9]*[A-Z]{1})/$1\t/g; + my @cigar_tokens = split /\t/, $cigar_line; + my %parsed = ('M' => 0, + 'I' => 0, + 'D' => 0); + my @events = (); + for(my $i = 0; $i < scalar(@cigar_tokens); $i++) { + if ($cigar_tokens[$i] =~ /([0-9]+)([A-Z]{1})/g) { + if (!defined($parsed{$2})) { $parsed{$2} = 0; } + my $nt = $2; + if ($nt ne "M" && $nt ne "D" && $nt ne "I") { $nt = "M"; } + $parsed{$nt} += $1; + my %event_el = ("t" => $nt, + "n" => $1); + push @events, \%event_el; + } + } + $parsed{'events'} = \@events; + return \%parsed; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/misc/maq2sam.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,173 @@ +#include <string.h> +#include <zlib.h> +#include <stdio.h> +#include <inttypes.h> +#include <stdlib.h> +#include <assert.h> + +#define PACKAGE_VERSION "r439" + +//#define MAQ_LONGREADS + +#ifdef MAQ_LONGREADS +# define MAX_READLEN 128 +#else +# define MAX_READLEN 64 +#endif + +#define MAX_NAMELEN 36 +#define MAQMAP_FORMAT_OLD 0 +#define MAQMAP_FORMAT_NEW -1 + +#define PAIRFLAG_FF 0x01 +#define PAIRFLAG_FR 0x02 +#define PAIRFLAG_RF 0x04 +#define PAIRFLAG_RR 0x08 +#define PAIRFLAG_PAIRED 0x10 +#define PAIRFLAG_DIFFCHR 0x20 +#define PAIRFLAG_NOMATCH 0x40 +#define PAIRFLAG_SW 0x80 + +typedef struct +{ + uint8_t seq[MAX_READLEN]; /* the last base is the single-end mapping quality. */ + uint8_t size, map_qual, info1, info2, c[2], flag, alt_qual; + uint32_t seqid, pos; + int dist; + char name[MAX_NAMELEN]; +} maqmap1_t; + +typedef struct +{ + int format, n_ref; + char **ref_name; + uint64_t n_mapped_reads; + maqmap1_t *mapped_reads; +} maqmap_t; + +maqmap_t *maq_new_maqmap() +{ + maqmap_t *mm = (maqmap_t*)calloc(1, sizeof(maqmap_t)); + mm->format = MAQMAP_FORMAT_NEW; + return mm; +} +void maq_delete_maqmap(maqmap_t *mm) +{ + int i; + if (mm == 0) return; + for (i = 0; i < mm->n_ref; ++i) + free(mm->ref_name[i]); + free(mm->ref_name); + free(mm->mapped_reads); + free(mm); +} +maqmap_t *maqmap_read_header(gzFile fp) +{ + maqmap_t *mm; + int k, len; + mm = maq_new_maqmap(); + gzread(fp, &mm->format, sizeof(int)); + if (mm->format != MAQMAP_FORMAT_NEW) { + if (mm->format > 0) { + fprintf(stderr, "** Obsolete map format is detected. Please use 'mapass2maq' command to convert the format.\n"); + exit(3); + } + assert(mm->format == MAQMAP_FORMAT_NEW); + } + gzread(fp, &mm->n_ref, sizeof(int)); + mm->ref_name = (char**)calloc(mm->n_ref, sizeof(char*)); + for (k = 0; k != mm->n_ref; ++k) { + gzread(fp, &len, sizeof(int)); + mm->ref_name[k] = (char*)malloc(len * sizeof(char)); + gzread(fp, mm->ref_name[k], len); + } + /* read number of mapped reads */ + gzread(fp, &mm->n_mapped_reads, sizeof(uint64_t)); + return mm; +} + +void maq2tam_core(gzFile fp, const char *rg) +{ + maqmap_t *mm; + maqmap1_t mm1, *m1; + int ret; + m1 = &mm1; + mm = maqmap_read_header(fp); + while ((ret = gzread(fp, m1, sizeof(maqmap1_t))) == sizeof(maqmap1_t)) { + int j, flag = 0, se_mapq = m1->seq[MAX_READLEN-1]; + if (m1->flag) flag |= 1; + if ((m1->flag&PAIRFLAG_PAIRED) || ((m1->flag&PAIRFLAG_SW) && m1->flag != 192)) flag |= 2; + if (m1->flag == 192) flag |= 4; + if (m1->flag == 64) flag |= 8; + if (m1->pos&1) flag |= 0x10; + if ((flag&1) && m1->dist != 0) { + int c; + if (m1->dist > 0) { + if (m1->flag&(PAIRFLAG_FF|PAIRFLAG_RF)) c = 0; + else if (m1->flag&(PAIRFLAG_FR|PAIRFLAG_RR)) c = 1; + else c = m1->pos&1; + } else { + if (m1->flag&(PAIRFLAG_FF|PAIRFLAG_FR)) c = 0; + else if (m1->flag&(PAIRFLAG_RF|PAIRFLAG_RR)) c = 1; + else c = m1->pos&1; + } + if (c) flag |= 0x20; + } + if (m1->flag) { + int l = strlen(m1->name); + if (m1->name[l-2] == '/') { + flag |= (m1->name[l-1] == '1')? 0x40 : 0x80; + m1->name[l-2] = '\0'; + } + } + printf("%s\t%d\t", m1->name, flag); + printf("%s\t%d\t", mm->ref_name[m1->seqid], (m1->pos>>1)+1); + if (m1->flag == 130) { + int c = (int8_t)m1->seq[MAX_READLEN-1]; + printf("%d\t", m1->alt_qual); + if (c == 0) printf("%dM\t", m1->size); + else { + if (c > 0) printf("%dM%dI%dM\t", m1->map_qual, c, m1->size - m1->map_qual - c); + else printf("%dM%dD%dM\t", m1->map_qual, -c, m1->size - m1->map_qual); + } + se_mapq = 0; // zero SE mapQ for reads aligned by SW + } else { + if (flag&4) printf("0\t*\t"); + else printf("%d\t%dM\t", m1->map_qual, m1->size); + } + printf("*\t0\t%d\t", m1->dist); + for (j = 0; j != m1->size; ++j) { + if (m1->seq[j] == 0) putchar('N'); + else putchar("ACGT"[m1->seq[j]>>6&3]); + } + putchar('\t'); + for (j = 0; j != m1->size; ++j) + putchar((m1->seq[j]&0x3f) + 33); + putchar('\t'); + if (rg) printf("RG:Z:%s\t", rg); + if (flag&4) { // unmapped + printf("MF:i:%d\n", m1->flag); + } else { + printf("MF:i:%d\t", m1->flag); + if (m1->flag) printf("AM:i:%d\tSM:i:%d\t", m1->alt_qual, se_mapq); + printf("NM:i:%d\tUQ:i:%d\tH0:i:%d\tH1:i:%d\n", m1->info1&0xf, m1->info2, m1->c[0], m1->c[1]); + } + } + if (ret > 0) + fprintf(stderr, "Truncated! Continue anyway.\n"); + maq_delete_maqmap(mm); +} + +int main(int argc, char *argv[]) +{ + gzFile fp; + if (argc == 1) { + fprintf(stderr, "Version: %s\n", PACKAGE_VERSION); + fprintf(stderr, "Usage: maq2sam <in.map> [<readGroup>]\n"); + return 1; + } + fp = strcmp(argv[1], "-")? gzopen(argv[1], "r") : gzdopen(fileno(stdin), "r"); + maq2tam_core(fp, argc > 2? argv[2] : 0); + gzclose(fp); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/misc/md5.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,296 @@ +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + */ + +/* Brutally hacked by John Walker back from ANSI C to K&R (no + prototypes) to maintain the tradition that Netfone will compile + with Sun's original "cc". */ + +#include <string.h> +#include "md5.h" + +#ifndef HIGHFIRST +#define byteReverse(buf, len) /* Nothing */ +#else +/* + * Note: this code is harmless on little-endian machines. + */ +void byteReverse(buf, longs) + unsigned char *buf; unsigned longs; +{ + uint32_t t; + do { + t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 | + ((unsigned) buf[1] << 8 | buf[0]); + *(uint32_t *) buf = t; + buf += 4; + } while (--longs); +} +#endif + +void MD5Transform(uint32_t buf[4], uint32_t in[16]); + + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void MD5Init(ctx) + struct MD5Context *ctx; +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bits[0] = 0; + ctx->bits[1] = 0; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +void MD5Update(ctx, buf, len) + struct MD5Context *ctx; unsigned char *buf; unsigned len; +{ + uint32_t t; + + /* Update bitcount */ + + t = ctx->bits[0]; + if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) + ctx->bits[1]++; /* Carry from low to high */ + ctx->bits[1] += len >> 29; + + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ + + /* Handle any leading odd-sized chunks */ + + if (t) { + unsigned char *p = (unsigned char *) ctx->in + t; + + t = 64 - t; + if (len < t) { + memcpy(p, buf, len); + return; + } + memcpy(p, buf, t); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + buf += t; + len -= t; + } + /* Process data in 64-byte chunks */ + + while (len >= 64) { + memcpy(ctx->in, buf, 64); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + + memcpy(ctx->in, buf, len); +} + +/* + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +void MD5Final(digest, ctx) + unsigned char digest[16]; struct MD5Context *ctx; +{ + unsigned count; + unsigned char *p; + + /* Compute number of bytes mod 64 */ + count = (ctx->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset(p, 0, count); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + + /* Now fill the next block with 56 bytes */ + memset(ctx->in, 0, 56); + } else { + /* Pad block to 56 bytes */ + memset(p, 0, count - 8); + } + byteReverse(ctx->in, 14); + + /* Append length in bits and transform */ + ((uint32_t *) ctx->in)[14] = ctx->bits[0]; + ((uint32_t *) ctx->in)[15] = ctx->bits[1]; + + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + byteReverse((unsigned char *) ctx->buf, 4); + memcpy(digest, ctx->buf, 16); + memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ +} + + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +void MD5Transform(buf, in) + uint32_t buf[4]; uint32_t in[16]; +{ + register uint32_t a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +/* lh3: the following code is added by me */ + +#ifdef MD5SUM_MAIN +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#define HEX_STR "0123456789abcdef" + +static void md5_one(const char *fn) +{ + unsigned char buf[4096], digest[16]; + MD5_CTX md5; + int l; + FILE *fp; + + fp = strcmp(fn, "-")? fopen(fn, "r") : stdin; + if (fp == 0) { + fprintf(stderr, "md5sum: %s: No such file or directory\n", fn); + exit(1); + } + MD5Init(&md5); + while ((l = fread(buf, 1, 4096, fp)) > 0) + MD5Update(&md5, buf, l); + MD5Final(digest, &md5); + if (fp != stdin) fclose(fp); + for (l = 0; l < 16; ++l) + printf("%c%c", HEX_STR[digest[l]>>4&0xf], HEX_STR[digest[l]&0xf]); + printf(" %s\n", fn); +} +int main(int argc, char *argv[]) +{ + int i; + if (argc == 1) md5_one("-"); + else for (i = 1; i < argc; ++i) md5_one(argv[i]); + return 0; +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/misc/md5.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,57 @@ +/* + This file is adapted from a program in this page: + + http://www.fourmilab.ch/md5/ + + The original source code does not work on 64-bit machines due to the + wrong typedef "uint32". I also added prototypes. + + -lh3 + */ + +#ifndef MD5_H +#define MD5_H + +/* The following tests optimise behaviour on little-endian + machines, where there is no need to reverse the byte order + of 32 bit words in the MD5 computation. By default, + HIGHFIRST is defined, which indicates we're running on a + big-endian (most significant byte first) machine, on which + the byteReverse function in md5.c must be invoked. However, + byteReverse is coded in such a way that it is an identity + function when run on a little-endian machine, so calling it + on such a platform causes no harm apart from wasting time. + If the platform is known to be little-endian, we speed + things up by undefining HIGHFIRST, which defines + byteReverse as a null macro. Doing things in this manner + insures we work on new platforms regardless of their byte + order. */ + +#define HIGHFIRST + +#if __LITTLE_ENDIAN__ != 0 +#undef HIGHFIRST +#endif + +#include <stdint.h> + +struct MD5Context { + uint32_t buf[4]; + uint32_t bits[2]; + unsigned char in[64]; +}; + +void MD5Init(struct MD5Context *ctx); +void MD5Update(struct MD5Context *ctx, unsigned char *buf, unsigned len); +void MD5Final(unsigned char digest[16], struct MD5Context *ctx); + +/* + * This is needed to make RSAREF happy on some MS-DOS compilers. + */ +typedef struct MD5Context MD5_CTX; + +/* Define CHECK_HARDWARE_PROPERTIES to have main,c verify + byte order and uint32_t settings. */ +#define CHECK_HARDWARE_PROPERTIES + +#endif /* !MD5_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/misc/md5fa.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,58 @@ +#include <stdio.h> +#include <zlib.h> +#include "md5.h" +#include "kseq.h" + +#define HEX_STR "0123456789abcdef" + +KSEQ_INIT(gzFile, gzread) + +static void md5_one(const char *fn) +{ + MD5_CTX md5_one, md5_all; + int l, i, k; + gzFile fp; + kseq_t *seq; + unsigned char unordered[16], digest[16]; + + for (l = 0; l < 16; ++l) unordered[l] = 0; + fp = strcmp(fn, "-")? gzopen(fn, "r") : gzdopen(fileno(stdin), "r"); + if (fp == 0) { + fprintf(stderr, "md5fa: %s: No such file or directory\n", fn); + exit(1); + } + + MD5Init(&md5_all); + seq = kseq_init(fp); + while ((l = kseq_read(seq)) >= 0) { + for (i = k = 0; i < seq->seq.l; ++i) { + if (islower(seq->seq.s[i])) seq->seq.s[k++] = toupper(seq->seq.s[i]); + else if (isupper(seq->seq.s[i])) seq->seq.s[k++] = seq->seq.s[i]; + } + MD5Init(&md5_one); + MD5Update(&md5_one, (unsigned char*)seq->seq.s, k); + MD5Final(digest, &md5_one); + for (l = 0; l < 16; ++l) { + printf("%c%c", HEX_STR[digest[l]>>4&0xf], HEX_STR[digest[l]&0xf]); + unordered[l] ^= digest[l]; + } + printf(" %s %s\n", fn, seq->name.s); + MD5Update(&md5_all, (unsigned char*)seq->seq.s, k); + } + MD5Final(digest, &md5_all); + kseq_destroy(seq); + for (l = 0; l < 16; ++l) + printf("%c%c", HEX_STR[digest[l]>>4&0xf], HEX_STR[digest[l]&0xf]); + printf(" %s >ordered\n", fn); + for (l = 0; l < 16; ++l) + printf("%c%c", HEX_STR[unordered[l]>>4&0xf], HEX_STR[unordered[l]&0xf]); + printf(" %s >unordered\n", fn); +} + +int main(int argc, char *argv[]) +{ + int i; + if (argc == 1) md5_one("-"); + else for (i = 1; i < argc; ++i) md5_one(argv[i]); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/misc/novo2sam.pl Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,281 @@ +#!/usr/bin/perl -w + +# Contact: lh3 +# Version: 0.1.3 + +#Modified by Zayed Albertyn(zayed.albertyn@gmail.com) & Colin Hercus(colin@novocraft.com) + +#use strict; +#use warnings; +use Data::Dumper; +use Getopt::Std; + +&novo2sam; +exit; + +sub mating { + my ($s1, $s2) = @_; + my $isize = 0; + if ($s1->[2] ne '*' && $s1->[2] eq $s2->[2]) { # then calculate $isize + my $x1 = ($s1->[1] & 0x10)? $s1->[3] + length($s1->[9]) : $s1->[3]; + my $x2 = ($s2->[1] & 0x10)? $s2->[3] + length($s2->[9]) : $s2->[3]; + $isize = $x2 - $x1; + } + # update mate coordinate + if ($s2->[2] ne '*') { + @$s1[6..8] = (($s2->[2] eq $s1->[2])? "=" : $s2->[2], $s2->[3], $isize); + $s1->[1] |= 0x20 if ($s2->[1] & 0x10); + } else { + $s1->[1] |= 0x8; + } + if ($s1->[2] ne '*') { + @$s2[6..8] = (($s1->[2] eq $s2->[2])? "=" : $s1->[2], $s1->[3], -$isize); + $s2->[1] |= 0x20 if ($s1->[1] & 0x10); + } else { + $s2->[1] |= 0x8; + } +} + +sub novo2sam { + my %opts = (); + getopts("p", \%opts); + die("Usage: novo2sam.pl [-p] <aln.novo>\n") if (@ARGV == 0); + my $is_paired = defined($opts{p}); + # core loop + my @s1 = (); + my @s2 = (); + my ($s_last, $s_curr) = (\@s1, \@s2); + while (<>) { + next if (/^#/); + next if (/(QC|NM)\s*$/ || /(R\s+\d+)\s*$/); + &novo2sam_aux($_, $s_curr, $is_paired); + if (@$s_last != 0 && $s_last->[0] eq $s_curr->[0]) { + &mating($s_last, $s_curr); + print join("\t", @$s_last), "\n"; + print join("\t", @$s_curr), "\n"; + @$s_last = (); @$s_curr = (); + } else { + print join("\t", @$s_last), "\n" if (@$s_last != 0); + my $s = $s_last; $s_last = $s_curr; $s_curr = $s; + } + } + print join("\t", @$s_last), "\n" if (@$s_last != 0); +} + +sub novo2sam_aux { + my ($line, $s, $is_paired) = @_; + + chomp($line); + my @t = split(/\s+/, $line); + my @variations = @t[13 .. $#t]; + @$s = (); + return if ($t[4] ne 'U'); + my $len = length($t[2]); + # read name + $s->[0] = substr($t[0], 1); + $s->[0] =~ s/\/[12]$//g; + # initial flag (will be updated later) + $s->[1] = 0; + $s->[1] |= 1 | 1<<($t[1] eq 'L'? 6 : 7); + $s->[1] |= 2 if ($t[10] eq '.'); + # read & quality + if ($t[9] eq 'R') { + $s->[9] = reverse($t[2]); + $s->[10] = reverse($t[3]); + $s->[9] =~ tr/ACGTRYMKWSNacgtrymkwsn/TGCAYRKMWSNtgcayrkmwsn/; + } else { + $s->[9] = $t[2]; $s->[10] = $t[3]; + } + # cigar + my $cigarstring =""; + if (scalar @variations ==0 ) { + $s->[5] = $len . "M"; # IMPORTANT: this cigar is not correct for gapped alignment + } else { + #convert to correct CIGAR + my $tmpstr = join" ",@variations ; + if ( $tmpstr=~ /\+|\-/ ) { + $cigarstring = cigar_method($line,\@variations,$len); + $s->[5]=$cigarstring; + } else { + $s->[5]=$len. "M"; + } +} + +# coor + $s->[2] = substr($t[7], 1); $s->[3] = $t[8]; + $s->[1] |= 0x10 if ($t[9] eq 'R'); + # mapQ + $s->[4] = $t[5] > $t[6]? $t[5] : $t[6]; + # mate coordinate + $s->[6] = '*'; $s->[7] = $s->[8] = 0; + # aux + push(@$s, "NM:i:".(@t-13)); + my $md = ''; + $md = mdtag($md,$line,\@variations,$len); + push(@$s, "MD:Z:$md"); + +} + +sub mdtag { + my $oldmd = shift; + my $line = shift; + my $ref =shift; + my $rdlen = shift; + my @variations = @$ref; + my $string=""; + my $mdtag=""; + my $t=1; + my $q=1; + my $deleteflag=0; + my $len =0; + foreach $string (@variations) { + my ($indeltype,$insert) = indeltype($string); + if ($indeltype eq "+") { + $len = length ($insert); + $q+=$len; + next; + } + my $pos = $1 if $string =~ /^(\d+)/; + $len = $pos - $t; + if ($len !=0 || ($deleteflag eq 1 && $indeltype eq ">")) { + $mdtag.=$len; + } + $t+=$len; + $q+=$len; + if ($indeltype eq ">") { + $mdtag.=$insert; + $deleteflag=0; + $t+=1; + $q+=1; + } + if ($indeltype eq "-") { + my $deletedbase = $2 if $string =~ /(\d+)\-([A-Za-z]+)/; + if ($deleteflag == 0 ) { + $mdtag.="^"; + } + $mdtag.=$deletedbase; + $deleteflag=1; + $t+=1; + } + } + $len = $rdlen - $q + 1; + if ($len > 0) { + $mdtag.="$len"; + } +# print "In:$line\n"; +# print "MD: OLD => NEW\nMD: $oldmd => $mdtag\n\n"; + + return $mdtag; +} + +sub indeltype { + my $string = shift; + my $insert=""; + my $indeltype; + if ($string =~ /([A-Za-z]+)\>/) { + $indeltype=">"; + $insert=$1; + } elsif ($string =~ /\-/) { + $indeltype="-"; + } elsif ($string =~ /\+([A-Za-z]+)/) { + $indeltype="+"; + $insert=$1; + } + return ($indeltype,$insert); + +} + + +sub cigar_method { + my $line = shift; + my $ref =shift; + my $rdlen = shift; + my @variations = @$ref; + my $string=""; + my $type=""; + my $t =1; + my $q=1; + my $indeltype=""; + my $cigar= ""; + my $insert = ""; + my $len=0; + my @cig=(); + foreach $string (@variations) { + next if $string =~ />/; + my $pos = $1 if $string =~ /^(\d+)/; + + if ($string =~ /\+([A-Za-z]+)/) { + $indeltype="+"; + $insert = $1; + }elsif ($string =~ /\-([A-Za-z]+)/) { + $indeltype="-"; + $insert = $1; + } +#print "$pos $indeltype $insert $t $q\n"; + $len = $pos - $t; + if ( $len > 0) { + $cigar.=$len."M"; + push(@cig,$len."M"); + } + $t+=$len; + $q+=$len; + + if ($indeltype eq "-") { + $cigar.="D"; + push(@cig,"D"); + $t++; + } + if ($indeltype eq "+") { + $len = length ($insert); + if ($len == 1) { + $cigar.="I"; + push(@cig,"I"); + } + if ($len > 1) { + $cigar.=$len."I"; + push(@cig,$len."I") + } + $q+=$len; + } + $insert=""; + } + $len= $rdlen - $q + 1; + if ($len > 0) { + $cigar.=$len."M"; + push(@cig,$len."M"); + } + + $cigar = newcigar($cigar,'D'); + $cigar = newcigar($cigar,'I'); + + #print "$line\n"; + #print "c CIGAR:\t$cigar\n\n"; + return $cigar; + +} + + + +sub newcigar { + my $cigar = shift; + my $char = shift; + my $new = ""; + my $copy = $cigar; +#print "$cigar\n"; + $copy =~ s/^($char+)/$1;/g; +#print "$copy\n"; + $copy =~ s/([^0-9$char])($char+)/$1;$2;/g; +#print "$copy\n"; + my @parts = split(/;/,$copy); + my $el=""; + foreach $el (@parts) { +#print "$el\n"; + if ($el =~ /^$char+$/) { + $new.=length($el).$char; + }else { + $new.=$el; + } + + } + return $new; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/misc/psl2sam.pl Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,65 @@ +#!/usr/bin/perl -w + +# Author: lh3 + +# This script calculates a score using the BLAST scoring +# system. However, I am not sure how to count gap opens and gap +# extensions. It seems to me that column 5-8 are not what I am +# after. This script counts gaps from the last three columns. It does +# not generate reference skip (N) in the CIGAR as it is not easy to +# directly tell which gaps correspond to introns. + +use strict; +use warnings; +use Getopt::Std; + +my %opts = (a=>1, b=>3, q=>5, r=>2); +getopts('a:b:q:r:', \%opts); +die("Usage: psl2sam.pl [-a $opts{a}] [-b $opts{b}] [-q $opts{q}] [-r $opts{r}] <in.psl>\n") if (@ARGV == 0 && -t STDIN); + +my @stack; +my $last = ''; +my ($a, $b, $q, $r) = ($opts{a}, $opts{b}, $opts{q}, $opts{r}); +while (<>) { + next unless (/^\d/); + my @t = split; + my @s; + my $cigar = ''; + if ($t[8] eq '-') { + my $tmp = $t[11]; + $t[11] = $t[10] - $t[12]; + $t[12] = $t[10] - $tmp; + } + @s[0..4] = ($t[9], (($t[8] eq '+')? 0 : 16), $t[13], $t[15]+1, 0); + @s[6..10] = ('*', 0, 0, '*', '*'); + $cigar .= $t[11].'H' if ($t[11]); # 5'-end clipping + my @x = split(',', $t[18]); + my @y = split(',', $t[19]); + my @z = split(',', $t[20]); + my ($y0, $z0) = ($y[0], $z[0]); + my ($gap_open, $gap_ext) = (0, 0, 0); + for (1 .. $t[17]-1) { + my $ly = $y[$_] - $y[$_-1] - $x[$_-1]; + my $lz = $z[$_] - $z[$_-1] - $x[$_-1]; + if ($ly < $lz) { # del: the reference gap is longer + ++$gap_open; + $gap_ext += $lz - $ly; + $cigar .= ($y[$_] - $y0) . 'M'; + $cigar .= ($lz - $ly) . 'D'; + ($y0, $z0) = ($y[$_], $z[$_]); + } elsif ($lz < $ly) { # ins: the query gap is longer + ++$gap_open; + $gap_ext += $ly - $lz; + $cigar .= ($z[$_] - $z0) . 'M'; + $cigar .= ($ly - $lz) . 'I'; + ($y0, $z0) = ($y[$_], $z[$_]); + } + } + $cigar .= ($t[12] - $y0) . 'M'; + $cigar .= ($t[10] - $t[12]).'H' if ($t[10] != $t[12]); # 3'-end clipping + $s[5] = $cigar; + my $score = $a * $t[0] - $b * $t[1] - $q * $gap_open - $r * $gap_ext; + $score = 0 if ($score < 0); + $s[11] = "AS:i:$score"; + print join("\t", @s), "\n"; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/misc/sam2vcf.pl Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,270 @@ +#!/usr/bin/perl -w +# +# VCF specs: http://www.1000genomes.org/wiki/doku.php?id=1000_genomes:analysis:vcf3.3 +# +# Contact: pd3@sanger +# Version: 2010-04-23 + +use strict; +use warnings; +use Carp; + +my $opts = parse_params(); +do_pileup_to_vcf($opts); + +exit; + +#--------------- + +sub error +{ + my (@msg) = @_; + if ( scalar @msg ) { croak(@msg); } + die + "Usage: sam2vcf.pl [OPTIONS] < in.pileup > out.vcf\n", + "Options:\n", + " -h, -?, --help This help message.\n", + " -i, --indels-only Ignore SNPs.\n", + " -r, --refseq <file.fa> The reference sequence, required when indels are present.\n", + " -R, --keep-ref Print reference alleles as well.\n", + " -s, --snps-only Ignore indels.\n", + " -t, --column-title <string> The column title.\n", + "\n"; +} + + +sub parse_params +{ + my %opts = (); + + $opts{fh_in} = *STDIN; + $opts{fh_out} = *STDOUT; + + while (my $arg=shift(@ARGV)) + { + if ( $arg eq '-R' || $arg eq '--keep-ref' ) { $opts{keep_ref}=1; next; } + if ( $arg eq '-r' || $arg eq '--refseq' ) { $opts{refseq}=shift(@ARGV); next; } + if ( $arg eq '-t' || $arg eq '--column-title' ) { $opts{title}=shift(@ARGV); next; } + if ( $arg eq '-s' || $arg eq '--snps-only' ) { $opts{snps_only}=1; next; } + if ( $arg eq '-i' || $arg eq '--indels-only' ) { $opts{indels_only}=1; next; } + if ( $arg eq '-?' || $arg eq '-h' || $arg eq '--help' ) { error(); } + + error("Unknown parameter \"$arg\". Run -h for help.\n"); + } + return \%opts; +} + +sub iupac_to_gtype +{ + my ($ref,$base) = @_; + my %iupac = ( + 'K' => ['G','T'], + 'M' => ['A','C'], + 'S' => ['C','G'], + 'R' => ['A','G'], + 'W' => ['A','T'], + 'Y' => ['C','T'], + ); + if ( !exists($iupac{$base}) ) + { + if ( $base ne 'A' && $base ne 'C' && $base ne 'G' && $base ne 'T' ) { error("FIXME: what is this [$base]?\n"); } + if ( $ref eq $base ) { return ('.','0/0'); } + return ($base,'1/1'); + } + my $gt = $iupac{$base}; + if ( $$gt[0] eq $ref ) { return ($$gt[1],'0/1'); } + elsif ( $$gt[1] eq $ref ) { return ($$gt[0],'0/1'); } + return ("$$gt[0],$$gt[1]",'1/2'); +} + + +sub parse_indel +{ + my ($cons) = @_; + if ( $cons=~/^-/ ) + { + my $len = length($'); + return "D$len"; + } + elsif ( $cons=~/^\+/ ) { return "I$'"; } + elsif ( $cons eq '*' ) { return undef; } + error("FIXME: could not parse [$cons]\n"); +} + + +# An example of the pileup format: +# 1 3000011 C C 32 0 98 1 ^~, A +# 1 3002155 * +T/+T 53 119 52 5 +T * 4 1 0 +# 1 3003094 * -TT/-TT 31 164 60 11 -TT * 5 6 0 +# 1 3073986 * */-AAAAAAAAAAAAAA 3 3 45 9 * -AAAAAAAAAAAAAA 7 2 0 +# +sub do_pileup_to_vcf +{ + my ($opts) = @_; + + my $fh_in = $$opts{fh_in}; + my $fh_out = $$opts{fh_out}; + my ($prev_chr,$prev_pos,$prev_ref); + my $refseq; + my $ignore_indels = $$opts{snps_only} ? 1 : 0; + my $ignore_snps = $$opts{indels_only} ? 1 : 0; + my $keep_ref = $$opts{keep_ref} ? 1 : 0; + my $title = exists($$opts{title}) ? $$opts{title} : 'data'; + + print $fh_out + qq[##fileformat=VCFv3.3\n], + qq[##INFO=DP,1,Integer,"Total Depth"\n], + qq[##FORMAT=GT,1,String,"Genotype"\n], + qq[##FORMAT=GQ,1,Integer,"Genotype Quality"\n], + qq[##FORMAT=DP,1,Integer,"Read Depth"\n], + qq[#CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\tINFO\tFORMAT\t$title\n] + ; + + while (my $line=<$fh_in>) + { + chomp($line); + my (@items) = split(/\t/,$line); + if ( scalar @items<8 ) + { + error("\nToo few columns, does not look like output of 'samtools pileup -c': $line\n"); + } + my ($chr,$pos,$ref,$cons,$cons_qual,$snp_qual,$rms_qual,$depth,$a1,$a2) = @items; + $ref = uc($ref); + $cons = uc($cons); + + my ($alt,$gt); + if ( $ref eq '*' ) + { + # An indel is involved. + if ( $ignore_indels ) + { + $prev_ref = $ref; + $prev_pos = $pos; + $prev_chr = $chr; + next; + } + + if (!defined $prev_chr || $chr ne $prev_chr || $pos ne $prev_pos) + { + if ( !$$opts{refseq} ) { error("Cannot do indels without the reference.\n"); } + if ( !$refseq ) { $refseq = Fasta->new(file=>$$opts{refseq}); } + $ref = $refseq->get_base($chr,$pos); + $ref = uc($ref); + } + else { $ref = $prev_ref; } + + # One of the alleles can be a reference and it can come in arbitrary order. In some + # cases */* can be encountered. In such a case, look in the additional columns. + my ($al1,$al2) = split(m{/},$cons); + if ( $al1 eq $al2 && $al1 eq '*' ) { $al1=$a1; $al2=$a2; } + my $alt1 = parse_indel($al1); + my $alt2 = parse_indel($al2); + if ( !$alt1 && !$alt2 ) { error("FIXME: could not parse indel:\n", $line); } + if ( !$alt1 ) + { + $alt=$alt2; + $gt='0/1'; + } + elsif ( !$alt2 ) + { + $alt=$alt1; + $gt='0/1'; + } + elsif ( $alt1 eq $alt2 ) + { + $alt="$alt1"; + $gt='1/1'; + } + else + { + $alt="$alt1,$alt2"; + $gt='1/2'; + } + } + else + { + if ( $ignore_snps || (!$keep_ref && $ref eq $cons) ) + { + $prev_ref = $ref; + $prev_pos = $pos; + $prev_chr = $chr; + next; + } + + # SNP + ($alt,$gt) = iupac_to_gtype($ref,$cons); + } + + print $fh_out "$chr\t$pos\t.\t$ref\t$alt\t$snp_qual\t0\tDP=$depth\tGT:GQ:DP\t$gt:$cons_qual:$depth\n"; + + $prev_ref = $ref; + $prev_pos = $pos; + $prev_chr = $chr; + } +} + + +#------------- Fasta -------------------- +# +# Uses samtools to get a requested base from a fasta file. For efficiency, preloads +# a chunk to memory. The size of the cached sequence can be controlled by the 'size' +# parameter. +# +package Fasta; + +use strict; +use warnings; +use Carp; + +sub Fasta::new +{ + my ($class,@args) = @_; + my $self = {@args}; + bless $self, ref($class) || $class; + if ( !$$self{file} ) { $self->throw(qq[Missing the parameter "file"\n]); } + $$self{chr} = undef; + $$self{from} = undef; + $$self{to} = undef; + if ( !$$self{size} ) { $$self{size}=10_000_000; } + bless $self, ref($class) || $class; + return $self; +} + +sub read_chunk +{ + my ($self,$chr,$pos) = @_; + my $to = $pos + $$self{size}; + my $cmd = "samtools faidx $$self{file} $chr:$pos-$to"; + my @out = `$cmd`; + if ( $? ) { $self->throw("$cmd: $!"); } + my $line = shift(@out); + if ( !($line=~/^>$chr:(\d+)-(\d+)/) ) { $self->throw("Could not parse: $line"); } + $$self{chr} = $chr; + $$self{from} = $1; + $$self{to} = $2; + my $chunk = ''; + while ($line=shift(@out)) + { + chomp($line); + $chunk .= $line; + } + $$self{chunk} = $chunk; + return; +} + +sub get_base +{ + my ($self,$chr,$pos) = @_; + if ( !$$self{chr} || $chr ne $$self{chr} || $pos<$$self{from} || $pos>$$self{to} ) + { + $self->read_chunk($chr,$pos); + } + my $idx = $pos - $$self{from}; + return substr($$self{chunk},$idx,1); +} + +sub throw +{ + my ($self,@msg) = @_; + croak(@msg); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/misc/samtools.pl Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,528 @@ +#!/usr/bin/perl -w + +# Author: lh3 + +use strict; +use warnings; +use Getopt::Std; + +my $version = '0.3.3'; +&usage if (@ARGV < 1); + +my $command = shift(@ARGV); +my %func = (showALEN=>\&showALEN, pileup2fq=>\&pileup2fq, varFilter=>\&varFilter, plp2vcf=>\&plp2vcf, + unique=>\&unique, uniqcmp=>\&uniqcmp, sra2hdr=>\&sra2hdr, sam2fq=>\&sam2fq); + +die("Unknown command \"$command\".\n") if (!defined($func{$command})); +&{$func{$command}}; +exit(0); + +# +# showALEN +# + +sub showALEN { + die(qq/Usage: samtools.pl showALEN <in.sam>\n/) if (@ARGV == 0 && -t STDIN); + while (<>) { + my @t = split; + next if (/^\@/ || @t < 11); + my $l = 0; + $_ = $t[5]; + s/(\d+)[MI]/$l+=$1/eg; + print join("\t", @t[0..5]), "\t$l\t", join("\t", @t[6..$#t]), "\n"; + } +} + +# +# varFilter +# + +# +# Filtration code: +# +# d low depth +# D high depth +# W too many SNPs in a window (SNP only) +# G close to a high-quality indel (SNP only) +# Q low RMS mapping quality (SNP only) +# g close to another indel with higher quality (indel only) +# s low SNP quality (SNP only) +# i low indel quality (indel only) + +sub varFilter { + my %opts = (d=>3, D=>100, l=>30, Q=>25, q=>10, G=>25, s=>100, w=>10, W=>10, N=>2, p=>undef, S=>'', i=>''); + getopts('pq:d:D:l:Q:w:W:N:G:S:i:', \%opts); + die(qq/ +Usage: samtools.pl varFilter [options] <in.cns-pileup> + +Options: -Q INT minimum RMS mapping quality for SNPs [$opts{Q}] + -q INT minimum RMS mapping quality for gaps [$opts{q}] + -d INT minimum read depth [$opts{d}] + -D INT maximum read depth [$opts{D}] + -S INT minimum SNP quality [$opts{S}] + -i INT minimum indel quality [$opts{i}] + + -G INT min indel score for nearby SNP filtering [$opts{G}] + -w INT SNP within INT bp around a gap to be filtered [$opts{w}] + + -W INT window size for filtering dense SNPs [$opts{W}] + -N INT max number of SNPs in a window [$opts{N}] + + -l INT window size for filtering adjacent gaps [$opts{l}] + + -p print filtered variants +\n/) if (@ARGV == 0 && -t STDIN); + + # calculate the window size + my ($ol, $ow, $oW) = ($opts{l}, $opts{w}, $opts{W}); + my $max_dist = $ol > $ow? $ol : $ow; + $max_dist = $oW if ($max_dist < $oW); + # the core loop + my @staging; # (indel_filtering_score, flt_tag) + while (<>) { + my @t = split; + next if (uc($t[2]) eq uc($t[3]) || $t[3] eq '*/*'); # skip non-var sites + # clear the out-of-range elements + while (@staging) { + # Still on the same chromosome and the first element's window still affects this position? + last if ($staging[0][3] eq $t[0] && $staging[0][4] + $staging[0][2] + $max_dist >= $t[1]); + varFilter_aux(shift(@staging), $opts{p}); # calling a function is a bit slower, not much + } + my ($flt, $score) = (0, -1); + # first a simple filter + if ($t[7] < $opts{d}) { + $flt = 2; + } elsif ($t[7] > $opts{D}) { + $flt = 3; + } + if ($t[2] eq '*') { # an indel + if ($opts{i} && $opts{i}>$t[5]) { $flt = 8; } + } + elsif ($opts{S} && $opts{S}>$t[5]) { $flt = 7; } # SNP + + # site dependent filters + my $len=0; + if ($flt == 0) { + if ($t[2] eq '*') { # an indel + # If deletion, remember the length of the deletion + my ($a,$b) = split(m{/},$t[3]); + my $alen = length($a) - 1; + my $blen = length($b) - 1; + if ( $alen>$blen ) + { + if ( substr($a,0,1) eq '-' ) { $len=$alen; } + } + elsif ( substr($b,0,1) eq '-' ) { $len=$blen; } + + $flt = 1 if ($t[6] < $opts{q}); + # filtering SNPs + if ($t[5] >= $opts{G}) { + for my $x (@staging) { + # Is it a SNP and is it outside the SNP filter window? + next if ($x->[0] >= 0 || $x->[4] + $x->[2] + $ow < $t[1]); + $x->[1] = 5 if ($x->[1] == 0); + } + } + # calculate the filtering score (different from indel quality) + $score = $t[5]; + $score += $opts{s} * $t[10] if ($t[8] ne '*'); + $score += $opts{s} * $t[11] if ($t[9] ne '*'); + # check the staging list for indel filtering + for my $x (@staging) { + # Is it a SNP and is it outside the gap filter window + next if ($x->[0] < 0 || $x->[4] + $x->[2] + $ol < $t[1]); + if ($x->[0] < $score) { + $x->[1] = 6; + } else { + $flt = 6; last; + } + } + } else { # a SNP + $flt = 1 if ($t[6] < $opts{Q}); + # check adjacent SNPs + my $k = 1; + for my $x (@staging) { + ++$k if ($x->[0] < 0 && $x->[4] + $x->[2] + $oW >= $t[1] && ($x->[1] == 0 || $x->[1] == 4 || $x->[1] == 5)); + } + # filtering is necessary + if ($k > $opts{N}) { + $flt = 4; + for my $x (@staging) { + $x->[1] = 4 if ($x->[0] < 0 && $x->[4] + $x->[2] + $oW >= $t[1] && $x->[1] == 0); + } + } else { # then check gap filter + for my $x (@staging) { + next if ($x->[0] < 0 || $x->[4] + $x->[2] + $ow < $t[1]); + if ($x->[0] >= $opts{G}) { + $flt = 5; last; + } + } + } + } + } + push(@staging, [$score, $flt, $len, @t]); + } + # output the last few elements in the staging list + while (@staging) { + varFilter_aux(shift @staging, $opts{p}); + } +} + +sub varFilter_aux { + my ($first, $is_print) = @_; + if ($first->[1] == 0) { + print join("\t", @$first[3 .. @$first-1]), "\n"; + } elsif ($is_print) { + print STDERR join("\t", substr("UQdDWGgsiX", $first->[1], 1), @$first[3 .. @$first-1]), "\n"; + } +} + +# +# pileup2fq +# + +sub pileup2fq { + my %opts = (d=>3, D=>255, Q=>25, G=>25, l=>10); + getopts('d:D:Q:G:l:', \%opts); + die(qq/ +Usage: samtools.pl pileup2fq [options] <in.cns-pileup> + +Options: -d INT minimum depth [$opts{d}] + -D INT maximum depth [$opts{D}] + -Q INT min RMS mapQ [$opts{Q}] + -G INT minimum indel score [$opts{G}] + -l INT indel filter winsize [$opts{l}]\n +/) if (@ARGV == 0 && -t STDIN); + + my ($last_chr, $seq, $qual, @gaps, $last_pos); + my $_Q = $opts{Q}; + my $_d = $opts{d}; + my $_D = $opts{D}; + + $last_chr = ''; + while (<>) { + my @t = split; + if ($last_chr ne $t[0]) { + &p2q_post_process($last_chr, \$seq, \$qual, \@gaps, $opts{l}) if ($last_chr); + $last_chr = $t[0]; + $last_pos = 0; + $seq = ''; $qual = ''; + @gaps = (); + } + if ($t[1] - $last_pos != 1) { + $seq .= 'n' x ($t[1] - $last_pos - 1); + $qual .= '!' x ($t[1] - $last_pos - 1); + } + if ($t[2] eq '*') { + push(@gaps, $t[1]) if ($t[5] >= $opts{G}); + } else { + $seq .= ($t[6] >= $_Q && $t[7] >= $_d && $t[7] <= $_D)? uc($t[3]) : lc($t[3]); + my $q = $t[4] + 33; + $q = 126 if ($q > 126); + $qual .= chr($q); + } + $last_pos = $t[1]; + } + &p2q_post_process($last_chr, \$seq, \$qual, \@gaps, $opts{l}); +} + +sub p2q_post_process { + my ($chr, $seq, $qual, $gaps, $l) = @_; + &p2q_filter_gaps($seq, $gaps, $l); + print "\@$chr\n"; &p2q_print_str($seq); + print "+\n"; &p2q_print_str($qual); +} + +sub p2q_filter_gaps { + my ($seq, $gaps, $l) = @_; + for my $g (@$gaps) { + my $x = $g > $l? $g - $l : 0; + substr($$seq, $x, $l + $l) = lc(substr($$seq, $x, $l + $l)); + } +} + +sub p2q_print_str { + my ($s) = @_; + my $l = length($$s); + for (my $i = 0; $i < $l; $i += 60) { + print substr($$s, $i, 60), "\n"; + } +} + +# +# sam2fq +# + +sub sam2fq { + my %opts = (n=>20, p=>''); + getopts('n:p:', \%opts); + die("Usage: samtools.pl sam2fq [-n 20] [-p <prefix>] <inp.sam>\n") if (@ARGV == 0 && -t STDIN); + if ($opts{p} && $opts{n} > 1) { + my $pre = $opts{p}; + my @fh; + for (0 .. $opts{n}-1) { + open($fh[$_], sprintf("| gzip > $pre.%.3d.fq.gz", $_)) || die; + } + my $i = 0; + while (<>) { + next if (/^@/); + chomp; + my @t = split("\t"); + next if ($t[9] eq '*'); + my ($name, $seq, $qual); + if ($t[1] & 16) { # reverse strand + $seq = reverse($t[9]); + $qual = reverse($t[10]); + $seq =~ tr/ACGTacgt/TGCAtgca/; + } else { + ($seq, $qual) = @t[9,10]; + } + $name = $t[0]; + $name .= "/1" if ($t[1] & 0x40); + $name .= "/2" if ($t[1] & 0x80); + print {$fh[$i]} "\@$name\n$seq\n"; + if ($qual ne '*') { + print {$fh[$i]} "+\n$qual\n"; + } + $i = 0 if (++$i == $opts{n}); + } + close($fh[$_]) for (0 .. $opts{n}-1); + } else { + die("To be implemented.\n"); + } +} + +# +# sra2hdr +# + +# This subroutine does not use an XML parser. It requires that the SRA +# XML files are properly formated. +sub sra2hdr { + my %opts = (); + getopts('', \%opts); + die("Usage: samtools.pl sra2hdr <SRA.prefix>\n") if (@ARGV == 0); + my $pre = $ARGV[0]; + my $fh; + # read sample + my $sample = 'UNKNOWN'; + open($fh, "$pre.sample.xml") || die; + while (<$fh>) { + $sample = $1 if (/<SAMPLE.*alias="([^"]+)"/i); + } + close($fh); + # read experiment + my (%exp2lib, $exp); + open($fh, "$pre.experiment.xml") || die; + while (<$fh>) { + if (/<EXPERIMENT.*accession="([^\s"]+)"/i) { + $exp = $1; + } elsif (/<LIBRARY_NAME>\s*(\S+)\s*<\/LIBRARY_NAME>/i) { + $exp2lib{$exp} = $1; + } + } + close($fh); + # read run + my ($run, @fn); + open($fh, "$pre.run.xml") || die; + while (<$fh>) { + if (/<RUN.*accession="([^\s"]+)"/i) { + $run = $1; @fn = (); + } elsif (/<EXPERIMENT_REF.*accession="([^\s"]+)"/i) { + print "\@RG\tID:$run\tSM:$sample\tLB:$exp2lib{$1}\n"; + } elsif (/<FILE.*filename="([^\s"]+)"/i) { + push(@fn, $1); + } elsif (/<\/RUN>/i) { + if (@fn == 1) { + print STDERR "$fn[0]\t$run\n"; + } else { + for (0 .. $#fn) { + print STDERR "$fn[$_]\t$run", "_", $_+1, "\n"; + } + } + } + } + close($fh); +} + +# +# unique +# + +sub unique { + my %opts = (f=>250.0, q=>5, r=>2, a=>1, b=>3); + getopts('Qf:q:r:a:b:m', \%opts); + die("Usage: samtools.pl unique [-f $opts{f}] <in.sam>\n") if (@ARGV == 0 && -t STDIN); + my $last = ''; + my $recal_Q = !defined($opts{Q}); + my $multi_only = defined($opts{m}); + my @a; + while (<>) { + my $score = -1; + print $_ if (/^\@/); + $score = $1 if (/AS:i:(\d+)/); + my @t = split("\t"); + next if (@t < 11); + if ($score < 0) { # AS tag is unavailable + my $cigar = $t[5]; + my ($mm, $go, $ge) = (0, 0, 0); + $cigar =~ s/(\d+)[ID]/++$go,$ge+=$1/eg; + $cigar = $t[5]; + $cigar =~ s/(\d+)M/$mm+=$1/eg; + $score = $mm * $opts{a} - $go * $opts{q} - $ge * $opts{r}; # no mismatches... + } + $score = 1 if ($score < 1); + if ($t[0] ne $last) { + &unique_aux(\@a, $opts{f}, $recal_Q, $multi_only) if (@a); + $last = $t[0]; + } + push(@a, [$score, \@t]); + } + &unique_aux(\@a, $opts{f}, $recal_Q, $multi_only) if (@a); +} + +sub unique_aux { + my ($a, $fac, $is_recal, $multi_only) = @_; + my ($max, $max2, $max_i) = (0, 0, -1); + for (my $i = 0; $i < @$a; ++$i) { + if ($a->[$i][0] > $max) { + $max2 = $max; $max = $a->[$i][0]; $max_i = $i; + } elsif ($a->[$i][0] > $max2) { + $max2 = $a->[$i][0]; + } + } + if ($is_recal) { + if (!$multi_only || @$a > 1) { + my $q = int($fac * ($max - $max2) / $max + .499); + $q = 250 if ($q > 250); + $a->[$max_i][1][4] = $q < 250? $q : 250; + } + } + print join("\t", @{$a->[$max_i][1]}); + @$a = (); +} + +# +# uniqcmp: compare two SAM files +# + +sub uniqcmp { + my %opts = (q=>10, s=>100); + getopts('pq:s:', \%opts); + die("Usage: samtools.pl uniqcmp <in1.sam> <in2.sam>\n") if (@ARGV < 2); + my ($fh, %a); + warn("[uniqcmp] read the first file...\n"); + &uniqcmp_aux($ARGV[0], \%a, 0); + warn("[uniqcmp] read the second file...\n"); + &uniqcmp_aux($ARGV[1], \%a, 1); + warn("[uniqcmp] stats...\n"); + my @cnt; + $cnt[$_] = 0 for (0..9); + for my $x (keys %a) { + my $p = $a{$x}; + my $z; + if (defined($p->[0]) && defined($p->[1])) { + $z = ($p->[0][0] == $p->[1][0] && $p->[0][1] eq $p->[1][1] && abs($p->[0][2] - $p->[1][2]) < $opts{s})? 0 : 1; + if ($p->[0][3] >= $opts{q} && $p->[1][3] >= $opts{q}) { + ++$cnt[$z*3+0]; + } elsif ($p->[0][3] >= $opts{q}) { + ++$cnt[$z*3+1]; + } elsif ($p->[1][3] >= $opts{q}) { + ++$cnt[$z*3+2]; + } + print STDERR "$x\t$p->[0][1]:$p->[0][2]\t$p->[0][3]\t$p->[0][4]\t$p->[1][1]:$p->[1][2]\t$p->[1][3]\t$p->[1][4]\t", + $p->[0][5]-$p->[1][5], "\n" if ($z && defined($opts{p}) && ($p->[0][3] >= $opts{q} || $p->[1][3] >= $opts{q})); + } elsif (defined($p->[0])) { + ++$cnt[$p->[0][3]>=$opts{q}? 6 : 7]; + print STDERR "$x\t$p->[0][1]:$p->[0][2]\t$p->[0][3]\t$p->[0][4]\t*\t0\t*\t", + $p->[0][5], "\n" if (defined($opts{p}) && $p->[0][3] >= $opts{q}); + } else { + print STDERR "$x\t*\t0\t*\t$p->[1][1]:$p->[1][2]\t$p->[1][3]\t$p->[1][4]\t", + -$p->[1][5], "\n" if (defined($opts{p}) && $p->[1][3] >= $opts{q}); + ++$cnt[$p->[1][3]>=$opts{q}? 8 : 9]; + } + } + print "Consistent (high, high): $cnt[0]\n"; + print "Consistent (high, low ): $cnt[1]\n"; + print "Consistent (low , high): $cnt[2]\n"; + print "Inconsistent (high, high): $cnt[3]\n"; + print "Inconsistent (high, low ): $cnt[4]\n"; + print "Inconsistent (low , high): $cnt[5]\n"; + print "Second missing (high): $cnt[6]\n"; + print "Second missing (low ): $cnt[7]\n"; + print "First missing (high): $cnt[8]\n"; + print "First missing (low ): $cnt[9]\n"; +} + +sub uniqcmp_aux { + my ($fn, $a, $which) = @_; + my $fh; + $fn = "samtools view $fn |" if ($fn =~ /\.bam/); + open($fh, $fn) || die; + while (<$fh>) { + my @t = split; + next if (@t < 11); +# my $l = ($t[5] =~ /^(\d+)S/)? $1 : 0; + my $l = 0; + my ($x, $nm) = (0, 0); + $nm = $1 if (/NM:i:(\d+)/); + $_ = $t[5]; + s/(\d+)[MI]/$x+=$1/eg; + @{$a->{$t[0]}[$which]} = (($t[1]&0x10)? 1 : 0, $t[2], $t[3]-$l, $t[4], "$x:$nm", $x - 4 * $nm); + } + close($fh); +} + +sub plp2vcf { + while (<>) { + my @t = split; + next if ($t[3] eq '*/*'); + if ($t[2] eq '*') { # indel + my @s = split("/", $t[3]); + my (@a, @b); + my ($ref, $alt); + for (@s) { + next if ($_ eq '*'); + if (/^-/) { + push(@a, 'N'.substr($_, 1)); + push(@b, 'N'); + } elsif (/^\+/) { + push(@a, 'N'); + push(@b, 'N'.substr($_, 1)); + } + } + if ($a[0] && $a[1]) { + if (length($a[0]) < length($a[1])) { + $ref = $a[1]; + $alt = ($b[0] . ('N' x (length($a[1]) - length($a[0])))) . ",$b[1]"; + } elsif (length($a[0]) > length($a[1])) { + $ref = $a[0]; + $alt = ($b[1] . ('N' x (length($a[0]) - length($a[1])))) . ",$b[0]"; + } else { + $ref = $a[0]; + $alt = ($b[0] eq $b[1])? $b[0] : "$b[0],$b[1]"; + } + } else { + $ref = $a[0]; $alt = $b[0]; + } + print join("\t", @t[0,1], '.', $ref, $alt, $t[5], '.', '.'), "\n"; + } else { # SNP + } + } +} + +# +# Usage +# + +sub usage { + die(qq/ +Program: samtools.pl (helper script for SAMtools) +Version: $version +Contact: Heng Li <lh3\@sanger.ac.uk>\n +Usage: samtools.pl <command> [<arguments>]\n +Command: varFilter filtering SNPs and short indels + pileup2fq generate fastq from `pileup -c' + showALEN print alignment length (ALEN) following CIGAR +\n/); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/misc/soap2sam.pl Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,109 @@ +#!/usr/bin/perl -w + +# Contact: lh3 +# Version: 0.1.1 + +use strict; +use warnings; +use Getopt::Std; + +&soap2sam; +exit; + +sub mating { + my ($s1, $s2) = @_; + my $isize = 0; + if ($s1->[2] ne '*' && $s1->[2] eq $s2->[2]) { # then calculate $isize + my $x1 = ($s1->[1] & 0x10)? $s1->[3] + length($s1->[9]) : $s1->[3]; + my $x2 = ($s2->[1] & 0x10)? $s2->[3] + length($s2->[9]) : $s2->[3]; + $isize = $x2 - $x1; + } + # update mate coordinate + if ($s2->[2] ne '*') { + @$s1[6..8] = (($s2->[2] eq $s1->[2])? "=" : $s2->[2], $s2->[3], $isize); + $s1->[1] |= 0x20 if ($s2->[1] & 0x10); + } else { + $s1->[1] |= 0x8; + } + if ($s1->[2] ne '*') { + @$s2[6..8] = (($s1->[2] eq $s2->[2])? "=" : $s1->[2], $s1->[3], -$isize); + $s2->[1] |= 0x20 if ($s1->[1] & 0x10); + } else { + $s2->[1] |= 0x8; + } +} + +sub soap2sam { + my %opts = (); + getopts("p", \%opts); + die("Usage: soap2sam.pl [-p] <aln.soap>\n") if (@ARGV == 0 && -t STDIN); + my $is_paired = defined($opts{p}); + # core loop + my @s1 = (); + my @s2 = (); + my ($s_last, $s_curr) = (\@s1, \@s2); + while (<>) { + s/[\177-\377]|[\000-\010]|[\012-\040]//g; + next if (&soap2sam_aux($_, $s_curr, $is_paired) < 0); + if (@$s_last != 0 && $s_last->[0] eq $s_curr->[0]) { + &mating($s_last, $s_curr); + print join("\t", @$s_last), "\n"; + print join("\t", @$s_curr), "\n"; + @$s_last = (); @$s_curr = (); + } else { + print join("\t", @$s_last), "\n" if (@$s_last != 0); + my $s = $s_last; $s_last = $s_curr; $s_curr = $s; + } + } + print join("\t", @$s_last), "\n" if (@$s_last != 0); +} + +sub soap2sam_aux { + my ($line, $s, $is_paired) = @_; + chomp($line); + my @t = split(/\s+/, $line); + return -1 if (@t < 9 || $line =~ /^\s/ || !$t[0]); + @$s = (); + # fix SOAP-2.1.x bugs + @t = @t[0..2,4..$#t] unless ($t[3] =~ /^\d+$/); + # read name + $s->[0] = $t[0]; + $s->[0] =~ s/\/[12]$//g; + # initial flag (will be updated later) + $s->[1] = 0; + $s->[1] |= 1 | 1<<($t[4] eq 'a'? 6 : 7); + $s->[1] |= 2 if ($is_paired); + # read & quality + $s->[9] = $t[1]; + $s->[10] = (length($t[2]) > length($t[1]))? substr($t[2], 0, length($t[1])) : $t[2]; + # cigar + $s->[5] = length($s->[9]) . "M"; + # coor + $s->[2] = $t[7]; $s->[3] = $t[8]; + $s->[1] |= 0x10 if ($t[6] eq '-'); + # mapQ + $s->[4] = $t[3] == 1? 30 : 0; + # mate coordinate + $s->[6] = '*'; $s->[7] = $s->[8] = 0; + # aux + push(@$s, "NM:i:$t[9]"); + my $md = ''; + if ($t[9]) { + my @x; + for (10 .. $#t) { + push(@x, sprintf("%.3d,$1", $2)) if ($t[$_] =~ /^([ACGT])->(\d+)/i); + } + @x = sort(@x); + my $a = 0; + for (@x) { + my ($y, $z) = split(","); + $md .= (int($y)-$a) . $z; + $a += $y - $a + 1; + } + $md .= length($t[1]) - $a; + } else { + $md = length($t[1]); + } + push(@$s, "MD:Z:$md"); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/misc/varfilter.py Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,205 @@ +#!/software/bin/python + +# Author: lh3, converted to python and modified to add -C option by Aylwyn Scally +# +# About: +# varfilter.py is a port of Heng's samtools.pl varFilter script into +# python, with an additional -C INT option. This option sets a minimum +# consensus score, above which the script will output a pileup line +# wherever it _could have_ called a variant, even if none is actually +# called (i.e. hom-ref positions). This is important if you want to +# subsequently merge the calls with those for another individual to get a +# synoptic view of calls at each site. Without this option, and in all +# other respects, it behaves like samtools.pl varFilter. +# +# Aylwyn Scally as6@sanger.ac.uk + + +# Filtration code: +# +# C low CNS quality (hom-ref only) +# d low depth +# D high depth +# W too many SNPs in a window (SNP only) +# G close to a high-quality indel (SNP only) +# Q low RMS mapping quality (SNP only) +# g close to another indel with higher quality (indel only) +# s low SNP quality (SNP only) +# i low indel quality (indel only) + + +import sys +import getopt + +def usage(): + print '''usage: varfilter.py [options] [cns-pileup] + +Options: -Q INT minimum RMS mapping quality for SNPs + -q INT minimum RMS mapping quality for gaps + -d INT minimum read depth + -D INT maximum read depth + -S INT minimum SNP quality + -i INT minimum indel quality + -C INT minimum consensus quality for hom-ref sites + + -G INT min indel score for nearby SNP filtering + -w INT SNP within INT bp around a gap to be filtered + + -W INT window size for filtering dense SNPs + -N INT max number of SNPs in a window + + -l INT window size for filtering adjacent gaps + + -p print filtered variants''' + +def varFilter_aux(first, is_print): + try: + if first[1] == 0: + sys.stdout.write("\t".join(first[4:]) + "\n") + elif is_print: + sys.stderr.write("\t".join(["UQdDWGgsiCX"[first[1]]] + first[4:]) + "\n") + except IOError: + sys.exit() + +mindepth = 3 +maxdepth = 100 +gapgapwin = 30 +minsnpmapq = 25 +mingapmapq = 10 +minindelscore = 25 +scorefactor = 100 +snpgapwin = 10 +densesnpwin = 10 +densesnps = 2 +printfilt = False +minsnpq = 0 +minindelq = 0 +mincnsq = 0 + +try: + options, args = getopt.gnu_getopt(sys.argv[1:], 'pq:d:D:l:Q:w:W:N:G:S:i:C:', []) +except getopt.GetoptError: + usage() + sys.exit(2) +for (oflag, oarg) in options: + if oflag == '-d': mindepth = int(oarg) + if oflag == '-D': maxdepth = int(oarg) + if oflag == '-l': gapgapwin = int(oarg) + if oflag == '-Q': minsnpmapq = int(oarg) + if oflag == '-q': mingapmapq = int(oarg) + if oflag == '-G': minindelscore = int(oarg) + if oflag == '-s': scorefactor = int(oarg) + if oflag == '-w': snpgapwin = int(oarg) + if oflag == '-W': densesnpwin = int(oarg) + if oflag == '-C': mincnsq = int(oarg) + if oflag == '-N': densesnps = int(oarg) + if oflag == '-p': printfilt = True + if oflag == '-S': minsnpq = int(oarg) + if oflag == '-i': minindelq = int(oarg) + +if len(args) < 1: + inp = sys.stdin +else: + inp = open(args[0]) + +# calculate the window size +max_dist = max(gapgapwin, snpgapwin, densesnpwin) + +staging = [] +for t in (line.strip().split() for line in inp): + (flt, score) = (0, -1) + # non-var sites + if t[3] == '*/*': + continue + is_snp = t[2].upper() != t[3].upper() + if not (is_snp or mincnsq): + continue + # clear the out-of-range elements + while staging: + # Still on the same chromosome and the first element's window still affects this position? + if staging[0][4] == t[0] and int(staging[0][5]) + staging[0][2] + max_dist >= int(t[1]): + break + varFilter_aux(staging.pop(0), printfilt) + + # first a simple filter + if int(t[7]) < mindepth: + flt = 2 + elif int(t[7]) > maxdepth: + flt = 3 + if t[2] == '*': # an indel + if minindelq and minindelq > int(t[5]): + flt = 8 + elif is_snp: + if minsnpq and minsnpq> int(t[5]): + flt = 7 + else: + if mincnsq and mincnsq > int(t[4]): + flt = 9 + + # site dependent filters + dlen = 0 + if flt == 0: + if t[2] == '*': # an indel + # If deletion, remember the length of the deletion + (a,b) = t[3].split('/') + alen = len(a) - 1 + blen = len(b) - 1 + if alen>blen: + if a[0] == '-': dlen=alen + elif b[0] == '-': dlen=blen + + if int(t[6]) < mingapmapq: + flt = 1 + # filtering SNPs + if int(t[5]) >= minindelscore: + for x in (y for y in staging if y[3]): + # Is it a SNP and is it outside the SNP filter window? + if x[0] >= 0 or int(x[5]) + x[2] + snpgapwin < int(t[1]): + continue + if x[1] == 0: + x[1] = 5 + + # calculate the filtering score (different from indel quality) + score = int(t[5]) + if t[8] != '*': + score += scorefactor * int(t[10]) + if t[9] != '*': + score += scorefactor * int(t[11]) + # check the staging list for indel filtering + for x in (y for y in staging if y[3]): + # Is it a SNP and is it outside the gap filter window + if x[0] < 0 or int(x[5]) + x[2] + gapgapwin < int(t[1]): + continue + if x[0] < score: + x[1] = 6 + else: + flt = 6 + break + else: # a SNP or hom-ref + if int(t[6]) < minsnpmapq: + flt = 1 + # check adjacent SNPs + k = 1 + for x in (y for y in staging if y[3]): + if x[0] < 0 and int(x[5]) + x[2] + densesnpwin >= int(t[1]) and (x[1] == 0 or x[1] == 4 or x[1] == 5): + k += 1 + + # filtering is necessary + if k > densesnps: + flt = 4 + for x in (y for y in staging if y[3]): + if x[0] < 0 and int(x[5]) + x[2] + densesnpwin >= int(t[1]) and x[1] == 0: + x[1] = 4 + else: # then check gap filter + for x in (y for y in staging if y[3]): + if x[0] < 0 or int(x[5]) + x[2] + snpgapwin < int(t[1]): + continue + if x[0] >= minindelscore: + flt = 5 + break + + staging.append([score, flt, dlen, is_snp] + t) + +# output the last few elements in the staging list +while staging: + varFilter_aux(staging.pop(0), printfilt)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/misc/wgsim.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,502 @@ +/* The MIT License + + Copyright (c) 2008 Genome Research Ltd (GRL). + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* Contact: Heng Li <lh3@sanger.ac.uk> */ + +/* This program is separated from maq's read simulator with Colin + * Hercus' modification to allow longer indels. Colin is the chief + * developer of novoalign. */ + +#include <stdlib.h> +#include <math.h> +#include <time.h> +#include <assert.h> +#include <stdio.h> +#include <unistd.h> +#include <stdint.h> +#include <ctype.h> +#include <string.h> + +#define PACKAGE_VERSION "0.2.3" + +const uint8_t nst_nt4_table[256] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5 /*'-'*/, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 0, 4, 1, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 0, 4, 1, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 +}; + +const int nst_color_space_table[] = { 4, 0, 0, 1, 0, 2, 3, 4, 0, 3, 2, 4, 1, 4, 4, 4}; + +/* Simple normal random number generator, copied from genran.c */ + +double ran_normal() +{ + static int iset = 0; + static double gset; + double fac, rsq, v1, v2; + if (iset == 0) { + do { + v1 = 2.0 * drand48() - 1.0; + v2 = 2.0 * drand48() - 1.0; + rsq = v1 * v1 + v2 * v2; + } while (rsq >= 1.0 || rsq == 0.0); + fac = sqrt(-2.0 * log(rsq) / rsq); + gset = v1 * fac; + iset = 1; + return v2 * fac; + } else { + iset = 0; + return gset; + } +} + +/* FASTA parser, copied from seq.c */ + +typedef struct { + int l, m; /* length and maximum buffer size */ + unsigned char *s; /* sequence */ +} seq_t; + +#define INIT_SEQ(seq) (seq).s = 0; (seq).l = (seq).m = 0 + +static int SEQ_BLOCK_SIZE = 512; + +void seq_set_block_size(int size) +{ + SEQ_BLOCK_SIZE = size; +} + +int seq_read_fasta(FILE *fp, seq_t *seq, char *locus, char *comment) +{ + int c, l, max; + char *p; + + c = 0; + while (!feof(fp) && fgetc(fp) != '>'); + if (feof(fp)) return -1; + p = locus; + while (!feof(fp) && (c = fgetc(fp)) != ' ' && c != '\t' && c != '\n') + if (c != '\r') *p++ = c; + *p = '\0'; + if (comment) { + p = comment; + if (c != '\n') { + while (!feof(fp) && ((c = fgetc(fp)) == ' ' || c == '\t')); + if (c != '\n') { + *p++ = c; + while (!feof(fp) && (c = fgetc(fp)) != '\n') + if (c != '\r') *p++ = c; + } + } + *p = '\0'; + } else if (c != '\n') while (!feof(fp) && fgetc(fp) != '\n'); + l = 0; max = seq->m; + while (!feof(fp) && (c = fgetc(fp)) != '>') { + if (isalpha(c) || c == '-' || c == '.') { + if (l + 1 >= max) { + max += SEQ_BLOCK_SIZE; + seq->s = (unsigned char*)realloc(seq->s, sizeof(char) * max); + } + seq->s[l++] = (unsigned char)c; + } + } + if (c == '>') ungetc(c,fp); + seq->s[l] = 0; + seq->m = max; seq->l = l; + return l; +} + +/* Error-checking open, copied from utils.c */ + +#define xopen(fn, mode) err_xopen_core(__func__, fn, mode) + +FILE *err_xopen_core(const char *func, const char *fn, const char *mode) +{ + FILE *fp = 0; + if (strcmp(fn, "-") == 0) + return (strstr(mode, "r"))? stdin : stdout; + if ((fp = fopen(fn, mode)) == 0) { + fprintf(stderr, "[%s] fail to open file '%s'. Abort!\n", func, fn); + abort(); + } + return fp; +} + +/* wgsim */ + +enum muttype_t {NOCHANGE = 0, INSERT = 0x1000, SUBSTITUTE = 0xe000, DELETE = 0xf000}; +typedef unsigned short mut_t; +static mut_t mutmsk = (mut_t)0xf000; + +typedef struct { + int l, m; /* length and maximum buffer size */ + mut_t *s; /* sequence */ +} mutseq_t; + +static double ERR_RATE = 0.02; +static double MUT_RATE = 0.001; +static double INDEL_FRAC = 0.1; +static double INDEL_EXTEND = 0.3; +static int IS_SOLID = 0; +static int SHOW_MM_INFO = 1; + +void maq_mut_diref(const seq_t *seq, int is_hap, mutseq_t *hap1, mutseq_t *hap2) +{ + int i, deleting = 0; + mutseq_t *ret[2]; + + ret[0] = hap1; ret[1] = hap2; + ret[0]->l = seq->l; ret[1]->l = seq->l; + ret[0]->m = seq->m; ret[1]->m = seq->m; + ret[0]->s = (mut_t *)calloc(seq->m, sizeof(mut_t)); + ret[1]->s = (mut_t *)calloc(seq->m, sizeof(mut_t)); + for (i = 0; i != seq->l; ++i) { + int c; + c = ret[0]->s[i] = ret[1]->s[i] = (mut_t)nst_nt4_table[(int)seq->s[i]]; + if (deleting) { + if (drand48() < INDEL_EXTEND) { + if (deleting & 1) ret[0]->s[i] |= DELETE; + if (deleting & 2) ret[1]->s[i] |= DELETE; + continue; + } else deleting = 0; + } + if (c < 4 && drand48() < MUT_RATE) { // mutation + if (drand48() >= INDEL_FRAC) { // substitution + double r = drand48(); + c = (c + (int)(r * 3.0 + 1)) & 3; + if (is_hap || drand48() < 0.333333) { // hom + ret[0]->s[i] = ret[1]->s[i] = SUBSTITUTE|c; + } else { // het + ret[drand48()<0.5?0:1]->s[i] = SUBSTITUTE|c; + } + } else { // indel + if (drand48() < 0.5) { // deletion + if (is_hap || drand48() < 0.333333) { // hom-del + ret[0]->s[i] = ret[1]->s[i] = DELETE; + deleting = 3; + } else { // het-del + deleting = drand48()<0.5?1:2; + ret[deleting-1]->s[i] = DELETE; + } + } else { // insertion + int num_ins = 0, ins = 0; + do { + num_ins++; + ins = (ins << 2) | (int)(drand48() * 4.0); + } while (num_ins < 4 && drand48() < INDEL_EXTEND); + + if (is_hap || drand48() < 0.333333) { // hom-ins + ret[0]->s[i] = ret[1]->s[i] = (num_ins << 12) | (ins << 4) | c; + } else { // het-ins + ret[drand48()<0.5?0:1]->s[i] = (num_ins << 12) | (ins << 4) | c; + } + } + } + } + } +} +void maq_print_mutref(const char *name, const seq_t *seq, mutseq_t *hap1, mutseq_t *hap2) +{ + int i; + for (i = 0; i != seq->l; ++i) { + int c[3]; + c[0] = nst_nt4_table[(int)seq->s[i]]; + c[1] = hap1->s[i]; c[2] = hap2->s[i]; + if (c[0] >= 4) continue; + if ((c[1] & mutmsk) != NOCHANGE || (c[2] & mutmsk) != NOCHANGE) { + printf("%s\t%d\t", name, i+1); + if (c[1] == c[2]) { // hom + if ((c[1]&mutmsk) == SUBSTITUTE) { // substitution + printf("%c\t%c\t-\n", "ACGTN"[c[0]], "ACGTN"[c[1]&0xf]); + } else if ((c[1]&mutmsk) == DELETE) { // del + printf("%c\t-\t-\n", "ACGTN"[c[0]]); + } else if (((c[1] & mutmsk) >> 12) <= 5) { // ins + printf("-\t"); + int n = (c[1]&mutmsk) >> 12, ins = c[1] >> 4; + while(n > 0) { + putchar("ACGTN"[ins & 0x3]); + n--; + } + printf("\t-\n"); + } else assert(0); + } else { // het + if ((c[1]&mutmsk) == SUBSTITUTE || (c[2]&mutmsk) == SUBSTITUTE) { // substitution + printf("%c\t%c\t+\n", "ACGTN"[c[0]], "XACMGRSVTWYHKDBN"[1<<(c[1]&0x3)|1<<(c[2]&0x3)]); + } else if ((c[1]&mutmsk) == DELETE) { + printf("%c\t-\t+\n", "ACGTN"[c[0]]); + } else if ((c[2]&mutmsk) == DELETE) { + printf("%c\t-\t+\n", "ACGTN"[c[0]]); + } else if (((c[1] & mutmsk) >> 12) <= 4) { // ins1 + printf("-\t"); + int n = (c[1]&mutmsk) >> 12, ins = c[1] >> 4; + while (n > 0) { + putchar("ACGTN"[ins & 0x3]); + n--; + } + printf("\t+\n"); + } else if (((c[2] & mutmsk) >> 12) <= 5) { // ins2 + printf("-\t"); + int n = (c[2]&mutmsk) >> 12, ins = c[2] >> 4; + while (n > 0) { + putchar("ACGTN"[ins & 0x3]); + ins >>= 2; + n--; + } + printf("\t+\n"); + } else assert(0); + } + } + } +} + +void wgsim_core(FILE *fpout1, FILE *fpout2, FILE *fp_fa, int is_hap, uint64_t N, int dist, int std_dev, int size_l, int size_r) +{ + seq_t seq; + mutseq_t rseq[2]; + uint64_t tot_len, ii; + int i, l, n_ref; + char name[256], *qstr; + int size[2], Q; + uint8_t *tmp_seq[2]; + mut_t *target; + + INIT_SEQ(seq); + srand48(time(0)); + seq_set_block_size(0x1000000); + l = size_l > size_r? size_l : size_r; + qstr = (char*)calloc(l+1, 1); + tmp_seq[0] = (uint8_t*)calloc(l+2, 1); + tmp_seq[1] = (uint8_t*)calloc(l+2, 1); + size[0] = size_l; size[1] = size_r; + + Q = (ERR_RATE == 0.0)? 'I' : (int)(-10.0 * log(ERR_RATE) / log(10.0) + 0.499) + 33; + + tot_len = n_ref = 0; + while ((l = seq_read_fasta(fp_fa, &seq, name, 0)) >= 0) { + tot_len += l; + ++n_ref; + } + fprintf(stderr, "[wgsim_core] %d sequences, total length: %llu\n", n_ref, (long long)tot_len); + rewind(fp_fa); + + while ((l = seq_read_fasta(fp_fa, &seq, name, 0)) >= 0) { + uint64_t n_pairs = (uint64_t)((long double)l / tot_len * N + 0.5); + if (l < dist + 3 * std_dev) { + fprintf(stderr, "[wgsim_core] kkip sequence '%s' as it is shorter than %d!\n", name, dist + 3 * std_dev); + continue; + } + + // generate mutations and print them out + maq_mut_diref(&seq, is_hap, rseq, rseq+1); + maq_print_mutref(name, &seq, rseq, rseq+1); + + for (ii = 0; ii != n_pairs; ++ii) { // the core loop + double ran; + int d, pos, s[2], is_flip = 0; + int n_sub[2], n_indel[2], n_err[2], ext_coor[2], j, k; + FILE *fpo[2]; + + do { // avoid boundary failure + ran = ran_normal(); + ran = ran * std_dev + dist; + d = (int)(ran + 0.5); + pos = (int)((l - d + 1) * drand48()); + } while (pos < 0 || pos >= seq.l || pos + d - 1 >= seq.l); + + // flip or not + if (drand48() < 0.5) { + fpo[0] = fpout1; fpo[1] = fpout2; + s[0] = size[0]; s[1] = size[1]; + } else { + fpo[1] = fpout1; fpo[0] = fpout2; + s[1] = size[0]; s[0] = size[1]; + is_flip = 1; + } + + // generate the read sequences + target = rseq[drand48()<0.5?0:1].s; // haplotype from which the reads are generated + n_sub[0] = n_sub[1] = n_indel[0] = n_indel[1] = n_err[0] = n_err[1] = 0; + +#define __gen_read(x, start, iter) do { \ + for (i = (start), k = 0, ext_coor[x] = -10; i >= 0 && i < seq.l && k < s[x]; iter) { \ + int c = target[i], mut_type = c & mutmsk; \ + if (ext_coor[x] < 0) { \ + if (mut_type != NOCHANGE && mut_type != SUBSTITUTE) continue; \ + ext_coor[x] = i; \ + } \ + if (mut_type == DELETE) ++n_indel[x]; \ + else if (mut_type == NOCHANGE || mut_type == SUBSTITUTE) { \ + tmp_seq[x][k++] = c & 0xf; \ + if (mut_type == SUBSTITUTE) ++n_sub[x]; \ + } else { \ + int n, ins; \ + ++n_indel[x]; \ + tmp_seq[x][k++] = c & 0xf; \ + for (n = mut_type>>12, ins = c>>4; n > 0 && k < s[x]; --n, ins >>= 2) \ + tmp_seq[x][k++] = ins & 0x3; \ + } \ + } \ + if (k != s[x]) ext_coor[x] = -10; \ + } while (0) + + if (!IS_SOLID) { + __gen_read(0, pos, ++i); + __gen_read(1, pos + d - 1, --i); + for (k = 0; k < s[1]; ++k) tmp_seq[1][k] = tmp_seq[1][k] < 4? 3 - tmp_seq[1][k] : 4; // complement + } else { + int c1, c2, c; + ++s[0]; ++s[1]; // temporarily increase read length by 1 + if (is_flip) { // RR pair + __gen_read(0, pos + s[0], --i); + __gen_read(1, pos + d - 1, --i); + } else { // FF pair + __gen_read(0, pos, ++i); + __gen_read(1, pos + d - 1 - s[1], ++i); + ++ext_coor[0]; ++ext_coor[1]; + } + // change to color sequence: (0,1,2,3) -> (A,C,G,T) + for (j = 0; j < 2; ++j) { + c1 = tmp_seq[j][0]; + for (i = 1; i < s[j]; ++i) { + c2 = tmp_seq[j][i]; + c = (c1 >= 4 || c2 >= 4)? 4 : nst_color_space_table[(1<<c1)|(1<<c2)]; + tmp_seq[j][i-1] = c; + c1 = c2; + } + } + --s[0]; --s[1]; // change back + } + if (ext_coor[0] < 0 || ext_coor[1] < 0) { // fail to generate the read(s) + --ii; + continue; + } + + // generate sequencing errors + for (j = 0; j < 2; ++j) { + for (i = 0; i < s[j]; ++i) { + int c = tmp_seq[j][i]; + if (c >= 4) c = 4; // actually c should be never larger than 4 if everything is correct + else if (drand48() < ERR_RATE) { + c = (c + (int)(drand48() * 3.0 + 1)) & 3; + ++n_err[j]; + } + tmp_seq[j][i] = c; + } + } + + // print + for (j = 0; j < 2; ++j) { + for (i = 0; i < s[j]; ++i) qstr[i] = Q; + qstr[i] = 0; + if (SHOW_MM_INFO) { + fprintf(fpo[j], "@%s_%u_%u_%d:%d:%d_%d:%d:%d_%llx/%d\n", name, ext_coor[0]+1, ext_coor[1]+1, + n_err[0], n_sub[0], n_indel[0], n_err[1], n_sub[1], n_indel[1], + (long long)ii, j==0? is_flip+1 : 2-is_flip); + } else { + fprintf(fpo[j], "@%s_%u_%u_%llx/%d %d:%d:%d_%d:%d:%d\n", name, ext_coor[0]+1, ext_coor[1]+1, + (long long)ii, j==0? is_flip+1 : 2-is_flip, + n_err[0], n_sub[0], n_indel[0], n_err[1], n_sub[1], n_indel[1]); + } + for (i = 0; i < s[j]; ++i) + fputc("ACGTN"[(int)tmp_seq[j][i]], fpo[j]); + fprintf(fpo[j], "\n+\n%s\n", qstr); + } + } + free(rseq[0].s); free(rseq[1].s); + } + free(seq.s); free(qstr); + free(tmp_seq[0]); free(tmp_seq[1]); +} + +static int simu_usage() +{ + fprintf(stderr, "\n"); + fprintf(stderr, "Program: wgsim (short read simulator)\n"); + fprintf(stderr, "Version: %s\n", PACKAGE_VERSION); + fprintf(stderr, "Contact: Heng Li <lh3@sanger.ac.uk>\n\n"); + fprintf(stderr, "Usage: wgsim [options] <in.ref.fa> <out.read1.fq> <out.read2.fq>\n\n"); + fprintf(stderr, "Options: -e FLOAT base error rate [%.3f]\n", ERR_RATE); + fprintf(stderr, " -d INT outer distance between the two ends [500]\n"); + fprintf(stderr, " -s INT standard deviation [50]\n"); + fprintf(stderr, " -N INT number of read pairs [1000000]\n"); + fprintf(stderr, " -1 INT length of the first read [70]\n"); + fprintf(stderr, " -2 INT length of the second read [70]\n"); + fprintf(stderr, " -r FLOAT rate of mutations [%.4f]\n", MUT_RATE); + fprintf(stderr, " -R FLOAT fraction of indels [%.2f]\n", INDEL_FRAC); + fprintf(stderr, " -X FLOAT probability an indel is extended [%.2f]\n", INDEL_EXTEND); + fprintf(stderr, " -c generate reads in color space (SOLiD reads)\n"); + fprintf(stderr, " -C show mismatch info in comment rather than read name\n"); + fprintf(stderr, " -h haplotype mode\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "Note: For SOLiD reads, the first read is F3 and the second is R3.\n\n"); + return 1; +} + +int main(int argc, char *argv[]) +{ + int64_t N; + int dist, std_dev, c, size_l, size_r, is_hap = 0; + FILE *fpout1, *fpout2, *fp_fa; + + N = 1000000; dist = 500; std_dev = 50; + size_l = size_r = 70; + while ((c = getopt(argc, argv, "e:d:s:N:1:2:r:R:hX:cC")) >= 0) { + switch (c) { + case 'd': dist = atoi(optarg); break; + case 's': std_dev = atoi(optarg); break; + case 'N': N = atoi(optarg); break; + case '1': size_l = atoi(optarg); break; + case '2': size_r = atoi(optarg); break; + case 'e': ERR_RATE = atof(optarg); break; + case 'r': MUT_RATE = atof(optarg); break; + case 'R': INDEL_FRAC = atof(optarg); break; + case 'X': INDEL_EXTEND = atof(optarg); break; + case 'c': IS_SOLID = 1; break; + case 'C': SHOW_MM_INFO = 0; break; + case 'h': is_hap = 1; break; + } + } + if (argc - optind < 3) return simu_usage(); + fp_fa = (strcmp(argv[optind+0], "-") == 0)? stdin : xopen(argv[optind+0], "r"); + fpout1 = xopen(argv[optind+1], "w"); + fpout2 = xopen(argv[optind+2], "w"); + wgsim_core(fpout1, fpout2, fp_fa, is_hap, N, dist, std_dev, size_l, size_r); + + fclose(fpout1); fclose(fpout2); fclose(fp_fa); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/misc/wgsim_eval.pl Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,91 @@ +#!/usr/bin/perl -w + +# Contact: lh3 +# Version: 0.1.5 + +use strict; +use warnings; +use Getopt::Std; + +&wgsim_eval; +exit; + +sub wgsim_eval { + my %opts = (g=>5); + getopts('pcag:', \%opts); + die("Usage: wgsim_eval.pl [-pca] [-g $opts{g}] <in.sam>\n") if (@ARGV == 0 && -t STDIN); + my (@c0, @c1, %fnfp); + my ($max_q, $flag) = (0, 0); + my $gap = $opts{g}; + $flag |= 1 if (defined $opts{p}); + $flag |= 2 if (defined $opts{c}); + while (<>) { + next if (/^\@/); + my @t = split("\t"); + next if (@t < 11); + my $line = $_; + my ($q, $is_correct, $chr, $left, $rght) = (int($t[4]/10), 1, $t[2], $t[3], $t[3]); + $max_q = $q if ($q > $max_q); + # right coordinate + $_ = $t[5]; s/(\d+)[MDN]/$rght+=$1,'x'/eg; + --$rght; + # correct for soft clipping + my ($left0, $rght0) = ($left, $rght); + $left -= $1 if (/^(\d+)[SH]/); + $rght += $1 if (/(\d+)[SH]$/); + $left0 -= $1 if (/(\d+)[SH]$/); + $rght0 += $1 if (/^(\d+)[SH]/); + # skip unmapped reads + next if (($t[1]&0x4) || $chr eq '*'); + # parse read name and check + if ($t[0] =~ /^(\S+)_(\d+)_(\d+)_/) { + if ($1 ne $chr) { # different chr + $is_correct = 0; + } else { + if ($flag & 2) { + if (($t[1]&0x40) && !($t[1]&0x10)) { # F3, forward + $is_correct = 0 if (abs($2 - $left) > $gap && abs($2 - $left0) > $gap); + } elsif (($t[1]&0x40) && ($t[1]&0x10)) { # F3, reverse + $is_correct = 0 if (abs($3 - $rght) > $gap && abs($3 - $rght0) > $gap); + } elsif (($t[1]&0x80) && !($t[1]&0x10)) { # R3, forward + $is_correct = 0 if (abs($3 - $left) > $gap && abs($3 - $left0) > $gap); + } else { # R3, reverse + $is_correct = 0 if (abs($2 - $rght) > $gap && abs($3 - $rght0) > $gap); + } + } else { + if ($t[1] & 0x10) { # reverse + $is_correct = 0 if (abs($3 - $rght) > $gap && abs($3 - $rght0) > $gap); # in case of indels that are close to the end of a reads + } else { + $is_correct = 0 if (abs($2 - $left) > $gap && abs($2 - $left0) > $gap); + } + } + } + } else { + warn("[wgsim_eval] read '$t[0]' was not generated by wgsim?\n"); + next; + } + ++$c0[$q]; + ++$c1[$q] unless ($is_correct); + @{$fnfp{$t[4]}} = (0, 0) unless (defined $fnfp{$t[4]}); + ++$fnfp{$t[4]}[0]; + ++$fnfp{$t[4]}[1] unless ($is_correct); + print STDERR $line if (($flag&1) && !$is_correct && $q > 0); + } + # print + my ($cc0, $cc1) = (0, 0); + if (!defined($opts{a})) { + for (my $i = $max_q; $i >= 0; --$i) { + $c0[$i] = 0 unless (defined $c0[$i]); + $c1[$i] = 0 unless (defined $c1[$i]); + $cc0 += $c0[$i]; $cc1 += $c1[$i]; + printf("%.2dx %12d / %-12d %12d %.3e\n", $i, $c1[$i], $c0[$i], $cc0, $cc1/$cc0) if ($cc0); + } + } else { + for (reverse(sort {$a<=>$b} (keys %fnfp))) { + next if ($_ == 0); + $cc0 += $fnfp{$_}[0]; + $cc1 += $fnfp{$_}[1]; + print join("\t", $_, $cc0, $cc1), "\n"; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/misc/zoom2sam.pl Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,97 @@ +#!/usr/bin/perl -w + +# Contact: lh3 +# Version: 0.1.0 + +use strict; +use warnings; +use Getopt::Std; + +&zoom2sam; +exit; + +sub mating { + my ($s1, $s2) = @_; + my $isize = 0; + if ($s1->[2] ne '*' && $s1->[2] eq $s2->[2]) { # then calculate $isize + my $x1 = ($s1->[1] & 0x10)? $s1->[3] + length($s1->[9]) : $s1->[3]; + my $x2 = ($s2->[1] & 0x10)? $s2->[3] + length($s2->[9]) : $s2->[3]; + $isize = $x2 - $x1; + } + # update mate coordinate + if ($s2->[2] ne '*') { + @$s1[6..8] = (($s2->[2] eq $s1->[2])? "=" : $s2->[2], $s2->[3], $isize); + $s1->[1] |= 0x20 if ($s2->[1] & 0x10); + } else { + $s1->[1] |= 0x8; + } + if ($s1->[2] ne '*') { + @$s2[6..8] = (($s1->[2] eq $s2->[2])? "=" : $s1->[2], $s1->[3], -$isize); + $s2->[1] |= 0x20 if ($s1->[1] & 0x10); + } else { + $s2->[1] |= 0x8; + } +} + +sub zoom2sam { + my %opts = (); + getopts("p", \%opts); + die("Usage: zoom2sam.pl [-p] <readLen> <aln.zoom> +Warnings: This script only supports the default Illumina outputs.\n") if (@ARGV < 2); + my $is_paired = defined($opts{p}); + my $len = shift(@ARGV); + # core loop + my @s1 = (); + my @s2 = (); + my ($s_last, $s_curr) = (\@s1, \@s2); + while (<>) { + &zoom2sam_aux($_, $s_curr, $is_paired, $len); + if (@$s_last != 0 && $s_last->[0] eq $s_curr->[0]) { + &mating($s_last, $s_curr); + print join("\t", @$s_last), "\n"; + print join("\t", @$s_curr), "\n"; + @$s_last = (); @$s_curr = (); + } else { + print join("\t", @$s_last), "\n" if (@$s_last != 0); + my $s = $s_last; $s_last = $s_curr; $s_curr = $s; + } + } + print join("\t", @$s_last), "\n" if (@$s_last != 0); +} + +sub zoom2sam_aux { + my ($line, $s, $is_paired, $len) = @_; + chomp($line); + my @t = split("\t", $line); + @$s = (); + # read name + $s->[0] = $t[0]; + # initial flag (will be updated later) + $s->[1] = 0; + $s->[1] |= 1 | 1<<6 if ($s->[0] =~ /_F$/); + $s->[1] |= 1 | 1<<7 if ($s->[0] =~ /_R$/); + $s->[1] |= 2 if ($is_paired); + # read & quality + $s->[9] = "*"; $s->[10] = "*"; + # cigar + $s->[5] = $len . "M"; + # coor + my @s = split(/\s+/, $t[1]); + $s->[2] = $s[0]; + $t[1] =~ /:(\d+)$/; + $s->[3] = $1 + 1; + if ($s->[0] =~ /_[FR]$/) { + my $u = ($s->[0] =~ /_F$/)? 1 : 0; + my $w = ($t[2] eq '+')? 1 : 0; + $s->[1] |= 0x10 if ($u ^ $w); + $s->[0] =~ s/_[FR]$//; + } else { + $s->[1] |= 0x10 if ($t[2] eq '-'); + } + # mapQ + $s->[4] = 30; + # mate coordinate + $s->[6] = '*'; $s->[7] = $s->[8] = 0; + # aux + push(@$s, "NM:i:$t[3]"); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/phase.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,687 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <stdint.h> +#include <math.h> +#include <zlib.h> +#include "bam.h" +#include "errmod.h" + +#include "kseq.h" +KSTREAM_INIT(gzFile, gzread, 16384) + +#define MAX_VARS 256 +#define FLIP_PENALTY 2 +#define FLIP_THRES 4 +#define MASK_THRES 3 + +#define FLAG_FIX_CHIMERA 0x1 +#define FLAG_LIST_EXCL 0x4 +#define FLAG_DROP_AMBI 0x8 + +typedef struct { + // configurations, initialized in the main function + int flag, k, min_baseQ, min_varLOD, max_depth; + // other global variables + int vpos_shift; + bamFile fp; + char *pre; + bamFile out[3]; + // alignment queue + int n, m; + bam1_t **b; +} phaseg_t; + +typedef struct { + int8_t seq[MAX_VARS]; // TODO: change to dynamic memory allocation! + int vpos, beg, end; + uint32_t vlen:16, single:1, flip:1, phase:1, phased:1, ambig:1; + uint32_t in:16, out:16; // in-phase and out-phase +} frag_t, *frag_p; + +#define rseq_lt(a,b) ((a)->vpos < (b)->vpos) + +#include "khash.h" +KHASH_SET_INIT_INT64(set64) +KHASH_MAP_INIT_INT64(64, frag_t) + +typedef khash_t(64) nseq_t; + +#include "ksort.h" +KSORT_INIT(rseq, frag_p, rseq_lt) + +static char nt16_nt4_table[] = { 4, 0, 1, 4, 2, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4 }; + +static inline uint64_t X31_hash_string(const char *s) +{ + uint64_t h = *s; + if (h) for (++s ; *s; ++s) h = (h << 5) - h + *s; + return h; +} + +static void count1(int l, const uint8_t *seq, int *cnt) +{ + int i, j, n_ambi; + uint32_t z, x; + if (seq[l-1] == 0) return; // do nothing is the last base is ambiguous + for (i = n_ambi = 0; i < l; ++i) // collect ambiguous bases + if (seq[i] == 0) ++n_ambi; + if (l - n_ambi <= 1) return; // only one SNP + for (x = 0; x < 1u<<n_ambi; ++x) { // count + for (i = j = 0, z = 0; i < l; ++i) { + int c; + if (seq[i]) c = seq[i] - 1; + else { + c = x>>j&1; + ++j; + } + z = z<<1 | c; + } + ++cnt[z]; + } +} + +static int **count_all(int l, int vpos, nseq_t *hash) +{ + khint_t k; + int i, j, **cnt; + uint8_t *seq; + seq = calloc(l, 1); + cnt = calloc(vpos, sizeof(void*)); + for (i = 0; i < vpos; ++i) cnt[i] = calloc(1<<l, sizeof(int)); + for (k = 0; k < kh_end(hash); ++k) { + if (kh_exist(hash, k)) { + frag_t *f = &kh_val(hash, k); + if (f->vpos >= vpos || f->single) continue; // out of region; or singleton + if (f->vlen == 1) { // such reads should be flagged as deleted previously if everything is right + f->single = 1; + continue; + } + for (j = 1; j < f->vlen; ++j) { + for (i = 0; i < l; ++i) + seq[i] = j < l - 1 - i? 0 : f->seq[j - (l - 1 - i)]; + count1(l, seq, cnt[f->vpos + j]); + } + } + } + free(seq); + return cnt; +} + +// phasing +static int8_t *dynaprog(int l, int vpos, int **w) +{ + int *f[2], *curr, *prev, max, i; + int8_t **b, *h = 0; + uint32_t x, z = 1u<<(l-1), mask = (1u<<l) - 1; + f[0] = calloc(z, sizeof(int)); + f[1] = calloc(z, sizeof(int)); + b = calloc(vpos, sizeof(void*)); + prev = f[0]; curr = f[1]; + // fill the backtrack matrix + for (i = 0; i < vpos; ++i) { + int *wi = w[i], *tmp; + int8_t *bi; + bi = b[i] = calloc(z, 1); + /* In the following, x is the current state, which is the + * lexicographically smaller local haplotype. xc is the complement of + * x, or the larger local haplotype; y0 and y1 are the two predecessors + * of x. */ + for (x = 0; x < z; ++x) { // x0 is the smaller + uint32_t y0, y1, xc; + int c0, c1; + xc = ~x&mask; y0 = x>>1; y1 = xc>>1; + c0 = prev[y0] + wi[x] + wi[xc]; + c1 = prev[y1] + wi[x] + wi[xc]; + if (c0 > c1) bi[x] = 0, curr[x] = c0; + else bi[x] = 1, curr[x] = c1; + } + tmp = prev; prev = curr; curr = tmp; // swap + } + { // backtrack + uint32_t max_x = 0; + int which = 0; + h = calloc(vpos, 1); + for (x = 0, max = 0, max_x = 0; x < z; ++x) + if (prev[x] > max) max = prev[x], max_x = x; + for (i = vpos - 1, x = max_x; i >= 0; --i) { + h[i] = which? (~x&1) : (x&1); + which = b[i][x]? !which : which; + x = b[i][x]? (~x&mask)>>1 : x>>1; + } + } + // free + for (i = 0; i < vpos; ++i) free(b[i]); + free(f[0]); free(f[1]); free(b); + return h; +} + +// phase each fragment +static uint64_t *fragphase(int vpos, const int8_t *path, nseq_t *hash, int flip) +{ + khint_t k; + uint64_t *pcnt; + uint32_t *left, *rght, max; + left = rght = 0; max = 0; + pcnt = calloc(vpos, 8); + for (k = 0; k < kh_end(hash); ++k) { + if (kh_exist(hash, k)) { + int i, c[2]; + frag_t *f = &kh_val(hash, k); + if (f->vpos >= vpos) continue; + // get the phase + c[0] = c[1] = 0; + for (i = 0; i < f->vlen; ++i) { + if (f->seq[i] == 0) continue; + ++c[f->seq[i] == path[f->vpos + i] + 1? 0 : 1]; + } + f->phase = c[0] > c[1]? 0 : 1; + f->in = c[f->phase]; f->out = c[1 - f->phase]; + f->phased = f->in == f->out? 0 : 1; + f->ambig = (f->in && f->out && f->out < 3 && f->in <= f->out + 1)? 1 : 0; + // fix chimera + f->flip = 0; + if (flip && c[0] >= 3 && c[1] >= 3) { + int sum[2], m, mi, md; + if (f->vlen > max) { // enlarge the array + max = f->vlen; + kroundup32(max); + left = realloc(left, max * 4); + rght = realloc(rght, max * 4); + } + for (i = 0, sum[0] = sum[1] = 0; i < f->vlen; ++i) { // get left counts + if (f->seq[i]) { + int c = f->phase? 2 - f->seq[i] : f->seq[i] - 1; + ++sum[c == path[f->vpos + i]? 0 : 1]; + } + left[i] = sum[1]<<16 | sum[0]; + } + for (i = f->vlen - 1, sum[0] = sum[1] = 0; i >= 0; --i) { // get right counts + if (f->seq[i]) { + int c = f->phase? 2 - f->seq[i] : f->seq[i] - 1; + ++sum[c == path[f->vpos + i]? 0 : 1]; + } + rght[i] = sum[1]<<16 | sum[0]; + } + // find the best flip point + for (i = m = 0, mi = -1, md = -1; i < f->vlen - 1; ++i) { + int a[2]; + a[0] = (left[i]&0xffff) + (rght[i+1]>>16&0xffff) - (rght[i+1]&0xffff) * FLIP_PENALTY; + a[1] = (left[i]>>16&0xffff) + (rght[i+1]&0xffff) - (rght[i+1]>>16&0xffff) * FLIP_PENALTY; + if (a[0] > a[1]) { + if (a[0] > m) m = a[0], md = 0, mi = i; + } else { + if (a[1] > m) m = a[1], md = 1, mi = i; + } + } + if (m - c[0] >= FLIP_THRES && m - c[1] >= FLIP_THRES) { // then flip + f->flip = 1; + if (md == 0) { // flip the tail + for (i = mi + 1; i < f->vlen; ++i) + if (f->seq[i] == 1) f->seq[i] = 2; + else if (f->seq[i] == 2) f->seq[i] = 1; + } else { // flip the head + for (i = 0; i <= mi; ++i) + if (f->seq[i] == 1) f->seq[i] = 2; + else if (f->seq[i] == 2) f->seq[i] = 1; + } + } + } + // update pcnt[] + if (!f->single) { + for (i = 0; i < f->vlen; ++i) { + int c; + if (f->seq[i] == 0) continue; + c = f->phase? 2 - f->seq[i] : f->seq[i] - 1; + if (c == path[f->vpos + i]) { + if (f->phase == 0) ++pcnt[f->vpos + i]; + else pcnt[f->vpos + i] += 1ull<<32; + } else { + if (f->phase == 0) pcnt[f->vpos + i] += 1<<16; + else pcnt[f->vpos + i] += 1ull<<48; + } + } + } + } + } + free(left); free(rght); + return pcnt; +} + +static uint64_t *genmask(int vpos, const uint64_t *pcnt, int *_n) +{ + int i, max = 0, max_i = -1, m = 0, n = 0, beg = 0, score = 0; + uint64_t *list = 0; + for (i = 0; i < vpos; ++i) { + uint64_t x = pcnt[i]; + int c[4], pre = score, s; + c[0] = x&0xffff; c[1] = x>>16&0xffff; c[2] = x>>32&0xffff; c[3] = x>>48&0xffff; + s = (c[1] + c[3] == 0)? -(c[0] + c[2]) : (c[1] + c[3] - 1); + if (c[3] > c[2]) s += c[3] - c[2]; + if (c[1] > c[0]) s += c[1] - c[0]; + score += s; + if (score < 0) score = 0; + if (pre == 0 && score > 0) beg = i; // change from zero to non-zero + if ((i == vpos - 1 || score == 0) && max >= MASK_THRES) { + if (n == m) { + m = m? m<<1 : 4; + list = realloc(list, m * 8); + } + list[n++] = (uint64_t)beg<<32 | max_i; + i = max_i; // reset i to max_i + score = 0; + } else if (score > max) max = score, max_i = i; + if (score == 0) max = 0; + } + *_n = n; + return list; +} + +// trim heading and tailing ambiguous bases; mark deleted and remove sequence +static int clean_seqs(int vpos, nseq_t *hash) +{ + khint_t k; + int ret = 0; + for (k = 0; k < kh_end(hash); ++k) { + if (kh_exist(hash, k)) { + frag_t *f = &kh_val(hash, k); + int beg, end, i; + if (f->vpos >= vpos) { + ret = 1; + continue; + } + for (i = 0; i < f->vlen; ++i) + if (f->seq[i] != 0) break; + beg = i; + for (i = f->vlen - 1; i >= 0; --i) + if (f->seq[i] != 0) break; + end = i + 1; + if (end - beg <= 0) kh_del(64, hash, k); + else { + if (beg != 0) memmove(f->seq, f->seq + beg, end - beg); + f->vpos += beg; f->vlen = end - beg; + f->single = f->vlen == 1? 1 : 0; + } + } + } + return ret; +} + +static void dump_aln(phaseg_t *g, int min_pos, const nseq_t *hash) +{ + int i, is_flip, drop_ambi; + drop_ambi = g->flag & FLAG_DROP_AMBI; + is_flip = (drand48() < 0.5); + for (i = 0; i < g->n; ++i) { + int end, which; + uint64_t key; + khint_t k; + bam1_t *b = g->b[i]; + key = X31_hash_string(bam1_qname(b)); + end = bam_calend(&b->core, bam1_cigar(b)); + if (end > min_pos) break; + k = kh_get(64, hash, key); + if (k == kh_end(hash)) which = 3; + else { + frag_t *f = &kh_val(hash, k); + if (f->ambig) which = drop_ambi? 2 : 3; + else if (f->phased && f->flip) which = 2; + else if (f->phased == 0) which = 3; + else { // phased and not flipped + char c = 'Y'; + which = f->phase; + bam_aux_append(b, "ZP", 'A', 1, (uint8_t*)&c); + } + if (which < 2 && is_flip) which = 1 - which; // increase the randomness + } + if (which == 3) which = (drand48() < 0.5); + bam_write1(g->out[which], b); + bam_destroy1(b); + g->b[i] = 0; + } + memmove(g->b, g->b + i, (g->n - i) * sizeof(void*)); + g->n -= i; +} + +static int phase(phaseg_t *g, const char *chr, int vpos, uint64_t *cns, nseq_t *hash) +{ + int i, j, n_seqs = kh_size(hash), n_masked = 0, min_pos; + khint_t k; + frag_t **seqs; + int8_t *path, *sitemask; + uint64_t *pcnt, *regmask; + + if (vpos == 0) return 0; + i = clean_seqs(vpos, hash); // i is true if hash has an element with its vpos >= vpos + min_pos = i? cns[vpos]>>32 : 0x7fffffff; + if (vpos == 1) { + printf("PS\t%s\t%d\t%d\n", chr, (int)(cns[0]>>32) + 1, (int)(cns[0]>>32) + 1); + printf("M0\t%s\t%d\t%d\t%c\t%c\t%d\t0\t0\t0\t0\n//\n", chr, (int)(cns[0]>>32) + 1, (int)(cns[0]>>32) + 1, + "ACGTX"[cns[0]&3], "ACGTX"[cns[0]>>16&3], g->vpos_shift + 1); + for (k = 0; k < kh_end(hash); ++k) { + if (kh_exist(hash, k)) { + frag_t *f = &kh_val(hash, k); + if (f->vpos) continue; + f->flip = 0; + if (f->seq[0] == 0) f->phased = 0; + else f->phased = 1, f->phase = f->seq[0] - 1; + } + } + dump_aln(g, min_pos, hash); + ++g->vpos_shift; + return 1; + } + { // phase + int **cnt; + uint64_t *mask; + printf("PS\t%s\t%d\t%d\n", chr, (int)(cns[0]>>32) + 1, (int)(cns[vpos-1]>>32) + 1); + sitemask = calloc(vpos, 1); + cnt = count_all(g->k, vpos, hash); + path = dynaprog(g->k, vpos, cnt); + for (i = 0; i < vpos; ++i) free(cnt[i]); + free(cnt); + pcnt = fragphase(vpos, path, hash, 0); // do not fix chimeras when masking + mask = genmask(vpos, pcnt, &n_masked); + regmask = calloc(n_masked, 8); + for (i = 0; i < n_masked; ++i) { + regmask[i] = cns[mask[i]>>32]>>32<<32 | cns[(uint32_t)mask[i]]>>32; + for (j = mask[i]>>32; j <= (int32_t)mask[i]; ++j) + sitemask[j] = 1; + } + free(mask); + if (g->flag & FLAG_FIX_CHIMERA) { + free(pcnt); + pcnt = fragphase(vpos, path, hash, 1); + } + } + for (i = 0; i < n_masked; ++i) + printf("FL\t%s\t%d\t%d\n", chr, (int)(regmask[i]>>32) + 1, (int)regmask[i] + 1); + for (i = 0; i < vpos; ++i) { + uint64_t x = pcnt[i]; + int8_t c[2]; + c[0] = (cns[i]&0xffff)>>2 == 0? 4 : (cns[i]&3); + c[1] = (cns[i]>>16&0xffff)>>2 == 0? 4 : (cns[i]>>16&3); + printf("M%d\t%s\t%d\t%d\t%c\t%c\t%d\t%d\t%d\t%d\t%d\n", sitemask[i]+1, chr, (int)(cns[0]>>32) + 1, (int)(cns[i]>>32) + 1, "ACGTX"[c[path[i]]], "ACGTX"[c[1-path[i]]], + i + g->vpos_shift + 1, (int)(x&0xffff), (int)(x>>16&0xffff), (int)(x>>32&0xffff), (int)(x>>48&0xffff)); + } + free(path); free(pcnt); free(regmask); free(sitemask); + seqs = calloc(n_seqs, sizeof(void*)); + for (k = 0, i = 0; k < kh_end(hash); ++k) + if (kh_exist(hash, k) && kh_val(hash, k).vpos < vpos && !kh_val(hash, k).single) + seqs[i++] = &kh_val(hash, k); + n_seqs = i; + ks_introsort_rseq(n_seqs, seqs); + for (i = 0; i < n_seqs; ++i) { + frag_t *f = seqs[i]; + printf("EV\t0\t%s\t%d\t40\t%dM\t*\t0\t0\t", chr, f->vpos + 1 + g->vpos_shift, f->vlen); + for (j = 0; j < f->vlen; ++j) { + uint32_t c = cns[f->vpos + j]; + if (f->seq[j] == 0) putchar('N'); + else putchar("ACGT"[f->seq[j] == 1? (c&3) : (c>>16&3)]); + } + printf("\t*\tYP:i:%d\tYF:i:%d\tYI:i:%d\tYO:i:%d\tYS:i:%d\n", f->phase, f->flip, f->in, f->out, f->beg+1); + } + free(seqs); + printf("//\n"); + fflush(stdout); + g->vpos_shift += vpos; + dump_aln(g, min_pos, hash); + return vpos; +} + +static void update_vpos(int vpos, nseq_t *hash) +{ + khint_t k; + for (k = 0; k < kh_end(hash); ++k) { + if (kh_exist(hash, k)) { + frag_t *f = &kh_val(hash, k); + if (f->vpos < vpos) kh_del(64, hash, k); // TODO: if frag_t::seq is allocated dynamically, free it + else f->vpos -= vpos; + } + } +} + +static nseq_t *shrink_hash(nseq_t *hash) // TODO: to implement +{ + return hash; +} + +static int readaln(void *data, bam1_t *b) +{ + phaseg_t *g = (phaseg_t*)data; + int ret; + ret = bam_read1(g->fp, b); + if (ret < 0) return ret; + if (!(b->core.flag & (BAM_FUNMAP|BAM_FSECONDARY|BAM_FQCFAIL|BAM_FDUP)) && g->pre) { + if (g->n == g->m) { + g->m = g->m? g->m<<1 : 16; + g->b = realloc(g->b, g->m * sizeof(void*)); + } + g->b[g->n++] = bam_dup1(b); + } + return ret; +} + +static khash_t(set64) *loadpos(const char *fn, bam_header_t *h) +{ + gzFile fp; + kstream_t *ks; + int ret, dret; + kstring_t *str; + khash_t(set64) *hash; + + hash = kh_init(set64); + str = calloc(1, sizeof(kstring_t)); + fp = strcmp(fn, "-")? gzopen(fn, "r") : gzdopen(fileno(stdin), "r"); + ks = ks_init(fp); + while (ks_getuntil(ks, 0, str, &dret) >= 0) { + int tid = bam_get_tid(h, str->s); + if (tid >= 0 && dret != '\n') { + if (ks_getuntil(ks, 0, str, &dret) >= 0) { + uint64_t x = (uint64_t)tid<<32 | (atoi(str->s) - 1); + kh_put(set64, hash, x, &ret); + } else break; + } + if (dret != '\n') while ((dret = ks_getc(ks)) > 0 && dret != '\n'); + if (dret < 0) break; + } + ks_destroy(ks); + gzclose(fp); + free(str->s); free(str); + return hash; +} + +static int gl2cns(float q[16]) +{ + int i, j, min_ij; + float min, min2; + min = min2 = 1e30; min_ij = -1; + for (i = 0; i < 4; ++i) { + for (j = i; j < 4; ++j) { + if (q[i<<2|j] < min) min_ij = i<<2|j, min2 = min, min = q[i<<2|j]; + else if (q[i<<2|j] < min2) min2 = q[i<<2|j]; + } + } + return (min_ij>>2&3) == (min_ij&3)? 0 : 1<<18 | (min_ij>>2&3)<<16 | (min_ij&3) | (int)(min2 - min + .499) << 2; +} + +int main_phase(int argc, char *argv[]) +{ + extern void bam_init_header_hash(bam_header_t *header); + int c, tid, pos, vpos = 0, n, lasttid = -1, max_vpos = 0; + const bam_pileup1_t *plp; + bam_plp_t iter; + bam_header_t *h; + nseq_t *seqs; + uint64_t *cns = 0; + phaseg_t g; + char *fn_list = 0; + khash_t(set64) *set = 0; + errmod_t *em; + uint16_t *bases; + + memset(&g, 0, sizeof(phaseg_t)); + g.flag = FLAG_FIX_CHIMERA; + g.min_varLOD = 37; g.k = 13; g.min_baseQ = 13; g.max_depth = 256; + while ((c = getopt(argc, argv, "Q:eFq:k:b:l:D:A:")) >= 0) { + switch (c) { + case 'D': g.max_depth = atoi(optarg); break; + case 'q': g.min_varLOD = atoi(optarg); break; + case 'Q': g.min_baseQ = atoi(optarg); break; + case 'k': g.k = atoi(optarg); break; + case 'F': g.flag &= ~FLAG_FIX_CHIMERA; break; + case 'e': g.flag |= FLAG_LIST_EXCL; break; + case 'A': g.flag |= FLAG_DROP_AMBI; break; + case 'b': g.pre = strdup(optarg); break; + case 'l': fn_list = strdup(optarg); break; + } + } + if (argc == optind) { + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: samtools phase [options] <in.bam>\n\n"); + fprintf(stderr, "Options: -k INT block length [%d]\n", g.k); + fprintf(stderr, " -b STR prefix of BAMs to output [null]\n"); + fprintf(stderr, " -q INT min het phred-LOD [%d]\n", g.min_varLOD); + fprintf(stderr, " -Q INT min base quality in het calling [%d]\n", g.min_baseQ); + fprintf(stderr, " -D INT max read depth [%d]\n", g.max_depth); +// fprintf(stderr, " -l FILE list of sites to phase [null]\n"); + fprintf(stderr, " -F do not attempt to fix chimeras\n"); + fprintf(stderr, " -A drop reads with ambiguous phase\n"); +// fprintf(stderr, " -e do not discover SNPs (effective with -l)\n"); + fprintf(stderr, "\n"); + return 1; + } + g.fp = strcmp(argv[optind], "-")? bam_open(argv[optind], "r") : bam_dopen(fileno(stdin), "r"); + h = bam_header_read(g.fp); + if (fn_list) { // read the list of sites to phase + bam_init_header_hash(h); + set = loadpos(fn_list, h); + free(fn_list); + } else g.flag &= ~FLAG_LIST_EXCL; + if (g.pre) { // open BAMs to write + char *s = malloc(strlen(g.pre) + 20); + strcpy(s, g.pre); strcat(s, ".0.bam"); g.out[0] = bam_open(s, "w"); + strcpy(s, g.pre); strcat(s, ".1.bam"); g.out[1] = bam_open(s, "w"); + strcpy(s, g.pre); strcat(s, ".chimera.bam"); g.out[2] = bam_open(s, "w"); + for (c = 0; c <= 2; ++c) bam_header_write(g.out[c], h); + free(s); + } + + iter = bam_plp_init(readaln, &g); + g.vpos_shift = 0; + seqs = kh_init(64); + em = errmod_init(1. - 0.83); + bases = calloc(g.max_depth, 2); + printf("CC\n"); + printf("CC\tDescriptions:\nCC\n"); + printf("CC\t CC comments\n"); + printf("CC\t PS start of a phase set\n"); + printf("CC\t FL filtered region\n"); + printf("CC\t M[012] markers; 0 for singletons, 1 for phased and 2 for filtered\n"); + printf("CC\t EV supporting reads; SAM format\n"); + printf("CC\t // end of a phase set\nCC\n"); + printf("CC\tFormats of PS, FL and M[012] lines (1-based coordinates):\nCC\n"); + printf("CC\t PS chr phaseSetStart phaseSetEnd\n"); + printf("CC\t FL chr filterStart filterEnd\n"); + printf("CC\t M? chr PS pos allele0 allele1 hetIndex #supports0 #errors0 #supp1 #err1\n"); + printf("CC\nCC\n"); + fflush(stdout); + while ((plp = bam_plp_auto(iter, &tid, &pos, &n)) != 0) { + int i, k, c, tmp, dophase = 1, in_set = 0; + float q[16]; + if (tid < 0) break; + if (tid != lasttid) { // change of chromosome + g.vpos_shift = 0; + if (lasttid >= 0) { + seqs = shrink_hash(seqs); + phase(&g, h->target_name[lasttid], vpos, cns, seqs); + update_vpos(0x7fffffff, seqs); + } + lasttid = tid; + vpos = 0; + } + if (set && kh_get(set64, set, (uint64_t)tid<<32 | pos) != kh_end(set)) in_set = 1; + if (n > g.max_depth) continue; // do not proceed if the depth is too high + // fill the bases array and check if there is a variant + for (i = k = 0; i < n; ++i) { + const bam_pileup1_t *p = plp + i; + uint8_t *seq; + int q, baseQ, b; + if (p->is_del || p->is_refskip) continue; + baseQ = bam1_qual(p->b)[p->qpos]; + if (baseQ < g.min_baseQ) continue; + seq = bam1_seq(p->b); + b = bam_nt16_nt4_table[bam1_seqi(seq, p->qpos)]; + if (b > 3) continue; + q = baseQ < p->b->core.qual? baseQ : p->b->core.qual; + if (q < 4) q = 4; + if (q > 63) q = 63; + bases[k++] = q<<5 | (int)bam1_strand(p->b)<<4 | b; + } + if (k == 0) continue; + errmod_cal(em, k, 4, bases, q); // compute genotype likelihood + c = gl2cns(q); // get the consensus + // tell if to proceed + if (set && (g.flag&FLAG_LIST_EXCL) && !in_set) continue; // not in the list + if (!in_set && (c&0xffff)>>2 < g.min_varLOD) continue; // not a variant + // add the variant + if (vpos == max_vpos) { + max_vpos = max_vpos? max_vpos<<1 : 128; + cns = realloc(cns, max_vpos * 8); + } + cns[vpos] = (uint64_t)pos<<32 | c; + for (i = 0; i < n; ++i) { + const bam_pileup1_t *p = plp + i; + uint64_t key; + khint_t k; + uint8_t *seq = bam1_seq(p->b); + frag_t *f; + if (p->is_del || p->is_refskip) continue; + if (p->b->core.qual == 0) continue; + // get the base code + c = nt16_nt4_table[(int)bam1_seqi(seq, p->qpos)]; + if (c == (cns[vpos]&3)) c = 1; + else if (c == (cns[vpos]>>16&3)) c = 2; + else c = 0; + // write to seqs + key = X31_hash_string(bam1_qname(p->b)); + k = kh_put(64, seqs, key, &tmp); + f = &kh_val(seqs, k); + if (tmp == 0) { // present in the hash table + if (vpos - f->vpos + 1 < MAX_VARS) { + f->vlen = vpos - f->vpos + 1; + f->seq[f->vlen-1] = c; + f->end = bam_calend(&p->b->core, bam1_cigar(p->b)); + } + dophase = 0; + } else { // absent + memset(f->seq, 0, MAX_VARS); + f->beg = p->b->core.pos; + f->end = bam_calend(&p->b->core, bam1_cigar(p->b)); + f->vpos = vpos, f->vlen = 1, f->seq[0] = c, f->single = f->phased = f->flip = f->ambig = 0; + } + } + if (dophase) { + seqs = shrink_hash(seqs); + phase(&g, h->target_name[tid], vpos, cns, seqs); + update_vpos(vpos, seqs); + cns[0] = cns[vpos]; + vpos = 0; + } + ++vpos; + } + if (tid >= 0) phase(&g, h->target_name[tid], vpos, cns, seqs); + bam_header_destroy(h); + bam_plp_destroy(iter); + bam_close(g.fp); + kh_destroy(64, seqs); + kh_destroy(set64, set); + free(cns); + errmod_destroy(em); + free(bases); + if (g.pre) { + for (c = 0; c <= 2; ++c) bam_close(g.out[c]); + free(g.pre); free(g.b); + } + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/razf.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,853 @@ +/* + * RAZF : Random Access compressed(Z) File + * Version: 1.0 + * Release Date: 2008-10-27 + * + * Copyright 2008, Jue Ruan <ruanjue@gmail.com>, Heng Li <lh3@sanger.ac.uk> + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _NO_RAZF + +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include "razf.h" + + +#if ZLIB_VERNUM < 0x1221 +struct _gz_header_s { + int text; + uLong time; + int xflags; + int os; + Bytef *extra; + uInt extra_len; + uInt extra_max; + Bytef *name; + uInt name_max; + Bytef *comment; + uInt comm_max; + int hcrc; + int done; +}; +#warning "zlib < 1.2.2.1; RAZF writing is disabled." +#endif + +#define DEF_MEM_LEVEL 8 + +static inline uint32_t byte_swap_4(uint32_t v){ + v = ((v & 0x0000FFFFU) << 16) | (v >> 16); + return ((v & 0x00FF00FFU) << 8) | ((v & 0xFF00FF00U) >> 8); +} + +static inline uint64_t byte_swap_8(uint64_t v){ + v = ((v & 0x00000000FFFFFFFFLLU) << 32) | (v >> 32); + v = ((v & 0x0000FFFF0000FFFFLLU) << 16) | ((v & 0xFFFF0000FFFF0000LLU) >> 16); + return ((v & 0x00FF00FF00FF00FFLLU) << 8) | ((v & 0xFF00FF00FF00FF00LLU) >> 8); +} + +static inline int is_big_endian(){ + int x = 0x01; + char *c = (char*)&x; + return (c[0] != 0x01); +} + +#ifndef _RZ_READONLY +static void add_zindex(RAZF *rz, int64_t in, int64_t out){ + if(rz->index->size == rz->index->cap){ + rz->index->cap = rz->index->cap * 1.5 + 2; + rz->index->cell_offsets = realloc(rz->index->cell_offsets, sizeof(int) * rz->index->cap); + rz->index->bin_offsets = realloc(rz->index->bin_offsets, sizeof(int64_t) * (rz->index->cap/RZ_BIN_SIZE + 1)); + } + if(rz->index->size % RZ_BIN_SIZE == 0) rz->index->bin_offsets[rz->index->size / RZ_BIN_SIZE] = out; + rz->index->cell_offsets[rz->index->size] = out - rz->index->bin_offsets[rz->index->size / RZ_BIN_SIZE]; + rz->index->size ++; +} + +static void save_zindex(RAZF *rz, int fd){ + int32_t i, v32; + int is_be; + is_be = is_big_endian(); + if(is_be) write(fd, &rz->index->size, sizeof(int)); + else { + v32 = byte_swap_4((uint32_t)rz->index->size); + write(fd, &v32, sizeof(uint32_t)); + } + v32 = rz->index->size / RZ_BIN_SIZE + 1; + if(!is_be){ + for(i=0;i<v32;i++) rz->index->bin_offsets[i] = byte_swap_8((uint64_t)rz->index->bin_offsets[i]); + for(i=0;i<rz->index->size;i++) rz->index->cell_offsets[i] = byte_swap_4((uint32_t)rz->index->cell_offsets[i]); + } + write(fd, rz->index->bin_offsets, sizeof(int64_t) * v32); + write(fd, rz->index->cell_offsets, sizeof(int32_t) * rz->index->size); +} +#endif + +#ifdef _USE_KNETFILE +static void load_zindex(RAZF *rz, knetFile *fp){ +#else +static void load_zindex(RAZF *rz, int fd){ +#endif + int32_t i, v32; + int is_be; + if(!rz->load_index) return; + if(rz->index == NULL) rz->index = malloc(sizeof(ZBlockIndex)); + is_be = is_big_endian(); +#ifdef _USE_KNETFILE + knet_read(fp, &rz->index->size, sizeof(int)); +#else + read(fd, &rz->index->size, sizeof(int)); +#endif + if(!is_be) rz->index->size = byte_swap_4((uint32_t)rz->index->size); + rz->index->cap = rz->index->size; + v32 = rz->index->size / RZ_BIN_SIZE + 1; + rz->index->bin_offsets = malloc(sizeof(int64_t) * v32); +#ifdef _USE_KNETFILE + knet_read(fp, rz->index->bin_offsets, sizeof(int64_t) * v32); +#else + read(fd, rz->index->bin_offsets, sizeof(int64_t) * v32); +#endif + rz->index->cell_offsets = malloc(sizeof(int) * rz->index->size); +#ifdef _USE_KNETFILE + knet_read(fp, rz->index->cell_offsets, sizeof(int) * rz->index->size); +#else + read(fd, rz->index->cell_offsets, sizeof(int) * rz->index->size); +#endif + if(!is_be){ + for(i=0;i<v32;i++) rz->index->bin_offsets[i] = byte_swap_8((uint64_t)rz->index->bin_offsets[i]); + for(i=0;i<rz->index->size;i++) rz->index->cell_offsets[i] = byte_swap_4((uint32_t)rz->index->cell_offsets[i]); + } +} + +#ifdef _RZ_READONLY +static RAZF* razf_open_w(int fd) +{ + fprintf(stderr, "[razf_open_w] Writing is not available with zlib ver < 1.2.2.1\n"); + return 0; +} +#else +static RAZF* razf_open_w(int fd){ + RAZF *rz; +#ifdef _WIN32 + setmode(fd, O_BINARY); +#endif + rz = calloc(1, sizeof(RAZF)); + rz->mode = 'w'; +#ifdef _USE_KNETFILE + rz->x.fpw = fd; +#else + rz->filedes = fd; +#endif + rz->stream = calloc(sizeof(z_stream), 1); + rz->inbuf = malloc(RZ_BUFFER_SIZE); + rz->outbuf = malloc(RZ_BUFFER_SIZE); + rz->index = calloc(sizeof(ZBlockIndex), 1); + deflateInit2(rz->stream, RZ_COMPRESS_LEVEL, Z_DEFLATED, WINDOW_BITS + 16, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); + rz->stream->avail_out = RZ_BUFFER_SIZE; + rz->stream->next_out = rz->outbuf; + rz->header = calloc(sizeof(gz_header), 1); + rz->header->os = 0x03; //Unix + rz->header->text = 0; + rz->header->time = 0; + rz->header->extra = malloc(7); + strncpy((char*)rz->header->extra, "RAZF", 4); + rz->header->extra[4] = 1; // obsolete field + // block size = RZ_BLOCK_SIZE, Big-Endian + rz->header->extra[5] = RZ_BLOCK_SIZE >> 8; + rz->header->extra[6] = RZ_BLOCK_SIZE & 0xFF; + rz->header->extra_len = 7; + rz->header->name = rz->header->comment = 0; + rz->header->hcrc = 0; + deflateSetHeader(rz->stream, rz->header); + rz->block_pos = rz->block_off = 0; + return rz; +} + +static void _razf_write(RAZF* rz, const void *data, int size){ + int tout; + rz->stream->avail_in = size; + rz->stream->next_in = (void*)data; + while(1){ + tout = rz->stream->avail_out; + deflate(rz->stream, Z_NO_FLUSH); + rz->out += tout - rz->stream->avail_out; + if(rz->stream->avail_out) break; +#ifdef _USE_KNETFILE + write(rz->x.fpw, rz->outbuf, RZ_BUFFER_SIZE - rz->stream->avail_out); +#else + write(rz->filedes, rz->outbuf, RZ_BUFFER_SIZE - rz->stream->avail_out); +#endif + rz->stream->avail_out = RZ_BUFFER_SIZE; + rz->stream->next_out = rz->outbuf; + if(rz->stream->avail_in == 0) break; + }; + rz->in += size - rz->stream->avail_in; + rz->block_off += size - rz->stream->avail_in; +} + +static void razf_flush(RAZF *rz){ + uint32_t tout; + if(rz->buf_len){ + _razf_write(rz, rz->inbuf, rz->buf_len); + rz->buf_off = rz->buf_len = 0; + } + if(rz->stream->avail_out){ +#ifdef _USE_KNETFILE + write(rz->x.fpw, rz->outbuf, RZ_BUFFER_SIZE - rz->stream->avail_out); +#else + write(rz->filedes, rz->outbuf, RZ_BUFFER_SIZE - rz->stream->avail_out); +#endif + rz->stream->avail_out = RZ_BUFFER_SIZE; + rz->stream->next_out = rz->outbuf; + } + while(1){ + tout = rz->stream->avail_out; + deflate(rz->stream, Z_FULL_FLUSH); + rz->out += tout - rz->stream->avail_out; + if(rz->stream->avail_out == 0){ +#ifdef _USE_KNETFILE + write(rz->x.fpw, rz->outbuf, RZ_BUFFER_SIZE - rz->stream->avail_out); +#else + write(rz->filedes, rz->outbuf, RZ_BUFFER_SIZE - rz->stream->avail_out); +#endif + rz->stream->avail_out = RZ_BUFFER_SIZE; + rz->stream->next_out = rz->outbuf; + } else break; + } + rz->block_pos = rz->out; + rz->block_off = 0; +} + +static void razf_end_flush(RAZF *rz){ + uint32_t tout; + if(rz->buf_len){ + _razf_write(rz, rz->inbuf, rz->buf_len); + rz->buf_off = rz->buf_len = 0; + } + while(1){ + tout = rz->stream->avail_out; + deflate(rz->stream, Z_FINISH); + rz->out += tout - rz->stream->avail_out; + if(rz->stream->avail_out < RZ_BUFFER_SIZE){ +#ifdef _USE_KNETFILE + write(rz->x.fpw, rz->outbuf, RZ_BUFFER_SIZE - rz->stream->avail_out); +#else + write(rz->filedes, rz->outbuf, RZ_BUFFER_SIZE - rz->stream->avail_out); +#endif + rz->stream->avail_out = RZ_BUFFER_SIZE; + rz->stream->next_out = rz->outbuf; + } else break; + } +} + +static void _razf_buffered_write(RAZF *rz, const void *data, int size){ + int i, n; + while(1){ + if(rz->buf_len == RZ_BUFFER_SIZE){ + _razf_write(rz, rz->inbuf, rz->buf_len); + rz->buf_len = 0; + } + if(size + rz->buf_len < RZ_BUFFER_SIZE){ + for(i=0;i<size;i++) ((char*)rz->inbuf + rz->buf_len)[i] = ((char*)data)[i]; + rz->buf_len += size; + return; + } else { + n = RZ_BUFFER_SIZE - rz->buf_len; + for(i=0;i<n;i++) ((char*)rz->inbuf + rz->buf_len)[i] = ((char*)data)[i]; + size -= n; + data += n; + rz->buf_len += n; + } + } +} + +int razf_write(RAZF* rz, const void *data, int size){ + int ori_size, n; + int64_t next_block; + ori_size = size; + next_block = ((rz->in / RZ_BLOCK_SIZE) + 1) * RZ_BLOCK_SIZE; + while(rz->in + rz->buf_len + size >= next_block){ + n = next_block - rz->in - rz->buf_len; + _razf_buffered_write(rz, data, n); + data += n; + size -= n; + razf_flush(rz); + add_zindex(rz, rz->in, rz->out); + next_block = ((rz->in / RZ_BLOCK_SIZE) + 1) * RZ_BLOCK_SIZE; + } + _razf_buffered_write(rz, data, size); + return ori_size; +} +#endif + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define RESERVED 0xE0 /* bits 5..7: reserved */ + +static int _read_gz_header(unsigned char *data, int size, int *extra_off, int *extra_len){ + int method, flags, n, len; + if(size < 2) return 0; + if(data[0] != 0x1f || data[1] != 0x8b) return 0; + if(size < 4) return 0; + method = data[2]; + flags = data[3]; + if(method != Z_DEFLATED || (flags & RESERVED)) return 0; + n = 4 + 6; // Skip 6 bytes + *extra_off = n + 2; + *extra_len = 0; + if(flags & EXTRA_FIELD){ + if(size < n + 2) return 0; + len = ((int)data[n + 1] << 8) | data[n]; + n += 2; + *extra_off = n; + while(len){ + if(n >= size) return 0; + n ++; + len --; + } + *extra_len = n - (*extra_off); + } + if(flags & ORIG_NAME) while(n < size && data[n++]); + if(flags & COMMENT) while(n < size && data[n++]); + if(flags & HEAD_CRC){ + if(n + 2 > size) return 0; + n += 2; + } + return n; +} + +#ifdef _USE_KNETFILE +static RAZF* razf_open_r(knetFile *fp, int _load_index){ +#else +static RAZF* razf_open_r(int fd, int _load_index){ +#endif + RAZF *rz; + int ext_off, ext_len; + int n, is_be, ret; + int64_t end; + unsigned char c[] = "RAZF"; + rz = calloc(1, sizeof(RAZF)); + rz->mode = 'r'; +#ifdef _USE_KNETFILE + rz->x.fpr = fp; +#else +#ifdef _WIN32 + setmode(fd, O_BINARY); +#endif + rz->filedes = fd; +#endif + rz->stream = calloc(sizeof(z_stream), 1); + rz->inbuf = malloc(RZ_BUFFER_SIZE); + rz->outbuf = malloc(RZ_BUFFER_SIZE); + rz->end = rz->src_end = 0x7FFFFFFFFFFFFFFFLL; +#ifdef _USE_KNETFILE + n = knet_read(rz->x.fpr, rz->inbuf, RZ_BUFFER_SIZE); +#else + n = read(rz->filedes, rz->inbuf, RZ_BUFFER_SIZE); +#endif + ret = _read_gz_header(rz->inbuf, n, &ext_off, &ext_len); + if(ret == 0){ + PLAIN_FILE: + rz->in = n; + rz->file_type = FILE_TYPE_PLAIN; + memcpy(rz->outbuf, rz->inbuf, n); + rz->buf_len = n; + free(rz->stream); + rz->stream = NULL; + return rz; + } + rz->header_size = ret; + ret = inflateInit2(rz->stream, -WINDOW_BITS); + if(ret != Z_OK){ inflateEnd(rz->stream); goto PLAIN_FILE;} + rz->stream->avail_in = n - rz->header_size; + rz->stream->next_in = rz->inbuf + rz->header_size; + rz->stream->avail_out = RZ_BUFFER_SIZE; + rz->stream->next_out = rz->outbuf; + rz->file_type = FILE_TYPE_GZ; + rz->in = rz->header_size; + rz->block_pos = rz->header_size; + rz->next_block_pos = rz->header_size; + rz->block_off = 0; + if(ext_len < 7 || memcmp(rz->inbuf + ext_off, c, 4) != 0) return rz; + if(((((unsigned char*)rz->inbuf)[ext_off + 5] << 8) | ((unsigned char*)rz->inbuf)[ext_off + 6]) != RZ_BLOCK_SIZE){ + fprintf(stderr, " -- WARNING: RZ_BLOCK_SIZE is not %d, treat source as gz file. in %s -- %s:%d --\n", RZ_BLOCK_SIZE, __FUNCTION__, __FILE__, __LINE__); + return rz; + } + rz->load_index = _load_index; + rz->file_type = FILE_TYPE_RZ; +#ifdef _USE_KNETFILE + if(knet_seek(fp, -16, SEEK_END) == -1){ +#else + if(lseek(fd, -16, SEEK_END) == -1){ +#endif + UNSEEKABLE: + rz->seekable = 0; + rz->index = NULL; + rz->src_end = rz->end = 0x7FFFFFFFFFFFFFFFLL; + } else { + is_be = is_big_endian(); + rz->seekable = 1; +#ifdef _USE_KNETFILE + knet_read(fp, &end, sizeof(int64_t)); +#else + read(fd, &end, sizeof(int64_t)); +#endif + if(!is_be) rz->src_end = (int64_t)byte_swap_8((uint64_t)end); + else rz->src_end = end; + +#ifdef _USE_KNETFILE + knet_read(fp, &end, sizeof(int64_t)); +#else + read(fd, &end, sizeof(int64_t)); +#endif + if(!is_be) rz->end = (int64_t)byte_swap_8((uint64_t)end); + else rz->end = end; + if(n > rz->end){ + rz->stream->avail_in -= n - rz->end; + n = rz->end; + } + if(rz->end > rz->src_end){ +#ifdef _USE_KNETFILE + knet_seek(fp, rz->in, SEEK_SET); +#else + lseek(fd, rz->in, SEEK_SET); +#endif + goto UNSEEKABLE; + } +#ifdef _USE_KNETFILE + knet_seek(fp, rz->end, SEEK_SET); + if(knet_tell(fp) != rz->end){ + knet_seek(fp, rz->in, SEEK_SET); +#else + if(lseek(fd, rz->end, SEEK_SET) != rz->end){ + lseek(fd, rz->in, SEEK_SET); +#endif + goto UNSEEKABLE; + } +#ifdef _USE_KNETFILE + load_zindex(rz, fp); + knet_seek(fp, n, SEEK_SET); +#else + load_zindex(rz, fd); + lseek(fd, n, SEEK_SET); +#endif + } + return rz; +} + +#ifdef _USE_KNETFILE +RAZF* razf_dopen(int fd, const char *mode){ + if (strstr(mode, "r")) fprintf(stderr,"[razf_dopen] implement me\n"); + else if(strstr(mode, "w")) return razf_open_w(fd); + return NULL; +} + +RAZF* razf_dopen2(int fd, const char *mode) +{ + fprintf(stderr,"[razf_dopen2] implement me\n"); + return NULL; +} +#else +RAZF* razf_dopen(int fd, const char *mode){ + if(strstr(mode, "r")) return razf_open_r(fd, 1); + else if(strstr(mode, "w")) return razf_open_w(fd); + else return NULL; +} + +RAZF* razf_dopen2(int fd, const char *mode) +{ + if(strstr(mode, "r")) return razf_open_r(fd, 0); + else if(strstr(mode, "w")) return razf_open_w(fd); + else return NULL; +} +#endif + +static inline RAZF* _razf_open(const char *filename, const char *mode, int _load_index){ + int fd; + RAZF *rz; + if(strstr(mode, "r")){ +#ifdef _USE_KNETFILE + knetFile *fd = knet_open(filename, "r"); + if (fd == 0) { + fprintf(stderr, "[_razf_open] fail to open %s\n", filename); + return NULL; + } +#else +#ifdef _WIN32 + fd = open(filename, O_RDONLY | O_BINARY); +#else + fd = open(filename, O_RDONLY); +#endif +#endif + if(fd < 0) return NULL; + rz = razf_open_r(fd, _load_index); + } else if(strstr(mode, "w")){ +#ifdef _WIN32 + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666); +#else + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666); +#endif + if(fd < 0) return NULL; + rz = razf_open_w(fd); + } else return NULL; + return rz; +} + +RAZF* razf_open(const char *filename, const char *mode){ + return _razf_open(filename, mode, 1); +} + +RAZF* razf_open2(const char *filename, const char *mode){ + return _razf_open(filename, mode, 0); +} + +int razf_get_data_size(RAZF *rz, int64_t *u_size, int64_t *c_size){ + int64_t n; + if(rz->mode != 'r' && rz->mode != 'R') return 0; + switch(rz->file_type){ + case FILE_TYPE_PLAIN: + if(rz->end == 0x7fffffffffffffffLL){ +#ifdef _USE_KNETFILE + if(knet_seek(rz->x.fpr, 0, SEEK_CUR) == -1) return 0; + n = knet_tell(rz->x.fpr); + knet_seek(rz->x.fpr, 0, SEEK_END); + rz->end = knet_tell(rz->x.fpr); + knet_seek(rz->x.fpr, n, SEEK_SET); +#else + if((n = lseek(rz->filedes, 0, SEEK_CUR)) == -1) return 0; + rz->end = lseek(rz->filedes, 0, SEEK_END); + lseek(rz->filedes, n, SEEK_SET); +#endif + } + *u_size = *c_size = rz->end; + return 1; + case FILE_TYPE_GZ: + return 0; + case FILE_TYPE_RZ: + if(rz->src_end == rz->end) return 0; + *u_size = rz->src_end; + *c_size = rz->end; + return 1; + default: + return 0; + } +} + +static int _razf_read(RAZF* rz, void *data, int size){ + int ret, tin; + if(rz->z_eof || rz->z_err) return 0; + if (rz->file_type == FILE_TYPE_PLAIN) { +#ifdef _USE_KNETFILE + ret = knet_read(rz->x.fpr, data, size); +#else + ret = read(rz->filedes, data, size); +#endif + if (ret == 0) rz->z_eof = 1; + return ret; + } + rz->stream->avail_out = size; + rz->stream->next_out = data; + while(rz->stream->avail_out){ + if(rz->stream->avail_in == 0){ + if(rz->in >= rz->end){ rz->z_eof = 1; break; } + if(rz->end - rz->in < RZ_BUFFER_SIZE){ +#ifdef _USE_KNETFILE + rz->stream->avail_in = knet_read(rz->x.fpr, rz->inbuf, rz->end -rz->in); +#else + rz->stream->avail_in = read(rz->filedes, rz->inbuf, rz->end -rz->in); +#endif + } else { +#ifdef _USE_KNETFILE + rz->stream->avail_in = knet_read(rz->x.fpr, rz->inbuf, RZ_BUFFER_SIZE); +#else + rz->stream->avail_in = read(rz->filedes, rz->inbuf, RZ_BUFFER_SIZE); +#endif + } + if(rz->stream->avail_in == 0){ + rz->z_eof = 1; + break; + } + rz->stream->next_in = rz->inbuf; + } + tin = rz->stream->avail_in; + ret = inflate(rz->stream, Z_BLOCK); + rz->in += tin - rz->stream->avail_in; + if(ret == Z_NEED_DICT || ret == Z_MEM_ERROR || ret == Z_DATA_ERROR){ + fprintf(stderr, "[_razf_read] inflate error: %d %s (at %s:%d)\n", ret, rz->stream->msg ? rz->stream->msg : "", __FILE__, __LINE__); + rz->z_err = 1; + break; + } + if(ret == Z_STREAM_END){ + rz->z_eof = 1; + break; + } + if ((rz->stream->data_type&128) && !(rz->stream->data_type&64)){ + rz->buf_flush = 1; + rz->next_block_pos = rz->in; + break; + } + } + return size - rz->stream->avail_out; +} + +int razf_read(RAZF *rz, void *data, int size){ + int ori_size, i; + ori_size = size; + while(size > 0){ + if(rz->buf_len){ + if(size < rz->buf_len){ + for(i=0;i<size;i++) ((char*)data)[i] = ((char*)rz->outbuf + rz->buf_off)[i]; + rz->buf_off += size; + rz->buf_len -= size; + data += size; + rz->block_off += size; + size = 0; + break; + } else { + for(i=0;i<rz->buf_len;i++) ((char*)data)[i] = ((char*)rz->outbuf + rz->buf_off)[i]; + data += rz->buf_len; + size -= rz->buf_len; + rz->block_off += rz->buf_len; + rz->buf_off = 0; + rz->buf_len = 0; + if(rz->buf_flush){ + rz->block_pos = rz->next_block_pos; + rz->block_off = 0; + rz->buf_flush = 0; + } + } + } else if(rz->buf_flush){ + rz->block_pos = rz->next_block_pos; + rz->block_off = 0; + rz->buf_flush = 0; + } + if(rz->buf_flush) continue; + rz->buf_len = _razf_read(rz, rz->outbuf, RZ_BUFFER_SIZE); + if(rz->z_eof && rz->buf_len == 0) break; + } + rz->out += ori_size - size; + return ori_size - size; +} + +int razf_skip(RAZF* rz, int size){ + int ori_size; + ori_size = size; + while(size > 0){ + if(rz->buf_len){ + if(size < rz->buf_len){ + rz->buf_off += size; + rz->buf_len -= size; + rz->block_off += size; + size = 0; + break; + } else { + size -= rz->buf_len; + rz->buf_off = 0; + rz->buf_len = 0; + rz->block_off += rz->buf_len; + if(rz->buf_flush){ + rz->block_pos = rz->next_block_pos; + rz->block_off = 0; + rz->buf_flush = 0; + } + } + } else if(rz->buf_flush){ + rz->block_pos = rz->next_block_pos; + rz->block_off = 0; + rz->buf_flush = 0; + } + if(rz->buf_flush) continue; + rz->buf_len = _razf_read(rz, rz->outbuf, RZ_BUFFER_SIZE); + if(rz->z_eof || rz->z_err) break; + } + rz->out += ori_size - size; + return ori_size - size; +} + +static void _razf_reset_read(RAZF *rz, int64_t in, int64_t out){ +#ifdef _USE_KNETFILE + knet_seek(rz->x.fpr, in, SEEK_SET); +#else + lseek(rz->filedes, in, SEEK_SET); +#endif + rz->in = in; + rz->out = out; + rz->block_pos = in; + rz->next_block_pos = in; + rz->block_off = 0; + rz->buf_flush = 0; + rz->z_eof = rz->z_err = 0; + inflateReset(rz->stream); + rz->stream->avail_in = 0; + rz->buf_off = rz->buf_len = 0; +} + +int64_t razf_jump(RAZF *rz, int64_t block_start, int block_offset){ + int64_t pos; + rz->z_eof = 0; + if(rz->file_type == FILE_TYPE_PLAIN){ + rz->buf_off = rz->buf_len = 0; + pos = block_start + block_offset; +#ifdef _USE_KNETFILE + knet_seek(rz->x.fpr, pos, SEEK_SET); + pos = knet_tell(rz->x.fpr); +#else + pos = lseek(rz->filedes, pos, SEEK_SET); +#endif + rz->out = rz->in = pos; + return pos; + } + if(block_start == rz->block_pos && block_offset >= rz->block_off) { + block_offset -= rz->block_off; + goto SKIP; // Needn't reset inflate + } + if(block_start == 0) block_start = rz->header_size; // Automaticly revist wrong block_start + _razf_reset_read(rz, block_start, 0); + SKIP: + if(block_offset) razf_skip(rz, block_offset); + return rz->block_off; +} + +int64_t razf_seek(RAZF* rz, int64_t pos, int where){ + int64_t idx; + int64_t seek_pos, new_out; + rz->z_eof = 0; + if (where == SEEK_CUR) pos += rz->out; + else if (where == SEEK_END) pos += rz->src_end; + if(rz->file_type == FILE_TYPE_PLAIN){ +#ifdef _USE_KNETFILE + knet_seek(rz->x.fpr, pos, SEEK_SET); + seek_pos = knet_tell(rz->x.fpr); +#else + seek_pos = lseek(rz->filedes, pos, SEEK_SET); +#endif + rz->buf_off = rz->buf_len = 0; + rz->out = rz->in = seek_pos; + return seek_pos; + } else if(rz->file_type == FILE_TYPE_GZ){ + if(pos >= rz->out) goto SKIP; + return rz->out; + } + if(pos == rz->out) return pos; + if(pos > rz->src_end) return rz->out; + if(!rz->seekable || !rz->load_index){ + if(pos >= rz->out) goto SKIP; + } + idx = pos / RZ_BLOCK_SIZE - 1; + seek_pos = (idx < 0)? rz->header_size:(rz->index->cell_offsets[idx] + rz->index->bin_offsets[idx / RZ_BIN_SIZE]); + new_out = (idx + 1) * RZ_BLOCK_SIZE; + if(pos > rz->out && new_out <= rz->out) goto SKIP; + _razf_reset_read(rz, seek_pos, new_out); + SKIP: + razf_skip(rz, (int)(pos - rz->out)); + return rz->out; +} + +uint64_t razf_tell2(RAZF *rz) +{ + /* + if (rz->load_index) { + int64_t idx, seek_pos; + idx = rz->out / RZ_BLOCK_SIZE - 1; + seek_pos = (idx < 0)? rz->header_size:(rz->index->cell_offsets[idx] + rz->index->bin_offsets[idx / RZ_BIN_SIZE]); + if (seek_pos != rz->block_pos || rz->out%RZ_BLOCK_SIZE != rz->block_off) + fprintf(stderr, "[razf_tell2] inconsistent block offset: (%lld, %lld) != (%lld, %lld)\n", + (long long)seek_pos, (long long)rz->out%RZ_BLOCK_SIZE, (long long)rz->block_pos, (long long) rz->block_off); + } + */ + return (uint64_t)rz->block_pos<<16 | (rz->block_off&0xffff); +} + +int64_t razf_seek2(RAZF *rz, uint64_t voffset, int where) +{ + if (where != SEEK_SET) return -1; + return razf_jump(rz, voffset>>16, voffset&0xffff); +} + +void razf_close(RAZF *rz){ + if(rz->mode == 'w'){ +#ifndef _RZ_READONLY + razf_end_flush(rz); + deflateEnd(rz->stream); +#ifdef _USE_KNETFILE + save_zindex(rz, rz->x.fpw); + if(is_big_endian()){ + write(rz->x.fpw, &rz->in, sizeof(int64_t)); + write(rz->x.fpw, &rz->out, sizeof(int64_t)); + } else { + uint64_t v64 = byte_swap_8((uint64_t)rz->in); + write(rz->x.fpw, &v64, sizeof(int64_t)); + v64 = byte_swap_8((uint64_t)rz->out); + write(rz->x.fpw, &v64, sizeof(int64_t)); + } +#else + save_zindex(rz, rz->filedes); + if(is_big_endian()){ + write(rz->filedes, &rz->in, sizeof(int64_t)); + write(rz->filedes, &rz->out, sizeof(int64_t)); + } else { + uint64_t v64 = byte_swap_8((uint64_t)rz->in); + write(rz->filedes, &v64, sizeof(int64_t)); + v64 = byte_swap_8((uint64_t)rz->out); + write(rz->filedes, &v64, sizeof(int64_t)); + } +#endif +#endif + } else if(rz->mode == 'r'){ + if(rz->stream) inflateEnd(rz->stream); + } + if(rz->inbuf) free(rz->inbuf); + if(rz->outbuf) free(rz->outbuf); + if(rz->header){ + free(rz->header->extra); + free(rz->header->name); + free(rz->header->comment); + free(rz->header); + } + if(rz->index){ + free(rz->index->bin_offsets); + free(rz->index->cell_offsets); + free(rz->index); + } + free(rz->stream); +#ifdef _USE_KNETFILE + if (rz->mode == 'r') + knet_close(rz->x.fpr); + if (rz->mode == 'w') + close(rz->x.fpw); +#else + close(rz->filedes); +#endif + free(rz); +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/razf.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,134 @@ + /*- + * RAZF : Random Access compressed(Z) File + * Version: 1.0 + * Release Date: 2008-10-27 + * + * Copyright 2008, Jue Ruan <ruanjue@gmail.com>, Heng Li <lh3@sanger.ac.uk> + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#ifndef __RAZF_RJ_H +#define __RAZF_RJ_H + +#include <stdint.h> +#include <stdio.h> +#include "zlib.h" + +#ifdef _USE_KNETFILE +#include "knetfile.h" +#endif + +#if ZLIB_VERNUM < 0x1221 +#define _RZ_READONLY +struct _gz_header_s; +typedef struct _gz_header_s _gz_header; +#define gz_header _gz_header +#endif + +#define WINDOW_BITS 15 + +#ifndef RZ_BLOCK_SIZE +#define RZ_BLOCK_SIZE (1<<WINDOW_BITS) +#endif + +#ifndef RZ_BUFFER_SIZE +#define RZ_BUFFER_SIZE 4096 +#endif + +#ifndef RZ_COMPRESS_LEVEL +#define RZ_COMPRESS_LEVEL 6 +#endif + +#define RZ_BIN_SIZE ((1LLU << 32) / RZ_BLOCK_SIZE) + +typedef struct { + uint32_t *cell_offsets; // i + int64_t *bin_offsets; // i / BIN_SIZE + int size; + int cap; +} ZBlockIndex; +/* When storing index, output bytes in Big-Endian everywhere */ + +#define FILE_TYPE_RZ 1 +#define FILE_TYPE_PLAIN 2 +#define FILE_TYPE_GZ 3 + +typedef struct RandomAccessZFile { + char mode; /* 'w' : write mode; 'r' : read mode */ + int file_type; + /* plain file or rz file, razf_read support plain file as input too, in this case, razf_read work as buffered fread */ +#ifdef _USE_KNETFILE + union { + knetFile *fpr; + int fpw; + } x; +#else + int filedes; /* the file descriptor */ +#endif + z_stream *stream; + ZBlockIndex *index; + int64_t in, out, end, src_end; + /* in: n bytes total in; out: n bytes total out; */ + /* end: the end of all data blocks, while the start of index; src_end: the true end position in uncompressed file */ + int buf_flush; // buffer should be flush, suspend inflate util buffer is empty + int64_t block_pos, block_off, next_block_pos; + /* block_pos: the start postiion of current block in compressed file */ + /* block_off: tell how many bytes have been read from current block */ + void *inbuf, *outbuf; + int header_size; + gz_header *header; + /* header is used to transfer inflate_state->mode from HEAD to TYPE after call inflateReset */ + int buf_off, buf_len; + int z_err, z_eof; + int seekable; + /* Indice where the source is seekable */ + int load_index; + /* set has_index to 0 in mode 'w', then index will be discarded */ +} RAZF; + +#ifdef __cplusplus +extern "C" { +#endif + + RAZF* razf_dopen(int data_fd, const char *mode); + RAZF *razf_open(const char *fn, const char *mode); + int razf_write(RAZF* rz, const void *data, int size); + int razf_read(RAZF* rz, void *data, int size); + int64_t razf_seek(RAZF* rz, int64_t pos, int where); + void razf_close(RAZF* rz); + +#define razf_tell(rz) ((rz)->out) + + RAZF* razf_open2(const char *filename, const char *mode); + RAZF* razf_dopen2(int fd, const char *mode); + uint64_t razf_tell2(RAZF *rz); + int64_t razf_seek2(RAZF *rz, uint64_t voffset, int where); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/razip.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,141 @@ +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include "razf.h" + +#define WINDOW_SIZE 4096 + +static int razf_main_usage() +{ + printf("\n"); + printf("Usage: razip [options] [file] ...\n\n"); + printf("Options: -c write on standard output, keep original files unchanged\n"); + printf(" -d decompress\n"); + printf(" -l list compressed file contents\n"); + printf(" -b INT decompress at INT position in the uncompressed file\n"); + printf(" -s INT decompress INT bytes in the uncompressed file\n"); + printf(" -h give this help\n"); + printf("\n"); + return 0; +} + +static int write_open(const char *fn, int is_forced) +{ + int fd = -1; + char c; + if (!is_forced) { + if ((fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0666)) < 0 && errno == EEXIST) { + printf("razip: %s already exists; do you wish to overwrite (y or n)? ", fn); + scanf("%c", &c); + if (c != 'Y' && c != 'y') { + printf("razip: not overwritten\n"); + exit(1); + } + } + } + if (fd < 0) { + if ((fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) { + fprintf(stderr, "razip: %s: Fail to write\n", fn); + exit(1); + } + } + return fd; +} + +int main(int argc, char **argv) +{ + int c, compress, pstdout, is_forced; + RAZF *rz; + void *buffer; + long start, end, size; + + compress = 1; pstdout = 0; start = 0; size = -1; end = -1; is_forced = 0; + while((c = getopt(argc, argv, "cdlhfb:s:")) >= 0){ + switch(c){ + case 'h': return razf_main_usage(); + case 'd': compress = 0; break; + case 'c': pstdout = 1; break; + case 'l': compress = 2; break; + case 'b': start = atol(optarg); break; + case 's': size = atol(optarg); break; + case 'f': is_forced = 1; break; + } + } + if (size >= 0) end = start + size; + if(end >= 0 && end < start){ + fprintf(stderr, " -- Illegal region: [%ld, %ld] --\n", start, end); + return 1; + } + if(compress == 1){ + int f_src, f_dst = -1; + if(argc > optind){ + if((f_src = open(argv[optind], O_RDONLY)) < 0){ + fprintf(stderr, " -- Cannot open file: %s --\n", argv[optind]); + return 1; + } + if(pstdout){ + f_dst = fileno(stdout); + } else { + char *name = malloc(sizeof(strlen(argv[optind]) + 5)); + strcpy(name, argv[optind]); + strcat(name, ".rz"); + f_dst = write_open(name, is_forced); + if (f_dst < 0) return 1; + free(name); + } + } else if(pstdout){ + f_src = fileno(stdin); + f_dst = fileno(stdout); + } else return razf_main_usage(); + rz = razf_dopen(f_dst, "w"); + buffer = malloc(WINDOW_SIZE); + while((c = read(f_src, buffer, WINDOW_SIZE)) > 0) razf_write(rz, buffer, c); + razf_close(rz); // f_dst will be closed here + if (argc > optind && !pstdout) unlink(argv[optind]); + free(buffer); + close(f_src); + return 0; + } else { + if(argc <= optind) return razf_main_usage(); + if(compress == 2){ + rz = razf_open(argv[optind], "r"); + if(rz->file_type == FILE_TYPE_RZ) { + printf("%20s%20s%7s %s\n", "compressed", "uncompressed", "ratio", "name"); + printf("%20lld%20lld%6.1f%% %s\n", (long long)rz->end, (long long)rz->src_end, rz->end * 100.0f / rz->src_end, + argv[optind]); + } else fprintf(stdout, "%s is not a regular rz file\n", argv[optind]); + } else { + int f_dst; + if (argc > optind && !pstdout) { + char *name; + if (strstr(argv[optind], ".rz") - argv[optind] != strlen(argv[optind]) - 3) { + printf("razip: %s: unknown suffix -- ignored\n", argv[optind]); + return 1; + } + name = strdup(argv[optind]); + name[strlen(name) - 3] = '\0'; + f_dst = write_open(name, is_forced); + free(name); + } else f_dst = fileno(stdout); + rz = razf_open(argv[optind], "r"); + buffer = malloc(WINDOW_SIZE); + razf_seek(rz, start, SEEK_SET); + while(1){ + if(end < 0) c = razf_read(rz, buffer, WINDOW_SIZE); + else c = razf_read(rz, buffer, (end - start > WINDOW_SIZE)? WINDOW_SIZE:(end - start)); + if(c <= 0) break; + start += c; + write(f_dst, buffer, c); + if(end >= 0 && start >= end) break; + } + free(buffer); + if (!pstdout) unlink(argv[optind]); + } + razf_close(rz); + return 0; + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/sam.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,179 @@ +#include <string.h> +#include <unistd.h> +#include "faidx.h" +#include "sam.h" + +#define TYPE_BAM 1 +#define TYPE_READ 2 + +bam_header_t *bam_header_dup(const bam_header_t *h0) +{ + bam_header_t *h; + int i; + h = bam_header_init(); + *h = *h0; + h->hash = h->dict = h->rg2lib = 0; + h->text = (char*)calloc(h->l_text + 1, 1); + memcpy(h->text, h0->text, h->l_text); + h->target_len = (uint32_t*)calloc(h->n_targets, 4); + h->target_name = (char**)calloc(h->n_targets, sizeof(void*)); + for (i = 0; i < h->n_targets; ++i) { + h->target_len[i] = h0->target_len[i]; + h->target_name[i] = strdup(h0->target_name[i]); + } + return h; +} +static void append_header_text(bam_header_t *header, char* text, int len) +{ + int x = header->l_text + 1; + int y = header->l_text + len + 1; // 1 byte null + if (text == 0) return; + kroundup32(x); + kroundup32(y); + if (x < y) header->text = (char*)realloc(header->text, y); + strncpy(header->text + header->l_text, text, len); // we cannot use strcpy() here. + header->l_text += len; + header->text[header->l_text] = 0; +} + +samfile_t *samopen(const char *fn, const char *mode, const void *aux) +{ + samfile_t *fp; + fp = (samfile_t*)calloc(1, sizeof(samfile_t)); + if (strchr(mode, 'r')) { // read + fp->type |= TYPE_READ; + if (strchr(mode, 'b')) { // binary + fp->type |= TYPE_BAM; + fp->x.bam = strcmp(fn, "-")? bam_open(fn, "r") : bam_dopen(fileno(stdin), "r"); + if (fp->x.bam == 0) goto open_err_ret; + fp->header = bam_header_read(fp->x.bam); + } else { // text + fp->x.tamr = sam_open(fn); + if (fp->x.tamr == 0) goto open_err_ret; + fp->header = sam_header_read(fp->x.tamr); + if (fp->header->n_targets == 0) { // no @SQ fields + if (aux) { // check if aux is present + bam_header_t *textheader = fp->header; + fp->header = sam_header_read2((const char*)aux); + if (fp->header == 0) goto open_err_ret; + append_header_text(fp->header, textheader->text, textheader->l_text); + bam_header_destroy(textheader); + } + if (fp->header->n_targets == 0 && bam_verbose >= 1) + fprintf(stderr, "[samopen] no @SQ lines in the header.\n"); + } else if (bam_verbose >= 2) fprintf(stderr, "[samopen] SAM header is present: %d sequences.\n", fp->header->n_targets); + } + } else if (strchr(mode, 'w')) { // write + fp->header = bam_header_dup((const bam_header_t*)aux); + if (strchr(mode, 'b')) { // binary + char bmode[3]; + int i, compress_level = -1; + for (i = 0; mode[i]; ++i) if (mode[i] >= '0' && mode[i] <= '9') break; + if (mode[i]) compress_level = mode[i] - '0'; + if (strchr(mode, 'u')) compress_level = 0; + bmode[0] = 'w'; bmode[1] = compress_level < 0? 0 : compress_level + '0'; bmode[2] = 0; + fp->type |= TYPE_BAM; + fp->x.bam = strcmp(fn, "-")? bam_open(fn, bmode) : bam_dopen(fileno(stdout), bmode); + if (fp->x.bam == 0) goto open_err_ret; + bam_header_write(fp->x.bam, fp->header); + } else { // text + // open file + fp->x.tamw = strcmp(fn, "-")? fopen(fn, "w") : stdout; + if (fp->x.tamr == 0) goto open_err_ret; + if (strchr(mode, 'X')) fp->type |= BAM_OFSTR<<2; + else if (strchr(mode, 'x')) fp->type |= BAM_OFHEX<<2; + else fp->type |= BAM_OFDEC<<2; + // write header + if (strchr(mode, 'h')) { + int i; + bam_header_t *alt; + // parse the header text + alt = bam_header_init(); + alt->l_text = fp->header->l_text; alt->text = fp->header->text; + sam_header_parse(alt); + alt->l_text = 0; alt->text = 0; + // check if there are @SQ lines in the header + fwrite(fp->header->text, 1, fp->header->l_text, fp->x.tamw); // FIXME: better to skip the trailing NULL + if (alt->n_targets) { // then write the header text without dumping ->target_{name,len} + if (alt->n_targets != fp->header->n_targets && bam_verbose >= 1) + fprintf(stderr, "[samopen] inconsistent number of target sequences. Output the text header.\n"); + } else { // then dump ->target_{name,len} + for (i = 0; i < fp->header->n_targets; ++i) + fprintf(fp->x.tamw, "@SQ\tSN:%s\tLN:%d\n", fp->header->target_name[i], fp->header->target_len[i]); + } + bam_header_destroy(alt); + } + } + } + return fp; + +open_err_ret: + free(fp); + return 0; +} + +void samclose(samfile_t *fp) +{ + if (fp == 0) return; + if (fp->header) bam_header_destroy(fp->header); + if (fp->type & TYPE_BAM) bam_close(fp->x.bam); + else if (fp->type & TYPE_READ) sam_close(fp->x.tamr); + else fclose(fp->x.tamw); + free(fp); +} + +int samread(samfile_t *fp, bam1_t *b) +{ + if (fp == 0 || !(fp->type & TYPE_READ)) return -1; // not open for reading + if (fp->type & TYPE_BAM) return bam_read1(fp->x.bam, b); + else return sam_read1(fp->x.tamr, fp->header, b); +} + +int samwrite(samfile_t *fp, const bam1_t *b) +{ + if (fp == 0 || (fp->type & TYPE_READ)) return -1; // not open for writing + if (fp->type & TYPE_BAM) return bam_write1(fp->x.bam, b); + else { + char *s = bam_format1_core(fp->header, b, fp->type>>2&3); + int l = strlen(s); + fputs(s, fp->x.tamw); fputc('\n', fp->x.tamw); + free(s); + return l + 1; + } +} + +int sampileup(samfile_t *fp, int mask, bam_pileup_f func, void *func_data) +{ + bam_plbuf_t *buf; + int ret; + bam1_t *b; + b = bam_init1(); + buf = bam_plbuf_init(func, func_data); + bam_plbuf_set_mask(buf, mask); + while ((ret = samread(fp, b)) >= 0) + bam_plbuf_push(b, buf); + bam_plbuf_push(0, buf); + bam_plbuf_destroy(buf); + bam_destroy1(b); + return 0; +} + +char *samfaipath(const char *fn_ref) +{ + char *fn_list = 0; + if (fn_ref == 0) return 0; + fn_list = calloc(strlen(fn_ref) + 5, 1); + strcat(strcpy(fn_list, fn_ref), ".fai"); + if (access(fn_list, R_OK) == -1) { // fn_list is unreadable + if (access(fn_ref, R_OK) == -1) { + fprintf(stderr, "[samfaipath] fail to read file %s.\n", fn_ref); + } else { + if (bam_verbose >= 3) fprintf(stderr, "[samfaipath] build FASTA index...\n"); + if (fai_build(fn_ref) == -1) { + fprintf(stderr, "[samfaipath] fail to build FASTA index.\n"); + free(fn_list); fn_list = 0; + } + } + } + return fn_list; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/sam.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,98 @@ +#ifndef BAM_SAM_H +#define BAM_SAM_H + +#include "bam.h" + +/*! + @header + + This file provides higher level of I/O routines and unifies the APIs + for SAM and BAM formats. These APIs are more convenient and + recommended. + + @copyright Genome Research Ltd. + */ + +/*! @typedef + @abstract SAM/BAM file handler + @field type type of the handler; bit 1 for BAM, 2 for reading and bit 3-4 for flag format + @field bam BAM file handler; valid if (type&1) == 1 + @field tamr SAM file handler for reading; valid if type == 2 + @field tamw SAM file handler for writing; valid if type == 0 + @field header header struct + */ +typedef struct { + int type; + union { + tamFile tamr; + bamFile bam; + FILE *tamw; + } x; + bam_header_t *header; +} samfile_t; + +#ifdef __cplusplus +extern "C" { +#endif + + /*! + @abstract Open a SAM/BAM file + + @param fn SAM/BAM file name; "-" is recognized as stdin (for + reading) or stdout (for writing). + + @param mode open mode /[rw](b?)(u?)(h?)([xX]?)/: 'r' for reading, + 'w' for writing, 'b' for BAM I/O, 'u' for uncompressed BAM output, + 'h' for outputing header in SAM, 'x' for HEX flag and 'X' for + string flag. If 'b' present, it must immediately follow 'r' or + 'w'. Valid modes are "r", "w", "wh", "wx", "whx", "wX", "whX", + "rb", "wb" and "wbu" exclusively. + + @param aux auxiliary data; if mode[0]=='w', aux points to + bam_header_t; if strcmp(mode, "rb")!=0 and @SQ header lines in SAM + are absent, aux points the file name of the list of the reference; + aux is not used otherwise. If @SQ header lines are present in SAM, + aux is not used, either. + + @return SAM/BAM file handler + */ + samfile_t *samopen(const char *fn, const char *mode, const void *aux); + + /*! + @abstract Close a SAM/BAM handler + @param fp file handler to be closed + */ + void samclose(samfile_t *fp); + + /*! + @abstract Read one alignment + @param fp file handler + @param b alignment + @return bytes read + */ + int samread(samfile_t *fp, bam1_t *b); + + /*! + @abstract Write one alignment + @param fp file handler + @param b alignment + @return bytes written + */ + int samwrite(samfile_t *fp, const bam1_t *b); + + /*! + @abstract Get the pileup for a whole alignment file + @param fp file handler + @param mask mask transferred to bam_plbuf_set_mask() + @param func user defined function called in the pileup process + #param data user provided data for func() + */ + int sampileup(samfile_t *fp, int mask, bam_pileup_f func, void *data); + + char *samfaipath(const char *fn_ref); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/sam_header.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,736 @@ +#include "sam_header.h" +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <stdlib.h> +#include <stdarg.h> + +#include "khash.h" +KHASH_MAP_INIT_STR(str, const char *) + +struct _HeaderList +{ + struct _HeaderList *last; // Hack: Used and maintained only by list_append_to_end. Maintained in the root node only. + struct _HeaderList *next; + void *data; +}; +typedef struct _HeaderList list_t; +typedef list_t HeaderDict; + +typedef struct +{ + char key[2]; + char *value; +} +HeaderTag; + +typedef struct +{ + char type[2]; + list_t *tags; +} +HeaderLine; + +const char *o_hd_tags[] = {"SO","GO",NULL}; +const char *r_hd_tags[] = {"VN",NULL}; + +const char *o_sq_tags[] = {"AS","M5","UR","SP",NULL}; +const char *r_sq_tags[] = {"SN","LN",NULL}; +const char *u_sq_tags[] = {"SN",NULL}; + +const char *o_rg_tags[] = {"CN","DS","DT","FO","KS","LB","PG","PI","PL","PU","SM",NULL}; +const char *r_rg_tags[] = {"ID",NULL}; +const char *u_rg_tags[] = {"ID",NULL}; + +const char *o_pg_tags[] = {"VN","CL",NULL}; +const char *r_pg_tags[] = {"ID",NULL}; + +const char *types[] = {"HD","SQ","RG","PG","CO",NULL}; +const char **optional_tags[] = {o_hd_tags,o_sq_tags,o_rg_tags,o_pg_tags,NULL,NULL}; +const char **required_tags[] = {r_hd_tags,r_sq_tags,r_rg_tags,r_pg_tags,NULL,NULL}; +const char **unique_tags[] = {NULL, u_sq_tags,u_rg_tags,NULL,NULL,NULL}; + + +static void debug(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); +} + +#if 0 +// Replaced by list_append_to_end +static list_t *list_prepend(list_t *root, void *data) +{ + list_t *l = malloc(sizeof(list_t)); + l->next = root; + l->data = data; + return l; +} +#endif + +// Relies on the root->last being correct. Do not use with the other list_* +// routines unless they are fixed to modify root->last as well. +static list_t *list_append_to_end(list_t *root, void *data) +{ + list_t *l = malloc(sizeof(list_t)); + l->last = l; + l->next = NULL; + l->data = data; + + if ( !root ) + return l; + + root->last->next = l; + root->last = l; + return root; +} + +static list_t *list_append(list_t *root, void *data) +{ + list_t *l = root; + while (l && l->next) + l = l->next; + if ( l ) + { + l->next = malloc(sizeof(list_t)); + l = l->next; + } + else + { + l = malloc(sizeof(list_t)); + root = l; + } + l->data = data; + l->next = NULL; + return root; +} + +static void list_free(list_t *root) +{ + list_t *l = root; + while (root) + { + l = root; + root = root->next; + free(l); + } +} + + + +// Look for a tag "XY" in a predefined const char *[] array. +static int tag_exists(const char *tag, const char **tags) +{ + int itag=0; + if ( !tags ) return -1; + while ( tags[itag] ) + { + if ( tags[itag][0]==tag[0] && tags[itag][1]==tag[1] ) return itag; + itag++; + } + return -1; +} + + + +// Mimics the behaviour of getline, except it returns pointer to the next chunk of the text +// or NULL if everything has been read. The lineptr should be freed by the caller. The +// newline character is stripped. +static const char *nextline(char **lineptr, size_t *n, const char *text) +{ + int len; + const char *to = text; + + if ( !*to ) return NULL; + + while ( *to && *to!='\n' && *to!='\r' ) to++; + len = to - text + 1; + + if ( *to ) + { + // Advance the pointer for the next call + if ( *to=='\n' ) to++; + else if ( *to=='\r' && *(to+1)=='\n' ) to+=2; + } + if ( !len ) + return to; + + if ( !*lineptr ) + { + *lineptr = malloc(len); + *n = len; + } + else if ( *n<len ) + { + *lineptr = realloc(*lineptr, len); + *n = len; + } + if ( !*lineptr ) { + debug("[nextline] Insufficient memory!\n"); + return 0; + } + + memcpy(*lineptr,text,len); + (*lineptr)[len-1] = 0; + + return to; +} + +// name points to "XY", value_from points to the first character of the value string and +// value_to points to the last character of the value string. +static HeaderTag *new_tag(const char *name, const char *value_from, const char *value_to) +{ + HeaderTag *tag = malloc(sizeof(HeaderTag)); + int len = value_to-value_from+1; + + tag->key[0] = name[0]; + tag->key[1] = name[1]; + tag->value = malloc(len+1); + memcpy(tag->value,value_from,len+1); + tag->value[len] = 0; + return tag; +} + +static HeaderTag *header_line_has_tag(HeaderLine *hline, const char *key) +{ + list_t *tags = hline->tags; + while (tags) + { + HeaderTag *tag = tags->data; + if ( tag->key[0]==key[0] && tag->key[1]==key[1] ) return tag; + tags = tags->next; + } + return NULL; +} + + +// Return codes: +// 0 .. different types or unique tags differ or conflicting tags, cannot be merged +// 1 .. all tags identical -> no need to merge, drop one +// 2 .. the unique tags match and there are some conflicting tags (same tag, different value) -> error, cannot be merged nor duplicated +// 3 .. there are some missing complementary tags and no unique conflict -> can be merged into a single line +static int sam_header_compare_lines(HeaderLine *hline1, HeaderLine *hline2) +{ + HeaderTag *t1, *t2; + + if ( hline1->type[0]!=hline2->type[0] || hline1->type[1]!=hline2->type[1] ) + return 0; + + int itype = tag_exists(hline1->type,types); + if ( itype==-1 ) { + debug("[sam_header_compare_lines] Unknown type [%c%c]\n", hline1->type[0],hline1->type[1]); + return -1; // FIXME (lh3): error; I do not know how this will be handled in Petr's code + } + + if ( unique_tags[itype] ) + { + t1 = header_line_has_tag(hline1,unique_tags[itype][0]); + t2 = header_line_has_tag(hline2,unique_tags[itype][0]); + if ( !t1 || !t2 ) // this should never happen, the unique tags are required + return 2; + + if ( strcmp(t1->value,t2->value) ) + return 0; // the unique tags differ, cannot be merged + } + if ( !required_tags[itype] && !optional_tags[itype] ) + { + t1 = hline1->tags->data; + t2 = hline2->tags->data; + if ( !strcmp(t1->value,t2->value) ) return 1; // identical comments + return 0; + } + + int missing=0, itag=0; + while ( required_tags[itype] && required_tags[itype][itag] ) + { + t1 = header_line_has_tag(hline1,required_tags[itype][itag]); + t2 = header_line_has_tag(hline2,required_tags[itype][itag]); + if ( !t1 && !t2 ) + return 2; // this should never happen + else if ( !t1 || !t2 ) + missing = 1; // there is some tag missing in one of the hlines + else if ( strcmp(t1->value,t2->value) ) + { + if ( unique_tags[itype] ) + return 2; // the lines have a matching unique tag but have a conflicting tag + + return 0; // the lines contain conflicting tags, cannot be merged + } + itag++; + } + itag = 0; + while ( optional_tags[itype] && optional_tags[itype][itag] ) + { + t1 = header_line_has_tag(hline1,optional_tags[itype][itag]); + t2 = header_line_has_tag(hline2,optional_tags[itype][itag]); + if ( !t1 && !t2 ) + { + itag++; + continue; + } + if ( !t1 || !t2 ) + missing = 1; // there is some tag missing in one of the hlines + else if ( strcmp(t1->value,t2->value) ) + { + if ( unique_tags[itype] ) + return 2; // the lines have a matching unique tag but have a conflicting tag + + return 0; // the lines contain conflicting tags, cannot be merged + } + itag++; + } + if ( missing ) return 3; // there are some missing complementary tags with no conflicts, can be merged + return 1; +} + + +static HeaderLine *sam_header_line_clone(const HeaderLine *hline) +{ + list_t *tags; + HeaderLine *out = malloc(sizeof(HeaderLine)); + out->type[0] = hline->type[0]; + out->type[1] = hline->type[1]; + out->tags = NULL; + + tags = hline->tags; + while (tags) + { + HeaderTag *old = tags->data; + + HeaderTag *new = malloc(sizeof(HeaderTag)); + new->key[0] = old->key[0]; + new->key[1] = old->key[1]; + new->value = strdup(old->value); + out->tags = list_append(out->tags, new); + + tags = tags->next; + } + return out; +} + +static int sam_header_line_merge_with(HeaderLine *out_hline, const HeaderLine *tmpl_hline) +{ + list_t *tmpl_tags; + + if ( out_hline->type[0]!=tmpl_hline->type[0] || out_hline->type[1]!=tmpl_hline->type[1] ) + return 0; + + tmpl_tags = tmpl_hline->tags; + while (tmpl_tags) + { + HeaderTag *tmpl_tag = tmpl_tags->data; + HeaderTag *out_tag = header_line_has_tag(out_hline, tmpl_tag->key); + if ( !out_tag ) + { + HeaderTag *tag = malloc(sizeof(HeaderTag)); + tag->key[0] = tmpl_tag->key[0]; + tag->key[1] = tmpl_tag->key[1]; + tag->value = strdup(tmpl_tag->value); + out_hline->tags = list_append(out_hline->tags,tag); + } + tmpl_tags = tmpl_tags->next; + } + return 1; +} + + +static HeaderLine *sam_header_line_parse(const char *headerLine) +{ + HeaderLine *hline; + HeaderTag *tag; + const char *from, *to; + from = headerLine; + + if ( *from != '@' ) { + debug("[sam_header_line_parse] expected '@', got [%s]\n", headerLine); + return 0; + } + to = ++from; + + while (*to && *to!='\t') to++; + if ( to-from != 2 ) { + debug("[sam_header_line_parse] expected '@XY', got [%s]\nHint: The header tags must be tab-separated.\n", headerLine); + return 0; + } + + hline = malloc(sizeof(HeaderLine)); + hline->type[0] = from[0]; + hline->type[1] = from[1]; + hline->tags = NULL; + + int itype = tag_exists(hline->type, types); + + from = to; + while (*to && *to=='\t') to++; + if ( to-from != 1 ) { + debug("[sam_header_line_parse] multiple tabs on line [%s] (%d)\n", headerLine,(int)(to-from)); + return 0; + } + from = to; + while (*from) + { + while (*to && *to!='\t') to++; + + if ( !required_tags[itype] && !optional_tags[itype] ) + { + // CO is a special case, it can contain anything, including tabs + if ( *to ) { to++; continue; } + tag = new_tag(" ",from,to-1); + } + else + tag = new_tag(from,from+3,to-1); + + if ( header_line_has_tag(hline,tag->key) ) + debug("The tag '%c%c' present (at least) twice on line [%s]\n", tag->key[0],tag->key[1], headerLine); + hline->tags = list_append(hline->tags, tag); + + from = to; + while (*to && *to=='\t') to++; + if ( *to && to-from != 1 ) { + debug("[sam_header_line_parse] multiple tabs on line [%s] (%d)\n", headerLine,(int)(to-from)); + return 0; + } + + from = to; + } + return hline; +} + + +// Must be of an existing type, all tags must be recognised and all required tags must be present +static int sam_header_line_validate(HeaderLine *hline) +{ + list_t *tags; + HeaderTag *tag; + int itype, itag; + + // Is the type correct? + itype = tag_exists(hline->type, types); + if ( itype==-1 ) + { + debug("The type [%c%c] not recognised.\n", hline->type[0],hline->type[1]); + return 0; + } + + // Has all required tags? + itag = 0; + while ( required_tags[itype] && required_tags[itype][itag] ) + { + if ( !header_line_has_tag(hline,required_tags[itype][itag]) ) + { + debug("The tag [%c%c] required for [%c%c] not present.\n", required_tags[itype][itag][0],required_tags[itype][itag][1], + hline->type[0],hline->type[1]); + return 0; + } + itag++; + } + + // Are all tags recognised? + tags = hline->tags; + while ( tags ) + { + tag = tags->data; + if ( !tag_exists(tag->key,required_tags[itype]) && !tag_exists(tag->key,optional_tags[itype]) ) + { + debug("Unknown tag [%c%c] for [%c%c].\n", tag->key[0],tag->key[1], hline->type[0],hline->type[1]); + return 0; + } + tags = tags->next; + } + + return 1; +} + + +static void print_header_line(FILE *fp, HeaderLine *hline) +{ + list_t *tags = hline->tags; + HeaderTag *tag; + + fprintf(fp, "@%c%c", hline->type[0],hline->type[1]); + while (tags) + { + tag = tags->data; + + fprintf(fp, "\t"); + if ( tag->key[0]!=' ' || tag->key[1]!=' ' ) + fprintf(fp, "%c%c:", tag->key[0],tag->key[1]); + fprintf(fp, "%s", tag->value); + + tags = tags->next; + } + fprintf(fp,"\n"); +} + + +static void sam_header_line_free(HeaderLine *hline) +{ + list_t *tags = hline->tags; + while (tags) + { + HeaderTag *tag = tags->data; + free(tag->value); + free(tag); + tags = tags->next; + } + list_free(hline->tags); + free(hline); +} + +void sam_header_free(void *_header) +{ + HeaderDict *header = (HeaderDict*)_header; + list_t *hlines = header; + while (hlines) + { + sam_header_line_free(hlines->data); + hlines = hlines->next; + } + list_free(header); +} + +HeaderDict *sam_header_clone(const HeaderDict *dict) +{ + HeaderDict *out = NULL; + while (dict) + { + HeaderLine *hline = dict->data; + out = list_append(out, sam_header_line_clone(hline)); + dict = dict->next; + } + return out; +} + +// Returns a newly allocated string +char *sam_header_write(const void *_header) +{ + const HeaderDict *header = (const HeaderDict*)_header; + char *out = NULL; + int len=0, nout=0; + const list_t *hlines; + + // Calculate the length of the string to allocate + hlines = header; + while (hlines) + { + len += 4; // @XY and \n + + HeaderLine *hline = hlines->data; + list_t *tags = hline->tags; + while (tags) + { + HeaderTag *tag = tags->data; + len += strlen(tag->value) + 1; // \t + if ( tag->key[0]!=' ' || tag->key[1]!=' ' ) + len += strlen(tag->value) + 3; // XY: + tags = tags->next; + } + hlines = hlines->next; + } + + nout = 0; + out = malloc(len+1); + hlines = header; + while (hlines) + { + HeaderLine *hline = hlines->data; + + nout += sprintf(out+nout,"@%c%c",hline->type[0],hline->type[1]); + + list_t *tags = hline->tags; + while (tags) + { + HeaderTag *tag = tags->data; + nout += sprintf(out+nout,"\t"); + if ( tag->key[0]!=' ' || tag->key[1]!=' ' ) + nout += sprintf(out+nout,"%c%c:", tag->key[0],tag->key[1]); + nout += sprintf(out+nout,"%s", tag->value); + tags = tags->next; + } + hlines = hlines->next; + nout += sprintf(out+nout,"\n"); + } + out[len] = 0; + return out; +} + +void *sam_header_parse2(const char *headerText) +{ + list_t *hlines = NULL; + HeaderLine *hline; + const char *text; + char *buf=NULL; + size_t nbuf = 0; + int tovalidate = 0; + + if ( !headerText ) + return 0; + + text = headerText; + while ( (text=nextline(&buf, &nbuf, text)) ) + { + hline = sam_header_line_parse(buf); + if ( hline && (!tovalidate || sam_header_line_validate(hline)) ) + // With too many (~250,000) reference sequences the header parsing was too slow with list_append. + hlines = list_append_to_end(hlines, hline); + else + { + if (hline) sam_header_line_free(hline); + sam_header_free(hlines); + if ( buf ) free(buf); + return NULL; + } + } + if ( buf ) free(buf); + + return hlines; +} + +void *sam_header2tbl(const void *_dict, char type[2], char key_tag[2], char value_tag[2]) +{ + const HeaderDict *dict = (const HeaderDict*)_dict; + const list_t *l = dict; + khash_t(str) *tbl = kh_init(str); + khiter_t k; + int ret; + + if (_dict == 0) return tbl; // return an empty (not null) hash table + while (l) + { + HeaderLine *hline = l->data; + if ( hline->type[0]!=type[0] || hline->type[1]!=type[1] ) + { + l = l->next; + continue; + } + + HeaderTag *key, *value; + key = header_line_has_tag(hline,key_tag); + value = header_line_has_tag(hline,value_tag); + if ( !key || !value ) + { + l = l->next; + continue; + } + + k = kh_get(str, tbl, key->value); + if ( k != kh_end(tbl) ) + debug("[sam_header_lookup_table] They key %s not unique.\n", key->value); + k = kh_put(str, tbl, key->value, &ret); + kh_value(tbl, k) = value->value; + + l = l->next; + } + return tbl; +} + +char **sam_header2list(const void *_dict, char type[2], char key_tag[2], int *_n) +{ + const HeaderDict *dict = (const HeaderDict*)_dict; + const list_t *l = dict; + int max, n; + char **ret; + + ret = 0; *_n = max = n = 0; + while (l) + { + HeaderLine *hline = l->data; + if ( hline->type[0]!=type[0] || hline->type[1]!=type[1] ) + { + l = l->next; + continue; + } + + HeaderTag *key; + key = header_line_has_tag(hline,key_tag); + if ( !key ) + { + l = l->next; + continue; + } + + if (n == max) { + max = max? max<<1 : 4; + ret = realloc(ret, max * sizeof(void*)); + } + ret[n++] = key->value; + + l = l->next; + } + *_n = n; + return ret; +} + +const char *sam_tbl_get(void *h, const char *key) +{ + khash_t(str) *tbl = (khash_t(str)*)h; + khint_t k; + k = kh_get(str, tbl, key); + return k == kh_end(tbl)? 0 : kh_val(tbl, k); +} + +int sam_tbl_size(void *h) +{ + khash_t(str) *tbl = (khash_t(str)*)h; + return h? kh_size(tbl) : 0; +} + +void sam_tbl_destroy(void *h) +{ + khash_t(str) *tbl = (khash_t(str)*)h; + kh_destroy(str, tbl); +} + +void *sam_header_merge(int n, const void **_dicts) +{ + const HeaderDict **dicts = (const HeaderDict**)_dicts; + HeaderDict *out_dict; + int idict, status; + + if ( n<2 ) return NULL; + + out_dict = sam_header_clone(dicts[0]); + + for (idict=1; idict<n; idict++) + { + const list_t *tmpl_hlines = dicts[idict]; + + while ( tmpl_hlines ) + { + list_t *out_hlines = out_dict; + int inserted = 0; + while ( out_hlines ) + { + status = sam_header_compare_lines(tmpl_hlines->data, out_hlines->data); + if ( status==0 ) + { + out_hlines = out_hlines->next; + continue; + } + + if ( status==2 ) + { + print_header_line(stderr,tmpl_hlines->data); + print_header_line(stderr,out_hlines->data); + debug("Conflicting lines, cannot merge the headers.\n"); + return 0; + } + if ( status==3 ) + sam_header_line_merge_with(out_hlines->data, tmpl_hlines->data); + + inserted = 1; + break; + } + if ( !inserted ) + out_dict = list_append(out_dict, sam_header_line_clone(tmpl_hlines->data)); + + tmpl_hlines = tmpl_hlines->next; + } + } + + return out_dict; +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/sam_header.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,24 @@ +#ifndef __SAM_HEADER_H__ +#define __SAM_HEADER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + void *sam_header_parse2(const char *headerText); + void *sam_header_merge(int n, const void **dicts); + void sam_header_free(void *header); + char *sam_header_write(const void *headerDict); // returns a newly allocated string + + char **sam_header2list(const void *_dict, char type[2], char key_tag[2], int *_n); + + void *sam_header2tbl(const void *dict, char type[2], char key_tag[2], char value_tag[2]); + const char *sam_tbl_get(void *h, const char *key); + int sam_tbl_size(void *h); + void sam_tbl_destroy(void *h); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/sam_view.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,351 @@ +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <unistd.h> +#include <math.h> +#include "sam_header.h" +#include "sam.h" +#include "faidx.h" +#include "kstring.h" +#include "khash.h" +KHASH_SET_INIT_STR(rg) + +// When counting records instead of printing them, +// data passed to the bam_fetch callback is encapsulated in this struct. +typedef struct { + bam_header_t *header; + int *count; +} count_func_data_t; + +typedef khash_t(rg) *rghash_t; + +static rghash_t g_rghash = 0; +static int g_min_mapQ = 0, g_flag_on = 0, g_flag_off = 0; +static char *g_library, *g_rg; +static int g_sol2sanger_tbl[128]; +static void *g_bed; + +void *bed_read(const char *fn); +void bed_destroy(void *_h); +int bed_overlap(const void *_h, const char *chr, int beg, int end); + +static void sol2sanger(bam1_t *b) +{ + int l; + uint8_t *qual = bam1_qual(b); + if (g_sol2sanger_tbl[30] == 0) { + for (l = 0; l != 128; ++l) { + g_sol2sanger_tbl[l] = (int)(10.0 * log(1.0 + pow(10.0, (l - 64 + 33) / 10.0)) / log(10.0) + .499); + if (g_sol2sanger_tbl[l] >= 93) g_sol2sanger_tbl[l] = 93; + } + } + for (l = 0; l < b->core.l_qseq; ++l) { + int q = qual[l]; + if (q > 127) q = 127; + qual[l] = g_sol2sanger_tbl[q]; + } +} + +static inline int __g_skip_aln(const bam_header_t *h, const bam1_t *b) +{ + if (b->core.qual < g_min_mapQ || ((b->core.flag & g_flag_on) != g_flag_on) || (b->core.flag & g_flag_off)) + return 1; + if (g_bed && b->core.tid >= 0 && !bed_overlap(g_bed, h->target_name[b->core.tid], b->core.pos, bam_calend(&b->core, bam1_cigar(b)))) + return 1; + if (g_rg || g_rghash) { + uint8_t *s = bam_aux_get(b, "RG"); + if (s) { + if (g_rg) return (strcmp(g_rg, (char*)(s + 1)) == 0)? 0 : 1; + if (g_rghash) { + khint_t k = kh_get(rg, g_rghash, (char*)(s + 1)); + return (k != kh_end(g_rghash))? 0 : 1; + } + } + } + if (g_library) { + const char *p = bam_get_library((bam_header_t*)h, b); + return (p && strcmp(p, g_library) == 0)? 0 : 1; + } + return 0; +} + +static char *drop_rg(char *hdtxt, rghash_t h, int *len) +{ + char *p = hdtxt, *q, *r, *s; + kstring_t str; + memset(&str, 0, sizeof(kstring_t)); + while (1) { + int toprint = 0; + q = strchr(p, '\n'); + if (q == 0) q = p + strlen(p); + if (q - p < 3) break; // the line is too short; then stop + if (strncmp(p, "@RG\t", 4) == 0) { + int c; + khint_t k; + if ((r = strstr(p, "\tID:")) != 0) { + r += 4; + for (s = r; *s != '\0' && *s != '\n' && *s != '\t'; ++s); + c = *s; *s = '\0'; + k = kh_get(rg, h, r); + *s = c; + if (k != kh_end(h)) toprint = 1; + } + } else toprint = 1; + if (toprint) { + kputsn(p, q - p, &str); kputc('\n', &str); + } + p = q + 1; + } + *len = str.l; + return str.s; +} + +// callback function for bam_fetch() that prints nonskipped records +static int view_func(const bam1_t *b, void *data) +{ + if (!__g_skip_aln(((samfile_t*)data)->header, b)) + samwrite((samfile_t*)data, b); + return 0; +} + +// callback function for bam_fetch() that counts nonskipped records +static int count_func(const bam1_t *b, void *data) +{ + if (!__g_skip_aln(((count_func_data_t*)data)->header, b)) { + (*((count_func_data_t*)data)->count)++; + } + return 0; +} + +static int usage(int is_long_help); + +int main_samview(int argc, char *argv[]) +{ + int c, is_header = 0, is_header_only = 0, is_bamin = 1, ret = 0, compress_level = -1, is_bamout = 0, slx2sngr = 0, is_count = 0; + int of_type = BAM_OFDEC, is_long_help = 0; + int count = 0; + samfile_t *in = 0, *out = 0; + char in_mode[5], out_mode[5], *fn_out = 0, *fn_list = 0, *fn_ref = 0, *fn_rg = 0; + + /* parse command-line options */ + strcpy(in_mode, "r"); strcpy(out_mode, "w"); + while ((c = getopt(argc, argv, "Sbct:h1Ho:q:f:F:ul:r:xX?T:CR:L:")) >= 0) { + switch (c) { + case 'c': is_count = 1; break; + case 'C': slx2sngr = 1; break; + case 'S': is_bamin = 0; break; + case 'b': is_bamout = 1; break; + case 't': fn_list = strdup(optarg); is_bamin = 0; break; + case 'h': is_header = 1; break; + case 'H': is_header_only = 1; break; + case 'o': fn_out = strdup(optarg); break; + case 'f': g_flag_on = strtol(optarg, 0, 0); break; + case 'F': g_flag_off = strtol(optarg, 0, 0); break; + case 'q': g_min_mapQ = atoi(optarg); break; + case 'u': compress_level = 0; break; + case '1': compress_level = 1; break; + case 'l': g_library = strdup(optarg); break; + case 'L': g_bed = bed_read(optarg); break; + case 'r': g_rg = strdup(optarg); break; + case 'R': fn_rg = strdup(optarg); break; + case 'x': of_type = BAM_OFHEX; break; + case 'X': of_type = BAM_OFSTR; break; + case '?': is_long_help = 1; break; + case 'T': fn_ref = strdup(optarg); is_bamin = 0; break; + default: return usage(is_long_help); + } + } + if (compress_level >= 0) is_bamout = 1; + if (is_header_only) is_header = 1; + if (is_bamout) strcat(out_mode, "b"); + else { + if (of_type == BAM_OFHEX) strcat(out_mode, "x"); + else if (of_type == BAM_OFSTR) strcat(out_mode, "X"); + } + if (is_bamin) strcat(in_mode, "b"); + if (is_header) strcat(out_mode, "h"); + if (compress_level >= 0) { + char tmp[2]; + tmp[0] = compress_level + '0'; tmp[1] = '\0'; + strcat(out_mode, tmp); + } + if (argc == optind) return usage(is_long_help); // potential memory leak... + + // read the list of read groups + if (fn_rg) { + FILE *fp_rg; + char buf[1024]; + int ret; + g_rghash = kh_init(rg); + fp_rg = fopen(fn_rg, "r"); + while (!feof(fp_rg) && fscanf(fp_rg, "%s", buf) > 0) // this is not a good style, but bear me... + kh_put(rg, g_rghash, strdup(buf), &ret); // we'd better check duplicates... + fclose(fp_rg); + } + + // generate the fn_list if necessary + if (fn_list == 0 && fn_ref) fn_list = samfaipath(fn_ref); + // open file handlers + if ((in = samopen(argv[optind], in_mode, fn_list)) == 0) { + fprintf(stderr, "[main_samview] fail to open \"%s\" for reading.\n", argv[optind]); + ret = 1; + goto view_end; + } + if (in->header == 0) { + fprintf(stderr, "[main_samview] fail to read the header from \"%s\".\n", argv[optind]); + ret = 1; + goto view_end; + } + if (g_rghash) { // FIXME: I do not know what "bam_header_t::n_text" is for... + char *tmp; + int l; + tmp = drop_rg(in->header->text, g_rghash, &l); + free(in->header->text); + in->header->text = tmp; + in->header->l_text = l; + } + if (!is_count && (out = samopen(fn_out? fn_out : "-", out_mode, in->header)) == 0) { + fprintf(stderr, "[main_samview] fail to open \"%s\" for writing.\n", fn_out? fn_out : "standard output"); + ret = 1; + goto view_end; + } + if (is_header_only) goto view_end; // no need to print alignments + + if (argc == optind + 1) { // convert/print the entire file + bam1_t *b = bam_init1(); + int r; + while ((r = samread(in, b)) >= 0) { // read one alignment from `in' + if (!__g_skip_aln(in->header, b)) { + if (slx2sngr) sol2sanger(b); + if (!is_count) samwrite(out, b); // write the alignment to `out' + count++; + } + } + if (r < -1) { + fprintf(stderr, "[main_samview] truncated file.\n"); + ret = 1; + } + bam_destroy1(b); + } else { // retrieve alignments in specified regions + int i; + bam_index_t *idx = 0; + if (is_bamin) idx = bam_index_load(argv[optind]); // load BAM index + if (idx == 0) { // index is unavailable + fprintf(stderr, "[main_samview] random alignment retrieval only works for indexed BAM files.\n"); + ret = 1; + goto view_end; + } + for (i = optind + 1; i < argc; ++i) { + int tid, beg, end, result; + bam_parse_region(in->header, argv[i], &tid, &beg, &end); // parse a region in the format like `chr2:100-200' + if (tid < 0) { // reference name is not found + fprintf(stderr, "[main_samview] region \"%s\" specifies an unknown reference name. Continue anyway.\n", argv[i]); + continue; + } + // fetch alignments + if (is_count) { + count_func_data_t count_data = { in->header, &count }; + result = bam_fetch(in->x.bam, idx, tid, beg, end, &count_data, count_func); + } else + result = bam_fetch(in->x.bam, idx, tid, beg, end, out, view_func); + if (result < 0) { + fprintf(stderr, "[main_samview] retrieval of region \"%s\" failed due to truncated file or corrupt BAM index file\n", argv[i]); + ret = 1; + break; + } + } + bam_index_destroy(idx); // destroy the BAM index + } + +view_end: + if (is_count && ret == 0) { + printf("%d\n", count); + } + // close files, free and return + free(fn_list); free(fn_ref); free(fn_out); free(g_library); free(g_rg); free(fn_rg); + if (g_bed) bed_destroy(g_bed); + if (g_rghash) { + khint_t k; + for (k = 0; k < kh_end(g_rghash); ++k) + if (kh_exist(g_rghash, k)) free((char*)kh_key(g_rghash, k)); + kh_destroy(rg, g_rghash); + } + samclose(in); + if (!is_count) + samclose(out); + return ret; +} + +static int usage(int is_long_help) +{ + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: samtools view [options] <in.bam>|<in.sam> [region1 [...]]\n\n"); + fprintf(stderr, "Options: -b output BAM\n"); + fprintf(stderr, " -h print header for the SAM output\n"); + fprintf(stderr, " -H print header only (no alignments)\n"); + fprintf(stderr, " -S input is SAM\n"); + fprintf(stderr, " -u uncompressed BAM output (force -b)\n"); + fprintf(stderr, " -1 fast compression (force -b)\n"); + fprintf(stderr, " -x output FLAG in HEX (samtools-C specific)\n"); + fprintf(stderr, " -X output FLAG in string (samtools-C specific)\n"); + fprintf(stderr, " -c print only the count of matching records\n"); + fprintf(stderr, " -L FILE output alignments overlapping the input BED FILE [null]\n"); + fprintf(stderr, " -t FILE list of reference names and lengths (force -S) [null]\n"); + fprintf(stderr, " -T FILE reference sequence file (force -S) [null]\n"); + fprintf(stderr, " -o FILE output file name [stdout]\n"); + fprintf(stderr, " -R FILE list of read groups to be outputted [null]\n"); + fprintf(stderr, " -f INT required flag, 0 for unset [0]\n"); + fprintf(stderr, " -F INT filtering flag, 0 for unset [0]\n"); + fprintf(stderr, " -q INT minimum mapping quality [0]\n"); + fprintf(stderr, " -l STR only output reads in library STR [null]\n"); + fprintf(stderr, " -r STR only output reads in read group STR [null]\n"); + fprintf(stderr, " -? longer help\n"); + fprintf(stderr, "\n"); + if (is_long_help) + fprintf(stderr, "Notes:\n\ +\n\ + 1. By default, this command assumes the file on the command line is in\n\ + the BAM format and it prints the alignments in SAM. If `-t' is\n\ + applied, the input file is assumed to be in the SAM format. The\n\ + file supplied with `-t' is SPACE/TAB delimited with the first two\n\ + fields of each line consisting of the reference name and the\n\ + corresponding sequence length. The `.fai' file generated by `faidx'\n\ + can be used here. This file may be empty if reads are unaligned.\n\ +\n\ + 2. SAM->BAM conversion: `samtools view -bT ref.fa in.sam.gz'.\n\ +\n\ + 3. BAM->SAM conversion: `samtools view in.bam'.\n\ +\n\ + 4. A region should be presented in one of the following formats:\n\ + `chr1', `chr2:1,000' and `chr3:1000-2,000'. When a region is\n\ + specified, the input alignment file must be an indexed BAM file.\n\ +\n\ + 5. Option `-u' is preferred over `-b' when the output is piped to\n\ + another samtools command.\n\ +\n\ + 6. In a string FLAG, each character represents one bit with\n\ + p=0x1 (paired), P=0x2 (properly paired), u=0x4 (unmapped),\n\ + U=0x8 (mate unmapped), r=0x10 (reverse), R=0x20 (mate reverse)\n\ + 1=0x40 (first), 2=0x80 (second), s=0x100 (not primary), \n\ + f=0x200 (failure) and d=0x400 (duplicate). Note that `-x' and\n\ + `-X' are samtools-C specific. Picard and older samtools do not\n\ + support HEX or string flags.\n\ +\n"); + return 1; +} + +int main_import(int argc, char *argv[]) +{ + int argc2, ret; + char **argv2; + if (argc != 4) { + fprintf(stderr, "Usage: bamtk import <in.ref_list> <in.sam> <out.bam>\n"); + return 1; + } + argc2 = 6; + argv2 = calloc(6, sizeof(char*)); + argv2[0] = "import", argv2[1] = "-o", argv2[2] = argv[3], argv2[3] = "-bt", argv2[4] = argv[1], argv2[5] = argv[2]; + ret = main_samview(argc2, argv2); + free(argv2); + return ret; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/sample.c Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,93 @@ +#include <stdlib.h> +#include <string.h> +#include "sample.h" +#include "khash.h" +KHASH_MAP_INIT_STR(sm, int) + +bam_sample_t *bam_smpl_init(void) +{ + bam_sample_t *s; + s = calloc(1, sizeof(bam_sample_t)); + s->rg2smid = kh_init(sm); + s->sm2id = kh_init(sm); + return s; +} + +void bam_smpl_destroy(bam_sample_t *sm) +{ + int i; + khint_t k; + khash_t(sm) *rg2smid = (khash_t(sm)*)sm->rg2smid; + if (sm == 0) return; + for (i = 0; i < sm->n; ++i) free(sm->smpl[i]); + free(sm->smpl); + for (k = kh_begin(rg2smid); k != kh_end(rg2smid); ++k) + if (kh_exist(rg2smid, k)) free((char*)kh_key(rg2smid, k)); + kh_destroy(sm, sm->rg2smid); + kh_destroy(sm, sm->sm2id); + free(sm); +} + +static void add_pair(bam_sample_t *sm, khash_t(sm) *sm2id, const char *key, const char *val) +{ + khint_t k_rg, k_sm; + int ret; + khash_t(sm) *rg2smid = (khash_t(sm)*)sm->rg2smid; + k_rg = kh_get(sm, rg2smid, key); + if (k_rg != kh_end(rg2smid)) return; // duplicated @RG-ID + k_rg = kh_put(sm, rg2smid, strdup(key), &ret); + k_sm = kh_get(sm, sm2id, val); + if (k_sm == kh_end(sm2id)) { // absent + if (sm->n == sm->m) { + sm->m = sm->m? sm->m<<1 : 1; + sm->smpl = realloc(sm->smpl, sizeof(void*) * sm->m); + } + sm->smpl[sm->n] = strdup(val); + k_sm = kh_put(sm, sm2id, sm->smpl[sm->n], &ret); + kh_val(sm2id, k_sm) = sm->n++; + } + kh_val(rg2smid, k_rg) = kh_val(sm2id, k_sm); +} + +int bam_smpl_add(bam_sample_t *sm, const char *fn, const char *txt) +{ + const char *p = txt, *q, *r; + kstring_t buf; + int n = 0; + khash_t(sm) *sm2id = (khash_t(sm)*)sm->sm2id; + memset(&buf, 0, sizeof(kstring_t)); + while ((q = strstr(p, "@RG")) != 0) { + p = q + 3; + r = q = 0; + if ((q = strstr(p, "\tID:")) != 0) q += 4; + if ((r = strstr(p, "\tSM:")) != 0) r += 4; + if (r && q) { + char *u, *v; + int oq, or; + for (u = (char*)q; *u && *u != '\t' && *u != '\n'; ++u); + for (v = (char*)r; *v && *v != '\t' && *v != '\n'; ++v); + oq = *u; or = *v; *u = *v = '\0'; + buf.l = 0; kputs(fn, &buf); kputc('/', &buf); kputs(q, &buf); + add_pair(sm, sm2id, buf.s, r); + *u = oq; *v = or; + } else break; + p = q > r? q : r; + ++n; + } + if (n == 0) add_pair(sm, sm2id, fn, fn); +// add_pair(sm, sm2id, fn, fn); + free(buf.s); + return 0; +} + +int bam_smpl_rg2smid(const bam_sample_t *sm, const char *fn, const char *rg, kstring_t *str) +{ + khint_t k; + khash_t(sm) *rg2smid = (khash_t(sm)*)sm->rg2smid; + if (rg) { + str->l = 0; + kputs(fn, str); kputc('/', str); kputs(rg, str); + k = kh_get(sm, rg2smid, str->s); + } else k = kh_get(sm, rg2smid, fn); + return k == kh_end(rg2smid)? -1 : kh_val(rg2smid, k); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/sample.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,17 @@ +#ifndef BAM_SAMPLE_H +#define BAM_SAMPLE_H + +#include "kstring.h" + +typedef struct { + int n, m; + char **smpl; + void *rg2smid, *sm2id; +} bam_sample_t; + +bam_sample_t *bam_smpl_init(void); +int bam_smpl_add(bam_sample_t *sm, const char *abs, const char *txt); +int bam_smpl_rg2smid(const bam_sample_t *sm, const char *fn, const char *rg, kstring_t *str); +void bam_smpl_destroy(bam_sample_t *sm); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/samtools.1 Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,824 @@ +.TH samtools 1 "21 April 2011" "samtools-0.1.16" "Bioinformatics tools" +.SH NAME +.PP +samtools - Utilities for the Sequence Alignment/Map (SAM) format +.SH SYNOPSIS +.PP +samtools view -bt ref_list.txt -o aln.bam aln.sam.gz +.PP +samtools sort aln.bam aln.sorted +.PP +samtools index aln.sorted.bam +.PP +samtools idxstats aln.sorted.bam +.PP +samtools view aln.sorted.bam chr2:20,100,000-20,200,000 +.PP +samtools merge out.bam in1.bam in2.bam in3.bam +.PP +samtools faidx ref.fasta +.PP +samtools pileup -vcf ref.fasta aln.sorted.bam +.PP +samtools mpileup -C50 -gf ref.fasta -r chr3:1,000-2,000 in1.bam in2.bam +.PP +samtools tview aln.sorted.bam ref.fasta + +.SH DESCRIPTION +.PP +Samtools is a set of utilities that manipulate alignments in the BAM +format. It imports from and exports to the SAM (Sequence Alignment/Map) +format, does sorting, merging and indexing, and allows to retrieve reads +in any regions swiftly. + +Samtools is designed to work on a stream. It regards an input file `-' +as the standard input (stdin) and an output file `-' as the standard +output (stdout). Several commands can thus be combined with Unix +pipes. Samtools always output warning and error messages to the standard +error output (stderr). + +Samtools is also able to open a BAM (not SAM) file on a remote FTP or +HTTP server if the BAM file name starts with `ftp://' or `http://'. +Samtools checks the current working directory for the index file and +will download the index upon absence. Samtools does not retrieve the +entire alignment file unless it is asked to do so. + +.SH COMMANDS AND OPTIONS + +.TP 10 +.B view +samtools view [-bchuHS] [-t in.refList] [-o output] [-f reqFlag] [-F +skipFlag] [-q minMapQ] [-l library] [-r readGroup] [-R rgFile] <in.bam>|<in.sam> [region1 [...]] + +Extract/print all or sub alignments in SAM or BAM format. If no region +is specified, all the alignments will be printed; otherwise only +alignments overlapping the specified regions will be output. An +alignment may be given multiple times if it is overlapping several +regions. A region can be presented, for example, in the following +format: `chr2' (the whole chr2), `chr2:1000000' (region starting from +1,000,000bp) or `chr2:1,000,000-2,000,000' (region between 1,000,000 and +2,000,000bp including the end points). The coordinate is 1-based. + +.B OPTIONS: +.RS +.TP 8 +.B -b +Output in the BAM format. +.TP +.BI -f \ INT +Only output alignments with all bits in INT present in the FLAG +field. INT can be in hex in the format of /^0x[0-9A-F]+/ [0] +.TP +.BI -F \ INT +Skip alignments with bits present in INT [0] +.TP +.B -h +Include the header in the output. +.TP +.B -H +Output the header only. +.TP +.BI -l \ STR +Only output reads in library STR [null] +.TP +.BI -o \ FILE +Output file [stdout] +.TP +.BI -q \ INT +Skip alignments with MAPQ smaller than INT [0] +.TP +.BI -r \ STR +Only output reads in read group STR [null] +.TP +.BI -R \ FILE +Output reads in read groups listed in +.I FILE +[null] +.TP +.B -S +Input is in SAM. If @SQ header lines are absent, the +.B `-t' +option is required. +.TP +.B -c +Instead of printing the alignments, only count them and print the +total number. All filter options, such as +.B `-f', +.B `-F' +and +.B `-q' +, are taken into account. +.TP +.BI -t \ FILE +This file is TAB-delimited. Each line must contain the reference name +and the length of the reference, one line for each distinct reference; +additional fields are ignored. This file also defines the order of the +reference sequences in sorting. If you run `samtools faidx <ref.fa>', +the resultant index file +.I <ref.fa>.fai +can be used as this +.I <in.ref_list> +file. +.TP +.B -u +Output uncompressed BAM. This option saves time spent on +compression/decomprssion and is thus preferred when the output is piped +to another samtools command. +.RE + +.TP +.B tview +samtools tview <in.sorted.bam> [ref.fasta] + +Text alignment viewer (based on the ncurses library). In the viewer, +press `?' for help and press `g' to check the alignment start from a +region in the format like `chr10:10,000,000' or `=10,000,000' when +viewing the same reference sequence. + +.TP +.B mpileup +samtools mpileup [-EBug] [-C capQcoef] [-r reg] [-f in.fa] [-l list] [-M capMapQ] [-Q minBaseQ] [-q minMapQ] in.bam [in2.bam [...]] + +Generate BCF or pileup for one or multiple BAM files. Alignment records +are grouped by sample identifiers in @RG header lines. If sample +identifiers are absent, each input file is regarded as one sample. + +.B OPTIONS: +.RS +.TP 10 +.B -A +Do not skip anomalous read pairs in variant calling. +.TP +.B -B +Disable probabilistic realignment for the computation of base alignment +quality (BAQ). BAQ is the Phred-scaled probability of a read base being +misaligned. Applying this option greatly helps to reduce false SNPs +caused by misalignments. +.TP +.BI -C \ INT +Coefficient for downgrading mapping quality for reads containing +excessive mismatches. Given a read with a phred-scaled probability q of +being generated from the mapped position, the new mapping quality is +about sqrt((INT-q)/INT)*INT. A zero value disables this +functionality; if enabled, the recommended value for BWA is 50. [0] +.TP +.BI -d \ INT +At a position, read maximally +.I INT +reads per input BAM. [250] +.TP +.B -D +Output per-sample read depth +.TP +.BI -e \ INT +Phred-scaled gap extension sequencing error probability. Reducing +.I INT +leads to longer indels. [20] +.TP +.B -E +Extended BAQ computation. This option helps sensitivity especially for MNPs, but may hurt +specificity a little bit. +.TP +.BI -f \ FILE +The reference file [null] +.TP +.B -g +Compute genotype likelihoods and output them in the binary call format (BCF). +.TP +.BI -h \ INT +Coefficient for modeling homopolymer errors. Given an +.IR l -long +homopolymer +run, the sequencing error of an indel of size +.I s +is modeled as +.IR INT * s / l . +[100] +.TP +.B -I +Do not perform INDEL calling +.TP +.BI -l \ FILE +File containing a list of sites where pileup or BCF is outputted [null] +.TP +.BI -L \ INT +Skip INDEL calling if the average per-sample depth is above +.IR INT . +[250] +.TP +.BI -o \ INT +Phred-scaled gap open sequencing error probability. Reducing +.I INT +leads to more indel calls. [40] +.TP +.BI -P \ STR +Comma dilimited list of platforms (determined by +.BR @RG-PL ) +from which indel candidates are obtained. It is recommended to collect +indel candidates from sequencing technologies that have low indel error +rate such as ILLUMINA. [all] +.TP +.BI -q \ INT +Minimum mapping quality for an alignment to be used [0] +.TP +.BI -Q \ INT +Minimum base quality for a base to be considered [13] +.TP +.BI -r \ STR +Only generate pileup in region +.I STR +[all sites] +.TP +.B -S +Output per-sample Phred-scaled strand bias P-value +.TP +.B -u +Similar to +.B -g +except that the output is uncompressed BCF, which is preferred for piping. +.RE + +.TP +.B reheader +samtools reheader <in.header.sam> <in.bam> + +Replace the header in +.I in.bam +with the header in +.I in.header.sam. +This command is much faster than replacing the header with a +BAM->SAM->BAM conversion. + +.TP +.B cat +samtools cat [-h header.sam] [-o out.bam] <in1.bam> <in2.bam> [ ... ] + +Concatenate BAMs. The sequence dictionary of each input BAM must be identical, +although this command does not check this. This command uses a similar trick +to +.B reheader +which enables fast BAM concatenation. + +.TP +.B sort +samtools sort [-no] [-m maxMem] <in.bam> <out.prefix> + +Sort alignments by leftmost coordinates. File +.I <out.prefix>.bam +will be created. This command may also create temporary files +.I <out.prefix>.%d.bam +when the whole alignment cannot be fitted into memory (controlled by +option -m). + +.B OPTIONS: +.RS +.TP 8 +.B -o +Output the final alignment to the standard output. +.TP +.B -n +Sort by read names rather than by chromosomal coordinates +.TP +.BI -m \ INT +Approximately the maximum required memory. [500000000] +.RE + +.TP +.B merge +samtools merge [-nur1f] [-h inh.sam] [-R reg] <out.bam> <in1.bam> <in2.bam> [...] + +Merge multiple sorted alignments. +The header reference lists of all the input BAM files, and the @SQ headers of +.IR inh.sam , +if any, must all refer to the same set of reference sequences. +The header reference list and (unless overridden by +.BR -h ) +`@' headers of +.I in1.bam +will be copied to +.IR out.bam , +and the headers of other files will be ignored. + +.B OPTIONS: +.RS +.TP 8 +.B -1 +Use zlib compression level 1 to comrpess the output +.TP +.B -f +Force to overwrite the output file if present. +.TP 8 +.BI -h \ FILE +Use the lines of +.I FILE +as `@' headers to be copied to +.IR out.bam , +replacing any header lines that would otherwise be copied from +.IR in1.bam . +.RI ( FILE +is actually in SAM format, though any alignment records it may contain +are ignored.) +.TP +.B -n +The input alignments are sorted by read names rather than by chromosomal +coordinates +.TP +.BI -R \ STR +Merge files in the specified region indicated by +.I STR +[null] +.TP +.B -r +Attach an RG tag to each alignment. The tag value is inferred from file names. +.TP +.B -u +Uncompressed BAM output +.RE + +.TP +.B index +samtools index <aln.bam> + +Index sorted alignment for fast random access. Index file +.I <aln.bam>.bai +will be created. + +.TP +.B idxstats +samtools idxstats <aln.bam> + +Retrieve and print stats in the index file. The output is TAB delimited +with each line consisting of reference sequence name, sequence length, # +mapped reads and # unmapped reads. + +.TP +.B faidx +samtools faidx <ref.fasta> [region1 [...]] + +Index reference sequence in the FASTA format or extract subsequence from +indexed reference sequence. If no region is specified, +.B faidx +will index the file and create +.I <ref.fasta>.fai +on the disk. If regions are speficified, the subsequences will be +retrieved and printed to stdout in the FASTA format. The input file can +be compressed in the +.B RAZF +format. + +.TP +.B fixmate +samtools fixmate <in.nameSrt.bam> <out.bam> + +Fill in mate coordinates, ISIZE and mate related flags from a +name-sorted alignment. + +.TP +.B rmdup +samtools rmdup [-sS] <input.srt.bam> <out.bam> + +Remove potential PCR duplicates: if multiple read pairs have identical +external coordinates, only retain the pair with highest mapping quality. +In the paired-end mode, this command +.B ONLY +works with FR orientation and requires ISIZE is correctly set. It does +not work for unpaired reads (e.g. two ends mapped to different +chromosomes or orphan reads). + +.B OPTIONS: +.RS +.TP 8 +.B -s +Remove duplicate for single-end reads. By default, the command works for +paired-end reads only. +.TP 8 +.B -S +Treat paired-end reads and single-end reads. +.RE + +.TP +.B calmd +samtools calmd [-EeubSr] [-C capQcoef] <aln.bam> <ref.fasta> + +Generate the MD tag. If the MD tag is already present, this command will +give a warning if the MD tag generated is different from the existing +tag. Output SAM by default. + +.B OPTIONS: +.RS +.TP 8 +.B -A +When used jointly with +.B -r +this option overwrites the original base quality. +.TP 8 +.B -e +Convert a the read base to = if it is identical to the aligned reference +base. Indel caller does not support the = bases at the moment. +.TP +.B -u +Output uncompressed BAM +.TP +.B -b +Output compressed BAM +.TP +.B -S +The input is SAM with header lines +.TP +.BI -C \ INT +Coefficient to cap mapping quality of poorly mapped reads. See the +.B pileup +command for details. [0] +.TP +.B -r +Compute the BQ tag (without -A) or cap base quality by BAQ (with -A). +.TP +.B -E +Extended BAQ calculation. This option trades specificity for sensitivity, though the +effect is minor. +.RE + +.TP +.B targetcut +samtools targetcut [-Q minBaseQ] [-i inPenalty] [-0 em0] [-1 em1] [-2 em2] [-f ref] <in.bam> + +This command identifies target regions by examining the continuity of read depth, computes +haploid consensus sequences of targets and outputs a SAM with each sequence corresponding +to a target. When option +.B -f +is in use, BAQ will be applied. This command is +.B only +designed for cutting fosmid clones from fosmid pool sequencing [Ref. Kitzman et al. (2010)]. +.RE + +.TP +.B phase +samtools phase [-AF] [-k len] [-b prefix] [-q minLOD] [-Q minBaseQ] <in.bam> + +Call and phase heterozygous SNPs. +.B OPTIONS: +.RS +.TP 8 +.B -A +Drop reads with ambiguous phase. +.TP 8 +.BI -b \ STR +Prefix of BAM output. When this option is in use, phase-0 reads will be saved in file +.BR STR .0.bam +and phase-1 reads in +.BR STR .1.bam. +Phase unknown reads will be randomly allocated to one of the two files. Chimeric reads +with switch errors will be saved in +.BR STR .chimeric.bam. +[null] +.TP +.B -F +Do not attempt to fix chimeric reads. +.TP +.BI -k \ INT +Maximum length for local phasing. [13] +.TP +.BI -q \ INT +Minimum Phred-scaled LOD to call a heterozygote. [40] +.TP +.BI -Q \ INT +Minimum base quality to be used in het calling. [13] +.RE + +.TP +.B pileup +samtools pileup [-2sSBicv] [-f in.ref.fasta] [-t in.ref_list] [-l +in.site_list] [-C capMapQ] [-M maxMapQ] [-T theta] [-N nHap] [-r +pairDiffRate] [-m mask] [-d maxIndelDepth] [-G indelPrior] +<in.bam>|<in.sam> + +Print the alignment in the pileup format. In the pileup format, each +line represents a genomic position, consisting of chromosome name, +coordinate, reference base, read bases, read qualities and alignment +mapping qualities. Information on match, mismatch, indel, strand, +mapping quality and start and end of a read are all encoded at the read +base column. At this column, a dot stands for a match to the reference +base on the forward strand, a comma for a match on the reverse strand, +a '>' or '<' for a reference skip, `ACGTN' for a mismatch on the forward +strand and `acgtn' for a mismatch on the reverse strand. A pattern +`\\+[0-9]+[ACGTNacgtn]+' indicates there is an insertion between this +reference position and the next reference position. The length of the +insertion is given by the integer in the pattern, followed by the +inserted sequence. Similarly, a pattern `-[0-9]+[ACGTNacgtn]+' +represents a deletion from the reference. The deleted bases will be +presented as `*' in the following lines. Also at the read base column, a +symbol `^' marks the start of a read. The ASCII of the character +following `^' minus 33 gives the mapping quality. A symbol `$' marks the +end of a read segment. + +If option +.B -c +is applied, the consensus base, Phred-scaled consensus quality, SNP +quality (i.e. the Phred-scaled probability of the consensus being +identical to the reference) and root mean square (RMS) mapping quality +of the reads covering the site will be inserted between the `reference +base' and the `read bases' columns. An indel occupies an additional +line. Each indel line consists of chromosome name, coordinate, a star, +the genotype, consensus quality, SNP quality, RMS mapping quality, # +covering reads, the first alllele, the second allele, # reads supporting +the first allele, # reads supporting the second allele and # reads +containing indels different from the top two alleles. + +.B NOTE: +Since 0.1.10, the `pileup' command is deprecated by `mpileup'. + +.B OPTIONS: +.RS +.TP 10 +.B -B +Disable the BAQ computation. See the +.B mpileup +command for details. +.TP +.B -c +Call the consensus sequence. Options +.BR -T ", " -N ", " -I " and " -r +are only effective when +.BR -c " or " -g +is in use. +.TP +.BI -C \ INT +Coefficient for downgrading the mapping quality of poorly mapped +reads. See the +.B mpileup +command for details. [0] +.TP +.BI -d \ INT +Use the first +.I NUM +reads in the pileup for indel calling for speed up. Zero for unlimited. [1024] +.TP +.BI -f \ FILE +The reference sequence in the FASTA format. Index file +.I FILE.fai +will be created if +absent. +.TP +.B -g +Generate genotype likelihood in the binary GLFv3 format. This option +suppresses -c, -i and -s. This option is deprecated by the +.B mpileup +command. +.TP +.B -i +Only output pileup lines containing indels. +.TP +.BI -I \ INT +Phred probability of an indel in sequencing/prep. [40] +.TP +.BI -l \ FILE +List of sites at which pileup is output. This file is space +delimited. The first two columns are required to be chromosome and +1-based coordinate. Additional columns are ignored. It is +recommended to use option +.TP +.BI -m \ INT +Filter reads with flag containing bits in +.I INT +[1796] +.TP +.BI -M \ INT +Cap mapping quality at INT [60] +.TP +.BI -N \ INT +Number of haplotypes in the sample (>=2) [2] +.TP +.BI -r \ FLOAT +Expected fraction of differences between a pair of haplotypes [0.001] +.TP +.B -s +Print the mapping quality as the last column. This option makes the +output easier to parse, although this format is not space efficient. +.TP +.B -S +The input file is in SAM. +.TP +.BI -t \ FILE +List of reference names ane sequence lengths, in the format described +for the +.B import +command. If this option is present, samtools assumes the input +.I <in.alignment> +is in SAM format; otherwise it assumes in BAM format. +.B -s +together with +.B -l +as in the default format we may not know the mapping quality. +.TP +.BI -T \ FLOAT +The theta parameter (error dependency coefficient) in the maq consensus +calling model [0.85] +.RE + +.SH SAM FORMAT + +SAM is TAB-delimited. Apart from the header lines, which are started +with the `@' symbol, each alignment line consists of: + +.TS +center box; +cb | cb | cb +n | l | l . +Col Field Description +_ +1 QNAME Query (pair) NAME +2 FLAG bitwise FLAG +3 RNAME Reference sequence NAME +4 POS 1-based leftmost POSition/coordinate of clipped sequence +5 MAPQ MAPping Quality (Phred-scaled) +6 CIAGR extended CIGAR string +7 MRNM Mate Reference sequence NaMe (`=' if same as RNAME) +8 MPOS 1-based Mate POSistion +9 ISIZE Inferred insert SIZE +10 SEQ query SEQuence on the same strand as the reference +11 QUAL query QUALity (ASCII-33 gives the Phred base quality) +12 OPT variable OPTional fields in the format TAG:VTYPE:VALUE +.TE + +.PP +Each bit in the FLAG field is defined as: + +.TS +center box; +cb | cb | cb +l | c | l . +Flag Chr Description +_ +0x0001 p the read is paired in sequencing +0x0002 P the read is mapped in a proper pair +0x0004 u the query sequence itself is unmapped +0x0008 U the mate is unmapped +0x0010 r strand of the query (1 for reverse) +0x0020 R strand of the mate +0x0040 1 the read is the first read in a pair +0x0080 2 the read is the second read in a pair +0x0100 s the alignment is not primary +0x0200 f the read fails platform/vendor quality checks +0x0400 d the read is either a PCR or an optical duplicate +.TE + +.SH EXAMPLES +.IP o 2 +Import SAM to BAM when +.B @SQ +lines are present in the header: + + samtools view -bS aln.sam > aln.bam + +If +.B @SQ +lines are absent: + + samtools faidx ref.fa + samtools view -bt ref.fa.fai aln.sam > aln.bam + +where +.I ref.fa.fai +is generated automatically by the +.B faidx +command. + +.IP o 2 +Attach the +.B RG +tag while merging sorted alignments: + + perl -e 'print "@RG\\tID:ga\\tSM:hs\\tLB:ga\\tPL:Illumina\\n@RG\\tID:454\\tSM:hs\\tLB:454\\tPL:454\\n"' > rg.txt + samtools merge -rh rg.txt merged.bam ga.bam 454.bam + +The value in a +.B RG +tag is determined by the file name the read is coming from. In this +example, in the +.IR merged.bam , +reads from +.I ga.bam +will be attached +.IR RG:Z:ga , +while reads from +.I 454.bam +will be attached +.IR RG:Z:454 . + +.IP o 2 +Call SNPs and short indels for one diploid individual: + + samtools mpileup -ugf ref.fa aln.bam | bcftools view -bvcg - > var.raw.bcf + bcftools view var.raw.bcf | vcfutils.pl varFilter -D 100 > var.flt.vcf + +The +.B -D +option of varFilter controls the maximum read depth, which should be +adjusted to about twice the average read depth. One may consider to add +.B -C50 +to +.B mpileup +if mapping quality is overestimated for reads containing excessive +mismatches. Applying this option usually helps +.B BWA-short +but may not other mappers. + +.IP o 2 +Generate the consensus sequence for one diploid individual: + + samtools mpileup -uf ref.fa aln.bam | bcftools view -cg - | vcfutils.pl vcf2fq > cns.fq + +.IP o 2 +Phase one individual: + + samtools calmd -AEur aln.bam ref.fa | samtools phase -b prefix - > phase.out + +The +.B calmd +command is used to reduce false heterozygotes around INDELs. + +.IP o 2 +Call SNPs and short indels for multiple diploid individuals: + + samtools mpileup -P ILLUMINA -ugf ref.fa *.bam | bcftools view -bcvg - > var.raw.bcf + bcftools view var.raw.bcf | vcfutils.pl varFilter -D 2000 > var.flt.vcf + +Individuals are identified from the +.B SM +tags in the +.B @RG +header lines. Individuals can be pooled in one alignment file; one +individual can also be separated into multiple files. The +.B -P +option specifies that indel candidates should be collected only from +read groups with the +.B @RG-PL +tag set to +.IR ILLUMINA . +Collecting indel candidates from reads sequenced by an indel-prone +technology may affect the performance of indel calling. + +.IP o 2 +Derive the allele frequency spectrum (AFS) on a list of sites from multiple individuals: + + samtools mpileup -Igf ref.fa *.bam > all.bcf + bcftools view -bl sites.list all.bcf > sites.bcf + bcftools view -cGP cond2 sites.bcf > /dev/null 2> sites.1.afs + bcftools view -cGP sites.1.afs sites.bcf > /dev/null 2> sites.2.afs + bcftools view -cGP sites.2.afs sites.bcf > /dev/null 2> sites.3.afs + ...... + +where +.I sites.list +contains the list of sites with each line consisting of the reference +sequence name and position. The following +.B bcftools +commands estimate AFS by EM. + +.IP o 2 +Dump BAQ applied alignment for other SNP callers: + + samtools calmd -bAr aln.bam > aln.baq.bam + +It adds and corrects the +.B NM +and +.B MD +tags at the same time. The +.B calmd +command also comes with the +.B -C +option, the same as the one in +.B pileup +and +.BR mpileup . +Apply if it helps. + +.SH LIMITATIONS +.PP +.IP o 2 +Unaligned words used in bam_import.c, bam_endian.h, bam.c and bam_aux.c. +.IP o 2 +In merging, the input files are required to have the same number of +reference sequences. The requirement can be relaxed. In addition, +merging does not reconstruct the header dictionaries +automatically. Endusers have to provide the correct header. Picard is +better at merging. +.IP o 2 +Samtools paired-end rmdup does not work for unpaired reads (e.g. orphan +reads or ends mapped to different chromosomes). If this is a concern, +please use Picard's MarkDuplicate which correctly handles these cases, +although a little slower. + +.SH AUTHOR +.PP +Heng Li from the Sanger Institute wrote the C version of samtools. Bob +Handsaker from the Broad Institute implemented the BGZF library and Jue +Ruan from Beijing Genomics Institute wrote the RAZF library. John +Marshall and Petr Danecek contribute to the source code and various +people from the 1000 Genomes Project have contributed to the SAM format +specification. + +.SH SEE ALSO +.PP +Samtools website: <http://samtools.sourceforge.net>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/win32/xcurses.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,1377 @@ +/* Public Domain Curses */ + +/* $Id: curses.h,v 1.295 2008/07/15 17:13:25 wmcbrine Exp $ */ + +/*----------------------------------------------------------------------* + * PDCurses * + *----------------------------------------------------------------------*/ + +#ifndef __PDCURSES__ +#define __PDCURSES__ 1 + +/*man-start************************************************************** + +PDCurses definitions list: (Only define those needed) + + XCURSES True if compiling for X11. + PDC_RGB True if you want to use RGB color definitions + (Red = 1, Green = 2, Blue = 4) instead of BGR. + PDC_WIDE True if building wide-character support. + PDC_DLL_BUILD True if building a Win32 DLL. + NCURSES_MOUSE_VERSION Use the ncurses mouse API instead + of PDCurses' traditional mouse API. + +PDCurses portable platform definitions list: + + PDC_BUILD Defines API build version. + PDCURSES Enables access to PDCurses-only routines. + XOPEN Always true. + SYSVcurses True if you are compiling for SYSV portability. + BSDcurses True if you are compiling for BSD portability. + +**man-end****************************************************************/ + +#define PDC_BUILD 3401 +#define PDCURSES 1 /* PDCurses-only routines */ +#define XOPEN 1 /* X/Open Curses routines */ +#define SYSVcurses 1 /* System V Curses routines */ +#define BSDcurses 1 /* BSD Curses routines */ +#define CHTYPE_LONG 1 /* size of chtype; long */ + +/*----------------------------------------------------------------------*/ + +#include <stdarg.h> +#include <stddef.h> +#include <stdio.h> /* Required by X/Open usage below */ + +#ifdef PDC_WIDE +# include <wchar.h> +#endif + +#if defined(__cplusplus) || defined(__cplusplus__) || defined(__CPLUSPLUS) +extern "C" +{ +# define bool _bool +#endif + +/*---------------------------------------------------------------------- + * + * PDCurses Manifest Constants + * + */ + +#ifndef FALSE +# define FALSE 0 +#endif +#ifndef TRUE +# define TRUE 1 +#endif +#ifndef NULL +# define NULL (void *)0 +#endif +#ifndef ERR +# define ERR (-1) +#endif +#ifndef OK +# define OK 0 +#endif + +/*---------------------------------------------------------------------- + * + * PDCurses Type Declarations + * + */ + +typedef unsigned char bool; /* PDCurses Boolean type */ + +#ifdef CHTYPE_LONG +# if _LP64 +typedef unsigned int chtype; +# else +typedef unsigned long chtype; /* 16-bit attr + 16-bit char */ +# endif +#else +typedef unsigned short chtype; /* 8-bit attr + 8-bit char */ +#endif + +#ifdef PDC_WIDE +typedef chtype cchar_t; +#endif + +typedef chtype attr_t; + +/*---------------------------------------------------------------------- + * + * PDCurses Mouse Interface -- SYSVR4, with extensions + * + */ + +typedef struct +{ + int x; /* absolute column, 0 based, measured in characters */ + int y; /* absolute row, 0 based, measured in characters */ + short button[3]; /* state of each button */ + int changes; /* flags indicating what has changed with the mouse */ +} MOUSE_STATUS; + +#define BUTTON_RELEASED 0x0000 +#define BUTTON_PRESSED 0x0001 +#define BUTTON_CLICKED 0x0002 +#define BUTTON_DOUBLE_CLICKED 0x0003 +#define BUTTON_TRIPLE_CLICKED 0x0004 +#define BUTTON_MOVED 0x0005 /* PDCurses */ +#define WHEEL_SCROLLED 0x0006 /* PDCurses */ +#define BUTTON_ACTION_MASK 0x0007 /* PDCurses */ + +#define PDC_BUTTON_SHIFT 0x0008 /* PDCurses */ +#define PDC_BUTTON_CONTROL 0x0010 /* PDCurses */ +#define PDC_BUTTON_ALT 0x0020 /* PDCurses */ +#define BUTTON_MODIFIER_MASK 0x0038 /* PDCurses */ + +#define MOUSE_X_POS (Mouse_status.x) +#define MOUSE_Y_POS (Mouse_status.y) + +/* + * Bits associated with the .changes field: + * 3 2 1 0 + * 210987654321098765432109876543210 + * 1 <- button 1 has changed + * 10 <- button 2 has changed + * 100 <- button 3 has changed + * 1000 <- mouse has moved + * 10000 <- mouse position report + * 100000 <- mouse wheel up + * 1000000 <- mouse wheel down + */ + +#define PDC_MOUSE_MOVED 0x0008 +#define PDC_MOUSE_POSITION 0x0010 +#define PDC_MOUSE_WHEEL_UP 0x0020 +#define PDC_MOUSE_WHEEL_DOWN 0x0040 + +#define A_BUTTON_CHANGED (Mouse_status.changes & 7) +#define MOUSE_MOVED (Mouse_status.changes & PDC_MOUSE_MOVED) +#define MOUSE_POS_REPORT (Mouse_status.changes & PDC_MOUSE_POSITION) +#define BUTTON_CHANGED(x) (Mouse_status.changes & (1 << ((x) - 1))) +#define BUTTON_STATUS(x) (Mouse_status.button[(x) - 1]) +#define MOUSE_WHEEL_UP (Mouse_status.changes & PDC_MOUSE_WHEEL_UP) +#define MOUSE_WHEEL_DOWN (Mouse_status.changes & PDC_MOUSE_WHEEL_DOWN) + +/* mouse bit-masks */ + +#define BUTTON1_RELEASED 0x00000001L +#define BUTTON1_PRESSED 0x00000002L +#define BUTTON1_CLICKED 0x00000004L +#define BUTTON1_DOUBLE_CLICKED 0x00000008L +#define BUTTON1_TRIPLE_CLICKED 0x00000010L +#define BUTTON1_MOVED 0x00000010L /* PDCurses */ + +#define BUTTON2_RELEASED 0x00000020L +#define BUTTON2_PRESSED 0x00000040L +#define BUTTON2_CLICKED 0x00000080L +#define BUTTON2_DOUBLE_CLICKED 0x00000100L +#define BUTTON2_TRIPLE_CLICKED 0x00000200L +#define BUTTON2_MOVED 0x00000200L /* PDCurses */ + +#define BUTTON3_RELEASED 0x00000400L +#define BUTTON3_PRESSED 0x00000800L +#define BUTTON3_CLICKED 0x00001000L +#define BUTTON3_DOUBLE_CLICKED 0x00002000L +#define BUTTON3_TRIPLE_CLICKED 0x00004000L +#define BUTTON3_MOVED 0x00004000L /* PDCurses */ + +/* For the ncurses-compatible functions only, BUTTON4_PRESSED and + BUTTON5_PRESSED are returned for mouse scroll wheel up and down; + otherwise PDCurses doesn't support buttons 4 and 5 */ + +#define BUTTON4_RELEASED 0x00008000L +#define BUTTON4_PRESSED 0x00010000L +#define BUTTON4_CLICKED 0x00020000L +#define BUTTON4_DOUBLE_CLICKED 0x00040000L +#define BUTTON4_TRIPLE_CLICKED 0x00080000L + +#define BUTTON5_RELEASED 0x00100000L +#define BUTTON5_PRESSED 0x00200000L +#define BUTTON5_CLICKED 0x00400000L +#define BUTTON5_DOUBLE_CLICKED 0x00800000L +#define BUTTON5_TRIPLE_CLICKED 0x01000000L + +#define MOUSE_WHEEL_SCROLL 0x02000000L /* PDCurses */ +#define BUTTON_MODIFIER_SHIFT 0x04000000L /* PDCurses */ +#define BUTTON_MODIFIER_CONTROL 0x08000000L /* PDCurses */ +#define BUTTON_MODIFIER_ALT 0x10000000L /* PDCurses */ + +#define ALL_MOUSE_EVENTS 0x1fffffffL +#define REPORT_MOUSE_POSITION 0x20000000L + +/* ncurses mouse interface */ + +typedef unsigned long mmask_t; + +typedef struct +{ + short id; /* unused, always 0 */ + int x, y, z; /* x, y same as MOUSE_STATUS; z unused */ + mmask_t bstate; /* equivalent to changes + button[], but + in the same format as used for mousemask() */ +} MEVENT; + +#ifdef NCURSES_MOUSE_VERSION +# define BUTTON_SHIFT BUTTON_MODIFIER_SHIFT +# define BUTTON_CONTROL BUTTON_MODIFIER_CONTROL +# define BUTTON_CTRL BUTTON_MODIFIER_CONTROL +# define BUTTON_ALT BUTTON_MODIFIER_ALT +#else +# define BUTTON_SHIFT PDC_BUTTON_SHIFT +# define BUTTON_CONTROL PDC_BUTTON_CONTROL +# define BUTTON_ALT PDC_BUTTON_ALT +#endif + +/*---------------------------------------------------------------------- + * + * PDCurses Structure Definitions + * + */ + +typedef struct _win /* definition of a window */ +{ + int _cury; /* current pseudo-cursor */ + int _curx; + int _maxy; /* max window coordinates */ + int _maxx; + int _begy; /* origin on screen */ + int _begx; + int _flags; /* window properties */ + chtype _attrs; /* standard attributes and colors */ + chtype _bkgd; /* background, normally blank */ + bool _clear; /* causes clear at next refresh */ + bool _leaveit; /* leaves cursor where it is */ + bool _scroll; /* allows window scrolling */ + bool _nodelay; /* input character wait flag */ + bool _immed; /* immediate update flag */ + bool _sync; /* synchronise window ancestors */ + bool _use_keypad; /* flags keypad key mode active */ + chtype **_y; /* pointer to line pointer array */ + int *_firstch; /* first changed character in line */ + int *_lastch; /* last changed character in line */ + int _tmarg; /* top of scrolling region */ + int _bmarg; /* bottom of scrolling region */ + int _delayms; /* milliseconds of delay for getch() */ + int _parx, _pary; /* coords relative to parent (0,0) */ + struct _win *_parent; /* subwin's pointer to parent win */ +} WINDOW; + +/* Avoid using the SCREEN struct directly -- use the corresponding + functions if possible. This struct may eventually be made private. */ + +typedef struct +{ + bool alive; /* if initscr() called, and not endwin() */ + bool autocr; /* if cr -> lf */ + bool cbreak; /* if terminal unbuffered */ + bool echo; /* if terminal echo */ + bool raw_inp; /* raw input mode (v. cooked input) */ + bool raw_out; /* raw output mode (7 v. 8 bits) */ + bool audible; /* FALSE if the bell is visual */ + bool mono; /* TRUE if current screen is mono */ + bool resized; /* TRUE if TERM has been resized */ + bool orig_attr; /* TRUE if we have the original colors */ + short orig_fore; /* original screen foreground color */ + short orig_back; /* original screen foreground color */ + int cursrow; /* position of physical cursor */ + int curscol; /* position of physical cursor */ + int visibility; /* visibility of cursor */ + int orig_cursor; /* original cursor size */ + int lines; /* new value for LINES */ + int cols; /* new value for COLS */ + unsigned long _trap_mbe; /* trap these mouse button events */ + unsigned long _map_mbe_to_key; /* map mouse buttons to slk */ + int mouse_wait; /* time to wait (in ms) for a + button release after a press, in + order to count it as a click */ + int slklines; /* lines in use by slk_init() */ + WINDOW *slk_winptr; /* window for slk */ + int linesrippedoff; /* lines ripped off via ripoffline() */ + int linesrippedoffontop; /* lines ripped off on + top via ripoffline() */ + int delaytenths; /* 1/10ths second to wait block + getch() for */ + bool _preserve; /* TRUE if screen background + to be preserved */ + int _restore; /* specifies if screen background + to be restored, and how */ + bool save_key_modifiers; /* TRUE if each key modifiers saved + with each key press */ + bool return_key_modifiers; /* TRUE if modifier keys are + returned as "real" keys */ + bool key_code; /* TRUE if last key is a special key; + used internally by get_wch() */ +#ifdef XCURSES + int XcurscrSize; /* size of Xcurscr shared memory block */ + bool sb_on; + int sb_viewport_y; + int sb_viewport_x; + int sb_total_y; + int sb_total_x; + int sb_cur_y; + int sb_cur_x; +#endif + short line_color; /* color of line attributes - default -1 */ +} SCREEN; + +/*---------------------------------------------------------------------- + * + * PDCurses External Variables + * + */ + +#ifdef PDC_DLL_BUILD +# ifdef CURSES_LIBRARY +# define PDCEX __declspec(dllexport) extern +# else +# define PDCEX __declspec(dllimport) +# endif +#else +# define PDCEX extern +#endif + +PDCEX int LINES; /* terminal height */ +PDCEX int COLS; /* terminal width */ +PDCEX WINDOW *stdscr; /* the default screen window */ +PDCEX WINDOW *curscr; /* the current screen image */ +PDCEX SCREEN *SP; /* curses variables */ +PDCEX MOUSE_STATUS Mouse_status; +PDCEX int COLORS; +PDCEX int COLOR_PAIRS; +PDCEX int TABSIZE; +PDCEX chtype acs_map[]; /* alternate character set map */ +PDCEX char ttytype[]; /* terminal name/description */ + +/*man-start************************************************************** + +PDCurses Text Attributes +======================== + +Originally, PDCurses used a short (16 bits) for its chtype. To include +color, a number of things had to be sacrificed from the strict Unix and +System V support. The main problem was fitting all character attributes +and color into an unsigned char (all 8 bits!). + +Today, PDCurses by default uses a long (32 bits) for its chtype, as in +System V. The short chtype is still available, by undefining CHTYPE_LONG +and rebuilding the library. + +The following is the structure of a win->_attrs chtype: + +short form: + +------------------------------------------------- +|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +------------------------------------------------- + color number | attrs | character eg 'a' + +The available non-color attributes are bold, reverse and blink. Others +have no effect. The high order char is an index into an array of +physical colors (defined in color.c) -- 32 foreground/background color +pairs (5 bits) plus 3 bits for other attributes. + +long form: + +---------------------------------------------------------------------------- +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|..| 3| 2| 1| 0| +---------------------------------------------------------------------------- + color number | modifiers | character eg 'a' + +The available non-color attributes are bold, underline, invisible, +right-line, left-line, protect, reverse and blink. 256 color pairs (8 +bits), 8 bits for other attributes, and 16 bits for character data. + +**man-end****************************************************************/ + +/*** Video attribute macros ***/ + +#define A_NORMAL (chtype)0 + +#ifdef CHTYPE_LONG +# define A_ALTCHARSET (chtype)0x00010000 +# define A_RIGHTLINE (chtype)0x00020000 +# define A_LEFTLINE (chtype)0x00040000 +# define A_INVIS (chtype)0x00080000 +# define A_UNDERLINE (chtype)0x00100000 +# define A_REVERSE (chtype)0x00200000 +# define A_BLINK (chtype)0x00400000 +# define A_BOLD (chtype)0x00800000 + +# define A_ATTRIBUTES (chtype)0xffff0000 +# define A_CHARTEXT (chtype)0x0000ffff +# define A_COLOR (chtype)0xff000000 + +# define A_ITALIC A_INVIS +# define A_PROTECT (A_UNDERLINE | A_LEFTLINE | A_RIGHTLINE) + +# define PDC_ATTR_SHIFT 19 +# define PDC_COLOR_SHIFT 24 +#else +# define A_BOLD (chtype)0x0100 /* X/Open */ +# define A_REVERSE (chtype)0x0200 /* X/Open */ +# define A_BLINK (chtype)0x0400 /* X/Open */ + +# define A_ATTRIBUTES (chtype)0xff00 /* X/Open */ +# define A_CHARTEXT (chtype)0x00ff /* X/Open */ +# define A_COLOR (chtype)0xf800 /* System V */ + +# define A_ALTCHARSET A_NORMAL /* X/Open */ +# define A_PROTECT A_NORMAL /* X/Open */ +# define A_UNDERLINE A_NORMAL /* X/Open */ + +# define A_LEFTLINE A_NORMAL +# define A_RIGHTLINE A_NORMAL +# define A_ITALIC A_NORMAL +# define A_INVIS A_NORMAL + +# define PDC_ATTR_SHIFT 8 +# define PDC_COLOR_SHIFT 11 +#endif + +#define A_STANDOUT (A_REVERSE | A_BOLD) /* X/Open */ +#define A_DIM A_NORMAL + +#define CHR_MSK A_CHARTEXT /* Obsolete */ +#define ATR_MSK A_ATTRIBUTES /* Obsolete */ +#define ATR_NRM A_NORMAL /* Obsolete */ + +/* For use with attr_t -- X/Open says, "these shall be distinct", so + this is a non-conforming implementation. */ + +#define WA_ALTCHARSET A_ALTCHARSET +#define WA_BLINK A_BLINK +#define WA_BOLD A_BOLD +#define WA_DIM A_DIM +#define WA_INVIS A_INVIS +#define WA_LEFT A_LEFTLINE +#define WA_PROTECT A_PROTECT +#define WA_REVERSE A_REVERSE +#define WA_RIGHT A_RIGHTLINE +#define WA_STANDOUT A_STANDOUT +#define WA_UNDERLINE A_UNDERLINE + +#define WA_HORIZONTAL A_NORMAL +#define WA_LOW A_NORMAL +#define WA_TOP A_NORMAL +#define WA_VERTICAL A_NORMAL + +/*** Alternate character set macros ***/ + +/* 'w' = 32-bit chtype; acs_map[] index | A_ALTCHARSET + 'n' = 16-bit chtype; it gets the fallback set because no bit is + available for A_ALTCHARSET */ + +#ifdef CHTYPE_LONG +# define ACS_PICK(w, n) ((chtype)w | A_ALTCHARSET) +#else +# define ACS_PICK(w, n) ((chtype)n) +#endif + +/* VT100-compatible symbols -- box chars */ + +#define ACS_ULCORNER ACS_PICK('l', '+') +#define ACS_LLCORNER ACS_PICK('m', '+') +#define ACS_URCORNER ACS_PICK('k', '+') +#define ACS_LRCORNER ACS_PICK('j', '+') +#define ACS_RTEE ACS_PICK('u', '+') +#define ACS_LTEE ACS_PICK('t', '+') +#define ACS_BTEE ACS_PICK('v', '+') +#define ACS_TTEE ACS_PICK('w', '+') +#define ACS_HLINE ACS_PICK('q', '-') +#define ACS_VLINE ACS_PICK('x', '|') +#define ACS_PLUS ACS_PICK('n', '+') + +/* VT100-compatible symbols -- other */ + +#define ACS_S1 ACS_PICK('o', '-') +#define ACS_S9 ACS_PICK('s', '_') +#define ACS_DIAMOND ACS_PICK('`', '+') +#define ACS_CKBOARD ACS_PICK('a', ':') +#define ACS_DEGREE ACS_PICK('f', '\'') +#define ACS_PLMINUS ACS_PICK('g', '#') +#define ACS_BULLET ACS_PICK('~', 'o') + +/* Teletype 5410v1 symbols -- these are defined in SysV curses, but + are not well-supported by most terminals. Stick to VT100 characters + for optimum portability. */ + +#define ACS_LARROW ACS_PICK(',', '<') +#define ACS_RARROW ACS_PICK('+', '>') +#define ACS_DARROW ACS_PICK('.', 'v') +#define ACS_UARROW ACS_PICK('-', '^') +#define ACS_BOARD ACS_PICK('h', '#') +#define ACS_LANTERN ACS_PICK('i', '*') +#define ACS_BLOCK ACS_PICK('0', '#') + +/* That goes double for these -- undocumented SysV symbols. Don't use + them. */ + +#define ACS_S3 ACS_PICK('p', '-') +#define ACS_S7 ACS_PICK('r', '-') +#define ACS_LEQUAL ACS_PICK('y', '<') +#define ACS_GEQUAL ACS_PICK('z', '>') +#define ACS_PI ACS_PICK('{', 'n') +#define ACS_NEQUAL ACS_PICK('|', '+') +#define ACS_STERLING ACS_PICK('}', 'L') + +/* Box char aliases */ + +#define ACS_BSSB ACS_ULCORNER +#define ACS_SSBB ACS_LLCORNER +#define ACS_BBSS ACS_URCORNER +#define ACS_SBBS ACS_LRCORNER +#define ACS_SBSS ACS_RTEE +#define ACS_SSSB ACS_LTEE +#define ACS_SSBS ACS_BTEE +#define ACS_BSSS ACS_TTEE +#define ACS_BSBS ACS_HLINE +#define ACS_SBSB ACS_VLINE +#define ACS_SSSS ACS_PLUS + +/* cchar_t aliases */ + +#ifdef PDC_WIDE +# define WACS_ULCORNER (&(acs_map['l'])) +# define WACS_LLCORNER (&(acs_map['m'])) +# define WACS_URCORNER (&(acs_map['k'])) +# define WACS_LRCORNER (&(acs_map['j'])) +# define WACS_RTEE (&(acs_map['u'])) +# define WACS_LTEE (&(acs_map['t'])) +# define WACS_BTEE (&(acs_map['v'])) +# define WACS_TTEE (&(acs_map['w'])) +# define WACS_HLINE (&(acs_map['q'])) +# define WACS_VLINE (&(acs_map['x'])) +# define WACS_PLUS (&(acs_map['n'])) + +# define WACS_S1 (&(acs_map['o'])) +# define WACS_S9 (&(acs_map['s'])) +# define WACS_DIAMOND (&(acs_map['`'])) +# define WACS_CKBOARD (&(acs_map['a'])) +# define WACS_DEGREE (&(acs_map['f'])) +# define WACS_PLMINUS (&(acs_map['g'])) +# define WACS_BULLET (&(acs_map['~'])) + +# define WACS_LARROW (&(acs_map[','])) +# define WACS_RARROW (&(acs_map['+'])) +# define WACS_DARROW (&(acs_map['.'])) +# define WACS_UARROW (&(acs_map['-'])) +# define WACS_BOARD (&(acs_map['h'])) +# define WACS_LANTERN (&(acs_map['i'])) +# define WACS_BLOCK (&(acs_map['0'])) + +# define WACS_S3 (&(acs_map['p'])) +# define WACS_S7 (&(acs_map['r'])) +# define WACS_LEQUAL (&(acs_map['y'])) +# define WACS_GEQUAL (&(acs_map['z'])) +# define WACS_PI (&(acs_map['{'])) +# define WACS_NEQUAL (&(acs_map['|'])) +# define WACS_STERLING (&(acs_map['}'])) + +# define WACS_BSSB WACS_ULCORNER +# define WACS_SSBB WACS_LLCORNER +# define WACS_BBSS WACS_URCORNER +# define WACS_SBBS WACS_LRCORNER +# define WACS_SBSS WACS_RTEE +# define WACS_SSSB WACS_LTEE +# define WACS_SSBS WACS_BTEE +# define WACS_BSSS WACS_TTEE +# define WACS_BSBS WACS_HLINE +# define WACS_SBSB WACS_VLINE +# define WACS_SSSS WACS_PLUS +#endif + +/*** Color macros ***/ + +#define COLOR_BLACK 0 + +#ifdef PDC_RGB /* RGB */ +# define COLOR_RED 1 +# define COLOR_GREEN 2 +# define COLOR_BLUE 4 +#else /* BGR */ +# define COLOR_BLUE 1 +# define COLOR_GREEN 2 +# define COLOR_RED 4 +#endif + +#define COLOR_CYAN (COLOR_BLUE | COLOR_GREEN) +#define COLOR_MAGENTA (COLOR_RED | COLOR_BLUE) +#define COLOR_YELLOW (COLOR_RED | COLOR_GREEN) + +#define COLOR_WHITE 7 + +/*---------------------------------------------------------------------- + * + * Function and Keypad Key Definitions. + * Many are just for compatibility. + * + */ + +#define KEY_CODE_YES 0x100 /* If get_wch() gives a key code */ + +#define KEY_BREAK 0x101 /* Not on PC KBD */ +#define KEY_DOWN 0x102 /* Down arrow key */ +#define KEY_UP 0x103 /* Up arrow key */ +#define KEY_LEFT 0x104 /* Left arrow key */ +#define KEY_RIGHT 0x105 /* Right arrow key */ +#define KEY_HOME 0x106 /* home key */ +#define KEY_BACKSPACE 0x107 /* not on pc */ +#define KEY_F0 0x108 /* function keys; 64 reserved */ + +#define KEY_DL 0x148 /* delete line */ +#define KEY_IL 0x149 /* insert line */ +#define KEY_DC 0x14a /* delete character */ +#define KEY_IC 0x14b /* insert char or enter ins mode */ +#define KEY_EIC 0x14c /* exit insert char mode */ +#define KEY_CLEAR 0x14d /* clear screen */ +#define KEY_EOS 0x14e /* clear to end of screen */ +#define KEY_EOL 0x14f /* clear to end of line */ +#define KEY_SF 0x150 /* scroll 1 line forward */ +#define KEY_SR 0x151 /* scroll 1 line back (reverse) */ +#define KEY_NPAGE 0x152 /* next page */ +#define KEY_PPAGE 0x153 /* previous page */ +#define KEY_STAB 0x154 /* set tab */ +#define KEY_CTAB 0x155 /* clear tab */ +#define KEY_CATAB 0x156 /* clear all tabs */ +#define KEY_ENTER 0x157 /* enter or send (unreliable) */ +#define KEY_SRESET 0x158 /* soft/reset (partial/unreliable) */ +#define KEY_RESET 0x159 /* reset/hard reset (unreliable) */ +#define KEY_PRINT 0x15a /* print/copy */ +#define KEY_LL 0x15b /* home down/bottom (lower left) */ +#define KEY_ABORT 0x15c /* abort/terminate key (any) */ +#define KEY_SHELP 0x15d /* short help */ +#define KEY_LHELP 0x15e /* long help */ +#define KEY_BTAB 0x15f /* Back tab key */ +#define KEY_BEG 0x160 /* beg(inning) key */ +#define KEY_CANCEL 0x161 /* cancel key */ +#define KEY_CLOSE 0x162 /* close key */ +#define KEY_COMMAND 0x163 /* cmd (command) key */ +#define KEY_COPY 0x164 /* copy key */ +#define KEY_CREATE 0x165 /* create key */ +#define KEY_END 0x166 /* end key */ +#define KEY_EXIT 0x167 /* exit key */ +#define KEY_FIND 0x168 /* find key */ +#define KEY_HELP 0x169 /* help key */ +#define KEY_MARK 0x16a /* mark key */ +#define KEY_MESSAGE 0x16b /* message key */ +#define KEY_MOVE 0x16c /* move key */ +#define KEY_NEXT 0x16d /* next object key */ +#define KEY_OPEN 0x16e /* open key */ +#define KEY_OPTIONS 0x16f /* options key */ +#define KEY_PREVIOUS 0x170 /* previous object key */ +#define KEY_REDO 0x171 /* redo key */ +#define KEY_REFERENCE 0x172 /* ref(erence) key */ +#define KEY_REFRESH 0x173 /* refresh key */ +#define KEY_REPLACE 0x174 /* replace key */ +#define KEY_RESTART 0x175 /* restart key */ +#define KEY_RESUME 0x176 /* resume key */ +#define KEY_SAVE 0x177 /* save key */ +#define KEY_SBEG 0x178 /* shifted beginning key */ +#define KEY_SCANCEL 0x179 /* shifted cancel key */ +#define KEY_SCOMMAND 0x17a /* shifted command key */ +#define KEY_SCOPY 0x17b /* shifted copy key */ +#define KEY_SCREATE 0x17c /* shifted create key */ +#define KEY_SDC 0x17d /* shifted delete char key */ +#define KEY_SDL 0x17e /* shifted delete line key */ +#define KEY_SELECT 0x17f /* select key */ +#define KEY_SEND 0x180 /* shifted end key */ +#define KEY_SEOL 0x181 /* shifted clear line key */ +#define KEY_SEXIT 0x182 /* shifted exit key */ +#define KEY_SFIND 0x183 /* shifted find key */ +#define KEY_SHOME 0x184 /* shifted home key */ +#define KEY_SIC 0x185 /* shifted input key */ + +#define KEY_SLEFT 0x187 /* shifted left arrow key */ +#define KEY_SMESSAGE 0x188 /* shifted message key */ +#define KEY_SMOVE 0x189 /* shifted move key */ +#define KEY_SNEXT 0x18a /* shifted next key */ +#define KEY_SOPTIONS 0x18b /* shifted options key */ +#define KEY_SPREVIOUS 0x18c /* shifted prev key */ +#define KEY_SPRINT 0x18d /* shifted print key */ +#define KEY_SREDO 0x18e /* shifted redo key */ +#define KEY_SREPLACE 0x18f /* shifted replace key */ +#define KEY_SRIGHT 0x190 /* shifted right arrow */ +#define KEY_SRSUME 0x191 /* shifted resume key */ +#define KEY_SSAVE 0x192 /* shifted save key */ +#define KEY_SSUSPEND 0x193 /* shifted suspend key */ +#define KEY_SUNDO 0x194 /* shifted undo key */ +#define KEY_SUSPEND 0x195 /* suspend key */ +#define KEY_UNDO 0x196 /* undo key */ + +/* PDCurses-specific key definitions -- PC only */ + +#define ALT_0 0x197 +#define ALT_1 0x198 +#define ALT_2 0x199 +#define ALT_3 0x19a +#define ALT_4 0x19b +#define ALT_5 0x19c +#define ALT_6 0x19d +#define ALT_7 0x19e +#define ALT_8 0x19f +#define ALT_9 0x1a0 +#define ALT_A 0x1a1 +#define ALT_B 0x1a2 +#define ALT_C 0x1a3 +#define ALT_D 0x1a4 +#define ALT_E 0x1a5 +#define ALT_F 0x1a6 +#define ALT_G 0x1a7 +#define ALT_H 0x1a8 +#define ALT_I 0x1a9 +#define ALT_J 0x1aa +#define ALT_K 0x1ab +#define ALT_L 0x1ac +#define ALT_M 0x1ad +#define ALT_N 0x1ae +#define ALT_O 0x1af +#define ALT_P 0x1b0 +#define ALT_Q 0x1b1 +#define ALT_R 0x1b2 +#define ALT_S 0x1b3 +#define ALT_T 0x1b4 +#define ALT_U 0x1b5 +#define ALT_V 0x1b6 +#define ALT_W 0x1b7 +#define ALT_X 0x1b8 +#define ALT_Y 0x1b9 +#define ALT_Z 0x1ba + +#define CTL_LEFT 0x1bb /* Control-Left-Arrow */ +#define CTL_RIGHT 0x1bc +#define CTL_PGUP 0x1bd +#define CTL_PGDN 0x1be +#define CTL_HOME 0x1bf +#define CTL_END 0x1c0 + +#define KEY_A1 0x1c1 /* upper left on Virtual keypad */ +#define KEY_A2 0x1c2 /* upper middle on Virt. keypad */ +#define KEY_A3 0x1c3 /* upper right on Vir. keypad */ +#define KEY_B1 0x1c4 /* middle left on Virt. keypad */ +#define KEY_B2 0x1c5 /* center on Virt. keypad */ +#define KEY_B3 0x1c6 /* middle right on Vir. keypad */ +#define KEY_C1 0x1c7 /* lower left on Virt. keypad */ +#define KEY_C2 0x1c8 /* lower middle on Virt. keypad */ +#define KEY_C3 0x1c9 /* lower right on Vir. keypad */ + +#define PADSLASH 0x1ca /* slash on keypad */ +#define PADENTER 0x1cb /* enter on keypad */ +#define CTL_PADENTER 0x1cc /* ctl-enter on keypad */ +#define ALT_PADENTER 0x1cd /* alt-enter on keypad */ +#define PADSTOP 0x1ce /* stop on keypad */ +#define PADSTAR 0x1cf /* star on keypad */ +#define PADMINUS 0x1d0 /* minus on keypad */ +#define PADPLUS 0x1d1 /* plus on keypad */ +#define CTL_PADSTOP 0x1d2 /* ctl-stop on keypad */ +#define CTL_PADCENTER 0x1d3 /* ctl-enter on keypad */ +#define CTL_PADPLUS 0x1d4 /* ctl-plus on keypad */ +#define CTL_PADMINUS 0x1d5 /* ctl-minus on keypad */ +#define CTL_PADSLASH 0x1d6 /* ctl-slash on keypad */ +#define CTL_PADSTAR 0x1d7 /* ctl-star on keypad */ +#define ALT_PADPLUS 0x1d8 /* alt-plus on keypad */ +#define ALT_PADMINUS 0x1d9 /* alt-minus on keypad */ +#define ALT_PADSLASH 0x1da /* alt-slash on keypad */ +#define ALT_PADSTAR 0x1db /* alt-star on keypad */ +#define ALT_PADSTOP 0x1dc /* alt-stop on keypad */ +#define CTL_INS 0x1dd /* ctl-insert */ +#define ALT_DEL 0x1de /* alt-delete */ +#define ALT_INS 0x1df /* alt-insert */ +#define CTL_UP 0x1e0 /* ctl-up arrow */ +#define CTL_DOWN 0x1e1 /* ctl-down arrow */ +#define CTL_TAB 0x1e2 /* ctl-tab */ +#define ALT_TAB 0x1e3 +#define ALT_MINUS 0x1e4 +#define ALT_EQUAL 0x1e5 +#define ALT_HOME 0x1e6 +#define ALT_PGUP 0x1e7 +#define ALT_PGDN 0x1e8 +#define ALT_END 0x1e9 +#define ALT_UP 0x1ea /* alt-up arrow */ +#define ALT_DOWN 0x1eb /* alt-down arrow */ +#define ALT_RIGHT 0x1ec /* alt-right arrow */ +#define ALT_LEFT 0x1ed /* alt-left arrow */ +#define ALT_ENTER 0x1ee /* alt-enter */ +#define ALT_ESC 0x1ef /* alt-escape */ +#define ALT_BQUOTE 0x1f0 /* alt-back quote */ +#define ALT_LBRACKET 0x1f1 /* alt-left bracket */ +#define ALT_RBRACKET 0x1f2 /* alt-right bracket */ +#define ALT_SEMICOLON 0x1f3 /* alt-semi-colon */ +#define ALT_FQUOTE 0x1f4 /* alt-forward quote */ +#define ALT_COMMA 0x1f5 /* alt-comma */ +#define ALT_STOP 0x1f6 /* alt-stop */ +#define ALT_FSLASH 0x1f7 /* alt-forward slash */ +#define ALT_BKSP 0x1f8 /* alt-backspace */ +#define CTL_BKSP 0x1f9 /* ctl-backspace */ +#define PAD0 0x1fa /* keypad 0 */ + +#define CTL_PAD0 0x1fb /* ctl-keypad 0 */ +#define CTL_PAD1 0x1fc +#define CTL_PAD2 0x1fd +#define CTL_PAD3 0x1fe +#define CTL_PAD4 0x1ff +#define CTL_PAD5 0x200 +#define CTL_PAD6 0x201 +#define CTL_PAD7 0x202 +#define CTL_PAD8 0x203 +#define CTL_PAD9 0x204 + +#define ALT_PAD0 0x205 /* alt-keypad 0 */ +#define ALT_PAD1 0x206 +#define ALT_PAD2 0x207 +#define ALT_PAD3 0x208 +#define ALT_PAD4 0x209 +#define ALT_PAD5 0x20a +#define ALT_PAD6 0x20b +#define ALT_PAD7 0x20c +#define ALT_PAD8 0x20d +#define ALT_PAD9 0x20e + +#define CTL_DEL 0x20f /* clt-delete */ +#define ALT_BSLASH 0x210 /* alt-back slash */ +#define CTL_ENTER 0x211 /* ctl-enter */ + +#define SHF_PADENTER 0x212 /* shift-enter on keypad */ +#define SHF_PADSLASH 0x213 /* shift-slash on keypad */ +#define SHF_PADSTAR 0x214 /* shift-star on keypad */ +#define SHF_PADPLUS 0x215 /* shift-plus on keypad */ +#define SHF_PADMINUS 0x216 /* shift-minus on keypad */ +#define SHF_UP 0x217 /* shift-up on keypad */ +#define SHF_DOWN 0x218 /* shift-down on keypad */ +#define SHF_IC 0x219 /* shift-insert on keypad */ +#define SHF_DC 0x21a /* shift-delete on keypad */ + +#define KEY_MOUSE 0x21b /* "mouse" key */ +#define KEY_SHIFT_L 0x21c /* Left-shift */ +#define KEY_SHIFT_R 0x21d /* Right-shift */ +#define KEY_CONTROL_L 0x21e /* Left-control */ +#define KEY_CONTROL_R 0x21f /* Right-control */ +#define KEY_ALT_L 0x220 /* Left-alt */ +#define KEY_ALT_R 0x221 /* Right-alt */ +#define KEY_RESIZE 0x222 /* Window resize */ +#define KEY_SUP 0x223 /* Shifted up arrow */ +#define KEY_SDOWN 0x224 /* Shifted down arrow */ + +#define KEY_MIN KEY_BREAK /* Minimum curses key value */ +#define KEY_MAX KEY_SDOWN /* Maximum curses key */ + +#define KEY_F(n) (KEY_F0 + (n)) + +/*---------------------------------------------------------------------- + * + * PDCurses Function Declarations + * + */ + +/* Standard */ + +int addch(const chtype); +int addchnstr(const chtype *, int); +int addchstr(const chtype *); +int addnstr(const char *, int); +int addstr(const char *); +int attroff(chtype); +int attron(chtype); +int attrset(chtype); +int attr_get(attr_t *, short *, void *); +int attr_off(attr_t, void *); +int attr_on(attr_t, void *); +int attr_set(attr_t, short, void *); +int baudrate(void); +int beep(void); +int bkgd(chtype); +void bkgdset(chtype); +int border(chtype, chtype, chtype, chtype, chtype, chtype, chtype, chtype); +int box(WINDOW *, chtype, chtype); +bool can_change_color(void); +int cbreak(void); +int chgat(int, attr_t, short, const void *); +int clearok(WINDOW *, bool); +int clear(void); +int clrtobot(void); +int clrtoeol(void); +int color_content(short, short *, short *, short *); +int color_set(short, void *); +int copywin(const WINDOW *, WINDOW *, int, int, int, int, int, int, int); +int curs_set(int); +int def_prog_mode(void); +int def_shell_mode(void); +int delay_output(int); +int delch(void); +int deleteln(void); +void delscreen(SCREEN *); +int delwin(WINDOW *); +WINDOW *derwin(WINDOW *, int, int, int, int); +int doupdate(void); +WINDOW *dupwin(WINDOW *); +int echochar(const chtype); +int echo(void); +int endwin(void); +char erasechar(void); +int erase(void); +void filter(void); +int flash(void); +int flushinp(void); +chtype getbkgd(WINDOW *); +int getnstr(char *, int); +int getstr(char *); +WINDOW *getwin(FILE *); +int halfdelay(int); +bool has_colors(void); +bool has_ic(void); +bool has_il(void); +int hline(chtype, int); +void idcok(WINDOW *, bool); +int idlok(WINDOW *, bool); +void immedok(WINDOW *, bool); +int inchnstr(chtype *, int); +int inchstr(chtype *); +chtype inch(void); +int init_color(short, short, short, short); +int init_pair(short, short, short); +WINDOW *initscr(void); +int innstr(char *, int); +int insch(chtype); +int insdelln(int); +int insertln(void); +int insnstr(const char *, int); +int insstr(const char *); +int instr(char *); +int intrflush(WINDOW *, bool); +bool isendwin(void); +bool is_linetouched(WINDOW *, int); +bool is_wintouched(WINDOW *); +char *keyname(int); +int keypad(WINDOW *, bool); +char killchar(void); +int leaveok(WINDOW *, bool); +char *longname(void); +int meta(WINDOW *, bool); +int move(int, int); +int mvaddch(int, int, const chtype); +int mvaddchnstr(int, int, const chtype *, int); +int mvaddchstr(int, int, const chtype *); +int mvaddnstr(int, int, const char *, int); +int mvaddstr(int, int, const char *); +int mvchgat(int, int, int, attr_t, short, const void *); +int mvcur(int, int, int, int); +int mvdelch(int, int); +int mvderwin(WINDOW *, int, int); +int mvgetch(int, int); +int mvgetnstr(int, int, char *, int); +int mvgetstr(int, int, char *); +int mvhline(int, int, chtype, int); +chtype mvinch(int, int); +int mvinchnstr(int, int, chtype *, int); +int mvinchstr(int, int, chtype *); +int mvinnstr(int, int, char *, int); +int mvinsch(int, int, chtype); +int mvinsnstr(int, int, const char *, int); +int mvinsstr(int, int, const char *); +int mvinstr(int, int, char *); +int mvprintw(int, int, const char *, ...); +int mvscanw(int, int, const char *, ...); +int mvvline(int, int, chtype, int); +int mvwaddchnstr(WINDOW *, int, int, const chtype *, int); +int mvwaddchstr(WINDOW *, int, int, const chtype *); +int mvwaddch(WINDOW *, int, int, const chtype); +int mvwaddnstr(WINDOW *, int, int, const char *, int); +int mvwaddstr(WINDOW *, int, int, const char *); +int mvwchgat(WINDOW *, int, int, int, attr_t, short, const void *); +int mvwdelch(WINDOW *, int, int); +int mvwgetch(WINDOW *, int, int); +int mvwgetnstr(WINDOW *, int, int, char *, int); +int mvwgetstr(WINDOW *, int, int, char *); +int mvwhline(WINDOW *, int, int, chtype, int); +int mvwinchnstr(WINDOW *, int, int, chtype *, int); +int mvwinchstr(WINDOW *, int, int, chtype *); +chtype mvwinch(WINDOW *, int, int); +int mvwinnstr(WINDOW *, int, int, char *, int); +int mvwinsch(WINDOW *, int, int, chtype); +int mvwinsnstr(WINDOW *, int, int, const char *, int); +int mvwinsstr(WINDOW *, int, int, const char *); +int mvwinstr(WINDOW *, int, int, char *); +int mvwin(WINDOW *, int, int); +int mvwprintw(WINDOW *, int, int, const char *, ...); +int mvwscanw(WINDOW *, int, int, const char *, ...); +int mvwvline(WINDOW *, int, int, chtype, int); +int napms(int); +WINDOW *newpad(int, int); +SCREEN *newterm(const char *, FILE *, FILE *); +WINDOW *newwin(int, int, int, int); +int nl(void); +int nocbreak(void); +int nodelay(WINDOW *, bool); +int noecho(void); +int nonl(void); +void noqiflush(void); +int noraw(void); +int notimeout(WINDOW *, bool); +int overlay(const WINDOW *, WINDOW *); +int overwrite(const WINDOW *, WINDOW *); +int pair_content(short, short *, short *); +int pechochar(WINDOW *, chtype); +int pnoutrefresh(WINDOW *, int, int, int, int, int, int); +int prefresh(WINDOW *, int, int, int, int, int, int); +int printw(const char *, ...); +int putwin(WINDOW *, FILE *); +void qiflush(void); +int raw(void); +int redrawwin(WINDOW *); +int refresh(void); +int reset_prog_mode(void); +int reset_shell_mode(void); +int resetty(void); +int ripoffline(int, int (*)(WINDOW *, int)); +int savetty(void); +int scanw(const char *, ...); +int scr_dump(const char *); +int scr_init(const char *); +int scr_restore(const char *); +int scr_set(const char *); +int scrl(int); +int scroll(WINDOW *); +int scrollok(WINDOW *, bool); +SCREEN *set_term(SCREEN *); +int setscrreg(int, int); +int slk_attroff(const chtype); +int slk_attr_off(const attr_t, void *); +int slk_attron(const chtype); +int slk_attr_on(const attr_t, void *); +int slk_attrset(const chtype); +int slk_attr_set(const attr_t, short, void *); +int slk_clear(void); +int slk_color(short); +int slk_init(int); +char *slk_label(int); +int slk_noutrefresh(void); +int slk_refresh(void); +int slk_restore(void); +int slk_set(int, const char *, int); +int slk_touch(void); +int standend(void); +int standout(void); +int start_color(void); +WINDOW *subpad(WINDOW *, int, int, int, int); +WINDOW *subwin(WINDOW *, int, int, int, int); +int syncok(WINDOW *, bool); +chtype termattrs(void); +attr_t term_attrs(void); +char *termname(void); +void timeout(int); +int touchline(WINDOW *, int, int); +int touchwin(WINDOW *); +int typeahead(int); +int untouchwin(WINDOW *); +void use_env(bool); +int vidattr(chtype); +int vid_attr(attr_t, short, void *); +int vidputs(chtype, int (*)(int)); +int vid_puts(attr_t, short, void *, int (*)(int)); +int vline(chtype, int); +int vw_printw(WINDOW *, const char *, va_list); +int vwprintw(WINDOW *, const char *, va_list); +int vw_scanw(WINDOW *, const char *, va_list); +int vwscanw(WINDOW *, const char *, va_list); +int waddchnstr(WINDOW *, const chtype *, int); +int waddchstr(WINDOW *, const chtype *); +int waddch(WINDOW *, const chtype); +int waddnstr(WINDOW *, const char *, int); +int waddstr(WINDOW *, const char *); +int wattroff(WINDOW *, chtype); +int wattron(WINDOW *, chtype); +int wattrset(WINDOW *, chtype); +int wattr_get(WINDOW *, attr_t *, short *, void *); +int wattr_off(WINDOW *, attr_t, void *); +int wattr_on(WINDOW *, attr_t, void *); +int wattr_set(WINDOW *, attr_t, short, void *); +void wbkgdset(WINDOW *, chtype); +int wbkgd(WINDOW *, chtype); +int wborder(WINDOW *, chtype, chtype, chtype, chtype, + chtype, chtype, chtype, chtype); +int wchgat(WINDOW *, int, attr_t, short, const void *); +int wclear(WINDOW *); +int wclrtobot(WINDOW *); +int wclrtoeol(WINDOW *); +int wcolor_set(WINDOW *, short, void *); +void wcursyncup(WINDOW *); +int wdelch(WINDOW *); +int wdeleteln(WINDOW *); +int wechochar(WINDOW *, const chtype); +int werase(WINDOW *); +int wgetch(WINDOW *); +int wgetnstr(WINDOW *, char *, int); +int wgetstr(WINDOW *, char *); +int whline(WINDOW *, chtype, int); +int winchnstr(WINDOW *, chtype *, int); +int winchstr(WINDOW *, chtype *); +chtype winch(WINDOW *); +int winnstr(WINDOW *, char *, int); +int winsch(WINDOW *, chtype); +int winsdelln(WINDOW *, int); +int winsertln(WINDOW *); +int winsnstr(WINDOW *, const char *, int); +int winsstr(WINDOW *, const char *); +int winstr(WINDOW *, char *); +int wmove(WINDOW *, int, int); +int wnoutrefresh(WINDOW *); +int wprintw(WINDOW *, const char *, ...); +int wredrawln(WINDOW *, int, int); +int wrefresh(WINDOW *); +int wscanw(WINDOW *, const char *, ...); +int wscrl(WINDOW *, int); +int wsetscrreg(WINDOW *, int, int); +int wstandend(WINDOW *); +int wstandout(WINDOW *); +void wsyncdown(WINDOW *); +void wsyncup(WINDOW *); +void wtimeout(WINDOW *, int); +int wtouchln(WINDOW *, int, int, int); +int wvline(WINDOW *, chtype, int); + +/* Wide-character functions */ + +#ifdef PDC_WIDE +int addnwstr(const wchar_t *, int); +int addwstr(const wchar_t *); +int add_wch(const cchar_t *); +int add_wchnstr(const cchar_t *, int); +int add_wchstr(const cchar_t *); +int border_set(const cchar_t *, const cchar_t *, const cchar_t *, + const cchar_t *, const cchar_t *, const cchar_t *, + const cchar_t *, const cchar_t *); +int box_set(WINDOW *, const cchar_t *, const cchar_t *); +int echo_wchar(const cchar_t *); +int erasewchar(wchar_t *); +int getbkgrnd(cchar_t *); +int getcchar(const cchar_t *, wchar_t *, attr_t *, short *, void *); +int getn_wstr(wint_t *, int); +int get_wch(wint_t *); +int get_wstr(wint_t *); +int hline_set(const cchar_t *, int); +int innwstr(wchar_t *, int); +int ins_nwstr(const wchar_t *, int); +int ins_wch(const cchar_t *); +int ins_wstr(const wchar_t *); +int inwstr(wchar_t *); +int in_wch(cchar_t *); +int in_wchnstr(cchar_t *, int); +int in_wchstr(cchar_t *); +char *key_name(wchar_t); +int killwchar(wchar_t *); +int mvaddnwstr(int, int, const wchar_t *, int); +int mvaddwstr(int, int, const wchar_t *); +int mvadd_wch(int, int, const cchar_t *); +int mvadd_wchnstr(int, int, const cchar_t *, int); +int mvadd_wchstr(int, int, const cchar_t *); +int mvgetn_wstr(int, int, wint_t *, int); +int mvget_wch(int, int, wint_t *); +int mvget_wstr(int, int, wint_t *); +int mvhline_set(int, int, const cchar_t *, int); +int mvinnwstr(int, int, wchar_t *, int); +int mvins_nwstr(int, int, const wchar_t *, int); +int mvins_wch(int, int, const cchar_t *); +int mvins_wstr(int, int, const wchar_t *); +int mvinwstr(int, int, wchar_t *); +int mvin_wch(int, int, cchar_t *); +int mvin_wchnstr(int, int, cchar_t *, int); +int mvin_wchstr(int, int, cchar_t *); +int mvvline_set(int, int, const cchar_t *, int); +int mvwaddnwstr(WINDOW *, int, int, const wchar_t *, int); +int mvwaddwstr(WINDOW *, int, int, const wchar_t *); +int mvwadd_wch(WINDOW *, int, int, const cchar_t *); +int mvwadd_wchnstr(WINDOW *, int, int, const cchar_t *, int); +int mvwadd_wchstr(WINDOW *, int, int, const cchar_t *); +int mvwgetn_wstr(WINDOW *, int, int, wint_t *, int); +int mvwget_wch(WINDOW *, int, int, wint_t *); +int mvwget_wstr(WINDOW *, int, int, wint_t *); +int mvwhline_set(WINDOW *, int, int, const cchar_t *, int); +int mvwinnwstr(WINDOW *, int, int, wchar_t *, int); +int mvwins_nwstr(WINDOW *, int, int, const wchar_t *, int); +int mvwins_wch(WINDOW *, int, int, const cchar_t *); +int mvwins_wstr(WINDOW *, int, int, const wchar_t *); +int mvwin_wch(WINDOW *, int, int, cchar_t *); +int mvwin_wchnstr(WINDOW *, int, int, cchar_t *, int); +int mvwin_wchstr(WINDOW *, int, int, cchar_t *); +int mvwinwstr(WINDOW *, int, int, wchar_t *); +int mvwvline_set(WINDOW *, int, int, const cchar_t *, int); +int pecho_wchar(WINDOW *, const cchar_t*); +int setcchar(cchar_t*, const wchar_t*, const attr_t, short, const void*); +int slk_wset(int, const wchar_t *, int); +int unget_wch(const wchar_t); +int vline_set(const cchar_t *, int); +int waddnwstr(WINDOW *, const wchar_t *, int); +int waddwstr(WINDOW *, const wchar_t *); +int wadd_wch(WINDOW *, const cchar_t *); +int wadd_wchnstr(WINDOW *, const cchar_t *, int); +int wadd_wchstr(WINDOW *, const cchar_t *); +int wbkgrnd(WINDOW *, const cchar_t *); +void wbkgrndset(WINDOW *, const cchar_t *); +int wborder_set(WINDOW *, const cchar_t *, const cchar_t *, + const cchar_t *, const cchar_t *, const cchar_t *, + const cchar_t *, const cchar_t *, const cchar_t *); +int wecho_wchar(WINDOW *, const cchar_t *); +int wgetbkgrnd(WINDOW *, cchar_t *); +int wgetn_wstr(WINDOW *, wint_t *, int); +int wget_wch(WINDOW *, wint_t *); +int wget_wstr(WINDOW *, wint_t *); +int whline_set(WINDOW *, const cchar_t *, int); +int winnwstr(WINDOW *, wchar_t *, int); +int wins_nwstr(WINDOW *, const wchar_t *, int); +int wins_wch(WINDOW *, const cchar_t *); +int wins_wstr(WINDOW *, const wchar_t *); +int winwstr(WINDOW *, wchar_t *); +int win_wch(WINDOW *, cchar_t *); +int win_wchnstr(WINDOW *, cchar_t *, int); +int win_wchstr(WINDOW *, cchar_t *); +wchar_t *wunctrl(cchar_t *); +int wvline_set(WINDOW *, const cchar_t *, int); +#endif + +/* Quasi-standard */ + +chtype getattrs(WINDOW *); +int getbegx(WINDOW *); +int getbegy(WINDOW *); +int getmaxx(WINDOW *); +int getmaxy(WINDOW *); +int getparx(WINDOW *); +int getpary(WINDOW *); +int getcurx(WINDOW *); +int getcury(WINDOW *); +void traceoff(void); +void traceon(void); +char *unctrl(chtype); + +int crmode(void); +int nocrmode(void); +int draino(int); +int resetterm(void); +int fixterm(void); +int saveterm(void); +int setsyx(int, int); + +int mouse_set(unsigned long); +int mouse_on(unsigned long); +int mouse_off(unsigned long); +int request_mouse_pos(void); +int map_button(unsigned long); +void wmouse_position(WINDOW *, int *, int *); +unsigned long getmouse(void); +unsigned long getbmap(void); + +/* ncurses */ + +int assume_default_colors(int, int); +const char *curses_version(void); +bool has_key(int); +int use_default_colors(void); +int wresize(WINDOW *, int, int); + +int mouseinterval(int); +mmask_t mousemask(mmask_t, mmask_t *); +bool mouse_trafo(int *, int *, bool); +int nc_getmouse(MEVENT *); +int ungetmouse(MEVENT *); +bool wenclose(const WINDOW *, int, int); +bool wmouse_trafo(const WINDOW *, int *, int *, bool); + +/* PDCurses */ + +int addrawch(chtype); +int insrawch(chtype); +bool is_termresized(void); +int mvaddrawch(int, int, chtype); +int mvdeleteln(int, int); +int mvinsertln(int, int); +int mvinsrawch(int, int, chtype); +int mvwaddrawch(WINDOW *, int, int, chtype); +int mvwdeleteln(WINDOW *, int, int); +int mvwinsertln(WINDOW *, int, int); +int mvwinsrawch(WINDOW *, int, int, chtype); +int raw_output(bool); +int resize_term(int, int); +WINDOW *resize_window(WINDOW *, int, int); +int waddrawch(WINDOW *, chtype); +int winsrawch(WINDOW *, chtype); +char wordchar(void); + +#ifdef PDC_WIDE +wchar_t *slk_wlabel(int); +#endif + +void PDC_debug(const char *, ...); +int PDC_ungetch(int); +int PDC_set_blink(bool); +int PDC_set_line_color(short); +void PDC_set_title(const char *); + +int PDC_clearclipboard(void); +int PDC_freeclipboard(char *); +int PDC_getclipboard(char **, long *); +int PDC_setclipboard(const char *, long); + +unsigned long PDC_get_input_fd(void); +unsigned long PDC_get_key_modifiers(void); +int PDC_return_key_modifiers(bool); +int PDC_save_key_modifiers(bool); + +#ifdef XCURSES +WINDOW *Xinitscr(int, char **); +void XCursesExit(void); +int sb_init(void); +int sb_set_horz(int, int, int); +int sb_set_vert(int, int, int); +int sb_get_horz(int *, int *, int *); +int sb_get_vert(int *, int *, int *); +int sb_refresh(void); +#endif + +/*** Functions defined as macros ***/ + +/* getch() and ungetch() conflict with some DOS libraries */ + +#define getch() wgetch(stdscr) +#define ungetch(ch) PDC_ungetch(ch) + +#define COLOR_PAIR(n) (((chtype)(n) << PDC_COLOR_SHIFT) & A_COLOR) +#define PAIR_NUMBER(n) (((n) & A_COLOR) >> PDC_COLOR_SHIFT) + +/* These will _only_ work as macros */ + +#define getbegyx(w, y, x) (y = getbegy(w), x = getbegx(w)) +#define getmaxyx(w, y, x) (y = getmaxy(w), x = getmaxx(w)) +#define getparyx(w, y, x) (y = getpary(w), x = getparx(w)) +#define getyx(w, y, x) (y = getcury(w), x = getcurx(w)) + +#define getsyx(y, x) { if (curscr->_leaveit) (y)=(x)=-1; \ + else getyx(curscr,(y),(x)); } + +#ifdef NCURSES_MOUSE_VERSION +# define getmouse(x) nc_getmouse(x) +#endif + +/* return codes from PDC_getclipboard() and PDC_setclipboard() calls */ + +#define PDC_CLIP_SUCCESS 0 +#define PDC_CLIP_ACCESS_ERROR 1 +#define PDC_CLIP_EMPTY 2 +#define PDC_CLIP_MEMORY_ERROR 3 + +/* PDCurses key modifier masks */ + +#define PDC_KEY_MODIFIER_SHIFT 1 +#define PDC_KEY_MODIFIER_CONTROL 2 +#define PDC_KEY_MODIFIER_ALT 4 +#define PDC_KEY_MODIFIER_NUMLOCK 8 + +#if defined(__cplusplus) || defined(__cplusplus__) || defined(__CPLUSPLUS) +# undef bool +} +#endif + +#endif /* __PDCURSES__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/win32/zconf.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,332 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define deflateBound z_deflateBound +# define deflatePrime z_deflatePrime +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateCopy z_inflateCopy +# define inflateReset z_inflateReset +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table +# define zError z_zError + +# define alloc_func z_alloc_func +# define free_func z_free_func +# define in_func z_in_func +# define out_func z_out_func +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include <windows.h> + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ +# include <sys/types.h> /* for off_t */ +# include <unistd.h> /* for SEEK_* and off_t */ +# ifdef VMS +# include <unixio.h> /* for off_t */ +# endif +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +# ifdef FAR +# undef FAR +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(deflateBound,"DEBND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(compressBound,"CMBND") +# pragma map(inflate_table,"INTABL") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pyPRADA_1.2/tools/samtools-0.1.16/win32/zlib.h Thu Feb 20 00:44:58 2014 -0500 @@ -0,0 +1,1357 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.3, July 18th, 2005 + + Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.3" +#define ZLIB_VERNUM 0x1230 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumualte before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + the value returned by deflateBound (see below). If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, + Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() stop + if and when it gets to the next deflate block boundary. When decoding the + zlib or gzip format, this will cause inflate() to return immediately after + the header and before the first block. When doing a raw inflate, inflate() + will go ahead and process the first block, and will return when it gets to + the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 + if inflate() is currently decoding the last block in the deflate stream, + plus 128 if inflate() returned immediately after decoding an end-of-block + code or decoding the complete header up to just before the first byte of the + deflate stream. The end-of-block will not be indicated until all of the + uncompressed data from that block has been written to strm->next_out. The + number of unused bits may in general be greater than seven, except when + bit 7 of data_type is set, in which case the number of unused bits will be + less than eight. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster approach + may be used for the single inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() will decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically. Any information + contained in the gzip header is not retained, so applications that need that + information should instead use raw inflate, see inflateInit2() below, or + inflateBack() and perform their own processing of the gzip header and + trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may then + call inflateSync() to look for a good compression block if a partial recovery + of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), + no header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as + Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy + parameter only affects the compression ratio but not the correctness of the + compressed output even if it is not set appropriately. Z_FIXED prevents the + use of dynamic Huffman codes, allowing for a simpler decoder for special + applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. In addition, the + current implementation of deflate will use at most the window size minus + 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() + or deflateInit2(). This would be used to allocate an output buffer + for deflation in a single pass, and so would be called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the + bits leftover from a previous deflate stream when appending to it. As such, + this function can only be used for raw deflate, and must be used before the + first deflate() call after a deflateInit2() or deflateReset(). bits must be + less than or equal to 16, and that many of the least significant bits of + value will be inserted in the output. + + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is + a crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg + is set to null if there is no error message. inflateInit2 does not perform + any decompression apart from reading the zlib header if present: this will + be done by inflate(). (So next_in and avail_in may be modified, but next_out + and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called + immediately after inflateInit2() or inflateReset() and before any call of + inflate() to set the dictionary. The application must insure that the + dictionary that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK can be used to + force inflate() to return immediately after header processing is complete + and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When + any of extra, name, or comment are not Z_NULL and the respective field is + not present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the paramaters are invalid, Z_MEM_ERROR if the internal state could not + be allocated, or Z_VERSION_ERROR if the version of the library does not + match the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free + the allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects + only the raw deflate stream to decompress. This is different from the + normal behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format + error in the deflate stream (in which case strm->msg is set to indicate the + nature of the error), or Z_STREAM_ERROR if the stream was not properly + initialized. In the case of Z_BUF_ERROR, an input or output error can be + distinguished using strm->next_in which will be Z_NULL only if in() returned + an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to + out() returning non-zero. (in() will always be called before out(), so + strm->next_in is assured to be defined if out() returns non-zero.) Note + that inflateBack() cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least the value returned + by compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before + a compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + +typedef voidp gzFile; + +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h", or 'R' for run-length encoding + as in "wb1R". (See the description of deflateInit2 for more information + about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). The number of + uncompressed bytes written is limited to 4095. The caller should assure that + this limit is not exceeded. If it is exceeded, then gzprintf() will return + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf() + because the secure snprintf() or vsnprintf() functions were not available. +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read again later. + Only one character of push-back is allowed. gzungetc() returns the + character pushed, or -1 on failure. gzungetc() will fail if a + character has been pushed but not read yet, or if c is -1. The pushed + character will be discarded if the stream is repositioned with gzseek() + or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns 1 if file is being read directly without decompression, otherwise + zero. +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); +/* + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is NULL, this function returns the required initial + value for the for the crc. Pre- and post-conditioning (one's complement) is + performed within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + +/* + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */