"""This module defines the Fingerprint class."""from__future__importannotationsfromcollections.abcimportIterablefromcollections.abcimportIteratorfromcollections.abcimportMutableMappingfromtypingimportTYPE_CHECKINGimportnumpyasnpifTYPE_CHECKING:importasefromnumpy.typingimportNDArray
[docs]classFingerprint(MutableMapping):"""A set of displacement vectors relative to a particular atom. The displacement vectors for atoms of a given chemical symbol can be accessed through the ``MutableMapping`` interface. For example:: structure = ase.Atoms("CO", positions=[[0, 0, 0], [1, 0, 0]]) fp = Fingerprint(structure, 0, [0, 1]) fp["C"] Attributes: structure: The ase.Atoms instance to which the :class:`Fingerprint` instance is related. reference: An int indicating the index of the reference atom used to construct the :class:`Fingerprint` instance. indices: A tuple indicating the indices of the atoms within the structure used to construct the :class:`Fingerprint` instance. """def__init__(self,structure:ase.Atoms,reference:int,indices:Iterable[int]|None=None,)->None:"""Generate a fingerprint from a structure. Args: structure: The structure for which the ``Fingerprint`` will be generated. reference: The index of the reference atom within ``structure`` to ``Fingerprint``. indices: The indices of the atoms corresponding to the points for which the displacements will be calculated to generate the fingerprint. Defaults to None. """ifindicesisNone:indices=range(len(structure))indices=list(indices)histogram={}foratominstructure[indices]:displacement=atom.position-structure[reference].positionifatom.symbolnotinhistogram:histogram[atom.symbol]=np.array([displacement])else:histogram[atom.symbol]=np.vstack([histogram[atom.symbol],displacement])self._histogram:dict[str,NDArray[np.floating]]=histogramself.structure=structureself.reference=referenceself.indices=tuple(indices)def__getitem__(self,__k:str)->NDArray[np.floating]:"""Get displacements to atoms with symbol __k. Args: __k: A chemical symbol. """returnself._histogram[__k]def__setitem__(self,__k:str,__v:NDArray[np.floating])->None:"""Set displacements` to atoms with symbol __k. Args: __k: A chemical symbol. __v: A 2D array of atomic displacements. """self._histogram[__k]=__vdef__delitem__(self,__k)->None:"""Delete displacements to atoms with symbol __k. Args: __k: A chemical symbol. """delself._histogram[__k]def__iter__(self)->Iterator[str]:"""An iterator of chemical symbols."""returniter(self._histogram)def__len__(self)->int:"""The number of chemical symbols in the ``Fingerprint``."""returnlen(self._histogram)
[docs]@classmethoddeffrom_structure(cls,structure:ase.Atoms)->list[Fingerprint]:"""Creates a list of Fingerprint objects from an ase.Atoms object. Args: structure: An ase.Atoms instance representing the structure from which to create the list of ``Fingerprints``. Returns: A list of the ``Fingerprints`` for each atom. """fingerprints=[]fori,_inenumerate(structure):fingerprints.append(cls(structure,i))returnfingerprints