Skip to content

sgnts.transforms.sumindex

SumIndex dataclass

Bases: TSTransform


              flowchart TD
              sgnts.transforms.sumindex.SumIndex[SumIndex]
              sgnts.base.base.TSTransform[TSTransform]
              sgnts.base.base.TimeSeriesMixin[TimeSeriesMixin]

                              sgnts.base.base.TSTransform --> sgnts.transforms.sumindex.SumIndex
                                sgnts.base.base.TimeSeriesMixin --> sgnts.base.base.TSTransform
                



              click sgnts.transforms.sumindex.SumIndex href "" "sgnts.transforms.sumindex.SumIndex"
              click sgnts.base.base.TSTransform href "" "sgnts.base.base.TSTransform"
              click sgnts.base.base.TimeSeriesMixin href "" "sgnts.base.base.TimeSeriesMixin"
            

Sum array values over slices in the zero-th dimension.

Parameters:

Name Type Description Default
sl list[slice]

list[slice], the slices to sum over

required
Notes

Thread safety: Marked thread_safe = True. Pad layout: 1 sink + 1 source (@transform.one_to_one). No same-element pull/new concurrency. internal runs alone.

``pull`` (inherited): per-pad-keyed dict writes. ``new``
(inherited): read-only lookup. ``process``: NumPy
``sum``/``stack`` (release the GIL for large arrays) on
local buffers; reads ``self.sl`` (post-init read-only).

**Future editors MUST preserve thread safety**: do not
relax the one-to-one constraint without re-auditing.
Keep ``process`` purely functional on its inputs.
Source code in src/sgnts/transforms/sumindex.py
@dataclass(kw_only=True)
class SumIndex(TSTransform):
    """Sum array values over slices in the zero-th dimension.

    Args:
        sl:
            list[slice], the slices to sum over

    Notes:
        Thread safety:
            Marked ``thread_safe = True``. Pad layout: 1 sink + 1
            source (``@transform.one_to_one``). No same-element
            ``pull``/``new`` concurrency. ``internal`` runs alone.

            ``pull`` (inherited): per-pad-keyed dict writes. ``new``
            (inherited): read-only lookup. ``process``: NumPy
            ``sum``/``stack`` (release the GIL for large arrays) on
            local buffers; reads ``self.sl`` (post-init read-only).

            **Future editors MUST preserve thread safety**: do not
            relax the one-to-one constraint without re-auditing.
            Keep ``process`` purely functional on its inputs.
    """

    thread_safe = True

    # sum / stack are standard-xp ops; works in any namespace.
    backends = ANY_BACKEND

    sl: list[slice]

    @validator.one_to_one
    def validate(self) -> None:
        for sl in self.sl:
            assert isinstance(sl, slice)

    @transform.one_to_one
    def process(self, input_frame: TSFrame, output_frame: TSCollectFrame) -> None:
        """Sum array values over slices."""
        for buf in input_frame:
            if buf.is_gap:
                data = None
                shape = (len(self.sl),) + buf.shape[-2:]
            else:
                xp = array_namespace(buf.data)
                assert xp is not None
                data_all = []
                for sl in self.sl:
                    if sl.stop - sl.start == 1:
                        data_all.append((buf.data[sl.start, :, :]))
                    else:
                        data_all.append(xp.sum(buf.data[sl, :, :], axis=0))

                data = xp.stack(data_all)
                shape = data.shape

            buf = buf.copy(data=data, shape=shape)
            output_frame.append(buf)

process(input_frame, output_frame)

Sum array values over slices.

Source code in src/sgnts/transforms/sumindex.py
@transform.one_to_one
def process(self, input_frame: TSFrame, output_frame: TSCollectFrame) -> None:
    """Sum array values over slices."""
    for buf in input_frame:
        if buf.is_gap:
            data = None
            shape = (len(self.sl),) + buf.shape[-2:]
        else:
            xp = array_namespace(buf.data)
            assert xp is not None
            data_all = []
            for sl in self.sl:
                if sl.stop - sl.start == 1:
                    data_all.append((buf.data[sl.start, :, :]))
                else:
                    data_all.append(xp.sum(buf.data[sl, :, :], axis=0))

            data = xp.stack(data_all)
            shape = data.shape

        buf = buf.copy(data=data, shape=shape)
        output_frame.append(buf)