Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,18 @@ API changes; these are called out under **Changed** where they occur.

## [Unreleased]

### Changed

- **Breaking:** the ``native-3d`` descriptor preset no longer emits the six
absolute-coordinate columns ``centroid_x/y/z`` and ``center_of_mass_x/y/z``
(preset width drops from 80 to 74). These recorded where a structure happened
to sit in its input file's coordinate frame, so they were translation- and
rotation-variant: two identical molecules placed differently produced different
features, letting a model learn the arbitrary input frame. Size and shape are
already captured frame-independently by ``radius_of_gyration``, ``dim_x/y/z``,
``principal_moments`` and the gyration-tensor shape scalars. The ``native-basic``
and ``rdkit-basic`` presets are unaffected.

## [0.15.0] - 2026-06-07

### Added
Expand Down
20 changes: 0 additions & 20 deletions molscope/descriptors.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,7 @@ def descriptors(
return _apply_preset(desc, preset, elements_to_count, distance_bins, rdkit_prefix)

dims = molecule.dimensions
centroid = molecule.centroid
center_of_mass = molecule.center_of_mass
desc.update({
"centroid_x": float(centroid[0]),
"centroid_y": float(centroid[1]),
"centroid_z": float(centroid[2]),
"center_of_mass_x": float(center_of_mass[0]),
"center_of_mass_y": float(center_of_mass[1]),
"center_of_mass_z": float(center_of_mass[2]),
"radius_of_gyration": molecule.radius_of_gyration,
"dim_x": float(dims[0]),
"dim_y": float(dims[1]),
Expand Down Expand Up @@ -462,12 +454,6 @@ def flatten_descriptors(desc: dict) -> dict[str, float]:

def _empty_descriptors(desc: dict, distance_bins: int) -> dict:
desc.update({
"centroid_x": 0.0,
"centroid_y": 0.0,
"centroid_z": 0.0,
"center_of_mass_x": 0.0,
"center_of_mass_y": 0.0,
"center_of_mass_z": 0.0,
"radius_of_gyration": 0.0,
"dim_x": 0.0,
"dim_y": 0.0,
Expand Down Expand Up @@ -674,12 +660,6 @@ def _preset_scalar_names(preset: str, elements_to_count, rdkit_prefix: str) -> l
]
if preset == "native-3d":
names += [
"centroid_x",
"centroid_y",
"centroid_z",
"center_of_mass_x",
"center_of_mass_y",
"center_of_mass_z",
"shape_anisotropy",
"asphericity",
"acylindricity",
Expand Down
14 changes: 14 additions & 0 deletions tests/test_descriptors.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,20 @@ def test_native_3d_preset_includes_shape_descriptors():
assert "asphericity" not in water().descriptors(preset="native-basic")


def test_native_3d_omits_pose_variant_absolute_coordinates():
# Absolute centroid / centre-of-mass coordinates are translation- and
# rotation-variant, so they were dropped from the ML feature table.
desc = water().descriptors(preset="native-3d")
abs_cols = {
"centroid_x", "centroid_y", "centroid_z",
"center_of_mass_x", "center_of_mass_y", "center_of_mass_z",
}
assert abs_cols.isdisjoint(desc)
assert abs_cols.isdisjoint(descriptor_feature_names("native-3d"))
# The default (preset=None) output drops them too, not just the named preset.
assert abs_cols.isdisjoint(water().descriptors())


def test_flatten_descriptors_expands_vector_features():
flat = flatten_descriptors({"n_atoms": 3.0, "principal_moments": [1.0, 2.0, 3.0]})
assert flat == {
Expand Down