ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-3.0/src/selection/SelectionEvaluator.cpp
Revision: 1962
Committed: Tue Feb 1 22:49:23 2005 UTC (19 years, 5 months ago) by tim
File size: 10209 byte(s)
Log Message:
Selection in progress

File Contents

# Content
1 /*
2 * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3 *
4 * The University of Notre Dame grants you ("Licensee") a
5 * non-exclusive, royalty free, license to use, modify and
6 * redistribute this software in source and binary code form, provided
7 * that the following conditions are met:
8 *
9 * 1. Acknowledgement of the program authors must be made in any
10 * publication of scientific results based in part on use of the
11 * program. An acceptable form of acknowledgement is citation of
12 * the article in which the program was described (Matthew
13 * A. Meineke, Charles F. Vardeman II, Teng Lin, Christopher
14 * J. Fennell and J. Daniel Gezelter, "OOPSE: An Object-Oriented
15 * Parallel Simulation Engine for Molecular Dynamics,"
16 * J. Comput. Chem. 26, pp. 252-271 (2005))
17 *
18 * 2. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * 3. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the
24 * distribution.
25 *
26 * This software is provided "AS IS," without a warranty of any
27 * kind. All express or implied conditions, representations and
28 * warranties, including any implied warranty of merchantability,
29 * fitness for a particular purpose or non-infringement, are hereby
30 * excluded. The University of Notre Dame and its licensors shall not
31 * be liable for any damages suffered by licensee as a result of
32 * using, modifying or distributing the software or its
33 * derivatives. In no event will the University of Notre Dame or its
34 * licensors be liable for any lost revenue, profit or data, or for
35 * direct, indirect, special, consequential, incidental or punitive
36 * damages, however caused and regardless of the theory of liability,
37 * arising out of the use of or inability to use software, even if the
38 * University of Notre Dame has been advised of the possibility of
39 * such damages.
40 */
41
42 #include "selection/SelectionEvaluator.hpp"
43 namespace oopse {
44
45
46 bool SelectionEvaluator::loadScript(const std::string& filename, const std::string& script) {
47 this->filename = filename;
48 this->script = script;
49 if (! compiler.compile(filename, script)) {
50 error = true;
51 errorMessage = compiler.getErrorMessage();
52 return false;
53 }
54
55 pc = 0;
56 aatoken = compiler.getAatokenCompiled();
57 linenumbers = compiler.getLineNumbers();
58 lineIndices = compiler.getLineIndices();
59 return true;
60 }
61
62 void SelectionEvaluator::clearState() {
63 for (int i = scriptLevelMax; --i >= 0; )
64 stack[i] = null;
65 scriptLevel = 0;
66 error = false;
67 errorMessage = null;
68 }
69
70 bool SelectionEvaluator::loadScriptString(const std::string& script) {
71 clearState();
72 return loadScript(null, script);
73 }
74
75 bool SelectionEvaluator::loadScriptFile(const std::string& filename) {
76 clearState();
77 return loadScriptFileInternal(filename);
78 }
79
80
81 void SelectionEvaluator::instructionDispatchLoop(){
82
83 while ( pc < aatoken.length) {
84 statement = aatoken[pc++];
85 statementLength = statement.length;
86 Token token = statement[0];
87 switch (token.tok) {
88 case Token.define:
89 define();
90 break;
91 case Token.select:
92 select();
93 break;
94 default:
95 unrecognizedCommand(token);
96 return;
97 }
98 }
99 }
100
101 void SelectionEvaluator::predefine(String script) {
102 if (compiler.compile("#predefine", script)) {
103 Token [][] aatoken = compiler.getAatokenCompiled();
104 if (aatoken.length != 1) {
105 viewer.scriptStatus("predefinition does not have exactly 1 command:"
106 + script);
107 return;
108 }
109 Token[] statement = aatoken[0];
110 if (statement.length > 2) {
111 int tok = statement[1].tok;
112 if (tok == Token.identifier ||
113 (tok & Token.predefinedset) == Token.predefinedset) {
114 String variable = (String)statement[1].value;
115 variables.put(variable, statement);
116 } else {
117 viewer.scriptStatus("invalid variable name:" + script);
118 }
119 } else {
120 viewer.scriptStatus("bad predefinition length:" + script);
121 }
122 } else {
123 viewer.scriptStatus("predefined set compile error:" + script +
124 "\ncompile error:" + compiler.getErrorMessage());
125 }
126 }
127
128
129
130 BitSet SelectionEvaluator::expression(Token[] code, int pcStart) throws ScriptException {
131 int numberOfAtoms = viewer.getAtomCount();
132 BitSet bs;
133 BitSet[] stack = new BitSet[10];
134 int sp = 0;
135
136 for (int pc = pcStart; ; ++pc) {
137 Token instruction = code[pc];
138 if (logMessages)
139 viewer.scriptStatus("instruction=" + instruction);
140 switch (instruction.tok) {
141 case Token.expressionBegin:
142 break;
143 case Token.expressionEnd:
144 break expression_loop;
145 case Token.all:
146 bs = stack[sp++] = new BitSet(numberOfAtoms);
147 for (int i = numberOfAtoms; --i >= 0; )
148 bs.set(i);
149 break;
150 case Token.none:
151 stack[sp++] = new BitSet();
152 break;
153 case Token.opOr:
154 bs = stack[--sp];
155 stack[sp-1].or(bs);
156 break;
157 case Token.opAnd:
158 bs = stack[--sp];
159 stack[sp-1].and(bs);
160 break;
161 case Token.opNot:
162 bs = stack[sp - 1];
163 notSet(bs);
164 break;
165 case Token.within:
166 bs = stack[sp - 1];
167 stack[sp - 1] = new BitSet();
168 withinInstruction(instruction, bs, stack[sp - 1]);
169 break;
170 case Token.selected:
171 stack[sp++] = copyBitSet(viewer.getSelectionSet());
172 break;
173 case Token.y:
174 case Token.amino:
175 case Token.backbone:
176 case Token.solvent:
177 case Token.identifier:
178 case Token.sidechain:
179 case Token.surface:
180 stack[sp++] = lookupIdentifierValue((String)instruction.value);
181 break;
182 case Token.opLT:
183 case Token.opLE:
184 case Token.opGE:
185 case Token.opGT:
186 case Token.opEQ:
187 case Token.opNE:
188 bs = stack[sp++] = new BitSet();
189 comparatorInstruction(instruction, bs);
190 break;
191 default:
192 unrecognizedExpression();
193 }
194 }
195 if (sp != 1)
196 evalError("atom expression compiler error - stack over/underflow");
197 return stack[0];
198 }
199
200
201
202 void SelectionEvaluator::comparatorInstruction(Token instruction, BitSet bs) {
203 int comparator = instruction.tok;
204 int property = instruction.intValue;
205 float propertyValue = 0; // just for temperature
206 int comparisonValue = ((Integer)instruction.value).intValue();
207 int numberOfAtoms = viewer.getAtomCount();
208 Frame frame = viewer.getFrame();
209 for (int i = 0; i < numberOfAtoms; ++i) {
210 Atom atom = frame.getAtomAt(i);
211 switch (property) {
212 case Token.atomno:
213 propertyValue = atom.getAtomNumber();
214 break;
215 case Token.elemno:
216 propertyValue = atom.getElementNumber();
217 break;
218 case Token.temperature:
219 propertyValue = atom.getBfactor100();
220 if (propertyValue < 0)
221 continue;
222 propertyValue /= 100;
223 break;
224 case Token._atomID:
225 propertyValue = atom.getSpecialAtomID();
226 if (propertyValue < 0)
227 continue;
228 break;
229 case Token._structure:
230 propertyValue = getProteinStructureType(atom);
231 if (propertyValue == -1)
232 continue;
233 break;
234 case Token.radius:
235 propertyValue = atom.getRasMolRadius();
236 break;
237 case Token._bondedcount:
238 propertyValue = atom.getCovalentBondCount();
239 break;
240 case Token.model:
241 propertyValue = atom.getModelTagNumber();
242 break;
243 default:
244 unrecognizedAtomProperty(property);
245 }
246 boolean match = false;
247 switch (comparator) {
248 case Token.opLT:
249 match = propertyValue < comparisonValue;
250 break;
251 case Token.opLE:
252 match = propertyValue <= comparisonValue;
253 break;
254 case Token.opGE:
255 match = propertyValue >= comparisonValue;
256 break;
257 case Token.opGT:
258 match = propertyValue > comparisonValue;
259 break;
260 case Token.opEQ:
261 match = propertyValue == comparisonValue;
262 break;
263 case Token.opNE:
264 match = propertyValue != comparisonValue;
265 break;
266 }
267 if (match)
268 bs.set(i);
269 }
270 }
271
272 void SelectionEvaluator::withinInstruction(Token instruction, BitSet bs, BitSet bsResult)
273
274 Object withinSpec = instruction.value;
275 if (withinSpec instanceof Float) {
276 withinDistance(((Float)withinSpec).floatValue(), bs, bsResult);
277 return;
278 }
279 evalError("Unrecognized within parameter:" + withinSpec);
280 }
281
282 void SelectionEvaluator::withinDistance(float distance, BitSet bs, BitSet bsResult) {
283 Frame frame = viewer.getFrame();
284 for (int i = frame.getAtomCount(); --i >= 0; ) {
285 if (bs.get(i)) {
286 Atom atom = frame.getAtomAt(i);
287 AtomIterator iterWithin =
288 frame.getWithinIterator(atom, distance);
289 while (iterWithin.hasNext())
290 bsResult.set(iterWithin.next().getAtomIndex());
291 }
292 }
293 }
294
295 void SelectionEvaluator::define() throws ScriptException {
296 String variable = (String)statement[1].value;
297 variables.put(variable, (expression(statement, 2)));
298 }
299 }
300
301 void SelectionEvaluator::predefine(Token[] statement) {
302 String variable = (String)statement[1].value;
303 variables.put(variable, statement);
304 }
305
306 void SelectionEvaluator::select(){
307 // NOTE this is called by restrict()
308 if (statementLength == 1) {
309 viewer.selectAll();
310 if (!viewer.getRasmolHydrogenSetting())
311 viewer.excludeSelectionSet(getHydrogenSet());
312 if (!viewer.getRasmolHeteroSetting())
313 viewer.excludeSelectionSet(getHeteroSet());
314 } else {
315 viewer.setSelectionSet(expression(statement, 1));
316 }
317 viewer.scriptStatus("" + viewer.getSelectionCount() + " atoms selected");
318 }
319
320 }