class_docstr: Stores multi-agent episode data.
  
  The central attribute of the class is the timestep mapping
  `global_t_to_local_t` that maps the global (environment)
  timestep to the local (agent) timesteps.
  
  The `MultiAgentEpisode` is based on the `SingleAgentEpisode`s
  for each agent, stored in `MultiAgentEpisode.agent_episodes`.
class_docstr_tok: ["Stores","multi-agent","episode","data",".","The","central","attribute","of","the","class","is","the","timestep","mapping","`","global_t_to_local_t","`","that","maps","the","global","(","environment",")","timestep","to","the","local","(","agent",")","timesteps",".","The","`","MultiAgentEpisode","`","is","based","on","the","`","SingleAgentEpisode","`","s","for","each","agent",",","stored","in","`","MultiAgentEpisode.agent_episodes","`","."]
docstr: Generates a timestep mapping to local agent timesteps.
  
  This helps us to keep track of which agent stepped at
  which global (environment) timestep.
  Note that the local (agent) timestep is given by the index
  of the list for each agent.
  
  Args:
      observations: A list of observations.Each observations maps agent
          ids to their corresponding observation.
  
  Returns: A dictionary mapping agents to time index lists. The latter
      contain the global (environment) timesteps at which the agent
      stepped (was ready).
code: def _generate_ts_mapping(
      self, observations: List[MultiAgentDict]
  ) -> MultiAgentDict:
      """Generates a timestep mapping to local agent timesteps.
  
      This helps us to keep track of which agent stepped at
      which global (environment) timestep.
      Note that the local (agent) timestep is given by the index
      of the list for each agent.
  
      Args:
          observations: A list of observations.Each observations maps agent
              ids to their corresponding observation.
  
      Returns: A dictionary mapping agents to time index lists. The latter
          contain the global (environment) timesteps at which the agent
          stepped (was ready).
      """
      # Only if agent ids have been provided we can build the timestep mapping.
      if len(self._agent_ids) > 0:
          global_t_to_local_t = {
              agent: _IndexMapping() for agent in self._agent_ids
          }
  
          # We need the observations to create the timestep mapping.
          if observations:
              for t, agent_map in enumerate(observations):
                  for agent_id in agent_map:
                      # If agent stepped add the timestep to the timestep mapping.
                      global_t_to_local_t[agent_id].append(
                          t + self.ts_carriage_return
                      )
          # Otherwise, set to an empoty dict (when creating an empty episode).
          else:
              global_t_to_local_t = {}
      # Otherwise, set to an empoty dict (when creating an empty episode).
      else:
          # TODO (sven, simon): Shall we return an empty dict or an agent dict with
          # empty lists?
          global_t_to_local_t = {}
      # Return the index mapping.
      return global_t_to_local_t
  
imports: from collections import defaultdict
  from queue import Queue
  from typing import Any, Dict, List, Optional, Set, Union
  import uuid
  import numpy
  from ray.rllib.env.single_agent_episode import SingleAgentEpisode
  from ray.rllib.policy.sample_batch import MultiAgentBatch
  from ray.rllib.utils.typing import MultiAgentDict
label_desc: Use image node_id 21 for calling the MultiAgentEpisode obj's underlying member method code with example usage: obj._generate_ts_mapping(observations) and returns: global_t_to_local_t