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 
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 
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 
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 }
T close(T... args)
T data(T... args)
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
T is_open(T... args)
T open(T... args)
T push_back(T... args)
T size(T... args)
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