NormalizeCoord#

class NormalizeCoord(center=None, scale=None)[source]#

Bases: object

Recenter and rescale coord into a normalized frame.

Computes coord = (coord - center) / scale in place. When center is None the per-sample centroid (mean of coord) is used; when scale is None the max point norm after centering is used, mapping the cloud into the unit ball. The same shift/scale is applied to v3 vertex metadata and to opt-in aux_position_keys so position targets stay aligned; direction keys are left untouched (isotropic scale + translation preserve orientation). Requires coord; a no-op if coord is absent. Registered as NormalizeCoord – use this string as the type in a transform=[...] config list.

Parameters:
  • center (Sequence[float], optional) – fixed center to subtract. If None, the per-sample centroid is used. Defaults to None.

  • scale (float, optional) – fixed divisor applied after centering. If None, the max post-centering point norm is used (unit ball). Defaults to None.

Note

NormalizeCoord(scale=X) computes (coord - center) / scale – it divides by X, it does not multiply. For PILArNet the standard fixed values are center=[384, 384, 384] and scale = 768 * sqrt(3) / 2 approx 665.1076 (the half-diagonal of the 768^3 volume), mapping the detector into roughly [-1, 1]^3.

Example

>>> import numpy as np
>>> from pimm.datasets.transform import NormalizeCoord
>>> data = {"coord": np.array([[0., 0., 0.], [1000., 0., 0.]], dtype="f4"),
...         "energy": np.array([[1.], [5.]], dtype="f4")}
>>> out = NormalizeCoord(center=[500., 0., 0.], scale=500.)(data)
>>> out["coord"]  # (coord - center) / scale: [0,1000] -> [-1,1]
array([[-1.,  0.,  0.],
       [ 1.,  0.,  0.]], dtype=float32)