| Bsoft 1.9 Bernard's software package

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
img_complex.cpp
Go to the documentation of this file.
1
9 #include "rwimg.h"
10 #include "img_complex.h"
11 #include "img_colour.h"
12 #include "timer.h"
13 #include "utilities.h"
14
15 // Declaration of global variables
16 extern int verbose; // Level of output to the screen
17
30 int img_complex_product(Bimage* p, Bimage* p2)
31 {
32 if ( !p ) return -1;
33
34 if ( p->compound_type() != TComplex || p2->compound_type() != TComplex ) return -1;
35
36 p->change_type(Float);
37 p2->change_type(Float);
38
39 if ( verbose & VERB_FULL )
40 cout << "Calculating the complex product" << endl << endl;
41
42 unsigned long i, datasize = p->sizeX()*p->sizeY()*p->sizeZ()*p->images();
43
44 for ( i=0; i<datasize; i++ ) p->set(i, p->complex(i) * p2->complex(i));
45
46 return 0;
47 }
48
61 int img_complex_conjugate_product(Bimage* p, Bimage* p2)
62 {
63 if ( !p ) return -1;
64
65 if ( p->compound_type() != TComplex || p2->compound_type() != TComplex ) return -1;
66
67 p->change_type(Float);
68 p2->change_type(Float);
69
70 if ( verbose & VERB_FULL )
71 cout << "Calculating the complex product" << endl << endl;
72
73 unsigned long i, datasize = p->sizeX()*p->sizeY()*p->sizeZ()*p->images();
74
75 for ( i=0; i<datasize; i++ ) p->set(i, p->complex(i) * (p2->complex(i)).conj());
76
77 return 0;
78 }
79
91 int img_complex_apply_mask(Bimage* p, Bimage* pmask)
92 {
93 if ( !p ) return -1;
94 if ( !pmask ) return -1;
95
96 pmask->change_type(Float);
97
98 if ( verbose & VERB_FULL )
99 cout << "Masking a complex image" << endl;
100
101 unsigned long i, datasize = p->sizeX()*p->sizeY()*p->sizeZ()*p->images();
102 Complex<double> cv;
103
104 for ( i=0; i<datasize; i++ )
105 if ( (*pmask)[i] <= 0 ) p->set(i, cv);
106
107 return 0;
108 }
109
121 int img_complex_apply_negative_mask(Bimage* p, Bimage* pmask)
122 {
123 if ( !p ) return -1;
124 if ( !pmask ) return -1;
125
126 pmask->change_type(Float);
127
128 if ( verbose & VERB_FULL )
129 cout << "Masking a complex image" << endl;
130
131 unsigned long i, datasize = p->sizeX()*p->sizeY()*p->sizeZ()*p->images();
132 Complex<double> cv;
133
134 for ( i=0; i<datasize; i++ )
135 if ( (*pmask)[i] >= 0 ) p->set(i, cv);
136
137 return 0;
138 }
139
155 int img_complex_apply_dual_mask(Bimage* p, Bimage* pmask)
156 {
157 if ( !p ) return -1;
158 if ( !pmask ) return -1;
159
160 pmask->change_type(Float);
161
162 if ( verbose & VERB_FULL )
163 cout << "Masking a complex image with a dual mask" << endl;
164
165 Bimage* p2 = p->copy();
166 p->next = p2;
167
168 unsigned long i, datasize = p->sizeX()*p->sizeY()*p->sizeZ()*p->images();
169 Complex<double> cv;
170
171 for ( i=0; i<datasize; i++ ) {
172 if ( (*pmask)[i] <= 0 ) p->set(i, cv);
173 if ( (*pmask)[i] >= 0 ) p2->set(i, cv);
174 }
175
176 return 0;
177 }
178
190 int img_complex_bandpass(Bimage* p, float hires, float lores)
191 {
192 if ( !p ) return -1;
193
194 if ( p->compound_type() != TComplex ) return -1;
195
196 p->change_type(Float);
197
198 unsigned long i, n, x, y, z;
199 long xx, yy, zz;
200 double sx2, sy2, sz2, s2;
201
202 if ( lores <= 0 ) lores = 1e30;
203 if ( hires <= 0 ) hires = 2*p->sampling().x();
204 if ( lores < hires ) swap(lores, hires);
205 double s2hi = 1/(hires*hires);
206 double s2lo = 1/(lores*lores);
207 Vector3<double> iscale(1.0/p->real_size());
208 Vector3<int> h((p->sizeX() - 1)/2, (p->sizeY() - 1)/2, (p->sizeZ() - 1)/2);
209 Complex<double> cv;
210
211 if ( verbose & VERB_FULL )
212 cout << "Bandpass limit to: " << 1/sqrt(s2hi) << " - " << 1/sqrt(s2lo) << " Å" << endl;
213
214 if ( verbose & VERB_DEBUG )
215 cout << "DEBUG img_complex_bandpass: hires=" << hires << " lores" << lores << endl;
216
217 for ( n=i=0; n<p->images(); n++ ) {
218 for ( z=0; z<p->sizeZ(); z++ ) {
219 zz = z;
220 if ( z > h.z() ) zz -= p->sizeZ();
221 sz2 = zz*iscale.z();
222 sz2 *= sz2;
223 for ( y=0; y<p->sizeY(); y++ ) {
224 yy = y;
225 if ( y > h.y() ) yy -= p->sizeY();
226 sy2 = yy*iscale.y();
227 sy2 *= sy2;
228 for ( x=0; x<p->sizeX(); x++, i++ ) {
229 xx = x;
230 if ( x > h.x() ) xx -= p->sizeX();
231 sx2 = xx*iscale.x();
232 sx2 *= sx2;
233 s2 = sx2 + sy2 + sz2;
234 if ( s2 > s2hi || s2 < s2lo ) p->set(i, cv);
235 }
236 }
237 }
238 }
239
240 return 0;
241 }
242
255 Bimage* img_pack_two_in_complex(Bimage* p1, Bimage* p2)
256 {
257 if ( !p1->data_pointer() ) {
258 error_show("Error in img_pack_two_in_complex", __FILE__, __LINE__);
259 cerr << "No data for " << p1->file_name() << endl;
260 return NULL;
261 }
262
263 if ( !p2->data_pointer() ) {
264 error_show("Error in img_pack_two_in_complex", __FILE__, __LINE__);
265 cerr << "No data for " << p2->file_name() << endl;
266 return NULL;
267 }
268
269 if ( p1->compound_type() > TSimple ) {
270 error_show("Error in img_pack_two_in_complex", __FILE__, __LINE__);
271 cerr << "Data for " << p1->file_name() << " may not be compound!" << endl;
272 return NULL;
273 }
274
275 if ( p2->compound_type() > TSimple ) {
276 error_show("Error in img_pack_two_in_complex", __FILE__, __LINE__);
277 cerr << "Data for " << p2->file_name() << " may not be compound!" << endl;
278 return NULL;
279 }
280
281 p1->check_if_same_size(p2);
282
283 unsigned long i, j;
284
285 Bimage* p = new Bimage(Float, TComplex, p1->size(), p1->images());
286
287 if ( !p ) {
288 error_show("img_pack_two_in_complex", __FILE__, __LINE__);
289 return NULL;
290 }
291
292 p->fourier_type(NoTransform);
293 p->sampling(p1->sampling());
294 for ( i=0; i<p->images(); i++ ) p->image[i] = p1->image[i];
295
296 if ( verbose & VERB_FULL )
297 cout << "Packing two real images into a complex image" << endl;
298
299 unsigned long datasize = p1->data_size();
300
301 for ( i=j=0; i<datasize; i++ ) {
302 p->set(j++, (*p1)[i]);
303 p->set(j++, (*p2)[i]);
304 }
305
306 p->statistics();
307
308 p->check();
309
310 if ( verbose & VERB_DEBUG )
311 cout << "DEBUG img_pack_two_in_complex: std=" << p->standard_deviation() << endl;
312
313 return p;
314 }
315
331 Bimage* img_unpack_combined_transform(Bimage* p)
332 {
333 if ( p->compound_type() != TComplex ) return NULL;
334
335 p->change_type(Float);
336
337 int use;
338 unsigned long i, j, x, y, z, n, xh = p->sizeX()/2 + 1;
339 unsigned long ix, iy, iz;
340 Vector3<int> h(p->size()/2);
341 Complex<float> temp1, temp2, cv;
342
343 Bimage* p2 = p->copy();
344
345 // Bimage* pd = new Bimage(Float, TSimple, p->sizeX(),
346 // p->sizeY(), p->sizeZ(), p->images());
347
348 if ( verbose & VERB_FULL )
349 cout << "Unpacking a combined Fourier transform" << endl << endl;
350
351 for ( n=0; n<p->images(); n++ ) {
352 for ( z=0; z<p->sizeZ(); z++ ) {
353 iz = (z>0)? p->sizeZ() - z: 0;
354 for ( y=0; y<p->sizeY(); y++ ) {
355 iy = (y>0)? p->sizeY() - y: 0;
356 for ( x=0; x<xh; x++ ) {
357 ix = (x>0)? p->sizeX() - x: 0;
358 use = 1;
359 if ( x == ix ) {
360 if ( y > h.y() ) use = 0;
361 if ( y == iy && z > h.z() ) use = 0;
362 }
363 if ( use ) {
364 i = p->index(x, y, z, n);
365 j = p->index(ix, iy, iz, n);
366 temp1 = p->complex(i).unpack_first(p->complex(j));
367 temp2 = p->complex(i).unpack_second(p->complex(j));
368 p->set(i, temp1);
369 p->set(j, temp1.conj());
370 p2->set(i, temp2);
371 p2->set(j, temp2.conj());
372 // pd->add(i, 1);
373 // pd->add(j, 1);
374 }
375 }
376 }
377 }
378 }
379
380 // write_img("m.map", pd);
381 // delete pd;
382
383 return p2;
384 }
385
404 int img_combined_complex_product(Bimage* p)
405 {
406 if ( !p ) return -1;
407
408 if ( p->compound_type() != TComplex ) return -1;
409
410 p->change_type(Float);
411
412 int use;
413 unsigned long i, j, n, x, y, z, xh = p->sizeX()/2 + 1;
414 unsigned long ix, iy, iz;
415 Vector3<int> h(p->size()/2);
416
417 unsigned long imgsize = p->sizeX()*p->sizeY()*p->sizeZ()*p->channels();
418 double scale = 1, sum1, sum2;
419 Complex<double> temp1, temp2;
420
421 if ( verbose & VERB_FULL )
422 cout << "Calculating the complex conjugate product" << endl;
423
424 if ( verbose & VERB_DEBUG )
425 cout << "DEBUG img_combined_complex_product: F0=" << p->complex(0).real() << " " << p->complex(0).imag() << endl;
426
427 double tvs = getwalltime(), tvf;
428
429 for ( n=0; n<p->images(); n++ ) {
430 sum1 = sum2 = 0;
431 for ( z=0; z<p->sizeZ(); z++ ) {
432 iz = (z>0)? p->sizeZ() - z: 0;
433 for ( y=0; y<p->sizeY(); y++ ) {
434 iy = (y>0)? p->sizeY() - y: 0;
435 for ( x=0; x<xh; x++ ) {
436 ix = (x>0)? p->sizeX() - x: 0;
437 use = 1;
438 if ( x == ix ) {
439 if ( y > h.y() ) use = 0;
440 if ( y == iy && z > h.z() ) use = 0;
441 }
442 if ( use ) {
443 i = p->index(x, y, z, n);
444 j = p->index(ix, iy, iz, n);
445 temp1 = p->complex(i).unpack_first(p->complex(j));
446 temp2 = p->complex(i).unpack_second(p->complex(j));
447 p->set(i, temp1 * temp2.conj());
448 p->set(j, p->complex(i).conj());
449 sum1 += temp1.power();
450 sum2 += temp2.power();
451 }
452 }
453 }
454 }
455 if ( sum1*sum2 ) {
456 scale = 0.5/sqrt(sum1*sum2);
457 p->multiply(n, scale);
458 }
459 }
460
461 if ( !isfinite(scale) ) {
462 error_show("Error in img_combined_complex_product", __FILE__, __LINE__);
463 cerr << "Scale not finite = " << scale << endl;
464 return -9;
465 }
466
467 if ( verbose & VERB_TIME ) {
468 tvf = getwalltime();
469 cout << "CC time: " << tvf - tvs << endl;
470 }
471
472 return 0;
473 }
474
494 int img_combined_masked_complex_product(Bimage* p, Bimage* pmask)
495 {
496 if ( !p ) return -1;
497
498 if ( !pmask ) return img_combined_complex_product(p);
499
500 if ( p->compound_type() != TComplex ) return -1;
501
502 p->change_type(Float);
503
504 pmask->change_type(Float);
505
506 int use;
507 unsigned long i, j, n, x, y, z, xh = p->sizeX()/2 + 1;
508 unsigned long ix, iy, iz;
509 // Vector3<int> h((p->sizeX() - 1)/2, (p->sizeY() - 1)/2, (p->sizeZ() - 1)/2);
510 Vector3<int> h(p->size()/2);
511
512 unsigned long imgsize = p->sizeX()*p->sizeY()*p->sizeZ()*p->channels();
513 double scale = 1, sum1, sum2;
514 Complex<double> temp1, temp2, cv;
515
516 if ( verbose & VERB_FULL )
517 cout << "Calculating the masked complex conjugate product" << endl;
518
519 if ( verbose & VERB_DEBUG )
520 cout << "DEBUG img_combined_masked_complex_product: F0 = " << p->complex(0).real() << " " << p->complex(0).imag() << endl;
521 // cout << "DEBUG img_combined_masked_complex_product: F0 = " << p->complex(0) << endl;
522
523 for ( n=0; n<p->images(); n++ ) {
524 sum1 = sum2 = 0;
525 for ( z=0; z<p->sizeZ(); z++ ) {
526 iz = (z>0)? p->sizeZ() - z: 0;
527 for ( y=0; y<p->sizeY(); y++ ) {
528 iy = (y>0)? p->sizeY() - y: 0;
529 for ( x=0; x<xh; x++ ) {
530 ix = (x>0)? p->sizeX() - x: 0;
531 use = 1;
532 if ( x == ix ) {
533 if ( y > h.y() ) use = 0;
534 if ( y == iy && z > h.z() ) use = 0;
535 }
536 if ( use ) {
537 i = p->index(x, y, z, n);
538 j = p->index(ix, iy, iz, n);
539 if ( (*pmask)[i] > 0 ) {
540 temp1 = p->complex(i).unpack_first(p->complex(j));
541 temp2 = p->complex(i).unpack_second(p->complex(j));
542 p->set(i, temp1 * temp2.conj());
543 p->set(j, p->complex(i).conj());
544 sum1 += temp1.power();
545 sum2 += temp2.power();
546 } else {
547 p->set(i, cv);
548 p->set(j, cv);
549 }
550 }
551 }
552 }
553 }
554 if ( sum1*sum2 ) {
555 scale = 0.5/sqrt(sum1*sum2);
556 p->multiply(n, scale);
557 }
558 }
559
560 if ( !isfinite(scale) ) {
561 error_show("Error in img_combined_bandpass_complex_product", __FILE__, __LINE__);
562 cerr << "Scale not finite = " << scale << endl;
563 return -9;
564 }
565
566 return 0;
567 }
568
589 int img_combined_bandpass_complex_product(Bimage* p, float hires, float lores)
590 {
591 if ( !p ) return -1;
592
593 if ( p->compound_type() != TComplex ) return -1;
594
595 p->change_type(Float);
596
597 int use;
598 unsigned long i, j,n, x, y, z, xh = p->sizeX()/2 + 1;
599 unsigned long ix, iy, iz;
600 long xx, yy, zz;
601 double sx2, sy2, sz2, s2;
602
603 if ( hires <= 0 ) hires = p->sampling().x();
604 if ( lores > 0 && lores < hires ) swap(lores, hires);
605 double s2hi = 1/(hires*hires);
606 double s2lo = (lores > 0)? 1/(lores*lores): 0;
607
608 Vector3<double> iscale(1.0/p->real_size());
609 Vector3<int> h(p->size()/2);
610
611 if ( verbose & VERB_FULL ) {
612 cout << "Calculating the complex conjugate product" << endl;
613 cout << "Resolution range: " << 1/sqrt(s2hi) << " - ";
614 if ( lores > 0 ) cout << 1/sqrt(s2lo) << " A" << endl;
615 else cout << "inf A" << endl;
616 }
617
618 unsigned long imgsize = p->sizeX()*p->sizeY()*p->sizeZ()*p->channels();
619 double scale = 1, sum1, sum2;
620 Complex<double> temp1, temp2, cv;
621
622 if ( verbose & VERB_DEBUG )
623 cout << "DEBUG img_combined_bandpass_complex_product: F0 = " << p->complex(0).real() << " " << p->complex(0).imag() << endl;
624
625 double tvs = getwalltime(), tvf;
626
627 for ( n=0; n<p->images(); n++ ) {
628 sum1 = sum2 = 0;
629 for ( z=0; z<p->sizeZ(); z++ ) {
630 zz = z;
631 if ( z > h.z() ) zz -= p->sizeZ();
632 iz = (z>0)? p->sizeZ() - z: 0;
633 sz2 = zz*iscale.z();
634 sz2 *= sz2;
635 for ( y=0; y<p->sizeY(); y++ ) {
636 yy = y;
637 if ( y > h.y() ) yy -= p->sizeY();
638 iy = (y>0)? p->sizeY() - y: 0;
639 sy2 = yy*iscale.y();
640 sy2 *= sy2;
641 for ( x=0; x<xh; x++ ) {
642 ix = (x>0)? p->sizeX() - x: 0;
643 use = 1;
644 if ( x == ix ) {
645 if ( y > h.y() ) use = 0;
646 if ( y == iy && z > h.z() ) use = 0;
647 }
648 if ( use ) {
649 xx = x;
650 if ( x > h.x() ) xx -= p->sizeX();
651 sx2 = xx*iscale.x();
652 sx2 *= sx2;
653 i = p->index(x, y, z, n);
654 j = p->index(ix, iy, iz, n);
655 s2 = sx2 + sy2 + sz2;
656 if ( s2 >= s2lo && s2 <= s2hi ) {
657 temp1 = p->complex(i).unpack_first(p->complex(j));
658 temp2 = p->complex(i).unpack_second(p->complex(j));
659 p->set(i, temp1 * temp2.conj());
660 p->set(j, p->complex(i).conj());
661 sum1 += temp1.power();
662 sum2 += temp2.power();
663 } else {
664 p->set(i, cv);
665 p->set(j, cv);
666 }
667 }
668 }
669 }
670 }
671 if ( sum1*sum2 ) {
672 scale = 0.5/sqrt(sum1*sum2);
673 p->multiply(n, scale);
674 }
675 }
676
677 if ( !isfinite(scale) ) {
678 error_show("Error in img_combined_bandpass_complex_product", __FILE__, __LINE__);
679 cerr << "Scale not finite = " << scale << endl;
680 return -9;
681 }
682
683 if ( verbose & VERB_TIME ) {
684 tvf = getwalltime();
685 cout << "CC(BP) time: " << tvf - tvs << endl;
686 }
687
688 return 0;
689 }
690
712 int img_combined_bandpass_masked_complex_product(Bimage* p, float hires, float lores, Bimage* pmask)
713 {
714 if ( !p ) return -1;
715
716 if ( !pmask ) return img_combined_bandpass_complex_product(p, hires, lores);
717
718 if ( p->compound_type() != TComplex ) return -1;
719
720 p->change_type(Float);
721
722 int use;
723 unsigned long i, j,n, x, y, z, xh = p->sizeX()/2 + 1;
724 unsigned long ix, iy, iz;
725 long xx, yy, zz;
726 double sx2, sy2, sz2, s2;
727
728 if ( hires <= 0 ) hires = p->sampling().x();
729 if ( lores > 0 && lores < hires ) swap(lores, hires);
730 double s2hi = 1/(hires*hires);
731 double s2lo = (lores > 0)? 1/(lores*lores): 0;
732
733 Vector3<double> iscale(1.0/p->real_size());
734 Vector3<int> h(p->size()/2);
735
736 if ( verbose & VERB_FULL ) {
737 cout << "Calculating the masked and bandpassed complex conjugate product" << endl;
738 cout << "Resolution range: " << 1/sqrt(s2hi) << " - ";
739 if ( lores > 0 ) cout << 1/sqrt(s2lo) << " A" << endl;
740 else cout << "inf A" << endl;
741 }
742
743 unsigned long imgsize = p->sizeX()*p->sizeY()*p->sizeZ()*p->channels();
744 double scale = 1, sum1, sum2;
745 Complex<double> temp1, temp2, cv;
746
747 if ( verbose & VERB_DEBUG )
748 cout << "DEBUG img_combined_bandpass_masked_complex_product: F0 = " << p->complex(0).real() << " " << p->complex(0).imag() << endl;
749
750 double tvs = getwalltime(), tvf;
751
752 for ( n=0; n<p->images(); n++ ) {
753 sum1 = sum2 = 0;
754 for ( z=0; z<p->sizeZ(); z++ ) {
755 zz = z;
756 if ( z > h.z() ) zz -= p->sizeZ();
757 iz = (z>0)? p->sizeZ() - z: 0;
758 sz2 = zz*iscale.z();
759 sz2 *= sz2;
760 for ( y=0; y<p->sizeY(); y++ ) {
761 yy = y;
762 if ( y > h.y() ) yy -= p->sizeY();
763 iy = (y>0)? p->sizeY() - y: 0;
764 sy2 = yy*iscale.y();
765 sy2 *= sy2;
766 for ( x=0; x<xh; x++ ) {
767 ix = (x>0)? p->sizeX() - x: 0;
768 use = 1;
769 if ( x == ix ) {
770 if ( y > h.y() ) use = 0;
771 if ( y == iy && z > h.z() ) use = 0;
772 }
773 if ( use ) {
774 xx = x;
775 if ( x > h.x() ) xx -= p->sizeX();
776 sx2 = xx*iscale.x();
777 sx2 *= sx2;
778 i = p->index(x, y, z, n);
779 j = p->index(ix, iy, iz, n);
780 s2 = sx2 + sy2 + sz2;
781 if ( (*pmask)[i] <= 0 ) use = 0;
782 if ( s2 < s2lo || s2 > s2hi ) use = 0;
783 if ( use ) {
784 temp1 = p->complex(i).unpack_first(p->complex(j));
785 temp2 = p->complex(i).unpack_second(p->complex(j));
786 p->set(i, temp1 * temp2.conj());
787 p->set(j, p->complex(i).conj());
788 sum1 += temp1.power();
789 sum2 += temp2.power();
790 } else {
791 p->set(i, cv);
792 p->set(j, cv);
793 }
794 }
795 }
796 }
797 }
798 if ( sum1*sum2 ) {
799 scale = 0.5/sqrt(sum1*sum2);
800 p->multiply(n, scale);
801 }
802 }
803
804 if ( !isfinite(scale) ) {
805 error_show("Error in img_combined_bandpass_masked_complex_product", __FILE__, __LINE__);
806 cerr << "Scale not finite = " << scale << endl;
807 return -9;
808 }
809
810 if ( verbose & VERB_TIME ) {
811 tvf = getwalltime();
812 cout << "CC(BP) time: " << tvf - tvs << endl;
813 }
814
815 return 0;
816 }
817
830 double img_merge_amplitudes_and_phases(Bimage* pamp, Bimage* p)
831 {
832 if ( !p ) return -1;
833 if ( !pamp ) return -1;
834
835 if ( p->compound_type() != TComplex ) return -1;
836
837 p->change_type(Float);
838
839 pamp->change_type(Float);
840
841 if ( verbose & VERB_FULL )
842 cout << "Merging amplitudes and phases" << endl << endl;
843
844 unsigned long i, datasize = p->sizeX()*p->sizeY()*p->sizeZ()*p->images();
845 double a, ar, d, R = 0;
846 Complex<double> cv;
847
848 for ( i=0; i<datasize; i++ ) {
849 cv = (*p)[i];
850 a = cv.amp();
851 if ( pamp->compound_type() == TSimple ) ar = (*pamp)[i];
852 else ar = (pamp->complex(i)).amp();
853 d = a - ar;
854 R += d*d;
855 cv.amp(ar);
856 p->set(i, cv);
857 }
858
859 R = sqrt(R/datasize);
860
861 return R;
862 }
863
879 double img_merge_amplitudes_and_phases(Bimage* p, Bimage* pref, float res_hi, float res_lo)
880 {
881 if ( !p ) return -1;
882 if ( !pref ) return -1;
883
884 if ( pref->compound_type() != TComplex ) {
885 cerr << "Error: The reference map must be a Fourier transform!" << endl << endl;
886 return -1;
887 }
888
889 p->change_type(Float);
890
891 pref->change_type(Float);
892
893 if ( res_hi < p->sampling().x() ) res_hi = p->sampling().x();
894 if ( res_lo < res_hi ) res_lo = res_hi;
895
896 if ( verbose & VERB_FULL )
897 cout << "Merging amplitudes and phases in the range " << res_hi << " - " << res_lo << " Å" << endl << endl;
898
899 double minrad = p->size().x()*p->sampling().x()/res_lo;
900 double maxrad = p->size().x()*p->sampling().x()/res_hi;
901 if ( maxrad < minrad + 1 ) maxrad = minrad + 1;
902 double minrad2 = minrad*minrad, maxrad2 = maxrad*maxrad;
903
904 unsigned long i, n, x, y, z, na(0);
905 double x2, y2, z2, r2;
906 Vector3<int> h((p->sizeX() - 1)/2, (p->sizeY() - 1)/2, (p->sizeZ() - 1)/2);
907
908 double a, ar, d, R(0);
909 Complex<double> cv;
910
911 for ( i=n=0; n<p->images(); n++ ) {
912 for ( z=0; z<p->sizeZ(); z++ ) {
913 z2 = z;
914 if ( z > h.z() ) z2 -= p->sizeZ();
915 z2 *= z2;
916 for ( y=0; y<p->sizeY(); y++ ) {
917 y2 = y;
918 if ( y > h.y() ) y2 -= p->sizeY();
919 y2 *= y2;
920 for ( x=0; x<p->sizeX(); x++, i++ ) {
921 x2 = x;
922 if ( x > h.x() ) x2 -= p->sizeX();
923 x2 *= x2;
924 r2 = x2 + y2 + z2;
925 cv = (*p)[i];
926 if ( r2 > maxrad2 ) { // Low-pass filter
927 cv = 0;
928 } else if ( r2 < minrad2 ) { // Keep original low-frequency data
929 cv = pref->complex(i);
930 } else { // Reset to the original amplitudes
931 a = cv.amp();
932 ar = (pref->complex(i)).amp();
933 d = a - ar;
934 R += d*d;
935 na++;
936 cv.amp(ar);
937 }
938 p->set(i, cv);
939 }
940 }
941 }
942 }
943
944 if ( na ) R = sqrt(R/na);
945
946 if ( verbose & VERB_DEBUG )
947 cout << "DEBUG img_merge_amplitudes_and_phases: minrad=" << minrad
948 << " maxrad=" << maxrad << " n=" << n << " R" << R << endl;
949
950 return R;
951 }
952
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1440
Vector3::z
Type z()
Definition: Vector3.h:141
Bimage::sizeZ
void sizeZ(size_t nz)
Definition: Bimage.h:383
img_combined_bandpass_masked_complex_product
int img_combined_bandpass_masked_complex_product(Bimage *p, float hires, float lores, Bimage *pmask)
Calculates the complex conjugate product of a complex image resulting from combining and Fourier tran...
Definition: img_complex.cpp:712
utilities.h
Header file for general utilities.
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:104
Bimage::compound_type
CompoundType compound_type()
Definition: Bimage.h:294
img_unpack_combined_transform
Bimage * img_unpack_combined_transform(Bimage *p)
Unpacks a complex transform obtained from two real images.
Definition: img_complex.cpp:331
Float
Definition: Bimage.h:57
Complex::conj
Complex conj()
Definition: Complex.h:106
Vector3< double >
error_show
int error_show(const char *message, const char *file, int line)
Displays the error with file and line reference.
Definition: utilities.cpp:616
Bimage::check
void check()
Checks an image for reasonable properties.
Definition: Bimage.cpp:312
use
const char * use[]
Definition: mg2imod.cpp:164
getwalltime
double getwalltime()
Returns the current time.
Definition: timer.cpp:23
TComplex
Definition: Bimage.h:69
Bimage::index
size_t index(size_t nx, size_t ny)
Definition: Bimage.h:387
Bimage::statistics
size_t statistics()
Calculates the statistics for an image.
Definition: Bimage.cpp:2199
img_complex.h
Functions to handle complex data sets.
TSimple
Definition: Bimage.h:68
timer.h
Utilities for timing functions.
img_colour.h
Functions to handle RGB images.
Bimage::size
Vector3< int > size()
Definition: Bimage.h:378
verbose
int verbose
Bimage
General image parameter class.
Definition: Bimage.h:150
Bimage::real_size
Vector3< double > real_size()
Definition: Bimage.h:459
img_complex_conjugate_product
int img_complex_conjugate_product(Bimage *p, Bimage *p2)
Calculates the product of a complex image with the conjugate of a second.
Definition: img_complex.cpp:61
img_complex_apply_dual_mask
int img_complex_apply_dual_mask(Bimage *p, Bimage *pmask)
Applies a dual mask to a complex image.
Definition: img_complex.cpp:155
Bimage::complex
Complex< double > complex(size_t j)
Returns a complex value at the given index.
Definition: Bimage.cpp:824
Bimage::channels
size_t channels()
Definition: Bimage.h:376
Bimage::sampling
void sampling(double s)
Definition: Bimage.h:462
VERB_TIME
#define VERB_TIME
Definition: utilities.h:102
Bimage::multiply
void multiply(size_t j, Complex< double > cv)
Definition: Bimage.h:268
img_complex_bandpass
int img_complex_bandpass(Bimage *p, float hires, float lores)
Bandpasses a Fourier transform.
Definition: img_complex.cpp:190
img_combined_complex_product
int img_combined_complex_product(Bimage *p)
Calculates the complex conjugate product of a complex image resulting from combining and Fourier tran...
Definition: img_complex.cpp:404
Complex::amp
double amp()
Definition: Complex.h:104
img_complex_apply_negative_mask
int img_complex_apply_negative_mask(Bimage *p, Bimage *pmask)
Applies a mask to a complex image.
Definition: img_complex.cpp:121
Vector3::x
Type x()
Definition: Vector3.h:139
Bimage::file_name
void file_name(Bstring s)
Definition: Bimage.h:212
img_complex_product
int img_complex_product(Bimage *p, Bimage *p2)
Calculates the complex product of two complex images.
Definition: img_complex.cpp:30
img_combined_bandpass_complex_product
int img_combined_bandpass_complex_product(Bimage *p, float hires, float lores)
Calculates the complex conjugate product of a complex image resulting from combining and Fourier tran...
Definition: img_complex.cpp:589
Bimage::set
void set(size_t j, double v)
Sets a single value at the given index.
Definition: Bimage.cpp:916
Bimage::standard_deviation
double standard_deviation()
Definition: Bimage.h:480
Bimage::next
Bimage * next
Definition: Bimage.h:152
Bimage::images
size_t images()
Definition: Bimage.h:460
Complex
Definition: Complex.h:23
Bimage::data_pointer
unsigned char * data_pointer()
Definition: Bimage.h:228
Bimage::data_size
size_t data_size()
Definition: Bimage.h:222
Bimage::copy
Bimage * copy()
Copies the header information and data of an image into a new image structure.
Definition: Bimage.cpp:2448
Bimage::sizeX
void sizeX(size_t nx)
Definition: Bimage.h:381
img_complex_apply_mask
int img_complex_apply_mask(Bimage *p, Bimage *pmask)
Applies a mask to a complex image.
Definition: img_complex.cpp:91
img_combined_masked_complex_product
int img_combined_masked_complex_product(Bimage *p, Bimage *pmask)
Calculates the complex conjugate product of a complex image resulting from combining and Fourier tran...
Definition: img_complex.cpp:494
Bimage::sizeY
void sizeY(size_t ny)
Definition: Bimage.h:382
img_merge_amplitudes_and_phases
double img_merge_amplitudes_and_phases(Bimage *pamp, Bimage *p)
Merges the amplitudes from one map with the phases of another.
Definition: img_complex.cpp:830
img_pack_two_in_complex
Bimage * img_pack_two_in_complex(Bimage *p1, Bimage *p2)
Packs two real images into one complex image.
Definition: img_complex.cpp:255
Bimage::check_if_same_size
bool check_if_same_size(Bimage *p)
Check if two images are the same size.
Definition: Bimage.cpp:453
rwimg.h
Header file for 2D and 3D image I/O.
Complex::power
double power()
Definition: Complex.h:103
NoTransform
Definition: Bimage.h:30
VERB_FULL
#define VERB_FULL
Definition: utilities.h:101
Vector3::y
Type y()
Definition: Vector3.h:140
Bimage::fourier_type
FourierType fourier_type()
Definition: Bimage.h:372
Bimage::image
Bsub_image * image
Definition: Bimage.h:181