EMAN2
cmp.h
Go to the documentation of this file.
00001 
00005 /*
00006  * Author: Steven Ludtke, 04/10/2003 (sludtke@bcm.edu)
00007  * Copyright (c) 2000-2006 Baylor College of Medicine
00008  *
00009  * This software is issued under a joint BSD/GNU license. You may use the
00010  * source code in this file under either license. However, note that the
00011  * complete EMAN2 and SPARX software packages have some GPL dependencies,
00012  * so you are responsible for compliance with the licenses of these packages
00013  * if you opt to use BSD licensing. The warranty disclaimer below holds
00014  * in either instance.
00015  *
00016  * This complete copyright notice must be included in any revised version of the
00017  * source code. Additional authorship citations may be added, but existing
00018  * author citations must be preserved.
00019  *
00020  * This program is free software; you can redistribute it and/or modify
00021  * it under the terms of the GNU General Public License as published by
00022  * the Free Software Foundation; either version 2 of the License, or
00023  * (at your option) any later version.
00024  *
00025  * This program is distributed in the hope that it will be useful,
00026  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00027  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00028  * GNU General Public License for more details.
00029  *
00030  * You should have received a copy of the GNU General Public License
00031  * along with this program; if not, write to the Free Software
00032  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00033  *
00034  * */
00035 
00036 #ifndef eman_cmp__h__
00037 #define eman_cmp__h__ 1
00038 
00039 
00040 #include "emobject.h"
00041 
00042 namespace EMAN
00043 {
00044 
00045         class EMData;
00085         class Cmp
00086         {
00087           public:
00088                 virtual ~ Cmp()
00089                 {
00090                 }
00091 
00100                 virtual float cmp(EMData * image, EMData * with) const = 0;
00101 
00105                 virtual string get_name() const = 0;
00106 
00107                 virtual string get_desc() const = 0;
00108 
00112                 virtual Dict get_params() const
00113                 {
00114                         return params;
00115                 }
00116 
00120                 virtual void set_params(const Dict & new_params)
00121                 {
00122                         params = new_params;
00123                 }
00124 
00131                 virtual TypeDict get_param_types() const = 0;
00132 
00133         protected:
00134                 void validate_input_args(const EMData * image, const EMData *with) const;
00135 
00136                 mutable Dict params;
00137         };
00138 
00156         class CccCmp:public Cmp
00157         {
00158           public:
00159                 float cmp(EMData * image, EMData * with) const;
00160 
00161                 string get_name() const
00162                 {
00163                         return NAME;
00164                 }
00165 
00166                 string get_desc() const
00167                 {
00168                         return "Cross-correlation coefficient (default -1 * ccc)";
00169                 }
00170 
00171                 static Cmp *NEW()
00172                 {
00173                         return new CccCmp();
00174                 }
00175 
00176                 //param mask Image mask
00177                 TypeDict get_param_types() const
00178                 {
00179                         TypeDict d;
00180                         d.put("negative", EMObject::INT, "If set, returns -1 * ccc product. Set by default so smaller is better");
00181                         d.put("mask", EMObject::EMDATA, "image mask");
00182                         return d;
00183                 }
00184 
00185                 static const string NAME;
00186         };
00187 
00188 
00189         /* Compues the L^1 difference, after normalization.*/
00190         class LodCmp:public Cmp
00191         {
00192           public:
00193                 float cmp(EMData * image, EMData * with) const;
00194 
00195                 string get_name() const
00196                 {
00197                         return NAME;
00198                 }
00199 
00200                 string get_desc() const
00201                 {
00202                         return "L^1 normalized difference (positive by default)";
00203                 }
00204 
00205                 static Cmp *NEW()
00206                 {
00207                         return new LodCmp();
00208                 }
00209 
00210                 //param mask Image mask
00211                 TypeDict get_param_types() const
00212                 {
00213                         TypeDict d;
00214                         d.put("negative", EMObject::INT, "If set (which is the default), returns Lod. (The smaller the better)");
00215                         d.put("normalize", EMObject::INT, "If set, normalizes maps prior to computing the difference. Default=0 (no normalization)");
00216                         d.put("mask", EMObject::EMDATA, "image mask");
00217                         return d;
00218                 }
00219 
00220                 static const string NAME;
00221         };
00222 
00223 
00225         //  I corrected this as there is no such thing as "variance between two images"
00226         //  I corrected naive coding to avoid square
00227         //  Also, the equation in return statement was incorrect, grrrr!!!
00228         //  Finally, I added mask option  PAP 04/23/06
00229         class SqEuclideanCmp:public Cmp
00230         {
00231           public:
00232                 SqEuclideanCmp() {}
00233 
00234                 float cmp(EMData * image, EMData * with) const;
00235 
00236                 string get_name() const
00237                 {
00238                         return NAME;
00239                 }
00240 
00241                 string get_desc() const
00242                 {
00243                         return "Squared Euclidean distance (sum(a - b)^2)/n.";
00244                 }
00245 
00246                 static Cmp *NEW()
00247                 {
00248                         return new SqEuclideanCmp();
00249                 }
00250 
00251                 TypeDict get_param_types() const
00252                 {
00253                         TypeDict d;
00254                         d.put("mask", EMObject::EMDATA, "image mask");
00255                         d.put("zeromask", EMObject::INT, "If set, zero pixels in either image will be excluded from the statistics");
00256                         d.put("normto",EMObject::INT,"If set, 'with' is normalized to 'this' before computing the distance");
00257                         return d;
00258                 }
00259 
00260                 static const string NAME;
00261         };
00262 
00263 
00272         class DotCmp:public Cmp
00273         {
00274           public:
00275                 float cmp(EMData * image, EMData * with) const;
00276 
00277                 string get_name() const
00278                 {
00279                         return NAME;
00280                 }
00281 
00282                 string get_desc() const
00283                 {
00284                         return "Dot product (default -1 * dot product)";
00285                 }
00286 
00287                 static Cmp *NEW()
00288                 {
00289                         return new DotCmp();
00290                 }
00291 
00292                 TypeDict get_param_types() const
00293                 {
00294                         TypeDict d;
00295                         d.put("negative", EMObject::INT, "If set, returns -1 * dot product. Set by default so smaller is better");
00296                         d.put("normalize", EMObject::INT, "If set, returns normalized dot product (cosine of the angle) -1.0 - 1.0.");
00297                         d.put("mask", EMObject::EMDATA, "image mask");
00298                         return d;
00299                 }
00300                 
00301                 static const string NAME;
00302         };
00303 
00317         class TomoCccCmp:public Cmp
00318         {
00319           public:
00320                 virtual float cmp(EMData * image, EMData * with) const;
00321 
00322                 virtual string get_name() const 
00323                 {
00324                         return NAME;
00325                 }
00326 
00327                 virtual string get_desc() const
00328                 {
00329                         return "Ccc with consideration given for the missing wedge";
00330                 }
00331 
00332                 static Cmp *NEW()
00333                 {
00334                         return new TomoCccCmp();
00335                 }
00336 
00337                 TypeDict get_param_types() const
00338                 {
00339                         TypeDict d;
00340                         d.put("norm", EMObject::BOOL,"Whether the cross correlation image should be normalized (should be for normalized images). Default is true.");
00341                         d.put("ccf", EMObject::EMDATA,"The ccf image, can be provided if it already exists to avoid recalculating it");
00342                         d.put("normalize", EMObject::EMDATA,"Return the negative value (which is EMAN2 convention), Defalut is true(1)");
00343                         d.put("searchx", EMObject::INT, "The maximum range of the peak location in the x direction. Default is sizex/4");
00344                         d.put("searchy", EMObject::INT, "The maximum range of the peak location in the y direction. Default is sizey/4");
00345                         d.put("searchz", EMObject::INT, "The maximum range of the peak location in the z direction. Default is sizez/4");
00346                         return d;
00347                 }
00348                 
00349                 static const string NAME;
00350         };
00351 
00352         
00362         class TomoFscCmp:public Cmp
00363         {
00364           public:
00365                 virtual float cmp(EMData * image, EMData * with) const;
00366 
00367                 virtual string get_name() const 
00368                 {
00369                         return NAME;
00370                 }
00371 
00372                 virtual string get_desc() const
00373                 {
00374                         return "EXPERIMENTAL - Fsc with consideration given for the missing wedge. Not ready for routine use.";
00375                 }
00376 
00377                 static Cmp *NEW()
00378                 {
00379                         return new TomoFscCmp();
00380                 }
00381 
00382                 TypeDict get_param_types() const
00383                 {
00384                         TypeDict d;
00385                         d.put("normalize", EMObject::EMDATA,"Return the negative value (which is EMAN2 convention), Defalut is true(1)");
00386                         d.put("sigmas", EMObject::FLOAT, "The number of times the standard deviation of Fourier amplitudes to accept");
00387                         d.put("minres", EMObject::FLOAT, "The minimum resolution to accept (1/A) Default is inf");
00388                         d.put("maxres", EMObject::FLOAT, "The maximum resolution to accept (1/A) Default=0.0");
00389                         d.put("apix", EMObject::FLOAT, "The angstroms per pixel to use. Default = apix_x(1.0 if not present)");
00390                         return d;
00391                 }
00392                 
00393                 static const string NAME;
00394         };
00395         
00403         class QuadMinDotCmp:public Cmp
00404         {
00405           public:
00406                 float cmp(EMData * image, EMData * with) const;
00407 
00408                 string get_name() const
00409                 {
00410                         return NAME;
00411                 }
00412 
00413                 string get_desc() const
00414                 {
00415                         return "Calculates dot product for each quadrant and returns worst value (default -1 * dot product)";
00416                 }
00417 
00418                 static Cmp *NEW()
00419                 {
00420                         return new QuadMinDotCmp();
00421                 }
00422 
00423                 TypeDict get_param_types() const
00424                 {
00425                         TypeDict d;
00426                         d.put("negative", EMObject::INT, "If set, returns -1 * dot product. Default = true (smaller is better)");
00427                         d.put("normalize", EMObject::INT, "If set, returns normalized dot product -1.0 - 1.0.");
00428                         return d;
00429                 }
00430                 
00431                 static const string NAME;
00432         };
00433 
00439         class OptSubCmp:public Cmp
00440         {
00441           public:
00442                 OptSubCmp() {}
00443 
00444                 float cmp(EMData * image, EMData * with) const;
00445 
00446                 string get_name() const
00447                 {
00448                         return NAME;
00449                 }
00450 
00451                 string get_desc() const
00452                 {
00453                         return "Residual power left in the image after optimally subtracting the reference with math.sub.optimal. Smaller values indicate a closer match.";
00454                 }
00455 
00456                 static Cmp *NEW()
00457                 {
00458                         return new OptSubCmp();
00459                 }
00460 
00461                 TypeDict get_param_types() const
00462                 {
00463                         TypeDict d;
00464                         d.put("minres", EMObject::FLOAT, "Lowest resolution to use in comparison (soft cutoff). Requires accurate A/pix in image. <0 disables. Default=200");
00465                         d.put("maxres", EMObject::FLOAT, "Highest resolution to use in comparison (soft cutoff). Requires accurate A/pix in image. <0 disables.  Default=10");
00466                         d.put("zeromask", EMObject::BOOL, "Treat zero regions in 'with' as a mask");
00467                         d.put("ctfweight", EMObject::BOOL, "Weight frequencies using CTF");
00468 //                      d.put("swap", EMObject::BOOL, "Swaps the identity of this and with, since A->B comparisons are not equivalent to B->A");
00469                         d.put("mask", EMObject::EMDATA, "Real space mask. Only computes the residual power under the mask. Significant speed penalty if specified. Default=None.");
00470                         return d;
00471                 }
00472                 
00473                 static const string NAME;
00474 
00475         };
00476 
00477         
00490         class OptVarianceCmp:public Cmp
00491         {
00492           public:
00493                 OptVarianceCmp() : scale(0), shift(0) {}
00494 
00495                 float cmp(EMData * image, EMData * with) const;
00496 
00497                 string get_name() const
00498                 {
00499                         return NAME;
00500                 }
00501 
00502                 string get_desc() const
00503                 {
00504                         return "Real-space variance after density optimization, self should be noisy and target less noisy. Linear transform applied to density to minimize variance.";
00505                 }
00506 
00507                 static Cmp *NEW()
00508                 {
00509                         return new OptVarianceCmp();
00510                 }
00511 
00512                 TypeDict get_param_types() const
00513                 {
00514                         TypeDict d;
00515                         d.put("invert", EMObject::INT, "If set, 'with' is rescaled rather than 'this'. 'this' should still be the noisier image. (default=0)");
00516                         d.put("keepzero", EMObject::INT, "If set, zero pixels will not be adjusted in the linear density optimization. (default=1)");
00517                         d.put("matchfilt", EMObject::INT, "If set, with will be filtered so its radial power spectrum matches 'this' before density optimization of this. (default=1)");
00518                         d.put("matchamp", EMObject::INT, "Takes per-pixel Fourier amplitudes from self and imposes them on the target, but leaves the phases alone. (default=0)");
00519                         d.put("radweight", EMObject::INT, "Upweight variances closer to the edge of the image. (default=0)");
00520                         d.put("debug", EMObject::INT, "Performs various debugging actions if set.");
00521                         return d;
00522                 }
00523 
00524                 float get_scale() const
00525                 {
00526                         return scale;
00527                 }
00528 
00529                 float get_shift() const
00530                 {
00531                         return shift;
00532                 }
00533                 
00534                 static const string NAME;
00535 
00536         private:
00537                 mutable float scale;
00538                 mutable float shift;
00539         };
00540         
00551         class PhaseCmp:public Cmp
00552         {
00553           public:
00554                 float cmp(EMData * image, EMData * with) const;
00555 
00556                 string get_name() const
00557                 {
00558                         return NAME;
00559                 }
00560 
00561                 string get_desc() const
00562                 {
00563                         return "Mean phase difference";
00564                 }
00565 
00566                 static Cmp *NEW()
00567                 {
00568                         return new PhaseCmp();
00569                 }
00570 
00571                 TypeDict get_param_types() const
00572                 {
00573                         TypeDict d;
00574                         d.put("snrweight", EMObject::INT, "If set, the SNR of 'this' will be used to weight the result. If 'this' lacks CTF info, it will check 'with'. (default=0)");
00575                         d.put("snrfn", EMObject::INT, "If nonzero, an empirical function will be used as a radial weight rather than the true SNR. (1 - exp decay)'. (default=0)");
00576                         d.put("ampweight", EMObject::INT, "If set, the amplitude of 'with' will be used as a weight in the averaging'. (default=0)");
00577                         d.put("zeromask", EMObject::INT, "Treat regions in either image that are zero as a mask");
00578                         d.put("minres", EMObject::FLOAT, "Lowest resolution to use in comparison (soft cutoff). Requires accurate A/pix in image. <0 disables. Default=500");
00579                         d.put("maxres", EMObject::FLOAT, "Highest resolution to use in comparison (soft cutoff). Requires accurate A/pix in image. <0 disables.  Default=10");
00580                         return d;
00581                 }
00582                 
00583                 static const string NAME;
00584 
00585 //#ifdef EMAN2_USING_CUDA
00586 //               float cuda_cmp(EMData * image, EMData *with) const;
00587 //#endif //EMAN2_USING_CUDA
00588         };
00589 
00596         class FRCCmp:public Cmp
00597         {
00598           public:
00599                 float cmp(EMData * image, EMData * with) const;
00600 
00601                 string get_name() const
00602                 {
00603                         return NAME;
00604                 }
00605 
00606                 string get_desc() const
00607                 {
00608                         return "Computes the mean Fourier Ring Correlation between the image and reference (with optional weighting factors).";
00609                 }
00610 
00611                 static Cmp *NEW()
00612                 {
00613                         return new FRCCmp();
00614                 }
00615 
00616                 TypeDict get_param_types() const
00617                 {
00618                         TypeDict d;
00619                         d.put("snrweight", EMObject::INT, "If set, the SNR of 'this' will be used to weight the result. If 'this' lacks CTF info, it will check 'with'. (default=0)");
00620                         d.put("ampweight", EMObject::INT, "If set, the amplitude of 'this' will be used to weight the result (default=0)");
00621                         d.put("sweight", EMObject::INT, "If set, weight the (1-D) average by the number of pixels in each ring (default=1)");
00622                         d.put("nweight", EMObject::INT, "Downweight similarity based on number of particles in reference (default=0)");
00623                         d.put("zeromask", EMObject::INT, "Treat regions in either image that are zero as a mask");
00624                         d.put("minres", EMObject::FLOAT, "Lowest resolution to use in comparison (soft cutoff). Requires accurate A/pix in image. <0 disables. Default=500");
00625                         d.put("maxres", EMObject::FLOAT, "Highest resolution to use in comparison (soft cutoff). Requires accurate A/pix in image. <0 disables.  Default=10");
00626                         return d;
00627                 }
00628                 
00629                 static const string NAME;
00630         };
00631 
00632         template <> Factory < Cmp >::Factory();
00633 
00634         void dump_cmps();
00635         map<string, vector<string> > dump_cmps_list();
00636 }
00637 
00638 
00639 #endif
00640 
00641 /* vim: set ts=4 noet: */