comparison pyPRADA_1.2/tools/samtools-0.1.16/bam_cat.c @ 0:acc2ca1a3ba4

Uploaded
author siyuan
date Thu, 20 Feb 2014 00:44:58 -0500
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:acc2ca1a3ba4
1 /*
2
3 bam_cat -- efficiently concatenates bam files
4
5 bam_cat can be used to concatenate BAM files. Under special
6 circumstances, it can be used as an alternative to 'samtools merge' to
7 concatenate multiple sorted files into a single sorted file. For this
8 to work each file must be sorted, and the sorted files must be given
9 as command line arguments in order such that the final read in file i
10 is less than or equal to the first read in file i+1.
11
12 This code is derived from the bam_reheader function in samtools 0.1.8
13 and modified to perform concatenation by Chris Saunders on behalf of
14 Illumina.
15
16
17 ########## License:
18
19 The MIT License
20
21 Original SAMtools work copyright (c) 2008-2009 Genome Research Ltd.
22 Modified SAMtools work copyright (c) 2010 Illumina, Inc.
23
24 Permission is hereby granted, free of charge, to any person obtaining a copy
25 of this software and associated documentation files (the "Software"), to deal
26 in the Software without restriction, including without limitation the rights
27 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
28 copies of the Software, and to permit persons to whom the Software is
29 furnished to do so, subject to the following conditions:
30
31 The above copyright notice and this permission notice shall be included in
32 all copies or substantial portions of the Software.
33
34 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
37 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
38 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
39 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
40 THE SOFTWARE.
41
42 */
43
44
45 /*
46 makefile:
47 """
48 CC=gcc
49 CFLAGS+=-g -Wall -O2 -D_FILE_OFFSET_BITS=64 -D_USE_KNETFILE -I$(SAMTOOLS_DIR)
50 LDFLAGS+=-L$(SAMTOOLS_DIR)
51 LDLIBS+=-lbam -lz
52
53 all:bam_cat
54 """
55 */
56
57
58 #include <stdio.h>
59 #include <stdlib.h>
60 #include <unistd.h>
61
62 #include "bgzf.h"
63 #include "bam.h"
64
65 #define BUF_SIZE 0x10000
66
67 #define GZIPID1 31
68 #define GZIPID2 139
69
70 #define BGZF_EMPTY_BLOCK_SIZE 28
71
72
73 int bam_cat(int nfn, char * const *fn, const bam_header_t *h, const char* outbam)
74 {
75 BGZF *fp;
76 FILE* fp_file;
77 uint8_t *buf;
78 uint8_t ebuf[BGZF_EMPTY_BLOCK_SIZE];
79 const int es=BGZF_EMPTY_BLOCK_SIZE;
80 int i;
81
82 fp = strcmp(outbam, "-")? bgzf_open(outbam, "w") : bgzf_fdopen(fileno(stdout), "w");
83 if (fp == 0) {
84 fprintf(stderr, "[%s] ERROR: fail to open output file '%s'.\n", __func__, outbam);
85 return 1;
86 }
87 if (h) bam_header_write(fp, h);
88
89 buf = (uint8_t*) malloc(BUF_SIZE);
90 for(i = 0; i < nfn; ++i){
91 BGZF *in;
92 bam_header_t *old;
93 int len,j;
94
95 in = strcmp(fn[i], "-")? bam_open(fn[i], "r") : bam_dopen(fileno(stdin), "r");
96 if (in == 0) {
97 fprintf(stderr, "[%s] ERROR: fail to open file '%s'.\n", __func__, fn[i]);
98 return -1;
99 }
100 if (in->open_mode != 'r') return -1;
101
102 old = bam_header_read(in);
103 if (h == 0 && i == 0) bam_header_write(fp, old);
104
105 if (in->block_offset < in->block_length) {
106 bgzf_write(fp, in->uncompressed_block + in->block_offset, in->block_length - in->block_offset);
107 bgzf_flush(fp);
108 }
109
110 j=0;
111 #ifdef _USE_KNETFILE
112 fp_file=fp->x.fpw;
113 while ((len = knet_read(in->x.fpr, buf, BUF_SIZE)) > 0) {
114 #else
115 fp_file=fp->file;
116 while (!feof(in->file) && (len = fread(buf, 1, BUF_SIZE, in->file)) > 0) {
117 #endif
118 if(len<es){
119 int diff=es-len;
120 if(j==0) {
121 fprintf(stderr, "[%s] ERROR: truncated file?: '%s'.\n", __func__, fn[i]);
122 return -1;
123 }
124 fwrite(ebuf, 1, len, fp_file);
125 memcpy(ebuf,ebuf+len,diff);
126 memcpy(ebuf+diff,buf,len);
127 } else {
128 if(j!=0) fwrite(ebuf, 1, es, fp_file);
129 len-= es;
130 memcpy(ebuf,buf+len,es);
131 fwrite(buf, 1, len, fp_file);
132 }
133 j=1;
134 }
135
136 /* check final gzip block */
137 {
138 const uint8_t gzip1=ebuf[0];
139 const uint8_t gzip2=ebuf[1];
140 const uint32_t isize=*((uint32_t*)(ebuf+es-4));
141 if(((gzip1!=GZIPID1) || (gzip2!=GZIPID2)) || (isize!=0)) {
142 fprintf(stderr, "[%s] WARNING: Unexpected block structure in file '%s'.", __func__, fn[i]);
143 fprintf(stderr, " Possible output corruption.\n");
144 fwrite(ebuf, 1, es, fp_file);
145 }
146 }
147 bam_header_destroy(old);
148 bgzf_close(in);
149 }
150 free(buf);
151 bgzf_close(fp);
152 return 0;
153 }
154
155
156
157 int main_cat(int argc, char *argv[])
158 {
159 bam_header_t *h = 0;
160 char *outfn = 0;
161 int c, ret;
162 while ((c = getopt(argc, argv, "h:o:")) >= 0) {
163 switch (c) {
164 case 'h': {
165 tamFile fph = sam_open(optarg);
166 if (fph == 0) {
167 fprintf(stderr, "[%s] ERROR: fail to read the header from '%s'.\n", __func__, argv[1]);
168 return 1;
169 }
170 h = sam_header_read(fph);
171 sam_close(fph);
172 break;
173 }
174 case 'o': outfn = strdup(optarg); break;
175 }
176 }
177 if (argc - optind < 2) {
178 fprintf(stderr, "Usage: samtools cat [-h header.sam] [-o out.bam] <in1.bam> <in2.bam> [...]\n");
179 return 1;
180 }
181 ret = bam_cat(argc - optind, argv + optind, h, outfn? outfn : "-");
182 free(outfn);
183 return ret;
184 }