| 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_backproject.cpp
Go to the documentation of this file.
1
9 #include "img_backproject.h"
10 #include "img_fourier.h"
11 #include "mg_processing.h"
12 #include "rwimg.h"
13 #include "Matrix3.h"
14 #include "Complex.h"
15 #include "utilities.h"
16
17 // Declaration of global variables
18 extern int verbose; // Level of output to the screen
19
39 Bimage* project_back_projection(Bproject* project, int num_select, Vector3<int> map_size,
40 Vector3<float> sampling, double scale, double resolution)
41 {
42 Bfield* field = NULL;
43 Bmicrograph* mg = NULL;
44 Bparticle* part = NULL;
45 Bimage* p = NULL;
46
47 if ( map_size.volume() <= 0 ) {
48 error_show("Error in project_back_projection", __FILE__, __LINE__);
49 cerr << "No reconstruction size set!" << endl << endl;
50 return NULL;
51 }
52
53 for ( field = project->field; field && part == NULL; field = field->next )
54 for ( mg = field->mg; mg && part == NULL; mg = mg->next )
55 if ( ( part = mg->part ) ) break;
56
57 if ( !mg || !part ) {
58 cerr << "Error: No particles found!" << endl;
59 return NULL;
60 }
61
62 // Initialize the new 3D volume
63 Bimage* pmap = new Bimage(Float, TSimple, map_size.x(),
64 map_size.y(), map_size.z(), 1);
65
66 if ( sampling.volume() > 0 ) pmap->sampling(sampling);
67 else if ( mg ) pmap->sampling(mg->pixel_size/scale, mg->pixel_size/scale, mg->pixel_size/scale);
68
69 pmap->image->origin(pmap->size()/2);
70
71 pmap->FOM_initialize();
72
73 pmap->check();
74
75 long nsel = project_count_mg_part_selected(project, num_select);
76 long psel, nrec(0);
77
78 if ( verbose & VERB_FULL ) {
79 cout << "3D backprojection:" << endl;
80 cout << "Map size: " << pmap->size() << endl;
81 cout << "Resolution: " << resolution << " A" << endl;
82 cout << "Scale: " << scale << endl;
83 cout << "Sampling: " << pmap->sampling() << endl;
84 cout << "Number of selected particles: " << nsel << endl << endl;
85 }
86
87 // Do the back projection
88 for ( field = project->field; field; field = field->next ) {
89 for ( mg = field->mg; mg; mg = mg->next ) {
90 for ( part = mg->part; part; part = part->next ) {
91 psel = 0;
92 if ( part->sel ) {
93 if ( num_select < 0 ) {
94 psel = 1;
95 } else if ( part->sel == num_select ) {
96 psel = 1;
97 }
98 }
99 if ( psel ) { // Use only selected images
100 if ( ( p = read_img(mg->fpart, 1, part->id-1) ) == NULL ) {
101 error_show("project_back_projection", __FILE__, __LINE__);
102 return NULL;
103 }
104
105 p->sampling(mg->pixel_size, mg->pixel_size, 1);
106
107 if ( part->ori.x() <= 0 ) {
108 if ( p->image->origin().x() > 0 ) part->ori[0] = p->image->origin().x();
109 else part->ori[0] = pmap->image->origin().x();
110 }
111
112 if ( part->ori.y() <= 0 ) {
113 if ( p->image->origin().y() > 0 ) part->ori[1] = p->image->origin().y();
114 else part->ori[1] = pmap->image->origin().y();
115 }
116
117 part->ori[2] = 0;
118
119 p->image->origin(part->ori);
120
121 p->view(part->view);
122
123 p->image->magnification(part->mag / scale);
124
125 img_back_project_one(p, pmap);
126 delete p;
127
128 nrec++;
129
130 if ( verbose & ( VERB_TIME | VERB_PROCESS | VERB_RESULT ) )
131 cout << "Complete: " << nrec*100.0/nsel << "%\r" << flush;
132 }
133 }
134 }
135 }
136
137 if ( verbose ) {
138 cout << endl << "Particles used: " << nrec << endl << endl;
139 }
140
141 return pmap;
142 }
143
163 int img_back_project_one(Bimage* p, Bimage* pmap)
164 {
165 if ( !p->data_pointer() ) return 0;
166
167 if ( !pmap->FOM() ) {
168 cerr << "Map cannot be R-weighted!" << endl;
169 return -1;
170 }
171
172 unsigned long i, j, x, y, z;
173 long ir, xr, yr, zr, xo, xo1, yo, xx, yy, yw;
174 double xf[2], yf[2], pi_z;
175 Vector3<double> oldorigin, neworigin, oldcoor, newcoor;
176
177 p->change_type(Float);
178 p->statistics();
179 p->rescale_to_avg_std(0, 1);
180
181 oldorigin = p->image->origin();
182 neworigin = pmap->image->origin();
183
184 View view(p->image->view());
185 Matrix3 mat = view.matrix();
186 Vector3<float> scale(p->image->magnification(), p->image->magnification(), 1);
187
188 // The rotation matrix is transposed because the orientation parameters
189 // give the orientation as rotated from the reference view
190 mat = mat.transpose();
191 mat = scale*mat;
192 // cout << mat << endl;
193
194 float* fom = (float *) pmap->FOM();
195 double v, fill(0);
196
197 if ( verbose & VERB_LABEL )
198 cout << "Backprojecting" << endl << endl;
199
200 for ( i=z=0; z<pmap->sizeZ(); z++ ) {
201 newcoor[2] = z - neworigin.z();
202 zr = (long) (z - pmap->image->origin().z());
203 if ( zr < 0 ) zr += pmap->sizeZ();
204 for ( y=0; y<pmap->sizeY(); y++ ) {
205 newcoor[1] = y - neworigin.y();
206 yr = (long) (y - pmap->image->origin().y());
207 if ( yr < 0 ) yr += pmap->sizeY();
208 for ( x=0; x<pmap->sizeX(); x++, i++ ) {
209 newcoor[0] = x - neworigin.x();
210 xr = (long) (x - pmap->image->origin().x());
211 if ( xr < 0 ) xr += pmap->sizeX();
212 oldcoor = mat * newcoor + oldorigin;
213 yo = (long) oldcoor.y();
214 v = (*pmap)[i];
215 if ( ( yo >= 0 ) && ( yo < p->sizeY() ) ) {
216 xo = (long) oldcoor.x(); //cout << "xo=%d\n", xo);
217 if ( ( xo >= 0 ) && ( xo < p->sizeX() ) ) {
218 yf[1] = oldcoor.y() - yo;
219 yf[0] = 1.0 - yf[1];
220 xf[1] = oldcoor.x() - xo;
221 xf[0] = 1.0 - xf[1];
222 for ( yy=0; yy<2; yy++, yo++ ) if ( yo < p->sizeY() ) {
223 yw = yo*p->sizeX();
224 for ( xx=0, xo1=xo; xx<2; xx++, xo1++ ) if ( xo1 < p->sizeX() ) {
225 j = yw + xo1;
226 v += (*p)[j]*xf[xx]*yf[yy];
227 }
228 }
229 } else v += fill;
230 } else v += fill;
231 pmap->set(i, v);
232 ir = (zr*pmap->sizeY() + yr)*pmap->sizeX() + xr;
233 pi_z = M_PI*fabs(oldcoor.z());
234 if ( pi_z > 1e-10 )
235 fom[ir] += fabs(sin(pi_z)/pi_z);
236 else
237 fom[ir] += 1;
238 }
239 }
240 }
241
242 return 0;
243 }
244
256 int img_weigh_transform(Bimage* p, double resolution, double threshold)
257 {
258 if ( threshold < 1e-30 ) return 0;
259
260 p->fft();
261
262 unsigned long i, x, y, z, nzero = 0, nmax = 0;
263 long xx, yy, zz;
264 double sx2, sy2, sz2, res2(0.25);
265 double inv_threshold = 1.0/threshold;
266 double weight = 0;
267 Vector3<double> realsize(p->real_size());
268
269 if ( resolution > 0 ) res2 = 1/(resolution*resolution);
270
271 float* fom = (float *) p->FOM();
272
273 if ( verbose ) {
274 cout << "Filtering to a resolution of " << 1/sqrt(res2) << " A" << endl;
275 cout << "R-weighting with a cutoff factor of " << threshold << endl << endl;
276 }
277
278 for ( i=z=0; z<p->sizeZ(); z++ ) {
279 zz = z;
280 if ( z > (p->sizeZ() - 1)/2 ) zz -= p->sizeZ();
281 sz2 = zz/realsize.z();
282 sz2 *= sz2;
283 for ( y=0; y<p->sizeY(); y++ ) {
284 yy = y;
285 if ( y > (p->sizeY() - 1)/2 ) yy -= p->sizeY();
286 sy2 = yy/realsize.y();
287 sy2 *= sy2;
288 for ( x=0; x<p->sizeX(); x++, i++ ) {
289 xx = x;
290 if ( x > (p->sizeX() - 1)/2 ) xx -= p->sizeX();
291 sx2 = xx/realsize.x();
292 sx2 *= sx2;
293 if ( sx2 + sy2 + sz2 > res2 ) {
294 weight = 0;
295 nzero++;
296 } else if ( fom[i] < threshold ) {
297 weight = inv_threshold;
298 nmax++;
299 } else
300 weight = 1.0/fom[i];
301 p->set(i, p->complex(i) * weight);
302 // fom[i] = weight;
303 }
304 }
305 }
306
307 if ( verbose & VERB_PROCESS )
308 cout << "Weighed fractions: zeroed=" << nzero*1.0/i << " maximum=" << nmax*1.0/i << endl << endl;
309
310 p->fft_back();
311
312 return 0;
313 }
314
331 Bimage* img_backprojection_weigh(Bimage** pacc, int imap, int nmaps, int nthreads, double resolution, double threshold, fft_plan planf, fft_plan planb)
332 {
333 if ( verbose & VERB_DEBUG )
334 cout << "DEBUG img_backprojection_weigh: threshold=" << threshold << endl;
335
336 int maps_per_class = nthreads;
337 int iclass = imap/nmaps;
338
339 Bimage* prec = pacc[0]->copy_header();
340 prec->data_alloc();
341 float* fom = prec->FOM_initialize();
342
343 unsigned long i, j, k;
344 unsigned long datasize = (unsigned long) prec->size().volume();
345 float* fom_acc;
346
347 unsigned long st(0), inc(1);
348 if ( nmaps == 2 ) {
349 st = imap%2;
350 inc = 2;
351 }
352 if ( nmaps == 3 && imap%3 ) {
353 st = imap%3 - 1;
354 inc = 2;
355 }
356
357 if ( verbose & VERB_DEBUG ) {
358 cout << "DEBUG img_backprojection_weigh: nmaps=" << nmaps << " imap=" << imap << endl;
359 cout << "DEBUG img_backprojection_weigh: maps_per_class=" << maps_per_class << " iclass=" << iclass << endl;
360 cout << "DEBUG img_backprojection_weigh: st=" << st << " inc=" << inc << endl;
361 }
362
363 for ( i=iclass*maps_per_class+st, j=st; j<maps_per_class; i+=inc, j+=inc ) {
364 // cout << "Doing map " << i << endl;
365 fom_acc = pacc[i]->FOM();
366 for ( k=0; k<datasize; k++ ) {
367 prec->add(k, pacc[i]->complex(k));
368 fom[k] += fom_acc[k];
369 }
370 }
371
372 if ( verbose & VERB_DEBUG )
373 cout << "DEBUG img_backprojection_weigh: Accumulation done" << endl;
374
375 prec->fft(planf, 1);
376
377 unsigned long x, y, z, nzero = 0, nmax = 0;
378 long xx, yy, zz;
379 double sx2, sy2, sz2, res2(1);
380 double inv_threshold = ( threshold )? 1.0/threshold: 1;
381 double weight = 0;
382 Vector3<double> realsize(prec->real_size());
383
384 if ( resolution > 0 ) res2 = 1/(resolution*resolution);
385
386 if ( verbose & VERB_FULL ) {
387 cout << "Filtering to a resolution of " << 1/sqrt(res2) << " A" << endl;
388 cout << "R-weighting with a cutoff factor of " << threshold << endl << endl;
389 }
390
391 for ( i=z=0; z<prec->sizeZ(); z++ ) {
392 zz = z;
393 if ( z > (prec->sizeZ() - 1)/2 ) zz -= prec->sizeZ();
394 sz2 = zz/realsize.z();
395 sz2 *= sz2;
396 for ( y=0; y<prec->sizeY(); y++ ) {
397 yy = y;
398 if ( y > (prec->sizeY() - 1)/2 ) yy -= prec->sizeY();
399 sy2 = yy/realsize.y();
400 sy2 *= sy2;
401 for ( x=0; x<prec->sizeX(); x++, i++ ) {
402 xx = x;
403 if ( x > (prec->sizeX() - 1)/2 ) xx -= prec->sizeX();
404 sx2 = xx/realsize.x();
405 sx2 *= sx2;
406 if ( sx2 + sy2 + sz2 > res2 ) {
407 weight = 0;
408 nzero++;
409 } else if ( fom[i] <= threshold ) {
410 weight = inv_threshold;
411 nmax++;
412 } else
413 weight = 1.0/fom[i];
414 prec->set(i, prec->complex(i) * weight);
415 // fom[i] = weight;
416 }
417 }
418 }
419
420 if ( verbose ) {
421 cout << "Weighed fraction: " << (i-nzero-nmax)*1.0/i << endl;
422 cout << "Zeroed fraction: " << nzero*1.0/i << endl;
423 cout << "Fraction below threshold: " << nmax*1.0/i << endl << endl;
424 }
425
426 prec->fft(planb, 1);
427 prec->complex_to_real();
428
429 return prec;
430 }
431
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1438
Vector3::z
Type z()
Definition: Vector3.h:141
Bparticle::id
int id
Definition: mg_processing.h:60
Bimage::sizeZ
void sizeZ(size_t nz)
Definition: Bimage.h:330
Bimage::copy_header
Bimage * copy_header()
Definition: Bimage.h:502
Bsub_image::view
void view(double x, double y, double z, double a)
Definition: Bimage.h:136
Bparticle::view
View view
Definition: mg_processing.h:68
Bimage::fft
int fft()
Definition: Bimage.h:607
Bimage::fft_back
int fft_back()
Definition: Bimage.h:608
utilities.h
Header file for general utilities.
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:104
project_count_mg_part_selected
long project_count_mg_part_selected(Bproject *project)
Counts the number of particles in a project.
Definition: mg_processing.cpp:735
Complex.h
Class for complex numbers.
Float
Definition: Bimage.h:60
Matrix3
Definition: Matrix3.h:17
Vector3< int >
error_show
int error_show(const char *message, const char *file, int line)
Displays the error with file and line reference.
Definition: utilities.cpp:652
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:99
Bimage::check
void check()
Checks an image for reasonable properties.
Definition: Bimage.cpp:346
img_weigh_transform
int img_weigh_transform(Bimage *p, double resolution, double threshold)
Weighs a transform with the FOM.
Definition: img_backproject.cpp:256
Bimage::statistics
size_t statistics()
Calculates the statistics for an image.
Definition: Bimage_stats.cpp:22
Bfield::next
Bfield * next
Definition: mg_processing.h:221
Matrix3.h
3x3 Matrix manipulation functions
Bmicrograph::part
Bparticle * part
Definition: mg_processing.h:204
TSimple
Definition: Bimage.h:71
Bimage
General image parameter class.
Definition: Bimage.h:153
Bmicrograph::fpart
Bstring fpart
Definition: mg_processing.h:173
Bimage::real_size
Vector3< double > real_size()
Definition: Bimage.h:409
Bimage::data_alloc
unsigned char * data_alloc()
Definition: Bimage.h:227
Bfield
Definition: mg_processing.h:220
M_PI
#define M_PI
Definition: utilities.h:51
verbose
int verbose
Bmicrograph::pixel_size
float pixel_size
Definition: mg_processing.h:180
img_backproject.h
Header file for 3D reconstruction by backprojection.
Bimage::FOM_initialize
float * FOM_initialize()
Allocates and initializes the FOM block.
Definition: Bimage.cpp:677
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:823
Bimage::sampling
void sampling(double s)
Definition: Bimage.h:412
Bproject::field
Bfield * field
Definition: mg_processing.h:304
VERB_TIME
#define VERB_TIME
Definition: utilities.h:102
Bimage::FOM
float * FOM()
Definition: Bimage.h:240
img_back_project_one
int img_back_project_one(Bimage *p, Bimage *pmap)
Back-projects a 2D image into a 3D volume.
Definition: img_backproject.cpp:163
img_fourier.h
General FFT for n-dimensional data.
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:103
img_backprojection_weigh
Bimage * img_backprojection_weigh(Bimage **pacc, int imap, int nmaps, int nthreads, double resolution, double threshold, fft_plan planf, fft_plan planb)
Accumulates multiple backprojections and weighs the transform with the FOM.
Definition: img_backproject.cpp:331
Bmicrograph
Definition: mg_processing.h:167
Vector3::x
Type x()
Definition: Vector3.h:139
Bimage::size
Vector3< size_t > size()
Definition: Bimage.h:325
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:133
Bimage::add
void add(size_t j, double v)
Definition: Bimage.h:266
Bimage::set
void set(size_t j, double v)
Sets a single value at the given index.
Definition: Bimage.cpp:915
Bimage::view
void view(double vx, double vy, double vz, double va)
Definition: Bimage.h:450
Bfield::mg
Bmicrograph * mg
Definition: mg_processing.h:225
project
Bproject * project
Definition: tcltk_bshow.cpp:31
fftwnd_data
Definition: fftw.h:355
VERB_RESULT
#define VERB_RESULT
Definition: utilities.h:97
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
Bimage::data_pointer
unsigned char * data_pointer()
Definition: Bimage.h:232
Bparticle
Definition: mg_processing.h:57
Bimage::sizeX
void sizeX(size_t nx)
Definition: Bimage.h:328
project_back_projection
Bimage * project_back_projection(Bproject *project, int num_select, Vector3< int > map_size, Vector3< float > sampling, double scale, double resolution)
Back projects a set of 2D images into a 3D volume.
Definition: img_backproject.cpp:39
Bimage::sizeY
void sizeY(size_t ny)
Definition: Bimage.h:329
View
Definition: View.h:26
Bsub_image::magnification
double magnification()
Definition: Bimage.h:141
Bparticle::sel
int sel
Definition: mg_processing.h:70
mg_processing.h
Header file for micrograph processing.
rwimg.h
Header file for 2D and 3D image I/O.
Bparticle::ori
Vector3< float > ori
Definition: mg_processing.h:67
Bparticle::mag
float mag
Definition: mg_processing.h:62
Bparticle::next
Bparticle * next
Definition: mg_processing.h:58
VERB_FULL
#define VERB_FULL
Definition: utilities.h:101
VERB_LABEL
#define VERB_LABEL
Definition: utilities.h:98
Vector3::volume
double volume()
Definition: Vector3.h:207
Vector3::y
Type y()
Definition: Vector3.h:140
Bproject
Definition: mg_processing.h:294
Bimage::image
Bsub_image * image
Definition: Bimage.h:184
Bmicrograph::next
Bmicrograph * next
Definition: mg_processing.h:168