code: def matrix_to_euler_angles(
      matrix: torch.Tensor, convention: str
  ) -> torch.Tensor:
      """
      Convert rotations given as rotation matrices to Euler angles in radians.
  
      Args:
          matrix: Rotation matrices as tensor of shape (..., 3, 3).
          convention: Convention string of three uppercase letters.
  
      Returns:
          Euler angles in radians as tensor of shape (..., 3).
      """
      if len(convention) != 3:
          raise ValueError("Convention must have 3 letters.")
      if convention[1] in (convention[0], convention[2]):
          raise ValueError(f"Invalid convention {convention}.")
      for letter in convention:
          if letter not in ("X", "Y", "Z"):
              raise ValueError(
                  f"Invalid letter {letter} in convention string."
              )
      if matrix.size(-1) != 3 or matrix.size(-2) != 3:
          raise ValueError(
              f"Invalid rotation matrix shape {matrix.shape}."
          )
      i0 = _index_from_letter(convention[0])
      i2 = _index_from_letter(convention[2])
      tait_bryan = i0 != i2
      if tait_bryan:
          central_angle = torch.asin(
              matrix[..., i0, i2]
              * (-1.0 if i0 - i2 in [-1, 2] else 1.0)
          )
      else:
          central_angle = torch.acos(matrix[..., i0, i0])
  
      o = (
          _angle_from_tan(
              convention[0],
              convention[1],
              matrix[..., i2],
              False,
              tait_bryan,
          ),
          central_angle,
          _angle_from_tan(
              convention[2],
              convention[1],
              matrix[..., i0, :],
              True,
              tait_bryan,
          ),
      )
      return torch.stack(o, -1)
  
imports: from typing import Optional
  import torch
  import torch.nn.functional
  from ..common.datatypes import Device
label_desc: Use image node_id 9 for calling a global function with example usage: matrix_to_euler_angles(matrix, convention) and returns: torch