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 161 162 163 164 165 166 167 168 169 170 171 172
|
/*
* Atom iterators
*
* (c) 2014 Schrodinger, Inc.
*/
#ifndef _H_ATOMITERATORS
#define _H_ATOMITERATORS
#include "PyMOLGlobals.h"
#include "ObjectMolecule.h"
#include "CoordSet.h"
#include "AtomInfo.h"
/*
* Atom iterator base class
*/
class AbstractAtomIterator {
protected:
int atm; // atom index in object molecule
int idx; // atom index in coordset
public:
ObjectMolecule * obj;
CoordSet * cs;
// virtual destructor for dynamic types
virtual ~AbstractAtomIterator() {}
// resets the internal state to start over
virtual void reset() = 0;
// advance the internal state to the next atom, return false if there is no
// next atom
virtual bool next() = 0;
// get current atom
AtomInfoType * getAtomInfo() {
return obj->AtomInfo + atm;
};
// get current atom's coordinates
float * getCoord() {
return cs->Coord + (3 * idx);
};
// get current atom index in object molecule
int getAtm() {
return atm;
}
// get current coordinate index (atom index in coordset)
int getIdx() {
return idx;
}
};
/*
* State specific iterator over an atom selection. Similar to cmd.iterate_state.
* If state is -1 then iterate over all states.
*
* SeleCoordIterator iter(G, sele, state);
* while(iter.next()) {
* dump3f(iter.getCoord(), "coords");
* }
*/
class SeleCoordIterator : public AbstractAtomIterator {
PyMOLGlobals * G;
int statearg; // state argument, can be -1 (all), -2 (current), -3 (effective)
int statemax; // largest state in selection
bool per_object; // whether to iterate over object states or global states
ObjectMolecule * prev_obj; // for per_object=true
public:
int a; // index in selection
int state; // current state
void init(PyMOLGlobals * G_, int sele_, int state_);
SeleCoordIterator() {} // undefined state until "init()" called
SeleCoordIterator(PyMOLGlobals * G_, int sele_, int state_) {
init(G_, sele_, state_);
};
void reset();
bool next();
// return true if iterating over all states
bool isMultistate() const {
return statearg == -1;
}
// return true if iterating over all states of an object before advancing
// to the next object, rather than iterating over global states
bool isPerObject() const {
return per_object;
}
void setPerObject(bool per_object_) {
per_object = per_object_ && isMultistate();
}
private:
bool nextStateInPrevObject() {
if (prev_obj && (++state) < prev_obj->NCSet) {
a = prev_obj->SeleBase - 1;
return true;
}
return false;
}
};
/*
* Iterator over an atom selection. Similar to cmd.iterate.
*
* Does NOT provide coord or coordset access
*
* SeleAtomIterator iter(G, sele);
* while(iter.next()) {
* ai = iter.getAtomInfo();
* }
*/
class SeleAtomIterator : public AbstractAtomIterator {
PyMOLGlobals * G;
int sele; // selection
char * stmp; // temporary named selection
public:
int a; // index in selection
SeleAtomIterator(PyMOLGlobals * G_, int sele_) {
G = G_;
sele = sele_;
stmp = NULL;
reset();
};
SeleAtomIterator(PyMOLGlobals * G_, const char * sele_);
~SeleAtomIterator();
void reset();
bool next();
};
/*
* CoordSet atom iterator, iterates over sorted atoms
*
* CoordSetAtomIterator iter(G, cs);
* while(iter.next()) {
* dump3f(iter.getCoord(), "coords");
* }
*/
class CoordSetAtomIterator : public AbstractAtomIterator {
public:
CoordSetAtomIterator(CoordSet * cs_) {
cs = cs_;
obj = cs->Obj;
reset();
}
void reset() {
atm = -1;
}
bool next();
};
#endif
// vi:sw=2:expandtab
|