Index: kernel/include/IMP/decorators/XYZDecorator.h =================================================================== --- kernel/include/IMP/decorators/XYZDecorator.h (revision 441) +++ kernel/include/IMP/decorators/XYZDecorator.h (working copy) @@ -41,7 +41,7 @@ }); protected: - static FloatKey key_[3]; + static FloatKeys key_; public: IMP_DECORATOR_GET_SET(x, key_[0], Float, Float); @@ -81,6 +81,21 @@ b.get_coordinate(1) - get_coordinate(1), b.get_coordinate(2) - get_coordinate(2)); } + + //! Get a vector containing the keys for x,y,z + /** This is quite handy for initializing movers and things. + */ + const FloatKeys get_xyz_keys() const { + decorator_initialize_static_data(); + return key_; + } + + //! Generate random coordinates in a sphere centered at the vector + void randomize_in_sphere(const Vector3D ¢er, float radius); + + //! Generate random coordinates in a box defined by the vectors + void randomize_in_box(const Vector3D &lower_corner, + const Vector3D &upper_corner); protected: static FloatKey get_coordinate_key(unsigned int i) { IMP_check(i <3, "Out of range coordinate", Index: kernel/src/decorators/XYZDecorator.cpp =================================================================== --- kernel/src/decorators/XYZDecorator.cpp (revision 441) +++ kernel/src/decorators/XYZDecorator.cpp (working copy) @@ -5,17 +5,19 @@ * */ -#include +#include "IMP/decorators/XYZDecorator.h" +#include "IMP/random.h" + +#include + #include -#include "IMP/decorators/XYZDecorator.h" - namespace IMP { // These aren't statically initialized, as that way they may be initialized // before the table that caches them -FloatKey XYZDecorator::key_[3]; +FloatKeys XYZDecorator::key_(3); void XYZDecorator::show(std::ostream &out, std::string prefix) const { @@ -24,7 +26,32 @@ } +void XYZDecorator::randomize_in_sphere(const Vector3D ¢er, + float radius) { + IMP_check(radius > 0, "Radius in randomize must be postive", + ValueException("Radius must be positive")); + Vector3D min(center[0]-radius, center[1]-radius, center[2]-radius); + Vector3D max(center[0]+radius, center[1]+radius, center[2]+radius); + float norm; + do { + randomize_in_box(min, max); + norm=0; + for (int i=0; i< 3; ++i) { + norm+= square(center[i]-get_coordinate(i)); + } + norm = std::sqrt(norm); + } while (norm > radius); +} +void XYZDecorator::randomize_in_box(const Vector3D &min, + const Vector3D &max) { + for (unsigned int i=0; i< 3; ++i) { + IMP_check(min[i] < max[i], "Box for randomize must be non-empty", + ValueException("Box must be non-empty")); + ::boost::uniform_real<> rand(min[i], max[i]); + set_coordinate(i, rand(random_number_generator)); + } +} IMP_DECORATOR_INITIALIZE(XYZDecorator, DecoratorBase, { Index: kernel/test/states/test_nonbonded_list.py =================================================================== --- kernel/test/states/test_nonbonded_list.py (revision 441) +++ kernel/test/states/test_nonbonded_list.py (working copy) @@ -31,9 +31,8 @@ p= IMP.Particle() m.add_particle(p) d=IMP.XYZDecorator.create(p) - d.set_x(random.uniform(0,10)) - d.set_y(random.uniform(0,10)) - d.set_z(random.uniform(0,10)) + d.randomize_in_box(IMP.Vector3D(0,0,0), + IMP.Vector3D(10,10,10)); s= IMP.AllNonbondedListScoreState(m.get_particles()) m.add_score_state(s) o= OnePair() @@ -83,13 +82,11 @@ d=IMP.XYZDecorator.create(p) ps.append(p) if (i < 25): - d.set_x(random.uniform(0,10)) - d.set_y(random.uniform(0,10)) - d.set_z(random.uniform(0,10)) + d.randomize_in_box(IMP.Vector3D(0,0,0), + IMP.Vector3D(10,10,10)); else: - d.set_x(random.uniform(60,70)) - d.set_y(random.uniform(60,70)) - d.set_z(random.uniform(60,70)) + d.randomize_in_box(IMP.Vector3D(60,60,60), + IMP.Vector3D(70,70,70)); s= IMP.AllNonbondedListScoreState(ps) m.add_score_state(s) o= OnePair() @@ -106,9 +103,8 @@ p= IMP.Particle() m.add_particle(p) d=IMP.XYZDecorator.create(p) - d.set_x(random.uniform(0,10)) - d.set_y(random.uniform(0,10)) - d.set_z(random.uniform(0,10)) + d.randomize_in_box(IMP.Vector3D(0,0,0), + IMP.Vector3D(10,10,10)); if (i < 5): ps0.append(p) else: @@ -128,9 +124,8 @@ p= IMP.Particle() m.add_particle(p) d=IMP.XYZDecorator.create(p) - d.set_x(random.uniform(0,10)) - d.set_y(random.uniform(0,10)) - d.set_z(random.uniform(0,10)) + d.randomize_in_box(IMP.Vector3D(0,0,0), + IMP.Vector3D(10,10,10)); p.add_attribute(rk, i, False) d.set_coordinates_are_optimized(True) s= IMP.AllSphereNonbondedListScoreState(m.get_particles(), rk) @@ -148,9 +143,8 @@ p= IMP.Particle() m.add_particle(p) d=IMP.XYZDecorator.create(p) - d.set_x(random.uniform(0,10)) - d.set_y(random.uniform(0,10)) - d.set_z(random.uniform(0,10)) + d.randomize_in_box(IMP.Vector3D(0,0,0), + IMP.Vector3D(10,10,10)); p.add_attribute(rk, random.uniform(0,1000), False) d.set_coordinates_are_optimized(True) s= IMP.AllSphereNonbondedListScoreState(m.get_particles(), rk)