Skip to content

New snippet for tiff/http: empiar-10553-gemmata-fib-sem-membranes - #51

Open
mia-autodev[bot] wants to merge 2 commits into
mainfrom
snippets/issue-43
Open

mia-autodev[bot] wants to merge 2 commits into
mainfrom
snippets/issue-43

Conversation

@mia-autodev

@mia-autodev mia-autodev Bot commented Nov 10, 2026

Copy link
Copy Markdown
Contributor

Closes #43: For JaneliaSciComp/mia-workflow-data#222: dataset empiar-10553-gemmata-fib-sem-membranes has no snippet that reads it.

Implemented by snippets: Claude Code running in a sandboxed job on the cluster. The agent's own
summary is the first comment.

  • Merge: approve this PR, or comment /approve <head sha> (needed when running under a personal token; a
    trusted worker posts it when the output of this head is approved).
    snippets merges once an approval matches the current head and checks are not failing.
  • Request changes: submit a review with Request changes, or comment /revise <what to change>.
    Up to 3 revision rounds.
  • Stop: close this PR.

…ized to a zyx binary mask

For empiar-10553-gemmata-fib-sem-membranes (issue #43): parses the IMODV1.2 binary
model over io.open, selects one object per model, and fills (even-odd) or outlines
its contours on the model's image grid. Several models of one image are OR-ed.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
@mia-autodev

mia-autodev Bot commented Nov 10, 2026

Copy link
Copy Markdown
Contributor Author

snippets: round 1 pushed f971a6e181bc to snippets/issue-43 · $3.45

Added the imod-model-mask snippet in snippets/imod-model-mask/ (one commit, f971a6e, not pushed); smoke on the example binding passes with no errors.

What it does

  • Reader: parses an IMOD IMODV1.2 binary model through io.open, selects one object, and rasterizes its contours onto the model's own grid as a zyx uint8 {0,1} mask (requires: [numpy]).
  • draw: fill (default) fills closed contours by the even-odd rule; outline marks only the pixels the contour lines pass through.
  • object / objects: object is the 1-based object number. objects (e.g. "2,4") gives one number per URL when several models number the same class differently; the mask is the union.
  • Voxel size: always None. The models' pixel size and z scale are user-entered, and the two models of this one stack disagree (4.49 vs 4.05).

Example binding

Raw is unchanged from the draft (tiff-zip-member). There are four binary labels, each the union of the C1 and C2 models:

label_key objects (C1, C2) draw
manual_gt-cell_envelope-semantic 1, 1 outline
manual_gt-cytoplasmic_membrane-semantic 2, 4 outline
manual_gt-nucleoid-semantic 3, 3 fill
manual_gt-polyphosphate_granule-semantic 4, 2 fill

Testing

  • Smoke (MIA_HARNESS_ALLOWED_HOSTS=ftp.ebi.ac.uk): ok: true, raw and all four labels [470, 1602, 2268], errors: [], bytes_fetched: 12692411. The only warnings are four of label N: dtype uint8 is not the record's ['unknown'], expected because the record has no dtype for polygon labels.
  • Orientation on real data: I overlaid the C1 outlines on raw plane 110 fetched through the harness. They sit on the cell envelope, cytoplasmic membrane and nucleoid, which confirms the y-flip (IMOD's y runs bottom-up) and the 0-based z.
  • Synthetic models (ad hoc, not committed, since a PR may only add the snippet directory): fill with a nested hole, y-flip, z rounding, open-contour outline, multi-model union, sub-region and stepped reads, and each refusal path all pass.
  • CI checker and harness suite: ci/check_pr.py against the base commit exits 0; the harness tests give 222 passed.

For the human reviewer

  • Outline vs fill for the two membrane classes (issue's question b): I chose outline, because the contours trace the membranes and filling them would give the whole cell and the cytoplasm compartments. All contours are closed, so switching to fill is a one-word change per label.
  • C2 model included (question c): its URL is not in technical.sample.urls; I derived it from data.download_url plus the layout tree. I merged both cells into one mask per class because two labels on one raw cannot share a label_key.
  • Kind (question a): the snippet emits one binary mask per class and does not number cells as instances, hence -semantic keys with segmentation_type: binary.
  • Partial coverage: only two cells are modelled, on z 65..158 (C1) and 151..256 (C2). Zero elsewhere means "not annotated", not background.
  • Possibly interpolated contours: 84 of the 94 C1 cell-envelope contours carry contour flag 0x20. I believe this marks interpolator-generated contours but did not confirm it; if so, "manual" there means about 10 drawn sections.

@mia-autodev

mia-autodev Bot commented Nov 10, 2026

Copy link
Copy Markdown
Contributor Author

Crops at f971a6e181bcb14b9de09e57943c5afff6fdd204: passed, 16 of 16 verified (at least 8 needed); the crop job fetched 32615355 bytes.

16 crops
raw overlay caption
raw overlay i222-e35700097552-b0-000 · z=422 c=None · (496, 1757)
raw overlay i222-e35700097552-b0-001 · z=422 c=None · (626, 1972)
raw overlay i222-e35700097552-b0-002 · z=422 c=None · (815, 950)
raw overlay i222-e35700097552-b0-003 · z=113 c=None · (849, 761)
raw overlay i222-e35700097552-b0-004 · z=113 c=None · (233, 1590)
raw overlay i222-e35700097552-b0-005 · z=113 c=None · (1096, 927)
raw overlay i222-e35700097552-b0-006 · z=113 c=None · (1319, 1187)
raw overlay i222-e35700097552-b0-007 · z=252 c=None · (111, 332)
raw overlay i222-e35700097552-b0-008 · z=252 c=None · (697, 1068)
raw overlay i222-e35700097552-b0-009 · z=252 c=None · (857, 178)
raw overlay i222-e35700097552-b0-010 · z=252 c=None · (559, 2007)
raw overlay i222-e35700097552-b0-011 · z=25 c=None · (876, 396)
raw overlay i222-e35700097552-b0-012 · z=25 c=None · (79, 613)
raw overlay i222-e35700097552-b0-013 · z=22 c=None · (628, 1341)
raw overlay i222-e35700097552-b0-014 · z=22 c=None · (1266, 936)
raw overlay i222-e35700097552-b0-015 · z=22 c=None · (626, 1617)

Binding (sha256 5800ce31b9e870fde2eef672c1c142073a89a7c28a9d68a200874c02739954a5):

record: empiar-10553-gemmata-fib-sem-membranes
record_commit: bd965a656de8f35269c064a77912455b3d4058e7
snippets_commit: f971a6e181bcb14b9de09e57943c5afff6fdd204
raw:
- snippet: tiff-zip-member
  urls:
  - https://ftp.ebi.ac.uk/empiar/world_availability/10553/data/Seeger_5_reg.tif
  params: {}
labels:
- snippet: imod-model-mask
  urls:
  - https://ftp.ebi.ac.uk/empiar/world_availability/10553/data/20190819_Gobs_model_C1.mod
  - https://ftp.ebi.ac.uk/empiar/world_availability/10553/data/20190830_Gobs_model_C2.mod
  params:
    objects: 1,1
    draw: outline
  pairs_with: 0
  label_key: manual_gt-cell_envelope-semantic
  segmentation_type: binary
- snippet: imod-model-mask
  urls:
  - https://ftp.ebi.ac.uk/empiar/world_availability/10553/data/20190819_Gobs_model_C1.mod
  - https://ftp.ebi.ac.uk/empiar/world_availability/10553/data/20190830_Gobs_model_C2.mod
  params:
    objects: 2,4
    draw: outline
  pairs_with: 0
  label_key: manual_gt-cytoplasmic_membrane-semantic
  segmentation_type: binary
- snippet: imod-model-mask
  urls:
  - https://ftp.ebi.ac.uk/empiar/world_availability/10553/data/20190819_Gobs_model_C1.mod
  - https://ftp.ebi.ac.uk/empiar/world_availability/10553/data/20190830_Gobs_model_C2.mod
  params:
    objects: 3,3
  pairs_with: 0
  label_key: manual_gt-nucleoid-semantic
  segmentation_type: binary
- snippet: imod-model-mask
  urls:
  - https://ftp.ebi.ac.uk/empiar/world_availability/10553/data/20190819_Gobs_model_C1.mod
  - https://ftp.ebi.ac.uk/empiar/world_availability/10553/data/20190830_Gobs_model_C2.mod
  params:
    objects: 4,2
  pairs_with: 0
  label_key: manual_gt-polyphosphate_granule-semantic
  segmentation_type: binary
reasons:
- 'raw: record technical.arrays[0] is one ImageJ TIFF stack (data/Seeger_5_reg.tif,
  zyx, 470x1602x2268, uint8, uncompressed) at a plain https URL from technical.sample.urls,
  so tiff-zip-member with default params (no axes override)'
- 'labels with imod-model-mask: the record''s label arrays are IMOD binary contour
  models (format other, encoding polygons, ''Contours need rasterizing to masks'');
  both model headers have dims 2268x1602x470, the raw''s grid, so each object rasterizes
  to a zyx 470x1602x2268 mask that pairs with raw 0'
- 'both models in every label: C1 and C2 each outline one cell of the same stack with
  the same four classes, and two labels of one raw cannot share a label_key, so each
  class is one mask that is 1 where either model has it. The C2 URL is not in technical.sample.urls;
  it is data.download_url plus the layout tree''s data/20190830_Gobs_model_C2.mod,
  which path_pattern data/2019*_Gobs_model_C?.mod covers'
- 'objects per class, one number per url (C1, C2), from the OBJT names in the files:
  cell envelope 1,1 (''Cell Envelope'', ''CE (cell1)''); cytoplasmic membrane 2,4
  (''Cytoplasmic Membrane'', ''Cytoplasmic membrane (2)''); nucleoid / DNA 3,3 (''Nucleoid'',
  ''DNA''); large poly-phosphate granule 4,2 (''Large Poly-P granule'', ''Large poly-P
  granule''). The two models order their objects differently, hence objects and not
  object'
- 'draw: outline for cell envelope and cytoplasmic membrane: the contours trace the
  membranes, so the outline is the class the record names; filled they would be the
  whole cell and the cytoplasm (with invaginations as holes). All contours of both
  models are closed, so draw: fill also works: a human should confirm which is wanted
  (the record does not say)'
- 'draw: fill (default) for nucleoid / DNA and the poly-phosphate granule: the contours
  are drawn around bodies, so the class is the enclosed region'
- 'label_keys manual_gt-<class>-semantic with segmentation_type binary: annotations
  are manual (provenance manual_gt), each mask is {0,1} for one class, and binary
  folds to semantic in the key. Encoding ''polygons'' has no kind in the label_key
  rule; the rasterizer emits one binary mask per class and does not number the two
  cells as instances'
- 'coverage is partial: only two cells of the stack are modelled, and only on the
  sections that carry contours (C1 z 65..158, C2 z 151..256); everywhere else the
  masks are 0, which is ''not annotated'', not ''background'''
- 'voxel size: none from either array (TIFF uncalibrated; the snippet does not report
  the models'' pixsize 5 nm and z scales 4.49 / 4.05, which disagree and which the
  record calls unreliable)'

@mia-autodev

mia-autodev Bot commented Nov 14, 2026

Copy link
Copy Markdown
Contributor Author

/revise the crops at f971a6e181bcb14b9de09e57943c5afff6fdd204 failed; make them pass:

Test crops at f971a6e181bcb14b9de09e57943c5afff6fdd204: failed, the PR's example binding was not adopted:

  • snippets/imod-model-mask/examples/empiar-10553-gemmata-fib-sem-membranes.yaml: record_commit 'bd965a656de8f35269c064a77912455b3d4058e7' is not 'b4c57a61ef1f5cde7a19c4bcd5320f909c43f406'

@mia-autodev

mia-autodev Bot commented Nov 14, 2026

Copy link
Copy Markdown
Contributor Author

Round 2 started: agent job 155397226.

The mia-data crops rejected the binding because its record_commit
(bd965a6) was not the record's current commit (b4c57a6).

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
@mia-autodev

mia-autodev Bot commented Nov 14, 2026

Copy link
Copy Markdown
Contributor Author

snippets: round 2 pushed fb9ec63e1e4b to snippets/issue-43 · $0.82

The example binding now pins record_commit to b4c57a61ef1f5cde7a19c4bcd5320f909c43f406, the commit the crops test asked for. It is committed as fb9ec63 and not pushed.

One thing to check before trusting it: I could not read the record at b4c57a6, because GitHub is blocked from this sandbox. The binding's reasons and the smoke run are still based on the record text in the issue (at bd965a6). If the record's content changed between those commits (for example, the C2 model URL being added to technical.sample.urls), the reasons may need a matching edit.

Nothing else changed: the snippet code, snippet.yaml, README, and the rest of the binding are as they were.

Testing

  • Smoke (run from the repo root against ftp.ebi.ac.uk): passed.
    ok: true
    shapes: raw [[470, 1602, 2268]], labels 4 x [470, 1602, 2268]
    errors: []
    warnings: label 0..3: dtype uint8 is not the record's ['unknown']
    bytes_fetched: 12692411
    
    The four warnings are because the record lists the label dtype as unknown.
  • Harness tests: 222 passed, run with python -m pytest in harness/ because pixi is not on PATH here.
  • CI tests: 21 passed.
  • PR check: ci/check_pr.py --base origin/main exits 0, so the PR is still additions-only under snippets/imod-model-mask/.

@mia-autodev

mia-autodev Bot commented Nov 14, 2026

Copy link
Copy Markdown
Contributor Author

Crops at fb9ec63e1e4b8f665dfc8061cb0a10a280f909b0: passed, 16 of 16 verified (at least 8 needed); the crop job fetched 31566779 bytes.

16 crops
raw overlay caption
raw overlay i222-e1794684259261-b0-000 · z=212 c=None · (84, 503)
raw overlay i222-e1794684259261-b0-001 · z=212 c=None · (948, 828)
raw overlay i222-e1794684259261-b0-002 · z=212 c=None · (1160, 1073)
raw overlay i222-e1794684259261-b0-003 · z=366 c=None · (1295, 1177)
raw overlay i222-e1794684259261-b0-004 · z=366 c=None · (204, 7)
raw overlay i222-e1794684259261-b0-005 · z=366 c=None · (1037, 873)
raw overlay i222-e1794684259261-b0-006 · z=366 c=None · (302, 561)
raw overlay i222-e1794684259261-b0-007 · z=272 c=None · (699, 1859)
raw overlay i222-e1794684259261-b0-008 · z=272 c=None · (791, 350)
raw overlay i222-e1794684259261-b0-009 · z=272 c=None · (1135, 1171)
raw overlay i222-e1794684259261-b0-010 · z=272 c=None · (830, 735)
raw overlay i222-e1794684259261-b0-011 · z=67 c=None · (738, 1654)
raw overlay i222-e1794684259261-b0-012 · z=67 c=None · (679, 478)
raw overlay i222-e1794684259261-b0-013 · z=67 c=None · (294, 1727)
raw overlay i222-e1794684259261-b0-014 · z=67 c=None · (880, 469)
raw overlay i222-e1794684259261-b0-015 · z=1 c=None · (1301, 1191)

Binding (sha256 5bd3f05e3d1132ac5f7874629a441a332bb8b08bd559e94ddd2130a1a23930e8):

record: empiar-10553-gemmata-fib-sem-membranes
record_commit: b4c57a61ef1f5cde7a19c4bcd5320f909c43f406
snippets_commit: fb9ec63e1e4b8f665dfc8061cb0a10a280f909b0
raw:
- snippet: tiff-zip-member
  urls:
  - https://ftp.ebi.ac.uk/empiar/world_availability/10553/data/Seeger_5_reg.tif
  params: {}
labels:
- snippet: imod-model-mask
  urls:
  - https://ftp.ebi.ac.uk/empiar/world_availability/10553/data/20190819_Gobs_model_C1.mod
  - https://ftp.ebi.ac.uk/empiar/world_availability/10553/data/20190830_Gobs_model_C2.mod
  params:
    objects: 1,1
    draw: outline
  pairs_with: 0
  label_key: manual_gt-cell_envelope-semantic
  segmentation_type: binary
- snippet: imod-model-mask
  urls:
  - https://ftp.ebi.ac.uk/empiar/world_availability/10553/data/20190819_Gobs_model_C1.mod
  - https://ftp.ebi.ac.uk/empiar/world_availability/10553/data/20190830_Gobs_model_C2.mod
  params:
    objects: 2,4
    draw: outline
  pairs_with: 0
  label_key: manual_gt-cytoplasmic_membrane-semantic
  segmentation_type: binary
- snippet: imod-model-mask
  urls:
  - https://ftp.ebi.ac.uk/empiar/world_availability/10553/data/20190819_Gobs_model_C1.mod
  - https://ftp.ebi.ac.uk/empiar/world_availability/10553/data/20190830_Gobs_model_C2.mod
  params:
    objects: 3,3
  pairs_with: 0
  label_key: manual_gt-nucleoid-semantic
  segmentation_type: binary
- snippet: imod-model-mask
  urls:
  - https://ftp.ebi.ac.uk/empiar/world_availability/10553/data/20190819_Gobs_model_C1.mod
  - https://ftp.ebi.ac.uk/empiar/world_availability/10553/data/20190830_Gobs_model_C2.mod
  params:
    objects: 4,2
  pairs_with: 0
  label_key: manual_gt-polyphosphate_granule-semantic
  segmentation_type: binary
reasons:
- 'raw: record technical.arrays[0] is one ImageJ TIFF stack (data/Seeger_5_reg.tif,
  zyx, 470x1602x2268, uint8, uncompressed) at a plain https URL from technical.sample.urls,
  so tiff-zip-member with default params (no axes override)'
- 'labels with imod-model-mask: the record''s label arrays are IMOD binary contour
  models (format other, encoding polygons, ''Contours need rasterizing to masks'');
  both model headers have dims 2268x1602x470, the raw''s grid, so each object rasterizes
  to a zyx 470x1602x2268 mask that pairs with raw 0'
- 'both models in every label: C1 and C2 each outline one cell of the same stack with
  the same four classes, and two labels of one raw cannot share a label_key, so each
  class is one mask that is 1 where either model has it. The C2 URL is not in technical.sample.urls;
  it is data.download_url plus the layout tree''s data/20190830_Gobs_model_C2.mod,
  which path_pattern data/2019*_Gobs_model_C?.mod covers'
- 'objects per class, one number per url (C1, C2), from the OBJT names in the files:
  cell envelope 1,1 (''Cell Envelope'', ''CE (cell1)''); cytoplasmic membrane 2,4
  (''Cytoplasmic Membrane'', ''Cytoplasmic membrane (2)''); nucleoid / DNA 3,3 (''Nucleoid'',
  ''DNA''); large poly-phosphate granule 4,2 (''Large Poly-P granule'', ''Large poly-P
  granule''). The two models order their objects differently, hence objects and not
  object'
- 'draw: outline for cell envelope and cytoplasmic membrane: the contours trace the
  membranes, so the outline is the class the record names; filled they would be the
  whole cell and the cytoplasm (with invaginations as holes). All contours of both
  models are closed, so draw: fill also works: a human should confirm which is wanted
  (the record does not say)'
- 'draw: fill (default) for nucleoid / DNA and the poly-phosphate granule: the contours
  are drawn around bodies, so the class is the enclosed region'
- 'label_keys manual_gt-<class>-semantic with segmentation_type binary: annotations
  are manual (provenance manual_gt), each mask is {0,1} for one class, and binary
  folds to semantic in the key. Encoding ''polygons'' has no kind in the label_key
  rule; the rasterizer emits one binary mask per class and does not number the two
  cells as instances'
- 'coverage is partial: only two cells of the stack are modelled, and only on the
  sections that carry contours (C1 z 65..158, C2 z 151..256); everywhere else the
  masks are 0, which is ''not annotated'', not ''background'''
- 'voxel size: none from either array (TIFF uncalibrated; the snippet does not report
  the models'' pixsize 5 nm and z scales 4.49 / 4.05, which disagree and which the
  record calls unreliable)'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

New snippet for tiff/http: empiar-10553-gemmata-fib-sem-membranes

0 participants