18 #include <boost/foreach.hpp> 19 #include <boost/dynamic_bitset.hpp> 38 : bondType(
Bond::UNSPECIFIED),
39 bondStereo(static_cast<unsigned int>(
Bond::STEREONONE)),
45 bondStereo(static_cast<unsigned int>(bs)),
50 : bondType(bt), bondStereo(bs), nbrSymClass(nsc), nbrIdx(ni){};
64 unsigned int div = 1) {
97 isRingStereoAtom(false),
107 canon_atom *atoms, std::vector<bondholder> &nbrs);
110 canon_atom *atoms, std::vector<bondholder> &nbrs,
unsigned int atomIdx,
111 std::vector<std::pair<unsigned int, unsigned int>> &result);
133 dp_atomsInPlay(NULL),
134 dp_bondsInPlay(NULL){};
137 const boost::dynamic_bitset<> *atomsInPlay = NULL,
138 const boost::dynamic_bitset<> *bondsInPlay = NULL)
141 dp_atomsInPlay(atomsInPlay),
142 dp_bondsInPlay(bondsInPlay){};
147 if (dp_atomsInPlay && !((*dp_atomsInPlay)[i] || (*dp_atomsInPlay)[j])) {
151 if ((dp_atomsInPlay && (*dp_atomsInPlay)[i]) || !dp_atomsInPlay) {
154 if ((dp_atomsInPlay && (*dp_atomsInPlay)[j]) || !dp_atomsInPlay) {
157 for (
unsigned int ii = 0;
158 ii < dp_atoms[i].
bonds.size() && ii < dp_atoms[j].
bonds.size(); ++ii) {
164 std::vector<std::pair<unsigned int, unsigned int>> swapsi;
165 std::vector<std::pair<unsigned int, unsigned int>> swapsj;
166 if ((dp_atomsInPlay && (*dp_atomsInPlay)[i]) || !dp_atomsInPlay) {
169 if ((dp_atomsInPlay && (*dp_atomsInPlay)[j]) || !dp_atomsInPlay) {
172 for (
unsigned int ii = 0; ii < swapsi.size() && ii < swapsj.size(); ++ii) {
173 int cmp = swapsi[ii].second - swapsj[ii].second;
189 dp_atomsInPlay(NULL),
190 dp_bondsInPlay(NULL){};
193 const boost::dynamic_bitset<> *atomsInPlay = NULL,
194 const boost::dynamic_bitset<> *bondsInPlay = NULL)
197 dp_atomsInPlay(atomsInPlay),
198 dp_bondsInPlay(bondsInPlay){};
203 if (dp_atomsInPlay && !((*dp_atomsInPlay)[i] || (*dp_atomsInPlay)[j])) {
207 if (dp_atoms[i].neighborNum < dp_atoms[j].neighborNum) {
209 }
else if (dp_atoms[i].neighborNum > dp_atoms[j].neighborNum) {
213 if (dp_atoms[i].revistedNeighbors < dp_atoms[j].revistedNeighbors) {
215 }
else if (dp_atoms[i].revistedNeighbors > dp_atoms[j].revistedNeighbors) {
219 if ((dp_atomsInPlay && (*dp_atomsInPlay)[i]) || !dp_atomsInPlay) {
222 if ((dp_atomsInPlay && (*dp_atomsInPlay)[j]) || !dp_atomsInPlay) {
225 for (
unsigned int ii = 0;
226 ii < dp_atoms[i].
bonds.size() && ii < dp_atoms[j].
bonds.size(); ++ii) {
232 if (dp_atoms[i].bonds.size() < dp_atoms[j].
bonds.size()) {
234 }
else if (dp_atoms[i].bonds.size() > dp_atoms[j].
bonds.size()) {
242 unsigned int getAtomRingNbrCode(
unsigned int i)
const {
243 if (!dp_atoms[i].hasRingNbr)
return 0;
245 int *nbrs = dp_atoms[i].nbrIds;
246 unsigned int code = 0;
247 for (
unsigned j = 0; j < dp_atoms[i].degree; ++j) {
248 if (dp_atoms[nbrs[j]].isRingStereoAtom) {
249 code += dp_atoms[nbrs[j]].index * 10000 + 1;
255 int basecomp(
int i,
int j)
const {
257 unsigned int ivi, ivj;
260 ivi = dp_atoms[i].index;
261 ivj = dp_atoms[j].index;
272 int molAtomMapNumber_i = 0;
273 int molAtomMapNumber_j = 0;
278 if (molAtomMapNumber_i < molAtomMapNumber_j)
280 else if (molAtomMapNumber_i > molAtomMapNumber_j)
284 ivi = dp_atoms[i].degree;
285 ivj = dp_atoms[j].degree;
291 if (dp_atoms[i].p_symbol && dp_atoms[j].p_symbol) {
292 if (*(dp_atoms[i].p_symbol) < *(dp_atoms[j].p_symbol))
294 else if (*(dp_atoms[i].p_symbol) > *(dp_atoms[j].p_symbol))
301 ivi = dp_atoms[i].atom->getAtomicNum();
302 ivj = dp_atoms[j].atom->getAtomicNum();
309 if (df_useIsotopes) {
310 ivi = dp_atoms[i].atom->getIsotope();
311 ivj = dp_atoms[j].atom->getIsotope();
319 ivi = dp_atoms[i].totalNumHs;
320 ivj = dp_atoms[j].totalNumHs;
327 ivi = dp_atoms[i].atom->getFormalCharge();
328 ivj = dp_atoms[j].atom->getFormalCharge();
335 if (df_useChirality) {
342 ivi = cipCode ==
"R" ? 2 : 1;
346 ivj = cipCode ==
"R" ? 2 : 1;
354 ivi = dp_atoms[i].atom->getChiralTag() != 0;
355 ivj = dp_atoms[j].atom->getChiralTag() != 0;
362 if (df_useChiralityRings) {
364 ivi = getAtomRingNbrCode(i);
365 ivj = getAtomRingNbrCode(j);
387 dp_atomsInPlay(NULL),
388 dp_bondsInPlay(NULL),
390 df_useIsotopes(true),
391 df_useChirality(true),
392 df_useChiralityRings(true){};
394 const boost::dynamic_bitset<> *atomsInPlay = NULL,
395 const boost::dynamic_bitset<> *bondsInPlay = NULL)
398 dp_atomsInPlay(atomsInPlay),
399 dp_bondsInPlay(bondsInPlay),
401 df_useIsotopes(true),
402 df_useChirality(true),
403 df_useChiralityRings(true){};
408 if (dp_atomsInPlay && !((*dp_atomsInPlay)[i] || (*dp_atomsInPlay)[j])) {
412 int v = basecomp(i, j);
418 if ((dp_atomsInPlay && (*dp_atomsInPlay)[i]) || !dp_atomsInPlay) {
421 if ((dp_atomsInPlay && (*dp_atomsInPlay)[j]) || !dp_atomsInPlay) {
425 for (
unsigned int ii = 0;
426 ii < dp_atoms[i].
bonds.size() && ii < dp_atoms[j].
bonds.size();
433 if (dp_atoms[i].bonds.size() < dp_atoms[j].
bonds.size()) {
435 }
else if (dp_atoms[i].bonds.size() > dp_atoms[j].
bonds.size()) {
450 void getAtomNeighborhood(std::vector<bondholder> &nbrs)
const {
451 for (
unsigned j = 0; j < nbrs.size(); ++j) {
452 unsigned int nbrIdx = nbrs[j].nbrIdx;
453 if (nbrIdx == ATNUM_CLASS_OFFSET) {
457 const Atom *nbr = dp_atoms[nbrIdx].atom;
458 nbrs[j].nbrSymClass =
459 nbr->
getAtomicNum() * ATNUM_CLASS_OFFSET + dp_atoms[nbrIdx].index + 1;
465 int basecomp(
int i,
int j)
const {
467 unsigned int ivi, ivj;
470 ivi = dp_atoms[i].index;
471 ivj = dp_atoms[j].index;
478 ivi = dp_atoms[i].atom->getAtomicNum();
479 ivj = dp_atoms[j].atom->getAtomicNum();
486 ivi = dp_atoms[i].atom->getIsotope();
487 ivj = dp_atoms[j].atom->getIsotope();
499 ivi = cipCode ==
"R" ? 2 : 1;
503 ivj = cipCode ==
"R" ? 2 : 1;
519 : dp_atoms(NULL), dp_mol(NULL), df_useNbrs(false){};
521 : dp_atoms(atoms), dp_mol(&m), df_useNbrs(false){};
526 int v = basecomp(i, j);
530 getAtomNeighborhood(dp_atoms[i].bonds);
531 getAtomNeighborhood(dp_atoms[j].bonds);
536 for (
unsigned int ii = 0;
537 ii < dp_atoms[i].
bonds.size() && ii < dp_atoms[j].
bonds.size();
540 dp_atoms[i].bonds[ii], dp_atoms[j].bonds[ii], ATNUM_CLASS_OFFSET);
543 for (
unsigned int ii = 0;
544 ii < dp_atoms[i].
bonds.size() && ii < dp_atoms[j].
bonds.size();
550 if (dp_atoms[i].bonds.size() < dp_atoms[j].
bonds.size()) {
552 }
else if (dp_atoms[i].bonds.size() > dp_atoms[j].
bonds.size()) {
565 template <
typename CompareFunc>
567 int mode,
int *order,
int *count,
int &activeset,
568 int *next,
int *changed,
char *touchedPartitions) {
580 while (activeset != -1) {
592 partition = activeset;
593 activeset = next[partition];
594 next[partition] = -2;
596 len = count[partition];
597 offset = atoms[partition].
index;
598 start = order + offset;
609 hanoisort(start, len, count, changed, compar);
616 for (
int k = 0; k < len; ++k) {
617 changed[start[k]] = 0;
623 for (i = count[index]; i < len; i++) {
625 if (count[index]) symclass = offset + i;
626 atoms[index].
index = symclass;
631 for (
unsigned j = 0; j < atoms[index].
degree; ++j) {
632 changed[atoms[index].
nbrIds[j]] = 1;
639 for (i = count[index]; i < len; i++) {
641 for (
unsigned j = 0; j < atoms[index].
degree; ++j) {
642 unsigned int nbor = atoms[index].
nbrIds[j];
643 touchedPartitions[atoms[nbor].
index] = 1;
646 for (
unsigned int ii = 0; ii < nAtoms; ++ii) {
647 if (touchedPartitions[ii]) {
648 partition = order[ii];
649 if ((count[partition] > 1) && (next[partition] == -2)) {
650 next[partition] = activeset;
651 activeset = partition;
653 touchedPartitions[ii] = 0;
660 template <
typename CompareFunc>
662 int mode,
int *order,
int *count,
int &activeset,
int *next,
663 int *changed,
char *touchedPartitions) {
671 for (
unsigned int i = 0; i < nAtoms; i++) {
672 partition = order[i];
673 oldPart = atoms[partition].
index;
674 while (count[partition] > 1) {
675 len = count[partition];
676 offset = atoms[partition].
index + len - 1;
677 index = order[offset];
678 atoms[index].
index = offset;
679 count[partition] = len - 1;
683 if (atoms[index].degree < 1) {
686 for (
unsigned j = 0; j < atoms[index].
degree; ++j) {
687 unsigned int nbor = atoms[index].
nbrIds[j];
688 touchedPartitions[atoms[nbor].
index] = 1;
692 for (
unsigned int ii = 0; ii < nAtoms; ++ii) {
693 if (touchedPartitions[ii]) {
694 int npart = order[ii];
695 if ((count[npart] > 1) && (next[npart] == -2)) {
696 next[npart] = activeset;
699 touchedPartitions[ii] = 0;
703 changed, touchedPartitions);
706 if (atoms[partition].index != oldPart) {
713 int *order,
int *count,
717 int *count,
int &activeset,
718 int *next,
int *changed);
721 std::vector<unsigned int> &res,
722 bool breakTies =
true,
723 bool includeChirality =
true,
724 bool includeIsotopes =
true);
727 const ROMol &mol, std::vector<unsigned int> &res,
728 const boost::dynamic_bitset<> &atomsInPlay,
729 const boost::dynamic_bitset<> &bondsInPlay,
730 const std::vector<std::string> *atomSymbols = NULL,
bool breakTies =
true,
731 bool includeChirality =
true,
bool includeIsotopes =
true);
734 std::vector<unsigned int> &res);
737 std::vector<Canon::canon_atom> &atoms,
738 bool includeChirality =
true);
bool operator<(const bondholder &o) const
RDKIT_RDGENERAL_EXPORT const std::string molAtomMapNumber
SpecialSymmetryAtomCompareFunctor()
const boost::dynamic_bitset * dp_bondsInPlay
int operator()(int i, int j) const
RDKIT_GRAPHMOL_EXPORT void updateAtomNeighborNumSwaps(canon_atom *atoms, std::vector< bondholder > &nbrs, unsigned int atomIdx, std::vector< std::pair< unsigned int, unsigned int >> &result)
unsigned int getNumAtoms(bool onlyExplicit=1) const
returns our number of atoms
std::vector< int > neighborNum
Defines the primary molecule class ROMol as well as associated typedefs.
RDKIT_RDGENERAL_EXPORT const std::string _CIPCode
void hanoisort(int *base, int nel, int *count, int *changed, CompareFunc compar)
bool df_useChiralityRings
BondStereo
the nature of the bond's stereochem (for cis/trans)
Canon::canon_atom * dp_atoms
AtomCompareFunctor(Canon::canon_atom *atoms, const ROMol &m, const boost::dynamic_bitset<> *atomsInPlay=NULL, const boost::dynamic_bitset<> *bondsInPlay=NULL)
bondholder(Bond::BondType bt, Bond::BondStereo bs, unsigned int ni, unsigned int nsc)
RDKIT_GRAPHMOL_EXPORT void updateAtomNeighborIndex(canon_atom *atoms, std::vector< bondholder > &nbrs)
int operator()(int i, int j) const
const boost::dynamic_bitset * dp_bondsInPlay
static bool greater(const bondholder &lhs, const bondholder &rhs)
#define RDKIT_GRAPHMOL_EXPORT
int operator()(int i, int j) const
ChiralAtomCompareFunctor(Canon::canon_atom *atoms, const ROMol &m)
RDKIT_GRAPHMOL_EXPORT void rankMolAtoms(const ROMol &mol, std::vector< unsigned int > &res, bool breakTies=true, bool includeChirality=true, bool includeIsotopes=true)
const unsigned int ATNUM_CLASS_OFFSET
Canon::canon_atom * dp_atoms
RDKIT_GRAPHMOL_EXPORT void ActivatePartitions(unsigned int nAtoms, int *order, int *count, int &activeset, int *next, int *changed)
SpecialSymmetryAtomCompareFunctor(Canon::canon_atom *atoms, const ROMol &m, const boost::dynamic_bitset<> *atomsInPlay=NULL, const boost::dynamic_bitset<> *bondsInPlay=NULL)
RDKIT_GRAPHMOL_EXPORT void CreateSinglePartition(unsigned int nAtoms, int *order, int *count, canon_atom *atoms)
std::vector< bondholder > bonds
ChiralAtomCompareFunctor()
int operator()(int i, int j) const
RDKIT_GRAPHMOL_EXPORT void rankFragmentAtoms(const ROMol &mol, std::vector< unsigned int > &res, const boost::dynamic_bitset<> &atomsInPlay, const boost::dynamic_bitset<> &bondsInPlay, const std::vector< std::string > *atomSymbols=NULL, bool breakTies=true, bool includeChirality=true, bool includeIsotopes=true)
int getAtomicNum() const
returns our atomic number
void BreakTies(const ROMol &mol, canon_atom *atoms, CompareFunc compar, int mode, int *order, int *count, int &activeset, int *next, int *changed, char *touchedPartitions)
Canon::canon_atom * dp_atoms
const boost::dynamic_bitset * dp_bondsInPlay
std::vector< int > revistedNeighbors
class for representing a bond
SpecialChiralityAtomCompareFunctor()
static int compare(const bondholder &x, const bondholder &y, unsigned int div=1)
void RefinePartitions(const ROMol &mol, canon_atom *atoms, CompareFunc compar, int mode, int *order, int *count, int &activeset, int *next, int *changed, char *touchedPartitions)
#define PRECONDITION(expr, mess)
RDKIT_GRAPHMOL_EXPORT void initCanonAtoms(const ROMol &mol, std::vector< Canon::canon_atom > &atoms, bool includeChirality=true)
RDKIT_GRAPHMOL_EXPORT void chiralRankMolAtoms(const ROMol &mol, std::vector< unsigned int > &res)
bondholder(Bond::BondType bt, unsigned int bs, unsigned int ni, unsigned int nsc)
SpecialChiralityAtomCompareFunctor(Canon::canon_atom *atoms, const ROMol &m, const boost::dynamic_bitset<> *atomsInPlay=NULL, const boost::dynamic_bitset<> *bondsInPlay=NULL)
const std::string * p_symbol
The class for representing atoms.
Canon::canon_atom * dp_atoms