class_docstr: Composes models from explicit model definitions.
  
  :param action_spaces_dict: Dict of sub-step id to action space.
  :param observation_spaces_dict: Dict of sub-step id to observation space.
  :param distribution_mapper_config: Distribution mapper configuration.
  :param policy: Mapping of sub-step keys to models.
  :param critic: Configuration for the critic composer.
docstr: Build the critic input from the given observation input and a dummy pass through the policy network (in case
  shared embeddings are used).
  
  :return: The dict holding the enw critic input spaces dict, needed for building the model.
docstr_tok: ["Build","the","critic","input","from","the","given","observation","input","and","a","dummy","pass","through","the","policy","network","(","in","case","shared","embeddings","are","used",")",".",":","return",":","The","dict","holding","the","enw","critic","input","spaces","dict",",","needed","for","building","the","model","."]
code: def _build_critic_input_space_dict(
      self,
  ) -> Dict[StepKeyType, spaces.Dict]:
      """Build the critic input from the given observation input and a dummy pass through the policy network (in case
      shared embeddings are used).
  
      :return: The dict holding the enw critic input spaces dict, needed for building the model.
      """
      critic_input_spaces_dict = dict(
          copy.deepcopy(self.observation_spaces_dict)
      )
      for step_key, obs_space in self.observation_spaces_dict.items():
          step_observation = dict()
          for obs_key, obs in obs_space.spaces.items():
              if (
                  isinstance(obs, spaces.Box)
                  and np.any(
                      obs_space[obs_key].low == np.finfo(np.float32).min
                  )
                  or np.any(
                      obs_space[obs_key].high
                      == np.finfo(np.float32).max
                  )
              ):
                  # In case any of the lower or upper bounds of the space are infinite, resample the values.
                  step_observation[obs_key] = np.random.randn(
                      *obs.shape
                  ).astype(np.float32)
              else:
                  # Set random generator to None.. In case the observation spaces have been loaded from
                  #   a file not setting this may lead to problems
                  obs._np_random = None
                  step_observation[obs_key] = obs.sample()
          if self._policy_composer is not None:
              tmp_out = self._policy_composer.policy.compute_substep_policy_output(
                  step_observation, actor_id=ActorID(step_key, 0)
              )
              if tmp_out.embedding_logits is not None:
                  new_observation_space = dict()
                  critic_input = StateCriticStepInput.build(
                      tmp_out, step_observation
                  )
                  for (
                      in_key,
                      in_value,
                  ) in critic_input.tensor_dict.items():
                      if in_key in critic_input_spaces_dict[step_key]:
                          new_observation_space[
                              in_key
                          ] = critic_input_spaces_dict[step_key][in_key]
                      else:
                          new_observation_space[in_key] = spaces.Box(
                              low=np.finfo(np.float32).min,
                              high=np.finfo(np.float32).max,
                              shape=in_value.shape,
                              dtype=np.float32,
                          )
                  critic_input_spaces_dict[step_key] = gym.spaces.Dict(
                      dict(new_observation_space)
                  )
      return critic_input_spaces_dict
  
imports: import copy
  from typing import Dict, Union, Optional, Mapping
  import gym
  import numpy
  from gym import spaces
  from maze.core.agent.state_critic_input_output import StateCriticStepInput
  from maze.core.agent.torch_policy import TorchPolicy
  from maze.core.agent.torch_state_action_critic import TorchStateActionCritic
  from maze.core.agent.torch_state_critic import TorchStateCritic
  from maze.core.annotations import override
  from maze.core.env.structured_env import StepKeyType, ActorID
  from maze.core.utils.factory import Factory, ConfigType
  from maze.perception.models.critics import BaseStateCriticComposer, SharedStateCriticComposer
  from maze.perception.models.critics.base_state_action_critic_composer import BaseStateActionCriticComposer
  from maze.perception.models.critics.critic_composer_interface import CriticComposerInterface
  from maze.perception.models.model_composer import BaseModelComposer
  from maze.perception.models.policies.base_policy_composer import BasePolicyComposer
  from maze.perception.perception_utils import map_nested_structure
label_desc: Use image node_id 3 for calling the CustomModelComposer obj's underlying member method code with example usage: obj._build_critic_input_space_dict() and returns: critic_input_spaces_dict