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
4 changes: 0 additions & 4 deletions src/ess/reduce/nexus/workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,6 @@ def get_calibrated_monitor(
monitor: NeXusComponent[MonitorType, RunType],
transform: NeXusTransformation[MonitorType, RunType],
offset: MonitorPositionOffset[RunType, MonitorType],
source_position: Position[snx.NXsource, RunType],
) -> EmptyMonitor[RunType, MonitorType]:
"""
Extract the data array corresponding to a monitor's signal field.
Expand All @@ -450,15 +449,12 @@ def get_calibrated_monitor(
Transformation matrix for the monitor.
offset:
Offset to add to the monitor position.
source_position:
Position of the neutron source.
"""
transform_unit = transform.value.unit
return EmptyMonitor[RunType, MonitorType](
nexus.extract_signal_data_array(monitor).assign_coords(
position=transform.value * sc.vector([0, 0, 0], unit=transform_unit)
+ offset.to(unit=transform_unit),
source_position=source_position,
)
)

Expand Down
20 changes: 18 additions & 2 deletions src/ess/reduce/time_of_flight/eto_to_tof.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,19 @@ def _time_of_flight_data_events(
parts = da.bins.constituents
parts["data"] = tofs
result = da.bins.assign_coords(tof=sc.bins(**parts, validate_indices=False))
return result.bins.drop_coords("event_time_offset")
out = result.bins.drop_coords("event_time_offset")

# The result may still have an 'event_time_zero' dimension (in the case of an
# event monitor where events were not grouped by pixel).
if "event_time_zero" in out.dims:
if ("event_time_zero" in out.coords) and (
"event_time_zero" not in out.bins.coords
):
out.bins.coords["event_time_zero"] = sc.bins_like(
out, out.coords["event_time_zero"]
)
out = out.bins.concat("event_time_zero")
return out


def detector_ltotal_from_straight_line_approximation(
Expand Down Expand Up @@ -357,6 +369,7 @@ def detector_ltotal_from_straight_line_approximation(

def monitor_ltotal_from_straight_line_approximation(
monitor_beamline: EmptyMonitor[RunType, MonitorType],
source_position: Position[snx.NXsource, RunType],
) -> MonitorLtotal[RunType, MonitorType]:
"""
Compute Ltotal for the monitor.
Expand All @@ -369,7 +382,10 @@ def monitor_ltotal_from_straight_line_approximation(
Beamline data for the monitor that contains the positions necessary to compute
the straight-line approximation to Ltotal (source and monitor positions).
"""
graph = scn.conversion.graph.beamline.beamline(scatter=False)
graph = {
**scn.conversion.graph.beamline.beamline(scatter=False),
'source_position': lambda: source_position,
}
return MonitorLtotal[RunType, MonitorType](
monitor_beamline.transform_coords(
"Ltotal", graph=graph, keep_intermediate=False
Expand Down
17 changes: 2 additions & 15 deletions tests/nexus/workflow_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -502,13 +502,12 @@ def test_get_calibrated_monitor_extracts_data_field_from_nexus_monitor(
monitor = workflow.get_calibrated_monitor(
nexus_monitor,
offset=workflow.no_offset,
source_position=sc.vector([0.0, 0.0, -10.0], unit='m'),
transform=NeXusTransformation.from_chain(
workflow.get_transformation_chain(nexus_monitor),
),
)
assert_identical(
monitor.drop_coords(('position', 'source_position')),
monitor.drop_coords('position'),
compute_component_position(nexus_monitor)['data'],
)

Expand All @@ -520,7 +519,6 @@ def test_get_calibrated_monitor_subtracts_offset_from_position(
monitor = workflow.get_calibrated_monitor(
nexus_monitor,
offset=offset,
source_position=sc.vector([0.0, 0.0, -10.0], unit='m'),
transform=NeXusTransformation.from_chain(
workflow.get_transformation_chain(nexus_monitor),
),
Expand Down Expand Up @@ -551,17 +549,12 @@ def test_get_calibrated_monitor_with_time_dependent_transformation(
)

# Get the calibrated monitor
source_position = sc.vector([0.0, 0.0, -10.0], unit='m')
monitor = workflow.get_calibrated_monitor(
nexus_monitor,
transform=transform,
offset=workflow.no_offset,
source_position=source_position,
nexus_monitor, transform=transform, offset=workflow.no_offset
)

# Verify the monitor has the correct structure
assert 'position' in monitor.coords
assert 'source_position' in monitor.coords

# Verify the position is correctly computed
# The transformation: translate (1, 0, 0) then translate (0, 2, 0)
Expand All @@ -571,9 +564,6 @@ def test_get_calibrated_monitor_with_time_dependent_transformation(
monitor.coords['position'], expected_position, rtol=sc.scalar(1e-10)
)

# Verify source position is preserved
assert_identical(monitor.coords['source_position'], source_position)


@pytest.fixture
def calibrated_monitor() -> workflow.EmptyMonitor[SampleRun, FrameMonitor1]:
Expand Down Expand Up @@ -685,7 +675,6 @@ def test_load_event_monitor_workflow(loki_tutorial_sample_run_60250: Path) -> No
wf[NeXusName[FrameMonitor1]] = 'monitor_1'
da = wf.compute(RawMonitor[SampleRun, FrameMonitor1])
assert 'position' in da.coords
assert 'source_position' in da.coords
assert da.bins is not None
assert da.dims == ('event_time_zero',)
assert da.bins.constituents['data'].variances is not None
Expand All @@ -697,7 +686,6 @@ def test_load_histogram_monitor_workflow(dream_coda_test_file: Path) -> None:
wf[NeXusName[FrameMonitor1]] = 'monitor_bunker'
da = wf.compute(RawMonitor[SampleRun, FrameMonitor1])
assert 'position' in da.coords
assert 'source_position' in da.coords
assert da.bins is None
assert set(da.dims) == {'time', 'frame_time'}
assert 'time' in da.coords.keys()
Expand Down Expand Up @@ -755,7 +743,6 @@ def test_generic_nexus_workflow(
assert da.dims == ('detector_number',)
da = wf.compute(RawMonitor[SampleRun, FrameMonitor1])
assert 'position' in da.coords
assert 'source_position' in da.coords
assert da.bins is not None
assert da.dims == ('event_time_zero',)

Expand Down
Loading