From 30aadd066794667273ca5e2e01f6855927b78905 Mon Sep 17 00:00:00 2001
From: marco <marco@5a81b35b-ba03-0410-adc8-b2c5c5119f08>
Date: Sat, 3 Apr 2010 08:20:17 +0000
Subject: [PATCH] minor tweaks to PDBReader interface

git-svn-id: https://dng.biozentrum.unibas.ch/svn/openstructure/trunk@1917 5a81b35b-ba03-0410-adc8-b2c5c5119f08
---
 modules/io/pymod/export_pdb_io.cc             |  2 +
 modules/io/src/mol/entity_io_crd_handler.cc   |  2 +-
 modules/io/src/mol/pdb_io.hh                  |  9 +++-
 modules/io/src/mol/pdb_reader.cc              | 11 +----
 modules/io/src/mol/pdb_reader.hh              | 11 +++--
 modules/io/tests/test_io_pdb.cc               | 42 ++++++++++++++++++-
 .../testfiles/pdb/join-spread-records.pdb     |  3 ++
 .../testfiles/{test_in.pdb => pdb/simple.pdb} |  0
 8 files changed, 64 insertions(+), 16 deletions(-)
 create mode 100644 modules/io/tests/testfiles/pdb/join-spread-records.pdb
 rename modules/io/tests/testfiles/{test_in.pdb => pdb/simple.pdb} (100%)

diff --git a/modules/io/pymod/export_pdb_io.cc b/modules/io/pymod/export_pdb_io.cc
index 5f252d318..6cc80b813 100644
--- a/modules/io/pymod/export_pdb_io.cc
+++ b/modules/io/pymod/export_pdb_io.cc
@@ -38,12 +38,14 @@ void export_pdb_io()
     .value("SKIP_FAULTY_RECORDS", PDB::SKIP_FAULTY_RECORDS)
     .value("WRITE_MULTIPLE_MODELS", PDB::WRITE_MULTIPLE_MODELS)
     .value("JOIN_SPREAD_ATOM_RECORDS", PDB::JOIN_SPREAD_ATOM_RECORDS)
+    .value("SEQUENTIAL_ATOM_IMPORT", PDB::SEQUENTIAL_ATOM_IMPORT)
   ;
   class_<PDBReader, boost::noncopyable>("PDBReader", init<String>())
     .def("HasNext", &PDBReader::HasNext)
     .def("Import", &PDBReader::Import, 
          X_import(args("entity", "restrict_chains")))
     .def("SetFlags", &PDBReader::SetFlags)
+    .def("GetSequentialAtoms", &PDBReader::GetSequentialAtoms)
   ;
   
   class_<PDBWriter, boost::noncopyable>("PDBWriter", init<String>())
diff --git a/modules/io/src/mol/entity_io_crd_handler.cc b/modules/io/src/mol/entity_io_crd_handler.cc
index 8cd61e3e9..a7870b33e 100644
--- a/modules/io/src/mol/entity_io_crd_handler.cc
+++ b/modules/io/src/mol/entity_io_crd_handler.cc
@@ -259,7 +259,7 @@ mol::CoordGroupHandle LoadCHARMMTraj(const String& crd_fn,
   std::vector<mol::AtomHandle> alist;
   if(boost::filesystem::extension(crd_f)==".pdb") {
     PDBReader reader(crd_f);
-    reader.CollectSequentialAtoms(true);
+    reader.SetFlags(PDB::SEQUENTIAL_ATOM_IMPORT);
     LOGN_MESSAGE("importing coordinate data");
     reader.Import(ent);
     alist = reader.GetSequentialAtoms();
diff --git a/modules/io/src/mol/pdb_io.hh b/modules/io/src/mol/pdb_io.hh
index e14cfb2d4..54edc8a13 100644
--- a/modules/io/src/mol/pdb_io.hh
+++ b/modules/io/src/mol/pdb_io.hh
@@ -57,7 +57,14 @@ struct PDB {
     /// 
     /// By default, the atom 550 will start a new residue instead of being
     /// joined with atoms 43-48 into one residue.
-    JOIN_SPREAD_ATOM_RECORDS=16
+    JOIN_SPREAD_ATOM_RECORDS=16,
+    //// \brief keep track of the order of atom records
+    /// 
+    /// This option is mostly useful in combination with 
+    /// PDB::JOIN_SPREAD_ATOM_RECORDS and CoordGroups.
+    /// 
+    /// The atoms are accessible via PDBReader::GetSequentialAtoms()
+    SEQUENTIAL_ATOM_IMPORT=32
   } Type; 
 };
 
diff --git a/modules/io/src/mol/pdb_reader.cc b/modules/io/src/mol/pdb_reader.cc
index c59be53a6..5ad97901e 100644
--- a/modules/io/src/mol/pdb_reader.cc
+++ b/modules/io/src/mol/pdb_reader.cc
@@ -146,8 +146,6 @@ void PDBReader::Init(const boost::filesystem::path& loc)
   in_.push(instream_);
   if(!infile_) throw IOException("could not open "+loc.string());
   line_num_=0;
-  collect_sequential_atoms_=false;
-
   if(boost::iequals(boost::filesystem::extension(loc), ".pqr")) {
     is_pqr_=true;
   } else {
@@ -261,11 +259,6 @@ void PDBReader::ClearState()
   sequential_atom_list_.clear();
 }
 
-void PDBReader::CollectSequentialAtoms(bool f)
-{
-  collect_sequential_atoms_=f;
-}
-
 std::vector<mol::AtomHandle> PDBReader::GetSequentialAtoms() const
 {
   return sequential_atom_list_;
@@ -501,14 +494,14 @@ void PDBReader::ParseAndAddAtom(const String& line, int line_num,
     } else {
       mol::AtomHandle ah=editor.InsertAltAtom(curr_residue_, aname,
                                               String(1, alt_loc), apos, aprop);
-      if (collect_sequential_atoms_) {
+      if (flags_ & PDB::SEQUENTIAL_ATOM_IMPORT) {
         sequential_atom_list_.push_back(ah);
       }
       ++atom_count_;
     }
   } else {
     mol::AtomHandle ah = editor.InsertAtom(curr_residue_, aname, apos, aprop);
-    if (collect_sequential_atoms_) {
+    if (flags_ & PDB::SEQUENTIAL_ATOM_IMPORT) {
       sequential_atom_list_.push_back(ah);
     }
     ++atom_count_;
diff --git a/modules/io/src/mol/pdb_reader.hh b/modules/io/src/mol/pdb_reader.hh
index a3581510f..b41eef65a 100644
--- a/modules/io/src/mol/pdb_reader.hh
+++ b/modules/io/src/mol/pdb_reader.hh
@@ -49,8 +49,14 @@ public:
   void Import(mol::EntityHandle& ent,
               const String& restrict_chains="");
   void SetFlags(PDBFlags flags);
-  // these two are needed for synchronizing with a traj import
-  void CollectSequentialAtoms(bool f);
+  
+  /// \brief get list of atoms
+  /// 
+  /// The atom handles reflect the order of atom records in the PDb files. This 
+  /// is used to synchronize PDB and coordgroup io.
+  /// 
+  /// By default, the atom list is empty, The PDB::SEQUENTIAL_ATOM_IMPORT flag
+  /// must be set.
   std::vector<mol::AtomHandle> GetSequentialAtoms() const;
 
 private:
@@ -76,7 +82,6 @@ private:
   std::istream& instream_;
   boost::iostreams::filtering_stream<boost::iostreams::input>  in_;
   String curr_line_;
-  bool collect_sequential_atoms_;
   std::vector<mol::AtomHandle> sequential_atom_list_;
   PDBFlags flags_;
   // this needs to be set to true for reading pqr
diff --git a/modules/io/tests/test_io_pdb.cc b/modules/io/tests/test_io_pdb.cc
index 5bc9f8e4c..44b7f3db4 100644
--- a/modules/io/tests/test_io_pdb.cc
+++ b/modules/io/tests/test_io_pdb.cc
@@ -18,6 +18,7 @@
 //------------------------------------------------------------------------------
 #include <ost/mol/mol.hh>
 #include <ost/io/mol/entity_io_pdb_handler.hh>
+#include <ost/io/pdb_reader.hh>
 #define BOOST_TEST_DYN_LINK
 #include <boost/test/unit_test.hpp>
 using boost::unit_test_framework::test_suite;
@@ -29,7 +30,7 @@ BOOST_AUTO_TEST_SUITE( io )
 
 BOOST_AUTO_TEST_CASE(test_io_pdb) 
 {
-  const String fname("testfiles/test_in.pdb");
+  String fname("testfiles/test_in.pdb");
 
   mol::EntityHandle eh=mol::CreateEntity();
   EntityIOPDBHandler pdbh;
@@ -42,7 +43,44 @@ BOOST_AUTO_TEST_CASE(test_io_pdb)
   BOOST_CHECK(EntityIOPDBHandler::ProvidesExport(fname));
   BOOST_CHECK(EntityIOPDBHandler::ProvidesExport("test_in.PDB"));
     
-  pdbh.Import(eh,"testfiles/test_in.pdb");
+  pdbh.Import(eh,"testfiles/pdb/simple.pdb");
+}
+
+BOOST_AUTO_TEST_CASE(join_spread_records_on)
+{
+  String fname("testfiles/pdb/join-spread-records.pdb");
+  PDBReader reader(fname);
+  reader.SetFlags(PDB::JOIN_SPREAD_ATOM_RECORDS);
+  
+  mol::EntityHandle ent=mol::CreateEntity();
+  reader.Import(ent);
+  BOOST_CHECK_EQUAL(ent.GetResidueCount(), 2);
+  mol::ResidueHandle res1=ent.FindResidue("A", mol::ResNum(1));
+  BOOST_CHECK(res1.IsValid());
+  BOOST_CHECK_EQUAL(res1.GetAtomCount(), 2);
+  BOOST_CHECK(res1.FindAtom("N"));
+  BOOST_CHECK(res1.FindAtom("CE"));
+  mol::ResidueHandle res2=ent.FindResidue("A", mol::ResNum(2));  
+  BOOST_CHECK(res2.IsValid());
+  BOOST_CHECK_EQUAL(res2.GetAtomCount(), 1);
+  BOOST_CHECK(res2.FindAtom("N"));
+}
+
+BOOST_AUTO_TEST_CASE(join_spread_records_off)
+{
+  String fname("testfiles/pdb/join-spread-records.pdb");
+  PDBReader reader(fname);
+  mol::EntityHandle ent=mol::CreateEntity();
+  reader.Import(ent);
+  BOOST_CHECK_EQUAL(ent.GetResidueCount(), 2);
+  mol::ResidueHandle res1=ent.FindResidue("A", mol::ResNum(1));
+  BOOST_CHECK(res1.IsValid());
+  BOOST_CHECK_EQUAL(res1.GetAtomCount(), 1);
+  BOOST_CHECK(res1.FindAtom("N"));
+  mol::ResidueHandle res2=ent.FindResidue("A", mol::ResNum(2));  
+  BOOST_CHECK(res2.IsValid());
+  BOOST_CHECK_EQUAL(res2.GetAtomCount(), 1);
+  BOOST_CHECK(res2.FindAtom("N"));
 }
 
 BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file
diff --git a/modules/io/tests/testfiles/pdb/join-spread-records.pdb b/modules/io/tests/testfiles/pdb/join-spread-records.pdb
new file mode 100644
index 000000000..e87adc974
--- /dev/null
+++ b/modules/io/tests/testfiles/pdb/join-spread-records.pdb
@@ -0,0 +1,3 @@
+ATOM      1  N   MET A   1      21.609  35.384  56.705  1.00 41.48           N  
+ATOM      9  N   ARG A   2      20.202  33.112  58.011  1.00 36.39           N  
+ATOM      8  CE  MET A   1      23.233  37.697  58.529  1.00 54.59           C  
diff --git a/modules/io/tests/testfiles/test_in.pdb b/modules/io/tests/testfiles/pdb/simple.pdb
similarity index 100%
rename from modules/io/tests/testfiles/test_in.pdb
rename to modules/io/tests/testfiles/pdb/simple.pdb
-- 
GitLab