1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
//
//
// 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
|