pooltool.events =============== .. py:module:: pooltool.events Events, their detection, creation, and filtration. -------------------------------------------------- See `here `_ to learn about events and why they matter. Overview -------- .. list-table:: Classes :header-rows: 0 :widths: auto :class: summarytable * - :py:obj:`Agent ` - An event agent. * - :py:obj:`AgentType ` - An Enum of event agents * - :py:obj:`Event ` - Represents an event. * - :py:obj:`EventType ` - An Enum of event types .. list-table:: Function :header-rows: 0 :widths: auto :class: summarytable * - :py:obj:`ball_ball_collision `\ (ball1, ball2, time, set_initial) - Create a ball-ball collision. * - :py:obj:`ball_circular_cushion_collision `\ (ball, cushion, time, set_initial) - Create a ball-circular-cushion collision. * - :py:obj:`ball_linear_cushion_collision `\ (ball, cushion, time, set_initial) - Create a ball-linear-cushion collision. * - :py:obj:`ball_pocket_collision `\ (ball, pocket, time, set_initial) - Create a ball-pocket collision. * - :py:obj:`null_event `\ (time, set_initial) - Create a null event. * - :py:obj:`rolling_spinning_transition `\ (ball, time, set_initial) - Create a rolling-spinning transition. * - :py:obj:`rolling_stationary_transition `\ (ball, time, set_initial) - Create a rolling-stationary transition. * - :py:obj:`sliding_rolling_transition `\ (ball, time, set_initial) - Create a sliding-rolling transition. * - :py:obj:`spinning_stationary_transition `\ (ball, time, set_initial) - Create a spinning-stationary transition. * - :py:obj:`stick_ball_collision `\ (stick, ball, time, set_initial) - Create a cue stick-ball collision. * - :py:obj:`by_ball `\ (ball_ids, keep_nonevent) - Returns a function that filters events based on ball IDs. * - :py:obj:`by_time `\ (t, after) - Returns a function that filter events with respect to a time cutoff. * - :py:obj:`by_type `\ (types) - Returns a function that filters events based on event type. * - :py:obj:`filter_ball `\ (events, ball_ids, keep_nonevent) - Filter events based on ball IDs. * - :py:obj:`filter_events `\ (events, \*funcs) - Filter events using multiple criteria. * - :py:obj:`filter_time `\ (events, t, after) - Filter events with respect to a time cutoff. * - :py:obj:`filter_type `\ (events, types) - Filter events based on event type. Classes ------- .. autoclass:: Agent .. rubric:: Methods: .. py:method:: set_initial(obj: Object) -> None Sets the initial state of the agent (before event resolution). This makes a copy of the passed object and sets it to :attr:`initial`. In the case of a :attr:`pooltool.events.AgentType.BALL` agent type, it drops history fields before copying to save time and memory. :param obj: The object from which :attr:`initial` will be set. .. py:method:: set_final(obj: Object) -> None Sets the final state of the agent (after event resolution). This makes a copy of the passed object and sets it to :attr:`final`. In the case of a :attr:`pooltool.events.AgentType.BALL` agent type, it drops history fields before copying to save time and memory. :param obj: The object from which :attr:`final` will be set. .. py:method:: from_object(obj: Object, set_initial: bool = False) -> Agent :staticmethod: Creates an agent instance from an object. Optionally sets the initial state of the agent based on the provided object. The final state is not set. :param obj: The object to create the agent from. :param set_initial: If True, sets the initial state of the agent to the object's state. :returns: A new instance of Agent. :rtype: Agent .. py:method:: copy() -> Agent Create a copy. .. autoclass:: AgentType Bases: :py:obj:`pooltool.utils.strenum.StrEnum` .. autoclass:: Event .. py:property:: ids :type: tuple[str, Ellipsis] Retrieves the IDs of the agents involved in the event. This property provides access to a tuple of agent IDs, allowing identification of the agents involved in the event. :returns: A tuple containing the IDs of the agents involved in the event. :rtype: Tuple[str, ...] .. rubric:: Methods: .. py:method:: copy() -> Event Create a copy. .. py:method:: get_ball(ball_id: str, initial: bool = True) -> pooltool.objects.ball.datatypes.Ball Return the Ball object with the given ID, either final or initial. :param ball_id: The ID of the ball to retrieve. :param initial: If True, return the ball's initial state; otherwise final state. :raises ValueError: If the event does not involve a ball or if no matching ball is found. .. py:method:: get_pocket(pocket_id: str, initial: bool = True) -> pooltool.objects.table.components.Pocket Return the Pocket object with the given ID, either final or initial. .. py:method:: get_cushion(cushion_id: str) -> pooltool.objects.table.components.LinearCushionSegment | pooltool.objects.table.components.CircularCushionSegment Return the cushion segment with the given ID. .. py:method:: get_stick(stick_id: str) -> pooltool.objects.table.components.Pocket Return the cue stick with the given ID. .. autoclass:: EventType Bases: :py:obj:`pooltool.utils.strenum.StrEnum` .. rubric:: Methods: .. py:method:: is_collision() -> bool Returns whether the member is a collision .. py:method:: is_transition() -> bool Returns whether the member is a transition .. py:method:: has_ball() -> bool Returns True if this event type can involve a Ball. .. py:method:: has_cushion() -> bool Returns True if this event type can involve a cushion (linear or circular). .. py:method:: has_pocket() -> bool Returns True if this event type can involve a Pocket. .. py:method:: has_stick() -> bool Returns True if this event type can involve a CueStick. Functions --------- .. py:function:: ball_ball_collision(ball1: pooltool.objects.ball.datatypes.Ball, ball2: pooltool.objects.ball.datatypes.Ball, time: float, set_initial: bool = False) -> pooltool.events.datatypes.Event Create a ball-ball collision. .. py:function:: ball_circular_cushion_collision(ball: pooltool.objects.ball.datatypes.Ball, cushion: pooltool.objects.table.components.CircularCushionSegment, time: float, set_initial: bool = False) -> pooltool.events.datatypes.Event Create a ball-circular-cushion collision. .. py:function:: ball_linear_cushion_collision(ball: pooltool.objects.ball.datatypes.Ball, cushion: pooltool.objects.table.components.LinearCushionSegment, time: float, set_initial: bool = False) -> pooltool.events.datatypes.Event Create a ball-linear-cushion collision. .. py:function:: ball_pocket_collision(ball: pooltool.objects.ball.datatypes.Ball, pocket: pooltool.objects.table.components.Pocket, time: float, set_initial: bool = False) -> pooltool.events.datatypes.Event Create a ball-pocket collision. .. py:function:: null_event(time: float, set_initial: bool = False) -> pooltool.events.datatypes.Event Create a null event. .. py:function:: rolling_spinning_transition(ball: pooltool.objects.ball.datatypes.Ball, time: float, set_initial: bool = False) -> pooltool.events.datatypes.Event Create a rolling-spinning transition. .. py:function:: rolling_stationary_transition(ball: pooltool.objects.ball.datatypes.Ball, time: float, set_initial: bool = False) -> pooltool.events.datatypes.Event Create a rolling-stationary transition. .. py:function:: sliding_rolling_transition(ball: pooltool.objects.ball.datatypes.Ball, time: float, set_initial: bool = False) -> pooltool.events.datatypes.Event Create a sliding-rolling transition. .. py:function:: spinning_stationary_transition(ball: pooltool.objects.ball.datatypes.Ball, time: float, set_initial: bool = False) -> pooltool.events.datatypes.Event Create a spinning-stationary transition. .. py:function:: stick_ball_collision(stick: pooltool.objects.cue.datatypes.Cue, ball: pooltool.objects.ball.datatypes.Ball, time: float, set_initial: bool = False) -> pooltool.events.datatypes.Event Create a cue stick-ball collision. .. py:function:: by_ball(ball_ids: str | list[str], keep_nonevent: bool = False) -> FilterFunc Returns a function that filters events based on ball IDs. :param ball_ids: A collection of ball IDs. :param keep_nonevent: Retain non-events (:attr:`pooltool.events.EventType.NONE`). :returns: A function that when passed a list of events, returns a filtered list containing only events that involve balls matching the passed ball ID(s). :rtype: FilterFunc .. py:function:: by_time(t: float, after: bool = True) -> FilterFunc Returns a function that filter events with respect to a time cutoff. :param t: The cutoff time for filtering events. :param after: If ``True``, return events after time ``t`` (non-inclusive). If ``False``, return events before time ``t`` (non-inclusive). :returns: A function that when passed a list of events, returns a filtered list containing only events before or after the cutoff time, non-inclusive. :rtype: FilterFunc .. py:function:: by_type(types: pooltool.events.datatypes.EventType | list[pooltool.events.datatypes.EventType]) -> FilterFunc Returns a function that filters events based on event type. :param types: Event type(s) you want to include in your result. All others will be filtered. :returns: A function that when passed a list of events, returns a filtered list containing only events matching the passed event type(s). :rtype: FilterFunc .. py:function:: filter_ball(events: list[pooltool.events.datatypes.Event], ball_ids: str | list[str], keep_nonevent: bool = False) -> list[pooltool.events.datatypes.Event] Filter events based on ball IDs. :param events: A list of chronological events. :param ball_ids: A collection of ball IDs. :param keep_nonevent: Retain non-events (:attr:`pooltool.events.EventType.NONE`). :returns: A filtered event list containing only events that involve balls matching the passed ball ID(s). :rtype: List[Event] .. seealso:: - If you're filtering based on multiple criteria, you can (and should!) use :func:`pooltool.events.filter_events`. .. py:function:: filter_events(events: list[pooltool.events.datatypes.Event], *funcs: FilterFunc) -> list[pooltool.events.datatypes.Event] Filter events using multiple criteria. A convenient way to filter based multiple filtering criteria. :param events: A list of chronological events. :param \*funcs: An arbitrary number of functions that take a list of events as input, and gives a subset of that list as input. It sounds laborious--it's not. See *Examples*. :returns: A filtered event list containing only events passing the supplied criteria. :rtype: List[Event] .. admonition:: Examples Generate a list of events. >>> import pooltool as pt >>> system = pt.System.example() >>> system.cue.set_state(a=0.68) >>> pt.simulate(system, inplace=True) >>> events = system.events In this shot, both the cue-ball and the 1-ball are potted. We are interested in filtering for the cue-ball pocket event. Option 1 is to call :func:`pooltool.events.filter_type` and then :func:`pooltool.events.filter_ball`: >>> filtered_events = pt.events.filter_type(events, pt.EventType.BALL_POCKET) >>> filtered_events = pt.events.filter_ball(filtered_events, "cue") >>> event_of_interest = filtered_events[0] >>> event_of_interest ├── type : ball_pocket ├── time : 3.231130101576186 └── agents : ('cue', 'rt') Option 2, the better option, is to use :func:`pooltool.events.filter_events`: >>> filtered_events = pt.events.filter_events( >>> events, >>> pt.events.by_type(pt.EventType.BALL_POCKET), >>> pt.events.by_ball("cue"), >>> ) >>> event_of_interest = filtered_events[0] >>> event_of_interest ├── type : ball_pocket ├── time : 3.231130101576186 └── agents : ('cue', 'rt') .. seealso:: - If you're filtering based on a single criterion, you can consider using :func:`pooltool.events.filter_type`, :func:`pooltool.events.filter_ball`, :func:`pooltool.events.filter_time`, etc. .. py:function:: filter_time(events: list[pooltool.events.datatypes.Event], t: float, after: bool = True) -> list[pooltool.events.datatypes.Event] Filter events with respect to a time cutoff. :param events: A list of chronological events. :param t: The cutoff time for filtering events. :param after: If ``True``, return events after time ``t`` (non-inclusive). If ``False``, return events before time ``t`` (non-inclusive). :returns: A filtered event list containing only events before or after the cutoff time, non-inclusive. :rtype: List[Event] .. seealso:: - If you're filtering based on multiple criteria, you can (and should!) use :func:`pooltool.events.filter_events`. .. py:function:: filter_type(events: list[pooltool.events.datatypes.Event], types: pooltool.events.datatypes.EventType | list[pooltool.events.datatypes.EventType]) -> list[pooltool.events.datatypes.Event] Filter events based on event type. :param events: A list of chronological events. :param types: Event type(s) you want to include in your result. All others will be filtered. :returns: A filtered event list containing only events matching the passed event type(s). :rtype: List[Event] .. seealso:: - If you're filtering based on multiple criteria, you can (and should!) use :func:`pooltool.events.filter_events`.