void symmetriseMap(MultidimArray<DOUBLE> &img, FileName &fn_sym, bool do_wrap) { if (img.getDim() != 3) REPORT_ERROR("symmetriseMap ERROR: symmetriseMap can only be run on 3D maps!"); img.setXmippOrigin(); SymList SL; SL.read_sym_file(fn_sym); Matrix2D<DOUBLE> L(4, 4), R(4, 4); // A matrix from the list MultidimArray<DOUBLE> sum, aux; sum = img; aux.resize(img); for (int isym = 0; isym < SL.SymsNo(); isym++) { SL.get_matrices(isym, L, R); applyGeometry(img, aux, R, IS_INV, do_wrap); sum += aux; } // Overwrite the input img = sum / (SL.SymsNo() + 1); }
DOUBLE check_symmetries(DOUBLE rot1, DOUBLE tilt1, DOUBLE psi1, DOUBLE &rot2, DOUBLE &tilt2, DOUBLE &psi2) { int imax = SL.SymsNo() + 1; Matrix2D<DOUBLE> L(4, 4), R(4, 4); // A matrix from the list DOUBLE best_ang_dist = 3600; DOUBLE best_rot2, best_tilt2, best_psi2; DOUBLE tilt_angle, alpha, beta; for (int i = 0; i < imax; i++) { DOUBLE rot2p, tilt2p, psi2p; if (i == 0) { rot2p = rot2; tilt2p = tilt2; psi2p = psi2; } else { SL.get_matrices(i - 1, L, R); L.resize(3, 3); // Erase last row and column R.resize(3, 3); // as only the relative orientation is useful and not the translation Euler_apply_transf(L, R, rot2, tilt2, psi2, rot2p, tilt2p, psi2p); } DOUBLE ang_dist = check_tilt_pairs(rot1, tilt1, psi1, rot2p, tilt2p, psi2p); if (ang_dist < best_ang_dist) { best_ang_dist = ang_dist; best_rot2 = rot2p; best_tilt2 = tilt2p; best_psi2 = psi2p; } } rot2 = best_rot2; tilt2 = best_tilt2; psi2 = best_psi2; return best_ang_dist; }