code: def test_aggregation_chain_fork():
      """test the aggregation chain with two event attributes and different aggregation operations"""
  
      class _EventInterface(ABC):
          @define_epoch_stats(sum, input_name="attr1_sum")
          @define_epoch_stats(np.mean, input_name="attr2_mean")
          @define_episode_stats(sum, input_name="attr1_sum")
          @define_episode_stats(np.mean, input_name="attr2_mean")
          @define_step_stats(
              sum, input_name="attr1", output_name="attr1_sum"
          )
          @define_step_stats(
              np.mean, input_name="attr1", output_name="attr1_mean"
          )
          @define_step_stats(
              sum, input_name="attr2", output_name="attr2_sum"
          )
          @define_step_stats(
              np.mean, input_name="attr2", output_name="attr2_mean"
          )
          def event1(self, attr1, attr2):
              pass
  
      agg_episode = LogStatsAggregator(LogStatsLevel.EPOCH)
      agg_step = LogStatsAggregator(LogStatsLevel.EPISODE, agg_episode)
      agg_event = LogStatsAggregator(LogStatsLevel.STEP, agg_step)
  
      no_steps = 5
      no_episodes = 7
      for episode in range(no_episodes):
          for step in range(no_steps):
              agg_event.add_event(
                  EventRecord(
                      _EventInterface,
                      _EventInterface.event1,
                      dict(attr1=2.0, attr2=-2.0),
                  )
              )
              agg_event.add_event(
                  EventRecord(
                      _EventInterface,
                      _EventInterface.event1,
                      dict(attr1=3.0, attr2=-3.0),
                  )
              )
  
              step_stats = agg_event.reduce()
              assert len(step_stats) == 4
              value1_sum = step_stats[
                  (_EventInterface.event1, "attr1_sum", None)
              ]
              value1_mean = step_stats[
                  (_EventInterface.event1, "attr1_mean", None)
              ]
              value2_sum = step_stats[
                  (_EventInterface.event1, "attr2_sum", None)
              ]
              value2_mean = step_stats[
                  (_EventInterface.event1, "attr2_mean", None)
              ]
              assert value1_sum == 5.0
              assert value1_mean == 2.5
              assert value2_sum == -5.0
              assert value2_mean == -2.5
  
          episode_stats = agg_step.reduce()
          assert len(episode_stats) == 2
          value1 = episode_stats[
              (_EventInterface.event1, "attr1_sum", None)
          ]
          value2 = episode_stats[
              (_EventInterface.event1, "attr2_mean", None)
          ]
          assert value1 == no_steps * 5.0
          assert value2 == -2.5
  
      epoch_stats = agg_episode.reduce()
      assert len(epoch_stats) == 2
      value1 = epoch_stats[(_EventInterface.event1, "attr1_sum", None)]
      value2 = epoch_stats[(_EventInterface.event1, "attr2_mean", None)]
      assert value1 == no_episodes * no_steps * 5.0
      assert value2 == -2.5
  
file_path: maze/maze/test/core/test_log_stats.py
imports: from abc import ABC
  import numpy
  import pytest
  from maze.core.events.event_record import EventRecord
  from maze.core.log_stats.event_decorators import define_step_stats, define_episode_stats, define_epoch_stats, define_stats_grouping
  from maze.core.log_stats.log_stats import LogStatsAggregator, LogStatsLevel
  from maze.core.log_stats.reducer_functions import histogram
label_desc: Use image node_id 7 for calling a global function with example usage: test_aggregation_chain_fork() without return types