45#include "applications/dynamicProps/RotAngleDisplacement.hpp"
49#include "utils/Revision.hpp"
50#include "utils/simError.h"
53 RotAngleDisplacement::RotAngleDisplacement(SimInfo* info,
54 const std::string& filename,
55 const std::string& sele1,
56 const std::string& sele2) :
57 MoleculeACF<Vector3d>(info, filename, sele1, sele2) {
58 setCorrFuncType(
"Rotational Angle Displacement Function");
59 setOutputName(
getPrefix(dumpFilename_) +
".rotAngDisp");
61 if (!uniqueSelections_) { seleMan2_ = seleMan1_; }
63 rotMats_.resize(nTimeBins_);
64 histogram_.resize(nTimeBins_);
65 counts_.resize(nTimeBins_);
66 std::fill(histogram_.begin(), histogram_.end(), 0.0);
67 std::fill(counts_.begin(), counts_.end(), 0);
70 void RotAngleDisplacement::computeFrame(
int frame) {
71 MoleculeACF<Vector3d>::computeFrame(frame);
74 int RotAngleDisplacement::computeProperty1(
int frame, Molecule* mol) {
75 RotMat3x3d A = mol->getRigidBodyAt(0)->getA();
76 rotMats_[frame].push_back(A);
77 return rotMats_[frame].size() - 1;
80 Vector3d RotAngleDisplacement::calcCorrVal(
int frame1,
int frame2,
int id1,
82 RotMat3x3d A1 = rotMats_[frame1][id1];
83 RotMat3x3d A2 = rotMats_[frame2][id2];
85 RotMat3x3d A21 = A1.transpose() * A2;
86 Vector3d rpy = A21.toRPY();
91 void RotAngleDisplacement::correlateFrames(
int frame1,
int frame2,
96 std::vector<int>::iterator i1;
97 std::vector<int>::iterator i2;
99 Vector3d corrVal(0.0);
101 s1 = sele1ToIndex_[frame1];
103 if (uniqueSelections_)
104 s2 = sele2ToIndex_[frame2];
106 s2 = sele1ToIndex_[frame2];
108 for (i1 = s1.begin(), i2 = s2.begin(); i1 != s1.end() && i2 != s2.end();
115 while (i1 != s1.end() && *i1 < *i2) {
119 while (i2 != s2.end() && *i2 < *i1) {
123 if (i1 == s1.end() || i2 == s2.end())
break;
125 corrVal = calcCorrVal(frame1, frame2, i1 - s1.begin(), i2 - s2.begin());
127 histogram_[timeBin] += corrVal;
132 void RotAngleDisplacement::postCorrelate() {
133 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
134 if (counts_[i] > 0) { histogram_[i] /= counts_[i]; }
138 void RotAngleDisplacement::validateSelection(SelectionManager&) {
141 for (mol = seleMan1_.beginSelectedMolecule(i); mol != NULL;
142 mol = seleMan1_.nextSelectedMolecule(i)) {
143 if (mol->getNRigidBodies() < 1) {
144 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
145 "RotAngleDisplacement::validateSelection Error: "
146 "at least one selected molecule does not have a rigid body\n");
147 painCave.isFatal = 1;
151 if (seleMan1_.getMoleculeSelectionCount() < 1) {
152 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
153 "RotAngleDisplacement::validateSelection Error: "
154 "There needs to be at least one selected molecule.\n");
155 painCave.isFatal = 1;
160 void RotAngleDisplacement::writeCorrelate() {
161 std::string Anglefile = getOutputFileName();
162 std::ofstream ofs1(Anglefile.c_str());
164 if (ofs1.is_open()) {
167 ofs1 <<
"# " << getCorrFuncType() <<
"\n";
168 ofs1 <<
"# OpenMD " << r.getFullRevision() <<
"\n";
169 ofs1 <<
"# " << r.getBuildDate() <<
"\n";
170 ofs1 <<
"# selection script1: \"" << selectionScript1_;
171 ofs1 <<
"\"\tselection script2: \"" << selectionScript2_ <<
"\"\n";
173 ofs1 <<
"#time\troll\tpitch\tyaw\n";
175 for (
unsigned int i = 0; i < nTimeBins_; ++i) {
176 ofs1 << times_[i] - times_[0];
178 ofs1 <<
"\t" << histogram_[i][0];
179 ofs1 <<
"\t" << histogram_[i][1];
180 ofs1 <<
"\t" << histogram_[i][2] <<
"\n";
185 painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
186 "RotAngleDisplacement::writeCorrelate Error: failed to open %s\n",
188 painCave.isFatal = 1;
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
std::string getPrefix(const std::string &str)