#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 505 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 1172 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(), EMAN::EMData::update(), EMAN::Cmp::validate_input_args(), and weight. 01173 { 01174 ENTERFUNC; 01175 validate_input_args(image, with); 01176 01177 int snrweight = params.set_default("snrweight", 0); 01178 int ampweight = params.set_default("ampweight", 0); 01179 int sweight = params.set_default("sweight", 1); 01180 int nweight = params.set_default("nweight", 0); 01181 int zeromask = params.set_default("zeromask",0); 01182 float minres = params.set_default("minres",500.0f); 01183 float maxres = params.set_default("maxres",2.0f); 01184 01185 if (zeromask) { 01186 image=image->copy(); 01187 with=with->copy(); 01188 01189 int sz=image->get_xsize()*image->get_ysize()*image->get_zsize(); 01190 float *d1=image->get_data(); 01191 float *d2=with->get_data(); 01192 01193 for (int i=0; i<sz; i++) { 01194 if (d1[i]==0.0 || d2[i]==0.0) { d1[i]=0.0; d2[i]=0.0; } 01195 } 01196 01197 image->update(); 01198 with->update(); 01199 image->do_fft_inplace(); 01200 with->do_fft_inplace(); 01201 image->set_attr("free_me",1); 01202 with->set_attr("free_me",1); 01203 } 01204 01205 01206 if (!image->is_complex()) { 01207 image=image->do_fft(); 01208 image->set_attr("free_me",1); 01209 } 01210 if (!with->is_complex()) { 01211 with=with->do_fft(); 01212 with->set_attr("free_me",1); 01213 } 01214 01215 static vector < float >default_snr; 01216 01217 // if (image->get_zsize() > 1) { 01218 // throw ImageDimensionException("2D only"); 01219 // } 01220 01221 // int nx = image->get_xsize(); 01222 int ny = image->get_ysize(); 01223 int ny2=ny/2+1; 01224 01225 vector < float >fsc; 01226 01227 01228 01229 fsc = image->calc_fourier_shell_correlation(with,1); 01230 01231 // The fast hypot here was supposed to speed things up. Little effect 01232 // if (image->get_zsize()>1) fsc = image->calc_fourier_shell_correlation(with,1); 01233 // else { 01234 // double *sxy = (double *)malloc(ny2*sizeof(double)*4); 01235 // double *sxx = sxy+ny2; 01236 // double *syy = sxy+2*ny2; 01237 // double *norm= sxy+3*ny2; 01238 // 01239 // float *df1=image->get_data(); 01240 // float *df2=with->get_data(); 01241 // int nx2=image->get_xsize(); 01242 // 01243 // for (int y=-ny/2; y<ny/2; y++) { 01244 // for (int x=0; x<nx2/2; x++) { 01245 // if (x==0 && y<0) continue; // skip Friedel pair 01246 // short r=Util::hypot_fast_int(x,y); 01247 // if (r>ny2-1) continue; 01248 // int l=x*2+(y<0?ny+y:y)*nx2; 01249 // sxy[r]+=df1[l]*df2[l]+df1[l+1]*df2[l+1]; 01250 // sxx[r]+=df1[l]*df1[l]; 01251 // syy[r]+=df2[l]*df2[l]; 01252 // norm[r]+=1.0; 01253 // } 01254 // } 01255 // fsc.resize(ny2*3); 01256 // for (int r=0; r<ny2; r++) { 01257 // fsc[r]=r*0.5/ny2; 01258 // fsc[ny2+r]=sxy[r]/(sqrt(sxx[r])*sqrt(syy[r])); 01259 // fsc[ny2*2+r]=norm[r]; 01260 // } 01261 // free(sxy); 01262 // } 01263 01264 vector<float> snr; 01265 if (snrweight) { 01266 Ctf *ctf = NULL; 01267 if (!image->has_attr("ctf")) { 01268 if (!with->has_attr("ctf")) throw InvalidCallException("SNR weight with no CTF parameters"); 01269 ctf=with->get_attr("ctf"); 01270 } 01271 else ctf=image->get_attr("ctf"); 01272 01273 float ds=1.0f/(ctf->apix*ny); 01274 snr=ctf->compute_1d(ny,ds,Ctf::CTF_SNR); 01275 if(ctf) {delete ctf; ctf=0;} 01276 } 01277 01278 vector<float> amp; 01279 if (ampweight) amp=image->calc_radial_dist(ny/2,0,1,0); 01280 01281 // Min/max modifications to weighting 01282 float pmin,pmax; 01283 if (minres>0) pmin=((float)image->get_attr("apix_x")*image->get_ysize())/minres; //cutoff in pixels, assume square 01284 else pmin=0; 01285 if (maxres>0) pmax=((float)image->get_attr("apix_x")*image->get_ysize())/maxres; 01286 else pmax=0; 01287 01288 double sum=0.0, norm=0.0; 01289 01290 for (int i=0; i<ny/2; i++) { 01291 double weight=1.0; 01292 if (sweight) weight*=fsc[(ny2)*2+i]; 01293 if (ampweight) weight*=amp[i]; 01294 if (snrweight) weight*=snr[i]; 01295 // if (snrweight) { 01296 // if (snr[i]>0) weight*=sqrt(snr[i]); 01297 // else weight=0; 01298 // } 01299 //if(snr[i]<0) printf("snr[%d] = %1.5g\n",i,snr[i]); 01300 if (pmin>0) weight*=(tanh(5.0*(i-pmin)/pmin)+1.0)/2.0; 01301 if (pmax>0) weight*=(1.0-tanh(i-pmax))/2.0; 01302 01303 sum+=weight*fsc[ny2+i]; 01304 norm+=weight; 01305 // printf("%d\t%f\t%f\n",i,weight,fsc[ny/2+1+i]); 01306 } 01307 01308 // This performs a weighting that tries to normalize FRC by correcting from the number of particles represented by the average 01309 sum/=norm; 01310 if (nweight && with->get_attr_default("ptcl_repr",0) && sum>=0 && sum<1.0) { 01311 sum=sum/(1.0-sum); // convert to SNR 01312 sum/=(float)with->get_attr_default("ptcl_repr",0); // divide by ptcl represented 01313 sum=sum/(1.0+sum); // convert back to correlation 01314 } 01315 01316 if (image->has_attr("free_me")) delete image; 01317 if (with->has_attr("free_me")) delete with; 01318 01319 EXITFUNC; 01320 01321 01322 if (!Util::goodf(&sum)) sum=-3.0e38; 01323 //.Note the negative! This is because EMAN2 follows the convention that 01324 // smaller return values from comparitors indicate higher similarity - 01325 // this enables comparitors to be used in a generic fashion. 01326 return (float)-sum; 01327 }
|
|
Implements EMAN::Cmp. Definition at line 515 of file cmp.h. 00516 { 00517 return "Computes the mean Fourier Ring Correlation between the image and reference (with optional weighting factors)."; 00518 }
|
|
Get the Cmp's name. Each Cmp is identified by a unique name.
Implements EMAN::Cmp. Definition at line 510 of file cmp.h. 00511 {
00512 return NAME;
00513 }
|
|
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 525 of file cmp.h. References EMAN::TypeDict::put(). 00526 { 00527 TypeDict d; 00528 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)"); 00529 d.put("ampweight", EMObject::INT, "If set, the amplitude of 'this' will be used to weight the result (default=0)"); 00530 d.put("sweight", EMObject::INT, "If set, weight the (1-D) average by the number of pixels in each ring (default=1)"); 00531 d.put("nweight", EMObject::INT, "Downweight similarity based on number of particles in reference (default=0)"); 00532 d.put("zeromask", EMObject::INT, "Treat regions in either image that are zero as a mask"); 00533 d.put("minres", EMObject::FLOAT, "Lowest resolution to use in comparison (soft cutoff). Requires accurate A/pix in image. <0 disables. Default=500"); 00534 d.put("maxres", EMObject::FLOAT, "Highest resolution to use in comparison (soft cutoff). Requires accurate A/pix in image. <0 disables. Default=10"); 00535 return d; 00536 }
|
|
Definition at line 520 of file cmp.h. 00521 { 00522 return new FRCCmp(); 00523 }
|
|
|