| Bsoft 2.0.5 Bernard's software package

Bimage_complex.cpp
Go to the documentation of this file.
1
9 #include "Bimage.h"
10 #include "timer.h"
11 #include "utilities.h"
12
13 // Declaration of global variables
14 extern int verbose; // Level of output to the screen
15
22 void Bimage::simple_to_complex()
23 {
24 if ( compoundtype == TComplex ) return;
25
26 if ( compoundtype == TRGB || compoundtype == TRGBA || compoundtype == TCMYK ) color_to_simple();
27
28 if ( compoundtype != TSimple ) {
29 cerr << "Error: Conversion from compound types to complex type not supported!" << endl;
30 exit(-1);
31 }
32
33 long ds(x*y*z*n);
34 Complex<float>* cdata = new Complex<float>[ds];
35
36 for ( long j=0; j<ds; j++ ) cdata[j] = (*this)[j];
37
38 data_type(Float);
39 compoundtype = TComplex;
40 c = 2;
41
42 data_assign((unsigned char *) cdata);
43
44 statistics();
45 }
46
50 void Bimage::complex_to_real()
51 {
52 if ( compoundtype != TComplex ) return;
53
54 long j, k, ds(x*y*z*n);
55 float* fdata = new float[ds];
56
57 for ( j=k=0; j<ds; j++, k+=2 ) fdata[j] = (*this)[k];
58
59 data_type(Float);
60 compoundtype = TSimple;
61 c = 1;
62
63 data_assign((unsigned char *) fdata);
64
65 statistics();
66 }
67
71 void Bimage::complex_to_imaginary()
72 {
73 if ( compoundtype != TComplex ) return;
74
75 long j, k, ds(x*y*z*n);
76 float* fdata = new float[ds];
77
78 for ( j=0, k=1; j<ds; j++, k+=2 ) fdata[j] = (*this)[k];
79
80 data_type(Float);
81 compoundtype = TSimple;
82 c = 1;
83
84 data_assign((unsigned char *) fdata);
85
86 statistics();
87 }
88
92 void Bimage::complex_to_intensities()
93 {
94 if ( compoundtype != TComplex ) return;
95
96 long j, ds(x*y*z*n);
97 float* fdata = new float[ds];
98
99 for ( j=0; j<ds; j++ ) fdata[j] = (complex(j)).power();
100
101 data_type(Float);
102 compoundtype = TSimple;
103 c = 1;
104
105 data_assign((unsigned char *) fdata);
106
107 statistics();
108 }
109
114 void Bimage::complex_to_amplitudes()
115 {
116 if ( compoundtype != TComplex ) return;
117
118 long j, ds(x*y*z*n);
119 float* fdata = new float[ds];
120
121 for ( j=0; j<ds; j++ ) fdata[j] = (complex(j)).amp();
122
123 data_type(Float);
124 compoundtype = TSimple;
125 c = 1;
126
127 data_assign((unsigned char *) fdata);
128
129 statistics();
130 }
131
136 void Bimage::complex_to_signed_amplitudes()
137 {
138 if ( compoundtype != TComplex ) return;
139
140 long j, ds(x*y*z*n);
141 float* fdata = new float[ds];
142
143 for ( j=0; j<ds; j++ ) {
144 fdata[j] = (complex(j)).amp();
145 if ( (complex(j)).phi() < 0 ) fdata[j] = -fdata[j];
146 }
147
148 data_type(Float);
149 compoundtype = TSimple;
150 c = 1;
151
152 data_assign((unsigned char *) fdata);
153
154 statistics();
155 }
156
161 void Bimage::complex_to_phases()
162 {
163 if ( compoundtype != TComplex ) return;
164
165 long j, ds(x*y*z*n);
166 float* fdata = new float[ds];
167
168 for ( j=0; j<ds; j++ ) fdata[j] = (complex(j)).phi();
169
170 data_type(Float);
171 compoundtype = TSimple;
172 c = 1;
173
174 data_assign((unsigned char *) fdata);
175
176 statistics();
177 }
178
183 void Bimage::complex_conjugate()
184 {
185 if ( compoundtype != TComplex ) return;
186
187 long j;
188
189 for ( j=1; j<datasize; j+=2 ) set(j, -(*this)[j]);
190 }
191
200 double Bimage::complex_power()
201 {
202 if ( compoundtype != TComplex ) return 0;
203
204 long nn, i, j, ds(x*y*z);
205 double pwr(0), pwrn;
206
207 for ( nn=i=0; nn<n; nn++ ) {
208 pwrn = 0;
209 for ( j=0; j<ds; i++, j++ ) pwrn += (complex(i)).power();
210 pwr += pwrn;
211 image[nn].FOM(pwrn);
212 }
213
214 return pwr;
215 }
216
225 double Bimage::complex_normalize()
226 {
227 if ( compoundtype != TComplex ) return 0;
228
229 set(0, 0); set(1, 0);
230
231 long nn, i, j, ds(x*y*z);
232 double pwr = complex_power(), pwrn, f;
233
234 for ( nn=0; nn<n; nn++ ) {
235 pwrn = image[nn].FOM();
236 if ( pwrn ) {
237 f = 1/sqrt(pwrn);
238 for ( j=0, i=nn*ds; j<ds; i++, j++ ) set(i, complex(i) * f);
239 }
240 }
241
242 statistics();
243
244 return pwr;
245 }
246
256 int Bimage::phase_shift(Vector3<double> shift)
257 {
258 if ( compoundtype != TComplex ) return -1;
259
260 if ( shift.length() == 0 ) return 0;
261
262 long nn;
263
264 for ( nn=0; nn<n; nn++ )
265 phase_shift(nn, shift);
266
267 return 0;
268 }
269
280 int Bimage::phase_shift(long nn, Vector3<double> shift)
281 {
282 if ( compoundtype != TComplex ) return -1;
283
284 if ( shift.length() == 0 ) return 0;
285
286 if ( verbose & VERB_FULL )
287 cout << "Translate within unit cell by: " << shift << endl;
288
289 long j(nn*x*y*z), xx, yy, zz;
290 long h, k, l;
291 double phi(0);
292 Vector3<double> half((x - 1)/2, (y - 1)/2, (z - 1)/2);
293 Vector3<double> t(shift/size() * MIN2PI);
294 Complex<double> cv;
295
296 for ( zz=0; zz<z; zz++ ) {
297 l = zz;
298 if ( l > half[2] ) l -= (long)z;
299 for ( yy=0; yy<y; yy++ ) {
300 k = yy;
301 if ( k > half[1] ) k -= (long)y;
302 for ( xx=0; xx<x; xx++, j++ ) {
303 h = xx;
304 if ( h > half[0] ) h -= (long)x;
305 phi = h*t[0] + k*t[1] + l*t[2];
306 cv = complex(j);
307 cv.shift_phi(phi);
308 set(j, cv);
309 }
310 }
311 }
312
313 image[nn].origin(image[nn].origin() + shift);
314
315 return 0;
316 }
317
327 int Bimage::phase_shift_to_origin()
328 {
329 if ( compoundtype != TComplex ) return -1;
330
331 if ( verbose & VERB_PROCESS )
332 cout << "Translate within unit cell to phase origin:" << endl;
333
334 long j, nn, xx, yy, zz;
335 long h, k, l;
336 double skl, sl, phi;
337 Vector3<double> shift, half((x - 1)/2, (y - 1)/2, (z - 1)/2);
338 Complex<double> cv;
339
340 if ( verbose & VERB_PROCESS )
341 cout << "Image\tox\toy\toz" << endl;
342 for ( j=nn=0; nn<n; nn++ ) {
343 if ( verbose & VERB_PROCESS )
344 cout << nn+1 << tab << image[nn].origin()[0] << tab << image[nn].origin()[1] << tab << image[nn].origin()[2] << endl;
345 shift = (image[nn].origin()/size()) * TWOPI;
346 for ( zz=0; zz<z; zz++ ) {
347 l = zz;
348 if ( l > half[2] ) l -= (long)z;
349 sl = l*shift[2];
350 for ( yy=0; yy<y; yy++ ) {
351 k = yy;
352 if ( k > half[1] ) k -= (long)y;
353 skl = sl + k*shift[1];
354 for ( xx=0; xx<x; xx++, j++ ) {
355 h = xx;
356 if ( h > half[0] ) h -= (long)x;
357 phi = h*shift[0] + skl;
358 cv = complex(j);
359 cv.shift_phi(phi);
360 set(j, cv);
361 }
362 }
363 }
364 // image[nn].origin(image[nn].origin() + shift*size());
365 image[nn].origin(0.0,0.0,0.0);
366 }
367 if ( verbose & VERB_PROCESS )
368 cout << endl;
369
370 return 0;
371 }
372
382 int Bimage::phase_shift_to_center()
383 {
384 Vector3<double> shift(x/2, y/2, z/2);
385
386 phase_shift(shift);
387
388 return 0;
389 }
390
400 int Bimage::complex_multiply(Bimage* p)
401 {
402 if ( !d.uc ) return -1;
403
404 if ( compoundtype != TComplex || p->compound_type() != TSimple ) return -1;
405
406 change_type(Float);
407 p->change_type(Float);
408
409 if ( verbose & VERB_FULL )
410 cout << "Multiplying the complex image" << endl << endl;
411
412 long i, ds(x*y*z*n);
413
414 for ( i=0; i<ds; i++ ) set(i, complex(i) * (*p)[i]);
415
416 return 0;
417 }
418
430 int Bimage::complex_product(Bimage* p)
431 {
432 if ( !d.uc ) return -1;
433
434 if ( compoundtype != TComplex || p->compound_type() != TComplex ) return -1;
435
436 change_type(Float);
437 p->change_type(Float);
438
439 if ( verbose & VERB_FULL )
440 cout << "Calculating the complex product" << endl << endl;
441
442 long i, ds(x*y*z*n);
443
444 for ( i=0; i<ds; i++ ) set(i, complex(i) * p->complex(i));
445
446 return 0;
447 }
448
460 int Bimage::complex_conjugate_product(Bimage* p)
461 {
462 if ( !d.uc ) return -1;
463
464 if ( compound_type() != TComplex || p->compound_type() != TComplex ) return -1;
465
466 change_type(Float);
467 p->change_type(Float);
468
469 if ( verbose & VERB_FULL )
470 cout << "Calculating the complex conjugate product" << endl << endl;
471
472 long i, ds(x*y*z*n);
473
474 for ( i=0; i<ds; i++ ) set(i, complex(i) * (p->complex(i)).conj());
475
476 return 0;
477 }
478
490 Bimage* Bimage::complex_conjugate_product_one2many(Bimage* p)
491 {
492 if ( !d.uc ) return NULL;
493
494 if ( compound_type() != TComplex || p->compound_type() != TComplex ) return NULL;
495
496 if ( !check_if_same_image_size(p) ) return NULL;
497
498 Bimage* pc = p->copy();
499
500 if ( verbose & VERB_FULL )
501 cout << "Calculating the complex conjugate product" << endl << endl;
502
503 long i, j, nn, ds(x*y*z);
504
505 for ( nn=j=0; nn<p->n; nn++ )
506 for ( i=0; i<ds; i++, j++ ) pc->set(j, complex(i) * (p->complex(j)).conj());
507
508 return pc;
509 }
510
521 int Bimage::complex_apply_mask(Bimage* pmask)
522 {
523 if ( !d.uc ) return -1;
524 if ( !pmask ) return -1;
525
526 pmask->change_type(Float);
527
528 if ( verbose & VERB_FULL )
529 cout << "Masking a complex image" << endl;
530
531 long i, ds(x*y*z*n);
532 Complex<double> cv;
533
534 for ( i=0; i<ds; i++ )
535 if ( (*pmask)[i] <= 0 ) set(i, cv);
536
537 return 0;
538 }
539
550 int Bimage::complex_apply_negative_mask(Bimage* pmask)
551 {
552 if ( !d.uc ) return -1;
553 if ( !pmask ) return -1;
554
555 if ( verbose & VERB_FULL )
556 cout << "Masking a complex image" << endl;
557
558 long i, ds(x*y*z*n);
559 Complex<double> cv;
560
561 for ( i=0; i<ds; i++ )
562 if ( (*pmask)[i] >= 0 ) set(i, cv);
563
564 return 0;
565 }
566
581 int Bimage::complex_apply_dual_mask(Bimage* pmask)
582 {
583 if ( !d.uc ) return -1;
584 if ( !pmask ) return -1;
585
586 pmask->change_type(Float);
587
588 if ( verbose & VERB_FULL )
589 cout << "Masking a complex image with a dual mask" << endl;
590
591 Bimage* p = copy();
592 next = p;
593
594 long i, ds(x*y*z*n);
595 Complex<double> cv;
596
597 for ( i=0; i<ds; i++ ) {
598 if ( (*pmask)[i] <= 0 ) set(i, cv);
599 if ( (*pmask)[i] >= 0 ) p->set(i, cv);
600 }
601
602 return 0;
603 }
604
615 int Bimage::complex_bandpass(double hires, double lores)
616 {
617 if ( !d.uc ) return -1;
618
619 if ( compoundtype != TComplex ) return -1;
620
621 change_type(Float);
622
623 long i, nn, xx, yy, zz;
624 long ix, iy, iz;
625 double sx2, sy2, sz2, s2;
626
627 if ( lores <= 0 ) lores = 1e30;
628 if ( hires <= 0 ) hires = 2*sampling()[0];
629 if ( lores < hires ) swap(lores, hires);
630 double s2hi = 1/(hires*hires);
631 double s2lo = 1/(lores*lores);
632 Vector3<double> iscale(1.0/real_size());
633 Vector3<long> h((x - 1)/2, (y - 1)/2, (z - 1)/2);
634 Complex<double> cv;
635
636 if ( verbose & VERB_FULL )
637 cout << "Bandpass limit to: " << 1/sqrt(s2hi) << " - " << 1/sqrt(s2lo) << " Å" << endl;
638
639 if ( verbose & VERB_DEBUG )
640 cout << "DEBUG Bimage::complex_bandpass: hires=" << hires << " lores" << lores << endl;
641
642 for ( nn=i=0; nn<n; nn++ ) {
643 for ( zz=0; zz<z; zz++ ) {
644 iz = zz;
645 if ( zz > h[2] ) iz -= (long)z;
646 sz2 = iz*iscale[2];
647 sz2 *= sz2;
648 for ( yy=0; yy<y; yy++ ) {
649 iy = yy;
650 if ( yy > h[1] ) iy -= (long)y;
651 sy2 = iy*iscale[1];
652 sy2 *= sy2;
653 for ( xx=0; xx<x; xx++, i++ ) {
654 ix = xx;
655 if ( xx > h[0] ) ix -= (long)x;
656 sx2 = ix*iscale[0];
657 sx2 *= sx2;
658 s2 = sx2 + sy2 + sz2;
659 if ( s2 > s2hi || s2 < s2lo ) set(i, cv);
660 }
661 }
662 }
663 }
664
665 return 0;
666 }
667
679 Bimage* Bimage::pack_two_in_complex(Bimage* p)
680 {
681 if ( !d.uc ) {
682 error_show("Error in Bimage::pack_two_in_complex", __FILE__, __LINE__);
683 cerr << "No data for " << file_name() << endl;
684 return NULL;
685 }
686
687 if ( !p->data_pointer() ) {
688 error_show("Error in Bimage::pack_two_in_complex", __FILE__, __LINE__);
689 cerr << "No data for " << p->file_name() << endl;
690 return NULL;
691 }
692
693 if ( compound_type() > TSimple ) {
694 error_show("Error in Bimage::pack_two_in_complex", __FILE__, __LINE__);
695 cerr << "Data for " << file_name() << " may not be compound!" << endl;
696 return NULL;
697 }
698
699 if ( p->compound_type() > TSimple ) {
700 error_show("Error in Bimage::pack_two_in_complex", __FILE__, __LINE__);
701 cerr << "Data for " << p->file_name() << " may not be compound!" << endl;
702 return NULL;
703 }
704
705 check_if_same_size(p);
706
707 long i, j;
708
709 Bimage* pc = new Bimage(Float, TComplex, size(), n);
710
711 if ( !pc ) {
712 error_show("Bimage::pack_two_in_complex", __FILE__, __LINE__);
713 return NULL;
714 }
715
716 pc->fourier_type(NoTransform);
717 for ( i=0; i<n; i++ ) pc->image[i] = image[i];
718
719 if ( verbose & VERB_FULL )
720 cout << "Packing two real images into a complex image" << endl;
721
722 for ( i=j=0; i<datasize; i++ ) {
723 pc->set(j++, (*this)[i]);
724 pc->set(j++, (*p)[i]);
725 }
726
727 pc->check();
728
729 if ( verbose & VERB_DEBUG )
730 cout << "DEBUG Bimage::pack_two_in_complex: std=" << pc->standard_deviation() << endl;
731
732 return pc;
733 }
734
749 Bimage* Bimage::unpack_combined_transform()
750 {
751 if ( compoundtype != TComplex ) return NULL;
752
753 change_type(Float);
754
755 int use;
756 long i, j, xx, yy, zz, nn, xh(x/2 + 1);
757 long ix, iy, iz;
758 Vector3<long> h(size()/2);
759 Complex<float> temp1, temp2, cv;
760
761 Bimage* p = copy();
762
763 if ( verbose & VERB_FULL )
764 cout << "Unpacking a combined Fourier transform" << endl << endl;
765
766 for ( nn=0; nn<n; nn++ ) {
767 for ( zz=0; zz<z; zz++ ) {
768 iz = (zz>0)? z - zz: 0;
769 for ( yy=0; yy<y; yy++ ) {
770 iy = (yy>0)? y - yy: 0;
771 for ( xx=0; xx<xh; xx++ ) {
772 ix = (xx>0)? x - xx: 0;
773 use = 1;
774 if ( xx == ix ) {
775 if ( yy > h[1] ) use = 0;
776 if ( yy == iy && zz > h[2] ) use = 0;
777 }
778 if ( use ) {
779 i = index(xx, yy, zz, nn);
780 j = index(ix, iy, iz, nn);
781 temp1 = complex(i).unpack_first(complex(j));
782 temp2 = complex(i).unpack_second(complex(j));
783 set(i, temp1);
784 set(j, temp1.conj());
785 p->set(i, temp2);
786 p->set(j, temp2.conj());
787 }
788 }
789 }
790 }
791 }
792
793 return p;
794 }
795
813 int Bimage::combined_complex_product()
814 {
815 if ( !d.uc ) return -1;
816
817 if ( compound_type() != TComplex ) return -1;
818
819 change_type(Float);
820
821 int use;
822 long i, j, nn, xx, yy, zz, xh(x/2 + 1);
823 long ix, iy, iz;
824 Vector3<long> h(size()/2);
825
826 double scale(1), sum1, sum2;
827 Complex<double> temp1, temp2;
828
829 if ( verbose & VERB_FULL )
830 cout << "Calculating the complex conjugate product" << endl;
831
832 if ( verbose & VERB_DEBUG )
833 cout << "DEBUG Bimage::combined_complex_product: F0=" << complex(0).real() << " " << complex(0).imag() << endl;
834
835 double tvs = getwalltime(), tvf;
836
837 for ( nn=0; nn<n; nn++ ) {
838 sum1 = sum2 = 0;
839 for ( zz=0; zz<z; zz++ ) {
840 iz = (zz>0)? z - zz: 0;
841 for ( yy=0; yy<y; yy++ ) {
842 iy = (yy>0)? y - yy: 0;
843 for ( xx=0; xx<xh; xx++ ) {
844 ix = (xx>0)? x - xx: 0;
845 use = 1;
846 if ( xx == ix ) {
847 if ( yy > h[1] ) use = 0;
848 if ( yy == iy && zz > h[2] ) use = 0;
849 }
850 if ( use ) {
851 i = index(xx, yy, zz, nn);
852 j = index(ix, iy, iz, nn);
853 temp1 = complex(i).unpack_first(complex(j));
854 temp2 = complex(i).unpack_second(complex(j));
855 set(i, temp1 * temp2.conj());
856 set(j, complex(i).conj());
857 sum1 += temp1.power();
858 sum2 += temp2.power();
859 }
860 }
861 }
862 }
863 if ( sum1*sum2 ) {
864 scale = 0.5/sqrt(sum1*sum2);
865 multiply(nn, scale);
866 }
867 }
868
869 if ( !isfinite(scale) ) {
870 error_show("Error in Bimage::combined_complex_product", __FILE__, __LINE__);
871 cerr << "Scale not finite = " << scale << endl;
872 return -9;
873 }
874
875 if ( verbose & VERB_TIME ) {
876 tvf = getwalltime();
877 cout << "CC time: " << tvf - tvs << endl;
878 }
879
880 return 0;
881 }
882
901 int Bimage::combined_complex_product(Bimage* pmask)
902 {
903 return combined_complex_product(0, 0, pmask);
904 }
905
906
926 int Bimage::combined_complex_product(double hires, double lores)
927 {
928 return combined_complex_product(hires, lores, NULL);
929 }
930
951 int Bimage::combined_complex_product(double hires, double lores, Bimage* pmask)
952 {
953 if ( !d.uc ) return -1;
954
955 if ( compound_type() != TComplex ) return -1;
956
957 change_type(Float);
958
959 int use;
960 long i, j, nn, xx, yy, zz, xh(x/2 + 1);
961 long ix, iy, iz;
962 double sx2(0), sy2(0), sz2(0), s2;
963
964 if ( lores > 0 && lores < hires ) swap(lores, hires);
965 double s2hi = (hires > 0)? 1/(hires*hires): 0;
966 double s2lo = (lores > 0)? 1/(lores*lores): 0;
967
968 Vector3<double> iscale(1.0/real_size());
969 Vector3<long> h(size()/2);
970
971 if ( verbose & VERB_FULL ) {
972 cout << "Calculating the complex conjugate product:" << endl;
973 cout << "Resolution range: ";
974 if ( hires > 0 ) cout << 1/sqrt(s2hi) << " - ";
975 else cout << "0 - ";
976 if ( lores > 0 ) cout << 1/sqrt(s2lo) << " A" << endl;
977 else cout << "inf A" << endl;
978 if ( pmask ) cout << "Mask: " << pmask->file_name() << endl;
979 }
980
981 double scale(1), sum1, sum2;
982 Complex<double> temp1, temp2, cv(0,0);
983
984 if ( verbose & VERB_DEBUG )
985 cout << "DEBUG Bimage::combined_complex_product: F0 = " << complex(0).real() << " " << complex(0).imag() << endl;
986
987 int err(0);
988 double tvs = getwalltime(), tvf;
989
990 for ( nn=0; nn<n; nn++ ) {
991 sum1 = sum2 = 0;
992 for ( zz=0; zz<z; zz++ ) {
993 iz = (zz>0)? z - zz: 0;
994 if ( s2hi > 0 ) {
995 sz2 = zz;
996 if ( zz > h[2] ) sz2 -= (double)z;
997 sz2 *= iscale[2];
998 sz2 *= sz2;
999 }
1000 for ( yy=0; yy<y; yy++ ) {
1001 iy = (yy>0)? y - yy: 0;
1002 if ( s2hi > 0 ) {
1003 sy2 = yy;
1004 if ( yy > h[1] ) sy2 -= (double)y;
1005 sy2 *= iscale[1];
1006 sy2 *= sy2;
1007 }
1008 for ( xx=0; xx<xh; xx++ ) {
1009 ix = (xx>0)? x - xx: 0;
1010 use = 1;
1011 if ( xx == ix ) {
1012 if ( yy > h[1] ) use = 0;
1013 if ( yy == iy && zz > h[2] ) use = 0;
1014 }
1015 i = index(xx, yy, zz, nn);
1016 j = index(ix, iy, iz, nn);
1017 if ( use ) {
1018 if ( s2hi > 0 ) {
1019 sx2 = xx;
1020 if ( xx > h[0] ) sx2 -= (double)x;
1021 sx2 *= iscale[0];
1022 sx2 *= sx2;
1023 s2 = sx2 + sy2 + sz2;
1024 if ( s2 < s2lo || s2 > s2hi ) use = 0;
1025 }
1026 if ( pmask && (*pmask)[i] <= 0 ) use = 0;
1027 if ( use ) {
1028 temp1 = complex(i).unpack_first(complex(j));
1029 temp2 = complex(i).unpack_second(complex(j));
1030 set(i, temp1 * temp2.conj());
1031 set(j, complex(i).conj());
1032 sum1 += temp1.power();
1033 sum2 += temp2.power();
1034 } else {
1035 set(i, cv);
1036 set(j, cv);
1037 }
1038 }
1039 }
1040 }
1041 }
1042 scale = sum1*sum2;
1043 if ( scale > 0 ) {
1044 scale = 0.5/sqrt(scale);
1045 multiply(nn, scale);
1046 } else {
1047 cerr << "Error in Bimage::combined_complex_product: scaling failed!" << endl;
1048 err--;
1049 }
1050 }
1051
1052 if ( verbose & VERB_TIME ) {
1053 tvf = getwalltime();
1054 cout << "CC(BP) time: " << tvf - tvs << endl;
1055 }
1056
1057 if ( err ) {
1058 error_show("Error in Bimage::combined_complex_product", __FILE__, __LINE__);
1059 cerr << "Number of scaling errors: " << err << " (" << n << ")" << endl;
1060 }
1061
1062 return err;
1063 }
1064
1085 int Bimage::combined_complex_product_implicit_mask(double hires, double lores)
1086 {
1087 if ( !d.uc ) return -1;
1088
1089 if ( compound_type() != TComplex ) return -1;
1090
1091 change_type(Float);
1092
1093 int use;
1094 long i, j, nn, xx, yy, zz, xh(x/2 + 1);
1095 long ix, iy, iz;
1096 double sx2(0), sy2(0), sz2(0), s2, tp1, tp2;
1097
1098 if ( lores > 0 && lores < hires ) swap(lores, hires);
1099 double s2hi = (hires > 0)? 1/(hires*hires): 0;
1100 double s2lo = (lores > 0)? 1/(lores*lores): 0;
1101
1102 Vector3<double> iscale(1.0/real_size());
1103 Vector3<long> h(size()/2);
1104
1105 if ( verbose & VERB_FULL ) {
1106 cout << "Calculating the complex conjugate product:" << endl;
1107 cout << "Resolution range: ";
1108 if ( hires > 0 ) cout << 1/sqrt(s2hi) << " - ";
1109 else cout << "0 - ";
1110 if ( lores > 0 ) cout << 1/sqrt(s2lo) << " A" << endl;
1111 else cout << "inf A" << endl;
1112 cout << "Implicit mask" << endl;
1113 }
1114
1115 double scale(1), sum1, sum2;
1116 Complex<double> temp1, temp2, cv;
1117
1118 if ( verbose & VERB_DEBUG )
1119 cout << "DEBUG Bimage::combined_complex_product: F0 = " << complex(0).real() << " " << complex(0).imag() << endl;
1120
1121 int err(0);
1122 double tvs = getwalltime(), tvf;
1123
1124 for ( nn=0; nn<n; nn++ ) {
1125 sum1 = sum2 = 0;
1126 for ( zz=0; zz<z; zz++ ) {
1127 iz = (zz>0)? z - zz: 0;
1128 if ( s2hi > 0 ) {
1129 sz2 = zz;
1130 if ( zz > h[2] ) sz2 -= (double)z;
1131 sz2 *= iscale[2];
1132 sz2 *= sz2;
1133 }
1134 for ( yy=0; yy<y; yy++ ) {
1135 iy = (yy>0)? y - yy: 0;
1136 if ( s2hi > 0 ) {
1137 sy2 = yy;
1138 if ( yy > h[1] ) sy2 -= (double)y;
1139 sy2 *= iscale[1];
1140 sy2 *= sy2;
1141 }
1142 for ( xx=0; xx<xh; xx++ ) {
1143 ix = (xx>0)? x - xx: 0;
1144 use = 1;
1145 if ( xx == ix ) {
1146 if ( yy > h[1] ) use = 0;
1147 if ( yy == iy && zz > h[2] ) use = 0;
1148 }
1149 i = index(xx, yy, zz, nn);
1150 j = index(ix, iy, iz, nn);
1151 if ( use ) {
1152 if ( s2hi > 0 ) {
1153 sx2 = xx;
1154 if ( xx > h[0] ) sx2 -= (double)x;
1155 sx2 *= iscale[0];
1156 sx2 *= sx2;
1157 s2 = sx2 + sy2 + sz2;
1158 if ( s2 < s2lo || s2 > s2hi ) use = 0;
1159 }
1160 if ( use ) {
1161 temp1 = complex(i).unpack_first(complex(j));
1162 tp1 = temp1.power();
1163 if ( tp1 < SMALLFLOAT ) {
1164 use = 0;
1165 } else {
1166 temp2 = complex(i).unpack_second(complex(j));
1167 tp2 = temp2.power();
1168 if ( tp2 < SMALLFLOAT ) use = 0;
1169 }
1170 }
1171 if ( use ) {
1172 set(i, temp1 * temp2.conj());
1173 set(j, complex(i).conj());
1174 sum1 += temp1.power();
1175 sum2 += temp2.power();
1176 } else {
1177 set(i, cv);
1178 set(j, cv);
1179 }
1180 }
1181 }
1182 }
1183 }
1184 scale = sum1*sum2;
1185 if ( scale > 0 ) {
1186 scale = 0.5/sqrt(scale);
1187 multiply(nn, scale);
1188 } else {
1189 cerr << "Error in Bimage::combined_complex_product: scaling failed!" << endl;
1190 err--;
1191 }
1192 }
1193
1194 if ( verbose & VERB_TIME ) {
1195 tvf = getwalltime();
1196 cout << "CC(BP) time: " << tvf - tvs << endl;
1197 }
1198
1199 if ( err ) {
1200 error_show("Error in Bimage::combined_complex_product", __FILE__, __LINE__);
1201 cerr << "Number of scaling errors: " << err << " (" << n << ")" << endl;
1202 }
1203
1204 return err;
1205 }
1206
1218 double Bimage::merge_amplitudes_and_phases(Bimage* pamp)
1219 {
1220 if ( !d.uc ) return -1;
1221 if ( !pamp ) return -1;
1222
1223 if ( compound_type() != TComplex ) return -1;
1224
1225 change_type(Float);
1226
1227 pamp->change_type(Float);
1228
1229 if ( verbose & VERB_FULL )
1230 cout << "Merging amplitudes and phases" << endl << endl;
1231
1232 long i, ds(x*y*z*n);
1233 double a, ar, d, R(0);
1234 Complex<double> cv;
1235
1236 for ( i=0; i<ds; i++ ) {
1237 cv = complex(i);
1238 a = cv.amp();
1239 if ( pamp->compound_type() == TSimple ) ar = (*pamp)[i];
1240 else ar = (pamp->complex(i)).amp();
1241 d = a - ar;
1242 R += d*d;
1243 cv.amp(ar);
1244 set(i, cv);
1245 }
1246
1247 R = sqrt(R/ds);
1248
1249 return R;
1250 }
1251
1266 double Bimage::merge_amplitudes_and_phases(Bimage* pref, double res_hi, double res_lo)
1267 {
1268 if ( !d.uc ) return -1;
1269 if ( !pref ) return -1;
1270
1271 if ( pref->compound_type() != TComplex ) {
1272 cerr << "Error: The reference map must be a Fourier transform!" << endl << endl;
1273 return -1;
1274 }
1275
1276 change_type(Float);
1277
1278 pref->change_type(Float);
1279
1280 if ( res_hi < sampling()[0] ) res_hi = sampling()[0];
1281 if ( res_lo < res_hi ) res_lo = res_hi;
1282
1283 if ( verbose & VERB_FULL )
1284 cout << "Merging amplitudes and phases in the range " << res_hi << " - " << res_lo << " Å" << endl << endl;
1285
1286 double minrad = real_size()[0]/res_lo;
1287 double maxrad = real_size()[0]/res_hi;
1288 if ( maxrad < minrad + 1 ) maxrad = minrad + 1;
1289 double minrad2 = minrad*minrad, maxrad2 = maxrad*maxrad;
1290
1291 long i, nn, xx, yy, zz, na(0);
1292 double x2, y2, z2, r2;
1293 Vector3<long> h((x - 1)/2, (y - 1)/2, (z - 1)/2);
1294
1295 double a, ar, d, R(0);
1296 Complex<double> cv;
1297
1298 for ( i=nn=0; nn<n; nn++ ) {
1299 for ( zz=0; zz<z; zz++ ) {
1300 z2 = zz;
1301 if ( zz > h[2] ) z2 -= (long)z;
1302 z2 *= z2;
1303 for ( yy=0; yy<y; yy++ ) {
1304 y2 = yy;
1305 if ( yy > h[1] ) y2 -= (long)y;
1306 y2 *= y2;
1307 for ( xx=0; xx<x; xx++, i++ ) {
1308 x2 = xx;
1309 if ( xx > h[0] ) x2 -= (long)x;
1310 x2 *= x2;
1311 r2 = x2 + y2 + z2;
1312 cv = (*this)[i];
1313 if ( r2 > maxrad2 ) { // Low-pass filter
1314 cv = 0;
1315 } else if ( r2 < minrad2 ) { // Keep original low-frequency data
1316 cv = pref->complex(i);
1317 } else { // Reset to the original amplitudes
1318 a = cv.amp();
1319 ar = (pref->complex(i)).amp();
1320 d = a - ar;
1321 R += d*d;
1322 na++;
1323 cv.amp(ar);
1324 }
1325 set(i, cv);
1326 }
1327 }
1328 }
1329 }
1330
1331 if ( na ) R = sqrt(R/na);
1332
1333 if ( verbose & VERB_DEBUG )
1334 cout << "DEBUG Bimage::merge_amplitudes_and_phases: minrad=" << minrad
1335 << " maxrad=" << maxrad << " n=" << n << " R" << R << endl;
1336
1337 return R;
1338 }
1339
1358 Bimage* Bimage::intensities_phase_colored(double scale)
1359 {
1360 if ( compound_type() != TComplex ) return NULL;
1361
1362 change_type(Float);
1363
1364 statistics();
1365
1366 if ( verbose & VERB_PROCESS ) {
1367 cout << "Generating a phase-colored power spectrum" << endl;
1368 } else if ( verbose & VERB_LABEL )
1369 cout << "Generating a phase-colored power spectrum" << endl;
1370
1371 long i, ds(x*y*z*n);
1372 double amp_ratio;
1373
1374 if ( scale <= 0 ) scale = 1/(avg + std);
1375 else scale /= avg + std;
1376
1377 scale *= 255;
1378
1379 // Shift the phases
1380 phase_shift_to_origin();
1381
1382 Bimage* ps = new Bimage(UCharacter, TRGB, size(), n);
1383
1384 RGB<unsigned char> rgb;
1385
1386 for ( i=0; i<ds; i++ ) {
1387 amp_ratio = (complex(i)).amp()*scale; // Weigh with amplitudes
1388 if ( amp_ratio > 0 ) {
1389 if ( amp_ratio > 255 ) amp_ratio = 255;
1390 rgb.phase((complex(i)).phi(), amp_ratio);
1391 ps->set(i, rgb);
1392 }
1393 }
1394
1395 ps->center_wrap();
1396
1397 return ps;
1398 }
1399
1400
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1743
Bimage::phase_shift
int phase_shift(Vector3< double > shift)
Phase shifts a complex image.
Definition: Bimage_complex.cpp:256
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::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
Bimage::file_name
string & file_name()
Definition: Bimage.h:231
verbose
int verbose
SMALLFLOAT
#define SMALLFLOAT
Definition: utilities.h:45
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
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
Bimage::compound_type
CompoundType compound_type()
Definition: Bimage.h:351
Bimage::index
long index(long nx, long ny) const
Definition: Bimage.h:383
Complex::conj
Complex conj()
Definition: Complex.h:106
Bimage::complex
Complex< double > complex(long j)
Returns a complex value at the given index.
Definition: Bimage.cpp:1005
Bimage::merge_amplitudes_and_phases
double merge_amplitudes_and_phases(Bimage *pamp)
Merges the amplitudes from one map with the phases of another.
Definition: Bimage_complex.cpp:1218
TypePointer::uc
unsigned char * uc
Definition: Bimage.h:69
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
Bimage::check
void check()
Checks an image for reasonable properties.
Definition: Bimage.cpp:389
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::center_wrap
int center_wrap()
Centers an image with wrapping.
Definition: Bimage_transform.cpp:713
getwalltime
double getwalltime()
Returns the current time.
Definition: timer.cpp:23
TComplex
Definition: Bimage.h:59
Bimage::Bimage
Bimage()
Initializes an image.
Definition: Bimage.cpp:44
Bimage::check_if_same_image_size
bool check_if_same_image_size(Bimage *p)
Check if two images are the same size.
Definition: Bimage.cpp:562
TCMYK
Definition: Bimage.h:64
Complex::shift_phi
void shift_phi(const double d)
Definition: Complex.h:112
Bimage::complex_conjugate
void complex_conjugate()
Calculates the complex conjugate image.
Definition: Bimage_complex.cpp:183
TSimple
Definition: Bimage.h:58
timer.h
Utilities for timing functions.
Bimage::complex_to_amplitudes
void complex_to_amplitudes()
The amplitudes from a complex image is written to a simple image.
Definition: Bimage_complex.cpp:114
Float
Definition: utilities.h:157
Bimage
General image parameter class.
Definition: Bimage.h:163
Bimage::real_size
Vector3< double > real_size()
Definition: Bimage.h:487
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
isfinite
bool isfinite(complex< T > &value)
Bimage::shift
int shift(Vector3< double > vec, int fill_type=0, double fill=0)
Shifts an image.
Definition: Bimage_transform.cpp:587
Bimage::complex_to_signed_amplitudes
void complex_to_signed_amplitudes()
The signed amplitudes from a complex image is written to a simple image.
Definition: Bimage_complex.cpp:136
Bimage::phase_shift_to_center
int phase_shift_to_center()
Phase shifts a set of reflections to the nominal center of the image origin.
Definition: Bimage_complex.cpp:382
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
Bimage::data_assign
unsigned char * data_assign(unsigned char *nudata)
Assign image data.
Definition: Bimage.cpp:852
VERB_TIME
#define VERB_TIME
Definition: utilities.h:110
Bsub_image::FOM
double FOM()
Definition: Bimage.h:151
Bimage::simple_to_complex
void simple_to_complex()
A simple image is converted to a complex image.
Definition: Bimage_complex.cpp:22
RGB
Definition: Color.h:24
Complex::amp
double amp()
Definition: Complex.h:104
Bimage::phase_shift_to_origin
int phase_shift_to_origin()
Phase shifts a set of reflections to the image origin.
Definition: Bimage_complex.cpp:327
use
const char * use[]
Definition: b3v.cpp:19
Bimage::complex_to_intensities
void complex_to_intensities()
The intensities from a complex image is written to a simple image.
Definition: Bimage_complex.cpp:92
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
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:127
Bimage::rgb
RGB< double > rgb(long j)
Returns a color value at the given index.
Definition: Bimage.cpp:1033
Bimage::standard_deviation
double standard_deviation()
Definition: Bimage.h:537
Bimage::set
void set(long j, double v)
Sets a single value at the given index.
Definition: Bimage.cpp:1096
TRGB
Definition: Bimage.h:62
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
MIN2PI
#define MIN2PI
Definition: utilities.h:71
Bimage::data_pointer
unsigned char * data_pointer()
Definition: Bimage.h:261
Bimage::complex_conjugate_product_one2many
Bimage * complex_conjugate_product_one2many(Bimage *p)
Calculates the product of a complex image with the conjugate of a second.
Definition: Bimage_complex.cpp:490
UCharacter
Definition: utilities.h:149
Bimage::copy
Bimage * copy()
Copies the header information and data of an image into a new image structure.
Definition: Bimage.cpp:2695
Bimage::complex_to_imaginary
void complex_to_imaginary()
The imaginary part of a complex image is written to a simple image.
Definition: Bimage_complex.cpp:71
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 >
Bimage::complex_normalize
double complex_normalize()
Normalizes the power in a complex image.
Definition: Bimage_complex.cpp:225
Bimage::complex_bandpass
int complex_bandpass(double hires, double lores)
Bandpasses a Fourier transform.
Definition: Bimage_complex.cpp:615
Bimage::complex_to_phases
void complex_to_phases()
The phases from a complex image is written to a simple image.
Definition: Bimage_complex.cpp:161
Bimage::color_to_simple
void color_to_simple()
A color image is converted to a simple image.
Definition: Bimage_color.cpp:94
Bimage::check_if_same_size
bool check_if_same_size(Bimage *p)
Check if two images are the same size.
Definition: Bimage.cpp:536
Complex::power
double power()
Definition: Complex.h:103
TRGBA
Definition: Bimage.h:63
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::complex_multiply
int complex_multiply(Bimage *p)
Calculates the product of a complex image with a simple image.
Definition: Bimage_complex.cpp:400
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
Bimage::complex_apply_negative_mask
int complex_apply_negative_mask(Bimage *pmask)
Applies a negative mask to a complex image.
Definition: Bimage_complex.cpp:550
VERB_LABEL
#define VERB_LABEL
Definition: utilities.h:106
Bimage::data_type
DataType data_type()
Definition: Bimage.h:349
Bimage::intensities_phase_colored
Bimage * intensities_phase_colored(double scale)
Generates a power spectrum with phases colored according to a color wheel.
Definition: Bimage_complex.cpp:1358
TWOPI
#define TWOPI
Definition: utilities.h:68
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::image
Bsub_image * image
Definition: Bimage.h:188
Bimage::origin
void origin(double ox, double oy, double oz)
Definition: Bimage.h:563