Files
rdkit/Code/GraphMol/CIPLabeler/rules/Rule5New.cpp
tadhurst-cdd 0de215a1f8 Fix canonicalization of stereogroups (#7041)
* atropisomer handling added

* fixed non-used variables,  linking directives

* BOOST LIB start/stop fixes, linking fix

* Fixes for RDKIT CI errors

* minimalLib fix

* changed vector<enum> for java builds

* check for extra chars in CIP labeling

* removed wrong deprecated message

* fix ostrstream output error?

* restored _ChiralAtomRank to lowercase first letter

* changes for merged master

* Fixed catch label for new Catch package

* update expected psql results

* get swig wrappers building

* restore MolFileStereochem to FileParsers

* fix java wrapper for reapplyMolBlockWedging

* test changes

* some suggestions

* move a couple functions out of Bond

* Merge branch 'master' into pr/atropisomers2

* merged master

* Renamed setStereoanyFromSquiggleBond

* atropisomers in cdxml, rationalize atrop wedging, stereoGroups in drawMol

* Merge branch 'master' into pr/specialQueries

* changes from previous PR

* Iclude false chiral

* rigorous enhnced stereo canoncalization

* Added more tests and clenup

* removed commented out code

* corrected init of SmilesWriteParams

* added MolFileStereoChem.h to the header files

* Renamed Rxn parser to MrvBlockToChemicalReaction

* To make catch2 work, and match the checksum

* Fixed Structchecker errors

* fix CI for DetermineBonds catch test

* error in catch_test for CI

* Allow custom  smileWriteParams  in GetMolLayers

* misnamed entry point

* ReactionFromMrvString change name

* remove adding writeParams to GetMolLayers

* make rigorous enhanced stereo the default, and fix tests

* only one abs group no longer needs Rigorous Enhanced treatment

* changed string_view to string in catch test

* Canonicalize Enhnaced Stereo only resturne unique smiles

* Now allows or and and groups together

* internal routines inside detail scope

* fix test error

* changed string back to string_view and fixed a CHECK

* Fixes for PR review tests

* Fix RDKit_Book.rst failure on build test

* fix xqm sql test

* updated expected files for cxsmiles_test

* Fixed removal of atom attrs

* Fixed tests after merge of master

* More efficient version of Stereo Groups Canonicalization

* Fixes for ctests

* removed debug code

* readded cipLabel test

* fix generalizedSubstruct/catch_tests.cpp error

* hueristics to improve speed

* Rationaized control of abs groups

* removed unused routine

* added rigorous stereo group treatment to test

* some suggested changes

* Changes per PR review and removed some changes to smiles

* Fixed CI errors

* changes per PR review

* more PR review vhanges and cleanup

* Fixed PSql PKL change

* changes as per PR review

* Restored error type for bad mols for canonicalizeStereoGroups and added a test

* Merge master and fix test in MolDraw2D

* Fix for randomize test error and other PR review comments

* Removed unsued variable to fix mac CI

* do not force aromatization in canonicalizeStereoGroups

* changes as per PR review

---------

Co-authored-by: greg landrum <greg.landrum@gmail.com>
2024-10-11 17:09:18 +02:00

108 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 pseudo-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