mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-03 21:44:30 +08:00
Merge branch 'rdkit:master' into vuln_fix
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
3
Code/GraphMol/SynthonSpaceSearch/data/synthon_error.txt
Normal file
3
Code/GraphMol/SynthonSpaceSearch/data/synthon_error.txt
Normal 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
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user