Coverage for src/evutils/random.py: 97%
38 statements
« prev ^ index » next coverage.py v7.15.1, created at 2026-07-15 09:33 +0000
« prev ^ index » next coverage.py v7.15.1, created at 2026-07-15 09:33 +0000
1"""Generation and perturbation of synthetic events.
3Create random event arrays for testing and benchmarking
4(``random_events``, ``random_events_generator``) and add random timestamp
5jitter to existing events (``event_jitter``, ``event_jitter_n``).
6"""
9from typing import Generator
10from .types import Event_dtype
11import numpy as np
13def random_events(n_events: int, width: int = 1280, height: int = 720, start_ts: int = 0, end_ts: int = 10_000_000) -> np.ndarray:
14 """Generates n_events random events with x and y coordinates in the range [0, width) and [0, height) respectively.
16 Examples
17 --------
18 >>> import numpy as np
19 >>> from evutils.random import random_events
20 >>> events = random_events(10, width=640, height=480, start_ts=0, end_ts=1000)
21 >>> len(events)
22 10
23 >>> bool(events["x"].max() < 640)
24 True
25 """
26 events = np.empty(n_events, dtype=Event_dtype)
27 events["x"] = np.random.randint(0, width, n_events)
28 events["y"] = np.random.randint(0, height, n_events)
29 events["p"] = np.random.randint(0, 2, n_events)
30 events["t"] = np.random.randint(start_ts, end_ts, n_events)
32 # Sort the timestamps
33 events["t"].sort()
35 return events
38def random_events_generator(n_events: int, width: int = 1280, height: int = 720, start_ts: int = 0, end_ts: int = 10_000_000, chunk_size: int = 10000) -> Generator[np.ndarray, None, None]:
39 """Generates n_events random events with x and y coordinates in the range [0, width) and [0, height) respectively.
41 Examples
42 --------
43 >>> from evutils.random import random_events_generator
44 >>> gen = random_events_generator(25000, chunk_size=10000)
45 >>> for chunk in gen:
46 ... print(len(chunk))
47 10000
48 10000
49 5000
50 """
51 if n_events == 0:
52 return
54 n_chunks = int(np.ceil(n_events / chunk_size))
56 chunk_ts_len = (end_ts - start_ts) // n_chunks
57 if chunk_ts_len == 0:
58 chunk_ts_len = 1
60 chunk_end_ts = start_ts + chunk_ts_len
64 for chunk in range(n_chunks):
65 if chunk >= n_chunks - 1:
66 chunk_end_ts = end_ts
67 chunk_size = n_events - (chunk * chunk_size)
70 events = random_events(chunk_size, width, height, start_ts, chunk_end_ts)
72 start_ts += chunk_ts_len
73 chunk_end_ts += chunk_ts_len
75 yield events
78def event_jitter_n(events: np.ndarray, mean: float = 0.0, std: float = 1.0, sort: bool = True) -> np.ndarray:
79 """Adds a random jitter to the timestamps of the events.
81 Examples
82 --------
83 >>> import numpy as np
84 >>> from evutils.random import random_events, event_jitter_n
85 >>> events = random_events(5)
86 >>> jittered = event_jitter_n(events.copy(), mean=0.0, std=5.0)
87 >>> len(jittered) == len(events)
88 True
89 """
90 events["t"] += np.round(np.random.normal(mean, std, len(events))).astype(np.int64)
92 if sort:
93 events = np.sort(events, order="t")
95 return events
98def event_jitter(events: np.ndarray, jitter: int = 1, sort: bool = True) -> np.ndarray:
99 """Adds a random jitter to the timestamps of the events.
101 Examples
102 --------
103 >>> import numpy as np
104 >>> from evutils.random import random_events, event_jitter
105 >>> events = random_events(10)
106 >>> jittered = event_jitter(events.copy(), jitter=5, sort=True)
107 >>> len(jittered) == len(events)
108 True
109 """
110 jitter = int(jitter)
112 events["t"] += np.random.randint(-jitter, jitter, len(events))
114 if sort:
115 events = np.sort(events, order="t")
117 return events