/** * \file PCAFitRestraint.cpp * \brief Calculate match between density and particle pca * * Copyright 2007-2013 IMP Inventors. All rights reserved. * */ #include #include #include IMPEM_BEGIN_NAMESPACE namespace { double get_angle(const algebra::Vector3D &v1, const algebra::Vector3D &v2) { return std::acos((v1*v2)/(v1.get_magnitude()*v2.get_magnitude())); } algebra::PrincipalComponentAnalysis get_pca_from_particles(const core::XYZs &ps_xyz) { //find the pca of the protein algebra::Vector3Ds ps_vecs; for (core::XYZs::const_iterator it = ps_xyz.begin(); it != ps_xyz.end(); it++) { ps_vecs.push_back(it->get_coordinates()); } return algebra::get_principal_components(ps_vecs); } algebra::PrincipalComponentAnalysis get_pca_from_density( DensityMap *dmap, float threshold) { //find the pca of the density map algebra::Vector3Ds vecs=density2vectors(dmap,threshold); return algebra::get_principal_components(vecs); } } PCAFitRestraint::PCAFitRestraint( ParticlesTemp ps, DensityMap *em_map, float threshold, float max_pca_size_diff,float max_angle_diff, float max_centroid_diff, FloatKey weight_key): Restraint(IMP::internal::get_model(ps), "Fit restraint%1%"), max_angle_diff_(algebra::PI*max_angle_diff/180.), max_pca_size_diff_(max_pca_size_diff*max_pca_size_diff), max_centroid_diff_(max_centroid_diff){ target_dens_map_ = em_map; threshold_=threshold; weight_key_=weight_key; IMP_IF_CHECK(USAGE) { for (unsigned int i=0; i< ps.size(); ++i) { IMP_USAGE_CHECK(core::XYZR::particle_is_instance(ps[i]), "Particle " << ps[i]->get_name() << " is not XYZR" << std::endl); IMP_USAGE_CHECK(ps[i]->has_attribute(weight_key), "Particle " << ps[i]->get_name() << " is missing the mass "<< weight_key << std::endl); } } store_particles(ps); dens_pca_ = get_pca_from_density(target_dens_map_,threshold_); IMP_LOG_TERSE( "Finish initialization" << std::endl); } IMP_LIST_IMPL(PCAFitRestraint, Particle, particle,Particle*, Particles); double PCAFitRestraint::unprotected_evaluate(DerivativeAccumulator *accum) const { Float escore;//(1) 0 means that the pcas are (not) matching bool calc_deriv = accum? true: false; algebra::PrincipalComponentAnalysis ps_pca= get_pca_from_particles(core::XYZs(all_ps_)); /* std::cout<<"density PCA:"< max_pca_size_diff_) { IMP_LOG_VERBOSE( "Principal value "<(algebra::PI-max_angle_diff_)))) { IMP_LOG_VERBOSE( "Principal angle "< max_centroid_diff_) { IMP_LOG_VERBOSE( "Pricipal cnetroid distance does not match: " << algebra::get_distance(ps_pca.get_centroid(),dens_pca_.get_centroid()) <<" "<< max_centroid_diff_<(ps); add_particles(ps); } IMPEM_END_NAMESPACE