diff --git a/modules/mol/base/pymod/__init__.py b/modules/mol/base/pymod/__init__.py index 22c485bc0ec5a20295348afad99a0b2be299c231..5e7861c2521f05cfb875c168cbf8a6b51f3303e4 100644 --- a/modules/mol/base/pymod/__init__.py +++ b/modules/mol/base/pymod/__init__.py @@ -32,4 +32,4 @@ def MergeCoordGroups(*coord_groups): cg=CreateCoordGroup(coord_groups[0].atoms) for coord_group in coord_groups: cg.AddFrames(coord_group) - return cg \ No newline at end of file + return cg diff --git a/modules/mol/base/pymod/export_editors.cc b/modules/mol/base/pymod/export_editors.cc index 87c19665b6f50e7231d5088061980443ca6e8de1..e411bc30a9dbb4d4dc24f273ec461ed5019b08af 100644 --- a/modules/mol/base/pymod/export_editors.cc +++ b/modules/mol/base/pymod/export_editors.cc @@ -58,10 +58,6 @@ void (ICSEditor::*rotate_torsion_b)(const AtomHandle&, const AtomHandle&, const AtomHandle&, const AtomHandle&, Real)=&ICSEditor::RotateTorsionAngle; -void (XCSEditor::*set_pos1)(const AtomHandle&, const geom::Vec3&) = &XCSEditor::SetAtomPos; -void (XCSEditor::*set_t_pos1)(const AtomHandle&, const geom::Vec3&) = &XCSEditor::SetAtomTransformedPos; -void (XCSEditor::*set_o_pos1)(const AtomHandle&, const geom::Vec3&) = &XCSEditor::SetAtomOriginalPos; - #if OST_NUMPY_SUPPORT_ENABLED template<typename T, bool O> void set_pos2_nc_t(XCSEditor& e, const AtomHandleList& alist, PyArrayObject* na) @@ -70,12 +66,12 @@ void set_pos2_nc_t(XCSEditor& e, const AtomHandleList& alist, PyArrayObject* na) for(AtomHandleList::const_iterator ait=alist.begin();ait!=alist.end();++ait,++count) { if(O) { e.SetAtomOriginalPos(*ait,geom::Vec3(static_cast<Real>(*reinterpret_cast<T*>(PyArray_GETPTR2(na,count,0))), - static_cast<Real>(*reinterpret_cast<T*>(PyArray_GETPTR2(na,count,1))), - static_cast<Real>(*reinterpret_cast<T*>(PyArray_GETPTR2(na,count,2))))); + static_cast<Real>(*reinterpret_cast<T*>(PyArray_GETPTR2(na,count,1))), + static_cast<Real>(*reinterpret_cast<T*>(PyArray_GETPTR2(na,count,2))))); } else { e.SetAtomTransformedPos(*ait,geom::Vec3(static_cast<Real>(*reinterpret_cast<T*>(PyArray_GETPTR2(na,count,0))), - static_cast<Real>(*reinterpret_cast<T*>(PyArray_GETPTR2(na,count,1))), - static_cast<Real>(*reinterpret_cast<T*>(PyArray_GETPTR2(na,count,2))))); + static_cast<Real>(*reinterpret_cast<T*>(PyArray_GETPTR2(na,count,1))), + static_cast<Real>(*reinterpret_cast<T*>(PyArray_GETPTR2(na,count,2))))); } } } @@ -84,46 +80,46 @@ template<bool O> void set_pos2_t(XCSEditor& e, const AtomHandleList& alist, object pyobj) { size_t acount = alist.size(); - + if(!PyArray_Check(pyobj.ptr())) { throw std::runtime_error("expected a numpy array"); return; } PyArrayObject* na=reinterpret_cast<PyArrayObject*>(pyobj.ptr()); - - if(PyArray_NDIM(na)!=2 || PyArray_DIM(na,0)!=acount || PyArray_DIM(na,1)!=3) { + + if(PyArray_NDIM(na)!=2 || PyArray_DIM(na,0)!=int(acount) || PyArray_DIM(na,1)!=3) { throw std::runtime_error("excpected a numpy array of shape (NAtoms, 3)"); return; } - + if(PyArray_ISCONTIGUOUS(na)) { if(PyArray_TYPE(na)==NPY_FLOAT) { if(O) { - e.SetAtomOriginalPos(alist,reinterpret_cast<float*>(PyArray_DATA(na))); + e.SetAtomOriginalPos(alist,reinterpret_cast<float*>(PyArray_DATA(na))); } else { - e.SetAtomTransformedPos(alist,reinterpret_cast<float*>(PyArray_DATA(na))); + e.SetAtomTransformedPos(alist,reinterpret_cast<float*>(PyArray_DATA(na))); } } else if(PyArray_TYPE(na)==NPY_DOUBLE) { if(O) { - e.SetAtomOriginalPos(alist,reinterpret_cast<double*>(PyArray_DATA(na))); + e.SetAtomOriginalPos(alist,reinterpret_cast<double*>(PyArray_DATA(na))); } else { - e.SetAtomTransformedPos(alist,reinterpret_cast<double*>(PyArray_DATA(na))); + e.SetAtomTransformedPos(alist,reinterpret_cast<double*>(PyArray_DATA(na))); } } else { - throw std::runtime_error("excpected a numpy array of type float or double"); + throw std::runtime_error("expected a numpy array of type float or double"); return; } } else { // non-contiguous #if 0 - throw std::runtime_error("excpected contiguous numpy array"); + throw std::runtime_error("expected contiguous numpy array"); #else if(PyArray_TYPE(na)==NPY_FLOAT) { set_pos2_nc_t<float,O>(e,alist,na); } else if(PyArray_TYPE(na)==NPY_DOUBLE) { set_pos2_nc_t<double,O>(e,alist,na); } else { - throw std::runtime_error("excpected a numpy array of type float or double"); + throw std::runtime_error("expected a numpy array of type float or double"); return; } #endif @@ -131,27 +127,63 @@ void set_pos2_t(XCSEditor& e, const AtomHandleList& alist, object pyobj) } #endif -void set_t_pos2(XCSEditor& e, const AtomHandleList& alist, object pyobj) +void set_pos(XCSEditor& e, object o1, object o2, bool trans) { + extract<AtomHandle> eah(o1); + extract<geom::Vec3> ev3(o2); + if(eah.check() && ev3.check()) { + if(trans) { + e.SetAtomTransformedPos(eah(),ev3()); + } else { + e.SetAtomOriginalPos(eah(),ev3()); + } + return; + } + #if OST_NUMPY_SUPPORT_ENABLED - set_pos2_t<false>(e,alist,pyobj); + + extract<AtomHandleList> eal(o1); + if(eal.check()) { + if(trans) { + set_pos2_t<false>(e,eal(),o2); + } else { + set_pos2_t<true>(e,eal(),o2); + } + return; + } + + std::map<unsigned long,AtomHandle> amap; + EntityHandle eh=e.GetEntity(); + for(AtomHandleIter ait=eh.AtomsBegin(), aite=eh.AtomsEnd(); ait!=aite; ++ait) { + amap[(*ait).GetIndex()]=*ait; + } + + AtomHandleList alist; + for(int i=0;i<len(o1);++i) { + int gid = extract<int>(o1[i]); + std::map<unsigned long,AtomHandle>::iterator ait=amap.find(static_cast<unsigned long>(gid)); + alist.push_back(ait==amap.end() ? AtomHandle() : ait->second); + } + + if(trans) { + set_pos2_t<false>(e,alist,o2); + } else { + set_pos2_t<true>(e,alist,o2); + } + #else - throw std::runtime_error("SetAtomTransformedPos(alist,ndarray) disabled, since numpy support is not compiled in"); + throw std::runtime_error("SetAtom*Pos(...,ndarray) not available, because numpy support not compiled in"); #endif } -void set_o_pos2(XCSEditor& e, const AtomHandleList& alist, object pyobj) +void set_o_pos(XCSEditor& e, object o1, object o2) { -#if OST_NUMPY_SUPPORT_ENABLED - set_pos2_t<true>(e,alist,pyobj); -#else - throw std::runtime_error("SetAtomOriginalPos(alist,ndarray) disabled, since numpy support is not compiled in"); -#endif + set_pos(e,o1,o2,false); } -void set_pos2(XCSEditor& e, const AtomHandleList& alist, object pyobj) +void set_t_pos(XCSEditor& e, object o1, object o2) { - set_t_pos2(e,alist,pyobj); + set_pos(e,o1,o2,true); } } @@ -186,12 +218,9 @@ void export_Editors() ; class_<XCSEditor, bases<EditorBase> >("XCSEditor", no_init) - .def("SetAtomPos", set_pos1) - .def("SetAtomPos", set_pos2) - .def("SetAtomTransformedPos", set_t_pos1) - .def("SetAtomTransformedPos", set_t_pos2) - .def("SetAtomOriginalPos", set_o_pos1) - .def("SetAtomOriginalPos", set_o_pos2) + .def("SetAtomPos", set_t_pos) + .def("SetAtomTransformedPos", set_t_pos) + .def("SetAtomOriginalPos", set_o_pos) .def("ApplyTransform", &XCSEditor::ApplyTransform) .def("SetTransform", &XCSEditor::SetTransform) .def("UpdateICS", &XCSEditor::UpdateICS) diff --git a/modules/mol/base/src/editor_base.cc b/modules/mol/base/src/editor_base.cc index 5ab540f31087e2e6dd18a2161b3525a100d48890..3c1e071ee56b34e4cf90f17acf86f4ef46af6f67 100644 --- a/modules/mol/base/src/editor_base.cc +++ b/modules/mol/base/src/editor_base.cc @@ -196,11 +196,6 @@ TorsionHandle EditorBase::AddTorsion(const String& name, const AtomHandle& a1, } -EditMode EditorBase::GetMode() const -{ - return mode_; -} - void EditorBase::UpdateTrace() { if (mode_==UNBUFFERED_EDIT) { diff --git a/modules/mol/base/src/editor_base.hh b/modules/mol/base/src/editor_base.hh index fd6c63d2a718715ee14fd44128ef88c25a2eff0b..b62aa96252165e0a897d4bc21f6d2dca2ee756bc 100644 --- a/modules/mol/base/src/editor_base.hh +++ b/modules/mol/base/src/editor_base.hh @@ -190,8 +190,11 @@ public: void ReorderAllResidues(); /// \brief Get edit mode of editor - EditMode GetMode() const; + EditMode GetMode() const {return mode_;} + /// \ brief return entity this editor works on + EntityHandle GetEntity() const {return ent_;} + /// \brief change the name of the atom to the new name void RenameAtom(AtomHandle atom, const String& new_name); protected: diff --git a/modules/mol/base/src/entity_handle.hh b/modules/mol/base/src/entity_handle.hh index 559a2cf109fd1a1089d38ead2b60bc4781249584..fff9f6efc306b77df8ca9aa6f6b804f1480329c0 100644 --- a/modules/mol/base/src/entity_handle.hh +++ b/modules/mol/base/src/entity_handle.hh @@ -137,7 +137,7 @@ public: /// /// The two iterators returned by ResiduesBegin() and ResiduesEnd() form a /// half-closed range. It is cheaper to cache the iterator returned by - /// ResiduesEnd() than to call ResiduesEnd() after very loop, i.e. like + /// ResiduesEnd() than to call ResiduesEnd() after every loop, i.e. like /// \code /// // e is an instance of EntityHandle /// for (ResidueHandleIter i=e.ResiduesBegin(), x=e.ResiduesEnd(); i!=x; ++i) { diff --git a/modules/mol/base/src/xcs_editor.cc b/modules/mol/base/src/xcs_editor.cc index 41d6be611684698acffeb0775d865e64ef31c8e0..5a4a6063d92dcf4c58df294a2924baa1b2dbbb23 100644 --- a/modules/mol/base/src/xcs_editor.cc +++ b/modules/mol/base/src/xcs_editor.cc @@ -68,7 +68,7 @@ XCSEditor& XCSEditor::operator=(const XCSEditor& rhs) } void XCSEditor::SetAtomTransformedPos(const AtomHandle& atom, - const geom::Vec3& position) + const geom::Vec3& position) { CheckHandleValidity(atom); atom.Impl()->TransformedPos()=position; @@ -88,15 +88,17 @@ namespace { { bool has_tf=ent->IsTransfIdentity(); for(AtomHandleList::const_iterator ait=alist.begin();ait!=alist.end();++ait) { - ait->Impl()->TransformedPos()[0]=static_cast<Real>(positions[0]); - ait->Impl()->TransformedPos()[1]=static_cast<Real>(positions[1]); - ait->Impl()->TransformedPos()[2]=static_cast<Real>(positions[2]); - positions+=3; - if(has_tf) { - ait->Impl()->OriginalPos()=ait->Impl()->TransformedPos(); - } else { - ait->Impl()->OriginalPos() = geom::Vec3(ent->GetInvTransfMatrix()*geom::Vec4(ait->Impl()->TransformedPos())); + if(ait->IsValid()) { + ait->Impl()->TransformedPos()[0]=static_cast<Real>(positions[0]); + ait->Impl()->TransformedPos()[1]=static_cast<Real>(positions[1]); + ait->Impl()->TransformedPos()[2]=static_cast<Real>(positions[2]); + if(has_tf) { + ait->Impl()->OriginalPos()=ait->Impl()->TransformedPos(); + } else { + ait->Impl()->OriginalPos() = geom::Vec3(ent->GetInvTransfMatrix()*geom::Vec4(ait->Impl()->TransformedPos())); + } } + positions+=3; } ent->MarkICSDirty(); ent->MarkOrganizerDirty(); @@ -116,7 +118,7 @@ void XCSEditor::SetAtomTransformedPos(const AtomHandleList& alist, double *posit } void XCSEditor::SetAtomOriginalPos(const AtomHandle& atom, - const geom::Vec3& position) + const geom::Vec3& position) { CheckHandleValidity(atom); atom.Impl()->OriginalPos()=position; @@ -136,15 +138,17 @@ namespace { { bool has_tf=ent->IsTransfIdentity(); for(AtomHandleList::const_iterator ait=alist.begin();ait!=alist.end();++ait) { - ait->Impl()->OriginalPos()[0]=static_cast<Real>(positions[0]); - ait->Impl()->OriginalPos()[1]=static_cast<Real>(positions[1]); - ait->Impl()->OriginalPos()[2]=static_cast<Real>(positions[2]); - positions+=3; - if(has_tf) { - ait->Impl()->TransformedPos()=ait->Impl()->OriginalPos(); - } else { - ait->Impl()->TransformedPos() = geom::Vec3(ent->GetTransfMatrix()*geom::Vec4(ait->Impl()->OriginalPos())); + if(ait->IsValid()) { + ait->Impl()->OriginalPos()[0]=static_cast<Real>(positions[0]); + ait->Impl()->OriginalPos()[1]=static_cast<Real>(positions[1]); + ait->Impl()->OriginalPos()[2]=static_cast<Real>(positions[2]); + if(has_tf) { + ait->Impl()->TransformedPos()=ait->Impl()->OriginalPos(); + } else { + ait->Impl()->TransformedPos() = geom::Vec3(ent->GetTransfMatrix()*geom::Vec4(ait->Impl()->OriginalPos())); + } } + positions+=3; } ent->MarkICSDirty(); ent->MarkOrganizerDirty(); diff --git a/modules/mol/base/tests/test_numpy.py b/modules/mol/base/tests/test_numpy.py index cad6f764f3308fd26cc702686e6c7575aee877b6..1255425f85ad0bfed89b238f7264d7ec394b367d 100644 --- a/modules/mol/base/tests/test_numpy.py +++ b/modules/mol/base/tests/test_numpy.py @@ -7,6 +7,9 @@ import numpy def v2v(v): return geom.Vec3(float(v[0]),float(v[1]),float(v[2])) +def dd(v1,v2): + return geom.Distance(v1,v2)<1e-8 + class TestNumpy(unittest.TestCase): def setUp(self): pass @@ -17,32 +20,41 @@ class TestNumpy(unittest.TestCase): ch=ed.InsertChain("X") re=ed.AppendResidue(ch,"ALA") a0=ed.InsertAtom(re,"A",geom.Vec3(0,0,0)) - self.assertTrue(a0.GetIndex()==0) + self.assertEqual(a0.GetIndex(),0) a1=ed.InsertAtom(re,"B",geom.Vec3(1,0,0)) - self.assertTrue(a1.GetIndex()==1) + self.assertEqual(a1.GetIndex(),1) a2=ed.InsertAtom(re,"C",geom.Vec3(2,0,0)) - self.assertTrue(a2.GetIndex()==2) + self.assertEqual(a2.GetIndex(),2) a3=ed.InsertAtom(re,"D",geom.Vec3(3,0,0)) - self.assertTrue(a3.GetIndex()==3) + self.assertEqual(a3.GetIndex(),3) - self.assertTrue(geom.Distance(a0.pos,geom.Vec3(0,0,0))<1e-10) - self.assertTrue(geom.Distance(a1.pos,geom.Vec3(1,0,0))<1e-10) - self.assertTrue(geom.Distance(a2.pos,geom.Vec3(2,0,0))<1e-10) - self.assertTrue(geom.Distance(a3.pos,geom.Vec3(3,0,0))<1e-10) + self.assertTrue(dd(a0.pos,geom.Vec3(0,0,0))) + self.assertTrue(dd(a1.pos,geom.Vec3(1,0,0))) + self.assertTrue(dd(a2.pos,geom.Vec3(2,0,0))) + self.assertTrue(dd(a3.pos,geom.Vec3(3,0,0))) - ed.SetAtomTransformedPos(entity.GetAtomList(),numpy.array([[0,1,0],[0,2,0],[0,3,0],[0,4,0]], dtype=numpy.float32)) + ed.SetAtomTransformedPos(entity.GetAtomList(), + numpy.array([[0,1,0],[0,2,0],[0,3,0],[0,4,0]], dtype=numpy.float32)) - self.assertTrue(geom.Distance(a0.pos,geom.Vec3(0,1,0))<1e-10) - self.assertTrue(geom.Distance(a1.pos,geom.Vec3(0,2,0))<1e-10) - self.assertTrue(geom.Distance(a2.pos,geom.Vec3(0,3,0))<1e-10) - self.assertTrue(geom.Distance(a3.pos,geom.Vec3(0,4,0))<1e-10) + self.assertTrue(dd(a0.pos,geom.Vec3(0,1,0))) + self.assertTrue(dd(a1.pos,geom.Vec3(0,2,0))) + self.assertTrue(dd(a2.pos,geom.Vec3(0,3,0))) + self.assertTrue(dd(a3.pos,geom.Vec3(0,4,0))) na=entity.positions - self.assertTrue(geom.Distance(v2v(na[0]),geom.Vec3(0,1,0))<1e-10) - self.assertTrue(geom.Distance(v2v(na[1]),geom.Vec3(0,2,0))<1e-10) - self.assertTrue(geom.Distance(v2v(na[2]),geom.Vec3(0,3,0))<1e-10) - self.assertTrue(geom.Distance(v2v(na[3]),geom.Vec3(0,4,0))<1e-10) + self.assertTrue(dd(v2v(na[0]),geom.Vec3(0,1,0))) + self.assertTrue(dd(v2v(na[1]),geom.Vec3(0,2,0))) + self.assertTrue(dd(v2v(na[2]),geom.Vec3(0,3,0))) + self.assertTrue(dd(v2v(na[3]),geom.Vec3(0,4,0))) + + ed.SetAtomTransformedPos([3,99,2], + numpy.array([[0,0,-3],[-1,-1,-1],[0,0,-2]], dtype=numpy.float32)) + + self.assertTrue(dd(a0.pos,geom.Vec3(0,1,0))) + self.assertTrue(dd(a1.pos,geom.Vec3(0,2,0))) + self.assertTrue(dd(a2.pos,geom.Vec3(0,0,-2))) + self.assertTrue(dd(a3.pos,geom.Vec3(0,0,-3))) if __name__== '__main__': unittest.main()