LempelZiv

LZ76 complexity: how much a signal repeats itself.

LempelZiv py
data
complexity
Type name
signal:LempelZiv
Plane
signal
Tags
analysis
Language
python
Tier
in-process
Bundle
complexity
Source
node-bundles/complexity/lempel_ziv.py
Availability
available

Slots

SlotDirectionType
datainputARRAY
complexityoutputARRAY

Parameters

lz

NameTypeDefaultRangeDoc
thresholdstringmedianmedian | meanWhat each sample is called high or low against before the sequence is counted.
normalizebooltrueDivide by the complexity a random sequence of the same length would have.

common

NameTypeDefaultRangeDoc
autotriggerboolfalseRun on the node's own schedule, instead of waiting for an input frame. Turn this on for sources; leave it off for transforms driven by their input.
max_frequencyfloat00 … 100Rate cap for this node, read through `frequency_mode`. 0 means uncapped — the node runs as often as the scheduler and its inputs allow.
frequency_modestringupdates_per_secondupdates_per_second | seconds_per_updateHow to read `max_frequency`: as a rate in Hz (updates per second), or as a period in seconds between updates — convenient for very slow nodes.

Source

The current source of this node, as it stands in the goofi repository at node-bundles/complexity/lempel_ziv.py.

node-bundles/complexity/lempel_ziv.py
"""LempelZiv — LZ76 complexity, the EEG regularity measure, from antropy.

The last axis is time and it is what the measure consumes: `[C, T]` in, `[C]` out. Every axis
before it survives, because a complexity per channel is still a value per channel.
"""

import antropy
import numpy as np
import goofi


class LempelZiv(goofi.Node):
    """LZ76 complexity: how much a signal repeats itself."""

    TAGS = ["analysis"]
    INPUTS = {"data": goofi.InputSlot(goofi.DataType.ARRAY, required=True)}
    OUTPUTS = {"complexity": goofi.DataType.ARRAY}
    PARAMS = {
        "lz": {
            "threshold": goofi.StringParam(
                "median",
                ["median", "mean"],
                doc="What each sample is called high or low against before the sequence is counted.",
            ),
            "normalize": goofi.BoolParam(
                True, doc="Divide by the complexity a random sequence of the same length would have."
            ),
        }
    }

    def process(self, data):
        p = self.params.lz

        def lz(x):
            level = np.median(x) if p.threshold == "median" else np.mean(x)
            return antropy.lziv_complexity((x > level).astype(int), normalize=p.normalize)

        x = np.asarray(data.data, dtype=np.float64)
        return np.apply_along_axis(lz, -1, x).astype(np.float32)

← All nodes

This reference describes goofi 3.1.0(537cd394), generated from a running instance on 2026-09-06.