EMAN2
Public Member Functions | Static Public Member Functions | Static Public Attributes
EMAN::TranslationalAligner Class Reference

Translational 2D Alignment using cross correlation. More...

#include <aligner.h>

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

List of all members.

Public Member Functions

virtual EMDataalign (EMData *this_img, EMData *to_img, const string &cmp_name="dot", const Dict &cmp_params=Dict()) const
 To align 'this_img' with another image passed in through its parameters.
virtual EMDataalign (EMData *this_img, EMData *to_img) const
virtual string get_name () const
 Get the Aligner's name.
virtual string get_desc () const
virtual TypeDict get_param_types () const

Static Public Member Functions

static AlignerNEW ()

Static Public Attributes

static const string NAME = "translational"

Detailed Description

Translational 2D Alignment using cross correlation.

It calculates the shift for a translational alignment, then do the translation.

Parameters:
intonlyInteger pixel translations only
maxshiftMaximum translation in pixels
nozeroZero translation not permitted (useful for CCD images)

Definition at line 241 of file aligner.h.


Member Function Documentation

EMData * TranslationalAligner::align ( EMData this_img,
EMData to_img,
const string &  cmp_name = "dot",
const Dict cmp_params = Dict() 
) const [virtual]

To align 'this_img' with another image passed in through its parameters.

The alignment uses a user-given comparison method to compare the two images. If none is given, a default one is used.

Parameters:
this_imgThe image to be compared.
to_img'this_img" is aligned with 'to_img'.
cmp_nameThe comparison method to compare the two images.
cmp_paramsThe parameter dictionary for comparison method.
Returns:
The aligned image.

Implements EMAN::Aligner.

Definition at line 248 of file aligner.cpp.

References EMAN::EMData::calc_ccf(), EMAN::EMData::calc_flcf(), EMAN::EMData::calc_max_location_wrap(), calc_max_location_wrap_cuda(), data, EMAN::EMData::get_data(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), ImageDimensionException, EMAN::EMUtil::is_same_size(), nx, ny, EMAN::Aligner::params, EMAN::EMData::process(), EMAN::EMData::process_inplace(), CudaPeakInfo::px, CudaPeakInfo::py, CudaPeakInfo::pz, EMAN::EMData::set_attr(), EMAN::Dict::set_default(), EMAN::Transform::set_trans(), t, UnexpectedBehaviorException, EMAN::EMData::update(), and EMAN::EMData::zero_corner_circulant().

Referenced by align().

{
        if (!this_img) {
                return 0;
        }

        if (to && !EMUtil::is_same_size(this_img, to))
                throw ImageDimensionException("Images must be the same size to perform translational alignment");

        EMData *cf = 0;
        int nx = this_img->get_xsize();
        int ny = this_img->get_ysize();
        int nz = this_img->get_zsize();

        int masked = params.set_default("masked",0);
        int useflcf = params.set_default("useflcf",0);
        bool use_cpu = true;

#ifdef EMAN2_USING_CUDA
        if(EMData::usecuda == 1) {
                //if(!this_img->getcudarwdata()) this_img->copy_to_cuda();
                //if(to && !to->getcudarwdata()) to->copy_to_cuda();
                //if (masked) throw UnexpectedBehaviorException("Masked is not yet supported in CUDA");
                //if (useflcf) throw UnexpectedBehaviorException("Useflcf is not yet supported in CUDA");
                //cout << "Translate on GPU" << endl;
                //use_cpu = false;
                //cf = this_img->calc_ccf(to);
        }
#endif // EMAN2_USING_CUDA
        
        if (use_cpu) {
                if (useflcf) cf = this_img->calc_flcf(to);
                else cf = this_img->calc_ccf(to);
        }
        //return cf;
        // This is too expensive, esp for CUDA(we we can fix later
        if (masked) {
                EMData *msk=this_img->process("threshold.notzero");
                EMData *sqr=to->process("math.squared");
                EMData *cfn=msk->calc_ccf(sqr);
                cfn->process_inplace("math.sqrt");
                float *d1=cf->get_data();
                float *d2=cfn->get_data();
                for (size_t i=0; i<(size_t)nx*ny*nz; ++i) {
                        if (d2[i]!=0) d1[i]/=d2[i];
                }
                cf->update();
                delete msk;
                delete sqr;
                delete cfn;
        }

        int maxshiftx = params.set_default("maxshift",-1);
        int maxshifty = params["maxshift"];
        int maxshiftz = params["maxshift"];
        int nozero = params["nozero"];

        if (maxshiftx <= 0) {
                maxshiftx = nx / 4;
                maxshifty = ny / 4;
                maxshiftz = nz / 4;
        }

        if (maxshiftx > nx / 2 - 1) maxshiftx = nx / 2 - 1;
        if (maxshifty > ny / 2 - 1)     maxshifty = ny / 2 - 1;
        if (maxshiftz > nz / 2 - 1) maxshiftz = nz / 2 - 1;

        if (nx == 1) maxshiftx = 0; // This is justhere for completeness really... plus it saves errors
        if (ny == 1) maxshifty = 0;
        if (nz == 1) maxshiftz = 0;

        // If nozero the portion of the image in the center (and its 8-connected neighborhood) is zeroed
        if (nozero) {
                cf->zero_corner_circulant(1);
        }
        
        IntPoint peak;
#ifdef EMAN2_USING_CUDA
        if (!use_cpu) {
                cout << "USe CUDA TA 2" << endl;
                if (nozero) throw UnexpectedBehaviorException("Nozero is not yet supported in CUDA");
                CudaPeakInfo* data = calc_max_location_wrap_cuda(cf->getcudarwdata(), cf->get_xsize(), cf->get_ysize(), cf->get_zsize(), maxshiftx, maxshifty, maxshiftz);
                peak = IntPoint(data->px,data->py,data->pz);
                free(data);
        }
#endif // EMAN2_USING_CUDA
        
        if (use_cpu) {
                peak = cf->calc_max_location_wrap(maxshiftx, maxshifty, maxshiftz);
        }
        //cout << -peak[0] << " " << -peak[1] << " " << -peak[2] << endl;
        Vec3f cur_trans = Vec3f ( (float)-peak[0], (float)-peak[1], (float)-peak[2]);
        //cout << peak[0] << " " << peak[1] << endl;

        if (!to) {
                cur_trans /= 2.0f; // If aligning theimage to itself then only go half way -
                int intonly = params.set_default("intonly",false);
                if (intonly) {
                        cur_trans[0] = floor(cur_trans[0] + 0.5f);
                        cur_trans[1] = floor(cur_trans[1] + 0.5f);
                        cur_trans[2] = floor(cur_trans[2] + 0.5f);
                }
        }

        if( cf ){
                delete cf;
                cf = 0;
        }
        
        Dict params("trans",static_cast< vector<int> >(cur_trans));
        if (use_cpu){
                cf=this_img->process("xform.translate.int",params);
        }
        Transform t;
        t.set_trans(cur_trans);
        
#ifdef EMAN2_USING_CUDA
        if (!use_cpu) {
                cout << "USe CUDA TA 3" << endl;
                //this will work just fine....
                cf = this_img->process("xform",Dict("transform",&t));
        }
#endif // EMAN2_USING_CUDA

        if ( nz != 1 ) {
//              Transform* t = get_set_align_attr("xform.align3d",cf,this_img);
//              t->set_trans(cur_trans);
                cf->set_attr("xform.align3d",&t);
        } else if ( ny != 1 ) {
                //Transform* t = get_set_align_attr("xform.align2d",cf,this_img);
                cur_trans[2] = 0; // just make sure of it
                t.set_trans(cur_trans);
                cf->set_attr("xform.align2d",&t);
        }
        return cf;
}
virtual EMData* EMAN::TranslationalAligner::align ( EMData this_img,
EMData to_img 
) const [inline, virtual]

Implements EMAN::Aligner.

Definition at line 247 of file aligner.h.

References align().

                {
                        return align(this_img, to_img, "dot", Dict());
                }
virtual string EMAN::TranslationalAligner::get_desc ( ) const [inline, virtual]

Implements EMAN::Aligner.

Definition at line 257 of file aligner.h.

                {
                        return "Translational 2D and 3D alignment by cross-correlation";
                }
virtual string EMAN::TranslationalAligner::get_name ( ) const [inline, virtual]

Get the Aligner's name.

Each Aligner is identified by a unique name.

Returns:
The Aligner's name.

Implements EMAN::Aligner.

Definition at line 252 of file aligner.h.

References NAME.

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

Implements EMAN::Aligner.

Definition at line 267 of file aligner.h.

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

                {
                        TypeDict d;
                        d.put("intonly", EMObject::INT,"Integer pixel translations only");
                        d.put("useflcf", EMObject::INT,"Use Fast Local Correlation Function rather than CCF");
                        d.put("maxshift", EMObject::INT,"Maximum translation in pixels");
                        d.put("masked", EMObject::INT,"Treat zero pixels in 'this' as a mask for normalization (default false)");
                        d.put("nozero", EMObject::INT,"Zero translation not permitted (useful for CCD images)");
                        return d;
                }
static Aligner* EMAN::TranslationalAligner::NEW ( ) [inline, static]

Definition at line 262 of file aligner.h.

                {
                        return new TranslationalAligner();
                }

Member Data Documentation

const string TranslationalAligner::NAME = "translational" [static]

Definition at line 278 of file aligner.h.

Referenced by get_name().


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