@@ -306,6 +306,150 @@ static PyObject *py2bitBases(pyTwoBit_t *self, PyObject *args, PyObject *kwds) {
306
306
return NULL ;
307
307
}
308
308
309
+ static PyObject * py2bitHardMaskedBlocks (pyTwoBit_t * self , PyObject * args , PyObject * kwds ) {
310
+ PyObject * ret = NULL , * tup = NULL ;
311
+ TwoBit * tb = self -> tb ;
312
+ char * chrom ;
313
+ unsigned long startl = 0 , endl = 0 , totalBlocks = 0 , tid ;
314
+ uint32_t start , end , len , blockStart , blockEnd , i , j ;
315
+ static char * kwd_list [] = {"chrom" , "start" , "end" , NULL };
316
+
317
+ if (!tb ) {
318
+ PyErr_SetString (PyExc_RuntimeError , "The 2bit file handle is not open!" );
319
+ return NULL ;
320
+ }
321
+
322
+ if (!PyArg_ParseTupleAndKeywords (args , kwds , "s|kk" , kwd_list , & chrom , & startl , & endl )) {
323
+ PyErr_SetString (PyExc_RuntimeError , "You must supply at least a chromosome!" );
324
+ return NULL ;
325
+ }
326
+
327
+ //Get the chromosome ID
328
+ for (i = 0 ; i < tb -> hdr -> nChroms ; i ++ ) {
329
+ if (strcmp (tb -> cl -> chrom [i ], chrom ) == 0 ) {
330
+ tid = i ;
331
+ break ;
332
+ }
333
+ }
334
+
335
+ len = twobitChromLen (tb , chrom );
336
+ if (len == 0 ) {
337
+ PyErr_SetString (PyExc_RuntimeError , "The specified chromosome doesn't exist in the 2bit file!" );
338
+ return NULL ;
339
+ }
340
+ if (endl == 0 ) endl = len ;
341
+ if (endl > len ) endl = len ;
342
+ end = (uint32_t ) endl ;
343
+ if (startl >= endl && startl > 0 ) {
344
+ PyErr_SetString (PyExc_RuntimeError , "The start value must be less then the end value (and the end of the chromosome" );
345
+ return NULL ;
346
+ }
347
+ start = (uint32_t ) startl ;
348
+
349
+ // Count the total number of overlapping N-masked blocks
350
+ for (i = 0 ; i < tb -> idx -> nBlockCount [tid ]; i ++ ) {
351
+ blockStart = tb -> idx -> nBlockStart [tid ][i ];
352
+ blockEnd = blockStart + tb -> idx -> nBlockSizes [tid ][i ];
353
+ if (blockStart < end && blockEnd > start ) totalBlocks ++ ;
354
+ }
355
+
356
+ // Form the output
357
+ ret = PyList_New (totalBlocks );
358
+ if (!ret ) goto error ;
359
+ if (totalBlocks == 0 ) return ret ;
360
+ for (i = 0 , j = 0 ; i < tb -> idx -> nBlockCount [tid ]; i ++ ) {
361
+ blockStart = tb -> idx -> nBlockStart [tid ][i ];
362
+ blockEnd = blockStart + tb -> idx -> nBlockSizes [tid ][i ];
363
+ if (blockStart < end && blockEnd > start ) {
364
+ tup = Py_BuildValue ("(kk)" , (unsigned long ) blockStart , (unsigned long ) blockEnd );
365
+ if (!tup ) goto error ;
366
+ if (PyList_SetItem (ret , j ++ , tup )) goto error ;
367
+ }
368
+ }
369
+
370
+ return ret ;
371
+
372
+ error :
373
+ if (ret ) Py_XDECREF (ret );
374
+ if (tup ) Py_XDECREF (tup );
375
+ PyErr_SetString (PyExc_RuntimeError , "Received an error while constructing the output list and tuples!" );
376
+ return NULL ;
377
+ }
378
+
379
+ static PyObject * py2bitSoftMaskedBlocks (pyTwoBit_t * self , PyObject * args , PyObject * kwds ) {
380
+ PyObject * ret = NULL , * tup = NULL ;
381
+ TwoBit * tb = self -> tb ;
382
+ char * chrom ;
383
+ unsigned long startl = 0 , endl = 0 , totalBlocks = 0 , tid ;
384
+ uint32_t start , end , len , blockStart , blockEnd , i , j ;
385
+ static char * kwd_list [] = {"chrom" , "start" , "end" , NULL };
386
+
387
+ if (!tb ) {
388
+ PyErr_SetString (PyExc_RuntimeError , "The 2bit file handle is not open!" );
389
+ return NULL ;
390
+ }
391
+
392
+ if (!PyArg_ParseTupleAndKeywords (args , kwds , "s|kk" , kwd_list , & chrom , & startl , & endl )) {
393
+ PyErr_SetString (PyExc_RuntimeError , "You must supply at least a chromosome!" );
394
+ return NULL ;
395
+ }
396
+
397
+ //Get the chromosome ID
398
+ for (i = 0 ; i < tb -> hdr -> nChroms ; i ++ ) {
399
+ if (strcmp (tb -> cl -> chrom [i ], chrom ) == 0 ) {
400
+ tid = i ;
401
+ break ;
402
+ }
403
+ }
404
+
405
+ len = twobitChromLen (tb , chrom );
406
+ if (len == 0 ) {
407
+ PyErr_SetString (PyExc_RuntimeError , "The specified chromosome doesn't exist in the 2bit file!" );
408
+ return NULL ;
409
+ }
410
+ if (endl == 0 ) endl = len ;
411
+ if (endl > len ) endl = len ;
412
+ end = (uint32_t ) endl ;
413
+ if (startl >= endl && startl > 0 ) {
414
+ PyErr_SetString (PyExc_RuntimeError , "The start value must be less then the end value (and the end of the chromosome" );
415
+ return NULL ;
416
+ }
417
+ start = (uint32_t ) startl ;
418
+
419
+ if (!tb -> idx -> maskBlockStart ) {
420
+ PyErr_SetString (PyExc_RuntimeError , "The file was not opened with storeMasked=True! Consequently, there are no stored soft-masked regions." );
421
+ return NULL ;
422
+ }
423
+
424
+ // Count the total number of overlapping soft-masked blocks
425
+ for (i = 0 ; i < tb -> idx -> maskBlockCount [tid ]; i ++ ) {
426
+ blockStart = tb -> idx -> maskBlockStart [tid ][i ];
427
+ blockEnd = blockStart + tb -> idx -> maskBlockSizes [tid ][i ];
428
+ if (blockStart < end && blockEnd > start ) totalBlocks ++ ;
429
+ }
430
+
431
+ // Form the output
432
+ ret = PyList_New (totalBlocks );
433
+ if (!ret ) goto error ;
434
+ if (totalBlocks == 0 ) return ret ;
435
+ for (i = 0 , j = 0 ; i < tb -> idx -> maskBlockCount [tid ]; i ++ ) {
436
+ blockStart = tb -> idx -> maskBlockStart [tid ][i ];
437
+ blockEnd = blockStart + tb -> idx -> maskBlockSizes [tid ][i ];
438
+ if (blockStart < end && blockEnd > start ) {
439
+ tup = Py_BuildValue ("(kk)" , (unsigned long ) blockStart , (unsigned long ) blockEnd );
440
+ if (!tup ) goto error ;
441
+ if (PyList_SetItem (ret , j ++ , tup )) goto error ;
442
+ }
443
+ }
444
+
445
+ return ret ;
446
+ error :
447
+ if (ret ) Py_XDECREF (ret );
448
+ if (tup ) Py_XDECREF (tup );
449
+ PyErr_SetString (PyExc_RuntimeError , "Received an error while constructing the output list and tuples!" );
450
+ return NULL ;
451
+ }
452
+
309
453
#if PY_MAJOR_VERSION >= 3
310
454
PyMODINIT_FUNC PyInit_py2bit (void ) {
311
455
PyObject * res ;
0 commit comments