You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In analytical mode, the wavelength lookup table treats the source as a flat window of emission times, 0–5 ms (SourceBounds default, widened beyond 2.86 ms to include the tail). For each (distance, event_time_offset) it stores the midpoint of the range of possible wavelengths as the mean, and half the range as the "standard deviation".
Where choppers do not restrict the emission time (no pulse-shaping choppers, e.g. LoKI), this has two consequences:
Mean wavelength is biased. The flat window puts the mean emission time at 2.5 ms. The McStas ESS source used by tof has a mean that depends on wavelength (1.70 ms at 1 Å to 2.14 ms at 15 Å; after the table's conditioning on arrival time, 1.65–1.85 ms for 2–9 Å at 28.7 m). Wavelengths are therefore too short by roughly (h/m) · 0.7 ms / Ltotal, and Q is too large by the same fraction.
Variance is not a variance. Half the range corresponds to 2.5 ms of emission time, while the true standard deviation of the pulse is 0.86–1.0 ms (depending on wavelength). This matters for the Q resolution in [ESSSANS] Q resolution per I(Q) bin #766, which reads σ_λ from the table, and for the masking thresholds.
Comparison at 28.7 m (LoKI rear bank), no choppers, wavelengths 1–10 Å so that frames do not overlap:
toa [ms]
mean, analytical [Å]
mean, simulation [Å]
σ, analytical [Å]
σ, simulation [Å]
14.5
1.652
1.750
0.345
0.123
29.0
3.649
3.745
0.345
0.122
43.0
5.577
5.672
0.345
0.124
57.9
7.642
7.736
0.345
0.126
The mean error is 0.085–0.12 Å over 2–9 Å, largest near 2.2–2.4 Å: 5.4% at 2 Å, 1% at 9 Å. Because it depends on wavelength, it also shows up as a mismatch between data at the same Q from different wavelengths, e.g. between LoKI banks. esslivedata builds its tables in this mode. With pulse-shaping choppers (DREAM, Odin), the choppers define the emission-time window, so the effect should be much smaller, but I have not checked.
Proposal: weight the analytical table by the pulse profile
Split the emission window into K slices, run the chopper cascade once per slice, and combine the slices as a mixture weighted by the source intensity:
s0=s1=s2=0fort0, t1inslices: # e.g. K = 10 over 0–5 msrow=analytical_table(SourceBounds(time=(t0, t1), ...))
m=row.mean# midpoint of range within this slicev=row.half_range**2/3# uniform within the slicew=p(0.5* (t0+t1), m) * (t1-t0) # source intensity at (emission time, wavelength)s0+=w; s1+=w*m; s2+=w* (v+m**2)
mean=s1/s0variance=s2/s0-mean**2
Choppers are handled, since each slice goes through the cascade. Prototype with p from the tof ESS source file, same setup as the table above:
K
max |mean − simulation|
max relative error of σ
time
flat window (current)
0.119 Å
×2.8
–
5
0.013 Å
13%
0.4 s
10
0.023 Å
7%
0.6 s
20
0.027 Å
5%
1.4 s
The residual does not decrease with K (K = 40 gives 0.026 Å), so it is systematic, not a slicing error. It is about 0.004 Å at 2–4 Å and grows towards long wavelengths (0.021 Å and +4% in σ at 8 Å). Whether it comes from the prototype or from the simulated reference is not yet known; that bounds any accuracy claim for this approach. Not yet tested with realistic chopper settings (the LoKI coda test file has all chopper delays at 0).
For p, the separable profile in tof/facilities/ess_pulse/pulse_profile.py (plain arrays, no download) may be enough: the standard deviation of the emission time from the correlated 2D source only varies between 0.86 ms at 1 Å and 1.0 ms at 15 Å.
Open questions
Is this the direction you had in mind for approximating the pulse profile with multiple cascade runs, @nvaytet?
Cost: K times the cascade and rasterization. Acceptable for esslivedata, where the table is rebuilt on chopper changes?
The uncertainty-masking thresholds (LookupTableRelativeErrorThreshold) are tuned to the current half-range values and would need re-tuning.
Problem
In
analyticalmode, the wavelength lookup table treats the source as a flat window of emission times, 0–5 ms (SourceBoundsdefault, widened beyond 2.86 ms to include the tail). For each(distance, event_time_offset)it stores the midpoint of the range of possible wavelengths as the mean, and half the range as the "standard deviation".Where choppers do not restrict the emission time (no pulse-shaping choppers, e.g. LoKI), this has two consequences:
tofhas a mean that depends on wavelength (1.70 ms at 1 Å to 2.14 ms at 15 Å; after the table's conditioning on arrival time, 1.65–1.85 ms for 2–9 Å at 28.7 m). Wavelengths are therefore too short by roughly(h/m) · 0.7 ms / Ltotal, and Q is too large by the same fraction.Comparison at 28.7 m (LoKI rear bank), no choppers, wavelengths 1–10 Å so that frames do not overlap:
The mean error is 0.085–0.12 Å over 2–9 Å, largest near 2.2–2.4 Å: 5.4% at 2 Å, 1% at 9 Å. Because it depends on wavelength, it also shows up as a mismatch between data at the same Q from different wavelengths, e.g. between LoKI banks. esslivedata builds its tables in this mode. With pulse-shaping choppers (DREAM, Odin), the choppers define the emission-time window, so the effect should be much smaller, but I have not checked.
Proposal: weight the analytical table by the pulse profile
Split the emission window into K slices, run the chopper cascade once per slice, and combine the slices as a mixture weighted by the source intensity:
Choppers are handled, since each slice goes through the cascade. Prototype with
pfrom thetofESS source file, same setup as the table above:The residual does not decrease with K (K = 40 gives 0.026 Å), so it is systematic, not a slicing error. It is about 0.004 Å at 2–4 Å and grows towards long wavelengths (0.021 Å and +4% in σ at 8 Å). Whether it comes from the prototype or from the simulated reference is not yet known; that bounds any accuracy claim for this approach. Not yet tested with realistic chopper settings (the LoKI coda test file has all chopper delays at 0).
For
p, the separable profile intof/facilities/ess_pulse/pulse_profile.py(plain arrays, no download) may be enough: the standard deviation of the emission time from the correlated 2D source only varies between 0.86 ms at 1 Å and 1.0 ms at 15 Å.Open questions
LookupTableRelativeErrorThreshold) are tuned to the current half-range values and would need re-tuning.