| Bsoft 2.0.5 Bernard's software package

Bimage_correlate.cpp
Go to the documentation of this file.
1
11 #include "Bimage.h"
12 #include "rwimg.h"
13 #include "matrix_linear.h"
14 #include "math_util.h"
15 #include "qsort_functions.h"
16 #include "timer.h"
17 #include "utilities.h"
18
19 // Declaration of global variables
20 extern int verbose; // Level of output to the screen
21
36 double Bimage::correlate(Bimage* p)
37 {
38 if ( c > 1 || p->channels() > 1 ) {
39 cerr << "Error: Only single channel images are supported for correlation!" << endl;
40 return -1.0;
41 }
42
43 if ( n > 1 || p->images() > 1 ) {
44 cerr << "Error: Only single images are supported for correlation!" << endl;
45 return -1.0;
46 }
47
48 if ( !check_if_same_size(p) ) {
49 error_show("Bimage::correlate", __FILE__, __LINE__);
50 return -1;
51 }
52
53 long i;
54 double v1, v2, cc(0), sx(0), sy(0), sx2(0), sy2(0), sxy(0);
55
56 for ( i=0; i<datasize; i++ ) {
57 v1 = (*this)[i];
58 v2 = (*p)[i];
59 sx += v1;
60 sy += v2;
61 sx2 += v1*v1;
62 sy2 += v2*v2;
63 sxy += v1*v2;
64 }
65
66 double varx = sx2 - sx*sx/datasize;
67 double vary = sy2 - sy*sy/datasize;
68
69 if ( varx > 0 && vary > 0 )
70 cc = (sxy - sx*sy/datasize)/sqrt(varx*vary);
71
72 return cc;
73 }
74
90 double Bimage::correlate(Bimage* p, double rmin, double rmax, Bimage* pmask, int flag)
91 {
92 if ( n > 1 || p->images() > 1 ) {
93 cerr << "Error: Only single images are supported for correlation!" << endl;
94 return -1.0;
95 }
96
97 if ( !check_if_same_size(p) ) {
98 error_show("Bimage::correlate", __FILE__, __LINE__);
99 return -1;
100 }
101
102 if ( std <= 0 || p->std <= 0 ) return -1;
103
104 if ( rmin > x/2 ) rmin = 0;
105 if ( rmax <= rmin ) rmax = size().max();
106
107 if ( verbose & VERB_PROCESS ) {
108 cout << "Calculating a correlation map:" << endl;
109 cout << "Origin: " << image->origin() << endl;
110 cout << "Radii: " << rmin << " - " << rmax << endl;
111 if ( pmask )
112 cout << "Mask: " << pmask->file_name() << endl;
113 }
114
115 int use_this;
116 long i, xx, yy, zz, ns(0);
117 double v1, v2, dx, dy, dz, d2, rmin2(rmin*rmin), rmax2(rmax*rmax);
118 double avg1(0), avg2(0), std1(0), std2(0), c12(0), denom, cc(0);
119
120 for ( i=zz=0; zz<z; zz++ ) {
121 dz = (double)zz - image->origin()[2];
122 dz *= dz;
123 for ( yy=0; yy<y; yy++ ) {
124 dy = (double)yy - image->origin()[1];
125 dy *= dy;
126 for ( xx=0; xx<x; xx++, i++ ) {
127 dx = (double)xx - image->origin()[0];
128 dx *= dx;
129 d2 = dx + dy + dz;
130 use_this = 1;
131 if ( pmask && (*pmask)[i] < 1 ) use_this = 0;
132 if ( d2 < rmin2 || d2 > rmax2 ) use_this = 0;
133 if ( use_this ) {
134 v1 = (*this)[i];
135 v2 = (*p)[i];
136 avg1 += v1;
137 avg2 += v2;
138 std1 += v1*v1;
139 std2 += v2*v2;
140 c12 += v1*v2;
141 ns++;
142 } else if ( flag ) {
143 p->set(i, 0);
144 }
145 }
146 }
147 }
148
149 if ( ns ) {
150 avg1 /= ns;
151 avg2 /= ns;
152 std1 = std1/ns - avg1*avg1;
153 std2 = std2/ns - avg2*avg2;
154 if ( std1 > 0 ) std1 = sqrt(std1);
155 else std1 = 0;
156 if ( std2 > 0 ) std2 = sqrt(std2);
157 else std2 = 0;
158 c12 /= ns;
159 }
160
161 denom = std1*std2;
162 if ( denom <= 0 ) {
163 // cerr << "Error in Bimage::correlate: One or both standard deviations are zero!" << endl;
164 return 0;
165 }
166
167 denom = 1/denom;
168
169 cc = (c12 - avg1*avg2) * denom;
170
171 if (flag ) {
172 for ( i=0; i<datasize; i++ ) if ( (*p)[i] )
173 p->set(i, ((*this)[i] - avg1)*((*p)[i] - avg2)*denom);
174 p->statistics();
175 }
176
177 if ( verbose & VERB_PROCESS ) {
178 cout << "Averages: " << avg1 << " " << avg2 << endl;
179 cout << "Standard deviations: " << std1 << " " << std2 << endl;
180 cout << "Correlation: " << cc << " (" << ns << ")" << endl << endl;
181 }
182
183 return cc;
184 }
185
195 double Bimage::rotate_correlate(Vector3<double> axis, double angle)
196 {
197 Bimage* p = rotate(size(), axis, angle);
198
199 double CC = correlate(p);
200
201 delete p;
202
203 return CC;
204 }
205
218 double Bimage::R_factor(Bimage* p)
219 {
220 if ( n > 1 || p->images() > 1 ) {
221 cerr << "Error: Only single images are supported for R factor calculation!" << endl;
222 return -1.0;
223 }
224
225 if ( !check_if_same_size(p) ) {
226 error_show("Bimage::R_factor", __FILE__, __LINE__);
227 return -1;
228 }
229
230 long i;
231 double R(0);
232 double sx(0), sy(0), sx2(0), sy2(0), sxy(0);
233
234 for ( i=0; i<datasize; i++ ) {
235 sx += (*this)[i];
236 sy += (*p)[i];
237 sx2 += (*this)[i]*(*this)[i];
238 sy2 += (*p)[i]*(*p)[i];
239 sxy += (*this)[i]*(*p)[i];
240 }
241
242 R = sqrt((sx2 - 2*sxy + sy2)/sqrt((sx2 - sx*sx/datasize)*(sy2 - sy*sy/datasize)));
243
244 return R;
245 }
246
247
265 int Bimage::auto_correlate(double hires, double lores)
266 {
267 if ( hires > lores ) swap(hires, lores);
268
269 long nn, i, xx, yy, zz;
270 long ix, iy, iz;
271 double s2, sx2, sy2, sz2, smin2(0), smax2(0), sum, scale;
272 Vector3<double> u(image->sampling());
273 Vector3<double> realsize(real_size());
274
275 if ( lores > 0 ) smin2 = 1/(lores*lores);
276
277 if ( hires > 0 ) {
278 smax2 = 1/(hires*hires);
279 } else {
280 if ( x > 1 ) smax2 += 1.0/(4.0*u[0]*u[0]);
281 if ( y > 1 ) smax2 += 1.0/(4.0*u[1]*u[1]);
282 if ( z > 1 ) smax2 += 1.0/(4.0*u[2]*u[2]);
283 hires = 1/sqrt(smax2);
284 }
285
286 if ( verbose & VERB_FULL ) {
287 cout << "Auto-correlation:" << endl;
288 if ( lores > 0 )
289 cout << "Resolution range: " << hires << " - " << lores << " A" << endl;
290 else
291 cout << "No resolution limits" << endl;
292 cout << endl;
293 }
294
295 fft();
296
297 Complex<double> cv;
298 // set(0, cv);
299
300 for ( i=nn=0; nn<n; nn++ ) {
301 sum = 0;
302 for ( zz=0; zz<z; zz++ ) {
303 iz = zz;
304 if ( zz > (z - 1)/2 ) iz -= z;
305 sz2 = iz/realsize[2];
306 sz2 *= sz2;
307 for ( yy=0; yy<y; yy++ ) {
308 iy = yy;
309 if ( yy > (y - 1)/2 ) iy -= y;
310 sy2 = iy/realsize[1];
311 sy2 *= sy2;
312 for ( xx=0; xx<x; xx++, i++ ) {
313 ix = xx;
314 if ( xx > (x - 1)/2 ) ix -= x;
315 sx2 = ix/realsize[0];
316 sx2 *= sx2;
317 s2 = sx2 + sy2 + sz2;
318 if ( s2 >= smin2 && s2 <= smax2 ) {
319 cv = (complex(i)).power();
320 sum += cv.real();
321 } else {
322 cv = 0;
323 }
324 set(i, cv);
325 }
326 }
327 }
328 if ( sum ) {
329 scale = sqrt(x*y*z)/sum;
330 // cout << "scale=" << scale << endl;
331 multiply(nn, scale);
332 }
333 image[nn].origin(0.0,0.0,0.0);
334 }
335
336 // cout << "backtransforming" << endl;
337
338 fft_back();
339
340 return 0;
341 }
342
363 Bimage* Bimage::cross_correlate(Bimage* p, double hires, double lores,
364 fft_plan planf, fft_plan planb)
365 {
366 if ( lores > 0 && hires > lores ) swap(hires, lores);
367
368 Bimage* pc = pack_two_in_complex(p);
369 if ( !pc ) return NULL;
370
371 // if ( hires < pc->sampling()[0] ) hires = pc->sampling()[0];
372
373 if ( verbose & VERB_FULL ) {
374 cout << "Cross-correlation:" << endl;
375 if ( lores > 0 || hires > 0 ) {
376 cout << "Resolution range: " << hires << " - ";
377 if ( lores > 0 ) cout << lores << " A" << endl;
378 else cout << "inf A" << endl;
379 } else
380 cout << "No resolution limits" << endl;
381 cout << endl;
382 }
383
384 pc->fft(planf, 0);
385
386 // pc->set(0, Complex<double>(0,0));
387
388 pc->combined_complex_product_implicit_mask(hires, lores);
389
390 pc->fft(planb, 0);
391
392 pc->complex_to_real();
393
394 long nn;
395 for ( nn=0; nn<pc->images(); nn++ )
396 pc->image[nn].origin(p->image[nn].origin() - image[nn].origin());
397
398 return pc;
399 }
400
419 Bimage* Bimage::cross_correlate(Bimage* p, double hires, double lores, Bimage* pmask)
420 {
421 if ( lores > 0 && hires > lores ) swap(hires, lores);
422
423 Bimage* pc = pack_two_in_complex(p);
424 if ( !pc ) return NULL;
425
426 // if ( hires < pc->sampling()[0] ) hires = pc->sampling()[0];
427
428 if ( verbose & VERB_FULL ) {
429 cout << "Cross-correlation:" << endl;
430 if ( lores > 0 || hires > 0 ) {
431 cout << "Resolution range: " << hires << " - ";
432 if ( lores > 0 ) cout << lores << " A" << endl;
433 else cout << "inf A" << endl;
434 } else
435 cout << "No resolution limits" << endl;
436 if ( pmask )
437 cout << "With a mask: " << pmask->file_name() << endl;
438 cout << endl;
439 }
440
441 pc->fft(FFTW_FORWARD, 0);
442
443 // pc->set(0, Complex<double>(0,0));
444
445 pc->combined_complex_product(hires, lores, pmask);
446
447 pc->fft(FFTW_BACKWARD, 0);
448
449 pc->complex_to_real();
450
451 long nn;
452 for ( nn=0; nn<pc->images(); nn++ )
453 pc->image[nn].origin(p->image[nn].origin() - image[nn].origin());
454
455 // write_img("pcc.mrc", pc, 0);
456
457 return pc;
458 }
459
470 double Bimage::correlation_coefficient(Vector3<double> shift)
471 {
472 long i;
473 Vector3<long> k;
474 double phi, cc(0);
475 Complex<double> cv;
476
477 shift = shift*TWOPI;
478 shift /= size();
479
480 for ( i=k[2]=0; k[2]<z; ++k[2] ) {
481 for ( k[1]=0; k[1]<y; ++k[1] ) {
482 for ( k[0]=0; k[0]<x; ++k[0], ++i ) {
483 phi = (shift * k).sum();
484 cv = complex(i);
485 cc += cv.real()*cos(phi) - cv.imag()*sin(phi);
486 // cout << k << tab << phi << endl;
487 }
488 }
489 }
490
491 return cc;
492 }
493
505 Vector3<double> Bimage::find_shift_in_transform(double shift_limit)
506 {
507 long i, nn(0);
508 double ds(1), cc(0), ccmax(0);
509 Vector3<double> sh, bestshift;
510 Vector3<long> smn, smx(shift_limit,shift_limit,shift_limit);
511 smx = smx.min(size()/2);
512 smn = -smx;
513 Vector3<long> size = smx - smn + 1;
514 cout << size << tab << smn << tab << smx << endl;
515
516 Bimage* pc = new Bimage(Double, TSimple, size, 1);
517
518 for ( i=0, sh[2]=smn[2]; sh[2]<=smx[2]; sh[2]+=ds ) {
519 for ( sh[1]=smn[1]; sh[1]<=smx[1]; sh[1]+=ds ) {
520 for ( sh[0]=smn[0]; sh[0]<=smx[0]; sh[0]+=ds, ++i ) {
521 cc = correlation_coefficient(sh);
522 if ( ccmax < cc ) {
523 ccmax = cc;
524 bestshift = sh;
525 cout << setprecision(4) << ds << tab << sh << tab << cc << endl;
526 }
527 pc->set(i, cc);
528 }
529 }
530 }
531
532 pc->origin(bestshift+size/2);
533 bestshift += pc->fit_peak();
534
535 image[nn].origin(bestshift);
536 image[nn].FOM(ccmax);
537
538 // write_img("cck.mrc", pc, 0);
539
540 delete pc;
541
542 return bestshift;
543 }
544
563 Bimage* Bimage::cross_correlate_fspace(Bimage* p, double hires, double lores, double shift_limit)
564 {
565 if ( lores > 0 && hires > lores ) swap(hires, lores);
566
567 Bimage* pc = pack_two_in_complex(p);
568 if ( !pc ) return NULL;
569
570 // if ( hires < pc->sampling()[0] ) hires = pc->sampling()[0];
571
572 if ( verbose & VERB_FULL ) {
573 cout << "Cross-correlation:" << endl;
574 if ( lores > 0 || hires > 0 ) {
575 cout << "Resolution range: " << hires << " - ";
576 if ( lores > 0 ) cout << lores << " A" << endl;
577 else cout << "inf A" << endl;
578 } else
579 cout << "No resolution limits" << endl;
580 // if ( pmask )
581 // cout << "With a mask: " << pmask->file_name() << endl;
582 cout << endl;
583 }
584
585 pc->fft(FFTW_FORWARD, 0);
586
587 // pc->set(0, Complex<double>(0,0));
588
589 pc->combined_complex_product(hires, lores, NULL);
590
591 Vector3<double> shift = pc->find_shift_in_transform(shift_limit);
592
593 long nn;
594 for ( nn=0; nn<pc->images(); nn++ )
595 pc->image[nn].origin(shift);
596
597 // write_img("pcc.mrc", pc, 0);
598
599 return pc;
600 }
601
602
603 Bimage* Bimage::cross_correlate(Bimage* p, double hires, double lores,
604 Bimage* pmask, fft_plan planf, fft_plan planb)
605 {
606 if ( lores > 0 && hires > lores ) swap(hires, lores);
607
608 Bimage* pc = pack_two_in_complex(p);
609 if ( !pc ) return NULL;
610
611 // if ( hires < pc->sampling()[0] ) hires = pc->sampling()[0];
612
613 if ( verbose & VERB_FULL ) {
614 cout << "Cross-correlation:" << endl;
615 if ( lores > 0 || hires > 0 ) {
616 cout << "Resolution range: " << hires << " - ";
617 if ( lores > 0 ) cout << lores << " A" << endl;
618 else cout << "inf A" << endl;
619 } else
620 cout << "No resolution limits" << endl;
621 if ( pmask )
622 cout << "With a mask: " << pmask->file_name() << endl;
623 cout << endl;
624 }
625
626 pc->fft(planf, 0);
627
628 // pc->set(0, Complex<double>(0,0));
629
630 pc->combined_complex_product(hires, lores, pmask);
631
632 pc->fft(planb, 0);
633
634 pc->complex_to_real();
635
636 long nn;
637 for ( nn=0; nn<pc->images(); nn++ )
638 pc->image[nn].origin(p->image[nn].origin() - image[nn].origin());
639
641
642 return pc;
643 }
644
670 Bimage* Bimage::cross_correlate_two_way(Bimage* p, double hires,
671 double lores, fft_plan planf, fft_plan planb)
672 {
673 if ( hires > lores ) swap(hires, lores);
674
675 Bimage* pc = pack_two_in_complex(p);
676 if ( !pc ) return NULL;
677
678 if ( hires < pc->sampling()[0] ) hires = pc->sampling()[0];
679
680 if ( verbose & VERB_FULL ) {
681 cout << "Two-way cross-correlation:" << endl;
682 cout << "Resolution range: " << hires << " - " << lores << " A" << endl;
683 cout << endl;
684 }
685
686 pc->fft(planf, 0);
687
688 Complex<double> cv;
689 pc->set(0, cv);
690
691 pc->complex_bandpass(hires, lores);
692
693 Bimage* pc2 = pc->unpack_combined_transform();
694
695 pc->complex_normalize();
696 pc2->complex_normalize();
697
698 Bimage* pc1 = pc->copy();
699
700 pc->complex_conjugate_product(pc2);
701 pc1->complex_product(pc2);
702
703 // write_img("pc.map", pc, 0);
704 // bexit(0);
705
706 delete pc2;
707
708 pc->fft(planb, 0);
709 pc1->fft(planb, 0);
710
711 pc->complex_to_real();
712 pc1->complex_to_real();
713
714 // cout << pc->maximum() << tab << pc1->maximum() << endl;
715
716 if ( pc1->maximum() > pc->maximum() ) {
717 delete pc;
718 pc = pc1;
719 pc->image->view_angle(M_PI);
720 } else {
721 delete pc1;
722 pc->image->view_angle(0);
723 }
724
725 pc->fourier_type(NoTransform);
726
727 long nn;
728 for ( nn=0; nn<pc->images(); nn++ )
729 pc->image[nn].origin(p->image[nn].origin() - image[nn].origin());
730
731 return pc;
732 }
733
751 Bimage* Bimage::cross_correlate_validate(Bimage* p, Bimage* pmask)
752 {
753 Bimage* pc = pack_two_in_complex(p);
754 if ( !pc ) return NULL;
755
756 if ( verbose & VERB_FULL ) {
757 cout << "Cross-correlation with validation:" << endl;
758 if ( pmask )
759 cout << "With a mask: " << pmask->file_name() << endl;
760 cout << endl;
761 }
762
763 pc->fft(FFTW_FORWARD, 0);
764
765 Complex<double> cv;
766 pc->set(0, cv);
767
768 long nn;
769 for ( nn=0; nn<pc->images(); nn++ )
770 pc->image[nn].origin(p->image[nn].origin() - image[nn].origin());
771
772 if ( pmask ) pc->complex_apply_dual_mask(pmask);
773
774 pc->combined_complex_product();
775 pc->next->combined_complex_product();
776
777 pc->fft(FFTW_BACKWARD, 0);
778 pc->next->fft(FFTW_BACKWARD, 0);
779
780 pc->complex_to_real();
781 pc->next->complex_to_real();
782
783 return pc;
784 }
785
786 /*
787 @brief Searches a 2D/3D density map for a template using a specific view.
788 @param *p the image.
789 @param *pref the template to be searched for.
790 @param view view.
791 @param hires high resolution limit.
792 @param lores low resolution limit.
793 @param search_radius radius for shift search.
794 @param *pmask mask for cross-correlation (ignored if NULL).
795 @param &cc the best correlation coefficient
796 @param planf FFT forward plan.
797 @param planb FFT backward plan.
798 @return Vector3<double> best shift to impose on the image.
799
800 The template is rotated to the view and cross-correlated to find
801 a set of high-scoring fits.
802 The views must be calculated externally to allow for custom sets.
803 **/
804 Vector3<double> Bimage::rotate_cross_correlate(Bimage* pref, View view,
805 double hires, double lores, double search_radius, Bimage* pmask,
806 double& cc, fft_plan planf, fft_plan planb)
807 {
808 Vector3<double> shift(-1e37,-1e37,-1e37);
809
810 if ( !check_if_same_size(pref) ) {
811 error_show("Bimage::rotate_cross_correlate", __FILE__, __LINE__);
812 return shift;
813 }
814
815 Matrix3 mat = view.matrix();
816 mat = mat.transpose();
817
818 Bimage* prot = pref->rotate(pref->size(), mat);
819
820 Bimage* pcc = cross_correlate(prot, hires, lores, pmask, planf, planb);
821
822 pcc->find_peak(search_radius, 0);
823
824 if ( verbose & VERB_DEBUG ) {
825 cout << "DEBUG Bimage::rotate_cross_correlate: found origin = " << pcc->image->origin() << endl;
826 cout << "DEBUG Bimage::rotate_cross_correlate: cc = " << pcc->image->FOM() << endl;
827 }
828
829 pcc->refine_peak();
830
831 // if ( verbose & VERB_DEBUG )
832 // cout << "DEBUG Bimage::rotate_cross_correlate: refined origin = " << pcc->image->origin() << endl;
833
834 shift = -pcc->image->origin();
835 cc = pcc->image->FOM();
836
837 delete prot;
838 delete pcc;
839
840 return shift;
841 }
842
843 /*
844 @brief Rotates a 2D reference image and cross-correlates with an image.
845 @param *pref reference 2D image.
846 @param angle rotation angle.
847 @param res_hi high resolution limit.
848 @param res_lo low resolution limit.
849 @param shift_limit maximum shift from nominal origin of box.
850 @param planf FFT forward plan.
851 @param planb FFT backward plan.
852 @return double correlation coefficient.
853
854 The reference image is first rotated by the given angle.
855 Two cross-correlations are done to account for a 180° ambiguity in
856 the angle when it is derived from a polar power spectrum.
857 The shift is then determined from the best cross-correlation map.
858 The image origin is written into the image structure.
859 The correlation coefficient return is the cross-correlation peak.
860 The input images must be equal-sized square 2D images.
861 **/
862 double Bimage::rotate_cross_correlate_two_way(Bimage* pref,
863 double angle, double res_hi, double res_lo, double shift_limit,
864 fft_plan planf, fft_plan planb)
865 {
866 // cout << pref->image->origin() << endl;
867
868 Bimage* prot = pref->rotate(pref->size(), fabs(angle));
869
870 Bimage* pcc = cross_correlate_two_way(prot, res_hi, res_lo, planf, planb);
871
872 delete prot;
873
874 pcc->origin(0.0, 0.0, 0.0);
875
876 pcc->find_peak(shift_limit, 0);
877
878 pcc->refine_peak();
879
880 if ( angle > 0 ) image->view_angle(angle + pcc->image->view_angle());
881 else image->view_angle(angle - pcc->image->view_angle());
882
883 // cout << pcc->image->origin() << tab << pcc->image->FOM() << endl;
884
885 if ( fabs(pcc->image->view_angle()) > M_PI_2 ) {
886 // image->origin(pref->image->origin() - pcc->image->origin());
887 origin(pref->image->origin() - pcc->image->origin());
888 } else {
889 // image->origin(pref->image->origin() + pcc->image->origin());
890 origin(pref->image->origin() + pcc->image->origin());
891 }
892
893 image->FOM(pcc->image->FOM());
894
895 delete pcc;
896
897 if ( verbose & VERB_DEBUG ) {
898 cout << "DEBUG Bimage::rotate_cross_correlate_two_way: fom=" << image->FOM() << endl;
899 cout << "DEBUG Bimage::rotate_cross_correlate_two_way: ori=" << image->origin() << endl;
900 }
901
902 return image->FOM();
903 }
904
905
932 int Bimage::find_shift(Bimage* pref, Bimage* pmask, double hires,
933 double lores, double radius, double sigma, int refine_flag)
934 {
935 if ( verbose & VERB_FULL ) {
936 if ( refine_flag )
937 cout << "Finding shift by cross-correlation and polynomial fitting" << endl << endl;
938 else
939 cout << "Finding shift by cross-correlation" << endl << endl;
940 }
941
942 Bimage* pc = cross_correlate(pref, hires, lores, pmask);
943 if ( !pc ) return -1;
944
945 if ( verbose & VERB_DEBUG )
946 write_img("cc.map", pc, 0);
947
948 long nn;
949 pc->find_peak(radius, sigma);
950
951 if ( refine_flag ) pc->refine_peak();
952
953 for ( nn=0; nn<pc->images(); nn++ ) {
954 image[nn].origin(pref->image[nn].origin() + pc->image[nn].origin());
955 image[nn].FOM(pc->image[nn].FOM());
956 }
957
958 if ( verbose & VERB_FULL ) {
959 cout << "Image\t ox\t oy\t oz\t CC" << endl;
960 for ( nn=0; nn<n; nn++ )
961 cout << nn+1 << tab << image[nn].origin()
962 << tab << image[nn].FOM() << endl;
963 cout << endl;
964 }
965
966 delete pc;
967
968 return 0;
969 }
970
971 Vector3<double> Bimage::find_shift(Bimage* pref, Bimage* pmask, double hires,
972 double lores, double radius, double sigma, int refine_flag, double& cc)
973 {
974 if ( verbose & VERB_FULL ) {
975 if ( refine_flag )
976 cout << "Finding shift by cross-correlation and polynomial fitting" << endl << endl;
977 else
978 cout << "Finding shift by cross-correlation" << endl << endl;
979 }
980
981 Vector3<double> shift;
982
983 Bimage* pc = cross_correlate(pref, hires, lores, pmask);
984 if ( !pc ) return shift;
985
986 if ( verbose & VERB_DEBUG )
987 write_img("cc.map", pc, 0);
988
989 pc->find_peak(radius, sigma);
990
991 if ( refine_flag ) pc->refine_peak();
992
993 shift = pc->image->origin();
994
995 cc = pc->image->FOM();
996
997 delete pc;
998
999 return shift;
1000 }
1001
1031 Vector3<double> Bimage::find_shift(Bimage* pref, double hires,
1032 double lores, double radius, double sigma, int refine_flag,
1033 fft_plan planf, fft_plan planb)
1034 {
1035 if ( verbose & VERB_FULL ) {
1036 if ( refine_flag )
1037 cout << "Finding shift by cross-correlation and polynomial fitting" << endl << endl;
1038 else
1039 cout << "Finding shift by cross-correlation" << endl << endl;
1040 }
1041
1042 Vector3<double> shift;
1043
1044 Bimage* pc = cross_correlate(pref, hires, lores, planf, planb);
1045 if ( !pc ) return shift;
1046
1047 if ( verbose & VERB_DEBUG )
1048 write_img("cc.map", pc, 0);
1049
1050 pc->find_peak(radius, sigma);
1051
1052 if ( refine_flag ) pc->refine_peak();
1053
1054 shift = pc->image->origin();
1055
1056 image->FOM(pc->image->FOM());
1057
1058 delete pc;
1059
1060 return shift;
1061 }
1062
1094 Vector3<double> Bimage::find_shift(Bimage* pref, Bimage* pmask, double hires,
1095 double lores, double radius, double sigma, int refine_flag,
1096 fft_plan planf, fft_plan planb, double& cc)
1097 {
1098 if ( verbose & VERB_FULL ) {
1099 if ( refine_flag )
1100 cout << "Finding shift by cross-correlation and polynomial fitting" << endl << endl;
1101 else
1102 cout << "Finding shift by cross-correlation" << endl << endl;
1103 }
1104
1105 Vector3<double> shift;
1106
1107 Bimage* pc = cross_correlate(pref, hires, lores, pmask, planf, planb);
1108 if ( !pc ) return shift;
1109
1110 if ( verbose & VERB_DEBUG )
1111 write_img("cc.map", pc, 0);
1112
1113 pc->find_peak(radius, sigma);
1114
1115 if ( refine_flag ) pc->refine_peak();
1116
1117 shift = pc->image->origin();
1118
1119 cc = pc->image->FOM();
1120
1121 delete pc;
1122
1123 return shift;
1124 }
1125
1142 Vector3<double> Bimage::find_shift(long nn, Bimage* pref, Bimage* pmask,
1143 double hi_res, double lo_res, double shift_limit,
1144 fft_plan planf, fft_plan planb)
1145 {
1146 double cc(0);
1147 Bimage* p1 = extract(nn);
1148
1149 Vector3<double> shift = p1->find_shift(pref, pmask, hi_res, lo_res, shift_limit, 0, 1, planf, planb, cc);
1150
1151 delete p1;
1152
1153 image[nn].origin(pref->image->origin()+shift);
1154
1155 image[nn].FOM(cc);
1156
1157 return shift;
1158 }
1159
1175 Bimage* Bimage::find_template(Bimage* ptemp, Bimage* pmask,
1176 double hires, double lores, int bin, fft_plan planf, fft_plan planb)
1177 {
1178 Bimage* pc = bin_copy(bin);
1179
1180 Bimage* pt = ptemp->bin_copy(bin);
1181 pt->pad(pc->size(), FILL_USER, 0);
1182
1183 Bimage* pm = NULL;
1184 if ( pmask ) pm = pmask->pad_copy(pc->size(), FILL_USER, 0);
1185
1186 Vector3<double> shift(pt->image->origin());
1187
1188 if ( verbose & VERB_PROCESS ) {
1189 // cout << "Number of templates: " << pt->images() << endl;
1190 cout << "Template origin: " << pt->image->origin() << endl;
1191 cout << "Template avg & std: " << pt->average() <<
1192 tab << pt->standard_deviation() << endl;
1193 }
1194
1195 Bimage* pcc = pc->cross_correlate(pt, hires, lores, pm, planf, planb);
1196
1197 delete pc;
1198 delete pt;
1199 delete pm;
1200
1201 pcc->shift_wrap(shift);
1202
1203 pcc->statistics();
1204
1205 return pcc;
1206 }
1207
1233 int Bimage::find_center(Bimage* pmask, double hires,
1234 double lores, double radius, double sigma, int refine_flag)
1235 {
1236 if ( verbose & VERB_FULL ) {
1237 if ( refine_flag )
1238 cout << "Finding center by cross-correlation and polynomial fitting" << endl << endl;
1239 else
1240 cout << "Finding center by cross-correlation" << endl << endl;
1241 }
1242
1243 Bimage* pc = copy();
1244
1245 pc->fft(FFTW_FORWARD, 0);
1246
1247 Complex<double> cv;
1248 pc->set(0, cv);
1249 if ( pmask ) pc->complex_apply_mask(pmask);
1250
1251 if ( hires > sampling()[0] ) pc->complex_bandpass(hires, lores);
1252
1253 pc->complex_normalize();
1254
1255 pc->complex_product(pc);
1256
1257 pc->fft(FFTW_BACKWARD, 0);
1258
1259 pc->complex_to_real();
1260
1261 if ( verbose & VERB_DEBUG )
1262 write_img("cc.map", pc, 0);
1263
1264 long nn;
1265
1266 pc->origin(0.0,0.0,0.0);
1267 pc->find_peak(radius, sigma);
1268
1269 if ( refine_flag ) pc->refine_peak();
1270
1271 for ( nn=0; nn<n; nn++ ) {
1272 image[nn].origin(pc->image[nn].origin()/2 + size()/2);
1273 image[nn].FOM(pc->image[nn].FOM());
1274 }
1275
1276 delete pc;
1277
1278 if ( verbose & VERB_FULL ) {
1279 cout << "Image\t ox\t oy\t oz\t CC" << endl;
1280 for ( nn=0; nn<n; nn++ )
1281 cout << nn+1 << tab << image[nn].origin()
1282 << tab << image[nn].FOM() << endl;
1283 cout << endl;
1284 }
1285
1286 return 0;
1287 }
1288
1306 Vector3<double> Bimage::rotate_find_shift(Matrix3 mat,
1307 double hires, double lores, double radius, double sigma,
1308 int refine_flag, fft_plan planf, fft_plan planb, double& cc)
1309 {
1310 if ( radius <= 0 ) radius = x/4;
1311
1312 Bimage* p = rotate(size(), mat);
1313
1314 Vector3<double> shift = find_shift(p, NULL, hires, lores, radius, sigma, 1, planf, planb, cc);
1315
1316 Vector3<double> origin;
1317 mat = Matrix3(1) - mat;
1318 mat = mat.singular_value_decomposition();
1319 origin = mat * shift + image->origin();
1320
1321 delete p;
1322
1323 return origin;
1324 }
1325
1338 int Bimage::find_peak(double radius, double sigma)
1339 {
1340 if ( !d.uc ) return -1;
1341
1342 // information();
1343 // write_img("cc.map", p, 0);
1344 // bexit(0);
1345
1346 if ( radius < 0 ) radius = 1e30;
1347 else if ( radius < 1 ) radius = 0.9;
1348 // if ( sigma < 1e-30 ) sigma = 2e-30;
1349
1350 if ( verbose & VERB_DEBUG )
1351 cout << "DEBUG Bimage::find_peak: radius=" << radius << endl;
1352
1353 long i, nn, xx, yy, zz;
1354 long xh(x/2), yh(y/2), zh(z/2);
1355 double x2, y2, z2, r;
1356 double value, maxval, fac(GOLDEN/sigma);
1357 Vector3<double> ori, peak;
1358
1359 if ( verbose & VERB_FULL ) {
1360 cout << "Finding the brightest voxel:" << endl;
1361 cout << "Radius & sigma: " << radius << " " << sigma << endl;
1362 cout << "Origin: " << image->origin() << endl;
1363 cout << "n\tx\ty\tz\tv" << endl;
1364 }
1365
1366 for ( i=nn=0; nn<n; nn++ ) {
1367 ori = image[nn].origin();
1368 if ( x <= 1 ) ori[0] = 0;
1369 if ( y <= 1 ) ori[1] = 0;
1370 if ( z <= 1 ) ori[2] = 0;
1371 if ( verbose & VERB_DEBUG )
1372 cout << "DEBUG Bimage::find_peak: ori=" << ori << endl;
1373 maxval = -1e37;
1374 peak = ori;
1375 for ( zz=0; zz<z; zz++ ) {
1376 z2 = ori[2] - zz;
1377 if ( z2 < -zh ) z2 += z;
1378 if ( z2 > zh ) z2 -= z;
1379 z2 *= z2;
1380 for ( yy=0; yy<y; yy++ ) {
1381 y2 = ori[1] - yy;
1382 if ( y2 < -yh ) y2 += y;
1383 if ( y2 > yh ) y2 -= y;
1384 y2 *= y2;
1385 for ( xx=0; xx<x; xx++, i++ ) {
1386 x2 = ori[0] - xx;
1387 if ( x2 < -xh ) x2 += x;
1388 if ( x2 > xh ) x2 -= x;
1389 x2 *= x2;
1390 r = sqrt(x2 + y2 + z2) - radius;
1391 value = (*this)[i];
1392 if ( sigma > 1e-30 ) value *= 1/(1 + exp(fac*r));
1393 if ( r <= 0 && maxval < value ) {
1394 maxval = value;
1395 peak = Vector3<double>(double(xx), double(yy), double(zz));
1396 }
1397 // if ( r < 0 )
1398 // cout << xx << tab << yy << tab << zz << tab << r << tab << value << tab << maxval << endl;
1399 }
1400 }
1401 }
1402 image[nn].FOM(maxval);
1403 image[nn].origin(peak);
1404 if ( verbose & VERB_DEBUG )
1405 cout << "DEBUG Bimage::find_peak: peak=" << peak << endl;
1406 if ( verbose & VERB_FULL )
1407 cout << nn+1 << tab << image[nn].origin() << tab << image[nn].FOM() << endl;
1408 }
1409 if ( verbose & VERB_FULL ) cout << endl;
1410
1411 return 0;
1412 }
1413
1423 Vector3<double> Bimage::fit_peak()
1424 {
1425 // cout << "origin = " << image->origin() << endl;
1426
1427 // write_img("cck.mrc", this, 0);
1428
1429 long i, j, k, nterm(9);
1430 long xx, yy, zz;
1431 double vm(get(0, image->origin()));
1432 Vector3<double> peak;
1433 Matrix a(nterm,nterm);
1434
1435 vector<double> b(nterm);
1436 vector<double> vec(nterm);
1437
1438 for ( i=0; i<image_size(); ++i ) add(i, -vm);
1439
1440 for ( j=0; j<nterm; ++j ) { // Clear the matrix and vector
1441 for ( k=0; k<nterm; ++k ) a[j][k] = 0;
1442 b[j] = 0;
1443 }
1444
1445 for ( i=zz=0; zz<z; ++zz ) {
1446 vec[2] = zz - image->origin()[2];
1447 vec[8] = vec[2]*vec[2];
1448 for ( yy=0; yy<y; ++yy ) {
1449 vec[1] = yy - image->origin()[1];
1450 vec[5] = vec[1]*vec[2];
1451 vec[7] = vec[1]*vec[1];
1452 for ( xx=0; xx<x; ++xx, ++i ) {
1453 vec[0] = xx - image->origin()[0];
1454 vec[3] = vec[0]*vec[1];
1455 vec[4] = vec[0]*vec[2];
1456 vec[6] = vec[0]*vec[0];
1457 for ( j=0; j<nterm; ++j ) b[j] += vec[j]*(*this)[i];
1458 for ( j=0; j<nterm; ++j )
1459 for ( k=0; k<=j; ++k ) a[j][k] += vec[j]*vec[k];
1460 }
1461 }
1462 }
1463
1464 for ( j=0; j<nterm; ++j )
1465 for ( k=j+1; k<nterm; ++k ) a[j][k] = a[k][j];
1466 for ( j=0; j<nterm; ++j )
1467 if ( fabs(a[j][j]) < 1e-37 ) a[j][j] = 1;
1468
1469 if ( verbose & VERB_DEBUG ) {
1470 cout << "DEBUG Bimage::fit_peak: Input matrix:" << endl;
1471 cout << a;
1472 cout << "DEBUG Bimage::fit_peak: Input vector:";
1473 for ( j=0; j<nterm; ++j ) cout << tab << b[j];
1474 cout << endl;
1475 }
1476
1477 // a.LU_decomposition(b);
1478 a.singular_value_decomposition(b);
1479
1480 if ( verbose & VERB_DEBUG ) {
1481 cout << "DEBUG Bimage::fit_peak: Ouput matrix:" << endl;
1482 cout << a;
1483 cout << "DEBUG Bimage::fit_peak: Coefficients: ";
1484 for ( j=0; j<nterm; ++j ) cout << tab << b[j];
1485 cout << endl;
1486 }
1487
1488 Matrix c(3,3);
1489 vector<double> d(3);
1490 for ( j=0; j<3; ++j ) d[j] = -b[j];
1491 c[0][0] = 2*b[6];
1492 c[0][1] = c[1][0] = b[3];
1493 c[0][2] = c[2][0] = b[4];
1494 c[1][1] = 2*b[7];
1495 c[1][2] = c[2][1] = b[5];
1496 c[2][2] = 2*b[8];
1497
1498 c.LU_decomposition(d);
1499 /*
1500 vector<double> ev = c.jacobi_rotation();
1501 c.eigen_sort(ev);
1502 cout << c << endl;
1503 for ( auto it = ev.begin(); it != ev.end(); ++it ) cout << tab << *it;
1504 cout << endl;
1505 */
1506 peak = Vector3<double>(d[0], d[1], d[2]);
1507
1508 double cc = vm + b[0]*d[0] + b[1]*d[1] + b[2]*d[2]
1509 + b[3]*d[0]*d[1] + b[4]*d[0]*d[2] + b[5]*d[1]*d[2]
1510 + b[6]*d[0]*d[0] + b[7]*d[1]*d[1] + b[8]*d[2]*d[2];
1511
1512 if ( verbose & VERB_DEBUG ) {
1513 cout << "DEBUG Bimage::fit_peak: Shift: ";
1514 for ( j=0; j<3; ++j ) cout << tab << d[j];
1515 cout << tab << cc << endl;
1516 }
1517
1518 image->FOM(cc);
1519
1520 /*
1521 double R(0);
1522 Bimage* pt = copy();
1523 for ( i=zz=0; zz<z; ++zz ) {
1524 d[3] = zz - image->origin()[2];
1525 for ( yy=0; yy<y; ++yy ) {
1526 d[2] = yy - image->origin()[1];
1527 for ( xx=0; xx<x; ++xx, ++i ) {
1528 d[1] = xx - image->origin()[0];
1529 cc = vm + b[0]*d[0] + b[1]*d[1] + b[2]*d[2]
1530 + b[3]*d[0]*d[1] + b[4]*d[0]*d[2] + b[5]*d[1]*d[2]
1531 + b[6]*d[0]*d[0] + b[7]*d[1]*d[1] + b[8]*d[2]*d[2];
1532 pt->set(i, cc);
1533 cc -= (*this)[i];
1534 R += cc*cc;
1535 }
1536 }
1537 }
1538 write_img("cckc.mrc", pt, 0);
1539 delete pt;
1540 R /= size().volume();
1541 cout << "R2 = " << R << endl;
1542 */
1543
1544 return peak;
1545 }
1546
1556 int Bimage::refine_peak()
1557 {
1558 if ( !d.uc ) return -1;
1559
1560 change_type(Float);
1561
1562 long nn, kernel_size(2);
1563 Vector3<long> ksize(2*kernel_size+1,2*kernel_size+1,2*kernel_size+1);
1564 Vector3<double> shift;
1565 Matrix3 mat(1);
1566
1567 if ( verbose & VERB_FULL ) {
1568 cout << "Finding the shift in each image" << endl;
1569 cout << "n\tx\ty\tz" << endl;
1570 }
1571
1572 for ( nn=0; nn<n; nn++ ) {
1573 // cout << "refine_peak: origin = " << image[nn].origin() << endl;
1574 Bimage* pc = extract_wrap(nn, image[nn].origin(), ksize, ksize/2, mat);
1575 shift = image[nn].origin() + pc->fit_peak();
1576 shift = vector3_origin_to_shift(shift, size());
1577 image[nn].origin(shift);
1578 image[nn].FOM(pc->image->FOM());
1579 delete pc;
1580 if ( verbose & VERB_FULL )
1581 cout << nn+1 << tab << shift << endl;
1582 }
1583 if ( verbose & VERB_FULL ) cout << endl;
1584
1585 return 0;
1586 }
1587
1601 Bimage* Bimage::find_peaks(long kernelsize)
1602 {
1603 if ( kernelsize < 3 ) kernelsize = 3;
1604 if ( kernelsize%2 == 0 ) kernelsize++;
1605
1606 long i, ii, ip, xx, yy, zz, nn, np(0);
1607 long xlo, xhi, ylo, yhi, zlo, zhi, kx, ky, kz, ix, iy, iz;
1608 double max;
1609 Vector3<long> hk(size()/2);
1610
1611 hk = hk.min(kernelsize/2);
1612
1613 if ( verbose & VERB_PROCESS )
1614 cout << "Finding peaks:" << endl;
1615
1616 if ( verbose & VERB_DEBUG )
1617 cout << "DEBUG Bimage::find_peaks: hk=" << hk << endl;
1618
1619 Bimage* pfom = new Bimage(Float, TSimple, size(), n);
1620
1621 for ( i=nn=0; nn<n; nn++ ) {
1622 for ( zz=0; zz<z; zz++ ) {
1623 zlo = zz - hk[2];
1624 zhi = zz + hk[2];
1625 for ( yy=0; yy<y; yy++ ) {
1626 ylo = yy - hk[1];
1627 yhi = yy + hk[1];
1628 for ( xx=0; xx<x; xx++, i++ ) {
1629 xlo = xx - hk[0];
1630 xhi = xx + hk[0];
1631 max = (*this)[i];
1632 if ( max > 0 ) {
1633 // Highest voxel search in the kernel
1634 ip = i;
1635 for ( kz=zlo; kz<=zhi; kz++ ) {
1636 iz = kz;
1637 if ( iz < 0 ) iz += z; // Periodic boundaries
1638 if ( iz >= z ) iz -= z;
1639 for ( ky=ylo; ky<=yhi; ky++ ) {
1640 iy = ky;
1641 if ( iy < 0 ) iy += y; // Periodic boundaries
1642 if ( iy >= y ) iy -= y;
1643 for ( kx=xlo; kx<=xhi; kx++ ) {
1644 ix = kx;
1645 if ( ix < 0 ) ix += x; // Periodic boundaries
1646 if ( ix >= x ) ix -= x;
1647 ii = index(ix, iy, iz, nn);
1648 if ( max < (*this)[ii] ) {
1649 max = (*this)[ii];
1650 ip = ii;
1651 }
1652 }
1653 }
1654 }
1655 if ( ip == i ) {
1656 pfom->set(i, max);
1657 np++;
1658 }
1659 }
1660 }
1661 }
1662 }
1663 }
1664
1665 if ( verbose & VERB_PROCESS )
1666 cout << "Peaks found: " << np << endl << endl;
1667
1668 pfom->statistics();
1669
1670 return pfom;
1671 }
1672
1690 Vector3<double>* Bimage::find_peaks(double excl_dist, long& ncoor,
1691 double& threshold_min, double& threshold_max, double pix_min, double pix_max)
1692 {
1693 if ( threshold_min < min ) threshold_min = min;
1694 if ( threshold_max > max ) threshold_max = max;
1695
1696 long rad = (long) excl_dist/2;
1697
1698 Vector3<long> tile(size());
1699 tile = tile.min(rad);
1700
1701 Vector3<long> start;
1702 start = start.max(tile);
1703 start = start.min(size()-1);
1704
1705 Vector3<long> end(size()-tile);
1706 end = end.max(1);
1707
1708 Vector3<double> ori(rad, rad, rad);
1709 ori = ori.min(size());
1710
1711 if ( verbose & VERB_PROCESS ) {
1712 cout << "Finding peaks in the cross-correlation map:" << endl;
1713 cout << "Exclusion distance: " << excl_dist << endl;
1714 cout << "Thresholds: " << threshold_min << " - " << threshold_max << endl;
1715 cout << "Tile size: " << tile << endl;
1716 cout << "Starting coordinates: " << start << endl;
1717 cout << "Ending coordinates: " << end << endl;
1718 }
1719
1720 long i, k, l, nc, xx, yy, zz, tx, ty, tz, nn;
1721 long nt = ((x-1)/tile[0]+1)*((y-1)/tile[1]+1)*((z-1)/tile[2]+1);
1722 double max(-1e30), v;
1723 Vector3<long>* ct = new Vector3<long>[nt];
1724 double* cc = new double[nt];
1725
1726 if ( verbose & VERB_FULL )
1727 cout << "Allocated number of coordinates: " << nt << endl;
1728
1729 for ( nn=0, nc=0; nn<n; nn++ ) {
1730 for ( zz=start[2]; zz<end[2]; zz+=rad ) {
1731 for ( yy=start[1]; yy<end[1]; yy+=rad ) {
1732 for ( xx=start[0]; xx<end[0]; xx+=rad ) {
1733 cc[nc] = -1e30;
1734 for ( tz=zz; tz<zz+tile[2] && tz<end[2]; tz++ ) {
1735 for ( ty=yy; ty<yy+tile[1] && ty<end[1]; ty++ ) {
1736 for ( tx=xx; tx<xx+tile[0] && tx<end[0]; tx++ ) {
1737 i = index(0,tx,ty,tz,nn);
1738 v = (*this)[i];
1739 if ( v > threshold_min && v <= threshold_max && cc[nc] < v ) {
1740 cc[nc] = v;
1741 ct[nc][0] = tx;
1742 ct[nc][1] = ty;
1743 ct[nc][2] = tz;
1744 }
1745 }
1746 }
1747 }
1748 if ( cc[nc] > threshold_min && cc[nc] <= threshold_max ) {
1749 // sigma = peak_sigma(nn, ct[nc], 15);
1750 // cout << nc << tab << cc[nc] << tab << ct[nc] << tab << sigma << endl;
1751 // if ( sigma > pix_min && sigma < pix_max ) {
1752 // if ( max < cc[nc] ) max = cc[nc];
1753 nc++;
1754 // }
1755 } else cc[nc] = -1e30;
1756 }
1757 }
1758 }
1759 }
1760
1761 if ( threshold_min < 1e-6 ) threshold_min = kmeans_threshold(nc, cc);
1762 image->FOM(threshold_min);
1763
1764 if ( verbose & VERB_PROCESS ) {
1765 cout << "Number of peaks found: " << nc << endl;
1766 cout << "Maximum CC: " << max << endl;
1767 cout << "Threshold: " << threshold_min << endl;
1768 }
1769
1770 for ( k=0, ncoor=0; k<nc; k++ ) if ( cc[k] > threshold_min ) {
1771 for ( l=k+1; l<nc; l++ ) if ( cc[l] > threshold_min ) {
1772 if ( (ct[k] - ct[l]).length() < excl_dist ) {
1773 if ( cc[k] > cc[l] ) cc[l] = threshold_min - 1;
1774 else cc[k] = threshold_min - 1;
1775 }
1776 }
1777 if ( cc[k] > threshold_min ) ++ncoor;
1778 }
1779
1780 Vector3<double>* coor = new Vector3<double>[ncoor];
1781
1782 for ( i=k=0; k<nc; k++ ) if ( cc[k] >= threshold_min )
1783 coor[i++] = ct[k];
1784
1785 delete[] ct;
1786 delete[] cc;
1787
1788 if ( verbose & VERB_PROCESS )
1789 cout << "Number of peaks found: " << ncoor << endl << endl;
1790
1791 return coor;
1792 }
1793
1812 double Bimage::ccmap_confidence(long nn)
1813 {
1814 long i, j, imax(0), imgsize(x*y*z);
1815 double v, vmax(min), vmax2(min), zavg(0), zstd(0), pval(0);
1816 Vector3<long> coor, cmax, cmax2;
1817
1818 for ( i=nn*imgsize, j=0; j<imgsize; i++, j++ ) {
1819 v = (*this)[i];
1820 if ( vmax < v ) {
1821 vmax2 = vmax;
1822 // imax2 = imax;
1823 vmax = v;
1824 imax = i;
1825 } else if ( vmax2 < v ) {
1826 coor = coordinates(i);
1827 cmax = coordinates(imax);
1828 if ( coor.distance(cmax) > 1 ) {
1829 vmax2 = v;
1830 // imax2 = i;
1831 }
1832 }
1833 v = fishers_z_transform(v);
1834 zavg += v;
1835 zstd += v*v;
1836 }
1837
1838 zavg /= imgsize;
1839 zstd = zstd/imgsize - zavg*zavg;
1840 if ( zstd <= 0 ) {
1841 zstd = 0;
1842 } else {
1843 zstd = sqrt(zstd);
1844 pval = erfc(0.5 * (fishers_z_transform(vmax) - fishers_z_transform(vmax2))/zstd);
1845 }
1846 if ( !isfinite(pval) ) pval = 0;
1847
1848 if ( verbose & VERB_DEBUG ) {
1849 cout << "DEBUG Bimage::ccmap_confidence: z std:\t" << zstd << tab << 1/(sqrt(imgsize - 3.0)) << endl;
1850 cout << "DEBUG Bimage::ccmap_confidence: maxima:\t" << vmax << tab << vmax2 << endl;
1851 }
1852
1853 return pval;
1854 }
1855
1868 double Bimage::peak_sigma(long nn, Vector3<long> coor, long kernel_size)
1869 {
1870 long xx, yy, zz, nv(0);
1871 double sigma(0), dx2, dy2, dz2, r2, v, vmax(get(nn,coor));
1872 Vector3<long> k(kernel_size, kernel_size, kernel_size);
1873 k = k.min(size());
1874 Vector3<long> h(k/2), cmin(coor-h), cmax(coor+h+1);
1875 cmin = cmin.max(0);
1876 cmax = cmax.min(size());
1877
1878 // cout << vmax << tab << cmin << tab << cmax << endl;
1879
1880 for ( zz=cmin[2]; zz<cmax[2]; zz++ ) {
1881 dz2 = coor[2] - zz;
1882 dz2 *= dz2;
1883 for ( yy=cmin[1]; yy<cmax[1]; yy++ ) {
1884 dy2 = coor[1] - yy;
1885 dy2 *= dy2;
1886 for ( xx=cmin[0]; xx<cmax[0]; xx++ ) {
1887 dx2 = coor[0] - xx;
1888 dx2 *= dx2;
1889 r2 = dx2 + dy2 + dz2;
1890 if ( r2 ) {
1891 v = get(nn, xx, yy, zz);
1892 // cout << r2 << tab << vmax << tab << v << tab << log(vmax/v) << endl;
1893 if ( v > 0 && v < vmax ) {
1894 sigma += r2/log(vmax/v);
1895 nv++;
1896 }
1897 }
1898 }
1899 }
1900 }
1901
1902 if ( nv ) sigma = sqrt(sigma/(2*nv));
1903 //cout << nv << tab << sigma << endl;
1904 //bexit(-1);
1905 return sigma;
1906 }
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1743
Bimage::refine_peak
int refine_peak()
Refines the position of a peak to sub-voxel resolution.
Definition: Bimage_correlate.cpp:1556
M_PI_2
#define M_PI_2
Definition: utilities.h:62
qsort_functions.h
Header file for utility functions for use in qsort calls.
verbose
int verbose
Bimage::unpack_combined_transform
Bimage * unpack_combined_transform()
Unpacks a complex transform obtained from two real images.
Definition: Bimage_complex.cpp:749
Bimage.h
Header file for image class.
Bimage::combined_complex_product
int combined_complex_product()
Calculates the complex conjugate product of a complex image resulting from combining and Fourier tran...
Definition: Bimage_complex.cpp:813
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
planb
fft_plan planb
Definition: bico.cpp:24
Bimage::add
void add(long j, double v)
Definition: Bimage.h:308
Bimage::image_size
long image_size()
Definition: Bimage.h:267
Bimage::fft
int fft()
Definition: Bimage.h:822
Bimage::fft_back
int fft_back()
Definition: Bimage.h:823
utilities.h
Header file for general utilities.
Bimage::complex_product
int complex_product(Bimage *p)
Calculates the complex product of two complex images.
Definition: Bimage_complex.cpp:430
Bimage::bin_copy
Bimage * bin_copy(long b)
Definition: Bimage.h:1284
Bimage::shift_wrap
int shift_wrap(Vector3< double > vec)
Shifts an image.
Definition: Bimage_transform.cpp:643
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
planf
fft_plan planf
Definition: bico.cpp:24
Bimage::index
long index(long nx, long ny) const
Definition: Bimage.h:383
Matrix3
Definition: Matrix3.h:17
GOLDEN
#define GOLDEN
Definition: utilities.h:81
Bimage::complex
Complex< double > complex(long j)
Returns a complex value at the given index.
Definition: Bimage.cpp:1005
TypePointer::uc
unsigned char * uc
Definition: Bimage.h:69
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
Bimage::file_name
void file_name(string s)
Definition: Bimage.h:230
Bimage::multiply
void multiply(long j, Complex< double > cv)
Definition: Bimage.h:312
Bimage::fit_peak
Vector3< double > fit_peak()
Fits an elliptic parabole to locate the position of the peak to sub-voxel resolution.
Definition: Bimage_correlate.cpp:1423
Bimage::peak_sigma
double peak_sigma(long nn, Vector3< long > coor, long kernel_size)
Calculates a sigma value for a cross-correlation peak.
Definition: Bimage_correlate.cpp:1868
Vector3::distance
double distance(const Vector3 &v)
Definition: Vector3.h:227
Bimage::Bimage
Bimage()
Initializes an image.
Definition: Bimage.cpp:44
Bimage::auto_correlate
int auto_correlate(double hires, double lores)
Calculates an autocorrelation map by Fast Fourier transformation.
Definition: Bimage_correlate.cpp:265
Bimage::correlate
double correlate(Bimage *p)
Calculates correlation coefficient between two images.
Definition: Bimage_correlate.cpp:36
Bimage::rotate_correlate
double rotate_correlate(Vector3< double > axis, double angle)
Rotates a copy of an image and correlates it with the original.
Definition: Bimage_correlate.cpp:195
vector3_origin_to_shift
Vector3< T1 > vector3_origin_to_shift(Vector3< T1 > origin, Vector3< T2 > size)
Definition: Vector3.h:667
kmeans_threshold
double kmeans_threshold(long n, double *v)
Finds a threshold that partitions an array into foreground and background clusters.
Definition: math_util.cpp:345
Matrix::singular_value_decomposition
double singular_value_decomposition()
Singular value decomposition of a matrix .
Definition: matrix.cpp:177
TSimple
Definition: Bimage.h:58
timer.h
Utilities for timing functions.
Float
Definition: utilities.h:157
Bimage::cross_correlate_validate
Bimage * cross_correlate_validate(Bimage *p, Bimage *pmask)
Calculates a masked cross-correlation map by Fast Fourier transformation.
Definition: Bimage_correlate.cpp:751
Vector3::max
Type max()
Definition: Vector3.h:175
Bimage
General image parameter class.
Definition: Bimage.h:163
Bimage::real_size
Vector3< double > real_size()
Definition: Bimage.h:487
Bimage::power
void power(double v)
Calculates the power of an image.
Definition: Bimage.cpp:3288
Bimage::complex_conjugate_product
int complex_conjugate_product(Bimage *p)
Calculates the product of a complex image with the conjugate of a second.
Definition: Bimage_complex.cpp:460
Matrix::LU_decomposition
double LU_decomposition()
Matrix inversion by LU decomposition.
Definition: matrix.cpp:78
M_PI
#define M_PI
Definition: utilities.h:59
isfinite
bool isfinite(complex< T > &value)
Bimage::extract
Bimage * extract(long nn)
Extracts one sub-image into new image structure.
Definition: Bimage_extract.cpp:21
Bimage::shift
int shift(Vector3< double > vec, int fill_type=0, double fill=0)
Shifts an image.
Definition: Bimage_transform.cpp:587
Bimage::maximum
double maximum()
Definition: Bimage.h:535
Double
Definition: utilities.h:158
Bimage::cross_correlate
Bimage * cross_correlate(Bimage *p, double hires, double lores, fft_plan planf, fft_plan planb)
Calculates a cross-correlation map by Fast Fourier transformation.
Definition: Bimage_correlate.cpp:363
Bimage::statistics
long statistics()
Calculates the statistics for an image.
Definition: Bimage_stats.cpp:22
Bimage::complex_apply_dual_mask
int complex_apply_dual_mask(Bimage *pmask)
Applies a dual mask to a complex image.
Definition: Bimage_complex.cpp:581
fft_plan
fftwf_plan fft_plan
Definition: fft.h:16
Bsub_image::FOM
double FOM()
Definition: Bimage.h:151
length
double length(vector< T > v)
Definition: Vector3.h:528
Bimage::find_peak
int find_peak(double radius=1e30, double sigma=0)
Finds the peak in an image to the nearest voxel.
Definition: Bimage_correlate.cpp:1338
Bimage::R_factor
double R_factor(Bimage *p)
Calculates an R factor between two images.
Definition: Bimage_correlate.cpp:218
Bimage::sum
void sum(long m, Bimage **p)
Sums an array of images with their FOM blocks.
Definition: Bimage_combine.cpp:23
write_img
int write_img(const char *filename, Bimage *p, int compression)
General driver function to write multiple image formats.
Definition: rwimg.cpp:280
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
Bimage::complex_apply_mask
int complex_apply_mask(Bimage *pmask)
Applies a mask to a complex image.
Definition: Bimage_complex.cpp:521
Bimage::rotate_cross_correlate_two_way
double rotate_cross_correlate_two_way(Bimage *pref, double angle, double res_hi, double res_lo, double shift_limit, fft_plan planf, fft_plan planb)
Definition: Bimage_correlate.cpp:862
FILL_USER
#define FILL_USER
Definition: utilities.h:172
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:127
Bimage::channels
long channels()
Definition: Bimage.h:371
Bsub_image::sampling
void sampling(double x, double y, double z)
Definition: Bimage.h:123
Bimage::cross_correlate_two_way
Bimage * cross_correlate_two_way(Bimage *p, double hires, double lores, fft_plan planf, fft_plan planb)
Calculates a cross-correlation map by Fast Fourier transformation.
Definition: Bimage_correlate.cpp:670
Bimage::find_peaks
Bimage * find_peaks(long kernelsize)
Finds peaks in a map with periodic boundaries.
Definition: Bimage_correlate.cpp:1601
Bimage::get
double get(long nn, long xx, long yy, long zz, long cc=0)
Returns the data value at the given coordinates.
Definition: Bimage.cpp:937
Bimage::standard_deviation
double standard_deviation()
Definition: Bimage.h:537
Bimage::view
void view(double vx, double vy, double vz, double va)
Definition: Bimage.h:589
Bimage::ccmap_confidence
double ccmap_confidence(long nn)
Calculates a confidence level to associate with a cross-correlation peak.
Definition: Bimage_correlate.cpp:1812
Bimage::set
void set(long j, double v)
Sets a single value at the given index.
Definition: Bimage.cpp:1096
Bimage::next
Bimage * next
Definition: Bimage.h:165
Bimage::complex_to_real
void complex_to_real()
The real part of a complex image is written to a simple image.
Definition: Bimage_complex.cpp:50
Complex
Definition: Complex.h:23
Bimage::find_center
int find_center(Bimage *pmask, double hires, double lores, double radius, double sigma, int refine_flag)
Finds the center of mass of an image by cross-correlation with its inverse.
Definition: Bimage_correlate.cpp:1233
Bimage::extract_wrap
Bimage * extract_wrap(long nn, Vector3< double > loc, Vector3< long > size, Vector3< double > origin, Matrix3 mat)
Extracts a region of one sub-image into new image structure with wrapping.
Definition: Bimage_extract.cpp:154
Matrix
Definition: Matrix.h:21
Bimage::find_template
Bimage * find_template(Bimage *ptemp, Bimage *pmask, double hires, double lores, int bin, fft_plan planf, fft_plan planb)
Finds one or more matches to a template.
Definition: Bimage_correlate.cpp:1175
Bimage::pad
int pad(long sz, int fill_type=0, double fill=0)
Pads an image to a new size with a given fill value.
Definition: Bimage_resize.cpp:351
Bimage::copy
Bimage * copy()
Copies the header information and data of an image into a new image structure.
Definition: Bimage.cpp:2695
Bimage::find_shift_in_transform
Vector3< double > find_shift_in_transform(double shift_limit)
Finds the shift by brute force backtransformation for selected shifts.
Definition: Bimage_correlate.cpp:505
Matrix3::transpose
Matrix3 transpose() const
Definition: Matrix3.h:268
matrix_linear.h
Header file for matrix functions.
Bimage::combined_complex_product_implicit_mask
int combined_complex_product_implicit_mask(double hires, double lores)
Calculates the complex conjugate product of a complex image resulting from combining and Fourier tran...
Definition: Bimage_complex.cpp:1085
Vector3< double >
Matrix3::singular_value_decomposition
Matrix3 singular_value_decomposition()
Definition: Matrix3.h:320
Complex::imag
Type imag()
Definition: Complex.h:102
fishers_z_transform
double fishers_z_transform(double value)
Calculates Fisher's z-transform.
Definition: math_util.cpp:249
Bimage::complex_normalize
double complex_normalize()
Normalizes the power in a complex image.
Definition: Bimage_complex.cpp:225
Bimage::correlation_coefficient
double correlation_coefficient(Vector3< double > shift)
Calculates a coefficient from a Fourier correlation transform given a shift.
Definition: Bimage_correlate.cpp:470
View
Definition: View.h:26
Bimage::complex_bandpass
int complex_bandpass(double hires, double lores)
Bandpasses a Fourier transform.
Definition: Bimage_complex.cpp:615
Bimage::rotate
int rotate()
Rotates an image using parameters defined in the image in place.
Definition: Bimage_transform.cpp:253
Vector3::min
Type min()
Definition: Vector3.h:169
Bimage::cross_correlate_fspace
Bimage * cross_correlate_fspace(Bimage *p, double hires, double lores, double shift_limit)
Calculates a cross-correlation map by Fast Fourier transformation.
Definition: Bimage_correlate.cpp:563
Bimage::find_shift
int find_shift(Bimage *pref, Bimage *pmask, double hires, double lores, double radius, double sigma, int refine_flag)
Calculates a cross-correlation map to find the shift for the pair of images.
Definition: Bimage_correlate.cpp:932
Bimage::average
double average(long cc, double xf, double yf, double zf, long nn, double iscale)
Averages in 3D when scaling is less than 1.
Definition: Bimage.cpp:1349
Bimage::check_if_same_size
bool check_if_same_size(Bimage *p)
Check if two images are the same size.
Definition: Bimage.cpp:536
rwimg.h
Header file for 2D and 3D image I/O.
Complex::real
Type real()
Definition: Complex.h:101
Bimage::images
long images()
Definition: Bimage.h:491
Bimage::coordinates
void coordinates(long i, long &nx, long &ny, long &nz)
Definition: Bimage.h:416
NoTransform
Definition: Bimage.h:40
Bimage::pack_two_in_complex
Bimage * pack_two_in_complex(Bimage *p)
Packs two real images into one complex image.
Definition: Bimage_complex.cpp:679
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
Bimage::pad_copy
Bimage * pad_copy(long sz, int fill_type=0, double fill=0)
Pads an image to a new size with a given fill value.
Definition: Bimage_resize.cpp:392
Bsub_image::view_angle
void view_angle(double d)
Definition: Bimage.h:147
TWOPI
#define TWOPI
Definition: utilities.h:68
Bimage::rotate_find_shift
Vector3< double > rotate_find_shift(Matrix3 mat, double hires, double lores, double radius, double sigma, int refine_flag, fft_plan planf, fft_plan planb, double &cc)
Rotates and find shift by cross-correlation.
Definition: Bimage_correlate.cpp:1306
Bimage::fourier_type
FourierType fourier_type()
Definition: Bimage.h:367
error_show
int error_show(string message, string file, int line)
Displays the error with file and line reference.
Definition: utilities.cpp:755
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
Bimage::rotate_cross_correlate
Vector3< double > rotate_cross_correlate(Bimage *pref, View view, double hires, double lores, double search_radius, Bimage *pmask, double &cc, fft_plan planf, fft_plan planb)
Definition: Bimage_correlate.cpp:804
Bimage::image
Bsub_image * image
Definition: Bimage.h:188
Bimage::origin
void origin(double ox, double oy, double oz)
Definition: Bimage.h:563
math_util.h
Header file for general utilities.