xtalmet.distance module

This module offers a range of distance functions for crystals.

xtalmet.distance.distance(distance: str, xtal_1: Structure | Crystal | tuple[tuple[str, int]] | tuple[int, tuple[str]] | list[float] | ndarray[float32 | float64] | str | tuple[str, ndarray[float32 | float64]], xtal_2: Structure | Crystal | tuple[tuple[str, int]] | tuple[int, tuple[str]] | list[float] | ndarray[float32 | float64] | str | tuple[str, ndarray[float32 | float64]], normalize: bool = True, verbose: Literal[False] = False, **kwargs) → floatView on GitHub
xtalmet.distance.distance(distance: str, xtal_1: Structure | Crystal | tuple[tuple[str, int]] | tuple[int, tuple[str]] | list[float] | ndarray[float32 | float64] | str | tuple[str, ndarray[float32 | float64]], xtal_2: Structure | Crystal | tuple[tuple[str, int]] | tuple[int, tuple[str]] | list[float] | ndarray[float32 | float64] | str | tuple[str, ndarray[float32 | float64]], normalize: bool = True, verbose: Literal[True] = False, **kwargs) → tuple[float, tuple[tuple[str, int]] | tuple[int, tuple[str]] | list[float] | ndarray[float32 | float64] | str | tuple[str, ndarray[float32 | float64]], tuple[tuple[str, int]] | tuple[int, tuple[str]] | list[float] | ndarray[float32 | float64] | str | tuple[str, ndarray[float32 | float64]]]

Compute the distance between two crystals.

Failed embeddings, nonfinite smat geometry and nonfinite backend distances yield NaN. For “elmd+amd”, failure of either component invalidates the whole embedding. Blending coefficients must be finite and non-negative with a finite positive sum.

Parameters:
  • distance (str) – The distance metric to use. Currently supported metrics are listed in SUPPORTED_DISTANCES in constants.py. For more detailed information about each distance metric, please refer to the tutorial notebook.

  • xtal_1 (Structure | Crystal | TYPE_EMB_ALL) – pymatgen Structure or Crystal or an embedding.

  • xtal_2 (Structure | Crystal | TYPE_EMB_ALL) – pymatgen Structure or Crystal or an embedding.

  • normalize (bool) – Whether to normalize the distance d to [0, 1] by using d’ = d / (1 + d). This argument is only considered when d is a continuous distance that is not normalized to [0, 1]. Such distances are listed in CONTINUOUS_UNNORMALIZED_DISTANCES in constants.py. Default is True.

  • verbose (bool) – Whether to return intermediate embeddings. Default is False.

  • **kwargs – Additional keyword arguments for specific distance metrics. It can contain two keys: “args_emb” and “args_dist”. The value of “args_emb” is a dict of arguments for the calculation of embeddings, and the value of “args_dist” is a dict of arguments for the calculation of distance between the embeddings. If embeddings are pre-computed and provided as inputs, the “args_emb” will be ignored.

Returns:

Distance between crystals. If verbose is True, also returns the embeddings and the computing time.

Return type:

float | tuple[np.ndarray, TYPE_EMB_ALL, TYPE_EMB_ALL, dict[str, float]]

Raises:

ValueError – If a distance metric or blending coefficients are invalid.

xtalmet.distance.TYPE_D_MTX_RETURN = numpy.ndarray | tuple[numpy.ndarray, list[tuple[tuple[str, int]] | tuple[int, tuple[str]] | list[float] | numpy.ndarray[numpy.float32 | numpy.float64] | str | tuple[str, numpy.ndarray[numpy.float32 | numpy.float64]]], dict[str, float]] | tuple[numpy.ndarray, list[tuple[tuple[str, int]] | tuple[int, tuple[str]] | list[float] | numpy.ndarray[numpy.float32 | numpy.float64] | str | tuple[str, numpy.ndarray[numpy.float32 | numpy.float64]]], list[tuple[tuple[str, int]] | tuple[int, tuple[str]] | list[float] | numpy.ndarray[numpy.float32 | numpy.float64] | str | tuple[str, numpy.ndarray[numpy.float32 | numpy.float64]]], dict[str, float]]

Return type for distance_matrix function.

xtalmet.distance.distance_matrix(distance: str, xtals_1: list[Structure | Crystal | tuple[tuple[str, int]] | tuple[int, tuple[str]] | list[float] | ndarray[float32 | float64] | str | tuple[str, ndarray[float32 | float64]]], xtals_2: list[Structure | Crystal | tuple[tuple[str, int]] | tuple[int, tuple[str]] | list[float] | ndarray[float32 | float64] | str | tuple[str, ndarray[float32 | float64]]] | None = None, normalize: bool = True, multiprocessing: bool = False, n_processes: int | None = None, verbose: bool = False, **kwargs) → ndarray | tuple[ndarray, list[tuple[tuple[str, int]] | tuple[int, tuple[str]] | list[float] | ndarray[float32 | float64] | str | tuple[str, ndarray[float32 | float64]]], dict[str, float]] | tuple[ndarray, list[tuple[tuple[str, int]] | tuple[int, tuple[str]] | list[float] | ndarray[float32 | float64] | str | tuple[str, ndarray[float32 | float64]]], list[tuple[tuple[str, int]] | tuple[int, tuple[str]] | list[float] | ndarray[float32 | float64] | str | tuple[str, ndarray[float32 | float64]]], dict[str, float]]View on GitHub

Compute the distance matrix between two sets of crystals.

If xtals_2 is None, compute the distance matrix within xtals_1.

Parameters:
  • distance (str) – The distance metric to use. Currently supported metrics are listed in SUPPORTED_DISTANCES in constants.py. For more detailed information about each distance metric, please refer to the tutorial notebook.

  • xtals_1 (list[Structure | Crystal | TYPE_EMB_ALL]) – A list of pymatgen Structures or Crystals or embeddings.

  • xtals_2 (list[Structure | Crystal | TYPE_EMB_ALL] | None) – A list of pymatgen Structures or Crystals or embeddings, or None. Default is None.

  • normalize (bool) – Whether to normalize the distances d to [0, 1] by using d’ = d / (1 + d). This argument is only considered when d is a continuous distance that is not normalized to [0, 1]. Such distances are listed in CONTINUOUS_UNNORMALIZED_DISTANCES in constants.py. Default is True.

  • multiprocessing (bool) – Whether to use multiprocessing. Default is False.

  • n_processes (int | None) – Maximum number of processes for multiprocessing. If multiprocessing is False, this argument will be ignored. Default is None.

  • verbose (bool) – Whether to return embeddings and the computing time. Default is False.

  • **kwargs – Additional keyword arguments for specific distance metrics. It can contain two keys: “args_emb” and “args_dist”. The value of “args_emb” is a dict of arguments for the calculation of embeddings, and the value of “args_dist” is a dict of arguments for the calculation of distance matrix using the embeddings. If embeddings are pre-computed and provided as inputs, the “args_emb” will be ignored.

Returns:

Distance matrix, the embeddings of xtals_1 (and xtals_2 if xtals_2 is not None) and the computing time.

Return type:

TYPE_D_MTX_RETURN

Notes

Failed embeddings, including nonfinite numerical features, produce NaN rows and columns, including the diagonal. For “elmd+amd”, either component’s failure invalidates the whole embedding. Only valid inputs reach the backend; their matrix is restored to the original positions in one NaN-filled matrix. When failures occur, this temporarily holds both matrices in memory. All-valid inputs do not allocate a restoration matrix. Verbose embeddings retain input order and failures. AMD’s “out” buffer retains raw, unnormalized distances. Nonfinite backend distances are returned as NaN, including for normalize=False. When raw AMD output shares an “out” buffer, replacing nonfinite distances requires a copy; the caller-owned buffer keeps its raw backend values.

For “smat”, the dense matrix uses 0 for matches and 1 for mismatches. Structures with nonfinite lattice vectors or coordinates are excluded before native matching and produce NaN rows and columns. Composition-incompatible pairs are skipped using the configured comparator and ignored species; subset matching compares all pairs. Serial and parallel calculations both honor args_dist and reuse a matcher. Parallel tasks contain candidate row indices rather than a materialized list of all structure pairs. Participating structures undergo Niggli and optional primitive reduction once per input position in the parent process, after removing ignored species. Workers reuse the reductions; volume scaling and supercell matching remain pairwise. Unequal reduced site counts rule out matches unless subset or supercell matching is enabled. Pairs whose reduced compositions become incompatible fall back to normal matching of the original structures. Input structures and returned embeddings are not replaced by reductions.

For “magpie”, SciPy computes the dense Euclidean distance matrix without a Python worker pool. Multiprocessing settings still apply to embedding computation when structures are provided, but not to the matrix calculation. Continuous normalization updates the final matrix in place, one row at a time, copying first if it shares AMD’s caller-owned raw “out” buffer. “elmd+amd” reuses its internal ElMD matrix for rowwise blending and leaves the raw AMD component, including a supplied “out” buffer, unchanged. These operations avoid additional full-size arithmetic arrays. The two raw component matrices still coexist during blending. Dense output requires 8 bytes per pair: about 2.24 GiB for a 10,000-by-30,000 float64 matrix, excluding embeddings and other evaluation data.

For “comp” and “wyckoff”, identical tuple embeddings are grouped and their matching positions are filled with zero in a dense matrix of ones. No pairwise Python comparisons or matrix worker pools are used. Multiprocessing settings still apply to embedding computation. Evaluator also retains dense matrices when computing only U/N scores, with or without disk caching.

For “elmd” (also the ElMD component of “elmd+amd”), each distinct formula is parsed once per matrix call using the requested metric. Parsed objects are initialized once per worker, while tasks contain only indices of row sections of at most 1,024 columns. At most twice the worker count of tasks and results are retained per batch; no complete pair or result list is built.

For “pdd”, 128-by-128 blocks are dispatched to the requested joblib backend in batches of at most twice its effective worker count. Workers compute blocks serially without nested pools; diagonal blocks use a small condensed array, and off-diagonal blocks are mirrored for a single input set. Explicit args_dist[“n_jobs”] takes precedence over multiprocessing/n_processes. An explicit backend=None inherits joblib’s active backend. The AMD backend’s existing n_jobs semantics are retained, including negative values selecting parallel cdist but serial pdist. verbose reports completed pairs in the parent process.

Raises:

ValueError – If a distance metric or blending coefficients are invalid, or an input set is empty.