code: def _project_THn(self, hist: Hist) -> Any:
          
          # THnBase projections args are given as a list of axes, followed by any possible options.
          projection_axes = [axis.axis_type.value for axis in self.projection_axes]
  
          # Handle ROOT THnBase quirk...
          # 2D projection are called as (y, x, options), so we should reverse the order so it performs
          # as expected
          if len(projection_axes) == 2:
              # Reverses in place
              projection_axes.reverse()
  
          # Test calculating errors
          # Add "E" to ensure that errors will be calculated
          args = projection_axes + ["E"]
          # Do the actual projection
          logger.debug(f"hist: {hist.GetName()} args: {args}")
  
          if len(projection_axes) > 3:
              # Project into a THnBase object.
              projected_hist = hist.ProjectionND(*args)
          else:
              # Project a TH1 derived object.
              projected_hist = hist.Projection(*args)
  
          return projected_hist
docs: Perform the actual THn -> THn or TH1 projection.
  
          This projection could be to 1D, 2D, 3D, or ND.
  
          Args:
              hist (ROOT.THnBase): Histogram from which the projections should be performed.
          Returns:
              ROOT.THnBase or ROOT.TH1: The projected histogram.