eTOF response analysis¤
extra.applications.TOFAnalogResponse ¤
TOFAnalogResponse(roi: Optional[slice] = None, n_samples: int = 350, n_filter: int = 100, deconvolve: bool = False, count_threshold: float = 0)
Bases: SerializableMixin
Given a run with the Cookiebox in analog mode, obtain its impulse response.
Example usage:
tof_id = 4
channel = "3_A"
digitizer = "SQS_DIGITIZER_UTC4/ADC/1:network"
energy_source = "SA3_XTD10_MONO/MDL/PHOTON_ENERGY"
calib_run = open_run(proposal=900485, run=320)
scan = Scan(calib_run[energy_source, "actualEnergy.value"],
resolution=2, intra_step_filtering=1)
calib_run = calib_run.select([digitizer, energy_source], require_all=True)
tof = AdqRawChannel(calib_run,
channel=channel,
digitizer=digitizer,
first_pulse_offset=23300,
single_pulse_length=600,
interleaved=True,
baseline=np.s_[:20000],
)
response = TOFAnalogResponse(roi=np.s_[75:])
response.setup(tof, scan)
response.to_file("tof4.h5")
h = response.get_response()
This could also be coupled with the CookieboxCalibration object to deconvolve and denoise spectra before calibration.
# open a new run
run = open_run(proposal=900485, run=349)
# get the calibration constants
cal = CookieboxCalibration.from_file("my_calibration.h5")
# load the trace for this new run, exactly as required for calibration
trace = cal.load_trace(run)
# apply the deconvolution using this TOFResponse object
response = TOFAnalogResponse.from_file("tof4.h5")
trace.loc[dict(tof=4)] = response.apply(trace.sel(tof=4))
# now apply the calibration:
spectrum = cal.calibrate(trace)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
roi
|
Optional[slice]
|
Region of interest. Keep None to use the full trace. |
None
|
n_samples
|
int
|
Total number of samples use for impulse response. |
350
|
n_filter
|
int
|
Number of samples before the peak to select. |
100
|
deconvolve
|
bool
|
Whether to deconvolve the effect of two added peaks (ie: Auger-Meitner and monochromated photoline). |
False
|
count_threshold
|
float
|
If set, counts number of photo-electrons above this threshold. Should be negative. |
0
|
to_file ¤
Dump all data needed for applying the calibration into an h5 file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filename
|
str
|
The output file name. |
required |
estimate_truth ¤
Estimate response function from data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
The data as an numpy array. |
required |
Returns: The response function.
shift_h ¤
Align data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
The data as a numpy array. |
required | |
h_axis
|
The response function x-axis. |
required |
Returns: The response function.
setup ¤
Given a AdqRawChannel object, and an energy scan object calculate this eTOF's impulse response function, assuming the corresponding run contins a scan over monochromated beams.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tof
|
AdqRawChannel
|
|
required |
scan
|
Scan
|
|
None
|
apply ¤
apply(tof_trace: Union[DataArray, ndarray], n_iter: int = 5000, method: str = 'tv_matrix', extra_shift: int = 2, normalization: str = 'integral', **kwargs) -> xr.DataArray
Apply TV-deconvolution on TOF data taken in analog mode, assuming the given parameter setting and using the Lambda parameter as a denoising strength.
This could be coupled with the CookieboxCalibration object to deconvolve and denoise spectra before calibration.
# open a new run
run = open_run(proposal=900485, run=349)
# get the calibration constants
cal = CookieboxCalibration.from_file("my_calibration.h5")
# load the trace for this new run, exactly as required for calibration
trace = cal.load_trace(run)
# apply the deconvolution using this TOFResponse object
response = TOFAnalogResponse.from_file("tof4.h5")
trace.loc[dict(tof=4)] = response.apply(trace.sel(tof=4))
# now apply the calibration:
spectrum = cal.calibrate(trace)
If the raw trace is desired, this could be used independetly from the calibration object simply to mprove the trace resolution.
Example of usage without the calibration:
ts = "SQS_RR_UTC/TSYS/TIMESERVER:outputBunchPattern"
digitizer = 'SQS_DIGITIZER_UTC4/ADC/1:network'
digitizer_ctl = 'SQS_DIGITIZER_UTC4/ADC/1:network'
tof_id = 4
channel = "3_A"
calib_run = open_run(proposal=900485, run=509).select([ts,
digitizer, digitizer_ctl
], require_all=True)
# set up AdqRawChannel object to read data from each eTOF
tof = AdqRawChannel(run,
channel=channel,
digitizer=digi,
first_pulse_offset=23300,
single_pulse_length=600,
interleaved=True,
baseline=np.s_[:20000],
)
# fetch data
# select only first samples, since we don't care about the full trace
original = -tof.pulse_data(pulse_dim='pulseIndex').sel(sample=np.s_[0:400])
# retrieve impulse response from a file
response = TOFAnalogResponse.from_file("tof4.h5")
# apply it
result = response.apply(original)
# plot it
plt.plot(result.isel(trainId=0, pulseIndex=0), lw=2, label="Deconvolved")
plt.plot(original.isel(trainId=0, pulseIndex=0), lw=2, label="Original")
plt.show()
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tof_trace
|
Union[DataArray, ndarray]
|
The eTOF data as a DataArray returned by |
required |
n_iter
|
int
|
Number of deconvoluton iterations. |
5000
|
method
|
str
|
Set to "nn_matrix" for non-negative matrix multiplications. Set to "tv_matrix" for Total Variatio deconvolution. Use "standard" for standard deconvolution. |
'tv_matrix'
|
extra_shift
|
int
|
Shift the impulse response function by this many points before using it to align the data. |
2
|
normalization
|
str
|
If 'integral', preserves the sum of the spectrum. If 'maximum', preserves the maximum of the spectrum. |
'integral'
|
Returns:
| Type | Description |
|---|---|
DataArray
|
The deconvolved data as a DataArray. |