Import upstream version 0.3.18
Debian Janitor
2 years ago
0 | name: foo | |
1 | channels: | |
2 | - conda-forge | |
3 | - bioconda | |
4 | - default | |
5 | dependencies: | |
6 | - gcc_linux-64 | |
7 | - curl | |
8 | - zlib | |
9 | - python 3.8 | |
10 | - pip | |
11 | - numpy | |
12 | - nose |
0 | on: pull_request | |
1 | jobs: | |
2 | testLinux: | |
3 | name: TestLinux | |
4 | runs-on: "ubuntu-latest" | |
5 | defaults: | |
6 | run: | |
7 | shell: bash -l {0} | |
8 | steps: | |
9 | - uses: actions/checkout@v2 | |
10 | - uses: conda-incubator/setup-miniconda@v2 | |
11 | with: | |
12 | activate-environment: foo | |
13 | environment-file: .environmentLinux.yaml | |
14 | python-version: 3.8 | |
15 | auto-activate-base: false | |
16 | - run: | | |
17 | pip install . | |
18 | nosetests -sv |
0 | name: pypi | |
1 | on: [push] | |
2 | jobs: | |
3 | pypi: | |
4 | name: upload to pypi | |
5 | runs-on: ubuntu-latest | |
6 | steps: | |
7 | - uses: actions/checkout@v1 | |
8 | - name: Setup conda | |
9 | if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') | |
10 | run: | | |
11 | curl https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -o miniconda.sh | |
12 | bash miniconda.sh -b -p $HOME/miniconda | |
13 | export PATH="$HOME/miniconda/bin:$PATH" | |
14 | hash -r | |
15 | conda config --set always_yes yes --set changeps1 no | |
16 | - name: create env | |
17 | if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') | |
18 | run: | | |
19 | export PATH=$HOME/miniconda/bin:$PATH | |
20 | conda create -n foo -q --yes -c conda-forge -c bioconda python=3.7 twine numpy libcurl curl zlib | |
21 | - name: sdist | |
22 | if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') | |
23 | run: | | |
24 | export PATH=$HOME/miniconda/bin:$PATH | |
25 | source activate foo | |
26 | rm -f dist/* | |
27 | python setup.py sdist | |
28 | - name: upload | |
29 | if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') | |
30 | env: | |
31 | TWINE_USERNAME: "__token__" | |
32 | TWINE_PASSWORD: ${{ secrets.pypi_password }} | |
33 | run: | | |
34 | export PATH=$HOME/miniconda/bin:$PATH | |
35 | source activate foo | |
36 | twine upload dist/* |
0 | language: python | |
1 | python: | |
2 | - "3.5" | |
3 | - "3.6" | |
4 | install: | |
5 | - pip install numpy && python ./setup.py install | |
6 | matrix: | |
7 | include: | |
8 | - python: 3.7 | |
9 | dist: xenial | |
10 | script: nosetests -sv |
6 | 6 | ================= |
7 | 7 | |
8 | 8 | * [Installation](#installation) |
9 | * [Requirements](#requirements) | |
9 | 10 | * [Usage](#usage) |
10 | 11 | * [Load the extension](#load-the-extension) |
11 | 12 | * [Open a bigWig or bigBed file](#open-a-bigwig-or-bigbed-file) |
33 | 34 | |
34 | 35 | or with conda |
35 | 36 | |
36 | conda install pybigwig -c bioconda | |
37 | ||
38 | Note that libcurl (and the `curl-config` command) are required for installation. This is typically already installed on many Linux and OSX systems (if you install with conda then this will happen automatically). | |
37 | conda install pybigwig -c conda-forge -c bioconda | |
38 | ||
39 | ## Requirements | |
40 | ||
41 | The follow non-python requirements must be installed: | |
42 | ||
43 | - libcurl (and the `curl-config` config) | |
44 | - zlib | |
45 | ||
46 | The headers and libraries for these are required. | |
39 | 47 | |
40 | 48 | # Usage |
41 | 49 | Basic usage is as follows: |
196 | 196 | |
197 | 197 | //Return 1 if there are any entries at all |
198 | 198 | int hasEntries(bigWigFile_t *bw) { |
199 | if(bw->hdr->nBasesCovered > 0) return 1; | |
199 | if(bw->hdr->indexOffset != 0) return 1; // No index, no entries pyBigWig issue #111 | |
200 | //if(bw->hdr->nBasesCovered > 0) return 1; // Sometimes headers are broken | |
200 | 201 | return 0; |
201 | 202 | } |
202 | 203 | |
377 | 378 | double *val; |
378 | 379 | uint32_t start, end = -1, tid; |
379 | 380 | unsigned long startl = 0, endl = -1; |
380 | static char *kwd_list[] = {"chrom", "start", "end", "type", "nBins", "exact", NULL}; | |
381 | static char *kwd_list[] = {"chrom", "start", "end", "type", "nBins", "exact", "numpy", NULL}; | |
381 | 382 | char *chrom, *type = "mean"; |
382 | 383 | PyObject *ret, *exact = Py_False, *starto = NULL, *endo = NULL; |
384 | PyObject *outputNumpy = Py_False; | |
383 | 385 | int i, nBins = 1; |
384 | 386 | errno = 0; //In the off-chance that something elsewhere got an error and didn't clear it... |
385 | 387 | |
398 | 400 | return NULL; |
399 | 401 | } |
400 | 402 | |
401 | if(!PyArg_ParseTupleAndKeywords(args, kwds, "s|OOsiO", kwd_list, &chrom, &starto, &endo, &type, &nBins, &exact)) { | |
403 | if(!PyArg_ParseTupleAndKeywords(args, kwds, "s|OOsiOO", kwd_list, &chrom, &starto, &endo, &type, &nBins, &exact, &outputNumpy)) { | |
402 | 404 | PyErr_SetString(PyExc_RuntimeError, "You must supply at least a chromosome!"); |
403 | 405 | return NULL; |
404 | 406 | } |
463 | 465 | |
464 | 466 | //Return a list of None if there are no entries at all |
465 | 467 | if(!hasEntries(bw)) { |
466 | ret = PyList_New(nBins); | |
467 | for(i=0; i<nBins; i++) { | |
468 | Py_INCREF(Py_None); | |
469 | PyList_SetItem(ret, i, Py_None); | |
470 | } | |
468 | #ifdef WITHNUMPY | |
469 | if(outputNumpy == Py_True) { | |
470 | val = malloc(sizeof(double)*nBins); | |
471 | for(i=0; i<nBins; i++) { | |
472 | val[i] = NPY_NAN; | |
473 | } | |
474 | npy_intp len = nBins; | |
475 | ret = PyArray_SimpleNewFromData(1, &len, NPY_FLOAT64, (void *) val); | |
476 | //This will break if numpy ever stops using malloc! | |
477 | PyArray_ENABLEFLAGS((PyArrayObject*) ret, NPY_ARRAY_OWNDATA); | |
478 | } else { | |
479 | #endif | |
480 | ret = PyList_New(nBins); | |
481 | for(i=0; i<nBins; i++) { | |
482 | Py_INCREF(Py_None); | |
483 | PyList_SetItem(ret, i, Py_None); | |
484 | } | |
485 | #ifdef WITHNUMPY | |
486 | } | |
487 | #endif | |
471 | 488 | return ret; |
472 | 489 | } |
473 | 490 | |
483 | 500 | return NULL; |
484 | 501 | } |
485 | 502 | |
486 | ret = PyList_New(nBins); | |
487 | for(i=0; i<nBins; i++) { | |
488 | if(isnan(val[i])) { | |
489 | Py_INCREF(Py_None); | |
490 | PyList_SetItem(ret, i, Py_None); | |
491 | } else { | |
492 | PyList_SetItem(ret, i, PyFloat_FromDouble(val[i])); | |
493 | } | |
494 | } | |
495 | free(val); | |
496 | ||
503 | #ifdef WITHNUMPY | |
504 | if(outputNumpy == Py_True) { | |
505 | npy_intp len = nBins; | |
506 | ret = PyArray_SimpleNewFromData(1, &len, NPY_FLOAT64, (void *) val); | |
507 | //This will break if numpy ever stops using malloc! | |
508 | PyArray_ENABLEFLAGS((PyArrayObject*) ret, NPY_ARRAY_OWNDATA); | |
509 | } else { | |
510 | #endif | |
511 | ret = PyList_New(nBins); | |
512 | for(i=0; i<nBins; i++) { | |
513 | if(isnan(val[i])) { | |
514 | Py_INCREF(Py_None); | |
515 | PyList_SetItem(ret, i, Py_None); | |
516 | } else { | |
517 | PyList_SetItem(ret, i, PyFloat_FromDouble(val[i])); | |
518 | } | |
519 | } | |
520 | free(val); | |
521 | #ifdef WITHNUMPY | |
522 | } | |
523 | #endif | |
497 | 524 | return ret; |
498 | 525 | } |
499 | 526 |
1 | 1 | #include <structmember.h> |
2 | 2 | #include "bigWig.h" |
3 | 3 | |
4 | #define pyBigWigVersion "0.3.17" | |
4 | #define pyBigWigVersion "0.3.18" | |
5 | 5 | |
6 | 6 | typedef struct { |
7 | 7 | PyObject_HEAD |
307 | 307 | |
308 | 308 | bw.close() |
309 | 309 | os.remove("/tmp/delete.bw") |
310 | ||
311 | def testNumpyValues(self): | |
312 | if pyBigWig.numpy == 0: | |
313 | return 0 | |
314 | import numpy as np | |
315 | ||
316 | fname = "http://raw.githubusercontent.com/dpryan79/pyBigWig/master/pyBigWigTest/test.bw" | |
317 | bw = pyBigWig.open(fname, "r") | |
318 | ||
319 | assert np.allclose( | |
320 | bw.values("1", 0, 20, numpy=True), | |
321 | np.array(bw.values("1", 0, 20), dtype=np.float32), | |
322 | equal_nan=True | |
323 | ) | |
324 | ||
325 | assert np.allclose( | |
326 | bw.stats("1", 0, 20, "mean", 5, numpy=True), | |
327 | np.array(bw.stats("1", 0, 20, "mean", 5), dtype=np.float64), | |
328 | equal_nan=True | |
329 | ) |