Imported Upstream version 0.12.7
[bowtie.git] / SeqAn-1.1 / seqan / file / file_format_fasta_align.h
1  /*==========================================================================
2                 SeqAn - The Library for Sequence Analysis
3                           http://www.seqan.de 
4  ============================================================================
5   Copyright (C) 2007
6
7   This library is free software; you can redistribute it and/or
8   modify it under the terms of the GNU Lesser General Public
9   License as published by the Free Software Foundation; either
10   version 3 of the License, or (at your option) any later version.
11
12   This library is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   Lesser General Public License for more details.
16
17  ============================================================================
18   $Id: file_format_fasta_align.h,v 1.1 2008/08/25 16:20:03 langmead Exp $
19  ==========================================================================*/
20
21 #ifndef SEQAN_HEADER_FILE_FASTA_ALIGN_H
22 #define SEQAN_HEADER_FILE_FASTA_ALIGN_H
23
24 namespace SEQAN_NAMESPACE_MAIN
25 {
26
27 //////////////////////////////////////////////////////////////////////////////
28 // File Formats - Fasta alignment format
29 //////////////////////////////////////////////////////////////////////////////
30
31 //forward declarations
32 template <typename T>
33 struct Row;
34
35 template <typename T>
36 struct Rows;
37
38 //////////////////////////////////////////////////////////////////////////////
39
40 /**
41 .Tag.File Format.tag.Fasta alignment:
42         FASTA alignment file format for sequences.
43 */
44 struct TagFastaAlign_;
45 typedef Tag<TagFastaAlign_> const FastaAlign;
46
47
48 /////////////////////////////////////////////////////////////////////////
49
50 template <typename TFile, typename TSize>
51 void _fasta_align_scan_line(TFile & file, TSize & count) {
52
53         SEQAN_CHECKPOINT
54         SEQAN_ASSERT(!_streamEOF(file))
55
56         while (true) {
57                 typename Value<TFile>::Type c = _streamGet(file);
58
59                 if (_streamEOF(file)) return;
60                 if (c == '\n') return;
61
62                 if ((c != '\r') && (c!='-')) {
63                         ++count;
64                 }
65         }
66 }
67
68 //////////////////////////////////////////////////////////////////////////////
69 // read
70 //////////////////////////////////////////////////////////////////////////////
71 template <typename TFile, typename TSource, typename TSpec>
72 void read(TFile & file, Align<TSource, TSpec> & align, FastaAlign) {
73 SEQAN_CHECKPOINT
74
75         SEQAN_ASSERT(!_streamEOF(file))
76         
77         typedef typename Value<TSource>::Type TSourceValue;
78         typedef typename Size<TSourceValue>::Type TSize;
79         TSize limit = supremumValue<TSize>();
80
81         //Determine begin position, end position and length of each sequence
82         String<TSize> beg_end_length;
83         
84         typename Position<TFile>::Type begin_pos;
85         typename Position<TFile>::Type end_pos;
86         typename Value<TFile>::Type c;
87         TSize count;
88
89         while (!_streamEOF(file)) {
90                 begin_pos = _streamTellG(file);
91                 count = 0;
92                 SEQAN_ASSERT(!_streamEOF(file))
93
94         
95                 c = _streamGet(file);
96                 
97                 // Skip id
98                 if (c == '>') {
99                         _fasta_align_scan_line(file, count);
100                         begin_pos = _streamTellG(file);
101                         count = 0;
102                 } else {  //If no id first letter belongs to sequence
103                         count = 1;
104                 }
105
106                 // Count letters
107                 while (true) {
108                         _fasta_align_scan_line(file, count);
109
110                         typename Value<TFile>::Type c = _streamGet(file);
111                         if (c == '>') {
112                                 _streamSeek2G(file, -1);
113                                 end_pos = _streamTellG(file);
114                                 break;
115                         }
116                         if (_streamEOF(file)) {
117                                 end_pos = _streamTellG(file);
118                                 break;
119                         }
120                         if ((c != '\n') && (c != '\r') && (c!='-'))     {
121                                 ++count;
122                         }
123                 }
124                 if (count > limit) {
125                         count = limit;
126                 }
127
128                 append(beg_end_length, begin_pos);
129                 append(beg_end_length, end_pos);
130                 append(beg_end_length, count);
131         }
132
133         // Resize alignment data structure
134         TSize numRows=length(beg_end_length) / 3;
135         resize(rows(align), numRows);   //rows
136                 
137         typedef Align<TSource, TSpec> TAlign;
138         typedef typename Row<TAlign>::Type TRow;
139         
140         for(TSize i=0;i<numRows;++i) {
141                 TSize begin = beg_end_length[i*3];
142 //              TSize end = beg_end_length[i*3+1];
143                 count = beg_end_length[i*3+2];
144                 
145                 //Reserve space
146                 clear(row(align,i));
147                 createSource(row(align,i));
148                 resize(source(row(align,i)),count);
149                 if (length(source(row(align,i))) < count) {
150                         count = length(source(row(align,i)));
151                 }
152                 setSourceEndPosition(row(align,i),count);
153                 
154                 //Read sequence
155                 _streamSeekG(file, begin);
156
157                 typename Position<TSource>::Type pos;
158                 for (pos = 0; pos < count; ) {
159                         c = _streamGet(file);
160                         if ((c != '\n') && (c != '\r') && (c != '-'))   {
161                                 source(row(align,i))[pos] = c;
162                                 ++pos;
163                         }
164                         if (c=='-') {
165                                 insertGap(row(align,i), toViewPosition(row(align,i), pos));
166                         }
167                 }
168         }
169
170         _streamSeekG(file, 0);
171 }
172
173 //////////////////////////////////////////////////////////////////////////////
174 // readIDs
175 //////////////////////////////////////////////////////////////////////////////
176  
177 template <typename TFile, typename TStringContainer>
178 void readIDs(TFile& file, TStringContainer& ids, FastaAlign) {
179         
180         SEQAN_CHECKPOINT
181         
182         SEQAN_ASSERT(!_streamEOF(file))
183
184         typedef typename Value<TStringContainer>::Type TString;
185         typename Position<TFile>::Type start_pos;
186         typename Value<TFile>::Type c;
187
188
189         TString id;
190         while(true) {
191                 c = _streamGet(file);
192                 while ((!_streamEOF(file)) && (c != '>')) c = _streamGet(file);
193                 if (!_streamEOF(file)) {
194                         start_pos = _streamTellG(file);
195                         typename Size<TString>::Type count = 0;
196                         _fasta_align_scan_line(file, count);
197                         if (! count) clear(id);
198                         else {
199                                 resize(id, count);
200                                 if (length(id) < count) {
201                                         count = length(id);
202                                 }
203                                 _streamSeekG(file, start_pos);
204                                 for (typename Position<TString>::Type pos = 0; pos<count; ++pos) {
205                                         id[pos] = _streamGet(file);
206                                 }
207                         }
208                         appendValue(ids, id);
209                 } else {
210                         break;
211                 }
212         }
213         _streamSeekG(file, 0);
214 }
215
216 //////////////////////////////////////////////////////////////////////////////
217 // readMeta
218 //////////////////////////////////////////////////////////////////////////////
219
220 //Fasta file records have no meta data
221
222 template <typename TFile, typename TMeta>
223 void readMeta(TFile & file, TMeta & meta, FastaAlign) {
224         SEQAN_CHECKPOINT
225         clear(meta);
226 }
227
228
229 //////////////////////////////////////////////////////////////////////////////
230 // goNext
231 //////////////////////////////////////////////////////////////////////////////
232 template <typename TFile>
233 void goNext(TFile & file, FastaAlign) {
234         SEQAN_CHECKPOINT
235         SEQAN_ASSERT(!_streamEOF(file))
236         
237         return;
238 }
239
240
241 //////////////////////////////////////////////////////////////////////////////
242 // write
243 //////////////////////////////////////////////////////////////////////////////
244
245 template <typename TFile, typename TStringContainer, typename TSource, typename TSpec>
246 void _write_impl(TFile& file, Align<TSource, TSpec>& align, TStringContainer& ids, FastaAlign) {
247         SEQAN_CHECKPOINT
248
249         typedef Align<TSource, TSpec> const TAlign;
250         typedef typename Row<TAlign>::Type TRow;
251         typedef typename Position<typename Rows<TAlign>::Type>::Type TRowsPosition;
252         typedef typename Position<TAlign>::Type TPosition;
253         TRowsPosition row_count = length(rows(align));
254
255         for(TRowsPosition i=0;i<row_count;++i) {
256                 TRow & row_ = row(align, i);    
257         
258                 typedef typename Iterator<typename Row<TAlign>::Type const, Standard>::Type TIter;
259                 TIter begin_ = iter(row_, beginPosition(cols(align)));
260                 TIter end_ = iter(row_, endPosition(cols(align)));
261         
262                 _streamPut(file, '>');
263                 _streamWrite(file, getValue(ids,i));
264                 _streamPut(file, '\n');
265
266                 int chars=0;
267                 while(begin_ != end_) {
268                         if (chars == 60) {
269                                 _streamPut(file, '\n');
270                                 chars = 0;
271                         }
272                         if (isGap(begin_)) _streamPut(file, gapValue<char>());
273                         else _streamPut(file, getValue(source(begin_)));
274                         chars++;
275                         ++begin_;
276                 }
277                 _streamPut(file, '\n');
278         }
279 }
280
281 //____________________________________________________________________________
282
283 template <typename TFile, typename TSource, typename TSpec>
284 void write(TFile & file, Align<TSource, TSpec>& align, FastaAlign) {
285         SEQAN_CHECKPOINT
286         _write_impl(file, align, String<String<char> >(), FastaAlign());
287 }
288
289 //____________________________________________________________________________
290
291 template <typename TFile, typename TStringContainer, typename TSource, typename TSpec>
292 void write(TFile & file, Align<TSource, TSpec> & align, TStringContainer& ids, FastaAlign) {
293         SEQAN_CHECKPOINT
294         _write_impl(file, align, ids, FastaAlign());
295 }
296
297
298 //VisualC++ const array bug workaround
299 template <typename TFile, typename TStringContainer, typename TSource, typename TSpec>
300 void write(TFile & file, Align<TSource, TSpec>* align, TStringContainer & ids, FastaAlign) {
301         SEQAN_CHECKPOINT
302         _write_impl(file, align, ids, FastaAlign());
303 }
304
305 //____________________________________________________________________________
306
307 template <typename TFile, typename TStringContainer, typename TSource, typename TSpec, typename TMeta>
308 void write(TFile & file, Align<TSource, TSpec> & align, TStringContainer& ids, TMeta &, FastaAlign) {
309         SEQAN_CHECKPOINT
310         _write_impl(file, align, ids, FastaAlign());
311 }
312
313
314
315 //////////////////////////////////////////////////////////////////////////////
316 } //namespace SEQAN_NAMESPACE_MAIN
317
318 //////////////////////////////////////////////////////////////////////////////
319
320 #endif //#ifndef SEQAN_HEADER_...