diff --git a/modules/io/src/mol/sdf_reader.cc b/modules/io/src/mol/sdf_reader.cc index a64a46ec918332e4bdb27af3e6fe0c657ea80352..a34a277b0cb8b547f378a7cb9b1a42c4d9283fe6 100644 --- a/modules/io/src/mol/sdf_reader.cc +++ b/modules/io/src/mol/sdf_reader.cc @@ -85,7 +85,10 @@ void SDFReader::Import(mol::EntityHandle& ent) } else if (version_ == "V2000" && line_num<=bond_count_+atom_count_+4) { AddBond(ParseBond(line, line_num), line_num, ent, editor); } else if (version_ == "V2000" && boost::iequals(line.substr(0,6), "M CHG")) { - AddCharge(ParseMCharge(line, line_num), line_num, ent, editor); + auto charges = ParseMCharge(line, line_num); + for (const charge_data& c : charges) { + AddCharge(c, line_num, ent, editor); + } } else if (boost::iequals(line.substr(0,2), "> ")) { // parse data items int data_header_start = line.find('<'); @@ -385,8 +388,9 @@ void SDFReader::ResetCharges() } -SDFReader::charge_data SDFReader::ParseMCharge(const String& line, int line_num) +std::vector<SDFReader::charge_data> SDFReader::ParseMCharge(const String& line, int line_num) { + std::vector<charge_data> charges; LOG_TRACE( "line: [" << line << "]" ); @@ -394,22 +398,24 @@ SDFReader::charge_data SDFReader::ParseMCharge(const String& line, int line_num) ResetCharges(); } - if(line.length()<15 || line.length()>17) { + if(line.length()<15) { // Handle the case where we have trailing space characters - if (line.length()>17 && boost::trim_copy(line.substr(17)) == "") { - LOG_DEBUG( "Ignoring trailing space" ); - } - else { - String msg="Bad Charge line %d: Not correct number of characters on the" - " line: %i (should be between 15 and 17)"; - throw IOException(str(format(msg) % line_num % line.length())); - } + String msg="Bad Charge line %d: Not correct number of characters on the" + " line: %i (should be between 15 and 17)"; + throw IOException(str(format(msg) % line_num % line.length())); } - String atom_index=line.substr(10,3); - String charge=line.substr(14,3); + int nn=boost::lexical_cast<int>(boost::trim_copy(line.substr(6,3))); + LOG_TRACE( "Line contains " << nn << " charge(s)" ); + charges.reserve(nn); + + for (int i = 0; i < nn; i++) { + String atom_index=line.substr(10 + i * 8, 3); + String charge=line.substr(14 + i * 8, 3); + charges.push_back(std::make_tuple(atom_index, charge)); + } - return std::make_tuple(atom_index, charge); + return charges; } void SDFReader::AddCharge(const charge_data& charge_tuple, int line_num, mol::EntityHandle& ent, diff --git a/modules/io/src/mol/sdf_reader.hh b/modules/io/src/mol/sdf_reader.hh index f704462c2c93d9467b1bab3ba933b28ab7e50f25..59e733a937a3ed0dcb7171deec9ff9a32dd808ae 100644 --- a/modules/io/src/mol/sdf_reader.hh +++ b/modules/io/src/mol/sdf_reader.hh @@ -69,7 +69,7 @@ private: void AddBond(const bond_data& bond_tuple, int line_num, mol::EntityHandle& ent, mol::XCSEditor& editor); - charge_data ParseMCharge(const String& line, int line_num); + std::vector<charge_data> ParseMCharge(const String& line, int line_num); void AddCharge(const charge_data& charge_tuple, int line_num, mol::EntityHandle& ent, mol::XCSEditor& editor); void ResetCharges(); diff --git a/modules/io/tests/test_io_sdf.py b/modules/io/tests/test_io_sdf.py index 5ca35b7fe4f576f7a16830fceb9c9f71b815b425..7277a399d5a58ca696f50fb19e0775345999313a 100644 --- a/modules/io/tests/test_io_sdf.py +++ b/modules/io/tests/test_io_sdf.py @@ -40,11 +40,13 @@ class TestSDF(unittest.TestCase): def test_MChg(self): ent = io.LoadSDF('testfiles/sdf/m_chg.sdf') + n_at = ent.FindAtom("00001_Simple Ligand", 1, "1") + self.assertEqual(n_at.charge, 1) cl_at = ent.FindAtom("00001_Simple Ligand", 1, "6") self.assertEqual(cl_at.charge, -1) # Charge from atom line is ignored - n_at = ent.FindAtom("00001_Simple Ligand", 1, "1") - self.assertEqual(n_at.charge, 0) + o_at = ent.FindAtom("00001_Simple Ligand", 1, "3") + self.assertEqual(o_at.charge, 0) if __name__== '__main__': from ost import testutils diff --git a/modules/io/tests/testfiles/sdf/m_chg.sdf b/modules/io/tests/testfiles/sdf/m_chg.sdf index e13bae5a74e887fb15e6bd876a38ee642ec09977..da6b3e7d8262c797fb014867657f27f9759565b9 100644 --- a/modules/io/tests/testfiles/sdf/m_chg.sdf +++ b/modules/io/tests/testfiles/sdf/m_chg.sdf @@ -4,7 +4,7 @@ Simple Ligand 6 6 0 0 1 0 999 V2000 0.0000 0.0000 0.0000 N 0 3 0 0 0 0 1.0000 0.0000 0.0000 C 0 0 0 0 0 0 - 0.0000 1.0000 0.0000 O 0 0 0 0 0 0 + 0.0000 1.0000 0.0000 O 0 5 0 0 0 0 1.0000 1.0000 0.0000 S 0 0 0 0 0 0 2.0000 2.0000 0.0000 C 0 0 0 0 0 0 -1.0000 -1.0000 0.0000 Cl 0 0 0 0 0 0 @@ -14,6 +14,6 @@ Simple Ligand 2 4 1 0 0 0 3 4 1 0 0 0 4 5 3 0 0 0 -M CHG 1 6 -1 +M CHG 2 1 1 6 -1 M END $$$$