| Bsoft 2.0.5 Bernard's software package

Bimage_fspace.cpp
Go to the documentation of this file.
1
9 #include "Bimage.h"
10 #include "ctf.h"
11 #include "matrix_linear.h"
12 #include "utilities.h"
13
14 // Declaration of global variables
15 extern int verbose; // Level of output to the screen
16
25 long Bimage::fspace_maximum_radius(double resolution)
26 {
27 Vector3<double> u(image->sampling());
28 double rad_scale = u[0]*x;
29 if ( rad_scale < u[1]*y ) rad_scale = u[1]*y;
30 if ( rad_scale < u[2]*z ) rad_scale = u[2]*z;
31
32 long maxrad = x;
33 if ( maxrad < y ) maxrad = y;
34 if ( maxrad < z ) maxrad = z;
35 if ( resolution > 0.1 )
36 maxrad = (long) (rad_scale/resolution);
37 else
38 maxrad = (long) (maxrad/2.0);
39
40 return maxrad;
41 }
42
43
49 int Bimage::fspace_background()
50 {
51 long nn, xx, yy, zz, i, nb;
52 double bkg;
53 Vector3<long> bmin(0.4*x, 0.4*y, 0.4*z), bmax(0.6*x, 0.6*y, 0.6*z);
54 bmax = bmax.min(1);
55
56 if ( verbose )
57 cout << "Calculating the Fourier transform background" << endl;
58
59 for ( nn=0; nn<n; ++nn ) {
60 nb = 0;
61 bkg = 0;
62 for ( zz=bmin[2]; zz<bmax[2]; ++zz ) {
63 for ( yy=bmin[1]; yy<bmax[1]; ++yy ) {
64 for ( xx=bmin[0]; xx<bmax[0]; ++xx ) {
65 i = index(xx, yy, zz, nn);
66 bkg += complex(i).power();
67 nb++;
68 }
69 }
70 }
71 if ( nb ) bkg /= nb;
72 image[nn].background(bkg);
73 if ( verbose )
74 cout << nn << tab << scientific << bkg << endl;
75 }
76
77 return 0;
78 }
79
88 Complex<double> Bimage::fspace_interpolate(long img_num, Vector3<double> m, FSI_Kernel* kernel)
89 {
90 Complex<double> value(0,0);
91
92 if ( compoundtype != TComplex ) return value;
93
94 long xx, yy, zz, kx, ky, kz, mx, my, mz, jx, jy, jz;
95 long nx(kernel->width()), ny(kernel->width()), nz(kernel->width());
96 long ix = (long) floor(m[0]);
97 long iy = (long) floor(m[1]);
98 long iz = (long) floor(m[2]);
99 long ikx(kernel->half_width());
100 long iky(kernel->half_width());
101 long ikz(kernel->half_width());
102 double wyz;
103
104 if ( x > 1 ) {
105 ikx = ((long) ((m[0] - ix)*kernel->divisions() + 0.5))*kernel->width();
106 ix -= kernel->half_width();
107 } else nx = 1;
108
109 if ( y > 1 ) {
110 iky = ((long) ((m[1] - iy)*kernel->divisions() + 0.5))*kernel->width();
111 iy -= kernel->half_width();
112 } else ny = 1;
113
114 if ( z > 1 ) {
115 ikz = ((long) ((m[2] - iz)*kernel->divisions() + 0.5))*kernel->width();
116 iz -= kernel->half_width();
117 } else nz = 1;
118
119 for ( zz=0, kz=ikz, mz=iz; zz<nz; zz++, kz++, mz++ ) {
120 jz = mz;
121 while ( jz < 0 ) jz += z;
122 while ( jz >= z ) jz -= z;
123 jz = (img_num*z + jz)*y;
124 for ( yy=0, ky=iky, my=iy; yy<ny; yy++, ky++, my++ ) {
125 jy = my;
126 while ( jy < 0 ) jy += y;
127 while ( jy >= y ) jy -= y;
128 jy = (jz + jy)*x;
129 wyz = (*kernel)[ky]*(*kernel)[kz];
130 for ( xx=0, kx=ikx, mx=ix; xx<nx; xx++, kx++, mx++ ) {
131 jx = mx;
132 while ( jx < 0 ) jx += x;
133 while ( jx >= x ) jx -= x;
134 value += complex(jy + jx) * ((*kernel)[kx]*wyz);
135 }
136 }
137 }
138
139 if ( !value.is_finite() )
140 cerr << "Warning: Interpolated complex value not finite! (" << value << ")" << endl;
141
142 return value;
143 }
144
150 int Bimage::fspace_translate(Vector3<double> shift)
151 {
152 if ( verbose & VERB_PROCESS ) {
153 cout << "Translating in frequency space:" << endl;
154 cout << "Shift: " << shift << endl;
155 }
156
157 FourierType old_transform = fouriertype;
158
159 if ( fouriertype == NoTransform )
160 fft();
161
162 for ( long nn=0; nn<n; nn++ )
163 fspace_translate(nn, shift);
164
165 if ( old_transform == NoTransform )
166 fft_back();
167
168 return 0;
169 }
170
171
178 int Bimage::fspace_translate(long nn, Vector3<double> shift)
179 {
180 if ( verbose & VERB_PROCESS ) {
181 cout << "Translating in frequency space:" << endl;
182 cout << "Shift: " << shift << endl;
183 }
184
185 FourierType old_transform = fouriertype;
186
187 if ( fouriertype == NoTransform )
188 fft();
189
190 phase_shift(nn, shift);
191
192 if ( old_transform == NoTransform )
193 fft_back();
194
195 return 0;
196 }
197
205 int Bimage::fspace_resize(double scale, double res_hi, double res_lo)
206 {
207 Vector3<long> nusize = {x,y,z};
208 if ( x > 1 ) nusize[0] = (long) (x*scale);
209 if ( y > 1 ) nusize[1] = (long) (y*scale);
210 if ( z > 1 ) nusize[2] = (long) (z*scale);
211
212 Vector3<long> translate = {0,0,0};
213 Vector3<long> olsize = {x,y,z};
214 if ( x > 1 ) olsize[0] = (long) (nusize[0]/scale);
215 if ( y > 1 ) olsize[1] = (long) (nusize[1]/scale);
216 if ( z > 1 ) olsize[2] = (long) (nusize[2]/scale);
217
218 Vector3<double> error;
219 if ( x > 1 ) error[0] = olsize[0]*scale - nusize[0];
220 if ( y > 1 ) error[1] = olsize[1]*scale - nusize[1];
221 if ( z > 1 ) error[2] = olsize[2]*scale - nusize[2];
222
223 if ( verbose ) {
224 // if ( verbose & VERB_PROCESS ) {
225 cout << "Rescaling in frequency space:" << endl;
226 cout << "Scale: " << scale << endl;
227 cout << "New size: " << nusize << " voxels" << endl;
228 cout << "Error: " << error << " voxels" << endl << endl;
229 }
230
231 FourierType old_transform = fouriertype;
232
233 if ( fouriertype == NoTransform ) {
234 calculate_background();
235 resize(olsize, translate, FILL_BACKGROUND, 0);
236 fft();
237 }
238
239 change_transform_size(nusize);
240
241 if ( res_hi > 0 ) fspace_bandpass(res_hi, res_lo, 0);
242
243 if ( old_transform == NoTransform )
244 fft_back();
245
246 return 0;
247 }
248
256 Bimage* Bimage::fspace_resize(Bimage* pref)
257 {
258 if ( image->origin().length() < 1 ) origin(size()/2);
259
260 double r(pref->real_size()[0]/real_size()[0]);
261 long nx(x * r + 0.5);
262 // r = nx/(x * r);
263
264 Vector3<long> nusize(nx, nx, nx);
265 Vector3<double> scale(1,1,1), origin(image->origin());
266 // Vector3<double> translate(nusize/2 - image->origin());
267 // Vector3<double> translate(image->origin() * (nx * r/x - 1));
268 // Vector3<double> translate((nusize - size())/2);
269 Vector3<double> translate(nusize/2 - size()/2);
270 Matrix3 mat(1);
271
272 if ( verbose & VERB_RESULT ) {
273 cout << "Fitting " << file_name() << " to " << pref->file_name() << endl;
274 cout << "Intermediate size: " << nusize << endl;
275 cout << "Intermediate scale: " << scale << endl;
276 cout << "Intermediate translation: " << translate << endl << endl;
277 }
278
279 if ( verbose & VERB_PROCESS ) {
280 cout << "Comparing map " << file_name() << endl;
281 cout << "Map size: " << size() << endl;
282 cout << "Map origin: " << image->origin() << endl;
283 cout << "Map sampling: " << sampling() << endl;
284 cout << "Map real size: " << real_size() << endl << endl;
285 cout << "Reference: " << pref->file_name() << endl;
286 cout << "Reference size: " << pref->size() << endl;
287 cout << "Reference origin: " << pref->image->origin() << endl;
288 cout << "Reference sampling: " << pref->sampling() << endl;
289 cout << "Reference real size: " << pref->real_size() << endl << endl;
290 }
291
292 Bimage* pt = transform(nusize, scale, origin, translate, mat, FILL_BACKGROUND);
293
294 // write_img("pt.pif", pt);
295
296 if ( verbose & VERB_PROCESS ) {
297 cout << "Translate: " << translate << endl;
298 cout << "New map size: " << pt->size() << endl;
299 cout << "New map origin: " << pt->image->origin() << endl;
300 cout << "New map sampling: " << pt->sampling() << endl;
301 cout << "New map real size: " << pt->real_size() << endl << endl;
302 }
303
304 pt->fft();
305
306 pt->fspace_bandpass(2*pt->image->sampling()[0]); // Cut out the corners
307
308 Vector3<long> sz = {pref->sizeX(), pref->sizeY(), pref->sizeZ()};
309 pt->change_transform_size(sz);
310
311 pt->fft_back();
312
313 return pt;
314 }
315
326 int Bimage::fspace_amp_one()
327 {
328 if ( !d.uc ) {
329 cerr << "Error: No image data to process!" << endl << endl;
330 return -1;
331 }
332
333 FourierType old_transform = fouriertype;
334
335 if ( fouriertype == NoTransform )
336 fft();
337
338 if ( verbose & VERB_PROCESS )
339 cout << "Setting all amplitudes to one" << endl << endl;
340
341 long i, ds(x*y*z*n);
342 double amp;
343 Complex<double> cv;
344
345 for ( i=0; i<ds; i++ ) {
346 cv = complex(i);
347 if ( ( amp = cv.amp() ) )
348 set(i, cv/amp);
349 }
350
351 if ( old_transform == NoTransform )
352 fft_back();
353
354 statistics();
355
356 return 0;
357 }
358
371 int Bimage::fspace_amp_threshold(double threshold)
372 {
373 if ( !d.uc ) {
374 cerr << "Error: No image data to process!" << endl << endl;
375 return -1;
376 }
377
378 if ( threshold <= 0 ) return 0;
379
380 FourierType old_transform = fouriertype;
381
382 if ( fouriertype == NoTransform )
383 fft();
384
385 if ( verbose & VERB_PROCESS )
386 cout << "Applying an amplitude filter with a threshold of " << threshold << endl;
387
388 long i, ds(x*y*z*n);
389 long nk(0), nz(0);
390 double maxamp(0), zeroamp(1e-5*threshold);
391 double amp, ampkept(0), ampzeroed(0);
392 Complex<double> cv;
393
394 for ( i=0; i<ds; i++ ) {
395 amp = complex(i).amp();
396 if ( maxamp < amp ) maxamp = amp;
397 if ( amp < threshold ) {
398 ampzeroed += amp;
399 if ( amp > zeroamp ) nz++;
400 set(i, cv);
401 } else {
402 ampkept += amp;
403 nk++;
404 }
405 }
406
407 if ( verbose & VERB_PROCESS ) {
408 cout << "Number of amplitudes kept: " << nk << " (" << nk*100.0/ds << " %)" << endl;
409 cout << "Number of amplitudes zeroed: " << nz << " (" << nz*100.0/ds << " %)" << endl;
410 cout << "Maximum amplitude: " << maxamp << endl;
411 cout << "Amplitude kept sum: " << ampkept << endl;
412 cout << "Amplitude zeroed sum: " << ampzeroed << endl << endl;
413 }
414
415 if ( old_transform == NoTransform )
416 fft_back();
417
418 statistics();
419
420 return 0;
421 }
422
427 int Bimage::fspace_sqrt_amp()
428 {
429 if ( fouriertype != NoTransform ) {
430 cerr << "Error: File " << file_name() << " must be a real space map!" << endl;
431 return -1;
432 }
433
434 fft();
435
436 if ( verbose & VERB_PROCESS )
437 cout << "Changing the amplitudes to their square roots" << endl << endl;
438
439 long i, ds(x*y*z*n);
440 double d;
441 Complex<float> cv;
442
443 for ( i=0; i<ds; i++ ) {
444 cv = complex(i);
445 d = sqrt(cv.amp());
446 set(i, cv/d);
447 }
448
449 fft_back();
450
451 return 0;
452 }
453
458 int Bimage::fspace_square_amp()
459 {
460 if ( fouriertype != NoTransform ) {
461 cerr << "Error: File " << file_name() << " must be a real space map!" << endl;
462 return -1;
463 }
464
465 fft();
466
467 if ( verbose & VERB_PROCESS )
468 cout << "Changing the amplitudes to their squares" << endl << endl;
469
470 long i, ds(x*y*z*n);
471 double d;
472 Complex<float> cv;
473
474 for ( i=0; i<ds; i++ ) {
475 cv = complex(i);
476 d = cv.amp();
477 set(i, cv*d);
478 }
479
480 fft_back();
481
482 return 0;
483 }
484
499 int Bimage::fspace_bandpass(double res_hi, double res_lo, double width)
500 {
501 fft_plan planf = fft_setup(FFTW_FORWARD, 0);
502 fft_plan planb = fft_setup(FFTW_BACKWARD, 0);
503
504 fspace_bandpass(res_hi, res_lo, width, planf, planb);
505
506 fft_destroy_plan(planf);
507 fft_destroy_plan(planb);
508
509 return 0;
510 }
511
528 int Bimage::fspace_bandpass(double res_hi, double res_lo, double width, fft_plan planf, fft_plan planb)
529 {
530 if ( !d.uc ) {
531 cerr << "Error: No image data to process!" << endl << endl;
532 return -1;
533 }
534
535 if ( width < 1e-6 ) width = 1e-6;
536
537 FourierType old_transform = fouriertype;
538
539 if ( fouriertype == NoTransform )
540 fft(planf, 1);
541
542 if ( res_lo > 0 && res_hi > res_lo ) swap(res_hi, res_lo);
543 if ( res_hi == res_lo ) res_lo = 0;
544
545 if ( verbose & VERB_PROCESS ) {
546 cout << "Applying a bandpass filter:" << endl;
547 cout << "High and low resolution limits: " << res_hi << " - ";
548 if ( res_lo > 0 ) cout << res_lo << " A" << endl;
549 else cout << "inf A" << endl;
550 cout << "Gaussian edge: " << width << endl << endl;
551 }
552
553 long i, nn, xx, yy, zz;
554 double edge_lo, edge_hi, f, test_width(10*width), a(GOLDEN/fabs(width));
555 double s, sx2, sy2, sz2;
556 double shi = 1/res_hi;
557 double slo = (res_lo > 0)? 1/res_lo : 0;
558 Vector3<long> h((size()-1)/2);
559 Vector3<double> iscale(1/real_size());
560
561 for ( i=nn=0; nn<n; nn++ ) {
562 for ( zz=0; zz<z; zz++ ) {
563 sz2 = zz;
564 if ( zz > h[2] ) sz2 -= z;
565 sz2 *= iscale[2];
566 sz2 *= sz2;
567 for ( yy=0; yy<y; yy++ ) {
568 sy2 = yy;
569 if ( yy > h[1] ) sy2 -= y;
570 sy2 *= iscale[1];
571 sy2 *= sy2;
572 for ( xx=0; xx<x; xx++, i++ ) {
573 sx2 = xx;
574 if ( xx > h[0] ) sx2 -= x;
575 sx2 *= iscale[0];
576 sx2 *= sx2;
577 s = sqrt(sx2 + sy2 + sz2);
578 if ( slo - s > test_width ) edge_lo = 1e300;
579 else edge_lo = exp(a*(slo - s));
580 if ( s - shi > test_width ) edge_hi = 1e300;
581 else edge_hi = exp(a*(s - shi));
582 f = (edge_hi > edge_lo)? 1/(1 + edge_hi): 1/(1 + edge_lo);
583 set(i, complex(i) * f);
584 }
585 }
586 }
587 }
588
589 if ( old_transform == NoTransform ) {
590 fft(planb, 1);
591 complex_to_real();
592 fourier_type(NoTransform);
593 }
594
595 statistics();
596
597 return 0;
598 }
599
612 Bimage* Bimage::fspace_radial_power(double resolution)
613 {
614 if ( compoundtype != TComplex || fouriertype != Standard ) {
615 cerr << "Error: File " << file_name() << " must be a frequency space map!" << endl;
616 return NULL;
617 }
618
619 if ( resolution < 2*image->sampling()[0] ) resolution = 2*image->sampling()[0];
620
621 long i, j, nn, xx, yy, zz, iradius;
622 double radius, f, f1, rx, ry, rz, v;
623 double rad_scale(real_size().max());
624 Vector3<long> h((size()-1)/2);
625 Vector3<double> freq_scale(1/real_size());
626 long maxrad = (long) (2 + rad_scale/resolution);
627
628 Bimage* prad = new Bimage(Float, TSimple, maxrad, 1, 1, n);
629 prad->sampling(1.0/rad_scale, 1, 1);
630
631 vector<float> radstd(n*maxrad);
632 vector<float> num(maxrad);
633
634 if ( verbose & VERB_PROCESS ) {
635 cout << "Calculating a radial power spectrum:" << endl;
636 cout << "Radial scale: " << rad_scale << " A" << endl;
637 cout << "Radial step size: " << 1.0/rad_scale << " 1/A" << endl;
638 cout << "Resolution limit: " << resolution << " A" << endl;
639 cout << "Number of values: " << maxrad << endl << endl;
640 }
641
642 for ( nn=0; nn<n; nn++ ) {
643 for ( i=0; i<maxrad; i++ ) num[i] = 0;
644 for ( zz=0; zz<z; zz++ ) {
645 rz = zz;
646 if ( zz > h[2] ) rz -= z;
647 rz *= freq_scale[2];
648 rz *= rz;
649 for ( yy=0; yy<y; yy++ ) {
650 ry = yy;
651 if ( yy > h[1] ) ry -= y;
652 ry *= freq_scale[1];
653 ry *= ry;
654 for ( xx=0; xx<x; xx++ ) {
655 rx = xx;
656 if ( xx > h[0] ) rx -= x;
657 rx *= freq_scale[0];
658 rx *= rx;
659 radius = rad_scale*sqrt(rx + ry + rz);
660 iradius = (long) radius;
661 if ( iradius < maxrad ) {
662 f = radius - iradius;
663 f1 = 1 - f;
664 i = index(xx, yy, zz, nn);
665 num[iradius] += f1;
666 j = nn*maxrad + iradius;
667 v = complex(i).power();
668 prad->add(j, f1*v);
669 radstd[j] += f1*v*v;
670 iradius++;
671 if ( iradius < maxrad ) {
672 j++;
673 num[iradius] += f;
674 prad->add(j, f*v);
675 radstd[j] += f*v*v;
676 }
677 }
678 }
679 }
680 }
681 for ( i=0; i<maxrad; i++ ) {
682 if ( num[i] ) {
683 j = nn*maxrad + i;
684 prad->set(j, (*prad)[j]/num[i]);
685 radstd[j] = radstd[j]/num[i] - (*prad)[j]*(*prad)[j];
686 if ( radstd[j] > 0 )
687 radstd[j] = sqrt(radstd[j]);
688 else
689 radstd[j] = 0;
690 }
691 }
692 prad->image[nn].origin(0.0,0.0,0.0);
693 }
694
695 // delete[] num;
696
697 if ( verbose & VERB_DEBUG )
698 cout << "DEBUG Bimage::fspace_radial_power: Calculating statistics" << endl;
699
700 prad->statistics();
701
702 if ( verbose & VERB_FULL ) {
703 cout << endl << "Radial power spectrum:" << endl;
704 cout << "Radius";
705 for ( nn=0; nn<prad->images(); nn++ ) cout << " " << nn+1 << " (std)";
706 cout << endl;
707 for ( xx=0; xx<prad->sizeX(); xx++ ) {
708 cout << xx*prad->sampling()[0];
709 for ( nn=0, i=xx; nn<prad->images(); nn++, i+=prad->sizeX() )
710 cout << " " << (*prad)[i] << " " << radstd[i];
711 cout << endl;
712 }
713 }
714
715 // delete[] radstd;
716
717 return prad;
718 }
719
734 double* Bimage::fspace_radial(long nn, long maxrad, int flag)
735 {
736 if ( compoundtype != TComplex || fouriertype != Standard ) {
737 cerr << "Error: File " << file_name() << " must be a frequency space map!" << endl;
738 return NULL;
739 }
740
741 long i, xx, yy, zz, iradius, iradius2;
742 double radius, fraction, fraction2, v;
743 double rx, ry, rz;
744 Vector3<long> h((size()-1)/2);
745 double rad_scale(real_size().max());
746 Vector3<double> freq_scale(1.0/real_size());
747
748 double* num = new double[maxrad];
749 double* rps = new double[maxrad];
750
751 for ( i=0; i<maxrad; i++ ) num[i] = rps[i] = 0;
752
753 for ( zz=0; zz<z; zz++ ) {
754 rz = zz;
755 if ( zz > h[2] ) rz -= z;
756 rz *= freq_scale[2];
757 rz *= rz;
758 for ( yy=0; yy<y; yy++ ) {
759 ry = yy;
760 if ( yy > h[1] ) ry -= y;
761 ry *= freq_scale[1];
762 ry *= ry;
763 for ( xx=0; xx<x/2; xx++ ) {
764 rx = xx;
765 if ( xx > h[0] ) rx -= x;
766 rx *= freq_scale[0];
767 rx *= rx;
768 i = index(xx, yy, zz, nn);
769 radius = rad_scale*sqrt(rx + ry + rz);
770 iradius = (long) radius;
771 iradius2 = iradius + 1;
772 if ( iradius2 < maxrad ) {
773 fraction = radius - iradius;
774 fraction2 = 1.0 - fraction;
775 if ( flag )
776 v = complex(i).amp();
777 else
778 v = complex(i).power();
779 num[iradius] += fraction2;
780 num[iradius2] += fraction;
781 rps[iradius] += fraction2*v;
782 rps[iradius2] += fraction*v;
783 }
784 }
785 }
786 }
787
788 rps[0] = 0;
789 for ( i=0; i<maxrad; i++ )
790 if ( num[i] ) rps[i] /= num[i];
791
792 delete[] num;
793
794 return rps;
795 }
796
797 int Bimage::fspace_weigh(long maxrad, double* curve, int flag)
798 {
799 long i, nn;
800 double* rps;
801
802 FourierType old_transform = fouriertype;
803
804 if ( fouriertype == NoTransform )
805 fft();
806
807 for ( nn=0; nn<n; nn++ ) {
808 rps = fspace_radial(nn, maxrad, flag);
809 for ( i=0; i<maxrad; i++ )
810 if ( rps[i] ) rps[i] = curve[i]/rps[i];
811 fspace_scale(nn, maxrad, rps);
812 }
813
814 if ( old_transform == NoTransform )
815 fft_back();
816
817 return 0;
818 }
819
820 int Bimage::fspace_weigh(vector<double>& curve, int flag)
821 {
822 long maxrad(curve.size());
823 long i, nn;
824 double* rps;
825
826 FourierType old_transform = fouriertype;
827
828 if ( fouriertype == NoTransform )
829 fft();
830
831 for ( nn=0; nn<n; nn++ ) {
832 rps = fspace_radial(nn, maxrad, flag);
833 for ( i=0; i<maxrad; i++ )
834 if ( rps[i] ) rps[i] = curve[i]/rps[i];
835 fspace_scale(nn, maxrad, rps);
836 }
837
838 if ( old_transform == NoTransform )
839 fft_back();
840
841 return 0;
842 }
843
844 int Bimage::fspace_scale(long maxrad, double* scale, Bimage* pmask)
845 {
846 long nn;
847
848 FourierType old_transform = fouriertype;
849
850 if ( fouriertype == NoTransform )
851 fft();
852
853 for ( nn=0; nn<n; nn++ )
854 fspace_scale(nn, maxrad, scale, pmask);
855
856 if ( old_transform == NoTransform )
857 fft_back();
858
859 return 0;
860 }
861
862 int Bimage::fspace_scale(long nn, long maxrad, double* scale, Bimage* pmask)
863 {
864 int use_this;
865 long i, j, xx, yy, zz, iradius, iradius2;
866 double rx, ry, rz;
867 Vector3<long> h((size()-1)/2);
868 double radius, fraction, fraction2, w;
869 Complex<double> cv;
870
871 double rad_scale = real_size().max();
872 Vector3<double> freq_scale = 1.0/real_size();
873
874 for ( j=zz=0; zz<z; zz++ ) {
875 rz = zz;
876 if ( zz > h[2] ) rz -= z;
877 rz *= freq_scale[2];
878 rz *= rz;
879 for ( yy=0; yy<y; yy++ ) {
880 ry = yy;
881 if ( yy > h[1] ) ry -= y;
882 ry *= freq_scale[1];
883 ry *= ry;
884 for ( xx=0; xx<x; xx++, j++ ) {
885 rx = xx;
886 if ( xx > h[0] ) rx -= x;
887 rx *= freq_scale[0];
888 rx *= rx;
889 i = index(xx, yy, zz, nn);
890 radius = rad_scale*sqrt(rx + ry + rz);
891 iradius = (long) radius;
892 iradius2 = iradius + 1;
893 use_this = 1;
894 if ( pmask && (*pmask)[j] < 1 ) use_this = 0;
895 if ( iradius2 >= maxrad ) use_this = 0;
896 if ( use_this ) {
897 fraction = radius - iradius;
898 fraction2 = 1.0 - fraction;
899 w = scale[iradius]*fraction2 + scale[iradius2]*fraction;
900 set(i, complex(i) * w);
901 } else {
902 set(i, cv);
903 }
904 }
905 }
906 }
907
908 return 0;
909 }
910
911 int Bimage::fspace_scale(vector<double>& scale, Bimage* pmask)
912 {
913 long nn;
914
915 FourierType old_transform = fouriertype;
916
917 if ( fouriertype == NoTransform )
918 fft();
919
920 for ( nn=0; nn<n; nn++ )
921 fspace_scale(nn, scale, pmask);
922
923 if ( old_transform == NoTransform )
924 fft_back();
925
926 return 0;
927 }
928
929 int Bimage::fspace_scale(long nn, vector<double>& scale, Bimage* pmask)
930 {
931 long maxrad(scale.size());
932 int use_this;
933 long i, j, xx, yy, zz, iradius, iradius2;
934 double rx, ry, rz;
935 Vector3<long> h((size()-1)/2);
936 double radius, fraction, fraction2, w;
937 Complex<double> cv;
938
939 double rad_scale = real_size().max();
940 Vector3<double> freq_scale = 1.0/real_size();
941
942 for ( j=zz=0; zz<z; zz++ ) {
943 rz = zz;
944 if ( zz > h[2] ) rz -= z;
945 rz *= freq_scale[2];
946 rz *= rz;
947 for ( yy=0; yy<y; yy++ ) {
948 ry = yy;
949 if ( yy > h[1] ) ry -= y;
950 ry *= freq_scale[1];
951 ry *= ry;
952 for ( xx=0; xx<x; xx++, j++ ) {
953 rx = xx;
954 if ( xx > h[0] ) rx -= x;
955 rx *= freq_scale[0];
956 rx *= rx;
957 i = index(xx, yy, zz, nn);
958 radius = rad_scale*sqrt(rx + ry + rz);
959 iradius = (long) radius;
960 iradius2 = iradius + 1;
961 use_this = 1;
962 if ( pmask && (*pmask)[j] < 1 ) use_this = 0;
963 if ( iradius2 >= maxrad ) use_this = 0;
964 if ( use_this ) {
965 fraction = radius - iradius;
966 fraction2 = 1.0 - fraction;
967 w = scale[iradius]*fraction2 + scale[iradius2]*fraction;
968 set(i, complex(i) * w);
969 } else {
970 set(i, cv);
971 }
972 }
973 }
974 }
975
976 return 0;
977 }
978
996 double Bimage::fspace_fit_B_factor(double res_hi)
997 {
998 if ( !d.uc ) {
999 cerr << "Error: Cannot estimate the B-factor - the data block is empty!" << endl << endl;
1000 return -1;
1001 }
1002
1003 if ( res_hi < 2*image->sampling()[0] ) res_hi = 2*image->sampling()[0];
1004
1005 if ( verbose & VERB_PROCESS ) {
1006 cout << "B-factor estimation:" << endl;
1007 cout << "High resolution limit: " << res_hi << endl;
1008 }
1009
1010 if ( compoundtype != TComplex ) fft();
1011
1012 Bimage* prps = fspace_radial_power(res_hi);
1013
1014 long i;
1015 double realsize(real_size()[0]);
1016 double frac_res2(1.0/(realsize));
1017 frac_res2 *= frac_res2;
1018 double res_lo(200);
1019 long minrad((long) (realsize/res_lo));
1020 long maxrad((long) (realsize/res_hi));
1021 double scat, logScale, Bfactor(-1);
1022
1023 if ( verbose & VERB_DEBUG )
1024 cout << "DEBUG Bimage::fspace_fit_B_factor: minrad=" << minrad << " maxrad=" << maxrad << endl;
1025
1026 double* s2 = new double[maxrad];
1027 double* logF = new double[maxrad];
1028
1029 for ( i=0; i<maxrad; i++ ) {
1030 s2[i] = i*i*frac_res2;
1031 scat = 1.494*exp(-23.22*s2[i]) + 0.937*exp(-3.79*s2[i]);
1032 logF[i] = 4*(log(scat) - log((*prps)[i]));
1033 if ( verbose & VERB_FULL )
1034 cout << i << tab << sqrt(s2[i]) << tab << 1/sqrt(s2[i]) << tab << (*prps)[i] << tab << scat << endl;
1035 }
1036
1037 double CI = linear_least_squares(minrad, maxrad, s2, logF, logScale, Bfactor);
1038
1039 if ( verbose & VERB_PROCESS ) {
1040 cout << "B-factor: " << Bfactor << endl;
1041 cout << "Correlation index: " << CI << endl << endl;
1042 } else if ( verbose & VERB_LABEL ) {
1043 cout << "B-factor: " << Bfactor << endl << endl;
1044 }
1045
1046 delete[] s2;
1047 delete[] logF;
1048 delete prps;
1049
1050 return Bfactor;
1051 }
1052
1064 int Bimage::fspace_weigh_ramp(double resolution, fft_plan planf, fft_plan planb)
1065 {
1066 if ( resolution < 2*image->sampling()[0] ) resolution = 2*image->sampling()[0];
1067
1068 fft(planf, 1);
1069
1070 long i, xx, yy, zz, nzero(0), nuse(0);
1071 Vector3<long> h(size()/2);
1072 Vector3<long> k;
1073 Vector3<double> s;
1074 double s2max(1.0/(resolution*resolution)), weight(0), s2;
1075 Vector3<double> realsize(real_size());
1076
1077 if ( verbose & VERB_PROCESS )
1078 cout << "Filtering with a ramp to a resolution of " << resolution << " A" << endl;
1079
1080 for ( i=zz=0; zz<z; zz++ ) {
1081 k[2] = (zz>h[2])? z - zz: zz;
1082 s[2] = k[2]/realsize[2];
1083 for ( yy=0; yy<y; yy++ ) {
1084 k[1] = (yy>h[1])? y - yy: yy;
1085 s[1] = k[1]/realsize[1];
1086 for ( xx=0; xx<x; xx++, i++ ) {
1087 k[0] = (xx>h[1])? x - xx: xx;
1088 s[0] = k[0]/realsize[0];
1089 s2 = s.length2();
1090 if ( s2 > s2max ) {
1091 weight = 0;
1092 nzero++;
1093 } else {
1094 weight = sqrt(s2);
1095 nuse++;
1096 }
1097 set(i, complex(i) * weight);
1098 }
1099 }
1100 }
1101
1102 if ( verbose & VERB_FULL )
1103 cout << "Weighed fractions: zeroed=" << nzero*1.0/i << " used=" << nuse*1.0/i << endl << endl;
1104
1105 fft(planb, 1);
1106
1107 complex_to_real();
1108
1109 statistics();
1110
1111 return 0;
1112 }
1113
1126 int Bimage::fspace_weigh_ramp(double resolution, double axis, fft_plan planf, fft_plan planb)
1127 {
1128 if ( resolution < 2*image->sampling()[0] ) resolution = 2*image->sampling()[0];
1129
1130 fft(planf, 1);
1131
1132 long i, xx, yy, zz, nzero(0), nuse(0);
1133 Vector3<long> h(size()/2);
1134 Vector3<long> k;
1135 Vector3<double> s, a(cos(axis), sin(axis), 0);
1136 double s2max(1.0/(resolution*resolution)), weight(0), s2;
1137 Vector3<double> realsize(real_size());
1138
1139 if ( verbose & VERB_PROCESS )
1140 cout << "Filtering with a ramp to a resolution of " << resolution << " A" << endl;
1141
1142 for ( i=zz=0; zz<z; zz++ ) {
1143 k[2] = (zz>h[2])? z - zz: zz;
1144 for ( yy=0; yy<y; yy++ ) {
1145 k[1] = (yy>h[1])? y - yy: yy;
1146 s[1] = k[1]/realsize[1];
1147 for ( xx=0; xx<x; xx++, i++ ) {
1148 k[0] = (xx>h[1])? x - xx: xx;
1149 s[0] = k[0]/realsize[0];
1150 s2 = s.length2();
1151 if ( s2 > s2max ) {
1152 weight = 0;
1153 nzero++;
1154 } else {
1155 weight = sqrt(s2)*sin(axis-atan2(s[1],s[0]));
1156 nuse++;
1157 }
1158 set(i, complex(i) * weight);
1159 }
1160 }
1161 }
1162
1163 if ( verbose & VERB_FULL )
1164 cout << "Weighed fractions: zeroed=" << nzero*1.0/i << " used=" << nuse*1.0/i << endl << endl;
1165
1166 fft(planb, 1);
1167
1168 complex_to_real();
1169
1170 statistics();
1171
1172 return 0;
1173 }
1174
1185 int Bimage::fspace_weigh_B_factor(double B, double resolution)
1186 {
1187 check_resolution(resolution);
1188
1189 // The radius scaling is set to a value consistent with one pixel width
1190 // in reciprocal space for the longest dimension.
1191 double rad_scale = real_size().max();
1192
1193 // maxrad is the main limit for the length of all the arrays,
1194 // and is derived from the resolution set in the transform
1195 long maxrad = (long) (2 + rad_scale/resolution);
1196
1197 if ( verbose ) {
1198 cout << "Weighing amplitudes with a B factor:" << endl;
1199 cout << "B factor: " << B << endl;
1200 cout << "Resolution: " << resolution << " A (" << maxrad << " pixels)" << endl << endl;
1201 }
1202
1203 long i;
1204 vector<double> gcurve(maxrad);
1205 double s2, fac(-B/4);
1206
1207 for ( i=0; i<maxrad; i++ ) {
1208 s2 = i/rad_scale;
1209 s2 *= s2;
1210 gcurve[i] = exp(fac*s2);
1211 }
1212
1213 fspace_scale(gcurve);
1214
1215 return 0;
1216 }
1217
1228 int Bimage::fspace_weigh_C_curve(double resolution)
1229 {
1230 check_resolution(resolution);
1231
1232 // The radius scaling is set to a value consistent with one pixel width
1233 // in reciprocal space for the longest dimension.
1234 double rad_scale = real_size().max();
1235
1236 // maxrad is the main limit for the length of all the arrays,
1237 // and is derived from the resolution set in the transform
1238 long maxrad = (long) (2 + rad_scale/resolution);
1239
1240 if ( verbose ) {
1241 cout << "Weighing amplitudes with a C cross-section:" << endl;
1242 cout << "Resolution: " << resolution << " A (" << maxrad << " pixels)" << endl << endl;
1243 }
1244
1245 vector<double> ccurve = C_curve(maxrad, 1/rad_scale);
1246
1247 fspace_weigh(ccurve, 1);
1248
1249 return 0;
1250 }
1251
1263 int Bimage::fspace_weigh_LoG(double resolution, double sigma)
1264 {
1265 check_resolution(resolution);
1266
1267 // The radius scaling is set to a value consistent with one pixel width
1268 // in reciprocal space for the longest dimension.
1269 double rad_scale = real_size().max();
1270
1271 // maxrad is the main limit for the length of all the arrays,
1272 // and is derived from the resolution set in the transform
1273 long maxrad = (long) (2 + rad_scale/resolution);
1274
1275 if ( verbose ) {
1276 cout << "Weighing amplitudes with a Laplacian-of-Gaussian function:" << endl;
1277 cout << "Sigma: " << sigma << endl;
1278 cout << "Resolution: " << resolution << " A (" << maxrad << " pixels)" << endl << endl;
1279 }
1280
1281 long i;
1282 double s2, freq_step(1/rad_scale), c1(-TWOPI*TWOPI), c2(-2*M_PI*M_PI*sigma*sigma);
1283 double* curve = new double[maxrad];
1284
1285 for ( i=0; i<maxrad; i++ ) {
1286 s2 = i*freq_step;
1287 s2 *= s2;
1288 curve[i] = c1*s2*exp(c2*s2);
1289 }
1290
1291 fspace_weigh(maxrad, curve, 1);
1292
1293 delete[] curve;
1294
1295 return 0;
1296 }
1297
1310 int Bimage::fspace_weigh_RPS_curve(Bplot* plot, double resolution)
1311 {
1312 check_resolution(resolution);
1313
1314 // The radius scaling is set to a value consistent with one pixel width
1315 // in reciprocal space for the longest dimension.
1316 double rad_scale = real_size().max();
1317 double scale = 1/((*plot)[1] * rad_scale);
1318
1319 // maxrad is the main limit for the length of all the arrays,
1320 // and is derived from the resolution set in the transform
1321 long maxrad = (long) (2 + rad_scale/resolution);
1322
1323 if ( verbose ) {
1324 cout << "Weighing amplitudes with an RPS curve:" << endl;
1325 cout << "Resolution: " << resolution << " A (" << maxrad << " pixels)" << endl << endl;
1326 }
1327
1328 if ( verbose & VERB_DEBUG ) {
1329 cout << "rad_scale=" << rad_scale << endl;
1330 cout << "(*plot)[1]=" << (*plot)[1] << endl;
1331 cout << "scale=" << scale << endl;
1332 }
1333
1334 long i, j;
1335 double s;
1336 vector<double> rps(maxrad);
1337
1338 for ( i=plot->rows(); i<2*plot->rows(); ++i ) (*plot)[i] = sqrt((*plot)[i]);
1339
1340 for ( i=0; i<maxrad; ++i ) {
1341 s = scale*i;
1342 j = long(s);
1343 s -= j;
1344 j += plot->rows();
1345 rps[i] = (1-s)*(*plot)[j] + s*(*plot)[j+1];
1346 if ( verbose & VERB_DEBUG )
1347 cout << i << tab << j-plot->rows() << tab << i/rad_scale << tab << (j-plot->rows())*(*plot)[1] << tab << rps[i] << endl;
1348 }
1349
1350 fspace_weigh(rps, 1);
1351
1352 return 0;
1353 }
1354
1367 int Bimage::fspace_weigh_FSC_curve(Bplot* plot, double resolution)
1368 {
1369 check_resolution(resolution);
1370
1371 // The radius scaling is set to a value consistent with one pixel width
1372 // in reciprocal space for the longest dimension.
1373 double rad_scale = real_size().max();
1374
1375 // maxrad is the main limit for the length of all the arrays,
1376 // and is derived from the resolution set in the transform
1377 long maxrad = (long) (2 + rad_scale/resolution);
1378 if ( maxrad > plot->rows() ) maxrad = plot->rows();
1379
1380 if ( verbose ) {
1381 cout << "Weighing amplitudes with an FSC curve:" << endl;
1382 cout << "Resolution: " << resolution << " A (" << maxrad << " pixels)" << endl << endl;
1383 }
1384
1385 long i, j;
1386 double* fsc = new double[maxrad];
1387
1388 for ( i=0, j=plot->rows(); i<maxrad; i++, j++ )
1389 fsc[i] = sqrt((*plot)[j]);
1390
1391 fspace_weigh(maxrad, fsc, 1);
1392
1393 delete[] fsc;
1394
1395 return 0;
1396 }
1397
1398 int Bimage::fspace_weigh_dose(long nn, double dose_per_frame, vector<double> critdose)
1399 {
1400 long maxrad(critdose.size());
1401 long i;
1402 double dose(0);
1403
1404 if ( dose_per_frame > 1e-3 )
1405 for ( i=0; i<=nn; ++i ) dose += dose_per_frame;
1406 else
1407 for ( i=0; i<=nn; ++i ) dose += image->average()/image->sampling().volume();
1408
1409 if ( dose < 1e-3 ) {
1410 cerr << "Error: The dose is too low! (" << dose << ")" << endl;
1411 return -1;
1412 }
1413
1414 vector<double> scale(maxrad);
1415
1416 for ( i=0; i<maxrad; ++i )
1417 scale[i] = exp(-dose/critdose[i]);
1418
1419 fspace_scale(nn, scale);
1420
1421 return 0;
1422 }
1423
1433 int Bimage::fspace_weigh_dose(double dose_per_frame)
1434 {
1435 // maxrad is the main limit for the length of all the arrays,
1436 // and is derived from the resolution set in the transform
1437 long maxrad = (long) (size().length()/2+2);
1438
1439 long i;
1440 double s, ds(1.0/(real_size()[0])), a(0.245), b(-1.665), c(2.81);
1441
1442 if ( verbose ) {
1443 cout << "Weighing amplitudes with the accumulated dose:" << endl;
1444 cout << "Dose per frame: " << dose_per_frame << " e/Å2" << endl;
1445 cout << "Critical dose: " << a << "*s^" << b << " + " << c << " e/A2" << endl << endl;
1446 }
1447
1448 vector<double> critdose(maxrad);
1449
1450 for ( i=0, s=0; i<maxrad; ++i, s+=ds )
1451 critdose[i] = 2*(a*pow(s, b) + c);
1452
1453 FourierType old_transform = fouriertype;
1454
1455 if ( fouriertype == NoTransform )
1456 fft();
1457
1458 #ifdef HAVE_GCD
1459 dispatch_apply(n, dispatch_get_global_queue(0, 0), ^(size_t nn){
1460 fspace_weigh_dose(nn, dose_per_frame, critdose);
1461 });
1462 #else
1463 #pragma omp parallel for
1464 for ( long nn=0; nn<n; ++nn )
1465 fspace_weigh_dose(nn, dose_per_frame, critdose);
1466 #endif
1467
1468 if ( old_transform == NoTransform )
1469 fft_back();
1470
1471 statistics();
1472
1473 return 0;
1474 }
1475
1476
1490 int Bimage::fspace_weigh(Bimage* pref, Bimage* pmask, double resolution)
1491 {
1492 if ( pmask ) pmask->change_type(UCharacter);
1493
1494 check_resolution(resolution);
1495
1496 // The radius scaling is set to a value consistent with one pixel width
1497 // in reciprocal space for the longest dimension.
1498 double rad_scale = real_size().max();
1499
1500 // maxrad is the main limit for the length of all the arrays,
1501 // and is derived from the resolution set in the transform
1502 long maxrad = (long) (2 + rad_scale/resolution);
1503
1504 if ( verbose ) {
1505 cout << "Weighing amplitudes:" << endl;
1506 cout << "Reference map: " << pref->file_name() << endl;
1507 cout << "Resolution: " << resolution << " A (" << maxrad << " pixels)" << endl << endl;
1508 }
1509
1510 long i, nn;
1511 double* rps;
1512
1513 if ( pref->compound_type() == TSimple && pref->fourier_type() == NoTransform )
1514 pref->fft();
1515
1516 double* ref = pref->fspace_radial(0, maxrad, 1);
1517
1518 if ( compoundtype == TSimple && fouriertype == NoTransform )
1519 fft();
1520
1521 for ( nn=0; nn<n; nn++ ) {
1522 rps = fspace_radial(nn, maxrad, 1);
1523 for ( i=0; i<maxrad; i++ )
1524 if ( rps[i] ) rps[i] = ref[i]/rps[i];
1525 fspace_scale(nn, maxrad, rps, pmask);
1526 }
1527
1528 fft_back();
1529
1530 return 0;
1531 }
1532
1533
1539 int Bimage::fspace_normalize()
1540 {
1541 if ( fouriertype != Standard ) {
1542 cerr << "Error: File " << file_name() << " must be a Fourier transform!" << endl;
1543 return -1;
1544 }
1545
1546 complex_power();
1547
1548 long nn, i, j, ds(x*y*z);
1549 double scale;
1550
1551 for ( nn=i=0; nn<n; ++nn ) {
1552 scale = 1/sqrt(image[nn].FOM());
1553 for ( j=0; j<ds; i++, j++ ) set(i, complex(i)*scale);
1554 }
1555
1556 return 0;
1557 }
1558
1567 int Bimage::fspace_normalize_radial(Bimage* pmask, double resolution, int flag)
1568 {
1569 if ( fouriertype != NoTransform ) {
1570 cerr << "Error: File " << file_name() << " must be a real space map!" << endl;
1571 return -1;
1572 }
1573
1574 if ( pmask ) pmask->change_type(UCharacter);
1575
1576 check_resolution(resolution);
1577
1578 // The radius scaling is set to a value consistent with one pixel width
1579 // in reciprocal space for the longest dimension.
1580 double rad_scale = real_size().max();
1581
1582 // maxrad is the main limit for the length of all the arrays,
1583 // and is derived from the resolution set in the transform
1584 long maxrad = (long) (2 + rad_scale/resolution);
1585
1586 fft();
1587
1588 long i, nn;
1589 double* rps;
1590
1591 for ( nn=0; nn<n; nn++ ) {
1592 rps = fspace_radial(nn, maxrad, flag);
1593 for ( i=0; i<maxrad; i++ )
1594 if ( rps[i] ) rps[i] = 1/sqrt(rps[i]);
1595 fspace_scale(nn, maxrad, rps, pmask);
1596 }
1597
1598 fft_back();
1599
1600 return 0;
1601 }
1602
1608 int Bimage::fspace_positive()
1609 {
1610 int tflag(0);
1611 long i(0), ds(x*y*z);
1612 double fmax(0), scale;
1613
1614 fmax = ds * (avg-min);
1615
1616 if ( compoundtype != TComplex ) {
1617 tflag = 1;
1618 fft();
1619 }
1620
1621 if ( (*this)[i] > SMALLFLOAT ) fmax = (*this)[i];
1622 if ( verbose ) {
1623 cout << "Converting to a positive definite image:" << endl;
1624 cout << "F0: " << fmax << endl << endl;
1625 }
1626
1627 scale = 1/fmax;
1628
1629 set(0, fmax);
1630 set(1, 0);
1631
1632 for ( i=0; i<ds; i++ ) set(i, complex(i) * scale);
1633
1634 if ( tflag ) fft_back();
1635
1636 return 0;
1637 }
1638
1649 double Bimage::friedel_check()
1650 {
1651 simple_to_complex();
1652
1653 long i, j, nn, xx, yy, zz, xf, yf, zf;
1654 double d, w, s(0), R(0), Ri(0), Rr(0), Ra(0), Rp(0);
1655 Complex<double> v, vf;
1656
1657 for ( nn=0; nn<n; nn++ ) {
1658 for ( zz=0; zz<z; zz++ ) {
1659 zf = (zz)? z - zz: 0;
1660 for ( yy=0; yy<y; yy++ ) {
1661 yf = (yy)? y - yy: 0;
1662 for ( xx=0; xx<(x+1)/2; xx++ ) {
1663 xf = (xx)? x - xx: 0;
1664 i = index(xx, yy, zz, nn);
1665 j = index(xf, yf, zf, nn);
1666 v = complex(i);
1667 vf = complex(j);
1668 w = (v.power() + vf.power())/2;
1669 d = v.real() - vf.real();
1670 Rr += d*d*w;
1671 d = v.imag() + vf.imag();
1672 Ri += d*d*w;
1673 d = v.amp() - vf.amp();
1674 Ra += d*d*w;
1675 d = angle_set_negPI_to_PI(v.phi() + vf.phi());
1676 Rp += d*d*w;
1677 s += w;
1678 }
1679 }
1680 }
1681 }
1682
1683 Rr = sqrt(Rr/s);
1684 Ri = sqrt(Ri/s);
1685 Ra = sqrt(Ra/s);
1686 Rp = sqrt(Rp/s);
1687 R = sqrt(Rr*Rr + Ri*Ri);
1688
1689 if ( verbose & VERB_PROCESS ) {
1690 cout << "Friedel symmetry residuals:" << endl;
1691 cout << "Real: " << Rr << endl;
1692 cout << "Imaginary: " << Ri << endl;
1693 cout << "Amplitude: " << Ra << endl;
1694 cout << "Phase: " << Rp*180.0/M_PI << " degrees" << endl;
1695 cout << "Overall: " << R << endl << endl;
1696 }
1697
1698 return R;
1699 }
1700
1711 int Bimage::friedel_apply()
1712 {
1713 long i, j, nn, xx, yy, zz, xf, yf, zf, nR;
1714 double amp, amps, phi, phis, damp, dphi;
1715 double ampavg, phiavg, fomavg;
1716 double Ramp, Rphi;
1717 double tol(0.01);
1718 Complex<double> v, vf;
1719 float* fom = NULL;
1720 if ( next ) fom = (float *) next->data_pointer();
1721
1722 if ( verbose & VERB_PROCESS ) {
1723 cout << "Applying Friedel symmetry:" << endl;
1724 cout << "Image\tRefl\tR(amp)\tR(phi)" << endl;
1725 } else if ( verbose & VERB_LABEL )
1726 cout << "Applying Friedel symmetry" << endl << endl;
1727
1728 for ( nn=0; nn<n; nn++ ) {
1729 nR = 0;
1730 Ramp = Rphi = 0;
1731 for ( zz=0; zz<z; zz++ ) {
1732 zf = (zz)? z - zz: 0;
1733 for ( yy=0; yy<y; yy++ ) {
1734 yf = (yy)? y - yy: 0;
1735 for ( xx=0; xx<(x+1)/2; xx++ ) {
1736 xf = (xx)? x - xx: 0;
1737 i = index(xx, yy, zz, nn);
1738 j = index(xf, yf, zf, nn);
1739 v = complex(i);
1740 vf = complex(j);
1741 amp = v.amp();
1742 amps = vf.amp();
1743 phi = v.phi();
1744 phis = vf.phi();
1745 damp = amp - amps;
1746 dphi = phi + phis;
1747 dphi = angle_set_negPI_to_PI(dphi);
1748 if ( verbose & VERB_DEBUG )
1749 if ( fabs(dphi) > tol )
1750 cout << "amp dphi: " << xx << " " << yy << " "
1751 << zz << " " << j << " " << damp << " " << dphi << endl;
1752 ampavg = (amp + amps)/2;
1753 phiavg = phi - dphi/2;
1754 v = Complex<double>(ampavg*cos(phiavg), ampavg*sin(phiavg));
1755 set(i, v);
1756 set(j, v.conj());
1757 if ( fom ) {
1758 fomavg = (fom[i] + fom[j])/2;
1759 fom[i] = fomavg;
1760 fom[j] = fomavg;
1761 }
1762 Ramp += damp*damp;
1763 Rphi += dphi*dphi;
1764 nR++;
1765 }
1766 }
1767 }
1768 if ( nR ) {
1769 Ramp = sqrt(Ramp/nR);
1770 Rphi = sqrt(Rphi/nR);
1771 }
1772 if ( verbose & VERB_PROCESS )
1773 cout << nn+1 << tab << nR << tab << Ramp << tab << Rphi*180/M_PI << endl;
1774 }
1775 if ( verbose )
1776 cout << endl;
1777
1778 return 0;
1779 }
1780
1793 Bimage* Bimage::phase_difference(Bimage* p, int type, double res_hi, double res_lo)
1794 {
1795 if ( res_hi <= 0 ) res_hi = 0.1;
1796 if ( res_lo <= 0 ) res_lo = 1e10;
1797 if ( res_lo < res_hi + 1 ) res_lo = res_hi + 1;
1798
1799 Bimage* ppd = pack_two_in_complex(p);
1800
1801 ppd->fft();
1802
1803 // if ( verbose & VERB_FULL )
1804 if ( verbose )
1805 cout << "Cosine phase difference in the resolution range " << res_hi << " - " << res_lo << endl << endl;
1806
1807 long i, j, xx, yy, zz, nn;
1808 long ix, iy, iz, nw(0);
1809 Vector3<double> shift;
1810 double smax2 = 1.0/(res_hi*res_hi);
1811 double smin2 = 1.0/(res_lo*res_lo);
1812 double dy, dz, sx2, sy2, sz2, s2, w1, w(0);
1813 Vector3<double> scale(1.0/ppd->real_size());
1814 Complex<float> temp1, temp2;
1815
1816 float* dphi = new float[datasize];
1817
1818 for ( nn=0; nn<ppd->images(); nn++ ) {
1819 // ppd->image[nn].origin(image[nn].origin() - p->image[nn].origin());
1820 ppd->image[nn].origin(image[nn].origin() - p->image[nn].origin());
1821 shift = ppd->image[nn].origin()/ppd->size();
1822 if ( verbose & VERB_FULL )
1823 cout << nn+1 << tab << shift << endl;
1824 for ( zz=0; zz<ppd->z; zz++ ) {
1825 iz = -zz;
1826 if ( iz < 0 ) iz += ppd->z;
1827 dz = zz;
1828 if ( zz > (ppd->z - 1)/2 ) dz -= ppd->z;
1829 sz2 = dz*scale[2];
1830 sz2 *= sz2;
1831 for ( yy=0; yy<ppd->y; yy++ ) {
1832 iy = -yy;
1833 if ( iy < 0 ) iy += ppd->y;
1834 dy = yy;
1835 if ( yy > (ppd->y - 1)/2 ) dy -= ppd->y;
1836 sy2 = dy*scale[1];
1837 sy2 *= sy2;
1838 for ( xx=0; xx<ppd->x/2+1; xx++ ) {
1839 ix = -xx;
1840 if ( ix < 0 ) ix += ppd->x;
1841 sx2 = xx*scale[0];
1842 sx2 *= sx2;
1843 s2 = sx2 + sy2 + sz2;
1844 if ( s2 >= smin2 && s2 <= smax2 ) {
1845 i = ppd->index(xx,yy,zz,nn);
1846 j = ppd->index(ix,iy,iz,nn);
1847 temp1 = ppd->complex(i).unpack_first(ppd->complex(j));
1848 temp2 = ppd->complex(i).unpack_second(ppd->complex(j));
1849 dphi[i] = temp1.phi() - temp2.phi() - TWOPI*(xx*shift[0] + yy*shift[1] + zz*shift[2]);
1850 if ( type < 1 ) dphi[i] = angle_set_negPI_to_PI(dphi[i]);
1851 if ( type & 1 ) dphi[i] = cos(dphi[i]);
1852 if ( type & 2 ) {
1853 w1 = temp1.power()*temp2.power();
1854 dphi[i] *= w1;
1855 w += w1;
1856 nw++;
1857 }
1858 dphi[j] = dphi[i];
1859 }
1860 }
1861 }
1862 }
1863 }
1864
1865 ppd->data_type(Float);
1866 ppd->compound_type(TSimple);
1867 ppd->channels(1);
1868 ppd->fourier_type(NoTransform);
1869 ppd->data_assign((unsigned char *) dphi);
1870
1871 if ( nw ) {
1872 w = sqrt(1/w);
1873 ppd->multiply(w);
1874 }
1875
1876 return ppd;
1877 }
1878
1891 double Bimage::average_phase_difference(Bimage* p, double res_hi, double res_lo, int weighting)
1892 {
1893 if ( res_hi <= 0 ) res_hi = 0.1;
1894 if ( res_lo < res_hi + 1 ) res_lo = res_hi + 1;
1895
1896 Bimage* ppd = pack_two_in_complex(p);
1897
1898 ppd->fft();
1899
1900 long i, j, xx, yy, zz, nn;
1901 long ix, iy, iz;
1902 Vector3<double> shift;
1903 double smax2 = 1.0/(res_hi*res_hi);
1904 double smin2 = 1.0/(res_lo*res_lo);
1905 double dy, dz, sx2, sy2, sz2, s2;
1906 Vector3<double> scale(1.0/ppd->real_size());
1907 Complex<float> temp1, temp2;
1908
1909 double amp, dphi, sum_amp(0), avg_pd(0);
1910
1911 for ( nn=0; nn<ppd->images(); nn++ ) {
1912 // ppd->image[nn].origin(image[nn].origin() - p->image[nn].origin());
1913 ppd->image[nn].origin(image[nn].origin() - p->image[nn].origin());
1914 shift = ppd->image[nn].origin()/ppd->size();
1915 if ( verbose & VERB_FULL )
1916 cout << nn+1 << tab << shift << endl;
1917 for ( zz=0; zz<ppd->z; zz++ ) {
1918 iz = -zz;
1919 if ( iz < 0 ) iz += ppd->z;
1920 dz = zz;
1921 if ( zz > (ppd->z - 1)/2 ) dz -= ppd->z;
1922 sz2 = dz*scale[2];
1923 sz2 *= sz2;
1924 for ( yy=0; yy<ppd->y; yy++ ) {
1925 iy = -yy;
1926 if ( iy < 0 ) iy += ppd->y;
1927 dy = yy;
1928 if ( yy > (ppd->y - 1)/2 ) dy -= ppd->y;
1929 sy2 = dy*scale[1];
1930 sy2 *= sy2;
1931 for ( xx=0; xx<ppd->x/2+1; xx++ ) {
1932 ix = -xx;
1933 if ( ix < 0 ) ix += ppd->x;
1934 sx2 = xx*scale[0];
1935 sx2 *= sx2;
1936 s2 = sx2 + sy2 + sz2;
1937 if ( s2 >= smin2 && s2 <= smax2 ) {
1938 i = ppd->index(xx,yy,zz,nn);
1939 j = ppd->index(ix,iy,iz,nn);
1940 temp1 = ppd->complex(i).unpack_first(ppd->complex(j));
1941 temp2 = ppd->complex(i).unpack_second(ppd->complex(j));
1942 dphi = temp1.phi() - temp2.phi() - TWOPI*(xx*shift[0] + yy*shift[1] + zz*shift[2]);
1943 dphi = angle_set_negPI_to_PI(dphi);
1944 switch ( weighting ) {
1945 case 1:
1946 amp = temp1.amp();
1947 break;
1948 case 2:
1949 amp = temp2.amp();
1950 break;
1951 case 3:
1952 amp = temp1.amp() + temp2.amp();
1953 break;
1954 default:
1955 amp = 1;
1956 }
1957 sum_amp += amp;
1958 avg_pd += amp*fabs(dphi);
1959 }
1960 }
1961 }
1962 }
1963 }
1964
1965 if ( sum_amp ) avg_pd /= sum_amp;
1966 else avg_pd = M_PI;
1967
1968 delete ppd;
1969
1970 return avg_pd;
1971 }
1972
1978 int Bimage::phase_flip(Bimage* pd)
1979 {
1980 fft();
1981
1982 long i, ds(x*y*z*n);
1983
1984 for ( i=0; i<ds; i++ )
1985 if ( (*pd)[i] < 0 ) set(i, -complex(i));
1986
1987 fft_back();
1988
1989 return 0;
1990 }
1991
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1743
Bimage::fspace_weigh_FSC_curve
int fspace_weigh_FSC_curve(Bplot *plot, double resolution=0)
Weighs an image's amplitudes with a given FSC curve.
Definition: Bimage_fspace.cpp:1367
Bimage::phase_shift
int phase_shift(Vector3< double > shift)
Phase shifts a complex image.
Definition: Bimage_complex.cpp:256
FILL_BACKGROUND
#define FILL_BACKGROUND
Definition: utilities.h:174
Bimage.h
Header file for image class.
Bimage::complex_power
double complex_power()
Calculates the power in a complex image.
Definition: Bimage_complex.cpp:200
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
Vector3::length
double length()
Definition: Vector3.h:222
planb
fft_plan planb
Definition: bico.cpp:24
Bimage::add
void add(long j, double v)
Definition: Bimage.h:308
Bimage::file_name
string & file_name()
Definition: Bimage.h:231
Bimage::fspace_bandpass
int fspace_bandpass(double res_hi, double res_lo=0, double width=0)
Applies a bandpass filter to an image.
Definition: Bimage_fspace.cpp:499
Bimage::fspace_translate
int fspace_translate(Vector3< double > shift)
Translates an image in frequency space to avoid interpolation.
Definition: Bimage_fspace.cpp:150
Bimage::fspace_normalize_radial
int fspace_normalize_radial(Bimage *pmask, double resolution=0, int flag=0)
Normalizes an image's amplitudes.
Definition: Bimage_fspace.cpp:1567
SMALLFLOAT
#define SMALLFLOAT
Definition: utilities.h:45
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::phase_flip
int phase_flip(Bimage *pd)
Flips the phases of an image based on a phase difference map.
Definition: Bimage_fspace.cpp:1978
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
angle_set_negPI_to_PI
double angle_set_negPI_to_PI(double angle)
Returns an angle between -PI and PI.
Definition: utilities.cpp:594
Bsub_image::background
double background()
Definition: Bimage.h:121
planf
fft_plan planf
Definition: bico.cpp:24
Bimage::compound_type
CompoundType compound_type()
Definition: Bimage.h:351
Bimage::fspace_interpolate
Complex< double > fspace_interpolate(long img_num, Vector3< double > m, FSI_Kernel *kernel)
Calculates the complex value at an image location by kernel-based interpolation.
Definition: Bimage_fspace.cpp:88
Bimage::index
long index(long nx, long ny) const
Definition: Bimage.h:383
Matrix3
Definition: Matrix3.h:17
Complex::conj
Complex conj()
Definition: Complex.h:106
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
Bimage::fspace_weigh
int fspace_weigh(long maxrad, double *curve, int flag=0)
Definition: Bimage_fspace.cpp:797
TypePointer::uc
unsigned char * uc
Definition: Bimage.h:69
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
FSI_Kernel
Definition: FSI_Kernel.h:14
Bimage::fspace_resize
int fspace_resize(double scale, double res_hi, double res_lo)
Resizes an image in frequency space to avoid interpolation.
Definition: Bimage_fspace.cpp:205
FourierType
FourierType
Fourier transform format specifier.
Definition: Bimage.h:39
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
TComplex
Definition: Bimage.h:59
Bimage::fspace_weigh_C_curve
int fspace_weigh_C_curve(double resolution=0)
Weighs an image's amplitudes with the carbon scattering curve.
Definition: Bimage_fspace.cpp:1228
Bimage::fspace_background
int fspace_background()
Calculates the background for a Fourier transform.
Definition: Bimage_fspace.cpp:49
Bimage::Bimage
Bimage()
Initializes an image.
Definition: Bimage.cpp:44
Bimage::fspace_amp_threshold
int fspace_amp_threshold(double threshold)
Filters the amplitudes of the Fourier transform of an image.
Definition: Bimage_fspace.cpp:371
Bimage::check_resolution
void check_resolution(double &resolution)
Checks that the resolution falls within reasonable limits.
Definition: Bimage.cpp:605
Bimage::fspace_weigh_dose
int fspace_weigh_dose(long nn, double dose_per_frame, vector< double > critdose)
Definition: Bimage_fspace.cpp:1398
TSimple
Definition: Bimage.h:58
Float
Definition: utilities.h:157
Vector3::max
Type max()
Definition: Vector3.h:175
Bimage::fsc
Bplot * fsc(double hi_res, double sampling_ratio=1)
Definition: Bimage_resolution.cpp:250
Bimage
General image parameter class.
Definition: Bimage.h:163
Bimage::real_size
Vector3< double > real_size()
Definition: Bimage.h:487
Bimage::fspace_maximum_radius
long fspace_maximum_radius(double resolution)
Calculates the maximum radius in frequency space from a given resolution.
Definition: Bimage_fspace.cpp:25
Bimage::transform
int transform(Vector3< double > scale, Vector3< double > origin, Vector3< double > translate, Matrix3 mat, int fill_type=0, double fill=0)
Transforms an image by translation, rotation, scaling and skewing, in place.
Definition: Bimage_transform.cpp:37
M_PI
#define M_PI
Definition: utilities.h:59
Bimage::fspace_scale
int fspace_scale(long maxrad, double *scale, Bimage *pmask=NULL)
Definition: Bimage_fspace.cpp:844
Bimage::fspace_radial
double * fspace_radial(long nn, long maxrad, int flag=0)
Calculates the radial power spectrum from a Fourier transform.
Definition: Bimage_fspace.cpp:734
Bimage::shift
int shift(Vector3< double > vec, int fill_type=0, double fill=0)
Shifts an image.
Definition: Bimage_transform.cpp:587
Bimage::fspace_radial_power
Bimage * fspace_radial_power(double resolution)
Calculates the radial power spectrum from a Fourier transform.
Definition: Bimage_fspace.cpp:612
Bimage::statistics
long statistics()
Calculates the statistics for an image.
Definition: Bimage_stats.cpp:22
Bimage::data_assign
unsigned char * data_assign(unsigned char *nudata)
Assign image data.
Definition: Bimage.cpp:852
Bimage::resize
int resize(Vector3< long > nusize, Vector3< long > translate, int fill_type=0, double fill=0)
Resizes without interpolation or rescaling.
Definition: Bimage_resize.cpp:28
fft_plan
fftwf_plan fft_plan
Definition: fft.h:16
Standard
Definition: Bimage.h:41
Bimage::simple_to_complex
void simple_to_complex()
A simple image is converted to a complex image.
Definition: Bimage_complex.cpp:22
Complex::amp
double amp()
Definition: Complex.h:104
ctf.h
Header file for CTF (contrast transfer function) functions.
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
Bimage::calculate_background
int calculate_background(long nn, int flag)
Calculates the background for one sub-image.
Definition: Bimage_background.cpp:27
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:127
Complex::is_finite
bool is_finite()
Definition: Complex.h:100
Bimage::channels
long channels()
Definition: Bimage.h:371
Bsub_image::sampling
void sampling(double x, double y, double z)
Definition: Bimage.h:123
Vector3::length2
double length2()
Definition: Vector3.h:221
C_curve
vector< double > C_curve(long n, double freq_step)
Calculates the carbon scattering curve.
Definition: ctf.cpp:462
Bimage::fspace_sqrt_amp
int fspace_sqrt_amp()
Change the amlitudes to their square roots.
Definition: Bimage_fspace.cpp:427
Bimage::set
void set(long j, double v)
Sets a single value at the given index.
Definition: Bimage.cpp:1096
FOM
Definition: mg_processing.h:40
Bimage::next
Bimage * next
Definition: Bimage.h:165
VERB_RESULT
#define VERB_RESULT
Definition: utilities.h:105
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::data_pointer
unsigned char * data_pointer()
Definition: Bimage.h:261
UCharacter
Definition: utilities.h:149
Bimage::sizeX
void sizeX(long nx)
Definition: Bimage.h:377
Bimage::fft_setup
fft_plan fft_setup(fft_direction dir, int opt=0)
Sets up a plan for fast Fourier transforms.
Definition: Bimage_fft.cpp:29
Bplot::rows
void rows(long n)
Definition: Bplot.h:207
matrix_linear.h
Header file for matrix functions.
Bimage::fspace_square_amp
int fspace_square_amp()
Change the amlitudes to their squares.
Definition: Bimage_fspace.cpp:458
Bimage::fspace_fit_B_factor
double fspace_fit_B_factor(double res_hi=0)
Determines the overall B-factor of an image.
Definition: Bimage_fspace.cpp:996
Bimage::fspace_weigh_B_factor
int fspace_weigh_B_factor(double B, double resolution=0)
Weighs an image's amplitudes with B-factor (gaussian) curve.
Definition: Bimage_fspace.cpp:1185
Complex::phi
double phi()
Definition: Complex.h:105
Bimage::sizeZ
void sizeZ(long nz)
Definition: Bimage.h:379
Vector3< double >
Bimage::friedel_apply
int friedel_apply()
Applies Friedel symmetry.
Definition: Bimage_fspace.cpp:1711
fft_destroy_plan
int fft_destroy_plan(fft_plan plan)
Deallocates a plan for fast Fourier transforms.
Definition: fft.cpp:87
Complex::imag
Type imag()
Definition: Complex.h:102
Bimage::fspace_weigh_ramp
int fspace_weigh_ramp(double resolution, fft_plan planf, fft_plan planb)
Weighs a transform with a ramp.
Definition: Bimage_fspace.cpp:1064
Vector3::min
Type min()
Definition: Vector3.h:169
Bimage::fspace_positive
int fspace_positive()
Sets the image to positive definite.
Definition: Bimage_fspace.cpp:1608
Bimage::average_phase_difference
double average_phase_difference(Bimage *p, double res_hi, double res_lo, int weighting=1)
Calculates the average of the absolute phase difference between two images within given resolution sh...
Definition: Bimage_fspace.cpp:1891
Bimage::friedel_check
double friedel_check()
Checks Friedel symmetry.
Definition: Bimage_fspace.cpp:1649
Bimage::fspace_amp_one
int fspace_amp_one()
Sets all amplitudes to one.
Definition: Bimage_fspace.cpp:326
Bimage::fspace_normalize
int fspace_normalize()
Normalizes an image's amplitudes.
Definition: Bimage_fspace.cpp:1539
Complex::power
double power()
Definition: Complex.h:103
Bsub_image::average
double average()
Definition: Bimage.h:115
Complex::real
Type real()
Definition: Complex.h:101
kernel
Definition: kernlut.h:13
Bimage::images
long images()
Definition: Bimage.h:491
Bimage::plot
Bplot * plot()
Converts a one-dimensional image into a plot.
Definition: Bimage.cpp:3836
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
Bimage::change_transform_size
Vector3< double > change_transform_size(Vector3< long > nusize)
Resizes a "standard" transform.
Definition: Bimage_fft.cpp:239
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
Bimage::sizeY
void sizeY(long ny)
Definition: Bimage.h:378
VERB_LABEL
#define VERB_LABEL
Definition: utilities.h:106
Bimage::data_type
DataType data_type()
Definition: Bimage.h:349
Bimage::phase_difference
Bimage * phase_difference(Bimage *p, int type=0, double res_hi=0, double res_lo=0)
Calculates the cosine of the phase difference between two images.
Definition: Bimage_fspace.cpp:1793
TWOPI
#define TWOPI
Definition: utilities.h:68
verbose
int verbose
Bimage::fourier_type
FourierType fourier_type()
Definition: Bimage.h:367
Bimage::fspace_weigh_LoG
int fspace_weigh_LoG(double resolution, double sigma)
Weighs an image's amplitudes with a Laplacian-of-Gaussian function.
Definition: Bimage_fspace.cpp:1263
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
Bimage::image
Bsub_image * image
Definition: Bimage.h:188
Bimage::fspace_weigh_RPS_curve
int fspace_weigh_RPS_curve(Bplot *plot, double resolution=0)
Weighs an image's amplitudes with a given RPS curve.
Definition: Bimage_fspace.cpp:1310
Bimage::origin
void origin(double ox, double oy, double oz)
Definition: Bimage.h:563
Bplot
Definition: Bplot.h:146
linear_least_squares
double linear_least_squares(int n1, int n2, double *x, double *y, double &a, double &b)
Does a linear least squares fit between two vectors.
Definition: matrix_linear.cpp:28