-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Include chunk shape as a parameter in stream resource for HDF dataset #544
Changes from 18 commits
2202413
02332c3
561da46
edc8f1c
3cfb4e7
8117e4b
3313d1a
ada0b15
a835183
31dfcb1
54e42f0
ad8b63f
9856e2e
386e61b
415c398
deec8d1
5ad4b7a
09b51b3
578969c
00275f3
025ac06
1600a2c
4a76859
f105e34
395b58b
3821fc6
398ac01
9e28151
0bd5ba2
4d01dae
4f15ac1
4d4e12e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -102,7 +102,11 @@ async def _update_datasets(self) -> None: | |
|
||
capture_table = await self.panda_data_block.datasets.get_value() | ||
self._datasets = [ | ||
HDFDataset(dataset_name, "/" + dataset_name, [1], multiplier=1) | ||
# TODO: Update chunk size to read signal once available in IOC | ||
# Currently PandA IOC sets chunk size to 1024 points per chunk | ||
Comment on lines
+108
to
+109
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please make it an issue and link here. |
||
HDFDataset( | ||
dataset_name, "/" + dataset_name, [1], multiplier=1, chunk_size=(1024,) | ||
) | ||
for dataset_name in capture_table["name"] | ||
] | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,28 @@ | ||
import pytest | ||
from bluesky.run_engine import RunEngine | ||
|
||
from ophyd_async.core import ( | ||
DetectorTrigger, | ||
DeviceCollector, | ||
StaticPathProvider, | ||
set_mock_value, | ||
) | ||
from ophyd_async.core._detector import TriggerInfo | ||
from ophyd_async.epics import adkinetix | ||
from ophyd_async.epics.adkinetix import KinetixDetector | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We actually imported |
||
|
||
|
||
@pytest.fixture | ||
async def test_adkinetix( | ||
RE: RunEngine, | ||
static_path_provider: StaticPathProvider, | ||
) -> adkinetix.KinetixDetector: | ||
async with DeviceCollector(mock=True): | ||
test_adkinetix = adkinetix.KinetixDetector("KINETIX:", static_path_provider) | ||
|
||
return test_adkinetix | ||
async def test_adkinetix(ad_standard_det_factory): | ||
kinetix = await ad_standard_det_factory(KinetixDetector) | ||
return kinetix | ||
|
||
|
||
async def test_get_deadtime( | ||
test_adkinetix: adkinetix.KinetixDetector, | ||
test_adkinetix: KinetixDetector, | ||
): | ||
# Currently Kinetix driver doesn't support getting deadtime. | ||
assert test_adkinetix._controller.get_deadtime(0) == 0.001 | ||
|
||
|
||
async def test_trigger_modes(test_adkinetix: adkinetix.KinetixDetector): | ||
async def test_trigger_modes(test_adkinetix: KinetixDetector): | ||
set_mock_value(test_adkinetix.drv.trigger_mode, "Internal") | ||
|
||
async def setup_trigger_mode(trig_mode: DetectorTrigger): | ||
|
@@ -53,17 +46,17 @@ async def setup_trigger_mode(trig_mode: DetectorTrigger): | |
assert (await test_adkinetix.drv.trigger_mode.get_value()) == "Exp. Gate" | ||
|
||
|
||
async def test_hints_from_hdf_writer(test_adkinetix: adkinetix.KinetixDetector): | ||
assert test_adkinetix.hints == {"fields": ["test_adkinetix"]} | ||
async def test_hints_from_hdf_writer(test_adkinetix: KinetixDetector): | ||
assert test_adkinetix.hints == {"fields": ["test_adkinetix1"]} | ||
|
||
|
||
async def test_can_read(test_adkinetix: adkinetix.KinetixDetector): | ||
async def test_can_read(test_adkinetix: KinetixDetector): | ||
# Standard detector can be used as Readable | ||
assert (await test_adkinetix.read()) == {} | ||
|
||
|
||
async def test_decribe_describes_writer_dataset( | ||
test_adkinetix: adkinetix.KinetixDetector, one_shot_trigger_info: TriggerInfo | ||
test_adkinetix: KinetixDetector, one_shot_trigger_info: TriggerInfo | ||
): | ||
set_mock_value(test_adkinetix._writer.hdf.file_path_exists, True) | ||
set_mock_value(test_adkinetix._writer.hdf.capture, True) | ||
|
@@ -72,9 +65,9 @@ async def test_decribe_describes_writer_dataset( | |
await test_adkinetix.stage() | ||
await test_adkinetix.prepare(one_shot_trigger_info) | ||
assert await test_adkinetix.describe() == { | ||
"test_adkinetix": { | ||
"source": "mock+ca://KINETIX:HDF1:FullFileName_RBV", | ||
"shape": (0, 0), | ||
"test_adkinetix1": { | ||
"source": "mock+ca://KINETIX1:HDF1:FullFileName_RBV", | ||
"shape": (10, 10), | ||
"dtype": "array", | ||
"dtype_numpy": "|i1", | ||
"external": "STREAM:", | ||
|
@@ -83,7 +76,7 @@ async def test_decribe_describes_writer_dataset( | |
|
||
|
||
async def test_can_collect( | ||
test_adkinetix: adkinetix.KinetixDetector, | ||
test_adkinetix: KinetixDetector, | ||
static_path_provider: StaticPathProvider, | ||
one_shot_trigger_info: TriggerInfo, | ||
): | ||
|
@@ -99,12 +92,13 @@ async def test_can_collect( | |
assert docs[0][0] == "stream_resource" | ||
stream_resource = docs[0][1] | ||
sr_uid = stream_resource["uid"] | ||
assert stream_resource["data_key"] == "test_adkinetix" | ||
assert stream_resource["data_key"] == "test_adkinetix1" | ||
assert stream_resource["uri"] == "file://localhost" + str(full_file_name) | ||
assert stream_resource["parameters"] == { | ||
"dataset": "/entry/data/data", | ||
"swmr": False, | ||
"multiplier": 1, | ||
"chunk_size": (1, 10, 10), | ||
} | ||
assert docs[1][0] == "stream_datum" | ||
stream_datum = docs[1][1] | ||
|
@@ -114,17 +108,17 @@ async def test_can_collect( | |
|
||
|
||
async def test_can_decribe_collect( | ||
test_adkinetix: adkinetix.KinetixDetector, one_shot_trigger_info: TriggerInfo | ||
test_adkinetix: KinetixDetector, one_shot_trigger_info: TriggerInfo | ||
): | ||
set_mock_value(test_adkinetix._writer.hdf.file_path_exists, True) | ||
set_mock_value(test_adkinetix._writer.hdf.capture, True) | ||
assert (await test_adkinetix.describe_collect()) == {} | ||
await test_adkinetix.stage() | ||
await test_adkinetix.prepare(one_shot_trigger_info) | ||
assert (await test_adkinetix.describe_collect()) == { | ||
"test_adkinetix": { | ||
"source": "mock+ca://KINETIX:HDF1:FullFileName_RBV", | ||
"shape": (0, 0), | ||
"test_adkinetix1": { | ||
"source": "mock+ca://KINETIX1:HDF1:FullFileName_RBV", | ||
"shape": (10, 10), | ||
"dtype": "array", | ||
"dtype_numpy": "|i1", | ||
"external": "STREAM:", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import pytest | ||
from bluesky.run_engine import RunEngine | ||
|
||
from ophyd_async.core._detector import StandardDetector | ||
from ophyd_async.core._device import DeviceCollector | ||
from ophyd_async.core._mock_signal_utils import set_mock_value | ||
|
||
|
||
@pytest.fixture | ||
async def ad_standard_det_factory( | ||
RE: RunEngine, | ||
static_path_provider, | ||
) -> StandardDetector: | ||
async def generate_ad_standard_det(ad_standard_detector_class, number=1): | ||
detector_name = ad_standard_detector_class.__name__ | ||
if detector_name.endswith("Detector"): | ||
detector_name = detector_name[:-8] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it because of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, I can maybe change it to |
||
|
||
async with DeviceCollector(mock=True): | ||
test_adstandard_det = ad_standard_detector_class( | ||
f"{detector_name.upper()}{number}:", | ||
static_path_provider, | ||
name=f"test_ad{detector_name.lower()}{number}", | ||
) | ||
|
||
# Set number of frames per chunk and frame dimensions to something reasonable | ||
set_mock_value(test_adstandard_det.hdf.num_frames_chunks, 1) | ||
set_mock_value(test_adstandard_det.drv.array_size_x, 10) | ||
set_mock_value(test_adstandard_det.drv.array_size_y, 10) | ||
|
||
return test_adstandard_det | ||
|
||
return generate_ad_standard_det |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the second half of this is actually always true, we happen to make this so for areaDetector, but in the general case the chunk size is just that, the size of the HDF chunk. This may or may not correspond to a multiple of images, it might be half an image in one direction and 15 in the other, but its magnitude is in the base datatype of the dataset.
I wonder if
chunk_shape
might be a better name to make people think ofshape
in the output ofdescribe()
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually had the same thought yesterday about calling it
chunk_shape
. If it's not too late, I'd +1 to that.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No preference from me about
chunk_shape
overchunk_size
- perhaps lets discuss tomorrow at the sprint catchup, and we can settle on a naming scheme