43#include "applications/dynamicProps/MultipassCorrFunc.hpp"
44#include "utils/simError.h"
45#include "utils/Revision.hpp"
53 MultipassCorrFunc<T>::MultipassCorrFunc(SimInfo* info,
54 const string& filename,
58 : storageLayout_(storageLayout), info_(info), dumpFilename_(filename),
59 seleMan1_(info_), seleMan2_(info_),
60 selectionScript1_(sele1), selectionScript2_(sele2),
61 evaluator1_(info_), evaluator2_(info_), autoCorrFunc_(false) {
67 storageLayout_ = info->getStorageLayout() | storageLayout;
69 reader_ =
new DumpReader(info_, dumpFilename_);
71 uniqueSelections_ = (sele1.compare(sele2) != 0) ?
true : false;
73 evaluator1_.loadScriptString(selectionScript1_);
75 if (!evaluator1_.isDynamic()) {
76 seleMan1_.setSelectionSet(evaluator1_.evaluate());
77 validateSelection(seleMan1_);
80 if (uniqueSelections_) {
81 evaluator2_.loadScriptString(selectionScript2_);
82 if (!evaluator2_.isDynamic()) {
83 seleMan2_.setSelectionSet(evaluator2_.evaluate());
84 validateSelection(seleMan2_);
88 Globals* simParams = info_->getSimParams();
89 if (simParams->haveSampleTime()){
90 deltaTime_ = simParams->getSampleTime();
92 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
93 "MultipassCorrFunc Error: can not figure out deltaTime\n");
98 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
"Scanning for frames.");
100 painCave.severity=OPENMD_INFO;
103 nFrames_ = reader_->getNFrames();
104 nTimeBins_ = nFrames_;
107 histogram_.resize(nTimeBins_, zeroType);
108 count_.resize(nTimeBins_, 0);
110 times_.resize(nFrames_);
111 sele1ToIndex_.resize(nFrames_);
112 if (uniqueSelections_) {
113 sele2ToIndex_.resize(nFrames_);
116 progressBar_ =
new ProgressBar();
120 void MultipassCorrFunc<T>::preCorrelate() {
122 progressBar_->clear();
124 for (
int istep = 0; istep < nFrames_; istep++) {
125 reader_->readFrame(istep);
126 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
127 times_[istep] = currentSnapshot_->getTime();
129 progressBar_->setStatus(istep+1, nFrames_);
130 progressBar_->update();
138 void MultipassCorrFunc<T>::computeFrame(
int istep) {
144 if (evaluator1_.isDynamic()) {
145 seleMan1_.setSelectionSet(evaluator1_.evaluate());
146 validateSelection(seleMan1_);
149 if (uniqueSelections_ && evaluator2_.isDynamic()) {
150 seleMan2_.setSelectionSet(evaluator2_.evaluate());
151 validateSelection(seleMan2_);
154 for (sd = seleMan1_.beginSelected(isd1); sd != NULL;
155 sd = seleMan1_.nextSelected(isd1)) {
157 index = computeProperty1(istep, sd);
159 if (index == sele1ToIndex_[istep].size()) {
160 sele1ToIndex_[istep].push_back(sd->getGlobalIndex());
162 sele1ToIndex_[istep].resize(index+1);
163 sele1ToIndex_[istep][index] = sd->getGlobalIndex();
166 if (!uniqueSelections_) {
167 index = computeProperty2(istep, sd);
171 if (uniqueSelections_) {
172 for (sd = seleMan2_.beginSelected(isd2); sd != NULL;
173 sd = seleMan2_.nextSelected(isd2)) {
176 index = computeProperty1(istep, sd);
178 index = computeProperty2(istep, sd);
180 if (index == sele2ToIndex_[istep].size()) {
181 sele2ToIndex_[istep].push_back(sd->getGlobalIndex());
183 sele2ToIndex_[istep].resize(index+1);
184 sele2ToIndex_[istep][index] = sd->getGlobalIndex();
191 void MultipassCorrFunc<T>::doCorrelate() {
193 painCave.isFatal = 0;
194 painCave.severity=OPENMD_INFO;
195 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
"Starting pre-correlate scan.");
199 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
"Calculating correlation function.");
203 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
"Doing post-correlation calculations.");
207 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
"Writing output.");
213 void MultipassCorrFunc<T>::correlation() {
215 for (
unsigned int i =0 ; i < nTimeBins_; ++i) {
216 histogram_[i] = zeroType;
220 progressBar_->clear();
221 RealType samples = 0.5 * (nFrames_ + 1) * nFrames_;
224 for (
int i = 0; i < nFrames_; ++i) {
226 RealType time1 = times_[i];
228 for(
int j = i; j < nFrames_; ++j) {
230 progressBar_->setStatus(visited, samples);
231 progressBar_->update();
237 RealType time2 = times_[j];
239 if ( fabs( (time2 - time1) - (j-i)*deltaTime_ ) > 1.0e-4 ) {
240 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
241 "MultipassCorrFunc::correlateBlocks Error: sampleTime (%f)\n"
242 "\tin %s does not match actual time-spacing between\n"
243 "\tconfigurations %d (t = %f) and %d (t = %f).\n",
244 deltaTime_, dumpFilename_.c_str(), i, time1, j, time2);
245 painCave.isFatal = 1;
249 int timeBin = int ((time2 - time1) / deltaTime_ + 0.5);
250 correlateFrames(i,j, timeBin);
257 void MultipassCorrFunc<T>::correlateFrames(
int frame1,
int frame2,
262 std::vector<int>::iterator i1;
263 std::vector<int>::iterator i2;
267 s1 = sele1ToIndex_[frame1];
269 if (uniqueSelections_)
270 s2 = sele2ToIndex_[frame2];
272 s2 = sele1ToIndex_[frame2];
274 for (i1 = s1.begin(), i2 = s2.begin();
275 i1 != s1.end() && i2 != s2.end(); ++i1, ++i2){
282 while ( i1 != s1.end() && *i1 < *i2 ) {
286 while ( i2 != s2.end() && *i2 < *i1 ) {
290 if ( i1 == s1.end() || i2 == s2.end() )
break;
292 corrVal = calcCorrVal(frame1, frame2, i1 - s1.begin(), i2 - s2.begin());
293 histogram_[timeBin] += corrVal;
300 void MultipassCorrFunc<T>::postCorrelate() {
302 for (
unsigned int i =0 ; i < nTimeBins_; ++i) {
304 histogram_[i] /= count_[i];
306 histogram_[i] = zeroType;
312 void MultipassCorrFunc<T>::writeCorrelate() {
313 ofstream ofs(outputFilename_.c_str());
319 ofs <<
"# " << getCorrFuncType() <<
"\n";
320 ofs <<
"# OpenMD " << r.getFullRevision() <<
"\n";
321 ofs <<
"# " << r.getBuildDate() <<
"\n";
322 ofs <<
"# selection script1: \"" << selectionScript1_ ;
323 ofs <<
"\"\tselection script2: \"" << selectionScript2_ <<
"\"\n";
324 if (!paramString_.empty())
325 ofs <<
"# parameters: " << paramString_ <<
"\n";
326 if (!labelString_.empty())
327 ofs <<
"#time\t" << labelString_ <<
"\n";
329 ofs <<
"#time\tcorrVal\n";
331 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
332 ofs << times_[i]-times_[0] <<
"\t" << histogram_[i] <<
"\n";
336 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
337 "MultipassCorrFunc::writeCorrelate Error: fail to open %s\n",
338 outputFilename_.c_str());
339 painCave.isFatal = 1;
348 void MultipassCorrFunc<Vector3d>::writeCorrelate() {
349 ofstream ofs(outputFilename_.c_str());
355 ofs <<
"# " << getCorrFuncType() <<
"\n";
356 ofs <<
"# OpenMD " << r.getFullRevision() <<
"\n";
357 ofs <<
"# " << r.getBuildDate() <<
"\n";
358 ofs <<
"# selection script1: \"" << selectionScript1_ ;
359 ofs <<
"\"\tselection script2: \"" << selectionScript2_ <<
"\"\n";
360 if (!paramString_.empty())
361 ofs <<
"# parameters: " << paramString_ <<
"\n";
362 if (!labelString_.empty())
363 ofs <<
"#time\t" << labelString_ <<
"\n";
365 ofs <<
"#time\tcorrVal\n";
367 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
368 ofs << times_[i]-times_[0] <<
"\t";
369 for (
int j = 0; j < 3; j++) {
370 ofs << histogram_[i](j) <<
'\t';
376 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
377 "MultipassCorrFunc::writeCorrelate Error: fail to open %s\n",
378 outputFilename_.c_str());
379 painCave.isFatal = 1;
389 void MultipassCorrFunc<Mat3x3d>::writeCorrelate() {
390 ofstream ofs(outputFilename_.c_str());
396 ofs <<
"# " << getCorrFuncType() <<
"\n";
397 ofs <<
"# OpenMD " << r.getFullRevision() <<
"\n";
398 ofs <<
"# " << r.getBuildDate() <<
"\n";
399 ofs <<
"# selection script1: \"" << selectionScript1_ ;
400 ofs <<
"\"\tselection script2: \"" << selectionScript2_ <<
"\"\n";
401 if (!paramString_.empty())
402 ofs <<
"# parameters: " << paramString_ <<
"\n";
403 if (!labelString_.empty())
404 ofs <<
"#time\t" << labelString_ <<
"\n";
406 ofs <<
"#time\tcorrVal\n";
408 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
409 ofs << times_[i]-times_[0] <<
"\t";
410 for (
int j = 0; j < 3; j++) {
411 for (
int k = 0; k < 3; k++) {
412 ofs << histogram_[i](j,k) <<
'\t';
419 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
420 "MultipassCorrFunc::writeCorrelate Error: fail to open %s\n",
421 outputFilename_.c_str());
422 painCave.isFatal = 1;
431 void MultipassCorrFunc<T>::validateSelection(SelectionManager& seleMan) {
437 CrossCorrFunc<T>::CrossCorrFunc(SimInfo* info,
const std::string& filename,
438 const std::string& sele1,
439 const std::string& sele2,
441 MultipassCorrFunc<T>(info, filename, sele1, sele2, storageLayout) {
442 this->autoCorrFunc_ =
false;
446 AutoCorrFunc<T>::AutoCorrFunc(SimInfo* info,
const std::string& filename,
447 const std::string& sele1,
448 const std::string& sele2,
450 MultipassCorrFunc<T>(info, filename, sele1, sele2, storageLayout) {
451 this->autoCorrFunc_ =
true;
454 template class AutoCorrFunc<RealType>;
455 template class MultipassCorrFunc<RealType>;
456 template class CrossCorrFunc<RealType>;
458 template class AutoCorrFunc<Vector3d>;
459 template class MultipassCorrFunc<Vector3d>;
460 template class CrossCorrFunc<Vector3d>;
462 template class AutoCorrFunc<Mat3x3d>;
463 template class MultipassCorrFunc<Mat3x3d>;
464 template class CrossCorrFunc<Mat3x3d>;
466 template class MultipassCorrFunc<DynamicVector<RealType> >;
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.