* fixes
* do not leak MolCatalogParams
* do not leak points on align failures
* give python ownership of pointers returned in getFingerprintsHelper
* clean up ScaffoldNetwork ptr if createNetworkHelper fails
* manage FF ptrs during construction
* wire in ownsBondInvGenerator in getMorganGenerator
* manage weights in rdMolAlign CalcRMS
* fix ownership of matches list/tuple in generateRmsdTransMatchPyTuple
* manage stream in createForwardSupplier during construction
* drop redundant Point3D allocations in GetUSRDistributionsFromPoints
* fix signed comparison mismatch
* fix unsigned int to int comparison
* revert previous mistake
* declaration & init together, sinthetaSq in [0, 1]
* using std::swap
* use that sinThetaSq in [0,1]
* declare & init at same time
* use knowledge about target range
* use std::clamp
* use std::max
* numerically more stable trigonometrics
* numerically more stable trigonometrics
* numerically more stable trigonometrics
* range based for-loop
* actually do the assignement
* Update Code/ForceField/MMFF/Params.h
Co-authored-by: Greg Landrum <greg.landrum@gmail.com>
* implemented suggested changes
* Revert "implemented suggested changes"
This reverts commit f56e8f0ab2.
* auto typing
* remove old comment
* revert to numerically more stable expression
* now correctly formatted
---------
Co-authored-by: Greg Landrum <greg.landrum@gmail.com>
* - added gen_rdkit_stubs Python module to generate rdkit-stubs
- added patch_rdkit_docstrings Python module to patch existing C++ sources to fix docstrings missing self parameter and add named parameters taken from C++ signatures where possible
- added rdkit-stubs/CMakeLists.txt to build rdkit-stubs as part of the RDKit build
- added an option to CMakeLists.txt to enable building rdkit-stubs as part of the RDKit build (defaults to OFF)
* fixed CMakeLists.txt, rdkit-stubs/CMakeLists.txt and a doctest
* - added missing cmp_func parameter
- fixed case with overloads with optional parameters
- do not trim params if expected_param_count == -1
- add dummy parameter names if we could not find any
- keep into account member functions when making up parameter names
- address __init__ and make_constructor __init__ functions
- fix incorrectly assigned staticmethods
* patched sources
* address residual few remarks
---------
Co-authored-by: ptosco <paolo.tosco@novartis.com>
* Remove accidentally tracked files and unset x flag
* Ignore ComicNeue
* Unify test tag to `reader`
* Trivial destructors
* Bump CMAKE_CXX_STANDARD to 14 (#4165)
- fixes energies and gradients for dihedral and angle constraints in both MMFF and UFF
- adds butane scan tests for MMFF and UFF
- reduce huge angle/dihedral restraint force constants that cause the minimizer to struggle in tests
Co-authored-by: Paolo Tosco <paolo.tosco@novartis.com>
* change minimal cmake version to a consistent 3.5
* progress towards a cleanup
* get the basic python deps working
* two more libs
* another round of changes
all tests pass at this point
* next round of changes
all tests pass at this point
* close to done
all tests pass
* very close
* almost done
* shift the RDBoost dependencies around a bit
* remove an extraneous python linkage
this is trying to get the mac builds working again
* Only link to python if it was built shared (#3091)
* change in response to review
Co-Authored-By: Ric <ricrogz@users.noreply.github.com>
* move that suppression of the maybe-uninitialized warning to BoostStartInclude.h
Co-authored-by: Brian Kelley <fustigator@gmail.com>
Co-authored-by: Ric <ricrogz@users.noreply.github.com>
* run clang-tidy with readability-braces-around-statements
clang-format the results
clean up all the parts that clang-tidy-8 broke
* fix problem on windows
* a round of cleanups courtesy of PVS studio
* add a test to make sure that a warning is a false alarm
* bug fix
* Fix a UFF bug
* more PVS studio cleanups
* next round of PVS studio cleanups
* completely remove the chances for that bug
* changes in response to review
* add an additional test
+ a bit of reformatting that snuck in
* disable builds of the StructChecker code by default
* operator"" _smarts() doesn't need to catch sanitization errors
* remove unused function
* turn back on some tests that shouldn't have been disabled
* Remove unused code from SMARTS parser and simplify a bit
SmilesParseOps::AddFragToMol is now used only from the SMARTS parser, so we can simplify the API
* Removes obsolete special case code for SMARTS
This was relevant when organic atoms in SMARTS queries were stored as two-part queries.
* improve SMARTS testing
make sure we can generate SMARTS from all the examples and then parse that again.
* Fixes#2814
* Fixes#2815
* some additional smarts tests to improve coverage
* test copy ctor and getPos
* remove obsolete test_list files
* include tests for the morgan invariant generators
* more cleanups and coverage improvements
* remove files that were mistakenly added
* - fixed UFF/MMFF torsion constraints when the dihedral is set to 0.0
- removed some code duplication
- added relevant test and fixed existing ones
* - fix Windows exports
* - added PRECONDITION for RDGeom::Point3D pointers
- removed inline keywords
o rdkit gains a RDKit::common_properties namespace that contains common string value properties
o Dict.h and below gain getPropIfPresent that attempts to retrieve a property and returns
true/false on success or failure. This is used to optimize access.
o rdkit learns how to pass property keys by reference, not value.
A new namespace has been added to RDKit, common_properties
that contains the std::string values for commonly used
properties. This helps to avoid typos in string values
but also avoids a creation of std::strings from character
values. All accessors (has/get/clear and getPropIfPresent) now pass
the key by reference.
Additionally, getPropIfPresent removes the double lookup
of hasProp/getProp which can be a significant speedup
in the smiles and smarts parsers (10-20%)
which caused issues with negative angles
- made also UFF/AngleConstraint.cpp and MMFF/AngleConstraint.cpp more
robust against angle ranges involving negative values
- added relevant C++ and Python tests
(i.e., equilibrium distances/angles and force constants) from
UFF and MMFF in response to two requests recently appeared
on the RDKit-discuss mailing list:
http://sourceforge.net/p/rdkit/mailman/message/32953737/http://sourceforge.net/p/rdkit/mailman/message/32880156/
- did some clean up on the MMFF code
- NB there are two ABI changes:
1) StretchBendContrib(ForceField *owner,
const unsigned int idx1, const unsigned int idx2, const unsigned int idx3,
const MMFFStbn *mmffStbnParams, const MMFFAngle *mmffAngleParams,
const MMFFBond *mmffBondParams1, const MMFFBond *mmffBondParams2);
previously was:
StretchBendContrib(ForceField *owner,
const unsigned int idx1, const unsigned int idx2, const unsigned int idx3,
const std::pair<bool, const MMFFStbn *> mmffStbnParams,
const MMFFAngle *mmffAngleParams, const MMFFBond *mmffBondParams1,
const MMFFBond *mmffBondParams2);
2) std::pair<double, double> calcStbnForceConstants(const MMFFStbn *mmffStbnParams);
previously was:
std::pair<double, double> calcStbnForceConstants
(const std::pair<bool, const MMFFStbn *> mmffStbnParams);
The two changes are NOT mandatory - however, both the StretchBendContrib constructor
and calcStbnForceConstants(), though public, are basically "internal" method that
most likely no-one has ever invoked. Given that the current API is MUCH better
and cleaner, I would really advise for the new version.
data races in the multithreaded test
- Removed a spurious #include in Code/ForceField/Wrap/ForceField.cpp
- Restored caching in Code/GraphMol/Descriptors/Crippen.cpp
to the current value) (C++/Python)
- added absolute/relative AngleConstraints (C++/Python)
- added absolute/relative TorsionConstraints (C++/Python)
- added PositionConstraints (C++/Python)
- exposed fixedPoints from Python
- added relevant C++/Python tests
- removed a number of redundant "this->" in member functions
- moved some getGrad() code into Utils::calcAngleBendGrad and
Utils::calcTorsionGrad to avoid repeating the same code
for constraints
to a newly allocated MMFFMolProperties object) with a simple
constructor of the MMFFMolProperties object
- Replaced in a few MMFF-related functions the "ROMol *" argument
with a "ROMol &" argument for consistency with similar RDKit
functions
- Renamed the SetupMMFFForceField() function in Python into
GetMMFFMolProperties() for consistency
- Updated the MMFF tests according to the aforementioned changes
in the API
incorrect typing might arise when hydrogens were not added after
generating 3D coordinates from SMILES strings; now all 761 test molecules
are correctly typed no matter whether hydrogens are explicit or implicit
- MMFF test suite: I have cut down to the bare essential the
MMFF94/MMFF94s reference log files, but their size could be reduced only
by about 30%. It could have been reduced more converting multiple spaces
into a tab, but the MMFF94 file (the larger one) would still be around
11 MB, and human readability would be greatly impaired. Hence I decided
to keep the spaces and gzip the reference logs, which reduces their
combined size to ~ 3.5 MB, which I think is fine; the test program checks
if the gunzipped files already exist, otherwise it gunzips them upfront.
While cutting, I also sorted the molecules in the same order as in the
SDF/SMILES files, so that it runs about 10 times faster than before.
Now the test runs on MMFF94 only (MMFF94s only concerns different OOP
parameters, there are no algorithmic differences, so as long as one does
not alter the original parameters it can be safely skipped), computing
every 4th molecule, and it runs in 12 seconds on my laptop. Running
all molecules takes ~ 50 seconds, but I think it is rather overkill,
and I would keep it as it is.
- I have added a test suite for MMFF ForceFieldHelpers (like the one
already existing for UFF); I have also complemented the Python wrapper
test suite for ForceFieldHelpers with a few tests for MMFF.
- I have written Python wrappers for the MMFF-related functionality;
while doing that I realized that many of the wrapper code relocations
that I made in my previous pull request were not necessary/appropriate,
so I reverted them. The only difference from the UFF Python API is that,
just like for the C++ API, in addition to the PyForceField object there
is a PyMMFFMolProperties object which is created before constructing the
force field itself; the PyMMFFMolProperties is necessary to set (e.g.,
dielectric constant, dielectric model) or get (e.g., atom type, formal
and partial charge) some MMFF properties which are not present in UFF,
while preserving binary compatibility of the libraries. Probably you
remember that we discussed about setting atom type and charge properties
with SetProp besides populating the MMFFMolProperties object, in order
to allow easy access to Python users. However, I think that the solution
I adopted is preferrable since it is more consistent with the C++ API,
it enables faster access to properties and it allows tailoring the MMFF
environment (i.e., choosing MMFF94/MMFF94s, setting the verbosity level,
including/excluding terms from the MMFF equation, setting dielectric
constant/model) just as from C++.
The MMFF-related Python functions I implemented are:
* MMFFOptimizeMolecule(mol, mmffVariant = "MMFF94", maxIters = 200,
nonBondedThresh = 100.0, confId = -1, ignoreInterfragInteractions
= true)
uses MMFF to optimize a molecule's structure (just like
UFFOptimizeMolecule)
* SanitizeMMFFMol(mol)
sanitizes a molecule according to MMFF requirements
* SetupMMFFForceField(mol, mmffVariant = "MMFF94", mmffVerbosity = 0)
returns a PyMMFFMolProperties object for a molecule; the
PyMMFFMolProperties object is required by MMFFGetMoleculeForceField()
and can be used to get/set MMFF properties
* MMFFGetMoleculeForceField(mol, pyMMFFMolProperties,
nonBondedThresh = 100.0, confId = -1, ignoreInterfragInteractions
= true)
returns a MMFF force field for a molecule (just like
UFFGetMoleculeForceField)
* MMFFHasAllMoleculeParams(mol)
checks if MMFF parameters are available for all of a molecule's atoms
(just like UFFHasAllMoleculeParams)
There are also a few methods connected to the PyMMFFMolProperties class
which mirror those available from C++ for the MMFFMolProperties class:
* GetMMFFAtomType(idx)
Retrieves MMFF atom type for atom with index idx
* GetMMFFFormalCharge(idx)
Retrieves MMFF formal charge for atom with index idx
* GetMMFFPartialCharge(idx)
Retrieves MMFF partial charge for atom with index idx
* SetMMFFDielectricModel(dielModel = 1)
sets the DielModel MMFF property (1: constant; 2: distance-dependent;
defaults to constant)
* SetMMFFDielectricConstant(dielConst = 1.0)
Sets the DielConst MMFF property (defaults to 1.0)
* SetMMFFBondTerm(state = True)
Sets the bond term to be included in the MMFF equation (defaults
to True)
* SetMMFFAngleTerm(state = True)
Sets the angle term to be included in the MMFF equation (defaults
to True)
* SetMMFFStretchBendTerm(state = True)
Sets the stretch-bend term to be included in the MMFF equation (defaults
to True)
* SetMMFFOopTerm(state = True)
Sets the out-of-plane bend term to be included in the MMFF equation
(defaults to True)
* SetMMFFTorsionTerm(state = True)
Sets the torsional term to be included in the MMFF equation (defaults
to True)
* SetMMFFVdWTerm(state = True)
Sets the Van der Waals term to be included in the MMFF equation
(defaults to True)
* SetMMFFEleTerm(state = True)
Sets the electrostatic term to be included in the MMFF equation
(defaults to True)
* SetMMFFVariant(mmffVariant = "MMFF94")
Sets the MMFF variant to be used ("MMFF94" or "MMFF94s"; defaults to
"MMFF94")
* SetMMFFVerbosity(verbosity = 0)
Sets the MMFF verbosity (0: none; 1: low; 2: high; defaults to 0)
Hence, most users will do something like this to optimize a molecule
structure obtained from a SMILES string:
from rdkit import Chem
from rdkit.Chem import AllChem
m = Chem.MolFromSmiles("O=C(C)c1cccnc1", False)
AllChem.SanitizeMMFFMol(m)
m2 = Chem.AddHs(m)
AllChem.EmbedMolecule(m2)
# Opt
AllChem.MMFFOptimizeMolecule(m2)
print >>file('structure_min.sdf','w'), Chem.MolToMolBlock(m2)
Those willing to play a bit more with MMFF properties may do the
following:
from rdkit import Chem
from rdkit.Chem import AllChem
m = Chem.MolFromSmiles("O=C(C)c1cccnc1", False)
AllChem.SanitizeMMFFMol(m)
m2 = Chem.AddHs(m)
AllChem.EmbedMolecule(m2)
pyMP = AllChem.SetupMMFFForceField(m2)
pyMP.SetMMFFVariant("MMFF94s")
pyMP.SetMMFFDielectricModel(2)
pyFF = AllChem.MMFFGetMoleculeForceField(m2, pyMP)
pyFF.Minimize()
print >>file('structure_min.sdf','w'), Chem.MolToMolBlock(m2)
print 'Energy = {0:12.4f}'.format(pyFF.CalcEnergy())
i = 0
for i in range(0, m2.GetNumAtoms()):
print '{0:4d} {1:4d} {2:8.4f} {3:8.4f}'.format(i + 1,
int(pyMP.GetMMFFAtomType(i)),
float(pyMP.GetMMFFFormalCharge(i)),
float(pyMP.GetMMFFPartialCharge(i)))
- OOP backport to UFF. I added the inversion term to the UFF
implementation following the original UFF paper by Rappe'. I have already
modified the figures in a couple of test files to reflect the new energy
values.
- 2-bit neighbor matrix and graph-based angle enumeration now reflect
the MMFF implementation.
Code/ForceField and Code/GraphMol/ForceFieldHelpers to the
respective UFF subfolders since from now on UFF will not be
the only available force field anymore. I updated the
relevant CMakeLists.txt files accordingly.
Paolo