Esempio n. 1
0
        /// <summary>
        /// Returna plot that has as its content its value divided by its error, and zero errors.
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="source"></param>
        /// <returns></returns>
        public static NTH1 asSigma(IScopeContext ctx, NTH1 plot)
        {
            var result = plot.Clone() as NTH1;

            Tags.CopyTags(ctx, plot, result);

            result.Reset();

            // Besure to do the overflow bins as well.
            for (int i_bin_x = 0; i_bin_x < result.NbinsX + 2; i_bin_x++)
            {
                for (int i_bin_y = 0; i_bin_y < result.NbinsY + 2; i_bin_y++)
                {
                    for (int i_bin_z = 0; i_bin_z < result.NbinsZ + 2; i_bin_z++)
                    {
                        var v = plot.GetBinContent(i_bin_x, i_bin_y, i_bin_z);
                        var e = plot.GetBinError(i_bin_x, i_bin_y, i_bin_z);

                        var sig = e == 0 ? 0.0 : v / e;
                        result.SetBinContent(i_bin_x, i_bin_y, i_bin_z, sig);
                    }
                }
            }

            return(result);
        }
Esempio n. 2
0
        /// <summary>
        /// Return the x-axis value for a particular efficiency.
        /// </summary>
        /// <param name="r"></param>
        /// <param name="bv"></param>
        /// <returns></returns>
        private static double CalcEffValue(NTH1 r, double bv, bool greater = true)
        {
            var firstValue = Range(0, r.NbinsX)
                .Where(bin => greater ? r.GetBinContent(bin) > bv : r.GetBinContent(bin) < bv)
                .FirstOrDefault();

            return r.Xaxis.GetBinCenter(firstValue);
        }
Esempio n. 3
0
 /// <summary>
 /// Given a cut value (x axis value), return the value of the histo at that point.
 /// </summary>
 /// <param name="hist"></param>
 /// <param name="xAxisValue"></param>
 /// <returns></returns>
 private static double LookupEffAtCut(NTH1 hist, double xAxisValue)
 {
     var bin = hist.Xaxis.FindBin(xAxisValue);
     return hist.GetBinContent(bin);
 }
Esempio n. 4
0
        /// <summary>
        /// Generate 2D turn on graphs from input signal and background plots.
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="plot"></param>
        /// <param name="xCutGreaterThan"></param>
        /// <param name="yCutGreaterThan"></param>
        /// <returns>A graph with the signal eff along the x axis, and the background eff along the y axis</returns>
        public static ROOTNET.Interface.NTGraph asROC(IScopeContext ctx, NTH1 signal, NTH1 background, bool xCutGreaterThan = true, bool yCutGreaterThan = true)
        {
            // The two plots must be identical.
            if (signal.NbinsX != background.NbinsX)
            {
                throw new ArgumentException($"AsROC requires the same binning on the input plots (signal has {signal.NbinsX} and background has {background.NbinsX}).");
            }

            // Now, develop pairs of values so we can track the background and signal efficiency.
            var numberPairs = Enumerable.Range(0, signal.NbinsX + 1)
                              .Select(ibin => Tuple.Create(signal.GetBinContent(ibin), background.GetBinContent(ibin)));

            // Now, turn them into efficiencies if we need to.
            var signalTotal     = numberPairs.Select(p => p.Item1).Sum();
            var backgroundTotal = numberPairs.Select(p => p.Item2).Sum();

            double runningTotalSignal     = xCutGreaterThan ? 0 : signalTotal;
            double runningTotalBackground = yCutGreaterThan ? 0 : backgroundTotal;

            Func <double, double> calcRunningSignal, calcRunningBackground;

            if (xCutGreaterThan)
            {
                calcRunningSignal = p => runningTotalSignal += p;
            }
            else
            {
                calcRunningSignal = p => runningTotalSignal -= p;
            }
            if (yCutGreaterThan)
            {
                calcRunningBackground = p => runningTotalBackground += p;
            }
            else
            {
                calcRunningBackground = p => runningTotalBackground -= p;
            }

            numberPairs = numberPairs
                          .Select(p => Tuple.Create(calcRunningSignal(p.Item1), calcRunningBackground(p.Item2)))
                          .Select(p => Tuple.Create(p.Item1 / signalTotal, p.Item2 / backgroundTotal))
                          .ToArray(); // Side effects, make sure this gets run only once!

            // Remove the non-unique pairs, since this is going to be a scatter plot.
            numberPairs = numberPairs
                          .Distinct(new TupleCompare());

            // Next, draw them in a graph.
            var pts  = numberPairs.ToArray();
            var graf = new ROOTNET.NTGraph(pts.Length, pts.Select(p => p.Item1).ToArray(), pts.Select(p => p.Item2).ToArray());

            graf.FillColor = 0; // Make sure the background is white

            // Track tags for the signal (assuming the background is "common"), and track everything else.
            Tags.CopyTags(ctx, signal, graf);
            graf.SetTitle($"{signal.Title} ROC");
            graf.Xaxis.Title       = $"Efficiency (signal)";
            graf.Yaxis.Title       = $"Efficiency (background)";
            graf.Histogram.Maximum = 1.0;
            graf.Histogram.Minimum = 0.0;

            return(graf);
        }