cathedralpkg-cantor 2026.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cathedralpkg_cantor-2026.0/PKG-INFO +338 -0
- cathedralpkg_cantor-2026.0/README.md +317 -0
- cathedralpkg_cantor-2026.0/cantor.py +2535 -0
- cathedralpkg_cantor-2026.0/cathedralpkg_cantor.egg-info/PKG-INFO +338 -0
- cathedralpkg_cantor-2026.0/cathedralpkg_cantor.egg-info/SOURCES.txt +9 -0
- cathedralpkg_cantor-2026.0/cathedralpkg_cantor.egg-info/dependency_links.txt +1 -0
- cathedralpkg_cantor-2026.0/cathedralpkg_cantor.egg-info/entry_points.txt +2 -0
- cathedralpkg_cantor-2026.0/cathedralpkg_cantor.egg-info/requires.txt +9 -0
- cathedralpkg_cantor-2026.0/cathedralpkg_cantor.egg-info/top_level.txt +1 -0
- cathedralpkg_cantor-2026.0/pyproject.toml +39 -0
- cathedralpkg_cantor-2026.0/setup.cfg +4 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cathedralpkg-cantor
|
|
3
|
+
Version: 2026.0
|
|
4
|
+
Summary: Automatic generation of search-ready Z-matrices with one proper torsion per rotatable axis
|
|
5
|
+
Author-email: David Ferro-Costas <david.ferro@usc.es>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/cathedralpkg/cantor
|
|
8
|
+
Keywords: Z-matrix,internal coordinates,torsions,rotatable bonds,conformational search,computational chemistry
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Intended Audience :: Science/Research
|
|
11
|
+
Classifier: Topic :: Scientific/Engineering :: Chemistry
|
|
12
|
+
Requires-Python: >=3.8
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
Requires-Dist: numpy
|
|
15
|
+
Requires-Dist: networkx
|
|
16
|
+
Provides-Extra: smiles
|
|
17
|
+
Requires-Dist: rdkit; extra == "smiles"
|
|
18
|
+
Provides-Extra: all
|
|
19
|
+
Requires-Dist: rdkit; extra == "all"
|
|
20
|
+
Requires-Dist: ase; extra == "all"
|
|
21
|
+
|
|
22
|
+
# CANTOR
|
|
23
|
+
|
|
24
|
+
**CA**rtesian-to-**N**on-redundant **TOR**sional coordinates
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
+---------------------------------+
|
|
28
|
+
| ____ _____ |
|
|
29
|
+
| / ___|__ _ _ _|_ _|__ _ __ |
|
|
30
|
+
| | | / _` | '_ \| |/ _ \| '__| |
|
|
31
|
+
| | |__| (_| | | | | | (_) | | |
|
|
32
|
+
| \____\__,_|_| |_|_|\___/|_| |
|
|
33
|
+
| |
|
|
34
|
+
+---------------------------------+
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
CANTOR is a Python program for the **automatic generation of search-ready
|
|
38
|
+
Z-matrices** from Cartesian coordinates or SMILES strings.
|
|
39
|
+
|
|
40
|
+
Torsion-driven conformational searches explore molecular flexibility by
|
|
41
|
+
assigning values to a predefined set of dihedral coordinates. This requires
|
|
42
|
+
every internal rotation to be described exactly once, by a coordinate that
|
|
43
|
+
moves the corresponding fragment as a whole. A conventional Z-matrix
|
|
44
|
+
guarantees neither condition: in the Z-matrix of ethanol written by most
|
|
45
|
+
programs, the three methyl hydrogens are placed by three H–C–C–O dihedrals
|
|
46
|
+
on the same C–C axis, and changing one of them moves a single hydrogen
|
|
47
|
+
instead of rotating the methyl group.
|
|
48
|
+
|
|
49
|
+
A Z-matrix written by CANTOR is **search-ready**:
|
|
50
|
+
|
|
51
|
+
- it is **valid**: every row is well defined, with no linear bond angle and
|
|
52
|
+
no collinear reference atoms (dummy atoms are added where needed);
|
|
53
|
+
- it is **non-redundant**: it contains exactly one proper torsion for each
|
|
54
|
+
rotatable axis;
|
|
55
|
+
- each of these torsions drives a **rigid rotation** of one side of its axis
|
|
56
|
+
with respect to the other.
|
|
57
|
+
|
|
58
|
+
The three properties are checked explicitly, and the same checks can be
|
|
59
|
+
applied to Z-matrices written by other programs. The torsions to be sampled
|
|
60
|
+
are labeled in the Z-matrix, which can be passed directly to the
|
|
61
|
+
conformational search of TorsiFlex, also part of the **Cathedral** package.
|
|
62
|
+
|
|
63
|
+
## How it works
|
|
64
|
+
|
|
65
|
+
**Molecular graph.** Two atoms are bonded when their distance, relative to
|
|
66
|
+
the sum of their covalent radii, falls below `RHO_CONN`; a bond is regarded as
|
|
67
|
+
multiple when this ratio falls below `RHO_MBOND`. Fragments that are not
|
|
68
|
+
bonded to each other (complexes, salts) are joined by artificial edges.
|
|
69
|
+
|
|
70
|
+
**Rods and rotatable axes.** Bonds that meet at a (near-)linear angle form a
|
|
71
|
+
*rod*, a straight chain of bonds such as the C–C≡C–C unit of 2-butyne; most
|
|
72
|
+
rods are a single bond. A rod is a *rotatable axis* when (i) it contains at
|
|
73
|
+
least one single bond, (ii) none of its bonds lies on a ring, and (iii) both
|
|
74
|
+
of its terminal atoms have a neighbor outside the rod. Hydrogen atoms count
|
|
75
|
+
as neighbors, so the rotations of methyl and hydroxyl groups are included:
|
|
76
|
+
ethanol has two rotatable axes, C–C and C–O.
|
|
77
|
+
|
|
78
|
+
**Construction.** The molecular graph is decomposed into ring systems,
|
|
79
|
+
chains, and terminal hydrogen atoms, and the Z-matrix is built along this
|
|
80
|
+
decomposition. Only the first atom placed on each side of an axis is given a
|
|
81
|
+
torsion about it; the other atoms on that side are placed from it (the
|
|
82
|
+
*sibling rule*), so that changing that torsion rotates the whole side.
|
|
83
|
+
Dummy atoms are inserted at linear fragments, where a bond angle would be
|
|
84
|
+
180° or a dihedral would be undefined.
|
|
85
|
+
|
|
86
|
+
**Classification.** Every dihedral is classified, and its class is the
|
|
87
|
+
prefix of its variable name:
|
|
88
|
+
|
|
89
|
+
| Prefix | Class |
|
|
90
|
+
|---|---|
|
|
91
|
+
| `ptor` | proper torsion of a rotatable axis (the coordinates to be sampled) |
|
|
92
|
+
| `rtor` | proper torsion of an axis with a cyclic bond |
|
|
93
|
+
| `etor` | proper torsion excluded because its axis is a multiple bond, an all-multiple rod (allene), or an artificial edge between fragments |
|
|
94
|
+
| `itor` | improper torsion, including every dihedral that involves a dummy atom |
|
|
95
|
+
|
|
96
|
+
## Requirements
|
|
97
|
+
|
|
98
|
+
- Python ≥ 3.8
|
|
99
|
+
- `numpy`
|
|
100
|
+
- `networkx`
|
|
101
|
+
|
|
102
|
+
Optional:
|
|
103
|
+
|
|
104
|
+
- `rdkit`, required for SMILES input;
|
|
105
|
+
- `ase` or `rdkit`, which provide the covalent radii (a built-in table with
|
|
106
|
+
the same values, from Cordero *et al.*, is used otherwise).
|
|
107
|
+
|
|
108
|
+
## Installation
|
|
109
|
+
|
|
110
|
+
### From PyPI
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
pip install cathedralpkg-cantor
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
To include the optional dependencies (RDKit for SMILES input):
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
pip install "cathedralpkg-cantor[smiles]"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### From GitHub
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
pip install git+https://github.com/cathedralpkg/cantor.git
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### In a conda environment
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
conda create -n cantor python=3.11
|
|
132
|
+
conda activate cantor
|
|
133
|
+
pip install "cathedralpkg-cantor[smiles]"
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Any of the above installs the `cantor` command in your `PATH`. The script can
|
|
137
|
+
also be executed directly with Python (`python3 cantor.py ...`) if the
|
|
138
|
+
required dependencies are available.
|
|
139
|
+
|
|
140
|
+
## Usage
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
cantor STRUCTURE ZMATFILE # generate a Z-matrix
|
|
144
|
+
cantor -a | --audit EXTZMAT [ZMATFILE] # check a Z-matrix written by another program
|
|
145
|
+
cantor -p | --parameters # write the parameter file
|
|
146
|
+
cantor -h | --help # show help
|
|
147
|
+
cantor -v | --version # show program version
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
`STRUCTURE` is an `xyz` file (in Ångström) or a SMILES string:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
cantor butanol.xyz butanol.zmat
|
|
154
|
+
cantor "CCCCO" butanol.zmat
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
For SMILES input, the Cartesian geometry is generated with RDKit (ETKDGv3
|
|
158
|
+
embedding with the seed of the parameter file, followed by MMFF or, if MMFF
|
|
159
|
+
parameters are missing, UFF optimization) and written next to the Z-matrix
|
|
160
|
+
(`butanol.xyz`). An existing file is never overwritten; a warning is printed
|
|
161
|
+
instead.
|
|
162
|
+
|
|
163
|
+
## Parameter file
|
|
164
|
+
|
|
165
|
+
The parameters are read from the file `.cathedralpkg.cantor` in the working
|
|
166
|
+
directory, if it exists; otherwise the default values are used. A template is
|
|
167
|
+
written with
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
cantor -p
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
```text
|
|
174
|
+
# two atoms are considered bonded if d_AB/(r_A+r_B) falls below this value
|
|
175
|
+
RHO_CONN 1.30
|
|
176
|
+
|
|
177
|
+
# a bond is regarded as multiple when d_AB/(r_A+r_B) falls below this value
|
|
178
|
+
RHO_MBOND 0.93
|
|
179
|
+
|
|
180
|
+
# a reference triad closer than this (in degrees) to 0 or 180 needs a dummy
|
|
181
|
+
EPS_LIN 5.00
|
|
182
|
+
|
|
183
|
+
# seed used by RDKit so that a SMILES always yields the same geometry
|
|
184
|
+
SEED 2025
|
|
185
|
+
|
|
186
|
+
# covalent radius (Angstrom) to use for a given element, overriding the
|
|
187
|
+
# tabulated one; useful when the default gives a poor connectivity
|
|
188
|
+
#RADIUS_Fe 1.32
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
| Keyword | Default | Meaning |
|
|
192
|
+
|---|---:|---|
|
|
193
|
+
| `RHO_CONN` | `1.30` | connectivity threshold, d<sub>AB</sub>/(r<sub>A</sub>+r<sub>B</sub>) |
|
|
194
|
+
| `RHO_MBOND` | `0.93` | multiple-bond threshold; must be smaller than `RHO_CONN` |
|
|
195
|
+
| `EPS_LIN` | `5.00` | linearity tolerance, in degrees, used to define rods and to detect linear angles and collinear references |
|
|
196
|
+
| `SEED` | `2025` | seed for the RDKit embedding of SMILES strings |
|
|
197
|
+
| `RADIUS_X` | tabulated | covalent radius of element X, in Ångström; any number of these lines may be given |
|
|
198
|
+
|
|
199
|
+
## Output
|
|
200
|
+
|
|
201
|
+
The standard output reports the parameters, the Cartesian coordinates, the
|
|
202
|
+
molecular graph (artificial bonds, rings, bonds joining rings, and rods of
|
|
203
|
+
more than one bond), the number of torsions of each class, the outcome of the
|
|
204
|
+
three checks, the list of `ptor` coordinates with their axes, the dummy
|
|
205
|
+
atoms, the RMSD of the geometry rebuilt from the Z-matrix, and the
|
|
206
|
+
correspondence between the rows of the Z-matrix and the input atoms, since
|
|
207
|
+
the construction renumbers the atoms. All atoms are numbered from 1. For
|
|
208
|
+
ethanol:
|
|
209
|
+
|
|
210
|
+
```text
|
|
211
|
+
(atoms numbered by their row in the Z-matrix)
|
|
212
|
+
torsions: ptor=2 rtor=0 etor=0 itor=4
|
|
213
|
+
valid Z-matrix: yes
|
|
214
|
+
non-redundant: yes (2 proper torsions for 2 rotatable axes)
|
|
215
|
+
rigid rotations: yes (2 of 2 proper torsions)
|
|
216
|
+
ptor04 4-3-2-1 axis 3-2
|
|
217
|
+
ptor05 5-1-2-3 axis 2-1
|
|
218
|
+
rebuilt geometry, RMSD to input: 6.52e-16 A
|
|
219
|
+
|
|
220
|
+
atom order (Z-matrix row <- input atom):
|
|
221
|
+
1 <- 3 2 <- 2 3 <- 1 4 <- 4 5 <- 9 6 <- 5
|
|
222
|
+
7 <- 6 8 <- 7 9 <- 8
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
The Z-matrix file has the usual two blocks, the rows with named variables and
|
|
226
|
+
the values of the variables:
|
|
227
|
+
|
|
228
|
+
```text
|
|
229
|
+
O
|
|
230
|
+
C 1 dist02
|
|
231
|
+
C 2 dist03 1 angl03
|
|
232
|
+
H 3 dist04 2 angl04 1 ptor04
|
|
233
|
+
H 1 dist05 2 angl05 3 ptor05
|
|
234
|
+
H 3 dist06 2 angl06 4 itor06
|
|
235
|
+
H 3 dist07 2 angl07 6 itor07
|
|
236
|
+
H 2 dist08 1 angl08 3 itor08
|
|
237
|
+
H 2 dist09 1 angl09 8 itor09
|
|
238
|
+
|
|
239
|
+
dist02 1.420178
|
|
240
|
+
dist03 1.514604
|
|
241
|
+
angl03 109.979154
|
|
242
|
+
dist04 1.094947
|
|
243
|
+
angl04 110.600997
|
|
244
|
+
ptor04 -58.180637
|
|
245
|
+
...
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
The methyl group is rotated by `ptor04` alone: its other two hydrogens are
|
|
249
|
+
placed from the first one (`itor06`, `itor07`) and follow it.
|
|
250
|
+
|
|
251
|
+
## Auditing Z-matrices from other programs
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
cantor --audit molden.zmat [renamed.zmat]
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
The Cartesian geometry is rebuilt from the Z-matrix, the molecular graph is
|
|
258
|
+
built from that geometry, and the rows are classified and checked as they
|
|
259
|
+
are. If a second file is given, the Z-matrix is rewritten there with the
|
|
260
|
+
variable names of CANTOR. Two layouts are read:
|
|
261
|
+
|
|
262
|
+
- the Gaussian layout, written by Gaussian, GaussView, Molden, Open Babel,
|
|
263
|
+
Chemcraft, and most other programs: each reference is followed by its
|
|
264
|
+
value, values may be given inline or as variables defined after the
|
|
265
|
+
matrix, and references may be row numbers or atom labels;
|
|
266
|
+
- the ORCA layout (the internal-coordinate block of its output): the three
|
|
267
|
+
references come first, with 0 for none, and then the three values.
|
|
268
|
+
|
|
269
|
+
Dummy atoms may be labeled `X`, `XX`, `Du`, `Q`, or `Bq`.
|
|
270
|
+
|
|
271
|
+
## Exit status
|
|
272
|
+
|
|
273
|
+
| Status | Meaning |
|
|
274
|
+
|---:|---|
|
|
275
|
+
| 0 | success |
|
|
276
|
+
| 1 | wrong usage |
|
|
277
|
+
| 2 | unreadable input |
|
|
278
|
+
| 3 | the Z-matrix is not search-ready (it is still written, so that it can be inspected, unless the construction itself failed) |
|
|
279
|
+
|
|
280
|
+
## Python interface
|
|
281
|
+
|
|
282
|
+
Every object of the construction is also available from Python:
|
|
283
|
+
|
|
284
|
+
```python
|
|
285
|
+
import cantor
|
|
286
|
+
|
|
287
|
+
xcc, symbols = cantor.read_xyz("butanol.xyz")
|
|
288
|
+
mol = cantor.MolGraph(xcc, symbols)
|
|
289
|
+
mol.calculate_connectivity()
|
|
290
|
+
print(mol.rotatable_axes()) # rods with their bonds, atoms and ends
|
|
291
|
+
|
|
292
|
+
zmat = cantor.ZMatrix(mol)
|
|
293
|
+
zmat.build()
|
|
294
|
+
for row in zmat.classify(): # one dict per row (atom indices from 0)
|
|
295
|
+
print(row["row"], row["refs"], row["kind"], row["central"])
|
|
296
|
+
print(zmat.checks()) # (valid, nonredundant, rigid)
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Cu## Current scope
|
|
300
|
+
|
|
301
|
+
Most limitations arise from inferring chemical information from the
|
|
302
|
+
geometry:
|
|
303
|
+
|
|
304
|
+
- the molecular graph depends on `RHO_CONN` and on the covalent radii, and
|
|
305
|
+
distance criteria may fail for transition-metal complexes, unusual
|
|
306
|
+
coordination environments, weakly bound complexes, or strongly distorted
|
|
307
|
+
structures such as transition states; the connectivity, rings, and rods
|
|
308
|
+
printed in the output should be checked in such cases, and the radius of
|
|
309
|
+
individual elements can be changed in the parameter file (`RADIUS_X`);
|
|
310
|
+
- `EPS_LIN` determines the rods: a C≡C fragment bent beyond the tolerance is
|
|
311
|
+
split into shorter rods;
|
|
312
|
+
- the multiple-bond criterion is empirical and limited to carbon, nitrogen,
|
|
313
|
+
and oxygen.
|
|
314
|
+
|
|
315
|
+
CANTOR builds and checks Z-matrices; it does not search conformations. It
|
|
316
|
+
exposes internal rotations only: ring puckering is outside its scope, and
|
|
317
|
+
different ring conformers must be supplied as separate structures.
|
|
318
|
+
|
|
319
|
+
tation
|
|
320
|
+
|
|
321
|
+
If you use CANTOR in your work, please cite:
|
|
322
|
+
|
|
323
|
+
> A. Lema-Saavedra, M. Castiñeira Reis, D. Ferro-Costas, *Cantor: a program
|
|
324
|
+
> for the automatic generation of search-ready Z-matrices with one torsion per
|
|
325
|
+
> rotatable axis*, submitted to *Journal of Chemical Information and
|
|
326
|
+
> Modeling* (2026).
|
|
327
|
+
|
|
328
|
+
Please replace the provisional citation above with the final bibliographic
|
|
329
|
+
information once the article is published.
|
|
330
|
+
|
|
331
|
+
## License
|
|
332
|
+
|
|
333
|
+
Distributed under the MIT License. See `LICENSE` for details.
|
|
334
|
+
|
|
335
|
+
## Author
|
|
336
|
+
|
|
337
|
+
David Ferro-Costas — Universidade de Santiago de Compostela
|
|
338
|
+
ORCID: 0000-0002-8365-4047
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
# CANTOR
|
|
2
|
+
|
|
3
|
+
**CA**rtesian-to-**N**on-redundant **TOR**sional coordinates
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
+---------------------------------+
|
|
7
|
+
| ____ _____ |
|
|
8
|
+
| / ___|__ _ _ _|_ _|__ _ __ |
|
|
9
|
+
| | | / _` | '_ \| |/ _ \| '__| |
|
|
10
|
+
| | |__| (_| | | | | | (_) | | |
|
|
11
|
+
| \____\__,_|_| |_|_|\___/|_| |
|
|
12
|
+
| |
|
|
13
|
+
+---------------------------------+
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
CANTOR is a Python program for the **automatic generation of search-ready
|
|
17
|
+
Z-matrices** from Cartesian coordinates or SMILES strings.
|
|
18
|
+
|
|
19
|
+
Torsion-driven conformational searches explore molecular flexibility by
|
|
20
|
+
assigning values to a predefined set of dihedral coordinates. This requires
|
|
21
|
+
every internal rotation to be described exactly once, by a coordinate that
|
|
22
|
+
moves the corresponding fragment as a whole. A conventional Z-matrix
|
|
23
|
+
guarantees neither condition: in the Z-matrix of ethanol written by most
|
|
24
|
+
programs, the three methyl hydrogens are placed by three H–C–C–O dihedrals
|
|
25
|
+
on the same C–C axis, and changing one of them moves a single hydrogen
|
|
26
|
+
instead of rotating the methyl group.
|
|
27
|
+
|
|
28
|
+
A Z-matrix written by CANTOR is **search-ready**:
|
|
29
|
+
|
|
30
|
+
- it is **valid**: every row is well defined, with no linear bond angle and
|
|
31
|
+
no collinear reference atoms (dummy atoms are added where needed);
|
|
32
|
+
- it is **non-redundant**: it contains exactly one proper torsion for each
|
|
33
|
+
rotatable axis;
|
|
34
|
+
- each of these torsions drives a **rigid rotation** of one side of its axis
|
|
35
|
+
with respect to the other.
|
|
36
|
+
|
|
37
|
+
The three properties are checked explicitly, and the same checks can be
|
|
38
|
+
applied to Z-matrices written by other programs. The torsions to be sampled
|
|
39
|
+
are labeled in the Z-matrix, which can be passed directly to the
|
|
40
|
+
conformational search of TorsiFlex, also part of the **Cathedral** package.
|
|
41
|
+
|
|
42
|
+
## How it works
|
|
43
|
+
|
|
44
|
+
**Molecular graph.** Two atoms are bonded when their distance, relative to
|
|
45
|
+
the sum of their covalent radii, falls below `RHO_CONN`; a bond is regarded as
|
|
46
|
+
multiple when this ratio falls below `RHO_MBOND`. Fragments that are not
|
|
47
|
+
bonded to each other (complexes, salts) are joined by artificial edges.
|
|
48
|
+
|
|
49
|
+
**Rods and rotatable axes.** Bonds that meet at a (near-)linear angle form a
|
|
50
|
+
*rod*, a straight chain of bonds such as the C–C≡C–C unit of 2-butyne; most
|
|
51
|
+
rods are a single bond. A rod is a *rotatable axis* when (i) it contains at
|
|
52
|
+
least one single bond, (ii) none of its bonds lies on a ring, and (iii) both
|
|
53
|
+
of its terminal atoms have a neighbor outside the rod. Hydrogen atoms count
|
|
54
|
+
as neighbors, so the rotations of methyl and hydroxyl groups are included:
|
|
55
|
+
ethanol has two rotatable axes, C–C and C–O.
|
|
56
|
+
|
|
57
|
+
**Construction.** The molecular graph is decomposed into ring systems,
|
|
58
|
+
chains, and terminal hydrogen atoms, and the Z-matrix is built along this
|
|
59
|
+
decomposition. Only the first atom placed on each side of an axis is given a
|
|
60
|
+
torsion about it; the other atoms on that side are placed from it (the
|
|
61
|
+
*sibling rule*), so that changing that torsion rotates the whole side.
|
|
62
|
+
Dummy atoms are inserted at linear fragments, where a bond angle would be
|
|
63
|
+
180° or a dihedral would be undefined.
|
|
64
|
+
|
|
65
|
+
**Classification.** Every dihedral is classified, and its class is the
|
|
66
|
+
prefix of its variable name:
|
|
67
|
+
|
|
68
|
+
| Prefix | Class |
|
|
69
|
+
|---|---|
|
|
70
|
+
| `ptor` | proper torsion of a rotatable axis (the coordinates to be sampled) |
|
|
71
|
+
| `rtor` | proper torsion of an axis with a cyclic bond |
|
|
72
|
+
| `etor` | proper torsion excluded because its axis is a multiple bond, an all-multiple rod (allene), or an artificial edge between fragments |
|
|
73
|
+
| `itor` | improper torsion, including every dihedral that involves a dummy atom |
|
|
74
|
+
|
|
75
|
+
## Requirements
|
|
76
|
+
|
|
77
|
+
- Python ≥ 3.8
|
|
78
|
+
- `numpy`
|
|
79
|
+
- `networkx`
|
|
80
|
+
|
|
81
|
+
Optional:
|
|
82
|
+
|
|
83
|
+
- `rdkit`, required for SMILES input;
|
|
84
|
+
- `ase` or `rdkit`, which provide the covalent radii (a built-in table with
|
|
85
|
+
the same values, from Cordero *et al.*, is used otherwise).
|
|
86
|
+
|
|
87
|
+
## Installation
|
|
88
|
+
|
|
89
|
+
### From PyPI
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pip install cathedralpkg-cantor
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
To include the optional dependencies (RDKit for SMILES input):
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
pip install "cathedralpkg-cantor[smiles]"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### From GitHub
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
pip install git+https://github.com/cathedralpkg/cantor.git
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### In a conda environment
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
conda create -n cantor python=3.11
|
|
111
|
+
conda activate cantor
|
|
112
|
+
pip install "cathedralpkg-cantor[smiles]"
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Any of the above installs the `cantor` command in your `PATH`. The script can
|
|
116
|
+
also be executed directly with Python (`python3 cantor.py ...`) if the
|
|
117
|
+
required dependencies are available.
|
|
118
|
+
|
|
119
|
+
## Usage
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
cantor STRUCTURE ZMATFILE # generate a Z-matrix
|
|
123
|
+
cantor -a | --audit EXTZMAT [ZMATFILE] # check a Z-matrix written by another program
|
|
124
|
+
cantor -p | --parameters # write the parameter file
|
|
125
|
+
cantor -h | --help # show help
|
|
126
|
+
cantor -v | --version # show program version
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
`STRUCTURE` is an `xyz` file (in Ångström) or a SMILES string:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
cantor butanol.xyz butanol.zmat
|
|
133
|
+
cantor "CCCCO" butanol.zmat
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
For SMILES input, the Cartesian geometry is generated with RDKit (ETKDGv3
|
|
137
|
+
embedding with the seed of the parameter file, followed by MMFF or, if MMFF
|
|
138
|
+
parameters are missing, UFF optimization) and written next to the Z-matrix
|
|
139
|
+
(`butanol.xyz`). An existing file is never overwritten; a warning is printed
|
|
140
|
+
instead.
|
|
141
|
+
|
|
142
|
+
## Parameter file
|
|
143
|
+
|
|
144
|
+
The parameters are read from the file `.cathedralpkg.cantor` in the working
|
|
145
|
+
directory, if it exists; otherwise the default values are used. A template is
|
|
146
|
+
written with
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
cantor -p
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
```text
|
|
153
|
+
# two atoms are considered bonded if d_AB/(r_A+r_B) falls below this value
|
|
154
|
+
RHO_CONN 1.30
|
|
155
|
+
|
|
156
|
+
# a bond is regarded as multiple when d_AB/(r_A+r_B) falls below this value
|
|
157
|
+
RHO_MBOND 0.93
|
|
158
|
+
|
|
159
|
+
# a reference triad closer than this (in degrees) to 0 or 180 needs a dummy
|
|
160
|
+
EPS_LIN 5.00
|
|
161
|
+
|
|
162
|
+
# seed used by RDKit so that a SMILES always yields the same geometry
|
|
163
|
+
SEED 2025
|
|
164
|
+
|
|
165
|
+
# covalent radius (Angstrom) to use for a given element, overriding the
|
|
166
|
+
# tabulated one; useful when the default gives a poor connectivity
|
|
167
|
+
#RADIUS_Fe 1.32
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
| Keyword | Default | Meaning |
|
|
171
|
+
|---|---:|---|
|
|
172
|
+
| `RHO_CONN` | `1.30` | connectivity threshold, d<sub>AB</sub>/(r<sub>A</sub>+r<sub>B</sub>) |
|
|
173
|
+
| `RHO_MBOND` | `0.93` | multiple-bond threshold; must be smaller than `RHO_CONN` |
|
|
174
|
+
| `EPS_LIN` | `5.00` | linearity tolerance, in degrees, used to define rods and to detect linear angles and collinear references |
|
|
175
|
+
| `SEED` | `2025` | seed for the RDKit embedding of SMILES strings |
|
|
176
|
+
| `RADIUS_X` | tabulated | covalent radius of element X, in Ångström; any number of these lines may be given |
|
|
177
|
+
|
|
178
|
+
## Output
|
|
179
|
+
|
|
180
|
+
The standard output reports the parameters, the Cartesian coordinates, the
|
|
181
|
+
molecular graph (artificial bonds, rings, bonds joining rings, and rods of
|
|
182
|
+
more than one bond), the number of torsions of each class, the outcome of the
|
|
183
|
+
three checks, the list of `ptor` coordinates with their axes, the dummy
|
|
184
|
+
atoms, the RMSD of the geometry rebuilt from the Z-matrix, and the
|
|
185
|
+
correspondence between the rows of the Z-matrix and the input atoms, since
|
|
186
|
+
the construction renumbers the atoms. All atoms are numbered from 1. For
|
|
187
|
+
ethanol:
|
|
188
|
+
|
|
189
|
+
```text
|
|
190
|
+
(atoms numbered by their row in the Z-matrix)
|
|
191
|
+
torsions: ptor=2 rtor=0 etor=0 itor=4
|
|
192
|
+
valid Z-matrix: yes
|
|
193
|
+
non-redundant: yes (2 proper torsions for 2 rotatable axes)
|
|
194
|
+
rigid rotations: yes (2 of 2 proper torsions)
|
|
195
|
+
ptor04 4-3-2-1 axis 3-2
|
|
196
|
+
ptor05 5-1-2-3 axis 2-1
|
|
197
|
+
rebuilt geometry, RMSD to input: 6.52e-16 A
|
|
198
|
+
|
|
199
|
+
atom order (Z-matrix row <- input atom):
|
|
200
|
+
1 <- 3 2 <- 2 3 <- 1 4 <- 4 5 <- 9 6 <- 5
|
|
201
|
+
7 <- 6 8 <- 7 9 <- 8
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
The Z-matrix file has the usual two blocks, the rows with named variables and
|
|
205
|
+
the values of the variables:
|
|
206
|
+
|
|
207
|
+
```text
|
|
208
|
+
O
|
|
209
|
+
C 1 dist02
|
|
210
|
+
C 2 dist03 1 angl03
|
|
211
|
+
H 3 dist04 2 angl04 1 ptor04
|
|
212
|
+
H 1 dist05 2 angl05 3 ptor05
|
|
213
|
+
H 3 dist06 2 angl06 4 itor06
|
|
214
|
+
H 3 dist07 2 angl07 6 itor07
|
|
215
|
+
H 2 dist08 1 angl08 3 itor08
|
|
216
|
+
H 2 dist09 1 angl09 8 itor09
|
|
217
|
+
|
|
218
|
+
dist02 1.420178
|
|
219
|
+
dist03 1.514604
|
|
220
|
+
angl03 109.979154
|
|
221
|
+
dist04 1.094947
|
|
222
|
+
angl04 110.600997
|
|
223
|
+
ptor04 -58.180637
|
|
224
|
+
...
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
The methyl group is rotated by `ptor04` alone: its other two hydrogens are
|
|
228
|
+
placed from the first one (`itor06`, `itor07`) and follow it.
|
|
229
|
+
|
|
230
|
+
## Auditing Z-matrices from other programs
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
cantor --audit molden.zmat [renamed.zmat]
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
The Cartesian geometry is rebuilt from the Z-matrix, the molecular graph is
|
|
237
|
+
built from that geometry, and the rows are classified and checked as they
|
|
238
|
+
are. If a second file is given, the Z-matrix is rewritten there with the
|
|
239
|
+
variable names of CANTOR. Two layouts are read:
|
|
240
|
+
|
|
241
|
+
- the Gaussian layout, written by Gaussian, GaussView, Molden, Open Babel,
|
|
242
|
+
Chemcraft, and most other programs: each reference is followed by its
|
|
243
|
+
value, values may be given inline or as variables defined after the
|
|
244
|
+
matrix, and references may be row numbers or atom labels;
|
|
245
|
+
- the ORCA layout (the internal-coordinate block of its output): the three
|
|
246
|
+
references come first, with 0 for none, and then the three values.
|
|
247
|
+
|
|
248
|
+
Dummy atoms may be labeled `X`, `XX`, `Du`, `Q`, or `Bq`.
|
|
249
|
+
|
|
250
|
+
## Exit status
|
|
251
|
+
|
|
252
|
+
| Status | Meaning |
|
|
253
|
+
|---:|---|
|
|
254
|
+
| 0 | success |
|
|
255
|
+
| 1 | wrong usage |
|
|
256
|
+
| 2 | unreadable input |
|
|
257
|
+
| 3 | the Z-matrix is not search-ready (it is still written, so that it can be inspected, unless the construction itself failed) |
|
|
258
|
+
|
|
259
|
+
## Python interface
|
|
260
|
+
|
|
261
|
+
Every object of the construction is also available from Python:
|
|
262
|
+
|
|
263
|
+
```python
|
|
264
|
+
import cantor
|
|
265
|
+
|
|
266
|
+
xcc, symbols = cantor.read_xyz("butanol.xyz")
|
|
267
|
+
mol = cantor.MolGraph(xcc, symbols)
|
|
268
|
+
mol.calculate_connectivity()
|
|
269
|
+
print(mol.rotatable_axes()) # rods with their bonds, atoms and ends
|
|
270
|
+
|
|
271
|
+
zmat = cantor.ZMatrix(mol)
|
|
272
|
+
zmat.build()
|
|
273
|
+
for row in zmat.classify(): # one dict per row (atom indices from 0)
|
|
274
|
+
print(row["row"], row["refs"], row["kind"], row["central"])
|
|
275
|
+
print(zmat.checks()) # (valid, nonredundant, rigid)
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## Cu## Current scope
|
|
279
|
+
|
|
280
|
+
Most limitations arise from inferring chemical information from the
|
|
281
|
+
geometry:
|
|
282
|
+
|
|
283
|
+
- the molecular graph depends on `RHO_CONN` and on the covalent radii, and
|
|
284
|
+
distance criteria may fail for transition-metal complexes, unusual
|
|
285
|
+
coordination environments, weakly bound complexes, or strongly distorted
|
|
286
|
+
structures such as transition states; the connectivity, rings, and rods
|
|
287
|
+
printed in the output should be checked in such cases, and the radius of
|
|
288
|
+
individual elements can be changed in the parameter file (`RADIUS_X`);
|
|
289
|
+
- `EPS_LIN` determines the rods: a C≡C fragment bent beyond the tolerance is
|
|
290
|
+
split into shorter rods;
|
|
291
|
+
- the multiple-bond criterion is empirical and limited to carbon, nitrogen,
|
|
292
|
+
and oxygen.
|
|
293
|
+
|
|
294
|
+
CANTOR builds and checks Z-matrices; it does not search conformations. It
|
|
295
|
+
exposes internal rotations only: ring puckering is outside its scope, and
|
|
296
|
+
different ring conformers must be supplied as separate structures.
|
|
297
|
+
|
|
298
|
+
tation
|
|
299
|
+
|
|
300
|
+
If you use CANTOR in your work, please cite:
|
|
301
|
+
|
|
302
|
+
> A. Lema-Saavedra, M. Castiñeira Reis, D. Ferro-Costas, *Cantor: a program
|
|
303
|
+
> for the automatic generation of search-ready Z-matrices with one torsion per
|
|
304
|
+
> rotatable axis*, submitted to *Journal of Chemical Information and
|
|
305
|
+
> Modeling* (2026).
|
|
306
|
+
|
|
307
|
+
Please replace the provisional citation above with the final bibliographic
|
|
308
|
+
information once the article is published.
|
|
309
|
+
|
|
310
|
+
## License
|
|
311
|
+
|
|
312
|
+
Distributed under the MIT License. See `LICENSE` for details.
|
|
313
|
+
|
|
314
|
+
## Author
|
|
315
|
+
|
|
316
|
+
David Ferro-Costas — Universidade de Santiago de Compostela
|
|
317
|
+
ORCID: 0000-0002-8365-4047
|