From 4b8c54e72b1a8da654a14aeb0e86a6519250093b Mon Sep 17 00:00:00 2001
From: Marco Biasini <marco.biasini@unibas.ch>
Date: Fri, 8 Apr 2011 11:37:41 +0200
Subject: [PATCH] check for duplicate atoms when importing PDB files

It's intentional to only check for duplicate atoms during PDB import an not directly in InsertAtom, since it is completely valid for a few fileformats to have more than one atom with the same name.
---
 modules/io/src/mol/pdb_reader.cc              | 10 +++++++++
 modules/io/tests/test_io_pdb.cc               | 22 +++++++++++++++++++
 .../io/tests/testfiles/pdb/duplicate-atom.pdb |  4 ++++
 3 files changed, 36 insertions(+)
 create mode 100644 modules/io/tests/testfiles/pdb/duplicate-atom.pdb

diff --git a/modules/io/src/mol/pdb_reader.cc b/modules/io/src/mol/pdb_reader.cc
index 7bafa40a0..a1e1b0718 100644
--- a/modules/io/src/mol/pdb_reader.cc
+++ b/modules/io/src/mol/pdb_reader.cc
@@ -647,6 +647,16 @@ void PDBReader::ParseAndAddAtom(const StringRef& line, int line_num,
       ++atom_count_;
     }
   } else {
+    mol::AtomHandle atom=curr_residue_.FindAtom(aname);
+    if (atom.IsValid()) {
+      if (profile_.fault_tolerant) {
+        LOG_WARNING("duplicate atom '" << aname << "' in residue " 
+                    << curr_residue_);
+        return;
+      }
+      throw IOException("duplicate atom '"+aname+"' in residue "+
+                        curr_residue_.GetQualifiedName());
+    }
     ah=editor.InsertAtom(curr_residue_, aname, apos, s_ele);
     ++atom_count_;
   }
diff --git a/modules/io/tests/test_io_pdb.cc b/modules/io/tests/test_io_pdb.cc
index 878a645d3..3b5335eef 100644
--- a/modules/io/tests/test_io_pdb.cc
+++ b/modules/io/tests/test_io_pdb.cc
@@ -463,6 +463,28 @@ BOOST_AUTO_TEST_CASE(res_name_mismatch_pedantic)
   BOOST_CHECK_THROW(reader.Import(ent), IOException);
 }
 
+BOOST_AUTO_TEST_CASE(duplicate_atom_strict)
+{
+  String fname("testfiles/pdb/more-than-one-name.pdb");
+  IOProfile profile;
+  PDBReader reader(fname, profile);
+  mol::EntityHandle ent=mol::CreateEntity();
+  BOOST_CHECK_THROW(reader.Import(ent), IOException);
+}
+
+BOOST_AUTO_TEST_CASE(duplicate_atom_tolerant)
+{
+  String fname("testfiles/pdb/duplicate-atom.pdb");
+  IOProfile profile;
+  profile.fault_tolerant=true;
+  PDBReader reader(fname, profile);
+  mol::EntityHandle ent=mol::CreateEntity();
+  BOOST_CHECK_NO_THROW(reader.Import(ent));
+  BOOST_CHECK_EQUAL(ent.GetChainCount(), 1);
+  BOOST_CHECK_EQUAL(ent.GetResidueCount(), 1);  
+  BOOST_CHECK_EQUAL(ent.GetAtomCount(), 2);
+}
+
 BOOST_AUTO_TEST_CASE(res_name_mismatch_tolerant)
 {
   String fname("testfiles/pdb/more-than-one-name.pdb");
diff --git a/modules/io/tests/testfiles/pdb/duplicate-atom.pdb b/modules/io/tests/testfiles/pdb/duplicate-atom.pdb
new file mode 100644
index 000000000..0cc10b3c8
--- /dev/null
+++ b/modules/io/tests/testfiles/pdb/duplicate-atom.pdb
@@ -0,0 +1,4 @@
+ATOM      1  N   GLU A   7       6.454 -37.820  25.751  1.00 96.94           N  
+ATOM      2  CA  GLU A   7       5.179 -37.470  26.444  1.00 97.55           C  
+ATOM      2  CA  GLU A   7       5.179 -37.470  26.444  1.00 97.55           C  
+END
\ No newline at end of file
-- 
GitLab