From 9060e0fc6213523c99a68d196e21f4cd330c5880 Mon Sep 17 00:00:00 2001
From: Niklaus Johner <nij2003@med.cornell.edu>
Date: Wed, 23 Oct 2013 10:35:46 -0400
Subject: [PATCH] Added support for non-orthogonal cells for the
 WrapEntityInPeriodicCell function.

---
 .../alg/pymod/export_structure_analysis.cc    |  2 +-
 modules/mol/alg/src/structure_analysis.cc     | 31 ++++++++++++++-----
 modules/mol/alg/src/structure_analysis.hh     |  2 +-
 3 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/modules/mol/alg/pymod/export_structure_analysis.cc b/modules/mol/alg/pymod/export_structure_analysis.cc
index f9f58347d..707006e3b 100644
--- a/modules/mol/alg/pymod/export_structure_analysis.cc
+++ b/modules/mol/alg/pymod/export_structure_analysis.cc
@@ -31,5 +31,5 @@ void export_StructureAnalysis()
   def("CalculateAverageAgreementWithDensityMap",&CalculateAverageAgreementWithDensityMap,(arg("pos_list"),arg("density_map")));
   def("CalculateAgreementWithDensityMap",&CalculateAgreementWithDensityMap,(arg("pos_list"),arg("density_map")));
 #endif
-  def("WrapEntityInPeriodicCell",&WrapEntityInPeriodicCell,(arg("Entity"),arg("cell_center"),arg("basis_vec"),arg("group_res")=true));
+  def("WrapEntityInPeriodicCell",&WrapEntityInPeriodicCell,(arg("Entity"),arg("cell_center"),arg("ucell_size"),arg("ucell_angles")=geom::Vec3(),arg("group_res")=true));
 }
diff --git a/modules/mol/alg/src/structure_analysis.cc b/modules/mol/alg/src/structure_analysis.cc
index c2d02f0ad..98d433339 100644
--- a/modules/mol/alg/src/structure_analysis.cc
+++ b/modules/mol/alg/src/structure_analysis.cc
@@ -61,8 +61,12 @@ Real CalculateAverageAgreementWithDensityMap(const geom::Vec3List& vl, img::MapH
 }
 
 #endif
-void DLLEXPORT_OST_MOL_ALG WrapEntityInPeriodicCell(EntityHandle eh, const geom::Vec3 cell_center, const geom::Vec3 basis_vec, bool group_residues){
+void DLLEXPORT_OST_MOL_ALG WrapEntityInPeriodicCell(EntityHandle eh, const geom::Vec3 cell_center, const geom::Vec3 ucell_size, \
+                                                    const geom::Vec3 ucell_angles, bool group_residues){
   mol::XCSEditor edi=eh.EditXCS(mol::BUFFERED_EDIT);
+  bool orthogonal;
+  if (ucell_angles==geom::Vec3()){ orthogonal=true; }
+  else { orthogonal=false; }
   if (group_residues) {
     geom::Vec3 cm,wrapped_cm,shift;
     ResidueHandleList residues=eh.GetResidueList();
@@ -71,14 +75,20 @@ void DLLEXPORT_OST_MOL_ALG WrapEntityInPeriodicCell(EntityHandle eh, const geom:
       ResidueHandle r=residues[i];
       AtomHandleList atoms=r.GetAtomList();
       geom::Vec3 ref_pos=atoms[0].GetPos();
-      for (AtomHandleList::iterator a=atoms.begin(), e=atoms.end(); a!=e; ++a) {
-        edi.SetAtomPos((*a),geom::WrapVec3((*a).GetPos(),ref_pos,basis_vec));
-      }
+      if (orthogonal) {
+        for (AtomHandleList::iterator a=atoms.begin(), e=atoms.end(); a!=e; ++a) {
+          edi.SetAtomPos((*a),geom::WrapVec3((*a).GetPos(),ref_pos,ucell_size));
+        }}
+      else {
+        for (AtomHandleList::iterator a=atoms.begin(), e=atoms.end(); a!=e; ++a) {
+          edi.SetAtomPos((*a),geom::WrapVec3((*a).GetPos(),ref_pos,ucell_size,ucell_angles));
+        }}
     }
     for (unsigned int i=0; i<n_residues; ++i) {
       ResidueHandle r=residues[i];
       cm=r.GetCenterOfMass();
-      wrapped_cm=geom::WrapVec3(cm,cell_center,basis_vec);
+      if (orthogonal) {wrapped_cm=geom::WrapVec3(cm,cell_center,ucell_size);}
+      else {wrapped_cm=geom::WrapVec3(cm,cell_center,ucell_size,ucell_angles);}
       if (wrapped_cm==cm) continue;
       AtomHandleList atoms=r.GetAtomList();
       unsigned int n_atoms=r.GetAtomCount();
@@ -90,9 +100,14 @@ void DLLEXPORT_OST_MOL_ALG WrapEntityInPeriodicCell(EntityHandle eh, const geom:
   }
   else {
     AtomHandleList atoms=eh.GetAtomList();
-    for (AtomHandleList::iterator a=atoms.begin(), e=atoms.end(); a!=e; ++a) {
-      edi.SetAtomPos((*a),geom::WrapVec3((*a).GetPos(),cell_center,basis_vec));
-    }
+    if (orthogonal){
+      for (AtomHandleList::iterator a=atoms.begin(), e=atoms.end(); a!=e; ++a) {
+        edi.SetAtomPos((*a),geom::WrapVec3((*a).GetPos(),cell_center,ucell_size));
+      }}
+    else {
+      for (AtomHandleList::iterator a=atoms.begin(), e=atoms.end(); a!=e; ++a) {
+        edi.SetAtomPos((*a),geom::WrapVec3((*a).GetPos(),cell_center,ucell_size,ucell_angles));
+      }}
   }
 }
 
diff --git a/modules/mol/alg/src/structure_analysis.hh b/modules/mol/alg/src/structure_analysis.hh
index 7ad8ad575..bafd70887 100644
--- a/modules/mol/alg/src/structure_analysis.hh
+++ b/modules/mol/alg/src/structure_analysis.hh
@@ -37,6 +37,6 @@ namespace ost { namespace mol { namespace alg {
   std::vector<Real> DLLEXPORT_OST_MOL_ALG CalculateAgreementWithDensityMap(const geom::Vec3List& vl, img::MapHandle& density_map);
   Real DLLEXPORT_OST_MOL_ALG CalculateAverageAgreementWithDensityMap(const geom::Vec3List& vl, img::MapHandle& density_map);
 #endif
-  void DLLEXPORT_OST_MOL_ALG WrapEntityInPeriodicCell(EntityHandle eh, const geom::Vec3 cell_center, const geom::Vec3 basis_vec, bool group_res=true);
+  void DLLEXPORT_OST_MOL_ALG WrapEntityInPeriodicCell(EntityHandle eh, const geom::Vec3 cell_center, const geom::Vec3 ucell_size, const geom::Vec3 ucell_angles=geom::Vec3(), bool group_res=true);
 }}}//ns
 #endif
-- 
GitLab