diff --git a/modules/io/src/mol/pdb_writer.cc b/modules/io/src/mol/pdb_writer.cc index 25faae932e3bcb292a26b56ba8628c59a68990b3..00778bc0ed64c7ca7a47a0ad4949d80d5218bf1b 100644 --- a/modules/io/src/mol/pdb_writer.cc +++ b/modules/io/src/mol/pdb_writer.cc @@ -141,7 +141,14 @@ void write_atom(std::ostream& ostr, FormattedLine& line, } } } - line(22, 4)=fmt::LPaddedInt(res.GetNumber().GetNum()); + + int num = res.GetNumber().GetNum(); + if(num < -999 || num > 9999) { + throw IOException("Residue number from " + res.GetQualifiedName() + + " is out of range supported by the PDB format " + "(-999 to 9999)"); + } + line(22, 4)=fmt::LPaddedInt(num); if (ins_code!=0) { line[26]=ins_code; } diff --git a/modules/io/tests/test_io_pdb.cc b/modules/io/tests/test_io_pdb.cc index ff4d3a8dbdfb70988274a0611802cc7413bded60..919092e5bcad7d88fc89bc5d3e5f862e394f31ce 100644 --- a/modules/io/tests/test_io_pdb.cc +++ b/modules/io/tests/test_io_pdb.cc @@ -781,6 +781,60 @@ BOOST_AUTO_TEST_CASE(res_name_too_long) BOOST_CHECK_THROW(writer.Write(ent), IOException); } +BOOST_AUTO_TEST_CASE(res_num_too_low) +{ + std::stringstream out; + PDBWriter writer(out, IOProfile()); + + mol::EntityHandle ent=mol::CreateEntity(); + mol::XCSEditor edi=ent.EditXCS(); + mol::ChainHandle ch = edi.InsertChain(String(1, 'A'));; + mol::ResidueHandle r = edi.AppendResidue(ch, "ARG"); + edi.InsertAtom(r,"N", geom::Vec3(26.861, 50.841, 38.803), "N"); + edi.InsertAtom(r,"CA", geom::Vec3(27.437, 49.969, 37.786), "C"); + edi.InsertAtom(r,"C", geom::Vec3(26.336, 48.959, 37.429), "C"); + edi.InsertAtom(r,"O", geom::Vec3(25.745, 48.313, 38.312), "O"); + edi.InsertAtom(r,"CB", geom::Vec3(28.653, 49.266, 38.349), "C"); + edi.InsertAtom(r,"CG", geom::Vec3(29.870, 50.188, 38.416), "C"); + edi.InsertAtom(r,"CD", geom::Vec3(31.033, 49.532, 39.173), "C"); + edi.InsertAtom(r,"NE", geom::Vec3(32.318, 50.244, 39.125), "N"); + edi.InsertAtom(r,"CZ", geom::Vec3(33.462, 49.750, 39.679), "C"); + edi.InsertAtom(r,"NH1", geom::Vec3(33.522, 48.572, 40.308), "N"); + edi.InsertAtom(r,"NH2", geom::Vec3(34.610, 50.427, 39.597), "N"); + + edi.SetResidueNumber(r, mol::ResNum(-999)); + BOOST_CHECK_NO_THROW(writer.Write(ent)); + edi.SetResidueNumber(r, mol::ResNum(-1000)); + BOOST_CHECK_THROW(writer.Write(ent), IOException); +} + +BOOST_AUTO_TEST_CASE(res_num_too_high) +{ + std::stringstream out; + PDBWriter writer(out, IOProfile()); + + mol::EntityHandle ent=mol::CreateEntity(); + mol::XCSEditor edi=ent.EditXCS(); + mol::ChainHandle ch = edi.InsertChain(String(1, 'A'));; + mol::ResidueHandle r = edi.AppendResidue(ch, "ARG"); + edi.InsertAtom(r,"N", geom::Vec3(26.861, 50.841, 38.803), "N"); + edi.InsertAtom(r,"CA", geom::Vec3(27.437, 49.969, 37.786), "C"); + edi.InsertAtom(r,"C", geom::Vec3(26.336, 48.959, 37.429), "C"); + edi.InsertAtom(r,"O", geom::Vec3(25.745, 48.313, 38.312), "O"); + edi.InsertAtom(r,"CB", geom::Vec3(28.653, 49.266, 38.349), "C"); + edi.InsertAtom(r,"CG", geom::Vec3(29.870, 50.188, 38.416), "C"); + edi.InsertAtom(r,"CD", geom::Vec3(31.033, 49.532, 39.173), "C"); + edi.InsertAtom(r,"NE", geom::Vec3(32.318, 50.244, 39.125), "N"); + edi.InsertAtom(r,"CZ", geom::Vec3(33.462, 49.750, 39.679), "C"); + edi.InsertAtom(r,"NH1", geom::Vec3(33.522, 48.572, 40.308), "N"); + edi.InsertAtom(r,"NH2", geom::Vec3(34.610, 50.427, 39.597), "N"); + + edi.SetResidueNumber(r, mol::ResNum(9999)); + BOOST_CHECK_NO_THROW(writer.Write(ent)); + edi.SetResidueNumber(r, mol::ResNum(10000)); + BOOST_CHECK_THROW(writer.Write(ent), IOException); +} + BOOST_AUTO_TEST_CASE(res_name_mismatch_alt_loc) {