| Bsoft 2.0.5 Bernard's software package

mg_hand.cpp
Go to the documentation of this file.
1
10 #include "mg_hand.h"
11 #include "Matrix3.h"
12 #include "qsort_functions.h"
13 #include "utilities.h"
14
15
16 // Global variables
17 extern int verbose; // Level of output to the screen
18
19
20 /*
21 @Object: struct Hand_Stats
22 @brief Statistical parameters for the hand functions (handedness tilt
23 experiment), and sums needed to compute them. Also, counts keep
24 score of hand A vs. hand B.
25 @Features:
26 **/
27 struct Hand_Stats {
28 int CountA; // Count of all particles that matched best with hand A, B, or neither
29 int CountB;
30 int Tie;
31 double Avg1A; // Average and Standard deviations:
32 double Avg2A; // control, view 1 hand A (1A); and hands A (2A) and B (2B)
33 double Avg2B;
34 double Std1A;
35 double Std2A;
36 double Std2B;
37 double AvgAbsDiff_2Aphi; // Absolute differences: measured angles - predicted angles
38 double AvgAbsDiff_2Athe;
39 double AvgAbsDiff_2Apsi;
40 double AvgAbsDiff_2Bphi;
41 double AvgAbsDiff_2Bthe;
42 double AvgAbsDiff_2Bpsi;
43 double StdAbsDiff_2Aphi;
44 double StdAbsDiff_2Athe;
45 double StdAbsDiff_2Apsi;
46 double StdAbsDiff_2Bphi;
47 double StdAbsDiff_2Bthe;
48 double StdAbsDiff_2Bpsi;
49 double Sum_1A; // Sums for computing averages and their standard deviations
50 double Sum_2A; // of correlation coefficients
51 double Sum_2B;
52 double Sum_1Asq;
53 double Sum_2Asq;
54 double Sum_2Bsq;
55 double Sum_AbsDiffPhi2A; // Sums for computing averages and their standard deviations
56 double Sum_AbsDiffThe2A; // of the absoluted differences between measured and predicted
57 double Sum_AbsDiffPsi2A; // angles
58 double Sum_AbsDiffPhi2B;
59 double Sum_AbsDiffThe2B;
60 double Sum_AbsDiffPsi2B;
61 double Sum_AbsDiffPhi2Asq;
62 double Sum_AbsDiffThe2Asq;
63 double Sum_AbsDiffPsi2Asq;
64 double Sum_AbsDiffPhi2Bsq;
65 double Sum_AbsDiffThe2Bsq;
66 double Sum_AbsDiffPsi2Bsq;
67 };
68
69
70 // Internal function prototypes
71 int field_get_handedness(Bimage* mapA, Bimage* mapB, Bmicrograph* mg1, Bmicrograph* mg2, Hand_Stats* Global,
72 double rad_min, double rad_max, double res_min, double res_max, double AmB_min, double AB_min, int diff_out,
73 int origins2, Bstring outimg, int fieldnum);
74 int get_handedness_from_tilt_pair(Bimage* mapA, Bimage* mapB, Bmicrograph* mg1, Bmicrograph* mg2,
75 Bparticle* particle1, Bparticle* particle2,
76 Hand_Stats* Pair, double rad_min, double rad_max, double res_min, double res_max, double AmB_min, double AB_min,
77 int diff_out, int origins2, Bstring outimg, int fieldnum);
78
79 int hand_compute_stats(Hand_Stats* stats, int diff_out);
80 int hand_prepare_image(Bimage* p, double resmin, double resmax);
81 int hand_print_outheader(int which_one, int diff_out);
82 int hand_print_stats(Hand_Stats* stats, int which_one, int diff_out);
83 int hand_write_img(Bimage* img, Bstring imgname, Bstring outimg, int fieldnum, int num);
84
85
86
113 int project_get_handedness(Bimage* mapA, Bproject* project, double* mg_ang,
114 int* mg_index, int* mg_select, double rad_min, double rad_max,
115 double res_min, double res_max, double AmB_min, double AB_min,
116 int diff_out, int origins2, Bstring outimg)
117 {
118 project->fom_tag[1] = FOM_HAND_A;
119 project->fom_tag[2] = FOM_HAND_B;
120
121 Bfield* field=NULL; // Placeholder for loop over the fields-of-view in project
122 int handedness; // Output to calling function: 1=hand A, 2=hand B, 0=undetermined
123 int ifield; // index for field block
124 Bmicrograph *mg1=NULL, *mg2=NULL; // Structures to hold input data for first and second views of a micrograph tilt pair
125 int n_Global; // Number of particle-image pairs analyzed, for statistical calculations
126 Bimage *mapB=NULL; // Mirror image of input map (mapA)
127
128 Hand_Stats* Global = new Hand_Stats; // Global statistics (i.e. for all micrographs)
129 memset(Global, 0, sizeof(Hand_Stats)); // zero sums for global statistics
130
131 if ( verbose ) {
132 cout << "Minimum Radius (pixels): " << rad_min << endl;
133 cout << "Maximum Radius (pixels): " << rad_max << endl;
134 cout << "High-Pass filter (angs.): " << res_min << endl;
135 cout << "Low-Pass filter (angs.): " << res_max << endl << endl;
136 }
137
138
139 // Copy enantiomer and invert it through origin where equation is
140 // mirror(x,y,z) = enantiomer(-x,-y,-z)
141 // if origin is given as (0,0,0). mapB is hand B map.
142 mapA->calculate_background(); // first be sure background is set correctly
143 Vector3<double> scale(-1,-1,-1), translate;
144 Matrix3 mat(1);
145 // mapB = img_transform_copy(mapA, mapA->size(), scale, mapA->image->origin(), translate, mat, FILL_BACKGROUND, 0);
146 mapB = mapA->transform(mapA->size(), scale, mapA->image->origin(), translate, mat, FILL_BACKGROUND, 0);
147
148 if (verbose) {
149 cout << "Hand A map origin: " << mapA->image->origin() << endl;
150 cout << "Hand B map origin: " << mapB->image->origin() << endl;
151 cout << "Map Sampling (angs./pixel): " << mapA->sampling() << endl << endl;
152 }
153
154
155 // Determine handedness
156 for ( field = project->field, ifield=1; field; field = field->next, ifield++ ) {
157 // select first view
158 mg1 = field_find_micrograph(field, mg_select[0], mg_index[0], mg_ang[0]);
159 // select second view
160 mg2 = field_find_micrograph(field, mg_select[1], mg_index[1], mg_ang[1]);
161 // find handedness for a field
162 field_get_handedness(mapA, mapB, mg1, mg2, Global, rad_min, rad_max,
163 res_min, res_max, AmB_min, AB_min, diff_out, origins2, outimg, ifield);
164 }
165
166
167 // Calculate and print global statistics to screen
168 hand_compute_stats(Global, diff_out);
169 if (verbose) {
170 cout << endl << endl;
171 hand_print_stats(Global, 1, diff_out);
172 }
173
174
175 // If 95% of particles agree with one handedness, handedness=1 if hand A or 2 if hand B. 0 if < 95%.
176 n_Global = Global->CountA + Global->CountB + Global->Tie;
177 if ( (Global->CountA/n_Global) >= 0.95 ) {
178 handedness = 1;
179 if (verbose) cout << "Output map has hand A (same as input map)." << endl;
180 } else if ( (Global->CountB/n_Global) >= 0.95 ) {
181 handedness = 2;
182 if (verbose) cout << "Output map has hand B (opposite of input map)." << endl;
183 } else {
184 handedness = 0;
185 if (verbose)
186 cout << "Output map is undetermined because the number of selected" << endl;
187 cout << "particles favoring hand A or B was not 95% or greater." << endl;
188 }
189
190
191 // Memory clean-up
192 delete mapB;
193 delete Global;
194
195
196 return handedness;
197 }
198
199
200
201 /*
202 @brief Determines handedness for all selected particles (sel > 0) for a
203 field--specifically a selected tilt pair of micrographs from the
204 field.
205 @param *mapA 3D map (hand A)
206 @param *mapB 3D map (hand B)
207 @param *mg1 Micrograph for view 1 of field
208 @param *mg2 Micrograph for view 2 of field
209 @param *Global Statistics for all fields-of-view
210 @param rad_min minimum radius for FOM calculation (pixels)
211 @param rad_max maximum radius for FOM calculation (pixels)
212 @param res_min minimum resolution for FOM calculation (angs.)
213 @param res_max maximum resolution for FOM calculation (angs.)
214 @param AmB_min |FOMA - FOMB| must be this value or greater
215 @param AB_min min. acceptable value for FOM of correct hand
216 @param diff_out output difference of measured & predicted orientations
217 @param origins2 flag to determine origins for second view
218 @param outimg prefix & suffix for output projection files
219 @param fieldnum index of current field (for image output)
220 @return int error code.
221
222 Gets tilt-axis direction and rotation angle for a micrograph pair.
223 Then, loops through the selected particles in pair. Sends data to
224 function get_handedness_from_tilt_pair, where handedness is
225 determined. Statistics are calculated for each pair and sums for
226 global statistics are tabulated.
227
228 **/
229 int field_get_handedness(Bimage* mapA, Bimage* mapB, Bmicrograph* mg1, Bmicrograph* mg2, Hand_Stats* Global,
230 double rad_min, double rad_max, double res_min, double res_max, double AmB_min, double AB_min, int diff_out,
231 int origins2, Bstring outimg, int fieldnum)
232 {
233
234 Bparticle* particle1 = NULL; // particles being processed
235 Bparticle* particle2 = NULL;
236
237 Hand_Stats* Pair = new Hand_Stats; // Statistics for current micrograph pair
238 memset(Pair, 0, sizeof(Hand_Stats)); // zero sums for pair statistics
239
240 // Get the pair's tilt-axis direction and the rotation angle from the mg1 and mg2 structures
241 if ( mg1->tilt_axis != mg2->tilt_axis ) {
242 error_show("Error in field_get_handedness", __FILE__, __LINE__);
243 cerr << "The tilt-axis direction is not the same or is invalid in this pair:" << endl;
244 cerr << mg1->fpart << " axis dir = " << mg1->tilt_axis*180.0/M_PI << endl;
245 cerr << mg2->fpart << " axis dir = " << mg2->tilt_axis*180.0/M_PI << endl;
246 cerr << "You may have a pair mismatch or may need to enter a value for both micrographs." << endl;
247 return -1;
248 }
249
250 if ( verbose ) {
251 cout << "Tilt pair:" << endl;
252 cout << "Micrograph 1: " << mg1->fpart << endl;
253 cout << "Micrograph 2: " << mg2->fpart << endl;
254 cout << "Tilt-axis direction: " << mg1->tilt_axis*(180/M_PI) << endl;
255 cout << "Rotation angle: " << (mg2->tilt_angle - mg1->tilt_angle)*(180/M_PI) << endl << endl;
256 }
257
258 // Loop through all particles in first micrograph
259 // -It is assumed that the ID numbers in the first and second micrographs refer to the same imaged object.
260 // -To be analyzed, a particle must
261 // a) have the identical number in second micrograph
262 // b) sel > 0
263 if (verbose) hand_print_outheader(0, diff_out); // Header for screen output
264 for ( particle1=mg1->part; particle1; particle1=particle1->next ) if ( particle1->sel ) {
265 // loop through particles in second mg to find identical particle ID
266 for ( particle2=mg2->part; particle2 && particle1->id != particle2->id; particle2=particle2->next ) ;
267 if ( particle2 )
268 get_handedness_from_tilt_pair(mapA, mapB, mg1, mg2, particle1, particle2, Pair,
269 rad_min, rad_max, res_min, res_max, AmB_min, AB_min, diff_out, origins2, outimg, fieldnum);
270 }
271
272
273 // Calculate and output pair statistics
274 hand_compute_stats(Pair, diff_out);
275 if ( verbose )
276 hand_print_stats(Pair, 0, diff_out);
277
278 // Tabulate sums for global statistics
279 Global->Sum_1A += Pair->Sum_1A;
280 Global->Sum_2A += Pair->Sum_2A;
281 Global->Sum_2B += Pair->Sum_2B;
282 Global->Sum_1Asq += Pair->Sum_1Asq;
283 Global->Sum_2Asq += Pair->Sum_2Asq;
284 Global->Sum_2Bsq += Pair->Sum_2Bsq;
285 Global->CountA += Pair->CountA;
286 Global->CountB += Pair->CountB;
287 Global->Tie += Pair->Tie;
288 if (diff_out > 0) {
289 Global->Sum_AbsDiffPhi2A += Pair->Sum_AbsDiffPhi2A;
290 Global->Sum_AbsDiffThe2A += Pair->Sum_AbsDiffThe2A;
291 Global->Sum_AbsDiffPsi2A += Pair->Sum_AbsDiffPsi2A;
292 Global->Sum_AbsDiffPhi2B += Pair->Sum_AbsDiffPhi2B;
293 Global->Sum_AbsDiffThe2B += Pair->Sum_AbsDiffThe2B;
294 Global->Sum_AbsDiffPsi2B += Pair->Sum_AbsDiffPsi2B;
295 Global->Sum_AbsDiffPhi2Asq += Pair->Sum_AbsDiffPhi2Asq;
296 Global->Sum_AbsDiffThe2Asq += Pair->Sum_AbsDiffThe2Asq;
297 Global->Sum_AbsDiffPsi2Asq += Pair->Sum_AbsDiffPsi2Asq;
298 Global->Sum_AbsDiffPhi2Bsq += Pair->Sum_AbsDiffPhi2Bsq;
299 Global->Sum_AbsDiffThe2Bsq += Pair->Sum_AbsDiffThe2Bsq;
300 Global->Sum_AbsDiffPsi2Bsq += Pair->Sum_AbsDiffPsi2Bsq;
301 }
302
303
304 delete Pair;
305
306 return 0;
307
308 } // End of function field_get_handedness
309
310
311
312 /*
313 @brief Determines handedness from tilt pair of images, (two views of the
314 same specimen in which the specimen was rotated about a known
315 axis and by a known angle).
316
317 @param *mapA 3D map (hand A)
318 @param *mapB 3D map (hand B)
319 @param *mg1 Micrograph for view 1
320 @param *mg2 Micrograph for view 2
321 @param *particle1 Particle from view 1
322 @param *particle2 Particle from view 2
323 @param *Pair Statistics for current micrograph pair
324 @param rad_min minimum radius for FOM calculation (pixels)
325 @param rad_max maximum radius for FOM calculation (pixels)
326 @param res_min minimum resolution for FOM calculation (angs.)
327 @param res_max maximum resolution for FOM calculation (angs.)
328 @param AmB_min |FOMA - FOMB| must be this value or greater
329 @param AB_min min. acceptable value for FOM of correct hand
330 @param diff_out output difference of measured & predicted orientations
331 @param origins2 flag to determine origins for second view
332 @param outimg prefix & suffix for output projection files
333 @param fieldnum index of current field (for image output)
334 @return int 0.
335
336 -Calculate two predicted orientations for second view from first
337 orientation, the tilt-axis direction, and the rotation angle. One
338 orientation is the predicted orientation for hand A (handedness
339 of input 3D map and first orientation) in the second view. The
340 other is the predicted orientation for hand B (mirror of hand A
341 map).
342 -Projections made of input map at first orientation and predicted
343 second orientation of hand A.
344 -Projection made of mirror map at predicted second orientation of
345 hand B.
346 -Projections of predicted second orientations are compared to image
347 of second view.
348 -As a control, projection of first orientation is compared to image
349 of first view.
350 **/
351 int get_handedness_from_tilt_pair(Bimage* mapA, Bimage* mapB, Bmicrograph* mg1, Bmicrograph* mg2,
352 Bparticle* particle1, Bparticle* particle2,
353 Hand_Stats* Pair, double rad_min, double rad_max, double res_min, double res_max, double AmB_min, double AB_min,
354 int diff_out, int origins2, Bstring outimg, int fieldnum)
355 {
356 double axis_dir(mg1->tilt_axis); // Angle of the tilt axis on the micrograph
357 double rotation_angle(mg2->tilt_angle - mg1->tilt_angle); // Angle of rotation about the tilt axis = tilt_angle (view2) - tilt_angle (view1)
358
359 double max_radius; // radius of largest sphere that will fit inside the 3D map
360 double cc1A; // Correlation coefficient for first view and predicted second views
361 double cc2A, cc2B; // model projections vs. particle image
362 double diff2A_phi(0); // measured angle - predicted angle
363 double diff2A_the(0);
364 double diff2A_psi(0);
365 double diff2B_phi(0);
366 double diff2B_the(0);
367 double diff2B_psi(0);
368 int ThresholdOK(1); // flag for |A-B| threshold
369
370 Vector3<double> translate1, translate2A, translate2B; // Translational-shift arrays for particle images
371 Vector3<double> translate0; // for cross-correlation option
372
373 Euler angles1A; // Euler angles for first view
374 Euler angles2A, angles2B; // Euler angles for second view, hands A & B
375 Euler euler2; // Euler angles for second view (input data)
376 View view1A(particle1->view); // View vector and angle for first view, hand A
377 View view1B(view1A);
378 view1B.angle(angle_set_negPI_to_PI(view1B.angle()+M_PI));
379 View view2; // View vector and angle for second view (input data)
380
381 Matrix3 rot_matrix1A(1); // 3x3 matrix for first and predicted second orientations,
382 Matrix3 rot_matrix1B(1); // for hands A and B
383 Matrix3 rot_matrix2A(1);
384 Matrix3 rot_matrix2B(1);
385 Matrix3 rot_matrixtilt(1); // 3x3 matrix for the tilt axis
386
387 Bimage* img1 = NULL; // a particle image from first micrograph
388 Bimage* img2A = NULL; // a particle image from second micrograph
389 Bimage* img2B = NULL; // a copy of img2A, but it may have a different origin
390 Bimage* prj1A = NULL; // a projection image corresponding to the particle image from first micrograph
391 Bimage* prj2A = NULL; // a projection image from hand A map, corresponding to the particle image from second micrograph
392 Bimage* prj2B = NULL; // a projection image from hand B map, corresponding to the particle image from second micrograph
393
394
395 // General parameters
396 max_radius = mapA->maximum_included_radius(); // reduces unnecessary computations in rotate_project and img_find_shift
397
398
399 // Compute predicted orientations for second view (for both hand A and hand B)
400 // -The addition of Pi for the 1B orientation must be added to the psi 1A value, it cannot be added to the
401 // tilt-axis direction. This is because the tilt axis does not change--and neither does the first view.
402 // Only the psi value for the first view changes.
403 rot_matrix1A = view1A.matrix(); // rotation matrices for views 1A & 1B
404 rot_matrix1B = view1B.matrix();
405
406 rot_matrixtilt = Matrix3(rotation_angle,angle_set_negPI_to_PI(axis_dir)); // rotation matrix for tilting operation
407
408 rot_matrix2A = rot_matrix1A * rot_matrixtilt; // rotation matrices for predicted views 2A & 2B
409 rot_matrix2B = rot_matrix1B * rot_matrixtilt;
410
411 // Get orientation angles
412 angles1A = Euler(view1A);
413 angles2A = Euler(rot_matrix2A); // get predicted angles from matrices
414 angles2B = Euler(rot_matrix2B);
415
416 if ( verbose & VERB_PROCESS ) {
417 cout << "Input orientation (phi, theta, psi) = " <<
418 angles1A.phi()*(180/M_PI) << " " << angles1A.theta()*(180/M_PI) << " " << angles1A.psi()*(180/M_PI) << endl;
419 cout << "Predicted orientation 2A (phi, theta, psi) = " <<
420 angles2A.phi()*(180/M_PI) << " " << angles2A.theta()*(180/M_PI) << " " << angles2A.psi()*(180/M_PI) << endl;
421 cout << "Predicted orientation 2B (phi, theta, psi) = " <<
422 angles2B.phi()*(180/M_PI) << " " << angles2B.theta()*(180/M_PI) << " " << angles2B.psi()*(180/M_PI) << endl;
423 }
424 if ( verbose & VERB_FULL ) {
425 cout << "Matrix for first view, hand A" << endl;
426 cout << rot_matrix1A << endl;
427 cout << "Matrix for tilt" << endl;
428 cout << rot_matrixtilt << endl;
429 cout << "Matrix for second view, hand A" << endl;
430 cout << rot_matrix2A << endl;
431 cout << "Matrix for second view, hand B" << endl;
432 cout << rot_matrix2B << endl;
433 }
434
435
436 // Read images and convert to double point, set pixel size to value from micrograph structure (if different)
437 img1 = read_img(mg1->fpart,1,(particle1->id - 1));
438 img1->change_type(Float);
439 img1->sampling(mg1->pixel_size,mg1->pixel_size,1);
440 img1->origin(particle1->ori);
441
442 img2A = read_img(mg2->fpart,1,(particle2->id - 1));
443 img2A->change_type(Float);
444 img2A->sampling(mg2->pixel_size,mg2->pixel_size,1);
445 img2A->origin(particle2->ori);
446
447 img2B = img2A->copy(); // copy made for hand 2B test because origin may differ
448
449 Vector3<double> oriA(mapA->image->origin()[0], mapA->image->origin()[1], 0);
450 Vector3<double> oriB(mapB->image->origin()[0], mapB->image->origin()[1], 0);
451
452 // Get translational offset (x & y only, z offset = 0) and set origins of data images
453 // -The translational offset is the origin of the particle image minus the center of the map array
454 translate1 = particle1->ori - oriA;
455
456 if (origins2 == 0) { // Get image origins (second view) from input parameter file
457 translate2A = particle2->ori - oriA;
458 translate2B = particle2->ori - oriB;
459 } else if (origins2 == 1) { // Determine origins of second view via cross-correlation with projections
460 prj2A = mapA->rotate_project(rot_matrix2A, translate0, max_radius); // project with no shifts
461 prj2B = mapB->rotate_project(rot_matrix2B, translate0, max_radius);
462
463 // img_find_shift(img2A, prj2A, NULL, res_max, res_min, max_radius, 0, 1); // hand A
464 img2A->find_shift(prj2A, NULL, res_max, res_min, max_radius, 0, 1); // hand A
465 translate2A = prj2A->image->origin() - img2A->image->origin();
466 img2A->image->origin(translate2A + oriA);
467
468 // img_find_shift(img2B, prj2B, NULL, res_max, res_min, max_radius, 0, 1); // hand B
469 img2B->find_shift(prj2B, NULL, res_max, res_min, max_radius, 0, 1); // hand B
470 translate2B = prj2B->image->origin() - img2B->image->origin();
471 // img2B->image->origin(translate2B + oriB);
472 img2B->origin(translate2B + oriB);
473
474 delete prj2A;
475 delete prj2B;
476 } else if (origins2 == 2) { // Get image origins (second view) from Bsubimage structure
477 translate2A = img2A->image->origin() - oriA;
478 translate2B = img2B->image->origin() - oriB;
479 }
480
481
482 // Compute projections for 1A, 2A, and 2B orientations, origins put at respective image origin
483 prj1A = mapA->rotate_project(rot_matrix1A, translate1, max_radius);
484 prj2A = mapA->rotate_project(rot_matrix2A, translate2A, max_radius);
485 prj2B = mapB->rotate_project(rot_matrix2B, translate2B, max_radius);
486
487
488 // Write projections to disk, if desired
489 if ( outimg.length() ) {
490 hand_write_img(prj1A, "prj1a", outimg, fieldnum, particle1->id);
491 hand_write_img(prj2A, "prj2a", outimg, fieldnum, particle1->id);
492 hand_write_img(prj2B, "prj2b", outimg, fieldnum, particle1->id);
493 }
494
495
496 // Projections have same origin and pixel size as images
497 // prj1A->image->origin(img1->image->origin());
498 // prj2A->image->origin(img2A->image->origin());
499 // prj2B->image->origin(img2B->image->origin());
500 prj1A->origin(0, img1->image->origin());
501 prj2A->origin(0, img2A->image->origin());
502 prj2B->origin(0, img2B->image->origin());
503
504 prj1A->sampling(img1->sampling());
505 prj2A->sampling(img2A->sampling());
506 prj2B->sampling(img2B->sampling());
507
508
509 // Prepare images for comparison test by setting statistics and applying a bandpass filter
510 hand_prepare_image(img1, res_min, res_max);
511 hand_prepare_image(img2A,res_min, res_max);
512 hand_prepare_image(img2B,res_min, res_max);
513 hand_prepare_image(prj1A,res_min, res_max);
514 hand_prepare_image(prj2A,res_min, res_max);
515 hand_prepare_image(prj2B,res_min, res_max);
516
517
518 // Debugging output
519 if ( outimg.length() && (verbose & VERB_DEBUG) ) {
520 hand_write_img(prj1A, "prj1a", outimg, fieldnum, particle1->id);
521 hand_write_img(prj2A, "prj2a", outimg, fieldnum, particle1->id);
522 hand_write_img(prj2B, "prj2b", outimg, fieldnum, particle1->id);
523 hand_write_img(img1, "img1", outimg, fieldnum, particle1->id);
524 hand_write_img(img2A, "img2a", outimg, fieldnum, particle1->id); // img2a and img2b will appear identical
525 hand_write_img(img2B, "img2b", outimg, fieldnum, particle1->id); // but their origins could be different
526 }
527 if ( verbose & VERB_DEBUG ) {
528 cout << "General parameters" << endl;
529 cout << " radius min,max: " << rad_min << " " << rad_max << endl;
530 cout << " resolution min,max: " << res_min << " " << res_max << endl;
531 cout << " micrograph 1,2: " << mg1->id << " " << mg2->id << endl;
532 cout << " particle 1,2: " << particle1->id << " " << particle2->id << endl;
533 cout << "Image 1 parameters" << endl;
534 cout << " background: " << img1->background(long(0)) << endl;
535 cout << " origin (x,y,z): " << img1->image->origin() << endl;
536 cout << " pixel size (x,y,z): " << img1->sampling() << endl;
537 cout << "Projection 1A parameters" << endl;
538 cout << " background: " << img2A->background(long(0)) << endl;
539 cout << " origin (x,y,z): " << prj1A->image->origin() << endl;
540 cout << " pixel size (x,y,z): " << prj1A->sampling() << endl;
541 cout << "Image 2A parameters" << endl;
542 cout << " background: " << img2B->background(long(0)) << endl;
543 cout << " origin (x,y,z): " << img2A->image->origin() << endl;
544 cout << " pixel size (x,y,z): " << img2A->sampling() << endl;
545 cout << "Projection 2A parameters" << endl;
546 cout << " background: " << prj1A->background(long(0)) << endl;
547 cout << " origin (x,y,z): " << prj2A->image->origin() << endl;
548 cout << " pixel size (x,y,z): " << prj2A->sampling() << endl;
549 cout << "Image 2B parameters" << endl;
550 cout << " background: " << prj2A->background(long(0)) << endl;
551 cout << " origin (x,y,z): " << img2B->image->origin() << endl;
552 cout << " pixel size (x,y,z): " << img2B->sampling() << endl;
553 cout << "Projection 2B parameters" << endl;
554 cout << " background: " << prj2B->background(long(0)) << endl;
555 cout << " origin (x,y,z): " << prj2B->image->origin() << endl;
556 cout << " pixel size (x,y,z): " << prj2B->sampling() << endl;
557 }
558
559
560 // Compare images to projections
561 // cc1A = img_correlation_coefficient_radial(img1, prj1A, rad_min, rad_max);
562 // cc2A = img_correlation_coefficient_radial(img2A, prj2A, rad_min, rad_max);
563 // cc2B = img_correlation_coefficient_radial(img2B, prj2B, rad_min, rad_max);
564 cc1A = img1->correlate(prj1A, rad_min, rad_max, NULL, 0);
565 cc2A = img2A->correlate(prj2A, rad_min, rad_max, NULL, 0);
566 cc2B = img2B->correlate(prj2B, rad_min, rad_max, NULL, 0);
567
568 particle1->fom[1] = cc1A;
569 particle2->fom[1] = cc2A;
570 particle2->fom[2] = cc2B;
571
572
573 // Print CCs to screen, check thresholds, selection option:
574 // -If 1) |difference| of CC2A-CC2B or 2) largest CC (CC2A or CC2B)
575 // is not equal to or greater than their respective thresholds,
576 // discard this particle from statistics and deselected it
577 // -User may also set selection numbers for hand A (1) or B (2)
578 if (verbose) cout << setprecision(4) << particle1->id << tab << cc1A << tab << cc2A << tab << cc2B << tab << cc2A-cc2B;
579
580 if ( fabs(cc2A-cc2B) >= AmB_min ) { // CC difference > difference threshold
581 if ( (cc2A < AB_min) && (cc2B < AB_min) ) { // both CCs less than CC threshold
582 ThresholdOK = 0;
583 } else { // at least one CC is >= CC threshold
584 if ( cc2A > cc2B ) { // Hand A
585 particle1->sel = 1;
586 particle2->sel = 1;
587 } else { // Hand B
588 particle1->sel = 2;
589 particle2->sel = 2;
590 }
591 if ( verbose && (diff_out > 0) ) { // No Deselections: print predicted orientations to screen
592 cout << setprecision(2) << tab << (180/M_PI)*angles2A.phi() << tab << (180/M_PI)*angles2A.theta() << tab << (180/M_PI)*angles2A.psi();
593 cout << tab << (180/M_PI)*angles2B.phi() << tab << (180/M_PI)*angles2B.theta() << tab << (180/M_PI)*angles2B.psi();
594 }
595 }
596 } else {
597 ThresholdOK = 0;
598 }
599
600 if ( !ThresholdOK ) {
601 particle1->sel = 0;
602 particle2->sel = 0;
603 // if (verbose) cout << "\t|A - B| < threshold, deselected (0)";
604 }
605 if ( verbose && !diff_out ) cout << tab << ThresholdOK;
606 if (verbose) cout << endl;
607
608
609 // Compute difference between measured and predicted angles if desired and if |A-B| threshold is okay
610 // -absolute difference will be tallied for pair and global statistics
611 if ( (ThresholdOK == 1) && (diff_out > 0) ) {
612
613 view2 = particle2->view;
614 euler2 = Euler(view2);
615 // euler2.check();
616 // angles2A.check();
617 // angles2B.check();
618
619 diff2A_phi = angle_set_negPI_to_PI(euler2.phi() - angles2A.phi()); // use angle_set_negPI_to_PI to get min. difference
620 diff2A_the = euler2.theta() - angles2A.theta();
621 diff2A_psi = angle_set_negPI_to_PI(euler2.psi() - angles2A.psi());
622 diff2B_phi = angle_set_negPI_to_PI(euler2.phi() - angles2B.phi());
623 diff2B_the = euler2.theta() - angles2B.theta();
624 diff2B_psi = angle_set_negPI_to_PI(euler2.psi() - angles2B.psi());
625
626 if ( verbose && (diff_out >= 2) ) {
627 cout << " Measured - Predicted =";
628 cout << " " << (180/M_PI)*diff2A_phi;
629 cout << " " << (180/M_PI)*diff2A_the;
630 cout << " " << (180/M_PI)*diff2A_psi;
631 cout << " " << (180/M_PI)*diff2B_phi;
632 cout << " " << (180/M_PI)*diff2B_the;
633 cout << " " << (180/M_PI)*diff2B_psi << endl << endl;
634 }
635 }
636
637
638 // Tabulate sums for pair statistics if |A-B| threshold is okay
639 if (ThresholdOK == 1) {
640 Pair->Sum_1A += cc1A;
641 Pair->Sum_2A += cc2A;
642 Pair->Sum_2B += cc2B;
643 Pair->Sum_1Asq += cc1A*cc1A;
644 Pair->Sum_2Asq += cc2A*cc2A;
645 Pair->Sum_2Bsq += cc2B*cc2B;
646 if (cc2A > cc2B) // Count to see which handedness wins the contest
647 Pair->CountA++;
648 else if (cc2B > cc2A)
649 Pair->CountB++;
650 else
651 Pair->Tie++;
652 if (diff_out > 0) {
653 Pair->Sum_AbsDiffPhi2A += fabs(diff2A_phi);
654 Pair->Sum_AbsDiffThe2A += fabs(diff2A_the);
655 Pair->Sum_AbsDiffPsi2A += fabs(diff2A_psi);
656 Pair->Sum_AbsDiffPhi2B += fabs(diff2B_phi);
657 Pair->Sum_AbsDiffThe2B += fabs(diff2B_the);
658 Pair->Sum_AbsDiffPsi2B += fabs(diff2B_psi);
659 Pair->Sum_AbsDiffPhi2Asq += diff2A_phi*diff2A_phi;
660 Pair->Sum_AbsDiffThe2Asq += diff2A_the*diff2A_the;
661 Pair->Sum_AbsDiffPsi2Asq += diff2A_psi*diff2A_psi;
662 Pair->Sum_AbsDiffPhi2Bsq += diff2B_phi*diff2B_phi;
663 Pair->Sum_AbsDiffThe2Bsq += diff2B_the*diff2B_the;
664 Pair->Sum_AbsDiffPsi2Bsq += diff2B_psi*diff2B_psi;
665 }
666 }
667
668
669 // Memory cleanup
670 delete img1;
671 delete img2A;
672 delete img2B;
673 delete prj1A;
674 delete prj2A;
675 delete prj2B;
676
677 return 0;
678
679
680 } // End of function get_handedness_from_tilt_pair
681
682
683
684 /*
685 @brief Computes statistics from data collected in Hand_Stats structure.
686 @param *stats Handedness statistical parameters
687 @param diff_out Switch for measured-predicted angle output
688 @return int 0.
689
690 Computes average and standard deviation for view1 projection vs.
691 image1, handA-view2 projection vs. image2, and handB-view2 projection
692 vs. image2 correlation coefficients. Also computes these parameters
693 for differences between measured and predicted angles, if user
694 desires.
695 **/
696 int hand_compute_stats(Hand_Stats* stats, int diff_out)
697 {
698 int N; // Number of data points
699 double d;
700
701 N = stats->CountA + stats->CountB + stats->Tie; // total number of selected particles
702 if (N == 0) return -1; // no data = no statistics
703
704 // Averages
705 stats->Avg1A = stats->Sum_1A/N;
706 stats->Avg2A = stats->Sum_2A/N;
707 stats->Avg2B = stats->Sum_2B/N;
708
709 if (diff_out > 0) { // Absolute differences: measured angles - predicted angles
710 stats->AvgAbsDiff_2Aphi = stats->Sum_AbsDiffPhi2A/N;
711 stats->AvgAbsDiff_2Athe = stats->Sum_AbsDiffThe2A/N;
712 stats->AvgAbsDiff_2Apsi = stats->Sum_AbsDiffPsi2A/N;
713 stats->AvgAbsDiff_2Bphi = stats->Sum_AbsDiffPhi2B/N;
714 stats->AvgAbsDiff_2Bthe = stats->Sum_AbsDiffThe2B/N;
715 stats->AvgAbsDiff_2Bpsi = stats->Sum_AbsDiffPsi2B/N;
716 }
717
718 // Standard deviations
719 if (N < 2) { // prevents divide-by-zero errors if only one data point
720 stats->Std1A = 0; stats->Std2A = 0; stats->Std2B = 0;
721 stats->StdAbsDiff_2Aphi = 0; stats->StdAbsDiff_2Athe = 0; stats->StdAbsDiff_2Apsi = 0;
722 stats->StdAbsDiff_2Bphi = 0; stats->StdAbsDiff_2Bthe = 0; stats->StdAbsDiff_2Bpsi = 0;
723 } else {
724 stats->Std1A = sqrt( (stats->Sum_1Asq - (stats->Sum_1A*stats->Sum_1A)/N) / (N - 1) );
725 stats->Std2A = sqrt( (stats->Sum_2Asq - (stats->Sum_2A*stats->Sum_2A)/N) / (N - 1) );
726 stats->Std2B = sqrt( (stats->Sum_2Bsq - (stats->Sum_2B*stats->Sum_2B)/N) / (N - 1) );
727 if (diff_out > 0) {
728 d = stats->Sum_AbsDiffPhi2Asq - (stats->Sum_AbsDiffPhi2A*stats->Sum_AbsDiffPhi2A)/N;
729 if ( d > 0 ) stats->StdAbsDiff_2Aphi = sqrt( d / (N-1) );
730 else stats->StdAbsDiff_2Aphi = 0;
731 d = stats->Sum_AbsDiffPhi2Asq - (stats->Sum_AbsDiffThe2Asq*stats->Sum_AbsDiffThe2A)/N;
732 if ( d > 0 ) stats->StdAbsDiff_2Athe = sqrt( d / (N-1) );
733 else stats->StdAbsDiff_2Athe = 0;
734 d = stats->Sum_AbsDiffPsi2Asq - (stats->Sum_AbsDiffPsi2A*stats->Sum_AbsDiffPsi2A)/N;
735 if ( d > 0 ) stats->StdAbsDiff_2Apsi = sqrt( d / (N-1) );
736 else stats->StdAbsDiff_2Apsi = 0;
737 d = stats->Sum_AbsDiffPhi2Bsq - (stats->Sum_AbsDiffPhi2B*stats->Sum_AbsDiffPhi2B)/N;
738 if ( d > 0 ) stats->StdAbsDiff_2Bphi = sqrt( d / (N-1) );
739 else stats->StdAbsDiff_2Bphi = 0;
740 d = stats->Sum_AbsDiffThe2Bsq - (stats->Sum_AbsDiffThe2B*stats->Sum_AbsDiffThe2B)/N;
741 if ( d > 0 ) stats->StdAbsDiff_2Bthe = sqrt( d / (N-1) );
742 else stats->StdAbsDiff_2Bthe = 0;
743 d = stats->Sum_AbsDiffPsi2Bsq - (stats->Sum_AbsDiffPsi2B*stats->Sum_AbsDiffPsi2B)/N;
744 if ( d > 0 ) stats->StdAbsDiff_2Bpsi = sqrt( d / (N-1) );
745 else stats->StdAbsDiff_2Bpsi = 0;
746 }
747 }
748
749 return 0;
750 }
751
752
753
754 /*
755 @brief Prepares image for comparison with another image
756 @param *p image.
757 @param resmin Lower resolution cut-off value.
758 @param resmax Higher resolution cut-off value.
759 @return int 0.
760
761 Updates image background and statistics, and applies a bandpass
762 filter to the image.
763 **/
764 int hand_prepare_image(Bimage* p, double resmin, double resmax)
765 {
766
767 p->statistics();
768 p->fspace_bandpass(resmax, resmin, 0);
769 p->correct_background();
770 p->subtract_background();
771
772 return 0;
773
774 }
775
776
777
778 /*
779 @brief Prints the output header to the screen.
780 @param which_one switch for Pair or Global header
781 @param diff_out switch for measured-predicted angle output
782 @return int 0.
783
784 Two headers: pair and global
785 **/
786 int hand_print_outheader(int which_one, int diff_out)
787 {
788 cout << "Particle images vs. projections at predicted orientations" << endl << endl;
789 cout << "\tCorrelation Coefficients";
790 if (which_one == 0) { /* for Pair statistics */
791 if (diff_out>0) cout << "\tPredicted Orientations";
792 cout << endl << endl;
793 cout << "\tprj.\tprj.\tprj." << endl;
794 cout << "\tview1\tview2\tview2\tprjs" << endl;
795 cout << "\thandA\thandA\thandB\tvs." << endl;
796 cout << "Part.\tvs.\tvs.\tvs.\timage2";
797 if (diff_out>0) cout << "\tview2, handA\tview2, handB";
798 cout << endl;
799 cout << "Id\timage1\timage2\timage2\tA - B";
800 if (diff_out>0) cout << "\tPhi\tTheta\tPsi\tPhi\tTheta\tPsi";
801 else cout << "\tselected";
802 cout << endl;
803 cout << "================================================";
804 if (diff_out>0) cout << "======================================";
805 cout << endl;
806 }
807 else { /* for Global statistics */
808 if (diff_out>0) cout << "\t|Measured Orientation -";
809 if (diff_out>0) cout << endl << "\tPredicted Orientation|" << endl;
810 else cout << endl << endl;
811 cout << "\tprj.\t prj.\tprj." << endl;
812 cout << "\tview1\tview2\tview2" << endl;
813 cout << "\thandA\thandA\thandB" << endl;
814 cout << "\tvs.\tvs.\tvs.";
815 if (diff_out>0) cout << "\tview2, handA\tview2, handB";
816 cout << endl;
817 cout << "Global\timage1\timage2\timage2";
818 if (diff_out>0) cout << "\tPhi\tTheta\tPsi\tPhi\tTheta\tPsi";
819 cout << endl;
820 cout << "====================================";
821 if (diff_out>0) cout << "============================================";
822 cout << endl;
823 }
824 return 0;
825 }
826
827
828
829 /*
830 @brief Prints statistics to the screen.
831 @param *stats Handedness statistical parameters
832 @param which_one Switch for Pair or Global statistics
833 @param diff_out Switch for measured-predicted angle output
834 @return int 0.
835 **/
836 int hand_print_stats(Hand_Stats* stats, int which_one, int diff_out)
837 {
838 double ToDeg = 180/M_PI;
839
840 cout << setprecision(4);
841
842 if (which_one == 0) { /* for Pair statistics */
843 if (diff_out > 0) {
844 cout << "*Average\t" << stats->Avg1A << tab << stats->Avg2A << " " <<stats->Avg2B << tab << stats->Avg2A-stats->Avg2B;
845 cout << tab << ToDeg*stats->AvgAbsDiff_2Aphi << tab << ToDeg*stats->AvgAbsDiff_2Athe << tab << ToDeg*stats->AvgAbsDiff_2Apsi;
846 cout << tab << ToDeg*stats->AvgAbsDiff_2Bphi << tab << ToDeg*stats->AvgAbsDiff_2Bthe << tab << ToDeg*stats->AvgAbsDiff_2Bpsi << endl;
847 cout << "Std dev\t" << stats->Std1A << tab << stats->Std2A << tab << stats->Std2B;
848 cout << tab << ToDeg*stats->StdAbsDiff_2Aphi << tab << ToDeg*stats->StdAbsDiff_2Athe << tab << ToDeg*stats->StdAbsDiff_2Apsi;
849 cout << tab << ToDeg*stats->StdAbsDiff_2Bphi << tab << ToDeg*stats->StdAbsDiff_2Bthe << tab << ToDeg*stats->StdAbsDiff_2Bpsi << endl;
850 } else {
851 cout << "Average\t" << stats->Avg1A << tab << stats->Avg2A << tab << stats->Avg2B << tab << stats->Avg2A-stats->Avg2B << endl;
852 cout << "Std dev\t" << stats->Std1A << tab << stats->Std2A << tab << stats->Std2B << endl;
853 }
854 cout << "Count\t\t" << stats->CountA << tab << stats->CountB << endl;
855 if (stats->Tie > 0) cout << "NOTE: " << stats->Tie << " particles in this pair did not favor either hand A or hand B" << endl;
856 if (diff_out > 0) cout << "*Average for pred. orientations is average of |measured angle - predicted angle|" << endl;
857 } else { /* for Global statistics */
858 hand_print_outheader(which_one, diff_out); // Header for screen output
859 if (diff_out > 0) {
860 cout << "Average " << stats->Avg1A << tab << stats->Avg2A << tab << stats->Avg2B;
861 cout << tab << ToDeg*stats->AvgAbsDiff_2Aphi << tab << ToDeg*stats->AvgAbsDiff_2Athe << tab << ToDeg*stats->AvgAbsDiff_2Apsi;
862 cout << tab << ToDeg*stats->AvgAbsDiff_2Bphi << tab << ToDeg*stats->AvgAbsDiff_2Bthe << tab << ToDeg*stats->AvgAbsDiff_2Bpsi << endl;
863 cout << "Std dev " << stats->Std1A << tab << stats->Std2A << tab << stats->Std2B;
864 cout << tab << ToDeg*stats->StdAbsDiff_2Aphi << tab << ToDeg*stats->StdAbsDiff_2Athe << tab << ToDeg*stats->StdAbsDiff_2Apsi;
865 cout << tab << ToDeg*stats->StdAbsDiff_2Bphi << tab << ToDeg*stats->StdAbsDiff_2Bthe << tab << ToDeg*stats->StdAbsDiff_2Bpsi << endl;
866 } else {
867 cout << "Average\t" << stats->Avg1A << tab << stats->Avg2A << tab << stats->Avg2B << endl;
868 cout << "Std dev\t" << stats->Std1A << tab << stats->Std2A << tab << stats->Std2B << endl;
869 }
870 cout << "Count\t\t" << stats->CountA << tab << stats->CountB << endl;
871 if (stats->Tie > 0) cout << "NOTE: " << stats->Tie << " particles in this analysis did not favor either hand A or hand B" << endl;
872 cout << endl << "NOTE: Hand A is handedness of input map. Mirror of input map is hand B." << endl;
873 }
874
875 return 0;
876 }
877
896 int hand_select_consist(Bproject* project, double* mg_ang, int* mg_index, int* mg_select, int sel_consist)
897 {
898 Bfield* field=NULL; // Placeholder for loop over the fields-of-view in project
899 int pcount1, pcount2; // count of particles in micrographs
900 int i; // counter
901 int index; // index for standard view
902 Bmicrograph* mg=NULL; // Micrograph to be reset
903 Bmicrograph* mgstd=NULL; // Standard view (1 or 2) of a micrograph tilt pair
904 Bparticle* particle=NULL; // Particles from micrograph to be reset
905 Bparticle* particlestd=NULL; // Particles from "standard" view (1 or 2), selection values copied from here
906
907 if ( sel_consist < 1 || sel_consist > 2 ) {
908 cerr << "Error: " << sel_consist << " is a wrong value for setting consistent selection values." << endl << "Set to 1 or 2." << endl;
909 bexit(-1);
910 }
911
912 index = sel_consist - 1;
913
914 if ( verbose )
915 cout << endl << "Selection values in all micrographs set to those of micrograph view "
916 << sel_consist << " (standard)." << endl << "standard micrograph reset micrograph (field-of-view):" << endl;
917 for ( field=project->field; field; field=field->next ) { // loop through fields-of-view
918 mgstd = field_find_micrograph(field, mg_select[index], mg_index[index], mg_ang[index]); // select sel_consist view
919 pcount1 = micrograph_count_particles(mgstd);
920 for ( mg=field->mg; mg; mg=mg->next ) { // if micrograph not sel_consist view, then reset selection values
921 if ( mg != mgstd ) {
922 if ( verbose ) cout << mgstd->id << " " << mg->id << " (" << field->id << ")" << endl;
923 pcount2 = micrograph_count_particles(mg);
924 if ( pcount2 == pcount1 ) // number of particles in each micrograph (mg and mgstd) is equivalent
925 for ( particlestd=mgstd->part, particle=mg->part; particlestd && particle; particlestd=particlestd->next, particle=particle->next )
926 particle->sel = particlestd->sel;
927 else { // number of particles in mg and mgstd differ
928 i = 0;
929 for ( particlestd=mgstd->part; particlestd; particlestd=particlestd->next )
930 for ( particle=mg->part; particle; particle=particle->next )
931 if ( particle->id == particlestd->id ) {
932 particle->sel = particlestd->sel;
933 i++;
934 }
935 if ( verbose ) {
936 cout << "Micrograph " << mgstd->id << " has " << pcount1 << " particles. Micrograph " << mg->id << " has " << pcount2 << " particles." << endl;
937 cout << "Only " << i << " particle select values in micrograph " << mg->id << " were changed." << endl;
938 }
939 }
940 }
941 }
942 }
943
944 return 0;
945 }
946
947
957 int hand_write_img(Bimage* img, Bstring imgname, Bstring outimg, int fieldnum, int num)
958 {
959 outimg = outimg.pre_rev('.') + Bstring(fieldnum, "_%04d") + Bstring(num, "_%04d_") + imgname + "." + outimg.post_rev('.');
960 write_img(outimg, img, 0);
961
962 return 0;
963 }
964
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1743
Bparticle::id
int id
Definition: mg_processing.h:92
Hand_Stats::Sum_AbsDiffPhi2A
double Sum_AbsDiffPhi2A
Definition: mg_hand.cpp:55
qsort_functions.h
Header file for utility functions for use in qsort calls.
FILL_BACKGROUND
#define FILL_BACKGROUND
Definition: utilities.h:174
mg_hand.h
Author: David Belnap.
Euler
Definition: Euler.h:28
Bparticle::view
View view
Definition: mg_processing.h:101
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
Hand_Stats::Avg1A
double Avg1A
Definition: mg_hand.cpp:31
Bimage::fspace_bandpass
int fspace_bandpass(double res_hi, double res_lo=0, double width=0)
Applies a bandpass filter to an image.
Definition: Bimage_fspace.cpp:499
Bmicrograph::id
Bstring id
Definition: mg_processing.h:202
Hand_Stats::Sum_2A
double Sum_2A
Definition: mg_hand.cpp:50
utilities.h
Header file for general utilities.
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
angle_set_negPI_to_PI
double angle_set_negPI_to_PI(double angle)
Returns an angle between -PI and PI.
Definition: utilities.cpp:594
Hand_Stats::Tie
int Tie
Definition: mg_hand.cpp:30
Hand_Stats::Sum_2Bsq
double Sum_2Bsq
Definition: mg_hand.cpp:54
Hand_Stats::Std2B
double Std2B
Definition: mg_hand.cpp:36
Bparticle::fom
double fom[NFOM]
Definition: mg_processing.h:102
Hand_Stats::Sum_AbsDiffPsi2B
double Sum_AbsDiffPsi2B
Definition: mg_hand.cpp:60
Matrix3
Definition: Matrix3.h:17
Hand_Stats::StdAbsDiff_2Aphi
double StdAbsDiff_2Aphi
Definition: mg_hand.cpp:43
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
hand_select_consist
int hand_select_consist(Bproject *project, double *mg_ang, int *mg_index, int *mg_select, int sel_consist)
Sets consistent selection values in all (including unused) micrographs.
Definition: mg_hand.cpp:896
Hand_Stats::AvgAbsDiff_2Bphi
double AvgAbsDiff_2Bphi
Definition: mg_hand.cpp:40
hand_print_outheader
int hand_print_outheader(int which_one, int diff_out)
Definition: mg_hand.cpp:786
hand_compute_stats
int hand_compute_stats(Hand_Stats *stats, int diff_out)
Definition: mg_hand.cpp:696
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
hand_print_stats
int hand_print_stats(Hand_Stats *stats, int which_one, int diff_out)
Definition: mg_hand.cpp:836
Hand_Stats::Sum_AbsDiffThe2Bsq
double Sum_AbsDiffThe2Bsq
Definition: mg_hand.cpp:65
Hand_Stats::AvgAbsDiff_2Aphi
double AvgAbsDiff_2Aphi
Definition: mg_hand.cpp:37
Bmicrograph::tilt_angle
double tilt_angle
Definition: mg_processing.h:217
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
Hand_Stats::Sum_1Asq
double Sum_1Asq
Definition: mg_hand.cpp:52
Bfield::next
Bfield * next
Definition: mg_processing.h:258
Hand_Stats::StdAbsDiff_2Bpsi
double StdAbsDiff_2Bpsi
Definition: mg_hand.cpp:48
Bimage::subtract_background
int subtract_background()
Subtracts the background for each sub-image.
Definition: Bimage_background.cpp:337
Matrix3.h
3x3 Matrix manipulation functions
field_get_handedness
int field_get_handedness(Bimage *mapA, Bimage *mapB, Bmicrograph *mg1, Bmicrograph *mg2, Hand_Stats *Global, double rad_min, double rad_max, double res_min, double res_max, double AmB_min, double AB_min, int diff_out, int origins2, Bstring outimg, int fieldnum)
Definition: mg_hand.cpp:229
Hand_Stats::AvgAbsDiff_2Bthe
double AvgAbsDiff_2Bthe
Definition: mg_hand.cpp:41
Bmicrograph::part
Bparticle * part
Definition: mg_processing.h:239
Float
Definition: utilities.h:157
Hand_Stats::Sum_AbsDiffPsi2A
double Sum_AbsDiffPsi2A
Definition: mg_hand.cpp:57
Hand_Stats::StdAbsDiff_2Bthe
double StdAbsDiff_2Bthe
Definition: mg_hand.cpp:47
Bimage
General image parameter class.
Definition: Bimage.h:163
Bmicrograph::fpart
Bstring fpart
Definition: mg_processing.h:207
Bmicrograph::tilt_axis
double tilt_axis
Definition: mg_processing.h:216
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
Bfield
Definition: mg_processing.h:257
M_PI
#define M_PI
Definition: utilities.h:59
Hand_Stats::StdAbsDiff_2Bphi
double StdAbsDiff_2Bphi
Definition: mg_hand.cpp:46
Hand_Stats::Sum_1A
double Sum_1A
Definition: mg_hand.cpp:49
Bimage::maximum_included_radius
double maximum_included_radius()
Returns the radius of the enclosed sphere or circle.
Definition: Bimage.cpp:2036
Bimage::correct_background
int correct_background(long nn, int flag)
Corrects the background for one sub-image.
Definition: Bimage_background.cpp:202
Euler::psi
double psi()
Definition: Euler.h:56
Euler::phi
double phi()
Definition: Euler.h:58
Hand_Stats::Sum_AbsDiffThe2A
double Sum_AbsDiffThe2A
Definition: mg_hand.cpp:56
hand_write_img
int hand_write_img(Bimage *img, Bstring imgname, Bstring outimg, int fieldnum, int num)
Appends micrograph number, image number, and a string tag to a file name. Then it writes out an image...
Definition: mg_hand.cpp:957
Bimage::statistics
long statistics()
Calculates the statistics for an image.
Definition: Bimage_stats.cpp:22
Bfield::id
Bstring id
Definition: mg_processing.h:259
Hand_Stats::Sum_2Asq
double Sum_2Asq
Definition: mg_hand.cpp:53
Hand_Stats::StdAbsDiff_2Athe
double StdAbsDiff_2Athe
Definition: mg_hand.cpp:44
Bproject::field
Bfield * field
Definition: mg_processing.h:343
Bproject::fom_tag
FOMType fom_tag[NFOM]
Definition: mg_processing.h:342
verbose
int verbose
FOM_HAND_B
Definition: mg_processing.h:47
Hand_Stats::Std2A
double Std2A
Definition: mg_hand.cpp:35
Hand_Stats::CountA
int CountA
Definition: mg_hand.cpp:28
Bmicrograph
Definition: mg_processing.h:200
Hand_Stats::Avg2B
double Avg2B
Definition: mg_hand.cpp:33
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
Bimage::calculate_background
int calculate_background(long nn, int flag)
Calculates the background for one sub-image.
Definition: Bimage_background.cpp:27
Hand_Stats
Definition: mg_hand.cpp:27
FOM_HAND_A
Definition: mg_processing.h:46
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
field_find_micrograph
Bmicrograph * field_find_micrograph(Bfield *field, int mg_select, int mg_index, double mg_ang)
Returns a pointer to a specific micrograph in a field-of-view structure based on a unique characteris...
Definition: mg_processing.cpp:183
micrograph_count_particles
long micrograph_count_particles(Bmicrograph *mg)
Counts all the particles in the micrograph structure.
Definition: mg_processing.cpp:1132
Hand_Stats::Avg2A
double Avg2A
Definition: mg_hand.cpp:32
Bstring::post_rev
Bstring post_rev(char c)
Definition: Bstring.cpp:428
Bfield::mg
Bmicrograph * mg
Definition: mg_processing.h:264
Euler::theta
double theta()
Definition: Euler.h:57
Bparticle
Definition: mg_processing.h:89
hand_prepare_image
int hand_prepare_image(Bimage *p, double resmin, double resmax)
Definition: mg_hand.cpp:764
Hand_Stats::CountB
int CountB
Definition: mg_hand.cpp:29
Bstring
Definition: Bstring.h:29
project_get_handedness
int project_get_handedness(Bimage *mapA, Bproject *project, double *mg_ang, int *mg_index, int *mg_select, double rad_min, double rad_max, double res_min, double res_max, double AmB_min, double AB_min, int diff_out, int origins2, Bstring outimg)
Determines handedness for all selected particles (sel > 0) in a project.
Definition: mg_hand.cpp:113
Bimage::copy
Bimage * copy()
Copies the header information and data of an image into a new image structure.
Definition: Bimage.cpp:2695
Hand_Stats::Sum_AbsDiffPsi2Bsq
double Sum_AbsDiffPsi2Bsq
Definition: mg_hand.cpp:66
View::matrix
Matrix3 matrix()
Definition: View.h:150
Vector3< double >
Hand_Stats::Std1A
double Std1A
Definition: mg_hand.cpp:34
Hand_Stats::AvgAbsDiff_2Apsi
double AvgAbsDiff_2Apsi
Definition: mg_hand.cpp:39
Bimage::rotate_project
Bimage * rotate_project(Matrix3 mat, Vector3< double > translate, double radial_cutoff, int norm_flag=1)
Rotates a 3D map and projects it along the z-axis.
Definition: Bimage_project.cpp:118
View::angle
double angle()
Definition: View.h:95
View
Definition: View.h:26
Hand_Stats::Sum_AbsDiffThe2Asq
double Sum_AbsDiffThe2Asq
Definition: mg_hand.cpp:62
Hand_Stats::AvgAbsDiff_2Athe
double AvgAbsDiff_2Athe
Definition: mg_hand.cpp:38
Hand_Stats::StdAbsDiff_2Apsi
double StdAbsDiff_2Apsi
Definition: mg_hand.cpp:45
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
Hand_Stats::Sum_AbsDiffPhi2B
double Sum_AbsDiffPhi2B
Definition: mg_hand.cpp:58
Hand_Stats::Sum_AbsDiffPhi2Asq
double Sum_AbsDiffPhi2Asq
Definition: mg_hand.cpp:61
Hand_Stats::Sum_AbsDiffPsi2Asq
double Sum_AbsDiffPsi2Asq
Definition: mg_hand.cpp:63
Hand_Stats::Sum_2B
double Sum_2B
Definition: mg_hand.cpp:51
Hand_Stats::Sum_AbsDiffThe2B
double Sum_AbsDiffThe2B
Definition: mg_hand.cpp:59
Bstring::pre_rev
Bstring pre_rev(char c)
Definition: Bstring.cpp:413
Hand_Stats::AvgAbsDiff_2Bpsi
double AvgAbsDiff_2Bpsi
Definition: mg_hand.cpp:42
Bparticle::next
Bparticle * next
Definition: mg_processing.h:90
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
Bimage::background
double background(long nn)
Definition: Bimage.h:542
Hand_Stats::Sum_AbsDiffPhi2Bsq
double Sum_AbsDiffPhi2Bsq
Definition: mg_hand.cpp:64
bexit
int bexit(int value)
Exit function for cleanup and debugging.
Definition: utilities.cpp:273
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
Bimage::image
Bsub_image * image
Definition: Bimage.h:188
Bimage::origin
void origin(double ox, double oy, double oz)
Definition: Bimage.h:563
Bmicrograph::next
Bmicrograph * next
Definition: mg_processing.h:201
get_handedness_from_tilt_pair
int get_handedness_from_tilt_pair(Bimage *mapA, Bimage *mapB, Bmicrograph *mg1, Bmicrograph *mg2, Bparticle *particle1, Bparticle *particle2, Hand_Stats *Pair, double rad_min, double rad_max, double res_min, double res_max, double AmB_min, double AB_min, int diff_out, int origins2, Bstring outimg, int fieldnum)
Definition: mg_hand.cpp:351