rascaline
rascaline copied to clipboard
`PowerSpectrum` TensorMap can not be fully merged in a single block
When computing a descriptor with PowerSpectrum from two frames that have different atomtypes i.e one with only an H and the other one only with an O the result can not be densified.
Consider the following example
import ase
import numpy as np
from equistore import EquistoreError
from rascaline import SoapPowerSpectrum, SphericalExpansion
from rascaline.utils import PowerSpectrum
frames = [
ase.Atoms("H", positions=np.zeros([1, 3])),
ase.Atoms("O", positions=np.zeros([1, 3])),
]
hypers = dict(
cutoff=3.0,
max_radial=6,
max_angular=1,
atomic_gaussian_width=0.3,
center_atom_weight=1.0,
radial_basis={"Gto": {}},
cutoff_function={"ShiftedCosine": {"width": 0.5}},
)
calculator_pyps = PowerSpectrum(SphericalExpansion(**hypers))
descriptor_pyps = calculator_pyps.compute(frames)
print(descriptor_pyps)
try:
descriptor_pyps.keys_to_samples("species_center")
except EquistoreError as err:
print(err)
which prints
TensorMap with 2 blocks
keys: species_center
1
8
invalid parameter: can not move keys to samples if the blocks have different property labels
The same happens when calling the SOAPPowerSpectrum
calculator_ps = SoapPowerSpectrum(**hypers)
descriptor_ps = calculator_ps.compute(frames)
print(descriptor_ps)
descriptor_moved = descriptor_ps.keys_to_properties(
["species_neighbor_1", "species_neighbor_2"]
)
print(descriptor_moved)
try:
descriptor_moved.keys_to_samples("species_center")
except EquistoreError as err:
print(err)
leading to
TensorMap with 2 blocks
keys: species_center species_neighbor_1 species_neighbor_2
1 1 1
8 8 8
TensorMap with 2 blocks
keys: species_center
1
8
invalid parameter: can not move keys to samples if the blocks have different property labels
For SOAPPowerSpectrum the error can be solved by changing the order of keys_to_properties and keys_to_samples. For PowerSpectrum we can not do this because we already move the keys to properties within the computation to avoid nasty bookkeeping. However, it might be that we have to do this because I see no current way to solve this.
Somebody has ideas?
I could be wrong, but I believe the solution is to provide labels here:
descriptor_moved = descriptor_ps.keys_to_properties(
["species_neighbor_1", "species_neighbor_2"]
)
instead of a list of strings. If you provide labels with all the species you want to be represented in the properties, then the extra ones will be filled with zeros and then you'll be able to do keys_to_samples. See the documentation of keys_to_properties
Yes this might be a solution. One could maybe in clever construct the species_neighbor_1 and species_neighbor_2. from the keys of the spherical expansion.