/// <summary>
        /// Given a 2D plot, map to a 1D plot assuming radial distances.
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="plot"></param>
        /// <returns>1D plot of the 2D plot</returns>
        /// <remarks>
        /// - Radial conversion assumes that both coordinates are the same units. For example, if they are x and y distances.
        /// - Overflow & underflow bins are not handled.
        /// - Errors are not properly handled.
        /// </remarks>
        public static ROOTNET.Interface.NTH1 asRadial(IScopeContext ctx, ROOTNET.Interface.NTH2 plot)
        {
            // First, determine the distances
            var xmin = plot.Xaxis.GetBinLowEdge(1);
            var ymin = plot.Yaxis.GetBinLowEdge(1);
            var xmax = plot.Xaxis.GetBinUpEdge(plot.Xaxis.Nbins);
            var ymax = plot.Yaxis.GetBinUpEdge(plot.Yaxis.Nbins);

            var rmin = Math.Sqrt(xmin * xmin + ymin * ymin);
            var rmax = Math.Sqrt(xmax * xmax + ymax * ymax);

            var nbin = Math.Max(plot.Xaxis.Nbins, plot.Yaxis.Nbins);

            var result = new ROOTNET.NTH1F(plot.Name, plot.Title, nbin, rmin, rmax);

            // Loop over, adding everything in.
            for (int i_x = 1; i_x <= plot.Xaxis.Nbins; i_x++)
            {
                for (int i_y = 1; i_y <= plot.Yaxis.Nbins; i_y++)
                {
                    var x = plot.Xaxis.GetBinCenter(i_x);
                    var y = plot.Yaxis.GetBinCenter(i_y);
                    var r = Math.Sqrt(x * x + y * y);

                    result.Fill(r, plot.GetBinContent(i_x, i_y));
                }
            }

            return(result);
        }
        /// <summary>
        /// Given a 2D plot, turn it into an efficiency plot. You can control the cut on each axis ( greater than or less than ).
        /// Each bin in the plot is the cut efficiency if you made the cut at those value.
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="plot">The 2D plot to convert to an efficiency map</param>
        /// <param name="xCutGreaterThan">True if the cut is greater than along the x axis</param>
        /// <param name="yCutGreaterThan">True if the cut is greater than along the y axis</param>
        /// <returns>The efficiency map</returns>
        /// <remarks>
        /// The overflow and underflow bins are taken into account for the total calculations, so they will contain
        /// sensible results.
        ///
        /// This works on a histogram, and thus a bin. So we have to define what the cut means. Since the cut is only has a real
        /// value at the bin edges, we must define it as such.
        ///   - For a ">" cut, the low edge of the bin is the cut value.
        ///   - for a "<" cut, the high edge of the bin is the cut value.
        ///
        /// </remarks>
        public static ROOTNET.Interface.NTH2 asEfficiency(IScopeContext ctx, ROOTNET.Interface.NTH2 plot, bool xCutGreaterThan = true, bool yCutGreaterThan = true)
        {
            var result = plot.Clone() as ROOTNET.Interface.NTH2;

            Tags.CopyTags(ctx, plot, result);

            var xBins = plot.Xaxis.Nbins;
            var yBins = plot.Yaxis.Nbins;

            var xBinRange = BinOrdering(xCutGreaterThan, xBins);
            var yBinRange = BinOrdering(yCutGreaterThan, yBins);

            // We must now build a cumulative 2D matrix with the sizes for each.
            foreach (var ixBin in xBinRange)
            {
                foreach (var iyBin in yBinRange)
                {
                    var binSum = SumBinArea(plot,
                                            BinOrdering(xCutGreaterThan, xBins, ixBin),
                                            BinOrdering(yCutGreaterThan, yBins, iyBin));

                    result.SetBinContent(ixBin, iyBin, binSum);
                }
            }

            // Turn it into an efficiency
            var totalSum = SumBinArea(plot, BinOrdering(true, xBins), BinOrdering(true, yBins));

            foreach (var ixBin in xBinRange)
            {
                foreach (var iyBin in yBinRange)
                {
                    result.SetBinContent(ixBin, iyBin, result.GetBinContent(ixBin, iyBin) / totalSum);
                }
            }

            // Set up for good display
            result.Maximum = 1.0;
            return(result);
        }