1 |
#include "GBam.h" |
2 |
#include "GArgs.h" |
3 |
#include "GStr.h" |
4 |
|
5 |
#define USAGE "Usage: bamread [--fasta|-a|--fastq|-q|-G|--gff]\n\ |
6 |
[-M|--mapped-only|-A|--all] [-o <outfile>] <in.bam>|<in.sam> \n" |
7 |
|
8 |
|
9 |
enum OutType { |
10 |
outFASTQ, |
11 |
outFASTA, |
12 |
outGFF |
13 |
}; |
14 |
|
15 |
OutType out_type=outFASTQ; |
16 |
bool all_reads=false; |
17 |
bool mapped_only=false; |
18 |
|
19 |
#define bam_unmapped(b) (((b)->core.flag & BAM_FUNMAP) != 0) |
20 |
|
21 |
void showfastq(GBamRecord& rec, FILE* fout) { |
22 |
if (rec.isMapped() && !all_reads) return; |
23 |
if (mapped_only && rec.isUnmapped()) return; |
24 |
char* qseq=rec.sequence(); |
25 |
fprintf(fout, "@%s\n%s\n", rec.name(), qseq); |
26 |
GFREE(qseq); |
27 |
qseq=rec.qualities(); |
28 |
fprintf(fout, "+\n%s\n",qseq); |
29 |
GFREE(qseq); |
30 |
} |
31 |
|
32 |
void showfasta(GBamRecord& rec, FILE* fout) { |
33 |
if (rec.isMapped() && !all_reads) return; |
34 |
if (mapped_only && rec.isUnmapped()) return; |
35 |
char* qseq=rec.sequence(); |
36 |
fprintf(fout, ">%s\n%s\n", rec.name(), qseq); |
37 |
GFREE(qseq); |
38 |
} |
39 |
|
40 |
void showgff(GBamRecord& rec, FILE* fout) { |
41 |
if (rec.isUnmapped()) return; |
42 |
char tstrand=rec.spliceStrand(); |
43 |
fprintf(fout, "%s\tbam\tmRNA\t%d\t%d\t.\t%c\t.\tID=%s\n", rec.refName(), |
44 |
rec.start, rec.end, tstrand, rec.name()); |
45 |
for (int i=0;i<rec.exons.Count();i++) { |
46 |
fprintf(fout, "%s\tbam\texon\t%d\t%d\t.\t%c\t.\tParent=%s\n", rec.refName(), |
47 |
rec.exons[i].start, rec.exons[i].end, tstrand, rec.name()); |
48 |
} |
49 |
} |
50 |
|
51 |
int main(int argc, char *argv[]) |
52 |
{ |
53 |
|
54 |
GArgs args(argc, argv, "fasta;fastq;gff;all;help;mapped-only;" |
55 |
"hAMGaqo:"); |
56 |
args.printError(USAGE, true); |
57 |
if (args.getOpt('h') || args.getOpt("help") || args.startNonOpt()==0) { |
58 |
GMessage(USAGE); |
59 |
return 1; |
60 |
} |
61 |
args.printCmdLine(stderr); |
62 |
|
63 |
all_reads=(args.getOpt('A') || args.getOpt("all")); |
64 |
mapped_only=(args.getOpt('M') || args.getOpt("mapped-only")); |
65 |
if ((all_reads && mapped_only)) { |
66 |
GError("Error: incompatible options !\n"); |
67 |
} |
68 |
|
69 |
if (args.getOpt('a') || args.getOpt("fasta")) |
70 |
out_type=outFASTA; |
71 |
else if (args.getOpt('G') || args.getOpt("gff")) { |
72 |
out_type=outGFF; |
73 |
mapped_only=true; |
74 |
} |
75 |
char* fname=args.nextNonOpt(); |
76 |
if (fname==NULL || fname[0]==0) { |
77 |
GMessage(USAGE); |
78 |
return 1; |
79 |
} |
80 |
GBamReader bamreader(fname); |
81 |
FILE* fout=stdout; |
82 |
char* outfname=args.getOpt('o'); |
83 |
if (outfname) { |
84 |
fout=fopen(outfname, "w"); |
85 |
if (fout==NULL) { |
86 |
fprintf(stderr, "Error creating output file %s\n", outfname); |
87 |
return 2; |
88 |
} |
89 |
} |
90 |
GBamRecord *aln=NULL; |
91 |
if (out_type==outFASTA) { |
92 |
while ((aln=bamreader.next())!=NULL) { |
93 |
showfasta(*aln, fout); |
94 |
delete aln; |
95 |
} |
96 |
} |
97 |
else if (out_type==outGFF) { |
98 |
while ((aln=bamreader.next())!=NULL) { |
99 |
showgff(*aln, fout); |
100 |
delete aln; |
101 |
} |
102 |
} |
103 |
else { |
104 |
while ((aln=bamreader.next())!=NULL) { |
105 |
showfastq(*aln, fout); |
106 |
delete aln; |
107 |
} |
108 |
} |
109 |
if (fout!=stdout) fclose(fout); |
110 |
return 0; |
111 |
} |