Python Binding (PyCPL)¶
The PyCPL is a library that creates the Python bindings for C++ library CppCPL. The bindings are created using pybind11 tool. For more information about pybind11, see here.
The resulting Python package is PyCPL and contains the binding of the main objects defined in the CppCPL library. Additional binding can be added on request based on the needs of instruments.
The binding of CPL based recipes and objects enables the integration of CPL with the Python ecosystem that includes many libraries, frameworks and tools. This may complement very well the image processing activities specially in the area of scientific computing or plotting libraries like matplotlib.
Python also provides interactivity, for instance by using Jupyter console where users can quickly verify visually the outcome of the image processing algorithms.
Error Handling¶
The errors produced in CPL or CLIPM and captured in exceptions by library CppCPL. These errors are reported in Python as RuntimeError. The exception message will contain the location of the CPL or CLIPM error when this information is available, see the example below.
import pycpl
""" Creating empty image object """
image = pycpl.image()
# This should generate a RuntimeError because image has not been allocated yet.
stat = pycpl.image_stat(image)
stat.Mean()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: Error executing statistics - cplerr: cpl_image_stats.c:232 errmsg:Null input data
PyCPL Constants¶
C/C++ Constant |
Binding |
---|---|
CLIPM_ALIGN_SHIFT |
pycpl.CLIPM_ALIGN_SHIFT |
CLIPM_ALIGN_SCALE |
pycpl.CLIPM_ALIGN_SCALE |
CLIPM_ALIGN_ROTATE |
pycpl.CLIPM_ALIGN_ROTATE |
CLIPM_ALIGN_FREE |
pycpl.CLIPM_ALIGN_FREE |
CLIPM_ALIGN_ROBUST |
pycpl.CLIPM_ALIGN_ROBUST |
PyCPL Enumerations¶
C/C++ Class Name |
Binding |
---|---|
cpl_type |
pycpl.cpl_type Supported values:
|
cpl_io_type |
pycpl.cpl_io_type Supported values:
|
PyCPL Classes¶
The pycpl module provides the binding of the following classes:
C++ Class Name |
Binding |
---|---|
odp::Image |
pycpl.image |
odp::Matrix |
pycpl.matrix |
odp::Array |
pycpl.array |
odp::Mask |
pycpl.mask |
odp::ImageStatistics |
pycpl.image_stat |
odp::Recipe |
pycpl.recipe |
odp::CenterGauss |
pycpl.center_gauss |
odp::Iqe |
pycpl.iqe |
odp::SlitPos |
pycpl.slitpos |
odp::ImageCube |
pycpl.imagecube |
Buffer Protocol¶
This is a cool feature of pybind11 that enables to expose the data of a C++ structure into a python. This allows to have an easy exchange of data between numpy arrays and CPL objects.
""" creating a numpy array from a cpl image """
image = pycpl.image()
image.Load(str(image_path), 0,0, pycpl.cpl_type.CPL_TYPE_FLOAT)
image_data = np.array(image, copy=False)
""" Creating a new matrix from a numpy vector """
ref = np.array([[366,430, 67, 283, 210, 207,354,348,360,425],
[91, 323, 275,275, 257, 311,341,452,216,424]]).astype(np.float64)
matrix = pycpl.matrix(ref)
Testing¶
The PyCPL library provides a set of unit tests implemented with Python unit tests. Tests can be executed as follow:
$ cd ifw-hl/odp/pycpl
$ waf test --alltests
Examples¶
Fake Star¶
import pycpl
""" Creates a dummy gaussian star """
NORM_STAR = 1000000.0
percent = 1
image = pycpl.image(512,512, pycpl.cpl_type.CPL_TYPE_FLOAT)
image.FillNoise(100,200)
star = pycpl.image(512,512, pycpl.cpl_type.CPL_TYPE_FLOAT)
norm = NORM_STAR * (percent * percent);
sigma = 512 * (percent / 100.0);
half = 512 / 2.0;
star.FillGaussian(half,half, norm, sigma, sigma)
image += star
Image Centroiding¶
import pycpl
""" Creates a dummy gaussian star """
NORM_STAR = 1000000.0
percent = 1
image = pycpl.image(512,512, pycpl.cpl_type.CPL_TYPE_FLOAT)
image.FillNoise(100,200)
star = pycpl.image(512,512, pycpl.cpl_type.CPL_TYPE_FLOAT)
norm = NORM_STAR * (percent * percent)
sigma = 512 * (percent / 100.0)
half = 512 / 2.0
star.FillGaussian(half,half, norm, sigma, sigma)
""" added dummy star to the background image """
image += star
center_gauss = pycpl.center_gauss();
recipe = pycpl.recipe()
""" computes center gauss """
recipe.CenterGauss(image, 1, 1, 512, 512, center_gauss, 1)
print(center_gauss.Center())
Instrument Extensions¶
Instruments can extend the ODP by creating new CPL based recipes or reusing existing ones from the Instrument DRS. Once these routines exists, Python bindings can be defined following the same mechanism used by ODP. There is already a template module implemented for the VLT (xxclipm) that was intended to implement instrument specific image processing algorithms. The following figure shows the possible phases to extend the ODP component.