-
Notifications
You must be signed in to change notification settings - Fork 122
/
GetEiT0atSNS.py
86 lines (78 loc) · 3.87 KB
/
GetEiT0atSNS.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
"""*WIKI*
Get Ei and T0 on ARCS and SEQUOIA instruments. It accounts for the following:
* in the ADARA framework, the monitors are in the first frame.
* SEQUOIA has event based monitors.
* some data aquisition errors will create unphysical monitor IDs. This will be ignored
* when vChTrans is 2, on ARCS and SEQUOIA there is no chopper in the beam (white beam). Will return not a number for both Ei and T0
*WIKI*"""
import mantid
import numpy
class GetEiT0atSNS(mantid.api.PythonAlgorithm):
def category(self):
""" Return category
"""
return "PythonAlgorithms;Inelastic"
def name(self):
""" Return name
"""
return "GetEiT0atSNS"
def PyInit(self):
""" Declare properties
"""
self.declareProperty(mantid.api.WorkspaceProperty("MonitorWorkspace", "",direction=mantid.kernel.Direction.InOut), "Monitor workspace")
self.declareProperty("IncidentEnergyGuess",-1.,doc="Incident energy guess")
self.declareProperty("Ei",0.0,mantid.kernel.Direction.Output)
self.declareProperty("T0",0.0,mantid.kernel.Direction.Output)
return
def PyExec(self):
""" Main execution body
"""
wm=self.getProperty("MonitorWorkspace").value
i=wm.getInstrument()
if numpy.mean(wm.getRun()['vChTrans'].value) == 2:
Ei=numpy.nan
Tzero=numpy.nan
else:
EGuess=self.getProperty("IncidentEnergyGuess").value
if EGuess<0:
try:
EGuess=wm.getRun()['EnergyRequest'].getStatistics().mean
except:
raise RuntimeError("No energy guess was given or could be found in sample logs")
try:
#fix more than 2 monitors
sp1=-1
sp2=-1
nsp=wm.getNumberHistograms()
if nsp < 2:
raise ValueError("There are less than 2 monitors")
for sp in range(nsp):
if wm.getSpectrum(sp).getDetectorIDs()[0]==-int(i.getNumberParameter('ei-mon1-spec')[0]):
sp1=sp
if wm.getSpectrum(sp).getDetectorIDs()[0]==-int(i.getNumberParameter('ei-mon2-spec')[0]):
sp2=sp
if sp1==-1:
raise RuntimeError("Could not find spectrum for the first monitor")
if sp2==-1:
raise RuntimeError("Could not find spectrum for the second monitor")
#change frame for monitors. ARCS monitors would be in the first frame for Ei>10meV
so=i.getSource().getPos()
m1=wm.getDetector(sp1).getPos()
m2=wm.getDetector(sp2).getPos()
v=437.4*numpy.sqrt(wm.getRun()['EnergyRequest'].getStatistics().mean)
t1=m1.distance(so)*1e6/v
t2=m2.distance(so)*1e6/v
t1f=int(t1*60e-6) #frame number for monitor 1
t2f=int(t2*60e-6) #frame number for monitor 2
wtemp=mantid.simpleapi.ChangeBinOffset(wm,t1f*16667,0,0)
wtemp=mantid.simpleapi.ChangeBinOffset(wtemp,t2f*16667,1,1)
wtemp=mantid.simpleapi.Rebin(InputWorkspace=wtemp,Params="1",PreserveEvents=True)
alg=mantid.simpleapi.GetEi(InputWorkspace=wtemp,Monitor1Spec=sp1+1,Monitor2Spec=sp2+1,EnergyEstimate=EGuess) #Run GetEi algorithm
Ei=alg[0]
Tzero=alg[3] #Extract incident energy and T0
mantid.simpleapi.DeleteWorkspace(wtemp)
except Exception as e:
raise RuntimeError("Could not get Ei, and this is not a white beam run\n"+e.message)
self.setProperty("Ei",Ei)
self.setProperty("T0",Tzero)
mantid.api.AlgorithmFactory.subscribe(GetEiT0atSNS)