44#include "selection/NameFinder.hpp"
49#include "utils/simError.h"
50#include "utils/wildcards.hpp"
54 NameFinder::NameFinder(SimInfo* info) : info_(info) {
55 nObjects_.push_back(info_->getNGlobalAtoms() +
56 info_->getNGlobalRigidBodies());
57 nObjects_.push_back(info_->getNGlobalBonds());
58 nObjects_.push_back(info_->getNGlobalBends());
59 nObjects_.push_back(info_->getNGlobalTorsions());
60 nObjects_.push_back(info_->getNGlobalInversions());
61 nObjects_.push_back(info_->getNGlobalMolecules());
66 void NameFinder::loadNames() {
67 SimInfo::MoleculeIterator mi;
68 Molecule::AtomIterator ai;
69 Molecule::RigidBodyIterator rbIter;
70 Molecule::BondIterator bondIter;
71 Molecule::BendIterator bendIter;
72 Molecule::TorsionIterator torsionIter;
73 Molecule::InversionIterator inversionIter;
83 root_ = std::make_shared<TreeNode>();
84 root_->bs.resize(nObjects_);
87 for (mol = info_->beginMolecule(mi); mol != NULL;
88 mol = info_->nextMolecule(mi)) {
89 std::string molName = mol->getMoleculeName();
90 TreeNodePtr molNode = createNode(root_, molName);
91 molNode->bs.bitsets_[MOLECULE].setBitOn(mol->getGlobalIndex());
93 for (atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) {
94 std::string atomName = atom->getType();
95 TreeNodePtr atomNode = createNode(molNode, atomName);
97 molNode->bs.bitsets_[
STUNTDOUBLE].setBitOn(atom->getGlobalIndex());
98 atomNode->bs.bitsets_[
STUNTDOUBLE].setBitOn(atom->getGlobalIndex());
101 for (rb = mol->beginRigidBody(rbIter); rb != NULL;
102 rb = mol->nextRigidBody(rbIter)) {
103 std::string rbName = rb->getType();
104 TreeNodePtr rbNode = createNode(molNode, rbName);
106 molNode->bs.bitsets_[
STUNTDOUBLE].setBitOn(rb->getGlobalIndex());
107 rbNode->bs.bitsets_[
STUNTDOUBLE].setBitOn(rb->getGlobalIndex());
124 for (bond = mol->beginBond(bondIter); bond != NULL;
125 bond = mol->nextBond(bondIter)) {
126 std::string bondName = bond->getName();
127 TreeNodePtr bondNode = createNode(molNode, bondName);
129 molNode->bs.bitsets_[BOND].setBitOn(bond->getGlobalIndex());
130 bondNode->bs.bitsets_[BOND].setBitOn(bond->getGlobalIndex());
132 std::vector<Atom*> atoms = bond->getAtoms();
133 std::vector<Atom*>::iterator ai;
135 for (ai = atoms.begin(); ai != atoms.end(); ++ai) {
136 std::string atomName = (*ai)->getType();
137 TreeNodePtr atomNode = createNode(bondNode, atomName);
138 atomNode->bs.bitsets_[
STUNTDOUBLE].setBitOn((*ai)->getGlobalIndex());
141 for (bend = mol->beginBend(bendIter); bend != NULL;
142 bend = mol->nextBend(bendIter)) {
143 std::string bendName = bend->getName();
144 TreeNodePtr bendNode = createNode(molNode, bendName);
146 molNode->bs.bitsets_[BEND].setBitOn(bend->getGlobalIndex());
147 bendNode->bs.bitsets_[BEND].setBitOn(bend->getGlobalIndex());
149 std::vector<Atom*> atoms = bend->getAtoms();
150 std::vector<Atom*>::iterator ai;
152 for (ai = atoms.begin(); ai != atoms.end(); ++ai) {
153 std::string atomName = (*ai)->getType();
154 TreeNodePtr atomNode = createNode(bendNode, atomName);
155 atomNode->bs.bitsets_[
STUNTDOUBLE].setBitOn((*ai)->getGlobalIndex());
158 for (torsion = mol->beginTorsion(torsionIter); torsion != NULL;
159 torsion = mol->nextTorsion(torsionIter)) {
160 std::string torsionName = torsion->getName();
161 TreeNodePtr torsionNode = createNode(molNode, torsionName);
163 molNode->bs.bitsets_[TORSION].setBitOn(torsion->getGlobalIndex());
164 torsionNode->bs.bitsets_[TORSION].setBitOn(torsion->getGlobalIndex());
166 std::vector<Atom*> atoms = torsion->getAtoms();
167 std::vector<Atom*>::iterator ai;
169 for (ai = atoms.begin(); ai != atoms.end(); ++ai) {
170 std::string atomName = (*ai)->getType();
171 TreeNodePtr atomNode = createNode(torsionNode, atomName);
172 atomNode->bs.bitsets_[
STUNTDOUBLE].setBitOn((*ai)->getGlobalIndex());
175 for (inversion = mol->beginInversion(inversionIter); inversion != NULL;
176 inversion = mol->nextInversion(inversionIter)) {
177 std::string inversionName = inversion->getName();
178 TreeNodePtr inversionNode = createNode(molNode, inversionName);
180 molNode->bs.bitsets_[INVERSION].setBitOn(inversion->getGlobalIndex());
181 inversionNode->bs.bitsets_[INVERSION].setBitOn(
182 inversion->getGlobalIndex());
183 std::vector<Atom*> atoms = inversion->getAtoms();
184 std::vector<Atom*>::iterator ai;
186 for (ai = atoms.begin(); ai != atoms.end(); ++ai) {
187 std::string atomName = (*ai)->getType();
188 TreeNodePtr atomNode = createNode(inversionNode, atomName);
189 atomNode->bs.bitsets_[
STUNTDOUBLE].setBitOn((*ai)->getGlobalIndex());
195 TreeNodePtr NameFinder::createNode(TreeNodePtr parent,
196 const std::string& name) {
198 std::map<std::string, TreeNodePtr>::iterator foundIter;
199 foundIter = parent->children.find(name);
200 if (foundIter == parent->children.end()) {
201 node = std::make_shared<TreeNode>();
203 node->bs.resize(nObjects_);
204 parent->children.insert(std::make_pair(name, node));
206 node = foundIter->second;
211 SelectionSet NameFinder::match(
const std::string& name) {
212 SelectionSet bs(nObjects_);
214 StringTokenizer tokenizer(name,
".");
216 std::vector<std::string> names;
217 while (tokenizer.hasMoreTokens()) {
218 names.push_back(tokenizer.nextToken());
221 int size = names.size();
226 matchMolecule(names[0], bs);
227 matchStuntDouble(
"*", names[0], bs);
228 matchBond(
"*", names[0], bs);
229 matchBend(
"*", names[0], bs);
230 matchTorsion(
"*", names[0], bs);
231 matchInversion(
"*", names[0], bs);
238 if (!isInteger(names[1])) {
239 matchRigidAtoms(
"*", names[0], names[1], bs);
240 matchStuntDouble(names[0], names[1], bs);
242 int internalIndex = lexi_cast<int>(names[1]);
243 if (internalIndex < 0) {
244 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
245 "NameFinder : Name %s.%s is an invalid name.\n",
246 names[0].c_str(), names[1].c_str());
247 painCave.severity = OPENMD_WARNING;
248 painCave.isFatal = 0;
251 matchInternalIndex(names[0], internalIndex, bs);
258 matchRigidAtoms(names[0], names[1], names[2], bs);
261 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
262 "NameFinder : Invalid Name %s.\n", name.c_str());
263 painCave.severity = OPENMD_WARNING;
264 painCave.isFatal = 0;
271 void NameFinder::matchMolecule(
const std::string& molName, SelectionSet& bs) {
272 std::vector<TreeNodePtr> molNodes = getMatchedChildren(root_, molName);
273 std::vector<TreeNodePtr>::iterator i;
274 for (i = molNodes.begin(); i != molNodes.end(); ++i) {
279 void NameFinder::matchStuntDouble(
const std::string& molName,
280 const std::string& sdName,
282 std::vector<TreeNodePtr> molNodes = getMatchedChildren(root_, molName);
283 std::vector<TreeNodePtr>::iterator i;
284 for (i = molNodes.begin(); i != molNodes.end(); ++i) {
285 std::vector<TreeNodePtr> sdNodes = getMatchedChildren(*i, sdName);
286 std::vector<TreeNodePtr>::iterator j;
287 for (j = sdNodes.begin(); j != sdNodes.end(); ++j) {
293 void NameFinder::matchBond(
const std::string& molName,
294 const std::string& bondName, SelectionSet& bs) {
295 std::vector<TreeNodePtr> molNodes = getMatchedChildren(root_, molName);
296 std::vector<TreeNodePtr>::iterator i;
297 for (i = molNodes.begin(); i != molNodes.end(); ++i) {
298 std::vector<TreeNodePtr> bondNodes = getMatchedChildren(*i, bondName);
299 std::vector<TreeNodePtr>::iterator j;
300 for (j = bondNodes.begin(); j != bondNodes.end(); ++j) {
302 std::vector<TreeNodePtr> bondAtomNodes = getAllChildren(*j);
303 std::vector<TreeNodePtr>::iterator k;
304 for (k = bondAtomNodes.begin(); k != bondAtomNodes.end(); ++k) {
311 void NameFinder::matchBend(
const std::string& molName,
312 const std::string& bendName, SelectionSet& bs) {
313 std::vector<TreeNodePtr> molNodes = getMatchedChildren(root_, molName);
314 std::vector<TreeNodePtr>::iterator i;
315 for (i = molNodes.begin(); i != molNodes.end(); ++i) {
316 std::vector<TreeNodePtr> bendNodes = getMatchedChildren(*i, bendName);
317 std::vector<TreeNodePtr>::iterator j;
318 for (j = bendNodes.begin(); j != bendNodes.end(); ++j) {
319 std::vector<TreeNodePtr> bendAtomNodes = getAllChildren(*j);
320 std::vector<TreeNodePtr>::iterator k;
321 for (k = bendAtomNodes.begin(); k != bendAtomNodes.end(); ++k) {
327 void NameFinder::matchTorsion(
const std::string& molName,
328 const std::string& torsionName,
330 std::vector<TreeNodePtr> molNodes = getMatchedChildren(root_, molName);
331 std::vector<TreeNodePtr>::iterator i;
332 for (i = molNodes.begin(); i != molNodes.end(); ++i) {
333 std::vector<TreeNodePtr> torsionNodes =
334 getMatchedChildren(*i, torsionName);
335 std::vector<TreeNodePtr>::iterator j;
336 for (j = torsionNodes.begin(); j != torsionNodes.end(); ++j) {
337 std::vector<TreeNodePtr> torsionAtomNodes = getAllChildren(*j);
338 std::vector<TreeNodePtr>::iterator k;
339 for (k = torsionAtomNodes.begin(); k != torsionAtomNodes.end(); ++k) {
345 void NameFinder::matchInversion(
const std::string& molName,
346 const std::string& inversionName,
348 std::vector<TreeNodePtr> molNodes = getMatchedChildren(root_, molName);
349 std::vector<TreeNodePtr>::iterator i;
350 for (i = molNodes.begin(); i != molNodes.end(); ++i) {
351 std::vector<TreeNodePtr> inversionNodes =
352 getMatchedChildren(*i, inversionName);
353 std::vector<TreeNodePtr>::iterator j;
354 for (j = inversionNodes.begin(); j != inversionNodes.end(); ++j) {
355 std::vector<TreeNodePtr> inversionAtomNodes = getAllChildren(*j);
356 std::vector<TreeNodePtr>::iterator k;
357 for (k = inversionAtomNodes.begin(); k != inversionAtomNodes.end();
365 void NameFinder::matchRigidAtoms(
const std::string& molName,
366 const std::string& rbName,
367 const std::string& rbAtomName,
369 std::vector<TreeNodePtr> molNodes = getMatchedChildren(root_, molName);
370 std::vector<TreeNodePtr>::iterator i;
371 for (i = molNodes.begin(); i != molNodes.end(); ++i) {
372 std::vector<TreeNodePtr> rbNodes = getMatchedChildren(*i, rbName);
373 std::vector<TreeNodePtr>::iterator j;
374 for (j = rbNodes.begin(); j != rbNodes.end(); ++j) {
375 std::vector<TreeNodePtr> rbAtomNodes =
376 getMatchedChildren(*j, rbAtomName);
377 std::vector<TreeNodePtr>::iterator k;
378 for (k = rbAtomNodes.begin(); k != rbAtomNodes.end(); ++k) {
385 std::vector<TreeNodePtr> NameFinder::getAllChildren(TreeNodePtr node) {
386 std::vector<TreeNodePtr> childNodes;
387 std::map<std::string, TreeNodePtr>::iterator i;
388 for (i = node->children.begin(); i != node->children.end(); ++i) {
389 childNodes.push_back(i->second);
394 std::vector<TreeNodePtr> NameFinder::getMatchedChildren(
395 TreeNodePtr node,
const std::string& name) {
396 std::vector<TreeNodePtr> matchedNodes;
397 std::map<std::string, TreeNodePtr>::iterator i;
398 for (i = node->children.begin(); i != node->children.end(); ++i) {
399 if (isMatched(i->first, name)) { matchedNodes.push_back(i->second); }
405 bool NameFinder::isMatched(
const std::string& str,
406 const std::string& wildcard) {
407 return Wildcard::wildcardfit(wildcard.c_str(), str.c_str()) > 0 ? true :
411 void NameFinder::matchInternalIndex(
const std::string& name,
412 int internalIndex, SelectionSet& bs) {
413 SimInfo::MoleculeIterator mi;
416 for (mol = info_->beginMolecule(mi); mol != NULL;
417 mol = info_->nextMolecule(mi)) {
418 if (isMatched(mol->getMoleculeName(), name)) {
419 int natoms = mol->getNAtoms();
420 int nrigidbodies = mol->getNRigidBodies();
421 if (internalIndex >= natoms + nrigidbodies) {
423 }
else if (internalIndex < natoms) {
425 mol->getAtomAt(internalIndex)->getGlobalIndex());
427 }
else if (internalIndex < natoms + nrigidbodies) {
429 mol->getRigidBodyAt(internalIndex - natoms)->getGlobalIndex());
435 bool NameFinder::isInteger(
const std::string& str) {
436 for (
unsigned int i = 0; i < str.size(); ++i) {
437 if (!std::isdigit(str[i])) {
return false; }
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
@ STUNTDOUBLE
StuntDoubles (Atoms & RigidBodies)