Imports
from libcpp.vector cimport vector from libcpp cimport bool from libc.time cimport time_t, ctime from libcpp.string cimport string cimport numpy as np import numpy as np
Useful ctypedefs
cdef extern from "<stdint.h>" nogil: ctypedef signed char int8_t ctypedef signed short int16_t ctypedef signed int int32_t ctypedef signed long int64_t ctypedef unsigned char uint8_t ctypedef unsigned short uint16_t ctypedef unsigned int uint32_t ctypedef unsigned long uint64_t ctypedef unsigned shape_t ctypedef uint16_t mask_t ctypedef uint16_t extrim_t ctypedef uint16_t pixstatus_t ctypedef uint32_t conmap_t #------------------------------ ctypedef fused nptype2d : np.ndarray[np.float64_t, ndim=2, mode="c"] np.ndarray[np.float32_t, ndim=2, mode="c"] np.ndarray[np.int16_t, ndim=2, mode="c"] np.ndarray[np.int32_t, ndim=2, mode="c"] np.ndarray[np.int64_t, ndim=2, mode="c"] np.ndarray[np.uint16_t, ndim=2, mode="c"] np.ndarray[np.uint32_t, ndim=2, mode="c"] np.ndarray[np.uint64_t, ndim=2, mode="c"]
Cython class attribute declaration and usage
cdef class image_algo : cdef uint16_t rows, cols def image_shape(self) : shape = (self.rows, self.cols)
C++ wrapper for python
Example of regular C++ class wrapper
cdef extern from "psalgos/PeakFinderAlgos.h" namespace "psalgos": cdef cppclass PeakFinderAlgos: #float m_r0 #float m_dr #size_t m_rank #size_t m_pixgrp_max_size #size_t m_img_size #float m_nsigm PeakFinderAlgos(const size_t& seg, const unsigned& pbits) except + void setPeakSelectionPars(const float& npix_min ,const float& npix_max ,const float& amax_thr ,const float& atot_thr ,const float& son_min) void peakFinderV3r3[T](const T *data ,const mask_t *mask ,const size_t& rows ,const size_t& cols ,const size_t& rank ,const double& r0 ,const double& dr ,const double& nsigm) void printParameters(); #------------------------------ cdef class peak_finder_algos : """ Python wrapper for C++ class. """ cdef PeakFinderAlgos* cptr # holds a C++ pointer to instance cdef uint16_t rows, cols def __cinit__(self, seg=0, pbits=0): #print "In peak_finder_algos.__cinit__" self.cptr = new PeakFinderAlgos(seg, pbits) def __dealloc__(self): #print "In peak_finder_algos.__dealloc__" del self.cptr def set_peak_selection_parameters(self\ ,const float& npix_min\ ,const float& npix_max\ ,const float& amax_thr\ ,const float& atot_thr\ ,const float& son_min) : self.cptr.setPeakSelectionPars(npix_min, npix_max, amax_thr, atot_thr, son_min) def print_attributes(self) : self.cptr.printParameters() def peak_finder_v3r3_d2(self\ ,nptype2d data\ ,np.ndarray[mask_t, ndim=2, mode="c"] mask\ ,const size_t& rank\ ,const double& r0\ ,const double& dr\ ,const double& nsigm) : self.cptr.peakFinderV3r3(&data[0,0], &mask[0,0], data.shape[0], data.shape[1], rank, r0, dr, nsigm) self.rows = data.shape[0] self.cols = data.shape[1] return self.list_of_peaks_selected() def list_of_peaks_selected(self) : cdef vector[Peak] peaks = self.cptr.vectorOfPeaksSelected() return [py_peak.factory(p) for p in peaks] def list_of_peaks(self) : cdef vector[Peak] peaks = self.cptr.vectorOfPeaks() return [py_peak.factory(p) for p in peaks]
Wrapping struct
file.h:
#include <iostream> // for cout, ostream struct Peak{ float seg; float row; float col; Peak(){} // do not fill out member by default Peak(const float& _seg=0, const float& _row=0, const float& _col=0) : seg(_seg), row(_row), col(_col){ } //copy constructor Peak(const Peak& o) : seg(o.seg) , row(o.row) , col(o.col){} Peak& operator=(const Peak& rhs) { seg = rhs.seg; row = rhs.row; col = rhs.col; return *this; } }; /// Stream insertion operator, std::ostream& operator<<(std::ostream& os, const Peak& p); // needs to be implemented in file.cpp
file.cpp:
#include <sstream> // for stringstream #include <iomanip> // for std::typedef std::ostream& operator<<(std::ostream& os, const Peak& p) { os << fixed << "Seg:" << std::setw(3) << std::setprecision(0) << p.seg << " Row:" << std::setw(4) << std::setprecision(0) << p.row << " Col:" << std::setw(4) << std::setprecision(0) << p.col return os; }
file.pyx:
cdef extern from "psalgos/PeakFinderAlgos.h" namespace "psalgos": cdef cppclass Peak : Peak() except + Peak(const Peak& o) except + Peak operator=(const Peak& rhs) except + float seg float row float col #------------------------------ cdef class py_peak : cdef Peak* cptr # holds a C++ pointer to instance def __cinit__(self, _make_obj=True): if _make_obj: self.cptr = new Peak() def __dealloc__(self): if self.cptr is not NULL : del self.cptr self.cptr = NULL # https://groups.google.com/forum/#!topic/cython-users/39Nwqsksdto @staticmethod cdef factory(Peak cpp_obj): py_obj = py_peak.__new__(py_peak, _make_obj=False) (<py_peak> py_obj).cptr = new Peak(cpp_obj) # C++ copy constructor return py_obj def parameters(self) : p = self.cptr return (p.seg, p.row, p.col) @property def seg (self) : return self.cptr.seg @property def row (self) : return self.cptr.row @property def col (self) : return self.cptr.col
Usage in other class, file.pyx:
def list_of_peaks(self) : cdef vector[Peak] peaks = self.cptr.vectorOfPeaks() return [py_peak.factory(p) for p in peaks]
Recommended wrappers for numpy
cdef extern from "psalgos/LocalExtrema.h" namespace "localextrema": void mapOfLocalMinimums[T](const T *data ,const mask_t *mask ,const size_t& rows ,const size_t& cols ,const size_t& rank ,extrim_t *arr2d ) def local_minimums(nptype2d data,\ np.ndarray[mask_t, ndim=2, mode="c"] mask,\ int32_t rank,\ np.ndarray[extrim_t, ndim=2, mode="c"] arr2d\ ): mapOfLocalMinimums(&data[0,0], &mask[0,0], data.shape[0], data.shape[1], rank, &arr2d[0,0])
Overview
Content Tools