class_docstr: A statistics logging wrapper for :class:`~maze.core.env.base_env.BaseEnv`.
  
  :param env: The environment to wrap.
class_docstr_tok: ["A","statistics","logging","wrapper","for",":","class",":","`","~maze.core.env.base_env.BaseEnv","`",".",":","param","env",":","The","environment","to","wrap","."]
docstr: Calculate KPIs and append them to both aggregated and logged events.
code: def _calculate_kpis(self):
      """Calculate KPIs and append them to both aggregated and logged events."""
      if (
          not isinstance(self.env, EventEnvMixin)
          or not self.episode_event_log
      ):
          return
  
      kpi_calculator = self.env.get_kpi_calculator()
      if kpi_calculator is None:
          return
  
      last_maze_state = (
          self.env.get_maze_state()
          if isinstance(self.env, RecordableEnvMixin)
          else None
      )
  
      kpis_dict = kpi_calculator.calculate_kpis(
          self.episode_event_log, last_maze_state
      )
      kpi_events = []
      for name, value in kpis_dict.items():
          kpi_events.append(
              EventRecord(
                  BaseEnvEvents,
                  BaseEnvEvents.kpi,
                  dict(name=name, value=value),
              )
          )
  
      for event_record in kpi_events:
          self.episode_stats.add_event(
              event_record
          )  # Add the events to episode aggregator
          self.episode_event_log.step_event_logs[-1].events.append(
              event_record
          )
  
imports: import uuid
  from typing import Callable, Optional, Iterable
  from typing import TypeVar, Union, Any, Tuple, Dict
  from maze.core.annotations import override
  from maze.core.env.base_env import BaseEnv
  from maze.core.env.base_env_events import BaseEnvEvents
  from maze.core.env.environment_context import EnvironmentContext
  from maze.core.env.event_env_mixin import EventEnvMixin
  from maze.core.env.maze_action import MazeActionType
  from maze.core.env.maze_env import MazeEnv
  from maze.core.env.maze_state import MazeStateType
  from maze.core.env.recordable_env_mixin import RecordableEnvMixin
  from maze.core.env.simulated_env_mixin import SimulatedEnvMixin
  from maze.core.env.structured_env import StructuredEnv
  from maze.core.env.time_env_mixin import TimeEnvMixin
  from maze.core.events.event_collection import EventCollection
  from maze.core.events.event_record import EventRecord
  from maze.core.log_events.episode_event_log import EpisodeEventLog
  from maze.core.log_events.log_events_writer_registry import LogEventsWriterRegistry
  from maze.core.log_events.step_event_log import StepEventLog
  from maze.core.log_stats.log_stats import LogStatsAggregator, LogStatsLevel, get_stats_logger, LogStatsValue
  from maze.core.log_stats.log_stats_env import LogStatsEnv
  from maze.core.rendering.events_stats_renderer import EventStatsRenderer
  from maze.core.wrappers.wrapper import Wrapper
label_desc: Use image node_id 12 for calling the LogStatsWrapper obj's underlying member method code with example usage: obj._calculate_kpis() without return types