[docs]defget_source_position(dg:LoadedFileContents[RunType],)->Position[snx.NXsource,RunType]:"""Get source position from raw data."""returnPosition[snx.NXsource,RunType](dg['data'].coords['source_position'])
[docs]defget_sample_position(dg:LoadedFileContents[RunType],offset:SampleOffset)->Position[snx.NXsample,RunType]:"""Get sample position from raw data and apply user offset."""returnPosition[snx.NXsample,RunType](dg['data'].coords['sample_position']+offset.to(unit='m'))
[docs]defget_detector_data(dg:LoadedFileContents[RunType],)->NeXusComponent[snx.NXdetector,RunType]:"""Get detector data and apply user offsets to raw data. Parameters ---------- dg: Data loaded with Mantid and converted to Scipp. """# The generic NeXus workflow will try to extract 'data' from this, which is exactly# what we also have in the Mantid data. We use the generic workflow since it also# applies offsets, etc.returnNeXusComponent[snx.NXdetector,RunType](dg)
[docs]defget_calibrated_isis_detector(detector:NeXusComponent[snx.NXdetector,RunType],*,offset:DetectorPositionOffset[RunType],)->CalibratedDetector[RunType]:""" Replacement for :py:func:`ess.reduce.nexus.workflow.get_calibrated_detector`. Differences: - The detector position is already pre-computed. - The detector is not reshaped. The reason for the partial duplication is to avoid having to put ISIS/Mantid specific code in the generic workflow. """da=detector['data']position=detector['data'].coords['position']returnCalibratedDetector[RunType](da.assign_coords(position=position+offset.to(unit=position.unit)))
[docs]defget_monitor_data(dg:LoadedFileContents[RunType],nexus_name:NeXusMonitorName[MonitorType])->NeXusComponent[MonitorType,RunType]:# The generic NeXus workflow will try to extract 'data' from this, which is exactly# what we also have in the Mantid data. We use the generic workflow since it also# applies offsets, etc.monitor=dg['monitors'][nexus_name]['data']returnNeXusComponent[MonitorType,RunType](sc.DataGroup(data=monitor,position=monitor.coords['position']))
[docs]defdummy_assemble_detector_data(detector:CalibratedDetector[RunType],)->DetectorData[RunType]:"""Dummy assembly of detector data, detector already contains neutron data."""returnDetectorData[RunType](detector)
[docs]defdummy_assemble_monitor_data(monitor:CalibratedMonitor[RunType,MonitorType],)->MonitorData[RunType,MonitorType]:"""Dummy assembly of monitor data, monitor already contains neutron data."""returnMonitorData[RunType,MonitorType](monitor)
[docs]defdata_to_tof(da:DetectorData[ScatteringRunType],)->TofData[ScatteringRunType]:"""Dummy conversion of data to time-of-flight data. The data already has a time-of-flight coordinate."""returnTofData[ScatteringRunType](da)
[docs]defmonitor_to_tof(da:MonitorData[RunType,MonitorType],)->TofMonitor[RunType,MonitorType]:"""Dummy conversion of monitor data to time-of-flight data. The monitor data already has a time-of-flight coordinate."""returnTofMonitor[RunType,MonitorType](da)
[docs]defexperiment_metadata(dg:LoadedFileContents[SampleRun])->Measurement:"""Get experiment metadata from the raw sample data."""returnMeasurement(title=dg['run_title'].value,run_number=dg['run_number'],)
[docs]defhelium3_tube_detector_pixel_shape()->DetectorPixelShape[ScatteringRunType]:# Pixel radius and length# found here:# https://github.com/mantidproject/mantid/blob/main/instrument/SANS2D_Definition_Tubes.xmlR=0.00405L=0.002033984375pixel_shape=sc.DataGroup({'vertices':sc.vectors(dims=['vertex'],values=[# Coordinates in pixel-local coordinate system# Bottom face center[0,0,0],# Bottom face edge[R,0,0],# Top face center[0,L,0],],unit='m',),'nexus_class':'NXcylindrical_geometry',})returnpixel_shape
[docs]deflab_frame_transform()->NeXusTransformation[snx.NXdetector,ScatteringRunType]:# Rotate +y to -xreturnNeXusTransformation[snx.NXdetector,ScatteringRunType](sc.spatial.rotation(value=[0,0,1/2**0.5,1/2**0.5]))
[docs]defget_detector_ids_from_sample_run(data:TofData[SampleRun])->DetectorIDs:"""Extract detector IDs from sample run. This overrides the function in the masking module which gets the detector IDs from the detector before loading event data. In this ISIS case files are loaded using Mantid which does not load event separately, so we get IDs from the data. """returnDetectorIDs(data.coords['detector_number'if'detector_number'indata.coordselse'detector_id'])