``pooltool.events`` =================== .. py:module:: pooltool.events Events, their detection, creation, and filtration. See `here `_ to learn about events and why they matter. 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:: ball_table_collision(ball: pooltool.objects.ball.datatypes.Ball, time: float, set_initial: bool = False) -> pooltool.events.datatypes.Event Create a ball-table collision. .. note:: - Since information about the ball-table interaction is stored exclusively in the ball (not the table), and since the table is a large composite of individual objects which is costly to serialize, the table is not stored as an agent of the returned event and is therefore not accepted as an argument of this function. .. 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`.