CrystalNets.jl is a a Julia package for automatic detection and identification of net topologies underlying crystalline materials. Its inputs can be chemical files in any format recognized by chemfiles.

To use it directly without any installation, simply use the website interface:

To use it through Python, check the Python interface tutorial.

Package installation

The installation follows the usual procedure. Start by downloading and installing Julia, v1.6 at least for CrystalNets.jl. This package was optimized with Julia v1.8 so performance and latency will be better on the more recent versions of Julia. Then, either

  • open the Julia REPL and enter the package manager by typing ], then install CrystalNets.jl by entering:
    pkg> add CrystalNets
  • alternatively, you can do it from a shell by executing:
    julia -e 'import Pkg; Pkg.add("CrystalNets")'

To use the package, open a REPL and enter

julia> using CrystalNets

or proceed with the Full installation to obtain an executable.

Quick usage as a module

To determine the topology of a structure stored in a file at location path, simply call

julia> determine_topology(path)

Known nets

If recognized, this yields the name of the net. For example:

julia> determine_topology("/path/to/diamond.cif")
Export of input is enabled: saving file at /tmp/input_diamond_0.vtf
Export of subnet_Auto is enabled: saving file at /tmp/subnet_Auto_diamond_0.vtf

By default, the parsed input and the extracted underlying nets are exported as .vtf files (see Visualization). To toggle on or off automatic exports, use CrystalNets.toggle_export, and similarly with CrystalNets.toggle_warning for warnings.

Unknown nets

If the net is not recognized, its topological genome is displayed preceded by an "UNKNOWN" mention, or "unstable" if the net is unstable:

julia> determine_topology("/path/to/new/material.cif")
UNKNOWN 2 1 2 -2 0 1 2 0 0 1 2 0 1 2 2 1 0

julia> determine_topology("/path/to/unstable/net.cif")
unstable 1 1 1 1 1 2 0 2 2 1

In both known and unknown cases, the result is an InterpenetratedTopologyResult.

Interpenetrating substructures

If the file contains multiple interpenetrating substructures, each substructure and its catenation multiplicity can be extracted from the InterpenetratedTopologyResult.

For example:

julia> x = determine_topology("/path/to/intertwinned/structures.cif")
2 interpenetrated substructures:
⋅ Subnet 1 → pcu
⋅ Subnet 2 → srs

Using options

Options can be added as individual keyword arguments to the call. For instance:

julia> path_to_mof5 = joinpath(dirname(dirname(pathof(CrystalNets))), "test", "cif", "MOF-5.cif");

julia> determine_topology(path_to_mof5; structure=StructureType.MOF,
PE: cab
Standard: fff

Full installation

To obtain an executable, CrystalNets.jl can be statically compiled. To do so, run the following julia script after changing the INSTALLATION_PATH variable to the location where the CrystalNets.jl executable will be installed. Note that this requires the PackageCompiler module.

const INSTALLATION_PATH = "/fill/with/installation/path"

using PackageCompiler
using CrystalNets

const root = dirname(dirname(pathof(CrystalNets)))

create_app(root, INSTALLATION_PATH;
           precompile_statements_file=abspath(root, "src", "precompile_statements.jl"),

Compilation can take between fifteen minutes and an hour, depending on your hardware and the version of Julia.

The executable will be located in the "bin" subdirectory of the specified INSTALLATION_PATH, under the name "CrystalNets".

The executable can then simply be used on a chemical file:

$ CrystalNets /path/to/diamond.cif

Run CrystalNets --help for the list of options available to the executable.


In terms of performance, the compiled executable is the best option if you only want to identify a few structures from time to time. Using the website is recommended as well for this use-case, unless the nets you study are too big.

For intensive workloads with many structures to identify, it is best to use CrystalNets.jl as a Julia module through the determine_topology_dataset function. The module is also the best option to perform more advanced analyses on the net in Julia, or to use the Options unavailable to the executable.