spacr.condition_annotations

Reproducible condition labels on an unchanged source table.

Assignments use content-bound positional row tokens, never pandas index labels or the sorted/filtered row number shown by a view. Definitions retain their source, selected table, schema, full ordered content fingerprint, metadata rules, and manually selected tokens. A changed source is refused before any labels are applied. Source measurements are never overwritten.

Version 1 defines one label column. Version 2 defines ordered label columns and combinations. Version 3 also extracts text with regular expressions, tests metadata with readable comparison rules, and composes values from ordered column references and fixed text. Each output may use source columns and earlier outputs, but cannot replace a source column.

Exceptions

AnnotationError

An invalid condition rule, ambiguous assignment or changed source.

Classes

ConditionPreview

Validated membership counts and row labels before application.

Functions

annotation_columns(definition)

Return the ordered output names from a legacy definition or recipe.

apply_conditions(frame, definition, source)

Return a labelled copy after source and overlap validation succeeds.

new_definition(frame, source, *[, column])

Create an unassigned condition definition for exactly this source snapshot.

preview(frame, definition, source)

Evaluate ordered outputs and report conflicts without changing source data.

save_annotated_table(path, name, frame, definition, ...)

Atomically save a new physical table plus its source and editable rules.

saved_table_annotation(path, name, frame)

Recover editable rules only when a saved physical table is unchanged.

source_context([path, table, merge_definition])

Identify the source without treating a derived table as a physical one.

table_identity(frame)

Hash table values efficiently while ignoring mutable pandas index labels.

Module Contents

exception spacr.condition_annotations.AnnotationError[source]

Bases: ValueError

An invalid condition rule, ambiguous assignment or changed source.

Initialize self. See help(type(self)) for accurate signature.

class spacr.condition_annotations.ConditionPreview[source]

Validated membership counts and row labels before application.

Parameters:
  • values – Final output labels in source row order; conflicts are diagnostic.

  • counts – Final output row counts per distinct label.

  • unmatched – Rows missing a value in the final output.

  • overlaps – Union of positions assigned different labels within any output.

  • column_values – Candidate values for every ordered output column.

  • column_previews – Per-column membership and conflict reports.

  • rule_counts – Individual rule counts before same-label unions.

spacr.condition_annotations.annotation_columns(definition)[source]

Return the ordered output names from a legacy definition or recipe.

Parameters:

definition – Version 1 condition definition, or an ordered column recipe using version 2 or 3.

Returns:

Distinct, nonempty output names in recipe order.

spacr.condition_annotations.apply_conditions(frame, definition, source)[source]

Return a labelled copy after source and overlap validation succeeds.

Parameters:
  • frame – Original source frame.

  • definition – Complete condition configuration.

  • source – Current source context.

Returns:

Copy with every requested output column; original remains unchanged.

Values are assigned by position, never by Series index alignment: duplicated pandas indices are legal input and play no role in condition identity.

spacr.condition_annotations.new_definition(frame, source, *, column='condition')[source]

Create an unassigned condition definition for exactly this source snapshot.

Parameters:
  • frame – Original source frame.

  • source – Identity returned by source_context.

  • column – New output column name.

Returns:

Reproducible JSON-compatible annotation definition.

spacr.condition_annotations.preview(frame, definition, source)[source]

Evaluate ordered outputs and report conflicts without changing source data.

Regex or exact-value includes select metadata rows. Manual row assignments join those selections, and excludes remove matches, including manual rows. In versions 2 and 3, combine selections that assign the same label. Different labels assigned to one row within a column remain conflicts.

Version 3 criteria can require all comparisons or any comparison to match. Supported comparisons include literal containment, equality, prefixes, suffixes, and regular expressions. Containment, equality, and regex comparisons also have negative forms. Missing metadata never matches, including negative comparisons. Matching is case-sensitive unless a regex explicitly changes that behavior. Criteria for containment, prefixes, suffixes, and regex matching require nonempty comparison text.

An empty legacy regex Include field selects no rows. This allows a rule that assigns only its manually selected rows; an empty regex criterion in version 3 is invalid.

Version 3 extraction searches each value for the first regex match. Return the selected numbered or named capture group; group zero returns the entire match. An absent match or empty capture produces a missing value.

Combinations join columns with a separator. Version 3 templates concatenate ordered column references and fixed text. An empty or missing column value makes the composed result missing. A template that produces empty text is also missing. Outputs may reference source columns and earlier outputs only.

Parameters:
  • frame – Original source frame, not a previously annotated copy.

  • definition – Saved version 1 rules, or an ordered version 2 or 3 recipe.

  • source – Current file/table/merge identity.

Returns:

ConditionPreview with all outputs and per-column diagnostics.

spacr.condition_annotations.save_annotated_table(path, name, frame, definition, source, *, merge_definition=None)[source]

Atomically save a new physical table plus its source and editable rules.

Parameters:
  • path – Existing SQLite source database, never a delimited input file.

  • name – New table name; physical, view and saved-derived collisions fail.

  • frame – Working frame including every annotation output column.

  • definition – Validated annotation rules used for the working frame.

  • source – Original annotation source context.

  • merge_definition – Original merged-source configuration, if applicable.

Returns:

Saved table name. A failure rolls back both table and provenance.

Reserved metadata is validated before the user table is created, so a conflicting unrelated table is never silently repurposed as the receipt store. Reopening and editing are bound to what SQLite actually stored, including dtype normalization, rather than assuming a pandas to SQL round trip is lossless.

spacr.condition_annotations.saved_table_annotation(path, name, frame)[source]

Recover editable rules only when a saved physical table is unchanged.

Parameters:
  • path – SQLite source database opened read-only.

  • name – Physical table name.

  • frame – Actual stored table including every annotation output column.

Returns:

Editable annotation definition or None for an ordinary table.

spacr.condition_annotations.source_context(path=None, table=None, merge_definition=None)[source]

Identify the source without treating a derived table as a physical one.

Parameters:
  • path – Source file, or None for an in-memory table.

  • table – Selected table name; None for a delimited file.

  • merge_definition – Reproduction configuration for a derived table.

Returns:

JSON-compatible source identity.

spacr.condition_annotations.table_identity(frame)[source]

Hash table values efficiently while ignoring mutable pandas index labels.

Parameters:

frame – Original unannotated source frame.

Returns:

Schema, ordered content digest, and opaque per-row tokens.

Hashing is vectorized so large measurement tables stay practical; the final digest binds every row, in order, to the schema and the source definition.

Nested helpers

_extract_preview.extract(value)

The captured group for one value, or NA when nothing matched.

spacr/condition_annotations.py:321

save_annotated_table.scalar(value)

One value as plain JSON: ISO dates, Python numbers, None for blanks.

spacr/condition_annotations.py:678