mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-03 21:44:30 +08:00
merge
This commit is contained in:
8
.gitignore
vendored
8
.gitignore
vendored
@@ -45,18 +45,16 @@ __pycache__/
|
||||
|
||||
/Data/templates.mae
|
||||
|
||||
/External/**/*.tar.gz
|
||||
/External/**/*.zip
|
||||
/External/catch/catch/
|
||||
/External/CoordGen/coordgen/
|
||||
/External/CoordGen/maeparser/
|
||||
/External/CoordGen/maeparser-v*.tar.gz
|
||||
/External/CoordGen/coordgenlibs-v*.tar.gz
|
||||
/External/FreeSASA/freesasa-2.0.1/
|
||||
/External/FreeSASA/master.tar.gz
|
||||
/External/INCHI-API/INCHI-1-SRC.zip
|
||||
/External/INCHI-API/INCHI-1-SRC/
|
||||
/External/INCHI-API/src/
|
||||
/External/rapidjson-1.1.0.tar.gz
|
||||
/External/rapidjson-1.1.0/
|
||||
/External/RingFamilies/RingDecomposerLib/
|
||||
|
||||
/rdkit/RDPaths.py
|
||||
/rdkit/Chem/inchi.py
|
||||
|
||||
@@ -98,7 +98,7 @@ class TestCase(unittest.TestCase):
|
||||
|
||||
# Test the new version also has the id and works as expected
|
||||
|
||||
# uncomment the following to generate (overrwrite) new version of pickled
|
||||
# uncomment the following to generate (overwrite) new version of pickled
|
||||
# data file
|
||||
#pickle.dump(ffeat,file(os.path.join(RDConfig.RDBaseDir, 'Code/ChemicalFeatures/Wrap/testData/featv2.pkl'),'wb+'))
|
||||
inTF = open(
|
||||
|
||||
@@ -29,7 +29,7 @@ class TestCase(unittest.TestCase):
|
||||
for i in range(numpy.shape(dmat)[0]):
|
||||
assert feq(dmat[i], exp[i])
|
||||
|
||||
# repeat with an flaot array
|
||||
# repeat with an float array
|
||||
desc = numpy.zeros((3, 2), 'f')
|
||||
desc[1, 0] = 1.0
|
||||
desc[2, 0] = 1.0
|
||||
@@ -39,7 +39,7 @@ class TestCase(unittest.TestCase):
|
||||
for i in range(numpy.shape(dmat)[0]):
|
||||
assert feq(dmat[i], exp[i])
|
||||
|
||||
# finally with an interger array
|
||||
# finally with an integer array
|
||||
desc = numpy.zeros((3, 2), 'i')
|
||||
desc[1, 0] = 1
|
||||
desc[2, 0] = 1
|
||||
|
||||
0
Code/DataManip/MetricMatrixCalc/testExecs/.cvskeep
Executable file → Normal file
0
Code/DataManip/MetricMatrixCalc/testExecs/.cvskeep
Executable file → Normal file
0
Code/Demos/RDKit/Basement/BinaryIO/Makefile
Executable file → Normal file
0
Code/Demos/RDKit/Basement/BinaryIO/Makefile
Executable file → Normal file
0
Code/Demos/RDKit/Basement/TemplEnum/Makefile
Executable file → Normal file
0
Code/Demos/RDKit/Basement/TemplEnum/Makefile
Executable file → Normal file
0
Code/Demos/RDKit/Basement/TemplEnum/Ts.1.sdf
Executable file → Normal file
0
Code/Demos/RDKit/Basement/TemplEnum/Ts.1.sdf
Executable file → Normal file
0
Code/Demos/RDKit/Basement/TemplEnum/Ts.sdf
Executable file → Normal file
0
Code/Demos/RDKit/Basement/TemplEnum/Ts.sdf
Executable file → Normal file
0
Code/Demos/RDKit/Basement/TemplEnum/box.1.mol
Executable file → Normal file
0
Code/Demos/RDKit/Basement/TemplEnum/box.1.mol
Executable file → Normal file
0
Code/Demos/RDKit/Basement/TemplEnum/box.1a.mol
Executable file → Normal file
0
Code/Demos/RDKit/Basement/TemplEnum/box.1a.mol
Executable file → Normal file
0
Code/Demos/RDKit/Basement/TemplEnum/box.mol
Executable file → Normal file
0
Code/Demos/RDKit/Basement/TemplEnum/box.mol
Executable file → Normal file
0
Code/Demos/RDKit/Basement/TemplEnum/esters.2.sdf
Executable file → Normal file
0
Code/Demos/RDKit/Basement/TemplEnum/esters.2.sdf
Executable file → Normal file
0
Code/Demos/RDKit/Basement/TemplEnum/esters.sdf
Executable file → Normal file
0
Code/Demos/RDKit/Basement/TemplEnum/esters.sdf
Executable file → Normal file
0
Code/Demos/RDKit/Basement/TemplEnum/template.1.mol
Executable file → Normal file
0
Code/Demos/RDKit/Basement/TemplEnum/template.1.mol
Executable file → Normal file
0
Code/Demos/RDKit/Basement/TemplEnum/template.2.mol
Executable file → Normal file
0
Code/Demos/RDKit/Basement/TemplEnum/template.2.mol
Executable file → Normal file
0
Code/Demos/RDKit/Basement/TemplEnum/template.mol
Executable file → Normal file
0
Code/Demos/RDKit/Basement/TemplEnum/template.mol
Executable file → Normal file
0
Code/Demos/boost/EBV_err/crossMod.dsw
Executable file → Normal file
0
Code/Demos/boost/EBV_err/crossMod.dsw
Executable file → Normal file
0
Code/Demos/boost/any_container/Makefile
Executable file → Normal file
0
Code/Demos/boost/any_container/Makefile
Executable file → Normal file
0
Code/Demos/boost/cross_mod_err/crossMod.dsw
Executable file → Normal file
0
Code/Demos/boost/cross_mod_err/crossMod.dsw
Executable file → Normal file
0
Code/Demos/boost/cross_module/readme.txt
Executable file → Normal file
0
Code/Demos/boost/cross_module/readme.txt
Executable file → Normal file
@@ -24,7 +24,7 @@ namespace RDGeom {
|
||||
unsigned int ci_GRIDPICKLE_VERSION = 0x1;
|
||||
|
||||
UniformGrid3D::UniformGrid3D(const UniformGrid3D &other) : Grid3D(other) {
|
||||
PRECONDITION(other.dp_storage, "cannot copy an unintialized grid");
|
||||
PRECONDITION(other.dp_storage, "cannot copy an uninitialized grid");
|
||||
auto *data = new RDKit::DiscreteValueVect(*other.dp_storage);
|
||||
initGrid(other.d_numX * other.d_spacing, other.d_numY * other.d_spacing,
|
||||
other.d_numZ * other.d_spacing, other.d_spacing,
|
||||
@@ -33,7 +33,7 @@ UniformGrid3D::UniformGrid3D(const UniformGrid3D &other) : Grid3D(other) {
|
||||
|
||||
UniformGrid3D &UniformGrid3D::operator=(const UniformGrid3D &other) {
|
||||
if (&other == this) return *this;
|
||||
PRECONDITION(other.dp_storage, "cannot copy an unintialized grid");
|
||||
PRECONDITION(other.dp_storage, "cannot copy an uninitialized grid");
|
||||
delete dp_storage;
|
||||
auto *data = new RDKit::DiscreteValueVect(*other.dp_storage);
|
||||
initGrid(other.d_numX * other.d_spacing, other.d_numY * other.d_spacing,
|
||||
@@ -274,8 +274,8 @@ void UniformGrid3D::setSphereOccupancy(const Point3D ¢er, double radius,
|
||||
}
|
||||
|
||||
UniformGrid3D &UniformGrid3D::operator|=(const UniformGrid3D &other) {
|
||||
PRECONDITION(dp_storage, "unintialized grid");
|
||||
PRECONDITION(other.dp_storage, "unintialized grid");
|
||||
PRECONDITION(dp_storage, "uninitialized grid");
|
||||
PRECONDITION(other.dp_storage, "uninitialized grid");
|
||||
PRECONDITION(compareParams(other), "incompatible grids");
|
||||
|
||||
// EFF: we're probably doing too much copying here:
|
||||
@@ -287,8 +287,8 @@ UniformGrid3D &UniformGrid3D::operator|=(const UniformGrid3D &other) {
|
||||
}
|
||||
|
||||
UniformGrid3D &UniformGrid3D::operator&=(const UniformGrid3D &other) {
|
||||
PRECONDITION(dp_storage, "unintialized grid");
|
||||
PRECONDITION(other.dp_storage, "unintialized grid");
|
||||
PRECONDITION(dp_storage, "uninitialized grid");
|
||||
PRECONDITION(other.dp_storage, "uninitialized grid");
|
||||
PRECONDITION(compareParams(other), "incompatible grids");
|
||||
|
||||
// EFF: we're probably doing too much copying here:
|
||||
@@ -300,8 +300,8 @@ UniformGrid3D &UniformGrid3D::operator&=(const UniformGrid3D &other) {
|
||||
}
|
||||
|
||||
UniformGrid3D &UniformGrid3D::operator+=(const UniformGrid3D &other) {
|
||||
PRECONDITION(dp_storage, "unintialized grid");
|
||||
PRECONDITION(other.dp_storage, "unintialized grid");
|
||||
PRECONDITION(dp_storage, "uninitialized grid");
|
||||
PRECONDITION(other.dp_storage, "uninitialized grid");
|
||||
PRECONDITION(compareParams(other), "incompatible grids");
|
||||
|
||||
// EFF: we're probably doing too much copying here:
|
||||
@@ -310,8 +310,8 @@ UniformGrid3D &UniformGrid3D::operator+=(const UniformGrid3D &other) {
|
||||
}
|
||||
|
||||
UniformGrid3D &UniformGrid3D::operator-=(const UniformGrid3D &other) {
|
||||
PRECONDITION(dp_storage, "unintialized grid");
|
||||
PRECONDITION(other.dp_storage, "unintialized grid");
|
||||
PRECONDITION(dp_storage, "uninitialized grid");
|
||||
PRECONDITION(other.dp_storage, "uninitialized grid");
|
||||
PRECONDITION(compareParams(other), "incompatible grids");
|
||||
|
||||
// EFF: we're probably doing too much copying here:
|
||||
|
||||
@@ -367,7 +367,7 @@ void applyHuckelToFused(
|
||||
// check is we are done with all the atoms in the fused
|
||||
// system, if so quit. This is a fix for Issue252 REVIEW: is
|
||||
// this check sufficient or should we add an additional
|
||||
// contraint on the the number of combinations of rings in a
|
||||
// constraint on the number of combinations of rings in a
|
||||
// fused system that we will try. The number of combinations
|
||||
// can obviously be quite large when the number of rings in
|
||||
// the fused system is large
|
||||
|
||||
@@ -108,7 +108,7 @@ RDKIT_CHEMREACTIONS_EXPORT std::string ChemicalReactionToRxnSmiles(
|
||||
//! returns an RXN block for a reaction
|
||||
/*!
|
||||
\param rxn chemical reaction
|
||||
\param separateAgents flag to decide if agents were put in a seperate block,
|
||||
\param separateAgents flag to decide if agents were put in a separate block,
|
||||
otherwise they were included in the reactants block
|
||||
(default)
|
||||
*/
|
||||
|
||||
@@ -229,7 +229,7 @@ Options:\n\
|
||||
docString = \
|
||||
"EnumerateLibrary\n\
|
||||
This class allows easy enumeration of reactions. Simply provide a reaction\n\
|
||||
and a set of reagents and you are off the the races.\n\
|
||||
and a set of reagents and you are off the races.\n\
|
||||
\n\
|
||||
Note that this functionality should be considered beta and that the API may\n\
|
||||
change in a future release.\n\
|
||||
|
||||
@@ -227,7 +227,7 @@ std::vector<ROMOL_SPTR> replaceSubstructs(
|
||||
}
|
||||
|
||||
// clear conformers and computed props and do basic updates
|
||||
// on the the resulting molecules, but allow unhappiness:
|
||||
// on the resulting molecules, but allow unhappiness:
|
||||
for (auto &re : res) {
|
||||
updateSubMolConfs(mol, *(RWMol *)re.get(), removedAtoms);
|
||||
re->clearComputedProps(true);
|
||||
|
||||
@@ -122,7 +122,7 @@ RDKIT_DEPICTOR_EXPORT RDGeom::Point2D reflectPoint(const RDGeom::Point2D &point,
|
||||
--D--
|
||||
|
|
||||
</pre>
|
||||
In this case the the number substituent of A, B, C, D are 3, 1, 1,
|
||||
In this case the number substituent of A, B, C, D are 3, 1, 1,
|
||||
4 respectively so want to A and D to go opposite sides and so that
|
||||
we draw
|
||||
<pre>
|
||||
@@ -150,7 +150,7 @@ RDKIT_DEPICTOR_EXPORT RDKit::INT_VECT setNbrOrder(unsigned int aid,
|
||||
in common with the rings that are already embedded.
|
||||
|
||||
\param doneRings a vertor of ring IDs that have been embedded already
|
||||
\param fusedRings list of all the rings in the the fused system
|
||||
\param fusedRings list of all the rings in the fused system
|
||||
\param nextId this is where the ID for the next ring is written
|
||||
|
||||
\return list of atom ids that are common
|
||||
|
||||
@@ -666,7 +666,7 @@ void EmbeddedFrag::mergeRing(const EmbeddedFrag &embRing, unsigned int nCommon,
|
||||
} else {
|
||||
// update the neighbor only on atoms that were used to compute the
|
||||
// transform to merge the
|
||||
// and only if the the two are the only common atoms
|
||||
// and only if the two are the only common atoms
|
||||
// i.e. we are doing bridged systems we will leave the nbrs untouched
|
||||
if (nCommon <= 2) {
|
||||
if (std::find(pinAtoms.begin(), pinAtoms.end(), aid) !=
|
||||
@@ -690,7 +690,7 @@ void EmbeddedFrag::mergeRing(const EmbeddedFrag &embRing, unsigned int nCommon,
|
||||
void EmbeddedFrag::addNonRingAtom(unsigned int aid, unsigned int toAid) {
|
||||
// const RDKit::ROMol *mol) {
|
||||
PRECONDITION(dp_mol, "");
|
||||
// check that aid does not belong the the embedded fragment yet
|
||||
// check that aid does not belong the embedded fragment yet
|
||||
PRECONDITION(d_eatoms.find(aid) == d_eatoms.end(), "");
|
||||
// and that toAid is already in the embedded system
|
||||
PRECONDITION(d_eatoms.find(toAid) != d_eatoms.end(), "");
|
||||
|
||||
@@ -484,7 +484,7 @@ class RDKIT_DEPICTOR_EXPORT EmbeddedFrag {
|
||||
/*
|
||||
Add an atom to this embedded fragment when the fragment already
|
||||
has a atleast two previously added neighbors to 'toAid'. In this
|
||||
case we have to choose where the the new neighbor goes based on
|
||||
case we have to choose where the new neighbor goes based on
|
||||
the angle that is already taken around the atom.
|
||||
|
||||
ARGUMENTS:
|
||||
|
||||
@@ -106,7 +106,7 @@ RDKIT_DEPICTOR_EXPORT unsigned int compute2DCoords(
|
||||
mol before adding a conformation
|
||||
|
||||
\param weightDistMat - A value between 0.0 and 1.0, this
|
||||
determines the importance of mimicing the the inter atoms
|
||||
determines the importance of mimicing the inter atoms
|
||||
distances in dmat. (1.0 - weightDistMat) is the weight associated
|
||||
to spreading out the structure (density) in the cost function
|
||||
|
||||
|
||||
0
Code/GraphMol/Depictor/testExecs/.cvskeep
Executable file → Normal file
0
Code/GraphMol/Depictor/testExecs/.cvskeep
Executable file → Normal file
0
Code/GraphMol/Depictor/test_data/7UPJ_default.mol
Executable file → Normal file
0
Code/GraphMol/Depictor/test_data/7UPJ_default.mol
Executable file → Normal file
0
Code/GraphMol/Depictor/test_data/7UPJ_mimic3D_1.mol
Executable file → Normal file
0
Code/GraphMol/Depictor/test_data/7UPJ_mimic3D_1.mol
Executable file → Normal file
0
Code/GraphMol/Depictor/test_data/7UPJ_mimic3D_2.mol
Executable file → Normal file
0
Code/GraphMol/Depictor/test_data/7UPJ_mimic3D_2.mol
Executable file → Normal file
0
Code/GraphMol/Depictor/test_data/7UPJ_spread.mol
Executable file → Normal file
0
Code/GraphMol/Depictor/test_data/7UPJ_spread.mol
Executable file → Normal file
0
Code/GraphMol/Depictor/test_data/7UPJ_xtal.mol
Executable file → Normal file
0
Code/GraphMol/Depictor/test_data/7UPJ_xtal.mol
Executable file → Normal file
0
Code/GraphMol/Depictor/test_data/first_200.tpsa.csv
Executable file → Normal file
0
Code/GraphMol/Depictor/test_data/first_200.tpsa.csv
Executable file → Normal file
@@ -18,14 +18,14 @@ class ROMol;
|
||||
namespace Descriptors {
|
||||
//! Normalized principal moments ratio 1 (=I1/I3)
|
||||
//! from Sauer and Schwarz JCIM 43:987-1003 (2003)
|
||||
//! https://dx.doi.org/10.1021/ci025599w
|
||||
//! https://doi.org/10.1021/ci025599w
|
||||
RDKIT_DESCRIPTORS_EXPORT double NPR1(const ROMol&, int confId = -1,
|
||||
bool useAtomicMasses = true,
|
||||
bool force = false);
|
||||
const std::string NPR1Version = "1.0.0";
|
||||
//! Normalized principal moments ratio 2 (=I2/I3)
|
||||
//! from Sauer and Schwarz JCIM 43:987-1003 (2003)
|
||||
//! https://dx.doi.org/10.1021/ci025599w
|
||||
//! https://doi.org/10.1021/ci025599w
|
||||
RDKIT_DESCRIPTORS_EXPORT double NPR2(const ROMol&, int confId = -1,
|
||||
bool useAtomicMasses = true,
|
||||
bool force = false);
|
||||
@@ -51,7 +51,7 @@ const std::string PMI3Version = "1.0.0";
|
||||
Radius of gyration
|
||||
from G. A. Arteca "Molecular Shape Descriptors"
|
||||
Reviews in Computational Chemistry vol 9
|
||||
http://dx.doi.org/10.1002/9780470125861.ch5
|
||||
https://doi.org/10.1002/9780470125861.ch5
|
||||
|
||||
Definition (eq: A4):
|
||||
sqrt(t_1 + t_2 + t_3) where t_i is the ith moment from the gyration matrix
|
||||
@@ -64,7 +64,7 @@ const std::string radiusOfGyrationVersion = "1.0.0";
|
||||
Inertial shape factor
|
||||
from Todeschini and Consoni "Descriptors from Molecular Geometry"
|
||||
Handbook of Chemoinformatics
|
||||
http://dx.doi.org/10.1002/9783527618279.ch37
|
||||
https://doi.org/10.1002/9783527618279.ch37
|
||||
|
||||
Definition:
|
||||
pm2 / (pm1*pm3)
|
||||
@@ -78,7 +78,7 @@ const std::string inertialShapeFactorVersion = "1.0.0";
|
||||
Molecular eccentricity
|
||||
from G. A. Arteca "Molecular Shape Descriptors"
|
||||
Reviews in Computational Chemistry vol 9
|
||||
http://dx.doi.org/10.1002/9780470125861.ch5
|
||||
https://doi.org/10.1002/9780470125861.ch5
|
||||
|
||||
Definition (eq 4):
|
||||
sqrt(pm_3**2 -pm_1**2) / pm_3**2 where pm_i is the ith moment of inertia
|
||||
@@ -91,7 +91,7 @@ const std::string eccentricityVersion = "1.0.0";
|
||||
molecular asphericity
|
||||
from A. Baumgaertner, "Shapes of flexible vesicles"
|
||||
J. Chem. Phys. 98:7496 (1993)
|
||||
http://dx.doi.org/10.1063/1.464689
|
||||
https://doi.org/10.1063/1.464689
|
||||
|
||||
Definition (eq 11):
|
||||
0.5 * ((t_3-t_2)**2 + (t_3-t_1)**2 + (t_2-t_1)**2)/(t_1+t_2+t_3)**2
|
||||
@@ -113,7 +113,7 @@ const std::string asphericityVersion = "1.0.0";
|
||||
Spherocity index
|
||||
from Todeschini and Consoni "Descriptors from Molecular Geometry"
|
||||
Handbook of Chemoinformatics
|
||||
http://dx.doi.org/10.1002/9783527618279.ch37
|
||||
https://doi.org/10.1002/9783527618279.ch37
|
||||
|
||||
Definition:
|
||||
3 * t_1 / (t_1+t_2+t_3)
|
||||
|
||||
@@ -1576,7 +1576,7 @@ BOOST_PYTHON_MODULE(rdMolDescriptors) {
|
||||
python::scope().attr("_CalcPBF_version") = RDKit::Descriptors::PBFVersion;
|
||||
docString =
|
||||
"Returns the PBF (plane of best fit) descriptor "
|
||||
"(http://dx.doi.org/10.1021/ci300293f)";
|
||||
"(https://doi.org/10.1021/ci300293f)";
|
||||
python::def("CalcPBF", RDKit::Descriptors::PBF,
|
||||
(python::arg("mol"), python::arg("confId") = -1),
|
||||
docString.c_str());
|
||||
|
||||
@@ -324,7 +324,7 @@ bool cleanUpMol2Substructures(RWMol *res) {
|
||||
// this should return only the bond between C.2 and O.co2
|
||||
Bond *b = res->getBondBetweenAtoms(idx, *nbrIdxIt);
|
||||
if (!isFixed[*nbrIdxIt]) {
|
||||
// the first occurence is negatively charged and has a single bond
|
||||
// the first occurrence is negatively charged and has a single bond
|
||||
b->setBondType(Bond::SINGLE);
|
||||
b->setIsAromatic(false);
|
||||
at->setFormalCharge(-1);
|
||||
@@ -333,7 +333,7 @@ bool cleanUpMol2Substructures(RWMol *res) {
|
||||
isFixed[idx] = 1;
|
||||
isFixed[*nbrIdxIt] = 1;
|
||||
} else {
|
||||
// the other occurences are not charged and have a double bond
|
||||
// the other occurrences are not charged and have a double bond
|
||||
b->setBondType(Bond::DOUBLE);
|
||||
b->setIsAromatic(false);
|
||||
at->setIsAromatic(false);
|
||||
|
||||
@@ -446,7 +446,7 @@ void ParseSGroupV2000SCDSEDLine(IDX_TO_SGROUP_MAP &sGroupMap,
|
||||
|
||||
if (lastDataSGroup != 0 && lastDataSGroup != sgIdx) {
|
||||
std::ostringstream errout;
|
||||
errout << "Found a Data Field not matching the the SGroup of the last Data "
|
||||
errout << "Found a Data Field not matching the SGroup of the last Data "
|
||||
"Field at line "
|
||||
<< line;
|
||||
throw FileParseException(errout.str());
|
||||
|
||||
@@ -1,393 +1,393 @@
|
||||
//
|
||||
// Copyright (C) 2013-2017 Greg Landrum and NextMove Software
|
||||
//
|
||||
// @@ 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 "ProximityBonds.h"
|
||||
#include <algorithm>
|
||||
#include <GraphMol/RDKitBase.h>
|
||||
#include <GraphMol/RWMol.h>
|
||||
#include <GraphMol/MonomerInfo.h>
|
||||
|
||||
namespace RDKit {
|
||||
|
||||
static const double EXTDIST = 0.45;
|
||||
// static const double MAXRAD = 2.50;
|
||||
// static const double MINDIST = 0.40;
|
||||
static const double MAXDIST = 5.45; // 2*MAXRAD + EXTDIST
|
||||
static const double MINDIST2 = 0.16; // MINDIST*MINDIST
|
||||
static const double MAXDIST2 = 29.7025; // MAXDIST*MAXDIST
|
||||
|
||||
struct ProximityEntry {
|
||||
float x, y, z, r;
|
||||
int atm, hash, next, elem;
|
||||
|
||||
bool operator<(const ProximityEntry &p) const { return x < p.x; }
|
||||
};
|
||||
|
||||
static bool IsBonded(ProximityEntry *p, ProximityEntry *q, unsigned int flags) {
|
||||
if (flags & ctdIGNORE_H_H_CONTACTS && p->elem == 1 && q->elem == 1)
|
||||
return false;
|
||||
double dx = (double)p->x - (double)q->x;
|
||||
double dist2 = dx * dx;
|
||||
if (dist2 > MAXDIST2) return false;
|
||||
double dy = (double)p->y - (double)q->y;
|
||||
dist2 += dy * dy;
|
||||
if (dist2 > MAXDIST2) return false;
|
||||
double dz = (double)p->z - (double)q->z;
|
||||
dist2 += dz * dz;
|
||||
|
||||
if (dist2 > MAXDIST2 || dist2 < MINDIST2) return false;
|
||||
|
||||
double radius = (double)p->r + (double)q->r + EXTDIST;
|
||||
return dist2 <= radius * radius;
|
||||
}
|
||||
|
||||
bool SamePDBResidue(AtomPDBResidueInfo *p, AtomPDBResidueInfo *q) {
|
||||
return p->getResidueNumber() == q->getResidueNumber() &&
|
||||
p->getResidueName() == q->getResidueName() &&
|
||||
p->getChainId() == q->getChainId() &&
|
||||
p->getInsertionCode() == q->getInsertionCode();
|
||||
}
|
||||
|
||||
static bool IsBlacklistedAtom(Atom *atom) {
|
||||
// blacklist metals, noble gasses and halogens
|
||||
int elem = atom->getAtomicNum();
|
||||
// make an inverse query (non-metals and metaloids)
|
||||
if ((5 <= elem && elem <= 8) || (14 <= elem && elem <= 16) ||
|
||||
(32 <= elem && elem <= 34) || (51 <= elem && elem <= 52))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsBlacklistedPair(Atom *beg_atom, Atom *end_atom) {
|
||||
PRECONDITION(beg_atom, "empty atom");
|
||||
PRECONDITION(end_atom, "empty atom");
|
||||
|
||||
AtomPDBResidueInfo *beg_info =
|
||||
(AtomPDBResidueInfo *)beg_atom->getMonomerInfo();
|
||||
AtomPDBResidueInfo *end_info =
|
||||
(AtomPDBResidueInfo *)end_atom->getMonomerInfo();
|
||||
if (!beg_info || beg_info->getMonomerType() != AtomMonomerInfo::PDBRESIDUE)
|
||||
return false;
|
||||
if (!end_info || end_info->getMonomerType() != AtomMonomerInfo::PDBRESIDUE)
|
||||
return false;
|
||||
|
||||
if (!SamePDBResidue(beg_info, end_info)) {
|
||||
if (IsBlacklistedAtom(beg_atom) || IsBlacklistedAtom(end_atom)) return true;
|
||||
// Dont make bonds to waters
|
||||
if (beg_info->getResidueName() == "HOH" ||
|
||||
end_info->getResidueName() == "HOH")
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
static void ConnectTheDots_Small(RWMol *mol)
|
||||
{
|
||||
unsigned int count = mol->getNumAtoms();
|
||||
ProximityEntry *tmp = (ProximityEntry*)malloc(count*sizeof(ProximityEntry));
|
||||
PeriodicTable *table = PeriodicTable::getTable();
|
||||
Conformer *conf = &mol->getConformer();
|
||||
for (unsigned int i=0; i<count; i++) {
|
||||
Atom *atom = mol->getAtomWithIdx(i);
|
||||
unsigned int elem = atom->getAtomicNum();
|
||||
RDGeom::Point3D p = conf->getAtomPos(i);
|
||||
ProximityEntry *tmpi = tmp+i;
|
||||
tmpi->x = (float)p.x;
|
||||
tmpi->y = (float)p.y;
|
||||
tmpi->z = (float)p.z;
|
||||
tmpi->r = (float)table->getRcovalent(elem);
|
||||
for (unsigned int j=0; j<i; j++) {
|
||||
ProximityEntry *tmpj = tmp+j;
|
||||
if (IsBonded(tmpi,tmpj) && !mol->getBondBetweenAtoms(i,j))
|
||||
mol->addBond(i,j,Bond::SINGLE);
|
||||
}
|
||||
}
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
|
||||
static void ConnectTheDots_Medium(RWMol *mol)
|
||||
{
|
||||
int count = mol->getNumAtoms();
|
||||
std::vector<ProximityEntry> tmp(count);
|
||||
PeriodicTable *table = PeriodicTable::getTable();
|
||||
Conformer *conf = &mol->getConformer();
|
||||
for (int i=0; i<count; i++) {
|
||||
Atom *atom = mol->getAtomWithIdx(i);
|
||||
unsigned int elem = atom->getAtomicNum();
|
||||
RDGeom::Point3D p = conf->getAtomPos(i);
|
||||
ProximityEntry *tmpi = &tmp[i];
|
||||
tmpi->x = (float)p.x;
|
||||
tmpi->y = (float)p.y;
|
||||
tmpi->z = (float)p.z;
|
||||
tmpi->r = (float)table->getRcovalent(elem);
|
||||
tmpi->atm = i;
|
||||
}
|
||||
|
||||
std::stable_sort(tmp.begin(),tmp.end());
|
||||
|
||||
for (int j=0; j<count; j++) {
|
||||
ProximityEntry *tmpj = &tmp[j];
|
||||
double limit = tmpj->x - MAXDIST;
|
||||
for (int k=j-1; k>=0; k--) {
|
||||
ProximityEntry *tmpk = &tmp[k];
|
||||
if (tmpk->x < limit)
|
||||
break;
|
||||
if (IsBonded(tmpj,tmpk) &&
|
||||
!mol->getBondBetweenAtoms(tmpj->atm,tmpk->atm))
|
||||
mol->addBond(tmpj->atm,tmpk->atm,Bond::SINGLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#define HASHSIZE 1024
|
||||
#define HASHMASK 1023
|
||||
#define HASHX 571
|
||||
#define HASHY 127
|
||||
#define HASHZ 3
|
||||
|
||||
static void ConnectTheDots_Large(RWMol *mol, unsigned int flags) {
|
||||
int HashTable[HASHSIZE];
|
||||
memset(HashTable, -1, sizeof(HashTable));
|
||||
|
||||
unsigned int count = mol->getNumAtoms();
|
||||
ProximityEntry *tmp =
|
||||
(ProximityEntry *)malloc(count * sizeof(ProximityEntry));
|
||||
CHECK_INVARIANT(tmp,"bad allocation");
|
||||
PeriodicTable *table = PeriodicTable::getTable();
|
||||
Conformer *conf = &mol->getConformer();
|
||||
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
Atom *atom = mol->getAtomWithIdx(i);
|
||||
unsigned int elem = atom->getAtomicNum();
|
||||
RDGeom::Point3D p = conf->getAtomPos(i);
|
||||
ProximityEntry *tmpi = tmp + i;
|
||||
tmpi->x = (float)p.x;
|
||||
tmpi->y = (float)p.y;
|
||||
tmpi->z = (float)p.z;
|
||||
tmpi->r = (float)table->getRcovalent(elem);
|
||||
tmpi->atm = i;
|
||||
tmpi->elem = elem;
|
||||
|
||||
int hash = HASHX * (int)(p.x / MAXDIST) + HASHY * (int)(p.y / MAXDIST) +
|
||||
HASHZ * (int)(p.z / MAXDIST);
|
||||
|
||||
for (int dx = -HASHX; dx <= HASHX; dx += HASHX)
|
||||
for (int dy = -HASHY; dy <= HASHY; dy += HASHY)
|
||||
for (int dz = -HASHZ; dz <= HASHZ; dz += HASHZ) {
|
||||
int probe = hash + dx + dy + dz;
|
||||
int list = HashTable[probe & HASHMASK];
|
||||
while (list != -1) {
|
||||
ProximityEntry *tmpj = &tmp[list];
|
||||
if (tmpj->hash == probe && IsBonded(tmpi, tmpj, flags) &&
|
||||
!mol->getBondBetweenAtoms(tmpi->atm, tmpj->atm) &&
|
||||
!IsBlacklistedPair(atom, mol->getAtomWithIdx(tmpj->atm)))
|
||||
mol->addBond(tmpi->atm, tmpj->atm, Bond::SINGLE);
|
||||
list = tmpj->next;
|
||||
}
|
||||
}
|
||||
int list = hash & HASHMASK;
|
||||
tmpi->next = HashTable[list];
|
||||
HashTable[list] = i;
|
||||
tmpi->hash = hash;
|
||||
}
|
||||
// Cleanup pass
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
Atom *atom = mol->getAtomWithIdx(i);
|
||||
unsigned int elem = atom->getAtomicNum();
|
||||
// detect multivalent Hs, which could happen with ConnectTheDots
|
||||
if (elem == 1 && atom->getDegree() > 1) {
|
||||
AtomPDBResidueInfo *atom_info =
|
||||
(AtomPDBResidueInfo *)(atom->getMonomerInfo());
|
||||
// cut all but shortest Bond
|
||||
RDGeom::Point3D p = conf->getAtomPos(i);
|
||||
RDKit::RWMol::ADJ_ITER nbr, end_nbr;
|
||||
boost::tie(nbr, end_nbr) = mol->getAtomNeighbors(atom);
|
||||
float best = 10000;
|
||||
unsigned int best_idx = mol->getNumAtoms() + 1;
|
||||
while (nbr != end_nbr) {
|
||||
RDGeom::Point3D pn = conf->getAtomPos(*nbr);
|
||||
float d = (p - pn).length();
|
||||
AtomPDBResidueInfo *n_info =
|
||||
(AtomPDBResidueInfo *)(mol->getAtomWithIdx(*nbr)->getMonomerInfo());
|
||||
if (d < best &&
|
||||
atom_info->getResidueNumber() == n_info->getResidueNumber()) {
|
||||
best = d;
|
||||
best_idx = *nbr;
|
||||
}
|
||||
++nbr;
|
||||
}
|
||||
// iterate again and remove all but closest
|
||||
boost::tie(nbr, end_nbr) = mol->getAtomNeighbors(atom);
|
||||
while (nbr != end_nbr) {
|
||||
if (*nbr == best_idx) {
|
||||
Bond *bond = mol->getBondBetweenAtoms(i, *nbr);
|
||||
bond->setBondType(Bond::SINGLE); // make sure this one is single
|
||||
} else {
|
||||
mol->removeBond(i, *nbr);
|
||||
}
|
||||
++nbr;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
void ConnectTheDots(RWMol *mol, unsigned int flags) {
|
||||
if (!mol || !mol->getNumConformers()) return;
|
||||
// Determine optimal algorithm to use by getNumAtoms()?
|
||||
ConnectTheDots_Large(mol, flags);
|
||||
}
|
||||
|
||||
// These are macros to allow their use in C++ constants
|
||||
#define BCNAM(A, B, C) (((A) << 16) | ((B) << 8) | (C))
|
||||
#define BCATM(A, B, C, D) (((A) << 24) | ((B) << 16) | ((C) << 8) | (D))
|
||||
|
||||
static bool StandardPDBDoubleBond(unsigned int rescode, unsigned int atm1,
|
||||
unsigned int atm2) {
|
||||
if (atm1 > atm2) {
|
||||
unsigned int tmp = atm1;
|
||||
atm1 = atm2;
|
||||
atm2 = tmp;
|
||||
}
|
||||
|
||||
switch (rescode) {
|
||||
case BCNAM('A', 'L', 'A'):
|
||||
case BCNAM('C', 'Y', 'S'):
|
||||
case BCNAM('G', 'L', 'Y'):
|
||||
case BCNAM('I', 'L', 'E'):
|
||||
case BCNAM('L', 'E', 'U'):
|
||||
case BCNAM('L', 'Y', 'S'):
|
||||
case BCNAM('M', 'E', 'T'):
|
||||
case BCNAM('P', 'R', 'O'):
|
||||
case BCNAM('S', 'E', 'R'):
|
||||
case BCNAM('T', 'H', 'R'):
|
||||
case BCNAM('V', 'A', 'L'):
|
||||
if (atm1 == BCATM(' ', 'C', ' ', ' ') &&
|
||||
atm2 == BCATM(' ', 'O', ' ', ' '))
|
||||
return true;
|
||||
break;
|
||||
case BCNAM('A', 'R', 'G'):
|
||||
if (atm1 == BCATM(' ', 'C', ' ', ' ') &&
|
||||
atm2 == BCATM(' ', 'O', ' ', ' '))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'Z', ' ') &&
|
||||
atm2 == BCATM(' ', 'N', 'H', '2'))
|
||||
return true;
|
||||
break;
|
||||
case BCNAM('A', 'S', 'N'):
|
||||
case BCNAM('A', 'S', 'P'):
|
||||
if (atm1 == BCATM(' ', 'C', ' ', ' ') &&
|
||||
atm2 == BCATM(' ', 'O', ' ', ' '))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'G', ' ') &&
|
||||
atm2 == BCATM(' ', 'O', 'D', '1'))
|
||||
return true;
|
||||
break;
|
||||
case BCNAM('G', 'L', 'N'):
|
||||
case BCNAM('G', 'L', 'U'):
|
||||
if (atm1 == BCATM(' ', 'C', ' ', ' ') &&
|
||||
atm2 == BCATM(' ', 'O', ' ', ' '))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'D', ' ') &&
|
||||
atm2 == BCATM(' ', 'O', 'E', '1'))
|
||||
return true;
|
||||
break;
|
||||
case BCNAM('H', 'I', 'S'):
|
||||
if (atm1 == BCATM(' ', 'C', ' ', ' ') &&
|
||||
atm2 == BCATM(' ', 'O', ' ', ' '))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'D', '2') &&
|
||||
atm2 == BCATM(' ', 'C', 'G', ' '))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'E', '1') &&
|
||||
atm2 == BCATM(' ', 'N', 'D', '1'))
|
||||
return true;
|
||||
break;
|
||||
case BCNAM('P', 'H', 'E'):
|
||||
case BCNAM('T', 'Y', 'R'):
|
||||
if (atm1 == BCATM(' ', 'C', ' ', ' ') &&
|
||||
atm2 == BCATM(' ', 'O', ' ', ' '))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'D', '1') &&
|
||||
atm2 == BCATM(' ', 'C', 'G', ' '))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'D', '2') &&
|
||||
atm2 == BCATM(' ', 'C', 'E', '2'))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'E', '1') &&
|
||||
atm2 == BCATM(' ', 'C', 'Z', ' '))
|
||||
return true;
|
||||
break;
|
||||
case BCNAM('T', 'R', 'P'):
|
||||
if (atm1 == BCATM(' ', 'C', ' ', ' ') &&
|
||||
atm2 == BCATM(' ', 'O', ' ', ' '))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'D', '1') &&
|
||||
atm2 == BCATM(' ', 'C', 'G', ' '))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'D', '2') &&
|
||||
atm2 == BCATM(' ', 'C', 'E', '2'))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'E', '3') &&
|
||||
atm2 == BCATM(' ', 'C', 'Z', '3'))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'H', '2') &&
|
||||
atm2 == BCATM(' ', 'C', 'Z', '2'))
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool StandardPDBDoubleBond(RWMol *mol, Atom *beg, Atom *end) {
|
||||
AtomPDBResidueInfo *bInfo = (AtomPDBResidueInfo *)beg->getMonomerInfo();
|
||||
if (!bInfo || bInfo->getMonomerType() != AtomMonomerInfo::PDBRESIDUE)
|
||||
return false;
|
||||
AtomPDBResidueInfo *eInfo = (AtomPDBResidueInfo *)end->getMonomerInfo();
|
||||
if (!eInfo || eInfo->getMonomerType() != AtomMonomerInfo::PDBRESIDUE)
|
||||
return false;
|
||||
if (!SamePDBResidue(bInfo, eInfo)) return false;
|
||||
if (bInfo->getIsHeteroAtom() || eInfo->getIsHeteroAtom()) return false;
|
||||
|
||||
const char *ptr = bInfo->getResidueName().c_str();
|
||||
unsigned int rescode = BCNAM(ptr[0], ptr[1], ptr[2]);
|
||||
ptr = bInfo->getName().c_str();
|
||||
unsigned int atm1 = BCATM(ptr[0], ptr[1], ptr[2], ptr[3]);
|
||||
ptr = eInfo->getName().c_str();
|
||||
unsigned int atm2 = BCATM(ptr[0], ptr[1], ptr[2], ptr[3]);
|
||||
|
||||
if (!StandardPDBDoubleBond(rescode, atm1, atm2)) return false;
|
||||
|
||||
// Check that neither end already has a double bond
|
||||
ROMol::OBOND_ITER_PAIR bp;
|
||||
for (bp = mol->getAtomBonds(beg); bp.first != bp.second; ++bp.first)
|
||||
if ((*mol)[*bp.first]->getBondType() == Bond::DOUBLE) return false;
|
||||
for (bp = mol->getAtomBonds(end); bp.first != bp.second; ++bp.first)
|
||||
if ((*mol)[*bp.first]->getBondType() == Bond::DOUBLE) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void StandardPDBResidueBondOrders(RWMol *mol) {
|
||||
RWMol::BondIterator bondIt;
|
||||
for (bondIt = mol->beginBonds(); bondIt != mol->endBonds(); ++bondIt) {
|
||||
Bond *bond = *bondIt;
|
||||
if (bond->getBondType() == Bond::SINGLE) {
|
||||
Atom *beg = bond->getBeginAtom();
|
||||
Atom *end = bond->getEndAtom();
|
||||
if (StandardPDBDoubleBond(mol, beg, end)) bond->setBondType(Bond::DOUBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace RDKit
|
||||
//
|
||||
// Copyright (C) 2013-2017 Greg Landrum and NextMove Software
|
||||
//
|
||||
// @@ 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 "ProximityBonds.h"
|
||||
#include <algorithm>
|
||||
#include <GraphMol/RDKitBase.h>
|
||||
#include <GraphMol/RWMol.h>
|
||||
#include <GraphMol/MonomerInfo.h>
|
||||
|
||||
namespace RDKit {
|
||||
|
||||
static const double EXTDIST = 0.45;
|
||||
// static const double MAXRAD = 2.50;
|
||||
// static const double MINDIST = 0.40;
|
||||
static const double MAXDIST = 5.45; // 2*MAXRAD + EXTDIST
|
||||
static const double MINDIST2 = 0.16; // MINDIST*MINDIST
|
||||
static const double MAXDIST2 = 29.7025; // MAXDIST*MAXDIST
|
||||
|
||||
struct ProximityEntry {
|
||||
float x, y, z, r;
|
||||
int atm, hash, next, elem;
|
||||
|
||||
bool operator<(const ProximityEntry &p) const { return x < p.x; }
|
||||
};
|
||||
|
||||
static bool IsBonded(ProximityEntry *p, ProximityEntry *q, unsigned int flags) {
|
||||
if (flags & ctdIGNORE_H_H_CONTACTS && p->elem == 1 && q->elem == 1)
|
||||
return false;
|
||||
double dx = (double)p->x - (double)q->x;
|
||||
double dist2 = dx * dx;
|
||||
if (dist2 > MAXDIST2) return false;
|
||||
double dy = (double)p->y - (double)q->y;
|
||||
dist2 += dy * dy;
|
||||
if (dist2 > MAXDIST2) return false;
|
||||
double dz = (double)p->z - (double)q->z;
|
||||
dist2 += dz * dz;
|
||||
|
||||
if (dist2 > MAXDIST2 || dist2 < MINDIST2) return false;
|
||||
|
||||
double radius = (double)p->r + (double)q->r + EXTDIST;
|
||||
return dist2 <= radius * radius;
|
||||
}
|
||||
|
||||
bool SamePDBResidue(AtomPDBResidueInfo *p, AtomPDBResidueInfo *q) {
|
||||
return p->getResidueNumber() == q->getResidueNumber() &&
|
||||
p->getResidueName() == q->getResidueName() &&
|
||||
p->getChainId() == q->getChainId() &&
|
||||
p->getInsertionCode() == q->getInsertionCode();
|
||||
}
|
||||
|
||||
static bool IsBlacklistedAtom(Atom *atom) {
|
||||
// blacklist metals, noble gasses and halogens
|
||||
int elem = atom->getAtomicNum();
|
||||
// make an inverse query (non-metals and metaloids)
|
||||
if ((5 <= elem && elem <= 8) || (14 <= elem && elem <= 16) ||
|
||||
(32 <= elem && elem <= 34) || (51 <= elem && elem <= 52))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsBlacklistedPair(Atom *beg_atom, Atom *end_atom) {
|
||||
PRECONDITION(beg_atom, "empty atom");
|
||||
PRECONDITION(end_atom, "empty atom");
|
||||
|
||||
AtomPDBResidueInfo *beg_info =
|
||||
(AtomPDBResidueInfo *)beg_atom->getMonomerInfo();
|
||||
AtomPDBResidueInfo *end_info =
|
||||
(AtomPDBResidueInfo *)end_atom->getMonomerInfo();
|
||||
if (!beg_info || beg_info->getMonomerType() != AtomMonomerInfo::PDBRESIDUE)
|
||||
return false;
|
||||
if (!end_info || end_info->getMonomerType() != AtomMonomerInfo::PDBRESIDUE)
|
||||
return false;
|
||||
|
||||
if (!SamePDBResidue(beg_info, end_info)) {
|
||||
if (IsBlacklistedAtom(beg_atom) || IsBlacklistedAtom(end_atom)) return true;
|
||||
// Dont make bonds to waters
|
||||
if (beg_info->getResidueName() == "HOH" ||
|
||||
end_info->getResidueName() == "HOH")
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
static void ConnectTheDots_Small(RWMol *mol)
|
||||
{
|
||||
unsigned int count = mol->getNumAtoms();
|
||||
ProximityEntry *tmp = (ProximityEntry*)malloc(count*sizeof(ProximityEntry));
|
||||
PeriodicTable *table = PeriodicTable::getTable();
|
||||
Conformer *conf = &mol->getConformer();
|
||||
for (unsigned int i=0; i<count; i++) {
|
||||
Atom *atom = mol->getAtomWithIdx(i);
|
||||
unsigned int elem = atom->getAtomicNum();
|
||||
RDGeom::Point3D p = conf->getAtomPos(i);
|
||||
ProximityEntry *tmpi = tmp+i;
|
||||
tmpi->x = (float)p.x;
|
||||
tmpi->y = (float)p.y;
|
||||
tmpi->z = (float)p.z;
|
||||
tmpi->r = (float)table->getRcovalent(elem);
|
||||
for (unsigned int j=0; j<i; j++) {
|
||||
ProximityEntry *tmpj = tmp+j;
|
||||
if (IsBonded(tmpi,tmpj) && !mol->getBondBetweenAtoms(i,j))
|
||||
mol->addBond(i,j,Bond::SINGLE);
|
||||
}
|
||||
}
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
|
||||
static void ConnectTheDots_Medium(RWMol *mol)
|
||||
{
|
||||
int count = mol->getNumAtoms();
|
||||
std::vector<ProximityEntry> tmp(count);
|
||||
PeriodicTable *table = PeriodicTable::getTable();
|
||||
Conformer *conf = &mol->getConformer();
|
||||
for (int i=0; i<count; i++) {
|
||||
Atom *atom = mol->getAtomWithIdx(i);
|
||||
unsigned int elem = atom->getAtomicNum();
|
||||
RDGeom::Point3D p = conf->getAtomPos(i);
|
||||
ProximityEntry *tmpi = &tmp[i];
|
||||
tmpi->x = (float)p.x;
|
||||
tmpi->y = (float)p.y;
|
||||
tmpi->z = (float)p.z;
|
||||
tmpi->r = (float)table->getRcovalent(elem);
|
||||
tmpi->atm = i;
|
||||
}
|
||||
|
||||
std::stable_sort(tmp.begin(),tmp.end());
|
||||
|
||||
for (int j=0; j<count; j++) {
|
||||
ProximityEntry *tmpj = &tmp[j];
|
||||
double limit = tmpj->x - MAXDIST;
|
||||
for (int k=j-1; k>=0; k--) {
|
||||
ProximityEntry *tmpk = &tmp[k];
|
||||
if (tmpk->x < limit)
|
||||
break;
|
||||
if (IsBonded(tmpj,tmpk) &&
|
||||
!mol->getBondBetweenAtoms(tmpj->atm,tmpk->atm))
|
||||
mol->addBond(tmpj->atm,tmpk->atm,Bond::SINGLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#define HASHSIZE 1024
|
||||
#define HASHMASK 1023
|
||||
#define HASHX 571
|
||||
#define HASHY 127
|
||||
#define HASHZ 3
|
||||
|
||||
static void ConnectTheDots_Large(RWMol *mol, unsigned int flags) {
|
||||
int HashTable[HASHSIZE];
|
||||
memset(HashTable, -1, sizeof(HashTable));
|
||||
|
||||
unsigned int count = mol->getNumAtoms();
|
||||
ProximityEntry *tmp =
|
||||
(ProximityEntry *)malloc(count * sizeof(ProximityEntry));
|
||||
CHECK_INVARIANT(tmp,"bad allocation");
|
||||
PeriodicTable *table = PeriodicTable::getTable();
|
||||
Conformer *conf = &mol->getConformer();
|
||||
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
Atom *atom = mol->getAtomWithIdx(i);
|
||||
unsigned int elem = atom->getAtomicNum();
|
||||
RDGeom::Point3D p = conf->getAtomPos(i);
|
||||
ProximityEntry *tmpi = tmp + i;
|
||||
tmpi->x = (float)p.x;
|
||||
tmpi->y = (float)p.y;
|
||||
tmpi->z = (float)p.z;
|
||||
tmpi->r = (float)table->getRcovalent(elem);
|
||||
tmpi->atm = i;
|
||||
tmpi->elem = elem;
|
||||
|
||||
int hash = HASHX * (int)(p.x / MAXDIST) + HASHY * (int)(p.y / MAXDIST) +
|
||||
HASHZ * (int)(p.z / MAXDIST);
|
||||
|
||||
for (int dx = -HASHX; dx <= HASHX; dx += HASHX)
|
||||
for (int dy = -HASHY; dy <= HASHY; dy += HASHY)
|
||||
for (int dz = -HASHZ; dz <= HASHZ; dz += HASHZ) {
|
||||
int probe = hash + dx + dy + dz;
|
||||
int list = HashTable[probe & HASHMASK];
|
||||
while (list != -1) {
|
||||
ProximityEntry *tmpj = &tmp[list];
|
||||
if (tmpj->hash == probe && IsBonded(tmpi, tmpj, flags) &&
|
||||
!mol->getBondBetweenAtoms(tmpi->atm, tmpj->atm) &&
|
||||
!IsBlacklistedPair(atom, mol->getAtomWithIdx(tmpj->atm)))
|
||||
mol->addBond(tmpi->atm, tmpj->atm, Bond::SINGLE);
|
||||
list = tmpj->next;
|
||||
}
|
||||
}
|
||||
int list = hash & HASHMASK;
|
||||
tmpi->next = HashTable[list];
|
||||
HashTable[list] = i;
|
||||
tmpi->hash = hash;
|
||||
}
|
||||
// Cleanup pass
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
Atom *atom = mol->getAtomWithIdx(i);
|
||||
unsigned int elem = atom->getAtomicNum();
|
||||
// detect multivalent Hs, which could happen with ConnectTheDots
|
||||
if (elem == 1 && atom->getDegree() > 1) {
|
||||
AtomPDBResidueInfo *atom_info =
|
||||
(AtomPDBResidueInfo *)(atom->getMonomerInfo());
|
||||
// cut all but shortest Bond
|
||||
RDGeom::Point3D p = conf->getAtomPos(i);
|
||||
RDKit::RWMol::ADJ_ITER nbr, end_nbr;
|
||||
boost::tie(nbr, end_nbr) = mol->getAtomNeighbors(atom);
|
||||
float best = 10000;
|
||||
unsigned int best_idx = mol->getNumAtoms() + 1;
|
||||
while (nbr != end_nbr) {
|
||||
RDGeom::Point3D pn = conf->getAtomPos(*nbr);
|
||||
float d = (p - pn).length();
|
||||
AtomPDBResidueInfo *n_info =
|
||||
(AtomPDBResidueInfo *)(mol->getAtomWithIdx(*nbr)->getMonomerInfo());
|
||||
if (d < best &&
|
||||
atom_info->getResidueNumber() == n_info->getResidueNumber()) {
|
||||
best = d;
|
||||
best_idx = *nbr;
|
||||
}
|
||||
++nbr;
|
||||
}
|
||||
// iterate again and remove all but closest
|
||||
boost::tie(nbr, end_nbr) = mol->getAtomNeighbors(atom);
|
||||
while (nbr != end_nbr) {
|
||||
if (*nbr == best_idx) {
|
||||
Bond *bond = mol->getBondBetweenAtoms(i, *nbr);
|
||||
bond->setBondType(Bond::SINGLE); // make sure this one is single
|
||||
} else {
|
||||
mol->removeBond(i, *nbr);
|
||||
}
|
||||
++nbr;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
void ConnectTheDots(RWMol *mol, unsigned int flags) {
|
||||
if (!mol || !mol->getNumConformers()) return;
|
||||
// Determine optimal algorithm to use by getNumAtoms()?
|
||||
ConnectTheDots_Large(mol, flags);
|
||||
}
|
||||
|
||||
// These are macros to allow their use in C++ constants
|
||||
#define BCNAM(A, B, C) (((A) << 16) | ((B) << 8) | (C))
|
||||
#define BCATM(A, B, C, D) (((A) << 24) | ((B) << 16) | ((C) << 8) | (D))
|
||||
|
||||
static bool StandardPDBDoubleBond(unsigned int rescode, unsigned int atm1,
|
||||
unsigned int atm2) {
|
||||
if (atm1 > atm2) {
|
||||
unsigned int tmp = atm1;
|
||||
atm1 = atm2;
|
||||
atm2 = tmp;
|
||||
}
|
||||
|
||||
switch (rescode) {
|
||||
case BCNAM('A', 'L', 'A'):
|
||||
case BCNAM('C', 'Y', 'S'):
|
||||
case BCNAM('G', 'L', 'Y'):
|
||||
case BCNAM('I', 'L', 'E'):
|
||||
case BCNAM('L', 'E', 'U'):
|
||||
case BCNAM('L', 'Y', 'S'):
|
||||
case BCNAM('M', 'E', 'T'):
|
||||
case BCNAM('P', 'R', 'O'):
|
||||
case BCNAM('S', 'E', 'R'):
|
||||
case BCNAM('T', 'H', 'R'):
|
||||
case BCNAM('V', 'A', 'L'):
|
||||
if (atm1 == BCATM(' ', 'C', ' ', ' ') &&
|
||||
atm2 == BCATM(' ', 'O', ' ', ' '))
|
||||
return true;
|
||||
break;
|
||||
case BCNAM('A', 'R', 'G'):
|
||||
if (atm1 == BCATM(' ', 'C', ' ', ' ') &&
|
||||
atm2 == BCATM(' ', 'O', ' ', ' '))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'Z', ' ') &&
|
||||
atm2 == BCATM(' ', 'N', 'H', '2'))
|
||||
return true;
|
||||
break;
|
||||
case BCNAM('A', 'S', 'N'):
|
||||
case BCNAM('A', 'S', 'P'):
|
||||
if (atm1 == BCATM(' ', 'C', ' ', ' ') &&
|
||||
atm2 == BCATM(' ', 'O', ' ', ' '))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'G', ' ') &&
|
||||
atm2 == BCATM(' ', 'O', 'D', '1'))
|
||||
return true;
|
||||
break;
|
||||
case BCNAM('G', 'L', 'N'):
|
||||
case BCNAM('G', 'L', 'U'):
|
||||
if (atm1 == BCATM(' ', 'C', ' ', ' ') &&
|
||||
atm2 == BCATM(' ', 'O', ' ', ' '))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'D', ' ') &&
|
||||
atm2 == BCATM(' ', 'O', 'E', '1'))
|
||||
return true;
|
||||
break;
|
||||
case BCNAM('H', 'I', 'S'):
|
||||
if (atm1 == BCATM(' ', 'C', ' ', ' ') &&
|
||||
atm2 == BCATM(' ', 'O', ' ', ' '))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'D', '2') &&
|
||||
atm2 == BCATM(' ', 'C', 'G', ' '))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'E', '1') &&
|
||||
atm2 == BCATM(' ', 'N', 'D', '1'))
|
||||
return true;
|
||||
break;
|
||||
case BCNAM('P', 'H', 'E'):
|
||||
case BCNAM('T', 'Y', 'R'):
|
||||
if (atm1 == BCATM(' ', 'C', ' ', ' ') &&
|
||||
atm2 == BCATM(' ', 'O', ' ', ' '))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'D', '1') &&
|
||||
atm2 == BCATM(' ', 'C', 'G', ' '))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'D', '2') &&
|
||||
atm2 == BCATM(' ', 'C', 'E', '2'))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'E', '1') &&
|
||||
atm2 == BCATM(' ', 'C', 'Z', ' '))
|
||||
return true;
|
||||
break;
|
||||
case BCNAM('T', 'R', 'P'):
|
||||
if (atm1 == BCATM(' ', 'C', ' ', ' ') &&
|
||||
atm2 == BCATM(' ', 'O', ' ', ' '))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'D', '1') &&
|
||||
atm2 == BCATM(' ', 'C', 'G', ' '))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'D', '2') &&
|
||||
atm2 == BCATM(' ', 'C', 'E', '2'))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'E', '3') &&
|
||||
atm2 == BCATM(' ', 'C', 'Z', '3'))
|
||||
return true;
|
||||
if (atm1 == BCATM(' ', 'C', 'H', '2') &&
|
||||
atm2 == BCATM(' ', 'C', 'Z', '2'))
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool StandardPDBDoubleBond(RWMol *mol, Atom *beg, Atom *end) {
|
||||
AtomPDBResidueInfo *bInfo = (AtomPDBResidueInfo *)beg->getMonomerInfo();
|
||||
if (!bInfo || bInfo->getMonomerType() != AtomMonomerInfo::PDBRESIDUE)
|
||||
return false;
|
||||
AtomPDBResidueInfo *eInfo = (AtomPDBResidueInfo *)end->getMonomerInfo();
|
||||
if (!eInfo || eInfo->getMonomerType() != AtomMonomerInfo::PDBRESIDUE)
|
||||
return false;
|
||||
if (!SamePDBResidue(bInfo, eInfo)) return false;
|
||||
if (bInfo->getIsHeteroAtom() || eInfo->getIsHeteroAtom()) return false;
|
||||
|
||||
const char *ptr = bInfo->getResidueName().c_str();
|
||||
unsigned int rescode = BCNAM(ptr[0], ptr[1], ptr[2]);
|
||||
ptr = bInfo->getName().c_str();
|
||||
unsigned int atm1 = BCATM(ptr[0], ptr[1], ptr[2], ptr[3]);
|
||||
ptr = eInfo->getName().c_str();
|
||||
unsigned int atm2 = BCATM(ptr[0], ptr[1], ptr[2], ptr[3]);
|
||||
|
||||
if (!StandardPDBDoubleBond(rescode, atm1, atm2)) return false;
|
||||
|
||||
// Check that neither end already has a double bond
|
||||
ROMol::OBOND_ITER_PAIR bp;
|
||||
for (bp = mol->getAtomBonds(beg); bp.first != bp.second; ++bp.first)
|
||||
if ((*mol)[*bp.first]->getBondType() == Bond::DOUBLE) return false;
|
||||
for (bp = mol->getAtomBonds(end); bp.first != bp.second; ++bp.first)
|
||||
if ((*mol)[*bp.first]->getBondType() == Bond::DOUBLE) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void StandardPDBResidueBondOrders(RWMol *mol) {
|
||||
RWMol::BondIterator bondIt;
|
||||
for (bondIt = mol->beginBonds(); bondIt != mol->endBonds(); ++bondIt) {
|
||||
Bond *bond = *bondIt;
|
||||
if (bond->getBondType() == Bond::SINGLE) {
|
||||
Atom *beg = bond->getBeginAtom();
|
||||
Atom *end = bond->getEndAtom();
|
||||
if (StandardPDBDoubleBond(mol, beg, end)) bond->setBondType(Bond::DOUBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace RDKit
|
||||
|
||||
0
Code/GraphMol/FileParsers/mol1.cdxml
Executable file → Normal file
0
Code/GraphMol/FileParsers/mol1.cdxml
Executable file → Normal file
0
Code/GraphMol/FileParsers/testExecs/.cvskeep
Executable file → Normal file
0
Code/GraphMol/FileParsers/testExecs/.cvskeep
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/Issue180.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/Issue180.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/NCI_aids_few.sdf
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/NCI_aids_few.sdf
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/badringstereochem.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/badringstereochem.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/badringstereochem2.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/badringstereochem2.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/badringstereochem3.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/badringstereochem3.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/bond-query.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/bond-query.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/chiral1.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/chiral1.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/chiral2.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/chiral2.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/chiral3.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/chiral3.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/chiral4.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/chiral4.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/cmpd1.tpl
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/cmpd1.tpl
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/cmpd2.tpl
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/cmpd2.tpl
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/earlyEOF.sdf
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/earlyEOF.sdf
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/empty.sdf
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/empty.sdf
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/empty.smi
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/empty.smi
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/esters.sdf
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/esters.sdf
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/esters_end.sdf
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/esters_end.sdf
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/fewSmi.2.csv
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/fewSmi.2.csv
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/fewSmi.csv
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/fewSmi.csv
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/first_200.tpsa.csv
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/first_200.tpsa.csv
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/issue123.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/issue123.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/list-query.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/list-query.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/missingCR.sdf
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/missingCR.sdf
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/mol1.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/mol1.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/outNCI_arom.sdf
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/outNCI_arom.sdf
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/triazine.mol
Executable file → Normal file
0
Code/GraphMol/FileParsers/test_data/triazine.mol
Executable file → Normal file
@@ -1087,7 +1087,7 @@ int findSSSR(const ROMol &mol, VECT_INT_VECT &res) {
|
||||
FindRings::storeRingsInfo(mol, res);
|
||||
|
||||
// update the ring memberships of atoms and bonds in the molecule:
|
||||
// store the SSSR rings on the the molecule as a property
|
||||
// store the SSSR rings on the molecule as a property
|
||||
// we will ignore any existing SSSRs ont eh molecule - simply overwrite
|
||||
return rdcast<int>(res.size());
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ const std::string morganFingerprintVersion = "1.0.0";
|
||||
The algorithm used is described in the paper
|
||||
Rogers, D. & Hahn, M. Extended-Connectivity Fingerprints. JCIM 50:742-54
|
||||
(2010)
|
||||
http://dx.doi.org/10.1021/ci100050t
|
||||
https://doi.org/10.1021/ci100050t
|
||||
|
||||
The original implementation was done using this paper:
|
||||
D. Rogers, R.D. Brown, M. Hahn J. Biomol. Screen. 10:682-6 (2005)
|
||||
@@ -115,7 +115,7 @@ RDKIT_FINGERPRINTS_EXPORT SparseIntVect<std::uint32_t> *getFingerprint(
|
||||
The algorithm used is described in the paper
|
||||
Rogers, D. & Hahn, M. Extended-Connectivity Fingerprints. JCIM 50:742-54
|
||||
(2010)
|
||||
http://dx.doi.org/10.1021/ci100050t
|
||||
https://doi.org/10.1021/ci100050t
|
||||
|
||||
The original implementation was done using this paper:
|
||||
D. Rogers, R.D. Brown, M. Hahn J. Biomol. Screen. 10:682-6 (2005)
|
||||
|
||||
0
Code/GraphMol/Fingerprints/testExecs/.cvskeep
Executable file → Normal file
0
Code/GraphMol/Fingerprints/testExecs/.cvskeep
Executable file → Normal file
244
Code/GraphMol/ForceFieldHelpers/FFConvenience.h
Executable file → Normal file
244
Code/GraphMol/ForceFieldHelpers/FFConvenience.h
Executable file → Normal file
@@ -1,122 +1,122 @@
|
||||
//
|
||||
// Copyright (C) 2019 Paolo Tosco
|
||||
//
|
||||
// @@ 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/export.h>
|
||||
#ifndef RD_FFCONVENIENCE_H
|
||||
#define RD_FFCONVENIENCE_H
|
||||
#include <ForceField/ForceField.h>
|
||||
#include <RDGeneral/RDThreads.h>
|
||||
|
||||
namespace RDKit {
|
||||
class ROMol;
|
||||
namespace ForceFieldsHelper {
|
||||
namespace detail {
|
||||
#ifdef RDK_THREADSAFE_SSS
|
||||
void OptimizeMoleculeConfsHelper_(ForceFields::ForceField ff, ROMol *mol,
|
||||
std::vector<std::pair<int, double>> *res,
|
||||
unsigned int threadIdx,
|
||||
unsigned int numThreads, int maxIters) {
|
||||
PRECONDITION(mol, "mol must not be nullptr");
|
||||
PRECONDITION(res, "res must not be nullptr");
|
||||
PRECONDITION(res->size() >= mol->getNumConformers(), "res->size() must be >= mol->getNumConformers()");
|
||||
unsigned int i = 0;
|
||||
ff.positions().resize(mol->getNumAtoms());
|
||||
for (ROMol::ConformerIterator cit = mol->beginConformers();
|
||||
cit != mol->endConformers(); ++cit, ++i) {
|
||||
if (i % numThreads != threadIdx) continue;
|
||||
for (unsigned int aidx = 0; aidx < mol->getNumAtoms(); ++aidx) {
|
||||
ff.positions()[aidx] = &(*cit)->getAtomPos(aidx);
|
||||
}
|
||||
ff.initialize();
|
||||
int needsMore = ff.minimize(maxIters);
|
||||
double e = ff.calcEnergy();
|
||||
(*res)[i] = std::make_pair(needsMore, e);
|
||||
}
|
||||
}
|
||||
|
||||
void OptimizeMoleculeConfsMT(ROMol &mol, const ForceFields::ForceField &ff,
|
||||
std::vector<std::pair<int, double>> &res,
|
||||
int numThreads, int maxIters) {
|
||||
std::vector<std::thread> tg;
|
||||
for (int ti = 0; ti < numThreads; ++ti) {
|
||||
tg.emplace_back(std::thread(detail::OptimizeMoleculeConfsHelper_,
|
||||
ff, &mol, &res, ti, numThreads, maxIters));
|
||||
}
|
||||
for (auto &thread : tg) {
|
||||
if (thread.joinable()) thread.join();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void OptimizeMoleculeConfsST(ROMol &mol, ForceFields::ForceField &ff,
|
||||
std::vector<std::pair<int, double>> &res,
|
||||
int maxIters) {
|
||||
PRECONDITION(res.size() >= mol.getNumConformers(), "res.size() must be >= mol.getNumConformers()");
|
||||
unsigned int i = 0;
|
||||
for (ROMol::ConformerIterator cit = mol.beginConformers();
|
||||
cit != mol.endConformers(); ++cit, ++i) {
|
||||
for (unsigned int aidx = 0; aidx < mol.getNumAtoms(); ++aidx) {
|
||||
ff.positions()[aidx] = &(*cit)->getAtomPos(aidx);
|
||||
}
|
||||
ff.initialize();
|
||||
int needsMore = ff.minimize(maxIters);
|
||||
double e = ff.calcEnergy();
|
||||
res[i] = std::make_pair(needsMore, e);
|
||||
}
|
||||
}
|
||||
} // end of detail namespace
|
||||
|
||||
//! Convenience function for optimizing a molecule using a pre-generated force-field
|
||||
/*
|
||||
\param ff the force-field
|
||||
\param res vector of (needsMore,energy) pairs
|
||||
\param maxIters the maximum number of force-field iterations
|
||||
|
||||
\return a pair with:
|
||||
first: -1 if parameters were missing, 0 if the optimization converged, 1 if
|
||||
more iterations are required.
|
||||
second: the energy
|
||||
*/
|
||||
std::pair<int, double> OptimizeMolecule(ForceFields::ForceField &ff, int maxIters = 1000) {
|
||||
ff.initialize();
|
||||
int res = ff.minimize(maxIters);
|
||||
double e = ff.calcEnergy();
|
||||
return std::make_pair(res, e);
|
||||
}
|
||||
|
||||
//! Convenience function for optimizing all of a molecule's conformations using
|
||||
// a pre-generated force-field
|
||||
/*
|
||||
\param mol the molecule to use
|
||||
\param ff the force-field
|
||||
\param res vector of (needsMore,energy) pairs
|
||||
\param numThreads the number of simultaneous threads to use (only has an
|
||||
effect if the RDKit is compiled with thread support).
|
||||
If set to zero, the max supported by the system will be
|
||||
used.
|
||||
\param maxIters the maximum number of force-field iterations
|
||||
|
||||
*/
|
||||
void OptimizeMoleculeConfs(ROMol &mol, ForceFields::ForceField &ff,
|
||||
std::vector<std::pair<int, double>> &res,
|
||||
int numThreads = 1, int maxIters = 1000) {
|
||||
res.resize(mol.getNumConformers());
|
||||
numThreads = getNumThreadsToUse(numThreads);
|
||||
if (numThreads == 1) {
|
||||
detail::OptimizeMoleculeConfsST(mol, ff, res, maxIters);
|
||||
}
|
||||
#ifdef RDK_THREADSAFE_SSS
|
||||
else {
|
||||
detail::OptimizeMoleculeConfsMT(mol, ff, res, numThreads, maxIters);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} // end of namespace ForceFieldsHelper
|
||||
} // end of namespace RDKit
|
||||
#endif
|
||||
//
|
||||
// Copyright (C) 2019 Paolo Tosco
|
||||
//
|
||||
// @@ 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/export.h>
|
||||
#ifndef RD_FFCONVENIENCE_H
|
||||
#define RD_FFCONVENIENCE_H
|
||||
#include <ForceField/ForceField.h>
|
||||
#include <RDGeneral/RDThreads.h>
|
||||
|
||||
namespace RDKit {
|
||||
class ROMol;
|
||||
namespace ForceFieldsHelper {
|
||||
namespace detail {
|
||||
#ifdef RDK_THREADSAFE_SSS
|
||||
void OptimizeMoleculeConfsHelper_(ForceFields::ForceField ff, ROMol *mol,
|
||||
std::vector<std::pair<int, double>> *res,
|
||||
unsigned int threadIdx,
|
||||
unsigned int numThreads, int maxIters) {
|
||||
PRECONDITION(mol, "mol must not be nullptr");
|
||||
PRECONDITION(res, "res must not be nullptr");
|
||||
PRECONDITION(res->size() >= mol->getNumConformers(), "res->size() must be >= mol->getNumConformers()");
|
||||
unsigned int i = 0;
|
||||
ff.positions().resize(mol->getNumAtoms());
|
||||
for (ROMol::ConformerIterator cit = mol->beginConformers();
|
||||
cit != mol->endConformers(); ++cit, ++i) {
|
||||
if (i % numThreads != threadIdx) continue;
|
||||
for (unsigned int aidx = 0; aidx < mol->getNumAtoms(); ++aidx) {
|
||||
ff.positions()[aidx] = &(*cit)->getAtomPos(aidx);
|
||||
}
|
||||
ff.initialize();
|
||||
int needsMore = ff.minimize(maxIters);
|
||||
double e = ff.calcEnergy();
|
||||
(*res)[i] = std::make_pair(needsMore, e);
|
||||
}
|
||||
}
|
||||
|
||||
void OptimizeMoleculeConfsMT(ROMol &mol, const ForceFields::ForceField &ff,
|
||||
std::vector<std::pair<int, double>> &res,
|
||||
int numThreads, int maxIters) {
|
||||
std::vector<std::thread> tg;
|
||||
for (int ti = 0; ti < numThreads; ++ti) {
|
||||
tg.emplace_back(std::thread(detail::OptimizeMoleculeConfsHelper_,
|
||||
ff, &mol, &res, ti, numThreads, maxIters));
|
||||
}
|
||||
for (auto &thread : tg) {
|
||||
if (thread.joinable()) thread.join();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void OptimizeMoleculeConfsST(ROMol &mol, ForceFields::ForceField &ff,
|
||||
std::vector<std::pair<int, double>> &res,
|
||||
int maxIters) {
|
||||
PRECONDITION(res.size() >= mol.getNumConformers(), "res.size() must be >= mol.getNumConformers()");
|
||||
unsigned int i = 0;
|
||||
for (ROMol::ConformerIterator cit = mol.beginConformers();
|
||||
cit != mol.endConformers(); ++cit, ++i) {
|
||||
for (unsigned int aidx = 0; aidx < mol.getNumAtoms(); ++aidx) {
|
||||
ff.positions()[aidx] = &(*cit)->getAtomPos(aidx);
|
||||
}
|
||||
ff.initialize();
|
||||
int needsMore = ff.minimize(maxIters);
|
||||
double e = ff.calcEnergy();
|
||||
res[i] = std::make_pair(needsMore, e);
|
||||
}
|
||||
}
|
||||
} // end of detail namespace
|
||||
|
||||
//! Convenience function for optimizing a molecule using a pre-generated force-field
|
||||
/*
|
||||
\param ff the force-field
|
||||
\param res vector of (needsMore,energy) pairs
|
||||
\param maxIters the maximum number of force-field iterations
|
||||
|
||||
\return a pair with:
|
||||
first: -1 if parameters were missing, 0 if the optimization converged, 1 if
|
||||
more iterations are required.
|
||||
second: the energy
|
||||
*/
|
||||
std::pair<int, double> OptimizeMolecule(ForceFields::ForceField &ff, int maxIters = 1000) {
|
||||
ff.initialize();
|
||||
int res = ff.minimize(maxIters);
|
||||
double e = ff.calcEnergy();
|
||||
return std::make_pair(res, e);
|
||||
}
|
||||
|
||||
//! Convenience function for optimizing all of a molecule's conformations using
|
||||
// a pre-generated force-field
|
||||
/*
|
||||
\param mol the molecule to use
|
||||
\param ff the force-field
|
||||
\param res vector of (needsMore,energy) pairs
|
||||
\param numThreads the number of simultaneous threads to use (only has an
|
||||
effect if the RDKit is compiled with thread support).
|
||||
If set to zero, the max supported by the system will be
|
||||
used.
|
||||
\param maxIters the maximum number of force-field iterations
|
||||
|
||||
*/
|
||||
void OptimizeMoleculeConfs(ROMol &mol, ForceFields::ForceField &ff,
|
||||
std::vector<std::pair<int, double>> &res,
|
||||
int numThreads = 1, int maxIters = 1000) {
|
||||
res.resize(mol.getNumConformers());
|
||||
numThreads = getNumThreadsToUse(numThreads);
|
||||
if (numThreads == 1) {
|
||||
detail::OptimizeMoleculeConfsST(mol, ff, res, maxIters);
|
||||
}
|
||||
#ifdef RDK_THREADSAFE_SSS
|
||||
else {
|
||||
detail::OptimizeMoleculeConfsMT(mol, ff, res, numThreads, maxIters);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} // end of namespace ForceFieldsHelper
|
||||
} // end of namespace RDKit
|
||||
#endif
|
||||
|
||||
@@ -2869,7 +2869,7 @@ MMFFMolProperties::getMMFFBondStretchEmpiricalRuleParams(const ROMol &mol,
|
||||
} else {
|
||||
// MMFF.V, page 627
|
||||
// Herschbach-Laurie version of Badger's rule
|
||||
// J. Chem. Phys. 35, 458 (1961); http://dx.doi.org/10.1063/1.1731952
|
||||
// J. Chem. Phys. 35, 458 (1961); https://doi.org/10.1063/1.1731952
|
||||
// equation (8), page 5
|
||||
mmffHerschbachLaurieParams = (*mmffHerschbachLaurie)(
|
||||
getPeriodicTableRowHL(atomicNum1), getPeriodicTableRowHL(atomicNum2));
|
||||
@@ -3575,7 +3575,7 @@ void MMFFMolProperties::computeMMFFCharges(const ROMol &mol) {
|
||||
}
|
||||
// now we compute partial charges
|
||||
// See Halgren, T. MMFF.V, J. Comput. Chem. 1996, 17, 616-641
|
||||
// http://dx.doi.org/10.1002/(SICI)1096-987X(199604)17:5/6<616::AID-JCC5>3.0.CO;2-X
|
||||
// https://doi.org/10.1002/(SICI)1096-987X(199604)17:5/6<616::AID-JCC5>3.0.CO;2-X
|
||||
for (idx = 0; idx < mol.getNumAtoms(); ++idx) {
|
||||
const Atom *atom = mol.getAtomWithIdx(idx);
|
||||
atomType = this->getMMFFAtomType(idx);
|
||||
|
||||
0
Code/GraphMol/ForceFieldHelpers/MMFF/test_data/cyclobutadiene.mol
Executable file → Normal file
0
Code/GraphMol/ForceFieldHelpers/MMFF/test_data/cyclobutadiene.mol
Executable file → Normal file
0
Code/GraphMol/ForceFieldHelpers/UFF/test_data/cyclobutadiene.mol
Executable file → Normal file
0
Code/GraphMol/ForceFieldHelpers/UFF/test_data/cyclobutadiene.mol
Executable file → Normal file
0
Code/GraphMol/FragCatalog/Wrap/testFrags.csv
Executable file → Normal file
0
Code/GraphMol/FragCatalog/Wrap/testFrags.csv
Executable file → Normal file
0
Code/GraphMol/FragCatalog/Wrap/test_data/testFrags.csv
Executable file → Normal file
0
Code/GraphMol/FragCatalog/Wrap/test_data/testFrags.csv
Executable file → Normal file
0
Code/GraphMol/FragCatalog/testExecs/.cvskeep
Executable file → Normal file
0
Code/GraphMol/FragCatalog/testExecs/.cvskeep
Executable file → Normal file
0
Code/GraphMol/FragCatalog/test_data/4mols.smi
Executable file → Normal file
0
Code/GraphMol/FragCatalog/test_data/4mols.smi
Executable file → Normal file
0
Code/GraphMol/FragCatalog/test_data/funcGroups.txt
Executable file → Normal file
0
Code/GraphMol/FragCatalog/test_data/funcGroups.txt
Executable file → Normal file
0
Code/GraphMol/FragCatalog/test_data/mols.smi
Executable file → Normal file
0
Code/GraphMol/FragCatalog/test_data/mols.smi
Executable file → Normal file
0
Code/GraphMol/FragCatalog/test_data/testFrags.csv
Executable file → Normal file
0
Code/GraphMol/FragCatalog/test_data/testFrags.csv
Executable file → Normal file
@@ -125,7 +125,7 @@ static void addResult(std::vector<std::pair<ROMOL_SPTR, ROMOL_SPTR>>&
|
||||
// remove the bond
|
||||
em.removeBond(bi.first, bi.second);
|
||||
|
||||
// now add attachement points and set attachment point lables
|
||||
// now add attachment points and set attachment point labels
|
||||
auto* a = new Atom(0);
|
||||
a->setProp(common_properties::molAtomMapNumber, (int)isotope);
|
||||
unsigned newAtomA = em.addAtom(a, true, true);
|
||||
|
||||
@@ -1707,7 +1707,6 @@ void MolDraw2D::drawTriangle(const Point2D &cds1, const Point2D &cds2,
|
||||
void MolDraw2D::drawArrow(const Point2D &arrowBegin, const Point2D &arrowEnd,
|
||||
bool asPolygon, double frac, double angle) {
|
||||
Point2D delta = arrowBegin - arrowEnd;
|
||||
double l = frac * delta.length();
|
||||
double cos_angle = std::cos(angle), sin_angle = std::sin(angle);
|
||||
|
||||
Point2D p1 = arrowEnd;
|
||||
|
||||
@@ -100,14 +100,14 @@ computePrincipalAxesAndMomentsFromGyrationMatrix(
|
||||
// the y-axis
|
||||
//! and the smallest with the z-axis
|
||||
/*!
|
||||
If center is not specified the the centroid of the conformer will be used
|
||||
If center is not specified the centroid of the conformer will be used
|
||||
\param conf Conformer of interest
|
||||
\param center Center to be used for canonicalization, defaults to
|
||||
the centroid of the
|
||||
conformation
|
||||
\param normalizeCovar Normalize the covariance matrix with the number of
|
||||
atoms
|
||||
\param ignoreHs Optinally ignore hydrogens
|
||||
\param ignoreHs Optionally ignore hydrogens
|
||||
*/
|
||||
RDKIT_MOLTRANSFORMS_EXPORT RDGeom::Transform3D *computeCanonicalTransform(
|
||||
const RDKit::Conformer &conf, const RDGeom::Point3D *center = 0,
|
||||
|
||||
0
Code/GraphMol/MolTransforms/ReadMe
Executable file → Normal file
0
Code/GraphMol/MolTransforms/ReadMe
Executable file → Normal file
@@ -134,7 +134,7 @@ BOOST_PYTHON_MODULE(rdMolTransforms) {
|
||||
|
||||
docString =
|
||||
"Compute the transformation required aligna conformer so that\n\
|
||||
the the principal axes align up with the x,y, z axes\n\
|
||||
the principal axes align up with the x,y, z axes\n\
|
||||
The conformer itself is left unchanged\n\
|
||||
ARGUMENTS:\n\
|
||||
- conf : the conformer of interest\n\
|
||||
|
||||
0
Code/GraphMol/MolTransforms/testExecs/.cvskeep
Executable file → Normal file
0
Code/GraphMol/MolTransforms/testExecs/.cvskeep
Executable file → Normal file
0
Code/GraphMol/PartialCharges/Wrap/test_data/PP_combi_charges.pkl
Executable file → Normal file
0
Code/GraphMol/PartialCharges/Wrap/test_data/PP_combi_charges.pkl
Executable file → Normal file
0
Code/GraphMol/PartialCharges/Wrap/test_data/PP_descrs_regress.2.csv
Executable file → Normal file
0
Code/GraphMol/PartialCharges/Wrap/test_data/PP_descrs_regress.2.csv
Executable file → Normal file
0
Code/GraphMol/PartialCharges/Wrap/test_data/halgren.smi
Executable file → Normal file
0
Code/GraphMol/PartialCharges/Wrap/test_data/halgren.smi
Executable file → Normal file
0
Code/GraphMol/PartialCharges/Wrap/test_data/halgren_out.txt
Executable file → Normal file
0
Code/GraphMol/PartialCharges/Wrap/test_data/halgren_out.txt
Executable file → Normal file
@@ -972,9 +972,9 @@ class HasPropWithValueQuery<TargetPtr, ExplicitBitVect>
|
||||
what->template getProp<const ExplicitBitVect &>(propname);
|
||||
const double tani = TanimotoSimilarity(val, bv);
|
||||
res = (1.0 - tani) <= tol;
|
||||
} catch (KeyErrorException) {
|
||||
} catch (KeyErrorException &) {
|
||||
res = false;
|
||||
} catch (boost::bad_any_cast) {
|
||||
} catch (boost::bad_any_cast &) {
|
||||
res = false;
|
||||
}
|
||||
#ifdef __GNUC__
|
||||
|
||||
@@ -825,7 +825,7 @@ struct RGroupDecompData {
|
||||
// Is this necessary?
|
||||
CHECK_INVARIANT(
|
||||
atom->getAtomicNum() > 1,
|
||||
"Multiple attachements to a dummy (or hydrogen) is weird.");
|
||||
"Multiple attachments to a dummy (or hydrogen) is weird.");
|
||||
auto *newAt = new Atom(0);
|
||||
setRlabel(newAt, rlabel);
|
||||
atomsToAdd.push_back(std::make_pair(atom, newAt));
|
||||
|
||||
@@ -433,7 +433,7 @@ class RDKIT_GRAPHMOL_EXPORT ROMol : public RDProps {
|
||||
\param conf - conformation to be added to the molecule, this molecule takes
|
||||
ownership
|
||||
of the conformer
|
||||
\param assignId - a unique ID will be assigned to the the conformation if
|
||||
\param assignId - a unique ID will be assigned to the conformation if
|
||||
true
|
||||
otherwise it is assumed that the conformation already has
|
||||
an (unique) ID set
|
||||
|
||||
@@ -34,7 +34,7 @@ class RDKIT_GRAPHMOL_EXPORT ResonanceMolSupplier {
|
||||
public:
|
||||
typedef enum {
|
||||
/*! include resonance structures whose octets are less complete
|
||||
* than the the most octet-complete structure */
|
||||
* than the most octet-complete structure */
|
||||
ALLOW_INCOMPLETE_OCTETS = (1 << 0),
|
||||
/*! include resonance structures featuring charge separation also
|
||||
* when uncharged resonance structures exist */
|
||||
|
||||
0
Code/GraphMol/SmilesParse/esmiles.flex
Executable file → Normal file
0
Code/GraphMol/SmilesParse/esmiles.flex
Executable file → Normal file
0
Code/GraphMol/SmilesParse/esmiles.y
Executable file → Normal file
0
Code/GraphMol/SmilesParse/esmiles.y
Executable file → Normal file
0
Code/GraphMol/SmilesParse/regress.txt
Executable file → Normal file
0
Code/GraphMol/SmilesParse/regress.txt
Executable file → Normal file
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user