Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
4018e88
Fix zero-overlap and zero-jitter synthetic plate generation (#172)
trissim Sep 29, 2026
6dce327
Push declared source selections into discovery and verify fragmented …
trissim Sep 29, 2026
ccdb10e
Record final scoped review paths and owned scratch cleanup
trissim Sep 29, 2026
808ea7a
Add paired ROI topology raster witness and validation boundary
trissim Sep 29, 2026
006361f
Merge remote-tracking branch 'openhcsdev/main' into fix/input-prepara…
trissim Sep 29, 2026
515018f
Retain bounded paired validation failures and fidelity evidence
trissim Sep 29, 2026
32a2b27
Factor preparation admission into binding owners and consume Java cap…
trissim Sep 29, 2026
6ffea8d
Record addressed independent ownership findings and remaining gates
trissim Sep 29, 2026
101a6a4
Keep cold plate inspection responsive and inherit declared bundle cac…
trissim Sep 29, 2026
6bc71ee
Record issue224 source proof and cold installed gates
trissim Sep 29, 2026
b2edc45
Merge remote-tracking branch 'openhcsdev/main' into fix/input-prepara…
trissim Sep 29, 2026
e0dd14e
Record corrected H002 query timing and cold preparation proof limits
trissim Sep 29, 2026
e8d6d32
Merge remote-tracking branch 'openhcsdev/main' into HEAD
trissim Oct 1, 2026
72a9607
Integrate paired input preparation on current main with preserved evi…
trissim Oct 1, 2026
a3179b2
Keep failed original structural guards explicit in the integration re…
trissim Oct 1, 2026
1998f8e
Compose metadata detection capability and reuse typed ROI metadata in…
trissim Oct 1, 2026
5703899
Record passing original input-preparation structural guards
trissim Oct 1, 2026
a1a1689
Declare the application workspace namespace through PolyStore configu…
trissim Oct 1, 2026
5660082
Archive paired source guards and preserve the parent registration bou…
trissim Oct 1, 2026
a980203
Merge commit '5660082fd9895fa0a8ddf0c6b7dc8392d9f6a7e0' into HEAD
trissim Oct 1, 2026
5ce9e30
Bind microscope workspaces to the application metadata declaration
trissim Oct 1, 2026
98e3b05
Record actual paired MCP initialization and retained Opera failure
trissim Oct 1, 2026
ad63a81
Pin normally merged PolyStore input and metadata owners
trissim Oct 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions benchmark/fragmented_roi_profile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"""Bounded provider-free profile of the declared ROI extraction/ZIP owners."""

from __future__ import annotations

import argparse
import cProfile
import json
import pstats
from collections import Counter
from pathlib import Path
from time import perf_counter
from zipfile import ZipFile

import numpy as np
from polystore.disk import DiskStorageBackend
from polystore.roi import extract_rois_from_labeled_mask
from polystore.roi_converters import FijiROIConverter, NapariShapeMetadata


def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"output_dir", type=Path, help="Owned disposable scratch directory."
)
args = parser.parse_args()
args.output_dir.mkdir(parents=True, exist_ok=True)
labels = np.zeros((128, 128), dtype=np.int32)
labels[4:124:4, 4:124:4] = 188
labels[1:3, 1:3] = 7
labels[125:127, 125:127] = 42
start = perf_counter()
extract_rois_from_labeled_mask(labels, min_area=1)
cold_extraction_seconds = perf_counter() - start
profiler = cProfile.Profile()
start = perf_counter()
rois = profiler.runcall(extract_rois_from_labeled_mask, labels, min_area=1)
warm_extraction_seconds = perf_counter() - start
stats = pstats.Stats(profiler)
bbox_scan_calls = sum(
value[1] for key, value in stats.stats.items() if key[2] == "find_objects"
)
start = perf_counter()
members = FijiROIConverter.rois_to_imagej_members(rois)
encoding_seconds = perf_counter() - start
archive = args.output_dir / "fragmented.roi.zip"
start = perf_counter()
DiskStorageBackend().save(rois, archive)
archive_seconds = perf_counter() - start
with ZipFile(archive) as zipped:
member_count = sum(name.endswith(".roi") for name in zipped.namelist())
print(
json.dumps(
{
"shape": list(labels.shape),
"parent_labels": [
NapariShapeMetadata.from_metadata(roi.metadata).label
for roi in rois
],
"fragments_by_parent": dict(
Counter(
NapariShapeMetadata.from_metadata(member.metadata).label
for member in members
)
),
"zip_roi_members": member_count,
"cold_extraction_seconds": cold_extraction_seconds,
"warm_extraction_seconds": warm_extraction_seconds,
"bbox_scan_calls": bbox_scan_calls,
"member_encoding_seconds": encoding_seconds,
"archive_encoding_and_write_seconds": archive_seconds,
},
sort_keys=True,
)
)
# The archive writer includes its own required conversion; this does not
# imply production converts twice. The standalone conversion isolates cost.
stats.strip_dirs().sort_stats("cumulative").print_stats(15)


if __name__ == "__main__":
main()
112 changes: 112 additions & 0 deletions docs/plans/h002_query_preparation_diagnosis_20260929.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# H002 attempt4 query preparation: timing correction and bounded diagnosis

Owner: Lovelace, original206/PolyStore16 source continuation only.
No edits to installed imagej-cache-progress source, H002 driver/receipts,
scientific pipeline or data. No repeated query, raw pixels/notebooks/biological
outputs, new JVM/runtime/download, install, profiling attach or process restart.

## Evidence and exact timing meaning

Named receipt:
`/home/ts/wt/openhcs-h002-uncoached-20260929/output/runtime/h002-live-attempt4/receipts/013-openhcs_query_plate_files.json`.
It records query with limit1, include_previews=false, terminal success.
No inspection of the underlying container was performed by this worker.

Actual driver source `output/mcp_session_attempt4.py:94` sets
`started = time.monotonic()` once before stdio-client/session initialization.
Lines113-115 calculate `elapsed_seconds = time.monotonic() - started` BEFORE
awaiting session.call_tool. Therefore90.16998135202448 is session age at request
admission, NOT query duration. Original90s claim is withdrawn; no new90s query
regression established and no fix justified by that number.

Receipt admission at1790718869.0149193, UTC2026-09-29T21:54:29.014919.
Result-bearing receipt mtime1790718875.589610, UTC21:54:35.589610.
Difference **6.574690818786621s**: admission-to-terminal-receipt-write interval,
including dispatch/serialization/receipt IO; not an exact native stage timer.
The driver rewrites the same receipt after the successful await. The parent's
next-receipt96.745 estimate is a separate upper bound including author time.
The previous cache acceptance explicitly measured0.211s differently; neither
figure proves identical fixture/warm/cold cost or a general latency reduction.

Both driver1614516 and MCP1614529 were alive when checked, started17:52:57/58
local time. The MCP stderr fd points at this attempt's mcp-stderr.log.
Read-only whitelist of actual MCP environ confirms:
`POLYSTORE_IMAGEJ_CACHE_ROOT=/home/ts/.cache/polystore/imagej` and
`POLYSTORE_IMAGEJ_ALLOW_DOWNLOAD=false`.
No credentials/unrelated environment values printed or retained.

Startup stderr reports BigStitcher override from the existing digest-addressed
shared Fiji jars, then OMETiffReader initialization. These lines contain **no
timestamps**. Several reader-open lines accumulated across this continuing
session; they cannot be attributed/count-budgeted to query013 alone. File mtime
is the most recent write, not each line's event time. Do not assign a precise
JVM/decoder split from their order or repeated filenames.

## Source-owned preparation boundary

QueryPlateFilesCapability -> PlateInspectionService.query_files/_query_files
(:997/:1114) -> _create_handler(:1869) -> existing registered detection/handler
owners -> BioFormatsMetadataHandler.source_dataset(:64) -> registered
SourcePlaneStoreAdapter -> BioFormatsJavaAdapter._declares_path and
_discover_container -> BioFormatsJavaContext.ensure_initialized/open_reader
-> FIJI_IMAGEJ_RUNTIME.initialize -> FijiArchiveDistribution.materialize.
Limit1 bounds returned records after inventory preparation, not container/JVM
initialization. include_previews=false prevents requested previews, not metadata
discovery. No biological behavior is assumed.

Existing ImageJRuntimePolicy.initialize separates materialization from Java:
with a fresh JVM it first materializes the canonical bundle, then configures
bundled Java with fetch=never and invokes imagej.init. If Java is already started,
it reuses Java subject to declared Java/gateway compatibility checks.
BioFormatsJavaContext additionally imports reader/metadata/format Java classes;
open_reader builds OME metadata and invokes setId before source-plane projection.
Its process-owned context/lifecycle lock retains initialized gateway state.
No alternate Java helper/cache/decoder has been added.

Installed false policy rejects a missing/invalid bundle before cold filesystem
materialization/network. Actual environment + successful query + stderr pointing
to the shared bundle are consistent with successful warm bundle admission,
followed by cold Java/decoder preparation. They do not time either component.
Bundle provisioning and JVM/decoder preparation are distinct;228 fixed sharing
and inspection responsiveness, not all cold latency.

Query currently does not declare inspection's progress heartbeat/worker offload,
and its description claims no detection although _query_files can create/detect
the handler. This is a source-backed exposure/observability concern, **not a
newly proved90s regression or measured stage bottleneck**. Keep it within the
existing capability/preparation ownership for a separately justified checkpoint;
do not create another progress runner or speculate about bypassing rich metadata.

## Reproduce the diagnosis without calling MCP

Read this single receipt and its actual driver; calculate
`receipt.stat().st_mtime - json.loads(receipt.read_text())["at"]`.
Inspect only the actual stderr fd/log and whitelist cache/download keys from the
existing process. Never replay the request to establish timing. Exact JVM,
reader-open and source-projection costs are **unavailable retrospectively**.
Future stage profiling belongs on ImageJRuntimePolicy/BioFormatsJavaContext and
existing preparation owners, using before/after monotonic events on an authorized
small synthetic run after the live science slot; do not attach/restart H002.

## Source integration and checks (not live fixes)

Original parent206 was6bc71ee5c, child16 was9e205fee, remote heads matched.
Normally merged fetched OpenHCS main8b090e and PolyStore main94bf443 into ONLY
their original isolated continuation branches. Merge heads parentb2edc4503,
child50c1e49; conflict resolution retains merged17/228 download-policy and launch
projection changes rather than older cache-only declarations. No rebase/reset/
force-push or installed-tree mutation. Main's recorded c16b8fc gitlink is retained;
the original16 worktree intentionally differs while its broader gates remain.

Six scoped source/test files parsed; both diff checks and Ruff on dependency
distribution/cache tests and parent cold-runtime tests pass. No pytest/runtime
rerun needed to answer this diagnostic and none performed. NRA/refactor-audit
coverage is focused source/consumer trace, not a global scan or native proof.
BOUND-2/6: canonical distribution/runtime/context own config/lifetime; do not
read/replace them in callers. IMPL-12/13: keep one materializer and Java lifecycle.
The merge restores current-main behavior, not a performance fix/new owner.

Remaining original206/16 **141 passed/26 failed** and **after-ROI profile not run**
unchanged. Fresh cold stage profile, source preservation controls and broader
Java/CZI fidelity remain pending. No performance/preservation/live claim from
syntax checks or this receipt. Parent's installed228 acceptance remains separate.
Loading
Loading