EMAN2
Public Member Functions | Static Public Member Functions | Static Public Attributes | Private Member Functions
EMAN::TransformProcessor Class Reference

Transform the image using a Transform object. More...

#include <processor.h>

Inheritance diagram for EMAN::TransformProcessor:
Inheritance graph
[legend]
Collaboration diagram for EMAN::TransformProcessor:
Collaboration graph
[legend]

List of all members.

Public Member Functions

virtual string get_name () const
 Get the processor's name.
virtual void process_inplace (EMData *image)
 
Exceptions:
ImageDimensionExceptionif the image is not 2D or 3D
InvalidParameterExceptionif the Transform parameter is not specified

virtual EMDataprocess (const EMData *const image)
 
Exceptions:
ImageDimensionExceptionif the image is not 2D or 3D
InvalidParameterExceptionif the Transform parameter is not specified

virtual TypeDict get_param_types () const
 Get processor parameter information in a dictionary.
virtual string get_desc () const
 Get the descrition of this specific processor.
float * transform (const EMData *const image, const Transform &t) const

Static Public Member Functions

static ProcessorNEW ()

Static Public Attributes

static const string NAME = "xform"

Private Member Functions

void assert_valid_aspect (const EMData *const image) const

Detailed Description

Transform the image using a Transform object.

Author:
David Woolford
Date:
September 2008
Parameters:
transformThe Transform object that will be applied to the image

Definition at line 1644 of file processor.h.


Member Function Documentation

void TransformProcessor::assert_valid_aspect ( const EMData *const  image) const [private]

Definition at line 9054 of file processor.cpp.

References EMAN::EMData::get_ndim(), EMAN::Dict::has_key(), ImageDimensionException, InvalidParameterException, and EMAN::Processor::params.

                                                                            {
        int ndim = image->get_ndim();
        if (ndim != 2 && ndim != 3) throw ImageDimensionException("Transforming an EMData only works if it's 2D or 3D");

        if (! params.has_key("transform") ) throw InvalidParameterException("You must specify a Transform in order to perform this operation");
}
virtual string EMAN::TransformProcessor::get_desc ( ) const [inline, virtual]

Get the descrition of this specific processor.

This function must be overwritten by a subclass.

Returns:
The description of this processor.

Implements EMAN::Processor.

Definition at line 1675 of file processor.h.

                        {
                                return "The image is transformed using Transform parameter.";
                        }
virtual string EMAN::TransformProcessor::get_name ( ) const [inline, virtual]

Get the processor's name.

Each processor is identified by a unique name.

Returns:
The processor's name.

Implements EMAN::Processor.

Definition at line 1647 of file processor.h.

References NAME.

                        {
                                return NAME;
                        }
virtual TypeDict EMAN::TransformProcessor::get_param_types ( ) const [inline, virtual]

Get processor parameter information in a dictionary.

Each parameter has one record in the dictionary. Each record contains its name, data-type, and description.

Returns:
A dictionary containing the parameter info.

Reimplemented from EMAN::Processor.

Definition at line 1668 of file processor.h.

References EMAN::TypeDict::put(), and EMAN::EMObject::TRANSFORM.

                        {
                                TypeDict d;
                                d.put("transform", EMObject::TRANSFORM, "The Transform object that will be applied to the image" );
                                return d;
                        }
static Processor* EMAN::TransformProcessor::NEW ( ) [inline, static]

Definition at line 1651 of file processor.h.

                        {
                                return new TransformProcessor();
                        }
EMData * TransformProcessor::process ( const EMData *const  image) [virtual]

Exceptions:
ImageDimensionExceptionif the image is not 2D or 3D
InvalidParameterExceptionif the Transform parameter is not specified

Reimplemented from EMAN::Processor.

Definition at line 9093 of file processor.cpp.

References EMAN::Transform::copy_matrix_into_array(), emdata_transform_cuda(), ENTERFUNC, EXITFUNC, EMAN::EMData::get_attr_dict(), EMAN::Transform::get_scale(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::Transform::inverse(), EMAN::Processor::params, EMAN::EMData::scale_pixel(), t, and EMAN::EMData::update().

                                                             {
        ENTERFUNC;

        assert_valid_aspect(image);

        Transform* t = params["transform"];

        EMData* p  = 0;
#ifdef EMAN2_USING_CUDA
        if(EMData::usecuda == 1 && image->isrodataongpu()){
                //cout << "using CUDA xform" << endl;
                p = new EMData(0,0,image->get_xsize(),image->get_ysize(),image->get_zsize(),image->get_attr_dict());
                float * m = new float[12];
                Transform inv = t->inverse();
                inv.copy_matrix_into_array(m);
                image->bindcudaarrayA(true);
                p->runcuda(emdata_transform_cuda(m,image->get_xsize(),image->get_ysize(),image->get_zsize()));
                image->unbindcudaarryA();
                delete [] m;
                p->update();
        }
#endif

        if ( p == 0 ) {
                float* des_data = transform(image,*t);
                p = new EMData(des_data,image->get_xsize(),image->get_ysize(),image->get_zsize(),image->get_attr_dict());
        }

        //      all_translation += transform.get_trans();

        float scale = t->get_scale();
        if (scale != 1.0) {
                p->scale_pixel(1.0f/scale);
//              update_emdata_attributes(p,image->get_attr_dict(),scale);
        }

        if(t) {delete t; t=0;}
        EXITFUNC;
        return p;
}
void TransformProcessor::process_inplace ( EMData image) [virtual]

Exceptions:
ImageDimensionExceptionif the image is not 2D or 3D
InvalidParameterExceptionif the Transform parameter is not specified

Implements EMAN::Processor.

Definition at line 9134 of file processor.cpp.

References EMAN::Transform::copy_matrix_into_array(), emdata_transform_cuda(), ENTERFUNC, EXITFUNC, EMAN::Transform::get_scale(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::Transform::inverse(), EMAN::Processor::params, EMAN::EMData::scale_pixel(), EMAN::EMData::set_data(), t, and EMAN::EMData::update().

                                                      {
        ENTERFUNC;

        assert_valid_aspect(image);

        Transform* t = params["transform"];

        //      all_translation += transform.get_trans();
        bool use_cpu = true;

#ifdef EMAN2_USING_CUDA
        if(EMData::usecuda == 1 && image->isrodataongpu()){
                //cout << "CUDA xform inplace" << endl;
                image->bindcudaarrayA(false);
                float * m = new float[12];
                Transform inv = t->inverse();
                inv.copy_matrix_into_array(m);
                image->runcuda(emdata_transform_cuda(m,image->get_xsize(),image->get_ysize(),image->get_zsize()));
                image->unbindcudaarryA();
                delete [] m;
                use_cpu = false;
                image->update();
        }
#endif
        if ( use_cpu ) {
                float* des_data = transform(image,*t);
                image->set_data(des_data,image->get_xsize(),image->get_ysize(),image->get_zsize());
                image->update();
        }
        float scale = t->get_scale();
        if (scale != 1.0f) {
                image->scale_pixel(1.0f/scale);
//              update_emdata_attributes(image,image->get_attr_dict(),scale);
        }

        if(t) {delete t; t=0;}

        EXITFUNC;
}
float * TransformProcessor::transform ( const EMData *const  image,
const Transform t 
) const

Definition at line 8932 of file processor.cpp.

References EMAN::Util::bilinear_interpolate(), EMAN::EMUtil::em_malloc(), ENTERFUNC, EXITFUNC, EMAN::Util::fast_floor(), EMAN::EMData::get_const_data(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::Transform::inverse(), nx, ny, and EMAN::Util::trilinear_interpolate().

                                                                                        {

        ENTERFUNC;

        Transform inv = t.inverse();
        int nx = image->get_xsize();
        int ny = image->get_ysize();
        int nz = image->get_zsize();
        int nxy = nx*ny;

        const float * const src_data = image->get_const_data();
        float *des_data = (float *) EMUtil::em_malloc(nx*ny*nz* sizeof(float));

        if (nz == 1) {
                Vec2f offset(nx/2,ny/2);
                for (int j = 0; j < ny; j++) {
                        for (int i = 0; i < nx; i++) {
                                Vec2f coord(i-nx/2,j-ny/2);
                                Vec2f soln = inv*coord;
                                soln += offset;

                                float x2 = soln[0];
                                float y2 = soln[1];

                                if (x2 < 0 || x2 >= nx || y2 < 0 || y2 >= ny ) {
                                        des_data[i + j * nx] = 0; // It may be tempting to set this value to the
                                        // mean but in fact this is not a good thing to do. Talk to S.Ludtke about it.
                                }
                                else {
                                        int ii = Util::fast_floor(x2);
                                        int jj = Util::fast_floor(y2);
                                        int k0 = ii + jj * nx;
                                        int k1 = k0 + 1;
                                        int k2 = k0 + nx;
                                        int k3 = k0 + nx + 1;

                                        if (ii == nx - 1) {
                                                k1--;
                                                k3--;
                                        }
                                        if (jj == ny - 1) {
                                                k2 -= nx;
                                                k3 -= nx;
                                        }

                                        float t = x2 - ii;
                                        float u = y2 - jj;

                                        des_data[i + j * nx] = Util::bilinear_interpolate(src_data[k0],src_data[k1], src_data[k2], src_data[k3],t,u);
                                }
                        }
                }
        }
        else {
                size_t l=0, ii, k0, k1, k2, k3, k4, k5, k6, k7;
                Vec3f offset(nx/2,ny/2,nz/2);
                float x2, y2, z2, tuvx, tuvy, tuvz;
                int ix, iy, iz;
                for (int k = 0; k < nz; ++k) {
                        for (int j = 0; j < ny; ++j) {
                                for (int i = 0; i < nx; ++i,++l) {
                                        Vec3f coord(i-nx/2,j-ny/2,k-nz/2);
                                        Vec3f soln = inv*coord;
                                        soln += offset;

                                        x2 = soln[0];
                                        y2 = soln[1];
                                        z2 = soln[2];

                                        if (x2 < 0 || y2 < 0 || z2 < 0 || x2 >= nx  || y2 >= ny  || z2>= nz ) {
                                                des_data[l] = 0;
                                        }
                                        else {
                                                ix = Util::fast_floor(x2);
                                                iy = Util::fast_floor(y2);
                                                iz = Util::fast_floor(z2);
                                                tuvx = x2-ix;
                                                tuvy = y2-iy;
                                                tuvz = z2-iz;
                                                ii = ix + iy * nx + iz * nxy;

                                                k0 = ii;
                                                k1 = k0 + 1;
                                                k2 = k0 + nx;
                                                k3 = k0 + nx+1;
                                                k4 = k0 + nxy;
                                                k5 = k1 + nxy;
                                                k6 = k2 + nxy;
                                                k7 = k3 + nxy;

                                                if (ix == nx - 1) {
                                                        k1--;
                                                        k3--;
                                                        k5--;
                                                        k7--;
                                                }
                                                if (iy == ny - 1) {
                                                        k2 -= nx;
                                                        k3 -= nx;
                                                        k6 -= nx;
                                                        k7 -= nx;
                                                }
                                                if (iz == nz - 1) {
                                                        k4 -= nxy;
                                                        k5 -= nxy;
                                                        k6 -= nxy;
                                                        k7 -= nxy;
                                                }

                                                des_data[l] = Util::trilinear_interpolate(src_data[k0],
                                                                src_data[k1], src_data[k2], src_data[k3], src_data[k4],
                                                                src_data[k5], src_data[k6],     src_data[k7], tuvx, tuvy, tuvz);
                                        }
                                }
                        }
                }
        }

        EXITFUNC;
        return des_data;
}

Member Data Documentation

const string TransformProcessor::NAME = "xform" [static]

Definition at line 1680 of file processor.h.

Referenced by get_name().


The documentation for this class was generated from the following files: