Skip to content

Commit e33f2f4

Browse files
Merge pull request #229 from scipp/allow-nxcite
Fix NXcite subgroup tripping up NXdetector loading
2 parents b9fb62d + df97f21 commit e33f2f4

7 files changed

Lines changed: 38 additions & 1 deletion

File tree

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ addopts = """
6161
testpaths = "tests"
6262
filterwarnings = [
6363
"error",
64-
"ignore:Failed to load :UserWarning",
6564
]
6665
markers = [
6766
"externalfile",

src/scippnexus/nxdata.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ def _init_field_dims(self, name: str, field: Field | Group) -> None:
9191
if name == self._signal_name or name in self._aux_signals:
9292
return
9393
if field.attrs.get('NX_class') not in [
94+
'NXcite',
9495
'NXoff_geometry',
9596
'NXcylindrical_geometry',
9697
'NXgeometry',

tests/nxdata_test.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ def test_guessed_dim_for_2d_coord_not_matching_axis_name(h5root):
149149
assert sc.identical(data[...], da)
150150

151151

152+
@pytest.mark.filterwarnings("ignore:Failed to load /data1:UserWarning")
152153
def test_skips_axis_if_dim_guessing_finds_ambiguous_shape(h5root):
153154
da = sc.DataArray(
154155
sc.array(dims=['xx', 'yy'], unit='m', values=[[1, 2, 3], [4, 5, 6], [7, 8, 9]])
@@ -186,6 +187,7 @@ def test_dim_guessing_with_ambiguous_shape_accepts_multi_dim_match_at_end(h5root
186187
assert_identical(loaded.coords['3x3'], da.data['aux', 0])
187188

188189

190+
@pytest.mark.filterwarnings("ignore:Failed to load /data1:UserWarning")
189191
def test_dim_guessing_with_ambiguous_shape_rejects_1d_dim_match_at_end(h5root):
190192
da = sc.DataArray(
191193
sc.array(dims=['xx', 'yy'], unit='m', values=[[1, 2, 3], [4, 5, 6], [7, 8, 9]])
@@ -348,6 +350,7 @@ def test_field_dims_match_NXdata_dims_when_selected_via_class_name(h5root):
348350
assert fields['yy'].dims == ('yy',)
349351

350352

353+
@pytest.mark.filterwarnings("ignore:Failed to load /data1:UserWarning")
351354
def test_uses_default_field_dims_if_inference_fails(h5root):
352355
da = sc.DataArray(
353356
sc.array(dims=['xx', 'yy'], unit='m', values=[[1, 2, 3], [4, 5, 6]])
@@ -691,6 +694,7 @@ def test_guesses_dims_of_2d_bin_edge_fields(h5root, axis_sep):
691694
assert sc.identical(data[...], da)
692695

693696

697+
@pytest.mark.filterwarnings("ignore:Failed to load /data1:UserWarning")
694698
def test_nested_groups_trigger_fallback_to_load_as_data_group(h5root):
695699
da = sc.DataArray(sc.array(dims=['xx', 'yy'], unit='m', values=[[1, 2], [4, 5]]))
696700
data = snx.create_class(h5root, 'data1', NXdata)

tests/nxdetector_test.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ def nxroot():
2828
yield root
2929

3030

31+
@pytest.mark.filterwarnings("ignore:Failed to load :UserWarning")
3132
def test_returns_as_datagroup_if_no_signal_found(nxroot):
3233
detector_numbers = sc.array(dims=[''], unit=None, values=np.array([1, 2, 3, 4]))
3334
detector = nxroot.create_class('detector0', NXdetector)
@@ -145,6 +146,24 @@ def test_loads_data_with_coords(h5root):
145146
assert sc.identical(detector[...]['data'], da.rename_dims({'yy': 'dim_1'}))
146147

147148

149+
def test_nxcite_does_not_prevent_load_as_nxdetector(h5root):
150+
da = sc.DataArray(
151+
sc.array(dims=['xx', 'yy'], unit='K', values=[[1.1, 2.2], [3.3, 4.4]])
152+
)
153+
da.coords['detector_number'] = detector_numbers_xx_yy_1234()
154+
da.coords['xx'] = sc.array(dims=['xx'], unit='m', values=[0.1, 0.2])
155+
detector = snx.create_class(h5root, 'detector0', NXdetector)
156+
snx.create_field(detector, 'detector_number', da.coords['detector_number'])
157+
snx.create_field(detector, 'xx', da.coords['xx'])
158+
snx.create_field(detector, 'data', da.data)
159+
snx.create_class(detector, 'cite', snx.NXcite)
160+
detector.attrs['axes'] = ['xx', '.']
161+
detector = make_group(detector)
162+
loaded = detector[...]
163+
assert 'cite' in loaded
164+
assert sc.identical(loaded['data'], da.rename_dims({'yy': 'dim_1'}))
165+
166+
148167
def test_slicing_works_as_in_scipp(h5root):
149168
da = sc.DataArray(
150169
sc.array(dims=['xx', 'yy'], unit='K', values=[[1.1, 2.2, 3.3], [3.3, 4.4, 5.5]])
@@ -657,6 +676,7 @@ def test_cylindrical_geometry_with_detector_numbers(nxroot):
657676
)
658677

659678

679+
@pytest.mark.filterwarnings("ignore:Failed to load :UserWarning")
660680
def test_falls_back_to_hdf5_dim_labels(nxroot):
661681
detector = nxroot.create_class('detector0', NXdetector)
662682
xy = sc.array(dims=['x', 'y'], values=[[1, 2], [3, 4]])
@@ -672,6 +692,7 @@ def test_falls_back_to_hdf5_dim_labels(nxroot):
672692
assert_identical(dg['z'], z)
673693

674694

695+
@pytest.mark.filterwarnings("ignore:Failed to load :UserWarning")
675696
def test_falls_back_to_partial_hdf5_dim_labels(nxroot):
676697
detector = nxroot.create_class('detector0', NXdetector)
677698
xyz = sc.ones(dims=['x', 'dim_1', 'z'], shape=(2, 2, 3))
@@ -683,6 +704,7 @@ def test_falls_back_to_partial_hdf5_dim_labels(nxroot):
683704
assert_identical(dg['xyz'], xyz)
684705

685706

707+
@pytest.mark.filterwarnings("ignore:Failed to load :UserWarning")
686708
def test_squeezes_trailing_when_fall_back_to_partial_hdf5_dim_labels(nxroot):
687709
detector = nxroot.create_class('detector0', NXdetector)
688710
x = sc.ones(dims=['x', 'dim_1'], shape=(2, 1))
@@ -693,6 +715,7 @@ def test_squeezes_trailing_when_fall_back_to_partial_hdf5_dim_labels(nxroot):
693715
assert_identical(dg['x'], sc.squeeze(x))
694716

695717

718+
@pytest.mark.filterwarnings("ignore:Failed to load :UserWarning")
696719
def test_falls_back_to_hdf5_dim_labels_given_unnamed_axes(h5root):
697720
xy = sc.array(dims=['x', 'y'], values=[[1, 2], [3, 4]])
698721
z = sc.array(dims=['z'], values=[1, 2, 3])
@@ -712,6 +735,7 @@ def test_falls_back_to_hdf5_dim_labels_given_unnamed_axes(h5root):
712735
assert_identical(dg['z'], z)
713736

714737

738+
@pytest.mark.filterwarnings("ignore:Failed to load :UserWarning")
715739
def test_falls_back_to_hdf5_dim_labels_given_partially_axes(h5root):
716740
xy = sc.array(dims=['x', 'yy'], values=[[1, 2], [3, 4]])
717741
z = sc.array(dims=['zz'], values=[1, 2, 3])

tests/nxevent_data_test.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ def test_negative_event_index_converted_to_num_event(nxroot):
4242
assert events.bins.size().values[3] == 0
4343

4444

45+
@pytest.mark.filterwarnings("ignore:Failed to load /entry/events_0:UserWarning")
4546
def test_bad_event_index_causes_load_as_DataGroup(nxroot):
4647
event_data = nxroot['entry'].create_class('events_0', snx.NXevent_data)
4748
event_data['event_id'] = sc.array(dims=[''], unit=None, values=[1, 2, 4, 1, 2])

tests/nxlog_test.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ def test_nxobject_log(h5root):
5252
assert sc.identical(log[...], da)
5353

5454

55+
@pytest.mark.filterwarnings("ignore:Failed to load /entry/log:UserWarning")
5556
def test_nxlog_with_missing_value_triggers_fallback(nxroot):
5657
time = sc.epoch(unit='ns') + sc.array(
5758
dims=['time'], unit='s', values=[4.4, 5.5, 6.6]

tests/nxtransformations_test.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,9 @@ def test_chain_with_multiple_values_and_different_time_unit(h5root):
327327
assert_identical(loaded['transformations']['t2'], expected2)
328328

329329

330+
@pytest.mark.filterwarnings(
331+
"ignore:Failed to load /detector_0/transformations/t1:UserWarning"
332+
)
330333
def test_broken_time_dependent_transformation_returns_datagroup_but_sets_up_depends_on(
331334
h5root,
332335
):
@@ -699,6 +702,7 @@ def test_compute_positions_with_rotation(h5root):
699702
)
700703

701704

705+
@pytest.mark.filterwarnings("ignore:Failed to load /instrument/monitor:UserWarning")
702706
def test_compute_positions_works_for_path_beyond_root(h5root):
703707
instrument = snx.create_class(h5root, 'instrument', snx.NXinstrument)
704708
value = sc.scalar(6.5, unit='m')
@@ -723,6 +727,7 @@ def test_compute_positions_works_for_path_beyond_root(h5root):
723727
assert 'position' in snx.compute_positions(loaded['instrument'])['monitor2']
724728

725729

730+
@pytest.mark.filterwarnings("ignore:Failed to load /instrument/monitor:UserWarning")
726731
def test_path_beyond_root_is_fully_resolved_and_can_compute_positions(h5root):
727732
instrument = snx.create_class(h5root, 'instrument', snx.NXinstrument)
728733
monitor1 = snx.create_class(instrument, 'monitor1', snx.NXmonitor)
@@ -752,6 +757,7 @@ def test_path_beyond_root_is_fully_resolved_and_can_compute_positions(h5root):
752757
assert_identical(snx.compute_positions(mon2)['position'], 2 * value * vector)
753758

754759

760+
@pytest.mark.filterwarnings("ignore:Failed to load /instrument/monitor:UserWarning")
755761
def test_compute_positions_returns_position_with_unit_meters(h5root):
756762
instrument = snx.create_class(h5root, 'instrument', snx.NXinstrument)
757763
value = sc.scalar(6.5, unit='cm')
@@ -768,6 +774,7 @@ def test_compute_positions_returns_position_with_unit_meters(h5root):
768774
assert mon['position'].unit == 'm'
769775

770776

777+
@pytest.mark.filterwarnings("ignore:Failed to load /instrument/monitor:UserWarning")
771778
def test_compute_positions_handles_chains_with_mixed_units(h5root):
772779
instrument = snx.create_class(h5root, 'instrument', snx.NXinstrument)
773780
vector = sc.vector(value=[0, 0, 1])

0 commit comments

Comments
 (0)