| Bsoft 2.0.5 Bernard's software package

mg_align.cpp
Go to the documentation of this file.
1
9 #include "Bimage.h"
10 #include "mg_align.h"
11 #include "rwimg.h"
12 #include "mg_processing.h"
13 #include "mg_img_proc.h"
14 #include "marker.h"
15 #include "ps_marker.h"
16 #include "linked_list.h"
17 #include "utilities.h"
18
19 #include <sys/stat.h>
20
21 // Declaration of global variables
22 extern int verbose; // Level of output to the screen
23
38 int mg_align_coordinates(Bproject* project, int refset)
39 {
40 if ( refset < 0 ) refset = 0;
41
42 int i;
43 long nmg, npart, nmg_max = 1000;
44 Transform t;
45
46 Bfield* field;
47 Bmicrograph* mg;
48 Bparticle* part;
49
50 Bmarker** set = new Bmarker*[nmg_max];
51 Bmarker* m = NULL;
52
53 Vector3<double> origin;
54
55 if ( verbose & VERB_LABEL )
56 cout << "Aligning micrograph particle coordinates for series of micrographs." << endl;
57 if ( verbose & VERB_PROCESS )
58 cout << "Particles\tX-shift\tY-shift\tX-scale\tY-scale\tAngle" << endl;
59
60 for ( field=project->field; field; field=field->next ) {
61 for ( i=1, mg=field->mg; mg->next && i < refset; mg=mg->next ) i++;
62 origin = micrograph_get_nominal_origin(mg);
63 nmg = field_count_micrographs(field);
64 npart = micrograph_count_particles(field->mg);
65 for ( i=0, mg=field->mg; mg; mg=mg->next, i++ ) {
66 for ( part=mg->part; part; part=part->next ) {
67 m = (Bmarker *) add_item((char **) &m, sizeof(Bmarker));
68 if ( !set[i] ) set[i] = m;
69 m->loc = part->loc;
70 m->sel = 1;
71 m->fom = 1;
72 }
73 }
74 for ( i=0, mg=field->mg->next; mg; mg=mg->next, i++ ) if ( i != refset ) {
75 t = markers_find_rottrans(set[refset], set[i], 0.01);
76 mg->rot_angle = t.angle;
77 mg->origin = origin + t.trans;
78 mg->scale = t.scale;
79 if ( verbose & VERB_PROCESS )
80 cout << npart << tab << t.trans[0] << tab << t.trans[1] << tab << t.trans[2] << tab <<
81 t.scale[0] << tab << t.scale[1] << tab << t.scale[2] << tab << t.angle*180.0/M_PI << endl;
82 }
83 for ( i=0; i<nmg; i++ )
84 kill_list((char *) set[i], sizeof(Bmarker));
85 }
86
87 delete[] set;
88
89 return 0;
90 }
91
92 /*
93 @brief Aligns the second image to the first.
94 @param *p1 first image.
95 @param *p2 second image (transformed)
96 @param tile_size 3-valued vector for the size of sub-images.
97 @param res_lo low resolution limit for cross-correlation.
98 @param res_hi high resolution limit for cross-correlation.
99 @param max_shift maximum shift allowed (default 1/4 of tile).
100 @param filter_flag flag to filter micrograph extremes.
101 @param refine_flag flag to turn on refinement of shift.
102 @return Transform structure with shift, scale, rotation angle, and R factor.
103
104 The second image is transformed to fit on the first image.
105
106 */
107 Transform img_align(Bimage* p1, Bimage* p2, Vector3<long> tile_size,
108 double res_lo, double res_hi, double max_shift, int filter_flag, int refine_flag)
109 {
110 long i, iter, maxiter(5);
111 Vector3<double> shift;
112 Transform t, best_t;
113 best_t.fom = 1e37;
114
115 Vector3<long> start1, common_size, step_size;
116
117 // Find the largest area covering both images
118 common_size = p1->size().min(p2->size());
119 common_size = common_size.max(1);
120
121 // Ensure the tile fits into the images
122 tile_size = tile_size.max(1);
123 tile_size = tile_size.min(common_size);
124 if ( tile_size[0] >= common_size[0] && common_size[0] > 1 ) {
125 tile_size[0] = (int) (0.4*common_size[0]);
126 // start1[0] = (common_size[0] - tile_size[0])/2;
127 }
128 if ( tile_size[1] >= common_size[1] && common_size[1] > 1 ) {
129 tile_size[1] = (int) (0.4*common_size[1]);
130 // start1[1] = (common_size[1] - tile_size[1])/2;
131 }
132 if ( tile_size[2] >= common_size[2] && common_size[2] > 1 ) {
133 tile_size[2] = (int) (0.4*common_size[2]);
134 // start1[2] = (common_size[2] - tile_size[2])/2;
135 }
136
137 if ( max_shift < 1 ) max_shift = tile_size[0]/4;
138
139 Vector3<double> half_tile;
140 half_tile[0] = (tile_size[0] - 1)/2;
141 half_tile[1] = (tile_size[1] - 1)/2;
142 half_tile[2] = (tile_size[2] - 1)/2;
143
144 Bimage* pex1 = NULL;
145 Bimage* pex2 = NULL;
146 Bmarker* set1 = NULL;
147 Bmarker* set2 = NULL;
148 Bmarker* m1 = NULL;
149 Bmarker* m2 = NULL;
150 // Bstring filename = p1->file_name().pre_rev('.') + "_" + p2->file_name().pre_rev('.') + ".ps";
151 Bstring fn1(p1->file_name()), fn2(p2->file_name());
152 Bstring filename(fn1.base() + "_" + fn2.base() + ".ps");
153
154 if ( verbose & VERB_LABEL ) {
155 cout << "Aligning images ";
156 if ( refine_flag ) cout << "with ";
157 else cout << "without ";
158 cout << "shift refinement." << endl << endl;
159 }
160
161 if ( common_size[0] > 2*tile_size[0] )
162 start1[0] = (common_size[0]
163 - (int) (tile_size[0]*(common_size[0]/tile_size[0])))/2;
164 if ( common_size[1] > 2*tile_size[1] )
165 start1[1] = (common_size[1]
166 - (int) (tile_size[1]*(common_size[1]/tile_size[1])))/2;
167 if ( common_size[2] > 2*tile_size[2] )
168 start1[2] = (common_size[2]
169 - (int) (tile_size[2]*(common_size[2]/tile_size[2])))/2;
170
171 if ( verbose & VERB_PROCESS ) {
172 cout << "Common size: " << common_size << endl;
173 cout << "Tile size: " << tile_size << endl;
174 cout << "Maximum shift: " << max_shift << endl;
175 cout << "Reference start: " << start1 << endl << endl;
176 }
177
178 if ( res_hi < 0.1 || res_hi > tile_size[0]*p1->sampling()[0] ) res_hi = 4.0*p1->sampling()[0];
179
180 if ( filter_flag ) {
181 p1->filter_extremes();
182 p2->filter_extremes();
183 }
184
185 pex1 = p1->extract_tiles(0, start1, common_size, tile_size, step_size, 0);
186
187 // Vector3<long>* tile_start = new Vector3<long>[pex1->images()];
188 vector<Vector3<long>> tile_start(pex1->images());
189
190 for ( i=0; i<pex1->images(); i++ ) {
191 m1 = (Bmarker *) add_item((char **) &m1, sizeof(Bmarker));
192 m2 = (Bmarker *) add_item((char **) &m2, sizeof(Bmarker));
193 if ( !set1 ) set1 = m1;
194 if ( !set2 ) set2 = m2;
195 m1->sel = m2->sel = 1;
196 m1->fom = m2->fom = 1;
197 m1->loc = pex1->image[i].origin() + half_tile;
198 tile_start[i] = pex1->image[i].origin();
199 }
200
201 for ( iter=0; iter<maxiter && best_t.fom>0.1; iter++ ) {
202 pex2 = p2->extract_tiles(0, tile_start, tile_size);
203 // Determines the shift of the second image onto the first
204 pex1->find_shift(pex2, NULL, res_hi, res_lo, max_shift, 0, refine_flag);
205 for ( i=0, m2=set2; i<pex1->images(); i++, m2=m2->next ) {
206 shift = pex1->image[i].origin() - pex2->image[i].origin();
207 if ( shift[0] > half_tile[0] ) shift[0] -= tile_size[0];
208 if ( shift[1] > half_tile[1] ) shift[1] -= tile_size[1];
209 if ( shift[2] > half_tile[2] ) shift[2] -= tile_size[2];
210 // To get the location in the second image, the shift must be subtracted
211 m2->loc = tile_start[i] + half_tile - shift;
212 }
213 t = markers_find_rottrans(set1, set2, 0.01);
214 if ( verbose & VERB_PROCESS )
215 cout << "Fit " << iter+1 << ":\t" << p1->file_name() << tab << p2->file_name() << tab
216 << t.trans << tab
217 << t.scale << tab
218 << t.angle*180.0/M_PI << tab << t.fom << endl;
219 if ( best_t.fom > t.fom ) best_t = t;
220 else iter = maxiter;
221 for ( i=0, m1=set1, m2=set2; i<pex1->images(); i++, m1=m1->next, m2=m2->next ) {
222 m2->loc[0] = best_t.scale[0]*(m1->loc[0]*cos(best_t.angle) -
223 m1->loc[1]*sin(best_t.angle)) + t.trans[0] + 0.5;
224 m2->loc[1] = best_t.scale[1]*(m1->loc[0]*sin(best_t.angle) +
225 m1->loc[1]*cos(best_t.angle)) + t.trans[1] + 0.5;
226 m2->loc[2] = best_t.scale[2]*m1->loc[2] + t.trans[2];
227 tile_start[i] = m2->loc - half_tile;
228 }
229 delete pex2;
230 }
231
232 if ( verbose & VERB_RESULT )
233 cout << "Best fit:\t" <<
234 p1->file_name() << tab << p2->file_name() << tab <<
235 best_t.trans << tab <<
236 best_t.scale << tab <<
237 best_t.angle*180.0/M_PI << tab << best_t.fom << endl;
238
239 delete pex1;
240
241 ps_marker_errors(filename, set1, set2, t, p1->size(), 20);
242
243 kill_list((char *) set1, sizeof(Bmarker));
244 kill_list((char *) set2, sizeof(Bmarker));
245
246 return best_t;
247 }
248
249 Bimage* img_sum_subset(Bimage* p, Bstring& subset)
250 {
251 long n, ns(0);
252 int* numsel = new int[p->images()];
253 select_numbers(subset, p->images(), numsel);
254
255 Bimage* p1;
256 Bimage* pa = p->copy_header(1);
257 pa->data_type(Float);
258 pa->sampling(p->sampling());
259 pa->data_alloc();
260
261 for ( n=0; n<p->images(); n++ ) if ( numsel[n] ) {
262 if ( verbose & VERB_PROCESS )
263 cout << "Adding frame " << n << endl;
264 p1 = p->extract(n);
265 p1->change_type(Float);
266 pa->add(p1);
267 delete p1;
268 ns++;
269 }
270
271 delete[] numsel;
272
273 double var1(p->standard_deviation()*p->standard_deviation());
274 double var(pa->standard_deviation()*pa->standard_deviation());
275 double snr(0);
276 if ( var < ns*ns*var1 ) snr = (var - ns*var1)/(ns*var1 - var/ns);
277
278 pa->image->FOM(snr);
279
280 return pa;
281 }
282
283
315 int mg_align_micrographs(Bproject* project, int refset,
316 Vector3<long> tile_size, double res_lo, double res_hi,
317 double max_shift, int filter_flag, int refine_flag)
318 {
319 long i;
320
321 Bfield* field;
322 Bmicrograph* mg, *mg_ref;
323
324 Bimage* p = NULL;
325 Bimage* p2 = NULL;
326
327 Transform t;
328
329 if ( verbose ) {
330 cout << "Aligning micrographs for micrograph series ";
331 if ( refine_flag ) cout << "with ";
332 else cout << "without ";
333 cout << "shift refinement." << endl << endl;
334 }
335
336 for ( field=project->field; field; field=field->next ) if ( field->mg ) {
337 for ( i=1, mg = mg_ref = field->mg; mg->next && i < refset; mg=mg->next, i++ ) ;
338 if ( mg ) mg_ref = mg;
339 p = read_img(mg_ref->fmg, 1, mg->img_num);
340 if ( !p ) {
341 cerr << "Error in mg_align_micrographs: File " << mg_ref->fmg << " not read!" << endl;
342 return -1;
343 }
344 if ( mg_ref->pixel_size > 0.1 ) p->sampling(mg_ref->pixel_size, mg_ref->pixel_size, 1);
345 mg_ref->origin = p->size()/2;
346 t = Transform();
347 mg_ref->rot_angle = 0;
348 mg_ref->scale = t.scale;
349 for ( mg=field->mg; mg; mg=mg->next ) {
350 if ( mg_ref != mg ) {
351 p2 = read_img(mg->fmg, 1, mg->img_num);
352 if ( !p ) {
353 cerr << "Error in mg_align_micrographs: File " << mg->fmg << " not read!" << endl;
354 return -1;
355 }
356 if ( mg->pixel_size > 0.1 ) p2->sampling(mg->pixel_size, mg->pixel_size, 1);
357 mg->origin = mg_ref->origin;
358 t = Transform();
359 // The alignment transforms the second image
360 // cout << "aligning:" << tab << p->file_name() << tab << p2->file_name() << endl;
361 t = img_align(p, p2, tile_size, res_lo, res_hi, max_shift, filter_flag, refine_flag);
362 mg->rot_angle = t.angle;
363 mg->origin += t.trans;
364 mg->scale = t.scale;
365 mg->matrix = Matrix3(t.axis, -t.angle);
366 mg_apply_transform(mg_ref, mg);
367 delete p2;
368 }
369 }
370 delete p;
371 }
372
373 return 0;
374 }
375
376 /*
377 @author Samuel Payne and Bernard Heymann
378 @brief Finds local minimums in a grey scale image and uses those as features
379 @param *p image (modified to floating point).
380 @param extract_method The method to determine the center of the particle
381 @param target_num Max number of desired features (-1 will return all)
382 @param threshold Threshold value used to determine whether
383 a pixel is considered a feature.
384 @return Bmarker* a set containing xyz coordinates of features
385
386 The input image is expected to have been cleaned in the following manner.
387 With each suggestion is listed the corresponding bsoft function call.
388 1. Any extremes such as white lettering, or black edges have been removed.
389 bfilter -e filname filename
390 2. Edge filter to smooth out the edges.
391 bedge -x<xsize>,<ysize>,<zsize> -o150,150,0 -g75 filename filename
392 3. Bandpass filtered to reduce the noise.
393 bfilter -b1000,2000 -df filename filename
394
395 The algorithm finds blocks of dark grey. The features are black dots
396 in the image, which could be particles, but don't have to be. As long
397 as the picking is consistent, it does not matter what is picked.
398 (it could be a pickle). The method used to find the center of the feature
399 depends on the input. (0=Center of Mass, 1=Center of Area, 2=Darkest pixel)
400
401 **/
402 Bmarker* img_extract_features(Bimage* p, int extract_method,
403 int target_num, double threshold)
404 {
405 // The extreme considered as a feature depends on the relative threshold
406 int sign = 1;
407 if ( threshold < p->average() ) sign = -1;
408
409 long i, j, x, y, z, n;
410 long count(0);
411 Vector3<long> coor;
412 double temp;
413
414 if ( verbose & VERB_LABEL ) {
415 cout << "Using the ";
416 switch ( extract_method ) {
417 case 1: cout << "center of mass "; break;
418 case 2: cout << "center of volume "; break;
419 case 3: cout << "highest pixel density "; break;
420 default: cout << "center of mass "; break;
421 }
422 cout << "to determine the feature coordinates in " << p->file_name() << endl;
423 }
424
425 // Definition of features based on regions beyond a threshold
426 Bimage* pmask = p->regions(threshold, 0);
427 count = (long) pmask->maximum();
428
429 if ( verbose & VERB_LABEL )
430 cout << "Features extracted: " << count << endl << endl;
431
432 if ( count < 1 ) {
433 delete pmask;
434 return NULL;
435 }
436
437 Bmarker* set = NULL;
438 Bmarker* m = NULL;
439 Bmarker** lut = new Bmarker*[count];
440
441 for ( i=0; i<count; i++ ) {
442 m = (Bmarker *) add_item((char **) &m, sizeof(Bmarker));
443 if ( !set ) set = m;
444 m->id = i+1;
445 m->sel = i+1;
446 lut[i] = m;
447 }
448
449 for ( i=n=0; n<p->images(); n++ ) {
450 for ( z=0; z<p->sizeZ(); z++ ) {
451 coor[2] = z;
452 for ( y=0; y<p->sizeY(); y++ ) {
453 coor[1] = y;
454 for ( x=0; x<p->sizeX(); x++, i++ ) {
455 coor[0] = x;
456 if ( (*pmask)[i] > 0 ) { //meaning that it belongs to a group
457 j = (long) ((*pmask)[i]-1);
458 m = lut[j];
459 // cout << "Region " << i << ": " << (*pmask)[i] << endl;
460 temp = fabs((*p)[i]);
461 if ( extract_method == 1 ) {
462 m->loc += coor * temp;
463 m->fom += temp;
464 } else if ( extract_method == 2 ) {
465 m->loc += coor;
466 m->fom += 1;
467 }
468 if ( sign*(*p)[i] > sign*m->fom ) {
469 m->fom = (*p)[i];
470 if ( extract_method == 3 ) {
471 m->loc = coor;
472 }
473 }
474 m->img_num = n;
475 }
476 }
477 }
478 }
479 }
480
481 delete pmask;
482 delete[] lut;
483
484 cout << "Feature marker list generated" << endl;
485
486 markers_limit(target_num, sign, &set);
487
488 // if ( verbose & VERB_FULL )
489 cout << "Feature\tx\ty\tz\tex\tey\tez\tFOM" << endl;
490
491 for ( m=set; m; m=m->next ) {
492 if ( extract_method == 1 || extract_method == 2 )
493 m->loc /= m->fom;
494 m->err = m->loc - p->size() /2;
495 // if ( verbose & VERB_FULL )
496 cout << m->id << tab << m->loc << tab <<
497 m->err << tab << m->fom << endl;
498 }
499 if ( verbose & VERB_FULL )
500 cout << endl;
501
502 if ( verbose & VERB_DEBUG ) {
503 cout << "\nDEBUG img_extract_features: The Feature set" << endl;
504 for ( m=set; m; m=m->next )
505 cout << "Feature " << m->id << ": " << m->loc << tab << m->fom << endl;
506 pmask = p->mask_by_threshold(threshold);
507 Bstring filename(p->file_name());
508 filename = filename.base() + "_features.pif";
509 write_img(filename, pmask, 0);
510 delete pmask;
511 }
512
513
514 return set;
515 }
516
517
541 int mg_align_feature_extraction(Bproject* project, int max_features,
542 double res_low, double res_high, double thresh, int extract_method)
543 {
544 long i, refset(-1), nmg;
545 Vector3<long> size;
546 Vector3<double> origin;
547 double width;
548 Transform* tlist = NULL;
549 Transform* t = NULL;
550
551 Bfield* field;
552 Bmicrograph* mg, *mg_ref = NULL;
553
554 long nmg_max = field_count_micrographs(project->field);
555 if ( nmg_max < 5 ) nmg_max = 5;
556
557 Bmarker** set = new Bmarker*[nmg_max];
558
559 Bimage* p = NULL;
560
561 if ( verbose & VERB_LABEL )
562 cout << "Aligning micrographs for micrograph series using features." << endl;
563
564 for ( field=project->field; field; field=field->next ) {
565 nmg = field_count_micrographs(field);
566 if ( refset < 0 ) refset = 0;
567 for ( i=0, mg=field->mg; mg; mg=mg->next, i++ ) {
568 if ( mg->part ) refset = i;
569 if ( i == refset ) mg_ref = mg;
570 p = read_img(mg->fmg, 1, 0);
571 mg->origin = p->size()/2;
572 // Before features are extracted, the image must be filtered for extreme
573 // values, the edge smoothed and finally bandpass-filtered.
574 p->filter_extremes();
575 width = 0.05*p->sizeX();
576 if ( p->sizeY() > p->sizeX() ) width = 0.05*p->sizeY();
577 origin = p->size() * 0.1;
578 if ( origin[0] > p->sizeX() - 1 ) origin[0] = p->sizeX() - 1;
579 if ( origin[1] > p->sizeY() - 1 ) origin[1] = p->sizeY() - 1;
580 if ( origin[2] > p->sizeZ() - 1 ) origin[2] = p->sizeZ() - 1;
581 size[0] = (int) (p->sizeX() - 2*origin[0]);
582 size[1] = (int) (p->sizeY() - 2*origin[1]);
583 size[2] = (int) (p->sizeZ() - 2*origin[2]);
584 if ( size[0] > p->sizeX() ) size[0] = p->sizeX();
585 if ( size[1] > p->sizeY() ) size[1] = p->sizeY();
586 if ( size[2] > p->sizeZ() ) size[2] = p->sizeZ();
587 p->shape(0, size, origin, width, FILL_AVERAGE, p->average());
588 p->fspace_bandpass(res_high, res_low, 0);
589 set[i] = img_extract_features(p, extract_method, max_features, thresh);
590 if ( set[i] == NULL) {
591 error_show("Error in mg_align_feature_extraction", __FILE__, __LINE__);
592 cerr << "Unable to extract any features from " << p->file_name() << endl;
593 return -1;
594 }
595 size = p->size();
596 delete p;
597 }
598 tlist = markers_map_and_find_transform(set, nmg, refset, size);
599 if ( !t->fom ) {
600 error_show("Error in mg_align_feature_extraction", __FILE__, __LINE__);
601 cerr << "Transformation parameters not found!" << endl;
602 return -1;
603 }
604 for ( i=0, mg=field->mg, t=tlist; mg; mg=mg->next, t=t->next, i++ ) if ( i != refset ) {
605 mg->rot_angle = t->angle;
606 mg->origin = mg->origin + t->trans;
607 mg->scale = t->scale;
608 mg_apply_transform(mg_ref, mg);
609 }
610 for ( i=0, mg=field->mg; mg; mg=mg->next, i++ )
611 kill_list((char *)set[i], sizeof(Bmarker));
612 }
613
614 delete[] set;
615 kill_list((char *) tlist, sizeof(Transform));
616
617 return 0;
618 }
619
630 int mg_apply_transform(Bmicrograph* mg_ref, Bmicrograph* mg_apply)
631 {
632 if ( mg_ref == mg_apply ) return 0;
633
634 long npref = micrograph_count_particles(mg_ref);
635 long npapp = micrograph_count_particles(mg_apply);
636 long nfref = filament_node_count(mg_ref->fil);
637 long nfapp = filament_node_count(mg_apply->fil);
638 Bparticle *part_ref, *part_app;
639 Bbadarea *bad_ref, *bad_app;
640 Bfilament *fil_ref, *fil_app;
641 Bfilnode *fn_ref, *fn_app;
642 Bmarker *mark_ref, *mark_app;
643
644 // double angle = mg_ref->rot_angle - mg_apply->rot_angle;
645 // double cos_ang = cos(angle), sin_ang = sin(angle);
646 // Vector3<float> shift = mg_ref->origin - mg_apply->origin;
647 // Vector3<float> scale = mg_ref->scale / mg_apply->scale;
648
649 double angle = mg_apply->rot_angle - mg_ref->rot_angle;
650 double cos_ang = cos(angle), sin_ang = sin(angle);
651 Vector3<double> shift = mg_apply->origin - mg_ref->origin;
652 Vector3<double> scale = mg_apply->scale / mg_ref->scale;
653 Vector3<double> loc;
654
655 // if ( npref < 1 ) {
656 // cerr << "Warning: No particle coordinates for reference micrograph " << mg_ref->id << endl;
657 // return 0;
658 // }
659
660 if ( verbose & VERB_PROCESS ) {
661 cout << "Applying transform parameters to micrographs:" << endl;
662 cout << "Reference micrograph: " << mg_ref->id << endl;
663 cout << "Transform micrograph: " << mg_apply->id << endl;
664 cout << "Shift: " << shift << endl;
665 cout << "Scale: " << scale << endl;
666 cout << "Rotation angle: " << angle*180.0/M_PI << endl << endl;
667 } else if ( verbose & VERB_LABEL )
668 cout << "Applying transform parameters to micrographs" << endl << endl;
669
670 mg_apply->box_size = mg_ref->box_size;
671 mg_apply->bad_radius = mg_ref->bad_radius;
672 mg_apply->filament_width = mg_ref->filament_width;
673 mg_apply->fil_node_radius = mg_ref->fil_node_radius;
674 mg_apply->mark_radius = mg_ref->mark_radius;
675
676 if ( npapp != npref ) {
677 particle_kill(mg_apply->part);
678 mg_apply->part = part_app = NULL;
679 for ( part_ref=mg_ref->part; part_ref; part_ref=part_ref->next ) {
680 part_app = particle_add(&part_app, part_ref->id);
681 if ( !mg_apply->part ) mg_apply->part = part_app;
682 }
683 }
684
685 if ( mg_ref->part ) {
686 for ( part_ref=mg_ref->part, part_app=mg_apply->part; part_ref;
687 part_ref=part_ref->next, part_app=part_app->next ) {
688 part_app->id = part_ref->id;
689 loc = scale*(part_ref->loc + shift);
690 part_app->loc[0] = loc[0] * cos_ang - loc[1] * sin_ang;
691 part_app->loc[1] = loc[0] * sin_ang + loc[1] * cos_ang;
692 }
693 }
694
695 if ( mg_apply->bad ) {
696 kill_list((char *) mg_apply->bad, sizeof(Bbadarea));
697 mg_apply->bad = NULL;
698 }
699
700 if ( mg_ref->bad ) {
701 for ( bad_ref=mg_ref->bad; bad_ref; bad_ref=bad_ref->next ) {
702 bad_app = (Bbadarea *) add_item((char **) &mg_apply->bad, sizeof(Bbadarea));
703 loc = scale*(bad_ref->loc + shift);
704 bad_app->loc[0] = loc[0] * cos_ang - loc[1] * sin_ang;
705 bad_app->loc[1] = loc[0] * sin_ang + loc[1] * cos_ang;
706 }
707 }
708
709 if ( nfapp != nfref ) {
710 filament_kill(mg_apply->fil);
711 mg_apply->fil = fil_app = NULL;
712 for ( fil_ref=mg_ref->fil; fil_ref; fil_ref=fil_ref->next ) {
713 fil_app = filament_add(&fil_app, fil_ref->id);
714 if ( !mg_apply->fil ) mg_apply->fil = fil_app;
715 fil_app->node = fn_app = NULL;
716 for ( fn_ref = fil_ref->node; fn_ref; fn_ref = fn_ref->next ) {
717 fn_app = filament_node_add(&fn_app, fn_ref->id);
718 if ( !fil_app->node ) fil_app->node = fn_app;
719 }
720 }
721 }
722
723 if ( mg_ref->fil ) {
724 for ( fil_ref=mg_ref->fil, fil_app=mg_apply->fil; fil_ref;
725 fil_ref=fil_ref->next, fil_app=fil_app->next ) {
726 fil_app->id = fil_ref->id;
727 for ( fn_ref=fil_ref->node, fn_app=fil_app->node; fn_ref;
728 fn_ref=fn_ref->next, fn_app=fn_app->next ) {
729 fn_app->id = fn_ref->id;
730 loc = scale*(fn_ref->loc + shift);
731 fn_app->loc[0] = loc[0] * cos_ang - loc[1] * sin_ang;
732 fn_app->loc[1] = loc[0] * sin_ang + loc[1] * cos_ang;
733 }
734 }
735 }
736
737 if ( mg_apply->mark ) {
738 kill_list((char *) mg_apply->mark, sizeof(Bmarker));
739 mg_apply->mark = NULL;
740 }
741
742 if ( mg_ref->mark ) {
743 for ( mark_ref=mg_ref->mark; mark_ref; mark_ref=mark_ref->next ) {
744 mark_app = (Bmarker *) add_item((char **) &mg_apply->mark, sizeof(Bmarker));
745 loc = scale*(mark_ref->loc + shift);
746 mark_app->loc[0] = loc[0] * cos_ang - loc[1] * sin_ang;
747 mark_app->loc[1] = loc[0] * sin_ang + loc[1] * cos_ang;
748 mark_app->sel = mark_ref->sel;
749 mark_app->fom = mark_ref->fom;
750 }
751 }
752
753 return 0;
754 }
755
762 int mg_merge_focal_series(Bproject* project, int use_old_origins)
763 {
764 int i, ifield(0);
765 double cc;
766
767 Bimage* p = NULL; // Particle image
768 Bimage* pt = NULL; // Temporary image
769 Bimage* pref = NULL; // Particle reference image
770 Bimage* ptr = NULL; // Temporary reference image
771 Bimage* psum = NULL; // Particle sum image
772
773 // Vector3<float>* shift = NULL; // Shift vectors
774 // Vector3<float>* origin = NULL; // Origin vectors
775
776 Bfield* field;
777 Bmicrograph *mg, *mg2, *mg_ref;
778 Bparticle *part, *part_ref;
779 Bstring filename;
780 Bstring insert("_merged.");
781 Vector3<double> origin, scale(1,1,1), axis(0,0,1), shift;
782 Matrix3 mat;
783
784 for ( ifield = 0, field=project->field; field; field=field->next, ifield++ ) {
785 // Find the closest-to-focus particle image
786 for ( mg_ref = mg = field->mg; mg; mg = mg->next )
787 if ( mg_ref->ctf && mg->ctf )
788 if ( mg_ref->ctf->defocus_average() < mg->ctf->defocus_average() ) mg_ref = mg;
789 pref = read_img(mg_ref->fpart, 1, -1);
790 if ( !pref )
791 return error_show("Error in mg_merge_focal_series", __FILE__, __LINE__);
792 pref->origin(pref->size()/2);
793 pref->change_type(Float);
794 psum = pref->copy();
795 for ( mg = field->mg; mg; mg = mg->next ) if ( mg != mg_ref ) {
796 p = read_img(mg->fpart, 1, -1);
797 if ( !p )
798 return error_show("Error in mg_merge_focal_series", __FILE__, __LINE__);
799 p->origin(p->size()/2);
800 p->change_type(Float);
801 /* origin = new Vector3<float>[p->images()];
802 if ( use_old_origins ) {
803 shift = new Vector3<float>[p->images()];
804 for ( i=0, part = mg->part, part_ref = mg_ref->part; part;
805 i++, part = part->next, part_ref = part_ref->next ) {
806 shift[i] = part_ref->ori - part->ori;
807 origin[i] = part->ori;
808 }
809 } else {
810 // shift = img_find_shift(pref, p, NULL, p->sampling()[0]*2, 1e10, p->sizeX()/4.0, 0, 1, NULL);
811 // for ( i=0, part = mg->part; part; i++, part = part->next )
812 // origin[i] = mg->origin - shift[i];
813 p->find_shift(pref, NULL, p->sampling()[0]*2, 1e10, p->sizeX()/4.0, 0, 1);
814 for ( i=0, part = mg->part; part; i++, part = part->next )
815 origin[i] = mg->origin + pref->image[i].origin() - p->image[i].origin();
816 }
817 img_unique_shift_global_rotate(p, shift, origin, mg->rot_angle - mg_ref->rot_angle);
818 delete[] shift;
819 delete[] origin;
820 // img_add(psum, p, 1, 0);
821 */
822 mat = Matrix3(axis, mg->rot_angle - mg_ref->rot_angle);
823 for ( i=0, part = mg->part, part_ref = mg_ref->part; part;
824 i++, part = part->next, part_ref = part_ref->next ) {
825 pt = p->extract(i);
826 if ( use_old_origins ) {
827 shift = part_ref->ori - part->ori;
828 origin = part->ori;
829 } else {
830 ptr = pref->extract(i);
831 shift = pt->find_shift(ptr, NULL, ptr->sampling()[0]*2, 1e10, ptr->sizeX()/4.0, 0, 1, cc);
832 origin = ptr->image->origin() - shift;
833 delete ptr;
834 }
835 pt->transform(scale, origin, shift, mat, FILL_BACKGROUND, 0);
836 p->replace(i, pt);
837 }
838 psum->add(p);
839 delete p;
840 }
841 delete pref;
842 filename = mg_ref->fpart;
843 filename = filename.pre_rev('.') + insert + filename.post_rev('.');
844 if ( verbose & VERB_DEBUG )
845 cout << "DEBUG mg_merge_focal_series: mg=" << mg_ref->id << " filename=" << filename << endl;
846 psum->label("Written by Bsoft: Merged image");
847 write_img(filename, psum, 0);
848 delete psum;
849 for ( mg = field->mg; mg; ) {
850 mg2 = mg->next;
851 if ( mg != mg_ref ) micrograph_kill(mg);
852 mg = mg2;
853 }
854 field->mg = mg_ref;
855 mg_ref->next = NULL;
856 mg_ref->block = ifield;
857 mg_ref->fpart = filename;
858 }
859
860 return 0;
861 }
862
863 double field_write_aligned_average(Bfield* field, Bimage* pgr,
864 Bstring& imgfile, DataType datatype, Bstring& subset, Bstring& label)
865 {
866 long i, n;
867 Bmicrograph* mg;
868 Vector3<double> ori;
869 Bimage* p;
870 Bimage* pavg = NULL;
871 Bimage* pstd = NULL;
872 Vector3<double> scale(1,1,1);
873 Matrix3 mat(1);
874 Vector3<double> nori;
875
876 for ( n=0, mg = field->mg; mg; mg = mg->next, n++ ) ;
877 int* numsel = new int[n];
878 select_numbers(subset, n, numsel);
879
880 for ( i=n=0, mg = field->mg; mg; mg = mg->next, i++ ) if ( numsel[i] ){
881 p = read_img(mg->fmg, 1, mg->img_num);
882 if ( datatype == Unknown_Type ) datatype = p->data_type();
883 if ( datatype > p->data_type() ) p->change_type(datatype);
884 if ( pgr ) p->multiply(pgr);
885 p->calculate_background();
886 ori = p->size()/2;
887 p->transform(scale, nori, (ori - mg->origin), mat, FILL_BACKGROUND, 0);
888 p->change_type(datatype);
889 if ( !pavg ) pavg = p->copy();
890 else pavg->add(p);
891 p->square();
892 if ( !pstd ) pstd = p->copy();
893 else pstd->add(p);
894 delete p;
895 n++;
896 }
897
898 delete[] numsel;
899
900 if ( n ) {
901 pavg->multiply(1.0L/n);
902 pstd->multiply(1.0L/n);
903 } else {
904 field->select = 0;
905 return -1;
906 }
907
908 double snr = pavg->standard_deviation()*pavg->standard_deviation();
909
910 mg = field->mg;
911 micrograph_kill(mg->next);
912 mg->next = NULL;
913
914 View view = View(mg->matrix);
915 pavg->image->origin(ori);
916 pavg->image->view(view);
917 if ( mg->pixel_size ) pavg->sampling(mg->pixel_size, mg->pixel_size, 1);
918
919 pavg->label(label.str());
920 if ( imgfile.length() && pavg ) {
921 write_img(imgfile, pavg, 0);
922 mg->fmg = imgfile;
923 mg->img_num = 0;
924 }
925
926 pavg->square();
927 pstd->subtract(pavg);
928 snr /= pstd->average();
929
930 delete pavg;
931 delete pstd;
932
933 field->fom = snr;
934
935 return snr;
936 }
937
950 double project_write_aligned_images(Bproject* project, Bimage* pgr,
951 Bstring& imgfile, DataType datatype, Bstring& label)
952 {
953 long i, nmg;
954 Bfield* field = project->field;
955 Bmicrograph* mg = field->mg;
956 Bimage* p, *pone, *paln;
957 Vector3<double> origin;
958 Vector3<double> scale(1,1,1);
959 Matrix3 mat(1);
960 Vector3<double> nori;
961 View view;
962
963 for ( field = project->field; field; field = field->next ) {
964 for ( nmg=0, mg = field->mg; mg; mg = mg->next ) nmg++;
965 mg = field->mg;
966 p = read_img(mg->fmg, 0, -1);
967 if ( datatype == Unknown_Type ) datatype = p->data_type();
968 paln = new Bimage(datatype, p->compound_type(), p->sizeX(), p->sizeY(), 1, nmg);
969 if ( p->sizeZ() > 1 || p->images() > 1 ) {
970 delete p;
971 p = read_img(mg->fmg, 1, -1);
972 if ( p->sizeZ() > 1 ) p->slices_to_images();
973 } else {
974 delete p;
975 p = NULL;
976 }
977 if ( pgr ) p->multiply(pgr);
978 if ( project->field->next )
979 imgfile = mg->fmg.pre_rev('.') + "_aln." + mg->fmg.post_rev('.');
980 for ( i=0, mg = field->mg; mg; mg = mg->next, i++ ) {
981 view = View(mg->matrix);
982 if ( p ) pone = p->extract(i);
983 else pone = read_img(mg->fmg, 1, mg->img_num);
984 if ( datatype > pone->data_type() ) pone->change_type(datatype);
985 origin = pone->size()/2;
986 if ( origin != mg->origin ) {
987 pone->calculate_background();
988 pone->transform(scale, nori, (origin - mg->origin), mat, FILL_BACKGROUND, 0);
989 }
990 pone->change_type(datatype);
991 paln->replace(i, pone);
992 paln->image[i].origin(origin);
993 paln->image[i].view(view);
994 if ( mg->pixel_size ) paln->sampling(mg->pixel_size, mg->pixel_size, 1);
995 if ( imgfile.length() ) {
996 mg->fmg = imgfile;
997 mg->img_num = i;
998 mg->origin = origin;
999 }
1000 delete pone;
1001 }
1002 paln->label(label.str());
1003 if ( imgfile.length() && paln )
1004 write_img(imgfile, paln, 0);
1005 delete paln;
1006 }
1007
1008 return 0;
1009 }
1010
1011 double mg_write_average_frames(Bmicrograph* mg, Bimage* pgr,
1012 Bstring& avgfile, DataType datatype, Bstring& subset, Bstring& label)
1013 {
1014 Bstring path(avgfile);
1015 Bstring ext = avgfile.extension();
1016 if ( ext.length() < 1 ) ext = mg->fframe.post_rev('.');
1017
1018 if ( path.contains(".") ) {
1019 if ( path.contains("/") ) path = path.pre_rev('/') + "/";
1020 else path = 0;
1021 }
1022
1023 mg->fmg = mg->fframe.pre_rev('.') + "_avg." + ext;
1024
1025 if ( path.length() > 1 ) {
1026 mkdir(path.c_str(), (mode_t)0755);
1027 if ( path[-1] != '/' ) path += "/";
1028 if ( mg->fmg.contains("/") ) mg->fmg = mg->fmg.post_rev('/');
1029 mg->fmg = path + mg->fmg;
1030 }
1031
1032 if ( verbose )
1033 cout << "Writing frame average to: " << mg->fmg << endl;
1034
1035 Bimage* p = read_img(mg->fframe, 1, -1);
1036 if ( p->sizeZ() > 1 ) p->slices_to_images();
1037
1038 if ( pgr ) p->multiply(pgr);
1039
1040 p->sampling(mg->pixel_size, mg->pixel_size, 1);
1041
1042 Bimage* pa = img_sum_subset(p, subset);
1043
1044 delete p;
1045
1046 pa->label(label.str());
1047 write_img(mg->fmg, pa, 0);
1048
1049 mg->fom = pa->image->FOM();
1050
1051 delete pa;
1052
1053 return mg->fom;
1054 }
1055
1067 double project_write_average_frames(Bproject* project, Bimage* pgr,
1068 Bstring& avgfile, DataType datatype, Bstring& subset, Bstring& label)
1069 {
1070 long i, n, nmg(0);
1071 double snr_avg(0);
1072
1073 if ( verbose && avgfile.length() ) {
1074 cout << "Writing frame average to " << avgfile << endl;
1075 if ( subset.length() )
1076 cout << "Subset: " << subset << endl;
1077 }
1078
1079 Bmicrograph** mgarr = project_micrograph_array(project, nmg);
1080
1081 #ifdef HAVE_GCD
1082 dispatch_apply(nmg, dispatch_get_global_queue(0, 0), ^(size_t i){
1083 mg_write_average_frames(mgarr[i], pgr, avgfile, datatype, subset, label);
1084 });
1085 #else
1086 #pragma omp parallel for
1087 for ( i=0; i<nmg; i++ ) {
1088 mg_write_average_frames(mgarr[i], pgr, avgfile, datatype, subset, label);
1089 }
1090 #endif
1091
1092 if ( verbose & VERB_RESULT )
1093 cout << "Micrograph\tSNR" << endl;
1094
1095 for ( i = n = 0; i < nmg; i++ ) {
1096 snr_avg += mgarr[i]->fom;
1097 n++;
1098 if ( verbose & VERB_RESULT )
1099 cout << mgarr[i]->id << tab << mgarr[i]->fom << endl;
1100 }
1101
1102 if ( n ) snr_avg /= n;
1103
1104 delete[] mgarr;
1105
1106 return snr_avg;
1107 }
1108
1122 double project_write_aligned_averages(Bproject* project, Bimage* pgr,
1123 Bstring& imgfile, DataType datatype, Bstring& subset, Bstring& label)
1124 {
1125 Bfield* field = project->field;
1126 long n, nfield(0);
1127 double snr_avg(0);
1128
1129 if ( verbose & VERB_RESULT ) {
1130 cout << "Writing micrograph average to " << imgfile << endl;
1131 if ( subset.length() )
1132 cout << "Subset: " << subset << endl;
1133 }
1134
1135 Bstring path;
1136 if ( imgfile.contains("/") ) path = imgfile.pre_rev('/') + "/";
1137
1138 for ( field = project->field; field; field = field->next ) nfield++;
1139
1140 Bfield** farr = new Bfield*[nfield];
1141 for ( n=0, field = project->field; field; field = field->next, n++ )
1142 farr[n] = field;
1143
1144 #ifdef HAVE_GCD
1145 dispatch_apply(nfield, dispatch_get_global_queue(0, 0), ^(size_t i){
1146 Bmicrograph* mg = farr[i]->mg;
1147 Bstring newname(imgfile);
1148 if ( project->field->next ) {
1149 newname = mg->fmg.pre_rev('.') + "_avg." + mg->fmg.post_rev('.');
1150 if ( path.length() ) newname = path + newname.post_rev('/');
1151 }
1152 field_write_aligned_average(farr[i], pgr, newname, datatype, subset, label);
1153 });
1154 #else
1155 #pragma omp parallel for
1156 for ( long i=0; i<nfield; i++ ) {
1157 Bmicrograph* mg = farr[i]->mg;
1158 Bstring newname(imgfile);
1159 if ( project->field->next ) {
1160 newname = mg->fmg.pre_rev('.') + "_avg." + mg->fmg.post_rev('.');
1161 if ( path.length() ) newname = path + newname.post_rev('/');
1162 }
1163 field_write_aligned_average(farr[i], pgr, newname, datatype, subset, label);
1164 }
1165 #endif
1166
1167 delete[] farr;
1168
1169 if ( verbose & VERB_RESULT )
1170 cout << "Field\tSNR" << endl;
1171
1172 for ( n=0, field = project->field; field; field = field->next ) {
1173 snr_avg += field->fom;
1174 n++;
1175 if ( verbose & VERB_RESULT )
1176 cout << field->id << tab << field->fom << endl;
1177 }
1178
1179 if ( n ) snr_avg /= n;
1180
1181 return snr_avg;
1182 }
1183 double mg_align_frames(Bmicrograph* mg, int ref_num, Bimage* pgr,
1184 Bimage* pmask, double hi_res, double lo_res,
1185 double shift_limit, double edge_width, double gauss_width,
1186 Vector3<long> bin, JSvalue& dose_frac, Bstring& subset, int flag)
1187 {
1188 Bimage* p = read_img(mg->fframe, 1, -1);
1189
1190 p->sampling(mg->pixel_size, mg->pixel_size, 1);
1191
1192 if ( p->sizeZ() > 1 ) p->slices_to_images();
1193
1194 if ( p->images() < 2 ) {
1195 delete p;
1196 return 0;
1197 }
1198
1199 double exposure(0), dose_per_frame(0);
1200 if ( dose_frac.exists("exposure") )
1201 exposure = dose_frac["exposure"].real();
1202 else if ( dose_frac.exists("frame_rate") )
1203 exposure = p->images()/dose_frac["frame_rate"].real();
1204
1205 if ( dose_frac.exists("dose_per_frame") )
1206 dose_per_frame = dose_frac["dose_per_frame"].real();
1207
1208 if ( pgr ) {
1209 if ( verbose )
1210 cout << "Multiplying with " << pgr->file_name() << endl;
1211 p->multiply(pgr);
1212 }
1213
1214 if ( verbose )
1215 cout << "Aligning frames from micrograph " << mg->id << endl;
1216
1217 if ( flag & 1 ) p->histogram_counts(2);
1218
1219 if ( flag & 2 ) p->fspace_weigh_dose(dose_per_frame);
1220
1221 if ( bin.volume() > 1 ) {
1222 p->bin(bin);
1223 mg->pixel_size = p->image->sampling()[0];
1224 }
1225
1226 Vector3<long> aln_bin(1,1,1);
1227 if ( hi_res > 3*p->image->sampling()[0] ) bin = Vector3<long>(2,2,1);
1228
1229 JSvalue job = p->align(ref_num, pmask, hi_res, lo_res, shift_limit,
1230 edge_width, gauss_width, aln_bin);
1231 // JSvalue job = p->align_fast(ref_num, pmask, hi_res, lo_res, shift_limit,
1232 // edge_width, gauss_width);
1233
1234 mg->fom = job["FOM"].real();
1235 double shift(job["shift_average"].real()*mg->pixel_size);
1236 JSvalue sh = job["shifts"];
1237 Bframe* frame = NULL;
1238
1239 mg->frame = NULL;
1240 for ( long i = 0; i<p->images(); ++i ) {
1241 frame = frame_add(&mg->frame, i+1);
1242 frame->shift[0] = sh[i][0].real();
1243 frame->shift[1] = sh[i][1].real();
1244 frame->fom = sh[i][2].real();
1245 }
1246
1247 if ( verbose ) {
1248 cout << "Average shift per frame: " << shift << " A" << endl;
1249 if ( exposure )
1250 cout << "Average shift rate: " <<
1251 (shift/exposure)*p->images() << " A/s" << endl << endl;
1252 cout << job << endl;
1253 }
1254
1255 Bstring ext = mg->fframe.extension();
1256 if ( ext.contains("dm") ) ext = "mrc";
1257 if ( ext.contains("tif") ) ext = "mrc";
1258
1259 if ( flag & 4 ) {
1260 mg->fframe = mg->fframe.pre_rev('.') + "_aln." + ext;
1261 if ( verbose )
1262 cout << "Writing aligned frames: " << mg->fframe << endl;
1263 write_img(mg->fframe, p, 0);
1264 }
1265
1266 if ( flag & 8 ) {
1267 Bimage* p1 = img_sum_subset(p, subset);
1268 mg->fmg = mg->fframe.pre_rev('.') + "_sum." + ext;
1269 if ( verbose )
1270 cout << "Writing aligned frame sum: " << mg->fmg << endl;
1271 write_img(mg->fmg, p1, 0);
1272 delete p1;
1273 }
1274
1275 delete p;
1276
1277 return mg->fom;
1278 }
1279
1307 double project_align_frames(Bproject* project, int ref_img, Bimage* pgr,
1308 Bimage* pmask, Vector3<double> origin, double hi_res, double lo_res,
1309 double shift_limit, double edge_width, double gauss_width,
1310 Vector3<long> bin, JSvalue& dose_frac, Bstring& subset, int flag)
1311 {
1312 bin[2] = 1;
1313
1314 Bfield* field = project->field;
1315 Bmicrograph* mg;
1316 long nmg = project_count_micrographs(project);
1317 double d(0);
1318
1319 // if ( verbose & ( VERB_LABEL | VERB_PROCESS ) ) {
1320 if ( verbose ) {
1321 cout << "Aligning micrograph frames by cross-correlation:" << endl;
1322 cout << "Number of micrographs: " << nmg << endl;
1323 cout << "Reference frame: " << ref_img << endl;
1324 cout << "Resolution limits: " << hi_res << " - " << lo_res << " A" << endl;
1325 cout << "Shift limit: " << shift_limit << endl;
1326 cout << "Edge masking width & smoothing: " << edge_width << " " << gauss_width << endl;
1327 cout << "Binning: " << bin << endl;
1328 if ( pgr )
1329 cout << "Gain reference file: " << pgr->file_name() << endl;
1330 if ( pmask )
1331 cout << "Using mask file: " << pmask->file_name() << endl;
1332 if ( dose_frac.exists("exposure") )
1333 cout << "Exposure time: " << dose_frac["exposure"].real() << " s" << endl;
1334 if ( dose_frac.exists("frame_rate") )
1335 cout << "Frame rate: " << dose_frac["frame_rate"].real() << " frames/s" << endl;
1336 cout << endl;
1337 }
1338
1339 for ( nmg=0, field = project->field; field; field = field->next ) {
1340 for ( mg = field->mg; mg; mg = mg->next, nmg++ ) {
1341 mg_align_frames(mg, ref_img, pgr, pmask, hi_res, lo_res, shift_limit,
1342 edge_width, gauss_width, bin, dose_frac, subset, flag);
1343 d += mg->fom;
1344 }
1345 }
1346
1347 d /= nmg;
1348
1349 if ( verbose & VERB_RESULT )
1350 cout << "Overall average shift per frame: " << d << endl << endl;
1351
1352 return d;
1353 }
1354
1355
1356 double mg_align_series(Bmicrograph* mg, Bmicrograph* mg_ref, Bimage* pref,
1357 Bimage* pgr, Bimage* pmask, double hi_res, double lo_res, double shift_limit,
1358 double edge_width, double gauss_width,
1359 Vector3<long> bin, fft_plan planf, fft_plan planb)
1360 {
1361 if ( mg == mg_ref ) return 0;
1362
1363 long bv(bin[0]*bin[1]*bin[2]);
1364 double cc(0);
1365 Vector3<long> obin(bin[0], bin[1], bin[2]);
1366 Vector3<double> edge_origin(edge_width, edge_width, 0), shift;
1367 Vector3<long> edge_size = pref->size() - (long) (2*edge_width);
1368 edge_size = edge_size.max(1);
1369
1370 Bimage* p = read_img(mg->fmg, 1, mg->img_num);
1371
1372 if ( pgr ) p->multiply(pgr);
1373
1374 p->calculate_background();
1375
1376 if ( edge_width > 0 )
1377 p->shape(0, edge_size, edge_origin, gauss_width, FILL_BACKGROUND, 0);
1378
1379 p->origin(mg_ref->origin);
1380 mg->pixel_size = mg_ref->pixel_size;
1381 p->sampling(pref->sampling());
1382
1383 if ( bv > 1 ) p->bin(bin);
1384
1385 shift = p->find_shift(pref, pmask, hi_res, lo_res, shift_limit, 0, 1, planf, planb, cc);
1386 if ( bv > 1 ) shift *= obin;
1387
1388 mg->origin = mg_ref->origin + shift;
1389 mg->fom = cc;
1390
1391 delete p;
1392
1393 mg->scale = Vector3<float>(1,1,1);
1394 mg->matrix = Matrix3(1);
1395 mg_apply_transform(mg_ref, mg);
1396
1397 return mg->fom;
1398 }
1399
1400 double field_align_series(Bfield* field, int ref_img, Bimage* pgr, Bimage* pmask,
1401 Vector3<double> origin, double hi_res, double lo_res,
1402 double shift_limit, double edge_width, double gauss_width,
1403 Vector3<long> bin, Bstring& subset, int flag)
1404 {
1405 long i, j, nmg, nsel(0);
1406 Bmicrograph* mg, *mg_ref;
1407
1408 for ( i=0, mg_ref = field->mg; mg_ref && ( i<ref_img ); mg_ref = mg_ref->next, i++ ) ;
1409 if ( !mg_ref ) {
1410 mg_ref = field->mg;
1411 ref_img = 0;
1412 }
1413
1414 for ( nmg=0, mg = field->mg; mg; mg = mg->next ) nmg++;
1415 int* numsel = new int[nmg];
1416 select_numbers(subset, nmg, numsel);
1417
1418 for ( i=nsel=0; i<nmg; i++ ) if ( numsel[i] ) nsel++;
1419
1420 Bmicrograph** mg_arr = new Bmicrograph*[nsel];
1421
1422 for ( i=j=0, mg = field->mg; mg; mg = mg->next, i++ )
1423 if ( numsel[i] ) mg_arr[j++] = mg;
1424
1425 Bimage* pref = read_img(mg_ref->fmg, 1, mg_ref->img_num);
1426 if ( origin.length() < 1 ) origin = pref->size()/2;
1427 pref->origin(origin);
1428 mg_ref->origin = origin;
1429 if ( !mg_ref->pixel_size ) mg_ref->pixel_size = pref->sampling()[0];
1430 pref->sampling(mg_ref->pixel_size, mg_ref->pixel_size, 1);
1431
1432 Vector3<double> edge_origin(edge_width, edge_width, 0);
1433 Vector3<long> edge_size = pref->size() - (long) (2*edge_width);
1434 edge_size = edge_size.max(1);
1435
1436 pref->calculate_background();
1437
1438 if ( edge_width > 0 )
1439 pref->edge(0, edge_size, edge_origin, gauss_width, FILL_BACKGROUND);
1440
1441 if ( bin[0]*bin[1]*bin[2] > 1 ) pref->bin(bin);
1442
1443 if ( shift_limit < 0 ) shift_limit = pref->sizeX()/10;
1444
1445 if ( verbose & VERB_RESULT )
1446 cout << "Field " << field->id << endl << "Micrograph\tdx\tdy\tdz\tCC" << endl;
1447
1448 fft_plan planf = pref->fft_setup(FFTW_FORWARD, 0);
1449 fft_plan planb = pref->fft_setup(FFTW_BACKWARD, 0);
1450
1451 #ifdef HAVE_GCD
1452 dispatch_apply(nsel, dispatch_get_global_queue(0, 0), ^(size_t i){
1453 mg_align_series(mg_arr[i], mg_ref, pref, pgr, pmask, hi_res, lo_res,
1454 shift_limit, edge_width, gauss_width, bin, planf, planb);
1455 });
1456 #else
1457 #pragma omp parallel for
1458 for ( long i=0; i<nsel; i++ )
1459 mg_align_series(mg_arr[i], mg_ref, pref, pgr, pmask, hi_res, lo_res,
1460 shift_limit, edge_width, gauss_width, bin, planf, planb);
1461 #endif
1462
1463 fft_destroy_plan(planf);
1464 fft_destroy_plan(planb);
1465
1466 delete[] mg_arr;
1467 delete pref;
1468
1469 double d, da(0);
1470
1471 for ( nsel=i=0, mg = field->mg; mg; mg = mg->next, i++ ) if ( numsel[i] ) {
1472 if ( verbose & VERB_RESULT )
1473 cout << mg->id << tab <<
1474 mg->origin - mg_ref->origin << tab <<
1475 mg->fom << endl;
1476 if ( mg != mg_ref ) {
1477 d = mg->origin.distance(mg_ref->origin)/(fabs(i-ref_img));
1478 da += d;
1479 nsel++;
1480 }
1481 }
1482
1483 if ( nsel ) da /= nsel;
1484
1485 if ( verbose & VERB_RESULT )
1486 cout << "Average shift per micrograph: " << da << endl;
1487
1488 delete[] numsel;
1489
1490 field->fom = da;
1491
1492 Bstring ext = mg->fmg.extension();
1493 if ( ext.contains("dm") ) ext = "mrc";
1494 if ( ext.contains("tif") ) ext = "mrc";
1495
1496 if ( flag & 4 ) {
1497 DataType dt(Float);
1498 Bstring label("Written by bseries");
1499 Bstring favg = field->mg->fmg.pre_rev('.') + "_avg." + ext;
1500 field_write_aligned_average(field, pgr, mg->fmg, dt, subset, label);
1501 }
1502
1503 return da;
1504 }
1505
1532 double project_align_series(Bproject* project, int ref_img, Bimage* pgr,
1533 Bimage* pmask, Vector3<double> origin, double hi_res, double lo_res,
1534 double shift_limit, double edge_width, double gauss_width,
1535 Vector3<long> bin, Bstring& subset, int flag)
1536 {
1537 Bfield* field = project->field;
1538 long nfield(0);
1539 long nmg = project_count_micrographs(project);
1540
1541 for ( field = project->field; field; field = field->next ) nfield++;
1542
1543
1544 // if ( verbose & ( VERB_LABEL | VERB_PROCESS ) ) {
1545 if ( verbose ) {
1546 cout << "Aligning micrographs in series by cross-correlation:" << endl;
1547 cout << "Number of images: " << nmg << endl;
1548 cout << "Resolution limits: " << hi_res << " - " << lo_res << " A" << endl;
1549 cout << "Shift limit: " << shift_limit << endl;
1550 cout << "Edge masking width & smoothing: " << edge_width << " " << gauss_width << endl;
1551 cout << "Binning: " << bin << endl;
1552 if ( pmask )
1553 cout << "Using mask file: " << pmask->file_name() << endl;
1554 if ( subset.length() )
1555 cout << "Subset: " << subset << endl;
1556 cout << endl;
1557 }
1558
1559 double d(0);
1560 for ( field = project->field; field; field = field->next ) {
1561 field_align_series(field, ref_img, pgr, pmask, origin, hi_res, lo_res,
1562 shift_limit, edge_width, gauss_width, bin, subset, flag);
1563 d += field->fom;
1564 }
1565
1566 d /= nfield;
1567
1568 if ( verbose & VERB_RESULT )
1569 cout << "Overall average shift per frame: " << d << endl << endl;
1570
1571 return d;
1572 }
1573
1574 Bimage* mg_tomo_reconstruct(Bmicrograph** mgarr, long mg_id, long mg_min, long mg_max,
1575 double hi_res, double scale, Vector3<long> size,
1576 long ft_size, fft_plan planf, fft_plan planb)
1577 {
1578 long i;
1579 Bimage* p = NULL;
1580
1581 Bmicrograph* mg_res = mgarr[mg_id];
1582 Bmicrograph* mg;
1583
1584 if ( !mg_res ) {
1585 error_show("Error in mg_tomo_reconstruct", __FILE__, __LINE__);
1586 cerr << "Micrograph number " << mg_id << " not found!" << endl << endl;
1587 return NULL;
1588 }
1589
1590 if ( !mg_res->select ) {
1591 if ( verbose & VERB_FULL )
1592 cout << "Skipping micrograph number " << mg_id << endl << endl;
1593 return NULL;
1594 }
1595
1596 if ( mg_max < mg_min || ( mg_max == mg_id && mg_min == mg_id ) ) {
1597 error_show("Error in mg_tomo_reconstruct", __FILE__, __LINE__);
1598 cerr << "Micrograph range is incorrect: " << mg_min << " - " << mg_max << endl << endl;
1599 return NULL;
1600 }
1601
1602 if ( mg_res->fmg.length() < 0 ) {
1603 error_show("Error in mg_tomo_reconstruct", __FILE__, __LINE__);
1604 cerr << "No micrograph image file name given for micrograph " << mg_res->id << endl;
1605 return NULL;
1606 }
1607
1608 if ( hi_res < 2*mg_res->pixel_size ) hi_res = 2*mg_res->pixel_size;
1609
1610 if ( verbose & VERB_DEBUG )
1611 cout << "DEBUG mg_tomo_reconstruct: size=" << size << " ft_size=" << ft_size << endl;
1612
1613 // Header structure for the final reconstruction
1614 Bimage* prec = new Bimage(Float, TComplex, size[0], size[1], 1, 1);
1615 prec->sampling(mg_res->pixel_size, mg_res->pixel_size, 1);
1616 prec->origin(prec->size()/2);
1617
1618 prec->next = new Bimage(Float, TSimple, prec->size(), prec->images());
1619
1620 long data_size = (long) prec->size().volume();
1621
1622 long nrec(0), nmg(mg_max-mg_min), nover(0);
1623 // long interp_type(0), pad_factor(0);
1624 // double pad_ratio(ft_size*1.0/prec->sizeX());
1625 Vector3<long> translate;
1626
1627 for ( i=mg_min; i<=mg_max; i++ ) if ( mgarr[i]->select && i != mg_id ) {
1628 mg = mgarr[i];
1629 if ( verbose & VERB_FULL )
1630 cout << "Reading image " << mg->img_num << " (micrograph " << mg->id << ")" << endl;
1631 if ( ( p = read_img(mg->fmg, 1, mg->img_num) ) == NULL ) {
1632 error_show("mg_tomo_reconstruct", __FILE__, __LINE__);
1633 return NULL;
1634 }
1635
1636 p->change_type(Float);
1637 p->image->origin(mg->origin[0], mg->origin[1], 0);
1638 p->sampling(mg->pixel_size, mg->pixel_size, 1);
1639 p->statistics();
1640 // p->rescale_to_avg_std(0,1);
1641 p->resize(prec->size(), translate, FILL_AVERAGE, 0);
1642
1643
1644 p->fft(planf);
1645 p->phase_shift_to_origin();
1646
1647 nover += prec->fspace_pack_2D_into_central_section(p, ft_size, 1, hi_res, 0, mg_res->matrix, mg->matrix);
1648
1649 delete p;
1650
1651 nrec++;
1652
1653 if ( verbose & ( VERB_TIME | VERB_PROCESS ) )
1654 cout << "Complete: " << nrec*100.0/nmg << "%\r" << flush;
1655
1656 }
1657
1658 if ( nrec < 1 ) {
1659 delete prec;
1660 error_show("Error in mg_tomo_reconstruct: No micrographs used in this reconstruction!", __FILE__, __LINE__);
1661 return NULL;
1662 }
1663
1664 float* fom = (float *) prec->next->data_pointer();
1665
1666 if ( verbose & VERB_FULL ) {
1667 cout << "Contributions: " << nover << " (" << nover*100.0/data_size << "%)" << endl;
1668 cout << "Weighing reconstruction. " << endl;
1669 }
1670
1671 for ( i=0; i<data_size; i++ ) {
1672 if ( fom[i] ) prec->set(i, prec->complex(i) / fom[i]);
1673 fom[i] = fom[i]/(fom[i] + 1);
1674 }
1675
1676 prec->set(0, 0);
1677 prec->origin(0, 0, 0);
1678 prec->phase_shift_to_center();
1679 prec->fft_back(planb);
1680 prec->statistics();
1681
1682 return prec;
1683 }
1684
1685 double mg_reconstruct_align(Bmicrograph** mgarr, long nmg,
1686 long mg_id, long dimg, double resolution, double shift_limit,
1687 Vector3<long> size, double edge_width, double gauss_width,
1688 long ft_size, fft_plan planf, fft_plan planb)
1689 {
1690 long imin, imax;
1691 double cc;
1692 Bmicrograph* mg_res = mgarr[mg_id];
1693
1694 if ( shift_limit < 0 ) shift_limit = size[0]/4;
1695
1696 for ( imin=(mg_id>dimg)? mg_id-dimg: 0; mgarr[imin]->fom < -0.5 && imin<=mg_id; imin++ ) ;
1697
1698 for ( imax=(mg_id+dimg<nmg)? mg_id+dimg: nmg-1; mgarr[imax]->fom < -0.5 && imax>=mg_id; imax-- ) ;
1699
1700 // cout << mg_id << ": " << imin << " - " << imax << endl;
1701
1702 Bimage* prec = mg_tomo_reconstruct(mgarr, mg_id, imin, imax,
1703 resolution, 1, size, ft_size, planf, planb);
1704
1705 if ( !prec ) {
1706 cerr << "Error: Reconstruction for " << mg_id << " failed!" << endl;
1707 bexit(-1);
1708 }
1709
1710 // cout << "reconstruction origin = " << prec->image->origin() << endl;
1711
1712 // cout << mg_id << ": " << imin << " - " << imax << endl;
1713
1714 /*
1715 long k(14);
1716 Bstring name(k, "t%d.pif");
1717 if ( mg_id == k ) {
1718 cout << "writing " << name << endl;
1719 write_img(name, prec, 0);
1720 bexit(0);
1721 }
1722 */
1723 Bimage* p = read_img(mg_res->fmg, 1, mg_res->img_num);
1724
1725 p->image->origin(p->size()/2);
1726 p->sampling(prec->sampling());
1727
1728 Vector3<long> translate;
1729 Vector3<double> edge_origin(edge_width, edge_width, 0);
1730 Vector3<double> edge_size(p->sizeX() - (long)edge_width, p->sizeY() - (long)edge_width, 1);
1731 if ( edge_width > 0 ) {
1732 p->edge(0, edge_size, edge_origin, gauss_width, FILL_AVERAGE, 0);
1733 prec->edge(0, edge_size, edge_origin, gauss_width, FILL_AVERAGE, 0);
1734 }
1735
1736 p->resize(prec->size(), translate, FILL_AVERAGE, 0);
1737
1738 Vector3<double> shift = p->find_shift(prec, NULL, resolution, 0, shift_limit, 0, 1, planf, planb, cc);
1739 // cout << "origin = " << p->image->origin() << endl;
1740 // cout << "mg origin = " << mg_res->origin << endl;
1741
1742 // Change in origin from previous one
1743 Vector3<double> oldori = mg_res->origin;
1744 mg_res->origin = prec->image->origin() + shift;
1745 mg_res->fom = cc;
1746 shift = mg_res->origin - oldori;
1747
1748 if ( verbose )
1749 cout << mg_id << ": " << imin << " - " << imax << tab <<
1750 mg_res->origin << tab << shift << tab << mg_res->fom << endl;
1751
1752 delete p;
1753 delete prec;
1754
1755 return shift.length();
1756 }
1757
1758
1759 /************************************************************************
1760 @brief Aligns a series of micrographs by cross-correlation sequentially.
1761 @param *project project parameter structure.
1762 @param thickness reconstruction thickness.
1763 @param iter number of alignment iterations.
1764 @param dchange threshold change in origin.
1765 @param dimg number of adjacent images in reconstructions.
1766 @param resolution high resolution limit (angstrom).
1767 @param shift_limit limit on shift search (pixels).
1768 @param edge_width smoothing edge width.
1769 @param gauss_width smoothing edge decay.
1770 @return long 0, <0 on failure.
1771
1772 Each pair of adjacent micrographs in the series is cross-correlated
1773 and the relative shift determined. The relative shifts are adjusted
1774 relative to the reference micrograph, defined as the one closest
1775 to a zero degree tilt.
1776 The images are stretched to compensate for tilt difference.
1777 The relationship between an euler representation of the view and
1778 the tilt axis and tilt angle is:
1779 tilt_axis = phi - 90 = - psi - 90
1780 tilt_angle = theta
1781
1782 **/
1783 long project_tomo_align(Bproject* project, long thickness, long iter, double dchange,
1784 long dimg, double resolution, double shift_limit, double edge_width, double gauss_width)
1785 {
1786 Bmicrograph* mg0 = field_find_zero_tilt_mg(project->field);
1787
1788 if ( !mg0->fmg.length() ) {
1789 error_show("Error in project_tomo_align ", __FILE__, __LINE__);
1790 cerr << "No micrograph image or transform file name given for micrograph "
1791 << mg0->id << endl << endl;
1792 return -1;
1793 }
1794
1795 Bimage* p = read_img(mg0->fmg, 0, mg0->img_num);
1796
1797 long ft_size = p->sizeX();
1798 if ( ft_size < p->sizeY() ) ft_size = p->sizeY();
1799 ft_size = findNextPowerOf(ft_size, 2);
1800
1801 if ( thickness < 10 ) thickness = ft_size/5;
1802
1803 delete p;
1804
1805 if ( resolution < 2*mg0->pixel_size ) resolution = 4*mg0->pixel_size;
1806
1807 long it, nmg(0), i, j, n, mg_id0(0);
1808 double dori(10);
1809 Vector3<long> size(ft_size,ft_size,thickness);
1810
1811 if ( shift_limit < 0 ) shift_limit = ft_size/4;
1812
1813 Bmicrograph** mgarr = project_micrograph_array(project, nmg);
1814 for ( i=0; i<nmg; i++ ) {
1815 mgarr[i]->fom = -1;
1816 if ( mg0 == mgarr[i] ) mg_id0 = i;
1817 }
1818 mg0->fom = 1;
1819
1820 // ft_size = part_ft_size(size[0], 1, 2);
1821
1822 if ( verbose ) {
1823 cout << "Aligning images in a tilt series by cross-correlation:" << endl;
1824 cout << "Maximum number of iterations: " << iter << endl;
1825 cout << "Number of images: " << nmg << endl;
1826 cout << "Fourier transform size: " << ft_size << " x " << ft_size << endl;
1827 cout << "Reconstruction size: " << size << endl;
1828 cout << "Number of adjacent images: " << dimg << endl;
1829 cout << "Resolution limit: " << resolution << " A" << endl;
1830 cout << "Shift limit: " << shift_limit << " pixels" << endl;
1831 cout << "Smoothing edge and width: " << edge_width << " " << gauss_width << " pixels" << endl;
1832 cout << endl;
1833 }
1834
1835 fft_plan planf = fft_setup_plan(ft_size, ft_size, 1, FFTW_FORWARD, 1);
1836 fft_plan planb = fft_setup_plan(ft_size, ft_size, 1, FFTW_BACKWARD, 1);
1837
1838 for ( it = 0; it < iter && dori > dchange; it++ ) {
1839 if ( verbose ) {
1840 cout << "Iteration " << it+1 << ":" << endl;
1841 cout << "Micrograph: range" << tab << "Origin" << tab << "Shift" << tab << "FOM" << endl;
1842 }
1843 n = 0;
1844 dori = 0;
1845 for ( i=mg_id0-1, j=mg_id0+1; i>=0 || j<nmg; i--, j++ ) {
1846 if ( i >= 0 ) {
1847 dori += mg_reconstruct_align(mgarr, nmg, i, dimg, resolution,
1848 shift_limit, size, edge_width, gauss_width, ft_size, planf, planb);
1849 n++;
1850 }
1851 if ( j < nmg ) {
1852 dori += mg_reconstruct_align(mgarr, nmg, j, dimg, resolution,
1853 shift_limit, size, edge_width, gauss_width, ft_size, planf, planb);
1854 n++;
1855 }
1856 }
1857 dori /= n;
1858 if ( verbose )
1859 cout << "Iteration:\t" << it+1 << tab << dori << endl;
1860 }
1861
1862 delete[] mgarr;
1863 fft_destroy_plan(planf);
1864 fft_destroy_plan(planb);
1865
1866 Bmicrograph* mg;
1867 if ( verbose & VERB_RESULT ) {
1868 cout << "\nImage\tdx\tdy\tdz" << endl;
1869 for ( mg = project->field->mg; mg; mg = mg->next )
1870 cout << mg->id << tab << mg->origin[0] << tab << mg->origin[1]
1871 << tab << mg->origin[2] << endl;
1872 cout << endl;
1873 }
1874
1875 return 0;
1876 }
1877
1878
1879
1880 double field_ssnr(Bfield* field, fft_plan plan)
1881 {
1882 long i;
1883 Bmicrograph* mg;
1884 Vector3<double> origin;
1885 Bimage* p, *ps;
1886 Bimage* pavg = NULL;
1887 Bimage* pstd = NULL;
1888 Vector3<double> scale(1,1,1), nori;
1889 Matrix3 mat(1);
1890 Vector3<long> size;
1891
1892 for ( i=0, mg = field->mg; mg; mg = mg->next, i++ ) {
1893 p = read_img(mg->fmg, 1, mg->img_num);
1894 p->calculate_background();
1895 origin = p->size()/2;
1896 if ( size.volume() < 1 ) { // Make sure it is square
1897 size = p->size();
1898 if ( size[0] < size[1] ) size[1] = size[0];
1899 else size[0] = size[1];
1900 }
1901 ps = p->transform(size, scale, nori, (origin - mg->origin), mat, FILL_BACKGROUND, 0);
1902 ps->fft(plan);
1903 if ( !pavg ) pavg = ps->copy();
1904 else pavg->add(ps);
1905 ps->complex_to_intensities();
1906 if ( !pstd ) pstd = ps->copy();
1907 else pstd->add(ps);
1908 delete p;
1909 delete ps;
1910 }
1911
1912 if ( i ) {
1913 pavg->multiply(1.0L/i);
1914 pstd->multiply(1.0L/i);
1915 }
1916
1917 pavg->complex_to_intensities();
1918 pstd->subtract(pavg);
1919 pstd->truncate_to_min_max(1e-10, pstd->maximum());
1920 pavg->divide(pstd, 1, 0);
1921
1922 field->fom = pavg->average();
1923
1924 Bstring imgfile = field->id + "_snr.map";
1925 write_img(imgfile, pavg, 0);
1926
1927 double rad_step(10), maxrad(size[0]/2);
1928 Bimage* prad = pavg->radial(0, maxrad, rad_step, 1);
1929 imgfile = field->id + "_snr.txt";
1930 write_img(imgfile, prad, 0);
1931
1932 delete pavg;
1933 delete pstd;
1934 delete prad;
1935
1936 return 0;
1937 }
1938
1939 double project_ssnr(Bproject* project)
1940 {
1941 Bfield* field = project->field;
1942 long n, nfield(0);
1943
1944 for ( field = project->field; field; field = field->next ) nfield++;
1945
1946 Bfield** farr = new Bfield*[nfield];
1947 for ( n=0, field = project->field; field; field = field->next, n++ )
1948 farr[n] = field;
1949
1950 if ( verbose )
1951 cout << "Calculating the SSNR for each field:" << endl;
1952
1953 Bimage* p = read_img(project->field->mg->fmg, 0, 0);
1954
1955 fft_plan plan = p->fft_setup(FFTW_FORWARD, 0);
1956
1957 delete p;
1958
1959 //#ifdef HAVE_GCD
1960 // dispatch_apply(nfield, dispatch_get_global_queue(0, 0), ^(size_t i){
1961 // field_ssnr(farr[i], plan);
1962 // });
1963 //#else
1964 //#pragma omp parallel for
1965 for ( long i=0; i<nfield; i++ ) {
1966 field_ssnr(farr[i], plan);
1967 }
1968 //#endif
1969
1970 fft_destroy_plan(plan);
1971 delete[] farr;
1972
1973 if ( verbose ) {
1974 cout << "Field\tSNR" << endl;
1975 for ( field = project->field; field; field = field->next )
1976 cout << field->id << tab << field->fom << endl;
1977 }
1978
1979 return 0;
1980 }
1981
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1743
Bimage::extract_tiles
Bimage * extract_tiles(long nn, vector< Vector3< long >> &coords, Vector3< long > tile_size)
Extracts a set of tiles at specified positions from an image into a new image.
Definition: Bimage_extract.cpp:335
filament_node_add
Bfilnode * filament_node_add(Bfilnode **fnode, int pid)
Adds a filament node parameter structure to a linked list.
Definition: mg_processing.cpp:655
Bparticle::id
int id
Definition: mg_processing.h:92
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::replace
int replace(Bimage *img)
Replaces the data with that from the given image.
Definition: Bimage.cpp:2828
Bimage::square
void square()
Calculates the square of an image.
Definition: Bimage_rescale.cpp:678
Bframe::shift
Vector3< double > shift
Definition: mg_processing.h:77
Bimage::copy_header
Bimage * copy_header()
Definition: Bimage.h:650
FILL_BACKGROUND
#define FILL_BACKGROUND
Definition: utilities.h:174
Bsub_image::view
void view(double x, double y, double z, double a)
Definition: Bimage.h:143
insert
string insert(string &filename, string ins)
Definition: string_util.cpp:48
Bimage.h
Header file for image class.
Bfield::select
long select
Definition: mg_processing.h:262
DataType
DataType
Base data type specifier.
Definition: utilities.h:146
mg_align_series
double mg_align_series(Bmicrograph *mg, Bmicrograph *mg_ref, Bimage *pref, Bimage *pgr, Bimage *pmask, double hi_res, double lo_res, double shift_limit, double edge_width, double gauss_width, Vector3< long > bin, fft_plan planf, fft_plan planb)
Definition: mg_align.cpp:1356
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
Vector3::length
double length()
Definition: Vector3.h:222
planb
fft_plan planb
Definition: bico.cpp:24
Bimage::add
void add(long j, double v)
Definition: Bimage.h:308
Bimage::slices_to_images
int slices_to_images()
Changes the slices in a 3D image into a set of 2D images.
Definition: Bimage.cpp:2052
Bimage::fspace_bandpass
int fspace_bandpass(double res_hi, double res_lo=0, double width=0)
Applies a bandpass filter to an image.
Definition: Bimage_fspace.cpp:499
field_ssnr
double field_ssnr(Bfield *field, fft_plan plan)
Definition: mg_align.cpp:1880
Bmicrograph::id
Bstring id
Definition: mg_processing.h:202
Bbadarea
Definition: mg_processing.h:142
Bmicrograph::img_num
int img_num
Definition: mg_processing.h:211
mg_tomo_reconstruct
Bimage * mg_tomo_reconstruct(Bmicrograph **mgarr, long mg_id, long mg_min, long mg_max, double hi_res, double scale, Vector3< long > size, long ft_size, fft_plan planf, fft_plan planb)
Definition: mg_align.cpp:1574
Bimage::fft
int fft()
Definition: Bimage.h:822
Bimage::fft_back
int fft_back()
Definition: Bimage.h:823
Bimage::regions
Bimage * regions(double threshold, int sign)
Segments an image into contiguous regions.
Definition: Bimage_segment.cpp:58
Bfilnode
Definition: mg_processing.h:115
img_extract_features
Bmarker * img_extract_features(Bimage *p, int extract_method, int target_num, double threshold)
Definition: mg_align.cpp:402
utilities.h
Header file for general utilities.
project_micrograph_array
Bmicrograph ** project_micrograph_array(Bproject *project, long &nmg)
Sets up an array of selected micrograph pointers.
Definition: mg_processing.cpp:2001
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
Bmicrograph::filament_width
double filament_width
Definition: mg_processing.h:231
Bimage::mask_by_threshold
Bimage * mask_by_threshold(double threshold)
Generates a mask based on an image at a given threshold.
Definition: Bimage_mask.cpp:93
planf
fft_plan planf
Definition: bico.cpp:24
Bimage::compound_type
CompoundType compound_type()
Definition: Bimage.h:351
mg_img_proc.h
Header file for image processing from micrograph structures.
Transform::angle
double angle
Definition: Transform.h:29
filament_node_count
long filament_node_count(Bfilament *fil)
Counts the number of filament nodes in a linked list of filaments.
Definition: mg_processing.cpp:1205
Bimage::shape
int shape(int type, Vector3< long > rect, Vector3< double > start, double width, int fill_type=0, double fill=0)
Creates a shape in an image and fills it with a constant value.
Definition: Bimage_edit.cpp:103
Bbadarea::loc
Vector3< double > loc
Definition: mg_processing.h:145
kill_list
long kill_list(char *list, unsigned long size)
Frees all the items in a linked list.
Definition: linked_list.cpp:214
Bimage::edge
int edge(int type, Vector3< long > rect, Vector3< double > start, double width, int fill_type=0, double fill=0)
Smooths the image edge with a soft rectangular function.
Definition: Bimage_edit.cpp:319
Transform::fom
double fom
Definition: Transform.h:32
Bmarker
Definition: marker.h:21
add_item
char * add_item(char **list, unsigned long size)
Adds an item to a linked list.
Definition: linked_list.cpp:26
Matrix3
Definition: Matrix3.h:17
FILL_AVERAGE
#define FILL_AVERAGE
Definition: utilities.h:173
frame_add
Bframe * frame_add(Bframe **frame, int pid)
Adds a movie frame parameter structure to a linked list.
Definition: mg_processing.cpp:495
particle_add
Bparticle * particle_add(Bparticle **part, int pid)
Adds a particle parameter structure to a linked list.
Definition: mg_processing.cpp:527
Bstring::length
long length() const
Definition: Bstring.cpp:263
Bmicrograph::pixel_size
double pixel_size
Definition: mg_processing.h:214
project
Bproject * project
Definition: bshow.cpp:31
project_write_average_frames
double project_write_average_frames(Bproject *project, Bimage *pgr, Bstring &avgfile, DataType datatype, Bstring &subset, Bstring &label)
Calculates average micrograph frame images and write them to a file.
Definition: mg_align.cpp:1067
particle_kill
int particle_kill(Bparticle *part)
Frees a list of particles.
Definition: mg_processing.cpp:1323
Bimage::complex
Complex< double > complex(long j)
Returns a complex value at the given index.
Definition: Bimage.cpp:1005
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
verbose
int verbose
Bimage::truncate_to_min_max
int truncate_to_min_max(double minim, double maxim)
Truncates image data to a given minimum and maximum.
Definition: Bimage_rescale.cpp:331
Bimage::file_name
void file_name(string s)
Definition: Bimage.h:230
Bimage::multiply
void multiply(long j, Complex< double > cv)
Definition: Bimage.h:312
project_count_micrographs
long project_count_micrographs(Bproject *project)
Counts all the micrographs in the project structure.
Definition: mg_processing.cpp:746
TComplex
Definition: Bimage.h:59
Bmicrograph::fil
Bfilament * fil
Definition: mg_processing.h:240
mg_align_feature_extraction
int mg_align_feature_extraction(Bproject *project, int max_features, double res_low, double res_high, double thresh, int extract_method)
Aligns images by feature extraction.
Definition: mg_align.cpp:541
Vector3::distance
double distance(const Vector3 &v)
Definition: Vector3.h:227
mg_align_coordinates
int mg_align_coordinates(Bproject *project, int refset)
Aligns the particle coordinates of a series of micrographs.
Definition: mg_align.cpp:38
read_img
Bimage * read_img(char *filename, int readdata, int img_select)
General driver function to read multiple image formats.
Definition: rwimg.cpp:76
JSvalue::real
double & real()
Definition: json.h:143
Bfield::next
Bfield * next
Definition: mg_processing.h:258
mg_merge_focal_series
int mg_merge_focal_series(Bproject *project, int use_old_origins)
Merges corresponding particle images in each focal series.
Definition: mg_align.cpp:762
Bimage::fspace_weigh_dose
int fspace_weigh_dose(long nn, double dose_per_frame, vector< double > critdose)
Definition: Bimage_fspace.cpp:1398
Bmicrograph::part
Bparticle * part
Definition: mg_processing.h:239
TSimple
Definition: Bimage.h:58
Bfilament::id
int id
Definition: mg_processing.h:131
Bfilament::node
Bfilnode * node
Definition: mg_processing.h:132
Float
Definition: utilities.h:157
field_write_aligned_average
double field_write_aligned_average(Bfield *field, Bimage *pgr, Bstring &imgfile, DataType datatype, Bstring &subset, Bstring &label)
Definition: mg_align.cpp:863
Vector3::max
Type max()
Definition: Vector3.h:175
mg_align_micrographs
int mg_align_micrographs(Bproject *project, int refset, Vector3< long > tile_size, double res_lo, double res_hi, double max_shift, int filter_flag, int refine_flag)
Aligns a focal series of micrographs.
Definition: mg_align.cpp:315
Bframe
Definition: mg_processing.h:74
Bmicrograph::matrix
Matrix3 matrix
Definition: mg_processing.h:222
Bimage
General image parameter class.
Definition: Bimage.h:163
Bmicrograph::fpart
Bstring fpart
Definition: mg_processing.h:207
Bfilament::next
Bfilament * next
Definition: mg_processing.h:129
Bimage::data_alloc
unsigned char * data_alloc()
Definition: Bimage.h:256
Bimage::align
JSvalue align(long ref_num, Bimage *pmask, double hi_res, double lo_res, double shift_limit, double edge_width, double gauss_width, Vector3< long > bin)
Aligns and sums a set of sub-images, first progressively and then iteratively.
Definition: Bimage_align.cpp:203
project_ssnr
double project_ssnr(Bproject *project)
Definition: mg_align.cpp:1939
mg_align.h
Header file for functions to align micrographs or coordinates from micrographs and apply the resultan...
Bstring::contains
bool contains(const Bstring &s)
Definition: Bstring.cpp:584
Bimage::transform
int transform(Vector3< double > scale, Vector3< double > origin, Vector3< double > translate, Matrix3 mat, int fill_type=0, double fill=0)
Transforms an image by translation, rotation, scaling and skewing, in place.
Definition: Bimage_transform.cpp:37
Transform
Definition: Transform.h:24
Bfield
Definition: mg_processing.h:257
M_PI
#define M_PI
Definition: utilities.h:59
linked_list.h
Header file for generalized linked list functions.
Bfilnode::id
int id
Definition: mg_processing.h:117
Bmicrograph::frame
Bframe * frame
Definition: mg_processing.h:237
Bmicrograph::ctf
CTFparam * ctf
Definition: mg_processing.h:238
Bimage::extract
Bimage * extract(long nn)
Extracts one sub-image into new image structure.
Definition: Bimage_extract.cpp:21
Bimage::maximum
double maximum()
Definition: Bimage.h:535
micrograph_kill
int micrograph_kill(Bmicrograph *mg)
Frees a whole micrograph parameter structure.
Definition: mg_processing.cpp:1288
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
select_numbers
int select_numbers(Bstring &string, int n, int *numsel)
Converts a string with a selection specification into an integer array.
Definition: utilities.cpp:328
markers_find_rottrans
Transform markers_find_rottrans(Bmarker *set1, Bmarker *set2, double tolerance)
Finds the rotation and shift between two sets of vectors.
Definition: marker.cpp:416
Bmicrograph::fframe
Bstring fframe
Definition: mg_processing.h:206
Bbadarea::next
Bbadarea * next
Definition: mg_processing.h:143
Bimage::statistics
long statistics()
Calculates the statistics for an image.
Definition: Bimage_stats.cpp:22
Bfield::id
Bstring id
Definition: mg_processing.h:259
project_write_aligned_averages
double project_write_aligned_averages(Bproject *project, Bimage *pgr, Bstring &imgfile, DataType datatype, Bstring &subset, Bstring &label)
Calculates aligned micrograph images and write them to a file.
Definition: mg_align.cpp:1122
Bmicrograph::select
long select
Definition: mg_processing.h:203
Bmicrograph::mark_radius
double mark_radius
Definition: mg_processing.h:235
Bimage::label
void label(string s)
Definition: Bimage.h:235
Bproject::field
Bfield * field
Definition: mg_processing.h:343
Bimage::resize
int resize(Vector3< long > nusize, Vector3< long > translate, int fill_type=0, double fill=0)
Resizes without interpolation or rescaling.
Definition: Bimage_resize.cpp:28
VERB_TIME
#define VERB_TIME
Definition: utilities.h:110
ps_marker_errors
int ps_marker_errors(Bstring &filename, Bmarker *set1, Bmarker *set2, Transform t, Vector3< int > size, float err_scale)
Output a postscript file that graphs the deviations of points in a Bmarker from their predicted locat...
Definition: ps_marker.cpp:34
Bstring::extension
Bstring extension()
Definition: Bstring.cpp:515
ps_marker.h
Header file for postscript tools dealing with Bmarkers.
fft_plan
fftwf_plan fft_plan
Definition: fft.h:16
Bsub_image::FOM
double FOM()
Definition: Bimage.h:151
markers_limit
long markers_limit(int target_num, int sign, Bmarker **set)
This method constricts a marker set to target_num points.
Definition: marker.cpp:909
field_find_zero_tilt_mg
Bmicrograph * field_find_zero_tilt_mg(Bfield *field)
Finds the micrograph closest to a zero degree tilt in a series.
Definition: mg_processing.cpp:400
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
Bmicrograph
Definition: mg_processing.h:200
Transform::scale
Vector3< double > scale
Definition: Transform.h:31
mg_write_average_frames
double mg_write_average_frames(Bmicrograph *mg, Bimage *pgr, Bstring &avgfile, DataType datatype, Bstring &subset, Bstring &label)
Definition: mg_align.cpp:1011
Bimage::complex_to_intensities
void complex_to_intensities()
The intensities from a complex image is written to a simple image.
Definition: Bimage_complex.cpp:92
Bmicrograph::origin
Vector3< double > origin
Definition: mg_processing.h:220
Bmarker::fom
float fom
Definition: marker.h:28
write_img
int write_img(const char *filename, Bimage *p, int compression)
General driver function to write multiple image formats.
Definition: rwimg.cpp:280
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
Bmarker::id
int id
Definition: marker.h:23
Bimage::calculate_background
int calculate_background(long nn, int flag)
Calculates the background for one sub-image.
Definition: Bimage_background.cpp:27
JSvalue
Definition: json.h:53
Transform::trans
Vector3< double > trans
Definition: Transform.h:30
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:127
Bparticle::ori
Vector3< double > ori
Definition: mg_processing.h:100
Bsub_image::sampling
void sampling(double x, double y, double z)
Definition: Bimage.h:123
field_align_series
double field_align_series(Bfield *field, int ref_img, Bimage *pgr, Bimage *pmask, Vector3< double > origin, double hi_res, double lo_res, double shift_limit, double edge_width, double gauss_width, Vector3< long > bin, Bstring &subset, int flag)
Definition: mg_align.cpp:1400
Bstring::c_str
const char * c_str()
Definition: Bstring.h:70
micrograph_count_particles
long micrograph_count_particles(Bmicrograph *mg)
Counts all the particles in the micrograph structure.
Definition: mg_processing.cpp:1132
Bmicrograph::mark
Bmarker * mark
Definition: mg_processing.h:242
Bmarker::next
Bmarker * next
Definition: marker.h:22
Bimage::standard_deviation
double standard_deviation()
Definition: Bimage.h:537
Bstring::post_rev
Bstring post_rev(char c)
Definition: Bstring.cpp:428
Bfield::mg
Bmicrograph * mg
Definition: mg_processing.h:264
Bimage::set
void set(long j, double v)
Sets a single value at the given index.
Definition: Bimage.cpp:1096
Bimage::next
Bimage * next
Definition: Bimage.h:165
VERB_RESULT
#define VERB_RESULT
Definition: utilities.h:105
Bstring::base
Bstring base()
Definition: Bstring.cpp:508
Bimage::filter_extremes
int filter_extremes()
Filters the extremes out of a micrograph image.
Definition: Bimage_segment.cpp:634
Bimage::data_pointer
unsigned char * data_pointer()
Definition: Bimage.h:261
Bparticle
Definition: mg_processing.h:89
Bmicrograph::block
int block
Definition: mg_processing.h:204
Bmicrograph::rot_angle
double rot_angle
Definition: mg_processing.h:219
Bstring
Definition: Bstring.h:29
Bimage::copy
Bimage * copy()
Copies the header information and data of an image into a new image structure.
Definition: Bimage.cpp:2695
Bimage::sizeX
void sizeX(long nx)
Definition: Bimage.h:377
Bimage::fft_setup
fft_plan fft_setup(fft_direction dir, int opt=0)
Sets up a plan for fast Fourier transforms.
Definition: Bimage_fft.cpp:29
Transform::next
Transform * next
Definition: Transform.h:26
img_align
Transform img_align(Bimage *p1, Bimage *p2, Vector3< long > tile_size, double res_lo, double res_hi, double max_shift, int filter_flag, int refine_flag)
Definition: mg_align.cpp:107
filament_kill
int filament_kill(Bfilament *fil)
Frees a list of filaments.
Definition: mg_processing.cpp:1347
Bmicrograph::box_size
Vector3< long > box_size
Definition: mg_processing.h:230
Bmarker::img_num
int img_num
Definition: marker.h:24
filament_add
Bfilament * filament_add(Bfilament **fil, int pid)
Adds a filament parameter structure to a linked list.
Definition: mg_processing.cpp:625
img_sum_subset
Bimage * img_sum_subset(Bimage *p, Bstring &subset)
Definition: mg_align.cpp:249
project_write_aligned_images
double project_write_aligned_images(Bproject *project, Bimage *pgr, Bstring &imgfile, DataType datatype, Bstring &label)
Calculates aligned micrograph images and write them to a file.
Definition: mg_align.cpp:950
mg_apply_transform
int mg_apply_transform(Bmicrograph *mg_ref, Bmicrograph *mg_apply)
Applies a transformation to particle coordinates in a reference micrograph and writes them into an ap...
Definition: mg_align.cpp:630
Bimage::sizeZ
void sizeZ(long nz)
Definition: Bimage.h:379
Vector3< double >
Bmicrograph::fmg
Bstring fmg
Definition: mg_processing.h:205
Bparticle::loc
Vector3< double > loc
Definition: mg_processing.h:99
JSvalue::exists
bool exists(string tag)
Definition: json.h:215
fft_destroy_plan
int fft_destroy_plan(fft_plan plan)
Deallocates a plan for fast Fourier transforms.
Definition: fft.cpp:87
Bmicrograph::fil_node_radius
double fil_node_radius
Definition: mg_processing.h:232
Bfilnode::next
Bfilnode * next
Definition: mg_processing.h:116
View
Definition: View.h:26
Bmarker::err
Vector3< float > err
Definition: marker.h:26
Bmicrograph::bad
Bbadarea * bad
Definition: mg_processing.h:241
Bmicrograph::fom
double fom
Definition: mg_processing.h:236
micrograph_get_nominal_origin
Vector3< double > micrograph_get_nominal_origin(Bmicrograph *mg)
Gets the nominal origin for a micrograph.
Definition: mg_img_proc.cpp:631
Vector3::min
Type min()
Definition: Vector3.h:169
Bmarker::loc
Vector3< float > loc
Definition: marker.h:25
Bimage::find_shift
int find_shift(Bimage *pref, Bimage *pmask, double hires, double lores, double radius, double sigma, int refine_flag)
Calculates a cross-correlation map to find the shift for the pair of images.
Definition: Bimage_correlate.cpp:932
fft_setup_plan
fft_plan fft_setup_plan(long x, long y, long z, fft_direction dir, int opt)
Sets up a plan for fast Fourier transforms.
Definition: fft.cpp:31
field_count_micrographs
long field_count_micrographs(Bfield *field)
Counts all the micrographs in the field-of-view structure.
Definition: mg_processing.cpp:1067
CTFparam::defocus_average
double defocus_average()
Definition: ctf.h:100
Bimage::divide
void divide(Bimage *p, double scale=1, double shift=0)
Divides the first image by the second.
Definition: Bimage.cpp:3579
Bimage::average
double average(long cc, double xf, double yf, double zf, long nn, double iscale)
Averages in 3D when scaling is less than 1.
Definition: Bimage.cpp:1349
project_align_frames
double project_align_frames(Bproject *project, int ref_img, Bimage *pgr, Bimage *pmask, Vector3< double > origin, double hi_res, double lo_res, double shift_limit, double edge_width, double gauss_width, Vector3< long > bin, JSvalue &dose_frac, Bstring &subset, int flag)
Aligns a series of micrographs by cross-correlation.
Definition: mg_align.cpp:1307
mg_processing.h
Header file for micrograph processing.
Transform::axis
Vector3< double > axis
Definition: Transform.h:28
Unknown_Type
Definition: utilities.h:147
rwimg.h
Header file for 2D and 3D image I/O.
Bframe::fom
double fom
Definition: mg_processing.h:78
Bimage::images
long images()
Definition: Bimage.h:491
Bimage::histogram_counts
Bplot * histogram_counts(int flags=0)
Finds the peaks in a quantized image from the histogram.
Definition: Bimage_histogram.cpp:206
Bmicrograph::bad_radius
double bad_radius
Definition: mg_processing.h:233
project_tomo_align
long project_tomo_align(Bproject *project, long thickness, long iter, double dchange, long dimg, double resolution, double shift_limit, double edge_width, double gauss_width)
Definition: mg_align.cpp:1783
Bstring::pre_rev
Bstring pre_rev(char c)
Definition: Bstring.cpp:413
findNextPowerOf
int findNextPowerOf(int startNumber, int powerOf)
Finds the next greatest number that is a power of a given number.
Definition: utilities.cpp:433
mg_reconstruct_align
double mg_reconstruct_align(Bmicrograph **mgarr, long nmg, long mg_id, long dimg, double resolution, double shift_limit, Vector3< long > size, double edge_width, double gauss_width, long ft_size, fft_plan planf, fft_plan planb)
Definition: mg_align.cpp:1685
Vector3::volume
double volume()
Definition: Vector3.h:235
Bparticle::next
Bparticle * next
Definition: mg_processing.h:90
Bfield::fom
double fom
Definition: mg_processing.h:263
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
Bimage::subtract
void subtract(Bimage *p)
Subtracts another image from an image.
Definition: Bimage.cpp:3403
Bimage::sizeY
void sizeY(long ny)
Definition: Bimage.h:378
VERB_LABEL
#define VERB_LABEL
Definition: utilities.h:106
Bmicrograph::scale
Vector3< double > scale
Definition: mg_processing.h:221
Bimage::data_type
DataType data_type()
Definition: Bimage.h:349
Bstring::str
string str()
Definition: Bstring.h:42
Bfilnode::loc
Vector3< double > loc
Definition: mg_processing.h:118
project_align_series
double project_align_series(Bproject *project, int ref_img, Bimage *pgr, Bimage *pmask, Vector3< double > origin, double hi_res, double lo_res, double shift_limit, double edge_width, double gauss_width, Vector3< long > bin, Bstring &subset, int flag)
Aligns a series of micrographs by cross-correlation.
Definition: mg_align.cpp:1532
bexit
int bexit(int value)
Exit function for cleanup and debugging.
Definition: utilities.cpp:273
marker.h
Header file for image parameter functions.
mg_align_frames
double mg_align_frames(Bmicrograph *mg, int ref_num, Bimage *pgr, Bimage *pmask, double hi_res, double lo_res, double shift_limit, double edge_width, double gauss_width, Vector3< long > bin, JSvalue &dose_frac, Bstring &subset, int flag)
Definition: mg_align.cpp:1183
Bmarker::sel
int sel
Definition: marker.h:29
error_show
int error_show(string message, string file, int line)
Displays the error with file and line reference.
Definition: utilities.cpp:755
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
Bproject
Definition: mg_processing.h:333
markers_map_and_find_transform
Transform * markers_map_and_find_transform(Bmarker **set, int nseries, int refset, Vector3< long > size)
This function finds the transform parameters between sets of coordinates. These sets are expected to ...
Definition: marker.cpp:585
Bimage::image
Bsub_image * image
Definition: Bimage.h:188
Bimage::origin
void origin(double ox, double oy, double oz)
Definition: Bimage.h:563
Bfilament
Definition: mg_processing.h:128
Bmicrograph::next
Bmicrograph * next
Definition: mg_processing.h:201