
    h"                     Z   S SK r S SKJr  S SKrS SKrS SKJr  S SK	J
r  S\R                  S\4S jr  SS\R                  S\S	\S\4S
 jjrS\R"                  S\R                  S\R"                  4S jr SS\\R&                  \\\R&                  4   4   S\R                  S\S\\R&                  \\\R&                  4   4   4S jjrS\R                  S\\\S4   \\\\S4   4   4   4S jrS\R                  S\4S jrS\R                  S\4S jrS\R                  SS4S jrg)    N)Union)spaces)
functionalobservation_spacereturnc                     [         R                  " U R                  5      R                  5       nUS:X  a  [        R
                  " S5        US:H  $ )av  
Check if an image observation space (see ``is_image_space``)
is channels-first (CxHxW, True) or channels-last (HxWxC, False).

Use a heuristic that channel dimension is the smallest of the three.
If second dimension is smallest, raise an exception (no support).

:param observation_space:
:return: True if observation space is channels-first image, False if channels-last.
   zXTreating image space as channels-last, while second dimension was smallest of the three.r   )npargminshapeitemwarningswarn)r   smallest_dimensions     `/home/james-whalen/.local/lib/python3.13/site-packages/stable_baselines3/common/preprocessing.pyis_image_space_channels_firstr   
   sC     #4#:#:;@@BQpq""    check_channelsnormalized_imagec                    U(       + =p4[        U [        R                  5      (       a  [        U R                  5      S:X  a  U(       a  U R
                  [        R                  :w  a  g[        R                  " U R                  S:g  5      =(       d#    [        R                  " U R                  S:g  5      nU(       a  U(       a  gU(       d  g[        U 5      (       a  U R                  S   nUS;   $ U R                  S   nUS;   $ g)a  
Check if a observation space has the shape, limits and dtype
of a valid image.
The check is conservative, so that it returns False if there is a doubt.

Valid images: RGB, RGBD, GrayScale with values in [0, 255]

:param observation_space:
:param check_channels: Whether to do or not the check for the number of channels.
    e.g., with frame-stacking, the observation space may have more channels than expected.
:param normalized_image: Whether to assume that the image is already normalized
    or not (this disables dtype and bounds checks): when True, it only checks that
    the space is a Box and has 3 dimensions.
    Otherwise, it checks that it has expected dtype (uint8) and bounds (values in [0, 255]).
:return:
   Fr      T)r	   r      )
isinstancer   Boxlenr   dtyper
   uint8anylowhighr   )r   r   r   check_dtypecheck_boundsincorrect_bounds
n_channelss          r   is_image_spacer'      s    * &6!55K#VZZ00S9J9P9P5QUV5V,22bhh> 66"3"7"71"<=fHYH^H^beHeAf, ():;;*003J Y&& +004JY&&r   observationc                 4   SSK Jn  [        U5      (       a  U R                  UR                  :X  dg  U R                  SS UR                  :X  dJ  UR	                  U 5      nUR                  UR                  :X  d  UR                  SS UR                  :X  a  Un U $ )z
Handle the different cases for images as PyTorch use channel first format.

:param observation:
:param observation_space:
:return: channel first observation if observation is an image
r   )VecTransposeImager	   N) stable_baselines3.common.vec_envr*   r'   r   transpose_image)r(   r   r*   transpose_obss       r   maybe_transposer.   H   s     C'((!!%6%<%<<@Q@QRSRT@UYjYpYp@p-==kJM""&7&=&==ATATUVUWAX\m\s\sAs+r   obsnormalize_imagesc                    [        U[        R                  5      (       aT  [        U [        5      (       d   S[	        U 5       35       e0 nU R                  5        H  u  pE[        XQU   US9X4'   M     U$ [        U [        R                  5      (       d   S[	        U 5       35       e[        U[        R                  5      (       a:  U(       a#  [        U5      (       a  U R                  5       S-  $ U R                  5       $ [        U[        R                  5      (       aD  [        R                  " U R                  5       [!        UR"                  5      S9R                  5       $ [        U[        R$                  5      (       a  [        R&                  " [)        [        R*                  " U R                  5       SSS95       VVs/ s HL  u  pg[        R                  " UR                  5       [!        UR,                  U   5      S9R                  5       PMN     snnSS9R/                  U R0                  S	   [3        UR,                  5      5      $ [        U[        R4                  5      (       a  U R                  5       $ [7        S
U 35      es  snnf )aP  
Preprocess observation to be to a neural network.
For images, it normalizes the values by dividing them by 255 (to have values in [0, 1])
For discrete observations, it create a one hot vector.

:param obs: Observation
:param observation_space:
:param normalize_images: Whether to normalize images or not
    (True by default)
:return:
zExpected dict, got )r0   z"Expecting a torch Tensor, but got g     o@)num_classesr	   )dimr   r   z"Preprocessing not implemented for )r   r   Dictdicttypeitemspreprocess_obsthTensorr   r'   floatDiscreteFone_hotlongintnMultiDiscretecat	enumeratesplitnvecviewr   sumMultiBinaryNotImplementedError)r/   r   r0   preprocessed_obskey_obsidxobs_s           r   r8   r8   \   s     #V[[11#t$$G(;DI;&GG$IC$2439Obr$s! %c299%%W)KDQTI;'WW%#VZZ00/@ A A99;&&yy{	%v	7	7yy5F5H5H1IJPPRR	%v';';	<	<vv "+288CHHJq+I!J!JIC 		$))+37H7M7Mc7R3STZZ\!J 
 $syy|S!2!7!78
9	: 
%v'9'9	:	:yy{!$FGXFY"Z[[s   AJ
.c                 0   [        U [        R                  5      (       a  U R                  $ [        U [        R                  5      (       a  g[        U [        R
                  5      (       a  [        U R                  5      4$ [        U [        R                  5      (       a  U R                  $ [        U [        R                  5      (       a9  U R                  R                  5        VVs0 s H  u  pU[        U5      _M     snn$ [        U  S35      es  snnf )z`
Get the shape of the observation (useful for the buffers).

:param observation_space:
:return:
)r	   z# observation space is not supported)r   r   r   r   r<   rB   r   rF   rI   r4   r7   get_obs_shaperJ   )r   rL   subspaces      r   rQ   rQ      s     #VZZ00 &&&	%v	7	7	%v';';	<	<%**+--	%v'9'9	:	: &&&	%v{{	3	3DUD\D\DbDbDdeDd#]8,,Ddee "%6$77Z"[\\ fs   (Dc                     [        U [        R                  5      (       a  [        U R                  5      $ [        R
                  R                  U 5      $ )z
Get the dimension of the observation space when flattened.
It does not apply to image observation space.

Used by the ``FlattenExtractor`` to compute the input shape.

:param observation_space:
:return:
)r   r   rB   rH   rF   utilsflatdim)r   s    r   get_flattened_obs_dimrV      sB     #V%9%9::$))** ||##$566r   action_spacec                 &   [        U [        R                  5      (       a)  [        [        R
                  " U R                  5      5      $ [        U [        R                  5      (       a  g[        U [        R                  5      (       a  [        U R                  5      $ [        U [        R                  5      (       aI  [        U R                  [        5      (       d   SU R                   S35       e[        U R                  5      $ [        U  S35      e)zG
Get the dimension of the action space.

:param action_space:
:return:
r	   zMulti-dimensional MultiBinary(z<) action space is not supported. You can flatten it instead.z action space is not supported)r   r   r   r@   r
   prodr   r<   rB   r   rF   rI   rA   rJ   )rW   s    r   get_action_dimrZ      s     ,

++277<--.//	L&//	2	2	L&"6"6	7	7<$$%%	L&"4"4	5	5NNC
 
 	y+LNN+;;wx	y 
 <>>""!\N2P"QRRr   	obs_spacec                 t   [        U [        R                  [        R                  45      (       a  [        U [        R                  5      (       a  U R                  R	                  5       OU R                  nU H=  n[        U[        R                  [        R                  45      (       d  M4  [        S5      e   gg)z
Make sure the observation space does not have nested spaces (Dicts/Tuples inside Dicts/Tuples).
If so, raise an Exception informing that there is no support for this.

:param obs_space: an observation space
zWNested observation spaces are not supported (Tuple/Dict space inside Tuple/Dict space).N)r   r   r4   TuplevaluesrJ   )r[   
sub_spaces	sub_spaces      r   check_for_nested_spacesra      s     )fkk6<<8992<Y2T2TY%%,,.ZcZjZj
#I)fkk6<<%@AA)m  $ :r   )FF)T)r   typingr   numpyr
   torchr9   	gymnasiumr   torch.nnr   r=   r   boolr   Spacer'   ndarrayr.   r:   r5   strr8   tupler@   rQ   rV   rZ   ra    r   r   <module>rm      s        $#VZZ #D #& !"*||** * 
	*Z  QSQ[Q[ . "0\	ryy$sBII~..	/0\||0\ 0\ 299d3		>**+	0\f]||]
5c?DeCHo!5667]67V\\ 7c 7&S S# S2v||  r   