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
26 changes: 26 additions & 0 deletions src/chexus/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,31 @@ def validate(self, node: Dataset | Group) -> Violation | None:
)


class event_id_subset_of_detector_number(Validator):
def __init__(self) -> None:
super().__init__(
"event_id is not subset of associated detector_numbers",
"The values in the event_id field in NXevent_data should be "
"a subset of the values in the detector_number dataset on the "
"associated NXdetector.",
)

def applies_to(self, node: Dataset | Group) -> bool:
return (
isinstance(node, Group)
and node.attrs.get('NX_class') == 'NXevent_data'
and 'event_id' in node.children
and 'detector_number' in node.parent.children
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we separately checking that event_id and detector_number exist? Or is it ok when they don't and we can load the file anyway?

Copy link
Copy Markdown
Contributor Author

@jokasimr jokasimr Oct 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have validators that makes sure event_id and detector_number exists at the moment.

Or is it ok when they don't and we can load the file anyway?

I don't know. Maybe we should create an issue for that.

)

def validate(self, node: Dataset | Group) -> Violation | None:
if not np.isin(
node.children['event_id'].value,
node.parent.children['detector_number'].value,
).all():
return Violation(node.name)


physical_components = [
"NXaperture",
"NXattenuator",
Expand Down Expand Up @@ -374,6 +399,7 @@ def base_validators(*, has_scipp=True):
units_invalid(),
NXlog_has_value(),
detector_numbers_unique_in_all_detectors(),
event_id_subset_of_detector_number(),
]
if has_scipp:
validators += [
Expand Down
51 changes: 51 additions & 0 deletions tests/validators_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,3 +505,54 @@ def test_duplicate_detector_number(value):
assert validator.validate(det2) is None
# Second time the same detector numbers are seen, we expect a violation
assert validator.validate(det) is not None


def test_event_id_not_in_detector_number():
det = chexus.Group(name="detector1", attrs={"NX_class": "NXdetector"})
det.children = {
'data_good': chexus.Group(
name="data_good", attrs={"NX_class": "NXevent_data"}, parent=det
),
'data_bad': chexus.Group(
name="data_bad", attrs={"NX_class": "NXevent_data"}, parent=det
),
'detector_number': chexus.Dataset(
name="detector_number", value=[1, 2, 3], shape=(3,), dtype=int, parent=det
),
}
det.children['data_good'].children = {
'event_id': chexus.Dataset(
name='event_id',
value=[1, 2, 3],
shape=(3,),
dtype=int,
parent=det.children['data_good'],
)
}
det.children['data_bad'].children = {
'event_id': chexus.Dataset(
name='event_id',
value=[1, 4],
shape=(2,),
dtype=int,
parent=det.children['data_bad'],
)
}
assert chexus.validators.event_id_subset_of_detector_number().applies_to(
det.children['data_good']
)
assert chexus.validators.event_id_subset_of_detector_number().applies_to(
det.children['data_bad']
)
assert (
chexus.validators.event_id_subset_of_detector_number().validate(
det.children['data_good']
)
is None
)
assert (
chexus.validators.event_id_subset_of_detector_number().validate(
det.children['data_bad']
)
is not None
)