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 ifsparse_ids=True).- Return type:
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:
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
Gridobject 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) -> floatgiving 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_stepevents and an attached Grid.- Return type:
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.
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:
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_fractionof 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_stepslog-spaced values between −0.2 ps and 5 ps.response_fn (callable, optional) –
f(t_seconds) -> relative_changefor 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:
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) -> floatgiving 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_stepevents and scan metadata.- Return type:
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) -> waveformgiving 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:
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