RxDock 0.1.0
A fast, versatile, and open-source program for docking ligands to proteins and nucleic acids
Loading...
Searching...
No Matches
Coord.h
1/***********************************************************************
2 * The rDock program was developed from 1998 - 2006 by the software team
3 * at RiboTargets (subsequently Vernalis (R&D) Ltd).
4 * In 2006, the software was licensed to the University of York for
5 * maintenance and distribution.
6 * In 2012, Vernalis and the University of York agreed to release the
7 * program as Open Source software.
8 * This version is licensed under GNU-LGPL version 3.0 with support from
9 * the University of Barcelona.
10 * http://rdock.sourceforge.net/
11 ***********************************************************************/
12
13// Simple class for handling cartesian coords (points) and 3-d vectors
14// The same class is used to represent both points and vectors, although the
15// Vector typedef can be used in argument lists to distinguish the two cases
16
17#ifndef _RBTCOORD_H_
18#define _RBTCOORD_H_
19
20#include <algorithm> //for min,max
21#include <cmath> //for sqrt
22#include <iterator> //for back_inserter
23#include <numeric> //for accumulate
24
25#ifdef __PGI
26#define EIGEN_DONT_VECTORIZE
27#endif
28#include <Eigen/Core>
29#include <Eigen/Geometry>
30
31#include <nlohmann/json.hpp>
32
33using json = nlohmann::json;
34
35#ifndef M_PI
36#define M_PI 3.14159265358979323846
37#endif
38
39#include "rxdock/Config.h"
40
41extern std::istream &eatSeps(std::istream &is);
42
43namespace rxdock {
44
45class Coord {
47 // Data members
49 //(leave public so we don't need
50 // to write accessor functions)
51public:
52 Eigen::Vector3d xyz;
53
55 // Constructors/destructors:
57public:
58 // Default constructor (initialise to zero)
59 inline Coord() : xyz(0.0, 0.0, 0.0) {}
60
61 // Constructor with initial values
62 inline Coord(double x1, double y1, double z1) : xyz(x1, y1, z1) {}
63
64 // Constructor using Eigen
65 inline Coord(Eigen::Vector3d xyz1) : xyz(xyz1) {}
66
67 // Destructor
68 virtual ~Coord() {}
69
70 // Copy constructor
71 inline Coord(const Coord &coord) { xyz = coord.xyz; }
72
74 // Operator functions:
76
77 // Copy assignment (*this = coord)
78 inline Coord &operator=(const Coord &coord) {
79 if (this != &coord) { // beware of self-assignment
80 xyz = coord.xyz;
81 }
82 return *this;
83 }
84
85 // Copy assignment (*this = const)
86 inline Coord &operator=(const double &d) {
87 xyz.setConstant(d);
88 return *this;
89 }
90
91 //*this += coord
92 inline void operator+=(const Coord &coord) { xyz += coord.xyz; }
93
94 //*this += const
95 inline void operator+=(const double &d) { xyz += xyz.Constant(d); }
96
97 //*this -= coord
98 inline void operator-=(const Coord &coord) { xyz -= coord.xyz; }
99
100 //*this -= const
101 inline void operator-=(const double &d) { xyz -= xyz.Constant(d); }
102
103 //*this *= const
104 inline void operator*=(const double &d) { xyz *= d; }
105
106 //*this /= const
107 inline void operator/=(const double &d) { xyz /= d; }
108
110 // Friend functions:
112
113 // Insertion (output) operator
114 friend std::ostream &operator<<(std::ostream &s, const Coord &coord) {
115 return s << "(" << coord.xyz(0) << "," << coord.xyz(1) << ","
116 << coord.xyz(2) << ")";
117 }
118
119 // Input operator
120 // DM 15 Apr 1999
121 // Valid formats (actually the comma can be any single non-whitespace
122 // character):
123 // x,y,z
124 // (x,y,z)
125 // BGD 06 Nov 2002
126 // Trying to make it more versatil. The separator now is any
127 // amount of white space or commas.
128 // x y,z
129 // (x y, z )
130 // uses the auxiliary function eatSeps
131
132 friend std::istream &operator>>(std::istream &s, Coord &coord) {
133 double x = 0, y = 0, z = 0;
134 char c = 0;
135 s >> c;
136 if (c == '(') {
137 s >> x;
138 eatSeps(s);
139 s >> y;
140 eatSeps(s);
141 s >> z;
142 eatSeps(s);
143 s >> c;
144 if (c != ')')
145 s.clear(std::ios_base::badbit); // Missing closing bracket
146 } else {
147 s.putback(c);
148 s >> x;
149 eatSeps(s);
150 s >> y;
151 eatSeps(s);
152 s >> z;
153 }
154 if (s)
155 coord = Coord(x, y, z);
156 return s;
157 }
158
159 // Equality
160 inline friend bool operator==(const Coord &coord1, const Coord &coord2) {
161 return coord1.xyz == coord2.xyz;
162 }
163
164 // Non-equality
165 inline friend bool operator!=(const Coord &coord1, const Coord &coord2) {
166 return coord1.xyz != coord2.xyz;
167 }
168
169 // Greater than
170 inline friend bool operator>(const Coord &coord1, const Coord &coord2) {
171 return (coord1.xyz.array() > coord2.xyz.array()).all();
172 }
173
174 // Greater than or equal
175 inline friend bool operator>=(const Coord &coord1, const Coord &coord2) {
176 return (coord1.xyz.array() >= coord2.xyz.array()).all();
177 }
178
179 // Less than
180 inline friend bool operator<(const Coord &coord1, const Coord &coord2) {
181 return (coord1.xyz.array() < coord2.xyz.array()).all();
182 }
183
184 // Less than or equal
185 inline friend bool operator<=(const Coord &coord1, const Coord &coord2) {
186 return (coord1.xyz.array() <= coord2.xyz.array()).all();
187 }
188
189 // Addition (coord + coord)
190 inline friend Coord operator+(const Coord &coord1, const Coord &coord2) {
191 return Coord(coord1.xyz + coord2.xyz);
192 }
193
194 // Addition (coord + const)
195 inline friend Coord operator+(const Coord &coord1, double d) {
196 return Coord(coord1.xyz + coord1.xyz.Constant(d));
197 }
198
199 // Addition (const + coord)
200 inline friend Coord operator+(double d, const Coord &coord1) {
201 return Coord(coord1.xyz.Constant(d) + coord1.xyz);
202 }
203
204 // Subtraction (coord - coord)
205 inline friend Coord operator-(const Coord &coord1, const Coord &coord2) {
206 return Coord(coord1.xyz - coord2.xyz);
207 }
208
209 // Subtraction (coord - const)
210 inline friend Coord operator-(const Coord &coord1, double d) {
211 return Coord(coord1.xyz - coord1.xyz.Constant(d));
212 }
213
214 // Subtraction (const - coord)
215 inline friend Coord operator-(double d, const Coord &coord1) {
216 return Coord(coord1.xyz.Constant(d) - coord1.xyz);
217 }
218
219 // Negation
220 inline friend Coord operator-(const Coord &coord) {
221 return Coord(-coord.xyz);
222 }
223
224 // Dot product
225 // DM 7 Jan 1999 - operator* replaced by Dot(coord) member function
226 // and by Dot(coord1,coord2) non-member function
227 // inline friend Double operator*(const Coord& coord1, const Coord&
228 // coord2) {
229 // return coord1.xyz.dot(coord.xyz);
230 //}
231
232 // Scalar product (coord * const)
233 inline friend Coord operator*(const Coord &coord, const double &d) {
234 return Coord(coord.xyz * d);
235 }
236
237 // Scalar product (const * coord)
238 inline friend Coord operator*(const double &d, const Coord &coord) {
239 return Coord(d * coord.xyz);
240 }
241
242 // Scalar product (coord * coord : component-wise multiplication)
243 inline friend Coord operator*(const Coord &coord1, const Coord &coord2) {
244 return Coord(coord1.xyz.array() * coord2.xyz.array());
245 }
246
247 // Scalar division (coord / const)
248 inline friend Coord operator/(const Coord &coord, const double &d) {
249 return Coord(coord.xyz / d);
250 }
251
252 friend void to_json(json &j, const Coord &c) {
253 j = json{c.xyz(0), c.xyz(1), c.xyz(2)};
254 }
255
256 friend void from_json(const json &j, Coord &c) {
257 j.at(0).get_to(c.xyz(0));
258 j.at(1).get_to(c.xyz(1));
259 j.at(2).get_to(c.xyz(2));
260 }
261
263 // Public methods
265
266 // Mostly applicable to vectors (rather than coords)
267
268 // Returns square of magnitude of vector (or distance from origin)
269 inline double Length2() const { return xyz.squaredNorm(); }
270
271 // Returns magnitude of vector (or distance from origin)
272 inline double Length() const { return xyz.norm(); }
273
274 // Returns unit vector in same direction
275 // Member function (V2 = V1.Unit())
276 // Checks for zero length
277 inline Coord Unit() const {
278 double l = Length();
279 return (l > 0) ? *this / l : *this;
280 }
281
282 // Cross product member function (V3 = V1.Cross(V2))
283 inline Coord Cross(const Coord &v2) const { return Coord(xyz.cross(v2.xyz)); }
284
285 // Dot product member function (D = V1.Dot(V2)
286 inline double Dot(const Coord &v2) const { return xyz.dot(v2.xyz); }
287};
288
289// Useful typedefs
290
291// DM 4 Mar 1999 - to make it easier to distinguish arguments that are
292// treated as -3D vectors from those are treated as 3-D points, use this typedef
293typedef Coord Vector;
294
295typedef std::vector<Coord> CoordList; // Vector of coords
296typedef CoordList::iterator CoordListIter;
297typedef CoordList::const_iterator CoordListConstIter;
298
299// DM 19/1/99 typedefs for a map of key=Int, value=Coord
300// typedef std::map<String,Coord> StringCoordMap;
301// typedef StringCoordMap::iterator StringCoordMapIter;
302// typedef StringCoordMap::const_iterator StringCoordMapConstIter;
303// DM 08 Feb 1999 - Changed from key=string to key=int
304typedef std::map<unsigned int, Coord> UIntCoordMap;
305typedef UIntCoordMap::iterator UIntCoordMapIter;
306typedef UIntCoordMap::const_iterator UIntCoordMapConstIter;
307
309// Non-member functions (in rxdock namespace)
311
313// VECTOR FUNCTIONS
315
316// Returns square of magnitude of vector
317inline double Length2(const Vector &v1) { return v1.Length2(); }
318
319// Returns square of distance between two coords
320inline double Length2(const Coord &c1, const Coord &c2) {
321 return Length2(c2 - c1);
322}
323
324// Returns magnitude of vector
325inline double Length(const Vector &v1) { return v1.Length(); }
326
327// Returns distance between two coords
328inline double Length(const Coord &c1, const Coord &c2) {
329 return Length(c2 - c1);
330}
331
332// Returns unit vector in same direction
333// V2 = Unit(V1)
334inline Vector Unit(const Vector &v1) { return v1.Unit(); }
335
336// Cross product (V3 = Cross(V1,V2))
337inline Vector Cross(const Vector &v11, const Vector &v2) {
338 return v11.Cross(v2);
339}
340
341// Dot product (D = Dot(V1,V2))
342inline double Dot(const Vector &v1, const Vector &v2) { return v1.Dot(v2); }
343
344// Returns angle formed between 2 vectors
345inline double Angle(const Vector &v1, const Vector &v2) {
346 // Calculate the product of the lengths
347 double d1d2 = v1.Length() * v2.Length();
348
349 // Calculate the sin and cos
350 double cos_theta = v1.Dot(v2) / d1d2;
351 double sin_theta = (v1.Cross(v2)).Length() / d1d2;
352
353 // Get theta and convert to degrees
354 double theta = std::atan2(sin_theta, cos_theta);
355 return theta * 180.0 / M_PI;
356}
357
358// Returns angle formed between 3 coords coord1..coord2..coord3
359inline double Angle(const Coord &coord1, const Coord &coord2,
360 const Coord &coord3) {
361 // Determine vectors between coords and call vector version of Angle()
362 return Angle(coord1 - coord2, coord3 - coord2);
363}
364
365// DM 7 June 1999
366// Returns dihedral formed between 3 vectors
367inline double Dihedral(const Vector &v1, const Vector &v2, const Vector &v3) {
368 // Calculate the cross products
369 Vector A = v1.Cross(v2);
370 Vector B = v2.Cross(v3);
371 Vector C = v2.Cross(A);
372 // Calculate the distances
373 double rA = A.Length();
374 double rB = B.Length();
375 double rC = C.Length();
376 // Calculate the sin and cos
377 double cos_phi = A.Dot(B) / (rA * rB);
378 double sin_phi = C.Dot(B) / (rC * rB);
379 // Get phi and convert to degrees
380 double phi = -std::atan2(sin_phi, cos_phi);
381 return phi * 180.0 / M_PI;
382}
383
384// Returns dihedral formed between 4 coords c1..c2..c3..c4
385inline double Dihedral(const Coord &c1, const Coord &c2, const Coord &c3,
386 const Coord &c4) {
387 // Determine vectors between coords and call vector version of Dihedral()
388 return Dihedral(c1 - c2, c2 - c3, c3 - c4);
389}
390
392// COORDINATE FUNCTIONS
394
395// DM 28 Jul 1999 - functions for use by STL transform
396inline double ExtractXCoord(const Coord &c) { return c.xyz(0); }
397inline double ExtractYCoord(const Coord &c) { return c.xyz(1); }
398inline double ExtractZCoord(const Coord &c) { return c.xyz(2); }
399
400// Returns minimum of two coords (component-wise minimum)
401inline Coord Min(const Coord &coord1, const Coord &coord2) {
402 return Coord(coord1.xyz.array().min(coord2.xyz.array()));
403}
404
405// Returns maximum of two coords (component-wise maximum)
406inline Coord Max(const Coord &coord1, const Coord &coord2) {
407 return Coord(coord1.xyz.array().max(coord2.xyz.array()));
408}
409
410// DM 28 Jul 1999 - returns component-wise min coord for coord list (i.e.min x,
411// min y, min z)
412inline Coord Min(const CoordList &cl) {
413 std::vector<double> cx, cy, cz;
414 // Extract arrays of x,y,z components separately
415 std::transform(cl.begin(), cl.end(), std::back_inserter(cx), ExtractXCoord);
416 std::transform(cl.begin(), cl.end(), std::back_inserter(cy), ExtractYCoord);
417 std::transform(cl.begin(), cl.end(), std::back_inserter(cz), ExtractZCoord);
418 // Compose the min coord from the min of each of the components
419 return Coord(*(std::min_element(cx.begin(), cx.end())),
420 *(std::min_element(cy.begin(), cy.end())),
421 *(std::min_element(cz.begin(), cz.end())));
422}
423
424// DM 28 Jul 1999 - returns component-wise max coord for coord list (i.e. max x,
425// max y, max z)
426inline Coord Max(const CoordList &cl) {
427 std::vector<double> cx, cy, cz;
428 // Extract arrays of x,y,z components separately
429 std::transform(cl.begin(), cl.end(), std::back_inserter(cx), ExtractXCoord);
430 std::transform(cl.begin(), cl.end(), std::back_inserter(cy), ExtractYCoord);
431 std::transform(cl.begin(), cl.end(), std::back_inserter(cz), ExtractZCoord);
432 // Compose the max coord from the max of each of the components
433 return Coord(*(std::max_element(cx.begin(), cx.end())),
434 *(std::max_element(cy.begin(), cy.end())),
435 *(std::max_element(cz.begin(), cz.end())));
436}
437
438// Returns center of "mass" of coords in coord list
439inline Coord GetCenterOfAtomicMass(const CoordList &coordList) {
440 Coord com;
441 com = std::accumulate(coordList.begin(), coordList.end(), com);
442 // Check for divide by zero
443 return coordList.empty() ? com : com / static_cast<double>(coordList.size());
444}
445
446} // namespace rxdock
447
448#endif //_RBTCOORD_H_
Definition Coord.h:45