File: Node.cpp

package info (click to toggle)
rdkit 202503.1-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 220,160 kB
  • sloc: cpp: 399,240; python: 77,453; ansic: 25,517; java: 8,173; javascript: 4,005; sql: 2,389; yacc: 1,565; lex: 1,263; cs: 1,081; makefile: 580; xml: 229; fortran: 183; sh: 105
file content (160 lines) | stat: -rw-r--r-- 4,326 bytes parent folder | download | duplicates (2)
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
//
//
//  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 <vector>

#include "Digraph.h"
#include "Edge.h"
#include "Node.h"
#include "CIPMol.h"

namespace RDKit {
namespace CIPLabeler {

Node *Node::newTerminalChild(int idx, Atom *atom, int flags) const {
  int new_dist = flags & DUPLICATE ? d_visit[idx] : d_dist + 1;
  std::vector<char> new_visit;

  if (flags & BOND_DUPLICATE) {
    auto frac = dp_g->getMol().getFractionalAtomicNum(dp_atom);
    if (frac.denominator() > 1) {
      return &dp_g->addNode(std::move(new_visit), atom, std::move(frac),
                            new_dist, flags);
    }
  }

  auto atomic_num = atom ? atom->getAtomicNum() : 1;
  return &dp_g->addNode(std::move(new_visit), atom, atomic_num, new_dist,
                        flags);
}

Node::Node(Digraph *g, std::vector<char> &&visit, Atom *atom,
           boost::rational<int> &&frac, int dist, int flags)
    : dp_g{g},
      dp_atom{atom},
      d_dist{dist},
      d_atomic_num{std::move(frac)},
      d_flags{flags},
      d_visit{std::move(visit)} {
  if (d_flags & DUPLICATE) {
    d_edges.reserve(4);
    d_atomic_mass = 0.;
  } else {
    const auto &table = RDKit::PeriodicTable::getTable();
    auto atomic_number = getAtomicNum();
    auto isotope = getMassNum();
    if (isotope == 0u) {
      d_atomic_mass = table->getAtomicWeight(atomic_number);
    } else {
      d_atomic_mass = table->getMassForIsotope(atomic_number, isotope);
    }
  }
  if (d_visit.empty() || d_flags & DUPLICATE) {
    d_flags |= EXPANDED;
  }
}

Digraph *Node::getDigraph() const { return dp_g; }

Atom *Node::getAtom() const { return dp_atom; }

int Node::getDistance() const { return d_dist; }

boost::rational<int> Node::getAtomicNumFraction() const { return d_atomic_num; }

int Node::getAtomicNum() const {
  if (dp_atom == nullptr) {
    return 1;
  }
  return dp_atom->getAtomicNum();
};

unsigned Node::getMassNum() const {
  if (dp_atom == nullptr || isDuplicate()) {
    return 0u;
  }
  return dp_atom->getIsotope();
}

double Node::getAtomicMass() const { return d_atomic_mass; }

Descriptor Node::getAux() const { return d_aux; }

bool Node::isSet(int mask) const { return mask & d_flags; }

bool Node::isDuplicate() const { return d_flags & DUPLICATE; }

bool Node::isDuplicateOrH() const { return d_flags & DUPLICATE_OR_H; }

bool Node::isTerminal() const {
  return d_visit.empty() || (isExpanded() && d_edges.size() == 1);
}

bool Node::isExpanded() const { return d_flags & EXPANDED; }

bool Node::isVisited(int idx) const { return d_visit[idx] != 0; }

Node *Node::newChild(int idx, Atom *atom) const {
  auto new_visit = d_visit;
  new_visit[idx] = static_cast<char>(d_dist + 1);
  auto atomic_num = atom ? atom->getAtomicNum() : 1;
  return &dp_g->addNode(std::move(new_visit), atom, atomic_num, d_dist + 1, 0);
}

Node *Node::newBondDuplicateChild(int idx, Atom *atom) const {
  return newTerminalChild(idx, atom, BOND_DUPLICATE);
}

Node *Node::newRingDuplicateChild(int idx, Atom *atom) const {
  return newTerminalChild(idx, atom, RING_DUPLICATE);
}

Node *Node::newImplicitHydrogenChild() const {
  return newTerminalChild(-1, nullptr, IMPL_HYDROGEN);
}

void Node::add(Edge *e) { d_edges.push_back(e); }

void Node::setAux(Descriptor desc) { d_aux = desc; }

const std::vector<Edge *> &Node::getEdges() const {
  if (!isExpanded()) {
    auto non_const_this = const_cast<Node *>(this);
    non_const_this->d_flags |= EXPANDED;
    dp_g->expand(non_const_this);
  }
  return d_edges;
}

std::vector<Edge *> Node::getEdges(Atom *end) const {
  std::vector<Edge *> res;
  for (auto &edge : getEdges()) {
    if (edge->getEnd()->isDuplicate()) {
      continue;
    };
    if (end == edge->getBeg()->getAtom() || end == edge->getEnd()->getAtom()) {
      res.push_back(edge);
    }
  }
  return res;
}

std::vector<Edge *> Node::getNonTerminalOutEdges() const {
  std::vector<Edge *> edges;
  for (auto &edge : getEdges()) {
    if (edge->isBeg(this) && !edge->getEnd()->isTerminal()) {
      edges.push_back(edge);
    }
  }
  return edges;
}

}  // namespace CIPLabeler
}  // namespace RDKit