8 #ifndef IMPCORE_RIGID_BODIES_H 
    9 #define IMPCORE_RIGID_BODIES_H 
   11 #include <IMP/core/core_config.h> 
   12 #include "internal/rigid_bodies.h" 
   23 #include <Eigen/Dense> 
   25 IMPCORE_BEGIN_NAMESPACE
 
   27 IMP_DECORATORS_DECL(RigidMember, RigidMembers);
 
   28 IMP_DECORATORS_DECL(RigidBodyMember, RigidBodyMembers);
 
   90   void add_member_internal(
Particle *p,
 
   99   static void teardown_constraints(
Particle *p);
 
  114   void setup_score_states();
 
  134     return internal::rigid_body_data().quaternion_;
 
  141     if (
get_model()->get_has_attribute(internal::rigid_body_data().members_,
 
  166     return get_member_particle_indexes() + get_body_member_particle_indexes();
 
  191   static void teardown_particle(
RigidBody rb);
 
  193   IMP_CXX11_DEFAULT_COPY_CONSTRUCTOR(
RigidBody);
 
  198     return internal::get_has_required_attributes_for_body(m, pi);
 
  209     return get_reference_frame().get_transformation_to().get_rotation();
 
  217         get_model()->get_attribute(internal::rigid_body_data().quaternion_[0],
 
  219         get_model()->get_attribute(internal::rigid_body_data().quaternion_[1],
 
  221         get_model()->get_attribute(internal::rigid_body_data().quaternion_[2],
 
  223         get_model()->get_attribute(internal::rigid_body_data().quaternion_[3],
 
  226                                 "Rotation is not a unit vector: " << v);
 
  232     bool assume_normalized = 
true;
 
  249   inline void set_reference_frame_lazy
 
  254     get_particle()->set_value(internal::rigid_body_data().quaternion_[0], v[0]);
 
  255     get_particle()->set_value(internal::rigid_body_data().quaternion_[1], v[1]);
 
  256     get_particle()->set_value(internal::rigid_body_data().quaternion_[2], v[2]);
 
  257     get_particle()->set_value(internal::rigid_body_data().quaternion_[3], v[3]);
 
  265   inline void set_rotation_lazy_using_internal_tables
 
  267      double* quaternion_tables[])
 
  272     quaternion_tables[0][pi]=v[0];
 
  273     quaternion_tables[1][pi]=v[1];
 
  274     quaternion_tables[2][pi]=v[2];
 
  275     quaternion_tables[3][pi]=v[3];
 
  280   inline void apply_rotation_lazy_using_internal_tables
 
  282      double* quaternion_tables[])
 
  286       ( quaternion_tables[0][pi],
 
  287         quaternion_tables[1][pi],
 
  288         quaternion_tables[2][pi],
 
  289         quaternion_tables[3][pi] );
 
  291       (cur_rot*rot).get_quaternion();;
 
  292     quaternion_tables[0][pi]=v[0];
 
  293     quaternion_tables[1][pi]=v[1];
 
  294     quaternion_tables[2][pi]=v[2];
 
  295     quaternion_tables[3][pi]=v[3];
 
  298 #endif // IMP_DOXYGEN 
  316   void set_reference_frame_from_members(
const ParticleIndexes &members);
 
  332   void pull_back_members_adjoints(DerivativeAccumulator &da);
 
  340                                  DerivativeAccumulator &da);
 
  355                                  const algebra::Transformation3D &T,
 
  359                                  algebra::Transformation3DAdjoint &DT,
 
  361                                  DerivativeAccumulator &da);
 
  370                                       DerivativeAccumulator &da);
 
  389                                       const algebra::Transformation3D &TA,
 
  390                                       algebra::Transformation3D &TB,
 
  391                                       algebra::Transformation3DAdjoint &DTC,
 
  392                                       algebra::Transformation3DAdjoint &DTA,
 
  393                                       algebra::Transformation3DAdjoint &DTB,
 
  395                                       DerivativeAccumulator &da);
 
  411   IMPCORE_DEPRECATED_METHOD_DECL(2.12)
 
  412   void add_to_derivatives(const algebra::
Vector3D &local_derivative,
 
  413                           const algebra::
Vector3D &local_location,
 
  414                           DerivativeAccumulator &da);
 
  427   IMPCORE_DEPRECATED_METHOD_DECL(2.12)
 
  428   void add_to_derivatives(const algebra::
Vector3D &local_derivative,
 
  429                           const algebra::
Vector3D &global_derivative,
 
  430                           const algebra::
Vector3D &local_location,
 
  431                           const algebra::Rotation3D &rot_local_to_global,
 
  432                           DerivativeAccumulator &da);
 
  449   IMPCORE_DEPRECATED_METHOD_DECL(2.12)
 
  450   void add_to_rotational_derivatives(const algebra::
Vector4D &other_qderiv,
 
  451                                             const algebra::Rotation3D &rot_other_to_local,
 
  452                                             const algebra::Rotation3D &rot_local_to_global,
 
  453                                             DerivativeAccumulator &da);
 
  462   inline 
void add_to_rotational_derivatives(const algebra::
Vector4D &qderiv,
 
  463                                             DerivativeAccumulator &da);
 
  473   inline 
void add_to_torque(const algebra::
Vector3D &torque_local,
 
  474         DerivativeAccumulator &da);
 
  480     for (
unsigned int i = 0; i < 3; ++i) {
 
  487 #if !defined(SWIG) && !defined(IMP_DOXYGEN) 
  490   static double const* access_torque_i_data
 
  495           internal::rigid_body_data().torque_[i];
 
  496     double const* ret=m->access_derivative_data(k);
 
  502   static double* access_torque_i_data
 
  507           internal::rigid_body_data().torque_[i];
 
  508     double* ret=m->access_derivative_data(k);
 
  513   static double const* access_quaternion_i_data
 
  518           internal::rigid_body_data().quaternion_[i];
 
  519     double const* ret=m->FloatAttributeTable::access_attribute_data(k);
 
  524   static double* access_quaternion_i_data
 
  529           internal::rigid_body_data().quaternion_[i];
 
  530     double* ret=m->FloatAttributeTable::access_attribute_data(k);
 
  546   void normalize_rotation();
 
  550   void update_members();
 
  553   algebra::VectorD<4> get_rotational_derivatives() 
const;
 
  556   unsigned int get_number_of_members()
 const {
 
  557     return get_body_member_particle_indexes().size() +
 
  558            get_member_particle_indexes().size();
 
  561   RigidBodyMember get_member(
unsigned int i) 
const;
 
  576   void add_member(ParticleIndexAdaptor p);
 
  583   void add_non_rigid_member(ParticleIndexAdaptor p);
 
  601   void remove_member(ParticleIndexAdaptor p);
 
  607                                               DerivativeAccumulator &da) {
 
  608   for (
unsigned int i = 0; i < 4; ++i) {
 
  609     get_model()->add_to_derivative(internal::rigid_body_data().quaternion_[i],
 
  610                                    get_particle_index(), qderiv[i], da);
 
  617                                    DerivativeAccumulator &da) {
 
  618   for (
unsigned int i = 0; i < 3; ++i) {
 
  619     get_model()->add_to_derivative(internal::rigid_body_data().torque_[i],
 
  620                                    get_particle_index(), torque_local[i], da);
 
  662         "Can only set the internal transformation if member is" 
  663             << 
" a rigid body itself.");
 
  690         "Can only set the internal transformation if member is a " 
  691             << 
"rigid body itself.");
 
  695         get_model()->get_attribute(internal::rigid_body_data().lquaternion_[0],
 
  697         get_model()->get_attribute(internal::rigid_body_data().lquaternion_[1],
 
  699         get_model()->get_attribute(internal::rigid_body_data().lquaternion_[2],
 
  701         get_model()->get_attribute(internal::rigid_body_data().lquaternion_[3],
 
  720   IMP_CXX11_DEFAULT_COPY_CONSTRUCTOR(RigidBodyMember);
 
  724     return internal::get_has_required_attributes_for_member(m, p);
 
  727   static FloatKeys get_internal_coordinate_keys() {
 
  728     return internal::rigid_body_data().child_keys_;
 
  731   static FloatKeys get_internal_rotation_keys() {
 
  732     return internal::rigid_body_data().lquaternion_;
 
  756     return internal::get_has_required_attributes_for_rigid_member(m, p);
 
  776     return internal::get_has_required_attributes_for_non_member(m, p);
 
  786     for (
unsigned int i = 0; i < 3; ++i) {
 
  787       get_model()->add_to_derivative(get_internal_coordinate_keys()[i],
 
  804   IMPCORE_DEPRECATED_METHOD_DECL(2.12)
 
  805   void add_to_internal_rotational_derivatives(
 
  806              const algebra::
Vector4D &local_qderiv,
 
  807              const algebra::Rotation3D &rot_local_to_parent,
 
  808              const algebra::Rotation3D &rot_parent_to_global,
 
  817   void add_to_internal_rotational_derivatives(const algebra::
Vector4D &qderiv,
 
  822         "Can only set derivatives of internal rotation if member is a " 
  823             << 
"rigid body itself.");
 
  824     for (
unsigned int i = 0; i < 4; ++i) {
 
  825       get_model()->add_to_derivative(get_internal_rotation_keys()[i],
 
  834     for (
unsigned int i = 0; i < 3; ++i) {
 
  844     for (
unsigned int i = 0; i < 4; ++i) {
 
  854 class IMPCOREEXPORT RigidMembersRefiner : 
public Refiner {
 
  856   RigidMembersRefiner(std::string name = 
"RigidMembersRefiner%d")
 
  862   virtual const ParticlesTemp 
get_refined(Particle *) 
const 
  865       Model *m, 
const ParticleIndexes &pis) 
const override;
 
  870 IMPCOREEXPORT RigidMembersRefiner *get_rigid_members_refiner();
 
  896   return get_initial_reference_frame(ps[0]->get_model(),
 
  913 IMP_DECORATORS_DEF(RigidMember, RigidMembers);
 
  919                                                  TextOutput(std::cout));
 
  925 IMPCORE_END_NAMESPACE
 
void set_internal_coordinates(const algebra::Vector3D &v) const 
set the internal (local) coordinates for this member 
 
A Modifier on ParticlesTemp. 
 
ParticleIndex get_particle_index() const 
Returns the particle index decorated by this decorator. 
 
algebra::Vector3D get_internal_derivatives() const 
Get derivatives wrt translation component of internal transformation. 
 
algebra::Vector4D get_internal_rotational_derivatives() const 
Get derivatives wrt quaternion component of internal transformation. 
 
Key< 0 > FloatKey
The type used to identify float attributes in the Particles. 
 
A member of a rigid body, it has internal (local) coordinates. 
 
A container for Singletons. 
 
ParticleIndex get_root_rigid_body(RigidMember m)
Return the index of the outer-most rigid body containing the member. 
 
#define IMP_USAGE_CHECK_FLOAT_EQUAL(expra, exprb, message)
 
algebra::Vector3D get_coordinates() const 
 
IMP::algebra::Rotation3D get_rotation() const 
 
#define IMP_DECORATOR_SETUP_1(Name, FirstArgumentType, first_argument_name)
 
#define IMP_OBJECT_METHODS(Name)
Define the basic things needed by any Object. 
 
Take Decorator, Particle or ParticleIndex. 
 
Model * get_model() const 
Returns the Model containing the particle. 
 
ParticlesTemp create_rigid_bodies(Model *m, unsigned int n, bool no_members=false)
 
Index< ParticleIndexTag > ParticleIndex
 
bool get_coordinates_are_optimized() const 
Get whether the coordinates are optimized. 
 
static FloatKeys get_rotation_keys()
Get keys for rotation quaternion. 
 
void add_rigid_body_cache_key(ObjectKey k)
 
A more IMP-like version of the std::vector. 
 
const Vector4D & get_quaternion() const 
Return the quaternion so that it can be stored. 
 
void show_rigid_body_hierarchy(RigidBody rb, TextOutput out=TextOutput(std::cout))
 
Take Decorator, Particle or ParticleIndex. 
 
void clear_particle_caches(ParticleIndex pi)
Clear all the cache attributes of a given particle. 
 
IMP::Vector< IMP::WeakPointer< ModelObject > > ModelObjectsTemp
 
Class for storing model, its restraints, constraints, and particles. 
 
static bool get_is_setup(Model *m, ParticleIndexAdaptor p)
return true if it is a rigid member 
 
virtual bool get_can_refine(Particle *) const 
Return true if this refiner can refine that particle. 
 
void set_reference_frame(const IMP::algebra::ReferenceFrame3D &tr)
Set the current reference frame. 
 
A Cartesian vector in D-dimensions. 
 
Refine a particle into a list of particles. 
 
void set_coordinates(const algebra::Vector3D &v)
set all coordinates from a vector 
 
const Transformation3D & get_transformation_to() const 
Return transformation from local to global coordinates. 
 
static bool get_is_setup(Model *m, ParticleIndex pi)
Return true if the particle is a rigid body. 
 
const ParticleIndexes & get_member_particle_indexes() const 
 
static bool get_is_setup(Model *m, ParticleIndexAdaptor p)
return true if it is a rigid member 
 
virtual ModelObjectsTemp do_get_inputs(Model *m, const ParticleIndexes &pis) const =0
Overload this method to specify the inputs. 
 
Represent an XYZR particle with a sphere. 
 
void set_attribute(TypeKey attribute_key, ParticleIndex particle, Type value)
set the value of particle attribute with the specified key 
 
void add_to_internal_derivatives(const algebra::Vector3D &deriv_parent, DerivativeAccumulator &da)
Add to derivatives of local coordinates. 
 
A decorator for a particle with x,y,z coordinates. 
 
const algebra::Vector3D & get_coordinates() const 
Convert it to a vector. 
 
virtual const ParticlesTemp get_refined(Particle *a) const =0
Refine the passed particle into a set of particles. 
 
A decorator for a particle that is part of a rigid body but not rigid. 
 
Simple 3D rotation class. 
 
void set_internal_transformation(const algebra::Transformation3D &v)
 
Particle * get_particle() const 
Returns the particle decorated by this decorator. 
 
Key< 4 > ObjectKey
The type used to identify an Object attribute. 
 
void set_coordinates_are_optimized(bool tf) const 
Set whether the coordinates are optimized. 
 
void set_coordinates(const algebra::Vector3D ¢er)
sets the global coordinates of this member using XYZ::set_coordinates() 
 
#define IMP_DECORATOR_METHODS(Name, Parent)
 
Abstract class to implement hierarchical methods. 
 
Class to handle individual particles of a Model object. 
 
#define IMP_USAGE_CHECK(expr, message)
A runtime test for incorrect usage of a class or method. 
 
#define IMP_DECORATORS(Name, PluralName, Parent)
Define the types for storing sets of decorators. 
 
void transform(RigidBody a, const algebra::Transformation3D &tr)
Transform a rigid body. 
 
ParticleIndexes get_member_indexes() const 
 
DensityMap * get_transformed(const DensityMap *input, const algebra::Transformation3D &tr, double threshold)
Return a new density map containing a rotated version of the old one. 
 
const ParticleIndexes & get_body_member_particle_indexes() const 
 
A decorator for a rigid body. 
 
algebra::Transformation3D get_internal_transformation() const 
 
Type get_attribute(TypeKey attribute_key, ParticleIndex particle)
get the value of the particle attribute with the specified key 
 
Decorator for a sphere-like particle. 
 
ParticleIndexes get_indexes(const ParticlesTemp &ps)
Get the indexes from a list of particles. 
 
static bool get_is_setup(Model *m, ParticleIndex p)
return true if it is a rigid member 
 
Class for adding derivatives from restraints to the model. 
 
const algebra::Vector3D & get_internal_coordinates() const 
Return the internal (local) coordinates of this member. 
 
IMP::algebra::ReferenceFrame3D get_reference_frame() const