00001
00002
00003
00004
00005
00006
00007
00008 #ifndef IMPCORE_XY_Z_H
00009 #define IMPCORE_XY_Z_H
00010
00011 #include "core_config.h"
00012 #include "../macros.h"
00013
00014 #include <IMP/Decorator.h>
00015 #include <IMP/algebra/Vector3D.h>
00016 #include <IMP/algebra/Transformation3D.h>
00017
00018 #include <vector>
00019 #include <limits>
00020
00021 IMPCORE_BEGIN_NAMESPACE
00022
00023
00024
00025
00026
00027
00028
00029 class IMPCOREEXPORT XYZ: public Decorator
00030 {
00031 public:
00032
00033 static FloatKey get_coordinate_key(unsigned int i) {
00034 IMP_USAGE_CHECK(i <3, "Out of range coordinate");
00035 return IMP::internal::xyzr_keys[i];
00036 }
00037
00038 IMP_DECORATOR(XYZ, Decorator);
00039
00040
00041 static XYZ setup_particle(Particle *p,
00042 const algebra::VectorD<3> &v=
00043 algebra::VectorD<3>(0,0,0)) {
00044 p->add_attribute(get_coordinate_key(0),v[0]);
00045 p->add_attribute(get_coordinate_key(1),v[1]);
00046 p->add_attribute(get_coordinate_key(2),v[2]);
00047 return XYZ(p);
00048 }
00049
00050 IMP_DECORATOR_GET_SET(x, get_coordinate_key(0), Float, Float);
00051 IMP_DECORATOR_GET_SET(y, get_coordinate_key(1), Float, Float);
00052 IMP_DECORATOR_GET_SET(z, get_coordinate_key(2), Float, Float);
00053
00054 void set_coordinate(unsigned int i, Float v) {
00055 get_particle()->set_value(get_coordinate_key(i), v);
00056 }
00057
00058 void set_coordinates(const algebra::VectorD<3> &v) {
00059 set_x(v[0]);
00060 set_y(v[1]);
00061 set_z(v[2]);
00062 }
00063
00064
00065 Float get_coordinate(int i) const {
00066 return get_particle()->get_value(get_coordinate_key(i));
00067 }
00068
00069 Float get_derivative(int i) const {
00070 return get_particle()->get_derivative(get_coordinate_key(i));
00071 }
00072
00073 void add_to_derivative(int i, Float v,
00074 DerivativeAccumulator &d) {
00075 get_particle()->add_to_derivative(get_coordinate_key(i), v, d);
00076 }
00077
00078 void add_to_derivatives(const algebra::VectorD<3>& v,
00079 DerivativeAccumulator &d) {
00080 add_to_derivative(0, v[0], d);
00081 add_to_derivative(1, v[1], d);
00082 add_to_derivative(2, v[2], d);
00083 }
00084
00085
00086
00087 bool get_coordinates_are_optimized() const {
00088 return get_particle()->get_is_optimized(get_coordinate_key(0))
00089 && get_particle()->get_is_optimized(get_coordinate_key(1))
00090 && get_particle()->get_is_optimized(get_coordinate_key(2));
00091 }
00092
00093 void set_coordinates_are_optimized(bool tf) const {
00094 get_particle()->set_is_optimized(get_coordinate_key(0), tf);
00095 get_particle()->set_is_optimized(get_coordinate_key(1), tf);
00096 get_particle()->set_is_optimized(get_coordinate_key(2), tf);
00097 }
00098
00099
00100 algebra::VectorD<3> get_vector_to(const XYZ &b) const {
00101 return algebra::VectorD<3>(b.get_coordinate(0) - get_coordinate(0),
00102 b.get_coordinate(1) - get_coordinate(1),
00103 b.get_coordinate(2) - get_coordinate(2));
00104 }
00105
00106
00107
00108
00109 algebra::VectorD<3> get_coordinates() const {
00110 return algebra::VectorD<3>(get_coordinate(0),
00111 get_coordinate(1),
00112 get_coordinate(2));
00113 }
00114
00115
00116
00117
00118 algebra::VectorD<3> get_derivatives() const {
00119 return algebra::VectorD<3>(get_derivative(0),
00120 get_derivative(1),
00121 get_derivative(2));
00122 }
00123
00124 static bool particle_is_instance(Particle *p) {
00125 IMP_USAGE_CHECK((p->has_attribute(get_coordinate_key(2))
00126 && p->has_attribute(get_coordinate_key(0))
00127 && p->has_attribute(get_coordinate_key(1)))
00128 || (!p->has_attribute(get_coordinate_key(2))
00129 && !p->has_attribute(get_coordinate_key(0))
00130 && !p->has_attribute(get_coordinate_key(1))),
00131 "Particle expected to either have all of x,y,z or none.");
00132 return p->has_attribute(get_coordinate_key(2));
00133 }
00134
00135
00136
00137
00138 static const FloatKeys& get_xyz_keys();
00139 };
00140
00141 IMP_OUTPUT_OPERATOR(XYZ);
00142
00143
00144
00145
00146
00147 inline double get_distance(XYZ a, XYZ b) {
00148 return algebra::get_distance(a.get_coordinates(),b.get_coordinates());
00149 }
00150
00151
00152
00153
00154
00155 inline void transform(XYZ a, const algebra::Transformation3D &tr) {
00156 a.set_coordinates(tr.get_transformed(a.get_coordinates()));
00157 }
00158
00159
00160 inline const algebra::VectorD<3> get_geometry(XYZ d) {
00161 return d.get_coordinates();
00162 }
00163
00164
00165 inline const algebra::VectorD<3>& get_geometry(const algebra::VectorD<3> &v) {
00166 return v;
00167 }
00168
00169 inline void set_geometry(XYZ d, const algebra::VectorD<3> &v) {
00170 d.set_coordinates(v);
00171 }
00172
00173 inline void set_geometry(algebra::VectorD<3> &vbase,
00174 const algebra::VectorD<3> &v) {vbase=v;}
00175
00176 IMP_DECORATORS(XYZ, Particles);
00177
00178
00179
00180
00181
00182
00183 IMPCORE_END_NAMESPACE
00184
00185 #endif