RDKit
Open-source cheminformatics and machine learning.
Loading...
Searching...
No Matches
ZMatrix.h
Go to the documentation of this file.
1//
2// Copyright (C) 2026 ETH Zurich
3// Created by: Katharina Buchthal
4//
5// @@ All Rights Reserved @@
6// This file is part of the RDKit.
7// The contents are covered by the terms of the BSD license
8// which is included in the file license.txt, found at the root
9// of the RDKit source tree.
10//
11#include <RDGeneral/export.h>
12#include <cstddef>
13#ifndef RD_Z_MATRIX_H
14#define RD_Z_MATRIX_H
15
17#include <RDGeneral/Invariant.h>
18#include <iterator>
19#include <optional>
20#include <variant>
21
22#include "ZMatrixUtils.h"
23
24namespace DistGeom {
25
26//! Class to store Z-Matrix
27/*!
28 Similar to a conventional ZMatrix with the following two main differences:
29 * torsions are not stored as fixed values but as ranges or set of distinct
30 values
31 * stores information of dependend torisions, i.e., direct neighbors that are
32 not the bond references with order (in Zmatrix) < than the current one
33*/
34
35template <typename T>
36std::ostream &operator<<(std::ostream &os, const std::optional<T> &opt) {
37 if (opt) {
38 return os << opt.value();
39 }
40 return os << "-";
41}
42
44 public:
46 std::optional<double> length;
47 std::optional<unsigned int> bondRef;
48 std::optional<double> angle;
49 std::optional<unsigned int> angleRef;
50 std::optional<TorsionCandidates> torsion;
51 std::optional<unsigned int> torsionRef;
52 };
53
55 double offset;
56 unsigned int reference;
57 };
58
59 struct ZMatrixRow {
60 unsigned int atomIdx;
62 const std::optional<TorsionDependence> &torsionDependence;
63 };
64
65 class Iterator {
66 // adapted from https://en.cppreference.com/cpp/iterator/iterator
67 public:
68 using iterator_category = std::bidirectional_iterator_tag;
69 using iterator_concept = std::bidirectional_iterator_tag;
71 using difference_type = std::ptrdiff_t;
73 using pointer = void;
74
75 Iterator() = default;
76
77 reference operator*() const { return (*d_matrix)[d_position]; }
78
80 ++d_position;
81 return *this;
82 }
84 auto result = *this;
85 ++(*this);
86 return result;
87 }
89 --d_position;
90 return *this;
91 }
93 auto result = *this;
94 --(*this);
95 return result;
96 }
97
98 bool operator==(const Iterator &other) const {
99 return d_matrix == other.d_matrix && d_position == other.d_position;
100 }
101 bool operator!=(const Iterator &other) const { return !(*this == other); }
102
103 private:
104 friend class ZMatrix;
105 explicit Iterator(const ZMatrix *matrix, std::size_t position)
106 : d_matrix(matrix), d_position(position) {}
107
108 const ZMatrix *d_matrix = nullptr;
109 std::size_t d_position = 0;
110 };
111
112 using iterator = Iterator; // note: we only traverse on constant/finished a
113 // z-matrix, thus we do not need mutable iterators
115 using reverse_iterator = std::reverse_iterator<iterator>;
116 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
117
118 ZMatrix(unsigned int nElements)
119 : d_order(),
120 d_internalCoordRefs(nElements),
121 d_torsionDependences(nElements) {
122 d_order.reserve(nElements);
123 }
124
125 void addElement(unsigned int idx, std::optional<double> length = {},
126 std::optional<unsigned int> bondRef = {},
127 std::optional<double> angle = {},
128 std::optional<unsigned int> angleRef = {},
129 std::optional<TorsionCandidates> torsion = {},
130 std::optional<unsigned int> torionRef = {},
131 std::optional<TorsionDependence> torsionDep = {}) {
132 PRECONDITION(idx < d_internalCoordRefs.size(), "Index out of range");
133 PRECONDITION(!d_internalCoordRefs[idx], "element already set");
134
135 d_order.emplace_back(idx);
136
137 d_internalCoordRefs[idx] = {length, bondRef, angle,
138 angleRef, torsion, torionRef};
139 d_torsionDependences[idx] = std::move(torsionDep);
140 }
141
143 const unsigned int atomIdx) const {
144 PRECONDITION(atomIdx < d_internalCoordRefs.size(), "Invalid atom index");
145 PRECONDITION(d_internalCoordRefs[atomIdx],
146 "Accessing an ZMatrix Element that was not set before");
147 return *d_internalCoordRefs[atomIdx];
148 }
149
150 const std::optional<TorsionDependence> &getTorsionReference(
151 const unsigned int atomIdx) const {
152 PRECONDITION(atomIdx < d_torsionDependences.size(), "Invalid atom index");
153 return d_torsionDependences[atomIdx];
154 }
155
156 void updateTorsion(const unsigned int atomIdx, TorsionRange torsion) {
157 PRECONDITION(atomIdx < d_internalCoordRefs.size(), "Invalid atom index");
158 d_internalCoordRefs[atomIdx]->torsion = {torsion}; // TODO check
159 }
160
161 void invertTorsionDependence(const unsigned int atomIdx) {
162 PRECONDITION(atomIdx < d_torsionDependences.size(), "Invalid atom index");
163 PRECONDITION(d_torsionDependences[atomIdx],
164 "Atom has no torsion dependence");
165 d_torsionDependences[atomIdx]->offset =
166 -d_torsionDependences[atomIdx]->offset;
167 }
168
169 ZMatrixRow operator[](unsigned int idx) const {
170 PRECONDITION(idx < d_order.size(), "Invalid row index");
171 auto atomIdx = d_order[idx];
172 PRECONDITION(d_internalCoordRefs[atomIdx],
173 "Accessing row in matrix that was not set before");
174 return {atomIdx, d_internalCoordRefs[atomIdx].value(),
175 d_torsionDependences[atomIdx]};
176 }
177
178 friend std::ostream &operator<<(std::ostream &os, const ZMatrix &zmat);
179
180 const_iterator cbegin() const { return const_iterator(this, 0); }
181 const_iterator cend() const { return const_iterator(this, d_order.size()); }
182
189
190 iterator begin() { return iterator(this, 0); }
191 iterator end() { return iterator(this, d_order.size()); }
193 return cbegin();
194 } // we need begin()/end() for ranges but do not want to allow iterators on a
195 // mutable z matrix
196 const_iterator end() const { return cend(); }
197
201 const_reverse_iterator rend() const { return crend(); }
202
203 private:
204 std::vector<unsigned int> d_order;
205 std::vector<std::optional<InternalCoordinateReference>> d_internalCoordRefs;
206 std::vector<std::optional<TorsionDependence>> d_torsionDependences;
207};
208
209typedef std::shared_ptr<ZMatrix> ZMatPtr;
210
211inline std::ostream &operator<<(std::ostream &os, const ZMatrix &zmat) {
212 os << "AtomIdx BondRefernece BondLength AngleReference BondAngle "
213 "TorsionReference TorsionAngle TorsionDependence Offset\n";
214
215 for (const auto &[atomIdx, internalReferences, torsionDependence] : zmat) {
216 const auto &[bl, bondRef, ba, angleRef, torsion, torsionRef] =
217 internalReferences;
218 os << atomIdx << " " << bl << " " << bondRef << " " << ba << " " << angleRef
219 << " " << torsionRef << " [";
220 if (torsion) {
221 std::visit(overloaded{[&os](const TorsionRange &r) {
222 os << r.lower << ',' << r.upper;
223 },
224 [&os](const TorsionValues &ts) {
225 for (const auto t : ts) {
226 os << dequantize(t) << "; ";
227 }
228 }},
229 *torsion);
230 } else {
231 os << "-,-";
232 }
233 os << "]";
234
235 if (torsionDependence) {
236 const auto &[offset, ref] = torsionDependence.value();
237 os << " " << ref << " " << offset;
238 } else {
239 os << " - -";
240 }
241 os << "\n";
242 }
243 return os;
244}
245
246} // namespace DistGeom
247
248#endif
RDKIT_GRAPHMOL_EXPORT std::ostream & operator<<(std::ostream &target, const RDKit::Atom &at)
allows Atom objects to be dumped to streams
#define PRECONDITION(expr, mess)
Definition Invariant.h:108
std::ptrdiff_t difference_type
Definition ZMatrix.h:71
Iterator operator--(int)
Definition ZMatrix.h:92
bool operator==(const Iterator &other) const
Definition ZMatrix.h:98
reference operator*() const
Definition ZMatrix.h:77
Iterator & operator++()
Definition ZMatrix.h:79
std::bidirectional_iterator_tag iterator_category
Definition ZMatrix.h:68
Iterator operator++(int)
Definition ZMatrix.h:83
Iterator & operator--()
Definition ZMatrix.h:88
bool operator!=(const Iterator &other) const
Definition ZMatrix.h:101
std::bidirectional_iterator_tag iterator_concept
Definition ZMatrix.h:69
reverse_iterator rend()
Definition ZMatrix.h:199
const std::optional< TorsionDependence > & getTorsionReference(const unsigned int atomIdx) const
Definition ZMatrix.h:150
const InternalCoordinateReference & getReferences(const unsigned int atomIdx) const
Definition ZMatrix.h:142
void updateTorsion(const unsigned int atomIdx, TorsionRange torsion)
Definition ZMatrix.h:156
Iterator const_iterator
Definition ZMatrix.h:114
void addElement(unsigned int idx, std::optional< double > length={}, std::optional< unsigned int > bondRef={}, std::optional< double > angle={}, std::optional< unsigned int > angleRef={}, std::optional< TorsionCandidates > torsion={}, std::optional< unsigned int > torionRef={}, std::optional< TorsionDependence > torsionDep={})
Definition ZMatrix.h:125
ZMatrixRow operator[](unsigned int idx) const
Definition ZMatrix.h:169
ZMatrix(unsigned int nElements)
Definition ZMatrix.h:118
const_iterator cbegin() const
Definition ZMatrix.h:180
reverse_iterator rbegin()
Definition ZMatrix.h:198
const_iterator begin() const
Definition ZMatrix.h:192
Iterator iterator
Definition ZMatrix.h:112
const_reverse_iterator rend() const
Definition ZMatrix.h:201
const_iterator end() const
Definition ZMatrix.h:196
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition ZMatrix.h:116
const_iterator cend() const
Definition ZMatrix.h:181
void invertTorsionDependence(const unsigned int atomIdx)
Definition ZMatrix.h:161
const_reverse_iterator rbegin() const
Definition ZMatrix.h:200
const_reverse_iterator crend() const
Definition ZMatrix.h:186
iterator end()
Definition ZMatrix.h:191
const_reverse_iterator crbegin() const
Definition ZMatrix.h:183
iterator begin()
Definition ZMatrix.h:190
std::reverse_iterator< iterator > reverse_iterator
Definition ZMatrix.h:115
#define RDKIT_DISTGEOMETRY_EXPORT
Definition export.h:171
std::shared_ptr< ZMatrix > ZMatPtr
Definition ZMatrix.h:209
std::ostream & operator<<(std::ostream &os, const std::optional< T > &opt)
Class to store Z-Matrix.
Definition ZMatrix.h:36
std::optional< unsigned int > torsionRef
Definition ZMatrix.h:51
std::optional< TorsionCandidates > torsion
Definition ZMatrix.h:50
std::optional< unsigned int > angleRef
Definition ZMatrix.h:49
std::optional< unsigned int > bondRef
Definition ZMatrix.h:47
const std::optional< TorsionDependence > & torsionDependence
Definition ZMatrix.h:62
const InternalCoordinateReference & internal
Definition ZMatrix.h:61