Exemple #1
0
        /// <summary>
        /// Convert everything and save it to the directory! Also write out
        /// all the sub-directories.
        /// </summary>
        /// <param name="calculateEverything">If true, then trigger all calculations here and below. Normally call with false.</param>
        public void Write(bool calculateEverything = true)
        {
            // Write everything associated with this directory.
            using (ROOTLock.Lock())
            {
                Directory.Write();
            }

            // Trigger all the calculatiosn that are needed for these directories.
            // This drives the ability for parallel calculation of everything.
            if (calculateEverything)
            {
                TriggerResolutions().Wait();
            }

            // Local values
            foreach (var item in _heldValues)
            {
                item.Save(Directory);
            }
            _heldValues.Clear();

            // Next, the subdirectories
            if (_subDirs.IsValueCreated)
            {
                foreach (var item in _subDirs.Value)
                {
                    item.Write();
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Create a TH1F plot from a stream of objects (with a lambda function to give flexability in conversion).
        /// </summary>
        /// <typeparam name="TSource">The type of the sequence that the plot will be run over</typeparam>
        /// <param name="source">The sequence over which a plot should be made. There will be one entry per item in the sequence.</param>
        /// <param name="plotName">The histogram will be created with this name</param>
        /// <param name="plotTitle">The histogram will be created with this title</param>
        /// <param name="nbins">Number of bins this histogram should have</param>
        /// <param name="lowBin">The xmin value for this histogram</param>
        /// <param name="highBin">The xmax value for this histogram</param>
        /// <param name="xValue">A lambda that returns the xvalue for each sequence item.</param>
        /// <param name="weight">A lambda that returns the weight for each sequence item. By default every entry has a weight of 1.</param>
        /// <returns></returns>
        public static ROOTNET.NTH1F Plot <TSource>
        (
            this IQueryable <TSource> source,
            string plotName, string plotTitle,
            int nbins, double lowBin, double highBin,
            Expression <Func <TSource, double> > xValue,
            Expression <Func <TSource, double> > weight = null)
        {
            using (ROOTLock.Lock())
            {
                if (weight == null)
                {
                    Expression <Func <TSource, double> > constWeight = s => 1.0;
                    weight = constWeight;
                }

                var hParameter = Expression.Parameter(typeof(ROOTNET.NTH1F), "h");
                var vParameter = Expression.Parameter(typeof(TSource), "v");

                // h.Fill(getter(v), weight(v)) is what we want to code up

                var callGetter = Expression.Invoke(xValue, vParameter);
                var callWeight = Expression.Invoke(weight, vParameter);

                var fillMethod = typeof(ROOTNET.NTH1F).GetMethod("Fill", new[] { typeof(double), typeof(double) });
                var callFill   = Expression.Call(hParameter, fillMethod, callGetter, callWeight);

                var lambda = Expression.Lambda <Action <ROOTNET.NTH1F, TSource> >(callFill, hParameter, vParameter);
                var h      = new ROOTNET.NTH1F(plotName, plotTitle.ReplaceLatexStrings(), nbins, lowBin, highBin);
                ConfigureHisto(h);
                return(source.ApplyToObject(h, lambda));
            }
        }
Exemple #3
0
        /// <summary>
        /// Write out an object. Eventually, with ROOTNET improvements this will work better and perahps
        /// won't be needed!
        /// </summary>
        /// <param name="obj">The object to be written. Assumed not null.</param>
        /// <param name="dir"></param>
        internal static void InternalWriteObject(this ROOTNET.Interface.NTObject obj, ROOTNET.Interface.NTDirectory dir)
        {
            if (obj == null)
            {
                Console.WriteLine("WARNING: Unable to write out null object to a TDirectory!");
                return;
            }

            using (ROOTLock.Lock())
            {
                if (obj is ROOTNET.Interface.NTH1 h)
                {
                    var copy = h.Clone();
                    dir.WriteTObject(copy); // Ugly from a memory pov, but...
                    copy.SetNull();
                }

                else
                {
                    dir.WriteTObject(obj);
                    obj.SetNull();
                }
            }
        }
        /// <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);
            }
        }