2
$\begingroup$

Is there a way to convert Gaussian input files (.gjf) to SMILES-codes (.smi)?

I'm aware of Open Babel (http://openbabel.org/docs/2.3.0/FileFormats/Overview.html), but this lists .gjf as "write-only" format. Is there nevertheless a way (which ideally can be integrated into a Python application) to convert .gjf to .smi?

Edit:

(as mentioned in the comments there could be two different formats in .gjf?!) Some example to clarify:

...

Winmostar

0 1
C
N 1 R2
C 2 R3 1 A3
C 3 R4 2 A4 1 D4
C 3 R5 2 A5 1 D5
C 5 R6 3 A6 2 D6
C 4 R7 3 A7 2 D7
C 6 R8 5 A8 3 D8
H 5 R9 3 A9 2 D9
N 1 R10 2 A10 3 D10
H 8 R11 6 A11 5 D11
C 10 R12 1 A12 2 D12
...
R2 1.380897451
R3 1.347679561
R4 1.373428060
R5 1.389879183
R6 1.397784043
R7 1.383546211
R8 1.399306496
R9 1.102440160
R10 1.375509032
...
A3 108.5501889
A4 108.1923111
A5 131.7222115
A6 117.5631443
A7 123.5229334
A8 121.6972504
A9 120.8892161
A10 105.3917963
...
D4 3.7044863
D5 -177.0963408
D6 -178.8876730
D7 178.9809960
D8 0.1218056
D9 0.5014806
D10 -7.3468625
...
$\endgroup$
  • 1
    $\begingroup$ Is it expressed as a Z-matrix or in cartesian coordinates? Are you interested in a single file or in batch? Cartesian coordinates can easily be converted by Avogadro (I am not sure about the Z-matrix format). Anyway, the whole gaussian input file can be used as an input on webmo demo server webmo.net/demo. Then, you can download the structure in the format you prefer. $\endgroup$ – The_Vinz Jul 24 at 22:20
  • 3
    $\begingroup$ You should be aware that a converter from structural information to a linear text format will make some assumptions. These might often be good enough, but I'd recommend using a GUI to check that the generated representation of bonds is actually what you intended. $\endgroup$ – Martin - マーチン Jul 24 at 23:26
  • 1
    $\begingroup$ Martin's warning comment is very true (sadly, only +1 is possible) since there are more than one implementations of SMILES (e.g., unified, inchified, canonical). Results may even vary if the same .mol2 file is exported/converted as Smiles by different sketchers, and the reverse input of the SMILES to generate a 2D structure might not re-create the original. $\endgroup$ – Buttonwood Jul 24 at 23:33
  • $\begingroup$ @The_Vinz, good point.... apparently Z-Matrix, correct? I will add some excerpt to the question. If I can do single file (e.g.with Python), batch is not a problem. Webmo might be good for checking but not for batch conversion. $\endgroup$ – theozh Jul 25 at 14:15
  • 1
    $\begingroup$ @theozh not really. These are z matrix inputs, they only define the coordinates in an internally consistent way. The bond connectivity would be another section entirely, but gaussview could construct that. $\endgroup$ – Martin - マーチン Jul 25 at 14:51
5
$\begingroup$

It is not aiming for code golf, but the following offers the conversion to intermediate .xyz which may be processed further (cf. vide infra):

import fnmatch
import os
import sys

gjf_register = []

for file in os.listdir("."):
    # collect all .gjf:
    if fnmatch.fnmatch(file, "*.gjf"):
        gjf_register.append(file)
    gjf_register.sort()

for entry in gjf_register:
    # recover only the atom block:
    per_file_register = []
    with open(entry, mode="r") as source:
        for line in source:
            per_file_register.append(line)
    del per_file_register[:5]  # clip the first lines

    # the other mandatory entry in the .xyz file:
    number_of_atoms = len(per_file_register) - 1

    # write an intermediate .xyz file:
    intermediate_xyz = str(entry)[:-4] + str(".xyz")
    print("File {} written.".format(intermediate_xyz))

    with open(intermediate_xyz, mode="w") as newfile:
        newfile.write(str(number_of_atoms))
        newfile.write(str("\n"))

        newfile.write(str(intermediate_xyz))
        newfile.write(str("\n"))

        for entry in per_file_register[:-1]:
            newfile.write(entry)

sys.exit(0)

The conversion into .smi may then be delegated to obabel, e.g. by

obabel *.xyz -osmi -m

if there are multiple files to consider.


Proof: The following .cif

data_EFAHAW
_cell_length_a 8.1819
_cell_length_b 10.4285
_cell_length_c 9.2965
_cell_angle_alpha 90
_cell_angle_beta 99.962
_cell_angle_gamma 90
_symmetry_space_group_name_H-M 'P 21/c'

loop_
_symmetry_equiv_pos_site_id
_symmetry_equiv_pos_as_xyz
1 x,y,z
2 -x,1/2+y,1/2-z
3 -x,-y,-z
4 x,1/2-y,1/2+z

loop_
_atom_site_label
_atom_site_type_symbol
_atom_site_fract_x
_atom_site_fract_y
_atom_site_fract_z
O3 O 0.19290 0.35524 0.46580
C9 C 0.16780 0.24532 0.42690
O2 O 0.05757 0.21719 0.30246
C7 C 0.05180 0.07991 0.27798
C1 C 0.16866 0.02605 0.40441
C6 C 0.23660 0.12584 0.49162
C3 C 0.35070 0.10279 0.61788
C5 C 0.39278 -0.02130 0.65283
C2 C 0.32245 -0.12294 0.56458
C4 C 0.20840 -0.10008 0.43826

was converted by

babel -icif EFAHAW.cif -ogjf test.gjf

into

#Put Keywords Here, check Charge and Multiplicity.

 EFAHAW

0  15
O           0.82917         3.70462         4.26502
C           0.68636         2.55832         3.90884
O          -0.01540         2.26497         2.76942
C          -0.02324         0.83334         2.54528
C           0.72957         0.27166         3.70291
C           1.14519         1.31232         4.50144
C           1.87569         1.07195         5.65752
C           2.16377        10.20637         5.97753
C           1.73027         9.14642         5.16948
C           1.00028         9.38482         4.01285

The above script converted it into .xyz

10
test.xyz
O           0.82917         3.70462         4.26502
C           0.68636         2.55832         3.90884
O          -0.01540         2.26497         2.76942
C          -0.02324         0.83334         2.54528
C           0.72957         0.27166         3.70291
C           1.14519         1.31232         4.50144
C           1.87569         1.07195         5.65752
C           2.16377        10.20637         5.97753
C           1.73027         9.14642         5.16948
C           1.00028         9.38482         4.01285

and already mentioned babel -ixyz test.xyz -osmi test.smiles offered the SMILES string

O=C1O[C][C]=C1[C].[C][C][C] test.xyz

Due to the definition of asymmetric unit and unit cell, other original input formats than .cif may work even better (i.e., may yield molecules which are not fragmented as here), e.g. «native» .mol2 or .sdf.

$\endgroup$
  • 1
    $\begingroup$ In my experience Babel often has trouble placing double and triple bonds correctly. I wrote xyz2mol which often does better. It converts an xyz file to an RDKit molecule, which can easily be converted to a SMILES string using RDKit $\endgroup$ – Jan Jensen Jul 25 at 8:04
  • $\begingroup$ Thank you @Buttonwood for the code. So if the format in my .gjf (see edited question) is Z-matrix, then Open Babel should be able to read it. I need to check... $\endgroup$ – theozh Jul 25 at 14:28
  • $\begingroup$ @JanJensen It definitively looks like an interesting alternative. Like .cif -> .xyz works virtually each time, but .cif -> .mol2 of course is not so smooth and automatic, hence your xyz2mol could help. Or for OSRA (cactus.nci.nih.gov/osra) related data retrieval (e.g. DataWarrior's supplements, openmolecules.org/datawarrior/datafiles.html). Or for similarity structure packings beyond uniformly single-bond bound atoms (e.g. the helpful calculate_rmsd.py by Jimmy Charnley et al.) which then equally could account for different bond orders, too. I anticipate weekend study ahead. $\endgroup$ – Buttonwood Jul 25 at 21:42
1
$\begingroup$

To summarize my learnings from the comments (thank you all):

It's probably not a good idea to use a Gaussian input file (.gjf) and trying to create a SMILES out of it. It apparently could happen that the bonds will not be the indended ones.

I thought it would have been easier to deal with the small input files (ca. 3-10 kB) instead of the large output files (ca. 10-60 MB).

Although, it doesn't strictly answer my original question, my solution is currently using the Gaussian output files and Open Babel.

With the following little Python script, I can convert Gaussian output files to SMILES codes via Open Babel and integrate it into my application.

### Gaussian to SMILES via OpenBabel
import subprocess
from subprocess import PIPE

obabelexe = r'C:\Users\OpenBabel-2.4.1\obabel.exe'
filename = r'C:\Users\Molecule.log'

output = subprocess.run([obabelexe, filename, "-osmi"],check=True, stdout=PIPE, stderr=PIPE)

print(output.stdout.decode("utf-8").split('\t')[0])
### end of code
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.