C++ library (CppCPL)

The CppCPL is a C++ library that wraps some CPL objects and CLIPM routines (ANSI C) in an object oriented fashion. This facilitates C++ programmers integrating these routines into their programs, as well as making easier its binding to Python. This library does not provides a one to one mapping of CPL functions, it only adds the needed objects and functions required by CLIPM recipes. Additional mappings can be added on request.

The CppCPL takes care of the automatic initialization and cleaning up of CPL so neither C++ nor Python users are exposed to this.

The CppCPL will provide a mechanism to obtain images directly from shared memory and thus avoiding the filesystem overhead. This will allow better integration with image acquisition and quick-look processes. This feature will be based on the capabilities of the DDT component but this component is not yet provided therefore this feature is not yet available.

The Doxygen documentation for the “cppcpl” module is available here.

Error Handling

The CppCPL make use of std::runtime exceptions to report errors coming from the underlying libraries like CPL or CLIPM. The CppCPL uses the CPL routine ‘cpl_error_get_message()’ to get the message that will be included in the exception.

Error Format

Each exception will report the related CPL error when it applies following the format below:

<context> - cplerr: <file>:<line> errmsg:<error_message>

Example:

Error executing statistics - cplerr: cpl_image_stats.c:232 errmsg:Null input data

Warning

At this point in time, CppCPL does not handle any history or error stack, only the last CPL error is reported.

 void Image::SetBadPixelMap(const Mask &mask) {

    ResetCplError();

    if (! IsImage()) {
        RAD_LOG_ERROR() << "cpl image is nullptr";
        throw std::runtime_error("Error cpl image is nullptr");
    }

    // Mark bad pixels
    if (cpl_image_reject_from_mask(GetCplImage(), mask.GetCplMask()) != CPL_ERROR_NONE) {
        const std::string msg = "Error setting pixel map - cplerr: " + GetErrorMsg();
        RAD_LOG_ERROR() << msg;
        throw std::runtime_error(msg);
    }
}

Classes

The CppCPL module provides the implementation of the following classes:

Class Name

Description

Odp::Image

Class wrapper to cpl_image.

Odp::Matrix

Class wrapper to cpl_matrix.

Odp::Array

Class wrapper to cpl_array.

Odp::Mask

Class wrapper to cpl_mask.

Odp::ImageStatistics

Class that encapsulates statistics functions over cpl images.

Odp::ImageWrapper

Template class to wrap a CPL image around a existing data vector. The types supported are restricted to the ones supported by CPL (int, float and double). This class inherits from Odp::Image.

Odp::ImageCube

Class that encapsulates CPL routines for image cubes.

Odp::ImageExtensions

Class that encapsulates CPL routines for image extensions.

Odp::Recipe

Class that encapsulates CLIPM image processing routines.

Testing

The CppCPL library provides a set of unit tests implemented with Google Test library. These tests cover each of the classes in the library. Tests can be executed as follow:

$ cd ifw-hl/odp/cppcpl
$ waf test --alltests

Examples

The usage of the library is straightforward, but here you can find a series of examples that will show how to use some of the classes that are part of this library. For more examples, please have a look to the CppCPL unit tests.

Image Class

// Local header files
#include "cppcpl/image.hpp"

odp::Image img;
img.Load("myimage.fits");
std::cout << "width: " << img.GetWidth();
std::cout << "height: " << img.GetHeight();

// creates a new image object from a subwindow of an existing one.
odp::Image img2(img, 1, 1, 10, 10);

// Increase each pixel value intensity by 100 ADUs
img2 += 100;
if (img == img2) {
   // do something
}

ImageStatistics Class

// Local header files
#include "cppcpl/imageStatistics.hpp"

odp::Image img;
img.Load("myimage.fits");
odp::ImageStatistics stat(img);
std::cout << "min: " << stat.GetMin();
std::cout << "max: " << stat.GetMax();
std::cout << "mean: " << stat.GetMean();
std::cout << "stdev: " << stat.GetStdev();
std::cout << "flux: " << stat.GetFlux();

ImageWrapper Class

// Local header files
#include "cppcpl/imageWrapper.hpp"

// We assume to have an image in data buffer
float* data;

// Create the image object and allocate the memory.
odp::ImageWrapper<float> image_wrapper(512, 512);
// Wrap the data into a image wrapper object
image_wrapper.Read(data, 512, 512);

Recipe Class

// Local header files
#include "cppcpl/recipe.hpp"

// Declare structure containing the output data
odp::CenterGauss cenGauss;

odp::Recipe recipe;
odp::Image img;

// Load image to be used by the recipe
img.Load("myimage.fits");

// Call the recipe
recipe.GetCenterGauss(&img, 1, 1, 512, 512, &cenGauss, 1);