Merge branch 'rdkit:master' into vuln_fix

This commit is contained in:
thomp-j
2024-12-18 09:03:06 -05:00
committed by GitHub
8 changed files with 141 additions and 15 deletions

View File

@@ -1295,14 +1295,17 @@ double normalizeDepiction(RDKit::ROMol &mol, int confId, int canonicalize,
}
}
std::unique_ptr<RDGeom::Transform3D> canonTrans;
auto ctd = MolTransforms::computeCentroid(conf);
if (canonicalize) {
auto ctd = MolTransforms::computeCentroid(conf);
canonTrans.reset(MolTransforms::computeCanonicalTransform(conf, &ctd));
if (canonicalize < 0) {
RDGeom::Transform3D rotate90;
rotate90.SetRotation(0., 1., RDGeom::Point3D(0., 0., 1.));
*canonTrans *= rotate90;
}
} else {
canonTrans.reset(new RDGeom::Transform3D());
canonTrans->SetTranslation(-ctd);
}
bool isScaleFactorSane = (scaleFactor > SCALE_FACTOR_THRESHOLD);
if (isScaleFactorSane && fabs(scaleFactor - 1.0) > SCALE_FACTOR_THRESHOLD) {

View File

@@ -2272,3 +2272,68 @@ M END
*methotrexateAnalog, *methotrexate, -1, refPatt.get(), p);
CHECK(match == expected);
}
TEST_CASE("Normalize should always center in centroid, irrespective of canonicalize parameter") {
auto m = R"CTAB(
RDKit 2D
25 27 0 0 0 0 0 0 0 0999 V2000
18.2425 6.6594 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
16.8948 6.0009 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
16.3808 7.4101 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
14.8817 7.3567 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
14.4692 5.9146 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
15.7134 5.0766 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0
13.0271 6.3270 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
13.4395 7.7692 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
12.7114 9.0806 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
11.7156 5.5989 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
10.4294 6.3705 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
10.4545 7.8703 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
9.1179 5.6424 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
7.8316 6.4141 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
7.8568 7.9139 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
6.5705 8.6855 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
5.2591 7.9574 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
5.2339 6.4576 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
6.5202 5.6860 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
3.9728 8.7291 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
9.0928 4.1426 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0
17.2187 8.6543 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
16.5602 10.0020 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
18.7151 8.5507 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
17.6905 4.7294 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
1 2 1 0
2 3 1 0
3 4 1 0
4 5 1 0
5 6 1 6
5 7 1 0
7 8 1 0
8 9 2 0
7 10 1 6
10 11 1 0
11 12 2 0
11 13 1 0
13 14 1 0
14 15 2 0
15 16 1 0
16 17 2 0
17 18 1 0
18 19 2 0
17 20 1 0
13 21 1 6
3 22 1 1
22 23 2 0
22 24 1 0
2 25 1 0
6 2 1 0
8 4 1 0
19 14 1 0
M END)CTAB"_ctab;
REQUIRE(m);
RDDepict::normalizeDepiction(*m, -1, 0);
auto ctd = MolTransforms::computeCentroid(m->getConformer());
CHECK_THAT(ctd.x, Catch::Matchers::WithinAbs(0.0, 1.0e-4));
CHECK_THAT(ctd.y, Catch::Matchers::WithinAbs(0.0, 1.0e-4));
}

View File

@@ -165,7 +165,7 @@ namespace {
std::vector<std::unique_ptr<ROMol>> buildSampleMolecules(
const std::vector<std::vector<ROMol *>> &synthons,
const size_t longVecNum) {
const size_t longVecNum, const SynthonSet &reaction) {
std::vector<std::unique_ptr<ROMol>> sampleMolecules;
sampleMolecules.reserve(synthons[longVecNum].size());
@@ -181,11 +181,26 @@ std::vector<std::unique_ptr<ROMol>> buildSampleMolecules(
combMol.reset(combineMols(*combMol, *synthons[j].front()));
}
}
auto sampleMol = molzip(*combMol, mzparams);
MolOps::sanitizeMol(*dynamic_cast<RWMol *>(sampleMol.get()));
sampleMolecules.push_back(std::move(sampleMol));
try {
auto sampleMol = molzip(*combMol, mzparams);
MolOps::sanitizeMol(*dynamic_cast<RWMol *>(sampleMol.get()));
sampleMolecules.push_back(std::move(sampleMol));
} catch (std::exception &e) {
const auto &synths = reaction.getSynthons();
std::string msg("Error:: in reaction " + reaction.getId() + " :: building molecule from synthons :");
for (size_t j = 0; j < synthons.size(); ++j) {
std::string sep = j ? " and " : " ";
if (j == longVecNum) {
msg += sep + synths[j][i]->getId() + " (" + synths[j][i]->getSmiles() + ")";
} else {
msg += sep + synths[j].front()->getId() + " (" + synths[j].front()->getSmiles() + ")";
}
}
msg += "\n" + std::string(e.what()) + "\n";
BOOST_LOG(rdErrorLog) << msg;
throw(e);
}
}
return sampleMolecules;
}
@@ -235,7 +250,7 @@ void SynthonSet::transferProductBondsToSynthons() {
synthsToUse[j][0] = true;
}
}
auto sampleMols = buildSampleMolecules(synthonMolCopies, synthSetNum);
auto sampleMols = buildSampleMolecules(synthonMolCopies, synthSetNum, *this);
for (size_t j = 0; j < sampleMols.size(); ++j) {
auto synthCp =
std::make_unique<RWMol>(*d_synthons[synthSetNum][j]->getOrigMol());

View File

@@ -74,6 +74,15 @@ class TestCase(unittest.TestCase):
with tempfile.NamedTemporaryFile() as tmp:
synthonspace.WriteEnumeratedFile(tmp.name)
def testSynthonError(self):
fName = self.sssDir / "amide_space_error.txt"
synthonspace = rdSynthonSpaceSearch.SynthonSpace()
self.assertRaises(RuntimeError, synthonspace.ReadTextFile, fName)
fName = self.sssDir / "synthon_error.txt"
synthonspace = rdSynthonSpaceSearch.SynthonSpace()
self.assertRaises(RuntimeError, synthonspace.ReadTextFile, fName)
if __name__ == "__main__":
unittest.main()

View File

@@ -0,0 +1,8 @@
SMILES synton_id synton# reaction_id
c1cc[1*]ccc1C(=O)[1*] 1-1 0 amide-1
C1CCCCC1C(=O)[1*] 1-2 0 amide-1
Clc1ccccc1C(=O)[1*] 1-3 0 amide-1
CCCCC(=O)[1*] 1-4 0 amide-1
[1*]N1CCCC1 2-1 1 amide-1
[1*]NCCCCC 2-2 1 amide-1
[1*]NCC1CC1 2-3 1 amide-1

View File

@@ -0,0 +1,3 @@
SMILES synton_id synton# reaction_id
C(=[2*])=CC=[1*] 1-1 0 error-1
ClC([2*])=CN=[1*] 2-1 1 error-1

View File

@@ -559,4 +559,21 @@ TEST_CASE("DOS File") {
SynthonSpace synthonspace;
synthonspace.readTextFile(libName);
CHECK(synthonspace.getNumProducts() == 12);
}
}
TEST_CASE("Synthon Error") {
REQUIRE(rdbase);
std::string fName(rdbase);
{
std::string libName =
fName + "/Code/GraphMol/SynthonSpaceSearch/data/amide_space_error.txt";
SynthonSpace synthonspace;
CHECK_THROWS(synthonspace.readTextFile(libName));
}
{
std::string libName =
fName + "/Code/GraphMol/SynthonSpaceSearch/data/synthon_error.txt";
SynthonSpace synthonspace;
CHECK_THROWS(synthonspace.readTextFile(libName));
}
}

View File

@@ -88,18 +88,22 @@ inline T EndianSwapBytes(T value) {
return SwapBytes<T, sizeof(T)>(value);
}
template <EEndian from, EEndian to>
inline char EndianSwapBytes(char value) {
return value;
}
template <EEndian from, EEndian to>
inline unsigned char EndianSwapBytes(unsigned char value) {
return value;
}
template <EEndian from, EEndian to>
inline signed char EndianSwapBytes(signed char value) {
return value;
}
// --------------------------------------
//! Packs an integer and outputs it to a stream
@@ -265,8 +269,8 @@ void streamWrite(std::ostream &ss, const T &val) {
//! special case for string
inline void streamWrite(std::ostream &ss, const std::string &what) {
unsigned int l = rdcast<unsigned int>(what.length());
ss.write((const char *)&l, sizeof(l));
unsigned int l = static_cast<unsigned int>(what.length());
streamWrite(ss, l);
ss.write(what.c_str(), sizeof(char) * l);
};
@@ -299,10 +303,7 @@ void streamRead(std::istream &ss, T &obj, int version) {
inline void streamRead(std::istream &ss, std::string &what, int version) {
RDUNUSED_PARAM(version);
unsigned int l;
ss.read((char *)&l, sizeof(l));
if (ss.fail()) {
throw std::runtime_error("failed to read from stream");
}
streamRead(ss, l);
auto buff = std::make_unique<char[]>(l);
ss.read(buff.get(), sizeof(char) * l);
if (ss.fail()) {
@@ -342,6 +343,7 @@ inline std::string getLine(std::istream *inStream) {
}
return res;
}
//! grabs the next line from an instream and returns it.
inline std::string getLine(std::istream &inStream) {
return getLine(&inStream);
@@ -370,10 +372,15 @@ const unsigned char EndTag = 0xFF;
class CustomPropHandler {
public:
virtual ~CustomPropHandler() {}
virtual const char *getPropName() const = 0;
virtual bool canSerialize(const RDValue &value) const = 0;
virtual bool read(std::istream &ss, RDValue &value) const = 0;
virtual bool write(std::ostream &ss, const RDValue &value) const = 0;
virtual CustomPropHandler *clone() const = 0;
};
@@ -642,7 +649,6 @@ inline unsigned int streamReadProps(std::istream &ss, RDProps &props,
return static_cast<unsigned int>(count);
}
} // namespace RDKit
#endif