17 #include <boost/cstdint.hpp> 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) {
96 isRingStereoAtom(false),
104 canon_atom *atoms, std::vector<bondholder> &nbrs,
unsigned int atomIdx,
105 std::vector<std::pair<unsigned int, unsigned int> > &result);
127 dp_atomsInPlay(NULL),
128 dp_bondsInPlay(NULL){};
131 const boost::dynamic_bitset<> *atomsInPlay = NULL,
132 const boost::dynamic_bitset<> *bondsInPlay = NULL)
135 dp_atomsInPlay(atomsInPlay),
136 dp_bondsInPlay(bondsInPlay){};
141 if (dp_atomsInPlay && !((*dp_atomsInPlay)[i] || (*dp_atomsInPlay)[j])) {
145 if ((dp_atomsInPlay && (*dp_atomsInPlay)[i]) || !dp_atomsInPlay) {
148 if ((dp_atomsInPlay && (*dp_atomsInPlay)[j]) || !dp_atomsInPlay) {
151 for (
unsigned int ii = 0;
152 ii < dp_atoms[i].
bonds.size() && ii < dp_atoms[j].
bonds.size(); ++ii) {
158 std::vector<std::pair<unsigned int, unsigned int> > swapsi;
159 std::vector<std::pair<unsigned int, unsigned int> > swapsj;
160 if ((dp_atomsInPlay && (*dp_atomsInPlay)[i]) || !dp_atomsInPlay) {
163 if ((dp_atomsInPlay && (*dp_atomsInPlay)[j]) || !dp_atomsInPlay) {
166 for (
unsigned int ii = 0; ii < swapsi.size() && ii < swapsj.size(); ++ii) {
167 int cmp = swapsi[ii].second - swapsj[ii].second;
183 dp_atomsInPlay(NULL),
184 dp_bondsInPlay(NULL){};
187 const boost::dynamic_bitset<> *atomsInPlay = NULL,
188 const boost::dynamic_bitset<> *bondsInPlay = NULL)
191 dp_atomsInPlay(atomsInPlay),
192 dp_bondsInPlay(bondsInPlay){};
197 if (dp_atomsInPlay && !((*dp_atomsInPlay)[i] || (*dp_atomsInPlay)[j])) {
201 if (dp_atoms[i].neighborNum < dp_atoms[j].neighborNum) {
203 }
else if (dp_atoms[i].neighborNum > dp_atoms[j].neighborNum) {
207 if (dp_atoms[i].revistedNeighbors < dp_atoms[j].revistedNeighbors) {
209 }
else if (dp_atoms[i].revistedNeighbors > dp_atoms[j].revistedNeighbors) {
213 if ((dp_atomsInPlay && (*dp_atomsInPlay)[i]) || !dp_atomsInPlay) {
216 if ((dp_atomsInPlay && (*dp_atomsInPlay)[j]) || !dp_atomsInPlay) {
219 for (
unsigned int ii = 0;
220 ii < dp_atoms[i].
bonds.size() && ii < dp_atoms[j].
bonds.size(); ++ii) {
226 if (dp_atoms[i].bonds.size() < dp_atoms[j].
bonds.size()) {
228 }
else if (dp_atoms[i].bonds.size() > dp_atoms[j].
bonds.size()) {
236 unsigned int getAtomRingNbrCode(
unsigned int i)
const {
237 if (!dp_atoms[i].hasRingNbr)
return 0;
239 int *nbrs = dp_atoms[i].nbrIds;
240 unsigned int code = 0;
241 for (
unsigned j = 0; j < dp_atoms[i].degree; ++j) {
242 if (dp_atoms[nbrs[j]].isRingStereoAtom) {
243 code += dp_atoms[nbrs[j]].index * 10000 + 1;
249 int basecomp(
int i,
int j)
const {
251 unsigned int ivi, ivj;
254 ivi = dp_atoms[i].index;
255 ivj = dp_atoms[j].index;
266 int molAtomMapNumber_i = 0;
267 int molAtomMapNumber_j = 0;
272 if (molAtomMapNumber_i < molAtomMapNumber_j)
274 else if (molAtomMapNumber_i > molAtomMapNumber_j)
278 ivi = dp_atoms[i].degree;
279 ivj = dp_atoms[j].degree;
285 if (dp_atoms[i].p_symbol && dp_atoms[j].p_symbol) {
286 if (*(dp_atoms[i].p_symbol) < *(dp_atoms[j].p_symbol))
288 else if (*(dp_atoms[i].p_symbol) > *(dp_atoms[j].p_symbol))
295 ivi = dp_atoms[i].atom->getAtomicNum();
296 ivj = dp_atoms[j].atom->getAtomicNum();
303 if (df_useIsotopes) {
304 ivi = dp_atoms[i].atom->getIsotope();
305 ivj = dp_atoms[j].atom->getIsotope();
313 ivi = dp_atoms[i].totalNumHs;
314 ivj = dp_atoms[j].totalNumHs;
321 ivi = dp_atoms[i].atom->getFormalCharge();
322 ivj = dp_atoms[j].atom->getFormalCharge();
329 if (df_useChirality) {
336 ivi = cipCode ==
"R" ? 2 : 1;
340 ivj = cipCode ==
"R" ? 2 : 1;
348 ivi = dp_atoms[i].atom->getChiralTag() != 0;
349 ivj = dp_atoms[j].atom->getChiralTag() != 0;
356 if (df_useChiralityRings) {
358 ivi = getAtomRingNbrCode(i);
359 ivj = getAtomRingNbrCode(j);
381 dp_atomsInPlay(NULL),
382 dp_bondsInPlay(NULL),
384 df_useIsotopes(true),
385 df_useChirality(true),
386 df_useChiralityRings(true){};
388 const boost::dynamic_bitset<> *atomsInPlay = NULL,
389 const boost::dynamic_bitset<> *bondsInPlay = NULL)
392 dp_atomsInPlay(atomsInPlay),
393 dp_bondsInPlay(bondsInPlay),
395 df_useIsotopes(true),
396 df_useChirality(true),
397 df_useChiralityRings(true){};
402 if (dp_atomsInPlay && !((*dp_atomsInPlay)[i] || (*dp_atomsInPlay)[j])) {
406 int v = basecomp(i, j);
412 if ((dp_atomsInPlay && (*dp_atomsInPlay)[i]) || !dp_atomsInPlay) {
415 if ((dp_atomsInPlay && (*dp_atomsInPlay)[j]) || !dp_atomsInPlay) {
419 for (
unsigned int ii = 0;
420 ii < dp_atoms[i].
bonds.size() && ii < dp_atoms[j].
bonds.size();
427 if (dp_atoms[i].bonds.size() < dp_atoms[j].
bonds.size()) {
429 }
else if (dp_atoms[i].bonds.size() > dp_atoms[j].
bonds.size()) {
444 void getAtomNeighborhood(std::vector<bondholder> &nbrs)
const {
445 for (
unsigned j = 0; j < nbrs.size(); ++j) {
446 unsigned int nbrIdx = nbrs[j].nbrIdx;
447 if (nbrIdx == ATNUM_CLASS_OFFSET) {
451 const Atom *nbr = dp_atoms[nbrIdx].atom;
452 nbrs[j].nbrSymClass =
453 nbr->
getAtomicNum() * ATNUM_CLASS_OFFSET + dp_atoms[nbrIdx].index + 1;
459 int basecomp(
int i,
int j)
const {
461 unsigned int ivi, ivj;
464 ivi = dp_atoms[i].index;
465 ivj = dp_atoms[j].index;
472 ivi = dp_atoms[i].atom->getAtomicNum();
473 ivj = dp_atoms[j].atom->getAtomicNum();
480 ivi = dp_atoms[i].atom->getIsotope();
481 ivj = dp_atoms[j].atom->getIsotope();
493 ivi = cipCode ==
"R" ? 2 : 1;
497 ivj = cipCode ==
"R" ? 2 : 1;
513 : dp_atoms(NULL), dp_mol(NULL), df_useNbrs(false){};
515 : dp_atoms(atoms), dp_mol(&m), df_useNbrs(false){};
520 int v = basecomp(i, j);
524 getAtomNeighborhood(dp_atoms[i].bonds);
525 getAtomNeighborhood(dp_atoms[j].bonds);
530 for (
unsigned int ii = 0;
531 ii < dp_atoms[i].
bonds.size() && ii < dp_atoms[j].
bonds.size();
534 dp_atoms[i].bonds[ii], dp_atoms[j].bonds[ii], ATNUM_CLASS_OFFSET);
537 for (
unsigned int ii = 0;
538 ii < dp_atoms[i].
bonds.size() && ii < dp_atoms[j].
bonds.size();
544 if (dp_atoms[i].bonds.size() < dp_atoms[j].
bonds.size()) {
546 }
else if (dp_atoms[i].bonds.size() > dp_atoms[j].
bonds.size()) {
559 template <
typename CompareFunc>
561 int mode,
int *order,
int *count,
int &activeset,
562 int *next,
int *changed,
char *touchedPartitions) {
574 while (activeset != -1) {
586 partition = activeset;
587 activeset = next[partition];
588 next[partition] = -2;
590 len = count[partition];
591 offset = atoms[partition].
index;
592 start = order + offset;
603 hanoisort(start, len, count, changed, compar);
610 for (
int k = 0; k < len; ++k) {
611 changed[start[k]] = 0;
617 for (i = count[index]; i < len; i++) {
619 if (count[index]) symclass = offset + i;
620 atoms[index].
index = symclass;
625 for (
unsigned j = 0; j < atoms[index].
degree; ++j) {
626 changed[atoms[index].
nbrIds[j]] = 1;
633 for (i = count[index]; i < len; i++) {
635 for (
unsigned j = 0; j < atoms[index].
degree; ++j) {
636 unsigned int nbor = atoms[index].
nbrIds[j];
637 touchedPartitions[atoms[nbor].
index] = 1;
640 for (
unsigned int ii = 0; ii < nAtoms; ++ii) {
641 if (touchedPartitions[ii]) {
642 partition = order[ii];
643 if ((count[partition] > 1) && (next[partition] == -2)) {
644 next[partition] = activeset;
645 activeset = partition;
647 touchedPartitions[ii] = 0;
654 template <
typename CompareFunc>
656 int mode,
int *order,
int *count,
int &activeset,
int *next,
657 int *changed,
char *touchedPartitions) {
665 for (
unsigned int i = 0; i < nAtoms; i++) {
666 partition = order[i];
667 oldPart = atoms[partition].
index;
668 while (count[partition] > 1) {
669 len = count[partition];
670 offset = atoms[partition].
index + len - 1;
671 index = order[offset];
672 atoms[index].
index = offset;
673 count[partition] = len - 1;
677 if (atoms[index].degree < 1) {
680 for (
unsigned j = 0; j < atoms[index].
degree; ++j) {
681 unsigned int nbor = atoms[index].
nbrIds[j];
682 touchedPartitions[atoms[nbor].
index] = 1;
686 for (
unsigned int ii = 0; ii < nAtoms; ++ii) {
687 if (touchedPartitions[ii]) {
688 int npart = order[ii];
689 if ((count[npart] > 1) && (next[npart] == -2)) {
690 next[npart] = activeset;
693 touchedPartitions[ii] = 0;
697 changed, touchedPartitions);
700 if (atoms[partition].index != oldPart) {
710 int &activeset,
int *next,
int *changed);
713 bool breakTies =
true,
bool includeChirality =
true,
714 bool includeIsotopes =
true);
717 const boost::dynamic_bitset<> &atomsInPlay,
718 const boost::dynamic_bitset<> &bondsInPlay,
719 const std::vector<std::string> *atomSymbols = NULL,
720 bool breakTies =
true,
bool includeChirality =
true,
721 bool includeIsotopes =
true);
726 bool includeChirality =
true);
bool operator<(const bondholder &o) const
RDKIT_RDGENERAL_EXPORT const std::string molAtomMapNumber
const std::string * p_symbol
SpecialSymmetryAtomCompareFunctor()
const boost::dynamic_bitset * dp_bondsInPlay
int operator()(int i, int j) const
std::vector< int > neighborNum
unsigned int getNumAtoms(bool onlyExplicit=1) const
returns our number of atoms
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
std::vector< bondholder > bonds
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)
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
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)
RDKIT_GRAPHMOL_EXPORT void updateAtomNeighborNumSwaps(canon_atom *atoms, std::vector< bondholder > &nbrs, unsigned int atomIdx, std::vector< std::pair< unsigned int, unsigned int > > &result)
#define PRECONDITION(expr, mess)
std::vector< int > revistedNeighbors
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)
The class for representing atoms.
Canon::canon_atom * dp_atoms