Skip to content

eTOF response analysis¤

extra.recipes.TOFAnalogResponse ¤

TOFAnalogResponse(roi: Optional[slice] = None, n_samples: int = 300, n_filter: int = 75)

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.

300

to_file ¤

to_file(filename: str)

Dump all data needed for applying the calibration into an h5 file.

Parameters:

Name Type Description Default
filename str

The output file name.

required

from_file classmethod ¤

from_file(filename: str)

Load setup saved with save previously.

setup ¤

setup(tof: AdqRawChannel, scan: Scan)

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

AdqRawChannel used to access data for a given eTOF.

required
scan Scan

Scan used to detect which regions cotain which energies.

required

get_response ¤

get_response(reflection_period: List[int] = list(), reflection_amplitude: List[float] = list())

Returns the instrument response.

Parameters:

Name Type Description Default
reflection_period List[int]

Simulate reflection with these distances.

list()
reflection_amplitude List[float]

Amplitudes of the reflections.

list()

plot ¤

plot()

Plot impulse response.

apply ¤

apply(tof_trace: Union[DataArray, ndarray], n_iter: int = 5000, reflection_period: List[int] = list(), reflection_amplitude: List[float] = list(), method: str = 'tv_matrix', extra_shift: int = 2, **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 AdqRawChannel with shape (pulses, samples), or a numpy array of shape (n_pulses, n_samples)

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

Returns:

Type Description
DataArray

The deconvolved data as a DataArray.

extra.recipes.TOFResponse ¤

TOFResponse(threshold: int = -7, n_peaks: Optional[int] = 1, n_samples: int = 400, n_filter: int = 100, roi: Optional[slice] = None)

Bases: SerializableMixin

Given a run with the Cookiebox in counting mode, obtain its impulse response.

Example usage:

tof_id = 4
channel = "3_A"
digitizer = "SQS_DIGITIZER_UTC4/ADC/1:network"
calib_run = open_run(proposal=900485, run=320)
calib_run = calib_run.select([digitizer], 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 = TOFResponse()
response.setup(tof)
response.to_file("tof4.h5")
h = response.get_response(type="aligned")

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 = TOFResponse.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
threshold int

Threshold to use when identifying edges.

-7
n_peaks Optional[int]

Number of peaks to select, if positive. Otherwise no peak selection is made.

1
n_samples int

Total number of samples use for impulse response.

400
n_filter int

Require no edges to be found before sample n_filter and after n_samples-n_filter.

100
roi Optional[slice]

Region of interest. Keep None to use the full trace.

None

to_file ¤

to_file(filename: str)

Dump all data needed for applying the calibration into an h5 file.

Parameters:

Name Type Description Default
filename str

The output file name.

required

from_file classmethod ¤

from_file(filename: str)

Load setup saved with save previously.

setup ¤

setup(tof: AdqRawChannel)

Given a AdqRawChannel object, calculate this eTOF's impulse response function.

Parameters:

Name Type Description Default
tof AdqRawChannel

AdqRawChannel used to access data for a given eTOF.

required

get_response ¤

get_response(kind: str = 'aligned', reflection_period: List[int] = list(), reflection_amplitude: List[float] = list())

Returns the instrument response.

Parameters:

Name Type Description Default
kind str

Which version of the isntrument response to retrieve. "aligned" provides the MCP response, which is edge-aligned. "digital" is the digital response. "analog" is the analog response.

'aligned'
reflection_period List[int]

Simulate reflection with these distances.

list()
reflection_amplitude List[float]

Amplitudes of the reflections.

list()

plot ¤

plot(kind: str = 'aligned')

Plot impulse response.

apply ¤

apply(tof_trace: Union[DataArray, ndarray], n_iter: int = 100, reflection_period: List[int] = list(), reflection_amplitude: List[float] = list(), extra_shift: int = 2, method: str = 'nn_matrix', **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 = TOFResponse.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 independently from the calibration object simply to improve 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 = TOFResponse.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 AdqRawChannel with shape (pulses, samples), or a numpy array of shape (n_pulses, n_samples)

required
n_iter int

Number of deconvoluton iterations.

100
method str

Set to "nn_matrix" for non-negative deconvolution with matrix multiplications. Set to "tv_matrix' for Total Variaton deconvolution. Use "standard" for standard deconvolution.

'nn_matrix'
extra_shift int

Number of samples to shift the impulse response to additionally for alignment.

2

Returns:

Type Description
DataArray

The deconvolved data as a DataArray.