Instrument view#
Overview#
A simple version of the Mantid instrument view is available in scippneutron
. It currently does not support detector ‘picking’ and manual drawing of masks, nor does it render the actual shape of the detectors (currently it represents them as 2-D squares), but basic functionalities such as spatial slicing, as well as navigation through the time-of-flight dimension via a slider, are provided.
Note
The file used in this notebook is from the Mantid training course data.
Warning
While you can interact with the 3D view of the instrument, the buttons and sliders will have no effect in the documentation pages, as there is no kernel to perform the operations. These will only work inside a Jupyter notebook.
We load a file containing a position
coordinate:
[1]:
import numpy as np
import scipp as sc
import scippneutron as scn
import scippneutron.data
[2]:
sample = scn.data.powder_sample()['data'].hist()
sample
FrameworkManager-[Notice] Welcome to Mantid 6.10.0
FrameworkManager-[Notice] Please cite: http://dx.doi.org/10.1016/j.nima.2014.07.029 and this release: http://dx.doi.org/10.5286/Software/Mantid6.10
CheckMantidVersion-[Notice] A new version of Mantid(6.11.0) is available for download from https://download.mantidproject.org
DownloadInstrument-[Notice] All instrument definitions up to date
Load-[Notice] Load started
Load-[Notice] Load successful, Duration 1.45 seconds
DeleteWorkspace-[Notice] DeleteWorkspace started
DeleteWorkspace-[Notice] DeleteWorkspace successful, Duration 0.00 seconds
[2]:
- spectrum: 24794
- tof: 1
- position(spectrum)vector3m[ 1.17451004 -1.01106149 -2.03796699], [ 1.18147634 -0.95946649 -2.05334117], ..., [1.81428985 0.09565841 3.84338287], [1.81375055 0.1499371 3.84269584]
Values:
array([[ 1.17451004, -1.01106149, -2.03796699], [ 1.18147634, -0.95946649, -2.05334117], [ 1.18844265, -0.90787149, -2.06871534], ..., [ 1.81482915, 0.04137972, 3.8440699 ], [ 1.81428985, 0.09565841, 3.84338287], [ 1.81375055, 0.1499371 , 3.84269584]]) - sample_position()vector3m[0. 0. 0.]
Values:
array([0., 0., 0.]) - source_position()vector3m[ 0. 0. -60.]
Values:
array([ 0., 0., -60.]) - spectrum(spectrum)int321, 2, ..., 24793, 24794
Values:
array([ 1, 2, 3, ..., 24792, 24793, 24794], dtype=int32) - tof(tof [bin-edge])float64µs19.0, 1.669e+04
Values:
array([ 19. , 16694.30078125])
- (spectrum, tof)float32counts0.0, 0.0, ..., 0.0, 0.0σ = 0.0, 0.0, ..., 0.0, 0.0
Values:
array([[0.], [0.], [0.], ..., [0.], [0.], [0.]], dtype=float32)
Variances (σ²):
array([[0.], [0.], [0.], ..., [0.], [0.], [0.]], dtype=float32)
The instrument_view
function can now be used to display a 3-D representation:
[3]:
scn.instrument_view(sample)
[3]:
The button in the toolbar activates a tool that lets you can create spatial cuts to slice your data in 3D.
It is possible to customize the figure using the usual arguments, as well as adjusting the pixel size, e.g.
[4]:
scn.instrument_view(
sample, cmap="magma", vmax=2000.0 * sc.units.counts, norm="log", pixel_size=0.03
)
[4]:
Displaying additional components#
Additional beamline components can be displayed in the instrument view by providing a dict
of component settings. As we can see above, the loaded data array also contains source_position
and sample_position
stored as 3-D vector coordinates. This is in addition to the position
coordinate, which defines only the positions of detector pixels.
Apart from position
, the instrument_view
does not require data arrays to follow a pre-defined naming convention for additional components. Instead it relies on the aforementioned dict
of components, which can be customized, e.g., for a particular beamline.
The dict
key of the component is used as the text label. Component settings are given in the form of a dictionary defining, e.g., color
, size
, and type
. We can pick from a limited number of type
s including cylinder
, disk
and box
:
[5]:
sample_settings = {
'center': sample.meta['sample_position'],
'color': '#000000',
'wireframe': True,
'size': sc.vector(value=[0.3, 0.3, 0.3], unit=sc.units.m),
'type': 'box',
}
source_settings = {
'center': sample.meta['source_position'],
'color': '#FFC133',
'size': sc.vector(value=[1000, 2000, 1000], unit=sc.units.mm),
'type': 'cylinder',
}
scn.instrument_view(
sample, components={'sample': sample_settings, 'source': source_settings}
)
sc.DataArray.attrs has been deprecated and will be removed in Scipp v24.12.0. The deprecation includes sc.DataArray.meta and sc.DataArray.drop_attrs. For unaligned coords, use sc.DataArray.coords and unset the alignment flag. For other attributes, use a higher-level data structure.
sc.DataArray.attrs has been deprecated and will be removed in Scipp v24.12.0. The deprecation includes sc.DataArray.meta and sc.DataArray.drop_attrs. For unaligned coords, use sc.DataArray.coords and unset the alignment flag. For other attributes, use a higher-level data structure.
[5]:
Defining detector positions#
If data comes without pre-defined detector-positions, e.g., when they are not contained in the original file, they can be defined by simply adding a position
coordinate to a data array:
[6]:
nx, ny = (10, 10)
points_x = np.linspace(0, 1, nx)
points_y = np.linspace(0, 1, ny)
xv, yv = np.meshgrid(points_x, points_y)
_x = sc.array(dims=['spectrum'], values=xv.ravel())
_y = sc.array(dims=['spectrum'], values=yv.ravel())
_z = sc.array(dims=['spectrum'], values=np.zeros(100))
data = sc.arange('spectrum', 100.0, unit='counts')
da = sc.DataArray(data)
da.coords['position'] = sc.spatial.as_vectors(_x, _y, _z)
da.coords['spectrum'] = sc.arange('spectrum', 100)
scn.instrument_view(da, pixel_size=0.1)
[6]: