code: def initialize_scene_construction_GM(
      T=6, reward=2.0, punishment=-4.0, urgency=-4.0
  ):
      loc_names = ["start"] + quadrant_names + choice_names
      what_obs_names = [
          "null",
          "UP",
          "RIGHT",
          "DOWN",
          "LEFT",
          "correct!",
          "incorrect!",
      ]
      where_obs_names = ["start"] + quadrant_names + choice_names
      action_names = ["start"] + quadrant_names + choice_names
  
      num_states = [len(all_scenes_all_configs), len(loc_names)]
      num_obs = [
          len(what_obs_names),
          len(where_obs_names),
      ]  # 7 possible visual outcomes (what I'm looking at: "null", "UP", "RIGHT", "DOWN", "LEFT", "CORRECT", "INCORRECT"), 9 possible proprioceptive outcomes (where I'm looking)
      num_controls = [1, len(action_names), 1]
  
      A = utils.initialize_empty_A(num_obs, num_states)
      B = utils.initialize_empty_B(num_states, num_controls)
      C_shapes = [[no, T] for no in num_obs]
      C = utils.obj_array_zeros(C_shapes)
      D = utils.obj_array_uniform(num_states)
  
      # # Create the A array (factorized representation)
      # for scene_id, scene_name in enumerate(scene_names):
      #     for loc_id, loc_name in enumerate(loc_names):
      #         for config_id, config_name in enumerate(config_names):
      #             _, flattened_scene_array = create_2x2_array(scene_name, config_name)
      #             if loc_name == 'start': # at fixation location
      #                 A[0][0, scene_id, loc_id, config_id] = 1.0
      #             elif loc_name in quadrant_names: # fixating one of the quadrants
      #                 A[0][0, scene_id, loc_id, config_id] = 'null' == flattened_scene_array[loc_id-1]
      #                 A[0][1, scene_id, loc_id, config_id] = 'UP' == flattened_scene_array[loc_id-1]
      #                 A[0][2, scene_id, loc_id, config_id] = 'RIGHT' == flattened_scene_array[loc_id-1]
      #                 A[0][3, scene_id, loc_id, config_id] = 'DOWN'  == flattened_scene_array[loc_id-1]
      #                 A[0][4, scene_id, loc_id, config_id] = 'LEFT'  == flattened_scene_array[loc_id-1]
      #             elif loc_name in choice_names: # making a choice
  
      #                 scene_choice = loc_name.split("_")[1] + "_" + loc_name.split("_")[2]
      #                 A[0][5,scene_id, loc_id, config_id] = scene_choice== scene_name # they get correct feedback if they choose the true scene at play
      #                 A[0][6,scene_id, loc_id, config_id] = scene_choice != scene_name # they get incorrect feedback if they choose anything other than the true scene at play
  
      #             A[1][loc_id, scene_id, loc_id, config_id] = 1.0
  
      # Create the A array (fully-enumerated parameterization)
      for state_id, scene_and_config_name in enumerate(
          all_scenes_all_configs
      ):
          scene_name, config_name = scene_and_config_name
          for loc_id, loc_name in enumerate(loc_names):
              _, flattened_scene_array = create_2x2_array(
                  scene_name, config_name
              )
              if loc_name == "start":  # at fixation location
                  A[0][0, state_id, loc_id] = 1.0
              elif (
                  loc_name in quadrant_names
              ):  # fixating one of the quadrants
                  A[0][0, state_id, loc_id] = (
                      "null" == flattened_scene_array[loc_id - 1]
                  )
                  A[0][1, state_id, loc_id] = (
                      "UP" == flattened_scene_array[loc_id - 1]
                  )
                  A[0][2, state_id, loc_id] = (
                      "RIGHT" == flattened_scene_array[loc_id - 1]
                  )
                  A[0][3, state_id, loc_id] = (
                      "DOWN" == flattened_scene_array[loc_id - 1]
                  )
                  A[0][4, state_id, loc_id] = (
                      "LEFT" == flattened_scene_array[loc_id - 1]
                  )
              elif loc_name in choice_names:  # making a choice
                  scene_choice = (
                      loc_name.split("_")[1]
                      + "_"
                      + loc_name.split("_")[2]
                  )
                  A[0][5, state_id, loc_id] = (
                      scene_choice == scene_name
                  )  # they get correct feedback if they choose the true scene at play
                  A[0][6, state_id, loc_id] = (
                      scene_choice != scene_name
                  )  # they get incorrect feedback if they choose anything other than the true scene at play
  
              A[1][loc_id, state_id, loc_id] = 1.0
  
      control_fac_idx = [1]
      for f, ns in enumerate(num_states):
          if f in control_fac_idx:
              B[f] = utils.construct_controllable_B(
                  [ns], [num_controls[f]]
              )[0]
          else:
              B[f][:, :, 0] = np.eye(ns)
  
      C[0][
          5, :
      ] = reward  # the agent expects to be right across timesteps
      C[0][
          6, :
      ] = punishment  # the agent expects to not be wrong across timesteps
      C[1][:5, 4:] = urgency  # make too much exploration costly
  
      D[1] = utils.onehot(
          0, num_states[1]
      )  # give agent certain beliefs about starting location
  
      parameters = {"A": A, "B": B, "C": C, "D": D}
  
      mapping = {
          "scene_names": scene_names,
          "what_obs_names": what_obs_names,
          "where_obs_names": where_obs_names,
          "action_names": action_names,
      }
  
      dimensions = {
          "num_states": num_states,
          "num_obs": num_obs,
          "num_controls": num_controls,
      }
  
      return parameters, mapping, dimensions
  
imports: from pymdp.envs import Env
  from pymdp import utils, maths
  import numpy
  from itertools import permutations, product
label_desc: Use image node_id 2 for calling a global function with example usage: initialize_scene_construction_GM(T, reward, punishment, urgency) and returns: parameters,  mapping,  dimensions