| Bsoft 2.0.5 Bernard's software package

Bimage_reconstruct.cpp
Go to the documentation of this file.
1
9 #include "Bimage.h"
10 #include "linked_list.h"
11 #include "utilities.h"
12
13 // Declaration of global variables
14 extern int verbose; // Level of output to the screen
15
26 int Bimage::fspace_2D_interpolate(Complex<float> cv, Vector3<double> m,
27 double part_weight, int interp_type, Vector3<double> vscale)
28 {
29 if ( !next ) next = new Bimage(Float, TSimple, size(), n);
30 if ( !next->next ) next->next = new Bimage(Float, TSimple, size(), n);
31 if ( !next->next->next ) next->next->next = new Bimage(Float, TSimple, size(), n);
32
33 long xx, yy, zz, j, jx, jy, jz;
34 double w(part_weight);
35 Vector3<long> coor;
36 Vector3<double> dist;
37
38 float* power = (float *) next->data_pointer();
39 float* weight = (float *) next->next->data_pointer();
40 float* weight2 = (float *) next->next->next->data_pointer();
41
42 if ( interp_type < 2 ) { // Nearest neighbour
43 coor = Vector3<long>((long) floor(m[0] + 0.5),
44 (long) floor(m[1] + 0.5),
45 (long) floor(m[2] + 0.5));
46 if ( interp_type == 1 ) { // Weighted nearest neighbour
47 dist = m - coor;
48 // dist /= vscale;
49 w *= 1 - dist.length();
50 }
51 if ( w > 0 ) {
52 j = index_wrap(coor);
53 add(j, cv * w);
54 power[j] += w*cv.power();
55 weight[j] += w;
56 weight2[j] += w*w;
57 }
58 } else if ( interp_type == 2 ) { // Trilinear interpolation
59 coor = Vector3<long>((long) floor(m[0]),
60 (long) floor(m[1]),
61 (long) floor(m[2]));
62 dist = m - coor;
63 for ( zz=0; zz<2; zz++ ) {
64 jz = coor[2] + zz;
65 if ( jz < 0 ) jz += z;
66 else if ( jz >= z ) jz -= z;
67 dist[2] = 1.0 - dist[2];
68 for ( yy=0; yy<2; yy++ ) {
69 jy = coor[1] + yy;
70 if ( jy < 0 ) jy += y;
71 else if ( jy >= y ) jy -= y;
72 dist[1] = 1.0 - dist[1];
73 for ( xx=0; xx<2; xx++ ) {
74 jx = coor[0] + xx;
75 if ( jx < 0 ) jx += x;
76 else if ( jx >= x ) jx -= x;
77 dist[0] = 1.0 - dist[0];
78 w = dist.volume() * part_weight;
79 j = index(jx, jy, jz);
80 add(j, cv * w);
81 power[j] += w*cv.power();
82 weight[j] += w;
83 weight2[j] += w*w;
84 }
85 }
86 }
87 }
88
89 return 0;
90 }
91
109 int Bimage::fspace_pack_2D(Bimage* p, Matrix3 mat, double hi_res,
110 double lo_res, double scale, double part_weight, int interp_type)
111 {
112 double min_rad_sq = (lo_res)? p->image->sampling()[0]/lo_res: 0;
113 double max_rad_sq = (hi_res)? p->image->sampling()[0]/hi_res: 0.5;
114 min_rad_sq *= p->x;
115 min_rad_sq *= min_rad_sq;
116 if ( max_rad_sq > 0.5 ) max_rad_sq = 0.5;
117 max_rad_sq *= p->x;
118 max_rad_sq += 1; // Add one pixel width additional interpolation to be removed later
119 max_rad_sq *= max_rad_sq;
120
121 long i, xx, yy;
122 long hx = (p->x - 1)/2, hy = (p->y - 1)/2;
123 double d, w;
124 Vector3<double> m, iv;
125 Vector3<double> vscale(size());
126 vscale /= scale*p->x;
127 if ( z < 2 ) vscale[2] = 1;
128
129 if ( verbose & VERB_FULL )
130 cout << "Packing an image into reciprocal space up to " << hi_res << " A resolution" << endl;
131
132 Matrix3 mf = vscale * mat;
133
134 if ( verbose & VERB_DEBUG )
135 cout << mat << endl;
136
137 // part_weight = 1;
138 // cout << part_weight << endl;
139
140 for ( yy=i=0; yy<p->y; yy++ ) {
141 iv[1] = yy;
142 if ( yy > hy ) iv[1] -= (double)p->y;
143 for ( xx=0; xx<p->x; xx++, i++ ) {
144 iv[0] = xx;
145 if ( xx > hx ) iv[0] -= (double)p->x;
146 // d = max_rad_sq - iv.length2();
147 d = iv.length2();
148 if ( d >= min_rad_sq && d <= max_rad_sq ) {
149 d = max_rad_sq - d;
150 m = mf * iv;
151 w = part_weight;
152 if ( d < 1 ) w *= sqrt(d);
153 fspace_2D_interpolate(p->complex(i), m,
154 w, interp_type, vscale);
155 }
156 }
157 }
158
159 return 0;
160 }
161
180 int Bimage::fspace_pack_2D(Bimage* p, View asu_view, Bsymmetry* sym, double hi_res,
181 double lo_res, double scale, double part_weight, int interp_type)
182 {
183 View* v;
184 View* view = symmetry_get_all_views(sym, asu_view);
185
186 if ( verbose & VERB_DEBUG ) {
187 cout << "DEBUG Bimage::fspace_pack_2D: sym=" << sym->label << endl;
188 cout << "DEBUG Bimage::fspace_pack_2D: view=" << asu_view << endl;
189 cout << "DEBUG Bimage::fspace_pack_2D: part_weight=" << part_weight << endl;
190 }
191
192 for ( v=view; v; v=v->next )
193 fspace_pack_2D(p, v->matrix(), hi_res, lo_res, scale, part_weight, interp_type);
194
195 kill_list((char *) view, sizeof(View));
196
197 return 0;
198 }
199
218 long Bimage::fspace_pack_2D_into_central_section(Bimage* p,
219 long ft_size, double scale, double hi_res, double lo_res,
220 Matrix3 matr, Matrix3 mat)
221 {
222 if ( !p->data_pointer() ) return 0;
223
224 if ( hi_res < 2*sampling()[0] ) hi_res = 2*sampling()[0];
225
226 if ( verbose & VERB_FULL )
227 cout << "Packing an image into reciprocal space up to " << hi_res << " A resolution" << endl << endl;
228
229 long i, j, xx, yy, kx, ky;
230 long ix, iy, ixx, iyy, nover(0);
231 double w, dx, dy, d2;
232 Vector3<double> m, d(0,0,1), iv;
233
234 Vector3<double> vscale(x/(scale*ft_size), y/(scale*ft_size), 1/scale);
235
236 float* fom = (float *) next->data_pointer();
237
238 if ( verbose & VERB_FULL )
239 cout << mat << endl;
240
241 double maxrad = p->sampling()[0]/hi_res;
242 double maxrad_sq = maxrad*maxrad; // Maximum radius squared on map scale
243 double ymin = floor(-maxrad*p->y);
244 double ymax = -ymin;
245 double xmin = floor(-maxrad*p->x);
246 double xmax = -xmin;
247
248 // Vector to calculate z-shift
249 Vector3<double> vn(matr[2][0]/matr[2][2], matr[2][1]/matr[2][2], 0);
250
251 matr = matr.transpose();
252 // matr = vscale * matr;
253
254 for ( iv[1]=ymin; iv[1]<=ymax; iv[1]+=1 ) {
255 if ( iv[1] >= 0 ) yy = (long)iv[1];
256 else yy = (long)(iv[1] + p->y);
257 dy = iv[1]/p->y;
258 for ( iv[0]=xmin; iv[0]<=xmax; iv[0]+=1 ) {
259 if ( iv[0] >= 0 ) xx = (long)iv[0];
260 else xx = (long)(iv[0] + p->x);
261 dx = iv[0]/p->x;
262 d2 = dx*dx + dy*dy;
263 if ( d2 <= maxrad_sq ) {
264 m = mat * iv;
265 m[2] = m.scalar(vn);
266 m = matr * m;
267 // d[2] = fabs(m[2]);
268 // if ( d[2] <= 1 ) {
269 ix = (long) floor(m[0]);
270 iy = (long) floor(m[1]);
271 d[0] = m[0] - ix;
272 d[1] = m[1] - iy;
273 i = yy*p->x + xx;
274 for ( ky=0; ky<2; ky++ ) {
275 iyy = iy + ky;
276 if ( iyy < 0 ) iyy += y;
277 d[1] = 1 - d[1];
278 for ( kx=0; kx<2; kx++ ) {
279 ixx = ix + kx;
280 if ( ixx < 0 ) ixx += x;
281 d[0] = 1 - d[0];
282 j = iyy*x + ixx;
283 w = d.volume();
284 fom[j] += w;
285 add(j, p->complex(i) * w);
286 }
287 }
288 nover++;
289 // }
290 }
291 }
292 }
293
294 return nover;
295 }
296
297
309 int Bimage::fspace_pack_3D(Bimage* p, double hi_res, double threshold)
310 {
311 if ( !next ) next = new Bimage(Float, TSimple, size(), n);
312 if ( !next->next ) next->next = new Bimage(Float, TSimple, size(), n);
313 if ( !next->next->next ) next->next->next = new Bimage(Float, TSimple, size(), n);
314
315 long i, xx, yy, zz;
316 double rx, ry, rz, r2, rad_scale, rad_scale2, maxrad, maxrad2, pwr, w;
317 Vector3<long> h((size()-1)/2);
318 Vector3<double> realsize(real_size());
319 Vector3<double> freq_scale(1.0/realsize);
320 Complex<float> cv;
321
322 float* power = (float *) next->data_pointer();
323 float* weight = (float *) next->next->data_pointer();
324 float* weight2 = (float *) next->next->next->data_pointer();
325
326 rad_scale = realsize[0];
327 if ( rad_scale < realsize[1] ) rad_scale = realsize[1];
328 if ( rad_scale < realsize[2] ) rad_scale = realsize[2];
329 rad_scale2 = rad_scale*rad_scale;
330
331 maxrad = x;
332 if ( maxrad < y ) maxrad = y;
333 if ( maxrad < z ) maxrad = z;
334 if ( hi_res > 0.1 )
335 maxrad = rad_scale/hi_res;
336 else
337 maxrad = maxrad/2.0;
338 maxrad2 = maxrad*maxrad;
339
340 for ( i=zz=0; zz<z; zz++ ) {
341 rz = zz;
342 if ( zz > h[2] ) rz -= z;
343 rz *= freq_scale[2];
344 rz *= rz;
345 for ( yy=0; yy<y; yy++ ) {
346 ry = yy;
347 if ( yy > h[1] ) ry -= y;
348 ry *= freq_scale[1];
349 ry *= ry;
350 for ( xx=0; xx<x; xx++, i++ ) {
351 rx = xx;
352 if ( xx > h[0] ) rx -= x;
353 rx *= freq_scale[0];
354 rx *= rx;
355 cv = p->complex(i);
356 pwr = cv.power();
357 if ( pwr >= threshold ) {
358 r2 = rad_scale2*(rx + ry + rz);
359 if ( r2 <= maxrad2 ) {
360 w = 1;
361 add(i, cv);
362 power[i] += pwr;
363 weight[i] += w;
364 weight2[i] += w*w;
365 }
366 }
367 }
368 }
369 }
370
371 return 0;
372 }
373
384 long Bimage::fspace_reconstruction_add(Bimage* p)
385 {
386 // cout << "adding" << endl;
387
388 add(p);
389
390 if ( next && p->next ) {
391 next->add(p->next);
392
393 if ( next->next && p->next->next ) {
394 next->next->add(p->next->next);
395
396 if ( next->next->next && p->next->next->next ) next->next->next->add(p->next->next->next);
397 }
398 }
399
400 return 0;
401 }
402
412 long Bimage::fspace_reconstruction_weigh()
413 {
414 long i, cov(0), ds(x*y*z);
415 Complex<double> cv;
416
417 float* power = (float *) next->data_pointer();
418 float* weight = (float *) next->next->data_pointer();
419 float* weight2 = (float *) next->next->next->data_pointer();
420
421 weight[0] = 0;
422
423 for ( i=0; i<ds; i++ ) {
424 if ( weight[i] > SMALLFLOAT ) {
425 weight2[i] = weight[i] - weight2[i]/weight[i];
426 set(i, complex(i) / weight[i]);
427 if ( weight2[i] > 1 ) power[i] /= weight2[i];
428 else if ( weight[i] > 1 ) power[i] /= weight[i];
429 if ( power[i] < 0 ) power[i] = 0;
430 cov++;
431 } else {
432 set(i, cv);
433 power[i] = 0;
434 weight[i] = weight2[i] = SMALLFLOAT;
435 }
436 }
437
438 power[0] = 1; // The zero frequency contains no information
439
440 return cov;
441 }
442
451 int Bimage::fspace_reconstruction_stats(double resolution)
452 {
453 // cout << "Compound type: " << compoundtype << endl;
454 // cout << "Fourier type: " << fouriertype << endl;
455
456 long maxrad = fspace_maximum_radius(resolution);
457
458 Bimage* prad = fspace_radial_power(resolution);
459 Bimage* pfom = prad->next = next->radial(0, maxrad, 1, 1);
460 Bimage* pw = prad->next->next = next->next->radial(0, maxrad, 1, 1);
461 Bimage* pw2 = prad->next->next->next = next->next->next->radial(0, maxrad, 1, 1);
462
463 long i;
464 double rad_scale = image->sampling()[0]*x;
465 double s, noise, signal, w, w2;
466 double res, fsc, fscp(1), snr, snrp(10), sc(0), res_fsc(0), res_snr(0);
467 double fsc_cut(0.3), snr_cut(0.5);
468
469 if ( verbose ) {
470 cout << "Radius\ts(1/A)\tRes(A)\tWeight\tPower\tSignal\tNoise\tSNR\tFSC" << endl;
471 for ( i=1; i<maxrad; i++ ) {
472 s = i/rad_scale;
473 res = rad_scale/i;
474 fsc = snr = signal = noise = 0;
475 w = (*pw)[i];
476 if ( w > 1 ) {
477 w2 = (*pw2)[i];
478 noise = ((*pfom)[i] - (*prad)[i])/w2;
479 signal = (w*(*prad)[i] - (*pfom)[i])/w2;
480 if ( noise < 0 )
481 cout << i << tab << w2 << tab << (*prad)[i] << tab << (*pfom)[i] << endl;
482 // if ( signal > 0 )signal -= sqrt(noise*signal);
483 // else signal = 0;
484 // signal = ((w-2-2/w)*(*prad)[i] - (1+2/w)*(*pfom)[i])/w2;
485 if ( signal < 0 ) signal = 0;
486 if ( noise > 0 ) snr = signal/noise;
487 // fsc = (w-(*pfom)[i]/(*prad)[i])/(w-1);
488 fsc = snr/(snr+1);
489 if ( fsc < 0 ) fsc = 0;
490 }
491 if ( fscp >= fsc_cut && fsc < fsc_cut ) {
492 sc = s - (fsc_cut - fsc)/((fscp - fsc)*rad_scale);
493 res_fsc = 1/sc;
494 }
495 if ( snrp >= snr_cut && snr < snr_cut ) {
496 sc = s - (snr_cut - snr)/((snrp - snr)*rad_scale);
497 res_snr = 1/sc;
498 }
499 fscp = fsc;
500 snrp = snr;
501 cout << i << tab << setprecision(4) << s << tab
502 << setprecision(2) << res << tab
503 << setprecision(2) << w << tab
504 << setprecision(6) << (*prad)[i] << tab
505 << setprecision(6) << signal << tab
506 << setprecision(6) << noise << tab
507 << setprecision(4) << snr << tab << fsc << endl;
508 }
509 cout << endl;
510 cout << "Resolution estimates:" << endl;
511 cout << "SNR(0.5): " << res_snr << " A" << endl;
512 cout << "FSC(0.3): " << res_fsc << " A" << endl << endl;
513 }
514
515 delete prad;
516
517 return 0;
518 }
519
529 long Bimage::fspace_reconstruction_snr()
530 {
531 long i, cov(0), ds(x*y*z);
532 double signal, noise;
533
534 float* power = (float *) next->data_pointer();
535 float* weight = (float *) next->next->data_pointer();
536
537 for ( i=0; i<ds; i++ ) {
538 signal = complex(i).power();
539 noise = power[i] - signal;
540 if ( noise < signal ) noise = signal;
541 // if ( signal < SMALLFLOAT && noise < SMALLFLOAT )
542 // cout << i << tab << signal << tab << noise << endl;
543 if ( weight[i] > 1 && signal > SMALLFLOAT && noise > SMALLFLOAT ) {
544 power[i] = (weight[i]*signal - power[i])/noise;
545 cov++;
546 } else
547 power[i] = 0;
548 }
549
550 power[0] = 1; // The zero frequency contains no information
551
552 return cov;
553 }
Bimage::fspace_pack_2D_into_central_section
long fspace_pack_2D_into_central_section(Bimage *p, long ft_size, double scale, double hi_res, double lo_res, Matrix3 matr, Matrix3 mat)
Packs a 2D Fourier transform into a central section of a 3D reciprocal space volume.
Definition: Bimage_reconstruct.cpp:218
Bimage::fspace_reconstruction_stats
int fspace_reconstruction_stats(double resolution)
Calculates Fourier shell statistics.
Definition: Bimage_reconstruct.cpp:451
Bimage::index_wrap
long index_wrap(long nx, long ny, long nz) const
Definition: Bimage.h:401
Bimage.h
Header file for image class.
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
Vector3::length
double length()
Definition: Vector3.h:222
Bimage::add
void add(long j, double v)
Definition: Bimage.h:308
View::next
View * next
Definition: View.h:28
SMALLFLOAT
#define SMALLFLOAT
Definition: utilities.h:45
utilities.h
Header file for general utilities.
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
kill_list
long kill_list(char *list, unsigned long size)
Frees all the items in a linked list.
Definition: linked_list.cpp:214
Bimage::index
long index(long nx, long ny) const
Definition: Bimage.h:383
Matrix3
Definition: Matrix3.h:17
Bimage::complex
Complex< double > complex(long j)
Returns a complex value at the given index.
Definition: Bimage.cpp:1005
Bimage::fspace_2D_interpolate
int fspace_2D_interpolate(Complex< float > cv, Vector3< double > m, double part_weight, int interp_type, Vector3< double > vscale)
Interpolates a 2D image for packing ito a 3D reciprocal space volume.
Definition: Bimage_reconstruct.cpp:26
Bimage::Bimage
Bimage()
Initializes an image.
Definition: Bimage.cpp:44
TSimple
Definition: Bimage.h:58
Float
Definition: utilities.h:157
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::fspace_reconstruction_add
long fspace_reconstruction_add(Bimage *p)
Adds all components to a reconstruction.
Definition: Bimage_reconstruct.cpp:384
Bimage::real_size
Vector3< double > real_size()
Definition: Bimage.h:487
Bimage::power
void power(double v)
Calculates the power of an image.
Definition: Bimage.cpp:3288
Bimage::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
verbose
int verbose
Bimage::fspace_pack_3D
int fspace_pack_3D(Bimage *p, double hi_res=0, double threshold=0)
Packs a 3D Fourier transform into a 3D reciprocal space volume.
Definition: Bimage_reconstruct.cpp:309
linked_list.h
Header file for generalized linked list functions.
Bimage::fspace_pack_2D
int fspace_pack_2D(Bimage *p, Matrix3 mat, double hi_res=0, double lo_res=0, double scale=1, double part_weight=1, int interp_type=0)
Packs a 2D Fourier transform into a 3D reciprocal space volume.
Definition: Bimage_reconstruct.cpp:109
Bimage::fspace_radial_power
Bimage * fspace_radial_power(double resolution)
Calculates the radial power spectrum from a Fourier transform.
Definition: Bimage_fspace.cpp:612
Vector3::scalar
double scalar(const Vector3 &v) const
Definition: Vector3.h:247
Bimage::fspace_reconstruction_snr
long fspace_reconstruction_snr()
Calculates the SNR map.
Definition: Bimage_reconstruct.cpp:529
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
Bsub_image::sampling
void sampling(double x, double y, double z)
Definition: Bimage.h:123
Vector3::length2
double length2()
Definition: Vector3.h:221
Bimage::fspace_reconstruction_weigh
long fspace_reconstruction_weigh()
Weighs a reconstruction.
Definition: Bimage_reconstruct.cpp:412
Bimage::view
void view(double vx, double vy, double vz, double va)
Definition: Bimage.h:589
Bsymmetry::label
Bstring label
Definition: symmetry.h:41
Bimage::set
void set(long j, double v)
Sets a single value at the given index.
Definition: Bimage.cpp:1096
Bsymmetry
Definition: symmetry.h:38
Bimage::next
Bimage * next
Definition: Bimage.h:165
Complex
Definition: Complex.h:23
Bimage::data_pointer
unsigned char * data_pointer()
Definition: Bimage.h:261
View::matrix
Matrix3 matrix()
Definition: View.h:150
Matrix3::transpose
Matrix3 transpose() const
Definition: Matrix3.h:268
Vector3< double >
View
Definition: View.h:26
Complex::power
double power()
Definition: Complex.h:103
Vector3::volume
double volume()
Definition: Vector3.h:235
Bimage::radial
Bimage * radial(long minrad, long maxrad, double rad_step=1, int wrap=0)
Calculates the radial average of an image.
Definition: Bimage_polar.cpp:33
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
symmetry_get_all_views
View * symmetry_get_all_views(Bsymmetry *sym, View asu_view)
Get all symmetry-related views of one given view.
Definition: symmetry.cpp:448
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
Bimage::image
Bsub_image * image
Definition: Bimage.h:188