EMAN2
Public Member Functions | Static Public Member Functions | Static Public Attributes | Private Member Functions | List of all members
EMAN::RT2Dto3DTreeAligner Class Reference

Alignment of a 2D image into a 3D volume using a hierarchical method with gradually decreasing downsampling in Fourier space. More...

#include <aligner.h>

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

Public Member Functions

virtual EMDataalign (EMData *this_img, EMData *to_img, const string &cmp_name="sqeuclidean", const Dict &cmp_params=Dict()) const
 See Aligner comments for more details. More...
 
virtual EMDataalign (EMData *this_img, EMData *to_img) const
 See Aligner comments for more details. More...
 
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. More...
 
virtual string get_name () const
 Get the Aligner's name. More...
 
virtual string get_desc () const
 
virtual TypeDict get_param_types () const
 
- Public Member Functions inherited from EMAN::Aligner
virtual ~Aligner ()
 
virtual Dict get_params () const
 Get the Aligner parameters in a key/value dictionary. More...
 
virtual void set_params (const Dict &new_params)
 Set the Aligner parameters using a key/value dictionary. More...
 

Static Public Member Functions

static AlignerNEW ()
 

Static Public Attributes

static const string NAME = "rotate_translate_2d_to_3d_tree"
 

Private Member Functions

bool testort (EMData *small_this, EMData *small_to, vector< float > &s_score, vector< Transform > &s_xform, int i, Dict &upd, Transform initxf, int maxshift, int maxang) const
 

Additional Inherited Members

- Protected Attributes inherited from EMAN::Aligner
Dict params
 

Detailed Description

Alignment of a 2D image into a 3D volume using a hierarchical method with gradually decreasing downsampling in Fourier space.

In theory, very fast, and without need for a "refine" aligner. Comparator is ignored. Uses an inbuilt comparison.

Parameters
symThe symmtery to use as the basis of the spherical sampling
verboseTurn this on to have useful information printed to standard out
Author
Steve Ludtke
Date
Feburary 2016

Finished by MuyuanChen, 07/2018

Definition at line 1825 of file aligner.h.

Member Function Documentation

◆ align() [1/2]

virtual EMData * EMAN::RT2Dto3DTreeAligner::align ( EMData this_img,
EMData to_img 
) const
inlinevirtual

See Aligner comments for more details.

Implements EMAN::Aligner.

Definition at line 1834 of file aligner.h.

1835 {
1836 return align(this_img, to_img, "sqeuclidean", Dict());
1837 }
virtual EMData * align(EMData *this_img, EMData *to_img, const string &cmp_name="sqeuclidean", const Dict &cmp_params=Dict()) const
See Aligner comments for more details.

References align().

◆ align() [2/2]

virtual EMData * EMAN::RT2Dto3DTreeAligner::align ( EMData this_img,
EMData to_img,
const string &  cmp_name = "sqeuclidean",
const Dict cmp_params = Dict() 
) const
virtual

See Aligner comments for more details.

Implements EMAN::Aligner.

Referenced by align().

◆ get_desc()

virtual string EMAN::RT2Dto3DTreeAligner::get_desc ( ) const
inlinevirtual

Implements EMAN::Aligner.

Definition at line 1849 of file aligner.h.

1850 {
1851 return "3D rotational and translational alignment using a hierarchical approach in Fourier space. Should be very fast and not require 'refine' alignment.";
1852 }

◆ get_name()

virtual string EMAN::RT2Dto3DTreeAligner::get_name ( ) const
inlinevirtual

Get the Aligner's name.

Each Aligner is identified by a unique name.

Returns
The Aligner's name.

Implements EMAN::Aligner.

Definition at line 1844 of file aligner.h.

1845 {
1846 return NAME;
1847 }
static const string NAME
Definition: aligner.h:1874

References NAME.

◆ get_param_types()

virtual TypeDict EMAN::RT2Dto3DTreeAligner::get_param_types ( ) const
inlinevirtual

Implements EMAN::Aligner.

Definition at line 1859 of file aligner.h.

1860 {
1861 TypeDict d;
1862 d.put("sym", EMObject::STRING,"The symmtery to use as the basis of the spherical sampling. Default is c1 (no symmetry)");
1863 d.put("maxshift", EMObject::INT,"maximum shift allowed");
1864// d.put("sigmathis", EMObject::FLOAT,"Only Fourier voxels larger than sigma times this value will be considered");
1865// d.put("sigmato", EMObject::FLOAT,"Only Fourier voxels larger than sigma times this value will be considered");
1866 d.put("initxform", EMObject::TRANSFORMARRAY,"An array of Transforms storing the starting positions.");
1867 d.put("maxang", EMObject::FLOAT,"maximum angle from initial rotation.");
1868 d.put("verbose", EMObject::BOOL,"Turn this on to have useful information printed to standard out.");
1869 d.put("maxres", EMObject::FLOAT,"Maximum resolution to consider when full sampling is used");
1870 d.put("minres", EMObject::FLOAT,"Minimum resolution to consider when full sampling is used");
1871 return d;
1872 }

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

◆ NEW()

static Aligner * EMAN::RT2Dto3DTreeAligner::NEW ( )
inlinestatic

Definition at line 1854 of file aligner.h.

1855 {
1856 return new RT2Dto3DTreeAligner();
1857 }

◆ testort()

bool RT2Dto3DTreeAligner::testort ( EMData small_this,
EMData small_to,
vector< float > &  s_score,
vector< Transform > &  s_xform,
int  i,
Dict upd,
Transform  initxf,
int  maxshift,
int  maxang 
) const
private

Definition at line 3339 of file aligner.cpp.

3339 {
3340 Transform t;
3341 Dict aap=s_xform[i].get_params("eman");
3342
3343 int ny=small_this->get_ysize();
3344 if (params.has_key("initxform")){
3345 // when doing refinement, search around the given position
3346 const vector< Transform > xfs=params["initxform"];
3347 Dict xf0=xfs[i].get_params("eman");
3348 aap["tx"]=(float)xf0["tx"]*ny/(float)params["boxsize"];
3349 aap["ty"]=(float)xf0["ty"]*ny/(float)params["boxsize"];
3350
3351 }
3352 else{
3353 aap["tx"]=0;
3354 aap["ty"]=0;
3355 }
3356 aap["tz"]=0;
3357 for (Dict::const_iterator p=upd.begin(); p!=upd.end(); p++) {
3358 aap[p->first]=(float)aap[p->first]+(float)p->second;
3359 }
3360
3361 t.set_params(aap);
3362
3363
3364 if (maxang>0){
3365
3366 Transform tmp=initxf * t.inverse();
3367 float r=tmp.get_params("spin")["omega"];
3368 if(r>maxang)
3369 return false;
3370
3371 }
3372 // rotate in Fourier space then use a CCF to find translation
3373// EMData *stt=small_this->process("xform",Dict("transform",EMObject(&t),"zerocorners",1));
3374 EMData *stt=small_this->project("gauss_fft", Dict("transform", EMObject(&t), "returnfft", 1));
3375 EMData *ccf=small_to->calc_ccf(stt);
3376
3377
3378 IntPoint ml=ccf->calc_max_location_wrap(maxshift,maxshift,0);
3379 aap["tx"]=(int)aap["tx"]+(int)ml[0];
3380 aap["ty"]=(int)aap["ty"]+(int)ml[1];
3381
3382 t.set_params(aap);
3383 stt->translate(t.get_trans());
3384// EMData *st2=small_this->project("gauss_fft", Dict("transform", EMObject(&t), "returnfft", 1));
3385
3386 float sim;
3387 sim=stt->cmp("frc",small_to, Dict("pmin",(float)ny*0.125f, "pmax", (float)ny*0.33f));
3388
3389 delete ccf;
3390 delete stt;
3391
3392 // If the score is better than before, we update this particular best value
3393 if (sim<s_score[i]) {
3394 s_score[i]=sim;
3395// s_coverage[i]=1;//st2->get_attr("fft_overlap");
3396 s_xform[i]=t;
3397
3398 return true;
3399 }
3400 return false;
3401}
Dict params
Definition: aligner.h:147
Const iterator support for the Dict object This is just a wrapper, everything is inherited from the m...
Definition: emobject.h:674
Dict is a dictionary to store <string, EMObject> pair.
Definition: emobject.h:385
iterator end()
Definition: emobject.cpp:1061
iterator begin()
Definition: emobject.cpp:1045
bool has_key(const string &key) const
Ask the Dictionary if it as a particular key.
Definition: emobject.h:511
EMData stores an image's data and defines core image processing routines.
Definition: emdata.h:82
void translate(float dx, float dy, float dz)
Translate this image.
Definition: emdata.cpp:904
EMObject is a wrapper class for types including int, float, double, etc as defined in ObjectType.
Definition: emobject.h:123
IntPoint defines an integer-coordinate point in a 1D/2D/3D space.
Definition: geometry.h:192
A Transform object is a somewhat specialized object designed specifically for EMAN2/Sparx storage of ...
Definition: transform.h:75
Dict get_params(const string &euler_type) const
Get the parameters of the entire transform, using a specific euler convention.
Definition: transform.cpp:479
Vec3f get_trans() const
Get the post trans as a vec3f.
Definition: transform.cpp:1046
void set_params(const Dict &d)
Set the parameters of the entire transform.
Definition: transform.cpp:254
Transform inverse() const
Get the inverse of this transformation matrix.
Definition: transform.cpp:1327
EMData * calc_ccf(EMData *with=0, fp_flag fpflag=CIRCULANT, bool center=false)
Calculate Cross-Correlation Function (CCF).
Definition: emdata.cpp:1499

References EMAN::Dict::begin(), EMAN::EMData::calc_ccf(), EMAN::Dict::end(), EMAN::Transform::get_params(), EMAN::Transform::get_trans(), EMAN::Dict::has_key(), EMAN::Transform::inverse(), EMAN::Aligner::params, EMAN::Transform::set_params(), and EMAN::EMData::translate().

Referenced by xform_align_nbest().

◆ xform_align_nbest()

vector< Dict > RT2Dto3DTreeAligner::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 2998 of file aligner.cpp.

2998 {
2999 if (this_img->get_zsize()!=1 || to->get_zsize()==1) throw InvalidParameterException("ERROR (RT2Dto3DTreeAligner): first image must be 2D and second 3D");
3000
3001 if (nrsoln == 0) throw InvalidParameterException("ERROR (RT2Dto3DTreeAligner): nsoln must be >0"); // What was the user thinking?
3002
3003
3004 int verbose = params.set_default("verbose",0);
3005 int nsoln = nrsoln*2;
3006 if (nrsoln<16) nsoln=32; // we start with at least 32 solutions, but then gradually decrease with increasing scale
3007 if (params.has_key("initxform")){// refine alignment
3008 const vector< Transform > xfs=params["initxform"];
3009 nsoln=xfs.size();
3010 }
3011
3012 vector<float> s_score(nsoln,1.0e24);
3013 vector<float> s_step(nsoln*3,7.5f);
3014 vector<Transform> s_xform(nsoln);
3015
3016 int curiter=-1;
3017 int sexp_start=4;
3018 int ny=this_img->get_ysize();
3019 int maxshift00=(int)params.set_default("maxshift",ny/4);
3020 float maxres = params.set_default("maxres",-1.0f);
3021 float apix=(float)this_img->get_attr("apix_x");
3022 int maxny=ny;
3023 int maxrescut=ny/2;
3024 if (maxres>0){
3025 maxrescut=int(ny*apix/maxres);
3026 maxny=maxrescut*3/2*2;
3027 if(maxny>ny) maxny=ny;
3028 }
3029 if (verbose>0)
3030 printf("\n\n*******\nmax resolution %1.2f, box size %d\n", maxres, maxny);
3031
3032
3033 float maxang=params.set_default("maxang",-1.0);
3034 Transform initxf;
3035
3036 if (params.has_key("initxform")){
3037 const vector< Transform > xfs=params["initxform"];
3038 initxf.set_params(xfs[0].get_params("eman"));
3039 for (unsigned int i=0; i<nsoln; i++){
3040 s_xform[i].set_params(xfs[i].get_params("eman"));
3041 }
3042 sexp_start=9;
3043
3044
3045 curiter=0;
3046 float s=2.5; // random initial direction to avoid bias, increased initial step 12/30/20
3047 if ((maxang>0) && (s>maxang/2)){
3048 s=maxang/2;
3049 }
3050 std::random_device rd;
3051 std::uniform_int_distribution<int> dist(0, 1);
3052 for (int i=0; i<nsoln*3; i++) {
3053 s_step[i]=s*(dist(rd))?1.0:-1.0;
3054 }
3055 }
3056
3057 if (verbose>0) printf("%d solutions\n",nsoln);
3058
3059 // !!!!!! IMPORTANT NOTE - we are inverting the order of this and to here to match convention in other aligners, and the transform that project the 3D image to the 2D image is returned.
3060 EMData *base_this;
3061 EMData *base_to;
3062 if (this_img->is_complex()) base_to=this_img->copy();
3063 else {
3064 base_to=this_img->do_fft();
3065 base_to->process_inplace("xform.phaseorigin.tocorner");
3066 }
3067
3068 if (to->is_complex()) base_this=to->copy();
3069 else {
3070 base_this=to->do_fft();
3071 base_this->process_inplace("xform.phaseorigin.tocorner");
3072 }
3073
3074
3075
3076 if (base_this->get_xsize()!=base_this->get_ysize()+2 || base_this->get_ysize()!=base_this->get_zsize()
3077 || base_to->get_xsize()!=base_to->get_ysize()+2 /*|| base_to->get_ysize()!=base_to->get_zsize()*/) throw InvalidCallException("ERROR (RT3DTreeAligner): requires cubic images with even numbered box sizes");
3078
3079 base_this->process_inplace("xform.fourierorigin.tocenter"); // easier to chop out Fourier subvolumes
3080 base_to->process_inplace("xform.fourierorigin.tocenter");
3081
3082 params["boxsize"]=ny;
3083
3084
3085 string axname[] = {"az","alt","phi"};
3086
3087 // We start with 32^3, 64^3 ...
3088
3089 for (int sexp=sexp_start; sexp<10; sexp++) {
3090 curiter++;
3091 int ss=pow(2.0,sexp);
3092 if (ss==16) ss=24; // 16 may be too small, but 32 takes too long...
3093 if (ss==32) ss=48; // 16 may be too small, but 32 takes too long...
3094 if (ss>maxny) ss=maxny;
3095
3096 int maxshift=maxshift00*ss/ny;
3097 if (maxshift00<0) maxshift=-1;
3098 if (verbose>0) printf("\nSize %d, maxshift %d\n",ss, maxshift);
3099
3100 EMData *small_this=base_this->get_clip(Region(0,(ny-ss)/2,(ny-ss)/2,ss+2,ss,ss)); // This one is 3D
3101 EMData *small_to= base_to-> get_clip(Region(0,(ny-ss)/2,0,ss+2,ss,1)); // to is 2D
3102 small_this->process_inplace("xform.fourierorigin.tocorner"); // after clipping back to canonical form
3103 small_this->process_inplace("filter.highpass.gauss",Dict("cutoff_pixels",4));
3104
3105 small_to->process_inplace("xform.fourierorigin.tocorner");
3106 small_to->process_inplace("filter.highpass.gauss",Dict("cutoff_pixels",4));
3107
3108 if (ss<maxny){
3109 small_to->process_inplace("filter.lowpass.gauss",Dict("cutoff_abs",0.375f));
3110 small_this->process_inplace("filter.lowpass.gauss",Dict("cutoff_abs",0.375f));
3111 }
3112
3113 small_this->process_inplace("xform.fourierorigin.tocenter");
3114
3115 // This is a solid estimate for very complete searching, 2.5 is a bit arbitrary
3116 // make sure the altitude step hits 90 degrees, not absolutely necessary for this, but can't hurt
3117// float astep = 89.999/floor(pi/(2.5*2.0*atan(2.0/ss)));
3118 float astep = 89.999/floor(pi/(1.5*2.0*atan(2.0/ss)));
3119 if ((maxang>0) && (astep>maxang/2)){
3120 astep=maxang/2;
3121 }
3122
3123 // This is drawn from single particle analysis testing, which in that case insures that enough sampling to
3124 // reasonably fill Fourier space is achieved, but doesn't perfectly apply to SPT
3125// float astep = (float)(89.99/ceil(90.0*9.0/(8.0*sqrt((float)(4300.0/ss))))); // 8 is (3+speed) from SPA with speed=5
3126
3127 // This insures we make at least one real effort at each level
3128 for (int i=0; i<nsoln; i++) {
3129 s_score[i]=1.0e24; // reset the scores since the different scales will not match
3130 if (fabs(s_step[i*3+0])<astep/4.0) s_step[i*3+0]*=2.0;
3131 if (fabs(s_step[i*3+1])<astep/4.0) s_step[i*3+1]*=2.0;
3132 if (fabs(s_step[i*3+2])<astep/4.0) s_step[i*3+2]*=2.0;
3133 }
3134
3135 // This is for the first loop, we do a full search in a heavily downsampled space
3136 if (curiter==0) {
3137 // Genrate points on a sphere in an asymmetric unit
3138 if (verbose>1) printf("stage 1 - ang step %1.2f\n",astep);
3139 Dict d;
3140 d["inc_mirror"] = 1;
3141 d["delta"] = astep;
3142 Symmetry3D* sym = Factory<Symmetry3D>::get((string)params.set_default("sym","c1"));
3143 // We don't generate for phi, since this can produce a very large number of orientations
3144 vector<Transform> transforms = sym->gen_orientations("eman", d);
3145 if (verbose>0) printf("%d orientations to test (%lu)\n",(int)(transforms.size()*(360.0/astep)),transforms.size());
3146
3147 for (unsigned int it=0; it<transforms.size(); it++) {
3148 if (verbose>2) {
3149 printf(" %d/%lu \r",it,transforms.size());
3150 fflush(stdout);
3151 }
3152 for (float phi=0; phi<360.0; phi+=astep) {
3153 Transform t = transforms[it];
3154 Dict aap=t.get_params("eman");
3155 aap["phi"]=phi;
3156 aap["tx"]=0;
3157 aap["ty"]=0;
3158 aap["tz"]=0;
3159 t.set_params(aap);
3160// t.invert();
3161// aap=t.get_params("eman");
3162
3163 // somewhat strangely, rotations are actually much more expensive than FFTs, so we use a CCF for translation
3164 EMData *stt=small_this->project("gauss_fft", Dict("transform", EMObject(&t), "returnfft", 1));
3165
3166// EMData *stt=small_this->process("xform",Dict("transform",EMObject(&t),"zerocorners",1));
3167 EMData *ccf=small_to->calc_ccf(stt);
3168 IntPoint ml=ccf->calc_max_location_wrap(maxshift,maxshift,0);
3169
3170 aap["tx"]=(int)ml[0];
3171 aap["ty"]=(int)ml[1];
3172 aap["tz"]=0;//(int)ml[2];
3173 t.set_params(aap);
3174
3175 delete stt;
3176 delete ccf;
3177 stt=small_this->project("gauss_fft", Dict("transform", EMObject(&t), "returnfft", 1));
3178 // stt=small_this->process("xform",Dict("transform",EMObject(&t),"zerocorners",1));
3179 // we have to do 1 slow transform here now that we have the translation
3180
3181// float sim=stt->cmp("ccc.tomo.thresh",small_to,Dict("sigmaimg",sigmathis,"sigmawith",sigmato));
3182// float sim=stt->cmp("ccc.tomo.thresh",small_to);
3183 float sim=stt->cmp("frc",small_to);
3184// float sim=stt->cmp("fsc.tomo.auto",small_to,Dict("sigmaimg",sigmathisv,"sigmawith",sigmatov));
3185// float sim=stt->cmp("fsc.tomo.auto",small_to);
3186
3187 // We want to make sure our starting points are somewhat separated from each other, so we replace any angles too close to an existing angle
3188 // If we find an existing 'best' angle within range, then we either replace it or skip
3189 int worst=-1;
3190 float worstv=1.0e20;
3191 for (int i=0; i<nsoln; i++) {
3192 if (s_score[i]>1.0e20) continue; // hasn't been set yet
3193 Transform tdif=s_xform[i].inverse();
3194 tdif=tdif*t;
3195 float adif=tdif.get_rotation("spin")["omega"];
3196 if (adif<astep*4) {
3197 worst=i;
3198// printf("= %1.3f\n",adif);
3199 }
3200 }
3201
3202 // if we weren't close to an existing angle, then we find the lowest current score and use that
3203 if (worst==-1) {
3204 // First we find the worst solution in the list of possible best solutions, or the first
3205 // solution which is currently "empty"
3206 for (int i=0; i<nsoln; i++) {
3207 if (s_score[i]>1.0e20) { worst=i; break; }
3208 if (s_score[i]<worstv) {worst=i; worstv=s_score[i];}
3209// if (s_score[i]<s_score[worst]) worst=i;
3210 }
3211 }
3212
3213 // If the current solution is better than the 'worst' of the previous solutions, then we
3214 // displace it. Note that there is no sorting performed here
3215 if (sim<s_score[worst]) {
3216 s_score[worst]=sim;
3217// s_coverage[worst]=1;//stt->get_attr("fft_overlap");
3218 s_xform[worst]=t;
3219 }
3220 delete stt;
3221 }
3222 }
3223 if (verbose>2) printf("\n");
3224
3225
3226 }
3227 // Once we have our initial list of best locations, we just refine each possibility individually
3228 else {
3229 // We generate a search pattern around each existing solution
3230 if (verbose>1) printf("stage 2 (%1.2f)\n",astep);
3231 for (int i=0; i<nsoln; i++) {
3232
3233 if (verbose>2) {
3234 printf(" %d\t%d\r",i,nsoln);
3235 fflush(stdout);
3236 }
3237 // We work an axis at a time until we get where we want to be. Somewhat like a simplex
3238 int changed=1;
3239 Dict upd0;
3240 int r=testort(small_this,small_to,s_score,s_xform,i,upd0,initxf,maxshift, maxang);
3241 while (changed) {
3242 changed=0;
3243 for (int axis=0; axis<3; axis++) {
3244 if (fabs(s_step[i*3+axis])<astep/4.0) continue; // skip axes where we already have enough precision on this axis
3245 Dict upd;
3246 upd[axname[axis]]=s_step[i*3+axis];
3247 // when moving az, we move phi in the opposite direction by the same amount since the two are singular at alt=0
3248 // phi continues to move independently. I believe this should produce a more monotonic energy surface
3249 if (axis==0) upd[axname[2]]=-s_step[i*3+axis];
3250
3251 int r=testort(small_this,small_to,s_score,s_xform,i,upd,initxf,maxshift, maxang);
3252
3253 // If we fail, we reverse direction with a slightly smaller step and try that
3254 // Whether this fails or not, we move on to the next axis
3255 if (r) changed=1;
3256 else {
3257 s_step[i*3+axis]*=-0.75;
3258 upd[axname[axis]]=s_step[i*3+axis];
3259 r=testort(small_this,small_to,s_score,s_xform,i,upd,initxf,maxshift, maxang);
3260 if (r) changed=1;
3261 }
3262 if (verbose>4) printf("\nX %1.3f\t%1.3f\t%1.3f\t%d\t",s_step[i*3],s_step[i*3+1],s_step[i*3+2],changed);
3263 }
3264 if (verbose>3) {
3265 Dict aap=s_xform[i].get_params("eman");
3266 printf("\n%1.3f\t%1.3f\t%1.3f\t%1.3f\t%1.3f\t%1.3f\t(%1.3f)",s_step[i*3],s_step[i*3+1],s_step[i*3+2],float(aap["az"]),float(aap["alt"]),float(aap["phi"]),s_score[i]);
3267 }
3268
3269 if (!changed) {
3270// for (int j=0; j<3; j++) s_step[i*3+j]*-0.75;
3271 changed=1;
3272 }
3273 if (fabs(s_step[i*3])<astep/4 && fabs(s_step[i*3+1])<astep/4 && fabs(s_step[i*3+2])<astep/4) changed=0;
3274 }
3275
3276 // Ouch, exhaustive (local) search
3277// for (int daz=-1; daz<=1; daz++) {
3278// for (int dalt=-1; dalt<=1; dalt++) {
3279// for (int dphi=-1; dphi<=1; dphi++) {
3280// Dict upd;
3281// upd["az"]=daz*astep;
3282// upd["alt"]=dalt*astep;
3283// upd["phi"]=dphi*astep;
3284// int r=testort(small_this,small_to,s_score,s_coverage,s_xform,i,upd);
3285// }
3286// }
3287// }
3288 }
3289 }
3290 // lazy earlier in defining s_ vectors, so lazy here too and inefficiently sorting
3291 // We are sorting inside the outermost loop so we can decrease the number of solutions
3292 // before we get to the finest precision
3293 for (unsigned int i=0; i<nsoln-1; i++) {
3294 for (unsigned int j=i+1; j<nsoln; j++) {
3295 if (s_score[i]>s_score[j]) {
3296 float t=s_score[i]; s_score[i]=s_score[j]; s_score[j]=t;
3297 Transform tt=s_xform[i]; s_xform[i]=s_xform[j]; s_xform[j]=tt;
3298 }
3299 }
3300 }
3301 for (unsigned int i=0; i<nsoln-1; i++) {
3302 Transform tt=s_xform[i];
3303 tt.set_trans(tt.get_trans()*(float)ny/(float)ss);
3304 s_xform[i]=tt;
3305 }
3306
3307 // At each level of sampling we (potentially) decrease the number of answers we check in detail
3308 // assuming we are gradually homing in on the best solution
3309 nsoln/=2;
3310 if (nsoln<nrsoln) nsoln=nrsoln;
3311
3312
3313 delete small_this;
3314 delete small_to;
3315 if (ss>=maxny && curiter>0) break;
3316 }
3317
3318 delete base_this;
3319 delete base_to;
3320
3321
3322 // initialize results
3323 vector<Dict> solns;
3324 for (unsigned int i = 0; i < nrsoln; ++i ) {
3325 Dict d;
3326 d["score"] = s_score[i];
3327// d["coverage"] = s_coverage[i];
3328// s_xform[i].invert(); // this is because we inverted the order of the input images above to match convention
3329 d["xform.align3d"] = &s_xform[i];
3330 d["xform.projection"] = &s_xform[i]; // we actually return the transform that project the 3D reference to 2D image.
3331 solns.push_back(d);
3332 }
3333
3334 return solns;
3335}
virtual Dict get_params() const
Get the Aligner parameters in a key/value dictionary.
Definition: aligner.h:112
size_t size() const
Ask the Dictionary for its size.
Definition: emobject.h:519
type set_default(const string &key, type val)
Default setting behavior This can be achieved using a template - d.woolford Jan 2008 (before there wa...
Definition: emobject.h:569
EMData * get_clip(const Region &area, const float fill=0) const
Get an inclusive clip.
Definition: emdata.cpp:592
static T * get(const string &instance_name)
Definition: emobject.h:781
bool testort(EMData *small_this, EMData *small_to, vector< float > &s_score, vector< Transform > &s_xform, int i, Dict &upd, Transform initxf, int maxshift, int maxang) const
Definition: aligner.cpp:3339
Region defines a 2D or 3D rectangular region specified by its origin coordinates and all edges' sizes...
Definition: geometry.h:497
Symmetry3D - A base class for 3D Symmetry objects.
Definition: symmetry.h:57
vector< Transform > gen_orientations(const string &generatorname="eman", const Dict &parms=Dict())
Ask the Symmetry3D object to generate a set of orientations in its asymmetric unit using an Orientati...
Definition: symmetry.cpp:167
Dict get_rotation(const string &euler_type="eman") const
Get a rotation in any Euler format.
Definition: transform.cpp:829
void set_trans(const float &x, const float &y, const float &z=0)
Set the post translation component.
Definition: transform.cpp:1036
#define InvalidParameterException(desc)
Definition: exception.h:361
#define InvalidCallException(desc)
Definition: exception.h:348

References EMAN::EMData::calc_ccf(), EMAN::Symmetry3D::gen_orientations(), EMAN::Factory< T >::get(), EMAN::EMData::get_clip(), EMAN::Aligner::get_params(), EMAN::Transform::get_params(), EMAN::Transform::get_rotation(), EMAN::Transform::get_trans(), EMAN::Dict::has_key(), InvalidCallException, InvalidParameterException, EMAN::Transform::inverse(), EMAN::Aligner::params, EMAN::Dict::set_default(), EMAN::Transform::set_params(), EMAN::Transform::set_trans(), EMAN::Dict::size(), and testort().

Member Data Documentation

◆ NAME

const string RT2Dto3DTreeAligner::NAME = "rotate_translate_2d_to_3d_tree"
static

Definition at line 1874 of file aligner.h.

Referenced by get_name().


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