mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-07 22:44:25 +08:00
* add port of centres
* Several changes:
- Added a test based on RDKit issue 2984
(default RDKit fails it, this gets it right)
- Use bond directions for bond stereo (label is no longer required)
- Fix bugs in rules 4b and 5new
- Fix some mem errors
- clang-formatted
- some other minor cleanups
* Several changes and some improvements:
- Added LGPL license, as well as a mention in the doc.
- Fix/update/add some comments
- Fix typo/bug in Mancude calculation
- Fix bug in rules 4b, 5New
- Fix Sp2 Bond dir reference
- Re clang-format
- other minor changes suggested by Dan
* Another bunch of changes:
- require integer-order bonds; kekulize when required
- fix fraction comparison
- rename sq Cis/Trans e/z
- replace queues with vectors
- update copyright notices
- revert LGPL changes
- fix Asymmetric typo
* move to separate lib/mod, add python validation test
* Moving away from the original implementation:
- Rename to CIPLabeler
- Remove the abstraction layer
- Remove some stats stuff
- Push some CIPMol functions down to Node
- Use RDKit's isotope info
* Another bundle of changes. The most relevant ones:
- fix parity translation
- use cis trans as bond reference -- breaks #2984 test
- kill a lot of unused code
- use lists for queues
- store nodes and edges in digraph
- add prefixes to class data member names
- update changeRoot() test
- use fastFindRings() for mancude rings
- update docs
- add references to the scientific paper
- Document the Mancude functions
- Fix Mancude atom types and their comments
- remove mol data member from SequenceRule
- replace Fraction with boost::rational
- update comments, docstrings and the doc
* fix building the test
* Changes here include:
- adding bitset overload for the labeling function
- python wrap of the overload
- handling trigonal pyramids with implicit H
- setting bond labels sets stereo atoms, cis/trans
- nix LEFT/RIGHT/TOGETHER/OPPOSITE constants
- don't use GLOB in cmake
- a decent amount of refactoring
* Minor edits to new_CIP_labeling (#6)
* Some changes for clarity
Added some documentation and changed some variable names to match
my understanding. Also a ran clang-tidy to ensure that all blocks
were brace-enclosed.
* Return a reference instead of a copy for performance
This is called many times and showed up after some light
profiling. This change bumped throughput by about 20%
* move out of Graphmol
* move .hpp headers to .h
* update documentation; add label set of atoms test
* Address comments:
- Added references to centres to CIPLabeler.h and Python Wrap.
- Update validation test to skip sanitization.
- Document mancude fractional atomic number calculation.
- Use unittest assertions in python test.
- Update mancude docstrings to 'resonance' instad of 'tautomers'.
- Rename prioritise() to prioritize().
- Add postcondition to check carriers size in Tetrahedral.cpp.
- Use getNeighbors() in Tetrahedral.cpp.
- Move findStereoAtoms to Chirality namespace.
- Move code back into GraphMol.
- Fix typos and reformat doc.
* More comments:
- Mention why we use boost's unordered map rather than the std one.
- Fix include in Python wrapper.
* Addressed second batch of comments:
- fix the bug in rule 4b
- fix docstring for rule 2
- move atomic mass calculation from rule 2 to node
- addressed some build warnings
- simplify sp2bond::label(comp)
- add start/end atoms to Sp2Bond constructor
- update system/local includes
Co-authored-by: Dan N <dan.nealschneider@schrodinger.com>
109 lines
3.0 KiB
C++
109 lines
3.0 KiB
C++
//
|
|
//
|
|
// Copyright (C) 2020 Schrödinger, LLC
|
|
//
|
|
// @@ 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 <list>
|
|
|
|
#include <RDGeneral/Invariant.h>
|
|
|
|
#include "Rule5New.h"
|
|
|
|
#include "../Digraph.h"
|
|
|
|
namespace RDKit {
|
|
namespace CIPLabeler {
|
|
|
|
Rule5New::Rule5New() = default;
|
|
|
|
Rule5New::Rule5New(Descriptor ref) : d_ref{ref} {}
|
|
|
|
int Rule5New::compare(const Edge *a, const Edge *b) const {
|
|
const auto &aBeg = a->getBeg();
|
|
const auto &aEnd = a->getEnd();
|
|
const auto &bBeg = b->getBeg();
|
|
const auto &bEnd = b->getEnd();
|
|
if (aBeg->getDigraph()->getCurrentRoot() != aBeg ||
|
|
bBeg->getDigraph()->getCurrentRoot() != bBeg) {
|
|
if (d_ref == Descriptor::NONE) {
|
|
return 0;
|
|
}
|
|
Descriptor aDesc = aEnd->getAux();
|
|
Descriptor bDesc = bEnd->getAux();
|
|
if (aDesc != Descriptor::NONE && bDesc != Descriptor::NONE &&
|
|
aDesc != Descriptor::ns && bDesc != Descriptor::ns) {
|
|
bool alike = PairList::ref(d_ref) == PairList::ref(aDesc);
|
|
bool blike = PairList::ref(d_ref) == PairList::ref(bDesc);
|
|
if (alike && !blike) {
|
|
return +1;
|
|
}
|
|
if (blike && !alike) {
|
|
return -1;
|
|
}
|
|
}
|
|
return 0;
|
|
} else {
|
|
auto listRA = PairList(Descriptor::R);
|
|
auto listRB = PairList(Descriptor::R);
|
|
auto listSA = PairList(Descriptor::S);
|
|
auto listSB = PairList(Descriptor::S);
|
|
fillPairs(aEnd, listRA);
|
|
fillPairs(aEnd, listSA);
|
|
fillPairs(bEnd, listRB);
|
|
fillPairs(bEnd, listSB);
|
|
int cmpR = listRA.compareTo(listRB);
|
|
int cmpS = listSA.compareTo(listSB);
|
|
// -2/+2 for psuedo-asymetric
|
|
// -1/+1 if not (e.g. the R > R and S > S lists)
|
|
if (cmpR < 0) {
|
|
return cmpS < 0 ? -1 : -2;
|
|
} else if (cmpR > 0) {
|
|
return cmpS > 0 ? +1 : +2;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Rule5New::fillPairs(const Node *beg, PairList &plist) const {
|
|
const Rule5New replacement_rule(plist.getRefDescriptor());
|
|
const auto &sorter = getRefSorter(&replacement_rule);
|
|
auto queue = std::list<const Node *>({beg});
|
|
|
|
for (const auto &node : queue) {
|
|
|
|
plist.add(node->getAux());
|
|
auto edges = node->getEdges();
|
|
sorter.prioritize(node, edges);
|
|
for (const auto &edge : edges) {
|
|
if (edge->isBeg(node) && !edge->getEnd()->isTerminal()) {
|
|
queue.push_back(edge->getEnd());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Sort Rule5New::getRefSorter(const SequenceRule *replacement_rule) const {
|
|
const auto &rules = getSorter()->getRules();
|
|
|
|
CHECK_INVARIANT(std::find(rules.begin(), rules.end(), this) != rules.end(),
|
|
"Rule5New instance not in rule set");
|
|
|
|
std::vector<const SequenceRule *> new_rules;
|
|
new_rules.reserve(rules.size());
|
|
for (const auto &rule : rules) {
|
|
if (this != rule) {
|
|
new_rules.push_back(rule);
|
|
}
|
|
}
|
|
new_rules.push_back(replacement_rule);
|
|
return {new_rules};
|
|
}
|
|
|
|
} // namespace CIPLabeler
|
|
} // namespace RDKit
|