Skip to main content
`Ctrl`+`K`

# File input and output

See also

- `ase.io.trajectory`

The `ase.io` module has three basic functions: `read()`, `iread()` and `write()`. The methods are described here:

ase.io.read(filename: str | PurePath | IO, index: Any = None, format: str | None = None, parallel: bool = True, do_not_split_by_at_sign: bool = False, **kwargs) → Atoms | List[Atoms]

  Read Atoms object(s) from file.

  filename: str or file

    Name of the file to read from or a file descriptor.

  index: int, slice or str

    The last configuration will be returned by default. Examples:

    > - `index=0`: first configuration

    > - `index=-2`: second to last

    > - `index=':'` or `index=slice(None)`: all

    > - `index='-3:'` or `index=slice(-3, None)`: three last

    > - `index='::2'` or `index=slice(0, None, 2)`: even

    > - `index='1::2'` or `index=slice(1, None, 2)`: odd

  format: str

    Used to specify the file-format. If not given, the file-format will be guessed by the filetype function.

  parallel: bool

    Default is to read on master and broadcast to slaves. Use parallel=False to read on all slaves.

  do_not_split_by_at_sign: bool

    If False (default) `filename` is splitted by at sign `@`

  Many formats allow on open file-like object to be passed instead of `filename`. In this case the format cannot be auto-detected, so the `format` argument should be explicitly given.

ase.io.iread(filename: str | PurePath | IO, index: Any = None, format: str = None, parallel: bool = True, do_not_split_by_at_sign: bool = False, **kwargs) → Iterator[Atoms]

  Iterator for reading Atoms objects from file.

  Works as the \(read\) function, but yields one Atoms object at a time instead of all at once.

ase.io.write(filename: str | PurePath | IO, images: Atoms | Sequence[Atoms], format: str = None, parallel: bool = True, append: bool = False, **kwargs: Any) → None

  Write Atoms object(s) to file.

  filename: str or file

    Name of the file to write to or a file descriptor. The name ‘-’ means standard output.

  images: Atoms object or list of Atoms objects

    A single Atoms object or a list of Atoms objects.

  format: str

    Used to specify the file-format. If not given, the file-format will be taken from suffix of the filename.

  parallel: bool

    Default is to write on master only. Use parallel=False to write from all slaves.

  append: bool

    Default is to open files in ‘w’ or ‘wb’ mode, overwriting existing files. In some cases opening the file in ‘a’ or ‘ab’ mode (appending) is useful, e.g. writing trajectories or saving multiple Atoms objects in one file. WARNING: If the file format does not support multiple entries without additional keywords/headers, files created using ‘append=True’ might not be readable by any program! They will nevertheless be written without error message.

  The use of additional keywords is format specific. write() may return an object after writing certain formats, but this behaviour may change in the future.

Use `ase info --formats` to see a list of formats. This information is programmatically accessible as `ase.io.formats.ioformats`, a dictionary which maps format names to `ase.io.formats.IOFormat` objects.

These are the file-formats that are recognized (formats with a `+` support multiple configurations):

format | description | capabilities
--- | --- | ---
abinit-gsr | ABINIT GSR file | R
abinit-in | ABINIT input file | RW
abinit-out | ABINIT output file | R
acemolecule-input | ACE input file | R
acemolecule-out | ACE output file | R
aims | FHI-aims geometry file | RW
aims-output | FHI-aims output | R+
bundletrajectory | ASE bundle trajectory | RW+
castep-castep | CASTEP output file | R+
castep-cell | CASTEP geom file | RW
castep-geom | CASTEP trajectory file | RW+
castep-md | CASTEP molecular dynamics file | RW+
castep-phonon | CASTEP phonon file | R
cfg | AtomEye configuration | RW
cif | CIF-file | RW+
cjson | Chemical json file | R
cmdft | CMDFT-file | R
cp2k-dcd | CP2K DCD file | R+
cp2k-restart | CP2K restart file | R
crystal | Crystal fort.34 format | RW
cube | CUBE file | RW
dacapo-text | Dacapo text output | R
db | ASE SQLite database file | RW+
dftb | DftbPlus input file | RW
dlp-history | DL_POLY HISTORY file | R+
dlp4 | DL_POLY_4 CONFIG file | RW
dmol-arc | DMol3 arc file | RW+
dmol-car | DMol3 structure file | RW
dmol-incoor | DMol3 structure file | RW
elk | ELK atoms definition from GEOMETRY.OUT | R
elk-in | ELK input file | W
eon | EON CON file | RW+
eps | Encapsulated Postscript | W
espresso-in | Quantum espresso in file | RW
espresso-out | Quantum espresso out file | R+
exciting | exciting output |
extxyz | Extended XYZ file | RW+
findsym | FINDSYM-format | W+
gamess-us-in | GAMESS-US input file | W
gamess-us-out | GAMESS-US output file | R
gamess-us-punch | GAMESS-US punchcard file | R
gaussian-in | Gaussian com (input) file | RW
gaussian-out | Gaussian output file | R+
gen | DFTBPlus GEN format | RW
gif | Graphics interchange format | W+
gpaw-out | GPAW text output | R+
gpumd | GPUMD input file | RW
gpw | GPAW restart-file | R
gromacs | Gromacs coordinates | RW
gromos | Gromos96 geometry file | RW
html | X3DOM HTML | W
json | ASE JSON database file | RW+
jsv | JSV file format | RW
lammps-data | LAMMPS data file | RW
lammps-dump-binary | LAMMPS binary dump file | R+
lammps-dump-text | LAMMPS text dump file | R+
magres | MAGRES ab initio NMR data file | RW
mol | MDL Molfile | R
mp4 | MP4 animation | W+
mustem | muSTEM xtl file | RW
mysql | ASE MySQL database file | RW+
netcdftrajectory | AMBER NetCDF trajectory file | RW+
nomad-json | JSON from Nomad archive | R+
nwchem-in | NWChem input file | RW
nwchem-out | NWChem output file | R+
octopus-in | Octopus input file | R
onetep-in | ONETEP input file | RW
onetep-out | ONETEP output file | R+
orca-output | ORCA output | R+
png | Portable Network Graphics | W
postgresql | ASE PostgreSQL database file | RW+
pov | Persistance of Vision | W
prismatic | prismatic and computem XYZ-file | RW
proteindatabank | Protein Data Bank | RW+
py | Python file | W+
qbox | QBOX output file | R+
res | SHELX format | RW
rmc6f | RMCProfile | RW
sdf | SDF format | R
siesta-xv | Siesta .XV file | R
struct | WIEN2k structure file | RW
struct_out | SIESTA STRUCT file | R
sys | qball sys file | RW
traj | ASE trajectory | RW+
turbomole | TURBOMOLE coord file | RW
turbomole-gradient | TURBOMOLE gradient file | R+
v-sim | V_Sim ascii file | RW
vasp | VASP POSCAR/CONTCAR | RW
vasp-out | VASP OUTCAR file | R+
vasp-xdatcar | VASP XDATCAR file | RW+
vasp-xml | VASP vasprun.xml file | R+
vti | VTK XML Image Data | W
vtu | VTK XML Unstructured Grid | W
wout | Wannier90 output | R
x3d | X3D | W
xsd | Materials Studio file | RW
xsf | XCrySDen Structure File | RW+
xtd | Materials Studio file | RW+
xyz | XYZ-file | RW+

Note

Even though that ASE does a good job reading the above listed formats, it may not read some unusual features or strangely formatted files.

For the CIF format, STAR extensions as save frames, global blocks, nested loops and multi-data values are not supported.

Note

ASE read and write functions are automatically parallelized if a suitable MPI library is found. This requires to call read and write with same input on all cores. For more information, see `ase.parallel`.

Note

ASE can read and write directly to compressed files. Simply add `.gz`, `.bz2` or `.xz` to your filename.

The `read()` function is only designed to retrieve the atomic configuration from a file, but for the CUBE format you can import the function:

ase.io.read_cube_data()

which will return a `(data, atoms)` tuple:

    from ase.io.cube import read_cube_data
    data, atoms = read_cube_data('abc.cube')

## Examples

    >>> from ase import Atoms
    >>> from ase.build import fcc111, add_adsorbate, bulk
    >>> from ase.io import read, write
    >>> adsorbate = Atoms('CO')
    >>> adsorbate[1].z = 1.1
    >>> a = 3.61
    >>> slab = fcc111('Cu', (2, 2, 3), a=a, vacuum=7.0)
    >>> add_adsorbate(slab, adsorbate, 1.8, 'ontop')

Write PNG image

    >>> write('slab.png', slab * (3, 3, 1), rotation='10z,-80x')

Write animation with 500 ms duration per frame

    >>> write('movie.gif', [bulk(s) for s in ['Cu', 'Ag', 'Au']], interval=500)

Write POVRAY file (the projection settings and povray specific settings are separated)

    >>> write('slab.pov', slab * (3, 3, 1),
    ...       generic_projection_settings = dict(rotation='10z,-80x'))

This will write both a `slab.pov` and a `slab.ini` file. Convert to PNG with the command `povray slab.ini` or use the `.render` method on the returned object:

Here is an example using `bbox`

    >>> d = a / 2**0.5
    >>> write('slab.pov', slab * (2, 2, 1),
    ...       generic_projection_settings = dict(
    ...       bbox=(d, 0, 3 * d, d * 3**0.5))).render()

This is an example of displaying bond order for a molecule

    # creates: C2H4.png
    from ase.build.molecule import molecule
    from ase.io import write
    from ase.io.pov import get_bondpairs, set_high_bondorder_pairs

    C2H4 = molecule('C2H4')
    r = [{'C': 0.4, 'H': 0.2}[at.symbol] for at in C2H4]
    bondpairs = get_bondpairs(C2H4, radius=1.1)
    high_bondorder_pairs = {}
    # This defines offset, bond order, and bond_offset of the bond between 0 and 1
    high_bondorder_pairs[(0, 1)] = ((0, 0, 0), 2, (0.17, 0.17, 0))
    bondpairs = set_high_bondorder_pairs(bondpairs, high_bondorder_pairs)

    renderer = write(
        'C2H4.pov',
        C2H4,
        format='pov',
        radii=r,
        rotation='90y',
        povray_settings=dict(canvas_width=200, bondatoms=bondpairs),
    )

    renderer.render()

Note that in general the XYZ-format does not contain information about the unit cell, however, ASE uses the extended XYZ-format which stores the unitcell:

    >>> from ase.io import read, write
    >>> write('slab.xyz', slab)
    >>> a = read('slab.xyz')
    >>> cell = a.get_cell()
    >>> cell.round(3)
    array([[  5.105,   0.   ,   0.   ],
           [  2.553,   4.421,   0.   ],
           [  0.   ,   0.   ,  18.168]])
    >>> a.get_pbc()
    array([ True,  True, False], dtype=bool)

Another way to include the unit cell is to write the cell vectors at the end of the file as `VEC<N> <x> <y> <z>` (used for example in the ADF software).

    >>> write('slab.xyz', vec_cell=True)

Use ASE’s native format for writing all information:

    >>> write('slab.traj', slab)
    >>> b = read('slab.traj')
    >>> b.cell.round(3)
    array([[  5.105,   0.   ,   0.   ],
           [  2.553,   4.421,   0.   ],
           [  0.   ,   0.   ,  18.168]])
    >>> b.pbc
    array([ True,  True, False], dtype=bool)

A script showing all of the povray parameters, and generating the image below, can be found here: `save_pov.py`

An other example showing how to change colors and textures in pov can be found here: `../../tutorials/saving_graphics.py`.

## Adding a new file-format to ASE

Try to model the read/write functions after the xyz format as implemented in ase/io/xyz.py and also read, understand and update ase/io/formats.py.

## Adding a new file-format in a plugin package

IO formats can also be implemented in external packages. For this the read write functions of the IO format are implemented as normal. To define the format the parameters are entered into a `ase.utils.plugins.ExternalIOFormat` object.

Note

The module name of the external IO format has to be absolute and cannot be omitted.

In the configuration of the package an entry point is added under the group `ase.ioformats` which points to the defined `ase.utils.plugins.ExternalIOFormat` object. The format of this entry point looks like `format-name=ase_plugin.io::ioformat`.