SpecularReflectionPositionCorrect v2

../_images/SpecularReflectionPositionCorrect-v2_dlg.png

SpecularReflectionPositionCorrect dialog.

Summary

Corrects a reflectometer’s detector component’s position.

Properties

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.

Description

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.

Schematic representation of angle correction when only TwoTheta is given.

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.

Schematic representation of angle correction when TwoTheta and LinePosition are given.

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.

Schematic representation of angle correction when direct beam reference is used.

Note

The line positions can be acquired by using, for instance, FindReflectometryLines.

Previous Versions

For version 1 of the algorithm, please see SpecularReflectionPositionCorrect-v1.

Usage

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

Source

C++ source: SpecularReflectionPositionCorrect2.cpp (last modified: 2019-07-17)

C++ header: SpecularReflectionPositionCorrect2.h (last modified: 2019-01-23)