ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/applications/staticProps/SpatialStatistics.cpp
Revision: 1865
Committed: Wed Apr 17 18:24:08 2013 UTC (12 years ago) by gezelter
Original Path: branches/development/src/applications/staticProps/SpatialStatistics.cpp
File size: 12478 byte(s)
Log Message:
Adding spatial statistics analysers.

File Contents

# User Rev Content
1 gezelter 1865 /*
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     RealType r;
225     Vector3d v;
226    
227     if( dat->dataType == odtReal ) {
228     dynamic_cast<Accumulator*>(dat->accumulator[bin])->getAverage(r);
229     if (isinf(r) || isnan(r) ) {
230     sprintf( painCave.errMsg,
231     "SpatialStatistics detected a numerical error writing:\n"
232     "\t%s for bin %d",
233     dat->title.c_str(), bin);
234     painCave.isFatal = 1;
235     simError();
236     }
237     if (dat->dataHandling == odhTotal) r *= dat->accumulator[bin]->count();
238     os << "\t" << r;
239    
240     } else if ( dat->dataType == odtVector3 ) {
241     dynamic_cast<VectorAccumulator*>(dat->accumulator[bin])->getAverage(v);
242     if (isinf(v[0]) || isnan(v[0]) ||
243     isinf(v[1]) || isnan(v[1]) ||
244     isinf(v[2]) || isnan(v[2]) ) {
245     sprintf( painCave.errMsg,
246     "SpatialStatistics detected a numerical error writing:\n"
247     "\t%s for bin %d",
248     dat->title.c_str(), bin);
249     painCave.isFatal = 1;
250     simError();
251     }
252     if (dat->dataHandling == odhTotal) v *= dat->accumulator[bin]->count();
253     os << "\t" << v[0] << "\t" << v[1] << "\t" << v[2];
254     }
255     }
256    
257     void SpatialStatistics::writeStdDev(ostream& os, OutputData* dat,
258     unsigned int bin) {
259     assert(int(bin) < nBins_);
260     int n = dat->accumulator[bin]->count();
261     if (n == 0) return;
262    
263     RealType r;
264     Vector3d v;
265    
266     if( dat->dataType == odtReal ) {
267     dynamic_cast<Accumulator*>(dat->accumulator[bin])->getStdDev(r);
268     if (isinf(r) || isnan(r) ) {
269     sprintf( painCave.errMsg,
270     "SpatialStatistics detected a numerical error writing:\n"
271     "\tstandard deviation of %s for bin %d",
272     dat->title.c_str(), bin);
273     painCave.isFatal = 1;
274     simError();
275     }
276     if (dat->dataHandling == odhTotal) r *= dat->accumulator[bin]->count();
277     os << "\t" << r;
278    
279     } else if ( dat->dataType == odtVector3 ) {
280     dynamic_cast<VectorAccumulator*>(dat->accumulator[bin])->getStdDev(v);
281     if (isinf(v[0]) || isnan(v[0]) ||
282     isinf(v[1]) || isnan(v[1]) ||
283     isinf(v[2]) || isnan(v[2]) ) {
284     sprintf( painCave.errMsg,
285     "SpatialStatistics detected a numerical error writing:\n"
286     "\tstandard deviation of %s for bin %d",
287     dat->title.c_str(), bin);
288     painCave.isFatal = 1;
289     simError();
290     }
291     if (dat->dataHandling == odhTotal) v *= dat->accumulator[bin]->count();
292     os << "\t" << v[0] << "\t" << v[1] << "\t" << v[2];
293     }
294     }
295    
296    
297     OutputData* SpatialStatistics::beginOutputData(vector<OutputData*>::iterator& i) {
298     i = data_.begin();
299     return i != data_.end()? *i : NULL;
300     }
301    
302     OutputData* SpatialStatistics::nextOutputData(vector<OutputData*>::iterator& i){
303     ++i;
304     return i != data_.end()? *i: NULL;
305     }
306    
307    
308     SlabStatistics::SlabStatistics(SimInfo* info, const string& filename,
309     const string& sele, int nbins) :
310     SpatialStatistics(info, filename, sele, nbins) {
311    
312     z_ = new OutputData;
313     z_->units = "Angstroms";
314     z_->title = "Z";
315     z_->dataType = odtReal;
316     z_->dataHandling = odhAverage;
317     z_->accumulator.reserve(nbins);
318     for (int i = 0; i < nbins; i++)
319     z_->accumulator.push_back( new Accumulator() );
320     data_.push_back(z_);
321     }
322    
323     void SlabStatistics::processFrame(int istep) {
324     RealType z;
325     hmat_ = currentSnapshot_->getHmat();
326     for (int i = 0; i < nBins_; i++) {
327     z = (((RealType)i + 0.5) / (RealType)nBins_) * hmat_(2,2);
328     dynamic_cast<Accumulator*>(z_->accumulator[i])->add(z);
329     }
330     volume_ = currentSnapshot_->getVolume();
331    
332     SpatialStatistics::processFrame(istep);
333     }
334    
335     int SlabStatistics::getBin(Vector3d pos) {
336     currentSnapshot_->wrapVector(pos);
337     // which bin is this stuntdouble in?
338     // wrapped positions are in the range [-0.5*hmat(2,2), +0.5*hmat(2,2)]
339     // Shift molecules by half a box to have bins start at 0
340     // The modulo operator is used to wrap the case when we are
341     // beyond the end of the bins back to the beginning.
342     return int(nBins_ * (pos.z() / hmat_(2,2) + 0.5)) % nBins_;
343     }
344    
345    
346     ShellStatistics::ShellStatistics(SimInfo* info, const string& filename,
347     const string& sele, int nbins) :
348     SpatialStatistics(info, filename, sele, nbins){
349    
350     coordinateOrigin_ = V3Zero;
351     binWidth_ = 1.0;
352    
353     r_ = new OutputData;
354     r_->units = "Angstroms";
355     r_->title = "R";
356     r_->dataType = odtReal;
357     r_->dataHandling = odhAverage;
358     r_->accumulator.reserve(nbins);
359     for (int i = 0; i < nbins; i++)
360     r_->accumulator.push_back( new Accumulator() );
361     data_.push_back(r_);
362    
363     for (int i = 0; i < nbins; i++) {
364     RealType r = (((RealType)i + 0.5) * binWidth_);
365     dynamic_cast<Accumulator*>(r_->accumulator[i])->add(r);
366     }
367     }
368    
369     int ShellStatistics::getBin(Vector3d pos) {
370     Vector3d rPos = pos - coordinateOrigin_;
371     return int(rPos.length() / binWidth_);
372     }
373     }
374    

Properties

Name Value
svn:eol-style native