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

rotational and translational alignment using a square qrid of Altitude and Azimuth values (the phi range is specifiable) This aligner is ported from the original tomohunter.py - it is less efficient than searching on the sphere (RT3DSphereAligner). More...

#include <aligner.h>

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

List of all members.

Public Member Functions

virtual EMDataalign (EMData *this_img, EMData *to_img, const string &cmp_name="ccc.tomo", const Dict &cmp_params=Dict()) const
 See Aligner comments for more details.
virtual EMDataalign (EMData *this_img, EMData *to_img) const
 See Aligner comments for more details.
virtual vector< Dictxform_align_nbest (EMData *this_img, EMData *to_img, const unsigned int nsoln, const string &cmp_name, const Dict &cmp_params) const
 See Aligner comments for more details.
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 = "rotate_translate_3d_grid"

Detailed Description

rotational and translational alignment using a square qrid of Altitude and Azimuth values (the phi range is specifiable) This aligner is ported from the original tomohunter.py - it is less efficient than searching on the sphere (RT3DSphereAligner).

This is for use as a course aligner. For refineing alignments, use the refine_3d_grid aligner. In general this aligner is not used much and is mostly depreciated.

Parameters:
dazThe angle increment in the azimuth direction
lazLower bound for the azimuth direction
uazUpper bound for the azimuth direction
dphiThe angle increment in the phi direction
lphiLower bound for the phi direction
uphiUpper bound for the phi direction
daltThe angle increment in the altitude direction
laltLower bound for the altitude direction
ualtUpper bound for the altitude direction
dotransDo a translational search
searchThe maximum length of the detectable translational shift - if you supply this parameter you can not supply the maxshiftx, maxshifty or maxshiftz parameters. Each approach is mutually exclusive
searchxThe maximum length of the detectable translational shift in the x direction- if you supply this parameter you can not supply the maxshift parameters
searchyThe maximum length of the detectable translational shift in the y direction- if you supply this parameter you can not supply the maxshift parameters
searchzThe maximum length of the detectable translational shift in the z direction- if you supply this parameter you can not supply the maxshift parameters
verboseTurn this on to have useful information printed to standard out
Author:
John Flanagan and David Woolford (ported from Mike Schmid's e2tomohuntThis is the increment applied to the inplane rotationer code - Mike Schmid is the intellectual author)
Date:
Feb 2011

Definition at line 1524 of file aligner.h.


Member Function Documentation

EMData * RT3DGridAligner::align ( EMData this_img,
EMData to_img,
const string &  cmp_name = "ccc.tomo",
const Dict cmp_params = Dict() 
) const [virtual]

See Aligner comments for more details.

Implements EMAN::Aligner.

Definition at line 2434 of file aligner.cpp.

References EMAN::EMData::process(), EMAN::EMData::set_attr(), t, and EMAN::Aligner::xform_align_nbest().

Referenced by align().

{

        vector<Dict> alis = xform_align_nbest(this_img,to,1,cmp_name,cmp_params);

        Dict t;
        Transform* tr = (Transform*) alis[0]["xform.align3d"];
        t["transform"] = tr;
        EMData* soln = this_img->process("xform",t);
        soln->set_attr("xform.align3d",tr);
        delete tr; tr = 0;

        return soln;

}
virtual EMData* EMAN::RT3DGridAligner::align ( EMData this_img,
EMData to_img 
) const [inline, virtual]

See Aligner comments for more details.

Implements EMAN::Aligner.

Definition at line 1533 of file aligner.h.

References align().

                        {
                                return align(this_img, to_img, "ccc.tomo", Dict());
                        }
virtual string EMAN::RT3DGridAligner::get_desc ( ) const [inline, virtual]

Implements EMAN::Aligner.

Definition at line 1548 of file aligner.h.

                        {
                                return "3D rotational and translational alignment using specified ranges and maximum shifts";
                        }
virtual string EMAN::RT3DGridAligner::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 1543 of file aligner.h.

References NAME.

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

Implements EMAN::Aligner.

Definition at line 1558 of file aligner.h.

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

                        {
                                TypeDict d;
                                d.put("daz", EMObject::FLOAT,"The angle increment in the azimuth direction. Default is 10");
                                d.put("az0", EMObject::FLOAT,"Lower bound for the azimuth direction. Default it 0");
                                d.put("az1", EMObject::FLOAT,"Upper bound for the azimuth direction. Default it 180.0");
                                d.put("dphi", EMObject::FLOAT,"The angle increment in the phi direction. Default is 10");
                                d.put("phi0", EMObject::FLOAT,"Lower bound for the phi direction. Default it 0");
                                d.put("phi1", EMObject::FLOAT,"Upper bound for the phi direction. Default it 360.0");
                                d.put("dalt", EMObject::FLOAT,"The angle increment in the altitude direction. Default is 10");
                                d.put("alt0", EMObject::FLOAT,"Lower bound for the altitude direction. Default it 0");
                                d.put("alt1", EMObject::FLOAT,"Upper bound for the altitude direction. Default it 360.0");
                                d.put("dotrans", EMObject::BOOL,"Do a translational search. Default is True(1)");
                                d.put("search", EMObject::INT,"The maximum length of the detectable translational shift - if you supply this parameter you can not supply the maxshiftx, maxshifty or maxshiftz parameters. Each approach is mutually exclusive.");
                                d.put("searchx", EMObject::INT,"The maximum length of the detectable translational shift in the x direction- if you supply this parameter you can not supply the maxshift parameters. Default is 3.");
                                d.put("searchy", EMObject::INT,"The maximum length of the detectable translational shift in the y direction- if you supply this parameter you can not supply the maxshift parameters. Default is 3.");
                                d.put("searchz", EMObject::INT,"The maximum length of the detectable translational shift in the z direction- if you supply this parameter you can not supply the maxshift parameters. Default is 3");
                                d.put("initxform", EMObject::TRANSFORM,"The Transform storing the starting position. If unspecified the identity matrix is used");
                                d.put("verbose", EMObject::BOOL,"Turn this on to have useful information printed to standard out.");
                                return d;
                        }
static Aligner* EMAN::RT3DGridAligner::NEW ( ) [inline, static]

Definition at line 1553 of file aligner.h.

                        {
                                return new RT3DGridAligner();
                        }
vector< Dict > RT3DGridAligner::xform_align_nbest ( EMData this_img,
EMData to_img,
const unsigned int  nsoln,
const string &  cmp_name,
const Dict cmp_params 
) const [virtual]

See Aligner comments for more details.

Reimplemented from EMAN::Aligner.

Definition at line 2450 of file aligner.cpp.

References EMAN::EMData::calc_ccf(), EMAN::EMData::calc_max_location_wrap(), calc_max_location_wrap_cuda(), EMAN::Cmp::cmp(), copy(), data, EMAN::EMData::do_fft(), EMAN::EMData::get_ndim(), get_stats_cuda(), EMAN::EMData::get_value_at_wrap(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::Dict::has_key(), ImageDimensionException, InvalidParameterException, EMAN::Aligner::params, CudaPeakInfo::peak, phi, EMAN::EMData::process(), EMAN::EMData::process_inplace(), CudaPeakInfo::px, CudaPeakInfo::py, CudaPeakInfo::pz, EMAN::Dict::set_default(), EMAN::Transform::set_trans(), sqrt(), and t.

                                                                                                                                                               {

        if ( this_img->get_ndim() != 3 || to->get_ndim() != 3 ) {
                throw ImageDimensionException("This aligner only works for 3D images");
        }

        int searchx = 0;
        int searchy = 0;
        int searchz = 0;
        
        bool dotrans = params.set_default("dotrans",1);
        if (params.has_key("search")) {
                vector<string> check;
                check.push_back("searchx");
                check.push_back("searchy");
                check.push_back("searchz");
                for(vector<string>::const_iterator cit = check.begin(); cit != check.end(); ++cit) {
                        if (params.has_key(*cit)) throw InvalidParameterException("The search parameter is mutually exclusive of the searchx, searchy, and searchz parameters");
                }
                int search  = params["search"];
                searchx = search;
                searchy = search;
                searchz = search;
        } else {
                searchx = params.set_default("searchx",3);
                searchy = params.set_default("searchy",3);
                searchz = params.set_default("searchz",3);
        }
        
        Transform* initxform;
        if (params.has_key("initxform") ) {
                // Unlike the 2d refine aligner, this class doesn't require the starting transform's
                // parameters to form the starting guess. Instead the Transform itself
                // is perturbed carefully (using quaternion rotation) to overcome problems that arise
                // when you use orthogonally-based Euler angles
                initxform = params["initxform"];
        }else {
                initxform = new Transform(); // is the identity
        }
        
        float lalt = params.set_default("alt0",0.0f);
        float laz = params.set_default("az0",0.0f);
        float lphi = params.set_default("phi0",0.0f);
        float ualt = params.set_default("alt1",180.0f); // I am using 179.9 rather than 180 to avoid resampling
        float uphi = params.set_default("phi1",360.0f); // I am using 359.9 rather than 180 to avoid resampling 0 = 360 (for perodic functions)
        float uaz = params.set_default("az1",360.0f);   // I am using 359.9 rather than 180 to avoid resampling 0 = 360 (for perodic functions)
        float dalt = params.set_default("dalt",10.f);
        float daz = params.set_default("daz",10.f);
        float dphi = params.set_default("dphi",10.f);
        bool verbose = params.set_default("verbose",false);
        
        //in case we arre aligning tomos
        Dict altered_cmp_params(cmp_params);
        if (cmp_name == "ccc.tomo") {
                altered_cmp_params.set_default("searchx", searchx);
                altered_cmp_params.set_default("searchy", searchy);
                altered_cmp_params.set_default("searchz", searchz);
                altered_cmp_params.set_default("norm", true);
        }

        vector<Dict> solns;
        if (nsoln == 0) return solns; // What was the user thinking?
        for (unsigned int i = 0; i < nsoln; ++i ) {
                Dict d;
                d["score"] = 1.e24;
                Transform t; // identity by default
                d["xform.align3d"] = &t; // deep copy is going on here
                solns.push_back(d);
        }
        
        bool tomography = (cmp_name == "ccc.tomo") ? 1 : 0;
        EMData * tofft = 0;
        if(dotrans || tomography){
                tofft = to->do_fft();
        }
        
#ifdef EMAN2_USING_CUDA 
        if(EMData::usecuda == 1) {
                if(!this_img->getcudarodata()) this_img->copy_to_cudaro();  // safer call
                if(!to->getcudarwdata()) to->copy_to_cuda();
                if(to->getcudarwdata()){if(tofft) tofft->copy_to_cuda();}
        }
#endif

        Dict d;
        d["type"] = "eman"; // d is used in the loop below
        Transform trans = Transform();
        Cmp* c = Factory <Cmp>::get(cmp_name, cmp_params);
        bool use_cpu = true;
        for ( float alt = lalt; alt <= ualt; alt += dalt) {
                // An optimization for the range of az is made at the top of the sphere
                // If you think about it, this is just a coarse way of making this approach slightly more efficient
                for ( float az = laz; az < uaz; az += daz ){
                        if (verbose) {
                                cout << "Trying angle alt " << alt << " az " << az << endl;
                        }
                        for( float phi = lphi; phi < uphi; phi += dphi ) {
                                d["alt"] = alt;
                                d["phi"] = phi; 
                                d["az"] = az;
                                Transform t(d);
                                t = t*(*initxform);
                                EMData* transformed = this_img->process("xform",Dict("transform",&t));
                        
                                //need to do things a bit diffrent if we want to compare two tomos
                                float best_score = 0.0f;
                                if(dotrans || tomography){
                                        EMData* ccf = transformed->calc_ccf(tofft);
#ifdef EMAN2_USING_CUDA 
                                        if(EMData::usecuda == 1){
                                                use_cpu = false;;
                                                CudaPeakInfo* data = calc_max_location_wrap_cuda(ccf->getcudarwdata(), ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize(), searchx, searchy, searchz);
                                                trans.set_trans((float)-data->px, (float)-data->py, (float)-data->pz);
                                                t = trans*t;    //composite transfrom to reflect the fact that we have done a rotation first and THEN a transformation
                                                if (tomography) {
                                                        float2 stats = get_stats_cuda(ccf->getcudarwdata(), ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize());
                                                        best_score = -(data->peak - stats.x)/sqrt(stats.y); // Normalize, this is better than calling the norm processor since we only need to normalize one point
                                                } else {
                                                        best_score = -data->peak;
                                                }
                                                delete data;
                                        }
#endif
                                        if(use_cpu){
                                                if(tomography) ccf->process_inplace("normalize");       
                                                IntPoint point = ccf->calc_max_location_wrap(searchx,searchy,searchz);
                                                trans.set_trans((float)-point[0], (float)-point[1], (float)-point[2]);
                                                t = trans*t;    //composite transfrom to reflect the fact that we have done a rotation first and THEN a transformation
                                                best_score = -ccf->get_value_at_wrap(point[0], point[1], point[2]);
                                        }
                                        delete ccf; ccf =0;
                                        delete transformed; transformed = 0;
                                }

                                if(!tomography){
                                        if(!transformed) transformed = this_img->process("xform",Dict("transform",&t));
                                        best_score = c->cmp(to,transformed);
                                        delete transformed; transformed = 0;
                                }
                                
                                unsigned int j = 0;
                                for ( vector<Dict>::iterator it = solns.begin(); it != solns.end(); ++it, ++j ) {
                                        if ( (float)(*it)["score"] > best_score ) {  // Note greater than - EMAN2 preferes minimums as a matter of policy
                                                vector<Dict>::reverse_iterator rit = solns.rbegin();
                                                copy(rit+1,solns.rend()-j,rit);
                                                Dict& d = (*it);
                                                d["score"] = best_score;
                                                d["xform.align3d"] = &t;
                                                break;
                                        }
                                }
                        }
                }
        }
        
        if(tofft) {delete tofft; tofft = 0;}
        if (c != 0) delete c;
        
        return solns;

}

Member Data Documentation

const string RT3DGridAligner::NAME = "rotate_translate_3d_grid" [static]

Definition at line 1580 of file aligner.h.

Referenced by get_name().


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