rascaline icon indicating copy to clipboard operation
rascaline copied to clipboard

`PowerSpectrum` TensorMap can not be fully merged in a single block

Open PicoCentauri opened this issue 2 years ago • 2 comments

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?

PicoCentauri avatar Aug 04 '23 12:08 PicoCentauri

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

frostedoyster avatar Aug 04 '23 15:08 frostedoyster

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.

PicoCentauri avatar Aug 04 '23 16:08 PicoCentauri