| Bsoft 2.0.5 Bernard's software package

Bimage_project.cpp
Go to the documentation of this file.
1
9 #include "Bimage.h"
10 #include "linked_list.h"
11 #include "symmetry.h"
12 #include "Complex.h"
13 #include "Matrix3.h"
14 #include "utilities.h"
15
16 // Declaration of global variables
17 extern int verbose; // Level of output to the screen
18
31 Bimage* Bimage::project(char axis, int flags)
32 {
33 bool scale_flag(flags & 1);
34 bool mnproj(flags & 2);
35 bool mxproj(flags & 4);
36 long i, j, xx, yy, zz, cc, nn;
37 double v, scale;
38 Vector3<double> u(image->sampling());
39
40 Bimage* proj = NULL;
41 if ( axis == 'x' ) {
42 proj = new Bimage(Float, compoundtype, z, y, 1, n);
43 scale = 1.0L/x;
44 proj->sampling(u[2], u[1], 1);
45 } else if ( axis == 'y' ) {
46 proj = new Bimage(Float, compoundtype, x, z, 1, n);
47 scale = 1.0L/y;
48 proj->sampling(u[0], u[2], 1);
49 } else {
50 proj = new Bimage(Float, compoundtype, x, y, 1, n);
51 scale = 1.0L/z;
52 proj->sampling(u[0], u[1], 1);
53 }
54
55 long ds(n*x*y*c);
56
57 if ( mxproj ) proj->fill(min);
58 else if ( mnproj ) proj->fill(max);
59
60 if ( verbose & VERB_LABEL )
61 cout << "Projecting along " << axis << " (" << flags << ")" << endl << endl;
62
63 // First calculate projection
64 for ( i=nn=0; nn<n; nn++ ) {
65 if ( axis == 'x' ) {
66 proj->image[nn].origin(image[nn].origin()[2], image[nn].origin()[1], 0.0);
67 } else if ( axis == 'y' ) {
68 proj->image[nn].origin(image[nn].origin()[0], image[nn].origin()[2], 0.0);
69 } else {
70 proj->image[nn].origin(image[nn].origin()[0], image[nn].origin()[1], 0.0);
71 }
72 for ( zz=0; zz<z; zz++ )
73 for ( yy=0; yy<y; yy++ )
74 for ( xx=0; xx<x; xx++ )
75 for ( cc=0; cc<c; cc++, i++ ) {
76 if ( axis == 'x' )
77 j = ((nn*y + yy)*z + zz)*c + cc;
78 else if ( axis == 'y' )
79 j = ((nn*z + zz)*x + xx)*c + cc;
80 else
81 j = ((nn*y + yy)*x + xx)*c + cc;
82 v = (*this)[i];
83 if ( mxproj ) {
84 if ( (*proj)[j] < v ) proj->set(j, v);
85 } else if ( mnproj ) {
86 if ( (*proj)[j] > v ) proj->set(j, v);
87 } else {
88 proj->add(j, v);
89 }
90 }
91 }
92
93 if ( scale_flag ) for ( i=0; i<ds; i++ ) proj->set(i, (*proj)[i] * scale);
94
95 proj->statistics();
96
97 return proj;
98 }
99
118 Bimage* Bimage::rotate_project(Matrix3 mat, Vector3<double> translate,
119 double radial_cutoff, int norm_flag)
120 {
121 long i, j, xx, yy, zz;
122 long xo, yo, xp, yp, yw;
123 double oldz_sq, oldyz_sq;
124 double xf, yf, maxlen(0);
125 Vector3<double> old, newvec;
126
127 if ( radial_cutoff < 1 ) radial_cutoff = x;
128 double rad_sq = radial_cutoff*radial_cutoff;
129
130 Vector3<double> oldorigin(image->origin());
131
132 Vector3<double> neworigin = oldorigin + translate;
133 neworigin[2] = 0;
134
135 Matrix3 matinv = mat.transpose();
136
137 if ( verbose & VERB_FULL ) {
138 cout << "Rotating around the map center and projecting:" << endl;
139 cout << "Rotation origin: " << oldorigin << endl;
140 cout << matinv << endl;
141 if ( translate[0] != 0 || translate[1] != 0 || translate[2] != 0 )
142 cout << "Translation: " << translate << endl;
143 cout << "Radial cutoff: " << radial_cutoff << " pixels" << endl;
144 cout << endl;
145 }
146
147 Bimage* proj = new Bimage(Float, TSimple, x, y, 1, 1);
148 proj->sampling(image->sampling()[0], image->sampling()[1], 1);
149 proj->origin(neworigin[0], neworigin[1], 0);
150
151 double bkg(background(long(0)));
152 double value;
153 long slice_size(x*y);
154
155 for ( zz=0; zz<z; zz++ ) {
156 old[2] = zz - oldorigin[2];
157 oldz_sq = old[2]*old[2];
158 if ( oldz_sq <= rad_sq ) for ( yy=0; yy<y; yy++ ) {
159 old[1] = yy - oldorigin[1];
160 oldyz_sq = oldz_sq + old[1]*old[1];
161 if ( oldyz_sq <= rad_sq ) for ( xx=0; xx<x; xx++ ) {
162 old[0] = xx - oldorigin[0];
163 if ( old[0]*old[0] + oldyz_sq <= rad_sq ) {
164 newvec = (matinv * old) + neworigin;
165 yo = (long) newvec[1];
166 if ( ( yo >= 0 ) && ( yo < y - 1 ) ) {
167 xo = (long) newvec[0];
168 if ( ( xo >= 0 ) && ( xo < x - 1 ) ) {
169 if ( maxlen < fabs(newvec[2]) ) maxlen = fabs(newvec[2]);
170 yf = newvec[1] - yo;
171 xf = newvec[0] - xo;
172 i = (zz*y + yy)*x + xx;
173 value = (*this)[i] - bkg;
174 for ( yp=yo; yp<yo+2; yp++ ) {
175 yw = yp*x;
176 yf = 1 - yf;
177 for ( xp=xo; xp<xo+2; xp++ ) {
178 j = yw + xp;
179 xf = 1 - xf;
180 proj->add(j, value*xf*yf);
181 }
182 }
183 }
184 }
185 }
186 }
187 }
188 }
189
190 if ( norm_flag )
191 for ( i=0; i<slice_size; i++ ) proj->set(i, (*proj)[i] / maxlen);
192
193 proj->statistics();
194
195 return proj;
196 }
197
207 Bimage* Bimage::project(View* view, int norm_flag)
208 {
209 if ( !view ) {
210 error_show("Error in Bimage::project: No views defined for projection!", __FILE__, __LINE__);
211 return NULL;
212 }
213
214 calculate_background();
215
216 long i;
217 Vector3<double> translate;
218
219 long nviews = count_list((char *)view);
220 Vector3<double> u(image->sampling());
221 u[2] = 1;
222
223 View* vlist = new View[nviews];
224 View* v;
225
226 for ( v=view, i=0; v; v = v->next, i++ ) vlist[i] = *v;
227
228 if ( verbose & VERB_PROCESS ) {
229 cout << "Calculating projections:" << endl;
230 cout << "Number of projections: " << nviews << endl;
231 if ( norm_flag ) cout << "with normalization" << endl;
232 }
233
234 Bimage* proj = new Bimage(Float, TSimple, x, y, 1, nviews);
235 proj->file_name(file_name());
236
237 #ifdef HAVE_GCD
238 dispatch_apply(nviews, dispatch_get_global_queue(0, 0), ^(size_t i){
239 // if ( verbose & VERB_LABEL )
240 // cout << "Projection " << i+1 << ":" << endl;
241 Matrix3 mat = vlist[i].matrix();
242 Bimage* one_proj = rotate_project(mat, translate, x/2.0, norm_flag);
243 one_proj->shift_background(0);
244 proj->replace(i, one_proj);
245 proj->origin(i, one_proj->image->origin());
246 proj->sampling(i, u);
247 proj->image[i].view(vlist[i]);
248 delete one_proj;
249 });
250 #else
251 #pragma omp parallel for
252 for ( long i=0; i<nviews; i++ ) {
253 // if ( verbose & VERB_LABEL )
254 // cout << "Projection " << i+1 << ":" << endl;
255 Matrix3 mat = vlist[i].matrix();
256 Bimage* one_proj = rotate_project(mat, translate, x/2.0, norm_flag);
257 one_proj->shift_background(0);
258 proj->replace(i, one_proj);
259 proj->origin(i, one_proj->image->origin());
260 proj->sampling(i, u);
261 proj->image[i].view(vlist[i]);
262 delete one_proj;
263 }
264 #endif
265
266 delete[] vlist;
267
268 proj->statistics();
269
270 // cout << proj->meta_data() < endl;
271
272 return proj;
273 }
274
287 Bimage* Bimage::central_section(Matrix3 mat, double resolution, FSI_Kernel* kernel)
288 {
289 if ( image->sampling()[0] < 1e-10 ) sampling(1,1,1);
290 if ( resolution < 1e-10 ) resolution = image->sampling()[0];
291
292 long i, xx, yy;
293 long hx((x - 1)/2), hy((y - 1)/2);
294 Vector3<double> m, iv;
295 double maxrad(real_size()[0]/resolution), maxrad2(maxrad*maxrad), rx2, ry2;
296 double zscale(z*1.0L/x);
297
298 if ( verbose & VERB_FULL ) {
299 cout << "Calculating a central section:" << endl;
300 cout << "Resolution limit: " << resolution << " A (" << maxrad << ")" << endl;
301 cout << mat << endl << endl;
302 }
303
304 Bimage* proj = new Bimage(Float, TComplex, x, y, 1, 1);
305 proj->fourier_type(Standard);
306 proj->image[0] = image[0];
307 proj->sampling(image->sampling()[0], image->sampling()[1], 1);
308 proj->origin(image->origin()[0], image->origin()[1], 0);
309
310 for ( i=yy=0; yy<y; yy++ ) {
311 iv[1] = yy;
312 if ( iv[1] > hy ) iv[1] -= y;
313 ry2 = iv[1]*iv[1];
314 for ( xx=0; xx<x; xx++, i++ ) {
315 iv[0] = xx;
316 if ( iv[0] > hx ) iv[0] -= x;
317 rx2 = iv[0]*iv[0];
318 if ( rx2 + ry2 <= maxrad2 ) {
319 m = mat * iv;
320 m[2] *= zscale;
321 proj->set(i, fspace_interpolate(0, m, kernel));
322 }
323 }
324 }
325
326 proj->statistics();
327
328 return proj;
329 }
330
343 Bimage* Bimage::project(View* view, double resolution, FSI_Kernel* kernel)
344 {
345 if ( !view ) {
346 error_show("Error in Bimage::project: No views defined for projection!", __FILE__, __LINE__);
347 return NULL;
348 }
349
350 if ( verbose & VERB_DEBUG )
351 cout << "DEBUG Bimage::project: transforming and shifting origin" << endl;
352
353 fft();
354
355 phase_shift_to_origin();
356
357 // friedel_check();
358
359 long i;
360 long nviews = count_list((char *)view);
361 View* vlist = new View[nviews];
362 View* v;
363
364 for ( v=view, i=0; v; v = v->next, i++ ) vlist[i] = *v;
365
366 if ( verbose & VERB_PROCESS ) {
367 cout << "Calculating projections:" << endl;
368 cout << "Number of projections: " << nviews << endl;
369 }
370
371 Bimage* proj = new Bimage(Float, TComplex, x, y, 1, nviews);
372 proj->file_name(file_name());
373 proj->sampling(image->sampling()[0], image->sampling()[1], 1);
374
375 if ( verbose & VERB_DEBUG )
376 cout << "DEBUG Bimage::project: origin after phase shift: " << image->origin() << endl;
377
378 #ifdef HAVE_GCD
379 dispatch_apply(nviews, dispatch_get_global_queue(0, 0), ^(size_t i){
380 // if ( verbose & VERB_LABEL )
381 // cout << "Projection " << i+1 << ":" << endl;
382 Matrix3 mat = vlist[i].matrix();
383 Bimage* psec = central_section(mat, resolution, kernel);
384 psec->phase_shift_to_center();
385 proj->replace(i, psec);
386 proj->image[i].view(vlist[i]);
387 delete psec;
388 });
389 #else
390 #pragma omp parallel for
391 for ( long i=0; i<nviews; i++ ) {
392 // if ( verbose & VERB_LABEL )
393 // cout << "Projection " << i+1 << ":" << endl;
394 Matrix3 mat = vlist[i].matrix();
395 Bimage* psec = central_section(mat, resolution, kernel);
396 psec->phase_shift_to_center();
397 proj->replace(i, psec);
398 proj->image[i].view(vlist[i]);
399 delete psec;
400 }
401 #endif
402
403 delete[] vlist;
404
405 // for ( i=0; i<proj->images(); i++ ) cout << proj->image[i].origin() << endl;
406
407 proj->friedel_check();
408
409 proj->fft_back();
410
411 proj->statistics();
412
413 return proj;
414 }
415
416 /*
417 @author Bernard Heymann and Peter Leong
418 @brief Back-projects a 2D image into a 3D volume.
419 @param *p a 2D image.
420 @param resolution high resolution limit (angstrom).
421 @param axis tilt axis for single tilt series (radians).
422 @param planf 2D forward Fourier transform plan.
423 @param planb 2D backward Fourier transform plan.
424 @return int 0.
425
426 Requirements:
427 The image must be 2D with the orientation parameters in
428 the sub-image structure.
429 The orientation parameters are defined as those giving the projection,
430 and is reversed for backprojection.
431 The 2D image is converted to floating point and rescaled to an average
432 of zero and a standard deviation of one. The 3D map is traversed and
433 the density added from the 2D image projected according to the orientation
434 parameters. The origin of the new map is in the center of the volume.
435
436 **/
437 int Bimage::back_project(Bimage* p, double resolution, double axis,
438 fft_plan planf, fft_plan planb)
439 {
440 if ( !p->data_pointer() ) return 0;
441
442 p->change_type(Float);
443 if ( axis ) p->fspace_weigh_ramp(resolution, axis, planf, planb);
444 else p->fspace_weigh_ramp(resolution, planf, planb);
445
446 p->statistics();
447 p->rescale_to_avg_std(0, 1);
448 p->calculate_background();
449
450 long i, xx, yy, zz;
451 double fill(p->background(long(0)));
452 Vector3<double> oldorigin(p->image->origin()), neworigin(image->origin());
453 Vector3<double> oldcoor, newcoor;
454 Vector3<double> scale(p->image->magnification(), p->image->magnification(), 1);
455
456 // The rotation matrix is transposed because the orientation parameters
457 // give the orientation as rotated from the reference view
458 Matrix3 mat = p->image->view().matrix();
459 mat = mat.transpose();
460 mat = scale*mat;
461 // cout << mat << endl;
462
463 if ( verbose & VERB_LABEL )
464 cout << "Backprojecting" << endl << endl;
465
466 for ( i=zz=0; zz<z; zz++ ) {
467 newcoor[2] = zz - neworigin[2];
468 for ( yy=0; yy<y; yy++ ) {
469 newcoor[1] = yy - neworigin[1];
470 for ( xx=0; xx<x; xx++, i++ ) {
471 newcoor[0] = xx - neworigin[0];
472 oldcoor = mat * newcoor + oldorigin;
473 oldcoor[2] = 0;
474 add(i, p->interpolate(oldcoor, 0, fill));
475 }
476 }
477 }
478
479 return 0;
480 }
481
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1743
Bimage::replace
int replace(Bimage *img)
Replaces the data with that from the given image.
Definition: Bimage.cpp:2828
Bsub_image::view
void view(double x, double y, double z, double a)
Definition: Bimage.h:143
Bimage.h
Header file for image class.
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
planb
fft_plan planb
Definition: bico.cpp:24
Bimage::add
void add(long j, double v)
Definition: Bimage.h:308
View::next
View * next
Definition: View.h:28
Bimage::file_name
string & file_name()
Definition: Bimage.h:231
symmetry.h
Header file for general symmetry functions.
Bimage::fft
int fft()
Definition: Bimage.h:822
Bimage::fft_back
int fft_back()
Definition: Bimage.h:823
utilities.h
Header file for general utilities.
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
planf
fft_plan planf
Definition: bico.cpp:24
Bimage::fspace_interpolate
Complex< double > fspace_interpolate(long img_num, Vector3< double > m, FSI_Kernel *kernel)
Calculates the complex value at an image location by kernel-based interpolation.
Definition: Bimage_fspace.cpp:88
Complex.h
Class for complex numbers.
Matrix3
Definition: Matrix3.h:17
count_list
long count_list(char *list)
Counts the number of items in a linked list.
Definition: linked_list.cpp:235
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
FSI_Kernel
Definition: FSI_Kernel.h:14
Bimage::file_name
void file_name(string s)
Definition: Bimage.h:230
TComplex
Definition: Bimage.h:59
Bimage::shift_background
int shift_background(double bkg)
Sets the background for each sub-image to a given value.
Definition: Bimage_background.cpp:351
Bimage::Bimage
Bimage()
Initializes an image.
Definition: Bimage.cpp:44
Bimage::interpolate
double interpolate(long cc, double xx, double yy=0, double zz=0, long nn=0, double fill=0) const
Interpolates using a given location.
Definition: Bimage.cpp:1392
Matrix3.h
3x3 Matrix manipulation functions
TSimple
Definition: Bimage.h:58
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
linked_list.h
Header file for generalized linked list functions.
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
fft_plan
fftwf_plan fft_plan
Definition: fft.h:16
Standard
Definition: Bimage.h:41
Bimage::rescale_to_avg_std
int rescale_to_avg_std(double nuavg, double nustd)
Rescales the image data to a given average and standard deviation.
Definition: Bimage_rescale.cpp:163
Bimage::project
Bimage * project(char axis, int flags=1)
Projects a 3D image to a 2D image down one of the three major axes.
Definition: Bimage_project.cpp:31
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
Bimage::calculate_background
int calculate_background(long nn, int flag)
Calculates the background for one sub-image.
Definition: Bimage_background.cpp:27
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:127
verbose
int verbose
Bsub_image::sampling
void sampling(double x, double y, double z)
Definition: Bimage.h:123
Bimage::view
void view(double vx, double vy, double vz, double va)
Definition: Bimage.h:589
Bimage::set
void set(long j, double v)
Sets a single value at the given index.
Definition: Bimage.cpp:1096
Bimage::data_pointer
unsigned char * data_pointer()
Definition: Bimage.h:261
Bimage::central_section
Bimage * central_section(Matrix3 mat, double resolution, FSI_Kernel *kernel)
Calculates a central section of a 3D fourier transform.
Definition: Bimage_project.cpp:287
View::matrix
Matrix3 matrix()
Definition: View.h:150
Matrix3::transpose
Matrix3 transpose() const
Definition: Matrix3.h:268
Vector3< double >
Bimage::rotate_project
Bimage * rotate_project(Matrix3 mat, Vector3< double > translate, double radial_cutoff, int norm_flag=1)
Rotates a 3D map and projects it along the z-axis.
Definition: Bimage_project.cpp:118
View
Definition: View.h:26
Bimage::fspace_weigh_ramp
int fspace_weigh_ramp(double resolution, fft_plan planf, fft_plan planb)
Weighs a transform with a ramp.
Definition: Bimage_fspace.cpp:1064
Bsub_image::magnification
double magnification()
Definition: Bimage.h:149
Bimage::friedel_check
double friedel_check()
Checks Friedel symmetry.
Definition: Bimage_fspace.cpp:1649
kernel
Definition: kernlut.h:13
Bimage::fill
void fill(double v)
Definition: Bimage.h:698
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
Bimage::background
double background(long nn)
Definition: Bimage.h:542
VERB_LABEL
#define VERB_LABEL
Definition: utilities.h:106
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
Bimage::image
Bsub_image * image
Definition: Bimage.h:188
Bimage::origin
void origin(double ox, double oy, double oz)
Definition: Bimage.h:563
Bimage::back_project
int back_project(Bimage *p, double resolution, double axis, fft_plan planf, fft_plan planb)
Definition: Bimage_project.cpp:437