Source code for the paper "LAMDA: Aiding Visual Exploration of Atomic Displacements in Molecular Dynamics Simulations".
Uses julia 1.11.4.
You need to install the Python environment manager poetry([https://python-poetry.org/]); once it is installed, run poetry install.
Your global julia installation needs Revise and PackageCompiler installed to build the binary and use the run.sh script.
To set up your Julia environment, run ./run.sh [num_workers]; num_workers should be your machine's number of processors - 1. To start the program, run go("trajectory_name") which should correspond to a name of a folder inside data e.g. go('nano_pt').
go has some keyword parameters as well.
| parameter | type | purpose |
|---|---|---|
chunk_size |
Int |
sets how many volumes get processed at a time |
init_h_cutoff |
Float |
sets the initial height cutoff value for the clustering |
align_with |
String |
sets the initial feature values used to align the transitions |
distance_matrix |
String |
sets which distance matrix to initially render |
If you have a binary already compiled, simply run ./exe "trajectory_name" --julia-args -t[num_workers]; num_workers should be your machine's number of processors - 1.
Inside the data directory, create a folder with a name that identifies the trajectory you're looking at. The name of the folder will be used as an argument to the go function; i.e. `go("trajectory_name"). The following is an example data directory:
trajectory_name/ # used as input to go()
transitions.pickle # list of transitions; Vector{Tuple{Int,Int}}
ase_dict.pickle # ASE data per state; Dict{Int, Atoms}
dms/
- some_distance_metric/
- dm.pickle # distance matrix defined for all transitions; Matrix{Float}
alignment/
- some_features.pickle # alignment features; Dict{Int, Matrix{Float}}
scalars/ # optional
- some_scalar.pickle # per-atom scalar values; Dict{Tuple{Int,Int}, Vector{Float}}
per_t_scalars/ # optional
- some_scalar.pickle # per-transition scalar values; Dict{Tuple{Int,Int}, Float}}
You also need a folder called dms, with subfolders corresponding to distance matrices you're interested in. You need at least one for the program to start. Each distance matrix directory requires a file called dm.pickle containing a matrix / 2d array. It is assumed that the rows of the distance matrix correspond to the transitions in the order presented by transition.pickle.
You will also need an alignment folder containing pickles with dictionaries of tuples to tuples of matrices that will be used to perform intra-cluster alignments with a variant of the Kabsch algorithm. Since each matrix should have signs, the initial state should have positive values & the final negative. Each matrix should be [num_atoms * num_features]. LAMDA will calculate the center of charge for each feature and then align each transition using these centers of charge. We found the bispectrum descriptor to be effective in aligning transitions, but in principle any descriptor can be used provided it returns the per-atom features in order.
You can optionally visualize per-atom scalars by placing dictionaries in the scalars folder and per-transition scalars in the per_t_scalars. The per-atom scalars must be dictionaries keyed by transition ids (i.e. (state1, state2)); the values of the dictionary are 1D arrays corresponding to each atom (Vector{Float}). per_t_scalars is accessed the same way, but contains per transition values.
If you use this program or parts of its code in your research, please use the following citation:
@ARTICLE{Hnatyshyn2026-lp,
title = "{LAMDA}: Aiding visual exploration of atomic displacements in
molecular dynamics simulations",
author = "Hnatyshyn, Rostyslav and Perez, Danny and Scheuermann, Gerik and
Maciejewski, Ross and Nsonga, Baldwin",
journal = "IEEE Trans. Vis. Comput. Graph.",
volume = "PP",
month = jan,
year = 2026,
language = "en"
}