Perform the actual TH3 -> TH1 projection.

        This projection could be to 1D or 2D.

        Args:
            hist (ROOT.TH3): Histogram from which the projections should be performed.
        Returns:
            ROOT.TH1: The projected histogram.

def _project_TH3(self, hist: Hist) -> Any:
        """ Perform the actual TH3 -> TH1 projection.

        This projection could be to 1D or 2D.

        Args:
            hist (ROOT.TH3): Histogram from which the projections should be performed.
        Returns:
            ROOT.TH1: The projected histogram.
        """
        # Axis length validation
        if len(self.projection_axes) < 1 or len(self.projection_axes) > 2:
            raise ValueError(len(self.projection_axes), "Invalid number of axes")

        # Need to concatenate the names of the axes together
        projection_axis_name = ""
        for axis in self.projection_axes:
            # Determine the axis name based on the name of the axis type.
            # [:1] returns just the first letter. For example, we could get "xy" if the first axis as
            # x_axis and the second was y_axis.
            # NOTE: Careful. This depends on the name of the enumerated values!!! Since this isn't terribly
            #       safe, we then perform additional validation on the same to ensure that it is one of the
            #       expected axis names.
            proj_axis_name = axis.axis_type.name[:1]
            if proj_axis_name not in ["x", "y", "z"]:
                raise ValueError(f"Projection axis name {proj_axis_name} is not 'x', 'y', or 'z'. Please check your configuration.")
            projection_axis_name += proj_axis_name

        # Handle ROOT Project3D quirk...
        # 2D projection are called as (y, x, options), so we should reverse the order so it performs
        # as expected.
        # NOTE: This isn't well documented in TH3. It is instead described in THnBase.Projection(...)
        if len(self.projection_axes) == 2:
            # Reverse the axes
            projection_axis_name = projection_axis_name[::-1]

        # Do the actual projection
        logger.info(f"Projecting onto axes \"{projection_axis_name}\" from hist {hist.GetName()}")
        projected_hist = hist.Project3D(projection_axis_name)

        return projected_hist