Skip to content

Commit e5db6bf

Browse files
committed
wip: try to figure out how to use numtracker correctly
1 parent 048d758 commit e5db6bf

3 files changed

Lines changed: 50 additions & 7 deletions

File tree

‎src/blueapi/utils/path_provider.py‎

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,32 @@ def __call__(self, device_name: str | None = None) -> PathInfo:
3838
example: "detector_file_template": "custom-{device_name}-{scan_id}".
3939
4040
If you do not provide a data_session_directory it will default to "/tmp".
41+
42+
If the start document has a scan_file in a subdirectory of the data session
43+
directory (e.g. "sample1/ixx-1234"), detector files are written alongside it
44+
in that subdirectory, which is created if it does not exist.
4145
"""
4246
if not self._docs:
4347
raise BlueskyRunStructureError(
4448
"Start document not found. This call must be made inside a run."
4549
)
4650
else:
47-
template = self._docs[-1].get("detector_file_template")
51+
doc = self._docs[-1]
52+
template = doc.get("detector_file_template")
4853
if not template:
4954
raise ValueError("detector_file_template must be set in metadata")
50-
sub_path = template.format_map(
51-
self._docs[-1] | {"device_name": device_name}
52-
)
53-
data_session_directory = Path(
54-
self._docs[-1].get("data_session_directory", "/tmp")
55+
sub_path = template.format_map(doc | {"device_name": device_name})
56+
data_session_directory = Path(doc.get("data_session_directory", "/tmp"))
57+
# numtracker's scan_file is relative to data_session_directory, write
58+
# detector files in the same directory as it ("." if there is no
59+
# scan_file or it has no subdirectory)
60+
scan_file_directory = Path(doc.get("scan_file", "")).parent
61+
return PathInfo(
62+
directory_path=data_session_directory / scan_file_directory,
63+
filename=sub_path,
64+
# Negative depth creates only the directories scan_file adds
65+
create_dir_depth=-len(scan_file_directory.parts),
5566
)
56-
return PathInfo(directory_path=data_session_directory, filename=sub_path)
5767

5868

5969
class BlueskyRunStructureError(Exception):

‎tests/system_tests/test_blueapi_system.py‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,10 +681,13 @@ def on_event(event: AnyEvent) -> None:
681681
@pytest.mark.usefixtures("numtracker_with_subdirectory")
682682
def test_plan_runs_with_subdirectory(client_with_stomp: BlueapiClient, scan_id: int):
683683
start = Queue(maxsize=1)
684+
stream_resources = Queue()
684685

685686
def on_event(event: AnyEvent) -> None:
686687
if isinstance(event, DataEvent) and event.name == "start":
687688
start.put_nowait(event.doc)
689+
if isinstance(event, DataEvent) and event.name == "stream_resource":
690+
stream_resources.put_nowait(event.doc)
688691

689692
cb_id = client_with_stomp.add_callback(on_event)
690693
try:
@@ -700,6 +703,9 @@ def on_event(event: AnyEvent) -> None:
700703
assert start_doc["data_session_subdirectory"] == "sample1"
701704
assert start_doc["data_session_directory"] == "/tmp"
702705
assert start_doc["scan_file"] == f"sample1/adsim-{scan_id}"
706+
# Detector files are written alongside the scan file, in the subdirectory
707+
resource = stream_resources.get_nowait()
708+
assert resource["uri"].endswith(f"/tmp/sample1/adsim-{scan_id}-det.h5")
703709

704710

705711
@pytest.mark.parametrize(

‎tests/unit_tests/utils/test_path_provider.py‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,33 @@ def test_start_document_path_provider_with_default_template_returns_correct_path
5252
)
5353

5454

55+
@pytest.mark.parametrize(
56+
"scan_file,directory,create_dir_depth",
57+
[
58+
("p01-22", "/p01/ab123", 0),
59+
("sample1/p01-22", "/p01/ab123/sample1", -1),
60+
("sample1/calibration/p01-22", "/p01/ab123/sample1/calibration", -2),
61+
],
62+
)
63+
def test_start_document_path_provider_writes_alongside_scan_file(
64+
start_doc_default_template: dict,
65+
scan_file: str,
66+
directory: str,
67+
create_dir_depth: int,
68+
):
69+
pp = StartDocumentPathProvider()
70+
pp.run_start(
71+
name="start",
72+
start_document=start_doc_default_template | {"scan_file": scan_file}, # type: ignore
73+
)
74+
75+
assert pp("det") == PathInfo(
76+
directory_path=PosixPath(directory),
77+
filename="p01-22-det",
78+
create_dir_depth=create_dir_depth,
79+
)
80+
81+
5582
@pytest.fixture
5683
def start_doc_custom_template() -> dict:
5784
return {

0 commit comments

Comments
 (0)