Skip to content

Implement BuildCompiler.plating with SBOL provenance, protocol artifacts, and robot helpers#50

Merged
Gonza10V merged 1 commit into
full_buildfrom
codex/implement-buildcompiler.plating-method
Apr 28, 2026
Merged

Implement BuildCompiler.plating with SBOL provenance, protocol artifacts, and robot helpers#50
Gonza10V merged 1 commit into
full_buildfrom
codex/implement-buildcompiler.plating-method

Conversation

@Gonza10V
Copy link
Copy Markdown
Contributor

Motivation

  • Provide a deterministic plating stage that consumes transformation(...) output (or simplified plating inputs) and produces a single solid 96-well plate with SBOL provenance and protocol artifacts.
  • Produce both human/manual protocols and PUDU/Opentrons automated scripts plus optional simulation output so plating can be integrated into automated build pipelines.
  • Keep core package Python requirement unchanged while exposing automation-only dependencies to users who need them.

Description

  • Added BuildCompiler.plating(...) which normalizes inputs, enforces a 96-sample capacity, places strains in deterministic row-major wells (A1H12), and returns a structured plating result dict.
  • Created SBOL provenance for plating: an Activity, Usage entries (one per transformed strain), a protocol-mode Agent, a Plan, and an Association linking activity↔agent↔plan; plated Implementations are created and annotated where possible.
  • Implemented robot/IO helpers in src/buildcompiler/robotutils.py: load_json_or_dict, normalize_plating_input, generate_96_well_positions, write_plate_map_json, write_plate_map_csv, write_manual_plating_protocol, write_plating_protocol_script, and run_opentrons_script_to_zip.
  • Added a stable plating role constant PLATING_ACTIVITY_ROLE in src/buildcompiler/constants.py and best-effort SBOLInventory integration (optional import) with an internal fallback so plating still works if SBOLInventory is not installed.
  • Updated pyproject.toml to add an optional automation dependency group (pudupy, opentrons, and SBOLInventory with python_version >= '3.10') to avoid forcing a global Python version bump.
  • Added unit tests in tests/test_plating.py covering normalization, well mapping/capacity, SBOL provenance, manual protocol artifacts, automated script content (ensuring json_params=), and simulation packaging using a mocked subprocess.

Testing

  • Ran unit tests: pytest -q tests/test_plating.py tests/test_buildcompiler_transformation.py and all tests passed (7 passed).
  • Verified automated-script generation includes def run(protocol: protocol_api.ProtocolContext):, imports protocol_api, and uses Plating(..., json_params=ADVANCED_PARAMS) (not advanced_params=) via tests.
  • Attempted to install SBOLInventory in the environment for integration testing but network/git access failed (GitHub clone returned a 403), so SBOLInventory support is implemented as optional and gracefully falls back when unavailable.

Codex Task

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6bce1f03ef

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +48 to +49
for idx, well in enumerate(sorted(payload["strain_locations"]), start=1):
impl_uri = payload["strain_locations"][well]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve well order numerically when normalizing location maps

Sorting well keys as plain strings reorders 96-well coordinates incorrectly (for example, A10 is processed before A2). Since plating() then assigns destination wells by normalized list order, this can silently remap strains to the wrong plate positions in generated plate maps/protocols whenever strain_locations (and similarly bacterium_locations) includes columns 10–12.

Useful? React with 👍 / 👎.

Comment on lines +227 to +231
proc = subprocess.run(
["opentrons_simulate", str(tmp_script)],
capture_output=True,
text=True,
cwd=tmpdir,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Raise when opentrons simulation exits with failure

The simulation subprocess return code is captured but never checked, so failed opentrons_simulate runs still produce a ZIP artifact and are reported as successful by plating() (no exception is raised, so no skip log is emitted). This can mark invalid automated protocols as if they were successfully simulated, which is misleading in CI or production build workflows.

Useful? React with 👍 / 👎.

@Gonza10V Gonza10V merged commit 873ed74 into full_build Apr 28, 2026
0 of 4 checks passed
@Gonza10V Gonza10V deleted the codex/implement-buildcompiler.plating-method branch April 28, 2026 05:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant