1 |
// |
2 |
// FastaTools.cpp |
3 |
// TopHat |
4 |
// |
5 |
// Created by Harold Pimentel on 10/27/11. |
6 |
// |
7 |
|
8 |
#include "FastaTools.h" |
9 |
|
10 |
FastaReader::FastaReader() |
11 |
{ |
12 |
isPrimed_ = false; |
13 |
} |
14 |
|
15 |
FastaReader::FastaReader(std::string fname) |
16 |
{ |
17 |
isPrimed_ = false; |
18 |
init(fname); |
19 |
} |
20 |
|
21 |
FastaReader::~FastaReader() |
22 |
{ |
23 |
ifstream_.close(); |
24 |
} |
25 |
|
26 |
void FastaReader::init(std::string fname) |
27 |
{ |
28 |
if (isPrimed_) { |
29 |
std::cerr << "Warning: object has already FastaReader has already been " |
30 |
<< "initialized with file: " << fname_ << std::endl; |
31 |
return; |
32 |
} |
33 |
|
34 |
fname_ = fname; |
35 |
ifstream_.open(fname_.c_str(), std::ios::in); |
36 |
if (!ifstream_.good()) { |
37 |
std::cerr << "ERROR: Could not open file " << fname_ << |
38 |
" in FastaReader" << std::endl; |
39 |
exit(1); |
40 |
} |
41 |
|
42 |
// Check the first character to see if it is valid |
43 |
char c = ifstream_.peek(); |
44 |
if (c != '>') |
45 |
{ |
46 |
std::cerr << "ERROR: Invalid format for FASTA file. Begins with a '" << |
47 |
c << "'instead of a '>'" << std::endl; |
48 |
exit(1); |
49 |
} |
50 |
|
51 |
|
52 |
isPrimed_ = true; |
53 |
|
54 |
} |
55 |
|
56 |
|
57 |
bool FastaReader::good() const |
58 |
{ |
59 |
return ifstream_.good() && !ifstream_.eof(); |
60 |
} |
61 |
|
62 |
// TODO: Make it read the description |
63 |
// Right now only reads the ID and sequence |
64 |
// Up to caller to allocate memory. |
65 |
// Only deallocates memory when there are no more records left |
66 |
void FastaReader::next(FastaRecord* rec) |
67 |
{ |
68 |
if (!isPrimed_) |
69 |
{ |
70 |
std::cerr << "ERROR: Stream has not been primed (FastaReader)" |
71 |
<< std::endl; |
72 |
exit(1); |
73 |
} |
74 |
// Get the entire first line and description |
75 |
ifstream_.getline(line_buf_, LINE_BUF_SIZE); |
76 |
sscanf(line_buf_, "%s", id_buf_); |
77 |
char *cur_id = new char[strlen(id_buf_) + 1]; |
78 |
strncpy(cur_id, id_buf_ + 1, strlen(id_buf_)); |
79 |
std::string id(static_cast<const char*>(cur_id)); |
80 |
delete cur_id; |
81 |
|
82 |
std::string seq; |
83 |
std::string cur_line; |
84 |
|
85 |
if (!good()) { |
86 |
delete rec; |
87 |
rec = NULL; |
88 |
return; |
89 |
} |
90 |
|
91 |
// Read until you see another ">" |
92 |
while (ifstream_.peek() != '>' && ifstream_.good() && !ifstream_.eof()) { |
93 |
ifstream_ >> cur_line >> std::ws; |
94 |
seq += cur_line; |
95 |
} |
96 |
|
97 |
rec->id_ = id; |
98 |
rec->seq_ = seq; |
99 |
|
100 |
return; |
101 |
} |
102 |
|
103 |
|
104 |
FastaWriter::FastaWriter() |
105 |
{ |
106 |
isPrimed_ = false; |
107 |
} |
108 |
|
109 |
FastaWriter::FastaWriter(std::string fname) |
110 |
{ |
111 |
isPrimed_ = false; |
112 |
init(fname); |
113 |
} |
114 |
|
115 |
FastaWriter::~FastaWriter() |
116 |
{ |
117 |
ofstream_.close(); |
118 |
} |
119 |
|
120 |
void FastaWriter::init(std::string fname) |
121 |
{ |
122 |
if (isPrimed_) |
123 |
{ |
124 |
std::cerr << "Warning: Cannot allocate FastaWriter to file '" << |
125 |
fname << "'. It has already been allocated to file '" |
126 |
<< fname_ << "'" << std::endl; |
127 |
return; |
128 |
} |
129 |
|
130 |
ofstream_.open(fname.c_str(), std::ios::out); |
131 |
if (!ofstream_.good()) |
132 |
{ |
133 |
std::cerr << "ERROR: Could not open " << fname << " for writing in " |
134 |
<< "FastaWriter" << std::endl; |
135 |
exit(1); |
136 |
} |
137 |
|
138 |
fname_ = fname; |
139 |
|
140 |
isPrimed_ = true; |
141 |
} |
142 |
|
143 |
void FastaWriter::write(FastaRecord* rec, size_t column_size) |
144 |
{ |
145 |
if (rec->seq_.length() == 0) |
146 |
return; //don't write empty records |
147 |
ofstream_ << ">" << rec->id_; //<< std::endl; |
148 |
if (rec->desc_.length()) { |
149 |
ofstream_ << " " << rec->desc_; |
150 |
} |
151 |
ofstream_ << std::endl; |
152 |
|
153 |
// iterate throught the string and print out the string |
154 |
size_t start = 0; |
155 |
while (start < rec->seq_.length()) |
156 |
{ |
157 |
ofstream_ << rec->seq_.substr(start, column_size) << std::endl; |
158 |
start += column_size; |
159 |
} |
160 |
} |