Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

EMAN::PhaseCmp Class Reference

Amplitude weighted mean phase difference (radians) with optional SNR weight. More...

#include <cmp.h>

Inheritance diagram for EMAN::PhaseCmp:

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

Collaboration graph
[legend]
List of all members.

Public Member Functions

float cmp (EMData *image, EMData *with) const
 To compare 'image' with another image passed in through its parameters.
string get_name () const
 Get the Cmp's name.
string get_desc () const
TypeDict get_param_types () const
 Get Cmp parameter information in a dictionary.

Static Public Member Functions

CmpNEW ()

Static Public Attributes

const string NAME = "phase"

Detailed Description

Amplitude weighted mean phase difference (radians) with optional SNR weight.

SNR should be an array as returned by ctfcurve() 'with' should be the less noisy image, since it's amplitudes will be used to weight the phase residual. 2D only.

Use Phase Residual as a measure of similarity Differential phase residual (DPR) is a measure of statistical dependency between two averages, computed over rings in Fourier space as a function of ring radius (= spatial frequency, or resolution)

Definition at line 460 of file cmp.h.


Member Function Documentation

float PhaseCmp::cmp EMData image,
EMData with
const [virtual]
 

To compare 'image' with another image passed in through its parameters.

An optional transformation may be used to transform the 2 images.

Parameters:
image The first image to be compared.
with The second image to be comppared.
Returns:
The comparison result. Smaller better by default

Implements EMAN::Cmp.

Definition at line 865 of file cmp.cpp.

References EMAN::Util::angle_err_ri(), EMAN::Ctf::apix, EMAN::Ctf::compute_1d(), EMAN::EMData::copy(), EMAN::EMData::do_fft(), EMAN::EMData::do_fft_inplace(), EMAN::EMData::do_ift_inplace(), EMAN::EMObject::f, EMAN::EMData::get_attr(), EMAN::EMData::get_const_data(), EMAN::EMData::get_data(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::EMData::has_attr(), EMAN::Util::hypot3(), EMAN::Util::hypot_fast_int(), InvalidCallException, EMAN::EMData::is_complex(), norm(), ny, EMAN::EMData::set_attr(), EMAN::Dict::set_default(), EMAN::EMData::update(), x, and y.

00866 {
00867         ENTERFUNC;
00868 
00869         int snrweight = params.set_default("snrweight", 0);
00870         int snrfn = params.set_default("snrfn",0);
00871         int ampweight = params.set_default("ampweight",0);
00872         int zeromask = params.set_default("zeromask",0);
00873         float minres = params.set_default("minres",500.0f);
00874         float maxres = params.set_default("maxres",2.0f);
00875 
00876         if (snrweight && snrfn) throw InvalidCallException("SNR weight and SNRfn cannot both be set in the phase comparator");
00877 
00878 #ifdef EMAN2_USING_CUDA
00879         if (image->gpu_operation_preferred()) {
00880 //              cout << "Cuda cmp" << endl;
00881                 EXITFUNC;
00882                 return cuda_cmp(image,with);
00883         }
00884 #endif
00885 
00886         EMData *image_fft = NULL;
00887         EMData *with_fft = NULL;
00888 
00889         int ny = image->get_ysize();
00890 //      int np = (int) ceil(Ctf::CTFOS * sqrt(2.0f) * ny / 2) + 2;
00891         int np = 0;
00892         vector<float> snr;
00893 
00894         // weighting based on SNR estimate from CTF
00895         if (snrweight) {
00896                 Ctf *ctf = NULL;
00897                 if (!image->has_attr("ctf")) {
00898                         if (!with->has_attr("ctf")) throw InvalidCallException("SNR weight with no CTF parameters");
00899                         ctf=with->get_attr("ctf");
00900                 }
00901                 else ctf=image->get_attr("ctf");
00902 
00903                 float ds=1.0f/(ctf->apix*ny);
00904                 snr=ctf->compute_1d(ny,ds,Ctf::CTF_SNR); // note that this returns ny/2 values
00905                 if(ctf) {delete ctf; ctf=0;}
00906                 np=snr.size();
00907         }
00908         // weighting based on empirical SNR function (not really good)
00909         else if (snrfn==1) {
00910                 np=ny/2;
00911                 snr.resize(np);
00912 
00913                 for (int i = 0; i < np; i++) {
00914                         float x2 = 10.0f*i/np;
00915                         snr[i] = x2 * exp(-x2);
00916                 }
00917         }
00918         // no weighting
00919         else {
00920                 np=ny/2;
00921                 snr.resize(np);
00922 
00923                 for (int i = 0; i < np; i++) snr[i]=1.0;
00924         }
00925 
00926         // Min/max modifications to weighting
00927         float pmin,pmax;
00928         if (minres>0) pmin=((float)image->get_attr("apix_x")*image->get_ysize())/minres;                //cutoff in pixels, assume square
00929         else pmin=0;
00930         if (maxres>0) pmax=((float)image->get_attr("apix_x")*image->get_ysize())/maxres;
00931         else pmax=0;
00932 
00933 //      printf("%f\t%f\n",pmin,pmax);
00934 
00935         // We use 'soft' edges for the Fourier cutoffs to minimize issues with pixel interpolation
00936         for (int i = 0; i < np; i++) {
00937                 if (pmin>0) snr[i]*=(tanh(5.0f*(i-pmin)/pmin)+1.0f)/2.0f;
00938                 if (pmax>0) snr[i]*=(1.0f-tanh(i-pmax))/2.0f;
00939 //              printf("%d\t%f\n",i,snr[i]);
00940         }
00941 
00942         if (zeromask) {
00943                 image_fft=image->copy();
00944                 with_fft=with->copy();
00945                 
00946                 if (image_fft->is_complex()) image_fft->do_ift_inplace();
00947                 if (with_fft->is_complex()) with_fft->do_ift_inplace();
00948                 
00949                 int sz=image_fft->get_xsize()*image_fft->get_ysize()*image_fft->get_zsize();
00950                 float *d1=image_fft->get_data();
00951                 float *d2=with_fft->get_data();
00952                 
00953                 for (int i=0; i<sz; i++) {
00954                         if (d1[i]==0.0 || d2[i]==0.0) { d1[i]=0.0; d2[i]=0.0; }
00955                 }
00956                 
00957                 image_fft->update();
00958                 with_fft->update();
00959                 image_fft->do_fft_inplace();
00960                 with_fft->do_fft_inplace();
00961                 image_fft->set_attr("free_me",1); 
00962                 with_fft->set_attr("free_me",1); 
00963         }
00964         else {
00965                 if (image->is_complex()) image_fft=image;
00966                 else {
00967                         image_fft=image->do_fft();
00968                         image_fft->set_attr("free_me",1);
00969                 }
00970                 
00971                 if (with->is_complex()) with_fft=with;
00972                 else {
00973                         with_fft=with->do_fft();
00974                         with_fft->set_attr("free_me",1);
00975                 }
00976         }
00977 //      image_fft->ri2ap();
00978 //      with_fft->ri2ap();
00979 
00980         const float *const image_fft_data = image_fft->get_const_data();
00981         const float *const with_fft_data = with_fft->get_const_data();
00982         double sum = 0;
00983         double norm = FLT_MIN;
00984         size_t i = 0;
00985 //      int nx=image_fft->get_xsize();
00986             ny=image_fft->get_ysize();
00987         int nz=image_fft->get_zsize();
00988         int nx2=image_fft->get_xsize()/2;
00989         int ny2=image_fft->get_ysize()/2;
00990 //      int nz2=image_fft->get_zsize()/2;
00991 
00992         // This can never happen any more...
00993         if (np==0) {
00994                 for (int z = 0; z < nz; z++){
00995                         for (int y = 0; y < ny; y++) {
00996                                 for (int x = 0; x < nx2; x ++) {
00997                                         float a;
00998                                         if (ampweight) a= (float)hypot(with_fft_data[i],with_fft_data[i+1]);
00999                                         else a=1.0f;
01000                                         sum += Util::angle_err_ri(image_fft_data[i],image_fft_data[i+1],with_fft_data[i],with_fft_data[i+1]) * a;
01001                                         norm += a;
01002                                         i += 2;
01003                                 }
01004                         }
01005                 }
01006                 
01007         }
01008         else if (nz==1) {
01009                 for (int y = 0; y < ny; y++) {
01010                         for (int x = 0; x < nx2; x ++) {
01011                                 int r=Util::hypot_fast_int(x,y>ny/2?ny-y:y);
01012                                 if (r>=ny2) { i+=2; continue; }         // we only have snr values to the box radius
01013                                 
01014                                 float a;
01015                                 if (ampweight) a= (float)hypot(with_fft_data[i],with_fft_data[i+1]);
01016                                 else a=1.0f;
01017                                 a*=snr[r];
01018                                 sum += Util::angle_err_ri(image_fft_data[i],image_fft_data[i+1],with_fft_data[i],with_fft_data[i+1]) * a;
01019                                 norm += a;
01020                                 i += 2;
01021                         }
01022                 }
01023         }
01024         else {
01025                 for (int z = 0; z < nz; z++){
01026                         for (int y = 0; y < ny; y++) {
01027                                 for (int x = 0; x < nx2; x ++) {
01028                                         int r=(int)Util::hypot3(x,y>ny/2?ny-y:y,z>nz/2?nz-z:z);
01029                                         if (r>=ny2) { i+=2; continue; }         // we only have snr values to the box radius
01030                                         
01031                                         float a;
01032                                         if (ampweight) a= (float)hypot(with_fft_data[i],with_fft_data[i+1]);
01033                                         else a=1.0f;
01034                                         a*=snr[r];
01035                                         sum += Util::angle_err_ri(image_fft_data[i],image_fft_data[i+1],with_fft_data[i],with_fft_data[i+1]) * a;
01036                                         norm += a;
01037                                         i += 2;
01038                                 } 
01039                         }
01040                 }
01041                 
01042         }
01043 
01044         EXITFUNC;
01045 
01046         if( image_fft->has_attr("free_me") )
01047         {
01048                 delete image_fft;
01049                 image_fft = 0;
01050         }
01051         if( with_fft->has_attr("free_me") )
01052         {
01053                 delete with_fft;
01054                 with_fft = 0;
01055         }
01056 #if 0
01057         return (1.0f - sum / norm);
01058 #endif
01059         return (float)(sum / norm);
01060 }

string EMAN::PhaseCmp::get_desc  )  const [inline, virtual]
 

Implements EMAN::Cmp.

Definition at line 470 of file cmp.h.

00471                 {
00472                         return "Mean phase difference";
00473                 }

string EMAN::PhaseCmp::get_name  )  const [inline, virtual]
 

Get the Cmp's name.

Each Cmp is identified by a unique name.

Returns:
The Cmp's name.

Implements EMAN::Cmp.

Definition at line 465 of file cmp.h.

00466                 {
00467                         return NAME;
00468                 }

TypeDict EMAN::PhaseCmp::get_param_types  )  const [inline, virtual]
 

Get Cmp parameter information in a dictionary.

Each parameter has one record in the dictionary. Each record contains its name, data-type, and description.

Returns:
A dictionary containing the parameter info.

Implements EMAN::Cmp.

Definition at line 480 of file cmp.h.

References EMAN::TypeDict::put().

00481                 {
00482                         TypeDict d;
00483                         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)");
00484                         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)");
00485                         d.put("ampweight", EMObject::INT, "If set, the amplitude of 'with' will be used as a weight in the averaging'. (default=0)");
00486                         d.put("zeromask", EMObject::INT, "Treat regions in either image that are zero as a mask");
00487                         d.put("minres", EMObject::FLOAT, "Lowest resolution to use in comparison (soft cutoff). Requires accurate A/pix in image. <0 disables. Default=500");
00488                         d.put("maxres", EMObject::FLOAT, "Highest resolution to use in comparison (soft cutoff). Requires accurate A/pix in image. <0 disables.  Default=10");
00489                         return d;
00490                 }

Cmp* EMAN::PhaseCmp::NEW  )  [inline, static]
 

Definition at line 475 of file cmp.h.

00476                 {
00477                         return new PhaseCmp();
00478                 }


Member Data Documentation

const string PhaseCmp::NAME = "phase" [static]
 

Definition at line 50 of file cmp.cpp.


The documentation for this class was generated from the following files:
Generated on Thu Dec 9 13:47:19 2010 for EMAN2 by  doxygen 1.3.9.1