From 155c80dfe65c28d419c1795ad6bfa9f86cd871f3 Mon Sep 17 00:00:00 2001
From: stefan <stefan@5a81b35b-ba03-0410-adc8-b2c5c5119f08>
Date: Tue, 2 Mar 2010 12:59:22 +0000
Subject: [PATCH] -Optimized mol::Difference()

-Fixed ViewOp Test

git-svn-id: https://dng.biozentrum.unibas.ch/svn/openstructure/trunk@1753 5a81b35b-ba03-0410-adc8-b2c5c5119f08
---
 modules/mol/base/src/view_op.cc        | 54 +++++++++++++++++---------
 modules/mol/base/tests/test_view_op.cc |  6 +--
 2 files changed, 39 insertions(+), 21 deletions(-)

diff --git a/modules/mol/base/src/view_op.cc b/modules/mol/base/src/view_op.cc
index c59ea852a..2999c1274 100644
--- a/modules/mol/base/src/view_op.cc
+++ b/modules/mol/base/src/view_op.cc
@@ -108,42 +108,60 @@ mol::EntityView Difference(const mol::EntityView& ev1,
   Profile diff_time("mol::Difference");
   if (ev1.GetHandle()!=ev2.GetHandle()) {
     throw IntegrityError(combining_not_allowed);
-  }  
-  mol::EntityView diff=ev1.Copy();
-  mol::ChainViewList::const_iterator c_it=ev2.GetChainList().begin();
-  for ( ; c_it!=ev2.GetChainList().end(); ++c_it) {
+  }
+  mol::EntityView diff=ev1.CreateEmptyView();
+  mol::ChainViewList::const_iterator c_it=ev1.GetChainList().begin();
+  for ( ; c_it!=ev1.GetChainList().end(); ++c_it) {
     mol::ChainView cv=*c_it;
-    mol::ChainView cv2=diff.FindChain(cv.GetHandle());
+    mol::ChainView cv2=ev2.FindChain(cv.GetHandle());
     if (!cv2) {
-      continue;
+      diff.AddChain(cv,mol::ViewAddFlag::INCLUDE_ALL);
     } else {
+      bool chain_added = false;
       mol::ResidueViewList::const_iterator r_it=cv.GetResidueList().begin();
       for (; r_it!=cv.GetResidueList().end(); ++r_it) {
         mol::ResidueView rv=*r_it;
         mol::ResidueView rv2=cv2.FindResidue(rv.GetHandle());
         if (!rv2) {
-          continue;
+          if(!chain_added){
+            diff.AddChain(cv);
+            chain_added = true;
+          }
+          diff.AddResidue(rv,mol::ViewAddFlag::INCLUDE_ALL);
         } else {
+          bool residue_added = false;
           mol::AtomViewList::const_iterator a_it=rv.GetAtomList().begin();
           for (; a_it!=rv.GetAtomList().end(); ++a_it) {
-            if (mol::AtomView av=rv2.FindAtom((*a_it).GetHandle())) {
-              rv2.RemoveAtom(av);
+            if (!rv2.FindAtom((*a_it).GetHandle())) {
+              if(!residue_added){
+                diff.AddResidue(rv);
+                residue_added = true;
+              }
+              diff.AddAtom((*a_it).GetHandle(),mol::ViewAddFlag::INCLUDE_ALL);
             }
           }
-          if (rv2.GetAtomList().empty()) {
-            cv2.RemoveResidue(rv2);
-          }
         }
       }
-      if (cv2.GetResidueList().empty()) {
-        diff.RemoveChain(cv2);
-      }
     }
   }
-  BondHandleList bonds=ev2.GetBondList();
-  for (BondHandleList::const_iterator i=bonds.begin(), 
+
+  BondSet bond_set;
+  // prepare for bond insertion
+  BondHandleList bonds=ev1.GetBondList();
+  for (BondHandleList::const_iterator i=bonds.begin(),
        e=bonds.end(); i!=e; ++i) {
-    diff.RemoveBond(*i);
+    bond_set.insert(*i);
+  }
+
+  BondHandleList bond_ev2 = ev2.GetBondList();
+  for (BondHandleList::const_iterator i=bond_ev2.begin(),
+         e=bond_ev2.end(); i!=e; ++i) {
+    bond_set.erase(*i);
+  }
+
+  for (BondSet::const_iterator i=bond_set.begin(),
+       e=bond_set.end(); i!=e; ++i) {
+    diff.AddBond(*i);
   }
   return diff;
 }
diff --git a/modules/mol/base/tests/test_view_op.cc b/modules/mol/base/tests/test_view_op.cc
index eccefc02b..6af7d87f3 100644
--- a/modules/mol/base/tests/test_view_op.cc
+++ b/modules/mol/base/tests/test_view_op.cc
@@ -65,13 +65,13 @@ BOOST_AUTO_TEST_SUITE( mol_base )
 
 BOOST_AUTO_TEST_CASE(test_difference)
 {
-  std::cout << "TEST DIFFERENCE!" << std::endl;
+
   EntityHandle ent=mk_test_ent();
   EntityView full=ent.CreateFullView();
   EntityView v1=ent.Select("aname=A,B,C");
   EntityView diff_view=mol::Difference(full, v1);
 
-  BOOST_CHECK_EQUAL(diff_view.GetBondCount(), 4);
+  BOOST_CHECK_EQUAL(diff_view.GetBondCount(), 5);
   BOOST_CHECK_EQUAL(diff_view.GetAtomCount(), 5);
   BOOST_CHECK_EQUAL(diff_view.GetResidueCount(), 3);
   BOOST_CHECK_EQUAL(diff_view.GetChainCount(), 2);
@@ -103,7 +103,7 @@ BOOST_AUTO_TEST_CASE(test_difference)
   BOOST_CHECK(!find_bond(ent.FindAtom("A", mol::ResNum(1), "B"),
                          ent.FindAtom("A", mol::ResNum(2), "C"),
                          bonds));
-  BOOST_CHECK(!find_bond(ent.FindAtom("A", mol::ResNum(2), "C"),
+  BOOST_CHECK(find_bond(ent.FindAtom("A", mol::ResNum(2), "C"),
                          ent.FindAtom("A", mol::ResNum(2), "D"),
                          bonds));
   BOOST_CHECK(find_bond(ent.FindAtom("B", mol::ResNum(1), "E"),
-- 
GitLab