Repository: duartegroup/autodE
Pull request #332 (2024-04-10 17:34:23)

Fix error in "atoms_to_xyz_file()" in "input_output.py"
Added explicit space to print xyz coordinates to account for occasional cases where there is no space printed between two numbers, for example, `H    13.56100 -35.93700-100.99000`, and thus the printed xyz file becomes invalid.

```
########################################################################

[ERROR] Program stopped due to fatal error
-2- reading geometry input 'test2_sp_xtb.xyz' failed
-1- Error: Could not parse coordinates from xyz file
  --> test2_sp_xtb.xyz:24:15-33
   |
24 | H    13.56100 -35.93700-100.99000
   |               ^^^^^^^^^^^^^^^^^^^ expected real value
   |
########################################################################
```

<!--
Please replace _#ISSUE_ with just e.g. #12 if this PR resolves issue 12.
## Resolves _#ISSUE_
-->


***

## Checklist

* [x] The changes include an associated explanation of how/why
* [x] Test pass
* [x] Documentation has been updated
* [x] Changelog has been updated


t-young31: Looks like a great fix – thanks @SijieFu 
Would you mind (a) updating the branch, (b) adding yourself to the [contributors list](https://github.com/duartegroup/autodE/blob/c9c2c2b552cf68301c38c723873a8425b58c12c2/README.md?plain=1#L88), (c) updating the [changelog](https://github.com/duartegroup/autodE/blob/c9c2c2b552cf68301c38c723873a8425b58c12c2/doc/changelog.rst?plain=1#L14) and if you have time (d) writing a test for this change 
SijieFu: I think I was able to check all of the items on the list. I imported an extra `sys` module in the test script to get information about float bounds to account for extreme cases, since the coordinates are stored as floats internally. I hope this is okay. Thanks!

Patch:
diff --git a/README.md b/README.md
index 7f3afaa..558dbe8 100644
--- a/README.md
+++ b/README.md
@@ -96,3 +96,4 @@ If **autodE** is used in a publication please consider citing the [paper](https:
 - Shoubhik Maiti ([@shoubhikraj](https://github.com/shoubhikraj))
 - Daniel Hollas ([@danielhollas](https://github.com/danielhollas))
 - Nils Heunemann ([@nilsheunemann](https://github.com/NilsHeunemann))
+- Sijie Fu ([@sijiefu](https://github.com/SijieFu))
diff --git a/autode/input_output.py b/autode/input_output.py
index 58c5053..4124b14 100644
--- a/autode/input_output.py
+++ b/autode/input_output.py
@@ -92,7 +92,7 @@ def atoms_to_xyz_file(
 
         for atom in atoms:
             x, y, z = atom.coord  # (Å)
-            print(f"{atom.label:<3}{x:10.5f}{y:10.5f}{z:10.5f}", file=xyz_file)
+            print(f"{atom.label:<3} {x:10.5f} {y:10.5f} {z:10.5f}", file=xyz_file)
     return None
 
 
diff --git a/doc/changelog.rst b/doc/changelog.rst
index 1cbf706..e4e5be5 100644
--- a/doc/changelog.rst
+++ b/doc/changelog.rst
@@ -12,6 +12,7 @@ Functionality improvements
 Bug Fixes
 *********
 - Fixes no solvent being added in QRC calculations
+- Fixes cases where .xyz files are printed with no space between coordinates when the coordinate value is large.
 
 Usability improvements/Changes
 ******************************


Test patch:
diff --git a/tests/test_input_output.py b/tests/test_input_output.py
index 649a9f5..1b17d35 100644
--- a/tests/test_input_output.py
+++ b/tests/test_input_output.py
@@ -1,3 +1,5 @@
+import sys
+
 import numpy as np
 
 from autode.input_output import (
@@ -76,6 +78,14 @@ def test_making_xyz_file():
     xyz_lines = open("test.xyz", "r").readlines()
     assert len(xyz_lines) == 4
 
+    # Simulate situations when the coordinates are super large (or small)
+    atoms[0].coord = (sys.float_info.min, sys.float_info.max, -1e6)
+    atoms_to_xyz_file(atoms, filename="test.xyz", append=False)
+    
+    # check if the first atom is written correctly: the third line (index 2)
+    xyz_lines = open("test.xyz", "r").readlines()
+    assert len(xyz_lines[2].split()) == 4 and np.isclose(float(xyz_lines[2].split()[-1]), -1e6)
+
     # With append should add the next set of atoms to the same file
     atoms_to_xyz_file(atoms, filename="test.xyz", append=True)