Example Data Generators

Synthetic data generators for escape documentation examples and testing.

These functions create realistic FEL-like event data without requiring external data sources, making them suitable for documentation notebooks and unit tests. All generators accept a seed parameter for reproducible output.

Available generators

make_array – plain 1-D Array (no scan) make_scan – 1-D scalar signal across a 1-D scan make_pump_probe_scan – pump-probe scan returning (signal, i0, pump_on, delay) make_image_scan – 2-D image data per event across a scan (map-plot repr) make_waveform_scan – 1-D waveform per event across a scan (map-plot repr) make_grid_scan – scalar signal on a 2-D (or N-D) grid with an attached Grid make_discrete_scan – integer/discrete-valued scan (exercises repr edge-case handling)

escape.storage.example_data.make_array(n_events: int = 2000, data_fn=None, name: str = 'signal', sparse_ids: bool = False, seed: int = None) Array[source]

Create a simple 1-D escape Array with synthetic scalar data.

Parameters:
  • n_events (int) – Number of events (pulses).

  • data_fn (callable, optional) – f(index) -> values. If None, standard-normal noise is used.

  • name (str) – Name tag stored in the returned Array.

  • sparse_ids (bool) – If True, ~5 % of pulse IDs are randomly dropped to mimic real data where not every instrument records every pulse.

  • seed (int, optional) – Random seed for reproducibility.

Returns:

1-D Array with shape (n_events,) (or fewer if sparse_ids=True).

Return type:

escape.Array

Examples

>>> from escape.storage.example_data import make_array
>>> import numpy as np
>>> sig = make_array(1000, lambda ix: np.sin(ix / 200.0), seed=0)
>>> sig.shape
(1000,)
escape.storage.example_data.make_discrete_scan(n_steps: int = 10, n_events_per_step: int = 300, scan_par_name: str = 'delay_ps', scan_par_values=None, values=(0, 1, 2, 3), name: str = 'photon_count', seed: int = None) Array[source]

Create a scan with discrete integer values.

Models a photon-counting detector or any channel with only a handful of distinct values. The degenerate percentile range (all steps may share the same min/max) exercises the robustness fixes in the hist-plot repr path.

Parameters:
  • n_steps (int) – Number of scan steps.

  • n_events_per_step (int) – Events per step.

  • scan_par_name (str) – Name of the scanned parameter.

  • scan_par_values (array-like, optional) – Defaults to equally spaced values in [0, 1].

  • values (sequence of int) – Discrete output values that are randomly drawn per event.

  • name (str) – Name tag.

  • seed (int, optional) – Random seed.

Returns:

1-D integer Array useful for testing edge-case repr behaviour.

Return type:

escape.Array

Examples

>>> from escape.storage.example_data import make_discrete_scan
>>> cnt = make_discrete_scan(values=(0, 1), name="binary_flag", seed=0)
>>> cnt.dtype
dtype('int32')
>>> cnt              # should render without errors despite degenerate range
escape.storage.example_data.make_grid_scan(shape=(5, 8), n_events_per_step: int = 150, dim_names=('delay_ps', 'motor_mm'), dim_ranges=((-0.5, 2.0), (0.0, 4.0)), signal_fn=None, noise: float = 0.08, name: str = 'signal', seed: int = None) Array[source]

Create a scalar scan Array with a multi-dimensional grid structure.

Steps are laid out on a full Cartesian grid so the attached Grid object can reshape per-step aggregates into a 2-D (or N-D) image. This exercises the grid heatmap repr path.

Parameters:
  • shape (tuple of int) – Grid dimensions, e.g. (5, 8) for a 5-row × 8-column grid. Can be higher-dimensional (e.g. (3, 4, 5)).

  • n_events_per_step (int) – Events recorded at each grid point.

  • dim_names (sequence of str) – Name of each grid axis (length must equal len(shape)).

  • dim_ranges (sequence of (float, float)) – (min, max) range of parameter values along each axis.

  • signal_fn (callable, optional) – f(*par_values) -> float giving the mean signal at a grid point. Receives one positional argument per grid dimension. Defaults to a Gaussian ridge along the first dimension.

  • noise (float) – Standard deviation of additive Gaussian noise.

  • name (str) – Name tag for the returned Array.

  • seed (int, optional) – Random seed.

Returns:

1-D scalar Array with prod(shape) * n_events_per_step events and an attached Grid.

Return type:

escape.Array

Examples

>>> from escape.storage.example_data import make_grid_scan
>>> sig = make_grid_scan(shape=(6, 10), seed=0)
>>> sig.grid.shape
[6, 10]
>>> sig.grid.nanmean(plot=True)          # 2-D heatmap
>>> sig                                   # triggers grid repr plot
escape.storage.example_data.make_image_scan(n_steps: int = 5, n_events_per_step: int = 100, image_shape=(64, 64), peak_center=(32, 32), scan_par_name: str = 'motor_mm', scan_par_values=None, seed: int = None) Array[source]

Create a scan Array with 2-D image data per event.

Models a Bragg peak that shifts position as a scan motor moves. Useful for demonstrating ROI selection and 2-D data processing.

Parameters:
  • n_steps (int) – Number of scan steps.

  • n_events_per_step (int) – Images per step.

  • image_shape (tuple of int) – Pixel dimensions (rows, cols).

  • peak_center (tuple of int) – Default peak centre in pixels (row, col) for step 0. The peak shifts by 1.5 pixels per step along the row axis.

  • scan_par_name (str) – Name of the scanned parameter.

  • scan_par_values (array-like, optional) – Values per step. Defaults to integers 0, 1, …, n_steps-1.

  • seed (int, optional) – Random seed.

Returns:

Array with shape (n_steps * n_events_per_step, *image_shape).

Return type:

escape.Array

Examples

>>> from escape.storage.example_data import make_image_scan
>>> imgs = make_image_scan(n_steps=3, n_events_per_step=20, seed=0)
>>> imgs.shape
(60, 64, 64)
>>> mean_step0 = imgs.scan[0].mean(axis=0)
escape.storage.example_data.make_pump_probe_scan(n_steps: int = 15, n_events_per_step: int = 600, delays=None, response_fn=None, i0_noise: float = 0.05, noise: float = 0.08, pump_fraction: float = 0.5, seed: int = None)[source]

Create synthetic pump-probe scan data with an intensity reference (I0).

Models a typical FEL pump-probe experiment where each scan step corresponds to a nominal delay, and within each step roughly pump_fraction of shots are laser-pumped while the rest serve as unpumped references.

Parameters:
  • n_steps (int) – Number of delay steps.

  • n_events_per_step (int) – Total events per step (split between pump-on and pump-off).

  • delays (array-like, optional) – Delay values in seconds. Defaults to n_steps log-spaced values between −0.2 ps and 5 ps.

  • response_fn (callable, optional) – f(t_seconds) -> relative_change for the pump signal. Defaults to an exponential rise with 500 fs time constant and 10 % amplitude.

  • i0_noise (float) – Fractional (relative) noise on the I0 reference.

  • noise (float) – Fractional shot-to-shot noise on the detector signal.

  • pump_fraction (float) – Fraction of shots per step that are pump-ON.

  • seed (int, optional) – Random seed.

Returns:

(signal, i0, pump_on, delay)

  • signal – detector signal.

  • i0 – incoming X-ray intensity.

  • pump_on – boolean flag (True = laser was fired).

  • delay – nominal delay value repeated for every event.

Return type:

tuple of escape.Array

Examples

>>> from escape.storage.example_data import make_pump_probe_scan
>>> sig, i0, pump_on, delay = make_pump_probe_scan(n_steps=10, seed=0)
>>> # normalised per-step pump/probe ratio:
>>> ratio = (sig[~pump_on] / i0[~pump_on]).scan.nanmean()
escape.storage.example_data.make_scan(n_steps: int = 10, n_events_per_step: int = 500, scan_par_name: str = 'delay', scan_par_values=None, signal_fn=None, noise: float = 0.1, name: str = 'signal', seed: int = None) Array[source]

Create a multi-step scan escape Array with per-step parameter metadata.

Generates realistic data where a 1-D scalar signal depends on a scan parameter (e.g. pump-probe delay) plus shot-to-shot noise.

Parameters:
  • n_steps (int) – Number of scan steps.

  • n_events_per_step (int) – Events recorded per step.

  • scan_par_name (str) – Name of the scanned parameter (e.g. "delay_ps").

  • scan_par_values (array-like, optional) – Values of the scan parameter per step. If None, equally spaced values in [0, 1] are used.

  • signal_fn (callable, optional) – f(par_value) -> float giving the mean signal at each step. If None a simple cosine response is used.

  • noise (float) – Standard deviation of additive Gaussian shot-to-shot noise.

  • name (str) – Name tag for the returned Array.

  • seed (int, optional) – Random seed.

Returns:

1-D Array with n_steps * n_events_per_step events and scan metadata.

Return type:

escape.Array

Examples

>>> import numpy as np
>>> from escape.storage.example_data import make_scan
>>> delays = np.linspace(-0.5e-12, 2e-12, 20)
>>> sig = make_scan(
...     n_steps=20,
...     n_events_per_step=300,
...     scan_par_name="delay_s",
...     scan_par_values=delays,
...     signal_fn=lambda t: 1.0 - float(t > 0) * np.exp(-t / 0.5e-12),
...     noise=0.05,
...     name="bragg_intensity",
...     seed=0,
... )
>>> len(sig.scan)
20
escape.storage.example_data.make_waveform_scan(n_steps: int = 12, n_events_per_step: int = 200, waveform_length: int = 128, scan_par_name: str = 'delay_ps', scan_par_values=None, signal_fn=None, noise: float = 0.05, name: str = 'tof_waveform', seed: int = None) Array[source]

Create a scan Array with a 1-D waveform per event.

Models a time-of-flight or photodiode trace that changes shape across a scan. This exercises the 2-D map-plot repr path (ndim_nonzero == 2).

Parameters:
  • n_steps (int) – Number of scan steps.

  • n_events_per_step (int) – Waveforms recorded per step.

  • waveform_length (int) – Number of samples in each waveform.

  • scan_par_name (str) – Name of the scanned parameter.

  • scan_par_values (array-like, optional) – Values per step. Defaults to [0, 1, …, n_steps-1].

  • signal_fn (callable, optional) – f(par_value, time_axis) -> waveform giving the mean waveform shape at each step. Defaults to a Gaussian peak that shifts with scan par.

  • noise (float) – Fractional shot-to-shot noise amplitude.

  • name (str) – Name tag for the returned Array.

  • seed (int, optional) – Random seed.

Returns:

Array with shape (n_steps * n_events_per_step, waveform_length).

Return type:

escape.Array

Examples

>>> from escape.storage.example_data import make_waveform_scan
>>> tof = make_waveform_scan(n_steps=8, waveform_length=64, seed=0)
>>> tof.shape
(1600, 64)
>>> tof.scan.nanmean(plot=True)  # mean waveform vs scan parameter