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 NAME;
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("useflcf", EMObject::INT,"Use Fast Local Correlation Function rather than CCF");
00204 d.put("maxshift", EMObject::INT,"Maximum translation in pixels");
00205 d.put("masked", EMObject::INT,"Treat zero pixels in 'this' as a mask for normalization (default false)");
00206 d.put("nozero", EMObject::INT,"Zero translation not permitted (useful for CCD images)");
00207 return d;
00208 }
00209
00210 static const string NAME;
00211 };
00212
00217 class RotationalAligner:public Aligner
00218 {
00219 public:
00220 virtual EMData * align(EMData * this_img, EMData * to_img,
00221 const string & cmp_name = "dot", const Dict& cmp_params = Dict()) const;
00222
00223 virtual EMData * align(EMData * this_img, EMData * to_img) const
00224 {
00225 return align(this_img, to_img, "", Dict());
00226 }
00227
00228 virtual string get_name() const
00229 {
00230 return NAME;
00231 }
00232
00233 virtual string get_desc() const
00234 {
00235 return "Performs rotational alignment,works accurately if the image is precentered, normally called internally in combination with translational and flip alignment";
00236 }
00237
00238 static Aligner *NEW()
00239 {
00240 return new RotationalAligner();
00241 }
00242
00243 static EMData * align_180_ambiguous(EMData * this_img, EMData * to_img, int rfp_mode = 0);
00244
00245 virtual TypeDict get_param_types() const
00246 {
00247 TypeDict d;
00248 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.");
00249 return d;
00250 }
00251
00252 static const string NAME;
00253 };
00254
00257 class RotatePrecenterAligner:public Aligner
00258 {
00259 public:
00260 virtual EMData * align(EMData * this_img, EMData * to_img,
00261 const string & cmp_name = "dot", const Dict& cmp_params = Dict()) const;
00262
00263 virtual EMData * align(EMData * this_img, EMData * to_img) const
00264 {
00265 return align(this_img, to_img, "", Dict());
00266 }
00267
00268 virtual string get_name() const
00269 {
00270 return NAME;
00271 }
00272
00273 virtual string get_desc() const
00274 {
00275 return "Performs rotational alignment and works accurately if the image is precentered";
00276 }
00277
00278 static Aligner *NEW()
00279 {
00280 return new RotatePrecenterAligner();
00281 }
00282
00283 virtual TypeDict get_param_types() const
00284 {
00285 TypeDict d;
00286 return d;
00287 }
00288
00289 static const string NAME;
00290 };
00291
00298 class RotateTranslateAligner:public Aligner
00299 {
00300 public:
00301 virtual EMData * align(EMData * this_img, EMData * to_img,
00302 const string & cmp_name="dot", const Dict& cmp_params = Dict()) const;
00303
00304 virtual EMData * align(EMData * this_img, EMData * to_img) const
00305 {
00306 return align(this_img, to_img, "sqeuclidean", Dict());
00307 }
00308
00309 virtual string get_name() const
00310 {
00311 return NAME;
00312 }
00313
00314 virtual string get_desc() const
00315 {
00316 return "Performs rotational alignment and follows this with translational alignment.";
00317 }
00318
00319 static Aligner *NEW()
00320 {
00321 return new RotateTranslateAligner();
00322 }
00323
00324 virtual TypeDict get_param_types() const
00325 {
00326 TypeDict d;
00327
00328 d.put("maxshift", EMObject::INT, "Maximum translation in pixels");
00329 d.put("nozero", EMObject::INT,"Zero translation not permitted (useful for CCD images)");
00330 d.put("rfp_mode", EMObject::INT,"Either 0,1 or 2. A temporary flag for testing the rotational foot print");
00331 d.put("useflcf", EMObject::INT,"Use Fast Local Correlation Function rather than CCF for translational alignment");
00332 return d;
00333 }
00334
00335 static const string NAME;
00336 };
00337
00342 class RotateTranslateBestAligner:public Aligner
00343 {
00344 public:
00345 virtual EMData * align(EMData * this_img, EMData * to_img,
00346 const string & cmp_name="dot", const Dict& cmp_params = Dict()) const;
00347
00348 virtual EMData * align(EMData * this_img, EMData * to_img) const
00349 {
00350 return align(this_img, to_img, "frc", Dict());
00351 }
00352
00353 virtual string get_name() const
00354 {
00355 return NAME;
00356 }
00357
00358 virtual string get_desc() const
00359 {
00360 return "Full 2D alignment using 'Rotational' and 'Translational', also incorporates 2D 'Refine' alignments.";
00361 }
00362
00363 static Aligner *NEW()
00364 {
00365 return new RotateTranslateBestAligner();
00366 }
00367
00368 virtual TypeDict get_param_types() const
00369 {
00370 TypeDict d;
00371 d.put("maxshift", EMObject::INT, "Maximum translation in pixels");
00372 d.put("snr", EMObject::FLOATARRAY, "signal to noise ratio array");
00373 return d;
00374 }
00375
00376 static const string NAME;
00377 };
00378
00384 class RotateFlipAligner:public Aligner
00385 {
00386 public:
00387 virtual EMData * align(EMData * this_img, EMData * to_img,
00388 const string & cmp_name="dot", const Dict& cmp_params = Dict()) const;
00389 virtual EMData * align(EMData * this_img, EMData * to_img) const
00390 {
00391 return align(this_img, to_img, "", Dict());
00392 }
00393 virtual string get_name() const
00394 {
00395 return NAME;
00396 }
00397
00398 virtual string get_desc() const
00399 {
00400 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";
00401 }
00402
00403 static Aligner *NEW()
00404 {
00405 return new RotateFlipAligner();
00406 }
00407
00408 virtual TypeDict get_param_types() const
00409 {
00410 return static_get_param_types();
00411 }
00412
00413 static TypeDict static_get_param_types() {
00414 TypeDict d;
00415
00416 d.put("imask", EMObject::INT);
00417 d.put("rfp_mode", EMObject::INT,"Either 0,1 or 2. A temporary flag for testing the rotational foot print");
00418 return d;
00419 }
00420
00421 static const string NAME;
00422 };
00423
00431 class RotateTranslateFlipAligner:public Aligner
00432 {
00433 public:
00434 virtual EMData * align(EMData * this_img, EMData * to_img,
00435 const string & cmp_name="dot", const Dict& cmp_params = Dict()) const;
00436 virtual EMData * align(EMData * this_img, EMData * to_img) const
00437 {
00438 return align(this_img, to_img, "sqeuclidean", Dict());
00439 }
00440
00441 virtual string get_name() const
00442 {
00443 return NAME;
00444 }
00445
00446 virtual string get_desc() const
00447 {
00448 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";
00449 }
00450
00451 static Aligner *NEW()
00452 {
00453 return new RotateTranslateFlipAligner();
00454 }
00455
00456 virtual TypeDict get_param_types() const
00457 {
00458 return static_get_param_types();
00459 }
00460
00461 static TypeDict static_get_param_types() {
00462 TypeDict d;
00463
00464 d.put("flip", EMObject::EMDATA);
00465 d.put("usedot", EMObject::INT);
00466 d.put("maxshift", EMObject::INT, "Maximum translation in pixels");
00467 d.put("rfp_mode", EMObject::INT,"Either 0,1 or 2. A temporary flag for testing the rotational foot print");
00468 d.put("useflcf", EMObject::INT,"Use Fast Local Correlation Function rather than CCF for translational alignment");
00469 return d;
00470 }
00471
00472 static const string NAME;
00473 };
00474
00479 class RTFExhaustiveAligner:public Aligner
00480 {
00481 public:
00482 virtual EMData * align(EMData * this_img, EMData * to_img,
00483 const string & cmp_name="dot", const Dict& cmp_params = Dict()) const;
00484 virtual EMData * align(EMData * this_img, EMData * to_img) const
00485 {
00486 return align(this_img, to_img, "sqeuclidean", Dict());
00487 }
00488
00489 virtual string get_name() const
00490 {
00491 return NAME;
00492 }
00493
00494 virtual string get_desc() const
00495 {
00496 return "Experimental full 2D alignment with handedness check using semi-exhaustive search (not necessarily better than RTFBest)";
00497 }
00498
00499 static Aligner *NEW()
00500 {
00501 return new RTFExhaustiveAligner();
00502 }
00503
00504 virtual TypeDict get_param_types() const
00505 {
00506 TypeDict d;
00507
00508 d.put("flip", EMObject::EMDATA);
00509 d.put("maxshift", EMObject::INT, "Maximum translation in pixels");
00510 return d;
00511 }
00512
00513 static const string NAME;
00514 };
00515
00523 class RTFSlowExhaustiveAligner:public Aligner
00524 {
00525 public:
00526 virtual EMData * align(EMData * this_img, EMData * to_img,
00527 const string & cmp_name, const Dict& cmp_params) const;
00528 virtual EMData * align(EMData * this_img, EMData * to_img) const
00529 {
00530 return align(this_img, to_img, "sqeuclidean", Dict());
00531 }
00532 virtual string get_name() const
00533 {
00534 return NAME;
00535 }
00536
00537 virtual string get_desc() const
00538 {
00539 return "Experimental full 2D alignment with handedness check using more exhaustive search (not necessarily better than RTFBest)";
00540 }
00541
00542 static Aligner *NEW()
00543 {
00544 return new RTFSlowExhaustiveAligner();
00545 }
00546
00547 virtual TypeDict get_param_types() const
00548 {
00549 TypeDict d;
00550 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");
00551 d.put("maxshift", EMObject::INT,"The maximum length of the detectable translational shift");
00552 d.put("transtep", EMObject::FLOAT,"The translation step to take when honing the alignment, which occurs after coarse alignment");
00553 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.");
00554 return d;
00555 }
00556
00557 static const string NAME;
00558 };
00559
00562 class RefineAligner:public Aligner
00563 {
00564 public:
00565 virtual EMData * align(EMData * this_img, EMData * to_img,
00566 const string & cmp_name="dot", const Dict& cmp_params = Dict()) const;
00567
00568 virtual EMData * align(EMData * this_img, EMData * to_img) const
00569 {
00570 return align(this_img, to_img, "sqeuclidean", Dict());
00571 }
00572
00573 virtual string get_name() const
00574 {
00575 return NAME;
00576 }
00577
00578 virtual string get_desc() const
00579 {
00580 return "Refines a preliminary 2D alignment using a simplex algorithm. Subpixel precision.";
00581 }
00582
00583 static Aligner *NEW()
00584 {
00585 return new RefineAligner();
00586 }
00587
00588 virtual TypeDict get_param_types() const
00589 {
00590 TypeDict d;
00591
00592 d.put("mode", EMObject::INT, "Currently unused");
00593 d.put("xform.align2d", EMObject::TRANSFORM, "The Transform storing the starting guess. If unspecified the identity matrix is used");
00594 d.put("stepx", EMObject::FLOAT, "The x increment used to create the starting simplex. Default is 1");
00595 d.put("stepy", EMObject::FLOAT, "The y increment used to create the starting simplex. Default is 1");
00596 d.put("stepaz", EMObject::FLOAT, "The rotational increment used to create the starting simplex. Default is 5");
00597 d.put("precision", EMObject::FLOAT, "The precision which, if achieved, can stop the iterative refinement before reaching the maximum iterations. Default is 0.04.");
00598 d.put("maxiter", EMObject::INT,"The maximum number of iterations that can be performed by the Simplex minimizer");
00599 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.");
00600 return d;
00601 }
00602
00603 static const string NAME;
00604 };
00605
00606
00615 class Refine3DAligner:public Aligner
00616 {
00617 public:
00618 virtual EMData * align(EMData * this_img, EMData * to_img,
00619 const string & cmp_name="dot", const Dict& cmp_params = Dict()) const;
00620
00621 virtual EMData * align(EMData * this_img, EMData * to_img) const
00622 {
00623 return align(this_img, to_img, "sqeuclidean", Dict());
00624 }
00625
00626 virtual string get_name() const
00627 {
00628 return NAME;
00629 }
00630
00631 virtual string get_desc() const
00632 {
00633 return "Refines a preliminary 3D alignment using a simplex algorithm. Subpixel precision.";
00634 }
00635
00636 static Aligner *NEW()
00637 {
00638 return new Refine3DAligner();
00639 }
00640
00641 virtual TypeDict get_param_types() const
00642 {
00643 TypeDict d;
00644 d.put("xform.align3d", EMObject::TRANSFORM,"The Transform storing the starting guess. If unspecified the identity matrix is used");
00645 d.put("stepx", EMObject::FLOAT, "The x increment used to create the starting simplex. Default is 1");
00646 d.put("stepy", EMObject::FLOAT,"The y increment used to create the starting simplex. Default is 1");
00647 d.put("stepz", EMObject::FLOAT, "The z increment used to create the starting simplex. Default is 1." );
00648 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." );
00649 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.");
00650 d.put("precision", EMObject::FLOAT, "The precision which, if achieved, can stop the iterative refinement before reaching the maximum iterations. Default is 0.04." );
00651 d.put("maxiter", EMObject::INT, "The maximum number of iterations that can be performed by the Simplex minimizer. Default is 60.");
00652 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.");
00653 return d;
00654 }
00655
00656 static const string NAME;
00657 };
00658
00665 class RT3DGridAligner:public Aligner
00666 {
00667 public:
00670 virtual EMData * align(EMData * this_img, EMData * to_img,
00671 const string & cmp_name, const Dict& cmp_params) const;
00674 virtual EMData * align(EMData * this_img, EMData * to_img) const
00675 {
00676 return align(this_img, to_img, "dot.tomo", Dict());
00677 }
00678
00679
00682 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;
00683
00684 virtual string get_name() const
00685 {
00686 return NAME;
00687 }
00688
00689 virtual string get_desc() const
00690 {
00691 return "3D rotational and translational alignment using specified ranges and maximum shifts";
00692 }
00693
00694 static Aligner *NEW()
00695 {
00696 return new RT3DGridAligner();
00697 }
00698
00699 virtual TypeDict get_param_types() const
00700 {
00701 TypeDict d;
00702 d.put("daz", EMObject::FLOAT,"The angle increment in the azimuth direction. Default is 10");
00703 d.put("raz", EMObject::FLOAT,"The range of angles to sample in the azimuth direction. Default is 360.");
00704 d.put("dphi", EMObject::FLOAT,"The angle increment in the phi direction. Default is 10.");
00705 d.put("rphi", EMObject::FLOAT,"The range of angles to sample in the phi direction. Default is 180.");
00706 d.put("dalt", EMObject::FLOAT,"The angle increment in the altitude direction. Default is 10.");
00707 d.put("ralt", EMObject::FLOAT,"The range of angles to sample in the altitude direction. Default is 180.");
00708 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.");
00709 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.");
00710 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.");
00711 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");
00712 d.put("verbose", EMObject::BOOL,"Turn this on to have useful information printed to standard out.");
00713 return d;
00714 }
00715
00716 static const string NAME;
00717 };
00718
00725 class RT3DSphereAligner:public Aligner
00726 {
00727 public:
00730 virtual EMData * align(EMData * this_img, EMData * to_img,
00731 const string & cmp_name, const Dict& cmp_params) const;
00734 virtual EMData * align(EMData * this_img, EMData * to_img) const
00735 {
00736 return align(this_img, to_img, "sqeuclidean", Dict());
00737 }
00738
00739
00742 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;
00743
00744 virtual string get_name() const
00745 {
00746 return NAME;
00747 }
00748
00749 virtual string get_desc() const
00750 {
00751 return "3D rotational and translational alignment using spherical sampling. Can reduce the search space if symmetry is supplied";
00752 }
00753
00754 static Aligner *NEW()
00755 {
00756 return new RT3DSphereAligner();
00757 }
00758
00759 virtual TypeDict get_param_types() const
00760 {
00761 TypeDict d;
00762 d.put("sym", EMObject::STRING,"The symmtery to use as the basis of the spherical sampling. Default is c1 (asymmetry).");
00763 d.put("orientgen", EMObject::STRING,"Advanced. The orientation generation strategy. Default is eman");
00764 d.put("delta", EMObject::FLOAT,"Angle the separates points on the sphere. This is exclusive of the \'n\' paramater. Default is 10");
00765 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");
00766 d.put("dphi", EMObject::FLOAT,"The angle increment in the phi direction. Default is 10.");
00767 d.put("rphi", EMObject::FLOAT,"The range of angles to sample in the phi direction. Default is 180.");
00768 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.");
00769 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.");
00770 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.");
00771 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");
00772 d.put("verbose", EMObject::BOOL,"Turn this on to have useful information printed to standard out.");
00773 return d;
00774 }
00775
00776 static const string NAME;
00777 };
00778
00779 #ifdef FFTW2
00780 class FRM2DAligner:public Aligner
00781 {
00782 public:
00783 virtual EMData * align(EMData * this_img, EMData * to_img,
00784 const string& cmp_name, const Dict& cmp_params=Dict()) const;
00785
00786 virtual EMData * align(EMData * this_img, EMData * to_img) const
00787 {
00788 return align(this_img, to_img, "", Dict());
00789 }
00790
00791 string get_name() const
00792 {
00793 return NAME;
00794 }
00795
00796 string get_desc() const
00797 {
00798 return "FRM2D uses two rotational parameters and one translational parameter";
00799 }
00800
00801 static Aligner *NEW()
00802 {
00803 return new FRM2DAligner();
00804 }
00805 virtual TypeDict get_param_types() const
00806 {
00807 TypeDict d;
00808 d.put("p_max", EMObject::FLOAT,"p_max is");
00809 return d;
00810 }
00811
00812 static const string NAME;
00813 };
00814 #endif //FFTW2
00815
00816 class CUDA_Aligner
00817 {
00818 public:
00819 CUDA_Aligner();
00820
00821 void finish();
00822
00823 void setup(int nima, int nx, int ny, int ring_length, int nring, int ou, float step, int kx, int ky, bool ctf);
00824
00825 void insert_image(EMData *image, int num);
00826
00827 void filter_stack(vector<float> ctf_params, int id);
00828
00829 void sum_oe(vector<float> ctf_params, vector<float> ali_params, EMData* ave1, EMData *ave2, int id);
00830
00831 vector<float> alignment_2d(EMData *ref_image, vector<float> sx, vector<float> sy, int id, int silent);
00832
00833 vector<float> ali2d_single_iter(EMData *ref_image, vector<float> ali_params, float csx, float csy, int id, int silent, float delta);
00834
00835 private:
00836 float *image_stack, *image_stack_filtered;
00837 float *ccf;
00838 int NIMA, NX, NY, RING_LENGTH, NRING, OU, KX, KY;
00839 bool CTF;
00840 float STEP;
00841 };
00842
00843
00844 template <> Factory < Aligner >::Factory();
00845
00846 void dump_aligners();
00847 map<string, vector<string> > dump_aligners_list();
00848 }
00849
00850 #endif