class_docstr: Encapsulates multiple torch policies along with a distribution mapper for training and rollouts
  in structured environments.
  
  :param networks: Mapping of policy networks to encapsulate
  :param distribution_mapper: Distribution mapper associated with the policy mapping.
  :param device: Device the policy should be located on (cpu or cuda)
class_docstr_tok: ["Encapsulates","multiple","torch","policies","along","with","a","distribution","mapper","for","training","and","rollouts","in","structured","environments",".",":","param","networks",":","Mapping","of","policy","networks","to","encapsulate",":","param","distribution_mapper",":","Distribution","mapper","associated","with","the","policy","mapping",".",":","param","device",":","Device","the","policy","should","be","located","on","(","cpu","or","cuda",")"]
docstr: Compute the full output of a specified policy.
  
  :param observation: The observation to use as input.
  :param actor_id: Optional, the actor id specifying the network to use.
  :param temperature: Optional, the temperature to use for initializing the probability distribution.
  :return: The computed PolicySubStepOutput.
docstr_tok: ["Compute","the","full","output","of","a","specified","policy",".",":","param","observation",":","The","observation","to","use","as","input",".",":","param","actor_id",":","Optional",",","the","actor","id","specifying","the","network","to","use",".",":","param","temperature",":","Optional",",","the","temperature","to","use","for","initializing","the","probability","distribution",".",":","return",":","The","computed","PolicySubStepOutput","."]
code: def compute_substep_policy_output(
      self,
      observation: ObservationType,
      actor_id: ActorID = None,
      temperature: float = 1.0,
  ) -> PolicySubStepOutput:
      """Compute the full output of a specified policy.
  
      :param observation: The observation to use as input.
      :param actor_id: Optional, the actor id specifying the network to use.
      :param temperature: Optional, the temperature to use for initializing the probability distribution.
      :return: The computed PolicySubStepOutput.
      """
  
      # Convert the import to torch in-place
      obs_t = convert_to_torch(
          observation, device=self._device, cast=None, in_place=True
      )
  
      # Compute a forward pass of the policy network retrieving all the outputs (action logits + embedding logits if
      #  applicable)
      network_out = self.network_for(actor_id)(obs_t)
  
      # Disentangle action and embedding logits
      if any(
          [
              key
              not in self.distribution_mapper.action_space.spaces.keys()
              for key in network_out.keys()
          ]
      ):
          # Filter out the action logits
          action_logits = dict(
              filter(
                  lambda ii: ii[0]
                  in self.distribution_mapper.action_space.spaces.keys(),
                  network_out.items(),
              )
          )
          # Filter out the embedding logits
          embedding_logits = dict(
              filter(
                  lambda ii: ii[0]
                  not in self.distribution_mapper.action_space.spaces.keys(),
                  network_out.items(),
              )
          )
      else:
          action_logits = network_out
          embedding_logits = None
  
      # Initialize the probability distributions
      prob_dist = self.distribution_mapper.logits_dict_to_distribution(
          action_logits, temperature
      )
  
      return PolicySubStepOutput(
          action_logits=action_logits,
          prob_dist=prob_dist,
          embedding_logits=embedding_logits,
          actor_id=actor_id,
      )
  
imports: from typing import Mapping, Union, List, Dict, Tuple, Sequence, Optional
  import torch
  from torch import nn
  from maze.core.agent.policy import Policy
  from maze.core.agent.torch_model import TorchModel
  from maze.core.agent.torch_policy_output import PolicySubStepOutput, PolicyOutput
  from maze.core.annotations import override
  from maze.core.env.action_conversion import ActionType
  from maze.core.env.base_env import BaseEnv
  from maze.core.env.maze_state import MazeStateType
  from maze.core.env.observation_conversion import ObservationType
  from maze.core.env.structured_env import ActorID, StepKeyType
  from maze.core.trajectory_recording.records.structured_spaces_record import StructuredSpacesRecord
  from maze.distributions.categorical import CategoricalProbabilityDistribution
  from maze.distributions.distribution_mapper import DistributionMapper
  from maze.perception.perception_utils import convert_to_torch, convert_to_numpy
label_desc: Use image node_id 13 for calling the TorchPolicy obj's underlying member method code with example usage: obj.compute_substep_policy_output(observation, actor_id, temperature) and returns: PolicySubStepOutput