diff --git a/modules/io/src/mol/pdb_reader.cc b/modules/io/src/mol/pdb_reader.cc index 8c8e7cbca13a568d497e2ecf1297aa12265c6558..b10069b633afcbf38f512be06e687ef3aa47f0cc 100644 --- a/modules/io/src/mol/pdb_reader.cc +++ b/modules/io/src/mol/pdb_reader.cc @@ -81,6 +81,7 @@ PDBReader::PDBReader(const boost::filesystem::path& loc): void PDBReader::Init(const boost::filesystem::path& loc) { + num_model_records_=0; if (boost::iequals(".gz", boost::filesystem::extension(loc))) { in_.push(boost::iostreams::gzip_decompressor()); } @@ -134,7 +135,7 @@ void PDBReader::Import(mol::EntityHandle& ent, do { if (curr_line_.empty()) { continue; - } + } StringRef curr_line(curr_line_.c_str(), curr_line_.size()); switch(curr_line[0]) { case 'A': @@ -166,6 +167,7 @@ void PDBReader::Import(mol::EntityHandle& ent, } if (IEquals(curr_line.substr(0, 6), StringRef("ENDMDL", 6))) { go_on=false; + num_model_records_=0; break; } case 'H': @@ -182,6 +184,26 @@ void PDBReader::Import(mol::EntityHandle& ent, } else if (IEquals(curr_line.substr(0, 6), StringRef("HELIX ", 6))) { this->ParseHelixEntry(curr_line); } + break; + case 'M': + case 'm': + if (curr_line.size()<6) { + continue; + } + if (IEquals(curr_line.substr(0, 6), StringRef("MODEL ", 6))) { + ++num_model_records_; + if (num_model_records_<2) { + continue; + } + if (PDB::Flags() & PDB::SKIP_FAULTY_RECORDS) { + go_on=false; + num_model_records_=1; + break; + } + String msg=str(format("MODEL record without matching ENDMDL on line %d")%line_num_); + throw IOException(msg); + } + break; case 'S': case 's': if (curr_line.size()<6) { @@ -190,6 +212,7 @@ void PDBReader::Import(mol::EntityHandle& ent, if (IEquals(curr_line.substr(0, 6), StringRef("SHEET ", 6))) { this->ParseStrandEntry(curr_line); } + break; default: break; } diff --git a/modules/io/src/mol/pdb_reader.hh b/modules/io/src/mol/pdb_reader.hh index 6d9f715c6cd9071a471d33427464533bb6b29294..41f7ffb21ca4769554d2b5a9fa3e195e5876a126 100644 --- a/modules/io/src/mol/pdb_reader.hh +++ b/modules/io/src/mol/pdb_reader.hh @@ -72,6 +72,7 @@ private: int atom_count_; int line_num_; bool hard_end_; + int num_model_records_; String restrict_chains_; HSList helix_list_; HSList strand_list_; diff --git a/modules/io/tests/test_io_pdb.cc b/modules/io/tests/test_io_pdb.cc index f8a5d70ad6e31ec3dbe17ba01469d729e0a892a3..8086022d66d9ada41930b0c3ffb1edd82f3b55e0 100644 --- a/modules/io/tests/test_io_pdb.cc +++ b/modules/io/tests/test_io_pdb.cc @@ -19,6 +19,7 @@ #include <ost/mol/mol.hh> #include <ost/io/mol/entity_io_pdb_handler.hh> #include <ost/io/pdb_reader.hh> +#include <ost/io/io_exception.hh> #define BOOST_TEST_DYN_LINK #include <boost/test/unit_test.hpp> using boost::unit_test_framework::test_suite; @@ -179,4 +180,31 @@ BOOST_AUTO_TEST_CASE(only_66_cols) reader.Import(ent); } +BOOST_AUTO_TEST_CASE(no_endmdl_record) +{ + String fname("testfiles/pdb/model.pdb"); + PDBReader reader(fname); + mol::EntityHandle ent=mol::CreateEntity(); + BOOST_CHECK_THROW(reader.Import(ent), IOException); + +} + +BOOST_AUTO_TEST_CASE(no_endmdl_record_fault_tolerant) +{ + String fname("testfiles/pdb/model.pdb"); + PDBReader reader(fname); + PDB::PushFlags(PDB::SKIP_FAULTY_RECORDS); + mol::EntityHandle ent=mol::CreateEntity(); + reader.Import(ent); + BOOST_CHECK_EQUAL(ent.GetChainCount(), 1); + BOOST_CHECK_EQUAL(ent.GetResidueCount(), 1); + BOOST_CHECK_EQUAL(ent.GetAtomCount(), 3); + ent=mol::CreateEntity(); + reader.Import(ent); + BOOST_CHECK_EQUAL(ent.GetChainCount(), 1); + BOOST_CHECK_EQUAL(ent.GetResidueCount(), 1); + BOOST_CHECK_EQUAL(ent.GetAtomCount(), 2); + PDB::PopFlags(); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/modules/io/tests/testfiles/pdb/model.pdb b/modules/io/tests/testfiles/pdb/model.pdb new file mode 100644 index 0000000000000000000000000000000000000000..e11a78b5a5498b913513bd6834ccdf5baf348537 --- /dev/null +++ b/modules/io/tests/testfiles/pdb/model.pdb @@ -0,0 +1,12 @@ +MODEL 1 +ATOM 1 N SER 1 -84.454 -4.478 -71.554 1.00 29.08 +ATOM 2 CA SER 1 -84.657 -3.972 -70.181 1.00 29.08 +ATOM 3 CB SER 1 -86.156 -3.976 -69.839 1.00 29.08 +MODEL 2 +ATOM 1 N SER 1 -84.454 -4.478 -71.554 1.00 29.08 +ATOM 2 CA SER 1 -84.657 -3.972 -70.181 1.00 29.08 +MODEL 3 +ATOM 1 N SER 1 -84.454 -4.478 -71.554 1.00 29.08 +ATOM 2 CA SER 1 -84.657 -3.972 -70.181 1.00 29.08 +ATOM 3 CB SER 1 -86.156 -3.976 -69.839 1.00 29.08 +