47#include "applications/staticProps/pAngle.hpp"
52#include "brains/Thermo.hpp"
55#include "utils/simError.h"
59 pAngle::pAngle(SimInfo* info,
const std::string& filename,
60 const std::string& sele1,
int nthetabins) :
61 StaticAnalyser(info, filename, nthetabins),
62 doVect_(true), doOffset_(false), selectionScript1_(sele1),
63 seleMan1_(info), seleMan2_(info), evaluator1_(info), evaluator2_(info),
64 nThetaBins_(nthetabins) {
65 setOutputName(
getPrefix(filename) +
".pAngle");
67 evaluator1_.loadScriptString(sele1);
68 if (!evaluator1_.isDynamic()) {
69 seleMan1_.setSelectionSet(evaluator1_.evaluate());
72 count_.resize(nThetaBins_);
73 histogram_.resize(nThetaBins_);
76 pAngle::pAngle(SimInfo* info,
const std::string& filename,
77 const std::string& sele1,
const std::string& sele2,
79 StaticAnalyser(info, filename, nthetabins),
80 doVect_(false), doOffset_(false), selectionScript1_(sele1),
81 selectionScript2_(sele2), seleMan1_(info), seleMan2_(info),
82 evaluator1_(info), evaluator2_(info), nThetaBins_(nthetabins) {
83 setOutputName(
getPrefix(filename) +
".pAngle");
85 evaluator1_.loadScriptString(sele1);
86 if (!evaluator1_.isDynamic()) {
87 seleMan1_.setSelectionSet(evaluator1_.evaluate());
90 evaluator2_.loadScriptString(sele2);
91 if (!evaluator2_.isDynamic()) {
92 seleMan2_.setSelectionSet(evaluator2_.evaluate());
95 count_.resize(nThetaBins_);
96 histogram_.resize(nThetaBins_);
99 pAngle::pAngle(SimInfo* info,
const std::string& filename,
100 const std::string& sele1,
int seleOffset,
int nthetabins) :
101 StaticAnalyser(info, filename, nthetabins),
102 doVect_(false), doOffset_(true), doOffset2_(false),
103 selectionScript1_(sele1), seleMan1_(info), seleMan2_(info),
104 evaluator1_(info), evaluator2_(info), seleOffset_(seleOffset),
105 nThetaBins_(nthetabins) {
106 setOutputName(
getPrefix(filename) +
".pAngle");
108 evaluator1_.loadScriptString(sele1);
109 if (!evaluator1_.isDynamic()) {
110 seleMan1_.setSelectionSet(evaluator1_.evaluate());
113 count_.resize(nThetaBins_);
114 histogram_.resize(nThetaBins_);
117 pAngle::pAngle(SimInfo* info,
const std::string& filename,
118 const std::string& sele1,
int seleOffset,
int seleOffset2,
120 StaticAnalyser(info, filename, nthetabins),
121 doVect_(false), doOffset_(true), doOffset2_(true),
122 selectionScript1_(sele1), seleMan1_(info), seleMan2_(info),
123 evaluator1_(info), evaluator2_(info), seleOffset_(seleOffset),
124 seleOffset2_(seleOffset2), nThetaBins_(nthetabins) {
125 setOutputName(
getPrefix(filename) +
".pAngle");
127 evaluator1_.loadScriptString(sele1);
128 if (!evaluator1_.isDynamic()) {
129 seleMan1_.setSelectionSet(evaluator1_.evaluate());
132 count_.resize(nThetaBins_);
133 histogram_.resize(nThetaBins_);
136 void pAngle::process() {
141 bool usePeriodicBoundaryConditions_ =
142 info_->getSimParams()->getUsePeriodicBoundaryConditions();
144 Thermo thermo(info_);
145 DumpReader reader(info_, dumpFilename_);
146 int nFrames = reader.getNFrames();
148 nProcessed_ = nFrames / step_;
150 std::fill(histogram_.begin(), histogram_.end(), 0.0);
151 std::fill(count_.begin(), count_.end(), 0);
153 for (
int istep = 0; istep < nFrames; istep += step_) {
154 reader.readFrame(istep);
155 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
157 Vector3d CenterOfMass = thermo.getCom();
159 if (evaluator1_.isDynamic()) {
160 seleMan1_.setSelectionSet(evaluator1_.evaluate());
164 for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL;
165 sd1 = seleMan1_.nextSelected(ii)) {
166 Vector3d pos = sd1->getPos();
168 Vector3d r1 = CenterOfMass - pos;
171 if (sd1->isDirectional()) {
172 Vector3d vec = sd1->getA().transpose() * V3Z;
175 RealType cosangle =
dot(r1, vec);
177 int binNo = int(nThetaBins_ * (1.0 + cosangle) / 2.0);
183 for (sd1 = seleMan1_.beginSelected(ii); sd1 != NULL;
184 sd1 = seleMan1_.nextSelected(ii)) {
191 int sd1Aind = sd1->getGlobalIndex() + seleOffset2_;
192 StuntDouble* sd1A = info_->getIOIndexToIntegrableObject(sd1Aind);
193 r1 = CenterOfMass - sd1A->getPos();
195 r1 = CenterOfMass - sd1->getPos();
198 if (usePeriodicBoundaryConditions_)
199 currentSnapshot_->wrapVector(r1);
201 int sd2Index = sd1->getGlobalIndex() + seleOffset_;
202 sd2 = info_->getIOIndexToIntegrableObject(sd2Index);
204 Vector3d r2 = CenterOfMass - sd2->getPos();
205 if (usePeriodicBoundaryConditions_)
206 currentSnapshot_->wrapVector(r1);
208 Vector3d rc = 0.5 * (r1 + r2);
209 if (usePeriodicBoundaryConditions_)
210 currentSnapshot_->wrapVector(rc);
212 Vector3d vec = r1 - r2;
213 if (usePeriodicBoundaryConditions_)
214 currentSnapshot_->wrapVector(vec);
218 RealType cosangle =
dot(rc, vec);
219 int binNo = int(nThetaBins_ * (1.0 + cosangle) / 2.0);
223 if (evaluator2_.isDynamic()) {
224 seleMan2_.setSelectionSet(evaluator2_.evaluate());
227 if (seleMan1_.getSelectionCount() != seleMan2_.getSelectionCount()) {
228 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
229 "In frame %d, the number of selected StuntDoubles are\n"
230 "\tnot the same in --sele1 and sele2\n",
232 painCave.severity = OPENMD_INFO;
233 painCave.isFatal = 0;
237 for (sd1 = seleMan1_.beginSelected(ii),
238 sd2 = seleMan2_.beginSelected(jj);
239 sd1 != NULL && sd2 != NULL; sd1 = seleMan1_.nextSelected(ii),
240 sd2 = seleMan2_.nextSelected(jj)) {
241 Vector3d r1 = CenterOfMass - sd1->getPos();
242 if (usePeriodicBoundaryConditions_)
243 currentSnapshot_->wrapVector(r1);
245 Vector3d r2 = CenterOfMass - sd2->getPos();
246 if (usePeriodicBoundaryConditions_)
247 currentSnapshot_->wrapVector(r1);
249 Vector3d rc = 0.5 * (r1 + r2);
250 if (usePeriodicBoundaryConditions_)
251 currentSnapshot_->wrapVector(rc);
253 Vector3d vec = r1 - r2;
254 if (usePeriodicBoundaryConditions_)
255 currentSnapshot_->wrapVector(vec);
259 RealType cosangle =
dot(rc, vec);
260 int binNo = int(nThetaBins_ * (1.0 + cosangle) / 2.0);
271 void pAngle::processHistogram() {
273 for (
unsigned int i = 0; i < count_.size(); ++i)
276 for (
unsigned int i = 0; i < count_.size(); ++i) {
277 histogram_[i] = double(count_[i] /
double(atot));
281 void pAngle::writeProbs() {
282 std::ofstream rdfStream(outputFilename_.c_str());
283 if (rdfStream.is_open()) {
284 rdfStream <<
"#pAngle\n";
285 rdfStream <<
"#nFrames:\t" << nProcessed_ <<
"\n";
286 rdfStream <<
"#selection1: (" << selectionScript1_ <<
")";
288 rdfStream <<
"\tselection2: (" << selectionScript2_ <<
")";
291 rdfStream <<
"#cos(theta)\tp(cos(theta))\n";
292 RealType dct = 2.0 / histogram_.size();
293 for (
unsigned int i = 0; i < histogram_.size(); ++i) {
294 RealType ct = -1.0 + (2.0 * i + 1) / (histogram_.size());
295 rdfStream << ct <<
"\t" << histogram_[i] / dct <<
"\n";
299 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
300 "pAngle: unable to open %s\n", outputFilename_.c_str());
301 painCave.isFatal = 1;
void normalize()
Normalizes this vector in place.
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
Real dot(const DynamicVector< Real > &v1, const DynamicVector< Real > &v2)
Returns the dot product of two DynamicVectors.
std::string getPrefix(const std::string &str)