77#include "numpy/npy_common.h"
88#include "numpy/halffloat.h"
99#include "numpy/ndarrayobject.h"
10+ #include "numpy/arrayscalars.h"
1011
1112int lsize = NPY_SIZEOF_LONG ;
1213
@@ -79,6 +80,52 @@ uint32_t getNumpyU32(PyArrayObject *obj, Py_ssize_t i) {
7980 return 0 ;
8081};
8182
83+ long getNumpyL (PyObject * obj ) {
84+ short s ;
85+ int i ;
86+ long l ;
87+ long long ll ;
88+ unsigned short us ;
89+ unsigned int ui ;
90+ unsigned long ul ;
91+ unsigned long long ull ;
92+
93+ if (!PyArray_IsIntegerScalar (obj )) {
94+ PyErr_SetString (PyExc_RuntimeError , "Received non-Integer scalar type for conversion to long!\n" );
95+ return 0 ;
96+ }
97+
98+ if (PyArray_IsScalar (obj , Short )) {
99+ s = ((PyShortScalarObject * )obj )-> obval ;
100+ l = s ;
101+ } else if (PyArray_IsScalar (obj , Int )) {
102+ i = ((PyLongScalarObject * )obj )-> obval ;
103+ l = i ;
104+ } else if (PyArray_IsScalar (obj , Long )) {
105+ l = ((PyLongScalarObject * )obj )-> obval ;
106+ } else if (PyArray_IsScalar (obj , LongLong )) {
107+ ll = ((PyLongScalarObject * )obj )-> obval ;
108+ l = ll ;
109+ } else if (PyArray_IsScalar (obj , UShort )) {
110+ us = ((PyLongScalarObject * )obj )-> obval ;
111+ l = us ;
112+ } else if (PyArray_IsScalar (obj , UInt )) {
113+ ui = ((PyLongScalarObject * )obj )-> obval ;
114+ l = ui ;
115+ } else if (PyArray_IsScalar (obj , ULong )) {
116+ ul = ((PyLongScalarObject * )obj )-> obval ;
117+ l = ul ;
118+ } else if (PyArray_IsScalar (obj , ULongLong )) {
119+ ull = ((PyLongScalarObject * )obj )-> obval ;
120+ l = ull ;
121+ } else {
122+ PyErr_SetString (PyExc_RuntimeError , "Received unknown scalar type for conversion to long!\n" );
123+ return 0 ;
124+ }
125+
126+ return l ;
127+ }
128+
82129//Raises an exception on error, which should be checked
83130float getNumpyF (PyArrayObject * obj , Py_ssize_t i ) {
84131 int dtype ;
@@ -324,7 +371,7 @@ static PyObject *pyBwGetStats(pyBigWigFile_t *self, PyObject *args, PyObject *kw
324371 unsigned long startl = 0 , endl = -1 ;
325372 static char * kwd_list [] = {"chrom" , "start" , "end" , "type" , "nBins" , "exact" , NULL };
326373 char * chrom , * type = "mean" ;
327- PyObject * ret , * exact = Py_False ;
374+ PyObject * ret , * exact = Py_False , * starto = NULL , * endo = NULL ;
328375 int i , nBins = 1 ;
329376 errno = 0 ; //In the off-chance that something elsewhere got an error and didn't clear it...
330377
@@ -338,7 +385,7 @@ static PyObject *pyBwGetStats(pyBigWigFile_t *self, PyObject *args, PyObject *kw
338385 return NULL ;
339386 }
340387
341- if (!PyArg_ParseTupleAndKeywords (args , kwds , "s|kksiO " , kwd_list , & chrom , & startl , & endl , & type , & nBins , & exact )) {
388+ if (!PyArg_ParseTupleAndKeywords (args , kwds , "s|OOsiO " , kwd_list , & chrom , & starto , & endo , & type , & nBins , & exact )) {
342389 PyErr_SetString (PyExc_RuntimeError , "You must supply at least a chromosome!" );
343390 return NULL ;
344391 }
@@ -347,6 +394,43 @@ static PyObject *pyBwGetStats(pyBigWigFile_t *self, PyObject *args, PyObject *kw
347394 if (!nBins ) nBins = 1 ; //For some reason, not specifying this overrides the default!
348395 if (!type ) type = "mean" ;
349396 tid = bwGetTid (bw , chrom );
397+
398+ if (starto ) {
399+ #ifdef WITHNUMPY
400+ if (PyArray_IsScalar (starto , Integer )) {
401+ startl = (long ) getNumpyL (starto );
402+ } else
403+ #endif
404+ if (PyLong_Check (starto )) {
405+ startl = PyLong_AsLong (starto );
406+ #if PY_MAJOR_VERSION < 3
407+ } else if (PyInt_Check (starto )) {
408+ startl = PyInt_AsLong (starto );
409+ #endif
410+ } else {
411+ PyErr_SetString (PyExc_RuntimeError , "The start coordinate must be a number!" );
412+ return NULL ;
413+ }
414+ }
415+
416+ if (endo ) {
417+ #ifdef WITHNUMPY
418+ if (PyArray_IsScalar (endo , Integer )) {
419+ endl = (long ) getNumpyL (endo );
420+ } else
421+ #endif
422+ if (PyLong_Check (endo )) {
423+ endl = PyLong_AsLong (endo );
424+ #if PY_MAJOR_VERSION < 3
425+ } else if (PyInt_Check (endo )) {
426+ endl = PyInt_AsLong (endo );
427+ #endif
428+ } else {
429+ PyErr_SetString (PyExc_RuntimeError , "The end coordinate must be a number!" );
430+ return NULL ;
431+ }
432+ }
433+
350434 if (endl == (unsigned long ) -1 && tid != (uint32_t ) -1 ) endl = bw -> cl -> len [tid ];
351435 if (tid == (uint32_t ) -1 || startl > end || endl > end ) {
352436 PyErr_SetString (PyExc_RuntimeError , "Invalid interval bounds!" );
@@ -412,7 +496,7 @@ static PyObject *pyBwGetValues(pyBigWigFile_t *self, PyObject *args) {
412496 uint32_t start , end = -1 , tid ;
413497 unsigned long startl , endl ;
414498 char * chrom ;
415- PyObject * ret ;
499+ PyObject * ret , * starto = NULL , * endo = NULL ;
416500 bwOverlappingIntervals_t * o ;
417501
418502 if (!bw ) {
@@ -429,20 +513,54 @@ static PyObject *pyBwGetValues(pyBigWigFile_t *self, PyObject *args) {
429513 static char * kwd_list [] = {"chrom" , "start" , "end" , "numpy" , NULL };
430514 PyObject * outputNumpy = Py_False ;
431515
432- if (!PyArg_ParseTupleAndKeywords (args , kwds , "skk |O" , kwd_list , & chrom , & startl , & endl , & outputNumpy )) {
516+ if (!PyArg_ParseTupleAndKeywords (args , kwds , "sOO |O" , kwd_list , & chrom , & starto , & endo , & outputNumpy )) {
433517#else
434- if (!PyArg_ParseTuple (args , "skk " , & chrom , & startl , & endl )) {
518+ if (!PyArg_ParseTuple (args , "sOO " , & chrom , & starto , & endo )) {
435519#endif
436520 PyErr_SetString (PyExc_RuntimeError , "You must supply a chromosome, start and end position.\n" );
437521 return NULL ;
438522 }
439523
440524 tid = bwGetTid (bw , chrom );
525+
526+ #ifdef WITHNUMPY
527+ if (PyArray_IsScalar (starto , Integer )) {
528+ startl = (long ) getNumpyL (starto );
529+ } else
530+ #endif
531+ if (PyLong_Check (starto )) {
532+ startl = PyLong_AsLong (starto );
533+ #if PY_MAJOR_VERSION < 3
534+ } else if (PyInt_Check (starto )) {
535+ startl = PyInt_AsLong (starto );
536+ #endif
537+ } else {
538+ PyErr_SetString (PyExc_RuntimeError , "The start coordinate must be a number!" );
539+ return NULL ;
540+ }
541+
542+ #ifdef WITHNUMPY
543+ if (PyArray_IsScalar (endo , Integer )) {
544+ endl = (long ) getNumpyL (endo );
545+ } else
546+ #endif
547+ if (PyLong_Check (endo )) {
548+ endl = PyLong_AsLong (endo );
549+ #if PY_MAJOR_VERSION < 3
550+ } else if (PyInt_Check (endo )) {
551+ endl = PyInt_AsLong (endo );
552+ #endif
553+ } else {
554+ PyErr_SetString (PyExc_RuntimeError , "The end coordinate must be a number!" );
555+ return NULL ;
556+ }
557+
441558 if (endl == (unsigned long ) -1 && tid != (uint32_t ) -1 ) endl = bw -> cl -> len [tid ];
442559 if (tid == (uint32_t ) -1 || startl > end || endl > end ) {
443560 PyErr_SetString (PyExc_RuntimeError , "Invalid interval bounds!" );
444561 return NULL ;
445562 }
563+
446564 start = (uint32_t ) startl ;
447565 end = (uint32_t ) endl ;
448566 if (end <= start || end > bw -> cl -> len [tid ] || start >= end ) {
@@ -496,7 +614,7 @@ static PyObject *pyBwGetIntervals(pyBigWigFile_t *self, PyObject *args, PyObject
496614 static char * kwd_list [] = {"chrom" , "start" , "end" , NULL };
497615 bwOverlappingIntervals_t * intervals = NULL ;
498616 char * chrom ;
499- PyObject * ret ;
617+ PyObject * ret , * starto = NULL , * endo = NULL ;
500618
501619 if (!bw ) {
502620 PyErr_SetString (PyExc_RuntimeError , "The bigWig file handle is not opened!" );
@@ -508,7 +626,7 @@ static PyObject *pyBwGetIntervals(pyBigWigFile_t *self, PyObject *args, PyObject
508626 return NULL ;
509627 }
510628
511- if (!PyArg_ParseTupleAndKeywords (args , kwds , "s|kk " , kwd_list , & chrom , & startl , & endl )) {
629+ if (!PyArg_ParseTupleAndKeywords (args , kwds , "s|OO " , kwd_list , & chrom , & starto , & endo )) {
512630 PyErr_SetString (PyExc_RuntimeError , "You must supply at least a chromosome.\n" );
513631 return NULL ;
514632 }
@@ -520,6 +638,43 @@ static PyObject *pyBwGetIntervals(pyBigWigFile_t *self, PyObject *args, PyObject
520638 PyErr_SetString (PyExc_RuntimeError , "Invalid interval bounds!" );
521639 return NULL ;
522640 }
641+
642+ if (starto ) {
643+ #ifdef WITHNUMPY
644+ if (PyArray_IsScalar (starto , Integer )) {
645+ startl = (long ) getNumpyL (starto );
646+ } else
647+ #endif
648+ if (PyLong_Check (starto )) {
649+ startl = PyLong_AsLong (starto );
650+ #if PY_MAJOR_VERSION < 3
651+ } else if (PyInt_Check (starto )) {
652+ startl = PyInt_AsLong (starto );
653+ #endif
654+ } else {
655+ PyErr_SetString (PyExc_RuntimeError , "The start coordinate must be a number!" );
656+ return NULL ;
657+ }
658+ }
659+
660+ if (endo ) {
661+ #ifdef WITHNUMPY
662+ if (PyArray_IsScalar (endo , Integer )) {
663+ endl = (long ) getNumpyL (endo );
664+ } else
665+ #endif
666+ if (PyLong_Check (endo )) {
667+ endl = PyLong_AsLong (endo );
668+ #if PY_MAJOR_VERSION < 3
669+ } else if (PyInt_Check (endo )) {
670+ endl = PyInt_AsLong (endo );
671+ #endif
672+ } else {
673+ PyErr_SetString (PyExc_RuntimeError , "The end coordinate must be a number!" );
674+ return NULL ;
675+ }
676+ }
677+
523678 start = (uint32_t ) startl ;
524679 end = (uint32_t ) endl ;
525680 if (end <= start || end > bw -> cl -> len [tid ] || start >= end ) {
@@ -1548,7 +1703,7 @@ static PyObject *pyBBGetEntries(pyBigWigFile_t *self, PyObject *args, PyObject *
15481703 unsigned long startl , endl ;
15491704 char * chrom ;
15501705 static char * kwd_list [] = {"chrom" , "start" , "end" , "withString" , NULL };
1551- PyObject * ret , * t ;
1706+ PyObject * ret , * t , * starto = NULL , * endo = NULL ;
15521707 PyObject * withStringPy = Py_True ;
15531708 int withString = 1 ;
15541709 bbOverlappingEntries_t * o ;
@@ -1563,12 +1718,45 @@ static PyObject *pyBBGetEntries(pyBigWigFile_t *self, PyObject *args, PyObject *
15631718 return NULL ;
15641719 }
15651720
1566- if (!PyArg_ParseTupleAndKeywords (args , kwds , "skk |O" , kwd_list , & chrom , & startl , & endl , & withStringPy )) {
1721+ if (!PyArg_ParseTupleAndKeywords (args , kwds , "sOO |O" , kwd_list , & chrom , & starto , & endo , & withStringPy )) {
15671722 PyErr_SetString (PyExc_RuntimeError , "You must supply a chromosome, start and end position.\n" );
15681723 return NULL ;
15691724 }
15701725
15711726 tid = bwGetTid (bw , chrom );
1727+
1728+ #ifdef WITHNUMPY
1729+ if (PyArray_IsScalar (starto , Integer )) {
1730+ startl = (long ) getNumpyL (starto );
1731+ } else
1732+ #endif
1733+ if (PyLong_Check (starto )) {
1734+ startl = PyLong_AsLong (starto );
1735+ #if PY_MAJOR_VERSION < 3
1736+ } else if (PyInt_Check (starto )) {
1737+ startl = PyInt_AsLong (starto );
1738+ #endif
1739+ } else {
1740+ PyErr_SetString (PyExc_RuntimeError , "The start coordinate must be a number!" );
1741+ return NULL ;
1742+ }
1743+
1744+ #ifdef WITHNUMPY
1745+ if (PyArray_IsScalar (endo , Integer )) {
1746+ endl = (long ) getNumpyL (endo );
1747+ } else
1748+ #endif
1749+ if (PyLong_Check (endo )) {
1750+ endl = PyLong_AsLong (endo );
1751+ #if PY_MAJOR_VERSION < 3
1752+ } else if (PyInt_Check (endo )) {
1753+ endl = PyInt_AsLong (endo );
1754+ #endif
1755+ } else {
1756+ PyErr_SetString (PyExc_RuntimeError , "The end coordinate must be a number!" );
1757+ return NULL ;
1758+ }
1759+
15721760 if (endl == (unsigned long ) -1 && tid != (uint32_t ) -1 ) endl = bw -> cl -> len [tid ];
15731761 if (tid == (uint32_t ) -1 || startl > end || endl > end ) {
15741762 PyErr_SetString (PyExc_RuntimeError , "Invalid interval bounds!" );
0 commit comments