/** * \file AlignSymmetric.cpp * \brief Fast alignment of a cyclic model to its density. * * Copyright 2007-2013 IMP Inventors. All rights reserved. * */ #include #include IMPCNMULTIFIT_BEGIN_NAMESPACE namespace { // sort eigen values such that the symm axis appears first void sort_helper(const algebra::PrincipalComponentAnalysis &pca, int symm_mol_axis_ind, Floats &ev_sorted) { Ints sorted_ind(3); if (symm_mol_axis_ind==0) { sorted_ind[0]=1;sorted_ind[1]=2;sorted_ind[2]=0; } else if (symm_mol_axis_ind == 1) { sorted_ind[0]=0;sorted_ind[1]=2;sorted_ind[2]=1; } else { sorted_ind[0]=0;sorted_ind[1]=1;sorted_ind[2]=2; } for(int i=0;i<3;i++) { ev_sorted[i]=std::sqrt(pca.get_principal_value(sorted_ind[i])); } } } algebra::Transformation3Ds AlignSymmetric::generate_cn_density_translations() const { float trans_delta=spacing_;float max_trans=spacing_*5; algebra::Transformation3Ds ret_trans; algebra::Vector3D symm_axis=symm_map_->get_symmetry_axis(); symm_axis = symm_axis*(1./algebra::get_l2_norm(symm_axis)); float curr_trans=-max_trans; algebra::Rotation3D id_rot = algebra::get_identity_rotation_3d(); while(curr_transget_symmetry_axis(); algebra::Vector3D cen=symm_map_->get_pca().get_centroid(); //translate such that the symm axis will pass through 0 algebra::Transformation3D move_to_zero(algebra::get_identity_rotation_3d(), -cen); algebra::Transformation3D move_to_zero_inv = move_to_zero.get_inverse(); for(int symm_ind=0;symm_indget_spacing(); cn_symm_deg_=cn_symm_deg;dn_symm_deg_=dn_symm_deg; symm_map_.reset(new CnSymmAxisDetector(cn_symm_deg_, dmap, dens_t, 0.0)); int symm_map_axis_ind = symm_map_->get_symmetry_axis_index(); map_v_ = Floats(3); sort_helper(symm_map_->get_pca(), symm_map_axis_ind,map_v_); } int AlignSymmetric::score_alignment(atom::Hierarchies mhs, float max_allowed_diff) { MolCnSymmAxisDetector symm_mol(cn_symm_deg_, mhs); int symm_mol_axis_ind = symm_mol.get_symmetry_axis_index(); int count=0; Floats mol_v(3);//the principal values of non-symm axis first sort_helper(symm_mol.get_pca(),symm_mol_axis_ind,mol_v); IMP_LOG_VERBOSE( "MAP :"<get_pca(); algebra::PrincipalComponentAnalysis mol_pca = symm_mol.get_pca(); //get all transformations from the mol_pca to the map_pca algebra::Transformation3Ds pca_trans; //pca_trans = algebra::get_alignments_from_first_to_second(mol_pca,map_pca); int mol_axis[2]; if (symm_mol_axis_ind==0) {mol_axis[0]=1;mol_axis[1]=2;} else if (symm_mol_axis_ind==1) {mol_axis[0]=0;mol_axis[1]=2;} else {mol_axis[0]=0;mol_axis[1]=1;} int symm_map_axis_ind = symm_map_->get_symmetry_axis_index(); int map_axis[2]; if (symm_map_axis_ind==0) {map_axis[0]=1;map_axis[1]=2;} else if (symm_map_axis_ind==1) {map_axis[0]=0;map_axis[1]=2;} else {map_axis[0]=0;map_axis[1]=1;} algebra::Rotation3D map_rot = algebra::get_rotation_from_x_y_axes( map_pca.get_principal_component(map_axis[0]), map_pca.get_principal_component(map_axis[1])); int x_sign[2];x_sign[0]=1;x_sign[1]=-1; algebra::ReferenceFrame3D map_rf(algebra::Transformation3D( map_rot,map_pca.get_centroid())); for(int i=0;i<2;i++){ algebra::Rotation3D mol_rot = algebra::get_rotation_from_x_y_axes( mol_pca.get_principal_component(mol_axis[0])*x_sign[i], mol_pca.get_principal_component(mol_axis[1])); algebra::ReferenceFrame3D mol_rf(algebra::Transformation3D( mol_rot,mol_pca.get_centroid())); algebra::Transformation3D mol_pca2map_pca = algebra::get_transformation_from_first_to_second( mol_rf,map_rf); pca_trans.push_back(mol_pca2map_pca); mol_rot = algebra::get_rotation_from_x_y_axes( mol_pca.get_principal_component(mol_axis[1])*x_sign[i], mol_pca.get_principal_component(mol_axis[0])); mol_rf=algebra::ReferenceFrame3D(algebra::Transformation3D( mol_rot,mol_pca.get_centroid())); mol_pca2map_pca = algebra::get_transformation_from_first_to_second( mol_rf,map_rf); pca_trans.push_back(mol_pca2map_pca); } //get all rotations around the mol center algebra::Transformation3Ds symm_dens_rots = generate_cn_density_rotations( fine_rotation_sampling); //get all translations around the mol axis algebra::Transformation3Ds symm_dens_trans; if (sample_translation) { symm_dens_trans= generate_cn_density_translations(); } else { symm_dens_trans.push_back(algebra::get_identity_transformation_3d()); } algebra::Transformation3Ds rtrans; for(algebra::Transformation3Ds::const_iterator pca_it = pca_trans.begin(); pca_it != pca_trans.end(); pca_it++) { for(algebra::Transformation3Ds::const_iterator rot_it = symm_dens_rots.begin(); rot_it != symm_dens_rots.end(); rot_it++) { for(algebra::Transformation3Ds::const_iterator trans_it = symm_dens_trans.begin(); trans_it != symm_dens_trans.end(); trans_it++) { rtrans.push_back((*trans_it)*(*rot_it)*(*pca_it)); } } } return rtrans; } IMPCNMULTIFIT_END_NAMESPACE