1 // ==========================================================================
2 // SeqAn - The Library for Sequence Analysis
3 // ==========================================================================
4 // Copyright (c) 2006-2010, Knut Reinert, FU Berlin
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 // * Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 // * Redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution.
15 // * Neither the name of Knut Reinert or the FU Berlin nor the names of
16 // its contributors may be used to endorse or promote products derived
17 // from this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
23 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
29 // DAMAGE.
30 //
31 // ==========================================================================
32 // Author: David Weese <david.weese@fu-berlin.de>
33 // ==========================================================================
34
35 #ifndef SEQAN_HEADER_STORE_IO_UCSC_H
36 #define SEQAN_HEADER_STORE_IO_UCSC_H
37
38 namespace SEQAN_NAMESPACE_MAIN
39 {
40
41 template <typename TSpec>
42 struct Ucsc_;
43
44 /**
45 .Tag.File Format.tag.Ucsc:
46 Ucsc Genome Browser annotation file (a.k.a. knownGene format).
47 ..include:seqan/store.h
48 */
49
50 struct UcscKnownGene_;
51 typedef Tag<Ucsc_<UcscKnownGene_> > const Ucsc;
52
53 /**
54 .Tag.File Format.tag.UcscIsoforms:
55 Ucsc Genome Browser isoforms file (a.k.a. knownIsoforms format).
56 ..include:seqan/store.h
57 */
58 struct UcscKnownIsoforms_;
59 typedef Tag<Ucsc_<UcscKnownIsoforms_> > const UcscIsoforms;
60
61 //////////////////////////////////////////////////////////////////////////////
62 // _parseReadUcscIdentifier
63
64 template<typename TFile, typename TString, typename TChar>
65 inline void
_parseReadUcscIdentifier(TFile & file,TString & str,TChar & c)66 _parseReadUcscIdentifier(TFile & file, TString & str, TChar& c)
67 {
68 if (c == ' ' || c == '\t' || c == '\n') return;
69 appendValue(str, c);
70 while (!_streamEOF(file))
71 {
72 c = _streamGet(file);
73 if (c == ' ' || c == '\t' || c == '\n') return;
74 appendValue(str, c);
75 }
76 }
77
78 template<typename TFile, typename TChar>
79 inline void
_parseSkipWhiteComma(TFile & file,TChar & c)80 _parseSkipWhiteComma(TFile& file, TChar& c)
81 {
82 if (c != ',' && c != ' ') return;
83 while (!_streamEOF(file)) {
84 c = _streamGet(file);
85 if (c != ',' && c != ' ') break;
86 }
87 }
88
89 //////////////////////////////////////////////////////////////////////////////
90 // Read Ucsc
91 //////////////////////////////////////////////////////////////////////////////
92
93 template <typename TFragmentStore, typename TSpec = void>
94 struct IOContextUcsc_
95 {
96 typedef typename TFragmentStore::TAnnotationStore TAnnotationStore;
97 typedef typename Value<TAnnotationStore>::Type TAnnotation;
98 typedef typename TAnnotation::TId TId;
99
100 CharString transName;
101 CharString contigName;
102 __int64 cdsBegin;
103 __int64 cdsEnd;
104 String<__int64> exonBegin;
105 String<__int64> exonEnd;
106 CharString proteinName;
107
108 enum { KNOWN_GENE, KNOWN_ISOFORMS } format;
109 TAnnotation annotation;
110 };
111
112 template <typename TFragmentStore, typename TSpec>
clear(IOContextUcsc_<TFragmentStore,TSpec> & ctx)113 inline void clear(IOContextUcsc_<TFragmentStore, TSpec> &ctx)
114 {
115 typedef typename TFragmentStore::TAnnotationStore TAnnotationStore;
116 typedef typename Value<TAnnotationStore>::Type TAnnotation;
117
118 clear(ctx.transName);
119 clear(ctx.contigName);
120 clear(ctx.exonBegin);
121 clear(ctx.exonEnd);
122 clear(ctx.proteinName);
123 clear(ctx.annotation.values);
124 }
125
126 //////////////////////////////////////////////////////////////////////////////
127 // _readOneAnnotation
128 //
129 // reads in one annotation line from a Gff file
130
131 template <typename TFile, typename TChar, typename TFragmentStore, typename TSpec>
132 inline bool
_readOneAnnotation(TFile & file,TChar & c,IOContextUcsc_<TFragmentStore,TSpec> & ctx)133 _readOneAnnotation (
134 TFile & file,
135 TChar & c,
136 IOContextUcsc_<TFragmentStore, TSpec> & ctx)
137 {
138 typedef typename TFragmentStore::TContigPos TContigPos;
139 typedef typename TFragmentStore::TAnnotationStore TAnnotationStore;
140 typedef typename Value<TAnnotationStore>::Type TAnnotation;
141 typedef typename TAnnotation::TId TId;
142
143 clear(ctx);
144
145 // read fields of alignments line
146 _parseSkipWhitespace(file, c);
147
148 // read column 1: transcript name
149 // The letters until the first whitespace will be read.
150 // Then, we skip until we hit the first tab character.
151 _parseReadUcscIdentifier(file, ctx.transName, c);
152 if (!empty(ctx.transName) && ctx.transName[0] == '#')
153 {
154 _parseSkipLine(file, c);
155 return false;
156 }
157 _parseSkipUntilChar(file, '\t', c);
158 c = _streamGet(file);
159
160 // read column 2: contig name
161 _parseReadUcscIdentifier(file, ctx.contigName, c);
162 _parseSkipSpace(file, c);
163
164 // read column 3: orientation
165 if (c != '+' && c != '-')
166 {
167 ctx.format = ctx.KNOWN_ISOFORMS;
168 assign(prefix(ctx.transName, 0), "GENE");
169 _parseSkipLine(file, c);
170 return true;
171 }
172 ctx.format = ctx.KNOWN_GENE;
173 char orientation = c;
174 c = _streamGet(file);
175 _parseSkipWhitespace(file, c);
176
177 // read column 4: transcript begin position
178 if (_parseIsDigit(c))
179 ctx.annotation.beginPos = _parseReadNumber(file, c);
180 else
181 {
182 ctx.annotation.beginPos = TAnnotation::INVALID_POS;
183 _parseSkipEntryUntilWhitespace(file, c);
184 }
185 _parseSkipWhitespace(file, c);
186
187 // read column 5: transcript end position
188 if (_parseIsDigit(c))
189 ctx.annotation.endPos = _parseReadNumber(file, c);
190 else
191 {
192 ctx.annotation.endPos = TAnnotation::INVALID_POS;
193 _parseSkipEntryUntilWhitespace(file, c);
194 }
195 _parseSkipWhitespace(file, c);
196
197 // read column 6: CDS begin position
198 if (_parseIsDigit(c))
199 ctx.cdsBegin = _parseReadNumber(file, c);
200 else
201 {
202 ctx.cdsBegin = TAnnotation::INVALID_POS;
203 _parseSkipEntryUntilWhitespace(file, c);
204 }
205 _parseSkipWhitespace(file, c);
206
207 // read column 7: CDS end position
208 if (_parseIsDigit(c))
209 ctx.cdsEnd = _parseReadNumber(file, c);
210 else
211 {
212 ctx.cdsEnd = TAnnotation::INVALID_POS;
213 _parseSkipEntryUntilWhitespace(file, c);
214 }
215 _parseSkipWhitespace(file, c);
216
217 // read column 8: exon count
218 int exons = -1;
219 if (_parseIsDigit(c))
220 exons = _parseReadNumber(file, c);
221 _parseSkipWhitespace(file, c);
222
223 // read column 9: exon begin positions
224 for (int i = 0; i < exons; ++i)
225 {
226 appendValue(ctx.exonBegin, _parseReadNumber(file, c), Generous());
227 _parseSkipWhiteComma(file, c);
228 }
229 _parseSkipUntilChar(file, '\t', c);
230 c = _streamGet(file);
231
232 // read column 10: exon end positions
233 for (int i = 0; i < exons; ++i)
234 {
235 appendValue(ctx.exonEnd, _parseReadNumber(file, c));
236 _parseSkipWhiteComma(file, c);
237 }
238 _parseSkipUntilChar(file, '\t', c);
239 c = _streamGet(file);
240
241 // read column 10: protein name
242 _parseReadUcscIdentifier(file, ctx.proteinName, c);
243 _parseSkipUntilChar(file, '\t', c);
244 c = _streamGet(file);
245
246 // skip column 11
247 _parseSkipEntryUntilWhitespace(file, c);
248 _parseSkipWhitespace(file, c);
249
250 // adapt positions
251 if (orientation == '-')
252 {
253 TContigPos tmp = ctx.annotation.beginPos;
254 ctx.annotation.beginPos = ctx.annotation.endPos;
255 ctx.annotation.endPos = tmp;
256 tmp = ctx.cdsBegin;
257 ctx.cdsBegin = ctx.cdsEnd;
258 ctx.cdsEnd = tmp;
259 for (int i = 0; i < exons; ++i)
260 {
261 tmp = ctx.exonBegin[i];
262 ctx.exonBegin[i] = ctx.exonEnd[i];
263 ctx.exonEnd[i] = tmp;
264 }
265 }
266
267 return true;
268 }
269
270 template <typename TFragmentStore, typename TSpec>
271 inline void
_storeOneAnnotationKnownGene(TFragmentStore & fragStore,IOContextUcsc_<TFragmentStore,TSpec> & ctx)272 _storeOneAnnotationKnownGene (
273 TFragmentStore & fragStore,
274 IOContextUcsc_<TFragmentStore, TSpec> & ctx)
275 {
276 typedef typename TFragmentStore::TAnnotationStore TAnnotationStore;
277 typedef typename Value<TAnnotationStore>::Type TAnnotation;
278 typedef typename TAnnotation::TId TId;
279
280 SEQAN_ASSERT_EQ(length(fragStore.annotationStore), length(fragStore.annotationNameStore));
281
282 TId annoStoreLen = length(fragStore.annotationStore);
283 TId transId = TAnnotation::INVALID_ID;
284 TId cdsId = TAnnotation::INVALID_ID;
285
286 // add transcript and CDS
287 _storeAppendAnnotationName(fragStore, transId, ctx.transName);
288 cdsId = length(fragStore.annotationNameStore);
289 appendName(fragStore.annotationNameStore, ctx.proteinName, fragStore.annotationNameStoreCache);
290
291 if (annoStoreLen <= transId)
292 annoStoreLen = transId + 1;
293
294 if (annoStoreLen <= cdsId)
295 annoStoreLen = cdsId + 1;
296
297 resize(fragStore.annotationStore, annoStoreLen + length(ctx.exonBegin), Generous());
298 resize(fragStore.annotationNameStore, annoStoreLen + length(ctx.exonBegin), Generous());
299
300 // add contig name
301 _storeAppendContig(fragStore, ctx.annotation.contigId, ctx.contigName);
302
303 TAnnotation &transcript = fragStore.annotationStore[transId];
304 TId geneId = transcript.parentId;
305 if (geneId == TAnnotation::INVALID_ID) geneId = 0;
306 transcript = ctx.annotation;
307 transcript.parentId = geneId;
308 transcript.typeId = TFragmentStore::ANNO_MRNA;
309
310 TAnnotation &cds = fragStore.annotationStore[cdsId];
311 cds = ctx.annotation;
312 cds.parentId = transId;
313 cds.typeId = TFragmentStore::ANNO_CDS;
314 cds.beginPos = ctx.cdsBegin;
315 cds.endPos = ctx.cdsEnd;
316 _adjustParent(transcript, cds);
317
318 // insert exons
319 ctx.annotation.parentId = transId;
320 ctx.annotation.typeId = TFragmentStore::ANNO_EXON;
321 for (unsigned i = 0; i < length(ctx.exonBegin); ++i)
322 {
323 ctx.annotation.beginPos = ctx.exonBegin[i];
324 ctx.annotation.endPos = ctx.exonEnd[i];
325 fragStore.annotationStore[annoStoreLen + i] = ctx.annotation;
326 _adjustParent(transcript, ctx.annotation);
327 }
328 if (geneId != 0)
329 _adjustParent(fragStore.annotationStore[geneId], transcript);
330 }
331
332 template <typename TFragmentStore, typename TSpec>
333 inline void
_storeOneAnnotationKnownIsoforms(TFragmentStore & fragStore,IOContextUcsc_<TFragmentStore,TSpec> & ctx)334 _storeOneAnnotationKnownIsoforms (
335 TFragmentStore & fragStore,
336 IOContextUcsc_<TFragmentStore, TSpec> & ctx)
337 {
338 typedef typename TFragmentStore::TAnnotationStore TAnnotationStore;
339 typedef typename Value<TAnnotationStore>::Type TAnnotation;
340 typedef typename TAnnotation::TId TId;
341
342 SEQAN_ASSERT_EQ(length(fragStore.annotationStore), length(fragStore.annotationNameStore));
343
344 TId annoStoreLen = length(fragStore.annotationStore);
345 TId geneId = TAnnotation::INVALID_ID;
346 TId transId = TAnnotation::INVALID_ID;
347
348 // add transcript and CDS
349 _storeAppendAnnotationName(fragStore, geneId, ctx.transName);
350 _storeAppendAnnotationName(fragStore, transId, ctx.contigName);
351
352 if (annoStoreLen <= geneId)
353 annoStoreLen = geneId + 1;
354
355 if (annoStoreLen <= transId)
356 annoStoreLen = transId + 1;
357
358 resize(fragStore.annotationStore, annoStoreLen, Generous());
359 resize(fragStore.annotationNameStore, annoStoreLen, Generous());
360
361 // set parent link locus->root
362 TAnnotation &locus = fragStore.annotationStore[geneId];
363 locus.parentId = 0;
364 locus.typeId = TFragmentStore::ANNO_GENE;
365
366 // set parent link transcript->locus
367 TAnnotation &transcript = fragStore.annotationStore[transId];
368 transcript.parentId = geneId;
369 transcript.typeId = TFragmentStore::ANNO_MRNA;
370
371 _adjustParent(locus, transcript);
372 }
373
374 template <typename TFragmentStore, typename TSpec>
375 inline void
_storeOneAnnotation(TFragmentStore & fragStore,IOContextUcsc_<TFragmentStore,TSpec> & ctx)376 _storeOneAnnotation (
377 TFragmentStore & fragStore,
378 IOContextUcsc_<TFragmentStore, TSpec> & ctx)
379 {
380 if (ctx.format == ctx.KNOWN_GENE)
381 _storeOneAnnotationKnownGene(fragStore, ctx);
382 else
383 _storeOneAnnotationKnownIsoforms(fragStore, ctx);
384 }
385
386 template<typename TFile, typename TSpec, typename TConfig, typename TFormatSpec>
387 inline void
read(TFile & file,FragmentStore<TSpec,TConfig> & fragStore,Tag<Ucsc_<TFormatSpec>> const)388 read (
389 TFile & file,
390 FragmentStore<TSpec, TConfig> & fragStore,
391 Tag<Ucsc_<TFormatSpec> > const)
392 {
393 typedef FragmentStore<TSpec, TConfig> TFragmentStore;
394
395 if (_streamEOF(file)) return;
396
397 // get first character from the stream
398 char c = _streamGet(file);
399 IOContextUcsc_<TFragmentStore> ctx;
400
401 refresh(fragStore.contigNameStoreCache);
402 refresh(fragStore.annotationNameStoreCache);
403 refresh(fragStore.annotationTypeStoreCache);
404
405 while (!_streamEOF(file))
406 {
407 if (_readOneAnnotation(file, c, ctx))
408 _storeOneAnnotation(fragStore, ctx);
409 }
410 _storeClearAnnoBackLinks(fragStore.annotationStore);
411 _storeCreateAnnoBackLinks(fragStore.annotationStore);
412 _storeRemoveTempAnnoNames(fragStore);
413 }
414
415 //////////////////////////////////////////////////////////////////////////////
416 // Write Ucsc
417 //////////////////////////////////////////////////////////////////////////////
418
419 template <typename TFragmentStore, typename TSpec, typename TAnnotation, typename TId>
420 inline bool
_retrieveOneAnnotation(TFragmentStore & fragStore,IOContextUcsc_<TFragmentStore,TSpec> & ctx,TAnnotation & annotation,TId id,Ucsc)421 _retrieveOneAnnotation (
422 TFragmentStore & fragStore,
423 IOContextUcsc_<TFragmentStore, TSpec> & ctx,
424 TAnnotation &annotation,
425 TId id,
426 Ucsc)
427 {
428 if (annotation.typeId != TFragmentStore::ANNO_MRNA) return false;
429
430 ctx.format = ctx.KNOWN_GENE;
431 ctx.transName = getAnnoUniqueName(fragStore, id);
432 if (annotation.contigId < length(fragStore.contigNameStore))
433 ctx.contigName = fragStore.contigNameStore[annotation.contigId];
434 else
435 clear(ctx.contigName);
436
437 ctx.annotation = annotation;
438 clear(ctx.proteinName);
439 clear(ctx.exonBegin);
440 clear(ctx.exonEnd);
441
442 TId lastChildId = annotation.lastChildId;
443 TId i = lastChildId;
444 do {
445 i = fragStore.annotationStore[i].nextSiblingId;
446 TAnnotation &anno = fragStore.annotationStore[i];
447 if (anno.typeId == TFragmentStore::ANNO_CDS)
448 {
449 if (i < length(fragStore.annotationNameStore))
450 ctx.proteinName = fragStore.annotationNameStore[i];
451 ctx.cdsBegin = anno.beginPos;
452 ctx.cdsEnd = anno.endPos;
453 }
454 if (anno.typeId == TFragmentStore::ANNO_EXON)
455 {
456 appendValue(ctx.exonBegin, anno.beginPos, Generous());
457 appendValue(ctx.exonEnd, anno.endPos, Generous());
458 }
459 } while (i != lastChildId);
460 return true;
461 }
462
463 template <typename TFragmentStore, typename TSpec, typename TAnnotation, typename TId>
464 inline bool
_retrieveOneAnnotation(TFragmentStore & fragStore,IOContextUcsc_<TFragmentStore,TSpec> & ctx,TAnnotation & annotation,TId id,UcscIsoforms)465 _retrieveOneAnnotation (
466 TFragmentStore & fragStore,
467 IOContextUcsc_<TFragmentStore, TSpec> & ctx,
468 TAnnotation &annotation,
469 TId id,
470 UcscIsoforms)
471 {
472 if (annotation.typeId != TFragmentStore::ANNO_MRNA) return false;
473 if (annotation.parentId == TAnnotation::INVALID_ID || annotation.parentId == 0) return false;
474
475 ctx.format = ctx.KNOWN_ISOFORMS;
476 ctx.transName = getAnnoUniqueName(fragStore, annotation.parentId);
477 ctx.contigName = getAnnoUniqueName(fragStore, id);
478 return true;
479 }
480
481 template<typename TTargetStream, typename TFragmentStore, typename TSpec>
482 inline void
_writeOneAnnotation(TTargetStream & file,IOContextUcsc_<TFragmentStore,TSpec> & ctx)483 _writeOneAnnotation (
484 TTargetStream & file,
485 IOContextUcsc_<TFragmentStore, TSpec> & ctx)
486 {
487 typedef typename TFragmentStore::TContigPos TContigPos;
488
489 unsigned suf = 0;
490 if (ctx.format == ctx.KNOWN_ISOFORMS && length(ctx.transName) >= 4 && prefix(ctx.transName, 4) == "GENE")
491 suf = 4;
492
493 // read column 1: transcript name
494 // The letters until the first whitespace will be read.
495 // Then, we skip until we hit the first tab character.
496 _streamWrite(file, suffix(ctx.transName, suf));
497 _streamPut(file, '\t');
498
499 // read column 2: contig name
500 _streamWrite(file, ctx.contigName);
501 if (ctx.format == ctx.KNOWN_ISOFORMS)
502 {
503 _streamPut(file, '\n');
504 return;
505 }
506 _streamPut(file, '\t');
507
508 // read column 3: orientation
509 TContigPos transBeginPos, transEndPos;
510 TContigPos cdsBeginPos, cdsEndPos;
511 if (ctx.annotation.beginPos < ctx.annotation.endPos)
512 {
513 _streamPut(file, '+');
514 transBeginPos = ctx.annotation.beginPos;
515 transEndPos = ctx.annotation.endPos;
516 cdsBeginPos = ctx.cdsBegin;
517 cdsEndPos = ctx.cdsEnd;
518 }
519 else
520 {
521 _streamPut(file, '-');
522 transEndPos = ctx.annotation.beginPos;
523 transBeginPos = ctx.annotation.endPos;
524 cdsEndPos = ctx.cdsBegin;
525 cdsBeginPos = ctx.cdsEnd;
526 }
527 _streamPut(file, '\t');
528
529 // read column 4: transcript begin position
530 _streamPutInt(file, transBeginPos);
531 _streamPut(file, '\t');
532
533 // read column 5: transcript end position
534 _streamPutInt(file, transEndPos);
535 _streamPut(file, '\t');
536
537 // read column 6: CDS begin position
538 _streamPutInt(file, cdsBeginPos);
539 _streamPut(file, '\t');
540
541 // read column 7: CDS end position
542 _streamPutInt(file, cdsEndPos);
543 _streamPut(file, '\t');
544
545 // read column 8: exon count
546 _streamPutInt(file, length(ctx.exonBegin));
547 _streamPut(file, '\t');
548
549 // read column 9: exon begin positions
550 for (unsigned i = 0; i < length(ctx.exonBegin); ++i)
551 {
552 _streamPutInt(file, _min(ctx.exonBegin[i], ctx.exonEnd[i]));
553 _streamPut(file, ',');
554 }
555 _streamPut(file, '\t');
556
557 // read column 10: exon end positions
558 for (unsigned i = 0; i < length(ctx.exonBegin); ++i)
559 {
560 _streamPutInt(file, _max(ctx.exonBegin[i], ctx.exonEnd[i]));
561 _streamPut(file, ',');
562 }
563 _streamPut(file, '\t');
564
565 // read column 10: protein name
566 _streamWrite(file, ctx.proteinName);
567 _streamPut(file, '\t');
568
569 // skip column 11
570 _streamWrite(file, ctx.transName);
571 _streamPut(file, '\n');
572 }
573
574 template<typename TTargetStream, typename TSpec, typename TConfig, typename TFormatSpec>
575 inline void
write(TTargetStream & target,FragmentStore<TSpec,TConfig> & store,Tag<Ucsc_<TFormatSpec>> const format)576 write (
577 TTargetStream & target,
578 FragmentStore<TSpec, TConfig> & store,
579 Tag<Ucsc_<TFormatSpec> > const format)
580 {
581 typedef FragmentStore<TSpec, TConfig> TFragmentStore;
582 typedef typename TFragmentStore::TAnnotationStore TAnnotationStore;
583 typedef typename Value<TAnnotationStore>::Type TAnnotation;
584 typedef typename Iterator<TAnnotationStore, Standard>::Type TAnnoIter;
585 typedef typename Id<TAnnotation>::Type TId;
586
587 IOContextUcsc_<TFragmentStore> ctx;
588
589 TAnnoIter it = begin(store.annotationStore, Standard());
590 TAnnoIter itEnd = end(store.annotationStore, Standard());
591
592 for(TId id = 0; it != itEnd; ++it, ++id)
593 {
594 if (_retrieveOneAnnotation(store, ctx, *it, id, format))
595 _writeOneAnnotation(target, ctx);
596 }
597 }
598
599 }// namespace SEQAN_NAMESPACE_MAIN
600
601 #endif //#ifndef SEQAN_HEADER_...
602