1 /*===========================================================================
2 *
3 * PUBLIC DOMAIN NOTICE
4 * National Center for Biotechnology Information
5 *
6 * This software/database is a "United States Government Work" under the
7 * terms of the United States Copyright Act. It was written as part of
8 * the author's official duties as a United States Government employee and
9 * thus cannot be copyrighted. This software/database is freely available
10 * to the public for use. The National Library of Medicine and the U.S.
11 * Government have not placed any restriction on its use or reproduction.
12 *
13 * Although all reasonable efforts have been taken to ensure the accuracy
14 * and reliability of the software and data, the NLM and the U.S.
15 * Government do not and cannot warrant the performance or results that
16 * may be obtained by using this software or data. The NLM and the U.S.
17 * Government disclaim all warranties, express or implied, including
18 * warranties of performance, merchantability or fitness for any particular
19 * purpose.
20 *
21 * Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26
27
28 #include "NGS_Read.h"
29
30 #include "NGS_String.h"
31
32 #include "NGS_ErrBlock.h"
33 #include <ngs/itf/FragmentItf.h>
34 #include <ngs/itf/ReadItf.h>
35
36 #include <kfc/ctx.h>
37 #include <kfc/rsrc.h>
38 #include <kfc/except.h>
39 #include <kfc/xc.h>
40 #include <klib/text.h>
41 #include <klib/printf.h>
42 #include <klib/refcount.h>
43 #include <vdb/cursor.h>
44 #include <vdb/schema.h>
45 #include <vdb/vdb-priv.h>
46 #include <insdc/insdc.h>
47
48 #include <sysalloc.h>
49
50 #include <stddef.h>
51 #include <assert.h>
52
53 /*--------------------------------------------------------------------------
54 * NGS_Read_v1
55 */
56
57 #define Self( obj ) \
58 ( ( NGS_Read* ) ( obj ) )
59
ITF_Read_v1_get_id(const NGS_Read_v1 * self,NGS_ErrBlock_v1 * err)60 static NGS_String_v1 * ITF_Read_v1_get_id ( const NGS_Read_v1 * self, NGS_ErrBlock_v1 * err )
61 {
62 HYBRID_FUNC_ENTRY ( rcSRA, rcRefcount, rcAccessing );
63 ON_FAIL ( struct NGS_String * ret = NGS_ReadGetReadId ( Self ( self ), ctx ) )
64 {
65 NGS_ErrBlockThrow ( err, ctx );
66 }
67
68 CLEAR ();
69 return ( NGS_String_v1 * ) ret;
70 }
71
ITF_Read_v1_get_num_frags(const NGS_Read_v1 * self,NGS_ErrBlock_v1 * err)72 static uint32_t ITF_Read_v1_get_num_frags ( const NGS_Read_v1 * self, NGS_ErrBlock_v1 * err )
73 {
74 HYBRID_FUNC_ENTRY ( rcSRA, rcRefcount, rcAccessing );
75 ON_FAIL ( uint32_t ret = NGS_ReadNumFragments ( Self ( self ), ctx ) )
76 {
77 NGS_ErrBlockThrow ( err, ctx );
78 }
79
80 CLEAR ();
81 return ret;
82 }
83
ITF_Read_v1_frag_is_aligned(const NGS_Read_v1 * self,NGS_ErrBlock_v1 * err,uint32_t frag_idx)84 static bool ITF_Read_v1_frag_is_aligned ( const NGS_Read_v1 * self, NGS_ErrBlock_v1 * err, uint32_t frag_idx )
85 {
86 HYBRID_FUNC_ENTRY ( rcSRA, rcRefcount, rcAccessing );
87 ON_FAIL ( bool ret = NGS_ReadFragIsAligned ( Self ( self ), ctx, frag_idx ) )
88 {
89 NGS_ErrBlockThrow ( err, ctx );
90 }
91
92 CLEAR ();
93 return ret;
94 }
95
ITF_Read_v1_get_category(const NGS_Read_v1 * self,NGS_ErrBlock_v1 * err)96 static uint32_t ITF_Read_v1_get_category ( const NGS_Read_v1 * self, NGS_ErrBlock_v1 * err )
97 {
98 HYBRID_FUNC_ENTRY ( rcSRA, rcRefcount, rcAccessing );
99 ON_FAIL ( uint32_t ret = NGS_ReadGetReadCategory ( Self ( self ), ctx ) )
100 {
101 NGS_ErrBlockThrow ( err, ctx );
102 }
103
104 CLEAR ();
105 return ret;
106 }
107
ITF_Read_v1_get_read_group(const NGS_Read_v1 * self,NGS_ErrBlock_v1 * err)108 static NGS_String_v1 * ITF_Read_v1_get_read_group ( const NGS_Read_v1 * self, NGS_ErrBlock_v1 * err )
109 {
110 HYBRID_FUNC_ENTRY ( rcSRA, rcRefcount, rcAccessing );
111 ON_FAIL ( struct NGS_String * ret = NGS_ReadGetReadGroup ( Self ( self ), ctx ) )
112 {
113 NGS_ErrBlockThrow ( err, ctx );
114 }
115
116 CLEAR ();
117 return ( NGS_String_v1 * ) ret;
118 }
119
ITF_Read_v1_get_name(const NGS_Read_v1 * self,NGS_ErrBlock_v1 * err)120 static NGS_String_v1 * ITF_Read_v1_get_name ( const NGS_Read_v1 * self, NGS_ErrBlock_v1 * err )
121 {
122 HYBRID_FUNC_ENTRY ( rcSRA, rcRefcount, rcAccessing );
123 ON_FAIL ( struct NGS_String * ret = NGS_ReadGetReadName ( Self ( self ), ctx ) )
124 {
125 NGS_ErrBlockThrow ( err, ctx );
126 }
127
128 CLEAR ();
129 return ( NGS_String_v1 * ) ret;
130 }
131
ITF_Read_v1_get_bases(const NGS_Read_v1 * self,NGS_ErrBlock_v1 * err,uint64_t offset,uint64_t length)132 static NGS_String_v1 * ITF_Read_v1_get_bases ( const NGS_Read_v1 * self, NGS_ErrBlock_v1 * err, uint64_t offset, uint64_t length )
133 {
134 HYBRID_FUNC_ENTRY ( rcSRA, rcRefcount, rcAccessing );
135 ON_FAIL ( struct NGS_String * ret = NGS_ReadGetReadSequence ( Self ( self ), ctx, offset, length ) )
136 {
137 NGS_ErrBlockThrow ( err, ctx );
138 }
139
140 CLEAR ();
141 return ( NGS_String_v1 * ) ret;
142 }
143
ITF_Read_v1_get_quals(const NGS_Read_v1 * self,NGS_ErrBlock_v1 * err,uint64_t offset,uint64_t length)144 static NGS_String_v1 * ITF_Read_v1_get_quals ( const NGS_Read_v1 * self, NGS_ErrBlock_v1 * err, uint64_t offset, uint64_t length )
145 {
146 HYBRID_FUNC_ENTRY ( rcSRA, rcRefcount, rcAccessing );
147 ON_FAIL ( struct NGS_String * ret = NGS_ReadGetReadQualities ( Self ( self ), ctx, offset, length ) )
148 {
149 NGS_ErrBlockThrow ( err, ctx );
150 }
151
152 CLEAR ();
153 return ( NGS_String_v1 * ) ret;
154 }
155
ITF_Read_v1_next(NGS_Read_v1 * self,NGS_ErrBlock_v1 * err)156 static bool ITF_Read_v1_next ( NGS_Read_v1 * self, NGS_ErrBlock_v1 * err )
157 {
158 HYBRID_FUNC_ENTRY ( rcSRA, rcRefcount, rcAccessing );
159 ON_FAIL ( bool ret = NGS_ReadIteratorNext ( Self ( self ), ctx ) )
160 {
161 NGS_ErrBlockThrow ( err, ctx );
162 }
163
164 CLEAR ();
165 return ret;
166 }
167
168 #undef Self
169
170
171 NGS_Read_v1_vt ITF_Read_vt =
172 {
173 {
174 "NGS_Read",
175 "NGS_Read_v1",
176 1,
177 & ITF_Fragment_vt . dad
178 },
179
180 ITF_Read_v1_get_id,
181 ITF_Read_v1_get_num_frags,
182 ITF_Read_v1_get_category,
183 ITF_Read_v1_get_read_group,
184 ITF_Read_v1_get_name,
185 ITF_Read_v1_get_bases,
186 ITF_Read_v1_get_quals,
187 ITF_Read_v1_next,
188
189 /* 1.1 */
190 ITF_Read_v1_frag_is_aligned
191 };
192
193 /*--------------------------------------------------------------------------
194 * NGS_Read
195 */
196 #define VT( self, msg ) \
197 ( ( ( const NGS_Read_vt* ) ( self ) -> dad . dad . vt ) -> msg )
198
NGS_ReadGetReadName(NGS_Read * self,ctx_t ctx)199 NGS_String * NGS_ReadGetReadName ( NGS_Read * self, ctx_t ctx )
200 {
201 if ( self == NULL )
202 {
203 FUNC_ENTRY ( ctx, rcSRA, rcDatabase, rcAccessing );
204 INTERNAL_ERROR ( xcSelfNull, "failed to get read name" );
205 }
206 else
207 {
208 return VT ( self, get_name ) ( self, ctx );
209 }
210
211 return NULL;
212 }
213
NGS_ReadGetReadId(NGS_Read * self,ctx_t ctx)214 NGS_String * NGS_ReadGetReadId ( NGS_Read * self, ctx_t ctx )
215 {
216 if ( self == NULL )
217 {
218 FUNC_ENTRY ( ctx, rcSRA, rcDatabase, rcAccessing );
219 INTERNAL_ERROR ( xcSelfNull, "failed to get read id" );
220 }
221 else
222 {
223 return VT ( self, get_id ) ( self, ctx );
224 }
225
226 return 0;
227 }
228
NGS_ReadGetReadGroup(NGS_Read * self,ctx_t ctx)229 NGS_String * NGS_ReadGetReadGroup ( NGS_Read * self, ctx_t ctx )
230 {
231 if ( self == NULL )
232 {
233 FUNC_ENTRY ( ctx, rcSRA, rcDatabase, rcAccessing );
234 INTERNAL_ERROR ( xcSelfNull, "failed to get read group" );
235 }
236 else
237 {
238 return VT ( self, get_read_group ) ( self, ctx );
239 }
240
241 return NULL;
242 }
243
NGS_ReadGetReadCategory(const NGS_Read * self,ctx_t ctx)244 enum NGS_ReadCategory NGS_ReadGetReadCategory ( const NGS_Read * self, ctx_t ctx )
245 {
246 if ( self == NULL )
247 {
248 FUNC_ENTRY ( ctx, rcSRA, rcDatabase, rcAccessing );
249 INTERNAL_ERROR ( xcSelfNull, "failed to get read category" );
250 }
251 else
252 {
253 return VT ( self, get_category ) ( self, ctx );
254 }
255
256 return NGS_ReadCategory_unaligned;
257 }
258
NGS_ReadGetReadSequence(NGS_Read * self,ctx_t ctx,uint64_t offset,uint64_t size)259 NGS_String * NGS_ReadGetReadSequence ( NGS_Read * self, ctx_t ctx, uint64_t offset, uint64_t size )
260 {
261 if ( self == NULL )
262 {
263 FUNC_ENTRY ( ctx, rcSRA, rcDatabase, rcAccessing );
264 INTERNAL_ERROR ( xcSelfNull, "failed to get read sequence" );
265 }
266 else
267 {
268 return VT ( self, get_sequence ) ( self, ctx, offset, size );
269 }
270
271 return NULL;
272 }
273
NGS_ReadGetReadQualities(NGS_Read * self,ctx_t ctx,uint64_t offset,uint64_t size)274 NGS_String * NGS_ReadGetReadQualities( NGS_Read * self, ctx_t ctx, uint64_t offset, uint64_t size )
275 {
276 if ( self == NULL )
277 {
278 FUNC_ENTRY ( ctx, rcSRA, rcDatabase, rcAccessing );
279 INTERNAL_ERROR ( xcSelfNull, "failed to get read qualities" );
280 }
281 else
282 {
283 return VT ( self, get_qualities ) ( self, ctx, offset, size );
284 }
285
286 return NULL;
287 }
288
NGS_ReadNumFragments(NGS_Read * self,ctx_t ctx)289 uint32_t NGS_ReadNumFragments ( NGS_Read * self, ctx_t ctx )
290 {
291 if ( self == NULL )
292 {
293 FUNC_ENTRY ( ctx, rcSRA, rcDatabase, rcAccessing );
294 INTERNAL_ERROR ( xcSelfNull, "failed to get read fragment count" );
295 }
296 else
297 {
298 return VT ( self, get_num_fragments ) ( self, ctx );
299 }
300
301 return 0;
302 }
303
NGS_ReadFragIsAligned(NGS_Read * self,ctx_t ctx,uint32_t frag_idx)304 bool NGS_ReadFragIsAligned ( NGS_Read * self, ctx_t ctx, uint32_t frag_idx )
305 {
306 if ( self == NULL )
307 {
308 FUNC_ENTRY ( ctx, rcSRA, rcDatabase, rcAccessing );
309 INTERNAL_ERROR ( xcSelfNull, "failed to test fragment alignment" );
310 }
311 else
312 {
313 return VT ( self, frag_is_aligned ) ( self, ctx, frag_idx );
314 }
315
316 return 0;
317 }
318
319 /*--------------------------------------------------------------------------
320 * NGS_ReadIterator
321 */
322
NGS_ReadIteratorNext(NGS_Read * self,ctx_t ctx)323 bool NGS_ReadIteratorNext ( NGS_Read * self, ctx_t ctx )
324 {
325 if ( self == NULL )
326 {
327 FUNC_ENTRY ( ctx, rcSRA, rcDatabase, rcAccessing );
328 INTERNAL_ERROR ( xcSelfNull, "failed to advance read iterator" );
329 }
330 else
331 {
332 return VT ( self, next ) ( self, ctx );
333 }
334
335 return false;
336 }
337
NGS_ReadIteratorGetCount(const NGS_Read * self,ctx_t ctx)338 uint64_t NGS_ReadIteratorGetCount ( const NGS_Read * self, ctx_t ctx )
339 {
340 if ( self == NULL )
341 {
342 FUNC_ENTRY ( ctx, rcSRA, rcDatabase, rcAccessing );
343 INTERNAL_ERROR ( xcSelfNull, "failed to get read iterator count" );
344 }
345 else
346 {
347 return VT ( self, get_count ) ( self, ctx );
348 }
349
350 return 0;
351 }
352
NGS_ReadInit(ctx_t ctx,NGS_Read * read,const NGS_Read_vt * vt,const char * clsname,const char * instname)353 void NGS_ReadInit ( ctx_t ctx, NGS_Read * read, const NGS_Read_vt * vt, const char *clsname, const char *instname )
354 {
355 FUNC_ENTRY ( ctx, rcSRA, rcRow, rcConstructing );
356
357 TRY ( NGS_FragmentInit ( ctx, & read -> dad, & ITF_Read_vt . dad, & vt -> dad, clsname, instname ) )
358 {
359 assert ( vt -> get_id != NULL );
360 assert ( vt -> get_name != NULL );
361 assert ( vt -> get_read_group != NULL );
362 assert ( vt -> get_category != NULL );
363 assert ( vt -> get_sequence != NULL );
364 assert ( vt -> get_qualities != NULL );
365 assert ( vt -> get_num_fragments != NULL );
366 }
367 }
368
NGS_ReadIteratorInit(ctx_t ctx,NGS_Read * read,const NGS_Read_vt * vt,const char * clsname,const char * instname)369 void NGS_ReadIteratorInit ( ctx_t ctx, NGS_Read * read, const NGS_Read_vt * vt, const char *clsname, const char *instname )
370 {
371 FUNC_ENTRY ( ctx, rcSRA, rcRow, rcConstructing );
372
373 TRY ( NGS_ReadInit ( ctx, read, vt, clsname, instname ) )
374 {
375 assert ( vt -> next != NULL );
376 assert ( vt -> get_count != NULL );
377 }
378 }
379
380 /*--------------------------------------------------------------------------
381 * NGS_NullRead
382 */
383
384 static
NullRead_ReadWhack(NGS_Read * self,ctx_t ctx)385 void NullRead_ReadWhack ( NGS_Read * self, ctx_t ctx )
386 {
387 }
388
389 static
NullRead_FragmentToString(NGS_Read * self,ctx_t ctx)390 struct NGS_String * NullRead_FragmentToString ( NGS_Read * self, ctx_t ctx )
391 {
392 FUNC_ENTRY ( ctx, rcSRA, rcCursor, rcAccessing);
393 INTERNAL_ERROR ( xcSelfNull, "NULL Alignment accessed" );
394 return 0;
395 }
396
397 static
NullRead_FragmentOffsetLenToString(NGS_Read * self,ctx_t ctx,uint64_t offset,uint64_t length)398 struct NGS_String * NullRead_FragmentOffsetLenToString ( NGS_Read * self, ctx_t ctx, uint64_t offset, uint64_t length )
399 {
400 FUNC_ENTRY ( ctx, rcSRA, rcCursor, rcAccessing);
401 INTERNAL_ERROR ( xcSelfNull, "NULL Alignment accessed" );
402 return 0;
403 }
404
405 static
NullRead_FragmentToBool(NGS_Read * self,ctx_t ctx)406 bool NullRead_FragmentToBool ( NGS_Read * self, ctx_t ctx )
407 {
408 FUNC_ENTRY ( ctx, rcSRA, rcCursor, rcAccessing);
409 INTERNAL_ERROR ( xcSelfNull, "NULL Alignment accessed" );
410 return 0;
411 }
412
413 static
NullRead_ReadToString(NGS_Read * self,ctx_t ctx)414 struct NGS_String * NullRead_ReadToString ( NGS_Read * self, ctx_t ctx )
415 {
416 FUNC_ENTRY ( ctx, rcSRA, rcCursor, rcAccessing);
417 INTERNAL_ERROR ( xcSelfNull, "NULL Alignment accessed" );
418 return 0;
419 }
420
421 static
NullRead_ConstReadToCategory(const NGS_Read * self,ctx_t ctx)422 enum NGS_ReadCategory NullRead_ConstReadToCategory ( const NGS_Read * self, ctx_t ctx )
423 {
424 FUNC_ENTRY ( ctx, rcSRA, rcCursor, rcAccessing);
425 INTERNAL_ERROR ( xcSelfNull, "NULL Alignment accessed" );
426 return 0;
427 }
428
NullRead_ReadOffsetLenToString(NGS_Read * self,ctx_t ctx,uint64_t offset,uint64_t length)429 static struct NGS_String * NullRead_ReadOffsetLenToString ( NGS_Read * self, ctx_t ctx, uint64_t offset, uint64_t length )
430 {
431 FUNC_ENTRY ( ctx, rcSRA, rcCursor, rcAccessing);
432 INTERNAL_ERROR ( xcSelfNull, "NULL Alignment accessed" );
433 return 0;
434 }
435
NullRead_ReadToU32(NGS_Read * self,ctx_t ctx)436 static uint32_t NullRead_ReadToU32 ( NGS_Read * self, ctx_t ctx )
437 {
438 FUNC_ENTRY ( ctx, rcSRA, rcCursor, rcAccessing);
439 INTERNAL_ERROR ( xcSelfNull, "NULL Alignment accessed" );
440 return 0;
441 }
442
NullRead_FragIsAligned(NGS_Read * self,ctx_t ctx,uint32_t frag_idx)443 static bool NullRead_FragIsAligned ( NGS_Read * self, ctx_t ctx, uint32_t frag_idx )
444 {
445 FUNC_ENTRY ( ctx, rcSRA, rcCursor, rcAccessing);
446 INTERNAL_ERROR ( xcSelfNull, "NULL Alignment accessed" );
447 return false;
448 }
449
NullRead_ReadToBool_NoError(NGS_Read * self,ctx_t ctx)450 static bool NullRead_ReadToBool_NoError ( NGS_Read * self, ctx_t ctx )
451 {
452 return false;
453 }
454
NullRead_ConstReadToU64_NoError(const NGS_Read * self,ctx_t ctx)455 static uint64_t NullRead_ConstReadToU64_NoError ( const NGS_Read * self, ctx_t ctx )
456 {
457 return 0;
458 }
459
460 static NGS_Read_vt NullRead_vt_inst =
461 {
462 {
463 {
464 /* NGS_Refcount */
465 NullRead_ReadWhack
466 },
467
468 /* NGS_Fragment */
469 NullRead_FragmentToString,
470 NullRead_FragmentOffsetLenToString,
471 NullRead_FragmentOffsetLenToString,
472 NullRead_FragmentToBool,
473 NullRead_FragmentToBool
474 },
475
476 /* NGS_Read */
477 NullRead_ReadToString, /* get-id */
478 NullRead_ReadToString, /* get-name */
479 NullRead_ReadToString, /* get-read-group */
480 NullRead_ConstReadToCategory, /* get-category */
481 NullRead_ReadOffsetLenToString, /* get-sequence */
482 NullRead_ReadOffsetLenToString, /* get-qualities */
483 NullRead_ReadToU32, /* get-num-frags */
484 NullRead_FragIsAligned, /* frag-is-aligned */
485
486 /* NGS_ReadIterator */
487 NullRead_ReadToBool_NoError, /* next */
488 NullRead_ConstReadToU64_NoError, /* get-count */
489 };
490
NGS_ReadMakeNull(ctx_t ctx,const NGS_String * run_name)491 struct NGS_Read * NGS_ReadMakeNull ( ctx_t ctx, const NGS_String * run_name )
492 {
493 FUNC_ENTRY ( ctx, rcSRA, rcCursor, rcConstructing );
494
495 NGS_Read * ref;
496
497 assert ( run_name != NULL );
498
499 ref = calloc ( 1, sizeof * ref );
500 if ( ref == NULL )
501 SYSTEM_ERROR ( xcNoMemory, "allocating NullRead on '%.*s'", NGS_StringSize ( run_name, ctx ), NGS_StringData ( run_name, ctx ) );
502 else
503 {
504 #if _DEBUGGING
505 char instname [ 256 ];
506 string_printf ( instname, sizeof instname, NULL, "%.*s(NULL)", NGS_StringSize ( run_name, ctx ), NGS_StringData ( run_name, ctx ) );
507 instname [ sizeof instname - 1 ] = 0;
508 #else
509 const char *instname = "";
510 #endif
511 TRY ( NGS_ReadInit ( ctx, ref, & NullRead_vt_inst, "NullRead", instname ) )
512 {
513 return ref;
514 }
515 free ( ref );
516 }
517
518 return NULL;
519 }
520
521
522
523