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