| 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_reflections.cpp
Go to the documentation of this file.
1
9 #include "rwimg.h"
10 #include "img_reflections.h"
11 #include "img_fourier.h"
12 #include "img_symmetry.h"
13 #include "Complex.h"
14 #include "utilities.h"
15
16 // Declaration of global variables
17 extern int verbose; // Level of output to the screen
18
29 int img_normalize_reflections(Bimage* p)
30 {
31 if ( p->compound_type() != TComplex ) return -1;
32
33 unsigned long i, n = p->images()*p->sizeX()*p->sizeY()*p->sizeZ();
34 double ampavg(0);
35 Complex<double> cv;
36
37 for ( i=0; i<n; i++ ) ampavg += (p->complex(i)).amp();
38
39 if ( ampavg < 1e-30 ) {
40 cout << "Error: Structure factor amplitude average too low: " << ampavg << endl;
41 return -1;
42 }
43
44 if ( verbose & VERB_LABEL )
45 cout << "Normalizing with amplitude average: " << ampavg << endl << endl;
46
47 for ( i=0; i<n; i++ ) {
48 cv = p->complex(i);
49 cv /= ampavg;
50 p->set(i, cv);
51 }
52
53 return 0;
54 }
55
64 int img_mirror_reflections(Bimage* p)
65 {
66 if ( p->compound_type() != TComplex ) return -1;
67
68 unsigned long i, n = p->images()*p->sizeX()*p->sizeY()*p->sizeZ();
69
70 if ( verbose & VERB_LABEL )
71 cout << "Mirroring reflections" << endl << endl;
72
73 for ( i=0; i<n; i++ ) p->set(i, (p->complex(i)).conj());
74
75 return 0;
76 }
77
94 unsigned long img_select_reflections(Bimage* p, double hires, double lores,
95 double cone, int weigh, double fomcut)
96 {
97 if ( cone <= 0 ) cone = M_PI_2;
98
99 if ( hires <= 0 ) hires = 0.1;
100 if ( lores > 0 && lores < hires ) swap(hires, lores);
101
102 unsigned long i, j, x, y, z, n, c, nr(0), deselect;
103 long h, k, l;
104 double s2, h2, k2, l2;
105 double smin2 = (lores > 0)? 1/lores: 0;
106 double smax2 = 1/hires;
107 smin2 *= smin2;
108 smax2 *= smax2;
109
110 Vector3<double> half((p->sizeX() - 1)/2, (p->sizeY() - 1)/2, (p->sizeZ() - 1)/2);
111 Vector3<double> freq(1.0/p->real_size());
112 double inv_tan_cone = 1/tan(cone);
113
114 float* fom = p->FOM();
115
116 if ( cone <= 0 ) cone = 0.01;
117 for ( i=n=0; n<p->images(); n++ ) {
118 for ( z=0; z<p->sizeZ(); z++ ) {
119 l = (long) (z - p->image[n].origin().z());
120 if ( l > half.z() ) l -= p->sizeZ();
121 l2 = l*freq.z();
122 l2 *= l2;
123 for ( y=0; y<p->sizeY(); y++ ) {
124 k = (long) (y - p->image[n].origin().y());
125 if ( k > half.y() ) k -= p->sizeY();
126 k2 = k*freq.y();
127 k2 *= k2;
128 for ( x=0; x<p->sizeX(); x++, i++ ) {
129 h = (long) (x - p->image[n].origin().x());
130 if ( h > half.x() ) h -= p->sizeX();
131 h2 = h*freq.x();
132 h2 *= h2;
133 deselect = 0;
134 s2 = h2 + k2 + l2;
135 if ( s2 > smax2 ) deselect = 1;
136 if ( s2 < smin2 ) deselect = 1;
137 if ( cone < M_PI_2 ) {
138 if ( s2 == 0 ) {
139 deselect = 1; // Center spot
140 } else if ( sqrt((double)h*h + (double)k*k) -
141 fabs((double)l)*inv_tan_cone < 0 ) {
142 deselect = 1; // Cone
143 }
144 }
145 if ( fom ) if ( fom[i] < fomcut ) {
146 deselect = 1;
147 fom[i] = 0;
148 }
149 for ( c=0, j=i*p->channels(); c<p->channels(); c++, j++ ) {
150 if ( deselect ) {
151 p->set(j, 0);
152 } else {
153 if ( weigh && fom ) {
154 if ( isfinite(fom[i]) ) {
155 p->set(j, (*p)[j] * fom[i]);
156 } else {
157 cout << "NaN at " << h << " " << k << " " << l << endl;
158 }
159 }
160 nr++;
161 }
162 }
163 }
164 }
165 }
166 }
167
168 nr /= p->channels();
169
170 if ( verbose & VERB_PROCESS )
171 cout << "Reflections selected: " << nr << endl << endl;
172
173 return nr;
174 }
175
182 Bprofile* img_reflection_profile(Bimage* p, double radius)
183 {
184 if ( p->compound_type() != TComplex ) return NULL;
185
186 Bprofile* prof = new Bprofile;
187 memset(prof, 0, sizeof(Bprofile));
188
189 unsigned long i, j, x, y, z, nmax = 0;
190 long h, k, l;
191 double hkl, idist, amp;
192 double ampsum[NSHELLS], ampssum[NSHELLS];
193 Vector3<float> half((p->sizeX() - 1)/2, (p->sizeY() - 1)/2, (p->sizeZ() - 1)/2);
194
195 prof->radius = radius;
196 for ( j=0; j<NSHELLS; j++ ) {
197 prof->dist[j] = 0;
198 prof->num[j] = 0;
199 prof->amp[j] = 0;
200 ampsum[j] = 0;
201 ampssum[j] = 0;
202 }
203
204 // Count reflections in each shell and calculate weighted amplitude averages
205 for ( i=z=0; z<p->sizeZ(); z++ ) {
206 l = z;
207 if ( l >= half.z() ) l -= p->sizeZ();
208 for ( y=0; y<p->sizeY(); y++ ) {
209 k = y;
210 if ( k >= half.y() ) k -= p->sizeY();
211 for ( x=0; x<p->sizeX(); x++, i++ ) {
212 h = x;
213 if ( h >= half.x() ) h -= p->sizeX();
214 amp = (p->complex(i)).amp();
215 if ( amp > 0.1 ) {
216 hkl = sqrt(1.0*h*h + k*k + l*l);
217 idist = hkl/radius;
218 j = (int) (idist*idist*idist);
219 if ( j >= NSHELLS ) j = NSHELLS - 1;
220 if ( nmax < j ) nmax = j;
221 if ( prof->dist[j] < hkl ) prof->dist[j] = hkl;
222 ampsum[j] += amp;
223 ampssum[j] += amp*amp;
224 prof->num[j] += 1;
225 }
226 }
227 }
228 }
229
230 for ( j=0; j<nmax; j++ )
231 if ( prof->num[j] ) prof->amp[j] = ampssum[j]/ampsum[j];
232
233 // Print shell statistics
234 if ( verbose & VERB_PROCESS ) {
235 cout << "Resolution shell statistics for " << p->file_name() << ":" << endl;
236 cout << "Number of shells: " << nmax << endl;
237 cout << "Radius of inner shell: " << radius << " voxels" << endl;
238 cout << "Shell\tOrder\tReflections\tAmplitude" << endl;
239 for ( j=0; j<nmax; j++ )
240 cout << j << tab << prof->dist[j] << tab <<
241 prof->num[j] << tab << prof->amp[j] << endl;
242 cout << endl;
243 }
244
245 return prof;
246 }
247
256 int img_octants(Bimage* p)
257 {
258 if ( p->compound_type() != TComplex ) return -1;
259
260 unsigned long i, j, x, y, z;
261 int iq, iqz, iqy, iqx, oct[8];
262 Complex<double> cv;
263
264 for ( iq=0; iq<8; iq++ ) oct[iq] = 0; // Octant counts
265
266 for ( i=z=0; z<p->sizeZ(); z++ ) {
267 iqz = (int) (4*floor(z*2.0/p->sizeZ()));
268 for ( y=0; y<p->sizeY(); y++ ) {
269 iqy = (int) (2*floor(y*2.0/p->sizeY()));
270 for ( x=0; x<p->sizeX(); x++, i++ ){
271 iqx = (int) (floor(x*2.0/p->sizeX()));
272 iq = iqx + iqy + iqz;
273 cv = p->complex(i);
274 if ( fabs(cv.real()) > 1e-10 || fabs(cv.imag()) > 1e-10 ) oct[iq]++;
275 }
276 }
277 }
278
279 j = 0;
280 for ( iq=0; iq<8; iq++ ) j += oct[iq];
281
282 if ( verbose & VERB_PROCESS ) {
283 cout << "Reflections: " << j << endl;
284 cout << "Octant coverage: ";
285 for ( iq=0; iq<8; iq++ ) cout << " " << oct[iq];
286 cout << endl << endl;
287 }
288
289 iq = 0;
290 for ( i=0; i<8; i++ ) if ( oct[i] ) iq++;
291
292 return iq;
293 }
294
300 int img_sfanalyze(Bimage* p)
301 {
302 if ( p->compound_type() != TComplex ) return -1;
303 if ( !p->FOM() ) return -1;
304
305 unsigned long i, x, y, z, ihkl, ihisto, nmax(0);
306 unsigned long n = p->images()*p->sizeX()*p->sizeY()*p->sizeZ();
307 double s; // HKL distance
308 double r1 = p->sizeX()/3; // Order radius of inner shell
309 double r3 = r1*r1*r1;
310 int nsh = 100; // Number of resolution shells
311 double realsize(p->sampling().x()*p->size().x());
312
313 float* sh = new float[nsh]; // Maximum order for each shell
314 int* npos = new int[nsh]; // Maximum possible number of reflections in each shell
315 int* nres = new int[nsh]; // Number of reflections in each shell
316 float* res = new float[nsh]; // Average resolution of each shell
317 float* amp = new float[nsh]; // Average amplitude of each shell
318 float* fomavg = new float[nsh]; // Average FOM of each shell
319 int* histo = new int[nsh]; // FOM histogram
320
321 float* fom = p->FOM();
322
323 Vector3<double> half((p->sizeX() - 1)/2, (p->sizeY() - 1)/2, (p->sizeZ() - 1)/2);
324
325 if ( verbose & VERB_LABEL )
326 cout << "Analyzing reflections" << endl;
327
328 // Setting up shell orders and initializing arrays
329 for ( i=0; i<nsh; i++ ) {
330 sh[i] = pow(i*r3,1.0/3.0);
331 npos[i] = nres[i] = histo[i] = 0;
332 res[i] = amp[i] = fomavg[i] = 0;
333 }
334
335 // Calculate the maximum possible number of reflections in each shell
336 long h, k, l;
337 int iq = img_octants(p);
338
339 for ( h=0; h<nsh; h++ )
340 for ( k=0; k<=nsh; k++ )
341 for ( l=0; l<=nsh; l++ ) {
342 s = sqrt(1.0*h*h + k*k + l*l);
343 ihkl = 0;
344 while ( ( s >= sh[ihkl] ) && ( ihkl < nsh ) ) ihkl++;
345 npos[ihkl] += iq; // Add the number for every octant present
346 }
347
348 // Calculate statistics
349 for ( i=z=0; z<p->sizeZ(); z++ ) {
350 l = z;
351 if ( l >= half.z() ) l -= p->sizeZ();
352 for ( y=0; y<p->sizeY(); y++ ) {
353 k = y;
354 if ( k >= half.y() ) k -= p->sizeY();
355 for ( x=0; x<p->sizeX(); x++, i++ ) {
356 h = x;
357 if ( h >= half.x() ) h -= p->sizeX();
358 s = sqrt(1.0*h*h + k*k + l*l);
359 ihkl = 0;
360 while ( ( s >= sh[ihkl] ) && ( ihkl < nsh ) ) ihkl++;
361 if ( ihkl >= nsh )
362 cout << "Too large: " << h << " " << k << " " << l << endl;
363 if ( fom[i] ) nres[ihkl]++;
364 if ( ihkl > nmax ) nmax = ihkl;
365 res[ihkl] += s;
366 amp[ihkl] += (p->complex(i)).amp();
367 fomavg[ihkl] += fom[i];
368 ihisto = (int) floor(19.9*fom[i]/p->FOM_maximum());
369 histo[ihisto]++;
370 }
371 }
372 }
373 nmax++;
374
375 // Printing shell statistics
376 cout << "Resolution shell statistics for " << iq << " octants:" << endl;
377 cout << "Shell\tMaxOrder\tMaxResol\tMaxRefl\tReflections\t%Complete\tAmplitudes\tFOM" << endl;
378 for ( i=1; i<nmax; i++ ) {
379 if ( nres[i] > 0 ) {
380 res[i] /= nres[i];
381 // res[i] = p->ua/res[i];
382 res[i] = realsize/res[i];
383 amp[i] /= nres[i];
384 fomavg[i] /= nres[i];
385 }
386 cout << i << tab << sh[i] << tab << realsize/sh[i] << tab << npos[i] << tab << nres[i] << tab <<
387 nres[i]*100.0/npos[i] << tab << amp[i] << tab << fomavg[i] << endl;
388 }
389 cout << endl;
390
391 // Printing FOM histogram
392 int rsum = n;
393 cout << "Histogram:" << endl;
394 cout << "Bin\tFOM\tCount\tFOM cutoff" << endl;
395 for ( i=0; i<20; i++ ) {
396 cout << i+1 << tab << p->FOM_maximum()*(i+0.5)/20.0 << tab << histo[i] << tab << rsum << endl;
397 rsum -= histo[i];
398 }
399 cout << endl;
400
401 delete[] sh;
402 delete[] npos;
403 delete[] nres;
404 delete[] res;
405 delete[] amp;
406 delete[] fomavg;
407 delete[] histo;
408
409 return 1;
410 }
411
418 int img_sfscale(Bimage* p, Bstring& hklname)
419 {
420 if ( p->compound_type() != TComplex ) return -1;
421
422 Bimage* p2 = read_img(hklname, 1, 0);
423
424 if ( p2->compound_type() != TComplex )
425 img_fft(FFTW_FORWARD, p2);
426
427 double radius = 0.15*p->sizeX();
428 Bprofile* prof = img_reflection_profile(p, radius);
429 Bprofile* prof2 = img_reflection_profile(p2, radius);
430
431 Vector3<float> half((p->sizeX() - 1)/2, (p->sizeY() - 1)/2, (p->sizeZ() - 1)/2);
432
433 if ( verbose & VERB_PROCESS )
434 cout << "Scale profile:" << endl;
435
436 unsigned long i, j, x, y, z;
437 long h, k, l;
438 double idist, thresh = 1e-10, scale[NSHELLS];
439
440 for ( i=0; i<NSHELLS; i++ ) {
441 scale[i] = 0;
442 if ( prof->amp[i] > thresh && prof2->amp[i] > thresh ) {
443 scale[i] = prof2->amp[i]/prof->amp[i];
444 if ( verbose & VERB_PROCESS )
445 cout << i << tab << scale[i] << endl;
446 }
447 }
448 if ( verbose & VERB_PROCESS ) cout << endl;
449
450 for ( i=z=0; z<p->sizeZ(); z++ ) {
451 l = z;
452 if ( l >= half.z() ) l -= p->sizeZ();
453 for ( y=0; y<p->sizeY(); y++ ) {
454 k = y;
455 if ( k >= half.y() ) k -= p->sizeY();
456 for ( x=0; x<p->sizeX(); x++, i++ ) {
457 h = x;
458 if ( h >= half.x() ) h -= p->sizeX();
459 idist = sqrt(1.0*h*h + k*k + l*l)/radius;
460 j = (int) floor(idist*idist*idist);
461 p->set(i, p->complex(i) * scale[j]);
462 }
463 }
464 }
465
466 delete p2;
467
468 return 0;
469 }
470
477 int img_sfmerge(Bimage* p, Bstring& hklname)
478 {
479 if ( p->compound_type() != TComplex ) return -1;
480
481 Bimage* p2 = read_img(hklname, 1, 0);
482
483 if ( p2->compound_type() != TComplex )
484 img_fft(FFTW_FORWARD, p2);
485
486 double radius = 0.15*p->sizeX();
487 Bprofile* prof = img_reflection_profile(p, radius);
488 Bprofile* prof2 = img_reflection_profile(p2, radius);
489
490 float* fom = p->FOM();
491 float* fom2 = p2->FOM();
492
493 if ( verbose )
494 cout << "Scale profile for 2nd data set:" << endl;
495
496 unsigned long i, j, x, y, z;
497 long h, k, l;
498 double idist, thresh = 0.1, scale[NSHELLS], fomsum;
499 Complex<double> cv, cv2;
500
501 for ( i=0; i<NSHELLS; i++ ) {
502 scale[i] = 0;
503 if ( prof->amp[i] > thresh && prof2->amp[i] > thresh ) {
504 scale[i] = prof->amp[i]/prof2->amp[i];
505 if ( verbose )
506 cout << i << tab << scale[i] << endl;
507 }
508 }
509
510 for ( i=z=0; z<p->sizeZ(); z++ ) {
511 l = z;
512 if ( l >= p->sizeZ()/2 ) l -= p->sizeZ();
513 for ( y=0; y<p->sizeY(); y++ ) {
514 k = y;
515 if ( k >= p->sizeY()/2 ) k -= p->sizeY();
516 for ( x=0; x<p->sizeX(); x++, i++ ) {
517 h = x;
518 if ( h >= p->sizeX()/2 ) h -= p->sizeX();
519 idist = sqrt(1.0*h*h + k*k + l*l)/radius;
520 j = (int) floor(idist*idist*idist);
521 fomsum = 0;
522 if ( fom && fom2 ) fomsum = fom[i] + fom2[i];
523 cv = p->complex(i);
524 cv2 = p2->complex(i);
525 if ( fomsum > thresh ) {
526 // data[i] = (data[i] * fom[i] + data2[i] * scale[j] * fom2[i])/fomsum;
527 p->set(i, (cv * fom[i] + cv2 * fom2[i] * scale[j])/fomsum);
528 fom[i] = (fom[i]*fom[i] + fom2[i]*fom2[i])/fomsum;
529 } else if ( fom2 && fom2[i] > thresh ) {
530 // data[i] = data2[i] * scale[j];
531 p->set(i, cv2 * scale[j]);
532 fom[i] = fom2[i];
533 }
534 }
535 }
536 }
537 cout << endl;
538
539 delete p2;
540
541 return 0;
542 }
543
Vector3::z
Type z()
Definition: Vector3.h:141
Bimage::sizeZ
void sizeZ(size_t nz)
Definition: Bimage.h:383
M_PI_2
#define M_PI_2
Definition: utilities.h:54
NSHELLS
#define NSHELLS
Definition: img_reflections.h:13
utilities.h
Header file for general utilities.
Bimage::compound_type
CompoundType compound_type()
Definition: Bimage.h:294
Bprofile::dist
float dist[NSHELLS]
Definition: img_reflections.h:18
Complex.h
Class for complex numbers.
Vector3< double >
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:99
TComplex
Definition: Bimage.h:69
Bimage::size
Vector3< int > size()
Definition: Bimage.h:378
Bimage
General image parameter class.
Definition: Bimage.h:150
img_normalize_reflections
int img_normalize_reflections(Bimage *p)
Normalizes a set of reflections encoded as a complex image.
Definition: img_reflections.cpp:29
Bimage::real_size
Vector3< double > real_size()
Definition: Bimage.h:459
Bprofile::radius
float radius
Definition: img_reflections.h:17
img_mirror_reflections
int img_mirror_reflections(Bimage *p)
Mirrors a set of reflections by negating the phases.
Definition: img_reflections.cpp:64
read_img
Bimage * read_img(const char *filename, int readdata, int img_select)
General driver function to read multiple image formats.
Definition: rwimg.cpp:75
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
verbose
int verbose
Bimage::FOM
float * FOM()
Definition: Bimage.h:236
img_fourier.h
General FFT for n-dimensional data.
freq
JHUFF_TBL long freq[]
Definition: jchuff.h:47
img_fft
int img_fft(Bimage *p)
Fast Fourier transforms an image.
Definition: img_fourier.cpp:42
Vector3::x
Type x()
Definition: Vector3.h:139
Bimage::file_name
void file_name(Bstring s)
Definition: Bimage.h:212
img_select_reflections
unsigned long img_select_reflections(Bimage *p, double hires, double lores, double cone, int weigh, double fomcut)
Selects reflections for output.
Definition: img_reflections.cpp:94
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:130
img_octants
int img_octants(Bimage *p)
Counts the number of reflections in each octant.
Definition: img_reflections.cpp:256
Bimage::set
void set(size_t j, double v)
Sets a single value at the given index.
Definition: Bimage.cpp:916
Bimage::FOM_maximum
double FOM_maximum()
Definition: Bimage.h:238
img_sfscale
int img_sfscale(Bimage *p, Bstring &hklname)
Scales the input reflections with a second set.
Definition: img_reflections.cpp:418
Bimage::images
size_t images()
Definition: Bimage.h:460
Complex
Definition: Complex.h:23
Bstring
Definition: Bstring.h:25
Bimage::sizeX
void sizeX(size_t nx)
Definition: Bimage.h:381
img_reflection_profile
Bprofile * img_reflection_profile(Bimage *p, double radius)
Calculates a radial profile average.
Definition: img_reflections.cpp:182
Bprofile
Definition: img_reflections.h:16
img_symmetry.h
Header file for symmetry functions.
Bimage::sizeY
void sizeY(size_t ny)
Definition: Bimage.h:382
Complex::imag
Type imag()
Definition: Complex.h:102
img_sfanalyze
int img_sfanalyze(Bimage *p)
Analyzes the FOM's of a set of reflections encoded as a complex image.
Definition: img_reflections.cpp:300
Bprofile::num
int num[NSHELLS]
Definition: img_reflections.h:19
Bprofile::amp
float amp[NSHELLS]
Definition: img_reflections.h:20
rwimg.h
Header file for 2D and 3D image I/O.
Complex::real
Type real()
Definition: Complex.h:101
FFTW_FORWARD
Definition: fftw.h:64
VERB_LABEL
#define VERB_LABEL
Definition: utilities.h:98
Vector3::y
Type y()
Definition: Vector3.h:140
img_reflections.h
Routines to manipulate reflection files.
img_sfmerge
int img_sfmerge(Bimage *p, Bstring &hklname)
Merges the input reflections with a second set.
Definition: img_reflections.cpp:477
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
Bimage::image
Bsub_image * image
Definition: Bimage.h:181