From 4e41b55e4aeab494ed38ac9479a3f02a346b31f8 Mon Sep 17 00:00:00 2001
From: Marco Biasini <marco.biasini@unibas.ch>
Date: Wed, 13 Oct 2010 18:41:09 +0200
Subject: [PATCH] added CoordGroupHandle.Filter(sel)

The method filters a trajectory by only keeping the positions of atoms
present in "sel".
---
 modules/mol/base/pymod/export_coord_group.cc |  1 +
 modules/mol/base/src/coord_group.cc          | 41 ++++++++++++++++++--
 modules/mol/base/src/coord_group.hh          |  4 ++
 3 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/modules/mol/base/pymod/export_coord_group.cc b/modules/mol/base/pymod/export_coord_group.cc
index 90efa24de..5589268af 100644
--- a/modules/mol/base/pymod/export_coord_group.cc
+++ b/modules/mol/base/pymod/export_coord_group.cc
@@ -58,6 +58,7 @@ void export_CoordGroup()
     .def("GetAtomList",&CoordGroupHandle::GetAtomList)
     .def("__getitem__",cg_getitem)
     .def("__setitem__",cg_setitem)
+    .def("Filter", &CoordGroupHandle::Filter)
   ;
 
   def("CreateCoordGroup",CreateCoordGroup);
diff --git a/modules/mol/base/src/coord_group.cc b/modules/mol/base/src/coord_group.cc
index df0b1a5de..4dcabf68b 100644
--- a/modules/mol/base/src/coord_group.cc
+++ b/modules/mol/base/src/coord_group.cc
@@ -18,10 +18,10 @@
 //------------------------------------------------------------------------------
 #include <ost/invalid_handle.hh>
 #include <ost/integrity_error.hh>
-
+#include <ost/log.hh>
 #include <ost/mol/in_mem_coord_source.hh>
-#include <ost/mol/entity_handle.hh>
-
+#include <ost/mol/view_op.hh>
+#include <ost/mol/mol.hh>
 #include "coord_group.hh"
 
 namespace ost { namespace mol {
@@ -154,4 +154,39 @@ void CoordGroupHandle::Capture(uint frame)
   }  
 }
 
+CoordGroupHandle CoordGroupHandle::Filter(const EntityView& selected) const
+{
+  this->CheckValidity();
+  std::vector<unsigned long> indices;
+  EntityHandle new_ent;  
+  if (!selected.IsValid()) {
+    indices.reserve(this->GetAtomCount());
+    for (size_t i=0;i<this->GetAtomCount(); ++i) {
+      indices.push_back(i);
+    }
+    new_ent=this->GetEntity().Copy();
+  } else {
+    AtomViewList atoms=selected.GetAtomList();
+    indices.reserve(atoms.size());
+    for (AtomViewList::const_iterator i=atoms.begin(), 
+         e=atoms.end(); i!=e; ++i) {
+      indices.push_back(i->GetIndex());
+    }
+    new_ent=CreateEntityFromView(selected, false);
+  }
+
+  CoordGroupHandle filtered_cg=CreateCoordGroup(new_ent.GetAtomList());
+  std::vector<geom::Vec3> vecs(indices.size());
+  for (size_t i=0; i<this->GetFrameCount(); ++i) {
+    LOG_INFO("Filtering frame " << i << "/" << this->GetFrameCount());
+    CoordFramePtr frame=this->GetFrame(i);
+    for (std::vector<unsigned long>::const_iterator 
+         j=indices.begin(), e2=indices.end(); j!=e2; ++j) {
+      vecs[j-indices.begin()]=(*frame)[*j];
+    }
+    filtered_cg.AddFrame(vecs);
+  }
+  return filtered_cg;
+}
+
 }} // ns
diff --git a/modules/mol/base/src/coord_group.hh b/modules/mol/base/src/coord_group.hh
index 70844a26b..dfa3c8530 100644
--- a/modules/mol/base/src/coord_group.hh
+++ b/modules/mol/base/src/coord_group.hh
@@ -82,6 +82,10 @@ public:
   AtomHandleList GetAtomList() const;
   CoordFramePtr GetFrame(uint frame) const;
   
+  /// \brief return a filtered coord group, containing only the atoms in the 
+  ///     view
+  CoordGroupHandle Filter(const EntityView& selected) const;
+  
   CoordGroupHandle(CoordSourcePtr source);
 private:
   void CheckValidity() const;
-- 
GitLab