39#ifdef EMAN2_USING_CUDA
47const string CccCmp::NAME =
"ccc";
48const string LodCmp::NAME =
"lod";
49const string SqEuclideanCmp::NAME =
"sqeuclidean";
50const string DotCmp::NAME =
"dot";
51const string TomoCccCmp::NAME =
"ccc.tomo";
52const string TomoWedgeCccCmp::NAME =
"ccc.tomo.thresh";
53const string TomoWedgeFscCmp::NAME =
"fsc.tomo.auto";
54const string TomoFscCmp::NAME =
"fsc.tomo";
55const string QuadMinDotCmp::NAME =
"quadmindot";
56const string OptVarianceCmp::NAME =
"optvariance";
57const string OptSubCmp::NAME =
"optsub";
58const string PhaseCmp::NAME =
"phase";
59const string FRCCmp::NAME =
"frc";
60const string VerticalCmp::NAME =
"vertical";
66 force_add<SqEuclideanCmp>();
68 force_add<TomoCccCmp>();
69 force_add<TomoWedgeCccCmp>();
70 force_add<TomoWedgeFscCmp>();
71 force_add<TomoFscCmp>();
72 force_add<QuadMinDotCmp>();
73 force_add<OptVarianceCmp>();
74 force_add<OptSubCmp>();
75 force_add<PhaseCmp>();
77 force_add<VerticalCmp>();
81void Cmp::validate_input_args(
const EMData * image,
const EMData *with)
const
84#ifdef EMAN2_USING_CUDA
85 if (image->getcudarwdata() && with->getcudarwdata()) {
101 float *d1 = image->get_data();
106 float *d2 = with->get_data();
117 if (image->is_complex() || with->is_complex())
121 const float *
const d1 = image->get_const_data();
122 const float *
const d2 = with->get_const_data();
125 if (negative) negative=-1.0;
else negative=1.0;
127 double avg1 = 0.0, var1 = 0.0, avg2 = 0.0, var2 = 0.0, ccc = 0.0;
129 size_t totsize = image->get_xsize()*image->get_ysize()*image->get_zsize();
131 bool has_mask =
false;
135 if(mask!=0) {has_mask=
true;}
137#ifdef EMAN2_USING_CUDA
138 if (image->getcudarwdata() && with->getcudarwdata()) {
141 if(has_mask && !mask->getcudarwdata()){
142 mask->copy_to_cuda();
143 maskdata = mask->getcudarwdata();
145 float ccc =
ccc_cmp_cuda(image->getcudarwdata(), with->getcudarwdata(), maskdata, image->get_xsize(), image->get_ysize(), image->get_zsize());
152 const float *
const dm = mask->get_const_data();
153 for (
size_t i = 0; i < totsize; ++i) {
155 avg1 += double(d1[i]);
156 var1 += d1[i]*double(d1[i]);
157 avg2 += double(d2[i]);
158 var2 += d2[i]*double(d2[i]);
159 ccc += d1[i]*double(d2[i]);
164 for (
size_t i = 0; i < totsize; ++i) {
165 avg1 += double(d1[i]);
166 var1 += d1[i]*double(d1[i]);
167 avg2 += double(d2[i]);
168 var2 += d2[i]*double(d2[i]);
169 ccc += d1[i]*double(d2[i]);
175 var1 = var1/double(n) - avg1*avg1;
177 var2 = var2/double(n) - avg2*avg2;
178 ccc = ccc/double(n) - avg1*avg2;
179 ccc /=
sqrt(var1*var2);
182 return static_cast<float>(ccc);
192 if (image->is_complex() || with->is_complex())
196 const float *
const d1 = image->get_const_data();
197 const float *
const d2 = with->get_const_data();
200 if (negative) negative=-1.0;
else negative=1.0;
202 double avg1 = 0.0, sig1 = 0.0, avg2 = 0.0, sig2 = 0.0, lod = 0.0;
204 size_t totsize = image->get_xsize()*image->get_ysize()*image->get_zsize();
207 bool has_mask =
false;
211 if(mask!=0) {has_mask=
true;}
216 normalize =
params[
"normalize"];
221 const float *
const dm = mask->get_const_data();
222 for (i = 0; i < totsize; ++i) {
224 avg1 += double(d1[i]);
225 avg2 += double(d2[i]);
230 for (i = 0; i < totsize; ++i) {
231 avg1 += double(d1[i]);
232 avg2 += double(d2[i]);
241 const float *
const dm = mask->get_const_data();
242 for (i = 0; i < totsize; ++i) {
244 sig1 += fabs(
double(d1[i])-avg1);
245 sig2 += fabs(
double(d2[i])-avg2);
249 for (i = 0; i < totsize; ++i) {
250 sig1 += fabs(
double(d1[i])-avg1);
251 sig2 += fabs(
double(d2[i])-avg2);
255 avg1 = 0.0; avg2 = 0.0;
256 sig1 = 1.0; sig2 = 1.0;
260 const float *
const dm = mask->get_const_data();
261 for (i = 0; i < totsize; ++i) {
263 lod += fabs((
double(d1[i])-avg1)/sig1 - (
double(d2[i])-avg2)/sig2);
267 for (i = 0; i < totsize; ++i) {
268 lod += fabs((
double(d1[i])-avg1)/sig1 - (
double(d2[i])-avg2)/sig2);
274 return static_cast<float>(lod);
290 if (zeromask) with = withorig->process(
"normalize.toimage",
Dict(
"to",image));
291 else with = withorig->process(
"normalize.toimage",
Dict(
"to",image,
"ignore_zero",0));
292 with->set_attr(
"deleteme",1);
293 if ((
float)(with->get_attr(
"norm_mult"))<=0) {
299 const float *
const y_data = with->get_const_data();
300 const float *
const x_data = image->get_const_data();
303 if(image->is_complex() && with->is_complex()) {
305 int nx = with->get_xsize();
306 int ny = with->get_ysize();
307 int nz = with->get_zsize();
308 nx = (nx - 2 + with->is_fftodd());
309 int lsd2 = (nx + 2 - nx%2) ;
311 int ixb = 2*((nx+1)%2);
316 for (
int iz = 0; iz <= nz-1; iz++) {
318 for (
int iy = 0; iy <= ny-1; iy++) {
319 for (
int ix = 2; ix <= lsd2 - 1 - ixb; ix++) {
320 size_t ii = ix + (iy + iz * ny)* lsd2;
321 part += (x_data[ii] - y_data[ii])*
double(x_data[ii] - y_data[ii]);
324 for (
int iy = 1; iy <= ny/2-1 + iyb; iy++) {
325 size_t ii = (iy + iz * ny)* lsd2;
326 part += (x_data[ii] - y_data[ii])*
double(x_data[ii] - y_data[ii]);
327 part += (x_data[ii+1] - y_data[ii+1])*
double(x_data[ii+1] - y_data[ii+1]);
330 for (
int iy = 1; iy <= ny/2-1 + iyb; iy++) {
331 size_t ii = lsd2 - 2 + (iy + iz * ny)* lsd2;
332 part += (x_data[ii] - y_data[ii])*
double(x_data[ii] - y_data[ii]);
333 part += (x_data[ii+1] - y_data[ii+1])*
double(x_data[ii+1] - y_data[ii+1]);
338 part += (x_data[0] - y_data[0])*
double(x_data[0] - y_data[0]);
340 int ii = (ny/2 + iz * ny)* lsd2;
341 part += (x_data[ii] - y_data[ii])*
double(x_data[ii] - y_data[ii]);
344 int ii = lsd2 - 2 + (0 + iz * ny)* lsd2;
345 part += (x_data[ii] - y_data[ii])*
double(x_data[ii] - y_data[ii]);
347 int ii = lsd2 - 2 +(ny/2 + iz * ny)* lsd2;
348 part += (x_data[ii] - y_data[ii])*
double(x_data[ii] - y_data[ii]);
353 n = (float)nx*(
float)ny*(float)nz*(
float)nx*(float)ny*(
float)nz;
357 int ny2 = ny/2;
int nz2 = nz/2;
358 for (
int iz = 0; iz <= nz-1; iz++) {
359 if(iz>nz2) kz=iz-nz;
else kz=iz;
360 for (
int iy = 0; iy <= ny-1; iy++) {
361 if(iy>ny2) ky=iy-ny;
else ky=iy;
362 for (
int ix = 0; ix <= lsd2-1; ix++) {
364 if(ix>0 || (kz>=0 && (ky>=0 || kz!=0))) {
365 size_t ii = ix + (iy + iz * ny)* (
size_t)lsd2;
366 result += (x_data[ii] - y_data[ii])*
double(x_data[ii] - y_data[ii]);
371 n = ((float)nx*(
float)ny*(float)nz*(
float)nx*(float)ny*(
float)nz)/2.0f;
374 size_t totsize = (size_t)image->get_xsize()*image->get_ysize()*image->get_zsize();
378 const float *
const dm = mask->get_const_data();
379 for (
size_t i = 0; i < totsize; i++) {
381 double temp = x_data[i]- y_data[i];
389 for (
size_t i = 0; i < totsize; i++) {
390 if (x_data[i]==0 || y_data[i]==0)
continue;
391 double temp = x_data[i]- y_data[i];
398 for (
size_t i = 0; i < totsize; i++) {
399 double temp = x_data[i]- y_data[i];
408 if (with->has_attr(
"deleteme"))
delete with;
409 float ret = (float)result;
425 if (negative) negative=-1.0;
else negative=1.0;
426#ifdef EMAN2_USING_CUDA
427 if(image->is_complex() && with->is_complex()) {
429 if (image->getcudarwdata() && with->getcudarwdata()) {
432 bool has_mask =
false;
436 if(mask!=0) {has_mask=
true;}
438 if(has_mask && !mask->getcudarwdata()){
439 mask->copy_to_cuda();
440 maskdata = mask->getcudarwdata();
443 float result =
dot_cmp_cuda(image->getcudarwdata(), with->getcudarwdata(), maskdata, image->get_xsize(), image->get_ysize(), image->get_zsize());
451 const float *
const x_data = image->get_const_data();
452 const float *
const y_data = with->get_const_data();
456 if(image->is_complex() && with->is_complex()) {
458 int nx = with->get_xsize();
459 int ny = with->get_ysize();
460 int nz = with->get_zsize();
461 nx = (nx - 2 + with->is_fftodd());
462 int lsd2 = (nx + 2 - nx%2) ;
464 int ixb = 2*((nx+1)%2);
469 for (
int iz = 0; iz <= nz-1; ++iz) {
471 for (
int iy = 0; iy <= ny-1; ++iy) {
472 for (
int ix = 2; ix <= lsd2 - 1 - ixb; ++ix) {
473 size_t ii = ix + (iy + iz * ny)* lsd2;
474 part += x_data[ii] * double(y_data[ii]);
477 for (
int iy = 1; iy <= ny/2-1 + iyb; ++iy) {
478 size_t ii = (iy + iz * ny)* lsd2;
479 part += x_data[ii] * double(y_data[ii]);
480 part += x_data[ii+1] * double(y_data[ii+1]);
483 for (
int iy = 1; iy <= ny/2-1 + iyb; ++iy) {
484 size_t ii = lsd2 - 2 + (iy + iz * ny)* lsd2;
485 part += x_data[ii] * double(y_data[ii]);
486 part += x_data[ii+1] * double(y_data[ii+1]);
491 part += x_data[0] * double(y_data[0]);
493 size_t ii = (ny/2 + iz * ny)* lsd2;
494 part += x_data[ii] * double(y_data[ii]);
497 size_t ii = lsd2 - 2 + (0 + iz * ny)* lsd2;
498 part += x_data[ii] * double(y_data[ii]);
500 int ii = lsd2 - 2 +(ny/2 + iz * ny)* lsd2;
501 part += x_data[ii] * double(y_data[ii]);
509 int ny2 = ny/2;
int nz2 = nz/2;
510 for (
int iz = 0; iz <= nz-1; ++iz) {
511 if(iz>nz2) kz=iz-nz;
else kz=iz;
512 for (
int iy = 0; iy <= ny-1; ++iy) {
513 if(iy>ny2) ky=iy-ny;
else ky=iy;
514 for (
int ix = 0; ix <= lsd2-1; ++ix) {
516 if (ix <= 1 || (ix >= lsd2-2 && nx%2 == 0) ) p = 1;
517 size_t ii = ix + (iy + iz * ny)* (
size_t)lsd2;
518 result += p * x_data[ii] * double(y_data[ii]);
523 double square_sum1 = 0., square_sum2 = 0.;
525 int ny2 = ny/2;
int nz2 = nz/2;
526 for (
int iz = 0; iz <= nz-1; ++iz) {
527 if(iz>nz2) kz=iz-nz;
else kz=iz;
528 for (
int iy = 0; iy <= ny-1; ++iy) {
529 if(iy>ny2) ky=iy-ny;
else ky=iy;
530 for (
int ix = 0; ix <= lsd2-1; ++ix) {
532 if (ix <= 1 || (ix >= lsd2-2 && nx%2 == 0) ) p = 1;
533 size_t ii = ix + (iy + iz * ny)* (
size_t)lsd2;
534 square_sum1 += p * x_data[ii] * double(x_data[ii]);
535 square_sum2 += p * y_data[ii] * double(y_data[ii]);
539 result /=
sqrt(square_sum1*square_sum2);
540 }
else result /= ((float)nx*(
float)ny*(float)nz*(
float)nx*(float)ny*(
float)nz);
543 double square_sum1 = 0., square_sum2 = 0.;
544 for (
int iz = 0; iz <= nz-1; ++iz) {
545 for (
int iy = 0; iy <= ny-1; ++iy) {
546 for (
int ix = 2; ix <= lsd2 - 1 - ixb; ++ix) {
547 size_t ii = ix + (iy + iz * ny)* lsd2;
548 square_sum1 += x_data[ii] * double(x_data[ii]);
549 square_sum2 += y_data[ii] * double(y_data[ii]);
552 for (
int iy = 1; iy <= ny/2-1 + iyb; ++iy) {
553 size_t ii = (iy + iz * ny)* lsd2;
554 square_sum1 += x_data[ii] * double(x_data[ii]);
555 square_sum1 += x_data[ii+1] * double(x_data[ii+1]);
556 square_sum2 += y_data[ii] * double(y_data[ii]);
557 square_sum2 += y_data[ii+1] * double(y_data[ii+1]);
560 for (
int iy = 1; iy <= ny/2-1 + iyb; ++iy) {
561 size_t ii = lsd2 - 2 + (iy + iz * ny)* lsd2;
562 square_sum1 += x_data[ii] * double(x_data[ii]);
563 square_sum1 += x_data[ii+1] * double(x_data[ii+1]);
564 square_sum2 += y_data[ii] * double(y_data[ii]);
565 square_sum2 += y_data[ii+1] * double(y_data[ii+1]);
570 square_sum1 += x_data[0] * double(x_data[0]);
572 square_sum2 += y_data[0] * double(y_data[0]);
574 int ii = (ny/2 + iz * ny)* lsd2;
575 square_sum1 += x_data[ii] * double(x_data[ii]);
576 square_sum2 += y_data[ii] * double(y_data[ii]);
579 int ii = lsd2 - 2 + (0 + iz * ny)* lsd2;
580 square_sum1 += x_data[ii] * double(x_data[ii]);
581 square_sum2 += y_data[ii] * double(y_data[ii]);
583 int ii = lsd2 - 2 +(ny/2 + iz * ny)* lsd2;
584 square_sum1 += x_data[ii] * double(x_data[ii]);
585 square_sum2 += y_data[ii] * double(y_data[ii]);
589 result /=
sqrt(square_sum1*square_sum2);
590 }
else result /= ((float)nx*(
float)ny*(float)nz*(
float)nx*(float)ny*(
float)nz);
596 size_t totsize = (size_t)image->get_xsize() * image->get_ysize() * image->get_zsize();
598 double square_sum1 = 0., square_sum2 = 0.;
603 const float *
const dm = mask->get_const_data();
605 for (
size_t i = 0; i < totsize; i++) {
607 square_sum1 += x_data[i]*double(x_data[i]);
608 square_sum2 += y_data[i]*double(y_data[i]);
609 result += x_data[i]*double(y_data[i]);
613 for (
size_t i = 0; i < totsize; i++) {
615 result += x_data[i]*double(y_data[i]);
622 for (
size_t i=0; i<totsize; i++) result += x_data[i]*y_data[i];
625 square_sum1 = image->get_attr(
"square_sum");
626 square_sum2 = with->get_attr(
"square_sum");
629 if (normalize) result /= (
sqrt(square_sum1*square_sum2));
else result /= n;
634 return (
float) (negative*result);
647 bool ccf_ownership =
false;
650 if (negative) negative=-1.0;
else negative=1.0;
652#ifdef EMAN2_USING_CUDA
653 if(image->getcudarwdata() && with->getcudarwdata()){
656 ccf_ownership =
true;
659 float2 stats =
get_stats_cuda(ccf->getcudarwdata(), ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize());
660 float best_score =
get_value_at_wrap_cuda(ccf->getcudarwdata(), 0, 0, 0, ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize());
662 best_score = negative*(best_score - stats.x)/
sqrt(stats.y);
664 best_score = negative*best_score;
667 if (ccf_ownership)
delete ccf; ccf = 0;
677 ccf_ownership =
true;
679 if (norm) ccf->process_inplace(
"normalize");
681 float best_score = ccf->get_value_at_wrap(0,0,0);
682 if (ccf_ownership)
delete ccf; ccf = 0;
684 return negative*best_score;
696 if (!image->is_complex()) image=image->do_fft();
697 if (!with ->
is_complex()) with =with ->do_fft();
698 if (image->get_xsize()!=with->get_xsize() || image->get_ysize()!=with->get_ysize() || image->get_zsize()!=with->get_zsize())
throw InvalidCallException(
"Error: TomoWedgeCccCmp requires same sized images");
706 float s1=pow((
float)image->get_attr(
"sigma")*sigmaimg,(
float)2.0);
707 float s2=pow((
float)with->get_attr(
"sigma")*sigmawith,(
float)2.0);
714 for (
int z=0; z<image->get_zsize(); z++) {
715 for (
int y=0;
y<image->get_ysize();
y++) {
716 for (
int x=0;
x<image->get_xsize();
x+=2) {
717 float v1r=image->get_value_at(
x,
y,z);
718 float v1i=image->get_value_at(
x+1,
y,z);
722 float v2r=with->get_value_at(
x,
y,z);
723 float v2i=with->get_value_at(
x+1,
y,z);
727 sum+=v1r*v2r+v1i*v2i;
729 if (
Util::is_nan(sumsq1)) { printf(
"TomoWedgeCccCmp: NaN encountered: %d %d %d %f %f %f\n",
x,
y,z,v1r,v1i,v1); }
735 imageo->set_attr(
"fft_overlap",(
float)(2.0*norm/(image->get_xsize()*image->get_ysize()*image->get_zsize())));
738 if (imageo!=image)
delete image;
739 if (witho!=with)
delete with;
741 if (negative) sum*=-1.0;
742 return float(sum/(
sqrt(sumsq1)*
sqrt(sumsq2)));
753 if (!image->is_complex()) image=image->do_fft();
754 if (!with ->
is_complex()) with =with ->do_fft();
755 if (image->get_xsize()!=with->get_xsize() || image->get_ysize()!=with->get_ysize() || image->get_zsize()!=with->get_zsize())
throw InvalidCallException(
"Error: TomoWedgeFscCmp requires 2 images the same size");
757 int nx=image->get_xsize();
758 int ny=image->get_ysize();
759 int nz=image->get_zsize();
768 vector<float> sigmaimg;
772 for (
int i=0; i<nx/2; i++) sigmaimg[i]*=sigmaimg[i]*sigmaimgval;
775 vector<float> sigmawith;
779 for (
int i=0; i<nx/2; i++) sigmawith[i]*=sigmawith[i]*sigmawithval;
791 pmin=(int)floor((apix*ny)/minres);
793 pmax=(int)ceil((apix*ny)/maxres);
801 vector<float> curve(nx/2), sqcv1(nx/2), sqcv2(nx/2);
802 for (
int z=0; z<nz; z++) {
803 int za=z<nz/2?z:nz-z;
804 if (za>pmax)
continue;
805 for (
int y=0;
y<ny;
y++) {
806 int ya=
y<ny/2?
y:ny-
y;
807 if (ya>pmax)
continue;
808 for (
int x=0;
x<nx;
x+=2) {
810 int r=int(sqrtf(r2));
813 if (r<pmin || r>pmax)
continue;
815 float v1r=image->get_value_at(
x,
y,z);
816 float v1i=image->get_value_at(
x+1,
y,z);
818 if (v1<sigmaimg[r])
continue;
820 float v2r=with->get_value_at(
x,
y,z);
821 float v2i=with->get_value_at(
x+1,
y,z);
823 if (v2<sigmawith[r])
continue;
825 sum+=(v1r*v2r+v1i*v2i)/r2;
831 curve[r]+=v1r*v2r+v1i*v2i;
838 image->set_attr(
"fft_overlap",(
float)(2.0*norm/(image->get_xsize()*image->get_ysize()*image->get_zsize())));
841 for(
int i=0; i<nx/2; i++){
842 if (sqcv1[i]==0) sqcv1[i]=1;
843 if (sqcv2[i]==0) sqcv2[i]=1;
844 curve[i]=curve[i]/(
sqrt(sqcv1[i])*
sqrt(sqcv2[i]));
846 image->set_attr(
"fsc_curve", curve);
849 if (imageo!=image)
delete image;
850 if (witho!=with)
delete with;
852 if (negative) sum*=-1.0;
853 return float(sum/(
sqrt(sumsq1)*
sqrt(sumsq2)));
860 bool del_imagefft = 0;
861 bool del_withfft = 0;
865 if (!image->has_attr(
"spt_wedge_mean") || !image->has_attr(
"spt_wedge_sigma"))
throw InvalidCallException(
"Rubbish!!! Image Subtomogram does not have mena and/or sigma amps metadata");
869 float image_meanwedgeamp = image->get_attr(
"spt_wedge_mean");
870 float image_sigmawedgeamp = image->get_attr(
"spt_wedge_sigma");
873 float with_meanwedgeamp = image_meanwedgeamp;
874 float with_sigmawedgeamp = image_sigmawedgeamp;
875 if (with->has_attr(
"spt_wedge_mean") && with->has_attr(
"spt_wedge_sigma"))
877 with_meanwedgeamp = with->get_attr(
"spt_wedge_mean");
878 with_sigmawedgeamp = with->get_attr(
"spt_wedge_sigma");
888 float img_amp_thres = pow(image_meanwedgeamp + sigmas*image_sigmawedgeamp, 2.0f);
889 float with_amp_thres = pow(with_meanwedgeamp + sigmas*with_sigmawedgeamp, 2.0f);
893 if (negative) negative=-1.0;
else negative=1.0;
897 EMData* image_fft = image;
900#ifdef EMAN2_USING_CUDA
902 if(EMData::usecuda == 1 && image->getcudarwdata() && with->getcudarwdata()) {
903 if(!image->is_complex()){
905 image_fft = image->do_fft_cuda();
907 if(!with->is_complex()){
909 with_fft = with->do_fft_cuda();
911 score =
fsc_tomo_cmp_cuda(image_fft->getcudarwdata(), with_fft->getcudarwdata(), img_amp_thres, with_amp_thres, 0.0, 0.0, image_fft->get_xsize(), image_fft->get_ysize(), image_fft->get_zsize());
916 if(!image->is_complex()){
918 image_fft = image->do_fft();
920 if(!with->is_complex()){
922 with_fft = with->do_fft();
927 double sum_imgamp_sq = 0.0;
928 double sum_withamp_sq = 0.0;
930 float* img_data = image_fft->get_data();
931 float* with_data = with_fft->get_data();
933 int nx = image_fft->get_xsize();
934 int ny = image_fft->get_ysize();
935 int nz = image_fft->get_zsize();
941 for (
int iz = 0; iz < nz; iz++) {
942 if(iz > nz2) kz = nz-iz;
else kz=iz;
943 for (
int iy = 0; iy < ny; iy++) {
944 if(iy > ny2) ky = ny-iy;
else ky=iy;
945 for (
int ix = 0; ix < nx; ix+=2) {
947 float freq =
std::sqrt(kz*kz + ky*ky + ix*ix/4.0f)/float(nz);
948 float reso = apix/freq;
951 if(reso < minres && reso > maxres){
952 ii = ix + (iy + iz * ny)* nx;
953 float img_r = img_data[ii];
954 float img_i = img_data[ii+1];
955 float with_r = with_data[ii];
956 float with_i = with_data[ii+1];
957 double img_amp_sq = img_r*img_r + img_i*img_i;
958 double with_amp_sq = with_r*with_r + with_i*with_i;
960 if((img_amp_sq > img_amp_thres) && (with_amp_sq > with_amp_thres)){
962 sum_imgamp_sq += img_amp_sq;
963 sum_withamp_sq += with_amp_sq;
964 cong += img_r*with_r + img_i*with_i;
972 score = (float)(cong/
sqrt(sum_imgamp_sq*sum_withamp_sq));
979 if(del_imagefft)
delete image_fft;
980 if(del_withfft)
delete with_fft;
982 return negative*score;
995 int nx=image->get_xsize();
996 int ny=image->get_ysize();
1001 if (negative) negative=-1.0;
else negative=1.0;
1003 double result[4] = { 0,0,0,0 }, sq1[4] = { 0,0,0,0 }, sq2[4] = { 0,0,0,0 } ;
1005 vector<int> image_saved_offsets = image->get_array_offsets();
1006 vector<int> with_saved_offsets = with->get_array_offsets();
1007 image->set_array_offsets(-nx/2,-ny/2);
1008 with->set_array_offsets(-nx/2,-ny/2);
1010 for (
y=-ny/2;
y<ny/2;
y++) {
1011 for (
x=-nx/2;
x<nx/2;
x++) {
1012 int quad=(
x<0?0:1) + (
y<0?0:2);
1013 result[quad]+=(*image)(
x,
y)*(*with)(
x,
y);
1015 sq1[quad]+=(*image)(
x,
y)*(*image)(
x,
y);
1016 sq2[quad]+=(*with)(
x,
y)*(*with)(
x,
y);
1020 image->set_array_offsets(image_saved_offsets);
1021 with->set_array_offsets(with_saved_offsets);
1024 for (i=0; i<4; i++) result[i]/=
sqrt(sq1[i]*sq2[i]);
1026 for (i=0; i<4; i++) result[i]/=nx*ny/4;
1029 float worst=
static_cast<float>(result[0]);
1030 for (i=1; i<4; i++) if (static_cast<float>(result[i])<worst) worst=
static_cast<float>(result[i]);
1033 return (
float) (negative*worst);
1048 size_t size = (size_t)image->get_xsize() * image->get_ysize() * image->get_zsize();
1053 EMData *a = image->do_fft();
1054 EMData *b = with->do_fft();
1060 for (
size_t i=0; i<a->get_ysize()/2.0f; i++) {
1061 rfa[i]=(rfb[i]==0?0.0f:(rfa[i]/rfb[i]));
1065 avg/=a->get_ysize()/2.0f;
1066 for (
size_t i=0; i<a->get_ysize()/2.0f; i++) {
1067 if (rfa[i]>avg*10.0) rfa[i]=10.0;
1071 if (dbug) b->write_image(
"a.hdf",-1);
1076 if (dbug) b->write_image(
"a.hdf",-1);
1077 if (dbug) a->write_image(
"a.hdf",-1);
1094 with2->write_image(
"a.hdf",-1);
1095 image->write_image(
"a.hdf",-1);
1105 EMData *a = image->do_fft();
1106 EMData *b = with->do_fft();
1107 size_t size2 = (size_t)a->get_xsize() * a->get_ysize() * a->get_zsize();
1112 const float *
const ad=a->get_const_data();
1113 float * bd=b->get_data();
1115 for (
size_t i=0; i<size2; i+=2) bd[i]=ad[i];
1125 const float * x_data;
1126 if (with2) x_data=with2->get_const_data();
1127 else x_data = with->get_const_data();
1128 const float *
const y_data = image->get_const_data();
1130 size_t nx = image->get_xsize();
1137 FILE *out=fopen(
"dbug.optvar.txt",
"w");
1139 for (
size_t i=0; i<size; i++) {
1140 if ( !keepzero || (x_data[i] && y_data[i])) fprintf(out,
"%g\t%g\n",x_data[i],y_data[i]);
1167 for (
size_t i = 0,
y=0; i < size;
y++) {
1168 for (
size_t x=0;
x<nx; i++,
x++) {
1169 if (y_data[i] && x_data[i]) {
1170 if (invert) result +=
Util::square(x_data[i] - (y_data[i]-b)/m)*(hypot((
float)
x,(
float)
y)+nx/4.0);
1171 else result +=
Util::square((x_data[i] * m) + b - y_data[i])*(hypot((
float)
x,(
float)
y)+nx/4.0);
1179 for (
size_t i = 0,
y=0; i < size;
y++) {
1180 for (
size_t x=0;
x<nx; i++,
x++) {
1181 if (invert) result +=
Util::square(x_data[i] - (y_data[i]-b)/m)*(hypot((
float)
x,(
float)
y)+nx/4.0);
1182 else result +=
Util::square((x_data[i] * m) + b - y_data[i])*(hypot((
float)
x,(
float)
y)+nx/4.0);
1185 result = result / size;
1190 for (
size_t i = 0; i < size; i++) {
1191 if (y_data[i] && x_data[i]) {
1192 if (invert) result +=
Util::square(x_data[i] - (y_data[i]-b)/m);
1193 else result +=
Util::square((x_data[i] * m) + b - y_data[i]);
1200 for (
size_t i = 0; i < size; i++) {
1201 if (invert) result +=
Util::square(x_data[i] - (y_data[i]-b)/m);
1202 else result +=
Util::square((x_data[i] * m) + b - y_data[i]);
1204 result = result / size;
1210 image->set_attr(
"ovcmp_m",m);
1211 image->set_attr(
"ovcmp_b",b);
1212 if (with2)
delete with2;
1216 return (1 - result);
1219 return static_cast<float>(result);
1233 if (snrweight && snrfn)
throw InvalidCallException(
"SNR weight and SNRfn cannot both be set in the phase comparator");
1235 EMData *image_fft = NULL;
1238 int ny = image->get_ysize();
1246 if (!image->has_attr(
"ctf")) {
1248 ctf=with->get_attr(
"ctf");
1250 else ctf=image->get_attr(
"ctf");
1252 float ds=1.0f/(ctf->
apix*ny);
1254 for (
int i=0; i<snr.size(); i++) {
1255 if (snr[i]<=0) snr[i]=0.001;
1257 if(ctf) {
delete ctf; ctf=0;}
1261 else if (snrfn==1) {
1265 for (
int i = 0; i < np; i++) {
1266 float x2 = 10.0f*i/np;
1267 snr[i] = x2 * exp(-x2);
1275 for (
int i = 0; i < np; i++) snr[i]=1.0;
1283 if (minres>0 && pmin==0) pmin=((float)image->get_attr(
"apix_x")*image->get_ysize())/minres;
1285 if (maxres>0 && pmax==0) pmax=((float)image->get_attr(
"apix_x")*image->get_ysize())/maxres;
1291 for (
int i = 0; i < np; i++) {
1292 if (pmin>0) snr[i]*=(tanh(5.0f*(i-pmin)/pmin)+1.0f)/2.0f;
1293 if (pmax>0) snr[i]*=(1.0f-tanh(i-pmax))/2.0f;
1298 image_fft=image->copy();
1299 with_fft=with->copy();
1301 if (image_fft->is_complex()) image_fft->do_ift_inplace();
1302 if (with_fft->is_complex()) with_fft->do_ift_inplace();
1304 int sz=image_fft->get_xsize()*image_fft->get_ysize()*image_fft->get_zsize();
1305 float *d1=image_fft->get_data();
1306 float *d2=with_fft->get_data();
1308 for (
int i=0; i<sz; i++) {
1309 if (d1[i]==0.0 || d2[i]==0.0) { d1[i]=0.0; d2[i]=0.0; }
1312 image_fft->update();
1314 image_fft->do_fft_inplace();
1315 with_fft->do_fft_inplace();
1316 image_fft->set_attr(
"free_me",1);
1317 with_fft->set_attr(
"free_me",1);
1320 if (image->is_complex()) image_fft=image;
1322 image_fft=image->do_fft();
1323 image_fft->set_attr(
"free_me",1);
1326 if (with->is_complex()) with_fft=with;
1328 with_fft=with->do_fft();
1329 with_fft->set_attr(
"free_me",1);
1335 const float *
const image_fft_data = image_fft->get_const_data();
1336 const float *
const with_fft_data = with_fft->get_const_data();
1338 double norm = FLT_MIN;
1341 ny=image_fft->get_ysize();
1342 int nz=image_fft->get_zsize();
1343 int nx2=image_fft->get_xsize()/2;
1344 int ny2=image_fft->get_ysize()/2;
1349 for (
int z = 0; z < nz; z++){
1350 for (
int y = 0;
y < ny;
y++) {
1351 for (
int x = 0;
x < nx2;
x ++) {
1353 if (ampweight) a= (float)hypot(with_fft_data[i],with_fft_data[i+1]);
1355 sum +=
Util::angle_err_ri(image_fft_data[i],image_fft_data[i+1],with_fft_data[i],with_fft_data[i+1]) * a;
1364 for (
int y = 0;
y < ny;
y++) {
1365 for (
int x = 0;
x < nx2;
x ++) {
1367 if (r>=ny2) { i+=2;
continue; }
1370 if (ampweight) a= (float)hypot(with_fft_data[i],with_fft_data[i+1]);
1373 sum +=
Util::angle_err_ri(image_fft_data[i],image_fft_data[i+1],with_fft_data[i],with_fft_data[i+1]) * a;
1380 for (
int z = 0; z < nz; z++){
1381 for (
int y = 0;
y < ny;
y++) {
1382 for (
int x = 0;
x < nx2;
x ++) {
1384 if (r>=ny2) { i+=2;
continue; }
1387 if (ampweight) a= (float)hypot(with_fft_data[i],with_fft_data[i+1]);
1390 sum +=
Util::angle_err_ri(image_fft_data[i],image_fft_data[i+1],with_fft_data[i],with_fft_data[i+1]) * a;
1401 if( image_fft->has_attr(
"free_me") )
1406 if( with_fft->has_attr(
"free_me") )
1412 return (1.0f - sum / norm);
1414 return (
float)(sum / norm);
1430 vector < float >fsc;
1431 bool use_cpu =
true;
1435 image=image->copy();
1438 int sz=image->get_xsize()*image->get_ysize()*image->get_zsize();
1439 float *d1=image->get_data();
1440 float *d2=with->get_data();
1442 for (
int i=0; i<sz; i++) {
1443 if (d1[i]==0.0 || d2[i]==0.0) { d1[i]=0.0; d2[i]=0.0; }
1448 image->do_fft_inplace();
1449 with->do_fft_inplace();
1450 image->set_attr(
"free_me",1);
1451 with->set_attr(
"free_me",1);
1455 if (!image->is_complex()) {
1456 image=image->do_fft();
1457 image->set_attr(
"free_me",1);
1459 if (!with->is_complex()) {
1460 with=with->do_fft();
1461 with->set_attr(
"free_me",1);
1464 fsc = image->calc_fourier_shell_correlation(with,1);
1467 int ny = image->get_ysize();
1506 if (!image->has_attr(
"ctf")) {
1508 ctf=with->get_attr(
"ctf");
1510 else ctf=image->get_attr(
"ctf");
1512 float ds=1.0f/(ctf->
apix*ny);
1514 for (
int i=0; i<snr.size(); i++) {
1515 if (snr[i]<=0) snr[i]=0.001;
1517 if(ctf) {
delete ctf; ctf=0;}
1527 if (pmin==0 && minres>0)
1528 pmin=((float)image->get_attr(
"apix_x")*image->get_ysize())/minres;
1530 if (pmax==0 && maxres>0)
1531 pmax=((float)image->get_attr(
"apix_x")*image->get_ysize())/maxres;
1534 double sum=0.0, norm=0.0;
1536 for (
int i=0; i<ny/2; i++) {
1538 if (sweight) weight*=fsc[(ny2)*2+i];
1539 if (ampweight) weight*=amp[i];
1540 if (snrweight) weight*=snr[i];
1546 if (pmin>0) weight*=(tanh(5.0*(i-pmin)/pmin)+1.0)/2.0;
1547 if (pmax>0) weight*=(1.0-tanh(i-pmax))/2.0;
1549 sum+=weight*fsc[ny2+i];
1556 if (nweight && with->get_attr_default(
"ptcl_repr",0) && sum>=0 && sum<1.0) {
1558 sum/=(float)with->get_attr_default(
"ptcl_repr",0);
1562 if (image->has_attr(
"free_me"))
delete image;
1563 if (with->has_attr(
"free_me"))
delete with;
1592 float apix=(float)image->get_attr(
"apix_x");
1597 if (image->has_attr(
"ctf")) diff=image->process(
"math.sub.optimal",
Dict(
"ref",with,
"return_presigma",1,
"low_cutoff_frequency",apix/minres ,
"high_cutoff_frequency",apix/maxres,
"ctfweight",ctfweight));
1598 else diff=with->process(
"math.sub.optimal",
Dict(
"ref",image,
"return_presigma",1,
"low_cutoff_frequency",apix/minres ,
"high_cutoff_frequency",apix/maxres,
"ctfweight",ctfweight));
1600 if (mask!=NULL) diff->mult(*mask);
1602 EMData *tmp=with->process(
"threshold.notzero");
1610 float ret=(float)diff->get_attr(
"sigma")/(float)diff->get_attr(
"sigma_presub");
1645 int nx=image->get_xsize();
1646 int ny=image->get_ysize();
1649 for (
int x=0;
x<nx;
x++){
1651 for (
int y=0;
y<ny;
y++){
1652 s+=image->get_value_at(
x,
y);
1666 dump_factory < Cmp > ();
1671 return dump_factory_list < Cmp > ();
float cmp(EMData *image, EMData *with) const
To compare 'image' with another image passed in through its parameters.
void validate_input_args(const EMData *image, const EMData *with) const
Ctf is the base class for all CTF model.
virtual vector< float > compute_1d(int size, float ds, CtfType t, XYData *struct_factor=0)=0
Dict is a dictionary to store <string, EMObject> pair.
type set_default(const string &key, type val)
Default setting behavior This can be achieved using a template - d.woolford Jan 2008 (before there wa...
bool has_key(const string &key) const
Ask the Dictionary if it as a particular key.
float cmp(EMData *image, EMData *with) const
To compare 'image' with another image passed in through its parameters.
EMData stores an image's data and defines core image processing routines.
void apply_radial_func(float x0, float dx, vector< float >array, bool interp=true)
multiplies by a radial function in fourier space.
vector< float > calc_radial_dist(int n, float x0, float dx, int inten)
calculates radial distribution.
static bool is_same_size(const EMData *image1, const EMData *image2)
Check whether two EMData images are of the same size.
float cmp(EMData *image, EMData *with) const
To compare 'image' with another image passed in through its parameters.
Factory is used to store objects to create new instances.
float cmp(EMData *image, EMData *with) const
To compare 'image' with another image passed in through its parameters.
float cmp(EMData *image, EMData *with) const
To compare 'image' with another image passed in through its parameters.
float cmp(EMData *image, EMData *with) const
To compare 'image' with another image passed in through its parameters.
float cmp(EMData *image, EMData *with) const
To compare 'image' with another image passed in through its parameters.
float cmp(EMData *image, EMData *with) const
To compare 'image' with another image passed in through its parameters.
float cmp(EMData *image, EMData *with) const
To compare 'image' with another image passed in through its parameters.
virtual float cmp(EMData *image, EMData *with) const
To compare 'image' with another image passed in through its parameters.
virtual float cmp(EMData *image, EMData *with) const
To compare 'image' with another image passed in through its parameters.
virtual float cmp(EMData *image, EMData *with) const
To compare 'image' with another image passed in through its parameters.
virtual float cmp(EMData *image, EMData *with) const
To compare 'image' with another image passed in through its parameters.
static void calc_least_square_fit(size_t nitems, const float *data_x, const float *data_y, float *p_slope, float *p_intercept, bool ignore_zero, float absmax=0)
calculate the least square fit value.
static int hypot3sq(int x, int y, int z)
Euclidean distance function squared in 3D: f(x,y,z) = (x*x + y*y + z*z);.
static short hypot_fast_int(int x, int y)
Euclidean distance in 2D for integers computed fast using a cached lookup table.
static int square(int n)
Calculate a number's square.
static int goodf(const float *p_f)
Check whether a number is a good float.
static float angle_err_ri(float r1, float i1, float r2, float i2)
Calculate the angular phase difference between two r/i vectors.
static bool is_nan(const float number)
tell whether a float value is a NaN
static float hypot3(int x, int y, int z)
Euclidean distance function in 3D: f(x,y,z) = sqrt(x*x + y*y + z*z);.
static float square_sum(float x, float y)
Calcuate (x*x + y*y).
float cmp(EMData *image, EMData *with) const
To compare 'image' with another image passed in through its parameters.
float get_value_at_wrap_cuda(float *data, int tx, int ty, int tz, int nx, int ny, int nz)
float2 get_stats_cuda(const float *data, const int nx, const int ny, const int nz)
float ccc_cmp_cuda(const float *data1, const float *data2, const float *dm, const int &nx, const int &ny, const int &nz)
float dot_cmp_cuda(float *data1, float *data2, const float *dm, const int &nx, const int &ny, const int &nz)
float fsc_tomo_cmp_cuda(const float *data1, const float *data2, const float data1threshold, const float data2threshold, const float minres, const float maxres, const int nx, const int ny, const int nz)
EMData * sqrt() const
return square root of current image
#define InvalidValueException(val, desc)
#define ImageFormatException(desc)
#define ImageDimensionException(desc)
#define InvalidCallException(desc)
#define NullPointerException(desc)
EMData * calc_ccf(EMData *with=0, fp_flag fpflag=CIRCULANT, bool center=false)
Calculate Cross-Correlation Function (CCF).
map< string, vector< string > > dump_cmps_list()