/** * \file symmetry_utils.cpp * \brief Symmetry utilities. * * Copyright 2007-2013 IMP Inventors. All rights reserved. * */ #include #include #include #include #include #include #include #include #include #include #include #include IMPCNMULTIFIT_BEGIN_NAMESPACE namespace { //return x%y int my_mod(int x,int y){ return (x%y+y)%y; } algebra::Transformation3Ds generate_d2_translations_along_symm_axis( atom::Hierarchies mhs,int symm_deg) { MolCnSymmAxisDetector symm_dec(symm_deg, mhs); algebra::Transformation3Ds all_trans; //find symmetry axis int symm_axis_ind=symm_dec.get_symmetry_axis_index(); algebra::PrincipalComponentAnalysis pca=symm_dec.get_pca(); algebra::Vector3D symm_axis = pca.get_principal_component(symm_axis_ind); float symm_axis_val=pca.get_principal_value(symm_axis_ind); algebra::Transformation3D translation( algebra::get_identity_rotation_3d(), symm_axis*symm_axis_val/2); all_trans.push_back(translation); return all_trans; } em::FittingSolutions fast_cc(em::DensityMap *dmap1, em::DensityMap *dmap2, algebra::Transformation3Ds trans_on_dmap2) { em::FittingSolutions fits; float threshold = dmap2->get_header()->dmin+em::EPS; float score; for(algebra::Transformation3Ds::iterator it = trans_on_dmap2.begin(); it != trans_on_dmap2.end();it++) { Pointer trans_map = em::get_transformed(dmap2,*it); score= em::CoarseCC::cross_correlation_coefficient( dmap1,dmap2,threshold); fits.add_solution(*it,score); } fits.sort(); return fits; } em::FittingSolutions fast_cc_translation(em::DensityMap *dmap1, em::DensityMap *dmap2, algebra::Transformation3Ds trans_on_dmap2) { em::FittingSolutions fits; float threshold = dmap2->get_header()->dmin+em::EPS; float score; algebra::Vector3D orig = dmap2->get_origin(); for(algebra::Transformation3Ds::iterator it = trans_on_dmap2.begin(); it != trans_on_dmap2.end();it++) { dmap2->set_origin(it->get_transformed(orig)); score= em::CoarseCC::cross_correlation_coefficient( dmap1,dmap2,threshold); fits.add_solution(*it,score); } fits.sort(); dmap2->set_origin(orig); return fits; } } //The axis is defined by points a and b algebra::Transformation3D calc_transformation_around_axis( algebra::Vector3D a, algebra::Vector3D b, float angle_rad) { algebra::Vector3D normal = b-a; algebra::Rotation3D rot = algebra::get_rotation_about_axis(normal,angle_rad); return algebra::Transformation3D(rot, (rot*(-a))+a); } algebra::Transformation3Ds generate_translations_along_symm_axis( atom::Hierarchies mhs,int symm_deg) { CnSymmAxisDetector symm_dec(symm_deg, mhs); algebra::Transformation3Ds all_trans; //find symmetry axis int symm_axis_ind=symm_dec.get_symmetry_axis_index(); algebra::PrincipalComponentAnalysis pca=symm_dec.get_pca(); algebra::Vector3D symm_axis = pca.get_principal_component(symm_axis_ind); float symm_axis_val=pca.get_principal_value(symm_axis_ind); //decide how much to translate on the symm axis float trans_delta=3.; for(float trans_step=0;trans_step1); } //calculate fitting along symmetry axis em::FittingSolutions symmetry_local_fitting(atom::Hierarchies mhs, int cn_symm_deg, int dn_symm_deg, em::DensityMap *dmap, int num_of_trans_to_consider) { em::FittingSolutions return_fit_sols; return_fit_sols.add_solution(algebra::get_identity_transformation_3d(),0.); return return_fit_sols; Particles ps; for(unsigned int i=0;ihalf;i--) { core::transform(core::RigidBody(mhs[i]),curr_t); curr_t=curr_t*monomer_t.get_inverse(); } } em::DensityMap* build_cn_dens_assembly( em::DensityMap *subunit_dens, const em::DensityHeader &asmb_dens_header, algebra::Transformation3D monomer_t, int symm_deg){ OwnerPointer ret(em::create_density_map( asmb_dens_header.get_nx(), asmb_dens_header.get_ny(), asmb_dens_header.get_nz(), asmb_dens_header.get_spacing())); ret->set_origin(algebra::Vector3D(asmb_dens_header.get_origin(0), asmb_dens_header.get_origin(1), asmb_dens_header.get_origin(2))); ret->reset_data(0); algebra::Transformation3D curr_t=algebra::get_identity_transformation_3d(); for (int i=0;i trans_subunit = get_transformed(subunit_dens, curr_t); ret->add(subunit_dens); curr_t=curr_t*monomer_t; } return ret.release(); } em::FittingSolutions fit_cn_assembly( atom::Hierarchies mhs, int dn_symm_deg, em::DensityMap *dmap, float threshold, const AlignSymmetric &aligner, bool sample_translation,bool fine_rotational_sampling) { Particles ps; //here change to CA !! for(unsigned int i=0;iget_atom_type()==atom::AT_CA){ ps.push_back(*it); } } // ps.insert(ps.end(),temp_ps.begin(),temp_ps.end()); } algebra::Transformation3Ds alignments; alignments = aligner.get_symm_axis_alignments_from_model_to_density( mhs, sample_translation, fine_rotational_sampling); em::FittingSolutions coarse_sols = em::compute_fitting_scores(ps,dmap, alignments,true);//false //create a rigid body /* core::RigidBody rb = atom::create_rigid_body(mhs); IMP_NEW(core::LeavesRefiner,refiner,(atom::Hierarchy::get_traits())); FloatKey weight_key = atom::Mass::get_mass_key(); IMP::OptimizerStates opts;*/ /* for (int jj=0;jj asmb_map_pca_aligned = em::get_transformed(asmb_map,coarse_sols.get_transformation(0)); //make translation only algebra::Transformation3Ds translations; int symm_axis_ind=symm_mol.get_symmetry_axis_index(); algebra::PrincipalComponentAnalysis pca=symm_mol.get_pca(); algebra::Vector3D symm_axis = pca.get_principal_component(symm_axis_ind); float symm_axis_val=pca.get_principal_value(symm_axis_ind); //decide how much to translate on the symm axis float trans_delta=3.; em::FittingSolutions return_sols; for(float trans_step=0;trans_stepget_origin(); for(int i=0;iset_origin( translations_fit_sols.get_transformation(i).get_transformed(orig)); algebra::Transformation3Ds refined_rot_trans; for(int symm_ind=0;symm_indset_origin(orig); } return return_fit_sols; } float cn_symm_score(atom::Hierarchies mhs, const algebra::Vector3D ¢er, const algebra::Vector3D &direction, int symm_deg){ //apply a transformation to each atom in a monomer and check the distance algebra::Rotation3D rot = algebra::get_rotation_about_axis(direction, 2*PI/symm_deg); algebra::Transformation3D symm_trans(rot, (rot*(-center))+center); core::XYZs monomer_xyz = core::XYZs(core::get_leaves(mhs[0])); core::XYZs second_monomer_xyz = core::XYZs(core::get_leaves(mhs[1])); float distance=0.; for(unsigned int i=0;i dmap = em::read_map(par.get_density_map_filename(), new em::MRCReaderWriter()); AlignSymmetric aligner(dmap,par.get_density_map_threshold(), par.get_cn_symm()); for(unsigned int i=0;i