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.
@@ -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