The Fingerprint base class
The fingerprint object provides a base class for the generation of material fingerprints.
It can use Material objects as input.
Usage
All built-in fingerprints can be generated from the base class:
from madas import Fingerprint
dos_fingerprint = Fingerprint("DOS", **<dos_fingerprint_kwargs>).from_material(<material>, **dos_fingerprint_calculate_kwargs)
This is equivalent to calling:
dos_fingerprint = Fingerprint("DOS", **<dos_fingerprint_kwargs>).calculate(<material>.data["dos_energies"], <material>.data["dos_values"], **dos_fingerprint_calculate_kwargs)
The fingerprints can be customized by passing (expected) keyword arguments to the initialization and to the calculate method.
The similarity to other materials can be calculated for single or many fingerprints:
single_similarity = dos_fingerprint.get_similarity(<other_dos_fingerprint>)
many_similarities = dos_fingerprint.get_similarities(<list_of_other_fingerprints>)
Custom fingerprint generation
New types of fingerprints can be defined as child classes of Fingerprint.
Say, you want to generate a fingerprint that compares the highest atomic number of the elements of a material.
The corresponding code would look like this:
from ase import Atoms
from madas import Material, Fingerprint
def MAN_similarity(fingerprint1, fingerprint2):
"""
Calculate similarity between two MANFingerprint objects.
"""
# extract data from fingerprint objects
man1 = fingerprint1.data["maximum_atomic_number"]
man2 = fingerprint2.data["maximum_atomic_number"]
# calculate absolute distance
atomic_number_differences = abs(man1 - man2)
# convert distance to similarity
similarity = 1/(1 + atomic_number_differences)
# return value
return similarity
class MANFingerprint(Fingerprint):
"""
(M)aximum (A)tomic (N)umber fingerprint.
Example fingerprint that compares the highest atomic number of the elements of a material.
"""
# This declaration can be skipped.
# However, it is advised to explicitly write the `__init__` function.
def __init__(self,
name = "MAN",
similarity_function=MAN_similarity,
pass_on_exceptions=True) -> None:
# set the fingerprint type name
self.set_fp_type("MAN")
# set a name of the specific fingerprint
self.set_name(name)
# set if the fingerprint shall raise an exeption if anything fails
self.set_pass_on_exceptions(pass_on_exceptions)
# set the similarity function used to calculate similarity values
self.set_similarity_function(similarity_function)
def calculate(self, atoms: Atoms):
# get the maximal atomic number from ASE Atoms object
atomic_numbers = atoms.get_atomic_numbers()
max_atomic_number = max(atomic_numbers)
# REQUIRED: set the fingerprint data
self.set_data("maximum_atomic_number", max_atomic_number)
# REQUIRED: return self
return self
def from_material(self, material: Material):
# REQUIRED: set the material identifier for this fingerprint
self.set_mid(material)
# use obtain properties from the material object
atoms = material.atoms
# calculate the fingerprint
self.calculate(atoms)
# REQUIRED: return self
return self
Note that two methods are required: a calculate method to compute the fingerprint directly from data,
and a from_material method that collects the required data from a Material
object and calls the calculate method internally.
Documentation
The documentation of all methods and parameters can be found below:
- class madas.fingerprint.Fingerprint(fp_type: str | type | None = None, name: str | None = None, similarity_function: ~typing.Callable | None = None, pass_on_exceptions: bool = False, importfunction: ~typing.Callable = <function import_builtin_module>, **kwargs)
Generic description of a fingerprint.
Intended use case is subclassing to integrate with the madas framework.
Arbitrary data can be passed to the Fingerprint object by using Fingerprint().set_data(<key>: str, <data>: Any). It can be retrieved either through the property Fingerprint().data as a dictionary, or directly via Fingerprint()[<key>].
Parameters:
- fp_type: str, type, or None
Type of fingerprint. The behavior changes based on the type of the argument:
None: Don’t intialize the fingerprint type. The object will be a generic Fingerprint
type: Intialize as a fingerprint of the given type. All keyword arguments will be passed to the child class.
str: Initialize as a built-in fingerprint type using the importfunction. All keyword arguments will be passed to the child class.
default: None
- name: str
Name of the fingerprint. Can be used to distinguish between fingerprints of the same type with different parameters.
- similarity_function: Callable or None
Function used to evaluate the similarity to other fingerprints.
This function will be called when Fingerprint().get_similarity() is called.
If set to None upon initialization and a fingerprint type is given, the respective similarity function will be set automatically.
If set to a callable, use this similarity function instead of any other, even if a fingerprint type is given.
default: None
- pass_on_exceptions: bool
In order to allow processing of big amounts of data without interruptions, the fingerprint can return 0 similarity instead of raising exceptions. A warning will be printed if the calculation of similarity is not successful.
default: False
- importfunction: callable
Function that imports fingerprint classes if the fingerprint type is provided as a string.
default: madas.fingerprint.import_builtin_module
Methods:
- calculate(mid: str, *args, **kwargs) object | None
To be defined in child class. Calculate the fingerprint from values.
Expected return value:
- self: Fingerprint
It is expected that the object returns itself after calling calculate.
- copy() object
Return a deep copy of the fingerprint.
- property data: dict
Get data dictionary of the Fingerprint.
- classmethod deserialize(data: str) object
Read a fingerprint object from string data. This returns a Fingerprint object, _not_ a subclass of it. The similarity function needs to be set separately, and calculate() won’t work.
Arguments:
- data: str
Sting data of fingerprint (json serialized), obtained by Fingerprint().serialize().
Returns:
- fingerprint: Fingerprint
Fingerprint object with all fields set.
- property fp_type
Property that contains the type of fingerprint.
- from_material(material: Material, *args, **kwargs)
To be defined in child class. Calculate the fingerprint from a Material object.
Expected return value:
- self: Fingerprint
It is expected that the object returns itself after calling calculate.
- get_data_json() str
Return fingerprint data in as a json-coded string.
- get_similarities(fingerprint_list: list) List[float]
Calculate similarity to all other fingerprints in fingerprint_list.
Arguments:
- fingerprint_list: List[Fingerpint]
Other fingerprints to calculate similarity
Returns:
- similarities: List[float]
Similarities of self to all other fingerprints
Raises:
TypeError: Different fingerprint types are used.
- get_similarity(other: object) float
Calculate similarity to another fingerprint.
Arguments:
- other: Fingerpint
Other fingerprint to calculate similarity
Returns:
- similarity: float
Similarity between both fingerprints
Raises:
TypeError: Different fingerprint types are used.
Warnings:
UserWarning: Fingerprints of different names are used.
- property mid
Material identifier property.
- property name
Property that contains the name of fingerprint.
- property pass_on_exceptions
Property that controls if exceptions should be raised.
- serialize() str
Write fingerprint data and metadata to dictionary or string.
Returns:
- data: str
json dump of fingerprint
- set_data(key: str, data: Any) None
Set data entries of the Fingerprint.
Arguments:
- key: str
Name of the property that is meant to be stored
- data: Any
Properties to be stored as fingerprint data
- set_import_function(import_function: Callable) None
Set the function used to import specialized fingerprint objects.
Arguments:
- import_function: Callable;
A function that returns a specialized Fingerprint class and a similarity function.
- set_mid(mid: str | Material) None
Set material id of Fingerprint.
Arguments:
- mid: str or Material
Material id to be set.
If a Material is given, the mid will be extracted from there.
Returns:
None
- set_pass_on_exceptions(behavior: bool) None
Set if fingerprint should pass and return None if an exception occures during calculation of similarities, or raise an Exception.
Arguments:
- behavior: bool
Set behavior.
True -> Return None if exceptions are raised during calculation of similarities.
False -> Raise exceptions.
- set_similarity_function(similarity_function: Callable, **kwargs) object
Set the function for calculating similarity and return self.
Arguments:
- similarity_function: Callable
Function that takes two fingerprint objects as input and calculates the similarity between them
Keyword arguments are passed to the function.
- specify(fingerprint_class, **kwargs)
Change self to class given by
fingerprint_class.Arguments:
- fingerprint_class: type
Subclass of Fingerprint
Keyword arguments are passed to the __init__ function of the specialized fingerprint.