spacr.qt.widgets.plate_layout

Design plate layouts and validate position-related experimental risks.

The module produces a single well-level artifact for acquisition and analysis. It uses spacr.schema identifiers such as r3, c7, and C07, allowing exported layouts to join measurement tables on (rowID, columnID) without a translation step.

check_design() identifies conditions or controls that are confounded with rows, columns, or edge wells. Edge-only placement is flagged because evaporation and thermal gradients can make the outer ring systematically different from the plate interior.

Randomized layouts cannot be represented by the whole-row and whole-column vocabulary accepted by spacr.utils.annotate_conditions. to_settings_fragment() therefore refuses to approximate them; the long-form well table remains the authoritative representation.

Classes

Condition

One thing being put on the plate.

DesignFinding

One thing worth knowing before the plate is poured.

PlateDesign

A plate map before the plate exists.

PlateTemplate

A ready-made design, shipped with spaCR, that a user starts from.

Functions

assign_wells(→ pandas.DataFrame)

Place every condition's replicates on the plate.

check_design(→ List[DesignFinding])

Everything worth saying about a design before it is acquired.

design_from_record(→ PlateDesign)

Rebuild a PlateDesign from the mapping plate_map.json holds.

format_findings(→ str)

Findings as plain text, worst first.

is_edge(→ bool)

Whether a 1-based (row, column) is in the plate's outer ring.

plate_shape(→ Tuple[int, int])

(n_rows, n_columns) for a well count.

plate_templates(→ List[PlateTemplate])

The layouts shipped in spacr/resources/plate_templates, in order.

to_settings_fragment(→ Dict[str, Any])

The design as the settings keys the analysis modules already read.

write_design(→ Dict[str, pathlib.Path])

Write the design where the pipeline and the plate handler can read it.

Module Contents

class spacr.qt.widgets.plate_layout.Condition[source]

One thing being put on the plate.

Variables:
  • name – label written into the exported table. Becomes the value of treatment (or host_cells/pathogen) downstream.

  • replicates – how many wells it gets.

  • role – one of ROLES.

class spacr.qt.widgets.plate_layout.DesignFinding[source]

One thing worth knowing before the plate is poured.

Variables:
  • key – stable identifier, for tests and for the exported record.

  • severity – "error" (the design cannot be laid out), "warn" (it can, and it will cost you), or "note".

  • message – one sentence, naming the wells involved where that helps.

class spacr.qt.widgets.plate_layout.PlateDesign[source]

A plate map before the plate exists.

Variables:
  • plate_id – the plate’s name. Written into plateID and must match the one the image file names will carry, or the exported table will not join to the measurements.

  • plate_format – well count; a key of PLATE_FORMATS.

  • conditions – what goes on it.

  • layout – one of LAYOUTS.

  • edge_policy – EDGE_USE or EDGE_LEAVE_EMPTY.

  • seed – makes random reproducible. A layout nobody can regenerate is a layout nobody can check, and the plate map is the one record that has to survive the person who made it.

property shape: Tuple[int, int][source]

(n_rows, n_columns).

property wells_available: int[source]

Wells the edge policy leaves usable.

property wells_requested: int[source]

Total wells the conditions ask for.

class spacr.qt.widgets.plate_layout.PlateTemplate[source]

A ready-made design, shipped with spaCR, that a user starts from.

Variables:
  • key – the file’s stem, stable across releases, e.g. 04_384_crispr_screen. The numeric prefix fixes the menu order.

  • title – the menu entry.

  • description – what the layout is for and what its findings mean.

  • design – the design itself; loading a template replaces the form with it apart from the plate name, which stays the user’s.

spacr.qt.widgets.plate_layout.assign_wells(design: PlateDesign) → pandas.DataFrame[source]

Place every condition’s replicates on the plate.

Parameters:

design – the design.

Returns:

one row per assigned well, with columns plateID, well, rowID, columnID, row_index, column_index, condition, role, replicate and is_edge. The ids are spacr.schema’s, so the frame joins to a measurements table on (plateID, rowID, columnID).

Raises:

ValueError – when the conditions need more wells than the plate and the edge policy leave usable. Refused rather than truncated: a silently dropped replicate is a plate that does not match its own map.

spacr.qt.widgets.plate_layout.check_design(design: PlateDesign, table: pandas.DataFrame | None = None) → List[DesignFinding][source]

Everything worth saying about a design before it is acquired.

Ordered worst first. An empty list means nothing was found, which is not the same as the design being good – there is no check here for whether the biology makes sense.

Parameters:
  • design – the design.

  • table – its assignment, from assign_wells(). Computed if omitted; pass it in when it has already been built.

Returns:

findings, "error" before "warn" before "note".

spacr.qt.widgets.plate_layout.design_from_record(record: Dict[str, Any]) → PlateDesign[source]

Rebuild a PlateDesign from the mapping plate_map.json holds.

The same keys write_design() writes, so an exported design and a shipped template are read by one function. Missing keys take the PlateDesign defaults; findings and well counts in the record are ignored, because they are recomputed from the design.

Parameters:

record – the mapping.

Returns:

the design.

Raises:

ValueError – when a condition or the design is invalid, with the message the dataclass gives.

spacr.qt.widgets.plate_layout.format_findings(findings: Sequence[DesignFinding]) → str[source]

Findings as plain text, worst first.

Parameters:

findings – layout findings, one output line each in the order given, prefixed STOP, ! or - by severity; an empty sequence gives the no-problems sentence.

spacr.qt.widgets.plate_layout.is_edge(row: int, column: int, n_rows: int, n_columns: int) → bool[source]

Whether a 1-based (row, column) is in the plate’s outer ring.

Parameters:
  • row – 1-based plate row.

  • column – 1-based plate column.

  • n_rows – number of rows on the plate.

  • n_columns – number of columns on the plate.

spacr.qt.widgets.plate_layout.plate_shape(plate_format: int) → Tuple[int, int][source]

(n_rows, n_columns) for a well count.

Parameters:

plate_format – number of wells: 6, 12, 24, 48, 96, 384 or 1536; any other value raises ValueError.

spacr.qt.widgets.plate_layout.plate_templates() → List[PlateTemplate][source]

The layouts shipped in spacr/resources/plate_templates, in order.

Read from package data on every call; the folder holds a handful of small files and is only read when Experiment Design builds its menu. A file that does not parse is skipped rather than raised: one bad template must not take the others off the menu.

Returns:

every template that loaded, sorted by key.

spacr.qt.widgets.plate_layout.to_settings_fragment(design: PlateDesign, table: pandas.DataFrame | None = None, *, key: str = 'treatment') → Dict[str, Any][source]

The design as the settings keys the analysis modules already read.

spacr.utils.annotate_conditions maps a condition onto wells through row and column ids, so this can only be produced when each condition occupies whole rows or whole columns. A random layout cannot be written that way, and this returns expressible=False with the reason rather than an approximation that would mislabel wells.

Parameters:
  • design – the design.

  • table – its assignment; computed if omitted.

  • key – which settings family to fill – "treatment", "cell" or "pathogen".

Returns:

{"expressible": bool, "reason": str, "settings": {...}}. settings holds <key>s and <key>_plate_metadata plus positive_control/negative_control when those roles are used.

spacr.qt.widgets.plate_layout.write_design(design: PlateDesign, folder: Any, *, table: pandas.DataFrame | None = None) → Dict[str, pathlib.Path][source]

Write the design where the pipeline and the plate handler can read it.

Three files, because they have three readers:

  • plate_map.csv – one row per well, keyed by (plateID, rowID, columnID). The artifact: it joins straight onto a measurements table and it survives a randomised layout, which the settings fragment does not.

  • plate_map.json – the design itself plus its findings, so the layout can be regenerated and so the warnings that were shown are on the record rather than only on somebody’s screen.

  • plate_map_settings.json – the treatments / treatment_plate_metadata pair to paste into an analysis settings file, when the layout can be expressed that way.

Parameters:
  • design – the design.

  • folder – destination directory; created if absent.

  • table – its assignment; computed if omitted.

Returns:

{name: path} for every file written.