Table of Contents
Name | Direction | Type | Default | Description |
---|---|---|---|---|
InputWorkspace | Input | MatrixWorkspace | Mandatory | An input workspace to correct. |
TwoTheta | Input | number | Optional | Angle used to correct the detector component [degrees]. |
DetectorCorrectionType | Input | string | VerticalShift | Whether detectors should be shifted vertically or rotated around the sample position. Allowed values: [‘VerticalShift’, ‘RotateAroundSample’] |
DetectorComponentName | Input | string | Name of the detector component to correct, for example point-detector | |
DetectorID | Input | number | Optional | The ID of the detector to correct; if both the component name and the detector ID are set the latter will be used. |
SampleComponentName | Input | string | some-surface-holder | Name of the sample component; if the given name is not found in the instrument, the default sample is used. |
OutputWorkspace | Output | MatrixWorkspace | Mandatory | A workspace with corrected detector position. |
DetectorFacesSample | Input | boolean | False | If true, a normal vector at the centre of the detector always points towards the sample. |
LinePosition | Input | number | Optional | A fractional workspace index for the specular line centre. |
DirectLinePosition | Input | number | Optional | A fractional workspace index for the direct line centre. |
PixelSize | Input | number | Optional | Size of a detector pixel, in metres. |
DirectLineWorkspace | Input | MatrixWorkspace | A direct beam workspace for reference. |
Moves the specified detector component to a given angle between the beam and the sample-to-detector vector. The detector component is moved as a block. The rest of the instrument components remain in original positions. The component can be shifted vertically (default), or rotated around the sample position. When rotating around the sample, an optional rotation can be applied so that the detector always faces the sample.
In the most basic operation, the detector is moved to the angle specified by TwoTheta. This case is schematically shown below for rotation around the sample position and DetectorFacesSample set to True.
If LinePosition and PixelSize are also given, the detector will be moved such that the angle will be TwoTheta for the pixel at workspace index LinePosition. Note that LinePosition can be a fractional index making it possible to adjust the detector angle to a fitted line position. The figure below illustrates this option.
The last possible detector position correction is calibration by a separate direct beam measurement. The idea is to correct the detector angle by difference between the nominal beam axis and the measured direct beam as shown in the figure below. In this mode TwoTheta is omitted but DirectLinePosition, DirectLineWorkspace and PixelSize have to be specified.
Note
The line positions can be acquired by using, for instance, FindReflectometryLines.
For version 1 of the algorithm, please see SpecularReflectionPositionCorrect-v1.
Note
To run these usage examples please first download the usage data, and add these to your path. In MantidPlot this is done using Manage User Directories.
Example - Correct ‘point-detector’
print('point-detector')
polref = Load(Filename=r'POLREF00004699.raw', PeriodList=1)
polref = polref[0]
instr = polref.getInstrument()
print('Original position: ' + str(instr.getComponentByName('point-detector').getPos()))
polref_vert = SpecularReflectionPositionCorrect(polref, TwoTheta = 2*0.49, DetectorComponentName='point-detector', DetectorCorrectionType='VerticalShift')
instr = polref_vert.getInstrument()
print('Vertical shift: ' + str(instr.getComponentByName('point-detector').getPos()))
polref_rot = SpecularReflectionPositionCorrect(polref, TwoTheta = 2*0.49, DetectorComponentName='point-detector', DetectorCorrectionType='RotateAroundSample')
instr = polref_rot.getInstrument()
print('Rotated: ' + str(instr.getComponentByName('point-detector').getPos()))
Output:
Note that in this case the difference between shifting the detectors vertically or rotating them is negligible.
point-detector
Original position: [25.6,0,0.0444961]
Vertical shift: [25.6,0,0.0444753]
Rotated: [25.6,0,0.0444753]
Example - Correct ‘lineardetector’
print('lineardetector')
polref = Load(Filename=r'POLREF00004699.raw', PeriodList=1)
polref = polref[0]
instr = polref.getInstrument()
print('Original position: ' + str(instr.getComponentByName('lineardetector').getPos()))
polref_vert = SpecularReflectionPositionCorrect(polref, TwoTheta = 2*0.49, DetectorComponentName='lineardetector')
instr = polref_vert.getInstrument()
print('Vertical shift: ' + str(instr.getComponentByName('lineardetector').getPos()))
polref_rot = SpecularReflectionPositionCorrect(polref, TwoTheta = 2*0.49, DetectorComponentName='lineardetector', DetectorCorrectionType='RotateAroundSample')
instr = polref_rot.getInstrument()
print('Rotated: ' + str(instr.getComponentByName('lineardetector').getPos()))
Output:
lineardetector
Original position: [26,0,0]
Vertical shift: [26,0,0.0513177]
Rotated: [25.9996,0,0.0513102]
Example - Correct ‘OSMOND’
print('OSMOND')
polref = Load(Filename=r'POLREF00004699.raw', PeriodList=1)
polref = polref[0]
instr = polref.getInstrument()
print('Original position: ' + str(instr.getComponentByName('OSMOND').getPos()))
polref_vert = SpecularReflectionPositionCorrect(polref, TwoTheta = 2*0.49, DetectorComponentName='OSMOND')
instr = polref_vert.getInstrument()
print('Vertical shift: ' + str(instr.getComponentByName('OSMOND').getPos()))
polref_rot = SpecularReflectionPositionCorrect(polref, TwoTheta = 2*0.49, DetectorComponentName='OSMOND', DetectorCorrectionType='RotateAroundSample')
instr = polref_rot.getInstrument()
print('Rotated: ' + str(instr.getComponentByName('OSMOND').getPos()))
Output:
OSMOND
Original position: [26,0,0]
Vertical shift: [26,0,0.0513177]
Rotated: [25.9996,0,0.0513102]
Example - Rotate given pixel
import numpy
# We'll just use an empty workspace here.
ws = LoadEmptyInstrument(InstrumentName='D17')
# Get rid of monitors
ExtractMonitors(ws, DetectorWorkspace='ws')
ws = mtd['ws']
line_position = 22.
spectrum_info = ws.spectrumInfo()
two_theta = numpy.rad2deg(spectrum_info.twoTheta(int(line_position)))
print('Pixel {} 2theta'.format(int(line_position)))
print('before angle correction: {:.3}'.format(two_theta))
ws = SpecularReflectionPositionCorrect(
ws,
TwoTheta=1.5,
DetectorCorrectionType='RotateAroundSample',
DetectorComponentName='detector',
DetectorFacesSample=True,
LinePosition=line_position,
PixelSize=0.001195)
spectrum_info = ws.spectrumInfo()
two_theta = numpy.rad2deg(spectrum_info.twoTheta(int(line_position)))
print('after angle correction: {:.3}'.format(two_theta))
Output:
Pixel 22 2theta
before angle correction: 2.33
after angle correction: 1.5
Example - Use direct beam for angle calibration
import numpy
# We'll just use empty workspaces here.
reflected = LoadEmptyInstrument(InstrumentName='Figaro')
direct = LoadEmptyInstrument(InstrumentName='Figaro')
# Get rid of monitors
ExtractMonitors(reflected, DetectorWorkspace='reflected')
reflected = mtd['reflected']
ExtractMonitors(direct, DetectorWorkspace='direct')
direct = mtd['direct']
line_position = 202.
spectrum_info = reflected.spectrumInfo()
two_theta = numpy.rad2deg(spectrum_info.twoTheta(int(line_position)))
print('Pixel {} 2theta'.format(int(line_position)))
print('before angle correction: {:.3}'.format(two_theta))
direct_line_position = 130.7 # This could come from some fitting procedure
reflected = SpecularReflectionPositionCorrect(
reflected,
DetectorCorrectionType='RotateAroundSample',
DetectorComponentName='detector',
DetectorFacesSample=True,
PixelSize=0.001195,
DirectLineWorkspace=direct,
DirectLinePosition=direct_line_position)
spectrum_info = reflected.spectrumInfo()
two_theta = numpy.rad2deg(spectrum_info.twoTheta(int(line_position)))
print('after angle correction: {:.3}'.format(two_theta))
Output:
Pixel 202 2theta
before angle correction: 5.11
after angle correction: 4.89
Categories: AlgorithmIndex | Reflectometry
C++ source: SpecularReflectionPositionCorrect2.cpp (last modified: 2019-07-17)
C++ header: SpecularReflectionPositionCorrect2.h (last modified: 2019-01-23)