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