From eb26aec415965e46bd9fa33f29e3a3ec96b61d89 Mon Sep 17 00:00:00 2001 From: Devon Ryan Date: Thu, 1 Aug 2019 11:42:01 +0200 Subject: [PATCH 1/4] PyUnicode_AsASCIIString returns a new object that needs to be DECREF'd --- pyBigWig.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pyBigWig.c b/pyBigWig.c index 66ebb63..c6d5da5 100644 --- a/pyBigWig.c +++ b/pyBigWig.c @@ -724,7 +724,11 @@ int PyString_Check(PyObject *obj) { //I don't know what happens if PyBytes_AsString(NULL) is used... char *PyString_AsString(PyObject *obj) { - return PyBytes_AsString(PyUnicode_AsASCIIString(obj)); + char *s; + PyObject *t = PyUnicode_AsASCIIString(obj); + s = PyBytes_AsString(t); + Py_DECREF(t); // Otherwise t just hangs around and wastes memory + return s; } #endif From cb0f153e922553258258eba9b86cf2cf77aa7ea5 Mon Sep 17 00:00:00 2001 From: Devon Ryan Date: Thu, 1 Aug 2019 11:53:21 +0200 Subject: [PATCH 2/4] only ascii is defined anyway. --- pyBigWig.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/pyBigWig.c b/pyBigWig.c index c6d5da5..48a25f5 100644 --- a/pyBigWig.c +++ b/pyBigWig.c @@ -724,11 +724,7 @@ int PyString_Check(PyObject *obj) { //I don't know what happens if PyBytes_AsString(NULL) is used... char *PyString_AsString(PyObject *obj) { - char *s; - PyObject *t = PyUnicode_AsASCIIString(obj); - s = PyBytes_AsString(t); - Py_DECREF(t); // Otherwise t just hangs around and wastes memory - return s; + return PyUnicode_AsUTF8(obj); } #endif From e685340c514f3276b695a0d0455ac6fe5e85bd91 Mon Sep 17 00:00:00 2001 From: dpryan79 Date: Mon, 5 Aug 2019 10:49:38 +0200 Subject: [PATCH 3/4] bump version --- pyBigWig.h | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyBigWig.h b/pyBigWig.h index d42fca5..b67b21d 100644 --- a/pyBigWig.h +++ b/pyBigWig.h @@ -2,7 +2,7 @@ #include #include "bigWig.h" -#define pyBigWigVersion "0.3.16" +#define pyBigWigVersion "0.3.17" typedef struct { PyObject_HEAD diff --git a/setup.py b/setup.py index 0910dfe..8806a7d 100755 --- a/setup.py +++ b/setup.py @@ -62,7 +62,7 @@ include_dirs = include_dirs) setup(name = 'pyBigWig', - version = '0.3.16', + version = '0.3.17', description = 'A package for accessing bigWig files using libBigWig', author = "Devon P. Ryan", author_email = "ryan@ie-freiburg.mpg.de", From 9f94cf99e668042cebcbcf48d3cd389be5941efb Mon Sep 17 00:00:00 2001 From: dpryan79 Date: Mon, 5 Aug 2019 11:11:08 +0200 Subject: [PATCH 4/4] Fix #88 --- README.md | 5 ++--- pyBigWig.c | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0f0841a..cada9d2 100644 --- a/README.md +++ b/README.md @@ -144,9 +144,6 @@ For the sake of consistency with other tools, pyBigWig adopts this same methodol 0.22213841940688142 >>> bw.stats('chr1', 89294, 91629, exact=True) [0.22213841940688142] -Additionally, `values()` can directly output a numpy vector: - - >>> bw = bw.open(" ## Retrieve values for individual bases in a range @@ -218,6 +215,8 @@ By default, up to 10 "zoom levels" are constructed for bigWig files. You can cha >>> bw.addHeader([("chr1", 1000000), ("chr2", 1500000)], maxZooms=0) +If you set `maxTooms=0`, please note that IGV and many other tools WILL NOT WORK as they assume that at least one zoom level will be present. You are advised to use the default unless you do not expect the bigWig files to be used by other packages. + ## Adding entries to a bigWig file Assuming you've opened a file for writing and added a header, you can then add entries. Note that the entries **must** be added in order, as bigWig files always contain ordered intervals. There are three formats that bigWig files can use internally to store entries. The most commonly observed format is identical to a [bedGraph](https://genome.ucsc.edu/goldenpath/help/bedgraph.html) file: diff --git a/pyBigWig.c b/pyBigWig.c index 48a25f5..5d63e08 100644 --- a/pyBigWig.c +++ b/pyBigWig.c @@ -276,6 +276,10 @@ static PyObject *pyBwGetHeader(pyBigWigFile_t *self, PyObject *args) { PyErr_SetString(PyExc_RuntimeError, "The bigWig file handle is not opened!"); return NULL; } + if(bw->isWrite == 1) { + PyErr_SetString(PyExc_RuntimeError, "The header cannot be accessed in files opened for writing!"); + return NULL; + } ret = PyDict_New(); val = PyLong_FromUnsignedLong(bw->hdr->version); @@ -321,6 +325,11 @@ static PyObject *pyBwGetChroms(pyBigWigFile_t *self, PyObject *args) { return NULL; } + if(bw->isWrite == 1) { + PyErr_SetString(PyExc_RuntimeError, "Chromosomes cannot be accessed in files opened for writing!"); + return NULL; + } + if(!(PyArg_ParseTuple(args, "|s", &chrom)) || !chrom) { ret = PyDict_New(); for(i=0; icl->nKeys; i++) { @@ -380,6 +389,11 @@ static PyObject *pyBwGetStats(pyBigWigFile_t *self, PyObject *args, PyObject *kw return NULL; } + if(bw->isWrite == 1) { + PyErr_SetString(PyExc_RuntimeError, "Statistics cannot be accessed in files opened for writing!"); + return NULL; + } + if(bw->type == 1) { PyErr_SetString(PyExc_RuntimeError, "bigBed files have no statistics!"); return NULL; @@ -621,6 +635,11 @@ static PyObject *pyBwGetIntervals(pyBigWigFile_t *self, PyObject *args, PyObject return NULL; } + if(bw->isWrite == 1) { + PyErr_SetString(PyExc_RuntimeError, "Intervals cannot be accessed in files opened for writing!"); + return NULL; + } + if(bw->type == 1) { PyErr_SetString(PyExc_RuntimeError, "bigBed files have no intervals! Use 'entries()' instead."); return NULL;