| Bsoft 2.0.5 Bernard's software package

bfcc.cpp
Go to the documentation of this file.
1
9 #include "rwimg.h"
10 #include "mg_processing.h"
11 #include "mg_particle_select.h"
12 #include "rwmg.h"
13 #include "linked_list.h"
14 #include "file_util.h"
15 #include "options.h"
16 #include "utilities.h"
17 #include "timer.h"
18
19
20 // Declaration of global variables
21 extern int verbose; // Level of output to the screen
22
23 // Function prototypes
24 double img_fcc_search(Bimage* p, Bimage* ptemp, View* view,
25 FSI_Kernel* kernel, double hires, double lores, Bimage* pmask);
26 double img_fcc_for_view(Bimage* p, Bimage* ptemp, View view,
27 FSI_Kernel* kernel, double hires, double lores, Bimage* pmask);
28 double img_cc_for_view(Bimage* p, Bimage* ptemp, View view,
29 FSI_Kernel* kernel, double hires, double lores, double searchrad,
30 Bimage* pmask);
31
32 // Usage assistance
33 const char* use[] = {
34 " ",
35 "Usage: bfcc [options] input.img/input.star output.img",
36 "-----------------------------------------------------",
37 "Fast cross-correlation for the best fit of a 3D map to a template.",
38 "Modes: Global: Search an asymmetric unit with a fixed angular step size.",
39 " Directional: Do a search around a view within an angular distance (-limit option).",
40 " Refine: Refine iteratively around a view to some accuracy (-accuracy option).",
41 " Symmetry: Search all symmetry-related views using a given view.",
42 "For modes other than global, the view is taken from the command line (-View option),",
43 " or from the parameter file, or as a last resort from the image header.",
44 "If a parameter file is used as input, the input image is selected based on ",
45 " the reconstruction ID and the particle image number.",
46 "Only one image in a multi-image file will be used (see -image option).",
47 "The output file contains the transformed map only if the input is an image (i.e., not a parameter file).",
48 "Output of the transformed map or template can be specified with the",
49 " -particle and -newtemplate options.",
50 " ",
51 "Actions:",
52 "-global Global search before other modes.",
53 "-mode refine Local modes: directional, refine or symmetric.",
54 " ",
55 "Parameters:",
56 "-verbose 7 Verbosity of output.",
57 "-datatype u Force writing of a new data type.",
58 "-sampling 1.5,1.5,1.5 Sampling (A/pixel; default from input file; a single value can be given).",
59 "-origin 110,50,44 Template image origin (default taken from template file).",
60 "-partorigin 50,80,47 Particle image origin (default taken from particle file).",
61 "-kernel 6,2 Kernel for reciprocal space interpolation: size and power.",
62 "-resolution 15.6,200 Resolution limits for cross-correlation (default 0).",
63 "-shiftlimit 5.2 Radial limit to search for shift in cross-correlation map (default 1/4 of map).",
64 " ",
65 "Selections:",
66 "-setsequential Set particle selection numbers sequentially.",
67 "-recid A435 The 3D reconstruction ID (should correspond to that in the parameter file).",
68 "-image 2 Image number in a multi-image file or particle number (default 1=first image).",
69 "-select 5 Particle selection number in parameter file (default not used).",
70 " ",
71 "View parameters:",
72 "-angles 8.8,2.5,5.2 Step size for alpha, theta and phi, one value sets all (default 45 degrees).",
73 "-side 15 Generate side view projections within the given angle from the equator.",
74 " ",
75 "Parameters for the global and symmetric modes:",
76 "-symmetry D6 Symmetry: Point group identifier.",
77 " ",
78 "Parameters for the directional and refinement modes:",
79 "-View 0.3,-0.5,0.8,33 View to initiate search: vector {xyz} and angle.",
80 " ",
81 "Parameters for the directional mode:",
82 "-limit 17.5 Radial limit around given view (default 20 degrees).",
83 " ",
84 "Parameters for the refinement mode:",
85 "-accuracy 0.3 Accuracy (default 0.5 degrees).",
86 " ",
87 "Input:",
88 "-Template image.map Template to search for.",
89 "-Mask mask.tif Mask in reciprocal space to apply during cross-correlation.",
90 " ",
91 "Output:",
92 //"-Postscript plot.ps Output postscript file with a plot of global view vectors.",
93 "-output file.star Parameter output file with best orientation.",
94 "-particle newpart.pif New transformed particle file.",
95 "-newtemplate newtemp.pif New transformed template file.",
96 " ",
97 NULL
98 };
99
100 int main(int argc, char **argv)
101 {
102 // Initialize variables
103 int global(0); // Flag for global search
104 Bstring mode; // Mode: directional, refine or symmetric
105 DataType nudatatype(Unknown_Type); // Conversion to new type
106 Bstring rec_id; // Reconstruction ID
107 int img_num(1); // Image number in file
108 int sel_num(-1); // Selection number in parameter file
109 int set_seq_sel(0); // Flag to set selection number sequentially
110 Vector3<double> sam; // Units for the three axes (A/pixel)
111 Vector3<double> origin; // Template origin
112 Vector3<double> part_ori; // Particle origin
113 int set_origin(0); // Flag to set origin
114 int kernel_width(6); // Reciprocal space kernel width
115 int kernel_power(2); // Reciprocal space kernel power
116 double alpha_step(M_PI_4); // Angular step size for alpha
117 double theta_step(M_PI_4); // Angular step size for theta
118 double phi_step(M_PI_4); // Angular step size for phi
119 double side_ang(-1); // Side view variation angle
120 double angle_limit(M_PI/9.0); // Angular limit for directional search
121 Bsymmetry* sym = NULL; // Default: asymmetric or C1 point group
122 double hires(0), lores(0); // Limiting resolution for cross-correlation
123 double search_radius(-1); // Use default search radius
124 int currview_set(0); // Flag to indicate current view is set
125 View currview; // View to initiate search from and use as current view
126 View bestview; // Eventually the best view
127 View ref_view; // Reference view
128 double accuracy(M_PI/360.0); // Accuracy for refinement default = 0.5 degrees
129 Bstring template_file; // Reference template file name
130 Bstring mask_file; // Reciprocal space mask file name
131 Bstring ps_file; // Postscript output file name
132 Bstring param_file; // Parameter file name
133 Bstring newpart_file; // Transformed particle output file name
134 Bstring newtemp_file; // Transformed template output file name
135
136 int i, optind;
137 Boption* option = get_option_list(use, argc, argv, optind);
138 Boption* curropt;
139 for ( curropt = option; curropt; curropt = curropt->next ) {
140 if ( curropt->tag == "global" ) global = 1;
141 if ( curropt->tag == "mode" ) {
142 if ( curropt->value.length() > 0 ) {
143 if ( curropt->value[0] == 'd' || curropt->value[0] == 'D' ) mode = "directional";
144 if ( curropt->value[0] == 'r' || curropt->value[0] == 'R' ) mode = "refine";
145 if ( curropt->value[0] == 's' || curropt->value[0] == 'S' ) mode = "symmetric";
146 } else
147 cerr << "-mode: A mode must be specified" << endl;
148 }
149 if ( curropt->tag == "setsequential" ) set_seq_sel = 1;
150 if ( curropt->tag == "image" )
151 if ( ( img_num = curropt->value.integer() ) < 1 )
152 cerr << "-image: An image number must be specified" << endl;
153 if ( curropt->tag == "select" )
154 if ( ( sel_num = curropt->value.integer() ) < 0 )
155 cerr << "-select: A selection number must be specified" << endl;
156 if ( curropt->tag == "datatype" )
157 nudatatype = curropt->datatype();
158 if ( curropt->tag == "sampling" )
159 sam = curropt->sampling();
160 if ( curropt->tag == "origin" ) {
161 if ( curropt->value[0] == 'c' ) {
162 set_origin = 2;
163 } else {
164 origin = curropt->origin();
165 set_origin = 1;
166 }
167 }
168 if ( curropt->tag == "partorigin" )
169 part_ori = curropt->origin();
170 if ( curropt->tag == "kernel" )
171 if ( curropt->values(kernel_width, kernel_power) < 1 )
172 cerr << "-kernel: At least the kernel size must be specified!" << endl;
173 if ( curropt->tag == "angles" ) {
174 if ( ( i = curropt->values(alpha_step, theta_step, phi_step) ) < 1 )
175 cerr << "-angles: An angle step size must be specified" << endl;
176 else {
177 if ( i < 2 ) phi_step = theta_step = alpha_step;
178 else if ( i < 3 ) phi_step = theta_step;
179 alpha_step *= M_PI/180.0;
180 theta_step *= M_PI/180.0;
181 phi_step *= M_PI/180.0;
182 }
183 }
184 if ( curropt->tag == "side" ) {
185 if ( ( side_ang = curropt->value.real() ) < 0.1 )
186 cerr << "-side: One angle must be specified!" << endl;
187 else
188 side_ang *= M_PI/180.0;
189 }
190 if ( curropt->tag == "limit" ) {
191 if ( ( angle_limit = curropt->value.real() ) < 0.1 )
192 cerr << "-limit: An angular limit must be specified!" << endl;
193 else
194 angle_limit *= M_PI/180.0;
195 }
196 if ( curropt->tag == "View" ) {
197 currview = curropt->view();
198 currview_set = 1;
199 }
200 if ( curropt->tag == "resolution" )
201 if ( curropt->values(hires, lores) < 1 )
202 cerr << "-resolution: A resolution must be specified!" << endl;
203 if ( curropt->tag == "shiftlimit" )
204 if ( ( search_radius = curropt->value.real() ) < 1 )
205 cerr << "-shiftlimit: A shift search radius must be specified!" << endl;
206 if ( curropt->tag == "symmetry" )
207 sym = curropt->symmetry();
208 if ( curropt->tag == "accuracy" ) {
209 if ( ( accuracy = curropt->value.real() ) < 0.1 )
210 cerr << "-accuracy: An accuracy in degrees must be specified!" << endl;
211 else
212 accuracy *= M_PI/180.0;
213 }
214 if ( curropt->tag == "recid" )
215 rec_id = curropt->value;
216 if ( curropt->tag == "Template" )
217 template_file = curropt->filename();
218 if ( curropt->tag == "Mask" )
219 mask_file = curropt->filename();
220 if ( curropt->tag == "Postscript" )
221 ps_file = curropt->filename();
222 if ( curropt->tag == "output" )
223 param_file = curropt->filename();
224 if ( curropt->tag == "particle" )
225 newpart_file = curropt->filename();
226 if ( curropt->tag == "newtemplate" )
227 newtemp_file = curropt->filename();
228 }
229 option_kill(option);
230
231 double ti = timer_start();
232
233 int read_img_num = img_num - 1;
234 int cnt(1), found;
235 Bimage* p = NULL;
236 Bimage* ptemp = NULL;
237 Bimage* pmask = NULL;
238 Bstring filename;
239 Vector3<double> scale(1,1,1);
240 Vector3<long> size;
241 Bproject* project = NULL;
242 Breconstruction* rec = NULL;
243 Bparticle* part = NULL;
244
245 // if ( hires > lores ) swap(hires, lores);
246
247 if ( kernel_width < 4 ) kernel_width = 4;
248 if ( kernel_power < 2 ) kernel_power = 2;
249 FSI_Kernel* kernel = new FSI_Kernel(kernel_width, kernel_power);
250
251 // Read image file
252 if ( optind < argc ) {
253 filename = argv[optind++];
254 if ( file_type(filename) == Micrograph ) {
255 project = read_project(filename);
256 part_set_FOM(project, 0, 0);
257 if ( set_seq_sel )
258 for ( rec = project->rec; rec; rec = rec->next )
259 for ( part = rec->part; part; part = part->next ) part->sel = cnt++;
260 rec = project->rec;
261 if ( sel_num > 0 ) { // Finds the first particle with this selection number
262 for ( found=0, rec = project->rec; rec && !found; ) {
263 for ( part = rec->part; part && !found; ) {
264 if ( part->sel == sel_num ) found = 1;
265 else part = part->next;
266 }
267 if ( !found ) rec = rec->next;
268 }
269 } else { // Finds the specified particle and image number
270 if ( rec_id.length() )
271 for ( rec = project->rec; rec && rec_id != rec->id; rec = rec->next ) ;
272 if ( rec ) {
273 for ( part = rec->part; part && part->id != img_num; part = part->next ) ;
274 } else {
275 cerr << "Error: No reconstruction with ID = " << rec_id << endl;
276 bexit(-1);
277 }
278 }
279 if ( rec ) {
280 filename = rec->frec;
281 if ( rec->fpart.length() ) filename = rec->fpart;
282 if ( part ) {
283 img_num = part->id;
284 read_img_num = part->id - 1;
285 if ( !currview_set ) {
286 currview = part->view;
287 currview_set = 1;
288 }
289 // cout << "part->ori=" << part->ori << endl;
290 if ( part_ori.length() < 1 && part->ori.length() ) part_ori = part->ori;
291 if ( part->fpart.length() ) {
292 filename = part->fpart;
293 read_img_num = 0;
294 }
295 } else {
296 cerr << "Error: Particle not defined!" << endl;
297 bexit(-1);
298 }
299 if ( !currview_set ) {
300 currview = rec->view;
301 currview_set = 1;
302 }
303 } else {
304 cerr << "Error: Reconstruction not defined!" << endl;
305 bexit(-1);
306 }
307 }
308 if ( filename.length() < 1 ) {
309 cerr << "Error: No image file name found!" << endl;
310 bexit (-1);
311 }
312 }
313
314 // cout << "part_ori=" << part_ori << endl;
315
316 if ( filename.length() < 1 ) {
317 cerr << "Error: No image file name specified!" << endl;
318 } else {
319 p = read_img(filename, 1, read_img_num);
320 if ( p ) {
321 if ( sam.volume() > 0 ) p->sampling(sam);
322 if ( part_ori.length() ) p->origin(part_ori);
323 else part_ori = p->image->origin();
324 } else {
325 cerr << "Error: %s not read!" << filename << endl;
326 }
327 }
328
329 if ( template_file.length() < 1 ) {
330 cerr << "Error: No input template file specified!" << endl;
331 } else {
332 ptemp = read_img(template_file, 1, 0);
333 if ( ptemp ) {
334 if ( sam.volume() > 0 ) ptemp->sampling(sam);
335 if ( set_origin ) {
336 if ( set_origin == 2 ) ptemp->origin(ptemp->size()/2);
337 else ptemp->origin(origin);
338 } else origin = ptemp->image->origin();
339 } else {
340 cerr << "Error: " << template_file << " not read!" << endl;
341 }
342 }
343
344 if ( mask_file.length() ) {
345 pmask = read_img(mask_file, 1, -1);
346 if ( !pmask ) {
347 cerr << "Error: " << mask_file << " not read!" << endl;
348 }
349 }
350
351 if ( search_radius < 1 ) search_radius = ptemp->sizeX()/4;
352
353 p->image->origin(origin);
354
355 if ( verbose ) {
356 cout << "Finding a template in a map:" << endl;
357 cout << "Template: " << ptemp->file_name() << endl;
358 cout << "Map: " << p->file_name() << " (" << read_img_num << ")" << endl;
359 if ( pmask ) cout << "Mask: " << pmask->file_name() << endl;
360 cout << "Template origin: " << ptemp->image->origin() << endl;
361 cout << "Map origin: " << p->image->origin() << endl;
362 cout << "Resolution range: ";
363 if ( lores <= 0 ) cout << "inf";
364 else cout << lores;
365 cout << " - " << hires << " A" << endl;
366 cout << "Shift search radius: " << search_radius << " pixels" << endl;
367 cout << "Kernel width and power: " << kernel_width << " " << kernel_power << endl << endl;
368 cout << "Angle\tShift\t\t\tView\t\t\t\tCC" << endl;
369 }
370
371
372 Bimage* pc = p->pack_two_in_complex(ptemp);
373 if ( !pc ) bexit(-1);
374
375 delete p;
376 delete ptemp;
377
378 // cout << "Doing forward transform" << endl;
379 pc->fft(FFTW_FORWARD, 0);
380
381 // cout << "Unpacking transform" << endl;
382 ptemp = pc->unpack_combined_transform();
383 p = pc;
384
385 // cout << "Phase shifting" << endl;
386 p->origin(origin);
387 ptemp->origin(origin);
388 p->phase_shift_to_origin();
389 ptemp->phase_shift_to_origin();
390
391 View* view = NULL, *view2 = NULL;
392 Vector3<double> currshift, bestshift;
393 double cc, best_cc = -1e37;
394
395 Matrix3 mat = ref_view.matrix();
396 if ( !sym ) sym = init_point_group_symmetry("C1");
397 for ( i=0; i<sym->n; i++ )
398 sym->op[i].axis = mat * sym->op[i].axis;
399
400 bestview = currview;
401
402 if ( global || !currview_set ) {
403 // cout << "Doing global" << endl;
404
405 if ( side_ang < 0 )
406 view = asymmetric_unit_views(sym, theta_step, phi_step, 1);
407 else
408 view = side_views(sym, side_ang, theta_step, phi_step);
409 view2 = view_list_expand_angles(view, -M_PI, M_PI - alpha_step/2, alpha_step);
410 kill_list((char *) view, sizeof(View));
411 view = view2;
412
413 if ( verbose & VERB_FULL )
414 show_views(view);
415
416 // if ( ps_file.length() && view ) ps_views(ps_file, symmetry_string, view, 0);
417
418 // if ( verbose )
419 // cout << "Number of global views: " << count_list((char *) view) << endl << endl;
420
421 best_cc = img_fcc_search(p, ptemp, view, kernel, hires, lores, pmask);
422 bestview = p->image->view();
423
424 best_cc = img_cc_for_view(p, ptemp, bestview, kernel, hires, lores,
425 search_radius, pmask);
426 bestshift = ptemp->image->origin() - p->image->origin();
427 p->phase_shift(bestshift);
428
429 if ( verbose )
430 cout << alpha_step*180.0/M_PI << tab << bestshift << tab << bestview << tab << best_cc << endl;
431
432 kill_list((char *) view, sizeof(View));
433 view = NULL;
434 }
435
436 if ( mode == "directional" ) {
437 view = views_within_limits(bestview, theta_step, phi_step, alpha_step, angle_limit, M_PI);
438 if ( verbose ) {
439 cout << "Central view: " << bestview << endl;
440 cout << "Number of directional views: " << count_list((char *) view) << endl << endl;
441 }
442 } else if ( mode == "symmetric" ) {
443 view = symmetry_get_all_views(sym, bestview);
444 if ( verbose )
445 cout << "Number of symmetry views: " << count_list((char *) view) << endl << endl;
446 }
447
448 kill_symmetry(sym);
449
450 if ( mode.length() ) {
451 if ( mode == "directional" || mode == "symmetric" ) {
452 best_cc = img_fcc_search(p, ptemp, view, kernel, hires, lores, pmask);
453 bestview = p->image->view();
454
455 kill_list((char *) view, sizeof(View));
456 } else if ( mode == "refine" ) {
457 currview = bestview;
458 best_cc = -1;
459 while ( alpha_step >= accuracy ) {
460 view = views_for_refinement(bestview, alpha_step);
461 cc = img_fcc_search(p, ptemp, view, kernel, hires, lores, pmask);
462 currview = p->image->view();
463 if ( currview.residual(bestview) < 1e-6 ) alpha_step /= 2; // Contract around best point
464 if ( best_cc < cc ) {
465 best_cc = cc;
466 bestview = currview;
467 // bestshift = currshift;
468 }
469
470 if ( verbose )
471 cout << alpha_step*180.0/M_PI << tab << bestshift << tab << bestview << tab << best_cc << endl;
472
473 kill_list((char *) view, sizeof(View));
474 }
475 }
476
477 best_cc = img_cc_for_view(p, ptemp, bestview, kernel, hires, lores,
478 search_radius, pmask);
479 bestshift += ptemp->image->origin() - p->image->origin();
480 }
481
482 if ( verbose )
483 cout << "Best view:\t" << setprecision(4) <<
484 bestshift[0] << tab << bestshift[1] << tab << bestshift[2] << tab <<
485 bestview[0] << tab << bestview[1] << tab << bestview[2] << tab <<
486 bestview.angle()*180/M_PI << tab << best_cc << endl;
487
488 delete p;
489 delete pmask;
490 delete ptemp;
491 delete kernel;
492
493 if ( newpart_file.length() < 1 && optind < argc ) newpart_file = argv[optind];
494
495 if ( newtemp_file.length() ) { // Output transformed template
496 ptemp = read_img(template_file, 1, 0);
497 // size = ptemp->size();
498 mat = bestview.matrix();
499 mat = mat.transpose();
500 ptemp->calculate_background();
501 ptemp->transform(scale, origin, -bestshift, mat, FILL_BACKGROUND, 0);
502 ptemp->view(bestview);
503 if ( nudatatype == Unknown_Type ) nudatatype = p->data_type(); // Preserve the old type
504 ptemp->change_type(nudatatype);
505 ptemp->label(get_cmd_line(argc, argv));
506 write_img(newtemp_file, ptemp, 0);
507 delete ptemp;
508 }
509
510 if ( newpart_file.length() ) { // Output transformed image
511 p = read_img(filename, 1, read_img_num);
512 // size = p->size();
513 mat = bestview.matrix();
514 // origin += bestshift; // Origin for rotation
515 p->calculate_background();
516 p->transform(scale, origin-bestshift, bestshift, mat, FILL_BACKGROUND, 0);
517 p->image->view(0,0,1,0);
518 if ( nudatatype == Unknown_Type ) nudatatype = p->data_type(); // Preserve the old type
519 p->change_type(nudatatype);
520 p->label(get_cmd_line(argc, argv));
521 write_img(newpart_file, p, 0);
522 delete p;
523 }
524
525 if ( param_file.length() ) {
526 p = read_img(filename, 0, 0);
527 if ( !project ) {
528 project = project_init();
529 if ( rec_id.length() < 1 ) {
530 rec_id = p->file_name();
531 rec_id = rec_id.pre_rev('.');
532 }
533 rec = reconstruction_add(&project->rec, rec_id);
534 part = particle_add(&rec->part, img_num);
535 }
536 if ( sam[0] > 0 ) rec->voxel_size = sam[0];
537 else rec->voxel_size = p->sampling()[0];
538 rec->symmetry = sym->label;
539 if ( part ) {
540 part->fpart = filename;
541 if ( newpart_file.length() ) {
542 part->fpart = newpart_file;
543 part->ori = origin;
544 } else {
545 part->view = bestview;
546 part->ori = origin - bestshift;
547 }
548 for ( part = rec->part; part; part = part->next )
549 if ( part->id == img_num ) part->fom[0] = best_cc;
550 else part->fom[0] = 0;
551 } else {
552 rec->frec = filename;
553 if ( newpart_file.length() ) {
554 rec->frec = newpart_file;
555 rec->origin = origin;
556 } else {
557 rec->view = bestview;
558 rec->origin = origin - bestshift;
559 }
560 for ( rec = project->rec; rec; rec = rec->next )
561 if ( rec->id == rec_id ) rec->fom = best_cc;
562 else rec->fom = 0;
563 }
564 project_update_comment(project, argc, argv);
565 write_project(param_file, project, 0, 0);
566 delete p;
567 }
568
569 project_kill(project);
570
571 if ( verbose & VERB_TIME )
572 timer_report(ti);
573
574 bexit(0);
575 }
576
594 double img_fcc_search(Bimage* p, Bimage* ptemp, View* view,
595 FSI_Kernel* kernel, double hires, double lores, Bimage* pmask)
596 {
597 if ( !p ) return -1e37;
598
599 long n, nviews, ibest;
600 double best(-1e37);
601
602 View* view_arr = view_array(view, nviews);
603
604 double* cc = new double[nviews];
605
606 if ( verbose & VERB_PROCESS )
607 cout << "Number of views: " << nviews << endl;
608
609 #ifdef HAVE_GCD
610 dispatch_apply(nviews, dispatch_get_global_queue(0, 0), ^(size_t k){
611 cc[k] = img_fcc_for_view(p, ptemp, view_arr[k], kernel, hires, lores, pmask);
612 });
613 #else
614 #pragma omp parallel for
615 for ( n=0; n<nviews; n++ )
616 cc[n] = img_fcc_for_view(p, ptemp, view_arr[n], kernel, hires, lores, pmask);
617 #endif
618
619 double ccmin(1), ccmax(-1), ccavg(0), ccstd(0);
620
621 for ( n=ibest=0; n<nviews; n++ ) {
622 if ( best < cc[n] ) {
623 best = cc[n];
624 ibest = n;
625 }
626 if ( ccmin > cc[n] ) ccmin = cc[n];
627 if ( ccmax < cc[n] ) ccmax = cc[n];
628 ccavg += cc[n];
629 ccstd += cc[n]*cc[n];
630 }
631
632 ccavg /= n;
633 ccstd = ccstd/n - ccavg*ccavg;
634 if ( ccstd > 0 ) ccstd = sqrt(ccstd);
635 else ccstd = 0;
636
637 if ( verbose & VERB_PROCESS )
638 cout << "Min, max, avg, std: " << ccmin << " " << ccmax << " " << ccavg << " " << ccstd << endl;
639
640 p->view(view_arr[ibest]);
641 p->image->FOM(best);
642
643 delete[] view_arr;
644 delete[] cc;
645
646 return best;
647 }
648
649 /*
650 @brief Searches a 2D/3D density map for a template using a specific view.
651 @param *p the Fourier transformed image.
652 @param *ptemp the Fourier transformed template to be searched for.
653 @param view view.
654 @param *cc interpolation kernel.
655 @param hires high resolution limit.
656 @param lores low resolution limit.
657 @param *pmask mask for cross-correlation (ignored if NULL).
658 @return double correlation coefficient.
659
660 The template is rotated to the view and cross-correlated to find
661 a set of high-scoring fits.
662 The views must be calculated externally to allow for custom sets.
663 **/
664 double img_fcc_for_view(Bimage* p, Bimage* ptemp, View view,
665 FSI_Kernel* kernel, double hires, double lores, Bimage* pmask)
666 {
667 Matrix3 mat = view.matrix();
668 // mat = mat.transpose();
669
670 long i, n(0);
671 double minrad = (lores>0)? ptemp->real_size()[0]/lores: 0;
672 double maxrad = (hires>0)? ptemp->real_size()[0]/hires: ptemp->sizeX()/2;
673 if ( maxrad > ptemp->sizeX()/2 ) maxrad = ptemp->sizeX()/2;
674
675 // cout << "minrad=" << minrad << " maxrad=" << maxrad << endl;
676
677 Complex<double> v1, v2, cv;
678 Vector3<double> c, cr;
679 Vector3<long> min = Vector3<int>((int) (-maxrad - 0.5), (int) (-maxrad - 0.5), (int) (-maxrad - 0.5));
680 Vector3<long> max = Vector3<int>((int) (maxrad + 0.5), (int) (maxrad + 0.5), (int) (maxrad + 0.5));
681 Vector3<long> ci;
682 double d, pwr1(0), pwr2(0), cc(0);
683
684 // cout << "min=" << min << " max=" << max << endl;
685
686 for ( c[2]=min[2]; c[2]<=max[2]; c[2]+=1 ) {
687 for ( c[1]=min[1]; c[1]<=max[1]; c[1]+=1 ) {
688 for ( c[0]=min[0]; c[0]<=max[0]; c[0]+=1 ) {
689 d = c.length();
690 if ( d >= minrad && d <= maxrad ) {
691 ci = c;
692 if ( ci[0] < 0 ) ci[0] += p->sizeX();
693 if ( ci[1] < 0 ) ci[1] += p->sizeY();
694 if ( ci[2] < 0 ) ci[2] += p->sizeZ();
695 i = (ci[2]*p->sizeY() + ci[1])*p->sizeX() + ci[0];
696 if ( !pmask || ( pmask && (*pmask)[i] ) ) {
697 v1 = p->complex(i);
698 cr = mat * c;
699 v2 = ptemp->fspace_interpolate(0, cr, kernel);
700 pwr1 += v1.power();
701 pwr2 += v2.power();
702 cv += v1*v2.conj();
703 n++;
704 }
705 }
706 }
707 }
708 }
709
710 d = pwr1*pwr2;
711 if ( d > 0 ) cc = cv.amp()/sqrt(d);
712
713 if ( verbose & VERB_FULL )
714 cout << view << tab << n << tab << cc << endl;
715
716 return cc;
717 }
718
719 /*
720 @brief Searches a 2D/3D density map for a template using a specific view.
721 @param *p the Fourier transformed image.
722 @param *ptemp the Fourier transformed template to be searched for.
723 @param view view.
724 @param *cc interpolation kernel.
725 @param hires high resolution limit.
726 @param lores low resolution limit.
727 @param searchrad correlation map search radius.
728 @param *pmask mask for cross-correlation (ignored if NULL).
729 @return double correlation coeficient.
730
731 The template is rotated to the view and cross-correlated to find
732 a set of high-scoring fits.
733 The views must be calculated externally to allow for custom sets.
734 The shift is encoded in the image origin.
735 **/
736 double img_cc_for_view(Bimage* p, Bimage* ptemp, View view,
737 FSI_Kernel* kernel, double hires, double lores, double searchrad,
738 Bimage* pmask)
739 {
740 Matrix3 mat = view.matrix();
741 // mat = mat.transpose();
742
743 long i;
744 double minrad = (lores>0)? ptemp->real_size()[0]/lores: 0;
745 double maxrad = ptemp->real_size()[0]/hires;
746 if ( maxrad > ptemp->sizeX()/2 ) maxrad = ptemp->sizeX()/2;
747
748 Complex<double> v1, v2;
749 Vector3<double> c, cr;
750 Vector3<long> min = Vector3<int>((int) (-maxrad - 0.5), (int) (-maxrad - 0.5), (int) (-maxrad - 0.5));
751 Vector3<long> max = Vector3<int>((int) (maxrad + 0.5), (int) (maxrad + 0.5), (int) (maxrad + 0.5));
752 Vector3<long> ci;
753 double d, pwr1(0), pwr2(0);
754
755 Bimage* pcc = new Bimage(Float, TComplex, ptemp->sizeX(),
756 ptemp->sizeY(), ptemp->sizeZ(), 1);
757
758 for ( c[2]=min[2]; c[2]<=max[2]; c[2]+=1 ) {
759 for ( c[1]=min[1]; c[1]<=max[1]; c[1]+=1 ) {
760 for ( c[0]=min[0]; c[0]<=max[0]; c[0]+=1 ) {
761 d = c.length();
762 if ( d >= minrad && d <= maxrad ) {
763 ci = c;
764 if ( ci[0] < 0 ) ci[0] += p->sizeX();
765 if ( ci[1] < 0 ) ci[1] += p->sizeY();
766 if ( ci[2] < 0 ) ci[2] += p->sizeZ();
767 i = (ci[2]*p->sizeY() + ci[1])*p->sizeX() + ci[0];
768 if ( !pmask || ( pmask && (*pmask)[i] ) ) {
769 v1 = p->complex(i);
770 cr = mat * c;
771 v2 = ptemp->fspace_interpolate(0, cr, kernel);
772 pwr1 += v1.power();
773 pwr2 += v2.power();
774 pcc->set(i, v1*v2.conj());
775 }
776 }
777 }
778 }
779 }
780
781 double scale = 1/sqrt(pwr1*pwr2);
782
783 for ( i=0; i<pcc->data_size(); i++ ) pcc->set(i, (*pcc)[i] * scale);
784
785 pcc->fft(FFTW_BACKWARD, 0);
786
787 pcc->complex_to_real();
788
789 pcc->find_peak(searchrad, 0);
790 double cc = pcc->image->FOM();
791
792 pcc->refine_peak();
793
794 // shift = mat * shift;
795
796 if ( verbose & VERB_FULL )
797 cout << view << tab << pcc->image->origin() << tab << cc << endl;
798
799 p->origin(ptemp->image->origin() + pcc->image->origin());
800
801 delete pcc;
802
803 return cc;
804 }
805
806
807
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1743
write_project
int write_project(const char *filename, Bproject *project)
Writing micrograph parameters to a file.
Definition: rwmg.cpp:320
Bparticle::id
int id
Definition: mg_processing.h:92
rwmg.h
Header file for reading and writing micrograph parameters.
Bimage::phase_shift
int phase_shift(Vector3< double > shift)
Phase shifts a complex image.
Definition: Bimage_complex.cpp:256
Bimage::refine_peak
int refine_peak()
Refines the position of a peak to sub-voxel resolution.
Definition: Bimage_correlate.cpp:1556
Bstring::real
double real()
Definition: Bstring.cpp:545
Bimage::unpack_combined_transform
Bimage * unpack_combined_transform()
Unpacks a complex transform obtained from two real images.
Definition: Bimage_complex.cpp:749
Bproject::rec
Breconstruction * rec
Definition: mg_processing.h:344
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
views_within_limits
View * views_within_limits(View theview, double theta_step, double phi_step, double alpha_step, double view_angle_limit, double alpha_angle_limit)
Generates a list of views within an angular distance from the input view.
Definition: View.cpp:207
DataType
DataType
Base data type specifier.
Definition: utilities.h:146
Bparticle::view
View view
Definition: mg_processing.h:101
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
Vector3::length
double length()
Definition: Vector3.h:222
Breconstruction::part
Bparticle * part
Definition: mg_processing.h:304
Bsymmetry::n
int n
Definition: symmetry.h:42
img_fcc_for_view
double img_fcc_for_view(Bimage *p, Bimage *ptemp, View view, FSI_Kernel *kernel, double hires, double lores, Bimage *pmask)
Definition: bfcc.cpp:664
Breconstruction::fpart
Bstring fpart
Definition: mg_processing.h:288
img_cc_for_view
double img_cc_for_view(Bimage *p, Bimage *ptemp, View view, FSI_Kernel *kernel, double hires, double lores, double searchrad, Bimage *pmask)
Definition: bfcc.cpp:736
mg_particle_select.h
Select particles.
show_views
int show_views(View *v)
Displays a linked list of views.
Definition: View.cpp:28
views_for_refinement
View * views_for_refinement(View theview, double alpha_step)
Generates a 3x3 grid of views around an input view.
Definition: View.cpp:285
Bimage::fft
int fft()
Definition: Bimage.h:822
utilities.h
Header file for general utilities.
Breconstruction::fom
double fom
Definition: mg_processing.h:302
Boption::sampling
Vector3< double > sampling()
Definition: options.h:202
Boption::value
Bstring value
Definition: options.h:30
img_fcc_search
double img_fcc_search(Bimage *p, Bimage *ptemp, View *view, FSI_Kernel *kernel, double hires, double lores, Bimage *pmask)
Fast cross-correlation searches a 2D/3D density map for a template.
Definition: bfcc.cpp:594
Breconstruction
Definition: mg_processing.h:280
Boption::tag
Bstring tag
Definition: options.h:29
Bimage::fspace_interpolate
Complex< double > fspace_interpolate(long img_num, Vector3< double > m, FSI_Kernel *kernel)
Calculates the complex value at an image location by kernel-based interpolation.
Definition: Bimage_fspace.cpp:88
kill_list
long kill_list(char *list, unsigned long size)
Frees all the items in a linked list.
Definition: linked_list.cpp:214
file_type
FileType file_type(const char *filename)
Checks the file type using the extension and contents.
Definition: file_util.cpp:178
Bparticle::fom
double fom[NFOM]
Definition: mg_processing.h:102
read_project
Bproject * read_project(const char *filename, int flags=0)
Reading micrograph parameters from files.
Definition: rwmg.cpp:140
Matrix3
Definition: Matrix3.h:17
Complex::conj
Complex conj()
Definition: Complex.h:106
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
project
Bproject * project
Definition: bshow.cpp:31
count_list
long count_list(char *list)
Counts the number of items in a linked list.
Definition: linked_list.cpp:235
Bimage::complex
Complex< double > complex(long j)
Returns a complex value at the given index.
Definition: Bimage.cpp:1005
kill_symmetry
int kill_symmetry(Bsymmetry *sym)
Deallocates a symmetry structure.
Definition: symmetry.cpp:207
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
FSI_Kernel
Definition: FSI_Kernel.h:14
Bimage::file_name
void file_name(string s)
Definition: Bimage.h:230
TComplex
Definition: Bimage.h:59
get_option_list
Boption * get_option_list(const char *use[], int argc, char *argv[], int &optind)
Parses command line arguments based on a template.
Definition: options.cpp:40
read_img
Bimage * read_img(char *filename, int readdata, int img_select)
General driver function to read multiple image formats.
Definition: rwimg.cpp:76
Breconstruction::origin
Vector3< double > origin
Definition: mg_processing.h:293
get_cmd_line
string get_cmd_line(int argc, char **argv)
Returns the command line as a string.
Definition: utilities.cpp:36
Boption::filename
Bstring filename()
Definition: options.h:85
project_init
Bproject * project_init()
Initializes a micrograph processing project parameter structure.
Definition: mg_processing.cpp:29
timer.h
Utilities for timing functions.
Float
Definition: utilities.h:157
M_PI_4
#define M_PI_4
Definition: utilities.h:65
Bimage
General image parameter class.
Definition: Bimage.h:163
Bimage::real_size
Vector3< double > real_size()
Definition: Bimage.h:487
Micrograph
Definition: file_util.h:23
reconstruction_add
Breconstruction * reconstruction_add(Breconstruction **rec, Bstring &rec_id)
Adds a reconstruction parameter structure to a linked list.
Definition: mg_processing.cpp:704
Bparticle::sel
long sel
Definition: mg_processing.h:103
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
M_PI
#define M_PI
Definition: utilities.h:59
linked_list.h
Header file for generalized linked list functions.
side_views
View * side_views(Bsymmetry *sym, double side_ang, double theta_step, double phi_step)
Initializes a set of views around the z-axis for helical projection.
Definition: symmetry.cpp:769
Boption::view
View view()
Definition: options.h:259
Boption
A class for a command line input option.
Definition: options.h:26
Bimage::label
void label(string s)
Definition: Bimage.h:235
VERB_TIME
#define VERB_TIME
Definition: utilities.h:110
Bsub_image::FOM
double FOM()
Definition: Bimage.h:151
init_point_group_symmetry
Bsymmetry * init_point_group_symmetry(Bstring symmetry_string)
Sets up a symmetry structure from a string identifier.
Definition: symmetry.cpp:39
Bimage::find_peak
int find_peak(double radius=1e30, double sigma=0)
Finds the peak in an image to the nearest voxel.
Definition: Bimage_correlate.cpp:1338
Complex::amp
double amp()
Definition: Complex.h:104
view_array
View * view_array(View *views, long &n)
Copies views from a list into an array.
Definition: View.cpp:44
Boption::symmetry
Bsymmetry * symmetry()
Definition: options.h:252
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
asymmetric_unit_views
View * asymmetric_unit_views(Bsymmetry *sym, double theta_step, double phi_step, int flag)
Initializes a well-distributed set of views in an asymmetric unit.
Definition: symmetry.cpp:570
write_img
int write_img(const char *filename, Bimage *p, int compression)
General driver function to write multiple image formats.
Definition: rwimg.cpp:280
Breconstruction::symmetry
Bstring symmetry
Definition: mg_processing.h:286
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
Bimage::calculate_background
int calculate_background(long nn, int flag)
Calculates the background for one sub-image.
Definition: Bimage_background.cpp:27
file_util.h
Header file for file checking functions.
Bparticle::fpart
Bstring fpart
Definition: mg_processing.h:91
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
part_set_FOM
long part_set_FOM(Bproject *project, int fom_index, double fom)
Sets the FOM for all particles.
Definition: mg_particle_select.cpp:357
Bimage::view
void view(double vx, double vy, double vz, double va)
Definition: Bimage.h:589
Bsymmetry::label
Bstring label
Definition: symmetry.h:41
Bimage::set
void set(long j, double v)
Sets a single value at the given index.
Definition: Bimage.cpp:1096
Bsymmetry
Definition: symmetry.h:38
Bimage::complex_to_real
void complex_to_real()
The real part of a complex image is written to a simple image.
Definition: Bimage_complex.cpp:50
Boption::datatype
DataType datatype()
Definition: options.h:93
Complex
Definition: Complex.h:23
Boption::next
Boption * next
Definition: options.h:28
Bparticle
Definition: mg_processing.h:89
Bstring
Definition: Bstring.h:29
View::residual
double residual(const View &view)
Definition: View.h:165
Bimage::sizeX
void sizeX(long nx)
Definition: Bimage.h:377
project_kill
int project_kill(Bproject *project)
Frees a whole project.
Definition: mg_processing.cpp:1224
View::matrix
Matrix3 matrix()
Definition: View.h:150
Matrix3::transpose
Matrix3 transpose() const
Definition: Matrix3.h:268
Bimage::sizeZ
void sizeZ(long nz)
Definition: Bimage.h:379
Vector3< double >
Boption::origin
Vector3< double > origin()
Definition: options.h:180
timer_report
double timer_report(double lasttime)
Reports the time elapsed since a given time.
Definition: timer.cpp:67
View::angle
double angle()
Definition: View.h:95
View
Definition: View.h:26
option_kill
int option_kill(Boption *option)
Deallocates a linked list of option structures.
Definition: options.cpp:109
Bstring::integer
long integer()
Definition: Bstring.cpp:539
mg_processing.h
Header file for micrograph processing.
Breconstruction::frec
Bstring frec
Definition: mg_processing.h:287
Breconstruction::voxel_size
double voxel_size
Definition: mg_processing.h:292
Unknown_Type
Definition: utilities.h:147
rwimg.h
Header file for 2D and 3D image I/O.
Complex::power
double power()
Definition: Complex.h:103
options.h
Header file for option handlers.
kernel
Definition: kernlut.h:13
main
int main(int argc, char **argv)
Definition: bfcc.cpp:100
use
const char * use[]
Definition: bfcc.cpp:33
Bsymmetry::op
Bsymop * op
Definition: symmetry.h:43
view_list_expand_angles
View * view_list_expand_angles(View *views, double amin, double amax, double astep)
Expands each view to several views with different rotation angles.
Definition: View.cpp:435
Bimage::pack_two_in_complex
Bimage * pack_two_in_complex(Bimage *p)
Packs two real images into one complex image.
Definition: Bimage_complex.cpp:679
Bstring::pre_rev
Bstring pre_rev(char c)
Definition: Bstring.cpp:413
Vector3::volume
double volume()
Definition: Vector3.h:235
project_update_comment
int project_update_comment(Bproject *project, int n, char **strings)
Puts a set of strings and time in the main comment of a project.
Definition: rwmg.cpp:468
Bparticle::next
Bparticle * next
Definition: mg_processing.h:90
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
Bimage::sizeY
void sizeY(long ny)
Definition: Bimage.h:378
Bimage::data_type
DataType data_type()
Definition: Bimage.h:349
Bsymop::axis
Vector3< double > axis
Definition: symmetry.h:25
Breconstruction::view
View view
Definition: mg_processing.h:295
Boption::values
long values(T1 &v1, T2 &v2)
Definition: options.h:115
bexit
int bexit(int value)
Exit function for cleanup and debugging.
Definition: utilities.cpp:273
Breconstruction::next
Breconstruction * next
Definition: mg_processing.h:281
timer_start
double timer_start()
Starts timer and prints the time.
Definition: timer.cpp:52
symmetry_get_all_views
View * symmetry_get_all_views(Bsymmetry *sym, View asu_view)
Get all symmetry-related views of one given view.
Definition: symmetry.cpp:448
Bimage::data_size
long data_size()
Definition: Bimage.h:255
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
Bproject
Definition: mg_processing.h:333
Bimage::image
Bsub_image * image
Definition: Bimage.h:188
Bimage::origin
void origin(double ox, double oy, double oz)
Definition: Bimage.h:563
Breconstruction::id
Bstring id
Definition: mg_processing.h:282
verbose
int verbose