ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/applications/staticProps/SpatialStatistics.cpp
Revision: 1875
Committed: Fri May 17 14:41:42 2013 UTC (11 years, 11 months ago) by gezelter
File size: 12602 byte(s)
Log Message:
Fixed a bunch of stylistic and performance issues discovered via cppcheck.

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. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the
15 * distribution.
16 *
17 * This software is provided "AS IS," without a warranty of any
18 * kind. All express or implied conditions, representations and
19 * warranties, including any implied warranty of merchantability,
20 * fitness for a particular purpose or non-infringement, are hereby
21 * excluded. The University of Notre Dame and its licensors shall not
22 * be liable for any damages suffered by licensee as a result of
23 * using, modifying or distributing the software or its
24 * derivatives. In no event will the University of Notre Dame or its
25 * licensors be liable for any lost revenue, profit or data, or for
26 * direct, indirect, special, consequential, incidental or punitive
27 * damages, however caused and regardless of the theory of liability,
28 * arising out of the use of or inability to use software, even if the
29 * University of Notre Dame has been advised of the possibility of
30 * such damages.
31 *
32 * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
33 * research, please cite the appropriate papers when you publish your
34 * work. Good starting points are:
35 *
36 * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
37 * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
38 * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
39 * [4] Kuang & Gezelter, J. Chem. Phys. 133, 164101 (2010).
40 * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
41 */
42
43 #include "applications/staticProps/SpatialStatistics.hpp"
44 #include "io/DumpReader.hpp"
45 #include "primitives/Molecule.hpp"
46
47 namespace OpenMD {
48
49 SpatialStatistics::SpatialStatistics(SimInfo* info, const string& filename,
50 const string& sele, int nbins)
51 : StaticAnalyser(info, filename), selectionScript_(sele), evaluator_(info),
52 seleMan_(info), nBins_(nbins){
53
54 evaluator_.loadScriptString(sele);
55 if (!evaluator_.isDynamic()) {
56 seleMan_.setSelectionSet(evaluator_.evaluate());
57 }
58
59 // Pre-load an OutputData for the count of objects:
60 counts_ = new OutputData;
61 counts_->units = "objects";
62 counts_->title = "Objects";
63 counts_->dataType = odtReal;
64 counts_->dataHandling = odhTotal;
65 counts_->accumulator.reserve(nBins_);
66 for (int i = 0; i < nBins_; i++)
67 counts_->accumulator.push_back( new Accumulator() );
68
69 setOutputName(getPrefix(filename) + ".spst");
70 }
71
72 SpatialStatistics::~SpatialStatistics() {
73 vector<OutputData*>::iterator i;
74 OutputData* outputData;
75
76 for(outputData = beginOutputData(i); outputData;
77 outputData = nextOutputData(i)) {
78 delete outputData;
79 }
80 data_.clear();
81
82 delete counts_;
83 }
84
85
86 void SpatialStatistics::process() {
87
88 DumpReader reader(info_, dumpFilename_);
89 int nFrames = reader.getNFrames();
90 nProcessed_ = nFrames/step_;
91
92 for (int istep = 0; istep < nFrames; istep += step_) {
93 reader.readFrame(istep);
94 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
95 processFrame(istep);
96 }
97 writeOutput();
98 }
99
100
101 void SpatialStatistics::processFrame(int istep) {
102 Molecule* mol;
103 RigidBody* rb;
104 StuntDouble* sd;
105 SimInfo::MoleculeIterator mi;
106 Molecule::RigidBodyIterator rbIter;
107 int i;
108
109 for (mol = info_->beginMolecule(mi); mol != NULL;
110 mol = info_->nextMolecule(mi)) {
111
112 // change the positions of atoms which belong to the rigidbodies
113
114 for (rb = mol->beginRigidBody(rbIter); rb != NULL;
115 rb = mol->nextRigidBody(rbIter)) {
116 rb->updateAtoms();
117 }
118 }
119
120 if (evaluator_.isDynamic()) {
121 seleMan_.setSelectionSet(evaluator_.evaluate());
122 }
123
124 // loop over the selected atoms:
125
126 for (sd = seleMan_.beginSelected(i); sd != NULL;
127 sd = seleMan_.nextSelected(i)) {
128
129 // figure out where that object is:
130
131 Vector3d pos = sd->getPos();
132
133 int bin = getBin(pos);
134
135 // forward the work of statistics on to the subclass:
136
137 processStuntDouble( sd, bin );
138
139 dynamic_cast<Accumulator *>(counts_->accumulator[bin])->add(1);
140 }
141 }
142
143
144 void SpatialStatistics::writeOutput() {
145
146 vector<OutputData*>::iterator i;
147 OutputData* outputData;
148
149 ofstream outStream(outputFilename_.c_str());
150 if (outStream.is_open()) {
151
152 //write title
153 outStream << "# SPATIAL STATISTICS\n";
154 outStream << "#";
155
156 for(outputData = beginOutputData(i); outputData;
157 outputData = nextOutputData(i)) {
158 outStream << "\t" << outputData->title <<
159 "(" << outputData->units << ")";
160 // add some extra tabs for column alignment
161 if (outputData->dataType == odtVector3) outStream << "\t\t";
162 }
163
164 outStream << std::endl;
165
166 outStream.precision(8);
167
168 for (int j = 0; j < nBins_; j++) {
169
170 int counts = counts_->accumulator[j]->count();
171
172 if (counts > 0) {
173 for(outputData = beginOutputData(i); outputData;
174 outputData = nextOutputData(i)) {
175
176 int n = outputData->accumulator[j]->count();
177 if (n != 0) {
178 writeData( outStream, outputData, j );
179 }
180 }
181 outStream << std::endl;
182 }
183 }
184
185 outStream << "#######################################################\n";
186 outStream << "# Standard Deviations in those quantities follow:\n";
187 outStream << "#######################################################\n";
188
189 for (int j = 0; j < nBins_; j++) {
190 int counts = counts_->accumulator[j]->count();
191 if (counts > 0) {
192
193 outStream << "#";
194 for(outputData = beginOutputData(i); outputData;
195 outputData = nextOutputData(i)) {
196
197 int n = outputData->accumulator[j]->count();
198 if (n != 0) {
199 writeStdDev( outStream, outputData, j );
200 }
201 }
202 outStream << std::endl;
203 }
204 }
205
206 outStream.flush();
207 outStream.close();
208
209 } else {
210 sprintf(painCave.errMsg, "SpatialStatistics: unable to open %s\n",
211 outputFilename_.c_str());
212 painCave.isFatal = 1;
213 simError();
214 }
215 }
216
217
218 void SpatialStatistics::writeData(ostream& os, OutputData* dat,
219 unsigned int bin) {
220 assert(int(bin) < nBins_);
221 int n = dat->accumulator[bin]->count();
222 if (n == 0) return;
223
224 if( dat->dataType == odtReal ) {
225 RealType r;
226 dynamic_cast<Accumulator*>(dat->accumulator[bin])->getAverage(r);
227 if (isinf(r) || isnan(r) ) {
228 sprintf( painCave.errMsg,
229 "SpatialStatistics detected a numerical error writing:\n"
230 "\t%s for bin %u",
231 dat->title.c_str(), bin);
232 painCave.isFatal = 1;
233 simError();
234 }
235 if (dat->dataHandling == odhTotal) r *= dat->accumulator[bin]->count();
236 os << "\t" << r;
237
238 } else if ( dat->dataType == odtVector3 ) {
239 Vector3d v;
240 dynamic_cast<VectorAccumulator*>(dat->accumulator[bin])->getAverage(v);
241 if (isinf(v[0]) || isnan(v[0]) ||
242 isinf(v[1]) || isnan(v[1]) ||
243 isinf(v[2]) || isnan(v[2]) ) {
244 sprintf( painCave.errMsg,
245 "SpatialStatistics detected a numerical error writing:\n"
246 "\t%s for bin %u",
247 dat->title.c_str(), bin);
248 painCave.isFatal = 1;
249 simError();
250 }
251 if (dat->dataHandling == odhTotal) v *= dat->accumulator[bin]->count();
252 os << "\t" << v[0] << "\t" << v[1] << "\t" << v[2];
253 }
254 }
255
256 void SpatialStatistics::writeStdDev(ostream& os, OutputData* dat,
257 unsigned int bin) {
258 assert(int(bin) < nBins_);
259 int n = dat->accumulator[bin]->count();
260 if (n == 0) return;
261
262 if( dat->dataType == odtReal ) {
263 RealType r;
264 dynamic_cast<Accumulator*>(dat->accumulator[bin])->getStdDev(r);
265 if (isinf(r) || isnan(r) ) {
266 sprintf( painCave.errMsg,
267 "SpatialStatistics detected a numerical error writing:\n"
268 "\tstandard deviation of %s for bin %u",
269 dat->title.c_str(), bin);
270 painCave.isFatal = 1;
271 simError();
272 }
273 if (dat->dataHandling == odhTotal) r *= dat->accumulator[bin]->count();
274 os << "\t" << r;
275
276 } else if ( dat->dataType == odtVector3 ) {
277 Vector3d v;
278 dynamic_cast<VectorAccumulator*>(dat->accumulator[bin])->getStdDev(v);
279 if (isinf(v[0]) || isnan(v[0]) ||
280 isinf(v[1]) || isnan(v[1]) ||
281 isinf(v[2]) || isnan(v[2]) ) {
282 sprintf( painCave.errMsg,
283 "SpatialStatistics detected a numerical error writing:\n"
284 "\tstandard deviation of %s for bin %u",
285 dat->title.c_str(), bin);
286 painCave.isFatal = 1;
287 simError();
288 }
289 if (dat->dataHandling == odhTotal) v *= dat->accumulator[bin]->count();
290 os << "\t" << v[0] << "\t" << v[1] << "\t" << v[2];
291 }
292 }
293
294
295 OutputData* SpatialStatistics::beginOutputData(vector<OutputData*>::iterator& i) {
296 i = data_.begin();
297 return i != data_.end()? *i : NULL;
298 }
299
300 OutputData* SpatialStatistics::nextOutputData(vector<OutputData*>::iterator& i){
301 ++i;
302 return i != data_.end()? *i: NULL;
303 }
304
305
306 SlabStatistics::SlabStatistics(SimInfo* info, const string& filename,
307 const string& sele, int nbins) :
308 SpatialStatistics(info, filename, sele, nbins) {
309
310 z_ = new OutputData;
311 z_->units = "Angstroms";
312 z_->title = "Z";
313 z_->dataType = odtReal;
314 z_->dataHandling = odhAverage;
315 z_->accumulator.reserve(nbins);
316 for (int i = 0; i < nbins; i++)
317 z_->accumulator.push_back( new Accumulator() );
318 data_.push_back(z_);
319 }
320
321 SlabStatistics::~SlabStatistics() {
322 delete z_;
323 }
324
325
326 void SlabStatistics::processFrame(int istep) {
327 RealType z;
328 hmat_ = currentSnapshot_->getHmat();
329 for (int i = 0; i < nBins_; i++) {
330 z = (((RealType)i + 0.5) / (RealType)nBins_) * hmat_(2,2);
331 dynamic_cast<Accumulator*>(z_->accumulator[i])->add(z);
332 }
333 volume_ = currentSnapshot_->getVolume();
334
335 SpatialStatistics::processFrame(istep);
336 }
337
338 int SlabStatistics::getBin(Vector3d pos) {
339 currentSnapshot_->wrapVector(pos);
340 // which bin is this stuntdouble in?
341 // wrapped positions are in the range [-0.5*hmat(2,2), +0.5*hmat(2,2)]
342 // Shift molecules by half a box to have bins start at 0
343 // The modulo operator is used to wrap the case when we are
344 // beyond the end of the bins back to the beginning.
345 return int(nBins_ * (pos.z() / hmat_(2,2) + 0.5)) % nBins_;
346 }
347
348 ShellStatistics::ShellStatistics(SimInfo* info, const string& filename,
349 const string& sele, int nbins) :
350 SpatialStatistics(info, filename, sele, nbins), coordinateOrigin_(V3Zero) {
351
352 binWidth_ = 1.0;
353
354 r_ = new OutputData;
355 r_->units = "Angstroms";
356 r_->title = "R";
357 r_->dataType = odtReal;
358 r_->dataHandling = odhAverage;
359 r_->accumulator.reserve(nbins);
360 for (int i = 0; i < nbins; i++)
361 r_->accumulator.push_back( new Accumulator() );
362 data_.push_back(r_);
363
364 for (int i = 0; i < nbins; i++) {
365 RealType r = (((RealType)i + 0.5) * binWidth_);
366 dynamic_cast<Accumulator*>(r_->accumulator[i])->add(r);
367 }
368 }
369
370 ShellStatistics::~ShellStatistics() {
371 delete r_;
372 }
373
374 int ShellStatistics::getBin(Vector3d pos) {
375 Vector3d rPos = pos - coordinateOrigin_;
376 return int(rPos.length() / binWidth_);
377 }
378 }
379

Properties

Name Value
svn:eol-style native