00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef eman__aligner_h__
00037 #define eman__aligner_h__ 1
00038
00039
00040 #include "emobject.h"
00041
00042
00043 namespace EMAN
00044 {
00045 class EMData;
00046 class Cmp;
00047
00084 class Aligner
00085 {
00086 public:
00087 virtual ~ Aligner()
00088 {
00089 }
00090
00091 virtual EMData *align(EMData * this_img, EMData * to_img) const = 0;
00092
00104 virtual EMData *align(EMData * this_img, EMData * to_img,
00105 const string & cmp_name, const Dict& cmp_params) const = 0;
00106
00110 virtual string get_name() const = 0;
00111
00112 virtual string get_desc() const = 0;
00116 virtual Dict get_params() const
00117 {
00118 return params;
00119 }
00120
00124 virtual void set_params(const Dict & new_params)
00125 {
00126 params = new_params;
00127 }
00128
00129 virtual TypeDict get_param_types() const = 0;
00130
00144 virtual vector<Dict> xform_align_nbest(EMData * this_img, EMData * to_img, const unsigned int nsoln, const string & cmp_name, const Dict& cmp_params) const {
00145 vector<Dict> solns;
00146 return solns;
00147 }
00148
00149 protected:
00150 mutable Dict params;
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 };
00164
00173 class TranslationalAligner:public Aligner
00174 {
00175 public:
00176 virtual EMData * align(EMData * this_img, EMData * to_img,
00177 const string & cmp_name="dot", const Dict& cmp_params = Dict()) const;
00178
00179 virtual EMData * align(EMData * this_img, EMData * to_img) const
00180 {
00181 return align(this_img, to_img, "", Dict());
00182 }
00183
00184 virtual string get_name() const
00185 {
00186 return "translational";
00187 }
00188
00189 virtual string get_desc() const
00190 {
00191 return "Translational 2D and 3D alignment by cross-correlation";
00192 }
00193
00194 static Aligner *NEW()
00195 {
00196 return new TranslationalAligner();
00197 }
00198
00199 virtual TypeDict get_param_types() const
00200 {
00201 TypeDict d;
00202 d.put("intonly", EMObject::INT,"Integer pixel translations only");
00203 d.put("maxshift", EMObject::INT,"Maximum translation in pixels");
00204 d.put("masked", EMObject::INT,"Treat zero pixels in 'this' as a mask for normalization (default false)");
00205 d.put("nozero", EMObject::INT,"Zero translation not permitted (useful for CCD images)");
00206 return d;
00207 }
00208 };
00209
00214 class RotationalAligner:public Aligner
00215 {
00216 public:
00217 virtual EMData * align(EMData * this_img, EMData * to_img,
00218 const string & cmp_name = "dot", const Dict& cmp_params = Dict()) const;
00219
00220 virtual EMData * align(EMData * this_img, EMData * to_img) const
00221 {
00222 return align(this_img, to_img, "", Dict());
00223 }
00224
00225 virtual string get_name() const
00226 {
00227 return "rotational";
00228 }
00229
00230 virtual string get_desc() const
00231 {
00232 return "Performs rotational alignment,works accurately if the image is precentered, normally called internally in combination with translational and flip alignment";
00233 }
00234
00235 static Aligner *NEW()
00236 {
00237 return new RotationalAligner();
00238 }
00239
00240 static EMData * align_180_ambiguous(EMData * this_img, EMData * to_img, int rfp_mode = 0);
00241
00242 virtual TypeDict get_param_types() const
00243 {
00244 TypeDict d;
00245 d.put("rfp_mode", EMObject::INT,"Either 0,1 or 2. A temporary flag for testing the rotational foot print. O is the original eman1 way. 1 is just using calc_ccf without padding. 2 is using calc_mutual_correlation without padding.");
00246 return d;
00247 }
00248 };
00249
00252 class RotatePrecenterAligner:public Aligner
00253 {
00254 public:
00255 virtual EMData * align(EMData * this_img, EMData * to_img,
00256 const string & cmp_name = "dot", const Dict& cmp_params = Dict()) const;
00257
00258 virtual EMData * align(EMData * this_img, EMData * to_img) const
00259 {
00260 return align(this_img, to_img, "", Dict());
00261 }
00262
00263 virtual string get_name() const
00264 {
00265 return "rotate_precenter";
00266 }
00267
00268 virtual string get_desc() const
00269 {
00270 return "Performs rotational alignment and works accurately if the image is precentered";
00271 }
00272
00273 static Aligner *NEW()
00274 {
00275 return new RotatePrecenterAligner();
00276 }
00277
00278 virtual TypeDict get_param_types() const
00279 {
00280 TypeDict d;
00281 return d;
00282 }
00283 };
00284
00291 class RotateTranslateAligner:public Aligner
00292 {
00293 public:
00294 virtual EMData * align(EMData * this_img, EMData * to_img,
00295 const string & cmp_name="dot", const Dict& cmp_params = Dict()) const;
00296
00297 virtual EMData * align(EMData * this_img, EMData * to_img) const
00298 {
00299 return align(this_img, to_img, "sqeuclidean", Dict());
00300 }
00301
00302 virtual string get_name() const
00303 {
00304 return "rotate_translate";
00305 }
00306
00307 virtual string get_desc() const
00308 {
00309 return "Performs rotational alignment and follows this with translational alignment.";
00310 }
00311
00312 static Aligner *NEW()
00313 {
00314 return new RotateTranslateAligner();
00315 }
00316
00317 virtual TypeDict get_param_types() const
00318 {
00319 TypeDict d;
00320
00321 d.put("maxshift", EMObject::INT, "Maximum translation in pixels");
00322 d.put("nozero", EMObject::INT,"Zero translation not permitted (useful for CCD images)");
00323 d.put("rfp_mode", EMObject::INT,"Either 0,1 or 2. A temporary flag for testing the rotational foot print");
00324 return d;
00325 }
00326 };
00327
00332 class RotateTranslateBestAligner:public Aligner
00333 {
00334 public:
00335 virtual EMData * align(EMData * this_img, EMData * to_img,
00336 const string & cmp_name="dot", const Dict& cmp_params = Dict()) const;
00337
00338 virtual EMData * align(EMData * this_img, EMData * to_img) const
00339 {
00340 return align(this_img, to_img, "frc", Dict());
00341 }
00342
00343 virtual string get_name() const
00344 {
00345 return "rotate_translate_best";
00346 }
00347
00348 virtual string get_desc() const
00349 {
00350 return "Full 2D alignment using 'Rotational' and 'Translational', also incorporates 2D 'Refine' alignments.";
00351 }
00352
00353 static Aligner *NEW()
00354 {
00355 return new RotateTranslateBestAligner();
00356 }
00357
00358 virtual TypeDict get_param_types() const
00359 {
00360 TypeDict d;
00361 d.put("maxshift", EMObject::INT, "Maximum translation in pixels");
00362 d.put("snr", EMObject::FLOATARRAY, "signal to noise ratio array");
00363 return d;
00364 }
00365
00366
00367 };
00368
00374 class RotateFlipAligner:public Aligner
00375 {
00376 public:
00377 virtual EMData * align(EMData * this_img, EMData * to_img,
00378 const string & cmp_name="dot", const Dict& cmp_params = Dict()) const;
00379 virtual EMData * align(EMData * this_img, EMData * to_img) const
00380 {
00381 return align(this_img, to_img, "", Dict());
00382 }
00383 virtual string get_name() const
00384 {
00385 return "rotate_flip";
00386 }
00387
00388 virtual string get_desc() const
00389 {
00390 return "Performs two rotational alignments, one using the original image and one using the hand-flipped image. Decides which alignment is better using a comparitor and returns it";
00391 }
00392
00393 static Aligner *NEW()
00394 {
00395 return new RotateFlipAligner();
00396 }
00397
00398 virtual TypeDict get_param_types() const
00399 {
00400 return static_get_param_types();
00401 }
00402
00403 static TypeDict static_get_param_types() {
00404 TypeDict d;
00405
00406 d.put("imask", EMObject::INT);
00407 d.put("rfp_mode", EMObject::INT,"Either 0,1 or 2. A temporary flag for testing the rotational foot print");
00408 return d;
00409 }
00410
00411 };
00412
00420 class RotateTranslateFlipAligner:public Aligner
00421 {
00422 public:
00423 virtual EMData * align(EMData * this_img, EMData * to_img,
00424 const string & cmp_name="dot", const Dict& cmp_params = Dict()) const;
00425 virtual EMData * align(EMData * this_img, EMData * to_img) const
00426 {
00427 return align(this_img, to_img, "sqeuclidean", Dict());
00428 }
00429
00430 virtual string get_name() const
00431 {
00432 return "rotate_translate_flip";
00433 }
00434
00435 virtual string get_desc() const
00436 {
00437 return " Does two 'rotate_translate' alignments, one to accommodate for possible handedness change. Decided which alignment is better using a comparitor and returns the aligned image as the solution";
00438 }
00439
00440 static Aligner *NEW()
00441 {
00442 return new RotateTranslateFlipAligner();
00443 }
00444
00445 virtual TypeDict get_param_types() const
00446 {
00447 return static_get_param_types();
00448 }
00449
00450 static TypeDict static_get_param_types() {
00451 TypeDict d;
00452
00453 d.put("flip", EMObject::EMDATA);
00454 d.put("usedot", EMObject::INT);
00455 d.put("maxshift", EMObject::INT, "Maximum translation in pixels");
00456 d.put("rfp_mode", EMObject::INT,"Either 0,1 or 2. A temporary flag for testing the rotational foot print");
00457 return d;
00458 }
00459 };
00460
00465 class RTFExhaustiveAligner:public Aligner
00466 {
00467 public:
00468 virtual EMData * align(EMData * this_img, EMData * to_img,
00469 const string & cmp_name="dot", const Dict& cmp_params = Dict()) const;
00470 virtual EMData * align(EMData * this_img, EMData * to_img) const
00471 {
00472 return align(this_img, to_img, "sqeuclidean", Dict());
00473 }
00474
00475 virtual string get_name() const
00476 {
00477 return "rtf_exhaustive";
00478 }
00479
00480 virtual string get_desc() const
00481 {
00482 return "Experimental full 2D alignment with handedness check using semi-exhaustive search (not necessarily better than RTFBest)";
00483 }
00484
00485 static Aligner *NEW()
00486 {
00487 return new RTFExhaustiveAligner();
00488 }
00489
00490 virtual TypeDict get_param_types() const
00491 {
00492 TypeDict d;
00493
00494 d.put("flip", EMObject::EMDATA);
00495 d.put("maxshift", EMObject::INT, "Maximum translation in pixels");
00496 return d;
00497 }
00498 };
00499
00507 class RTFSlowExhaustiveAligner:public Aligner
00508 {
00509 public:
00510 virtual EMData * align(EMData * this_img, EMData * to_img,
00511 const string & cmp_name, const Dict& cmp_params) const;
00512 virtual EMData * align(EMData * this_img, EMData * to_img) const
00513 {
00514 return align(this_img, to_img, "sqeuclidean", Dict());
00515 }
00516 virtual string get_name() const
00517 {
00518 return "rtf_slow_exhaustive";
00519 }
00520
00521 virtual string get_desc() const
00522 {
00523 return "Experimental full 2D alignment with handedness check using more exhaustive search (not necessarily better than RTFBest)";
00524 }
00525
00526 static Aligner *NEW()
00527 {
00528 return new RTFSlowExhaustiveAligner();
00529 }
00530
00531 virtual TypeDict get_param_types() const
00532 {
00533 TypeDict d;
00534 d.put("flip", EMObject::EMDATA,"Optional. This is the flipped version of the images that is being aligned. If specified it will be used for the handedness check, if not a flipped copy of the image will be made");
00535 d.put("maxshift", EMObject::INT,"The maximum length of the detectable translational shift");
00536 d.put("transtep", EMObject::FLOAT,"The translation step to take when honing the alignment, which occurs after coarse alignment");
00537 d.put("angstep", EMObject::FLOAT,"The angular step (in degrees) to take in the exhaustive search for the solution angle. Typically very small i.e. 3 or smaller.");
00538 return d;
00539 }
00540 };
00541
00544 class RefineAligner:public Aligner
00545 {
00546 public:
00547 virtual EMData * align(EMData * this_img, EMData * to_img,
00548 const string & cmp_name="dot", const Dict& cmp_params = Dict()) const;
00549
00550 virtual EMData * align(EMData * this_img, EMData * to_img) const
00551 {
00552 return align(this_img, to_img, "sqeuclidean", Dict());
00553 }
00554
00555 virtual string get_name() const
00556 {
00557 return "refine";
00558 }
00559
00560 virtual string get_desc() const
00561 {
00562 return "Refines a preliminary 2D alignment using a simplex algorithm. Subpixel precision.";
00563 }
00564
00565 static Aligner *NEW()
00566 {
00567 return new RefineAligner();
00568 }
00569
00570 virtual TypeDict get_param_types() const
00571 {
00572 TypeDict d;
00573
00574 d.put("mode", EMObject::INT, "Currently unused");
00575 d.put("xform.align2d", EMObject::TRANSFORM, "The Transform storing the starting guess. If unspecified the identity matrix is used");
00576 d.put("stepx", EMObject::FLOAT, "The x increment used to create the starting simplex. Default is 1");
00577 d.put("stepy", EMObject::FLOAT, "The y increment used to create the starting simplex. Default is 1");
00578 d.put("stepaz", EMObject::FLOAT, "The rotational increment used to create the starting simplex. Default is 5");
00579 d.put("precision", EMObject::FLOAT, "The precision which, if achieved, can stop the iterative refinement before reaching the maximum iterations. Default is 0.04.");
00580 d.put("maxiter", EMObject::INT,"The maximum number of iterations that can be performed by the Simplex minimizer");
00581 d.put("maxshift", EMObject::INT,"Maximum translation in pixels in any direction. If the solution yields a shift beyond this value in any direction, then the refinement is judged a failure and the original alignment is used as the solution.");
00582 return d;
00583 }
00584 };
00585
00586
00595 class Refine3DAligner:public Aligner
00596 {
00597 public:
00598 virtual EMData * align(EMData * this_img, EMData * to_img,
00599 const string & cmp_name="dot", const Dict& cmp_params = Dict()) const;
00600
00601 virtual EMData * align(EMData * this_img, EMData * to_img) const
00602 {
00603 return align(this_img, to_img, "sqeuclidean", Dict());
00604 }
00605
00606 virtual string get_name() const
00607 {
00608 return "refine.3d";
00609 }
00610
00611 virtual string get_desc() const
00612 {
00613 return "Refines a preliminary 3D alignment using a simplex algorithm. Subpixel precision.";
00614 }
00615
00616 static Aligner *NEW()
00617 {
00618 return new Refine3DAligner();
00619 }
00620
00621 virtual TypeDict get_param_types() const
00622 {
00623 TypeDict d;
00624 d.put("xform.align3d", EMObject::TRANSFORM,"The Transform storing the starting guess. If unspecified the identity matrix is used");
00625 d.put("stepx", EMObject::FLOAT, "The x increment used to create the starting simplex. Default is 1");
00626 d.put("stepy", EMObject::FLOAT,"The y increment used to create the starting simplex. Default is 1");
00627 d.put("stepz", EMObject::FLOAT, "The z increment used to create the starting simplex. Default is 1." );
00628 d.put("stepphi", EMObject::FLOAT, "The phi incremenent used to creat the starting simplex. This is the increment applied to the inplane rotation. Default is 5." );
00629 d.put("stepdelta", EMObject::FLOAT,"The angular increment which represents a good initial step along the sphere, thinking in terms of quaternions. Default is 5.");
00630 d.put("precision", EMObject::FLOAT, "The precision which, if achieved, can stop the iterative refinement before reaching the maximum iterations. Default is 0.04." );
00631 d.put("maxiter", EMObject::INT, "The maximum number of iterations that can be performed by the Simplex minimizer. Default is 60.");
00632 d.put("maxshift", EMObject::INT,"Maximum translation in pixels in any direction. If the solution yields a shift beyond this value in any direction, then the refinement is judged a failure and the original alignment is used as the solution.");
00633 return d;
00634 }
00635 };
00636
00643 class RT3DGridAligner:public Aligner
00644 {
00645 public:
00648 virtual EMData * align(EMData * this_img, EMData * to_img,
00649 const string & cmp_name, const Dict& cmp_params) const;
00652 virtual EMData * align(EMData * this_img, EMData * to_img) const
00653 {
00654 return align(this_img, to_img, "dot.tomo", Dict());
00655 }
00656
00657
00660 virtual vector<Dict> xform_align_nbest(EMData * this_img, EMData * to_img, const unsigned int nsoln, const string & cmp_name, const Dict& cmp_params) const;
00661
00662 virtual string get_name() const
00663 {
00664 return "rt.3d.grid";
00665 }
00666
00667 virtual string get_desc() const
00668 {
00669 return "3D rotational and translational alignment using specified ranges and maximum shifts";
00670 }
00671
00672 static Aligner *NEW()
00673 {
00674 return new RT3DGridAligner();
00675 }
00676
00677 virtual TypeDict get_param_types() const
00678 {
00679 TypeDict d;
00680 d.put("daz", EMObject::FLOAT,"The angle increment in the azimuth direction. Default is 10");
00681 d.put("raz", EMObject::FLOAT,"The range of angles to sample in the azimuth direction. Default is 360.");
00682 d.put("dphi", EMObject::FLOAT,"The angle increment in the phi direction. Default is 10.");
00683 d.put("rphi", EMObject::FLOAT,"The range of angles to sample in the phi direction. Default is 180.");
00684 d.put("dalt", EMObject::FLOAT,"The angle increment in the altitude direction. Default is 10.");
00685 d.put("ralt", EMObject::FLOAT,"The range of angles to sample in the altitude direction. Default is 180.");
00686 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.");
00687 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.");
00688 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.");
00689 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");
00690 d.put("verbose", EMObject::BOOL,"Turn this on to have useful information printed to standard out.");
00691 return d;
00692 }
00693 };
00694
00701 class RT3DSphereAligner:public Aligner
00702 {
00703 public:
00706 virtual EMData * align(EMData * this_img, EMData * to_img,
00707 const string & cmp_name, const Dict& cmp_params) const;
00710 virtual EMData * align(EMData * this_img, EMData * to_img) const
00711 {
00712 return align(this_img, to_img, "sqeuclidean", Dict());
00713 }
00714
00715
00718 virtual vector<Dict> xform_align_nbest(EMData * this_img, EMData * to_img, const unsigned int nsoln, const string & cmp_name, const Dict& cmp_params) const;
00719
00720 virtual string get_name() const
00721 {
00722 return "rt.3d.sphere";
00723 }
00724
00725 virtual string get_desc() const
00726 {
00727 return "3D rotational and translational alignment using spherical sampling. Can reduce the search space if symmetry is supplied";
00728 }
00729
00730 static Aligner *NEW()
00731 {
00732 return new RT3DSphereAligner();
00733 }
00734
00735 virtual TypeDict get_param_types() const
00736 {
00737 TypeDict d;
00738 d.put("sym", EMObject::STRING,"The symmtery to use as the basis of the spherical sampling. Default is c1 (asymmetry).");
00739 d.put("orientgen", EMObject::STRING,"Advanced. The orientation generation strategy. Default is eman");
00740 d.put("delta", EMObject::FLOAT,"Angle the separates points on the sphere. This is exclusive of the \'n\' paramater. Default is 10");
00741 d.put("n", EMObject::INT,"An alternative to the delta argument, this is the number of points you want generated on the sphere. Default is OFF");
00742 d.put("dphi", EMObject::FLOAT,"The angle increment in the phi direction. Default is 10.");
00743 d.put("rphi", EMObject::FLOAT,"The range of angles to sample in the phi direction. Default is 180.");
00744 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.");
00745 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.");
00746 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.");
00747 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");
00748 d.put("verbose", EMObject::BOOL,"Turn this on to have useful information printed to standard out.");
00749 return d;
00750 }
00751 };
00752
00753
00754 class CUDA_Aligner
00755 {
00756 public:
00757 CUDA_Aligner();
00758
00759 void finish();
00760
00761 void setup(int nima, int nx, int ny, int ring_length, int nring, int ou, float step, int kx, int ky, bool ctf);
00762
00763 void insert_image(EMData *image, int num);
00764
00765 void filter_stack(vector<float> ctf_params, int id);
00766
00767 void sum_oe(vector<float> ctf_params, vector<float> ali_params, EMData* ave1, EMData *ave2, int id);
00768
00769 vector<float> alignment_2d(EMData *ref_image, vector<float> sx, vector<float> sy, int id, int silent);
00770
00771 private:
00772 float *image_stack, *image_stack_filtered;
00773 float *ccf;
00774 int NIMA, NX, NY, RING_LENGTH, NRING, OU, KX, KY;
00775 bool CTF;
00776 float STEP;
00777 };
00778
00779
00780 template <> Factory < Aligner >::Factory();
00781
00782 void dump_aligners();
00783 map<string, vector<string> > dump_aligners_list();
00784 }
00785
00786 #endif