Skip to content

Pulse patterns

Analog to European XFEL's timing structure, its data is also organized in trains identifed by a unique and global train ID. Some data however, in particular many of the primary detectors in an experiment like AGIPD, DSSC, LPD or fast digitizers, also resolves every or at least some of the underlying pulses a train is composed of.

European XFEL timing structure

The PulsePattern family of components allows access to pulse patterns recorded by various sources. For example, in order to obtain the FEL pulses for a particular SASE:

p = XrayPulses(run)
p.pulse_ids()

There are different types available depending on the source that should be used for the pulse pattern information, but they all offer the same interface as PulsePattern for access. Furthermore, many other components like AdqRawChannel can be given a PulsePattern component to customize how pulse-resolved data is interpreted.

The primary source of pulse pattern information is the bunch pattern table from the machine side, which is recorded either through a so called timeserver or a pulse pattern decoder source. There are three different components available to access different parts of this data:

There is a special component available for pump-probe experiments, which can combine FEL and PPL pulses into a single pattern with corresponding labels which of these two is present in a given pulse:

All of the components above offer the interface of TimeserverPulses in addition to the general interface of PulsePattern.

Apart from that, there are components to access other sources of pulse pattern information via the same PulsePattern interface:

As opposed to trains, there is no single global mechanism how to record pulses and some sources use their own identification scheme. Therefore, these components aim to refer to the location of pulses in the machine bunch pattern table wherever possible as a shared and universal identification called pulse ID. An enumeration of pulses for a single SASE, instrument or device is called pulse index. If desired, the pulse time uses the relative time to the beginning of a subtrain.

extra.components.pulses.PulsePattern ¤

PulsePattern(source: SourceData = None, key: KeyData = None)

Abstract interface to pulse patterns.

This class should not be instantiated directly, but one of its implementations such as XrayPulses or OpticalLaserPulses. It provides the shared interface accessible from all oher pulse pattern implementations, however.

master_clock property ¤

master_clock: float

European XFEL timing system master clock in Hz.

bunch_clock_divider property ¤

bunch_clock_divider: int

Divider to generate repetition rate from master clock.

bunch_repetition_rate property ¤

bunch_repetition_rate: float

European XFEL fundamental bunch repetition rate in Hz.

Generated from the master clock using a divider of 288, resulting in 4.5 MHz.

source property ¤

source: SourceData

Source used for pulse information.

info ¤

info()

Print summary of described pulse pattern.

select_trains ¤

select_trains(trains)

Select a subset of trains.

The argument can be any object accepted by DataCollection.select_trains().

select_pulses ¤

select_pulses(pulse_sel, train_sel=None, reset_index=True) -> ManualPulses

Select a subset of pulses.

The possible options for pulse selection are:

  • By pulse index using extra_data.by_index with a slice, list or ndarray:

    by_index[5:]  # All pulses after the first five.
    by_index[[0, 1, 2]]  # Explicitly the first three pulses.
    
    Slices with negative indices are supported, but may be significantly slower than non-negative indices. by_index may be omitted and a regular slice, list or ndarray used directly instead.

  • By pulse ID using extra_data.by_id with a slice, list or ndarray:

    by_id[:1500]  # All pulse IDs up to 1500.
    by_id[[1146, 1154]]  # Explicitly pulse IDs 1146 and 1154.
    

  • By a boolean ndarray acting as a mask, must contain at least as many elements as the highest number of pulses per train,

    # Selects every other pulse.
    np.array([True, False, True, False, True])
    

The train selection may be any object accepted by DataCollection.select_trains(). If specified, the pulse selection is only applied for the selected trains. This will not change the trains described by the resulting pulse pattern, but only which trains actually contain any pulses.

Parameters:

Name Type Description Default
pulse_sel by_index or by_id or slice or list or ndarray

Pulse selection, may be a slice by pulse index or pulse ID or boolean mask.

required
train_sel by_index or by_id or slice or list or ndarray

Train selection to which the pulse selection is applied.

None
reset_index bool

Whether to re-enumerate the pulseIndex index level, True by default.

True

Returns:

Name Type Description
pulses ManualPulses

New manual pulse patterns containing only the selected pulses.

deselect_pulses ¤

deselect_pulses(pulse_sel, train_sel=None, reset_index=True) -> ManualPulses

Deselect a subset of pulses.

This method accepts the same option as PulsePattern.select_pulses() for its arguments, but removes the selected pulses and removes a pattern that remains.

Parameters:

Name Type Description Default
pulse_sel by_index or by_id or slice or list or ndarray

Pulse selection, may be a slice by pulse index or pulse ID or boolean mask.

required
train_sel by_index or by_id or slice or list or ndarray

Train selection to which the pulse selection is applied.

None
reset_index bool

Whether to re-enumerate the pulseIndex index level, True by default.

True

Returns:

Name Type Description
pulses ManualPulses

New manual pulse patterns not containing the deselected pulses.

union ¤

union(*others) -> ManualPulses

Join the pulses in this pattern with one or more others.

Any additional pulse index columns, e.g. flags for FEL/PPL pulses as used by PumpProbePulses are currently removed.

Parameters:

Name Type Description Default
*others PulsePattern

Pulse patterns to join with.

()

Returns:

Name Type Description
pulses ManualPulses

New manual pulse pattern containing the union of all pulses.

pulse_ids ¤

pulse_ids(labelled=True, copy=True)

Get pulse IDs.

Parameters:

Name Type Description Default
labelled bool

Whether a labelled pandas Series (default) or unlabelled numpy array is returned.

True
copy bool

Whether a copy is returned (default) or potentially a reference to an internal object. In the latter case, modifying the returned value will likely break other methods.

True

Returns:

Type Description
Series or ndarray

Pulse ID indexed by train ID and pulse index if labelled is True.

peek_pulse_ids ¤

peek_pulse_ids(labelled=True)

Get pulse IDs for the first train.

This method may be significantly faster than to pulse_ids() by only reading data for the very first train of data.

Parameters:

Name Type Description Default
labelled bool

Whether a labelled pandas Series (default) or unlabelled numpy array is returned.

True

Returns:

Type Description
Series or ndarray

Pulse ID in the first train of this data.

pulse_mask ¤

pulse_mask(labelled=True)

Get boolean pulse mask.

The returned mask has the same shape as the full bunch pattern table but only contains boolean flags whether a given pulse was present in this pattern.

Parameters:

Name Type Description Default
labelled bool

Whether a labelled xarray DataArray (default) or unlabelled numpy array is returned.

True

Returns:

Type Description
DataArray or ndarray

is_constant_pattern ¤

is_constant_pattern(*, include_empty_trains=False)

Whether pulse IDs are constant in this data.

Parameters:

Name Type Description Default
include_empty_trains bool

Whether trains without any pulses cause a pulse pattern to not be considered constant, False by default.

False

Returns:

Type Description
bool

Whether pulse IDs are identical in every train.

is_interleaved_with ¤

is_interleaved_with(other: PulsePattern) -> Optional[bool]

Check whether pulses are interleaved with other pattern.

This method returns True if and only if it can safely determine that the pulse pattern described by this component and the passed component are interleaved, and False if and only if it is clear they are not interleaved. In all other cases, the pulses may or may not be interleaved and None is returned.

Returns:

Type Description
Optional[bool]

(bool or None) Whether pulses are interleaved or None if the pulse patterns do not allow the determination.

pulse_counts ¤

pulse_counts(labelled=True)

Get number of pulses per train.

Parameters:

Name Type Description Default
labelled bool

Whether a labelled pandas Series (default) or unlabelled numpy array is returned.

True

Returns:

Type Description
Series or ndarray

Number of pulses per train, indexed by train ID if labelled is True.

pulse_periods ¤

pulse_periods(labelled=True, single_pulse_value=None, no_pulse_value=None)

Get pulse periods per train.

The pulse period is expressed in units of the fundamental bunch repetition rate of 4.5 MHz. Its exact value can be accessed via PulsePattern.bunch_repetition_rate.

In each train, the smallest period between consecutive pulses is considered if the pulses do not have equal distances. For trains with a single pulse, the value can be specified or is filled by the largest value encountered across other trains with more pulses.

The resulting series is cast to integers unless it contains non-finite values as a result of fill values.

Parameters:

Name Type Description Default
labelled bool

Whether a labelled pandas Series (default) or unlabelled numpy array is returned.

True
single_pulse_value number

Fill value for trains with a single pulse. If omitted the largest period encountered in the data is used or an exception raised if there are no trains with more than one pulse.

None
no_pulse_value number

Fill value for trains without any pulse, 0 if omitted.

None

Returns:

Type Description
Series or ndarray

Pulse period per train train, indexed by train ID if labelled is True.

pulse_repetition_rates ¤

pulse_repetition_rates(labelled=True)

Get pulse repetition rate per train in Hz.

In each train, the highest repetition rate is used if the pulses do not have equal distances.

For trains with a single pulse, 0.0 is returned while trains without any pulse return NaN. If different fill values are desired, PulsePattern.bunch_repetition_rate can be divided manually by the result from PulsePattern.pulse_periods().

Parameters:

Name Type Description Default
labelled bool

Whether a labelled pandas Series (default) or unlabelled numpy array is returned.

True

Returns:

Type Description
Series or ndarray

Pulse repetition rate per train, indexed by train ID if labelled is True.

train_durations ¤

train_durations(labelled=True)

Get durations of each train in seconds.

The duration is the time difference between the first and last pulse in each train. For trains with no pulses, NaN is returned.

Parameters:

Name Type Description Default
labelled bool

Whether a labelled pandas Series (default) or unlabelled numpy array is returned.

True

Returns:

Type Description
Series or ndarray

Train duration in seconds per train, indexed by train ID if labelled is True.

build_pulse_index ¤

build_pulse_index(pulse_dim='pulseId', include_extra_dims=True, pulse_dtype=None)

Get a multi-level index for pulse-resolved data.

Parameters:

Name Type Description Default
pulse_dim {pulseId, pulseIndex, pulseTime}

Label for pulse dimension, pulse ID by default.

'pulseId'
include_extra_dims bool

Whether to include any additional dimensions of this particular implementation beyond train ID and pulse dimension.

True
pulse_dtype dtype

If specified, force casts the pulse dimension to the specified dtype.

None

Returns:

Type Description
MultiIndex

Multi-level index covering train ID, pulse ID or pulse index and potentially any additonal extra index dimensions.

search_pulse_patterns ¤

search_pulse_patterns(labelled=True)

Search identical pulse patterns in this data.

Reads the bunch pattern table and gathers contiguous train regions of constant pulse pattern. It returns a list of train slices and corresponding pulse IDs.

Parameters:

Name Type Description Default
labelled bool

Whether a labelled pandas Series (default) or unlabelled numpy array is returned.

True

Returns:

Type Description
list of (slice, pandas.Series or ndarray) tuples

List of train regions identified by index slices with identical pulse IDs.

trains ¤

trains(labelled=True)

Iterate over pulse IDs by train.

Parameters:

Name Type Description Default
labelled bool

Whether a labelled pandas Series (default) or unlabelled numpy array is returned.

True

Yields:

Type Description
(int, Series or ndarray)

Train ID and pulse IDs.

extra.components.pulses.TimeserverPulses ¤

TimeserverPulses(data, source=None, sase=None)

Bases: PulsePattern

Abstract interface to timeserver-based based pulse patterns.

This class should not be instantiated directly, but one of its implementations such as XrayPulses or OpticalLaserPulses. It provides the shared interface to access pulse patterns encoded in the timeserver or pulse pattern decoder data.

timeserver property ¤

timeserver: SourceData

Used timeserver source.

pulse_pattern_decoder property ¤

pulse_pattern_decoder: SourceData

Used PulsePatternDecoder source.

bunch_pattern_table property ¤

bunch_pattern_table: KeyData

Used bunch pattern table key.

machine_pulses ¤

machine_pulses(**kwargs) -> MachinePulses

Get MachinePulses component for the same data.

Any additional keyword arguments are passed to the MachinePulses initializer.

Returns:

Type Description
MachinePulses

(MachinePulses) Corresponding component using the same data as this component.

machine_repetition_rate cached ¤

machine_repetition_rate() -> float

Actual machine repetition rate.

is_sa1_interleaved_with_sa3 cached ¤

is_sa1_interleaved_with_sa3() -> bool | None

Check whether SASE1 and SASE3 pulses are interleaved.

Due to their unique geometry, the pulses of the SASE1 and SASE3 beamlines can either occur after each other on the pulse train or be interleaved. Here, each beamline generally receives their first pulse directly after each other, with their relative pulse patterns following afterwards in a back-and-forth fashion.

This method returns True if and only if it can be safely determined the SA1 and SA3 pulses are intereavled, and False if and only if it is clear they are not interleaved. In all other cases, the pulses may or may not be interleaved and None is returned.

Returns:

Name Type Description
is_interleaved bool or None

Whether SA1 and SA3 are interleaved or None if the pulse patterns do not allow the determination.

plot_xray_patterns ¤

plot_xray_patterns(sase=[2, 1, 3], figsize=(9, 4), ax=None)

Visualize X-ray pulse patterns.

Plots the X-ray pulse pattterns in this data on a common time scale. Variable patterns are represented by levels of transparency weighted by their rate of occurence. The right Y axis includes statistics about pulse count (Σ) and period (Δ).

Parameters:

Name Type Description Default
sase Sequence of int

SASE beamlines to include and in which order, [2, 1, 3] by default.

[2, 1, 3]
figsize 2-tuple of float

Figure size in inches passed to matplotlib, ignored if ax is passed.

(9, 4)
ax Axes

Axes object to plot into, created automatically if omitted.

None

Returns:

Name Type Description
ax Axes

Axes object the plot was generated in.

extra.components.XrayPulses ¤

XrayPulses(data, source=None, sase=None)

Bases: TimeserverPulses

An interface to X-ray free electron laser pulses.

The pulse structure of each train at European XFEL is described by the bunch pattern table and accesssible in recorded data through the timeserver device or in decoded form through pulse pattern decoders.

This component aids in locating and reading the bunch pattern table, as well as providing utility methods to apply the pulse patterns to other recorded data. It only considers the X-ray laser pulses generated by one of the SASE beamlines and is thus a good choice for exclusive use of X-rays or pump-probe experiments with congruent optical laser pulses.

This class only deals with X-ray pulses of a particular SASE beamline. Please see OpticalLaserPulses to access pulses of the optical laser sources or PumpProbePulses to combine both into a single pattern.

Parameters:

Name Type Description Default
data DataCollection

Data to access bunch pattern data from.

required
source str

Source name of a timeserver or pulse pattern decoder, only needed if the data includes more than one such device or none could not be detected automatically.

None
sase int

SASE beamline to interpret pulses of, only needed if the data includes sources from more than one beamline or it could not be detected automatically.

None

sase property ¤

sase: int

Used SASE beamline.

extra.components.OpticalLaserPulses ¤

OpticalLaserPulses(data, source=None, ppl_seed=None)

Bases: TimeserverPulses

An interface to optical laser pulses.

The pump-probe lasers (LAS or PPL) are optical lasers commonly used in conjunction with X-ray pulses for pump-probe experiments. There are multiple laser sources called seeds distributed across the SASE beamlines and instruments with their pulse patterns also contained in the bunch pattern table.

However, an important difference to the FEL pulses is that only the number of pulses and their spacing can be inferred from the bunch pattern table. Optical laser pulses always starts at offset 0 for technical reasons, even if they temporally overlap with FEL pulses by means of optical delay.

For experiments where all FEL and PPL laser pulses overlap, it is recommended to just use the XrayPulses component. In the case of more complex or non-overlapping patterns, the PumpProbePulses allows to combine both into a single pulse pattern.

Parameters:

Name Type Description Default
data DataCollection

Data to access bunch pattern data from.

required
source str

Source name of a timeserver or pulse pattern decoder, only needed if the data includes more than one such device or none could not be detected automatically.

None
ppl_seed PPL_BITS or str

PPL seed to interpret pulses of, only needed if the data includes sources from more than one instrument or it could not be detected automatically. May either be an explicit seed value or an instrument as a string.

None

ppl_seed property ¤

ppl_seed: Optional[PPL_BITS]

Used laser seed.

extra.components.PumpProbePulses ¤

PumpProbePulses(data, source=None, instrument=None, *, bunch_table_position=None, bunch_table_offset=None, pulse_offset=None, extrapolate=True)

Bases: XrayPulses, OpticalLaserPulses

An interface to combined FEL and PPL pulses.

This component offers support for arbitrary pulse relations between X-ray FEL and optical laser pulses (PPL) in pump-probe experiments. As the PPL pulse information in the bunch pattern table always starts at offset 0 for technical reasons irrespective of its actual temporal relation, it is corrected during initialization by exactly one of three methods:

  1. Offset all PPL pulses to a fixed bunch table position.
  2. Offset all PPL pulses relative to the first FEL pulse in units of the bunch pattern table.
  3. Offset all PPL pulses relative to the first FEL pulse in units of FEL pulses.

In cases where there are no FEL pulses (for method 2) or too few (for method 3) to determine this offset, it may be extrapolated from a previous train if enabled. If extrapolation is disabled, an exception is raised.

Unlike XrayPulses and OpticalLaserPulses, this component adds additional levels to the pulse index indicated whether an FEL or PPL pulse is present in any particular position. It will only consider a pattern equal if it is equal for both FEL and PPL.

For experiments where all FEL and PPL laser pulses overlap, it is recommended to just use the XrayPulses component.

Parameters:

Name Type Description Default
data DataCollection

Data to access bunch pattern data from.

required
source str

Source name of a timeserver or pulse pattern decoder, only needed if the data includes more than one such device or none could not be detected automatically.

None
instrument src or tuple

Instrument to interpret FEL and PPL pulses of, only needed if the data includes sources from more than one instrument or it could not be detected automatically. May also be a tuple of (sase, ppl_seed) corresponding to arguments for XrayPulses and OpticalLaserPulses.

None
bunch_table_position int

Absolute bunch table position or pulse ID for the PPL pulse.

None
bunch_table_offset int

Offset to the first FEL pulse in bunch table positions or pulse IDs.

None
pulse_offset number

Offset to the first FEL pulse in units of the spacing between the first two FEL pulses, i.e. in units of FEL pulses.

None
extrapolate bool

Whether FEL pulse IDs may be extrapolated from past trains if missing, true by default. An exception is raised if disabled and the PPL anchoring method is missing the minimum number of required FEL pulses.

True

pulse_mask ¤

pulse_mask(labelled=True, field=None)

Get boolean pulse mask.

The returned mask has the same shape as the full bunch pattern table but only contains boolean flags whether a given pulse was present in this pattern.

For instance, to see whether each FEL pulse has a corresponding pump laser pulse in a consistent pulse pattern:

ppl_on = ppp.select_trains(0).pulse_mask(field='ppl').squeeze()
fel_on = ppp.select_trains(0).pulse_mask(field='fel').squeeze()

fel_pulse_is_pumped = ppl_on[fel_on]

Parameters:

Name Type Description Default
labelled bool

Whether a labelled xarray DataArray (default) or unlabelled numpy array is returned.

True
field str

'fel'/'ppl' to mark only FEL or only pump laser pulses in the returned array. By default, pulses are True whether either an FEL pulse or a PPL pulse occured.

None

Returns:

Type Description
DataArray or ndarray

pumped_pulses_ratios ¤

pumped_pulses_ratios(ppl_only_value=np.nan, labelled=True)

Determine ratio of pumped pulses per train.

Parameters:

Name Type Description Default
ppl_only_value float

Value for trains only containing PPL pulses, same value as for pulses without any pulses (np.nan) by default.

nan
labelled bool

Whether a labelled pandas Series (default) or unlabelled numpy array is returned.

True

Returns:

Type Description
Series or ndarray

Number of pulses per train, indexed by train ID if labelled is True.

extra.components.MachinePulses ¤

MachinePulses(data, source=None, mask=_all_dumps, require_all_bits=False)

Bases: TimeserverPulses

An interface to machine pulses and other bunch pattern data.

The bunch pattern table contains much more information than just the pulses of each SASE beamline or the optical laser systems, in particular about the upstream electron systems.

This component is configurable to extract any information from the bunch pattern table beyond the X-ray or optical laser pulses. By default, it considers all generated electron bunches by combining the various electron dumps along the accelerator. Please consult the XFEL Timing System Specification for the various mask bits used.

Note that the full range of bunch pattern table information is only available when used with timeserver data. The pulse pattern decoder data only contains information about those pulses in the main dump and SASE dumps.

Parameters:

Name Type Description Default
data DataCollection

Data to access bunch pattern data from.

required
source str

Source name of a timeserver or pulse pattern decoder, only needed if the data includes more than one such device or none could not be detected automatically.

None
mask int

Custom mask into the bunch pattern table, by default all electron dumps are used. When initialized with ppdecoder data, only the main and SASE dumps are supported.

_all_dumps
require_all_bits bool

Whether to consider entries having any or all of the bits specified by mask, False by default. Only supported when initialized with timeserver data.

False

extra.components.ManualPulses ¤

ManualPulses(train_ids, pulse_ids)

Bases: PulsePattern

Manual pulse patterns.

The pattern described by this component is directly loaded from data, but either generated manually or modified from another PulsePattern-based component through select_pulses(), deselect_pulses() or union().

from_constant_pulses classmethod ¤

from_constant_pulses(train_ids, pulse_ids)

Generate a pulse pattern from constant pulse IDs.

Parameters:

Name Type Description Default
train_ids ArrayLike or DataCollection or SourceData or KeyData

Train IDs or data to take train IDs from.

required
pulse_ids ArrayLike

Pulse IDs of a single train to be repeated in every train.

required

Returns:

Name Type Description
pulses ManualPulses

Manual pulse pattern with specified pulse IDs in every train.

from_constant_pattern classmethod ¤

from_constant_pattern(train_ids, pulses_per_train, repetition_rate=None, pulse_period=None, pulse_id_offset=0)

Generate a uniform pulse pattern.

Requires either repetition_rate or pulse_period to be passed.

Parameters:

Name Type Description Default
train_ids ArrayLike or DataCollection or SourceData or KeyData

Train IDs or data to take train IDs from.

required
pulses_per_train int

Number of pulses per train.

required
repetition_rate float

Repetition rate in Hz, mutually exclusive with pulse_period.

None
pulse_period int

Period between pulses in units of 4.5 MHz, mutually exclusive with repetition_rate.

None
pulse_id_offset int

Pulse ID for the first generated pulse in each train, 0 by default.

0

Returns:

Name Type Description
pulses ManualPulses

Manual pulse pattern with uniform pulses in every train.

extra.components.DldPulses ¤

DldPulses(detector, *, clock_ratio=None, first_pulse_id=None, negative_ppl_indices=False)

Bases: PulsePattern

An interface to pulses from DLD reconstruction.

The facility-provided event reconstruction for delay line detectors records its own pulse pattern information as part of its output in the raw.triggers key. This class exposes the same pulse pattern interface based on this information, and is primarily meant to be used alongside such data. Note that it is influenced by parameters set at the time of reconstruction, and hence may (incorrectly!) differ from timeserver data.

For data processed before October 2022, this data may not contain flags for FEL/PPL pulses and may also be based on analog trigger signals. It is also lacking the true pulse IDs, which are in this case estimated by this component based on trigger positions.

Parameters:

Name Type Description Default
detector SourceData

Instrument source of reconstructed event data to retrieve trigger information from.

required
clock_ratio int

Ratio between bunch repetition rate and digitizer sampling rate, only used in case of missing pulse ID information in data and 196 by default (non-interleaved ADQ412-3G).

None
first_pulse_id int

Pulse ID for the first pulse, only used in case of missing pulse ID information in data and 0 by default.

None
negative_ppl_indices bool

Whether to enumerate PPL-only pulses with negative indices (while keeping non-negative indices for FEL-only or pumped pulses) or interleave all pulses with positive indices (default).

False

triggers ¤

triggers(labelled=True)

Get trigger information.

Returns:

Type Description
Series or ndarray

Trigger fields start, stop, offset