#include <cmp.h>
Inheritance diagram for EMAN::FRCCmp:


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 | |
| Cmp * | NEW () |
Static Public Attributes | |
| const string | NAME = "frc" |
Fourier ring correlation (FRC) is a measure of statistical dependency between two averages, computed by comparison of rings in Fourier space. 1 means prefect agreement. 0 means no correlation.
Definition at line 508 of file cmp.h.
|
||||||||||||
|
To compare 'image' with another image passed in through its parameters. An optional transformation may be used to transform the 2 images.
Implements EMAN::Cmp. Definition at line 1126 of file cmp.cpp. References EMAN::Ctf::apix, EMAN::EMData::calc_fourier_shell_correlation(), EMAN::EMData::calc_radial_dist(), EMAN::Ctf::compute_1d(), EMAN::EMData::copy(), EMAN::EMData::do_fft(), EMAN::EMData::do_fft_inplace(), EMAN::EMObject::f, EMAN::EMData::get_attr(), EMAN::EMData::get_attr_default(), EMAN::EMData::get_data(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::Util::goodf(), EMAN::EMData::has_attr(), InvalidCallException, EMAN::EMData::is_complex(), norm(), ny, EMAN::EMData::set_attr(), EMAN::Dict::set_default(), UnexpectedBehaviorException, EMAN::EMData::update(), EMAN::Cmp::validate_input_args(), and weight. 01127 {
01128 ENTERFUNC;
01129 validate_input_args(image, with);
01130
01131 int snrweight = params.set_default("snrweight", 0);
01132 int ampweight = params.set_default("ampweight", 0);
01133 int sweight = params.set_default("sweight", 1);
01134 int nweight = params.set_default("nweight", 0);
01135 int zeromask = params.set_default("zeromask",0);
01136 float minres = params.set_default("minres",500.0f);
01137 float maxres = params.set_default("maxres",2.0f);
01138
01139 vector < float >fsc;
01140 bool use_cpu = true;
01141 #ifdef EMAN2_USING_CUDA
01142 if(image->getcudarwdata() && with->getcudarwdata()) {
01143 UnexpectedBehaviorException("CUDA FRC cmp under construction....");
01144 /*
01145 if (zeromask) throw UnexpectedBehaviorException("ZeroMask is not yet supported in CUDA");
01146
01147 if (!image->is_complex()) {
01148 image=image->do_fft_cuda();
01149 image->set_attr("free_me",1);
01150 }
01151 if (!with->is_complex()) {
01152 with=with->do_fft_cuda();
01153 with->set_attr("free_me",1);
01154 }
01155 image->copy_rw_to_ro();
01156 image->bindcudaarrayA(true);
01157 with->copy_rw_to_ro();
01158 with->bindcudaarrayB(true);
01159
01160 float* fscarr = calc_fourier_shell_correlation_cuda(image->get_xsize(), image->get_ysize(), image->get_zsize(), 1);
01161
01162 use_cpu = false;
01163 */
01164 }
01165
01166 #endif
01167 if (use_cpu) {
01168 if (zeromask) {
01169 image=image->copy();
01170 with=with->copy();
01171
01172 int sz=image->get_xsize()*image->get_ysize()*image->get_zsize();
01173 float *d1=image->get_data();
01174 float *d2=with->get_data();
01175
01176 for (int i=0; i<sz; i++) {
01177 if (d1[i]==0.0 || d2[i]==0.0) { d1[i]=0.0; d2[i]=0.0; }
01178 }
01179
01180 image->update();
01181 with->update();
01182 image->do_fft_inplace();
01183 with->do_fft_inplace();
01184 image->set_attr("free_me",1);
01185 with->set_attr("free_me",1);
01186 }
01187
01188
01189 if (!image->is_complex()) {
01190 image=image->do_fft();
01191 image->set_attr("free_me",1);
01192 }
01193 if (!with->is_complex()) {
01194 with=with->do_fft();
01195 with->set_attr("free_me",1);
01196 }
01197
01198 fsc = image->calc_fourier_shell_correlation(with,1);
01199 }
01200
01201 int ny = image->get_ysize();
01202 int ny2=ny/2+1;
01203
01204 // The fast hypot here was supposed to speed things up. Little effect
01205 // if (image->get_zsize()>1) fsc = image->calc_fourier_shell_correlation(with,1);
01206 // else {
01207 // double *sxy = (double *)malloc(ny2*sizeof(double)*4);
01208 // double *sxx = sxy+ny2;
01209 // double *syy = sxy+2*ny2;
01210 // double *norm= sxy+3*ny2;
01211 //
01212 // float *df1=image->get_data();
01213 // float *df2=with->get_data();
01214 // int nx2=image->get_xsize();
01215 //
01216 // for (int y=-ny/2; y<ny/2; y++) {
01217 // for (int x=0; x<nx2/2; x++) {
01218 // if (x==0 && y<0) continue; // skip Friedel pair
01219 // short r=Util::hypot_fast_int(x,y);
01220 // if (r>ny2-1) continue;
01221 // int l=x*2+(y<0?ny+y:y)*nx2;
01222 // sxy[r]+=df1[l]*df2[l]+df1[l+1]*df2[l+1];
01223 // sxx[r]+=df1[l]*df1[l];
01224 // syy[r]+=df2[l]*df2[l];
01225 // norm[r]+=1.0;
01226 // }
01227 // }
01228 // fsc.resize(ny2*3);
01229 // for (int r=0; r<ny2; r++) {
01230 // fsc[r]=r*0.5/ny2;
01231 // fsc[ny2+r]=sxy[r]/(sqrt(sxx[r])*sqrt(syy[r]));
01232 // fsc[ny2*2+r]=norm[r];
01233 // }
01234 // free(sxy);
01235 // }
01236
01237 vector<float> snr;
01238 if (snrweight) {
01239 Ctf *ctf = NULL;
01240 if (!image->has_attr("ctf")) {
01241 if (!with->has_attr("ctf")) throw InvalidCallException("SNR weight with no CTF parameters");
01242 ctf=with->get_attr("ctf");
01243 }
01244 else ctf=image->get_attr("ctf");
01245
01246 float ds=1.0f/(ctf->apix*ny);
01247 snr=ctf->compute_1d(ny,ds,Ctf::CTF_SNR);
01248 if(ctf) {delete ctf; ctf=0;}
01249 }
01250
01251 vector<float> amp;
01252 if (ampweight) amp=image->calc_radial_dist(ny/2,0,1,0);
01253
01254 // Min/max modifications to weighting
01255 float pmin,pmax;
01256 if (minres>0) pmin=((float)image->get_attr("apix_x")*image->get_ysize())/minres; //cutoff in pixels, assume square
01257 else pmin=0;
01258 if (maxres>0) pmax=((float)image->get_attr("apix_x")*image->get_ysize())/maxres;
01259 else pmax=0;
01260
01261 double sum=0.0, norm=0.0;
01262
01263 for (int i=0; i<ny/2; i++) {
01264 double weight=1.0;
01265 if (sweight) weight*=fsc[(ny2)*2+i];
01266 if (ampweight) weight*=amp[i];
01267 if (snrweight) weight*=snr[i];
01268 // if (snrweight) {
01269 // if (snr[i]>0) weight*=sqrt(snr[i]);
01270 // else weight=0;
01271 // }
01272 //if(snr[i]<0) printf("snr[%d] = %1.5g\n",i,snr[i]);
01273 if (pmin>0) weight*=(tanh(5.0*(i-pmin)/pmin)+1.0)/2.0;
01274 if (pmax>0) weight*=(1.0-tanh(i-pmax))/2.0;
01275
01276 sum+=weight*fsc[ny2+i];
01277 norm+=weight;
01278 // printf("%d\t%f\t%f\n",i,weight,fsc[ny/2+1+i]);
01279 }
01280
01281 // This performs a weighting that tries to normalize FRC by correcting from the number of particles represented by the average
01282 sum/=norm;
01283 if (nweight && with->get_attr_default("ptcl_repr",0) && sum>=0 && sum<1.0) {
01284 sum=sum/(1.0-sum); // convert to SNR
01285 sum/=(float)with->get_attr_default("ptcl_repr",0); // divide by ptcl represented
01286 sum=sum/(1.0+sum); // convert back to correlation
01287 }
01288
01289 if (image->has_attr("free_me")) delete image;
01290 if (with->has_attr("free_me")) delete with;
01291
01292 EXITFUNC;
01293
01294
01295 if (!Util::goodf(&sum)) sum=-3.0e38;
01296 //.Note the negative! This is because EMAN2 follows the convention that
01297 // smaller return values from comparitors indicate higher similarity -
01298 // this enables comparitors to be used in a generic fashion.
01299 return (float)-sum;
01300 }
|
|
|
Implements EMAN::Cmp. Definition at line 518 of file cmp.h. 00519 {
00520 return "Computes the mean Fourier Ring Correlation between the image and reference (with optional weighting factors).";
00521 }
|
|
|
Get the Cmp's name. Each Cmp is identified by a unique name.
Implements EMAN::Cmp. Definition at line 513 of file cmp.h. 00514 {
00515 return NAME;
00516 }
|
|
|
Get Cmp parameter information in a dictionary. Each parameter has one record in the dictionary. Each record contains its name, data-type, and description.
Implements EMAN::Cmp. Definition at line 528 of file cmp.h. References EMAN::TypeDict::put(). 00529 {
00530 TypeDict d;
00531 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)");
00532 d.put("ampweight", EMObject::INT, "If set, the amplitude of 'this' will be used to weight the result (default=0)");
00533 d.put("sweight", EMObject::INT, "If set, weight the (1-D) average by the number of pixels in each ring (default=1)");
00534 d.put("nweight", EMObject::INT, "Downweight similarity based on number of particles in reference (default=0)");
00535 d.put("zeromask", EMObject::INT, "Treat regions in either image that are zero as a mask");
00536 d.put("minres", EMObject::FLOAT, "Lowest resolution to use in comparison (soft cutoff). Requires accurate A/pix in image. <0 disables. Default=500");
00537 d.put("maxres", EMObject::FLOAT, "Highest resolution to use in comparison (soft cutoff). Requires accurate A/pix in image. <0 disables. Default=10");
00538 return d;
00539 }
|
|
|
Definition at line 523 of file cmp.h. 00524 {
00525 return new FRCCmp();
00526 }
|
|
|
|
1.3.9.1