Revert "ConfGen: Macrocycle torsion terms not being used with fused macrocycles (#3894)" (#3902)

This reverts commit 971e195b5b.
This commit is contained in:
Greg Landrum
2021-03-09 14:41:43 +01:00
committed by GitHub
parent 971e195b5b
commit e5c4e87633
3 changed files with 13 additions and 111 deletions

View File

@@ -11,10 +11,6 @@ rdkit_test(testDistGeomHelpers testDgeomHelpers.cpp
LINK_LIBRARIES
DistGeomHelpers MolAlign MolTransforms FileParsers SmilesParse )
rdkit_catch_test(distGeomHelpersCatch ../catch_main.cpp catch_tests.cpp
LINK_LIBRARIES DistGeomHelpers MolAlign MolTransforms FileParsers SmilesParse )
if(RDK_BUILD_PYTHON_WRAPPERS)
add_subdirectory(Wrap)
endif()

View File

@@ -1,79 +0,0 @@
//
// Copyright (C) 2021 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.
//
#include <RDGeneral/test.h>
#include "catch.hpp"
#include <RDGeneral/RDLog.h>
#include <GraphMol/RDKitBase.h>
#include <GraphMol/FileParsers/FileParsers.h>
#include <GraphMol/SmilesParse/SmilesParse.h>
#include <GraphMol/ForceFieldHelpers/CrystalFF/TorsionPreferences.h>
#include "Embedder.h"
#include <tuple>
using namespace RDKit;
TEST_CASE("Torsions not found in fused macrocycles", "[macrocycles]") {
RDLog::InitLogs();
SECTION("reported") {
// this is 6VY8 from the PDB
auto mol1 =
"CC[C@H](C)[C@@H]1NC(=O)[C@@H]2CCCN2C(=O)[C@@H]2CCCN2C(=O)[C@H]([C@@H](C)CC)NC(=O)[C@H](CO)NC(=O)[C@H](CCCC[NH3+])NC(=O)[C@H]([C@@H](C)O)NC(O)[C@@H]2CN3NNC[C@H]3C[C@H](NC1=O)C(O)N[C@@H](Cc1ccccc1)C(=O)N1CCC[C@H]1C(=O)N[C@@H](CC(=O)O)C(=O)NCC(=O)N[C@@H](CCCNC(N)=[NH2+])C(=O)N2"_smiles;
REQUIRE(mol1);
MolOps::addHs(*mol1);
ForceFields::CrystalFF::CrystalFFDetails details;
bool useExpTorsions = true;
bool useSmallRingTorsions = false;
bool useMacrocycleTorsions = true;
bool useBasicKnowledge = true;
unsigned int version = 2;
bool verbose = true;
std::stringstream sstrm;
rdInfoLog->SetTee(sstrm);
ForceFields::CrystalFF::getExperimentalTorsions(
*mol1, details, useExpTorsions, useSmallRingTorsions,
useMacrocycleTorsions, useBasicKnowledge, version, verbose);
rdInfoLog->ClearTee();
auto txt = sstrm.str();
CHECK(txt.find("{9-}") != std::string::npos);
}
SECTION("edges") {
std::vector<std::tuple<std::string, bool, unsigned int>> tests{
{"O=C1CNC(=O)C2CCC(N1)NC(=O)CNC2=O", true, 15}, // 9-9
{"O=C1NC2CCC(C(=O)N1)C(=O)NCC(=O)N2", true, 4}, // 9-8
{"O=C1NC2CCC(C(=O)N1)C(=O)NC(=O)N2", false, 0}}; // 8-8
for (const auto &tpl : tests) {
std::unique_ptr<RWMol> m{SmilesToMol(std::get<0>(tpl))};
REQUIRE(m);
MolOps::addHs(*m);
ForceFields::CrystalFF::CrystalFFDetails details;
bool useExpTorsions = true;
bool useSmallRingTorsions = false;
bool useMacrocycleTorsions = true;
bool useBasicKnowledge = true;
unsigned int version = 2;
bool verbose = true;
std::stringstream sstrm;
rdInfoLog->SetTee(sstrm);
std::cerr << "-----------" << std::endl;
ForceFields::CrystalFF::getExperimentalTorsions(
*m, details, useExpTorsions, useSmallRingTorsions,
useMacrocycleTorsions, useBasicKnowledge, version, verbose);
rdInfoLog->ClearTee();
auto txt = sstrm.str();
if (std::get<1>(tpl)) {
CHECK(txt.find("{9-}") != std::string::npos);
} else {
CHECK(txt.find("{9-}") == std::string::npos);
}
CHECK(details.expTorsionAngles.size() == std::get<2>(tpl));
}
}
}

View File

@@ -32,9 +32,6 @@ namespace ForceFields {
namespace CrystalFF {
using namespace RDKit;
// the "macrocycle" patterns for ETKDGv3 use a minimum ring size of 9
const unsigned int MIN_MACROCYCLE_SIZE = 9;
/* SMARTS patterns for experimental torsion angle preferences
* Version 1 taken from J. Med. Chem. 56, 1026-2028 (2013)
* Version 2 taken from J. Chem. Inf. Model. 56, 1 (2016)
@@ -175,15 +172,10 @@ void getExperimentalTorsions(const RDKit::ROMol &mol, CrystalFFDetails &details,
VECT_INT_VECT_CI rii, rjj;
for (rii = bondRings.begin(); rii != bondRings.end(); ++rii) {
boost::dynamic_bitset<> rs1(nb); // bitset for ring 1
for (auto riiv : *rii) {
rs1[riiv] = 1;
for (unsigned int i = 0; i < rii->size(); i++) {
rs1[(*rii)[i]] = 1;
}
for (rjj = rii + 1; rjj != bondRings.end(); ++rjj) {
// we don't worry about the overlap if both rings are macrocycles:
if (rii->size() >= MIN_MACROCYCLE_SIZE &&
rjj->size() >= MIN_MACROCYCLE_SIZE) {
continue;
}
unsigned int nInCommon = 0;
for (auto rjj_i : *rjj) {
if (rs1[rjj_i]) {
@@ -194,16 +186,11 @@ void getExperimentalTorsions(const RDKit::ROMol &mol, CrystalFFDetails &details,
}
}
if (nInCommon > 1) { // more than one bond in common
// exclude bonds from non-macrocycles:
if (rii->size() < MIN_MACROCYCLE_SIZE) {
for (unsigned int i = 0; i < rii->size(); i++) {
excludedBonds[(*rii)[i]] = 1; // exclude all bonds of ring 1
}
for (unsigned int i = 0; i < rii->size(); i++) {
excludedBonds[(*rii)[i]] = 1; // exclude all bonds of ring 1
}
if (rjj->size() < MIN_MACROCYCLE_SIZE) {
for (unsigned int i = 0; i < rjj->size(); i++) {
excludedBonds[(*rjj)[i]] = 1; // exclude all bonds of ring 2
}
for (unsigned int i = 0; i < rjj->size(); i++) {
excludedBonds[(*rjj)[i]] = 1; // exclude all bonds of ring 2
}
}
}
@@ -221,6 +208,7 @@ void getExperimentalTorsions(const RDKit::ROMol &mol, CrystalFFDetails &details,
for (const auto &param : *params) {
std::vector<MatchVectType> matches;
SubstructMatch(mol, *(param.dp_pattern.get()), matches, false, true);
// loop over matches
for (std::vector<MatchVectType>::const_iterator matchIt = matches.begin();
matchIt != matches.end(); ++matchIt) {
@@ -232,7 +220,7 @@ void getExperimentalTorsions(const RDKit::ROMol &mol, CrystalFFDetails &details,
// FIX: check if bond is NULL
bid2 = mol.getBondBetweenAtoms(aid2, aid3)->getIdx();
// check that a bond is part of maximum one ring
if (mol.getRingInfo()->numBondRings(bid2) > 3 ||
if (mol.getRingInfo()->numBondRings(bid2) > 1 ||
excludedBonds[bid2] == 1) {
doneBonds[bid2] = 1;
}
@@ -246,16 +234,13 @@ void getExperimentalTorsions(const RDKit::ROMol &mol, CrystalFFDetails &details,
details.expTorsionAtoms.push_back(atoms);
details.expTorsionAngles.emplace_back(param.signs, param.V);
if (verbose) {
// using the stringstream seems redundant, but we don't want the
// extra formatting provided by the logger after every entry;
std::stringstream sstr;
sstr << param.smarts << ": " << aid1 << " " << aid2 << " " << aid3
<< " " << aid4 << ", (";
BOOST_LOG(rdInfoLog) << param.smarts << ": " << aid1 << " " << aid2
<< " " << aid3 << " " << aid4 << ", (";
for (unsigned int i = 0; i < param.V.size() - 1; ++i) {
sstr << param.V[i] << ", ";
BOOST_LOG(rdInfoLog) << param.V[i] << ", ";
}
sstr << param.V[param.V.size() - 1] << ") ";
BOOST_LOG(rdInfoLog) << sstr.str() << std::endl;
BOOST_LOG(rdInfoLog)
<< param.V[param.V.size() - 1] << ") " << std::endl;
}
} // if not donePaths
} // end loop over matches