\(\renewcommand\AA{\unicode{x212B}}\)
Table of Contents
Corrects the time-of-flight axis with regards to the incident energy and the L1+L2 distance or a reference workspace.
Name | Direction | Type | Default | Description |
---|---|---|---|---|
InputWorkspace | Input | MatrixWorkspace | Mandatory | An input workspace. |
OutputWorkspace | Output | MatrixWorkspace | Mandatory | An output workspace. |
ReferenceWorkspace | Input | MatrixWorkspace | A reference workspace from which to copy the TOF axis as well as the ‘Ei’ and ‘wavelength’ sample logs. | |
EPPTable | Input | TableWorkspace | An input EPP table. | |
IndexType | Input | string | Detector ID | The type of indices used in ReferenceSpectra or ElasticBinIndex (default: ‘Detector ID’). Allowed values: [‘Detector ID’, ‘Spectrum Number’, ‘Workspace Index’] |
ReferenceSpectra | Input | int list | A list of reference spectra. | |
ElasticBinIndex | Input | number | Optional | Bin index of the nominal elastic TOF channel. |
EFixed | Input | number | Optional | Incident energy if the ‘EI’ sample log is not present/incorrect. |
L2 | Input | number | Optional | Sample to detector distance, in meters. |
This algorithm is meant to adjust the time-of-flight axis so that the elastic peak is at zero energy transfer after unit conversion from ‘TOF’ to ‘DeltaE’. The algorithm has two modes: either it uses a given ReferenceWorkspace, or it calculates a constant time-of-flight shift using the L1 + L2 distances of the InputWorkspace and incident energy.
If ReferenceWorkspace is set, this algorithm copies the X axis as well as the ‘Ei’ and ‘wavelength’ sample logs, if present, to OutputWorkspace. The rest of the input properties are discarded.
If no ReferenceWorkspace is given, the algorithm takes the source-to-sample distance \(l_1\) from the instrument attached to InputWorkspace. The source-to-detector distance \(l_2\) can either be given directly by the L2 property, or it is calculated as the mean L2 distance from the histograms specified by ReferenceSpectra. The algorithm also needs to know the TOF \(t_{elastic}\) corresponding to the zero-energy transfer. This is either taken from the first spectrum in InputWorkspace as the bin centre of the bin specified by ElasticBinIndex, or calculated from the elastic peak positions given in EPPTable. EPPTable should be in the format returned by the FindEPP v2 algorithm. In this case the algorithm averages the PeakCentre column for histograms listed in ReferenceSpectra. Finally, the algorithm needs the incident energy \(E_i\) which can be either specified by EFixed or is taken from the sample logs of InputWorkspace. In case EFixed is specified, the ‘Ei’ and ‘wavelength’ sample logs of OutputWorkspace are updated accordingly.
The TOF shift \(\Delta t\) is calculated by
\(\Delta t = t_{elastic} - (l_1 + l_2) / \sqrt{2 E_i / m_n}\),
where \(m_n\) is the neutron mass. The shift \(\Delta t\) is then added to all X values of OutputWorkspace.
The algorithm assumes micro seconds as units of time and meV as units of energy.
Whether the ReferenceSpectra input property refers to workspace indices, spectrum numbers or detector IDs is specified by IndexType.
Example - CorrectTOFAxis by specifying the elastic bin and L2
from mantid.kernel import DeltaEModeType, UnitConversion
L1 = 2.0 # in metres.
L2 = 2.0
Ei = 55.0 # in meV
elasticTOF = UnitConversion.run(src='Energy', dest='TOF',
srcValue=Ei,
l1=L1, l2=L2,
theta=0, emode=DeltaEModeType.Direct, efixed=Ei)
# Make a workspace with wrong TOF axis.
TOFMin = 0.0
TOFMax = 100.0
binWidth = 0.5
# Lets say the elastic bin is in the centre of the spectrum.
elasticBinIndex = int(((TOFMax - TOFMin) / binWidth) / 2.0)
# Build a Gaussian elastic peak in the workspace.
peakCentre = TOFMin + elasticBinIndex * binWidth
spectrumDescription = '''name=Gaussian, PeakCentre={0},
Height=100, Sigma={1}'''.format(peakCentre, 0.03 * peakCentre)
ws = CreateSampleWorkspace(WorkspaceType='Histogram',
NumBanks=1,
BankPixelWidth=1,
Function='User Defined',
UserDefinedFunction=spectrumDescription,
BankDistanceFromSample=L2,
SourceDistanceFromSample=L1,
XMin=TOFMin,
XMax=TOFMax,
BinWidth=binWidth)
# Do the correction.
correctedWs = CorrectTOFAxis(ws,
IndexType='Workspace Index',
ElasticBinIndex=elasticBinIndex,
EFixed=Ei,
L2=L2)
# Convert TOF to energy transfer.
convertedWs = ConvertUnits(correctedWs,
Target='DeltaE',
EMode='Direct')
# Check results
# Zero energy transfer should be around elasticBinIndex.
for index in range(elasticBinIndex-1, elasticBinIndex+2):
binCentre = (convertedWs.readX(0)[index+1] + convertedWs.readX(0)[index]) / 2
print('DeltaE at the centre of bin {0}: {1:0.4f}'.format(index,binCentre))
Output:
DeltaE at the centre of bin 99: -0.0893
DeltaE at the centre of bin 100: -0.0000
DeltaE at the centre of bin 101: 0.0891
Example - CorrectTOFAxis by specifying the elastic bin and taking L2 from reference spectra
from mantid.kernel import DeltaEModeType, UnitConversion
L1 = 2.0 # in metres.
L2 = 2.0
Ei = 55.0 # in meV
elasticTOF = UnitConversion.run(src='Energy', dest='TOF',
srcValue=Ei,
l1=L1, l2=L2,
theta=0, emode=DeltaEModeType.Direct, efixed=Ei)
# Make a workspace with wrong TOF axis.
TOFMin = 0.0
TOFMax = 100.0
binWidth = 0.5
# Lets say the elastic bin is in the centre of the spectrum.
elasticBinIndex = int(((TOFMax - TOFMin) / binWidth) / 2.0)
# Build a Gaussian elastic peak in the workspace.
peakCentre = TOFMin + elasticBinIndex * binWidth
spectrumDescription = '''name=Gaussian, PeakCentre={0},
Height=100, Sigma={1}'''.format(peakCentre, 0.03 * peakCentre)
ws = CreateSampleWorkspace(WorkspaceType='Histogram',
NumBanks=1,
BankPixelWidth=1,
Function='User Defined',
UserDefinedFunction=spectrumDescription,
BankDistanceFromSample=L2,
SourceDistanceFromSample=L1,
XMin=TOFMin,
XMax=TOFMax,
BinWidth=binWidth)
# Do the correction.
correctedWs = CorrectTOFAxis(ws,
IndexType='Workspace Index',
ReferenceSpectra='0',
ElasticBinIndex=elasticBinIndex,
EFixed=Ei)
# Convert TOF to energy transfer.
convertedWs = ConvertUnits(correctedWs,
Target='DeltaE',
EMode='Direct')
# Check results
# Zero energy transfer should be around elasticBinIndex.
for index in range(elasticBinIndex-1, elasticBinIndex+2):
binCentre = (convertedWs.readX(0)[index+1] + convertedWs.readX(0)[index]) / 2
print('DeltaE at the centre of bin {0}: {1:0.4f}'.format(index,binCentre))
Output:
DeltaE at the centre of bin 99: -0.0893
DeltaE at the centre of bin 100: -0.0000
DeltaE at the centre of bin 101: 0.0891
Example - CorrectTOFAxis using EPP table
from mantid.kernel import DeltaEModeType, UnitConversion
import numpy
L1 = 2.0 # in metres
L2 = 2.0
Ei = 55.0 # in meV
elasticTOF = UnitConversion.run(src='Energy', dest='TOF',
srcValue=Ei,
l1=L1, l2=L2,
theta=0, emode=DeltaEModeType.Direct, efixed=Ei)
# Make a workspace with wrong TOF axis.
TOFMin = 0.0
TOFMax = 100.0
# Build a Gaussian elastic peak in the workspace.
peakCentre = TOFMin + 2.0 * (TOFMax - TOFMin) / 3.0
spectrumDescription = '''name=Gaussian, PeakCentre={0},
Height=100, Sigma={1}'''.format(peakCentre, 0.03 * peakCentre)
ws = CreateSampleWorkspace(WorkspaceType='Histogram',
NumBanks=1,
BankPixelWidth=1,
Function='User Defined',
UserDefinedFunction=spectrumDescription,
BankDistanceFromSample=L2,
SourceDistanceFromSample=L1,
XMin=TOFMin,
XMax=TOFMax,
BinWidth=0.5)
# Prepare for the correction.
EPPTable = FindEPP(ws)
# Do the correction.
correctedWs = CorrectTOFAxis(ws,
EPPTable=EPPTable,
IndexType='Workspace Index',
ReferenceSpectra='0',
EFixed=Ei)
# Check results.
print('Original TOF for the elastic peak: {0:0.1f}'.format(
ws.readX(0)[numpy.argmax(ws.readY(0))]))
print('Corrected TOF for the elastic peak: {0:0.1f}'.format(
correctedWs.readX(0)[numpy.argmax(correctedWs.readY(0))]))
print('Actual elastic TOF: {0:0.1f}'.format(elasticTOF))
Output:
Original TOF for the elastic peak: 66.5
Corrected TOF for the elastic peak: 1232.7
Actual elastic TOF: 1233.1
Example - CorrectTOFAxis using a reference workspace
from mantid.kernel import DeltaEModeType, UnitConversion
import numpy
L1 = 2.0
L2 = 2.0
Ei = 55.0 # in meV
elasticTOF = UnitConversion.run(src='Energy', dest='TOF',
srcValue=Ei,
l1=L1, l2=L2,
theta=0, emode=DeltaEModeType.Direct, efixed=Ei)
# Make two workspaces with wrong TOF axis.
TOFMin = 0.0
TOFMax = 100.0
peakCentre = TOFMin + 2.0 * (TOFMax - TOFMin) / 3.0
# Build a Gaussian elastic peak in the first workspace.
spectrumDescription = '''name=Gaussian, PeakCentre={0},
Height=100, Sigma={1}'''.format(peakCentre, 0.03 * peakCentre)
ws1 = CreateSampleWorkspace(WorkspaceType='Histogram',
NumBanks=1,
BankPixelWidth=1,
Function='User Defined',
UserDefinedFunction=spectrumDescription,
BankDistanceFromSample=L2,
SourceDistanceFromSample=L1,
XMin=TOFMin,
XMax=TOFMax,
BinWidth=0.5)
# Build a second workspace with slightly different Gaussian.
spectrumDescription = '''name=Gaussian, PeakCentre={0},
Height=100, Sigma={1}'''.format(peakCentre, 0.06 * peakCentre)
ws2 = CreateSampleWorkspace(WorkspaceType='Histogram',
NumBanks=1,
BankPixelWidth=1,
Function='User Defined',
UserDefinedFunction=spectrumDescription,
BankDistanceFromSample=L2,
SourceDistanceFromSample=L1,
XMin=TOFMin,
XMax=TOFMax,
BinWidth=0.5)
# Correct the first workspace using the EPP table method.
EPPTable = FindEPP(ws1)
# Do the correction.
correctedWs1 = CorrectTOFAxis(ws1,
EPPTable=EPPTable,
IndexType='Workspace Index',
ReferenceSpectra='0',
EFixed=Ei)
# Correct the second workspace by using the first as a reference.
correctedWs2 = CorrectTOFAxis(ws2,
ReferenceWorkspace=correctedWs1)
# Check results
print('First workspace original TOF for the elastic peak: {0:0.1f}'.format(
ws1.readX(0)[numpy.argmax(ws1.readY(0))]))
print('EPP table corrected TOF for the elastic peak: {0:0.1f}'.format(
correctedWs1.readX(0)[numpy.argmax(correctedWs1.readY(0))]))
print('Elastic TOF for the corrected second workspace: {0:0.1f}'.format(
correctedWs2.readX(0)[numpy.argmax(correctedWs2.readY(0))]))
Output:
First workspace original TOF for the elastic peak: 66.5
EPP table corrected TOF for the elastic peak: 1232.7
Elastic TOF for the corrected second workspace: 1232.7
Categories: AlgorithmIndex | Inelastic\Corrections
C++ header: CorrectTOFAxis.h (last modified: 2021-03-31)
C++ source: CorrectTOFAxis.cpp (last modified: 2021-03-31)