diff --git a/examples/camera_to_aedat4.py b/examples/camera_to_aedat4.py index 169e5f1..a6b52f3 100644 --- a/examples/camera_to_aedat4.py +++ b/examples/camera_to_aedat4.py @@ -1,7 +1,7 @@ import faery ( - faery.events_stream_from_camera("Inivation") # Open an Inivation camera - .crop(10, 110, 10, 110) # Remove events outside the region (10, 10) to (110, 110) - .to_file("some.aedat4") # Save the events to a file + faery.events_stream_from_camera("Inivation") # Open an Inivation camera + .crop(10, 110, 10, 110) # Remove events outside the region (10, 10) to (110, 110) + .to_file("some.aedat4") # Save the events to a file ) diff --git a/python/faery/__init__.py b/python/faery/__init__.py index cc49980..1ee41bc 100644 --- a/python/faery/__init__.py +++ b/python/faery/__init__.py @@ -146,6 +146,7 @@ def name_to_colormaps() -> dict[str, Colormap]: ) } + from .event_camera_input import events_stream_from_camera diff --git a/python/faery/cli/colormaps.py b/python/faery/cli/colormaps.py index 8898eaa..aacaecf 100644 --- a/python/faery/cli/colormaps.py +++ b/python/faery/cli/colormaps.py @@ -26,18 +26,15 @@ class Command(command.Command): - @typing.override def usage(self) -> tuple[list[str], str]: return ( ["faery colormaps "], "render available colormaps", ) - @typing.override def first_block_keywords(self) -> set[str]: return {"colormaps"} - @typing.override def run(self, arguments: list[str]): parser = self.parser() parser.add_argument("output", help="path of the output PNG file") diff --git a/python/faery/cli/info.py b/python/faery/cli/info.py index df3d0d6..73b89aa 100644 --- a/python/faery/cli/info.py +++ b/python/faery/cli/info.py @@ -9,15 +9,12 @@ class Command(command.Command): - @typing.override def usage(self) -> tuple[list[str], str]: return (["faery info "], "prints information about a file") - @typing.override def first_block_keywords(self) -> set[str]: return {"info"} - @typing.override def run(self, arguments: list[str]): parser = self.parser() parser.add_argument("path", help="path of the input file") diff --git a/python/faery/cli/init.py b/python/faery/cli/init.py index 5e70c80..74d5820 100644 --- a/python/faery/cli/init.py +++ b/python/faery/cli/init.py @@ -10,15 +10,12 @@ class Command(command.Command): - @typing.override def usage(self) -> tuple[list[str], str]: return (["faery init"], "initialize a Faery script") - @typing.override def first_block_keywords(self) -> set[str]: return {"init"} - @typing.override def run(self, arguments: list[str]): parser = self.parser() parser.add_argument( diff --git a/python/faery/cli/list_filters.py b/python/faery/cli/list_filters.py index 43ba030..87f7e52 100644 --- a/python/faery/cli/list_filters.py +++ b/python/faery/cli/list_filters.py @@ -474,15 +474,12 @@ def class_to_name_to_filter() -> dict[typing.Any, dict[str, Filter]]: class Command(command.Command): - @typing.override def usage(self) -> tuple[list[str], str]: return (["faery list-filters"], "print available filters") - @typing.override def first_block_keywords(self) -> set[str]: return {"list-filters"} - @typing.override def run(self, arguments: list[str]): parser = self.parser() parser.parse_args(args=arguments) diff --git a/python/faery/cli/process.py b/python/faery/cli/process.py index c2f0602..b5f1855 100644 --- a/python/faery/cli/process.py +++ b/python/faery/cli/process.py @@ -128,7 +128,12 @@ def input_parser() -> argparse.ArgumentParser: add_csv_properties(subparser) # Inivation subparser subparser = subparsers.add_parser("inivation") - subparser.add_argument("--buffer-size", type=int, default=1024, help="Array buffer size (default: %(default)s)") + subparser.add_argument( + "--buffer-size", + type=int, + default=1024, + help="Array buffer size (default: %(default)s)", + ) # UDP subparser subparser = subparsers.add_parser("udp") subparser.add_argument("address", type=list_filters.parse_udp) @@ -282,7 +287,8 @@ def output_parser( subparser.add_argument( "--enforce-monotonic-timestamps", action=argparse.BooleanOptionalAction, - help="Enforce non-monitonic timestamps. Defaults to True. Negate this with causion: some file formats do not support non-monotonic timestamps.") + help="Enforce non-monitonic timestamps. Defaults to True. Negate this with causion: some file formats do not support non-monotonic timestamps.", + ) subparser.set_defaults(enforce_monotonic_timestamps=True) if stream_parent_class in { faery.FiniteEventsStream, @@ -612,7 +618,6 @@ def split_on_keywords(arguments: list[str]) -> typing.Iterator[list[str]]: class Command(command.Command): - @typing.override def usage(self) -> tuple[list[str], str]: return ( [ @@ -624,11 +629,9 @@ def usage(self) -> tuple[list[str], str]: "process data", ) - @typing.override def first_block_keywords(self) -> set[str]: return KEYWORDS - @typing.override def run(self, arguments: list[str]): stream_wrapper = StreamWrapper() subcommands_arguments = list(split_on_keywords(arguments)) diff --git a/python/faery/cli/run.py b/python/faery/cli/run.py index d0cea11..e0f5354 100644 --- a/python/faery/cli/run.py +++ b/python/faery/cli/run.py @@ -6,15 +6,12 @@ class Command(command.Command): - @typing.override def usage(self) -> tuple[list[str], str]: return (["faery run"], "run a Faery script") - @typing.override def first_block_keywords(self) -> set[str]: return {"run"} - @typing.override def run(self, arguments: list[str]): parser = self.parser() parser.add_argument( diff --git a/python/faery/event_camera_input.py b/python/faery/event_camera_input.py index 105a25e..41e5574 100644 --- a/python/faery/event_camera_input.py +++ b/python/faery/event_camera_input.py @@ -6,6 +6,7 @@ import faery.events_stream as events_stream + def has_event_camera_drivers(): return importlib.util.find_spec("event_camera_drivers") is not None @@ -13,6 +14,7 @@ def has_event_camera_drivers(): def has_inivation_camera_drivers(): if has_event_camera_drivers(): import event_camera_drivers as evd + return hasattr(evd, "InivationCamera") return False @@ -33,14 +35,17 @@ def __init__(self, buffer_size: int = 1024): """ super().__init__() - + try: import event_camera_drivers as evd + self.camera = evd.InivationCamera(buffer_size=buffer_size) except ImportError as e: - logging.error("Inivation camera drivers not available, please install the event_camera_drivers library") + logging.error( + "Inivation camera drivers not available, please install the event_camera_drivers library" + ) raise e - + def __iter__(self) -> typing.Iterator[np.ndarray]: while self.camera.is_running(): v = next(self.camera) @@ -50,11 +55,12 @@ def dimensions(self): return self.camera.resolution() -def events_stream_from_camera(manufacturer: typing.Literal["Inivation", "Prophesee"], buffer_size: int = 1024): +def events_stream_from_camera( + manufacturer: typing.Literal["Inivation", "Prophesee"], buffer_size: int = 1024 +): if manufacturer == "Inivation": return InivationCameraStream(buffer_size) elif manufacturer == "Prophesee": raise NotImplementedError("Prophesee camera drivers are not implemented yet") else: raise ValueError(f"Unknown camera manufacturer: {manufacturer}") - diff --git a/python/faery/events_stream_state.py b/python/faery/events_stream_state.py index d095d68..38f1ba9 100644 --- a/python/faery/events_stream_state.py +++ b/python/faery/events_stream_state.py @@ -110,6 +110,7 @@ class FiniteRegularEventsStreamState: Total number of packets in the stream. """ + class StateManager: """ Keeps track of the number of frames processed by the stream and calls `on_progress`. diff --git a/python/faery/file_encoder.py b/python/faery/file_encoder.py index d8a6f86..9ef8c38 100644 --- a/python/faery/file_encoder.py +++ b/python/faery/file_encoder.py @@ -94,7 +94,9 @@ def events_to_file( ) if file_type == "aedat": assert path is not None - assert enforce_monotonic_timestamps, "AEDAT files do not support non-monotonic timestamps, since timestamps may overflow" + assert ( + enforce_monotonic_timestamps + ), "AEDAT files do not support non-monotonic timestamps, since timestamps may overflow" with aedat.Encoder( path=path if write_path is None else write_path, description=[ @@ -174,7 +176,9 @@ def events_to_file( t0 = 0 elif file_type == "dat": assert path is not None - assert enforce_monotonic_timestamps, "DAT files do not support non-monotonic timestamps, since timestamps may overflow" + assert ( + enforce_monotonic_timestamps + ), "DAT files do not support non-monotonic timestamps, since timestamps may overflow" with dat.Encoder( path=path if write_path is None else write_path, version="dat2" if version is None else version, # type: ignore @@ -208,7 +212,9 @@ def events_to_file( state_manager.end() elif file_type == "es": assert path is not None - assert enforce_monotonic_timestamps, "ES files do not support non-monotonic timestamps" + assert ( + enforce_monotonic_timestamps + ), "ES files do not support non-monotonic timestamps" with event_stream.Encoder( path=path if write_path is None else write_path, event_type="dvs", diff --git a/python/faery/task.py b/python/faery/task.py index e61c68e..23ec1a6 100644 --- a/python/faery/task.py +++ b/python/faery/task.py @@ -82,28 +82,22 @@ def task_generator( ) -> Task: class DecoratedTask(Task): - @typing.override def suffix(self) -> str: return suffix - @typing.override def icon(self) -> str: return icon - @typing.override def name(self) -> str: return function.__name__.replace("_", "-") if name is None else name - @typing.override def code(self) -> str: return textwrap.dedent(inspect.getsource(function)) @functools.cached_property - @typing.override def hash(self) -> str: return hash(function=function) - @typing.override def __call__( self, input: pathlib.Path, diff --git a/tests/test_encoders.py b/tests/test_encoders.py index 415f84c..28a2df7 100644 --- a/tests/test_encoders.py +++ b/tests/test_encoders.py @@ -51,7 +51,7 @@ def test_low_level_decoder_encoder(file: assets.File): separator=b","[0], header=True, dimensions=file.dimensions, - enforce_monotonic=True + enforce_monotonic=True, ) as encoder: for events in decoder: encoder.write(events) @@ -151,7 +151,7 @@ def test_low_level_decoder_encoder(file: assets.File): version="evt2", zero_t0=True, dimensions=decoder.dimensions, - enforce_monotonic=True + enforce_monotonic=True, ) as encoder: for packet in decoder: encoder.write(packet) @@ -167,7 +167,7 @@ def test_low_level_decoder_encoder(file: assets.File): version="evt3", zero_t0=True, dimensions=decoder.dimensions, - enforce_monotonic=True + enforce_monotonic=True, ) as encoder: for packet in decoder: encoder.write(packet)