evutils 0.3.10__cp313-cp313-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. evutils/__init__.py +41 -0
  2. evutils/augment/__init__.py +11 -0
  3. evutils/augment/_drop.py +32 -0
  4. evutils/chunking.py +117 -0
  5. evutils/dataset/__init__.py +5 -0
  6. evutils/evutils_native.dll +0 -0
  7. evutils/io/__init__.py +14 -0
  8. evutils/io/_aedat.py +33 -0
  9. evutils/io/_aer.py +32 -0
  10. evutils/io/_bin.py +31 -0
  11. evutils/io/_csv.py +197 -0
  12. evutils/io/_dat.py +30 -0
  13. evutils/io/_event_reader.py +379 -0
  14. evutils/io/_event_writer.py +128 -0
  15. evutils/io/_evt.py +548 -0
  16. evutils/io/_hdf5.py +187 -0
  17. evutils/io/_native_evt.py +481 -0
  18. evutils/io/_npz.py +30 -0
  19. evutils/io/_source.py +276 -0
  20. evutils/io/buffer.py +98 -0
  21. evutils/io/common.py +207 -0
  22. evutils/io/decoders.py +131 -0
  23. evutils/io/encoders.py +68 -0
  24. evutils/processing/__init__.py +14 -0
  25. evutils/processing/_masking.py +30 -0
  26. evutils/processing/_utils.py +25 -0
  27. evutils/random.py +77 -0
  28. evutils/repr/__init__.py +25 -0
  29. evutils/repr/_frame.py +126 -0
  30. evutils/repr/_histogram.py +110 -0
  31. evutils/repr/_timesurface.py +59 -0
  32. evutils/repr/_tore.py +58 -0
  33. evutils/repr/_voxel.py +54 -0
  34. evutils/torch/__init__.py +19 -0
  35. evutils/types.py +127 -0
  36. evutils/utils/__init__.py +8 -0
  37. evutils/utils/_checker.py +32 -0
  38. evutils/vis/__init__.py +5 -0
  39. evutils/vis/open3d.py +32 -0
  40. evutils/vis/plot3d.py +182 -0
  41. evutils/vis/reconstructor/__init__.py +11 -0
  42. evutils/vis/reconstructor/_base.py +71 -0
  43. evutils/vis/reconstructor/metavision.py +71 -0
  44. evutils/vis/reconstructor/rpg.py +217 -0
  45. evutils/vis/reconstructor/rpg_e2vid/.git +1 -0
  46. evutils/vis/reconstructor/rpg_e2vid/.gitignore +1 -0
  47. evutils/vis/reconstructor/rpg_e2vid/LICENSE +674 -0
  48. evutils/vis/reconstructor/rpg_e2vid/README.md +179 -0
  49. evutils/vis/reconstructor/rpg_e2vid/__init__.py +0 -0
  50. evutils/vis/reconstructor/rpg_e2vid/base/__init__.py +1 -0
  51. evutils/vis/reconstructor/rpg_e2vid/base/base_model.py +30 -0
  52. evutils/vis/reconstructor/rpg_e2vid/data/.gitignore +0 -0
  53. evutils/vis/reconstructor/rpg_e2vid/image_reconstructor.py +112 -0
  54. evutils/vis/reconstructor/rpg_e2vid/model/__init__.py +0 -0
  55. evutils/vis/reconstructor/rpg_e2vid/model/model.py +100 -0
  56. evutils/vis/reconstructor/rpg_e2vid/model/submodules.py +275 -0
  57. evutils/vis/reconstructor/rpg_e2vid/model/unet.py +178 -0
  58. evutils/vis/reconstructor/rpg_e2vid/options/__init__.py +0 -0
  59. evutils/vis/reconstructor/rpg_e2vid/options/inference_options.py +66 -0
  60. evutils/vis/reconstructor/rpg_e2vid/pretrained/.gitignore +0 -0
  61. evutils/vis/reconstructor/rpg_e2vid/run_reconstruction.py +112 -0
  62. evutils/vis/reconstructor/rpg_e2vid/scripts/embed_reconstructed_images_in_rosbag.py +90 -0
  63. evutils/vis/reconstructor/rpg_e2vid/scripts/extract_events_from_rosbag.py +126 -0
  64. evutils/vis/reconstructor/rpg_e2vid/scripts/image_folder_to_rosbag.py +73 -0
  65. evutils/vis/reconstructor/rpg_e2vid/scripts/resample_reconstructions.py +56 -0
  66. evutils/vis/reconstructor/rpg_e2vid/utils/__init__.py +0 -0
  67. evutils/vis/reconstructor/rpg_e2vid/utils/event_readers.py +88 -0
  68. evutils/vis/reconstructor/rpg_e2vid/utils/inference_utils.py +545 -0
  69. evutils/vis/reconstructor/rpg_e2vid/utils/loading_utils.py +31 -0
  70. evutils/vis/reconstructor/rpg_e2vid/utils/path_utils.py +6 -0
  71. evutils/vis/reconstructor/rpg_e2vid/utils/timers.py +57 -0
  72. evutils/vis/reconstructor/rpg_e2vid/utils/util.py +50 -0
  73. evutils-0.3.10.dist-info/METADATA +227 -0
  74. evutils-0.3.10.dist-info/RECORD +76 -0
  75. evutils-0.3.10.dist-info/WHEEL +5 -0
  76. evutils-0.3.10.dist-info/licenses/LICENSE +19 -0
evutils/__init__.py ADDED
@@ -0,0 +1,41 @@
1
+ """evutils: utilities for event-based data.
2
+
3
+ Event-based data processing and visualization utilities.
4
+
5
+ To get started::
6
+
7
+ import evutils
8
+ ...
9
+
10
+
11
+
12
+ Notes
13
+ -----
14
+ Anything worth calling out up front.
15
+
16
+
17
+
18
+ """
19
+
20
+ import importlib.metadata
21
+
22
+ try:
23
+ __version__ = importlib.metadata.version("evutils")
24
+ except importlib.metadata.PackageNotFoundError:
25
+ # Fallback if the package is run without being installed
26
+ __version__ = "dev"
27
+
28
+
29
+ __all__ = [
30
+ 'augment',
31
+ 'chunking',
32
+ 'dataset',
33
+ 'io',
34
+ 'utils',
35
+ 'vis',
36
+ 'processing',
37
+ 'random',
38
+ 'types',
39
+ '__version__'
40
+ ]
41
+
@@ -0,0 +1,11 @@
1
+ """Data augmentation transforms for events.
2
+
3
+ Random and deterministic transformations for augmenting event streams
4
+ during training, such as spatial flips, time reversal, event dropout and
5
+ added noise.
6
+ """
7
+
8
+
9
+ from ._drop import drop_random_events
10
+
11
+ __all__ = ["drop_random_events"]
@@ -0,0 +1,32 @@
1
+
2
+ import numpy as np
3
+
4
+
5
+
6
+ def drop_random_events(events: np.ndarray, drop_rate: float = 0.1):
7
+ """Drops a percentage of events randomly using slicing.
8
+
9
+ Parameters
10
+ ----------
11
+ events : np.ndarray
12
+ Array of events to drop from.
13
+ drop_rate : float, optional
14
+ Percentage of events to drop, by default 0.1 (10%).
15
+
16
+ Returns
17
+ -------
18
+ np.ndarray:w
19
+
20
+ Array of events with the specified percentage dropped.
21
+ """
22
+ if drop_rate <= 0 or drop_rate >= 1:
23
+ raise ValueError("drop_rate must be between 0 and 1")
24
+
25
+ n_events = len(events)
26
+ indices = np.arange(n_events)
27
+ np.random.shuffle(indices)
28
+
29
+ drop_count = int(n_events * drop_rate)
30
+ keep_indices = indices[drop_count:]
31
+
32
+ return events[keep_indices]
evutils/chunking.py ADDED
@@ -0,0 +1,117 @@
1
+ """Splitting event streams into chunks.
2
+
3
+ Slice a continuous event stream into fixed-size windows, either by event
4
+ count or by time interval.
5
+ """
6
+
7
+ import numpy as np
8
+
9
+
10
+
11
+ def window_delta_t(events: np.ndarray, delta_t: int = 10_000):
12
+ '''
13
+ Returns a generator that chunks the events array into windows of size delta_t
14
+
15
+ Parameters
16
+ ----------
17
+ events : np.ndarray
18
+ Array of events
19
+ delta_t : int, optional
20
+ Size of the window in microseconds, by default 10_000'''
21
+
22
+
23
+ if len(events) == 0:
24
+ return
25
+
26
+ index_start = 0
27
+
28
+ ts = events["t"]
29
+ current_ts = ts[0]
30
+
31
+ while index_start < len(events):
32
+ next_index = np.searchsorted(ts[index_start:], current_ts + delta_t)
33
+
34
+ window = events[index_start:index_start + next_index]
35
+ yield window
36
+
37
+ current_ts += delta_t
38
+ index_start += next_index
39
+
40
+ def sliding_window(events: np.ndarray, delta_t: int = 10_000, window_size: int = 20_000, full_window: bool = False):
41
+ '''
42
+ Returns a generator that chunks the events array into windows of size delta_t
43
+
44
+ Parameters
45
+ ----------
46
+ events : np.ndarray
47
+ Array of events
48
+ delta_t : int, optional
49
+ Time delta between frames in microseconds, by default 10_000
50
+ window_size : int, optional
51
+ Size of the window in microseconds, by default 20_000
52
+ can overlap with the next frame
53
+ full_window : bool, optional
54
+ If True, the last window will be full, by default False
55
+ If False, the last window will be the remaining events
56
+ '''
57
+
58
+ if len(events) == 0:
59
+ return
60
+
61
+ index_start = 0
62
+
63
+ ts = events["t"]
64
+ current_ts = ts[0]
65
+
66
+ while index_start < len(events):
67
+
68
+
69
+ next_frame_index = np.searchsorted(ts[index_start:], current_ts + delta_t)
70
+ next_window_index = np.searchsorted(ts[index_start:], current_ts + window_size)
71
+
72
+
73
+
74
+ window = events[index_start:index_start + next_window_index]
75
+ yield window
76
+
77
+
78
+ # Exit if the next window index is not full
79
+ if full_window and index_start + next_window_index >= len(events):
80
+ break
81
+
82
+ current_ts += delta_t
83
+ index_start += next_frame_index
84
+
85
+
86
+
87
+
88
+ def sort_events(events: np.ndarray):
89
+ '''Sorts the events array by timestamp
90
+
91
+ Parameters
92
+ ----------
93
+ events : np.ndarray
94
+ Array of events
95
+
96
+ '''
97
+ return np.sort(events, order="t")
98
+
99
+ def get_dt_events(events: np.ndarray, dt: int =10_000):
100
+ '''
101
+ Returns the events that are within a time window of dt from the first event's timestamp.
102
+ Parameters
103
+ ----------
104
+ events : np.ndarray
105
+ Array of events
106
+ dt : int, optional
107
+ Time window in microseconds, by default 10_000
108
+ '''
109
+ if len(events) == 0:
110
+ return events
111
+
112
+ first_ts = events[0]['t']
113
+ last_ts = first_ts + dt
114
+
115
+ next_index = np.searchsorted(events['t'], last_ts)
116
+
117
+ return events[:next_index]
@@ -0,0 +1,5 @@
1
+ """Dataset loading and management.
2
+
3
+ Dataset classes and helpers for downloading, caching and iterating over
4
+ event-based datasets.
5
+ """
Binary file
evutils/io/__init__.py ADDED
@@ -0,0 +1,14 @@
1
+ """Reading and writing events in various file formats.
2
+
3
+ Format-specific readers and writers (``bin``, ``csv``, ``dat``, ``hdf5``,
4
+ ``npz``, ``raw``, ``txt``) built on a shared ``EventReader`` / ``EventWriter``
5
+ interface, plus ``EventReader_Any`` / ``EventWriter_Any`` which pick the
6
+ backend from the file extension. Backends that need optional dependencies
7
+ degrade gracefully and only raise on use.
8
+ """
9
+
10
+ from ._event_reader import EventReader
11
+ from ._event_writer import EventWriter
12
+
13
+
14
+ __all__ = ["EventReader", "EventWriter"]
evutils/io/_aedat.py ADDED
@@ -0,0 +1,33 @@
1
+
2
+
3
+
4
+ import numpy as np
5
+
6
+ from .common import EventDecoder, EventEncoder
7
+
8
+
9
+ class EventDecoder_Aedat(EventDecoder):
10
+ '''
11
+ A decoder for reading events from AEDAT files.
12
+
13
+ Parameters
14
+ ----------
15
+ file
16
+ Path to the data file
17
+ '''
18
+ def __init__(self, file):
19
+ super().__init__(file)
20
+
21
+
22
+ class EventEncoder_Aedat(EventEncoder):
23
+ '''
24
+ A encoder for writing events to AEDAT files.
25
+
26
+ Parameters
27
+ ----------
28
+ file
29
+ Path to the data file
30
+ '''
31
+ def __init__(self, file, width=1280, height=720):
32
+ super().__init__(file)
33
+
evutils/io/_aer.py ADDED
@@ -0,0 +1,32 @@
1
+
2
+
3
+
4
+ import numpy as np
5
+
6
+ from .common import EventDecoder, EventEncoder
7
+
8
+
9
+ class EventDecoder_AER(EventDecoder):
10
+ '''
11
+ A decoder for reading events from AER files.
12
+
13
+ Parameters
14
+ ----------
15
+ file
16
+ Path to the data file
17
+ '''
18
+ def __init__(self, file):
19
+ super().__init__(file)
20
+
21
+
22
+ class EventEncoder_AER(EventEncoder):
23
+ '''
24
+ A encoder for writing events to AER files.
25
+
26
+ Parameters
27
+ ----------
28
+ file
29
+ Path to the data file
30
+ '''
31
+ def __init__(self, file, width=1280, height=720):
32
+ super().__init__(file, width, height)
evutils/io/_bin.py ADDED
@@ -0,0 +1,31 @@
1
+
2
+ import numpy as np
3
+
4
+ from .common import EventDecoder, EventEncoder
5
+
6
+
7
+ class EventDecoder_Bin(EventDecoder):
8
+ '''
9
+ A decoder for reading events from binary files.
10
+
11
+ Parameters
12
+ ----------
13
+ file
14
+ Path to the data file
15
+ '''
16
+ def __init__(self, file):
17
+ super().__init__(file)
18
+
19
+
20
+ class EventEncoder_Bin(EventEncoder):
21
+ '''
22
+ A encoder for writing events to binary files.
23
+
24
+ Parameters
25
+ ----------
26
+ file
27
+ Path to the data file
28
+ '''
29
+ def __init__(self, file, width=1280, height=720):
30
+ super().__init__(file)
31
+
evutils/io/_csv.py ADDED
@@ -0,0 +1,197 @@
1
+
2
+
3
+
4
+ import io
5
+ from io import TextIOWrapper
6
+ from pathlib import Path
7
+ from typing import Any
8
+
9
+ import numpy as np
10
+ import pandas as pd
11
+ from pandas._typing import CSVEngine
12
+ from pandas.io.parsers import TextFileReader
13
+
14
+ from ..types import Event_dtype, EventArray
15
+ from .common import EventDecoder, EventEncoder
16
+
17
+
18
+ class EventDecoder_Csv(EventDecoder):
19
+ '''
20
+ A reader for CSV files with events.
21
+
22
+ Parameters
23
+ ----------
24
+ file
25
+ Path to the data file
26
+ order
27
+ Order of the columns in the CSV file, by default ['t', 'x', 'y', 'p']
28
+ chunk_size
29
+ Size of the chunk to read, by default 10_000
30
+ delimiter
31
+ Delimiter for the CSV file, by default ","
32
+ engine
33
+ Engine to use to read the CSV file, by default 'c'
34
+
35
+ Raises
36
+ ------
37
+ ValueError
38
+ If the order is not a list of 4 strings or if the order does not contain 't', 'x', 'y' and 'p'
39
+
40
+ '''
41
+
42
+ def __init__(self, readable:io.BufferedReader, order:list|None=None, chunk_size:int=1_000_000, delimiter:str=",", engine:CSVEngine='c'):
43
+ super().__init__(readable, chunk_size)
44
+
45
+
46
+ if order is None:
47
+ # we infer the header from the file, or use a default header
48
+ pass
49
+ else:
50
+ # Validate the parameters
51
+ if len(order) != 4:
52
+ raise ValueError("Order must be a list of 4 strings")
53
+ if "t" not in order or "x" not in order or "y" not in order or "p" not in order:
54
+ raise ValueError("Order must contain 't', 'x', 'y' and 'p'")
55
+
56
+ self._order = order
57
+ self._delimiter = delimiter
58
+ self._engine = engine
59
+
60
+ self._chunk_reader:TextFileReader|None= None
61
+
62
+ def _check_header(self):
63
+ have_header = False
64
+
65
+ # Check first line to see if it is a header
66
+ # TODO: Need to deal with non-seekable files
67
+ first_line: str = self._fd.readline().decode('utf-8').strip()
68
+
69
+ # Check if the first line is a header
70
+ # If we find a header, it will take precendence over the order parameter
71
+
72
+ if "t" in first_line or "x" in first_line or "y" in first_line or "p" in first_line:
73
+ # Header found
74
+ have_header = True
75
+
76
+ if have_header:
77
+ # We expect a header:
78
+ if "t" in first_line and "x" in first_line and "y" in first_line and "p" in first_line:
79
+ # Header found
80
+ order = first_line.split(",")
81
+
82
+ if self._order is not None and order != self._order:
83
+ print(ValueError(f"WARNING: Header order {self._order} does not match order file {order}"))
84
+ self._order = order
85
+
86
+
87
+ else:
88
+ raise ValueError(f"Header not found or invalid: {first_line}")
89
+ else:
90
+ # No header found, just seek to start of file
91
+ self._fd.seek(0)
92
+
93
+ # If we still don't have a header, we use a default one
94
+ if self._order is None:
95
+ self._order = ['t', 'x', 'y', 'p']
96
+
97
+
98
+
99
+ def init(self):
100
+
101
+ self._check_header()
102
+
103
+ self._chunk_reader = pd.read_csv(self._fd, iterator=True, header=None, names=self._order, engine=self._engine,
104
+ delimiter=self._delimiter, dtype={"t":"u8", "p":"u1", "x":"u2","y":"u2"})
105
+
106
+ # self.numpy_reader = np.fromtxt(self._fd, delimiter=",", dtype=np.uint64)
107
+ self._is_initialized = True
108
+
109
+
110
+ def read_chunk(self, delta_t_hint:int | None = None, n_events_hint:int | None = None) -> np.ndarray[Any, np.dtype[Any]]:
111
+ assert self._is_initialized, "Reader is not initialized"
112
+ assert self._chunk_reader is not None
113
+ # We can use the n_events_hint to read exactly n_events
114
+ #n_events_hint = None
115
+ #if not n_events_hint is None:
116
+ # chunk_size = n_events_hint
117
+ #else:
118
+ # chunk_size = self.chunk_size
119
+ chunk_size = self._chunk_size
120
+
121
+ try:
122
+ df = self._chunk_reader.get_chunk(chunk_size)
123
+ events = EventArray(df['t'].to_numpy(), df['x'].to_numpy(),
124
+ df['y'].to_numpy(), df['p'].to_numpy())
125
+ except StopIteration:
126
+ events = EventArray.empty()
127
+
128
+ # Detect end of file
129
+ if len(events) < chunk_size:
130
+ self._eof = True
131
+
132
+ return events
133
+
134
+
135
+ def reset(self):
136
+ assert self._fd is not None
137
+ self._fd.seek(0)
138
+ self._check_header()
139
+
140
+
141
+
142
+ class EventEncoder_Csv(EventEncoder):
143
+ '''
144
+ A writer for CSV files with events.
145
+
146
+ Parameters
147
+ ----------
148
+ file : str
149
+ Path to the data file
150
+ width : int, optional
151
+ Width of the frame, by default 1280 (not relevant for this formats)
152
+ height : int, optional
153
+ Height of the frame, by default 720 (not relevant for this formats)
154
+ sep : str, optional
155
+ Separator for the CSV file, by default ","
156
+ order : list, optional
157
+ Order of the columns in the CSV file, by default ['t', 'x', 'y', 'p']
158
+ header : bool, optional
159
+ If True, a header is written on the first line, by default True
160
+
161
+ Raises
162
+ ------
163
+ ValueError
164
+ If the order is not a list of 4 strings or if the order does not contain 't', 'x', 'y' and 'p'
165
+
166
+ '''
167
+
168
+ def __init__(self, writable: io.BufferedWriter, width:int=1280, height:int=720, sep:str=",", order:list=['t', 'x', 'y', 'p'], header:bool=True):
169
+ super().__init__(writable)
170
+
171
+
172
+ if len(order) != 4:
173
+ raise ValueError("Order must be a list of 4 strings")
174
+ if "t" not in order or "x" not in order or "y" not in order or "p" not in order:
175
+ raise ValueError("Order must contain 't', 'x', 'y' and 'p'")
176
+
177
+ self._order = order
178
+ self._header = header
179
+ self._sep = sep
180
+
181
+ def init(self):
182
+
183
+ if self._header:
184
+ header = self._sep.join(self._order) + "\n"
185
+ self._fd.write(header.encode('utf-8'))
186
+
187
+ self._is_initialized = True
188
+
189
+
190
+ def write(self, events: np.ndarray[Any, np.dtype[Any]]) -> int:
191
+ if not self._is_initialized:
192
+ self.init()
193
+
194
+ df = pd.DataFrame(events)
195
+ df.to_csv(self._fd, header=False, index=False, columns=self._order, sep=self._sep)
196
+ return len(events)
197
+
evutils/io/_dat.py ADDED
@@ -0,0 +1,30 @@
1
+
2
+ import numpy as np
3
+
4
+ from .common import EventDecoder, EventEncoder
5
+
6
+
7
+ class EventDecoder_Dat(EventDecoder):
8
+ '''
9
+ A decoder for reading events from DAT files.
10
+
11
+ Parameters
12
+ ----------
13
+ file
14
+ Path to the data file
15
+ '''
16
+ def __init__(self, file):
17
+ super().__init__(file)
18
+
19
+
20
+ class EventEncoder_Dat(EventEncoder):
21
+ '''
22
+ A encoder for writing events to DAT files.
23
+
24
+ Parameters
25
+ ----------
26
+ file
27
+ Path to the data file
28
+ '''
29
+ def __init__(self, file, width=1280, height=720):
30
+ super().__init__(file)