Skip to content

Commit 5b04644

Browse files
authored
Adds sample selection to equivariant power spectrum (#376)
1 parent 5bbae38 commit 5b04644

File tree

2 files changed

+55
-2
lines changed

2 files changed

+55
-2
lines changed

python/featomic/featomic/clebsch_gordan/_equivariant_power_spectrum.py

+18-2
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ def compute(
217217
self,
218218
systems: Union[IntoSystem, List[IntoSystem]],
219219
selected_keys: Optional[Labels] = None,
220+
selected_samples: Optional[Labels] = None,
220221
neighbors_to_properties: bool = False,
221222
) -> TensorMap:
222223
"""
@@ -245,6 +246,11 @@ def compute(
245246
:param selected_keys: :py:class:`Labels`, the output keys to computed. If
246247
``None``, all keys are computed. Subsets of key dimensions can be passed to
247248
compute output blocks that match in these dimensions.
249+
:param selected_samples: :py:class:`Labels`, Set of samples on which to run the
250+
calculation. Use ``None`` to run the calculation on all samples in
251+
the systems (this is the default). Gets passed to ``calculator_1`` and
252+
``calculator_2``, therefore requiring that both calculators support sample
253+
selection.
248254
:param neighbors_to_properties: :py:class:`bool`, if true, densifies the
249255
spherical expansion by moving key dimension "neighbor_type" to properties
250256
prior to performing the Clebsch Gordan product step. Defaults to false.
@@ -254,6 +260,7 @@ def compute(
254260
return self._equivariant_power_spectrum(
255261
systems=systems,
256262
selected_keys=selected_keys,
263+
selected_samples=selected_samples,
257264
neighbors_to_properties=neighbors_to_properties,
258265
compute_metadata=False,
259266
)
@@ -262,6 +269,7 @@ def forward(
262269
self,
263270
systems: Union[IntoSystem, List[IntoSystem]],
264271
selected_keys: Optional[Labels] = None,
272+
selected_samples: Optional[Labels] = None,
265273
neighbors_to_properties: bool = False,
266274
) -> TensorMap:
267275
"""
@@ -275,13 +283,15 @@ def forward(
275283
return self.compute(
276284
systems=systems,
277285
selected_keys=selected_keys,
286+
selected_samples=selected_samples,
278287
neighbors_to_properties=neighbors_to_properties,
279288
)
280289

281290
def compute_metadata(
282291
self,
283292
systems: Union[IntoSystem, List[IntoSystem]],
284293
selected_keys: Optional[Labels] = None,
294+
selected_samples: Optional[Labels] = None,
285295
neighbors_to_properties: bool = False,
286296
) -> TensorMap:
287297
"""
@@ -294,6 +304,7 @@ def compute_metadata(
294304
return self._equivariant_power_spectrum(
295305
systems=systems,
296306
selected_keys=selected_keys,
307+
selected_samples=selected_samples,
297308
neighbors_to_properties=neighbors_to_properties,
298309
compute_metadata=True,
299310
)
@@ -302,19 +313,24 @@ def _equivariant_power_spectrum(
302313
self,
303314
systems: Union[IntoSystem, List[IntoSystem]],
304315
selected_keys: Optional[Labels],
316+
selected_samples: Optional[Labels],
305317
neighbors_to_properties: bool,
306318
compute_metadata: bool,
307319
) -> TensorMap:
308320
"""
309321
Computes the equivariant power spectrum, either fully or just metadata
310322
"""
311323
# Compute density
312-
density_1 = self.calculator_1.compute(systems)
324+
density_1 = self.calculator_1.compute(
325+
systems, selected_samples=selected_samples
326+
)
313327

314328
if self.calculator_2 is None:
315329
density_2 = density_1
316330
else:
317-
density_2 = self.calculator_2.compute(systems)
331+
density_2 = self.calculator_2.compute(
332+
systems, selected_samples=selected_samples
333+
)
318334

319335
# Rename "neighbor_type" dimension so they are correlated
320336
density_1 = operations.rename_dimension(

python/featomic/tests/clebsch_gordan/equivariant_power_spectrum.py

+37
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,43 @@ def test_equivariant_power_spectrum_neighbors_to_properties():
136136
metatensor.equal_raise(powspec_1, powspec_2)
137137

138138

139+
def test_sample_selection() -> None:
140+
"""Tests that the sample selection works as expected.
141+
By first computing the powerspectruim for all atoms in H2O
142+
Then first for atom 1 and then atom 2 and 3.
143+
Their join should be identical to computing it for all atoms.
144+
"""
145+
146+
frame = h2o_periodic()
147+
148+
powspec_calc = EquivariantPowerSpectrum(SphericalExpansion(**SPHEX_HYPERS_SMALL))
149+
150+
label_1st = metatensor.Labels(
151+
["system", "atom"], np.array([[0, 0]], dtype=np.int32)
152+
)
153+
154+
label_2nd = metatensor.Labels(
155+
["system", "atom"], np.array([[0, 1], [0, 2]], dtype=np.int32)
156+
)
157+
158+
powspec_1 = powspec_calc.compute(
159+
frame, neighbors_to_properties=True, selected_samples=label_1st
160+
)
161+
162+
powspec_2 = powspec_calc.compute(
163+
frame, neighbors_to_properties=True, selected_samples=label_2nd
164+
)
165+
166+
powspec_3 = metatensor.join(
167+
[powspec_1, powspec_2], axis="samples", remove_tensor_name=True
168+
)
169+
powspec_4 = powspec_calc.compute(frame, neighbors_to_properties=True)
170+
171+
assert metatensor.equal(powspec_3, powspec_4)
172+
assert not metatensor.equal(powspec_2, powspec_4)
173+
assert not metatensor.equal(powspec_1, powspec_4)
174+
175+
139176
def test_fill_types_option() -> None:
140177
"""
141178
Test that ``neighbor_types`` options adds arbitrary atomic neighbor types.

0 commit comments

Comments
 (0)