Files
rdkit/Code/GraphMol/ChemReactions/catch_tests.cpp
2019-05-15 04:46:06 +02:00

170 lines
5.3 KiB
C++

//
// Copyright (c) 2018 Greg Landrum
//
// @@ All Rights Reserved @@
// This file is part of the RDKit.
// The contents are covered by the terms of the BSD license
// which is included in the file license.txt, found at the root
// of the RDKit source tree.
///
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do
// this in one cpp file
#include "catch.hpp"
#include <GraphMol/RDKitBase.h>
#include <GraphMol/MonomerInfo.h>
#include <GraphMol/SmilesParse/SmilesParse.h>
#include <GraphMol/SmilesParse/SmilesWrite.h>
#include <GraphMol/FileParsers/SequenceParsers.h>
#include <GraphMol/ChemReactions/Reaction.h>
#include <GraphMol/ChemReactions/ReactionParser.h>
#include <GraphMol/ChemReactions/ReactionRunner.h>
#include <GraphMol/ChemReactions/ReactionUtils.h>
using namespace RDKit;
using std::unique_ptr;
TEST_CASE("Github #1632", "[Reaction,PDB,bug]") {
SECTION("basics") {
bool sanitize = true;
int flavor = 0;
std::unique_ptr<RWMol> mol(SequenceToMol("K", sanitize, flavor));
REQUIRE(mol);
REQUIRE(mol->getAtomWithIdx(0)->getMonomerInfo());
auto res = static_cast<AtomPDBResidueInfo*>(
mol->getAtomWithIdx(0)->getMonomerInfo());
CHECK(res->getResidueNumber() == 1);
std::unique_ptr<ChemicalReaction> rxn(RxnSmartsToChemicalReaction(
"[O:1]=[CX3:2]-[CX4:3]-[NX3:4]>>[O:1]=[CX3:2]-[CX4:3]-[NX3:4]-[C]"));
REQUIRE(rxn);
rxn->initReactantMatchers();
MOL_SPTR_VECT reacts;
reacts.push_back(ROMOL_SPTR(new ROMol(*mol)));
auto prods = rxn->runReactants(reacts);
CHECK(prods.size() == 1);
CHECK(prods[0].size() == 1);
auto p = prods[0][0];
CHECK(p->getNumAtoms() == mol->getNumAtoms() + 1);
REQUIRE(p->getAtomWithIdx(0)->getMonomerInfo());
auto pres = static_cast<AtomPDBResidueInfo*>(
p->getAtomWithIdx(0)->getMonomerInfo());
CHECK(pres->getResidueNumber() == 1);
REQUIRE(!p->getAtomWithIdx(4)->getMonomerInfo());
}
}
static void clearAtomMappingProps(ROMol& mol) {
for (auto&& a : mol.atoms()) {
a->clear();
}
}
TEST_CASE("Github #2366 Enhanced Stereo", "[Reaction,StereoGroup,bug]") {
SECTION("Reaction Preserves Stereo") {
ROMOL_SPTR mol("F[C@H](Cl)Br |o1:1|"_smiles);
REQUIRE(mol);
unique_ptr<ChemicalReaction> rxn(
RxnSmartsToChemicalReaction("[C@:1]>>[C@:1]"));
REQUIRE(rxn);
MOL_SPTR_VECT reactants = {mol};
rxn->initReactantMatchers();
auto prods = rxn->runReactants(reactants);
REQUIRE(prods.size() == 1);
REQUIRE(prods[0].size() == 1);
auto p = prods[0][0];
clearAtomMappingProps(*p);
CHECK(MolToCXSmiles(*p) == "F[C@H](Cl)Br |o1:1|");
}
SECTION("Reaction destroys one center in StereoGroup") {
ROMOL_SPTR mol("F[C@H](Cl)[C@@H](Cl)Br |&1:1,3|"_smiles);
REQUIRE(mol);
unique_ptr<ChemicalReaction> rxn(
RxnSmartsToChemicalReaction("[C@:1]F>>[C:1]F"));
REQUIRE(rxn);
MOL_SPTR_VECT reactants = {mol};
rxn->initReactantMatchers();
auto prods = rxn->runReactants(reactants);
REQUIRE(prods.size() == 1);
REQUIRE(prods[0].size() == 1);
auto p = prods[0][0];
clearAtomMappingProps(*p);
CHECK(MolToCXSmiles(*p) == "FC(Cl)[C@@H](Cl)Br |&1:3|");
}
SECTION("Reaction splits StereoGroup") {
ROMOL_SPTR mol("F[C@H](Cl)[C@@H](Cl)Br |&1:1,3|"_smiles);
REQUIRE(mol);
unique_ptr<ChemicalReaction> rxn(RxnSmartsToChemicalReaction(
"[F:1][C@:2][C@:3][Cl:4]>>[F:1][C@:2]O.O[C@:3][Cl:4]"));
REQUIRE(rxn);
MOL_SPTR_VECT reactants = {mol};
rxn->initReactantMatchers();
auto prods = rxn->runReactants(reactants);
REQUIRE(prods.size() == 1);
REQUIRE(prods[0].size() == 2);
auto p0 = prods[0][0];
auto p1 = prods[0][1];
clearAtomMappingProps(*p0);
clearAtomMappingProps(*p1);
CHECK(MolToCXSmiles(*p0) == "O[C@@H](F)Cl |&1:1|");
CHECK(MolToCXSmiles(*p1) == "O[C@@H](Cl)Br |&1:1|");
}
SECTION("Reaction combines StereoGroups") {
ROMOL_SPTR mol1("F[C@H](Cl)O |&1:1|"_smiles);
REQUIRE(mol1);
ROMOL_SPTR mol2("Cl[C@H](Br)O |&1:1|"_smiles);
REQUIRE(mol2);
unique_ptr<ChemicalReaction> rxn(RxnSmartsToChemicalReaction(
"[F:1][C@:2]O.O[C@:3][Cl:4]>>[F:1][C@:2][C@:3][Cl:4]"));
REQUIRE(rxn);
MOL_SPTR_VECT reactants = {mol1, mol2};
rxn->initReactantMatchers();
auto prods = rxn->runReactants(reactants);
REQUIRE(prods.size() == 1);
REQUIRE(prods[0].size() == 1);
auto p0 = prods[0][0];
clearAtomMappingProps(*p0);
CHECK(MolToCXSmiles(*p0) == "F[C@@H](Cl)[C@H](Cl)Br |&1:1,&2:3|");
}
}
TEST_CASE("Github #2427 cannot set maxProducts>1000 in runReactants",
"[Reaction,bug]") {
SECTION("Basics") {
std::string smi = "[C]";
for (unsigned int i = 0; i < 49; ++i) {
smi += ".[C]";
}
ROMOL_SPTR mol(SmilesToMol(smi));
REQUIRE(mol);
unique_ptr<ChemicalReaction> rxn(
RxnSmartsToChemicalReaction("([#6:1].[#6:2])>>[#6:1]-[#6:2]"));
REQUIRE(rxn);
MOL_SPTR_VECT reactants = {mol};
rxn->initReactantMatchers();
// by default we only get 1000 products:
{
auto prods = rxn->runReactants(reactants);
CHECK(prods.size() == 1000);
CHECK(prods[0].size() == 1);
}
{
auto prods = rxn->runReactants(reactants, 2000);
CHECK(prods.size() == 2000);
CHECK(prods[0].size() == 1);
}
}
}