Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 22 additions & 0 deletions src/chexus/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,27 @@ def validate(self, node: Dataset | Group) -> Violation | None:
return Violation(node.name, "event_index type too small")


class event_data_group_has_event_datasets(Validator):
'''Strictly speaking, all fields of NXevent_data are optional.
But in practice they are required so it is better to be
lightly opinionated about this.'''

def __init__(self) -> None:
super().__init__(
"event_data_has_event_datasets", "NXevent_data must have event dataset(s)"
)

def applies_to(self, node: Dataset | Group) -> bool:
return isinstance(node, Group) and node.attrs.get("NX_class") == "NXevent_data"

def validate(self, node: Group | Dataset) -> Violation | None:
for name in node.children:
if name in ('event_time_offset', 'event_id'):
break
else:
return Violation(node.name, "NXevent_data must have event dataset(s)")


def base_validators(*, has_scipp=True):
validators = [
depends_on_missing(),
Expand All @@ -506,6 +527,7 @@ def base_validators(*, has_scipp=True):
event_id_subset_of_detector_number(),
NXdetector_pixel_offsets_are_unambiguous(),
event_index_is_eight_bytes(),
event_data_group_has_event_datasets(),
]
if has_scipp:
validators += [
Expand Down
56 changes: 56 additions & 0 deletions tests/validators_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -822,3 +822,59 @@ def test_event_index_is_eight_bytes() -> None:
assert isinstance(
chexus.validators.event_index_is_eight_bytes().validate(bad), chexus.Violation
)


@pytest.mark.parametrize('field', ['event_time_offset', 'event_id'])
def test_event_data_has_event_datasets_good(field) -> None:
parent = chexus.Group(
name="event_data",
attrs={"NX_class": "NXevent_data"},
)
parent.children = {
field: chexus.Dataset(
name=f'event_data/{field}',
value=[1, 2, 3],
shape=(3,),
dtype='int32',
parent=parent,
)
}
assert chexus.validators.event_data_group_has_event_datasets().applies_to(parent)
assert (
chexus.validators.event_data_group_has_event_datasets().validate(parent) is None
)


@pytest.mark.parametrize('field', ['event_time_something', 'event_ids'])
def test_event_data_has_event_datasets_bad(field) -> None:
parent = chexus.Group(
name="event_data",
attrs={"NX_class": "NXevent_data"},
)
parent.children = {
field: chexus.Dataset(
name=f'event_data/{field}',
value=[1, 2, 3],
shape=(3,),
dtype='int32',
parent=parent,
)
}
assert chexus.validators.event_data_group_has_event_datasets().applies_to(parent)
assert isinstance(
chexus.validators.event_data_group_has_event_datasets().validate(parent),
chexus.Violation,
)


def test_event_data_has_event_datasets_bad_empty() -> None:
parent = chexus.Group(
name="event_data",
attrs={"NX_class": "NXevent_data"},
)
parent.children = {}
assert chexus.validators.event_data_group_has_event_datasets().applies_to(parent)
assert isinstance(
chexus.validators.event_data_group_has_event_datasets().validate(parent),
chexus.Violation,
)
Loading