Skip to content
Commits on Source (6)
Metadata-Version: 1.1
Metadata-Version: 2.1
Name: pyBigWig
Version: 0.3.11
Version: 0.3.12
Summary: A package for accessing bigWig files using libBigWig
Home-page: https://github.com/dpryan79/pyBigWig
Author: Devon P. Ryan
Author-email: ryan@ie-freiburg.mpg.de
License: UNKNOWN
Download-URL: https://github.com/dpryan79/pyBigWig/tarball/0.3.11
Description-Content-Type: UNKNOWN
Description: UNKNOWN
Keywords: bioinformatics,bigWig,bigBed
Platform: UNKNOWN
Provides-Extra: numpy input
pybigwig (0.3.12-1) unstable; urgency=medium
* New upstream release.
-- Diane Trout <diane@ghic.org> Mon, 15 Oct 2018 21:30:28 -0700
pybigwig (0.3.11-1) unstable; urgency=medium
* New upstream release.
......
......@@ -13,7 +13,9 @@ Build-Depends: debhelper (>= 11),
python3-all-dev,
python3-numpy,
python3-setuptools
Standards-Version: 4.1.4
Standards-Version: 4.2.1
Vcs-Git: https://salsa.debian.org/med-team/pybigwig.git
Vcs-Browser: https://salsa.debian.org/med-team/pybigwig
Section: science
Homepage: https://github.com/dpryan79/pyBigWig
......
......@@ -4,7 +4,7 @@ Test-Command: set -e
; $py test.py
; cd ..
; done
Depends: python-pybigwig
Depends: python-pybigwig, python-all
Test-Command: set -e
; for py in $(py3versions -r 2>/dev/null)
......@@ -12,4 +12,4 @@ Test-Command: set -e
; $py test.py
; cd ..
; done
Depends: python3-pybigwig
Depends: python3-pybigwig, python3-all
......@@ -7,6 +7,7 @@
#include "numpy/npy_common.h"
#include "numpy/halffloat.h"
#include "numpy/ndarrayobject.h"
#include "numpy/arrayscalars.h"
int lsize = NPY_SIZEOF_LONG;
......@@ -79,6 +80,52 @@ error:
return 0;
};
long getNumpyL(PyObject *obj) {
short s;
int i;
long l;
long long ll;
unsigned short us;
unsigned int ui;
unsigned long ul;
unsigned long long ull;
if(!PyArray_IsIntegerScalar(obj)) {
PyErr_SetString(PyExc_RuntimeError, "Received non-Integer scalar type for conversion to long!\n");
return 0;
}
if(PyArray_IsScalar(obj, Short)) {
s = ((PyShortScalarObject *)obj)->obval;
l = s;
} else if(PyArray_IsScalar(obj, Int)) {
i = ((PyLongScalarObject *)obj)->obval;
l = i;
} else if(PyArray_IsScalar(obj, Long)) {
l = ((PyLongScalarObject *)obj)->obval;
} else if(PyArray_IsScalar(obj, LongLong)) {
ll = ((PyLongScalarObject *)obj)->obval;
l = ll;
} else if(PyArray_IsScalar(obj, UShort)) {
us = ((PyLongScalarObject *)obj)->obval;
l = us;
} else if(PyArray_IsScalar(obj, UInt)) {
ui = ((PyLongScalarObject *)obj)->obval;
l = ui;
} else if(PyArray_IsScalar(obj, ULong)) {
ul = ((PyLongScalarObject *)obj)->obval;
l = ul;
} else if(PyArray_IsScalar(obj, ULongLong)) {
ull = ((PyLongScalarObject *)obj)->obval;
l = ull;
} else {
PyErr_SetString(PyExc_RuntimeError, "Received unknown scalar type for conversion to long!\n");
return 0;
}
return l;
}
//Raises an exception on error, which should be checked
float getNumpyF(PyArrayObject *obj, Py_ssize_t i) {
int dtype;
......@@ -324,7 +371,7 @@ static PyObject *pyBwGetStats(pyBigWigFile_t *self, PyObject *args, PyObject *kw
unsigned long startl = 0, endl = -1;
static char *kwd_list[] = {"chrom", "start", "end", "type", "nBins", "exact", NULL};
char *chrom, *type = "mean";
PyObject *ret, *exact = Py_False;
PyObject *ret, *exact = Py_False, *starto = NULL, *endo = NULL;
int i, nBins = 1;
errno = 0; //In the off-chance that something elsewhere got an error and didn't clear it...
......@@ -338,7 +385,7 @@ static PyObject *pyBwGetStats(pyBigWigFile_t *self, PyObject *args, PyObject *kw
return NULL;
}
if(!PyArg_ParseTupleAndKeywords(args, kwds, "s|kksiO", kwd_list, &chrom, &startl, &endl, &type, &nBins, &exact)) {
if(!PyArg_ParseTupleAndKeywords(args, kwds, "s|OOsiO", kwd_list, &chrom, &starto, &endo, &type, &nBins, &exact)) {
PyErr_SetString(PyExc_RuntimeError, "You must supply at least a chromosome!");
return NULL;
}
......@@ -347,6 +394,43 @@ static PyObject *pyBwGetStats(pyBigWigFile_t *self, PyObject *args, PyObject *kw
if(!nBins) nBins = 1; //For some reason, not specifying this overrides the default!
if(!type) type = "mean";
tid = bwGetTid(bw, chrom);
if(starto) {
#ifdef WITHNUMPY
if(PyArray_IsScalar(starto, Integer)) {
startl = (long) getNumpyL(starto);
} else
#endif
if(PyLong_Check(starto)) {
startl = PyLong_AsLong(starto);
#if PY_MAJOR_VERSION < 3
} else if(PyInt_Check(starto)) {
startl = PyInt_AsLong(starto);
#endif
} else {
PyErr_SetString(PyExc_RuntimeError, "The start coordinate must be a number!");
return NULL;
}
}
if(endo) {
#ifdef WITHNUMPY
if(PyArray_IsScalar(endo, Integer)) {
endl = (long) getNumpyL(endo);
} else
#endif
if(PyLong_Check(endo)) {
endl = PyLong_AsLong(endo);
#if PY_MAJOR_VERSION < 3
} else if(PyInt_Check(endo)) {
endl = PyInt_AsLong(endo);
#endif
} else {
PyErr_SetString(PyExc_RuntimeError, "The end coordinate must be a number!");
return NULL;
}
}
if(endl == (unsigned long) -1 && tid != (uint32_t) -1) endl = bw->cl->len[tid];
if(tid == (uint32_t) -1 || startl > end || endl > end) {
PyErr_SetString(PyExc_RuntimeError, "Invalid interval bounds!");
......@@ -412,7 +496,7 @@ static PyObject *pyBwGetValues(pyBigWigFile_t *self, PyObject *args) {
uint32_t start, end = -1, tid;
unsigned long startl, endl;
char *chrom;
PyObject *ret;
PyObject *ret, *starto = NULL, *endo = NULL;
bwOverlappingIntervals_t *o;
if(!bw) {
......@@ -429,20 +513,54 @@ static PyObject *pyBwGetValues(pyBigWigFile_t *self, PyObject *args) {
static char *kwd_list[] = {"chrom", "start", "end", "numpy", NULL};
PyObject *outputNumpy = Py_False;
if(!PyArg_ParseTupleAndKeywords(args, kwds, "skk|O", kwd_list, &chrom, &startl, &endl, &outputNumpy)) {
if(!PyArg_ParseTupleAndKeywords(args, kwds, "sOO|O", kwd_list, &chrom, &starto, &endo, &outputNumpy)) {
#else
if(!PyArg_ParseTuple(args, "skk", &chrom, &startl, &endl)) {
if(!PyArg_ParseTuple(args, "sOO", &chrom, &starto, &endo)) {
#endif
PyErr_SetString(PyExc_RuntimeError, "You must supply a chromosome, start and end position.\n");
return NULL;
}
tid = bwGetTid(bw, chrom);
#ifdef WITHNUMPY
if(PyArray_IsScalar(starto, Integer)) {
startl = (long) getNumpyL(starto);
} else
#endif
if(PyLong_Check(starto)) {
startl = PyLong_AsLong(starto);
#if PY_MAJOR_VERSION < 3
} else if(PyInt_Check(starto)) {
startl = PyInt_AsLong(starto);
#endif
} else {
PyErr_SetString(PyExc_RuntimeError, "The start coordinate must be a number!");
return NULL;
}
#ifdef WITHNUMPY
if(PyArray_IsScalar(endo, Integer)) {
endl = (long) getNumpyL(endo);
} else
#endif
if(PyLong_Check(endo)) {
endl = PyLong_AsLong(endo);
#if PY_MAJOR_VERSION < 3
} else if(PyInt_Check(endo)) {
endl = PyInt_AsLong(endo);
#endif
} else {
PyErr_SetString(PyExc_RuntimeError, "The end coordinate must be a number!");
return NULL;
}
if(endl == (unsigned long) -1 && tid != (uint32_t) -1) endl = bw->cl->len[tid];
if(tid == (uint32_t) -1 || startl > end || endl > end) {
PyErr_SetString(PyExc_RuntimeError, "Invalid interval bounds!");
return NULL;
}
start = (uint32_t) startl;
end = (uint32_t) endl;
if(end <= start || end > bw->cl->len[tid] || start >= end) {
......@@ -496,7 +614,7 @@ static PyObject *pyBwGetIntervals(pyBigWigFile_t *self, PyObject *args, PyObject
static char *kwd_list[] = {"chrom", "start", "end", NULL};
bwOverlappingIntervals_t *intervals = NULL;
char *chrom;
PyObject *ret;
PyObject *ret, *starto = NULL, *endo = NULL;
if(!bw) {
PyErr_SetString(PyExc_RuntimeError, "The bigWig file handle is not opened!");
......@@ -508,7 +626,7 @@ static PyObject *pyBwGetIntervals(pyBigWigFile_t *self, PyObject *args, PyObject
return NULL;
}
if(!PyArg_ParseTupleAndKeywords(args, kwds, "s|kk", kwd_list, &chrom, &startl, &endl)) {
if(!PyArg_ParseTupleAndKeywords(args, kwds, "s|OO", kwd_list, &chrom, &starto, &endo)) {
PyErr_SetString(PyExc_RuntimeError, "You must supply at least a chromosome.\n");
return NULL;
}
......@@ -520,6 +638,43 @@ static PyObject *pyBwGetIntervals(pyBigWigFile_t *self, PyObject *args, PyObject
PyErr_SetString(PyExc_RuntimeError, "Invalid interval bounds!");
return NULL;
}
if(starto) {
#ifdef WITHNUMPY
if(PyArray_IsScalar(starto, Integer)) {
startl = (long) getNumpyL(starto);
} else
#endif
if(PyLong_Check(starto)) {
startl = PyLong_AsLong(starto);
#if PY_MAJOR_VERSION < 3
} else if(PyInt_Check(starto)) {
startl = PyInt_AsLong(starto);
#endif
} else {
PyErr_SetString(PyExc_RuntimeError, "The start coordinate must be a number!");
return NULL;
}
}
if(endo) {
#ifdef WITHNUMPY
if(PyArray_IsScalar(endo, Integer)) {
endl = (long) getNumpyL(endo);
} else
#endif
if(PyLong_Check(endo)) {
endl = PyLong_AsLong(endo);
#if PY_MAJOR_VERSION < 3
} else if(PyInt_Check(endo)) {
endl = PyInt_AsLong(endo);
#endif
} else {
PyErr_SetString(PyExc_RuntimeError, "The end coordinate must be a number!");
return NULL;
}
}
start = (uint32_t) startl;
end = (uint32_t) endl;
if(end <= start || end > bw->cl->len[tid] || start >= end) {
......@@ -1548,7 +1703,7 @@ static PyObject *pyBBGetEntries(pyBigWigFile_t *self, PyObject *args, PyObject *
unsigned long startl, endl;
char *chrom;
static char *kwd_list[] = {"chrom", "start", "end", "withString", NULL};
PyObject *ret, *t;
PyObject *ret, *t, *starto = NULL, *endo = NULL;
PyObject *withStringPy = Py_True;
int withString = 1;
bbOverlappingEntries_t *o;
......@@ -1563,12 +1718,45 @@ static PyObject *pyBBGetEntries(pyBigWigFile_t *self, PyObject *args, PyObject *
return NULL;
}
if(!PyArg_ParseTupleAndKeywords(args, kwds, "skk|O", kwd_list, &chrom, &startl, &endl, &withStringPy)) {
if(!PyArg_ParseTupleAndKeywords(args, kwds, "sOO|O", kwd_list, &chrom, &starto, &endo, &withStringPy)) {
PyErr_SetString(PyExc_RuntimeError, "You must supply a chromosome, start and end position.\n");
return NULL;
}
tid = bwGetTid(bw, chrom);
#ifdef WITHNUMPY
if(PyArray_IsScalar(starto, Integer)) {
startl = (long) getNumpyL(starto);
} else
#endif
if(PyLong_Check(starto)) {
startl = PyLong_AsLong(starto);
#if PY_MAJOR_VERSION < 3
} else if(PyInt_Check(starto)) {
startl = PyInt_AsLong(starto);
#endif
} else {
PyErr_SetString(PyExc_RuntimeError, "The start coordinate must be a number!");
return NULL;
}
#ifdef WITHNUMPY
if(PyArray_IsScalar(endo, Integer)) {
endl = (long) getNumpyL(endo);
} else
#endif
if(PyLong_Check(endo)) {
endl = PyLong_AsLong(endo);
#if PY_MAJOR_VERSION < 3
} else if(PyInt_Check(endo)) {
endl = PyInt_AsLong(endo);
#endif
} else {
PyErr_SetString(PyExc_RuntimeError, "The end coordinate must be a number!");
return NULL;
}
if(endl == (unsigned long) -1 && tid != (uint32_t) -1) endl = bw->cl->len[tid];
if(tid == (uint32_t) -1 || startl > end || endl > end) {
PyErr_SetString(PyExc_RuntimeError, "Invalid interval bounds!");
......
......@@ -2,7 +2,7 @@
#include <structmember.h>
#include "bigWig.h"
#define pyBigWigVersion "0.3.11"
#define pyBigWigVersion "0.3.12"
typedef struct {
PyObject_HEAD
......
......@@ -3,6 +3,7 @@ import tempfile
import os
import sys
import hashlib
import numpy as np
class TestRemote():
fname = "http://raw.githubusercontent.com/dpryan79/pyBigWig/master/pyBigWigTest/test.bw"
......@@ -28,14 +29,17 @@ class TestRemote():
assert(bw.stats("1", 0, 3) == [0.2000000054637591])
assert(bw.stats("1", 0, 3, type="max") == [0.30000001192092896])
assert(bw.stats("1",99,200, type="max", nBins=2) == [1.399999976158142, 1.5])
assert(bw.stats("1",np.int64(99), np.int64(200), type="max", nBins=2) == [1.399999976158142, 1.5])
assert(bw.stats("1") == [1.3351851569281683])
def doValues(self, bw):
assert(bw.values("1", 0, 3) == [0.10000000149011612, 0.20000000298023224, 0.30000001192092896])
assert(bw.values("1", np.int64(0), np.int64(3)) == [0.10000000149011612, 0.20000000298023224, 0.30000001192092896])
#assert(bw.values("1", 0, 4) == [0.10000000149011612, 0.20000000298023224, 0.30000001192092896, 'nan'])
def doIntervals(self, bw):
assert(bw.intervals("1", 0, 3) == ((0, 1, 0.10000000149011612), (1, 2, 0.20000000298023224), (2, 3, 0.30000001192092896)))
assert(bw.intervals("1", np.int64(0), np.int64(3)) == ((0, 1, 0.10000000149011612), (1, 2, 0.20000000298023224), (2, 3, 0.30000001192092896)))
assert(bw.intervals("1") == ((0, 1, 0.10000000149011612), (1, 2, 0.20000000298023224), (2, 3, 0.30000001192092896), (100, 150, 1.399999976158142), (150, 151, 1.5)))
def doSum(self, bw):
......@@ -161,7 +165,6 @@ class TestRemote():
os.remove(oname)
def doWriteNumpy(self):
import numpy as np
ofile = tempfile.NamedTemporaryFile(delete=False)
oname = ofile.name
ofile.close()
......@@ -237,6 +240,8 @@ class TestBigBed():
o = bb.entries('chr1',10000000,10020000)
expected = [(10009333, 10009640, '61035\t130\t-\t0.026\t0.42\t404'), (10014007, 10014289, '61047\t136\t-\t0.029\t0.42\t404'), (10014373, 10024307, '61048\t630\t-\t5.420\t0.00\t2672399')]
assert(o == expected)
o = bb.entries('chr1',np.int64(10000000),np.int64(10020000))
assert(o == expected)
bb.close()
class TestNumpy():
......
......@@ -15,7 +15,7 @@ srcs = [x for x in
glob.glob("libBigWig/*.c")]
srcs.append("pyBigWig.c")
libs=["m", "z", "curl"]
libs=["m", "z"]
# do not link to python on mac, see https://github.com/deeptools/pyBigWig/issues/58
if 'dynamic_lookup' not in (sysconfig.get_config_var('LDSHARED') or ''):
......@@ -34,6 +34,7 @@ additional_libs = [sysconfig.get_config_var("LIBDIR"), sysconfig.get_config_var(
defines = []
try:
foo, _ = subprocess.Popen(['curl-config', '--libs'], stdout=subprocess.PIPE).communicate()
libs.append("curl")
except:
foo = ''
defines.append(('NOCURL', None))
......@@ -61,7 +62,7 @@ module1 = Extension('pyBigWig',
include_dirs = include_dirs)
setup(name = 'pyBigWig',
version = '0.3.11',
version = '0.3.12',
description = 'A package for accessing bigWig files using libBigWig',
author = "Devon P. Ryan",
author_email = "ryan@ie-freiburg.mpg.de",
......