1
1
/* synced_bcf_reader.c -- stream through multiple VCF files.
2
2
3
- Copyright (C) 2012-2023 Genome Research Ltd.
3
+ Copyright (C) 2012-2023, 2025 Genome Research Ltd.
4
4
5
5
Author: Petr Danecek <[email protected] >
6
6
@@ -69,6 +69,7 @@ typedef struct
69
69
{
70
70
sr_sort_t sort ;
71
71
int regions_overlap , targets_overlap ;
72
+ int * closefile ; // close htsfile with sync reader close or not
72
73
}
73
74
aux_t ;
74
75
@@ -251,13 +252,32 @@ void bcf_sr_destroy_threads(bcf_srs_t *files) {
251
252
int bcf_sr_add_reader (bcf_srs_t * files , const char * fname )
252
253
{
253
254
char fmode [5 ];
255
+ int ret = 0 ;
256
+ const char * idxname = NULL ;
257
+
254
258
strcpy (fmode , "r" );
255
259
vcf_open_mode (fmode + 1 , fname , NULL );
256
260
htsFile * file_ptr = hts_open (fname , fmode );
257
261
if ( ! file_ptr ) {
258
262
files -> errnum = open_failed ;
259
263
return 0 ;
260
264
}
265
+ //get idx name and pass to add_hreader
266
+ idxname = strstr (fname , HTS_IDX_DELIM );
267
+ idxname += idxname ? sizeof (HTS_IDX_DELIM ) - 1 : 0 ;
268
+ if (!(ret = bcf_sr_add_hreader (files , file_ptr , 1 , idxname ))) {
269
+ hts_close (file_ptr ); //failed, close the file
270
+ }
271
+ return ret ;
272
+ }
273
+
274
+ int bcf_sr_add_hreader (bcf_srs_t * files , htsFile * file_ptr , int autoclose , const char * idxname )
275
+ {
276
+ aux_t * auxdata = NULL ;
277
+ if ( ! file_ptr ) {
278
+ files -> errnum = open_failed ;
279
+ return 0 ;
280
+ }
261
281
262
282
files -> has_line = (int * ) realloc (files -> has_line , sizeof (int )* (files -> nreaders + 1 ));
263
283
files -> has_line [files -> nreaders ] = 0 ;
@@ -274,7 +294,7 @@ int bcf_sr_add_reader(bcf_srs_t *files, const char *fname)
274
294
BGZF * bgzf = hts_get_bgzfp (reader -> file );
275
295
if ( bgzf && bgzf_check_EOF (bgzf ) == 0 ) {
276
296
files -> errnum = no_eof ;
277
- hts_log_warning ("No BGZF EOF marker; file '%s' may be truncated" , fname );
297
+ hts_log_warning ("No BGZF EOF marker; file '%s' may be truncated" , file_ptr -> fn );
278
298
}
279
299
if (files -> p )
280
300
bgzf_thread_pool (bgzf , files -> p -> pool , files -> p -> qsize );
@@ -290,7 +310,7 @@ int bcf_sr_add_reader(bcf_srs_t *files, const char *fname)
290
310
return 0 ;
291
311
}
292
312
293
- reader -> tbx_idx = tbx_index_load ( fname );
313
+ reader -> tbx_idx = tbx_index_load2 ( file_ptr -> fn , idxname );
294
314
if ( !reader -> tbx_idx )
295
315
{
296
316
files -> errnum = idx_load_failed ;
@@ -309,7 +329,7 @@ int bcf_sr_add_reader(bcf_srs_t *files, const char *fname)
309
329
310
330
reader -> header = bcf_hdr_read (reader -> file );
311
331
312
- reader -> bcf_idx = bcf_index_load ( fname );
332
+ reader -> bcf_idx = bcf_index_load2 ( file_ptr -> fn , idxname );
313
333
if ( !reader -> bcf_idx )
314
334
{
315
335
files -> errnum = idx_load_failed ;
@@ -362,7 +382,7 @@ int bcf_sr_add_reader(bcf_srs_t *files, const char *fname)
362
382
return 0 ;
363
383
}
364
384
365
- reader -> fname = strdup (fname );
385
+ reader -> fname = strdup (file_ptr -> fn );
366
386
if ( files -> apply_filters )
367
387
reader -> filter_ids = init_filters (reader -> header , files -> apply_filters , & reader -> nfilter_ids );
368
388
@@ -413,6 +433,18 @@ int bcf_sr_add_reader(bcf_srs_t *files, const char *fname)
413
433
}
414
434
}
415
435
436
+ if ((auxdata = BCF_SR_AUX (files ))) {
437
+ //store closure status for htsfile
438
+ int * tmp = realloc (auxdata -> closefile , sizeof (int ) * files -> nreaders );
439
+ if (!tmp ) {
440
+ hts_log_error ("Failed to allocate memory" );
441
+ return 0 ;
442
+ }
443
+ tmp [files -> nreaders - 1 ] = autoclose ;
444
+ auxdata -> closefile = tmp ;
445
+ }
446
+
447
+
416
448
return 1 ;
417
449
}
418
450
@@ -426,13 +458,15 @@ bcf_srs_t *bcf_sr_init(void)
426
458
return files ;
427
459
}
428
460
429
- static void bcf_sr_destroy1 (bcf_sr_t * reader )
461
+ static void bcf_sr_destroy1 (bcf_sr_t * reader , int closefile )
430
462
{
431
463
free (reader -> fname );
432
464
if ( reader -> tbx_idx ) tbx_destroy (reader -> tbx_idx );
433
465
if ( reader -> bcf_idx ) hts_idx_destroy (reader -> bcf_idx );
434
466
bcf_hdr_destroy (reader -> header );
435
- hts_close (reader -> file );
467
+ if (closefile ) {
468
+ hts_close (reader -> file );
469
+ }
436
470
if ( reader -> itr ) tbx_itr_destroy (reader -> itr );
437
471
int j ;
438
472
for (j = 0 ; j < reader -> mbuffer ; j ++ )
@@ -445,8 +479,10 @@ static void bcf_sr_destroy1(bcf_sr_t *reader)
445
479
void bcf_sr_destroy (bcf_srs_t * files )
446
480
{
447
481
int i ;
482
+ int * autoclose = BCF_SR_AUX (files )-> closefile ;
483
+
448
484
for (i = 0 ; i < files -> nreaders ; i ++ )
449
- bcf_sr_destroy1 (& files -> readers [i ]);
485
+ bcf_sr_destroy1 (& files -> readers [i ], autoclose [ i ] );
450
486
free (files -> has_line );
451
487
free (files -> readers );
452
488
for (i = 0 ; i < files -> n_smpl ; i ++ ) free (files -> samples [i ]);
@@ -456,19 +492,23 @@ void bcf_sr_destroy(bcf_srs_t *files)
456
492
if (files -> tmps .m ) free (files -> tmps .s );
457
493
if (files -> n_threads ) bcf_sr_destroy_threads (files );
458
494
bcf_sr_sort_destroy (& BCF_SR_AUX (files )-> sort );
495
+ free (autoclose );
459
496
free (files -> aux );
460
497
free (files );
461
498
}
462
499
463
500
void bcf_sr_remove_reader (bcf_srs_t * files , int i )
464
501
{
465
502
assert ( !files -> samples ); // not ready for this yet
503
+ int * autoclose = BCF_SR_AUX (files )-> closefile ;
504
+
466
505
bcf_sr_sort_remove_reader (files , & BCF_SR_AUX (files )-> sort , i );
467
- bcf_sr_destroy1 (& files -> readers [i ]);
506
+ bcf_sr_destroy1 (& files -> readers [i ], autoclose [ i ] );
468
507
if ( i + 1 < files -> nreaders )
469
508
{
470
509
memmove (& files -> readers [i ], & files -> readers [i + 1 ], (files -> nreaders - i - 1 )* sizeof (bcf_sr_t ));
471
510
memmove (& files -> has_line [i ], & files -> has_line [i + 1 ], (files -> nreaders - i - 1 )* sizeof (int ));
511
+ memmove (& autoclose [i ], & autoclose [i + 1 ], (files -> nreaders - i - 1 )* sizeof (int ));
472
512
}
473
513
files -> nreaders -- ;
474
514
}
0 commit comments