diff --git a/modules/io/src/mol/sdf_reader.cc b/modules/io/src/mol/sdf_reader.cc index 72488aa989ec1bc26e690d211fb39ae25cad4b06..a64a46ec918332e4bdb27af3e6fe0c657ea80352 100644 --- a/modules/io/src/mol/sdf_reader.cc +++ b/modules/io/src/mol/sdf_reader.cc @@ -55,27 +55,37 @@ SDFReader::SDFReader(std::istream& instream) this->ClearState(boost::filesystem::path("")); } +boost::iostreams::filtering_stream<boost::iostreams::input>& SDFReader::GetLine( + boost::iostreams::filtering_stream<boost::iostreams::input>& in, + String& line) + // Read next line from in and place it in line. + // Remove trailing \r characters. +{ + std::getline(in, line); + size_t cr_pos = line.find("\r"); + if (cr_pos != String::npos) { + LOG_TRACE( "Remove CR@" << cr_pos); + line.erase(cr_pos); + } + return in; +} + // import data from provided stream void SDFReader::Import(mol::EntityHandle& ent) { String line; mol::XCSEditor editor=ent.EditXCS(mol::BUFFERED_EDIT); - while (std::getline(in_,line)) { + while (GetLine(in_,line)) { ++line_num; - // std::getline removes EOL character but may leave a DOS CR (\r) in Unix - size_t cr_pos = line.find("\r"); - if (cr_pos != String::npos) { - LOG_TRACE( "Remove CR@" << cr_pos); - line.erase(cr_pos); - } - if (line_num<=4) { - ParseAndAddHeader(line, line_num, ent, editor); - } else if (line_num<=atom_count_+4) { - ParseAndAddAtom(line, line_num, ent, true, editor); - } else if (line_num<=bond_count_+atom_count_+4) { - ParseAndAddBond(line, line_num, ent, editor); + ParseHeader(line, line_num, ent, editor); + } else if (version_ == "V2000" && line_num<=atom_count_+4) { + AddAtom(ParseAtom(line, line_num), line_num, ent, true, editor); + } 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); } else if (boost::iequals(line.substr(0,2), "> ")) { // parse data items int data_header_start = line.find('<'); @@ -89,13 +99,15 @@ void SDFReader::Import(mol::EntityHandle& ent) throw IOException(str(format(msg) % line_num)); } String data_value=""; - while(std::getline(in_,line) && !boost::iequals(line, "")) { + while(GetLine(in_,line) && !boost::iequals(line, "")) { data_value.append(line); } curr_chain_.SetStringProp(data_header, data_value); } else if (boost::iequals(line, "$$$$")) { LOG_VERBOSE("MOLECULE " << curr_chain_.GetName() << " (" << chain_count_ << ") added.") NextMolecule(); + } else if (version_ == "V3000") { + ProcessV3000Line(line, ent, editor); } } @@ -117,6 +129,10 @@ void SDFReader::ClearState(const boost::filesystem::path& loc) atom_count_=0; bond_count_=0; line_num=0; + version_=""; + v3000_bond_block_=false; + v3000_atom_block_=false; + charges_reset_=false; } void SDFReader::NextMolecule() @@ -125,12 +141,16 @@ void SDFReader::NextMolecule() atom_count_=0; bond_count_=0; line_num=0; + version_=""; + v3000_bond_block_=false; + v3000_atom_block_=false; + charges_reset_=false; curr_residue_ = ost::mol::ResidueHandle(); curr_chain_ = ost::mol::ChainHandle(); } -void SDFReader::ParseAndAddHeader(const String& line, int line_num, - mol::EntityHandle& ent, mol::XCSEditor& editor) +void SDFReader::ParseHeader(const String& line, int line_num, + mol::EntityHandle& ent, mol::XCSEditor& editor) { LOG_TRACE( "line: [" << line << "]" ); format chain_fmter("%05i_%s"); @@ -165,34 +185,41 @@ void SDFReader::ParseAndAddHeader(const String& line, int line_num, throw IOException(str(format(msg) % line_num % line.length())); } String version_str=line.substr(34, 5); - if (version_str != "V2000") { + if (version_str == "V2000" || version_str == "V3000") { + version_=version_str; + } + else { String msg="Unsupported SDF version: %s."; throw IOException(str(format(msg) % version_str)); } + // Counts will be overridden in V3000 String s_anum=line.substr(0,3); - try { - atom_count_=boost::lexical_cast<int>(boost::trim_copy(s_anum)); - } catch(boost::bad_lexical_cast&) { - String msg="Bad counts line %d: Can't convert number of atoms" - " '%s' to integral constant."; - throw IOException(str(format(msg) % line_num % s_anum)); - } String s_bnum=line.substr(3,3); - try { - bond_count_=boost::lexical_cast<int>(boost::trim_copy(s_bnum)); - } catch(boost::bad_lexical_cast&) { - String msg="Bad counts line %d: Can't convert number of bonds" - " '%s' to integral constant."; - throw IOException(str(format(msg) % line_num % s_bnum)); - } + SetCounts(s_anum, s_bnum, line_num); break; } } } -void SDFReader::ParseAndAddAtom(const String& line, int line_num, - mol::EntityHandle& ent, bool hetatm, - mol::XCSEditor& editor) +void SDFReader::SetCounts(const String& anum, const String bnum, int line_num) +{ + try { + atom_count_=boost::lexical_cast<int>(boost::trim_copy(anum)); + } catch(boost::bad_lexical_cast&) { + String msg="Bad counts line %d: Can't convert number of atoms" + " '%s' to integral constant."; + throw IOException(str(format(msg) % line_num % anum)); + } + try { + bond_count_=boost::lexical_cast<int>(boost::trim_copy(bnum)); + } catch(boost::bad_lexical_cast&) { + String msg="Bad counts line %d: Can't convert number of bonds" + " '%s' to integral constant."; + throw IOException(str(format(msg) % line_num % bnum)); + } +} + +SDFReader::atom_data SDFReader::ParseAtom(const String& line, int line_num) { LOG_TRACE( "line: [" << line << "]" ); @@ -215,6 +242,16 @@ void SDFReader::ParseAndAddAtom(const String& line, int line_num, String s_ele=line.substr(31,3); String s_charge=line.substr(36,3); + return std::make_tuple(anum, s_posx, s_posy, s_posz, s_ele, s_charge); +} + +void SDFReader::AddAtom(const atom_data& atom_tuple, int line_num, mol::EntityHandle& ent, + bool hetatm, mol::XCSEditor& editor) +{ + int anum; + String s_posx, s_posy, s_posz, s_ele, s_charge; + tie(anum, s_posx, s_posy, s_posz, s_ele, s_charge) = atom_tuple; + geom::Vec3 apos; try { apos=geom::Vec3(boost::lexical_cast<Real>(boost::trim_copy(s_posx)), @@ -262,8 +299,7 @@ void SDFReader::ParseAndAddAtom(const String& line, int line_num, } -void SDFReader::ParseAndAddBond(const String& line, int line_num, - mol::EntityHandle& ent, mol::XCSEditor& editor) +SDFReader::bond_data SDFReader::ParseBond(const String& line, int line_num) { LOG_TRACE( "line: [" << line << "]" ); @@ -283,10 +319,20 @@ void SDFReader::ParseAndAddBond(const String& line, int line_num, String s_first_name=line.substr(0,3); String s_second_name=line.substr(3,3); String s_type=line.substr(6,3); - String first_name, second_name; + + return std::make_tuple(s_first_name, s_second_name, s_type); +} + +void SDFReader::AddBond(const bond_data& bond_tuple, int line_num, mol::EntityHandle& ent, + mol::XCSEditor& editor) +{ + String s_first_name, s_second_name, s_type; + tie(s_first_name, s_second_name, s_type) = bond_tuple; + unsigned char type; mol::BondHandle bond; + String first_name, second_name; first_name=boost::trim_copy(s_first_name); second_name=boost::trim_copy(s_second_name); @@ -323,4 +369,295 @@ void SDFReader::ParseAndAddBond(const String& line, int line_num, << s_type << ") "); } + +void SDFReader::ResetCharges() +// from doc of V2000 Atom Block: +// > Retained for compatibility with older Ctabs, M CHG and M RAD lines take +// > precedence. +// Therefore we must reset all charges of the residue if we encounter an +// M CHG line. +{ + LOG_DEBUG("Resetting all charges to 0."); + for (mol::AtomHandle & atom : curr_residue_.GetAtomList()) { + atom.SetCharge(0.0); + } + charges_reset_=true; +} + + +SDFReader::charge_data SDFReader::ParseMCharge(const String& line, int line_num) +{ + + LOG_TRACE( "line: [" << line << "]" ); + + if (!charges_reset_) { + ResetCharges(); + } + + if(line.length()<15 || line.length()>17) { + // 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 atom_index=line.substr(10,3); + String charge=line.substr(14,3); + + return std::make_tuple(atom_index, charge); +} + + void SDFReader::AddCharge(const charge_data& charge_tuple, int line_num, mol::EntityHandle& ent, + mol::XCSEditor& editor) +{ + String s_atom_index, s_charge; + tie(s_atom_index, s_charge) = charge_tuple; + + int atom_index; + Real charge; + + try { + atom_index=boost::lexical_cast<int>(boost::trim_copy(s_atom_index)); + if (atom_index > atom_count_) { + String msg="Bad charge line %d: Atom index" + " '%d' greater than number of atoms in the molecule (%d)."; + throw IOException(str(format(msg) % line_num % atom_index % atom_count_)); + } else if (atom_index < 1) { + String msg="Bad charge line %d: Atom index %d < 1."; + throw IOException(str(format(msg) % line_num % atom_index)); + } + } catch(boost::bad_lexical_cast&) { + String msg="Bad charge line %d: Can't convert atom index" + " '%s' to integral constant."; + throw IOException(str(format(msg) % line_num % s_atom_index)); + } + + try { + charge=boost::lexical_cast<Real>(boost::trim_copy(s_charge)); + } catch(boost::bad_lexical_cast&) { + String msg="Bad charge line %d: Can't convert charge" + " '%s' to real number."; + throw IOException(str(format(msg) % line_num % s_charge)); + } + + curr_residue_.GetAtomList()[atom_index - 1].SetCharge(charge); + + LOG_DEBUG("Setting charge of atom " << atom_index - 1 << " to " << charge); +} + +SDFReader::v3000_line_tokens SDFReader::TokenizeV3000Line(const String& line, + int line_num, + int num_posval) +// Read whitespace-separated tokens from a V3000 line. +// Tokens can be separated by any amount of whitespace. +// The function is guaranteed to return exactly num_posval positional elements, +// or throws an error. It returns any number of keyword elements with only +// syntax checks (ie no checks if the keywords are correct, only well-formed). +{ + std::istringstream v30_stream(line); + std::vector<String> positional; + std::map<String, String> keywords; + String token; + bool keywords_reached = false; + size_t kw_equal_pos; + positional.reserve(num_posval); + + while (v30_stream.tellg() != -1) { + std::getline(v30_stream, token, ' '); + if (token.empty()) { + continue; + } + kw_equal_pos = token.find('='); + if (kw_equal_pos != String::npos) { + keywords_reached = true; + } + if (keywords_reached) { + // Token can contain a list in round brackets + // We don't use them in OST so no fancy parsing, just capture them + // as a string keyword + if (token.find('(') == kw_equal_pos + 1) { + // Search for the closing bracket + while (token.find(')') == String::npos) { + String next_token; + std::getline(v30_stream, next_token, ' '); + token = token + " " + next_token; + } + } + + // Check if keyword is well formed + if (token.size() < 3 // too short + || kw_equal_pos == String::npos // no = + || kw_equal_pos == 0 // no key (starts with =) + || kw_equal_pos == token.size() - 1 // no value (ends with =) + ) { + String msg="Bad V3000 keyword on line %d: '%s'."; + throw IOException(str(format(msg) % line_num % token)); + } + String key = token.substr(0, kw_equal_pos); + String value = token.substr(kw_equal_pos + 1); + keywords.insert({key, value}); + } + else { + positional.push_back(token); + } + } + + int obtained_posval = positional.size(); + if (obtained_posval != num_posval) { + String msg="Bad V3000 line %d: expected %d positional values, got %d."; + throw IOException(str(format(msg) % line_num % num_posval % + obtained_posval)); + } + + return std::make_tuple(positional, keywords); +} + +String SDFReader::CleanupV3000Line(const String& line) +// String cleanup and aggregation for V3000 +// Return a string with no "M V30 " and not ending with - +{ + String v30_line = line; + if (v30_line.substr(0, 7) != "M V30 ") { + String msg="Bad V3000 line %d: starts with '%s'."; + throw IOException(str(format(msg) % line_num % line.substr(0, 6))); + } + + // Handle line continuation character - + while (v30_line.find("-") == v30_line.length()-1) { + // Read and append the next line + String next_line; + GetLine(in_,next_line); + ++line_num; // Update class member + + // Ensure we have a valid next_line + if (next_line.substr(0, 7) != "M V30 ") { + String msg="Bad V3000 line %d: starts with '%s'."; + throw IOException(str(format(msg) % line_num % next_line.substr(0, 6))); + } + // All clear, add data + v30_line = v30_line.erase(v30_line.find("-")) + next_line.substr(7); + LOG_TRACE( "V3000 line: [" << v30_line << "]" ); + } + + // Cleanup the line + return v30_line.substr(7); // We previously ensured it starts with M V30 +} + +SDFReader::atom_data SDFReader::ParseV3000Atom(const String& line, int line_num) +{ + v3000_line_tokens tokens = TokenizeV3000Line(line, line_num, 6); + std::vector<String> posval; + std::map<String, String> keywords; + tie(posval, keywords) = tokens; + + String s_anum = posval[0]; + String atype = posval[1]; + String posx = posval[2]; + String posy = posval[3]; + String posz = posval[4]; + + String chg; + try { + chg = keywords.at("CHG"); + } catch(std::out_of_range&) { + chg = "0"; + } + + int anum; + try { + anum=boost::lexical_cast<int>(boost::trim_copy(s_anum)); + } catch(boost::bad_lexical_cast&) { + String msg="Bad atom index '%s' on line %d."; + throw IOException(str(format(msg) % s_anum % line_num)); + } + + return std::make_tuple(anum, posx, posy, posz, atype, chg); +} + +SDFReader::bond_data SDFReader::ParseV3000Bond(const String& line, int line_num) +{ + v3000_line_tokens tokens = TokenizeV3000Line(line, line_num, 4); + std::vector<String> posval; + tie(posval, std::ignore) = tokens; + + String btype = posval[1]; + String s_first_name = posval[2]; + String s_second_name = posval[3]; + + return std::make_tuple(s_first_name, s_second_name, btype); +} + +std::tuple<String, String> SDFReader::ParseV3000Counts(const String& line, int line_num) +{ + v3000_line_tokens tokens = TokenizeV3000Line(line, line_num, 5); + std::vector<String> posval; + tie(posval, std::ignore) = tokens; + + String anum = posval[0]; + String bnum = posval[1]; + + return std::make_tuple(anum, bnum); +} + +void SDFReader::VerifyV3000Counts() +{ + int actual_atom_count = curr_residue_.GetAtomCount(); + int actual_bond_count = curr_residue_.GetBondCount(); + if (actual_atom_count != atom_count_) { + String msg="Bad counts for molecule ending on line %d: " + "expected %d atoms, got %d."; + throw IOException(str(format(msg) % line_num % atom_count_ % + actual_atom_count)); + } + if (actual_bond_count != bond_count_) { + String msg="Bad counts for molecule ending on line %d: " + "expected %d bonds, got %d."; + throw IOException(str(format(msg) % line_num % bond_count_ % + actual_bond_count)); + } +} + +void SDFReader::ProcessV3000Line(const String& line, + mol::EntityHandle& ent, + mol::XCSEditor& editor) +{ + if (line.substr(0, 6) == "M END") { + VerifyV3000Counts(); + return; + } + String v30_line = CleanupV3000Line(line); + + if (v30_line.substr(0, 6) == "COUNTS") { + String anum, bnum; + std::tie(anum, bnum) = ParseV3000Counts(v30_line.substr(7), line_num); + SetCounts(anum, bnum, line_num); + } + else if (v30_line.substr(0, 10) == "BEGIN ATOM") { + v3000_atom_block_=true; + } + else if (v30_line.substr(0, 8) == "END ATOM") { + v3000_atom_block_=false; + } + else if (v30_line.substr(0, 10) == "BEGIN BOND") { + v3000_bond_block_=true; + } + else if (v30_line.substr(0, 8) == "END BOND") { + v3000_bond_block_=false; + } + else if (v3000_atom_block_) { + AddAtom(ParseV3000Atom(v30_line, line_num), line_num, ent, true, editor); + } + else if (v3000_bond_block_) { + AddBond(ParseV3000Bond(v30_line, line_num), line_num, ent, editor); + } + else { + LOG_TRACE( "ignoring line: [" << v30_line << "]" ); + } +} + }} diff --git a/modules/io/src/mol/sdf_reader.hh b/modules/io/src/mol/sdf_reader.hh index f786f4e5426bf5068022ef0f8ed3657c8481be2c..f704462c2c93d9467b1bab3ba933b28ab7e50f25 100644 --- a/modules/io/src/mol/sdf_reader.hh +++ b/modules/io/src/mol/sdf_reader.hh @@ -22,6 +22,7 @@ #ifndef OST_IO_SDF_READER_HH #define OST_IO_SDF_READER_HH +#include <tuple> #include <boost/iostreams/filtering_stream.hpp> #include <boost/filesystem/fstream.hpp> #include <ost/mol/chain_handle.hh> @@ -30,6 +31,9 @@ namespace ost { namespace io { + + + class DLLEXPORT_OST_IO SDFReader { public: SDFReader(const String& filename); @@ -41,17 +45,45 @@ public: void Import(mol::EntityHandle& ent); private: + typedef std::tuple<int, String, String, String, String, String> atom_data; + typedef std::tuple<String, String, String> bond_data; + typedef std::tuple<String, String> charge_data; + typedef std::tuple<std::vector<String>, std::map<String, String>> v3000_line_tokens; + + boost::iostreams::filtering_stream<boost::iostreams::input>& GetLine( + boost::iostreams::filtering_stream<boost::iostreams::input>& in, + String& line); + void ClearState(const boost::filesystem::path& loc); void NextMolecule(); - void ParseAndAddHeader(const String& line, int line_num, mol::EntityHandle& ent, + void ParseHeader(const String& line, int line_num, mol::EntityHandle& ent, mol::XCSEditor& editor); + void SetCounts(const String& anum, const String bnum, int line_num); - void ParseAndAddAtom(const String& line, int line_num, mol::EntityHandle& ent, - bool hetatm, mol::XCSEditor& editor); + atom_data ParseAtom(const String& line, int line_num); + void AddAtom(const atom_data& atom_tuple, int line_num, mol::EntityHandle& ent, + bool hetatm, mol::XCSEditor& editor); + + bond_data ParseBond(const String& line, int line_num); + 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); + void AddCharge(const charge_data& charge_tuple, int line_num, mol::EntityHandle& ent, + mol::XCSEditor& editor); + void ResetCharges(); - void ParseAndAddBond(const String& line, int line_num, mol::EntityHandle& ent, + // V3000 methods + v3000_line_tokens TokenizeV3000Line(const String& line, int line_num, + int num_posval); + String CleanupV3000Line(const String& line); + void ProcessV3000Line(const String& line, mol::EntityHandle& ent, mol::XCSEditor& editor); + atom_data ParseV3000Atom(const String& line, int line_num); + bond_data ParseV3000Bond(const String& line, int line_num); + std::tuple<String, String> ParseV3000Counts(const String& line, int line_num); + void VerifyV3000Counts(); String curr_chain_name_; mol::ResidueKey curr_res_key_; @@ -65,6 +97,10 @@ private: boost::filesystem::ifstream infile_; std::istream& instream_; boost::iostreams::filtering_stream<boost::iostreams::input> in_; + String version_; + bool v3000_atom_block_; + bool v3000_bond_block_; + bool charges_reset_; }; }} diff --git a/modules/io/tests/CMakeLists.txt b/modules/io/tests/CMakeLists.txt index fbfef7413858ee6fdf249e801ca721f10aeb500d..e19fd631ec247f9ecd8fcf0ef5ff7685572281c0 100644 --- a/modules/io/tests/CMakeLists.txt +++ b/modules/io/tests/CMakeLists.txt @@ -8,6 +8,7 @@ set(OST_IO_UNIT_TESTS test_io_crd.cc test_io_dcd.cc test_io_sdf.cc + test_io_sdf_v3000.cc test_io_sequence_profile.cc test_pir.cc test_iomanager.cc diff --git a/modules/io/tests/test_io_sdf.py b/modules/io/tests/test_io_sdf.py index 735158fc3c38f8ed2345415ae913143f8b7d1bf1..5ca35b7fe4f576f7a16830fceb9c9f71b815b425 100644 --- a/modules/io/tests/test_io_sdf.py +++ b/modules/io/tests/test_io_sdf.py @@ -38,6 +38,13 @@ class TestSDF(unittest.TestCase): ent.FindAtom("00001_Simple Ligand", 1, "6").charge = -4 io.EntityToSDFStr(ent) + def test_MChg(self): + ent = io.LoadSDF('testfiles/sdf/m_chg.sdf') + 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) if __name__== '__main__': from ost import testutils diff --git a/modules/io/tests/test_io_sdf_v3000.cc b/modules/io/tests/test_io_sdf_v3000.cc new file mode 100644 index 0000000000000000000000000000000000000000..e9b26a1fd2e663bf0055cf040f580c6f9a047139 --- /dev/null +++ b/modules/io/tests/test_io_sdf_v3000.cc @@ -0,0 +1,194 @@ +//------------------------------------------------------------------------------ +// This file is part of the OpenStructure project <www.openstructure.org> +// +// Copyright (C) 2008-2020 by the OpenStructure authors +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation; either version 3.0 of the License, or (at your option) +// any later version. +// This library is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +// details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this library; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +//------------------------------------------------------------------------------ +#define BOOST_TEST_DYN_LINK +#include <boost/test/unit_test.hpp> +#include <boost/lexical_cast.hpp> +#include <boost/algorithm/string.hpp> +using boost::unit_test_framework::test_suite; + +#include <ost/test_utils/compare_files.hh> +#include <ost/mol/mol.hh> +#include <ost/io/mol/entity_io_sdf_handler.hh> +#include <ost/io/mol/save_entity.hh> +#include <ost/io/io_exception.hh> + +using namespace ost; +using namespace ost::io; + +BOOST_AUTO_TEST_SUITE( io ); + +BOOST_AUTO_TEST_CASE(simple_sdf_v3000) +{ + mol::EntityHandle eh=mol::CreateEntity(); + EntityIOSDFHandler sdfh; + sdfh.Import(eh,"testfiles/sdf_v3000/simple.sdf"); + + // check compounds/atoms/bonds count + BOOST_CHECK_EQUAL(eh.GetChainCount(), 1); + BOOST_CHECK_EQUAL(eh.GetAtomCount(), 6); + BOOST_CHECK_EQUAL(eh.GetBondCount(), 6); + BOOST_CHECK_CLOSE(eh.GetMass(), Real(121.546997), Real(1e-4)); + + // check atom/bond types + mol::AtomHandle ah=eh.GetAtomList()[0]; + mol::AtomHandle ah2=eh.GetAtomList()[5]; + + BOOST_CHECK_EQUAL(ah.GetElement(), "N"); + BOOST_CHECK_EQUAL(ah2.GetElement(), "CL"); + BOOST_CHECK_CLOSE(ah.GetRadius(), Real(1.55), Real(1e-2)); + BOOST_CHECK_CLOSE(ah2.GetRadius(), Real(1.75), Real(1e-2)); + BOOST_CHECK_CLOSE(ah.GetMass(), Real(14.007), Real(1e-4)); + BOOST_CHECK_CLOSE(ah2.GetMass(), Real(35.453), Real(1e-3)); + BOOST_CHECK_EQUAL(ah.GetBondCount(), 3); + BOOST_CHECK_EQUAL(ah2.GetBondCount(), 1); + BOOST_CHECK_EQUAL(ah.GetCharge(), 1); + BOOST_CHECK_EQUAL(ah2.GetCharge(), 0); + + mol::BondHandle bh=ah.GetBondList()[0]; + BOOST_CHECK_EQUAL(bh.GetBondOrder(), 2); +} + +BOOST_AUTO_TEST_CASE(multiple_sdf_v3000) +{ + mol::EntityHandle eh=mol::CreateEntity(); + EntityIOSDFHandler sdfh; + sdfh.Import(eh,"testfiles/sdf_v3000/multiple.sdf"); + + // check number of compounds + BOOST_CHECK_EQUAL(eh.GetChainCount(), 4); +} + +BOOST_AUTO_TEST_CASE(properties_sdf_v3000) +{ + mol::EntityHandle eh=mol::CreateEntity(); + EntityIOSDFHandler sdfh; + sdfh.Import(eh,"testfiles/sdf_v3000/properties.sdf"); + + // check number of compounds + mol::ChainHandleList chl=eh.GetChainList(); + int count=1; + for (mol::ChainHandleList::iterator i=chl.begin();i!=chl.end();++i,count++) + { + BOOST_REQUIRE(i->HasProp("prop_one")); + BOOST_REQUIRE(i->HasProp("prop_two")); + BOOST_CHECK_CLOSE(boost::lexical_cast<Real>(i->GetStringProp("prop_one")), + Real(count),Real(1e-4)); + BOOST_CHECK_CLOSE(boost::lexical_cast<Real>(i->GetStringProp("prop_two")), + Real(count*(-2.2)),Real(1e-4)); + } +} + +BOOST_AUTO_TEST_CASE(read_sdf_v3000) +{ + const String fname("testfiles/sdf_v3000/compound.sdf"); + + mol::EntityHandle eh=mol::CreateEntity(); + EntityIOSDFHandler sdfh; + + // check import + sdfh.Import(eh,"testfiles/sdf_v3000/compound.sdf"); + + // check atoms/bonds + BOOST_CHECK_EQUAL(eh.GetChainCount(), 4); + BOOST_CHECK_EQUAL(eh.GetAtomCount(), 180); + BOOST_CHECK_EQUAL(eh.GetBondCount(), 188); + + // check molecule name + mol::ChainHandle ch=eh.FindChain("00003_Test Ligand"); + BOOST_CHECK(ch.IsValid()); + + // check properties + BOOST_CHECK(ch.HasProp("r_i_glide_rmsd")); + BOOST_CHECK_EQUAL(boost::lexical_cast<float>(boost::trim_copy + (ch.GetStringProp("r_i_glide_rmsd"))), + 0.543804f); +} + +BOOST_AUTO_TEST_CASE(wrong_atomcount_error_sdf_v3000) +{ + mol::EntityHandle eh=mol::CreateEntity(); + EntityIOSDFHandler sdfh; + BOOST_CHECK_THROW(sdfh.Import(eh,"testfiles/sdf_v3000/wrong_atomcount.sdf"), IOException); +} + +BOOST_AUTO_TEST_CASE(wrong_bondcount_error_sdf_v3000) +{ + mol::EntityHandle eh=mol::CreateEntity(); + EntityIOSDFHandler sdfh; + BOOST_CHECK_THROW(sdfh.Import(eh,"testfiles/sdf_v3000/wrong_bondcount.sdf"), IOException); +} + +BOOST_AUTO_TEST_CASE(wrong_atomlinelength_error_sdf_v3000) +{ + mol::EntityHandle eh=mol::CreateEntity(); + EntityIOSDFHandler sdfh; + + BOOST_CHECK_THROW(sdfh.Import(eh,"testfiles/sdf_v3000/wrong_atomlinelength.sdf"), IOException); +} + +BOOST_AUTO_TEST_CASE(wrong_atompos_error_sdf_v3000) +{ + mol::EntityHandle eh=mol::CreateEntity(); + EntityIOSDFHandler sdfh; + + BOOST_CHECK_THROW(sdfh.Import(eh,"testfiles/sdf_v3000/wrong_atompos.sdf"), IOException); +} + +BOOST_AUTO_TEST_CASE(wrong_charge_error_sdf_v3000) +{ + mol::EntityHandle eh=mol::CreateEntity(); + EntityIOSDFHandler sdfh; + + BOOST_CHECK_THROW(sdfh.Import(eh,"testfiles/sdf_v3000/wrong_charge.sdf"), IOException); +} + +BOOST_AUTO_TEST_CASE(wrong_bondlinelength_error_sdf_v3000) +{ + mol::EntityHandle eh=mol::CreateEntity(); + EntityIOSDFHandler sdfh; + + BOOST_CHECK_THROW(sdfh.Import(eh,"testfiles/sdf_v3000/wrong_bondlinelength.sdf"), IOException); +} + +BOOST_AUTO_TEST_CASE(wrong_bondtype_error_sdf_v3000) +{ + mol::EntityHandle eh=mol::CreateEntity(); + EntityIOSDFHandler sdfh; + + BOOST_CHECK_THROW(sdfh.Import(eh,"testfiles/sdf_v3000/wrong_bondtype.sdf"), IOException); +} + +BOOST_AUTO_TEST_CASE(wrong_bondatomnumber_error_sdf_v3000) +{ + mol::EntityHandle eh=mol::CreateEntity(); + EntityIOSDFHandler sdfh; + + BOOST_CHECK_THROW(sdfh.Import(eh,"testfiles/sdf_v3000/wrong_bondatomnumber.sdf"), IOException); +} + +BOOST_AUTO_TEST_CASE(wrong_keyword_error_sdf_v3000) +{ + mol::EntityHandle eh=mol::CreateEntity(); + EntityIOSDFHandler sdfh; + + BOOST_CHECK_THROW(sdfh.Import(eh,"testfiles/sdf_v3000/wrong_keyword.sdf"), IOException); +} + + +BOOST_AUTO_TEST_SUITE_END(); diff --git a/modules/io/tests/testfiles/sdf/m_chg.sdf b/modules/io/tests/testfiles/sdf/m_chg.sdf new file mode 100644 index 0000000000000000000000000000000000000000..e13bae5a74e887fb15e6bd876a38ee642ec09977 --- /dev/null +++ b/modules/io/tests/testfiles/sdf/m_chg.sdf @@ -0,0 +1,19 @@ +Simple Ligand + + Teststructure + 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 + 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 + 1 2 2 0 0 0 + 1 3 1 0 0 0 + 1 6 1 0 0 0 + 2 4 1 0 0 0 + 3 4 1 0 0 0 + 4 5 3 0 0 0 +M CHG 1 6 -1 +M END +$$$$ diff --git a/modules/io/tests/testfiles/sdf_v3000/compound.sdf b/modules/io/tests/testfiles/sdf_v3000/compound.sdf new file mode 100644 index 0000000000000000000000000000000000000000..c1820344e37589ce52e37fade327060a95adb615 --- /dev/null +++ b/modules/io/tests/testfiles/sdf_v3000/compound.sdf @@ -0,0 +1,660 @@ +Test Ligand + OpenBabel06052308503D + + 0 0 0 0 0 999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 45 47 0 0 0 +M V30 BEGIN ATOM +M V30 1 C 35.9455 5.9021 22.1706 0 +M V30 2 O 34.6074 5.5226 22.4445 0 +M V30 3 C 33.9561 6.2475 23.4088 0 +M V30 4 C 32.6324 6.6232 23.1367 0 +M V30 5 C 34.5295 6.5843 24.6557 0 +M V30 6 C 31.8762 7.3329 24.0856 0 +M V30 7 C 33.7671 7.2733 25.6188 0 +M V30 8 C 32.4286 7.646 25.3459 0 +M V30 9 C 31.5951 8.3119 26.371 0 +M V30 10 C 31.3314 7.914 27.6484 0 +M V30 11 C 31.8735 6.7525 28.4344 0 +M V30 12 O 32.356 5.724 27.9527 0 +M V30 13 N 30.4351 8.7885 28.2094 0 +M V30 14 N 31.7811 6.9129 29.7679 0 +M V30 15 N 30.111 9.7809 27.3482 0 +M V30 16 C 32.3829 6.0325 30.7674 0 +M V30 17 C 30.7767 9.482 26.2306 0 +M V30 18 C 31.3859 4.9676 31.2295 0 +M V30 19 C 30.7144 10.3135 25.0185 0 +M V30 20 C 31.915 10.8059 24.4681 0 +M V30 21 C 31.8995 11.615 23.3143 0 +M V30 22 Cl 33.3805 12.232 22.6834 0 +M V30 23 C 30.6694 11.9024 22.6787 0 +M V30 24 O 30.636 12.6166 21.518 0 +M V30 25 C 29.4673 11.4261 23.2329 0 +M V30 26 C 29.4821 10.6385 24.4075 0 +M V30 27 O 28.2924 10.2274 24.9296 0 +M V30 28 H 36.3421 5.2876 21.3587 0 +M V30 29 H 35.9736 6.9432 21.8453 0 +M V30 30 H 36.6065 5.7791 23.0307 0 +M V30 31 H 32.1915 6.3459 22.1959 0 +M V30 32 H 35.5405 6.2957 24.9105 0 +M V30 33 H 30.8594 7.6089 23.8374 0 +M V30 34 H 34.2045 7.5053 26.5811 0 +M V30 35 H 30.0864 8.7388 29.1508 0 +M V30 36 H 31.3698 7.7591 30.1306 0 +M V30 37 H 33.2889 5.565 30.3864 0 +M V30 38 H 32.6785 6.6486 31.6135 0 +M V30 39 H 31.8211 4.339 32.0105 0 +M V30 40 H 30.4818 5.4213 31.6393 0 +M V30 41 H 31.1006 4.3181 30.401 0 +M V30 42 H 32.8629 10.577 24.9439 0 +M V30 43 H 29.7848 12.6362 21.103 0 +M V30 44 H 28.5336 11.6723 22.7555 0 +M V30 45 H 27.5318 10.6938 24.5843 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 28 +M V30 3 1 1 29 +M V30 4 1 1 30 +M V30 5 1 2 3 +M V30 6 1 3 4 +M V30 7 2 3 5 +M V30 8 2 4 6 +M V30 9 1 4 31 +M V30 10 1 5 7 +M V30 11 1 5 32 +M V30 12 1 6 8 +M V30 13 1 6 33 +M V30 14 2 7 8 +M V30 15 1 7 34 +M V30 16 1 8 9 +M V30 17 2 9 10 +M V30 18 1 9 17 +M V30 19 1 10 11 +M V30 20 1 10 13 +M V30 21 2 11 12 +M V30 22 1 11 14 +M V30 23 1 13 15 +M V30 24 1 13 35 +M V30 25 1 14 16 +M V30 26 1 14 36 +M V30 27 2 15 17 +M V30 28 1 16 18 +M V30 29 1 16 37 +M V30 30 1 16 38 +M V30 31 1 17 19 +M V30 32 1 18 39 +M V30 33 1 18 40 +M V30 34 1 18 41 +M V30 35 1 19 20 +M V30 36 2 19 26 +M V30 37 2 20 21 +M V30 38 1 20 42 +M V30 39 1 21 22 +M V30 40 1 21 23 +M V30 41 1 23 24 +M V30 42 2 23 25 +M V30 43 1 24 43 +M V30 44 1 25 26 +M V30 45 1 25 44 +M V30 46 1 26 27 +M V30 47 1 27 45 +M V30 END BOND +M V30 END CTAB +M END +> <i_i_glide_confnum> +2 + +> <i_i_glide_lignum> +1 + +> <i_i_glide_posenum> +352 + +> <r_i_docking_score> +-8.84426 + +> <r_i_glide_ecoul> +-16.1644 + +> <r_i_glide_einternal> +6.78671 + +> <r_i_glide_emodel> +-96.9661 + +> <r_i_glide_energy> +-62.2146 + +> <r_i_glide_erotb> +0.517993 + +> <r_i_glide_esite> +-0.0291388 + +> <r_i_glide_evdw> +-46.0502 + +> <r_i_glide_gscore> +-8.84426 + +> <r_i_glide_hbond> +-0.960751 + +> <r_i_glide_ligand_efficiency> +-0.327565 + +> <r_i_glide_ligand_efficiency_ln> +-2.0588 + +> <r_i_glide_ligand_efficiency_sa> +-0.982695 + +> <r_i_glide_lipo> +-2.84534 + +> <r_i_glide_metal> +-0 + +> <r_i_glide_rewards> +-0.799851 + +> <r_i_glide_rmsd> +0.6819 + +$$$$ +Test Ligand + OpenBabel06052308503D + + 0 0 0 0 0 999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 45 47 0 0 0 +M V30 BEGIN ATOM +M V30 1 C 34.3938 4.9895 21.4537 0 +M V30 2 O 34.9786 5.7318 22.5298 0 +M V30 3 C 34.145 6.3862 23.4047 0 +M V30 4 C 34.6745 6.7394 24.6654 0 +M V30 5 C 32.7998 6.7274 23.0916 0 +M V30 6 C 33.8742 7.4015 25.612 0 +M V30 7 C 32.0035 7.3913 24.0448 0 +M V30 8 C 32.5275 7.723 25.3191 0 +M V30 9 C 31.6607 8.3431 26.3377 0 +M V30 10 C 31.4133 7.937 27.6169 0 +M V30 11 C 31.9782 6.7689 28.3776 0 +M V30 12 O 32.369 5.715 27.8804 0 +M V30 13 N 30.5206 8.8053 28.2099 0 +M V30 14 N 32.0029 6.9625 29.7121 0 +M V30 15 N 30.1677 9.805 27.357 0 +M V30 16 C 32.5238 6.0208 30.6934 0 +M V30 17 C 30.8244 9.5086 26.2225 0 +M V30 18 C 31.3863 5.1079 31.1861 0 +M V30 19 C 30.7465 10.3438 25.0101 0 +M V30 20 C 31.9316 10.8558 24.4417 0 +M V30 21 C 31.892 11.6586 23.2829 0 +M V30 22 Cl 33.3681 12.254 22.6096 0 +M V30 23 C 30.6518 11.9231 22.66 0 +M V30 24 O 30.5979 12.6244 21.4907 0 +M V30 25 C 29.4612 11.4393 23.2345 0 +M V30 26 C 29.4978 10.6576 24.4073 0 +M V30 27 O 28.313 10.2277 24.9428 0 +M V30 28 H 35.1654 4.4015 20.952 0 +M V30 29 H 33.6444 4.2945 21.836 0 +M V30 30 H 33.93 5.6189 20.6923 0 +M V30 31 H 35.7051 6.503 24.9029 0 +M V30 32 H 32.3569 6.4909 22.1252 0 +M V30 33 H 34.2923 7.6473 26.581 0 +M V30 34 H 30.9795 7.6612 23.8114 0 +M V30 35 H 30.1658 8.7432 29.1625 0 +M V30 36 H 31.6728 7.8452 30.0908 0 +M V30 37 H 33.3536 5.4297 30.2888 0 +M V30 38 H 32.9238 6.5957 31.5354 0 +M V30 39 H 31.7451 4.4444 31.9834 0 +M V30 40 H 30.5677 5.7018 31.5922 0 +M V30 41 H 31.0015 4.4903 30.3675 0 +M V30 42 H 32.8807 10.6312 24.9124 0 +M V30 43 H 29.7389 12.639 21.0888 0 +M V30 44 H 28.5134 11.6612 22.7648 0 +M V30 45 H 27.5338 10.6743 24.5952 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 28 +M V30 3 1 1 29 +M V30 4 1 1 30 +M V30 5 1 2 3 +M V30 6 1 3 4 +M V30 7 2 3 5 +M V30 8 2 4 6 +M V30 9 1 4 31 +M V30 10 1 5 7 +M V30 11 1 5 32 +M V30 12 1 6 8 +M V30 13 1 6 33 +M V30 14 2 7 8 +M V30 15 1 7 34 +M V30 16 1 8 9 +M V30 17 2 9 10 +M V30 18 1 9 17 +M V30 19 1 10 11 +M V30 20 1 10 13 +M V30 21 2 11 12 +M V30 22 1 11 14 +M V30 23 1 13 15 +M V30 24 1 13 35 +M V30 25 1 14 16 +M V30 26 1 14 36 +M V30 27 2 15 17 +M V30 28 1 16 18 +M V30 29 1 16 37 +M V30 30 1 16 38 +M V30 31 1 17 19 +M V30 32 1 18 39 +M V30 33 1 18 40 +M V30 34 1 18 41 +M V30 35 1 19 20 +M V30 36 2 19 26 +M V30 37 2 20 21 +M V30 38 1 20 42 +M V30 39 1 21 22 +M V30 40 1 21 23 +M V30 41 1 23 24 +M V30 42 2 23 25 +M V30 43 1 24 43 +M V30 44 1 25 26 +M V30 45 1 25 44 +M V30 46 1 26 27 +M V30 47 1 27 45 +M V30 END BOND +M V30 END CTAB +M END +> <i_i_glide_confnum> +14 + +> <i_i_glide_lignum> +1 + +> <i_i_glide_posenum> +302 + +> <r_i_docking_score> +-8.79327 + +> <r_i_glide_ecoul> +-16.9687 + +> <r_i_glide_einternal> +5.76514 + +> <r_i_glide_emodel> +-98.4298 + +> <r_i_glide_energy> +-63.3874 + +> <r_i_glide_erotb> +0.517993 + +> <r_i_glide_esite> +-0.00975737 + +> <r_i_glide_evdw> +-46.4187 + +> <r_i_glide_gscore> +-8.79327 + +> <r_i_glide_hbond> +-0.966475 + +> <r_i_glide_ligand_efficiency> +-0.325677 + +> <r_i_glide_ligand_efficiency_ln> +-2.04693 + +> <r_i_glide_ligand_efficiency_sa> +-0.97703 + +> <r_i_glide_lipo> +-2.69167 + +> <r_i_glide_metal> +-0 + +> <r_i_glide_rewards> +-0.777126 + +> <r_i_glide_rmsd> +0.605551 + +$$$$ +Test Ligand + OpenBabel06052308503D + + 0 0 0 0 0 999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 45 47 0 0 0 +M V30 BEGIN ATOM +M V30 1 C 36.2241 5.1749 22.8554 0 +M V30 2 O 35.0609 5.8871 22.4479 0 +M V30 3 C 34.2768 6.4601 23.4276 0 +M V30 4 C 34.7199 6.6807 24.7535 0 +M V30 5 C 32.9608 6.8443 23.074 0 +M V30 6 C 33.8637 7.2655 25.7079 0 +M V30 7 C 32.1001 7.4207 24.0338 0 +M V30 8 C 32.5448 7.6388 25.3572 0 +M V30 9 C 31.6578 8.2493 26.3632 0 +M V30 10 C 31.3829 7.8493 27.6381 0 +M V30 11 C 31.8957 6.6637 28.4136 0 +M V30 12 O 32.3784 5.637 27.9299 0 +M V30 13 N 30.4903 8.7246 28.2064 0 +M V30 14 N 31.7656 6.7961 29.7467 0 +M V30 15 N 30.1647 9.7304 27.3526 0 +M V30 16 C 32.1947 5.8187 30.7363 0 +M V30 17 C 30.843 9.4334 26.233 0 +M V30 18 C 33.6957 5.9781 31.0077 0 +M V30 19 C 30.7874 10.2877 25.0301 0 +M V30 20 C 31.9854 10.7833 24.4695 0 +M V30 21 C 31.9583 11.608 23.3306 0 +M V30 22 Cl 33.4405 12.2408 22.7079 0 +M V30 23 C 30.7247 11.9044 22.7018 0 +M V30 24 O 30.6845 12.6266 21.5474 0 +M V30 25 C 29.5221 11.4297 23.2588 0 +M V30 26 C 29.5448 10.64 24.4309 0 +M V30 27 O 28.3508 10.232 24.9581 0 +M V30 28 H 36.6559 4.6879 21.9802 0 +M V30 29 H 36.9908 5.8287 23.2736 0 +M V30 30 H 35.9784 4.409 23.5916 0 +M V30 31 H 35.7217 6.4151 25.0626 0 +M V30 32 H 32.6094 6.6834 22.0613 0 +M V30 33 H 34.237 7.4405 26.7062 0 +M V30 34 H 31.0912 7.6917 23.745 0 +M V30 35 H 30.1426 8.6905 29.1645 0 +M V30 36 H 31.3915 7.6554 30.1264 0 +M V30 37 H 31.6292 6.0008 31.6531 0 +M V30 38 H 31.9544 4.8033 30.4192 0 +M V30 39 H 34.0395 5.2434 31.7401 0 +M V30 40 H 34.2801 5.8472 30.0923 0 +M V30 41 H 33.9143 6.9734 31.4067 0 +M V30 42 H 32.9388 10.5461 24.9301 0 +M V30 43 H 29.8267 12.6411 21.1471 0 +M V30 44 H 28.5699 11.6759 22.8051 0 +M V30 45 H 27.5929 10.6933 24.609 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 28 +M V30 3 1 1 29 +M V30 4 1 1 30 +M V30 5 1 2 3 +M V30 6 1 3 4 +M V30 7 2 3 5 +M V30 8 2 4 6 +M V30 9 1 4 31 +M V30 10 1 5 7 +M V30 11 1 5 32 +M V30 12 1 6 8 +M V30 13 1 6 33 +M V30 14 2 7 8 +M V30 15 1 7 34 +M V30 16 1 8 9 +M V30 17 2 9 10 +M V30 18 1 9 17 +M V30 19 1 10 11 +M V30 20 1 10 13 +M V30 21 2 11 12 +M V30 22 1 11 14 +M V30 23 1 13 15 +M V30 24 1 13 35 +M V30 25 1 14 16 +M V30 26 1 14 36 +M V30 27 2 15 17 +M V30 28 1 16 18 +M V30 29 1 16 37 +M V30 30 1 16 38 +M V30 31 1 17 19 +M V30 32 1 18 39 +M V30 33 1 18 40 +M V30 34 1 18 41 +M V30 35 1 19 20 +M V30 36 2 19 26 +M V30 37 2 20 21 +M V30 38 1 20 42 +M V30 39 1 21 22 +M V30 40 1 21 23 +M V30 41 1 23 24 +M V30 42 2 23 25 +M V30 43 1 24 43 +M V30 44 1 25 26 +M V30 45 1 25 44 +M V30 46 1 26 27 +M V30 47 1 27 45 +M V30 END BOND +M V30 END CTAB +M END +> <i_i_glide_confnum> +1 + +> <i_i_glide_lignum> +1 + +> <i_i_glide_posenum> +177 + +> <r_i_docking_score> +-8.70173 + +> <r_i_glide_ecoul> +-15.8862 + +> <r_i_glide_einternal> +1.84397 + +> <r_i_glide_emodel> +-99.0481 + +> <r_i_glide_energy> +-62.44 + +> <r_i_glide_erotb> +0.517993 + +> <r_i_glide_esite> +-0.0274759 + +> <r_i_glide_evdw> +-46.5538 + +> <r_i_glide_gscore> +-8.70173 + +> <r_i_glide_hbond> +-0.97397 + +> <r_i_glide_ligand_efficiency> +-0.322286 + +> <r_i_glide_ligand_efficiency_ln> +-2.02562 + +> <r_i_glide_ligand_efficiency_sa> +-0.966858 + +> <r_i_glide_lipo> +-2.74283 + +> <r_i_glide_metal> +-0 + +> <r_i_glide_rewards> +-0.764823 + +> <r_i_glide_rmsd> +0.543804 + +$$$$ +Test Ligand + OpenBabel06052308503D + + 0 0 0 0 0 999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 45 47 0 0 0 +M V30 BEGIN ATOM +M V30 1 C 36.1312 5.0238 22.8745 0 +M V30 2 O 35.3492 6.1234 22.4285 0 +M V30 3 C 34.5144 6.6833 23.3611 0 +M V30 4 C 33.188 6.9515 22.986 0 +M V30 5 C 34.9381 7.0224 24.661 0 +M V30 6 C 32.287 7.546 23.8905 0 +M V30 7 C 34.0422 7.6076 25.572 0 +M V30 8 C 32.7085 7.8735 25.1943 0 +M V30 9 C 31.7655 8.4568 26.1623 0 +M V30 10 C 31.4563 8.0176 27.4151 0 +M V30 11 C 31.9612 6.8234 28.1735 0 +M V30 12 O 32.4816 5.8265 27.6667 0 +M V30 13 N 30.4991 8.8399 27.9505 0 +M V30 14 N 31.7656 6.8973 29.5011 0 +M V30 15 N 30.1623 9.8254 27.0921 0 +M V30 16 C 32.179 5.9073 30.4826 0 +M V30 17 C 30.8968 9.5864 26.0023 0 +M V30 18 C 33.4739 6.3765 31.1528 0 +M V30 19 C 30.8088 10.4312 24.8021 0 +M V30 20 C 31.98 11.0176 24.2785 0 +M V30 21 C 31.9238 11.8291 23.1331 0 +M V30 22 Cl 33.3643 12.5911 22.5784 0 +M V30 23 C 30.6968 12.0157 22.4634 0 +M V30 24 O 30.6398 12.6873 21.2763 0 +M V30 25 C 29.5186 11.4761 23.006 0 +M V30 26 C 29.5649 10.7043 24.1795 0 +M V30 27 O 28.3911 10.2293 24.6826 0 +M V30 28 H 36.6829 4.6047 22.0257 0 +M V30 29 H 36.8626 5.3082 23.636 0 +M V30 30 H 35.4815 4.2419 23.2796 0 +M V30 31 H 32.8514 6.6935 21.9933 0 +M V30 32 H 35.957 6.8606 24.9671 0 +M V30 33 H 31.2689 7.7361 23.5858 0 +M V30 34 H 34.3918 7.8724 26.559 0 +M V30 35 H 30.065 8.7441 28.8594 0 +M V30 36 H 31.3489 7.7378 29.8826 0 +M V30 37 H 31.3881 5.8177 31.2263 0 +M V30 38 H 32.3154 4.9187 30.0437 0 +M V30 39 H 33.8094 5.6628 31.9076 0 +M V30 40 H 34.2829 6.5014 30.4282 0 +M V30 41 H 33.3311 7.3365 31.6549 0 +M V30 42 H 32.9245 10.8652 24.7777 0 +M V30 43 H 29.7851 12.6657 20.8657 0 +M V30 44 H 28.5664 11.6345 22.5199 0 +M V30 45 H 27.6152 10.7061 24.3768 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 1 1 2 +M V30 2 1 1 28 +M V30 3 1 1 29 +M V30 4 1 1 30 +M V30 5 1 2 3 +M V30 6 1 3 4 +M V30 7 2 3 5 +M V30 8 2 4 6 +M V30 9 1 4 31 +M V30 10 1 5 7 +M V30 11 1 5 32 +M V30 12 1 6 8 +M V30 13 1 6 33 +M V30 14 2 7 8 +M V30 15 1 7 34 +M V30 16 1 8 9 +M V30 17 2 9 10 +M V30 18 1 9 17 +M V30 19 1 10 11 +M V30 20 1 10 13 +M V30 21 2 11 12 +M V30 22 1 11 14 +M V30 23 1 13 15 +M V30 24 1 13 35 +M V30 25 1 14 16 +M V30 26 1 14 36 +M V30 27 2 15 17 +M V30 28 1 16 18 +M V30 29 1 16 37 +M V30 30 1 16 38 +M V30 31 1 17 19 +M V30 32 1 18 39 +M V30 33 1 18 40 +M V30 34 1 18 41 +M V30 35 1 19 20 +M V30 36 2 19 26 +M V30 37 2 20 21 +M V30 38 1 20 42 +M V30 39 1 21 22 +M V30 40 1 21 23 +M V30 41 1 23 24 +M V30 42 2 23 25 +M V30 43 1 24 43 +M V30 44 1 25 26 +M V30 45 1 25 44 +M V30 46 1 26 27 +M V30 47 1 27 45 +M V30 END BOND +M V30 END CTAB +M END +> <i_i_glide_confnum> +9 + +> <i_i_glide_lignum> +1 + +> <i_i_glide_posenum> +294 + +> <r_i_docking_score> +-8.69162 + +> <r_i_glide_ecoul> +-14.7519 + +> <r_i_glide_einternal> +5.89466 + +> <r_i_glide_emodel> +-97.7232 + +> <r_i_glide_energy> +-63.1839 + +> <r_i_glide_erotb> +0.517993 + +> <r_i_glide_esite> +-0.0119369 + +> <r_i_glide_evdw> +-48.432 + +> <r_i_glide_gscore> +-8.69162 + +> <r_i_glide_hbond> +-0.870172 + +> <r_i_glide_ligand_efficiency> +-0.321912 + +> <r_i_glide_ligand_efficiency_ln> +-2.02327 + +> <r_i_glide_ligand_efficiency_sa> +-0.965735 + +> <r_i_glide_lipo> +-2.92829 + +> <r_i_glide_metal> +-0 + +> <r_i_glide_rewards> +-0.764823 + +> <r_i_glide_rmsd> +0.463026 + +$$$$ diff --git a/modules/io/tests/testfiles/sdf_v3000/multiple.sdf b/modules/io/tests/testfiles/sdf_v3000/multiple.sdf new file mode 100644 index 0000000000000000000000000000000000000000..339ef0a58f64cb51c493c6296004cda33f1cc37a --- /dev/null +++ b/modules/io/tests/testfiles/sdf_v3000/multiple.sdf @@ -0,0 +1,100 @@ +Simple Ligand 1 + OpenBabel06052308472D +Teststructure + 0 0 0 0 0 999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 6 6 0 0 1 +M V30 BEGIN ATOM +M V30 1 N 0 0 0 0 CHG=1 +M V30 2 C 1 0 0 0 +M V30 3 O 0 1 0 0 +M V30 4 S 1 1 0 0 +M V30 5 C 2 2 0 0 +M V30 6 Cl -1 -1 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 2 1 2 +M V30 2 1 1 3 +M V30 3 1 1 6 +M V30 4 1 2 4 +M V30 5 1 3 4 +M V30 6 3 4 5 +M V30 END BOND +M V30 END CTAB +M END +$$$$ +Simple Ligand 2 + OpenBabel06052308472D +Teststructure + 0 0 0 0 0 999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 6 6 0 0 1 +M V30 BEGIN ATOM +M V30 1 N 0 0 0 0 CHG=1 +M V30 2 C 1 0 0 0 +M V30 3 O 0 1 0 0 +M V30 4 S 1 1 0 0 +M V30 5 C 2 2 0 0 +M V30 6 Cl -1 -1 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 2 1 2 +M V30 2 1 1 3 +M V30 3 1 1 6 +M V30 4 1 2 4 +M V30 5 1 3 4 +M V30 6 3 4 5 +M V30 END BOND +M V30 END CTAB +M END +$$$$ +Simple Ligand 3 + OpenBabel06052308472D +Teststructure + 0 0 0 0 0 999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 6 6 0 0 1 +M V30 BEGIN ATOM +M V30 1 N 0 0 0 0 CHG=1 +M V30 2 C 1 0 0 0 +M V30 3 O 0 1 0 0 +M V30 4 S 1 1 0 0 +M V30 5 C 2 2 0 0 +M V30 6 Cl -1 -1 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 2 1 2 +M V30 2 1 1 3 +M V30 3 1 1 6 +M V30 4 1 2 4 +M V30 5 1 3 4 +M V30 6 3 4 5 +M V30 END BOND +M V30 END CTAB +M END +$$$$ +Simple Ligand 4 + OpenBabel06052308472D +Teststructure + 0 0 0 0 0 999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 6 6 0 0 1 +M V30 BEGIN ATOM +M V30 1 N 0 0 0 0 CHG=1 +M V30 2 C 1 0 0 0 +M V30 3 O 0 1 0 0 +M V30 4 S 1 1 0 0 +M V30 5 C 2 2 0 0 +M V30 6 Cl -1 -1 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 2 1 2 +M V30 2 1 1 3 +M V30 3 1 1 6 +M V30 4 1 2 4 +M V30 5 1 3 4 +M V30 6 3 4 5 +M V30 END BOND +M V30 END CTAB +M END +$$$$ diff --git a/modules/io/tests/testfiles/sdf_v3000/properties.sdf b/modules/io/tests/testfiles/sdf_v3000/properties.sdf new file mode 100644 index 0000000000000000000000000000000000000000..2f6b6ed0be990baba2708a73a96619264944fcf3 --- /dev/null +++ b/modules/io/tests/testfiles/sdf_v3000/properties.sdf @@ -0,0 +1,62 @@ +Simple Ligand 1 + OpenBabel06052308492D +Teststructure + 0 0 0 0 0 999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 6 6 0 0 1 +M V30 BEGIN ATOM +M V30 1 N 0 0 0 0 CHG=1 +M V30 2 C 1 0 0 0 +M V30 3 O 0 1 0 0 +M V30 4 S 1 1 0 0 +M V30 5 C 2 2 0 0 +M V30 6 Cl -1 -1 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 2 1 2 +M V30 2 1 1 3 +M V30 3 1 1 6 +M V30 4 1 2 4 +M V30 5 1 3 4 +M V30 6 3 4 5 +M V30 END BOND +M V30 END CTAB +M END +> <prop_one> +1 + +> <prop_two> +-2.2 + +$$$$ +Simple Ligand 2 + OpenBabel06052308492D +Teststructure + 0 0 0 0 0 999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 6 6 0 0 1 +M V30 BEGIN ATOM +M V30 1 N 0 0 0 0 CHG=1 +M V30 2 C 1 0 0 0 +M V30 3 O 0 1 0 0 +M V30 4 S 1 1 0 0 +M V30 5 C 2 2 0 0 +M V30 6 Cl -1 -1 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 2 1 2 +M V30 2 1 1 3 +M V30 3 1 1 6 +M V30 4 1 2 4 +M V30 5 1 3 4 +M V30 6 3 4 5 +M V30 END BOND +M V30 END CTAB +M END +> <prop_one> +2 + +> <prop_two> +-4.4 + +$$$$ diff --git a/modules/io/tests/testfiles/sdf_v3000/simple.sdf b/modules/io/tests/testfiles/sdf_v3000/simple.sdf new file mode 100644 index 0000000000000000000000000000000000000000..1d4946404ec77c7ab100a48d1bcd0b17f94744ac --- /dev/null +++ b/modules/io/tests/testfiles/sdf_v3000/simple.sdf @@ -0,0 +1,26 @@ +Simple Ligand + OpenBabel06022310462D +Teststructure + 0 0 0 0 0 999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 6 6 0 0 1 +M V30 BEGIN ATOM +M V30 1 N 0 0 0 0 Rgroups=(2 1 2) CHG=- +M V30 3 +M V30 2 C 1 0 0 0 +M V30 3 O 0 1 0 0 +M V30 4 S 1 1 0 0 +M V30 5 C 2 2 0 0 +M V30 6 Cl -1 -1 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 2 1 2 +M V30 2 1 1 3 +M V30 3 1 1 6 +M V30 4 1 2 4 +M V30 5 1 3 4 +M V30 6 3 4 5 +M V30 END BOND +M V30 END CTAB +M END +$$$$ diff --git a/modules/io/tests/testfiles/sdf_v3000/test.py b/modules/io/tests/testfiles/sdf_v3000/test.py new file mode 100644 index 0000000000000000000000000000000000000000..85fa247dbe95dc5f9bd6aaadbd117f4dc07bb7da --- /dev/null +++ b/modules/io/tests/testfiles/sdf_v3000/test.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +import ost.io +ent = ost.io.LoadSDF("simple.sdf") + diff --git a/modules/io/tests/testfiles/sdf_v3000/wrong_atomcount.sdf b/modules/io/tests/testfiles/sdf_v3000/wrong_atomcount.sdf new file mode 100644 index 0000000000000000000000000000000000000000..6914bb7be339dd859f1b6dda565a4732ddf69b57 --- /dev/null +++ b/modules/io/tests/testfiles/sdf_v3000/wrong_atomcount.sdf @@ -0,0 +1,26 @@ +Simple Ligand + OpenBabel06022310462D +Teststructure + 0 0 0 0 0 999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 7 6 0 0 1 +M V30 BEGIN ATOM +M V30 1 N 0 0 0 0 CHG=- +M V30 1 +M V30 2 C 1 0 0 0 +M V30 3 O 0 1 0 0 +M V30 4 S 1 1 0 0 +M V30 5 C 2 2 0 0 +M V30 6 Cl -1 -1 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 2 1 2 +M V30 2 1 1 3 +M V30 3 1 1 6 +M V30 4 1 2 4 +M V30 5 1 3 4 +M V30 6 3 4 5 +M V30 END BOND +M V30 END CTAB +M END +$$$$ diff --git a/modules/io/tests/testfiles/sdf_v3000/wrong_atomlinelength.sdf b/modules/io/tests/testfiles/sdf_v3000/wrong_atomlinelength.sdf new file mode 100644 index 0000000000000000000000000000000000000000..db284bab1c22ed2683e5a4f485cd114ca6df6a77 --- /dev/null +++ b/modules/io/tests/testfiles/sdf_v3000/wrong_atomlinelength.sdf @@ -0,0 +1,26 @@ +Simple Ligand + OpenBabel06022310462D +Teststructure + 0 0 0 0 0 999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 6 6 0 0 1 +M V30 BEGIN ATOM +M V30 1 N 0 0 0 0 CHG=- +M V30 1 +M V30 2 C 1 0 0 +M V30 3 O 0 1 0 0 +M V30 4 S 1 1 0 0 +M V30 5 C 2 2 0 0 +M V30 6 Cl -1 -1 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 2 1 2 +M V30 2 1 1 3 +M V30 3 1 1 6 +M V30 4 1 2 4 +M V30 5 1 3 4 +M V30 6 3 4 5 +M V30 END BOND +M V30 END CTAB +M END +$$$$ diff --git a/modules/io/tests/testfiles/sdf_v3000/wrong_bondatomnumber.sdf b/modules/io/tests/testfiles/sdf_v3000/wrong_bondatomnumber.sdf new file mode 100644 index 0000000000000000000000000000000000000000..bd9115bfbae2ca0e49949325a6d6ebb3f6414b23 --- /dev/null +++ b/modules/io/tests/testfiles/sdf_v3000/wrong_bondatomnumber.sdf @@ -0,0 +1,26 @@ +Simple Ligand + OpenBabel06022310462D +Teststructure + 0 0 0 0 0 999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 6 6 0 0 1 +M V30 BEGIN ATOM +M V30 1 N 0 0 0 0 CHG=- +M V30 1 +M V30 2 C 1 0 0 0 +M V30 3 O 0 1 0 0 +M V30 4 S 1 1 0 0 +M V30 5 C 2 2 0 0 +M V30 6 Cl -1 -1 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 2 1 2 +M V30 2 1 1 3 +M V30 3 1 1 8 +M V30 4 1 2 4 +M V30 5 1 3 4 +M V30 6 3 4 5 +M V30 END BOND +M V30 END CTAB +M END +$$$$ diff --git a/modules/io/tests/testfiles/sdf_v3000/wrong_bondcount.sdf b/modules/io/tests/testfiles/sdf_v3000/wrong_bondcount.sdf new file mode 100644 index 0000000000000000000000000000000000000000..384d29ff4717fb5949ffe2835ad39c077c328afe --- /dev/null +++ b/modules/io/tests/testfiles/sdf_v3000/wrong_bondcount.sdf @@ -0,0 +1,26 @@ +Simple Ligand + OpenBabel06022310462D +Teststructure + 0 0 0 0 0 999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 6 7 0 0 1 +M V30 BEGIN ATOM +M V30 1 N 0 0 0 0 CHG=- +M V30 1 +M V30 2 C 1 0 0 0 +M V30 3 O 0 1 0 0 +M V30 4 S 1 1 0 0 +M V30 5 C 2 2 0 0 +M V30 6 Cl -1 -1 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 2 1 2 +M V30 2 1 1 3 +M V30 3 1 1 6 +M V30 4 1 2 4 +M V30 5 1 3 4 +M V30 6 3 4 5 +M V30 END BOND +M V30 END CTAB +M END +$$$$ diff --git a/modules/io/tests/testfiles/sdf_v3000/wrong_bondlinelength.sdf b/modules/io/tests/testfiles/sdf_v3000/wrong_bondlinelength.sdf new file mode 100644 index 0000000000000000000000000000000000000000..4b994b3f1accd915bbd822087d2c286487de5d0c --- /dev/null +++ b/modules/io/tests/testfiles/sdf_v3000/wrong_bondlinelength.sdf @@ -0,0 +1,26 @@ +Simple Ligand + OpenBabel06022310462D +Teststructure + 0 0 0 0 0 999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 6 6 0 0 1 +M V30 BEGIN ATOM +M V30 1 N 0 0 0 0 CHG=- +M V30 1 +M V30 2 C 1 0 0 0 +M V30 3 O 0 1 0 0 +M V30 4 S 1 1 0 0 +M V30 5 C 2 2 0 0 +M V30 6 Cl -1 -1 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 2 1 2 +M V30 2 1 1 +M V30 3 1 1 6 +M V30 4 1 2 4 +M V30 5 1 3 4 +M V30 6 3 4 5 +M V30 END BOND +M V30 END CTAB +M END +$$$$ diff --git a/modules/io/tests/testfiles/sdf_v3000/wrong_bondtype.sdf b/modules/io/tests/testfiles/sdf_v3000/wrong_bondtype.sdf new file mode 100644 index 0000000000000000000000000000000000000000..da4ad57405ee06f8a4645420e3f6841b5c8b68b8 --- /dev/null +++ b/modules/io/tests/testfiles/sdf_v3000/wrong_bondtype.sdf @@ -0,0 +1,26 @@ +Simple Ligand + OpenBabel06022310462D +Teststructure + 0 0 0 0 0 999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 6 6 0 0 1 +M V30 BEGIN ATOM +M V30 1 N 0 0 0 0 CHG=- +M V30 1 +M V30 2 C 1 0 0 0 +M V30 3 O 0 1 0 0 +M V30 4 S 1 1 0 0 +M V30 5 C 2 2 0 0 +M V30 6 Cl -1 -1 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 2 1 2 +M V30 2 1 1 3 +M V30 3 1 1 6 +M V30 4 -1 2 4 +M V30 5 1 3 4 +M V30 6 3 4 5 +M V30 END BOND +M V30 END CTAB +M END +$$$$ diff --git a/modules/io/tests/testfiles/sdf_v3000/wrong_charge.sdf b/modules/io/tests/testfiles/sdf_v3000/wrong_charge.sdf new file mode 100644 index 0000000000000000000000000000000000000000..ac7ee610f06570f2314df73646b1f27d51662b28 --- /dev/null +++ b/modules/io/tests/testfiles/sdf_v3000/wrong_charge.sdf @@ -0,0 +1,26 @@ +Simple Ligand + OpenBabel06022310462D +Teststructure + 0 0 0 0 0 999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 6 6 0 0 1 +M V30 BEGIN ATOM +M V30 1 N 0 0 0 0 CHG=- +M V30 i +M V30 2 C 1 0 0 0 +M V30 3 O 0 1 0 0 +M V30 4 S 1 1 0 0 +M V30 5 C 2 2 0 0 +M V30 6 Cl -1 -1 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 2 1 2 +M V30 2 1 1 3 +M V30 3 1 1 6 +M V30 4 1 2 4 +M V30 5 1 3 4 +M V30 6 3 4 5 +M V30 END BOND +M V30 END CTAB +M END +$$$$ diff --git a/modules/io/tests/testfiles/sdf_v3000/wrong_keyword.sdf b/modules/io/tests/testfiles/sdf_v3000/wrong_keyword.sdf new file mode 100644 index 0000000000000000000000000000000000000000..eb79262e467962dd7ab9b7a2b055e41c1ec4e824 --- /dev/null +++ b/modules/io/tests/testfiles/sdf_v3000/wrong_keyword.sdf @@ -0,0 +1,26 @@ +Simple Ligand + OpenBabel06022310462D +Teststructure + 0 0 0 0 0 999 V3000 +M V30 BEGIN CTAB +M V30 COUNTS 6 6 0 0 1 +M V30 BEGIN ATOM +M V30 1 N 0 0 0 0 Rgroups=(2 1 2) CHG=- +M V30 3 +M V30 2 C 1 0 0 0 +M V30 3 O 0 1 0 0 CHG= 2 +M V30 4 S 1 1 0 0 +M V30 5 C 2 2 0 0 +M V30 6 Cl -1 -1 0 0 +M V30 END ATOM +M V30 BEGIN BOND +M V30 1 2 1 2 +M V30 2 1 1 3 +M V30 3 1 1 6 +M V30 4 1 2 4 +M V30 5 1 3 4 +M V30 6 3 4 5 +M V30 END BOND +M V30 END CTAB +M END +$$$$