| Bsoft 2.0.5 Bernard's software package

mg_tomo_track.cpp
Go to the documentation of this file.
1
9 #include "Bimage.h"
10 #include "mg_tomography.h"
11 #include "mg_tomo_track.h"
12 #include "mg_img_proc.h"
13 #include "linked_list.h"
14 #include "qsort_functions.h"
15 #include "random_numbers.h"
16 #include "utilities.h"
17 #include "timer.h"
18
19 // Declaration of global variables
20 extern int verbose; // Level of output to the screen
21
22 // Internal function prototypes
23 int mg_marker_z_search(Bmicrograph* mg, Bmarker* model, Vector3<double> oriref,
24 Bimage* pgold, double thickness, int cc_type, int iz, double* z);
25 int mg_z_matrix_update(Bmarker* model, int nmg, int nmark, double* z, double* w, int recenter);
26
27
28 double fom_from_distance(double distance, double sigma)
29 {
30 double r = distance/sigma;
31
32 double fom = exp(-0.5*r*r);
33
34 return fom;
35 }
36
37 int marker_show(Bmarker* m1, Bmarker* m2)
38 {
39 for ( ; m1 && m2; m1 = m1->next, m2 = m2->next )
40 cout << m1->id << tab << m1->loc << tab << m2->loc << endl;
41
42 return 0;
43 }
44
58 Bimage* img_marker_projection(Vector3<long> size, Vector3<double> offset,
59 double radius, Bimage* pmark, Bmarker* mark)
60 {
61 double outrad = sqrt(2.0)*radius;
62 Bmarker* m;
63 Vector3<double> loc;
64
65 Bimage* p = new Bimage(Float, TSimple, size, 1);
66 p->origin(p->size()/2);
67
68 if ( pmark ) {
69 p->fill(pmark->background(long(0)));
70 for ( m = mark; m; m = m->next ) if ( m->sel ) {
71 loc = m->loc - offset;
72 p->place(0, pmark, loc, outrad, 1, 0, 1);
73 }
74 } else {
75 for ( m = mark; m; m = m->next ) if ( m->sel ) {
76 loc = m->loc - offset;
77 p->sphere(loc, outrad, 2, FILL_USER, 1);
78 p->sphere(loc, radius, 2, FILL_USER, -1);
79 }
80 }
81
82 p->statistics();
83
84 // write_img("mark_proj.map", p);
85
86 return p;
87 }
88
89 double mg_find_tilt_axis(Bmicrograph* mgp, Bmicrograph* mgn, Bmicrograph* mg_ref,
90 double axis_angle, Bimage* pgold, double hi_res, double lo_res,
91 double shift_limit, fft_plan planf, fft_plan planb)
92 {
93 if ( verbose & VERB_DEBUG )
94 cout << "DEBUG mg_find_tilt_axis: axis_angle=" << axis_angle << endl;
95
96 double cc(0);
97 Bmicrograph* mg = micrograph_copy(mgp);
98
99 mg->matrix = Matrix3(mg->tilt_angle, axis_angle);
100 // mg->matrix = mg->matrix.transpose();
101 // cout << mg->matrix << endl;
102
103 mg_marker_update(mg, mg_ref->mark, mg_ref->origin, 1);
104 // marker_show(mg_ref->mark, mg->mark);
105
106 cc = mg_marker_shift(mg, pgold, hi_res, lo_res, shift_limit, planf, planb);
107
108 micrograph_kill(mg);
109
110 mg = micrograph_copy(mgn);
111
112 mg->matrix = Matrix3(mg->tilt_angle, axis_angle);
113 // mg->matrix = mg->matrix.transpose();
114 // cout << mg->matrix << endl;
115
116 mg_marker_update(mg, mg_ref->mark, mg_ref->origin, 1);
117 // marker_show(mg_ref->mark, mg->mark);
118
119 cc += mg_marker_shift(mg, pgold, hi_res, lo_res, shift_limit, planf, planb);
120 cc /= 2;
121
122 micrograph_kill(mg);
123
124 if ( verbose & VERB_DEBUG )
125 cout << "DEBUG mg_find_tilt_axis: cc=" << cc << endl;
126
127 return cc;
128 }
129
153 double project_find_tilt_axis(Bproject* project, double tilt,
154 double axis_start, double axis_end, double axis_step,
155 double hi_res, double lo_res, double shift_limit)
156 {
157 if ( !project->field ) return -1;
158
159 double a(0), abest(0), ccbest(-1);
160 Bmicrograph* mg;
161 Bmicrograph* mg_ref = field_find_low_tilt_mg_with_markers(project->field);
162 Bmicrograph* mgp = mg_ref;
163 Bmicrograph* mgn = mg_ref;
164
165 if ( !mg_ref || !mg_ref->mark ) {
166 cerr << "Error: No zero-tilt markers specified!" << endl;
167 return 0;
168 }
169
170 for ( mg = project->field->mg; mg; mg = mg->next )
171 if ( a < fabs(mg->tilt_angle) ) a = fabs(mg->tilt_angle);
172
173 if ( a < tilt ) {
174 cerr << "Error: The micrograph tilt angles are smaller than the requested tilt!" << endl;
175 return 0;
176 }
177
178 // Choose micrographs close to the given tilt angle
179 for ( mg = project->field->mg; mg; mg = mg->next ) {
180 if ( fabs(mg->tilt_angle - tilt) < fabs(mgp->tilt_angle - tilt) ) mgp = mg;
181 if ( fabs(mg->tilt_angle + tilt) < fabs(mgn->tilt_angle + tilt) ) mgn = mg;
182 }
183
184 if ( mgp && mgp->tilt_angle <= 0.05 ) {
185 cerr << "Error: The postive test tilt is too small!" << endl;
186 return 0;
187 }
188
189 if ( mgn && mgn->tilt_angle >= -0.05 ) {
190 cerr << "Error: The negative test tilt is too large!" << endl;
191 return 0;
192 }
193
194 if ( verbose & VERB_DEBUG )
195 cout << "DEBUG project_find_tilt_axis: mg_ref=" << mg_ref->id << " mgp=" << mgp->id << " mgn=" << mgn->id << endl;
196
197 kill_list((char *) mgp->mark, sizeof(Bmarker));
198 kill_list((char *) mgn->mark, sizeof(Bmarker));
199
200 // Generate a composite gold particle image for cross-correlation
201 int cc_size = (int) (4*mg_ref->mark_radius);
202 if ( cc_size < 30 ) cc_size = 30;
203 Vector3<long> gsize(cc_size, cc_size, 1);
204 Bimage* pgold = mg_composite_particle(mg_ref, gsize);
205
206 if ( verbose ) {
207 cout << "Finding the tilt axis angle:" << endl;
208 cout << "Test tilt angle: " << tilt*180/M_PI << endl;
209 cout << "Micrograph tilt angles: " << mgn->tilt_angle*180/M_PI
210 << " " << mgp->tilt_angle*180/M_PI << endl;
211 cout << "Micrographs: " << mgn->id << " " << mgp->id << endl;
212 cout << "Axis start, end and step: " << axis_start*180/M_PI << " "
213 << axis_end*180/M_PI << " " << axis_step*180/M_PI << endl;
214 cout << "Resolution limits: " << hi_res << " - " << lo_res << endl << endl;
215 }
216
217 long i, na(0);
218 for ( a = axis_start; a < axis_end + 0.1*axis_step; a += axis_step ) na++;
219
220 double* ar = new double[na];
221 double* cc = new double[na];
222
223 for ( i=0, a = axis_start; a < axis_end + 0.1*axis_step; a += axis_step, i++ ) {
224 ar[i] = a;
225 cc[i] = 0;
226 }
227
228 Vector3<long> size = micrograph_get_size(mg_ref);
229
230 fft_plan planf = fft_setup_plan(size, FFTW_FORWARD, 1);
231 fft_plan planb = fft_setup_plan(size, FFTW_BACKWARD, 1);
232 // fft_plan planf = fft_setup_plan(size, FFTW_FORWARD, 0);
233 // fft_plan planb = fft_setup_plan(size, FFTW_BACKWARD, 0);
234
235 #ifdef HAVE_GCD
236 dispatch_apply(na, dispatch_get_global_queue(0, 0), ^(size_t i){
237 cc[i] = mg_find_tilt_axis(mgp, mgn, mg_ref, ar[i], pgold, hi_res, lo_res, shift_limit, planf, planb);
238 });
239 #else
240 #pragma omp parallel for
241 for ( i=0; i<na; i++ ) {
242 cc[i] = mg_find_tilt_axis(mgp, mgn, mg_ref, ar[i], pgold, hi_res, lo_res, shift_limit, planf, planb);
243 }
244 #endif
245
246 fft_destroy_plan(planf);
247 fft_destroy_plan(planb);
248
249 if ( verbose )
250 cout << "Angle\tCC" << endl;
251 for ( i=0; i<na; i++ ) {
252 if ( ccbest < cc[i] ) {
253 ccbest = cc[i];
254 abest = ar[i];
255 }
256 if ( verbose )
257 cout << ar[i]*180.0/M_PI << tab << cc[i] << endl;
258 }
259
260 delete[] ar;
261 delete[] cc;
262 delete pgold;
263
264 if ( verbose ) {
265 cout << "Best tilt axis angle: " << abest*180.0/M_PI << " degrees" << endl;
266 cout << "Alternative tilt axis angle: " << angle_set_negPI_to_PI(abest-M_PI)*180.0/M_PI << " degrees" << endl;
267 cout << "Best correlation coefficient: " << ccbest << endl << endl;
268 }
269
270 kill_list((char *) mgp->mark, sizeof(Bmarker));
271 kill_list((char *) mgn->mark, sizeof(Bmarker));
272 mgp->mark = NULL;
273 mgn->mark = NULL;
274
275 for ( mg = project->field->mg; mg; mg = mg->next )
276 mg->tilt_axis = abest;
277
278 return ccbest;
279 }
280
281
313 int project_track_markers(Bproject* project, double hi_res, double lo_res,
314 double shift_limit, double thickness, int max_cycle,
315 double target, int cc_type, int recenter, Bstring paramfile)
316 {
317 if ( max_cycle > 20 ) max_cycle = 20;
318
319 int i, j, nmark, n, iref(0);
320 Bfield* field = project->field;
321 Bmicrograph* mg = NULL;
322 Bmicrograph* mg_ref = field_find_low_tilt_mg_with_markers(field);
323 Breconstruction* rec = project->rec;
324 Bmarker* model = rec->mark;
325 Bmarker* mark = NULL;
326 Bmarker* mark2 = NULL;
327 Bmarker* model2 = NULL;
328
329 if ( mg_ref->mark_radius < 1 )
330 return error_show("Error: Cannot track markers with zero radius reference!", __FILE__, __LINE__);
331
332 if ( target < 0.1 ) target = mg_ref->mark_radius/10;
333
334 if ( !model )
335 return error_show("No seed markers found!", __FILE__, __LINE__);
336
337 if ( verbose ) {
338 cout << "Tracking markers:" << endl;
339 cout << "Maximum number of iterations: " << max_cycle << endl;
340 cout << "Marker radius: " << mg_ref->mark_radius << endl;
341 cout << "Model origin: " << rec->origin << endl << endl;
342 }
343
344 if ( paramfile.length() < 1 ) paramfile = "btrack_param.star";
345 Bstring filename;
346
347 // Generate a composite gold particle image for cross-correlation
348 int cc_size = (int) (4*mg_ref->mark_radius);
349 if ( cc_size < 30 ) cc_size = 30;
350 Vector3<long> gsize(cc_size, cc_size, 1);
351 Bimage* pgold = mg_composite_particle(mg_ref, gsize);
352 write_img("marker_track_ref.map", pgold, 0);
353
354 for ( nmark=0, mark = model; mark; mark = mark->next, nmark++ ) ;
355 model2 = markers_copy(model);
356
357 int nmg = field_count_micrographs(field);
358 int cycle, iz;
359 double R(100);
360
361 double* z = new double[nmark*nmg];
362 double* w = new double[nmg];
363 Bmicrograph** mglist = new Bmicrograph*[nmg];
364
365 for ( i=0; i<nmg*nmark; i++ ) z[i] = -1e30;
366
367 for ( i=0, mg = field->mg; mg; mg = mg->next, i++ ) {
368 mglist[i] = mg;
369 if ( mg == mg_ref ) iref = i;
370 w[i] = 1/(1 + exp(0.2*(0.35 - fabs(mg->tilt_angle))));
371 }
372
373 int imax = nmg - iref;
374 if ( imax < iref ) imax = iref;
375
376 Vector3<long> size = micrograph_get_size(mg_ref);
377
378 // fft_plan planf = fft_setup_plan(size, FFTW_FORWARD, 1);
379 // fft_plan planb = fft_setup_plan(size, FFTW_BACKWARD, 1);
380 fft_plan planf = fft_setup_plan(size, FFTW_FORWARD, 0);
381 fft_plan planb = fft_setup_plan(size, FFTW_BACKWARD, 0);
382
383 for ( cycle = 0; R > target && cycle < max_cycle; cycle++ ) {
384
385 for ( mark=model, mark2=model2; mark; mark=mark->next, mark2=mark2->next )
386 mark2->loc = mark->loc;
387
388 for ( i=1; i<=imax; i++ ) {
389 cout << "Processing images " << iref-i << " and " << iref+i << endl;
390 iz = iref - i;
391 if ( iz >= 0 ) {
392 mg = mglist[iz];
393 if ( mg->select ) {
394 mg_marker_update(mg, model, rec->origin, 1);
395 mg_marker_shift(mg, pgold, hi_res, lo_res, shift_limit, planf, planb);
396 mg_marker_z_search(mg, model, rec->origin, pgold, thickness, cc_type, iz*nmark, z);
397 }
398 }
399 // bexit(0);
400 iz = iref + i;
401 if ( iz < nmg ) {
402 mg = mglist[iz];
403 if ( mg->select ) {
404 mg_marker_update(mg, model, rec->origin, 1);
405 mg_marker_shift(mg, pgold, hi_res, lo_res, shift_limit, planf, planb);
406 mg_marker_z_search(mg, model, rec->origin, pgold, thickness, cc_type, iz*nmark, z);
407 }
408 }
409 mg_z_matrix_update(model, nmg, nmark, z, w, recenter);
410 }
411
412 for ( mg = field->mg; mg; mg = mg->next )
413 mg_marker_update(mg, model, rec->origin, 1);
414
415 R = 0;
416 for ( n=0, mark=model, mark2=model2; mark; mark=mark->next, mark2=mark2->next ) if ( mark2->sel ) {
417 R += (mark->loc - mark2->loc).length2();
418 n++;
419 }
420 R = sqrt(R/n);
421 cout << "Cycle " << cycle+1 << ":\tAverage change in positions = " << R << " (" << n << ")" << endl;
422
423 if ( max_cycle > 1 ) {
424 filename = paramfile.pre_rev('.') + Bstring(cycle+1, "_%02d.") + paramfile.post_rev('.');
425 write_project(filename, project);
426 }
427 }
428
429 fft_destroy_plan(planf);
430 fft_destroy_plan(planb);
431
432 kill_list((char *) model2, sizeof(Bmarker));
433
434 cout << "Marker z coordinate matrix:\nMicrograph\tw";
435 for ( j=0; j<nmark; j++ ) cout << tab << j+1;
436 cout << endl;
437 for ( i=0, mg=field->mg; i<nmg; i++, mg=mg->next ) if ( mg != mg_ref && mg->select ) {
438 cout << mg->id << ":\t" << w[i];
439 for ( j=0; j<nmark; j++ ) cout << tab << z[i*nmark+j];
440 cout << endl;
441 }
442
443 delete[] z;
444 delete[] w;
445 delete[] mglist;
446 delete pgold;
447
448 if ( verbose ) {
449 cout << "Marker\tx\ty\tz\tResidual" << endl;
450 for ( mark = model; mark; mark = mark->next )
451 cout << mark->id << tab << mark->loc[0] << tab << mark->loc[1] << tab << mark->loc[2] << tab << mark->res << endl;
452 cout << endl;
453 }
454
455 return 0;
456 }
457
489 int project_track_markers_dual(Bproject* project, double hi_res, double lo_res,
490 double shift_limit, double thickness, int max_cycle,
491 double target, int cc_type, int recenter, Bstring paramfile)
492 {
493 if ( max_cycle > 20 ) max_cycle = 20;
494
495 long i, j, k, h, nmark, n, jref(0);
496 Bstring filename;
497 Bfield* field = project->field;
498 Bmicrograph* mg = NULL;
499 Bmicrograph* mgr = NULL;
500 Bmicrograph* mg_ref = field_find_low_tilt_mg_with_markers(field);
501 Breconstruction* rec = project->rec;
502 Bmarker* model = rec->mark;
503 Bmarker* mark = NULL;
504 Bmarker* mark2 = NULL;
505 Bmarker* model2 = NULL;
506
507 if ( mg_ref->mark_radius < 1 )
508 return error_show("Error: Cannot track markers with zero radius reference!", __FILE__, __LINE__);
509
510 if ( target < 0.1 ) target = mg_ref->mark_radius/10;
511
512 if ( !model )
513 return error_show("No seed markers found!", __FILE__, __LINE__);
514
515 if ( verbose ) {
516 cout << "Tracking markers:" << endl;
517 cout << "Maximum number of iterations: " << max_cycle << endl;
518 cout << "Marker radius: " << mg_ref->mark_radius << endl;
519 cout << "Model origin: " << rec->origin << endl << endl;
520 }
521
522 if ( paramfile.length() < 1 ) paramfile = "btrack_param.star";
523
524 // Generate a composite gold particle image for cross-correlation
525 long cc_size = (long) (4*mg_ref->mark_radius);
526 if ( cc_size < 30 ) cc_size = 30;
527 Vector3<long> gsize(cc_size, cc_size, 1);
528 Bimage* pgold = mg_composite_particle(mg_ref, gsize);
529 write_img("marker_track_ref.map", pgold, 0);
530
531 for ( nmark=0, mark = model; mark; mark = mark->next, nmark++ ) ;
532 model2 = markers_copy(model);
533
534 long nmg = project_count_micrographs(project);
535 long cycle;
536 double R(100);
537
538 int* seq = new int[nmg];
539 double* z = new double[nmark*nmg];
540 double* w = new double[nmg];
541 Bmicrograph** mglist = new Bmicrograph*[nmg];
542
543 for ( i=0; i<nmg*nmark; i++ ) z[i] = -1e30;
544
545 if ( verbose )
546 cout << "Sequence:" << endl;
547 for ( i=k=0, field = project->field; field; field = field->next ) {
548 mgr = field_find_low_tilt_mg_with_markers(field);
549 for ( n=0, mg = field->mg; mg; mg = mg->next, n++ )
550 if ( mg == mgr ) jref = n;
551 for ( j=1, h=0, mg = field->mg; mg; mg = mg->next, i++ ) {
552 mglist[i] = mg;
553 seq[i] = -1;
554 if ( jref + j < n && h ) seq[i] = k + jref + j;
555 else if ( jref - j >= 0 && h == 0 ) seq[i] = k + jref - j;
556 if ( h ) j++;
557 h = 1 - h;
558 w[i] = 1/(1 + exp(0.2*(0.35 - fabs(mg->tilt_angle))));
559 if ( verbose )
560 cout << " " << seq[i];
561 }
562 k += n;
563 }
564
565 if ( verbose )
566 cout << endl;
567
568 Vector3<long> size = micrograph_get_size(mg_ref);
569
570 // fft_plan planf = fft_setup_plan(size, FFTW_FORWARD, 1);
571 // fft_plan planb = fft_setup_plan(size, FFTW_BACKWARD, 1);
572 fft_plan planf = fft_setup_plan(size, FFTW_FORWARD, 0);
573 fft_plan planb = fft_setup_plan(size, FFTW_BACKWARD, 0);
574
575 for ( cycle = 0; R > target && cycle < max_cycle; cycle++ ) {
576
577 for ( mark=model, mark2=model2; mark; mark=mark->next, mark2=mark2->next )
578 mark2->loc = mark->loc;
579
580 for ( i=0; i<nmg; i++ ) if ( seq[i] >= 0 ) {
581 cout << "Processing image " << seq[i] << endl;
582 mg = mglist[seq[i]];
583 if ( mg->select ) {
584 mg_marker_update(mg, model, rec->origin, 1);
585 mg_marker_shift(mg, pgold, hi_res, lo_res, shift_limit, planf, planb);
586 mg_marker_z_search(mg, model, rec->origin, pgold, thickness, cc_type, seq[i]*nmark, z);
587 mg_z_matrix_update(model, nmg, nmark, z, w, recenter);
588 }
589 }
590
591 for ( field = project->field; field; field = field->next )
592 for ( mg = field->mg; mg; mg = mg->next )
593 mg_marker_update(mg, model, rec->origin, 1);
594
595 R = 0;
596 for ( n=0, mark=model, mark2=model2; mark; mark=mark->next, mark2=mark2->next ) if ( mark2->sel ) {
597 R += (mark->loc - mark2->loc).length2();
598 n++;
599 }
600 R = sqrt(R/n);
601 cout << "Cycle " << cycle+1 << ":\tAverage change in positions = " << R << " (" << n << ")" << endl;
602
603 if ( max_cycle > 1 ) {
604 filename = paramfile.pre_rev('.') + Bstring(cycle+1, "_%02d.") + paramfile.post_rev('.');
605 write_project(filename, project);
606 }
607 }
608
609 fft_destroy_plan(planf);
610 fft_destroy_plan(planb);
611
612 kill_list((char *) model2, sizeof(Bmarker));
613
614 if ( verbose & VERB_PROCESS ) {
615 cout << "Marker z coordinate matrix:\nMicrograph\tw";
616 for ( j=0; j<nmark; j++ ) cout << tab << j+1;
617 cout << endl;
618 for ( i=0, field = project->field; field; field = field->next ) {
619 for ( mg = field->mg; mg; i++, mg = mg->next ) if ( mg != mg_ref && mg->select ) {
620 cout << mg->id << ":\t" << w[i];
621 for ( j=0; j<nmark; j++ ) cout << tab << z[i*nmark+j];
622 cout << endl;
623 }
624 }
625 }
626
627 delete[] seq;
628 delete[] z;
629 delete[] w;
630 delete[] mglist;
631 delete pgold;
632
633 if ( verbose ) {
634 cout << "Marker\tx\ty\tz\tResidual" << endl;
635 for ( mark = model; mark; mark = mark->next )
636 cout << mark->id << tab << mark->loc[0] << tab << mark->loc[1] << tab << mark->loc[2] << tab << mark->res << endl;
637 cout << endl;
638 }
639
640 return 0;
641 }
642
643 double marker_refine(Bmarker* mark, Bmarker* marklist, Bimage* p, Bimage* pgold,
644 double radius, double hi_res, double lo_res)
645 {
646 if ( !p->within_boundaries(mark->loc) ) return 0;
647
648 Vector3<long> extsize = pgold->size() * 2;
649 if ( pgold->sizeZ() < 2 ) extsize[2] = 1;
650 Vector3<double> extori(extsize[0]/2, extsize[1]/2, extsize[2]/2);
651
652 Bimage* pmark = img_marker_projection(extsize, (mark->loc - extori),
653 radius, pgold, marklist);
654
655 Bimage* pex = p->extract(0, (mark->loc - extori), extsize);
656 pex->origin(extori);
657
658 double cc(0);
659 mark->err = pex->find_shift(pmark, NULL, hi_res, lo_res, pex->sizeX()/4.0, 0.1, 1, cc);
660
661 delete pmark;
662 delete pex;
663
664 mark->loc += mark->err;
665 mark->res = mark->err.length();
666 mark->fom = cc;
667 if ( mark->fom < 0.0001 ) mark->fom = 0.0001;
668
669 return cc;
670 }
671
683 int project_refine_markers(Bproject* project, double hi_res, double lo_res)
684 {
685 int i, nmg, nmark, nms(0), nmsi;
686
687 Bfield* field = project->field;
688 Bmicrograph* mg;
689 Bmicrograph* mg_ref = field_find_zero_tilt_mg(field);
690 Bmarker* mark = NULL;
691 Bimage* p = NULL;
692
693 if ( !mg_ref->mark )
694 return error_show("No markers found!", __FILE__, __LINE__);
695
696 int cc_size = (int) (6*mg_ref->mark_radius);
697 if ( cc_size < 40 ) cc_size = 40;
698 Vector3<long> gsize(cc_size, cc_size, 1);
699 Bimage* pgold = mg_composite_particle(mg_ref, gsize);
700 write_img("marker_refine_ref.map", pgold, 0);
701
702 for ( nmark=0, mark = mg_ref->mark; mark; mark = mark->next ) nmark++;
703 double mg_shift, avg_shift, mg_fom, avg_fom, cc;
704 double* mark_shift = new double[nmark];
705 double* mark_fom = new double[nmark];
706
707 for ( i=0; i<nmark; i++ ) mark_shift[i] = mark_fom[i] = 0;
708
709 if ( verbose )
710 cout << "Image\tShift\tCC" << endl;
711 for ( nmg=0, field = project->field; field; field = field->next ) if ( field->select ) {
712 for ( mg = field->mg; mg; mg = mg->next, nmg++ ) if ( mg->select && mg->mark ) {
713 p = read_img(mg->fmg, 1, mg->img_num);
714 if ( !p )
715 return error_show("project_refine_markers", __FILE__, __LINE__);
716 nmsi = 0;
717 mg_shift = mg_fom = 0;
718 for ( i=0, mark = mg->mark; mark; mark = mark->next, i++ ) if ( mark->sel > 0 ) {
719 cc = marker_refine(mark, mg->mark, p, pgold, mg->mark_radius, hi_res, lo_res);
720 mark_shift[i] += mark->res;
721 mg_shift += mark->res;
722 mark_fom[i] += cc;
723 mg_fom += cc;
724 nmsi++;
725 }
726 delete p;
727 nms += nmsi;
728 if ( verbose )
729 cout << mg->id << tab << mg_shift/nmsi << tab << mg_fom/nmsi << endl;
730 }
731 }
732
733 if ( verbose )
734 cout << "\nMarker\tShift\tCC" << endl;
735 for ( avg_shift=avg_fom=0, i=0, mark=mg_ref->mark; i<nmark; i++, mark=mark->next ) {
736 mark_shift[i] /= nmg;
737 mark_fom[i] /= nmg;
738 avg_shift += mark_shift[i];
739 avg_fom += mark_fom[i];
740 if ( verbose )
741 cout << mark->id << tab << mark_shift[i] << tab << mark_fom[i] << endl;
742 }
743
744 if ( verbose ) {
745 cout << endl << "Average shift: " << avg_shift/nms << endl;
746 cout << "Average CC: " << avg_fom/nms << endl;
747 }
748
749 delete[] mark_shift;
750 delete[] mark_fom;
751 delete pgold;
752
753 return 0;
754 }
755
768 int project_refine_one_marker(Bproject* project, int id, double hi_res, double lo_res)
769 {
770 int nmg, nms(0);
771
772 Bfield* field = project->field;
773 Bmicrograph* mg;
774 Bmicrograph* mg_ref = field_find_zero_tilt_mg(field);
775 Bmarker* mark = NULL;
776 Bimage* p = NULL;
777
778 if ( !mg_ref->mark )
779 return error_show("No markers found!", __FILE__, __LINE__);
780
781 int cc_size = (int) (6*mg_ref->mark_radius);
782 if ( cc_size < 40 ) cc_size = 40;
783 Vector3<long> gsize(cc_size, cc_size, 1);
784 Bimage* pgold = mg_composite_particle(mg_ref, gsize);
785 write_img("marker_refine_ref.map", pgold, 0);
786
787 double cc;
788 double mark_shift(0);
789 double mark_fom(0);
790
791 for ( nmg=0, field = project->field; field; field = field->next ) if ( field->select ) {
792 for ( mg = field->mg; mg; mg = mg->next, nmg++ ) if ( mg->select && mg->mark ) {
793 p = read_img(mg->fmg, 1, mg->img_num);
794 if ( !p )
795 return error_show("project_refine_one_marker", __FILE__, __LINE__);
796 for ( mark = mg->mark; mark && mark->id != id; mark = mark->next ) ;
797 if ( mark && mark->sel > 0 ) {
798 cc = marker_refine(mark, mg->mark, p, pgold, mg->mark_radius, hi_res, lo_res);
799 mark_shift += mark->res;
800 mark_fom += cc;
801 nms++;
802 }
803 delete p;
804 }
805 }
806
807 if ( verbose ) {
808 cout << "Marker " << id << ":" << endl;
809 cout << "Average shift: " << mark_shift/nms << endl;
810 cout << "Average CC: " << mark_fom/nms << endl << endl;
811 }
812
813 delete pgold;
814
815 return 0;
816 }
817
818
831 int mg_refine_markers(Bmicrograph* mg, Bimage* pgold, double hi_res, double lo_res)
832 {
833 if ( !mg->mark )
834 return error_show("No markers found!", __FILE__, __LINE__);
835
836 int nmark, nms(0);
837 Bmarker* mark = NULL;
838 Bimage* p = NULL;
839
840 double mg_shift, mg_fom, cc;
841
842 p = read_img(mg->fmg, 1, mg->img_num);
843 if ( !p )
844 return error_show("mg_refine_markers", __FILE__, __LINE__);
845 mg_shift = mg_fom = 0;
846 for ( nmark=0, mark = mg->mark; mark; mark = mark->next, nmark++ ) if ( mark->sel > 0 ) {
847 cc = marker_refine(mark, mg->mark, p, pgold, mg->mark_radius, hi_res, lo_res);
848 mg_shift += mark->res;
849 mg_fom += cc;
850 nms++;
851 }
852 delete p;
853
854 if ( verbose & VERB_FULL )
855 cout << mg->id << tab << mg_shift/nms << tab << mg_fom/nms << endl;
856
857 return 0;
858 }
859
868 double project_refine(Bproject* project, int iter, double tol, Bstring refop)
869 {
870 long i, j;
871 double R = 1e30, dR = 1e30;
872
873 if ( verbose ) {
874 cout << "Refining model and orientation parameters:" << endl;
875 cout << "Model origin: " << project->rec->origin << endl;
876 cout << "Sequence of refinements: " << refop << endl << endl;
877 }
878
879 R = project_tomo_residuals(project, 0);
880
881 if ( verbose )
882 cout << "Cycle\tR\tdR" << endl;
883 for ( i = 1; i <= iter && R > 0.1 && fabs(dR) > tol; i++ ) {
884 dR = R;
885 for ( j=0; j<refop.length(); j++ ) {
886 switch ( refop[j] ) {
887 case 'z': project_refine_z(project); break;
888 case 'v': project_refine(project, 1, 0, 0); break;
889 case 'o': project_refine(project, 0, 1, 0); break;
890 case 's': project_refine(project, 0, 0, 1); break;
891 case 'a': project_refine(project, 1, 1, 1); break;
892 }
893 }
894 R = project_tomo_residuals(project, 0);
895 dR -= R;
896 if ( verbose )
897 cout << i << tab << R << tab << dR << endl;
898 }
899
900 project_calculate_angles(project);
901
902 if ( verbose )
903 cout << endl;
904
905 return R;
906 }
907
908 double tomo_z_residual(Bproject* project, Bmarker* mark)
909 {
910 Bfield* field = project->field;
911 Bmicrograph* mg = field->mg;
912 Bmarker* m;
913 Vector3<double> oriref = project->rec->origin;
914 Vector3<double> loc, rloc;
915 Matrix3 mat(1);
916 long n(0);
917 double d, R(0), w(0);
918
919 for ( field = project->field; field; field = field->next ) if ( field->select ) {
920 for ( mg = field->mg; mg; mg = mg->next ) if ( mg->select ) {
921 mat = mg->matrix.transpose(); // Handedness
922 for ( m = mg->mark; m && m->id != mark->id; m = m->next ) ;
923 if ( m && m->id == mark->id && m->sel > 0 ) {
924 loc = m->loc - mg->origin;
925 rloc = mark->loc - oriref;
926 // d = loc[0] - rloc[0]*mat[0] - rloc[1]*mat[1] - rloc[2]*mat[2];
927 d = loc[0] - rloc.scalar(mat[0]);
928 R += d*d*mark->fom;
929 // d = loc[1] - rloc[0]*mat[3] - rloc[1]*mat[4] - rloc[2]*mat[5];
930 d = loc[1] - rloc.scalar(mat[1]);
931 R += d*d*mark->fom;
932 n++;
933 w += mark->fom;
934 }
935 }
936 }
937
938 if ( w ) R = sqrt(R/(2*w));
939
940 return R;
941 }
942
948 double project_refine_z(Bproject* project)
949 {
950 Bmarker* mr;
951 Bmarker* model = project->rec->mark;
952 long n(0);
953 double oldz, zinc, d, Rz, Rp, Rm, R(0);
954
955 if ( !model )
956 return error_show("No markers found!", __FILE__, __LINE__);
957
958 if ( verbose & VERB_FULL )
959 cout << "Marker\tOld z\tNew z\tR" << endl;
960 for ( mr = model; mr; mr = mr->next ) if ( mr->sel ) {
961 oldz = mr->loc[2];
962 Rz = tomo_z_residual(project, mr);
963 for ( zinc = 1; zinc > 0.001; ) {
964 mr->loc[2] += zinc;
965 Rp = tomo_z_residual(project, mr);
966 if ( Rz > Rp ) {
967 Rz = Rp;
968 } else {
969 mr->loc[2] -= 2*zinc;
970 Rm = tomo_z_residual(project, mr);
971 if ( Rz > Rm ) {
972 Rz = Rm;
973 } else {
974 mr->loc[2] += zinc;
975 zinc *= 0.7;
976 }
977 }
978 }
979 if ( verbose & VERB_FULL )
980 cout << mr->id << tab << oldz << tab << mr->loc[2] << tab << Rz << endl;
981 d = mr->loc[2] - oldz;
982 R += d*d;
983 n++;
984 }
985
986 R = sqrt(R/n);
987
988 if ( verbose & VERB_PROCESS )
989 cout << "RMS change in z: " << R << endl;
990
991 return R;
992 }
993
1005 double project_refine(Bproject* project, int do_view, int do_origin, int do_scale)
1006 {
1007 if ( ( do_origin < 1 ) && ( do_scale < 1 ) && ( do_view < 1 ) ) return 0;
1008
1009 Bfield* field;
1010 Bmicrograph* mg;
1011 Breconstruction* rec = project->rec;
1012 double att(0.001), beta(100);
1013 int accept, ncyc(0), n(0), nacc;
1014 double irm = 1.0/get_rand_max();
1015 double R, pR, bR(0), d;
1016 Bmarker* model = rec->mark;
1017
1018 View v, vt, bv;
1019 Vector3<double> ori, oritemp, oribest;
1020 Vector3<double> scale, scaletemp, scalebest;
1021
1022 random_seed();
1023
1024 if ( verbose & VERB_PROCESS )
1025 cout << "Image\tdx\tdy\tsx\tsy\tvx\tvy\tvz\tva\tR" << endl;
1026 for ( field = project->field; field; field = field->next ) if ( field->select ) {
1027 for ( mg = field->mg; mg; mg = mg->next ) if ( mg->select ) {
1028 v = View(mg->matrix);
1029 ori = mg->origin;
1030 scale = mg->scale;
1031 v.normalize();
1032 bR = mg_tomo_residuals(mg, model, rec->origin);
1033 n = nacc = ncyc = 0;
1034 R = pR = bR = 1e30;
1035 while ( ncyc < 1000 && bR > 0.001 ) {
1036 oritemp = ori;
1037 scaletemp = scale;
1038 vt = v;
1039 if ( do_view ) {
1040 vt[0] = v[0] + att*(random()*irm*2.0 - 1);
1041 vt[1] = v[1] + att*(random()*irm*2.0 - 1);
1042 vt[2] = v[2] + att*(random()*irm*2.0 - 1);
1043 if ( vt[2] < 0 ) vt[2] = -vt[2]; // Is this good ?????
1044 vt[3] = v.angle() + att*(random()*irm*2.0 - 1);
1045 vt.normalize();
1046 mg->matrix = vt.matrix();
1047 }
1048 if ( do_origin ) {
1049 oritemp = ori + vector3_xy_random_gaussian(0.0, 1.0);
1050 mg->origin = oritemp;
1051 }
1052 if ( do_scale ) {
1053 scaletemp = scale + vector3_xy_random_gaussian(0.0, 0.001);
1054 mg->scale = scaletemp;
1055 }
1056 R = mg_tomo_residuals(mg, model, rec->origin);
1057 if ( bR > R ) {
1058 bR = R;
1059 bv = vt;
1060 oribest = oritemp;
1061 scalebest = scaletemp;
1062 ncyc = 0;
1063 }
1064 accept = 1;
1065 if ( R > pR ) {
1066 d = random()*irm;
1067 if ( exp(beta*(pR-R)) < d ) accept = 0;
1068 }
1069 if ( accept ) {
1070 pR = R;
1071 v = vt;
1072 ori = oritemp;
1073 scale = scaletemp;
1074 nacc++;
1075 } else {
1076 R = pR;
1077 vt = v;
1078 oritemp = ori;
1079 scaletemp = scale;
1080 }
1081 ncyc++;
1082 n++;
1083 }
1084 mg->matrix = bv.matrix();
1085 mg->origin = oribest;
1086 mg->scale = scalebest;
1087 if ( verbose & VERB_PROCESS )
1088 cout << mg->id << tab << bv[0] << tab << bv[1] << tab << bv[2] << tab <<
1089 bv.angle()*180/M_PI << tab << acos(bv[2])*180/M_PI << tab << bR << tab << nacc*100.0/n << endl;
1090 }
1091 }
1092
1093 return bR;
1094 }
1095
1112 double mg_marker_shift(Bmicrograph* mg, Bimage* pgold, double hi_res,
1113 double lo_res, double shift_limit, fft_plan planf, fft_plan planb)
1114 {
1115 if ( !mg->mark )
1116 return error_show("No markers found!", __FILE__, __LINE__);
1117
1118 if ( verbose & VERB_DEBUG )
1119 cout << "DEBUG mg_marker_shift: mg=" << mg->id << endl;
1120
1121 Bmarker* mark = NULL;
1122
1123 Bimage* p = read_img(mg->fmg, 1, mg->img_num);
1124 if ( !p )
1125 return error_show("mg_marker_shift", __FILE__, __LINE__);
1126
1127 p->origin(mg->origin);
1128
1129 Vector3<double> offset;
1130
1131 if ( shift_limit < 0 ) shift_limit = 0.2*p->sizeX();
1132
1133 Bimage* pmark = img_marker_projection(p->size(), offset, mg->mark_radius, pgold, mg->mark);
1134
1135 double cc(0);
1136 Vector3<double> shift = p->find_shift(pmark, NULL, hi_res, lo_res, shift_limit, 0, 1, planf, planb, cc);
1137
1138 // write_img("pmark.pif", pmark);
1139 delete pmark;
1140 delete p;
1141
1142 mg->origin += shift;
1143 for ( mark = mg->mark; mark; mark = mark->next ) if ( mark->sel )
1144 mark->loc += shift;
1145
1146 if ( verbose & VERB_PROCESS )
1147 cout << "Image " << mg->img_num << " origin:\t" << mg->origin[0] << tab << mg->origin[1] << tab << "CC: " << cc << endl;
1148
1149 return cc;
1150 }
1151
1152 double marker_fom(Bimage* p, Vector3<double> loc, double radius)
1153 {
1154 double sf, s;
1155 double f = p->density(0, loc, radius, sf);
1156 double d = p->density(0, loc, 2*radius, s);
1157
1158 // return fabs(f/d - 1);
1159 // return sf/s - 1;
1160 return f - d;
1161 }
1162
1163 int mg_marker_z_search_one(Bmicrograph* mg, Bimage* p, Bmarker* modmark, Vector3<double> oriref,
1164 Bimage* pgold, double thickness, int cc_type, int i, double* z, fft_plan planf, fft_plan planb)
1165 {
1166 Bmarker* mark;
1167
1168 for ( mark = mg->mark; mark && mark->id != modmark->id; mark = mark->next ) ;
1169
1170 if ( !mark || !mark->sel ) return 0;
1171
1172 Vector3<double> mloc = modmark->loc - oriref;
1173
1174 z[i] = mloc[2];
1175 mark->fom = 0;
1176
1177 double cc(-1);
1178 double dz(1/sin(fabs(mg->tilt_angle))); // Approximately one pixel in xy
1179 double z_range(thickness/mg->pixel_size); // Thickness in voxels
1180 double z_start = mloc[2] - z_range;
1181 double z_end = mloc[2] + z_range;
1182 Matrix3 mat = mg->matrix;
1183 Vector3<long> gsize(pgold->size());
1184 Vector3<double> gori(pgold->image->origin());
1185 Vector3<double> extori;
1186 Bimage* pmark;
1187 Bimage* pc;
1188
1189 if ( z_range > 100*dz ) z_range = 100*dz;
1190
1191 for ( mloc[2] = z_start; mloc[2] <= z_end; mloc[2] += dz ) {
1192 mark->loc = mg_location_from_3D_model(mloc, mat, mg->origin);
1193 if ( mark->loc[0] > gori[0] && mark->loc[0] < p->sizeX() - gori[0] &&
1194 mark->loc[1] > gori[1] && mark->loc[1] < p->sizeY() - gori[1] ) {
1195 extori = mark->loc - gori;
1196 pmark = p->extract(0, extori, gsize);
1197 pmark->origin(pmark->size()/2);
1198 if ( cc_type < 1 ) {
1199 cc = pmark->correlate(pgold, 0, pmark->sizeX()/2.0, NULL, 0);
1200 // cc = pmark->correlate(pgold);
1201 } else {
1202 pc = pmark->cross_correlate(pgold, 4*pmark->sampling()[0], 0, planf, planb);
1203 cc = pc->maximum();
1204 delete pc;
1205 }
1206 // write_img("m.map", pmark);
1207 delete pmark;
1208 if ( mark->fom < cc ) {
1209 mark->fom = cc;
1210 z[i] = mloc[2];
1211 }
1212 }
1213 }
1214
1215 // mark->fom = marker_fom(p, mark->loc, mg->mark_radius)/pgold->image->FOM();
1216 if ( mark->fom < 0.0001 ) mark->fom = 0.0001;
1217
1218 if ( verbose & VERB_FULL )
1219 cout << " " << z[i];
1220
1221 return cc;
1222 }
1223
1224 /*
1225 @brief Refines the z-coordinate of a global marker model.
1226 @param *mg micrograph.
1227 @param *model marker model.
1228 @param oriref reference origin.
1229 @param *pgold marker reference image.
1230 @param thickness estimated tomogram thickness (angstrom).
1231 @param cc_type indicates type of correlation: 0=real space, 1=cross correlation
1232 @param iz starting index in the z-matrix.
1233 @param *z z-matrix.
1234 @return int 0.
1235 **/
1236 int mg_marker_z_search(Bmicrograph* mg, Bmarker* model, Vector3<double> oriref,
1237 Bimage* pgold, double thickness, int cc_type, int iz, double* z)
1238 {
1239 if ( fabs(mg->tilt_angle) < 0.001 ) {
1240 cerr << "Warning: micrograph " << mg->id << " tilt angle is too small! (" << mg->tilt_angle << ")" << endl;
1241 return -1;
1242 }
1243
1244 if ( thickness < 1000 ) thickness = 1000; // Minimum thickness = 1000 angstrom (0.1 um)
1245 if ( thickness > 100000 ) thickness = 100000; // Maximum thickness = 100000 angstrom (10 um)
1246
1247 if ( !mg->mark )
1248 return error_show("No markers found!", __FILE__, __LINE__);
1249
1250 Bmarker* modmark = NULL;
1251
1252 Bimage* p = read_img(mg->fmg, 1, mg->img_num);
1253 if ( !p )
1254 return error_show("mg_marker_z_search", __FILE__, __LINE__);
1255
1256 long i, cc_size = (long) (4*mg->mark_radius);
1257 if ( cc_size < 30 ) cc_size = 30;
1258 double dz(1/sin(fabs(mg->tilt_angle))); // Approximately one pixel in xy
1259 Vector3<long> gsize;
1260
1261 int local_gold_particle(0);
1262 if ( pgold ) {
1263 gsize = pgold->size();
1264 } else {
1265 local_gold_particle = 1;
1266 gsize = Vector3<long>(cc_size, cc_size, 1);
1267 pgold = img_gold_particle(gsize, mg->mark_radius);
1268 }
1269
1270 p->sampling(mg->pixel_size, mg->pixel_size, 1);
1271 pgold->sampling(p->sampling());
1272
1273 long nmark;
1274 for ( nmark=0, modmark = model; modmark; modmark = modmark->next, nmark++ ) ;
1275
1276 Bmarker** marr = new Bmarker*[nmark];
1277 for ( i=0, modmark = model; i<nmark && modmark; i++, modmark = modmark->next )
1278 marr[i] = modmark;
1279
1280 fft_plan planf = fft_setup_plan(gsize, FFTW_FORWARD, 1);
1281 fft_plan planb = fft_setup_plan(gsize, FFTW_BACKWARD, 1);
1282
1283 if ( verbose )
1284 cout << "Image " << mg->img_num << " z search: " << dz << endl;
1285 #ifdef HAVE_GCD
1286 dispatch_apply(nmark, dispatch_get_global_queue(0, 0), ^(size_t i){
1287 mg_marker_z_search_one(mg, p, marr[i], oriref, pgold, thickness, cc_type, i+iz, z, planf, planb);
1288 });
1289 #else
1290 #pragma omp parallel for
1291 for ( i=0; i<nmark; i++ ) {
1292 mg_marker_z_search_one(mg, p, marr[i], oriref, pgold, thickness, cc_type, i+iz, z, planf, planb);
1293 }
1294 #endif
1295
1296 if ( verbose & VERB_FULL )
1297 cout << endl;
1298
1299 fft_destroy_plan(planf);
1300 fft_destroy_plan(planb);
1301
1302 delete p;
1303 delete[] marr;
1304
1305 if ( local_gold_particle ) delete pgold;
1306
1307 return 0;
1308 }
1309
1310 /*
1311 @brief Updates the z-coordinate of a global marker model.
1312 @param model reference marker list.
1313 @param nmg number of micrographs.
1314 @param nmark number of markers.
1315 @param *z z-matrix.
1316 @param *w array for micrograph weights.
1317 @param recenter flag to recenter z coordinates.
1318 @return int 0.
1319
1320 Calculates average and deviation of the z-coordinate of a global
1321 marker model over all of the available z measurements.
1322 The ultimate z-value accepted is the median.
1323 **/
1324 int mg_z_matrix_update(Bmarker* model, int nmg, int nmark, double* z, double* w, int recenter)
1325 {
1326 if ( !model )
1327 return error_show("No markers found!", __FILE__, __LINE__);
1328
1329 int i, j, k, n, m;
1330 double tw, avg_z, std_z, med_z, avg_all_z(0);
1331 double* za = new double[nmg];
1332 Bmarker* mark;
1333
1334 for ( i=0; i<nmg; i++ ) za[i] = 0;
1335
1336 if ( verbose )
1337 cout << "Marker\tZmed\tZavg\tZstd\tFOM\tCount" << endl;
1338 for ( i=m=0, mark = model; mark; i++, mark = mark->next ) if ( mark->sel ) {
1339 for ( avg_z=std_z=tw=0, j=n=0; j<nmg; j++ ) {
1340 k = j*nmark + i;
1341 if ( z[k] > -1e10 ) {
1342 avg_z += w[j]*z[k];
1343 std_z += w[j]*z[k]*z[k];
1344 za[n] = z[k];
1345 tw += w[j];
1346 n++;
1347 }
1348 }
1349 med_z = 0;
1350 if ( n ) {
1351 avg_z /= tw;
1352 std_z = std_z/tw - avg_z*avg_z;
1353 if ( std_z > 0 ) std_z = sqrt(std_z);
1354 else std_z = 0;
1355 qsort((void *) za, n, sizeof(double), QsortLargeToSmallDouble);
1356 med_z = za[n/2];
1357 // mark->loc.z = avg_z;
1358 // mark->loc[2] = med_z;
1359 mark->loc[2] = 0.5*(med_z + mark->loc[2]);
1360 // mark->loc[2] = 0.5*(med_z + avg_z);
1361 mark->res = std_z;
1362 mark->fom = fom_from_distance(std_z, 10);
1363 if ( mark->fom < 0.0001 ) mark->fom = 0.0001;
1364 // mark->fom = 1/(1 + std_z + fabs(avg_z - med_z));
1365 }
1366 avg_all_z += mark->loc[2];
1367 m++;
1368 if ( verbose )
1369 cout << setprecision(2) << mark->id << tab << med_z << tab <<
1370 avg_z << tab << std_z << tab << setprecision(5) << mark->fom << tab << n << endl;
1371 }
1372 // if ( verbose )
1373 // cout << endl;
1374
1375 delete[] za;
1376
1377 avg_all_z /= m;
1378
1379 if ( recenter ) {
1380 if ( verbose )
1381 cout << "Recentering z coordinates: " << avg_all_z << endl;
1382
1383 if ( verbose & VERB_FULL )
1384 cout << "Marker\tz\tFOM" << endl;
1385 for ( mark = model; mark; mark = mark->next ) {
1386 if ( mark->sel ) mark->loc[2] -= avg_all_z;
1387 else mark->loc[2] = mark->fom = 0;
1388 if ( verbose & VERB_FULL )
1389 cout << mark->id << tab << mark->loc[2] << tab << mark->fom << endl;
1390 }
1391 }
1392
1393 if ( verbose )
1394 cout << endl;
1395
1396 return 0;
1397 }
1398
1418 int project_transfer_seed(Bproject* project,
1419 double rot_start, double rot_end, double rot_step,
1420 double hi_res, double lo_res, double shift_limit)
1421 {
1422 Vector3<double> origin, bestshift;
1423 double cc(-1), bestcc(-1), bestangle(0);
1424 Bfield* field1 = project->field;
1425 Bfield* field2 = field1->next;
1426
1427 Bmicrograph* mg1 = field_find_zero_tilt_mg(field1);
1428 if ( !mg1->mark ) for ( mg1 = field1->mg; mg1 && !mg1->mark; mg1 = mg1->next ) ;
1429
1430 if ( !mg1 ) {
1431 cerr << "Error: No markers defined for the first tilt series!" << endl;
1432 return -1;
1433 }
1434
1435 if ( hi_res < 2*mg1->pixel_size ) hi_res = 2*mg1->pixel_size;
1436 if ( lo_res < 2*hi_res ) lo_res = 100*hi_res;
1437 if ( shift_limit < 10 ) shift_limit = 10;
1438
1439 Bmicrograph* mg2 = field_find_zero_tilt_mg(field2);
1440
1441 if ( !mg2 ) {
1442 cerr << "Error: No micrographs found in the second tilt series!" << endl;
1443 return -1;
1444 }
1445
1446 if ( mg1->matrix.determinant() < 0.5 )
1447 project_mg_tilt_to_matrix(project);
1448
1449 mg2->mark_radius = mg1->mark_radius;
1450
1451 // Generate a composite gold particle image for cross-correlation
1452 int cc_size = (int) (4*mg1->mark_radius);
1453 if ( cc_size < 30 ) cc_size = 30;
1454 Vector3<long> gsize(cc_size, cc_size, 1);
1455 Bimage* pgold = mg_composite_particle(mg1, gsize);
1456
1457 Transform t;
1458 t.origin = mg1->origin;
1459
1460 if ( verbose ) {
1461 cout << "Finding the best angle to transform the first seed to the second" << endl;
1462 cout << "Micrograph 1: " << mg1->id << endl;
1463 cout << "Micrograph 2: " << mg2->id << endl;
1464 cout << "Resolution: " << hi_res << " - " << lo_res << endl;
1465 cout << "Shift limit: " << shift_limit << endl;
1466 }
1467
1468 Vector3<long> size = micrograph_get_size(mg1);
1469
1470 fft_plan planf = fft_setup_plan(size[0], size[1], 1, FFTW_FORWARD, 1);
1471 fft_plan planb = fft_setup_plan(size[0], size[1], 1, FFTW_BACKWARD, 1);
1472
1473 if ( verbose )
1474 cout << "Angle\tOriX\tOriY\tCC" << endl;
1475 for ( t.angle = rot_start; t.angle <= rot_end; t.angle += rot_step ) {
1476 kill_list((char *) mg2->mark, sizeof(Bmarker));
1477 mg2->mark = markers_copy(mg1->mark);
1478 marker_transform(mg2->mark, t);
1479 mg2->origin = mg1->origin;
1480 cc = mg_marker_shift(mg2, pgold, hi_res, lo_res, shift_limit, planf, planb);
1481 if ( bestcc < cc ) {
1482 bestcc = cc;
1483 bestangle = t.angle;
1484 bestshift = mg2->origin - mg1->origin;
1485 }
1486 if ( verbose )
1487 cout << t.angle*180.0/M_PI << tab << mg2->origin[0] << tab << mg2->origin[1] << tab << cc << endl;
1488 }
1489
1490 fft_destroy_plan(planf);
1491 fft_destroy_plan(planb);
1492
1493 t.angle = bestangle;
1494 t.trans = bestshift;
1495 kill_list((char *) mg2->mark, sizeof(Bmarker));
1496 mg2->mark = markers_copy(mg1->mark);
1497 int nmark = marker_transform(mg2->mark, t);
1498
1499 if ( verbose ) {
1500 cout << "Best angle: " << bestangle*180.0/M_PI << " degrees" << endl;
1501 cout << "Best shift: " << bestshift[0] << " " << bestshift[1] << endl;
1502 cout << "Correlation coefficient: " << bestcc << endl << endl;
1503 }
1504
1505 field2->origin = t * mg1->origin;
1506
1507 // t = marker_find_transform(mg2->mark, mg1->mark, mg1->origin);
1508 // cout << "axis=" << t.axis*180/M_PI << tab << "angle=" << t.angle*180/M_PI << endl;
1509
1510 field2->matrix = Matrix3(t.axis, t.angle);
1511 cout << "Field origin: " << field2->origin << endl;
1512 cout << "Field matrix: " << field2->matrix << endl;
1513 for ( mg2 = field2->mg; mg2; mg2 = mg2->next ) {
1514 mg2->origin = field2->origin;
1515 // mg2->tilt_axis = mg1->tilt_axis;
1516 // mg2->matrix = mg2->matrix * field2->matrix.transpose();
1517 mg2->matrix = field2->matrix.transpose() * mg2->matrix;
1518 }
1519
1520 // if ( project->rec && project->rec->mark )
1521 // marker_transform(project->rec->mark, t);
1522
1523 delete pgold;
1524
1525 return nmark;
1526 }
1527
1541 int project_transform_dual(Bproject* project)
1542 {
1543 Breconstruction* rec1 = project->rec;
1544 Breconstruction* rec2 = project->rec->next;
1545 Bmarker* mark1 = rec1->mark;
1546 Bmarker* mark2 = rec2->mark;
1547
1548 Transform t = marker_find_transform(mark2, mark1, rec2->origin);
1549
1550 Matrix3 mat = Matrix3(t.axis, t.angle);
1551
1552 if ( verbose ) {
1553 cout << "Marker set 2 transformation:" << endl;
1554 cout << "Axis: " << t.axis << endl;
1555 cout << "Rotation angle: " << t.angle*180.0/M_PI << " degrees" << endl;
1556 cout << "Scale: " << t.scale << endl;
1557 cout << "Origin: " << t.origin << endl;
1558 cout << "Translation: " << t.trans << endl;
1559 matrix3_show_hp(mat);
1560 }
1561
1562 mat = t.scale * mat;
1563
1564 long n;
1565 double d, R(0);
1566 Vector3<double> loc, shift_avg;
1567 Vector3<double> shift = t.origin*t.scale + t.trans;
1568
1569 // Transform the markers to agree with the eventual reconstruction
1570 for ( mark2 = rec2->mark; mark2; mark2 = mark2->next ) {
1571 loc = mark2->loc - rec2->origin;
1572 loc = mat * loc;
1573 loc += shift;
1574 mark2->loc = loc;
1575 }
1576
1577 for ( n=0, mark1 = rec1->mark; mark1; mark1 = mark1->next ) if ( mark1->sel ) {
1578 for ( mark2 = rec2->mark; mark2 && mark2->id != mark1->id; mark2 = mark2->next ) ;
1579 if ( mark2 && mark2->sel ) {
1580 loc = mark1->loc - mark2->loc;
1581 shift_avg += loc;
1582 n++;
1583 }
1584 }
1585
1586 if ( n ) {
1587 shift_avg /= n;
1588 for ( mark2 = rec2->mark; mark2; mark2 = mark2->next ) mark2->loc += shift_avg;
1589 }
1590
1591 if ( verbose )
1592 cout << "Marker\tResidual" << endl;
1593 for ( n=0, mark1 = rec1->mark; mark1; mark1 = mark1->next ) if ( mark1->sel ) {
1594 for ( mark2 = rec2->mark; mark2 && mark2->id != mark1->id; mark2 = mark2->next ) ;
1595 if ( mark2 && mark2->sel ) {
1596 loc = mark1->loc - mark2->loc;
1597 d = loc.length();
1598 R += d*d;
1599 n++;
1600 if ( verbose )
1601 cout << mark1->id << tab << d << endl;
1602 }
1603 }
1604
1605 if ( n ) R = sqrt(R/n);
1606
1607 if ( verbose ) {
1608 cout << "Markers selected: " << n << endl;
1609 cout << "Additional shift: " << shift_avg << endl;
1610 cout << "Residual: " << R << endl << endl;
1611 }
1612
1613 Bmicrograph* mg;
1614 Matrix3 tmat = mat.transpose();
1615
1616 t.trans += shift_avg;
1617 cout << "Reconstruction origin = " << rec2->origin << endl;
1618
1619 // Adjust the micrograph matrices and origins
1620 for ( mg = project->field->next->mg; mg; mg = mg->next ) {
1621 mg->matrix = mat * mg->matrix;
1622 tmat = mg->matrix.transpose();
1623 mg->origin -= tmat * t.trans;
1624 // cout << mg->id << tab << mg->origin << endl;
1625 mg->origin[2] = 0;
1626 }
1627
1628 return n;
1629 }
1630
1631
1641 double project_dual_zcompare (Bproject* project)
1642 {
1643 int n(0);
1644 double d, R(0);
1645 Breconstruction* rec1 = project->rec;
1646 Breconstruction* rec2 = project->rec->next;
1647 Bmarker* mark1 = NULL;
1648 Bmarker* mark2 = NULL;
1649
1650 cout << "Z Coordinates Compare" << endl << endl;
1651 cout << "Marker\tz1\tz2\tz1-z2" << endl;
1652 for ( mark1 = rec1->mark; mark1; mark1 = mark1->next ) if ( mark1->sel ) {
1653 for ( mark2 = rec2->mark; mark2 && mark2->id != mark1->id; mark2 = mark2->next ) ;
1654 if ( mark2 && mark2->sel ) {
1655 d = mark1->loc[2] - mark2->loc[2];
1656 R += d*d;
1657 n++;
1658 cout << mark1->id << tab << mark1->loc[2] << tab << mark2->loc[2] << tab << d << endl;
1659 }
1660 }
1661
1662 if ( n ) R = sqrt(R/n);
1663
1664 cout << "Z RMSD: " << R << " (" << n << ")" << endl << endl;
1665
1666 cout << "Origin1: " << rec1->origin[0] << " " << rec1->origin[1] << endl;
1667 cout << "Origin2: " << rec2->origin[0] << " " << rec2->origin[1] << endl;
1668 cout << "Marker\tx1\ty1\tz1\tMarker\tx2\ty2\tz2" << endl;
1669 for ( mark1 = rec1->mark; mark1; mark1 = mark1->next ) if ( mark1->sel ) {
1670 for ( mark2 = rec2->mark; mark2 && mark2->id != mark1->id; mark2 = mark2->next ) ;
1671 if ( mark2 && mark2->sel ) {
1672 cout << mark1->id << tab << mark1->loc[0] << tab << mark1->loc[1] << tab << mark1->loc[2] << tab <<
1673 mark2->id << tab << mark2->loc[0] << tab << mark2->loc[1] << tab << mark2->loc[2] << endl;
1674 }
1675 }
1676
1677 cout << endl;
1678
1679 return R;
1680 }
1681
marker_find_transform
Transform marker_find_transform(Bmarker *markers1, Bmarker *markers2, Vector3< double > origin)
Determines the rotation matrix between two sets of markers.
Definition: marker.cpp:346
write_project
int write_project(const char *filename, Bproject *project)
Writing micrograph parameters to a file.
Definition: rwmg.cpp:320
distance
double distance(vector< T1 > &v1, vector< T2 > &v2)
Definition: Vector3.h:536
qsort_functions.h
Header file for utility functions for use in qsort calls.
Matrix3::determinant
double determinant()
Definition: Matrix3.h:260
Bproject::rec
Breconstruction * rec
Definition: mg_processing.h:344
mg_refine_markers
int mg_refine_markers(Bmicrograph *mg, Bimage *pgold, double hi_res, double lo_res)
Refines marker positions in a tomographic micrograph.
Definition: mg_tomo_track.cpp:831
micrograph_get_size
Vector3< long > micrograph_get_size(Bmicrograph *mg)
Gets the size of a micrograph.
Definition: mg_img_proc.cpp:602
marker_show
int marker_show(Bmarker *m1, Bmarker *m2)
Definition: mg_tomo_track.cpp:37
Bimage.h
Header file for image class.
random_seed
long random_seed()
Gets a random seed and sets the flag.
Definition: random_numbers.cpp:41
Bfield::select
long select
Definition: mg_processing.h:262
vector3_xy_random_gaussian
Vector3< double > vector3_xy_random_gaussian(double avg, double std)
Generates a random vector within a random gaussian-distributed length in the xy plane.
Definition: random_numbers.cpp:522
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
Breconstruction::mark
Bmarker * mark
Definition: mg_processing.h:307
Bmicrograph::id
Bstring id
Definition: mg_processing.h:202
mg_marker_update
int mg_marker_update(Bmicrograph *mg, Bmarker *model, Vector3< double > oriref, int update_location)
Calculates the predicted positions of markers from the reference.
Definition: mg_tomography.cpp:59
Bmicrograph::img_num
int img_num
Definition: mg_processing.h:211
utilities.h
Header file for general utilities.
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
verbose
int verbose
Breconstruction
Definition: mg_processing.h:280
project_dual_zcompare
double project_dual_zcompare(Bproject *project)
Lists two sets of Z coordinates for comparison.
Definition: mg_tomo_track.cpp:1641
fom_from_distance
double fom_from_distance(double distance, double sigma)
Definition: mg_tomo_track.cpp:28
angle_set_negPI_to_PI
double angle_set_negPI_to_PI(double angle)
Returns an angle between -PI and PI.
Definition: utilities.cpp:594
planf
fft_plan planf
Definition: bico.cpp:24
project_transform_dual
int project_transform_dual(Bproject *project)
Calculates the transformation of the second tilt series to fit the first.
Definition: mg_tomo_track.cpp:1541
mg_img_proc.h
Header file for image processing from micrograph structures.
Transform::angle
double angle
Definition: Transform.h:29
kill_list
long kill_list(char *list, unsigned long size)
Frees all the items in a linked list.
Definition: linked_list.cpp:214
Bimage::within_boundaries
bool within_boundaries(Vector3< double > loc)
Definition: Bimage.h:448
Bmarker
Definition: marker.h:21
marker_transform
int marker_transform(Bmarker *markers, Transform t)
Transforming markers.
Definition: marker.cpp:226
Matrix3
Definition: Matrix3.h:17
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
length2
double length2(vector< T > v)
Definition: Vector3.h:517
Bimage::place
int place(long nn, Bimage *p, Vector3< double > loc, double radius=0, double scale=1, double shift=0, int operation=0)
Places a small image into a large image.
Definition: Bimage_combine.cpp:178
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
project_count_micrographs
long project_count_micrographs(Bproject *project)
Counts all the micrographs in the project structure.
Definition: mg_processing.cpp:746
Bfield::origin
Vector3< float > origin
Definition: mg_processing.h:260
Bmicrograph::tilt_angle
double tilt_angle
Definition: mg_processing.h:217
img_gold_particle
Bimage * img_gold_particle(Vector3< long > size, double radius)
Generates an image representing a gold particle.
Definition: mg_tomography.cpp:187
read_img
Bimage * read_img(char *filename, int readdata, int img_select)
General driver function to read multiple image formats.
Definition: rwimg.cpp:76
Bimage::correlate
double correlate(Bimage *p)
Calculates correlation coefficient between two images.
Definition: Bimage_correlate.cpp:36
Breconstruction::origin
Vector3< double > origin
Definition: mg_processing.h:293
marker_fom
double marker_fom(Bimage *p, Vector3< double > loc, double radius)
Definition: mg_tomo_track.cpp:1152
Bfield::next
Bfield * next
Definition: mg_processing.h:258
TSimple
Definition: Bimage.h:58
timer.h
Utilities for timing functions.
Float
Definition: utilities.h:157
project_refine_z
double project_refine_z(Bproject *project)
Refines the z coordinates of the marker model.
Definition: mg_tomo_track.cpp:948
Bmicrograph::matrix
Matrix3 matrix
Definition: mg_processing.h:222
Bimage
General image parameter class.
Definition: Bimage.h:163
project_transfer_seed
int project_transfer_seed(Bproject *project, double rot_start, double rot_end, double rot_step, double hi_res, double lo_res, double shift_limit)
Transfers the seed markers from the first to the second project.
Definition: mg_tomo_track.cpp:1418
Bmicrograph::tilt_axis
double tilt_axis
Definition: mg_processing.h:216
project_find_tilt_axis
double project_find_tilt_axis(Bproject *project, double tilt, double axis_start, double axis_end, double axis_step, double hi_res, double lo_res, double shift_limit)
Finds the tilt axis for a tomographic tilt series.
Definition: mg_tomo_track.cpp:153
Transform
Definition: Transform.h:24
Bfield
Definition: mg_processing.h:257
mg_marker_shift
double mg_marker_shift(Bmicrograph *mg, Bimage *pgold, double hi_res, double lo_res, double shift_limit, fft_plan planf, fft_plan planb)
Finds the shift of a micrograph wrt the reference using markers.
Definition: mg_tomo_track.cpp:1112
M_PI
#define M_PI
Definition: utilities.h:59
linked_list.h
Header file for generalized linked list functions.
QsortLargeToSmallDouble
int QsortLargeToSmallDouble(const void *x, const void *y)
Utility function for sorting double precision floating point values in qsort.
Definition: qsort_functions.cpp:59
mg_find_tilt_axis
double mg_find_tilt_axis(Bmicrograph *mgp, Bmicrograph *mgn, Bmicrograph *mg_ref, double axis_angle, Bimage *pgold, double hi_res, double lo_res, double shift_limit, fft_plan planf, fft_plan planb)
Definition: mg_tomo_track.cpp:89
project_refine_markers
int project_refine_markers(Bproject *project, double hi_res, double lo_res)
Refines marker positions in a tomographic series.
Definition: mg_tomo_track.cpp:683
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
mg_marker_z_search
int mg_marker_z_search(Bmicrograph *mg, Bmarker *model, Vector3< double > oriref, Bimage *pgold, double thickness, int cc_type, int iz, double *z)
Definition: mg_tomo_track.cpp:1236
Vector3::scalar
double scalar(const Vector3 &v) const
Definition: Vector3.h:247
Bimage::cross_correlate
Bimage * cross_correlate(Bimage *p, double hires, double lores, fft_plan planf, fft_plan planb)
Calculates a cross-correlation map by Fast Fourier transformation.
Definition: Bimage_correlate.cpp:363
img_marker_projection
Bimage * img_marker_projection(Vector3< long > size, Vector3< double > offset, double radius, Bimage *pmark, Bmarker *mark)
Generates a projection image of the global marker model.
Definition: mg_tomo_track.cpp:58
Bimage::statistics
long statistics()
Calculates the statistics for an image.
Definition: Bimage_stats.cpp:22
Bmicrograph::select
long select
Definition: mg_processing.h:203
Bmicrograph::mark_radius
double mark_radius
Definition: mg_processing.h:235
Bimage::sphere
int sphere(Vector3< double > center, double radius, double width=0, int fill_type=0, double fill=0)
Fills a sphere within an image with a uniform value.
Definition: Bimage_edit.cpp:438
Bproject::field
Bfield * field
Definition: mg_processing.h:343
matrix3_show_hp
int matrix3_show_hp(Matrix3 &mat)
Print out a matrix.
Definition: Matrix3.cpp:31
fft_plan
fftwf_plan fft_plan
Definition: fft.h:16
project_mg_tilt_to_matrix
int project_mg_tilt_to_matrix(Bproject *project)
Sets the matrix from the tilt and axis angles for each micrograph.
Definition: mg_tomography.cpp:1960
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
project_track_markers
int project_track_markers(Bproject *project, double hi_res, double lo_res, double shift_limit, double thickness, int max_cycle, double target, int cc_type, int recenter, Bstring paramfile)
Aligns markers in a tomographic series.
Definition: mg_tomo_track.cpp:313
Bmicrograph
Definition: mg_processing.h:200
Transform::scale
Vector3< double > scale
Definition: Transform.h:31
project_tomo_residuals
double project_tomo_residuals(Bproject *project, int show)
Calculates the residuals for an alignment solution.
Definition: mg_tomography.cpp:671
mg_tomography.h
Header file for single particle image processing in Bsoft.
Bmarker::fom
float fom
Definition: marker.h:28
Bmicrograph::origin
Vector3< double > origin
Definition: mg_processing.h:220
irm
double irm(1.0L/get_rand_max())
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
project_track_markers_dual
int project_track_markers_dual(Bproject *project, double hi_res, double lo_res, double shift_limit, double thickness, int max_cycle, double target, int cc_type, int recenter, Bstring paramfile)
Aligns markers in a tomographic series.
Definition: mg_tomo_track.cpp:489
mg_tomo_track.h
Functions to track fiducial markers in a tomographic series of images.
View::normalize
double normalize()
Definition: View.h:106
Transform::trans
Vector3< double > trans
Definition: Transform.h:30
FILL_USER
#define FILL_USER
Definition: utilities.h:172
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:127
Bmicrograph::mark
Bmarker * mark
Definition: mg_processing.h:242
Bmodel::next
Bmodel * next
Definition: rwmodel.h:120
get_rand_max
long get_rand_max()
Finds the maximum random number for a system.
Definition: random_numbers.cpp:22
Bmarker::next
Bmarker * next
Definition: marker.h:22
Bstring::post_rev
Bstring post_rev(char c)
Definition: Bstring.cpp:428
Bfield::mg
Bmicrograph * mg
Definition: mg_processing.h:264
model
Bmodel * model
Definition: bshow.cpp:32
Transform::origin
Vector3< double > origin
Definition: Transform.h:27
mg_tomo_residuals
double mg_tomo_residuals(Bmicrograph *mg, Bmarker *model, Vector3< double > oriref)
Calculates the residuals for an alignment solution of one micrograph.
Definition: mg_tomography.cpp:809
random_numbers.h
Header file for functions for creating random images.
Bfield::matrix
Matrix3 matrix
Definition: mg_processing.h:261
Bstring
Definition: Bstring.h:29
Bimage::sizeX
void sizeX(long nx)
Definition: Bimage.h:377
View::matrix
Matrix3 matrix()
Definition: View.h:150
beta
double beta(double volt)
Calculates the relative electron velocity.
Definition: ctf.cpp:447
Matrix3::transpose
Matrix3 transpose() const
Definition: Matrix3.h:268
project_refine_one_marker
int project_refine_one_marker(Bproject *project, int id, double hi_res, double lo_res)
Refines marker positions in a tomographic series.
Definition: mg_tomo_track.cpp:768
mg_marker_z_search_one
int mg_marker_z_search_one(Bmicrograph *mg, Bimage *p, Bmarker *modmark, Vector3< double > oriref, Bimage *pgold, double thickness, int cc_type, int i, double *z, fft_plan planf, fft_plan planb)
Definition: mg_tomo_track.cpp:1163
micrograph_copy
Bmicrograph * micrograph_copy(Bmicrograph *mg)
Copies a micrograph.
Definition: mg_processing.cpp:1529
markers_copy
Bmarker * markers_copy(Bmarker *mark)
Copies a set of markers.
Definition: marker.cpp:92
Bimage::sizeZ
void sizeZ(long nz)
Definition: Bimage.h:379
Vector3< double >
Bmicrograph::fmg
Bstring fmg
Definition: mg_processing.h:205
fft_destroy_plan
int fft_destroy_plan(fft_plan plan)
Deallocates a plan for fast Fourier transforms.
Definition: fft.cpp:87
View::angle
double angle()
Definition: View.h:95
View
Definition: View.h:26
Bmarker::err
Vector3< float > err
Definition: marker.h:26
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_find_low_tilt_mg_with_markers
Bmicrograph * field_find_low_tilt_mg_with_markers(Bfield *field)
Finds the micrograph closest to a zero degree tilt in a series with markers.
Definition: mg_processing.cpp:431
field_count_micrographs
long field_count_micrographs(Bfield *field)
Counts all the micrographs in the field-of-view structure.
Definition: mg_processing.cpp:1067
project_calculate_angles
int project_calculate_angles(Bproject *project)
Calculates tilt and tilt axis angles from matrices in a project parameter structure.
Definition: mg_tomography.cpp:1749
tomo_z_residual
double tomo_z_residual(Bproject *project, Bmarker *mark)
Definition: mg_tomo_track.cpp:908
Transform::axis
Vector3< double > axis
Definition: Transform.h:28
Bimage::density
double density(long nn, Vector3< double > coord, double radius, double &sigma)
Calculates the density in a sphere around a coordinate in an image.
Definition: Bimage.cpp:3010
mg_z_matrix_update
int mg_z_matrix_update(Bmarker *model, int nmg, int nmark, double *z, double *w, int recenter)
Definition: mg_tomo_track.cpp:1324
project_refine
double project_refine(Bproject *project, int iter, double tol, Bstring refop)
Refines all the alignment parameters.
Definition: mg_tomo_track.cpp:868
Bimage::fill
void fill(double v)
Definition: Bimage.h:698
Bstring::pre_rev
Bstring pre_rev(char c)
Definition: Bstring.cpp:413
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
Bimage::background
double background(long nn)
Definition: Bimage.h:542
Bimage::sizeY
void sizeY(long ny)
Definition: Bimage.h:378
Bmicrograph::scale
Vector3< double > scale
Definition: mg_processing.h:221
mg_location_from_3D_model
Vector3< double > mg_location_from_3D_model(Vector3< double > loc, Matrix3 mat, Vector3< double > ori)
Calculates the 2D location of a marker from a 3D model.
Definition: mg_tomography.cpp:139
Bmarker::res
float res
Definition: marker.h:27
Breconstruction::next
Breconstruction * next
Definition: mg_processing.h:281
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
mg_composite_particle
Bimage * mg_composite_particle(Bmicrograph *mg, Vector3< long > size)
Generates an average particle image from a micrograph.
Definition: mg_tomography.cpp:1240
Bimage::image
Bsub_image * image
Definition: Bimage.h:188
Bimage::origin
void origin(double ox, double oy, double oz)
Definition: Bimage.h:563
marker_refine
double marker_refine(Bmarker *mark, Bmarker *marklist, Bimage *p, Bimage *pgold, double radius, double hi_res, double lo_res)
Definition: mg_tomo_track.cpp:643
Bmicrograph::next
Bmicrograph * next
Definition: mg_processing.h:201