Loading...
Searching...
No Matches
generic.cpp
Go to the documentation of this file.
1//-----------------------------------------------------------------------------------
2// d-SEAMS - Deferred Structural Elucidation Analysis for Molecular Simulations
3//
4// Copyright (c) 2018--present d-SEAMS core team
5//
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the MIT License as published by
8// the Open Source Initiative.
9//
10// A copy of the MIT License is included in the LICENSE file of this repository.
11// You should have received a copy of the MIT License along with this program.
12// If not, see <https://opensource.org/licenses/MIT>.
13//-----------------------------------------------------------------------------------
14
15#include <generic.hpp>
16#include <iostream>
17
27 std::string outFile) {
28 std::ofstream outputFile;
29 // Create a new file in the output directory
30 outputFile.open(outFile);
31
32 if (outputFile.is_open()) {
33 // First line
34 outputFile << "# Frame\tAtomID\tx\ty\tz\tcij\ticeType\n";
35 // Write out all the information out line by line
36 for (int i = 0; i < yCloud->nop; i++) {
37 outputFile << yCloud->currentFrame << "\t" << yCloud->pts[i].atomID
38 << "\t" << yCloud->pts[i].x << "\t" << yCloud->pts[i].y << "\t"
39 << yCloud->pts[i].z << "\t";
40 // Print out cij
41 // for(int c=0; c<yCloud->pts[i].c_ij.size(); c++){outputFile <<
42 // yCloud->pts[i].c_ij[c]<<"\t";} Print out the classifier
43 // TODO: Should print string representation
44 outputFile << static_cast<int>(yCloud->pts[i].iceType) << "\n";
45 }
46 }
47 // Close the file
48 outputFile.close();
49 return 0;
50}
51
72 molSys::PointCloud<molSys::Point<double>, double> *yCloud, int iatomIndex,
73 int jatomIndex, double *x_i, double *y_i, double *z_i, double *x_j,
74 double *y_j, double *z_j) {
75 //
76 double x_iatom, y_iatom, z_iatom;
77 double x_jatom, y_jatom, z_jatom;
78 double x_ij, y_ij, z_ij; // Relative distance
79 std::vector<double> box = yCloud->box;
80 double xPBC, yPBC, zPBC; // Actual unwrapped distance
81
82 // ----------------------------------------------------------------------
83 // INIT
84 // iatom
85 x_iatom = yCloud->pts[iatomIndex].x;
86 y_iatom = yCloud->pts[iatomIndex].y;
87 z_iatom = yCloud->pts[iatomIndex].z;
88 // jatom
89 x_jatom = yCloud->pts[jatomIndex].x;
90 y_jatom = yCloud->pts[jatomIndex].y;
91 z_jatom = yCloud->pts[jatomIndex].z;
92 // ----------------------------------------------------------------------
93 // GET RELATIVE DISTANCE
94 x_ij = x_iatom - x_jatom;
95 y_ij = y_iatom - y_jatom;
96 z_ij = z_iatom - z_jatom;
97 // ----------------------------------------------------------------------
98 // SHIFT COORDINATES IF REQUIRED
99 // Shift x
100 if (fabs(x_ij) > 0.5 * box[0]) {
101 // Get the actual distance
102 xPBC = box[0] - fabs(x_ij);
103 if (x_ij < 0) {
104 x_jatom = x_iatom - xPBC;
105 } // To the -x side of currentIndex
106 else {
107 x_jatom = x_iatom + xPBC;
108 } // Add to the + side
109 } // Shift nextElement
110 //
111 // Shift y
112 if (fabs(y_ij) > 0.5 * box[1]) {
113 // Get the actual distance
114 yPBC = box[1] - fabs(y_ij);
115 if (y_ij < 0) {
116 y_jatom = y_iatom - yPBC;
117 } // To the -y side of currentIndex
118 else {
119 y_jatom = y_iatom + yPBC;
120 } // Add to the + side
121 } // Shift nextElement
122 //
123 // Shift z
124 if (fabs(z_ij) > 0.5 * box[2]) {
125 // Get the actual distance
126 zPBC = box[2] - fabs(z_ij);
127 if (z_ij < 0) {
128 z_jatom = z_iatom - zPBC;
129 } // To the -z side of currentIndex
130 else {
131 z_jatom = z_iatom + zPBC;
132 } // Add to the + side
133 } // Shift nextElement
134 // ----------------------------------------------------------------------
135 // Assign values
136 *x_i = x_iatom;
137 *y_i = y_iatom;
138 *z_i = z_iatom;
139 *x_j = x_jatom;
140 *y_j = y_jatom;
141 *z_j = z_jatom;
142
143 return 0;
144}
145
155double gen::eigenVecAngle(std::vector<double> OO, std::vector<double> OH) {
156 Eigen::Vector3d eigOO = Eigen::Map<Eigen::Vector3d>(OO.data(), OO.size());
157 Eigen::Vector3d eigOH = Eigen::Map<Eigen::Vector3d>(OH.data(), OH.size());
158 double angle;
159 angle = acos(eigOO.dot(eigOH) / (eigOO.norm() * eigOH.norm()));
160 return angle;
161}
162
169double gen::getAverageWithoutOutliers(std::vector<double> inpVec) {
170 //
171 double avgVal = 0.0; // Average value, excluding the outliers
172 double median; // Median value
173 int n = inpVec.size(); // Number of values
174 std::vector<double> lowerRange,
175 upperRange; // n/2 smallest and n/2 largest numbers
176 double firstQuartile, thirdQuartile; // First and third quartiles
177 double iqr; // Interquartile range
178 double outlierLimLow, outlierLimHigh; // Outliers limit
179 int numOfObservations = 0; // Number of observations used for the average
180 // ----------------------
181 // Calculate the median (the vector is sorted inside the function)
182 median = calcMedian(&inpVec);
183 // ----------------------
184 // Get the n/2 smallest and largest numbers
185 //
186 if (n % 2 == 0) {
187 for (int i = 0; i < n / 2; i++) {
188 // n/2 smallest numbers
189 lowerRange.push_back(inpVec[i]);
190 // n/2 largest numbers
191 upperRange.push_back(inpVec[n / 2 + i]);
192 } // end of loop to fill up the n/2 smallest and n/2 largest
193 } // even
194 else {
195 //
196 int halfN = (n + 1) / 2;
197 // Exclude the median
198 for (int i = 0; i < halfN; i++) {
199 // (n+1)/2 smallest numbers
200 lowerRange.push_back(inpVec[i]);
201 // (n+1)/2 largest numbers
202 upperRange.push_back(inpVec[halfN + i]);
203 } // end of filling up the smallest and largest half-ranges
204 } // for odd numbers
205 // ----------------------
206 // Calculate the first and third quartiles, and interquartile range
207 //
208 // First quartile
209 firstQuartile = calcMedian(&lowerRange);
210 // Third quartile
211 thirdQuartile = calcMedian(&upperRange);
212 // Interquartile range
213 iqr = thirdQuartile - firstQuartile;
214 // ----------------------
215 // Calculate the average without outliers
216 // Outliers are defined as values which
217 // are less than Q1 - 1.5IQR
218 // or greater than Q3 + 1.5IQR
219 //
220 // Get the limits for the outliers
221 outlierLimLow = firstQuartile - 1.5 * iqr;
222 outlierLimHigh = thirdQuartile + 1.5 * iqr;
223 //
224 // Loop through the values in inpVec to get the average, excluding outliers
225 for (int i = 0; i < n; i++) {
226 //
227 if (inpVec[i] < outlierLimLow) {
228 continue;
229 } // lower limit outlier
230 else if (inpVec[i] > outlierLimHigh) {
231 continue;
232 } // higher limit outlier
233 else {
234 // Number of observations added
235 numOfObservations++;
236 // Add to the average
237 avgVal += inpVec[i];
238 } // take the average
239 } // end of loop for getting the average
240 //
241 // Divide by the number of observations used
242 avgVal /= numOfObservations;
243 // ----------------------
244 // This fails if there are not enough observations (ring size = 3)
245 if (numOfObservations == 0) {
246 double sumVal = 0.0;
247 // Loop through all the values and sum
248 for (int i = 0; i <= n; i++) {
249 sumVal += inpVec[i];
250 } // end of sum
251 // Normalize
252 avgVal = sumVal / n;
253 return avgVal;
254 } // for triangular prism blocks
255 // ----------------------
256
257 return avgVal;
258}
259
267double gen::angDistDegQuaternions(std::vector<double> quat1,
268 std::vector<double> quat2) {
269 //
270 double prod; // Product of quat1 and conjugate of quat2
271 // The angular distance is
272 // angularDistance = 2*cosInverse(quat1*conj(quat2))
273 prod = quat1[0] * quat2[0] - quat1[1] * quat2[1] - quat1[2] * quat2[2] -
274 quat1[3] * quat2[3];
275 // The angular distance is:
276 double angDist = 2 * acos(prod) * 180.0 / (gen::pi);
277 // Return the angular distance
278 return angDist;
279}
File for containing generic or common functions.
double eigenVecAngle(std::vector< double > OO, std::vector< double > OH)
Eigen function for getting the angle (in radians) between the O–O and O-H vectors.
Definition generic.cpp:155
double calcMedian(std::vector< double > *input)
Inline generic function for calculating the median given a vector of the values.
Definition generic.hpp:77
const double pi
Definition generic.hpp:54
double angDistDegQuaternions(std::vector< double > quat1, std::vector< double > quat2)
Definition generic.cpp:267
int unwrappedCoordShift(molSys::PointCloud< molSys::Point< double >, double > *yCloud, int iatomIndex, int jatomIndex, double *x_i, double *y_i, double *z_i, double *x_j, double *y_j, double *z_j)
Shift particles (unwrapped coordinates)
Definition generic.cpp:71
int prettyPrintYoda(molSys::PointCloud< molSys::Point< double >, double > *yCloud, std::string outFile)
Generic function for printing all the struct information.
Definition generic.cpp:25
double getAverageWithoutOutliers(std::vector< double > inpVec)
Get the average, after excluding the outliers, using quartiles.
Definition generic.cpp:169
This contains a collection of points; contains information for a particular frame.
Definition mol_sys.hpp:170
This contains per-particle information.
Definition mol_sys.hpp:149