Пример #1
0
        /// <summary>
        /// Save the plot to output. This is where we do the heavy lifting of generating a plot.
        /// </summary>
        /// <param name="filenameStub"></param>
        /// <returns></returns>
        public IEnumerable <FileInfo> Save(IScopeContext ctx, string filenameStub)
        {
            // Now, do the pre-plot hook
            foreach (var act in _prePlotHook)
            {
                act(ctx, this);
            }

            // Initialize the canvas
            ROOTNET.NTCanvas c = null;
            _canvasIndex++;
            c = new ROOTNET.NTCanvas($"c{_canvasIndex}", GetTitle());
            c.SetCanvasSize(DefaultCanvasWidth, DefaultCanvasHeight);

            if (_plots.Length > 0)
            {
                _plots[0].Title = GetTitle();
            }


            // x and y axis titles
            if (_plots.Length > 0)
            {
                if (_xaxisTitle != null)
                {
                    _plots[0].Xaxis.Title = _xaxisTitle;
                }
                if (_yaxisTitle != null)
                {
                    _plots[0].Yaxis.Title = _yaxisTitle;
                }
            }

            // Plot everything.
            var optS = _drawOptions;

            foreach (var p in _plots)
            {
                if (_maxIsSet)
                {
                    p.Maximum = _plotMaximum;
                }
                if (_minIsSet)
                {
                    p.Minimum = _plotMinimum;
                }

                var perHistoOps = p.Option;
                p.Draw(optS + " " + perHistoOps);
                optS = _drawOptions + "SAME";
            }

            // And post-process
            foreach (var a in _postPlotHook)
            {
                a(ctx, this, c);
            }

            // Save it
            string[] formats     = null;
            var      formatsExpr = ctx.GetVariableValue("plotformats") as object[];

            if (formatsExpr != null)
            {
                formats = formatsExpr.Cast <string>().ToArray();
            }
            if (formats == null)
            {
                formats = new string[] { "png" }
            }
            ;

            var finfos = formats
                         .Select(fmt =>
            {
                var fout = new FileInfo(string.Format("{0}.{1}", filenameStub, fmt));
                if (fout.Exists)
                {
                    try
                    {
                        fout.Delete();
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Had trouble removing the old file {0}", fout.FullName);
                        Console.WriteLine("  -> {0}", e.Message);
                    }
                }
                c.SaveAs(fout.FullName);
                return(fout);
            });

            return(finfos.ToArray());
        }
    }
Пример #2
0
        /// <summary>
        /// Create a canvas that is a set of stacked plots.
        /// </summary>
        /// <remarks>
        /// Only TH1F plots are dealt with properly here. Everything else is ignored and no stacked plot will be emitted.
        /// </remarks>
        /// <param name="histos"></param>
        /// <param name="canvasName">Name given to the canvas</param>
        /// <param name="canvasTitle">Title that will be put at the top of the canvas</param>
        /// <param name="colorize">True if colors should be automattically assigned to the canvas.</param>
        /// <param name="logy">True if the y axis should be log scale</param>
        /// <param name="normalize">True if the histograms should be set to normal area (1) before being plotted</param>
        /// <param name="legendContainsOnlyUniqueTitleWords">If true, then common words in the  histogram titles are removed before they are used for the legend</param>
        /// <returns></returns>
        public static ROOTNET.Interface.NTCanvas PlotStacked(this ROOTNET.Interface.NTH1[] histos, string canvasName, string canvasTitle,
                                                             bool logy      = false,
                                                             bool normalize = false,
                                                             bool legendContainsOnlyUniqueTitleWords = true,
                                                             bool colorize = true)
        {
            if (histos == null || histos.Length == 0)
            {
                return(null);
            }

            // Always build a clone... because that way if the histogram is modified after we look at it, the plot will be what
            // the user intended.
            using (ROOTLock.Lock())
            {
                var hToPlot = (from h in histos where (h as ROOTNET.Interface.NTH1) != null select h.Clone(string.Format("{0}{1}", h.Name, canvasName)) as ROOTNET.Interface.NTH1).ToArray();
                if (hToPlot.Length == 0)
                {
                    var msg = new StringBuilder();
                    msg.Append("Warning: Only able to build a stacked plot for TH1F type plots (");
                    foreach (var p in histos)
                    {
                        msg.AppendFormat(" {0}", p.Name);
                    }
                    msg.Append(")");
                    Console.WriteLine(msg.ToString());
                    return(null);
                }

                foreach (var h in hToPlot)
                {
                    h.SetDirectory(null);
                }

                //
                // If we have to normalize first, we need to normalize first!
                //

                if (normalize)
                {
                    hToPlot = (from h in hToPlot
                               select h.Normalize()).ToArray();
                }

                //
                // Reset the colors on these guys
                //

                if (colorize)
                {
                    var cloop = new ColorLoop();
                    foreach (var h in hToPlot)
                    {
                        h.LineColor = cloop.NextColor();
                    }
                }

                //
                // Remove common words from the titles.
                //

                if (legendContainsOnlyUniqueTitleWords && hToPlot.Length > 1)
                {
                    var splitTitles = from h in hToPlot
                                      select h.Title.Split();

                    var wordList = from index in Enumerable.Range(0, splitTitles.Select(ar => ar.Count()).Max())
                                   select(from titleWords in splitTitles select titleWords.Skip(index).FirstOrDefault()).ToArray();

                    var isTheSame = (from wl in wordList
                                     select(wl.All(tword => tword == wl.First()))).ToArray();

                    var fixedTitleStrings = from twords in splitTitles
                                            select(
                        from h in twords.Zip(isTheSame, (tword, issame) => issame ? "" : tword)
                        where !string.IsNullOrWhiteSpace(h)
                        select h
                        );

                    foreach (var histAndTitle in hToPlot.Zip(fixedTitleStrings, (h, strArr) => Tuple.Create(h, strArr)))
                    {
                        string title = string.Join(" ", histAndTitle.Item2);
                        histAndTitle.Item1.Title = title;
                    }
                }

                //
                // Grab the x and y axis titles from the first histogram
                //

                var xaxisTitle = hToPlot[0].Xaxis.Title;
                var yaxisTitle = hToPlot[0].Yaxis.Title;

                //
                // Use the nice ROOT utility THStack to make the plot. Once we do this, the plot is now owned by the TCanvas.
                //

                var stack = new ROOTNET.NTHStack(canvasName + "Stack", canvasTitle.ReplaceLatexStrings());
                foreach (var h in hToPlot)
                {
                    stack.Add(h);
                    h.SetNull();
                }

                //
                // Now do the plotting. Use the THStack to get all the axis stuff correct.
                // If we are plotting a log plot, then make sure to set that first before
                // calling it as it will use that information during its painting.
                //

                var result = new ROOTNET.NTCanvas(canvasName, canvasTitle.ReplaceLatexStrings())
                {
                    FillColor = ROOTNET.NTStyle.gStyle.FrameFillColor // This is not a sticky setting!
                };
                if (logy)
                {
                    result.Logy = 1;
                }
                stack.Draw("nostack");

                if (!string.IsNullOrWhiteSpace(xaxisTitle))
                {
                    stack.Xaxis.Title = xaxisTitle;
                }
                if (!string.IsNullOrWhiteSpace(yaxisTitle))
                {
                    stack.Yaxis.Title = yaxisTitle;
                }

                stack.Draw("nostack");

                //
                // The stack is now "attached" to the canvas. This means the canvas now owns it. So we
                // definately don't want the GC to delete it - so here we need to turn off the delete.
                //

                stack.SetNull();

                //
                // And a legend!
                //

                result.BuildLegend();

                //
                // Return the canvas so it can be saved to the file (or whatever).
                //

                return(result);
            }
        }
Пример #3
0
        /// <summary>
        /// Save to a file.
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="filenameStub"></param>
        /// <returns></returns>
        public IEnumerable <FileInfo> Save(IScopeContext ctx, string filenameStub)
        {
            // Do pre-plot actions.
            foreach (var ph in _prePlotHook)
            {
                ph(ctx, this);
            }

            // Initialize the canvas
            var c = new ROOTNET.NTCanvas();

            c.SetCanvasSize(DefaultCanvasWidth, DefaultCanvasHeight);
            c.Title = GetTitle();

            c.Logx = _logx ? 1 : 0;
            c.Logy = _logy ? 1 : 0;

            // Get the plot maximum
            bool   setMaximum = false;
            double graphMax   = 0.0;

            if (_maxIsSet)
            {
                setMaximum = true;
                graphMax   = _plotMaximum;
            }

            // Do the plot minimum
            bool setMinimum = _minIsSet;
            var  graphMin   = setMaximum ? _plotMinimum : 0.0;


            var mp = new ROOTNET.NTMultiGraph("graph", GetTitle());
            // Plot everything.
            var optS = _drawOptions + "A";

            foreach (var p in _g)
            {
                if (!string.IsNullOrWhiteSpace(_xaxisTitle))
                {
                    p.Xaxis.Title = _xaxisTitle;
                }
                if (!string.IsNullOrWhiteSpace(_yaxisTitle))
                {
                    p.Yaxis.Title = _yaxisTitle;
                }
                if (setMaximum)
                {
                    p.Maximum = graphMax;
                }
                if (setMinimum)
                {
                    p.Minimum = graphMin;
                }

                mp.Add(p, _drawOptions);
                //p.Draw(optS);
                optS    = _drawOptions;
                p.Title = GetTitle();
            }
            mp.Draw("a");

            // Post plot actions
            foreach (var ph in _postPlotHook)
            {
                ph(ctx, this, c);
            }

            // Save it
            string[] formats     = null;
            var      formatsExpr = ctx.GetVariableValue("plotformats") as object[];

            if (formatsExpr != null)
            {
                formats = formatsExpr.Cast <string>().ToArray();
            }
            if (formats == null)
            {
                formats = new string[] { "png" }
            }
            ;

            var finfos = formats
                         .Select(fmt =>
            {
                var fout = new FileInfo(string.Format("{0}.{1}", filenameStub, fmt));
                if (fout.Exists)
                {
                    try
                    {
                        fout.Delete();
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Had trouble removing the old file {0}", fout.FullName);
                        Console.WriteLine("  -> {0}", e.Message);
                    }
                }
                c.SaveAs(fout.FullName);
                return(fout);
            });

            return(finfos.ToArray());
        }
    }
Пример #4
0
        /// <summary>
        /// Create a canvas that is a set of stacked plots.
        /// </summary>
        /// <remarks>
        /// Only TH1F plots are dealt with properly here. Everything else is ignored and no stacked plot will be emitted.
        /// </remarks>
        /// <param name="histos"></param>
        /// <param name="canvasName">Name given to the canvas</param>
        /// <param name="canvasTitle">Title that will be put at the top of the canvas</param>
        /// <param name="colorize">True if colors should be automattically assigned to the canvas.</param>
        /// <param name="logy">True if the y axis should be log scale</param>
        /// <param name="normalize">True if the histograms should be set to normal area (1) before being plotted</param>
        /// <param name="legendContainsOnlyUniqueTitleWords">If true, then common words in the  histogram titles are removed before they are used for the legend</param>
        /// <returns></returns>
        public static ROOTNET.Interface.NTCanvas PlotStacked(this ROOTNET.Interface.NTH1[] histos, string canvasName, string canvasTitle,
            bool logy = false,
            bool normalize = false,
            bool legendContainsOnlyUniqueTitleWords = true,
            bool colorize = true)
        {
            if (histos == null || histos.Length == 0)
                return null;

            //
            // Always build a clone... because that way if the histogram is modified after we look at it, the plot will be what
            // the user intended.
            // 

            var hToPlot = (from h in histos where (h as ROOTNET.Interface.NTH1) != null select h.Clone(string.Format("{0}{1}", h.Name, canvasName)) as ROOTNET.Interface.NTH1).ToArray();
            if (hToPlot.Length == 0)
            {
                var msg = new StringBuilder();
                msg.Append("Warning: Only able to build a stacked plot for TH1F type plots (");
                foreach (var p in histos)
                {
                    msg.AppendFormat(" {0}", p.Name);
                }
                msg.Append(")");
                Console.WriteLine(msg.ToString());
                return null;
            }

            foreach (var h in hToPlot)
            {
                h.SetDirectory(null);
            }

            //
            // If we have to normalize first, we need to normalize first!
            // 

            if (normalize)
            {
                hToPlot = (from h in hToPlot
                           select h.Normalize()).ToArray();
            }

            //
            // Reset the colors on these guys
            // 

            if (colorize)
            {
                var cloop = new ColorLoop();
                foreach (var h in hToPlot)
                {
                    h.LineColor = cloop.NextColor();
                }
            }

            //
            // Remove common words from the titles.
            // 

            if (legendContainsOnlyUniqueTitleWords && hToPlot.Length > 1)
            {
                var splitTitles = from h in hToPlot
                                  select h.Title.Split();

                var wordList = from index in Enumerable.Range(0, splitTitles.Select(ar => ar.Count()).Max())
                               select (from titleWords in splitTitles select titleWords.Skip(index).FirstOrDefault()).ToArray();

                var isTheSame = (from wl in wordList
                                 select (wl.All(tword => tword == wl.First()))).ToArray();

                var fixedTitleStrings = from twords in splitTitles
                                        select (
                                        from h in twords.Zip(isTheSame, (tword, issame) => issame ? "" : tword)
                                        where !string.IsNullOrWhiteSpace(h)
                                        select h
                                        );

                foreach (var histAndTitle in hToPlot.Zip(fixedTitleStrings, (h, strArr) => Tuple.Create(h, strArr)))
                {
                    string title = string.Join(" ", histAndTitle.Item2);
                    histAndTitle.Item1.Title = title;
                }
            }

            //
            // Grab the x and y axis titles from the first histogram
            //

            var xaxisTitle = hToPlot[0].Xaxis.Title;
            var yaxisTitle = hToPlot[0].Yaxis.Title;

            //
            // Use the nice ROOT utility THStack to make the plot. Once we do this, the plot is now owned by the TCanvas.
            // 

            var stack = new ROOTNET.NTHStack(canvasName + "Stack", canvasTitle.ReplaceLatexStrings());
            foreach (var h in hToPlot)
            {
                stack.Add(h);
                h.SetNull();
            }

            //
            // Now do the plotting. Use the THStack to get all the axis stuff correct.
            // If we are plotting a log plot, then make sure to set that first before
            // calling it as it will use that information during its painting.
            // 

            var result = new ROOTNET.NTCanvas(canvasName, canvasTitle.ReplaceLatexStrings());
            result.FillColor = ROOTNET.NTStyle.gStyle.FrameFillColor; // This is not a sticky setting!
            if (logy)
                result.Logy = 1;
            stack.Draw("nostack");

            if (!string.IsNullOrWhiteSpace(xaxisTitle))
                stack.Xaxis.Title = xaxisTitle;
            if (!string.IsNullOrWhiteSpace(yaxisTitle))
                stack.Yaxis.Title = yaxisTitle;

            stack.Draw("nostack");

            //
            // The stack is now "attached" to the canvas. This means the canvas now owns it. So we
            // definately don't want the GC to delete it - so here we need to turn off the delete.
            // 

            stack.SetNull();

            //
            // And a legend!
            // 

            result.BuildLegend();

            //
            // Return the canvas so it can be saved to the file (or whatever).
            // 

            return result;
        }