Skip to content

performance_loss

performance_loss ¤

Performance/speed loss tracking.

Track when machine runs slower than ideal/target speed: - Identify slow periods vs target cycle time - Calculate performance loss in minutes and parts - Performance trend over time

PerformanceLossEvents ¤

PerformanceLossEvents(
    dataframe: DataFrame,
    *,
    time_column: str = "systime",
    shift_definitions: (
        dict[str, tuple[str, str]] | None
    ) = None,
    event_uuid: str = "prod:performance_loss"
)

Bases: Base

Track performance and speed losses against target cycle times.

Identifies hidden losses where the machine is running but slower than it should be. Typically 10-20% of production time is lost to speed losses.

Each method takes one signal: - cycle_uuid: cycle trigger or production counter

All methods compare against a single target_cycle_time; there are no per-part targets.

Definitions follow ISO 22400-2: actual_parts is the produced quantity (the sum of reset-aware counter increments, so a counter that steps by 2 counts 2 parts; for a trigger signal one part per row), run_seconds is the running time the parts were made in (the summed intervals between producing readings, minus any dropped by max_cycle_gap), avg_cycle_time_seconds = run_seconds / actual_parts and performance_pct = target_cycle_time x actual_parts / run_seconds x 100. The speed loss is run_seconds - actual_parts x target_cycle_time. Durations are in seconds (*_seconds); loss_minutes and the *_s cycle time columns are kept as a convenience. For a line that runs several part numbers, filter the data to one part (or one product run) per call.

Merge keys: [date, shift] for shift-level, [period] for trend data.

Pipeline example::

perf = PerformanceLossEvents(df)
shift_perf = perf.performance_by_shift('cycle', target_cycle_time=45)
# → merge with DowntimeEvents.downtime_by_shift() on [date, shift]
# → merge with QualityEvents.nok_by_shift() on [date, shift]
# → feed into ShiftHandoverEvents.from_shift_data()
Example usage

tracker = PerformanceLossEvents(df)

Performance by shift¤

perf = tracker.performance_by_shift( cycle_uuid='cycle_trigger', target_cycle_time=45.0, )

Identify slow periods¤

slow = tracker.slow_periods( cycle_uuid='cycle_trigger', target_cycle_time=45.0, threshold_pct=90, )

Initialize the performance-loss tracker.

Parameters:

Name Type Description Default
dataframe DataFrame

Input DataFrame with timeseries data.

required
time_column str

Name of timestamp column (default: 'systime').

'systime'
shift_definitions dict[str, tuple[str, str]] | None

Mapping of shift name to (start, end) times. Default: 3-shift operation (06:00-14:00, 14:00-22:00, 22:00-06:00).

None
event_uuid str

UUID tagged on derived interval events (the uuid column of :meth:slow_periods; default: 'prod:performance_loss').

'prod:performance_loss'

performance_by_shift ¤

performance_by_shift(
    cycle_uuid: str,
    target_cycle_time: float,
    *,
    value_column: str = "value_integer",
    max_cycle_gap: str | None = None,
    production_day: bool = True
) -> pd.DataFrame

Calculate performance percentage per shift.

Performance = (target_cycle_time * actual_parts) / run_seconds, with actual_parts the produced quantity (counter increments).

Parameters:

Name Type Description Default
cycle_uuid str

UUID of cycle trigger or counter signal.

required
target_cycle_time float

Target (ideal) cycle time in seconds.

required
value_column str

Column with counter values.

'value_integer'
max_cycle_gap str | None

Optional cap (e.g. "5min"). Intervals longer than this are treated as stoppages and excluded, so a break or downtime is not counted as slow-running time (which would otherwise report a large, spurious speed loss).

None
production_day bool

Attribute an overnight shift's post-midnight readings to the shift's start date, so a night shift is one (date, shift) row (default). False groups by raw calendar date, which splits a night shift across two rows.

True

Returns:

Type Description
DataFrame

DataFrame with columns:

DataFrame
  • start, end, duration_seconds: the shift window from shift_definitions (tz-aware in the data's tz; an overnight shift ends on the next day)
DataFrame
  • date, shift, actual_parts, avg_cycle_time_s, avg_cycle_time_seconds, target_cycle_time_s, target_cycle_time_seconds, performance_pct, loss_minutes, loss_seconds
DataFrame
  • run_seconds: running time of the shift (the basis of performance_pct)
DataFrame

avg_cycle_time_s / target_cycle_time_s / loss_minutes

DataFrame

are convenience duplicates of the *_seconds columns.

slow_periods ¤

slow_periods(
    cycle_uuid: str,
    target_cycle_time: float,
    *,
    threshold_pct: float = 90.0,
    window: str = "1h",
    value_column: str = "value_integer",
    max_cycle_gap: str | None = None
) -> pd.DataFrame

Identify time windows where performance is below threshold.

Parameters:

Name Type Description Default
cycle_uuid str

UUID of cycle trigger or counter signal.

required
target_cycle_time float

Target cycle time in seconds.

required
threshold_pct float

Performance must be below this to flag (default 90%).

90.0
window str

Fixed time window per row (default '1h').

'1h'
value_column str

Column with counter values.

'value_integer'
max_cycle_gap str | None

Optional cap (e.g. "5min"). Cycle intervals longer than it are dropped as stops instead of counted as slow cycles. None keeps every interval.

None

Returns:

Type Description
DataFrame

DataFrame with columns:

DataFrame
  • start, end, duration_seconds (float seconds, end - start), uuid (event uuid), source_uuid (cycle_uuid), actual_parts, avg_cycle_time_s, avg_cycle_time_seconds, performance_pct, loss_minutes, loss_seconds
DataFrame
  • run_seconds: running time in the window (the basis of performance_pct)

performance_trend ¤

performance_trend(
    cycle_uuid: str,
    target_cycle_time: float,
    *,
    window: str = "1D",
    value_column: str = "value_integer",
    max_cycle_gap: str | None = None
) -> pd.DataFrame

Track performance trend over time.

Parameters:

Name Type Description Default
cycle_uuid str

UUID of cycle trigger or counter signal.

required
target_cycle_time float

Target cycle time in seconds.

required
window str

Time window for aggregation (default '1D').

'1D'
value_column str

Column with counter values.

'value_integer'
max_cycle_gap str | None

Optional cap (e.g. "5min"). Cycle intervals longer than it are dropped as stops instead of counted as slow cycles. None keeps every interval.

None

Returns:

Type Description
DataFrame

DataFrame with columns:

DataFrame
  • start, end (start + window), duration_seconds
DataFrame
  • period, actual_parts, avg_cycle_time_s, avg_cycle_time_seconds, performance_pct, loss_minutes, loss_seconds
DataFrame
  • run_seconds: running time in the period (the basis of performance_pct)