Commit 38504ab0 by abonin

Final switch to the new cython interface on array.array

parent 1b8a867f
......@@ -146,8 +146,8 @@ def lenlcs(seq1,seq2,double minimum=0.,bint normalized=False, int reference=ALIL
cdef bint possible
cdef bint large
cdef array.array[uchar] w1
cdef array.array[uchar] w2
cdef array.array[unsigned char] w1
cdef array.array[unsigned char] w2
cdef char *s1
cdef char *s2
......@@ -6,8 +6,6 @@ Created on 6 Nov. 2009
from _dynamic cimport *
from array import array
cimport array
from obitools import BioSequence
from _upperbond cimport *
......@@ -24,11 +24,6 @@ from obitools.utils import universalOpen
import re
import sys
cimport array
#from cpython cimport array
cdef import from "math.h" :
double log10(double x)
double rint(double x)
......@@ -62,7 +57,7 @@ cpdef array.array[double] fastqQualityDecoder(char* qualstring, int base=0):
# (oaddress,olength)=quality.buffer_info()
if base==0:
mq = 255
\ No newline at end of file
# cython: profile=False
from cpython cimport array
from import iterOnAligment
from array import array
from obitools import NucSequence
cimport array
cdef class IterOnConsensus:
......@@ -20,7 +18,7 @@ cdef class IterOnConsensus:
cdef int __seqBInsertion
cdef int __seqADeletion
cdef int __seqBDeletion
cdef object __ioa
cdef object __ioa
cdef bint __firstSeqB
def __cinit__(self,ali):
......@@ -34,7 +32,7 @@ cdef class IterOnConsensus:
self.__ioa = iterOnAligment(self._ali)
......@@ -72,7 +70,7 @@ cdef class IterOnConsensus:
def get_seqBDeletion(self):
return self.__seqBDeletion
def __next__(self):
cdef bytes snuc0
cdef bytes snuc1
......@@ -83,12 +81,12 @@ cdef class IterOnConsensus:
cdef double score1
cdef double h0
cdef double h1
snuc0,score0,snuc1,score1 =
if nuc0[0]==nuc1[0]:
if nuc0[0]==nuc1[0]:
if nuc1[0]!=dash[0]:
......@@ -98,7 +96,7 @@ cdef class IterOnConsensus:
h0 = score0 * (1-score1/3)
h1 = score1 * (1-score0/3)
if h0 < h1:
if nuc0[0]!=dash[0]:
if nuc1[0]==dash[0]:
......@@ -126,10 +124,10 @@ cdef class IterOnConsensus:
def __iter__(self):
return self
seqASingle = property(get_seqASingle, None, None, "direct's docstring")
seqBSingle = property(get_seqBSingle, None, None, "reverse's docstring")
seqABMatch = property(get_seqABMatch, None, None, "idem's docstring")
......@@ -150,7 +148,7 @@ def buildConsensus(ali):
cdef bytes nuc
cdef double score
cdef bytes sseq
if len(ali[0])>999:
raise AssertionError,"To long alignemnt"
......@@ -161,13 +159,13 @@ def buildConsensus(ali):
seq.quality=array.array('d',[quality[j] for j in range(i)])
if hasattr(ali, "direction"):
if hasattr(ali, "counter"):
Cython interface to Python's array.array module.
* 1D contiguous data view
* tools for fast array creation, maximum C-speed and handiness
* suitable as allround light weight auto-array within Cython code too
>>> cimport array
Usage through Cython buffer interface (Py2.3+):
>>> def f(arg1, unsigned i, double dx)
array.array[double] a = arg1
a[i] += dx
Fast C-level new_array(_zeros), resize_array, copy_array, .length,
cdef array.array[double] k = array.copy(d)
cdef array.array[double] n = array.array(d, d.length * 2 )
cdef array.array[double] m = array.zeros_like(FLOAT_TEMPLATE)
array.resize(f, 200000)
Zero overhead with naked data pointer views by union:
_f, _d, _i, _c, _u, ...
=> Original C array speed + Python dynamic memory management
cdef array.array a = inarray
a._d[2] += 0.66 # use as double array without extra casting
float *subview = vector._f + 10 # starting from 10th element
unsigned char *subview_buffer = vector._B + 4
Suitable as lightweight arrays intra Cython without speed penalty.
Replacement for C stack/malloc arrays; no trouble with refcounting,
mem.leaks; seamless Python compatibility, buffer() option
IMPORTANT: arrayarray.h (arrayobject, arraydescr) is not part of
the official Python C-API so far; arrayarray.h is located
next to this file copy it to PythonXX/include or local or
somewhere on your -I path
last changes: 2009-05-15 rk
: 2009-12-06 bp
cimport stdlib
cdef extern from "stdlib.h" nogil:
void *memset(void *str, int c, size_t n)
char *strcat(char *str1, char *str2)
char *strncat(char *str1, char *str2, size_t n)
void *memchr(void *str, int c, size_t n)
int memcmp(void *str1, void *str2, size_t n)
void *memcpy(void *str1, void *str2, size_t n)
void *memmove(void *str1, void *str2, size_t n)
cdef extern from "arrayarray.h":
ctypedef void PyTypeObject
ctypedef short Py_UNICODE
int PyErr_BadArgument()
ctypedef class array.array [object arrayobject]
ctypedef object GETF(array a, Py_ssize_t ix)
ctypedef object SETF(array a, Py_ssize_t ix, object o)
ctypedef struct arraydescr: # [object arraydescr]:
int typecode
int itemsize
GETF getitem # PyObject * (*getitem)(struct arrayobject *, Py_ssize_t);
SETF setitem # int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *);
ctypedef class array.array [object arrayobject]:
cdef __cythonbufferdefaults__ = {'ndim' : 1, 'mode':'c'}
PyTypeObject* ob_type
int ob_size # number of valid items;
unsigned length # == ob_size (by union)
char* ob_item # to first item
Py_ssize_t allocated # bytes
arraydescr* ob_descr # struct arraydescr *ob_descr;
object weakreflist # /* List of weak references */
# view's of ob_item:
float* _f # direct float pointer access to buffer
double* _d # double ...
int* _i
unsigned *_I
unsigned char *_B
signed char *_b
char *_c
unsigned long *_L
long *_l
short *_h
unsigned short *_H
void* _v
def __getbuffer__(array self, Py_buffer* info, int flags):
# This implementation of getbuffer is geared towards Cython
# requirements, and does not yet fullfill the PEP.
# In particular strided access is always provided regardless
# of flags
cdef unsigned rows, columns, itemsize
info.suboffsets = NULL
info.buf = self.ob_item
info.readonly = 0
info.ndim = 1
info.itemsize = itemsize = self.ob_descr.itemsize # e.g. sizeof(float)
info.strides = <Py_ssize_t*> \
stdlib.malloc(sizeof(Py_ssize_t) * info.ndim * 2 + 2)
info.shape = info.strides + 1
info.shape[0] = self.ob_size # number of items
info.strides[0] = info.itemsize
info.format = <char*>(info.strides + 2 * info.ndim)
info.format[0] = self.ob_descr.typecode
info.format[1] = 0
info.obj = self
def __releasebuffer__(array self, Py_buffer* info):
#if PyArray_HASFIELDS(self):
#if sizeof(npy_intp) != sizeof(Py_ssize_t):
array newarrayobject(PyTypeObject* type, Py_ssize_t size,
arraydescr *descr)
# fast resize/realloc
# not suitable for small increments; reallocation 'to the point'
int resize(array self, Py_ssize_t n)
# efficient for small increments (not in Py2.3-)
int resize_smart(array self, Py_ssize_t n)
# fast creation of a new array - init with zeros
# yet you need a (any) template array of the same item type (but not same size)
cdef inline array zeros_like(array sametype):
cdef array op = newarrayobject(<PyTypeObject*>sametype.ob_type, sametype.ob_size, sametype.ob_descr)
if op:
memset(op.ob_item, 0, op.ob_size * op.ob_descr.itemsize)
return op
# fast creation of a new array - no init with zeros
cdef inline array empty_like(array sametype):
return newarrayobject(<PyTypeObject*>sametype.ob_type, sametype.op.ob_size,
cdef inline array copy(array self):
cdef array op = newarrayobject(<PyTypeObject*>self.ob_type, self.ob_size,
memcpy(op.ob_item, self.ob_item, op.ob_size * op.ob_descr.itemsize)
return op
cdef inline int extend_buffer(array self, char* stuff, Py_ssize_t n):
""" efficent appending of new stuff of same type (e.g. of same array type)
n: number of elements (not number of bytes!)
cdef Py_ssize_t itemsize = self.ob_descr.itemsize, orgsize = self.ob_size
if -1 == resize_smart(self, orgsize + n):
return -1
memcpy( self.ob_item + orgsize * itemsize, stuff, n * itemsize )
cdef inline int extend(array self, array other):
if self.ob_descr.typecode != self.ob_descr.typecode:
return -1
return extend_buffer(self, other.ob_item, other.ob_size)
cdef inline void zero(array op):
memset(op.ob_item, 0, op.ob_size * op.ob_descr.itemsize)
/* arrayarray.h
artificial C-API for Python's
<array.array> type.
copy this file to your -I path, e.g. .../pythonXX/include
See array.pxd next to this file
last changes: 2009-05-15 rk
#include <Python.h>
struct arrayobject; /* Forward */
/* All possible arraydescr values are defined in the vector "descriptors"
* below. That's defined later because the appropriate get and set
* functions aren't visible yet.
typedef struct arraydescr {
int typecode;
int itemsize;
PyObject * (*getitem)(struct arrayobject *, Py_ssize_t);
int (*setitem)(struct arrayobject *, Py_ssize_t, PyObject *);
#if PY_VERSION_HEX >= 0x03000000
char *formats;
} arraydescr;
typedef struct arrayobject {
union {
int ob_size;
unsigned length;
union {
char *ob_item;
float *_f;
double *_d;
int *_i;
unsigned *_I;
unsigned char *_BYTES;
signed char *_b;
char *_c;
unsigned long *_LONG;
long *_l;
short *_h;
unsigned short *_H;
void *_v;
#if PY_VERSION_HEX >= 0x02040000
Py_ssize_t allocated;
struct arraydescr *ob_descr;
#if PY_VERSION_HEX >= 0x02040000
PyObject *weakreflist; /* List of weak references */
#if PY_VERSION_HEX >= 0x03000000
int ob_exports; /* Number of exported buffers */
} arrayobject;
* fast creation of a new array - init with zeros
static inline PyObject *
newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr)
arrayobject *op;
size_t nbytes;
if (size < 0) {
return NULL;
nbytes = size * descr->itemsize;
/* Check for overflow */
if (nbytes / descr->itemsize != (size_t)size) {
return PyErr_NoMemory();
op = (arrayobject *) type->tp_alloc(type, 0);
if (op == NULL) {
return NULL;
op->ob_descr = descr;
#if !( PY_VERSION_HEX < 0x02040000 )
op->allocated = size;
op->weakreflist = NULL;
Py_SIZE(op) = size;
if (size <= 0) {
op->ob_item = NULL;
else {
op->ob_item = PyMem_NEW(char, nbytes);
if (op->ob_item == NULL) {
return PyErr_NoMemory();
return (PyObject *) op;
PyObject *
newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr);
/* fast resize (reallocation to the point)
not designed for filing small increments (but for fast opaque array apps) */
static inline int resize(arrayobject *self, Py_ssize_t n)
char *item=self->ob_item;
PyMem_RESIZE(item, char, (unsigned)(n * self->ob_descr->itemsize));
if (item == NULL) {
return -1;
self->ob_item = item;
self->ob_size = n;
#if PY_VERSION_HEX >= 0x02040000
self->allocated = n;
return 0;
/* suitable for small increments; over allocation 50% ;
Remains non-smart in Python 2.3- ; but exists for compatibility */
static inline int resize_smart(arrayobject *self, Py_ssize_t n)
char *item=self->ob_item;
#if PY_VERSION_HEX >= 0x02040000
if (n < self->allocated) {
if (n*4 > self->allocated) {
self->ob_size = n;
return 0;
Py_ssize_t newsize = n * 3 / 2 + 1;
PyMem_RESIZE(item, char, (unsigned)(newsize * self->ob_descr->itemsize));
if (item == NULL) {
return -1;
self->ob_item = item;
self->ob_size = n;
self->allocated = newsize;
return 0;
return resize(self, n) /* Python 2.3 has no 'allocated' */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment