Documentation ¶
Overview ¶
Package allowing to wrap all needed element of a TTree plotting analysis
Example (ASimpleUseCase) ¶
package main import ( "image/color" "math" "golang.org/x/exp/rand" "gonum.org/v1/gonum/stat/distuv" "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // Define samples samples := []*ana.Sample{ ana.CreateSample("data", "data", `Data`, fData, tName), ana.CreateSample("bkg1", "bkg", `Proc 1 (2.1 pb)`, fBkg1, tName, ana.WithWeight(w1), ana.WithXsec(1.2)), ana.CreateSample("bkg2", "bkg", `Proc 2 (0.5 pb)`, fBkg2, tName, ana.WithWeight(w2), ana.WithXsec(0.6)), ana.CreateSample("bkg3", "bkg", `Proc 3 (0.9 pb)`, fBkg1, tName, ana.WithWeight(w2), ana.WithXsec(0.9)), } // Define variables variables := []*ana.Variable{ ana.NewVariable("Mttbar", ana.TreeVarF32("ttbar_m"), 25, 350, 1000, ana.WithAxisLabels(`M(t,t) [GeV]`, "Events Yields"), ), ana.NewVariable("DphiLL", ana.TreeVarF64("truth_dphi_ll"), 10, 0, math.Pi, ana.WithAxisLabels(`dPhi(l,l)`, "Events Yields"), ana.WithLegLeft(true)), } // Create analyzer object analyzer := ana.New(samples, variables, ana.WithSavePath("testdata/Plots_simpleUseCase"), ) // Run the analyzer to produce all the plots if err := analyzer.Run(); err != nil { panic(err) } } var ( fData = "../testdata/file1.root" fBkg1 = "../testdata/file2.root" fBkg2 = "../testdata/file3.root" tName = "truth" w1 = ana.TreeValF64(1.0) w2 = ana.TreeValF64(0.5) )
Output:
Example (MultiComponentSamples) ¶
Creation of the default analysis maker type with multi-component samples. The files, trees and variables are dummy, they are here just for the example.
package main import ( "image/color" "math" "golang.org/x/exp/rand" "gonum.org/v1/gonum/stat/distuv" "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // Weights and cuts w := ana.TreeVarF32("weight") isQQ := ana.TreeVarBool("init_qq") // Data sample. data := ana.NewSample("data", "data", `Data 18-20`) data.AddComponent(fData, tName) data.AddComponent(fBkg1, tName) // Background A sample including three components. bkgA := ana.NewSample("BkgTotA", "bkg", `Total Bkg A`, ana.WithWeight(w)) bkgA.AddComponent(fBkg1, tName) bkgA.AddComponent(fBkg2, tName) bkgA.AddComponent(fBkg1, tName, ana.WithCut(isQQ)) // Background B sample including two components. bkgB := ana.NewSample("BkgTotB", "bkg", `Total Bkg B`, ana.WithWeight(w)) bkgB.AddComponent(fBkg1, tName) bkgB.AddComponent(fBkg2, tName) // Put samples together. samples := []*ana.Sample{data, bkgA, bkgB} // Define variables variables := []*ana.Variable{ ana.NewVariable("Mttbar", ana.TreeVarF32("ttbar_m"), 25, 350, 1000), ana.NewVariable("DphiLL", ana.TreeVarF64("truth_dphi_ll"), 10, 0, math.Pi), } // Create analyzer object with normalized histograms. analyzer := ana.New(samples, variables, ana.WithHistoNorm(true), ana.WithSavePath("testdata/Plots_multiComponents"), ) // Run the analyzer to produce all the plots if err := analyzer.Run(); err != nil { panic(err) } } var ( fData = "../testdata/file1.root" fBkg1 = "../testdata/file2.root" fBkg2 = "../testdata/file3.root" tName = "truth" )
Output:
Example (ProduceTreesNewVariables) ¶
package main import ( "image/color" "math" "golang.org/x/exp/rand" "gonum.org/v1/gonum/stat/distuv" "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // Sample to process data := ana.CreateSample("data", "data", `Data 18-20`, fData, tName) bkgA := ana.CreateSample("BkgTotA", "bkg", `Total Bkg A`, fBkg1, tName) bkgB := ana.CreateSample("BkgTotB", "bkg", `Total Bkg B`, fBkg2, tName) // Put samples together. samples := []*ana.Sample{data, bkgA, bkgB} // Define variables from the original tree variables := []*ana.Variable{ ana.NewVariable("Mttbar", ana.TreeVarF32("ttbar_m"), 0, 0, 0), ana.NewVariable("DphiLL", ana.TreeVarF64("truth_dphi_ll"), 0, 0, 0), } // Add a new (relarively) complex variable: a smeared ttbar mass by 10% smearedMtt := ana.TreeFunc{ VarsName: []string{"ttbar_m"}, Fct: func(m float32) float64 { return float64(m) * (1.0 + gausDist(0, 0.10).Rand()) }, } variables = append(variables, ana.NewVariable("smearMttbar", smearedMtt, 0, 0, 0)) // Create analyzer object with normalized histograms. analyzer := ana.New(samples, variables, ana.WithDumpTree(true), ana.WithPlotHisto(false), ana.WithSavePath("testdata/Plots_produceTreeNewVar"), ) // Run the analyzer and dump on tree per sample if err := analyzer.Run(); err != nil { panic(err) } // Read back 'data.root' and plot the two variables. newFilePath := "testdata/Plots_produceTreeNewVar/ntuples/data.root" newTreeName := "GOtree" plotter := ana.New( []*ana.Sample{ ana.CreateSample("new", "bkg", `new ntuple`, newFilePath, newTreeName), }, []*ana.Variable{ ana.NewVariable("Mttbar", ana.TreeVarF64("Mttbar"), 50, 0, 1500, ana.WithTickFormats("", "%.0f"), ana.WithAxisLabels("Orignal Mass [GeV]", "Events"), ), ana.NewVariable("smearMttbar", ana.TreeVarF64("smearMttbar"), 50, 0, 1500, ana.WithTickFormats("", "%.0f"), ana.WithAxisLabels("Smeared Mass [GeV]", "Events"), ), }, ana.WithSavePath("testdata/Plots_produceTreeNewVar"), ) if err := plotter.Run(); err != nil { panic(err) } } var ( fData = "../testdata/file1.root" fBkg1 = "../testdata/file2.root" fBkg2 = "../testdata/file3.root" tName = "truth" gausDist = func(mu, sigma float64) distuv.Normal { return distuv.Normal{ Mu: mu, Sigma: sigma, Src: rand.New(rand.NewSource(0)), } } )
Output:
Example (ShapeComparison) ¶
package main import ( "image/color" "math" "golang.org/x/exp/rand" "gonum.org/v1/gonum/stat/distuv" "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // Define samples samples := []*ana.Sample{ ana.CreateSample("data", "data", `Data`, fBkg1, tName), ana.CreateSample("proc1", "bkg", `Simulation A`, fBkg1, tName, ana.WithWeight(w3), ana.WithLineColor(darkBlue), ana.WithLineWidth(2), ana.WithBand(true), ), ana.CreateSample("proc2", "bkg", `Simulation B`, fBkg2, tName, ana.WithWeight(w4), ana.WithLineColor(darkRed), ana.WithLineWidth(2), ana.WithBand(true), ), } // Define variables variables := []*ana.Variable{ ana.NewVariable("TopPt", ana.TreeVarF32("t_pt"), 10, 0, 500), ana.NewVariable("DphiLL", ana.TreeVarF64("truth_dphi_ll"), 10, 0, math.Pi, ana.WithLegLeft(true)), } // Create analyzer object analyzer := ana.New(samples, variables, ana.WithNevtsMax(500), ana.WithHistoStack(false), ana.WithHistoNorm(true), ana.WithRatioPlot(false), ana.WithSavePath("testdata/Plots_shapeComparison"), ) // Run the analyzer to produce all the plots if err := analyzer.Run(); err != nil { panic(err) } } var ( fBkg1 = "../testdata/file2.root" fBkg2 = "../testdata/file3.root" tName = "truth" w3 = ana.TreeFunc{ VarsName: []string{"t_pt"}, Fct: func(pt float32) float64 { return 1.0 + float64(pt)/50. }, } w4 = ana.TreeFunc{ VarsName: []string{"t_pt"}, Fct: func(pt float32) float64 { return 1.0 - float64(pt)/250. }, } darkRed = color.NRGBA{R: 180, G: 30, B: 50, A: 200} darkBlue = color.NRGBA{B: 180, G: 30, R: 50, A: 200} )
Output:
Example (ShapeDistortion) ¶
package main import ( "image/color" "math" "golang.org/x/exp/rand" "gonum.org/v1/gonum/stat/distuv" "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // Selection TreeFunc generator ptTopGT := func(th float32) ana.TreeFunc { return ana.TreeFunc{ VarsName: []string{"t_pt"}, Fct: func(pt float32) bool { return pt > th }, } } // Samples samples := []*ana.Sample{ ana.CreateSample("noCut", "bkg", `No cut`, fBkg1, tName, ana.WithFillColor(shadowBlue), ), ana.CreateSample("cut1", "bkg", `pT>50`, fBkg1, tName, ana.WithCut(ptTopGT(50)), ana.WithLineColor(darkRed), ana.WithLineWidth(2), ), ana.CreateSample("cut2", "bkg", `pT>100`, fBkg1, tName, ana.WithCut(ptTopGT(100)), ana.WithLineColor(darkBlue), ana.WithLineWidth(2), ), ana.CreateSample("cut3", "bkg", `pT>200`, fBkg1, tName, ana.WithCut(ptTopGT(200)), ana.WithLineColor(darkGreen), ana.WithLineWidth(2), ), } // Define variables variables := []*ana.Variable{ ana.NewVariable("Mttbar", ana.TreeVarF32("ttbar_m"), 25, 350, 1500, ana.WithAxisLabels("M(t,t) [GeV]", "PDF"), ), ana.NewVariable("DphiLL", ana.TreeVarF64("truth_dphi_ll"), 10, 0, math.Pi, ana.WithLegLeft(true), ana.WithAxisLabels("dPhi(l,l)", "PDF"), ana.WithYRange(0, 0.3), ), } // Create analyzer object analyzer := ana.New(samples, variables, ana.WithAutoStyle(false), ana.WithHistoStack(false), ana.WithRatioPlot(false), ana.WithHistoNorm(true), ana.WithSavePath("testdata/Plots_shapeDistortion"), ) // Run the analyzer to produce all the plots if err := analyzer.Run(); err != nil { panic(err) } } var ( fBkg1 = "../testdata/file2.root" tName = "truth" shadowBlue = color.NRGBA{R: 50, G: 20, B: 150, A: 20} darkRed = color.NRGBA{R: 180, G: 30, B: 50, A: 200} darkGreen = color.NRGBA{G: 180, R: 30, B: 50, A: 200} darkBlue = color.NRGBA{B: 180, G: 30, R: 50, A: 200} )
Output:
Example (SystematicVariations) ¶
package main import ( "image/color" "math" "golang.org/x/exp/rand" "gonum.org/v1/gonum/stat/distuv" "gonum.org/v1/plot/vg" "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // Samples samples := []*ana.Sample{ ana.CreateSample("nom", "bkg", `Nominal`, fBkg1, tName, ana.WithLineColor(softBlack), ana.WithLineWidth(2.0), ana.WithBand(true), ), ana.CreateSample("up", "bkg", `Up`, fBkg1, tName, ana.WithWeight(w3), ana.WithLineColor(darkRed), ana.WithLineWidth(1.5), ana.WithLineDashes([]vg.Length{3, 2}), ), ana.CreateSample("down", "bkg", `Down`, fBkg1, tName, ana.WithWeight(w4), ana.WithLineColor(darkBlue), ana.WithLineWidth(1.5), ana.WithLineDashes([]vg.Length{3, 2}), ), } // Define variables variables := []*ana.Variable{ ana.NewVariable("Mttbar", ana.TreeVarF32("ttbar_m"), 25, 350, 1500, ana.WithRatioYRange(0.7, 1.3)), ana.NewVariable("DphiLL", ana.TreeVarF64("truth_dphi_ll"), 10, 0, math.Pi, ana.WithRatioYRange(0.7, 1.3), ana.WithYRange(0, 0.2), ana.WithLegLeft(true), ), } // Create analyzer object analyzer := ana.New(samples, variables, ana.WithRatioPlot(true), ana.WithHistoStack(false), ana.WithHistoNorm(true), ana.WithSavePath("testdata/Plots_systVariations"), ) // Run the analyzer to produce all the plots if err := analyzer.Run(); err != nil { panic(err) } } var ( fBkg1 = "../testdata/file2.root" tName = "truth" w3 = ana.TreeFunc{ VarsName: []string{"t_pt"}, Fct: func(pt float32) float64 { return 1.0 + float64(pt)/50. }, } w4 = ana.TreeFunc{ VarsName: []string{"t_pt"}, Fct: func(pt float32) float64 { return 1.0 - float64(pt)/250. }, } softBlack = color.NRGBA{R: 50, G: 30, B: 50, A: 200} darkRed = color.NRGBA{R: 180, G: 30, B: 50, A: 200} darkBlue = color.NRGBA{B: 180, G: 30, R: 50, A: 200} )
Output:
Example (WithJointTrees) ¶
package main import ( "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // File and tree names fNameM, tNameM := "../testdata/fileSlices.root", "modules" fNameJ, tNameJ := "../testdata/fileSlicesJoint.root", "constants" // Samples samples := []*ana.Sample{ ana.CreateSample("HGTD", "bkg", `Minimum Bias`, fNameM, tNameM, ana.WithJointTree(fNameJ, tNameJ), ), } calibHits := ana.TreeFunc{ VarsName: []string{"hits_time_mc", "c_mc_excl_mean"}, Fct: func(ts []float32, c float64) []float64 { res := make([]float64, len(ts)) for i, t := range ts { res[i] = float64(t) - c } return res }, } // Variables variables := []*ana.Variable{ // Variable in the main Tree ana.NewVariable("hitTimes", ana.TreeVarF32s("hits_time_mc"), 100, 10, 15, ana.WithAxisLabels("Uncalibrated times", "Number of Hits"), ), // Variable in the joint Tree ana.NewVariable("calibCon", ana.TreeVarF64("c_mc_excl_mean"), 50, 10, 15, ana.WithAxisLabels("Calibration constants", "Number of Modules"), ), // Newly computed based on both ana.NewVariable("calibHit", calibHits, 100, -2, 3, ana.WithAxisLabels("Calibrated Time", "Number of Hits"), ), } // Analyzer analyzer := ana.New(samples, variables, ana.WithHistoStack(false), ana.WithRatioPlot(false), ana.WithSavePath("testdata/Plots_withJointTrees"), ) // Run the analyzer to produce all the plots if err := analyzer.Run(); err != nil { panic(err) } }
Output:
Example (WithLogScale) ¶
package main import ( "image/color" "math" "golang.org/x/exp/rand" "gonum.org/v1/gonum/stat/distuv" "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // Define samples samples := []*ana.Sample{ ana.CreateSample("data", "data", `Data`, fData, tName), ana.CreateSample("bkg1", "bkg", `Proc 1`, fBkg1, tName, ana.WithWeight(w1)), ana.CreateSample("bkg2", "bkg", `Proc 2`, fBkg2, tName, ana.WithWeight(w2)), ana.CreateSample("bkg3", "bkg", `Proc 3`, fBkg1, tName, ana.WithWeight(w2)), } // Define variables variables := []*ana.Variable{ ana.NewVariable("Mttbar", ana.TreeVarF32("ttbar_m"), 30, 0, 3000, ana.WithAxisLabels("M(t,t) [GeV]", "Events Yields"), ana.WithLogY(true), ), ana.NewVariable("DphiLL", ana.TreeVarF64("truth_dphi_ll"), 10, 0, math.Pi, ana.WithAxisLabels("dPhi(l,l)", "Events Yields"), ana.WithLegLeft(true), ana.WithLogY(true), ), } // Create analyzer object analyzer := ana.New(samples, variables, ana.WithSavePath("testdata/Plots_LogScale"), ana.WithHistoStack(true), ) // Run the analyzer to produce all the plots if err := analyzer.Run(); err != nil { panic(err) } } var ( fData = "../testdata/file1.root" fBkg1 = "../testdata/file2.root" fBkg2 = "../testdata/file3.root" tName = "truth" w1 = ana.TreeValF64(1.0) w2 = ana.TreeValF64(0.5) )
Output:
Example (WithSignals) ¶
package main import ( "image/color" "math" "golang.org/x/exp/rand" "gonum.org/v1/gonum/stat/distuv" "gonum.org/v1/plot/vg" "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // Define samples samples := []*ana.Sample{ ana.CreateSample("data", "data", `Data`, fData, tName), ana.CreateSample("bkg1", "bkg", `Proc 1`, fBkg1, tName, ana.WithWeight(w1)), ana.CreateSample("bkg2", "bkg", `Proc 2`, fBkg2, tName, ana.WithWeight(w2)), ana.CreateSample("bkg3", "bkg", `Proc 3`, fBkg1, tName, ana.WithWeight(w2)), ana.CreateSample("sig1", "sig", `Sig 1`, fBkg2, tName, ana.WithWeight(wSigM(500, 0.04)), ana.WithLineColor(darkRed), ana.WithLineDashes([]vg.Length{2, 3, 2}), ana.WithLineWidth(3), ), ana.CreateSample("sig2", "sig", `Sig 2`, fBkg2, tName, ana.WithWeight(wSigM(650, 0.02)), ana.WithLineColor(darkGreen), ana.WithLineDashes([]vg.Length{1, 1, 1}), ana.WithLineWidth(3), ), ana.CreateSample("sig3", "sig", `Sig 2`, fBkg2, tName, ana.WithWeight(wSigM(800, 0.01)), ana.WithLineColor(darkBlue), ana.WithLineDashes([]vg.Length{3, 3, 3}), ana.WithLineWidth(3), ), } // Define variables variables := []*ana.Variable{ ana.NewVariable("Mttbar", ana.TreeVarF32("ttbar_m"), 100, 350, 1000, ana.WithAxisLabels("M(t,t) [GeV]", "Events Yields"), ), ana.NewVariable("DphiLL", ana.TreeVarF64("truth_dphi_ll"), 10, 0, math.Pi, ana.WithAxisLabels("dPhi(l,l)", "Events Yields"), ana.WithLegLeft(true)), } // Create analyzer object analyzer := ana.New(samples, variables, ana.WithSavePath("testdata/Plots_withSignals"), ) // Run the analyzer to produce all the plots if err := analyzer.Run(); err != nil { panic(err) } } var ( fData = "../testdata/file1.root" fBkg1 = "../testdata/file2.root" fBkg2 = "../testdata/file3.root" tName = "truth" w1 = ana.TreeValF64(1.0) w2 = ana.TreeValF64(0.5) wSigM = func(mass, relWidth float32) ana.TreeFunc { return ana.TreeFunc{ VarsName: []string{"ttbar_m"}, Fct: func(m float32) float64 { dM2 := float64((m - mass) * (m - mass)) sigma2 := float64(mass * relWidth * mass * relWidth) return 50 * 1 / float64(mass*relWidth) * math.Exp(-dM2/sigma2) }, } } darkRed = color.NRGBA{R: 180, G: 30, B: 50, A: 200} darkGreen = color.NRGBA{G: 180, R: 30, B: 50, A: 200} darkBlue = color.NRGBA{B: 180, G: 30, R: 50, A: 200} )
Output:
Example (WithSignalsStacked) ¶
package main import ( "image/color" "math" "golang.org/x/exp/rand" "gonum.org/v1/gonum/stat/distuv" "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // Define samples samples := []*ana.Sample{ ana.CreateSample("data", "data", `Data`, fData, tName, ana.WithCircleSize(2.8), ana.WithYErrBarsCapWidth(0.01), ), ana.CreateSample("bkg1", "bkg", `Proc 1`, fBkg1, tName, ana.WithWeight(w1)), ana.CreateSample("bkg2", "bkg", `Proc 2`, fBkg2, tName, ana.WithWeight(w2)), ana.CreateSample("bkg3", "bkg", `Proc 3`, fBkg1, tName, ana.WithWeight(w2)), ana.CreateSample("sig1", "sig", `Sig 1`, fBkg2, tName, ana.WithWeight(wSigM(500, 0.04))), ana.CreateSample("sig2", "sig", `Sig 2`, fBkg2, tName, ana.WithWeight(wSigM(650, 0.02))), ana.CreateSample("sig3", "sig", `Sig 2`, fBkg2, tName, ana.WithWeight(wSigM(800, 0.01))), } // Define variables variables := []*ana.Variable{ ana.NewVariable("Mttbar", ana.TreeVarF32("ttbar_m"), 100, 350, 1000, ana.WithAxisLabels("M(t,t) [GeV]", "Events Yields"), ), ana.NewVariable("DphiLL", ana.TreeVarF64("truth_dphi_ll"), 10, 0, math.Pi, ana.WithAxisLabels("dPhi(l,l)", "Events Yields"), ana.WithLegLeft(true)), } // Create analyzer object analyzer := ana.New(samples, variables, ana.WithSignalStack(true), ana.WithSavePath("testdata/Plots_withStackedSignals"), ) // Run the analyzer to produce all the plots if err := analyzer.Run(); err != nil { panic(err) } } var ( fData = "../testdata/file1.root" fBkg1 = "../testdata/file2.root" fBkg2 = "../testdata/file3.root" tName = "truth" w1 = ana.TreeValF64(1.0) w2 = ana.TreeValF64(0.5) wSigM = func(mass, relWidth float32) ana.TreeFunc { return ana.TreeFunc{ VarsName: []string{"ttbar_m"}, Fct: func(m float32) float64 { dM2 := float64((m - mass) * (m - mass)) sigma2 := float64(mass * relWidth * mass * relWidth) return 50 * 1 / float64(mass*relWidth) * math.Exp(-dM2/sigma2) }, } } )
Output:
Example (WithSliceVariables) ¶
package main import ( "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // File and tree names fName, tName := "../testdata/fileSlices.root", "modules" // Samples samples := []*ana.Sample{ ana.CreateSample("HGTD", "bkg", `w/o calib.`, fName, tName), } // Variables variables := []*ana.Variable{ ana.NewVariable("hitTimes", ana.TreeVarF32s("hits_time_mc"), 100, 10, 15), } // Analyzer analyzer := ana.New(samples, variables, ana.WithHistoStack(false), ana.WithRatioPlot(false), ana.WithSavePath("testdata/Plots_withSliceVariables"), ) // Run the analyzer to produce all the plots if err := analyzer.Run(); err != nil { panic(err) } }
Output:
Example (WithTreeDumping) ¶
package main import ( "image/color" "math" "golang.org/x/exp/rand" "gonum.org/v1/gonum/stat/distuv" "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // Weights and cuts w := ana.TreeVarF32("weight") isQQ := ana.TreeCutBool("init_qq") // Data sample. data := ana.NewSample("data", "data", `Data 18-20`) data.AddComponent(fData, tName) data.AddComponent(fBkg1, tName) // Background A sample including three components. bkgA := ana.NewSample("BkgTotA", "bkg", `Total Bkg A`, ana.WithWeight(w)) bkgA.AddComponent(fBkg1, tName) bkgA.AddComponent(fBkg2, tName) bkgA.AddComponent(fBkg1, tName, ana.WithCut(isQQ)) // Background B sample including two components. bkgB := ana.NewSample("BkgTotB", "bkg", `Total Bkg B`, ana.WithWeight(w)) bkgB.AddComponent(fBkg1, tName) bkgB.AddComponent(fBkg2, tName) // Put samples together. samples := []*ana.Sample{data, bkgA, bkgB} // Define variables variables := []*ana.Variable{ ana.NewVariable("Mttbar", ana.TreeVarF32("ttbar_m"), 25, 350, 1000), ana.NewVariable("DphiLL", ana.TreeVarF64("truth_dphi_ll"), 10, 0, math.Pi), } // Define some selections selections := []*ana.Selection{ ana.NewSelection("LowM", cutMlt500), ana.NewSelection("HighM", cutMgt500), } // Create analyzer object with normalized histograms. analyzer := ana.New(samples, variables, ana.WithKinemCuts(selections), ana.WithDumpTree(true), ana.WithSavePath("testdata/Plots_withTreeDumping"), ) // Run the analyzer to produce all the plots if err := analyzer.Run(); err != nil { panic(err) } } var ( fData = "../testdata/file1.root" fBkg1 = "../testdata/file2.root" fBkg2 = "../testdata/file3.root" tName = "truth" cutMlt500 = ana.TreeFunc{ VarsName: []string{"ttbar_m"}, Fct: func(m float32) bool { return m < 500 }, } cutMgt500 = ana.TreeFunc{ VarsName: []string{"ttbar_m"}, Fct: func(m float32) bool { return m >= 500 }, } )
Output:
Index ¶
- type Maker
- type Options
- func WithAutoStyle(b bool) Options
- func WithCompileLatex(b bool) Options
- func WithDumpTree(b bool) Options
- func WithHistoNorm(b bool) Options
- func WithHistoStack(b bool) Options
- func WithKinemCuts(c []*Selection) Options
- func WithLumi(l float64) Options
- func WithNevtsMax(n int64) Options
- func WithPlotHisto(b bool) Options
- func WithPlotTitle(t string) Options
- func WithRatioPlot(b bool) Options
- func WithSampleMT(b bool) Options
- func WithSaveFormat(f string) Options
- func WithSavePath(p string) Options
- func WithSignalStack(b bool) Options
- func WithTotalBand(b bool) Options
- func WithTotalBandColor(c color.NRGBA) Options
- type Sample
- type SampleOptions
- func WithBand(b bool) SampleOptions
- func WithBandColor(c color.NRGBA) SampleOptions
- func WithCircleColor(c color.NRGBA) SampleOptions
- func WithCircleMarkers(b bool) SampleOptions
- func WithCircleSize(s vg.Length) SampleOptions
- func WithCut(f TreeFunc) SampleOptions
- func WithDataStyle(b bool) SampleOptions
- func WithFillColor(c color.NRGBA) SampleOptions
- func WithJointTree(fname, tname string) SampleOptions
- func WithLineColor(c color.NRGBA) SampleOptions
- func WithLineDashes(s []vg.Length) SampleOptions
- func WithLineWidth(w vg.Length) SampleOptions
- func WithNgen(n float64) SampleOptions
- func WithWeight(f TreeFunc) SampleOptions
- func WithXsec(s float64) SampleOptions
- func WithYErrBars(b bool) SampleOptions
- func WithYErrBarsCapWidth(w vg.Length) SampleOptions
- func WithYErrBarsLineWidth(w vg.Length) SampleOptions
- type Selection
- type TreeFunc
- func TreeCutBool(v string) TreeFunc
- func TreeValF64(v float64) TreeFunc
- func TreeVarBool(v string) TreeFunc
- func TreeVarF32(v string) TreeFunc
- func TreeVarF32s(v string) TreeFunc
- func TreeVarF64(v string) TreeFunc
- func TreeVarF64s(v string) TreeFunc
- func TreeVarI32(v string) TreeFunc
- func TreeVarI32s(v string) TreeFunc
- func TreeVarI64(v string) TreeFunc
- func TreeVarI64s(v string) TreeFunc
- func (f *TreeFunc) FuncFormula() rfunc.Formula
- func (f *TreeFunc) GetFuncBool(r *rtree.Reader) (func() bool, bool)
- func (f *TreeFunc) GetFuncF64(r *rtree.Reader) (func() float64, bool)
- func (f *TreeFunc) GetFuncF64s(r *rtree.Reader) (func() []float64, bool)
- func (f *TreeFunc) IsSlow() bool
- func (f *TreeFunc) TreeFormulaFrom(r *rtree.Reader) rfunc.Formula
- type Variable
- type VariableOptions
- func WithAxisLabels(xlab, ylab string) VariableOptions
- func WithLegLeft(left bool) VariableOptions
- func WithLegTop(top bool) VariableOptions
- func WithLogY(b bool) VariableOptions
- func WithRatioYRange(min, max float64) VariableOptions
- func WithSaveName(n string) VariableOptions
- func WithTickFormats(xticks, yticks string) VariableOptions
- func WithXRange(min, max float64) VariableOptions
- func WithYRange(min, max float64) VariableOptions
Examples ¶
- Package (ASimpleUseCase)
- Package (MultiComponentSamples)
- Package (ProduceTreesNewVariables)
- Package (ShapeComparison)
- Package (ShapeDistortion)
- Package (SystematicVariations)
- Package (WithJointTrees)
- Package (WithKinemCuts)
- Package (WithLogScale)
- Package (WithSignals)
- Package (WithSignalsStacked)
- Package (WithSliceVariables)
- Package (WithTreeDumping)
- NewVariable
- Sample (MultiComponents)
- Sample (SingleComponent)
- Sample (WithCut)
- Sample (WithWeight)
- TreeFunc (General)
- TreeFunc (WithBranchBoolForCut)
- TreeFunc (WithBranchBoolForPlot)
- TreeFunc (WithBranchF32s)
- TreeFunc (WithBranchF64)
- TreeFunc (WithNumericalValue)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Maker ¶
type Maker struct { // Inputs Samples []*Sample // List of samples on which to run. Variables []*Variable // List of variables to plot. KinemCuts []*Selection // List of cuts to apply (default: no cut). NevtsMax int64 // Maximum event number per components (default: -1), Lumi float64 // Integrated luminosity en 1/fb (default: 1/pb). SampleMT bool // Enable concurency accross samples (default: true). // Ouputs SavePath string // Path to which plot will be saved (default: 'outputs'). SaveFormat string // Plot file extension: 'png' (default), 'pdf' or 'png'. CompileLatex bool // On-the-fly latex compilation (default: true). DumpTree bool // Dump a TTree in a file for each sample (default: false). PlotHisto bool // Enable histogram plotting (default: true). // Plots AutoStyle bool // Enable automatic styling (default: true). PlotTitle string // General plot title (default: 'TTree GOnalyzer'). HistoStack bool // Enable histogram stacking (default: true). SignalStack bool // Enable signal stack (default: false). HistoNorm bool // Normalize distributions to unit area (default: false). TotalBand bool // Enable total error band in stack mode (default: true). TotalBandColor color.NRGBA // Color for the uncertainty band (default: gray). // Enable ratio plot (default: true). // If stack is on, the ratio is defined as data over total bkg. // If stack is off, ratios are defined as sample[i] / data when // a data sample is defined, sample[i] / sample[0] otherwise. RatioPlot bool // contains filtered or unexported fields }
Analysis maker type is the main object of the ana package. It contains all samples and variables on which to loop to produce and plot histograms. Several options can be specified to normalize and/or stack histograms, add a ratio plot, or a list of kinematic selections.
func (*Maker) Normalizations ¶
Helper function computing the normalisation of of all samples for a given cut
func (*Maker) PlotVariables ¶
PlotVariables loops over all filled histograms and produce one plot for each variable and selection, including all sample histograms.
func (Maker) PrintReport ¶
func (ana Maker) PrintReport()
PrintReport prints some general information about the number of processed samples, events and produced histograms.
func (*Maker) PrintSlowTreeFuncs ¶
func (ana *Maker) PrintSlowTreeFuncs()
PrintSlowTreeFuncs prints the list of TreeFunc which relies on a generic groot/rfunc formula, ie based on 'reflect' calls. These function are ~ 5 times slower than the one defined using this example https://godoc.org/go-hep.org/x/hep/groot/rtree#example-Reader--WithFormulaFromUser
func (*Maker) Run ¶
Run performs the three steps in one function: fill histos, plot histos and print report.
func (*Maker) RunEventLoops ¶
RunEventLoops runs one event loop per sample to fill histograms for each variables and selections. If DumpTree is true, a tree is also dumped with all variables and one branch per selection.
func (*Maker) RunTimePerKEvts ¶
RunTimePerKEvts returns the running time in millisecond per kEvents.
type Options ¶
type Options func(cfg *config)
Options encodes the various settings to pass to an analysis, ie a Maker, as arguments of ana.New().
func WithAutoStyle ¶
WithAutoStyle enables automatic styling of the histograms.
func WithCompileLatex ¶
WithCompileLatex enables automatic latex compilation.
func WithDumpTree ¶
WithDumpTree enables tree dumping (one per sample).
func WithHistoNorm ¶
WithHistoNorm enables histogram normalization to unity.
func WithHistoStack ¶
WithHistoStack enables histogram stacking for bkg-typed samples.
func WithKinemCuts ¶
WithKinemCuts sets the list of kinematic cuts to run on.
func WithLumi ¶
WithLumi sets the integrated luminosity in fb-1. The full normalisation factor is (xsec*lumi)/ngen. 'ngen' and 'xsec' are given for each sample/component, via ana.CreateSample() or s.AddComponent(). While the 'lumi' is given to via ana.New(). By default, lumi = 1000/fb (=1/pb).
func WithNevtsMax ¶
WithNevtsMax sets the maximum processed event for each sample component. If n[sample]<n, the tool will run n[sample] events for this sample.
func WithPlotHisto ¶
WithPlotHisto enables histogram plotting. It can be set to false to only dump trees.
func WithPlotTitle ¶
WithPlotTitle sets the general plot title.
func WithSampleMT ¶
WithSampleMT enables a concurent sample processing.
func WithSaveFormat ¶
WithSaveFormat sets the format for the plots.
func WithSignalStack ¶
WithSignalStack enables histogram stacking for bkg-typed samples.
func WithTotalBand ¶
WithHistoStack enables histogram stacking for bkg-typed samples.
func WithTotalBandColor ¶
WithTotalBandColor sets the color for the error band of total histogram (and ratio).
type Sample ¶
type Sample struct { // General settings Name string // Sample name. Type string // Sample type: 'data', 'bkg' or 'sig'. LegLabel string // Label used in the legend. // Gobal weight and cut (applied to all components). CutFunc TreeFunc WeightFunc TreeFunc // Cosmetic settings DataStyle bool // Enable data-like style (default: Type == 'data'). LineColor color.NRGBA // Line color of the histogram (default: blue). LineWidth vg.Length // Line width of the histogram (default: 1.5). LineDashes []vg.Length // Line dashes format (default: continous). FillColor color.NRGBA // Fill color of the histogram (default: none). CircleMarkers bool // Enable circle markers (default: false). CircleSize vg.Length // Circle size (default: 0). CircleColor color.NRGBA // Circle color (default: transparent). Band bool // Enable error band display. BandColor color.NRGBA // Circle color (default: gray). YErrBars bool // Display error bars (default: false || DataStyle). YErrBarsLineWidth vg.Length // Width of error bars line. YErrBarsCapWidth vg.Length // Width of horizontal bars of the error bars. // contains filtered or unexported fields }
Sample contains all the information defining a single histogram of the final plot. A sample is made of (potentially) several components, or sub-sample. Each component can have different file/tree names, as well as additional cuts and weights, on top of the global ones. Concretly, the global cut is combined with the component cut with a AND, while weights are multiplied.
Example (MultiComponents) ¶
package main import ( "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // Declare weights and cuts wGlobal := ana.TreeVarF64("evtWeight") // evtWeight is float64 branch wBljets := ana.TreeValF64(0.30) cIsHadr := ana.TreeCutBool("isHadronic") // isHadronic is boolean branch // ttbar background starting with an empty sample with a global weight ttbarIncl := ana.NewSample("ttbar", "bkg", `Inclusive`, ana.WithWeight(wGlobal)) // Adding dilepont decay ttbarIncl.AddComponent("dilep.root", "mytree") // Adding l+jets decay, weighted by BR(ttbar->l+jets) ttbarIncl.AddComponent("ljets.root", "mytree", ana.WithWeight(wBljets)) // Adding full hadronic decay, applying a cut to make sure of the decay ttbarIncl.AddComponent("fullhad.root", "mytree", ana.WithCut(cIsHadr)) }
Output:
Example (SingleComponent) ¶
package main import ( "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // Data sample sData := ana.CreateSample("DATA", "data", `pp data`, "myfile.root", "mytree") // Background sample, say QCD pp->ttbar production sBkg := ana.CreateSample("ttbar", "bkg", `QCD prod.`, "myfile.root", "mytree") // Signal sample, say pp->H->ttbar production sSig := ana.CreateSample("Htt", "sig", `Higgs prod.`, "myfile.root", "mytree") // New analysis ana.New([]*ana.Sample{sData, sBkg, sSig}, []*ana.Variable{}) }
Output:
Example (WithCut) ¶
package main import ( "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // Selection criteria computed from several branches sel := ana.TreeFunc{ VarsName: []string{"pt", "eta", "m"}, Fct: func(pt, eta, m float64) bool { return (pt > 150 && eta > 0) || m < 125 }, } // Sample with computed boolean ana.CreateSample("proc", "bkg", `leg`, "myfile.root", "mytree", ana.WithCut(sel), ) // Sample with single branch boolean ana.CreateSample("proc", "bkg", `leg`, "myfile.root", "mytree", ana.WithCut(ana.TreeCutBool("passCriteria")), ) }
Output:
Example (WithWeight) ¶
package main import ( "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // Weight computed from several branches w := ana.TreeFunc{ VarsName: []string{"w1", "w2", "w3"}, Fct: func(w1, w2, w3 float64) float64 { return w1 * w2 * w3 }, } // Sample with computed weight ana.CreateSample("proc", "bkg", `leg`, "myfile.root", "mytree", ana.WithWeight(w), ) // Sample with single branch weight ana.CreateSample("proc", "bkg", `leg`, "myfile.root", "mytree", ana.WithWeight(ana.TreeVarF64("evtWght")), ) }
Output:
func CreateSample ¶
func CreateSample(sname, stype, sleg, fname, tname string, opts ...SampleOptions) *Sample
CreateSample creates a non-empty sample having the default settings, with only one component. This function is a friendly API to ease single-component samples declaration. For multi-component samples, one can either add components on top with s.AddComponent(...), or start from an empty sample using NewSample(...) followed by few s.AddComponent(...).
func NewSample ¶
func NewSample(sname, stype, sleg string, opts ...SampleOptions) *Sample
NewSample creates a new empty sample, ie without any components, with the default options. Components can be then added using s.AddComponent(...) function.
func (*Sample) AddComponent ¶
func (s *Sample) AddComponent(fname, tname string, opts ...SampleOptions)
AddComponent adds a new component (ie file and tree) to the sample. A additional cut and weight can be applied to the added component only. The component cut is combined with the global cut using a AND, while the component weight is multiplied with the global weight.
func (Sample) CreateHisto ¶
CreateHisto returns a hplot.H1D with the sample style.
type SampleOptions ¶
type SampleOptions func(cfg *config)
SampleOptions encodes the various settings to pass to a Sample type, as arguments of ana.NewSample().
func WithBandColor ¶
func WithBandColor(c color.NRGBA) SampleOptions
WithBandColor sets the color of the sample error band.
func WithCircleColor ¶
func WithCircleColor(c color.NRGBA) SampleOptions
WithCircleColor sets the color of circle markers.
func WithCircleMarkers ¶
func WithCircleMarkers(b bool) SampleOptions
WithCircleMarkers enables the use of circle markers (as for data histogram).
func WithCircleSize ¶
func WithCircleSize(s vg.Length) SampleOptions
WithCircleSize sets the size of circle markers.
func WithCut ¶
func WithCut(f TreeFunc) SampleOptions
WithCut sets the cut to be applied to the sample, as defined by the TreeFunc f, which must return a bool. Maker.FillHisto() will panic otherwise.
func WithDataStyle ¶
func WithDataStyle(b bool) SampleOptions
WithDataStyle enables the default data histogram style.
func WithFillColor ¶
func WithFillColor(c color.NRGBA) SampleOptions
WithFillColor sets the color with which the histo will be filled.
func WithJointTree ¶
func WithJointTree(fname, tname string) SampleOptions
WithJointTree adds a tree to be joint for this sample/component. Branches of joint tree are added to the list of available variables. Several joint trees can be added using WithJointTree() option several times.
func WithLineColor ¶
func WithLineColor(c color.NRGBA) SampleOptions
WithLineColor sets the line color of the histogram.
func WithLineDashes ¶
func WithLineDashes(s []vg.Length) SampleOptions
WithLineWidth sets line width of the sample histogram.
func WithLineWidth ¶
func WithLineWidth(w vg.Length) SampleOptions
WithLineWidth sets line width of the sample histogram.
func WithNgen ¶
func WithNgen(n float64) SampleOptions
WithNgen sets the total number of generated events for the sample/component. The full normalisation factor is (xsec*lumi)/ngen. 'ngen' and 'xsec' are given by sample/component while 'lumi' is given to via ana.New(). By default, Ngen = 1. This option cannot be passed to a sample (or component) of type "data".
func WithWeight ¶
func WithWeight(f TreeFunc) SampleOptions
WithWeight sets the weight to be used for this sample, as defined by the TreeFunc f, which must return a float64. Maker.FillHisto() will panic otherwise.
func WithXsec ¶
func WithXsec(s float64) SampleOptions
WithXsec sets the cross-section in pb to the sample/component. The full normalisation factor is (xsec*lumi)/ngen. 'ngen' and 'xsec' are given by sample/component while 'lumi' is given to via ana.New(). By default, xsec = 1 pb. This option cannot be passed to a sample (or component) of type "data".
func WithYErrBarsCapWidth ¶
func WithYErrBarsCapWidth(w vg.Length) SampleOptions
WithYErrBarsCapsWidth sets the width of the y error bars caps.
func WithYErrBarsLineWidth ¶
func WithYErrBarsLineWidth(w vg.Length) SampleOptions
WithYErrBarsLineWidth sets the width of the error bars line
type Selection ¶
The returned type of TreeFunc must be a boolean.
func EmptySelection ¶
func EmptySelection() *Selection
EmptySelection returns an empty selection type, i.e. without name (empty string) and returning always true.
func NewSelection ¶
NewSelection returns a selection with the specified name and TreeFunc fct. Fct must return a boolean.
type TreeFunc ¶
type TreeFunc struct { VarsName []string // List of branch names, being function arguments Fct interface{} // User-defined function Formula rfunc.Formula // Formula that can be bound to a ROOT tree }
TreeFunc is a wrapper to use rtree.Formula in an easy way. It provides a set of functions to ease the simple cases of boolean, float32 and float64 branches.
Once the slice of variable (branch) names and the function are given, one can either access the rtree.Formula or directly the GO function to be called in the event loop for boolean, float32 and float64.
Except `TreeCutBool()`, all `NewXXX()` functions lead to a treeFunc.Fct returning a float64 a or []float64 in order to be accpeted by hplot.h1d.Fill(v, w) method. Instead `TreeCutBool()` lead to a treeFunc.Fct returning a bool, specifically for cuts.
Example (General) ¶
package main import ( "fmt" "log" "go-hep.org/x/hep/groot" "go-hep.org/x/hep/groot/rtree" "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // Get a reader for the example f, r := getReader(5) defer f.Close() defer r.Close() // TreeFunc object computing t_pt*t_eta treeFunc := ana.TreeFunc{ VarsName: []string{"t_pt", "t_eta"}, Fct: func(pt, eta float32) float64 { fmt.Printf("pt=%.2f, eta=%.2f,", pt, eta) return float64(pt * eta) }, } // Get the rtree.Formula object formula := treeFunc.TreeFormulaFrom(r) // Go function to be called in the event loop getValue := formula.Func().(func() float64) // Event loop r.Read(func(ctx rtree.RCtx) error { fmt.Printf(" pt*eta=%.2f\n", getValue()) return nil }) } // Helper function get a reader (w/o slices) for the examples func getReader(nmax int64) (*groot.File, *rtree.Reader) { return getReaderFile("../testdata/file1.root", "truth", nmax) } // Helper function to get a tree tname from a file fname. func getReaderFile(fname, tname string, nmax int64) (*groot.File, *rtree.Reader) { f, err := groot.Open(fname) if err != nil { log.Fatal("example_treefunc_test.go: could not open "+fname+": %w", err) } obj, err := f.Get(tname) if err != nil { log.Fatal("could not retrieve object: %w", err) } t := obj.(rtree.Tree) r, err := rtree.NewReader(t, []rtree.ReadVar{}, rtree.WithRange(0, nmax)) if err != nil { log.Fatal("could not create tree reader: %w", err) } return f, r }
Output: pt=145.13, eta=-2.08, pt*eta=-302.15 pt=13.85, eta=-1.69, pt*eta=-23.35 pt=44.03, eta=-3.93, pt*eta=-173.06 pt=136.98, eta=0.64, pt*eta=87.88 pt=77.47, eta=2.93, pt*eta=226.79
Example (WithBranchBoolForCut) ¶
package main import ( "fmt" "log" "go-hep.org/x/hep/groot" "go-hep.org/x/hep/groot/rtree" "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // Get a reader for the example f, r := getReader(5) defer f.Close() defer r.Close() // TreeFunc object from a boolean branch name in the TTree // The return type is boolean, since it's for a cut. treeFunc := ana.TreeCutBool("init_qq") // Go function to be called in the event loop getTreeFuncVal, ok := treeFunc.GetFuncBool(r) if !ok { log.Fatal("type assertion failed: expect bool") } // rtree.Formula object formula := treeFunc.TreeFormulaFrom(r) getFormulaVal := formula.Func().(func() bool) // Event loop r.Read(func(ctx rtree.RCtx) error { vTreeFunc := getTreeFuncVal() vFormula := getFormulaVal() fmt.Printf("%v %v %v\n", ctx.Entry, vTreeFunc, vFormula) return nil }) } // Helper function get a reader (w/o slices) for the examples func getReader(nmax int64) (*groot.File, *rtree.Reader) { return getReaderFile("../testdata/file1.root", "truth", nmax) } // Helper function to get a tree tname from a file fname. func getReaderFile(fname, tname string, nmax int64) (*groot.File, *rtree.Reader) { f, err := groot.Open(fname) if err != nil { log.Fatal("example_treefunc_test.go: could not open "+fname+": %w", err) } obj, err := f.Get(tname) if err != nil { log.Fatal("could not retrieve object: %w", err) } t := obj.(rtree.Tree) r, err := rtree.NewReader(t, []rtree.ReadVar{}, rtree.WithRange(0, nmax)) if err != nil { log.Fatal("could not create tree reader: %w", err) } return f, r }
Output: 0 false false 1 false false 2 true true 3 false false 4 false false
Example (WithBranchBoolForPlot) ¶
package main import ( "fmt" "log" "go-hep.org/x/hep/groot" "go-hep.org/x/hep/groot/rtree" "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // Get a reader for the example f, r := getReader(5) defer f.Close() defer r.Close() // TreeFunc object from a boolean branch name in the TTree treeFunc := ana.TreeVarBool("init_qq") // Go function to be called in the event loop // The return type is float64, since it's for plotting. getTreeFuncVal, ok := treeFunc.GetFuncF64(r) if !ok { log.Fatal("type assertion failed: expect float64") } // rtree.Formula object formula := treeFunc.TreeFormulaFrom(r) getFormulaVal := formula.Func().(func() float64) // Event loop r.Read(func(ctx rtree.RCtx) error { vTreeFunc := getTreeFuncVal() vFormula := getFormulaVal() fmt.Printf("%v %v %v\n", ctx.Entry, vTreeFunc, vFormula) return nil }) } // Helper function get a reader (w/o slices) for the examples func getReader(nmax int64) (*groot.File, *rtree.Reader) { return getReaderFile("../testdata/file1.root", "truth", nmax) } // Helper function to get a tree tname from a file fname. func getReaderFile(fname, tname string, nmax int64) (*groot.File, *rtree.Reader) { f, err := groot.Open(fname) if err != nil { log.Fatal("example_treefunc_test.go: could not open "+fname+": %w", err) } obj, err := f.Get(tname) if err != nil { log.Fatal("could not retrieve object: %w", err) } t := obj.(rtree.Tree) r, err := rtree.NewReader(t, []rtree.ReadVar{}, rtree.WithRange(0, nmax)) if err != nil { log.Fatal("could not create tree reader: %w", err) } return f, r }
Output: 0 0 0 1 0 0 2 1 1 3 0 0 4 0 0
Example (WithBranchF32s) ¶
package main import ( "fmt" "log" "go-hep.org/x/hep/groot" "go-hep.org/x/hep/groot/rtree" "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // Get a reader for the example f, r := getReaderWithSlices(5) defer f.Close() defer r.Close() // TreeFunc object from a []float32 branch name in the TTree. // The return type is []float64. treeFunc := ana.TreeVarF32s("hits_time_mc") // Go function to be called in the event loop getTreeFuncVal, ok := treeFunc.GetFuncF64s(r) if !ok { log.Fatal("type assertion failed: expect []float64") } // rtree.Formula object formula := treeFunc.TreeFormulaFrom(r) getFormulaVal := formula.Func().(func() []float64) // Event loop r.Read(func(ctx rtree.RCtx) error { vTreeFunc := getTreeFuncVal() vFormula := getFormulaVal() fmt.Printf("Evt[%v]\n -> %v\n -> %v\n\n", ctx.Entry, vTreeFunc[:5], vFormula[:5]) return nil }) } // Helper function get a reader with slices for the examples func getReaderWithSlices(nmax int64) (*groot.File, *rtree.Reader) { return getReaderFile("../testdata/fileSlices.root", "modules", nmax) } // Helper function to get a tree tname from a file fname. func getReaderFile(fname, tname string, nmax int64) (*groot.File, *rtree.Reader) { f, err := groot.Open(fname) if err != nil { log.Fatal("example_treefunc_test.go: could not open "+fname+": %w", err) } obj, err := f.Get(tname) if err != nil { log.Fatal("could not retrieve object: %w", err) } t := obj.(rtree.Tree) r, err := rtree.NewReader(t, []rtree.ReadVar{}, rtree.WithRange(0, nmax)) if err != nil { log.Fatal("could not create tree reader: %w", err) } return f, r }
Output: Evt[0] -> [12.206398963928223 11.711121559143066 11.734919548034668 12.457039833068848 11.558056831359863] -> [12.206398963928223 11.711121559143066 11.734919548034668 12.457039833068848 11.558056831359863] Evt[1] -> [11.718018531799316 12.985346794128418 12.231209754943848 11.825081825256348 12.405976295471191] -> [11.718018531799316 12.985346794128418 12.231209754943848 11.825081825256348 12.405976295471191] Evt[2] -> [12.231328964233398 12.214682579040527 12.194867134094238 12.246091842651367 11.859249114990234] -> [12.231328964233398 12.214682579040527 12.194867134094238 12.246091842651367 11.859249114990234] Evt[3] -> [11.33843994140625 11.725604057312012 12.774130821228027 12.108593940734863 12.192085266113281] -> [11.33843994140625 11.725604057312012 12.774130821228027 12.108593940734863 12.192085266113281] Evt[4] -> [12.156414031982422 12.641215324401855 11.678815841674805 12.329707145690918 11.578168869018555] -> [12.156414031982422 12.641215324401855 11.678815841674805 12.329707145690918 11.578168869018555]
Example (WithBranchF64) ¶
package main import ( "fmt" "log" "go-hep.org/x/hep/groot" "go-hep.org/x/hep/groot/rtree" "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // Get a reader for the example f, r := getReader(5) defer f.Close() defer r.Close() // TreeFunc object from a float64 branch name in the TTree. // The return type is []float64. treeFunc := ana.TreeVarF64("truth_dphi_ll") // Go function to be called in the event loop getTreeFuncVal, ok := treeFunc.GetFuncF64(r) if !ok { log.Fatal("type assertion failed: expect float64") } // rtree.Formula object formula := treeFunc.TreeFormulaFrom(r) getFormulaVal := formula.Func().(func() float64) // Event loop r.Read(func(ctx rtree.RCtx) error { vTreeFunc := getTreeFuncVal() vFormula := getFormulaVal() fmt.Printf("%v %.2f %.2f\n", ctx.Entry, vTreeFunc, vFormula) return nil }) } // Helper function get a reader (w/o slices) for the examples func getReader(nmax int64) (*groot.File, *rtree.Reader) { return getReaderFile("../testdata/file1.root", "truth", nmax) } // Helper function to get a tree tname from a file fname. func getReaderFile(fname, tname string, nmax int64) (*groot.File, *rtree.Reader) { f, err := groot.Open(fname) if err != nil { log.Fatal("example_treefunc_test.go: could not open "+fname+": %w", err) } obj, err := f.Get(tname) if err != nil { log.Fatal("could not retrieve object: %w", err) } t := obj.(rtree.Tree) r, err := rtree.NewReader(t, []rtree.ReadVar{}, rtree.WithRange(0, nmax)) if err != nil { log.Fatal("could not create tree reader: %w", err) } return f, r }
Output: 0 2.99 2.99 1 1.07 1.07 2 3.03 3.03 3 0.07 0.07 4 2.35 2.35
Example (WithNumericalValue) ¶
Example showing how to load a numerical value in a TreeFunc. The reason why this approach exists is to be able to pass a simple constant to a sample, using the same API ana.With.Weight(f TreeFunc).
package main import ( "fmt" "log" "go-hep.org/x/hep/groot" "go-hep.org/x/hep/groot/rtree" "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // Get a reader for the example f, r := getReader(5) defer f.Close() defer r.Close() // TreeFunc object from a float64 treeFunc := ana.TreeValF64(0.33) // Go function to be called in the event loop getTreeFuncVal, ok := treeFunc.GetFuncF64(r) if !ok { log.Fatal("type assertion failed: expect float64") } // Event loop r.Read(func(ctx rtree.RCtx) error { vTreeFunc := getTreeFuncVal() fmt.Printf("%v %.2f\n", ctx.Entry, vTreeFunc) return nil }) } // Helper function get a reader (w/o slices) for the examples func getReader(nmax int64) (*groot.File, *rtree.Reader) { return getReaderFile("../testdata/file1.root", "truth", nmax) } // Helper function to get a tree tname from a file fname. func getReaderFile(fname, tname string, nmax int64) (*groot.File, *rtree.Reader) { f, err := groot.Open(fname) if err != nil { log.Fatal("example_treefunc_test.go: could not open "+fname+": %w", err) } obj, err := f.Get(tname) if err != nil { log.Fatal("could not retrieve object: %w", err) } t := obj.(rtree.Tree) r, err := rtree.NewReader(t, []rtree.ReadVar{}, rtree.WithRange(0, nmax)) if err != nil { log.Fatal("could not create tree reader: %w", err) } return f, r }
Output: 0 0.33 1 0.33 2 0.33 3 0.33 4 0.33
func TreeCutBool ¶
TreeCutBool returns a TreeFunc to get a single boolean branch-based variable for cuts. The output value is a boolean and cannot be used to be plotted. To plot a boolean, use TreeVarBool(v).
func TreeValF64 ¶
TreeValF64 returns a TreeFunc to get float value, ie not a branch-based variable.
func TreeVarBool ¶
TreeVarBool returns a TreeFunc to get a single boolean branch-based variable to plot. The output value is a float64 and cannot be used for selection. For cuts, use TreeCutBool(v).
func TreeVarF32 ¶
TreeVarF32 returns a TreeFunc to get a single float32 branch-based variable. The output value is a float64.
func TreeVarF32s ¶
TreeVarF32s returns a TreeFunc to get a slice of float32 branch-based variable. The output value is a float64.
func TreeVarF64 ¶
TreeVarF64 returns a TreeFunc to get a single float64 branch-based variable. The output value is a float64.
func TreeVarF64s ¶
TreeVarF64s returns a TreeFunc to get a slice of float64 branch-based variable. The output value is a float64.
func TreeVarI32 ¶
TreeVarI32 returns a TreeFunc to get a single int32 branch-based variable. The output value is a float64.
func TreeVarI32s ¶
TreeVarI32s returns a TreeFunc to get a slice of int32 branch-based variable. The output value is a float64.
func TreeVarI64 ¶
TreeVarI64 returns a TreeFunc to get a single int64 branch-based variable. The output value is a float64.
func TreeVarI64s ¶
TreeVarI64s returns a TreeFunc to get a slice of int64 branch-based variable. The output value is a float64.
func (*TreeFunc) FuncFormula ¶
FuncFormula returns the rfunc.Formula function associated to the TreeFunc f. If the type of f.Fct corresponds to either a pre-defined function from rtree/rfunc, or to a user-defined rfunc, it's loaded. A generic rtree function is loaded otherwise (~5 times slower).
func (*TreeFunc) GetFuncBool ¶
GetFuncBool returns the function to be called in the event loop to get the boolean value computed in f.Fct function.
func (*TreeFunc) GetFuncF64 ¶
GetFuncF64 returns a function to be called in the event loop to get the float64 value computed in f.Fct function.
func (*TreeFunc) GetFuncF64s ¶
GetFuncF64s returns a function to be called in the event loop to get a slice []float64 values computed in f.Fct function.
type Variable ¶
type Variable struct { Name string // Variable name. TreeFunc TreeFunc // Variable definition from branches & functions. Nbins int // Number of bins of final histograms. Xmin, Xmax float64 // Mininum and maximum values of the histogram. LogY bool // Enable logarithm scale for the y-axis. SaveName string // Name of the saved plot (default 'Name'). XLabel, YLabel string // Axis labels (default: 'Variable', 'Events'). XTickFormat, YTickFormat string // Axis tick formatting (default: hplot default). RangeXmin, RangeXmax float64 // X-axis range (default: hplot default). RangeYmin, RangeYmax float64 // Y-axis range (default: hplot default). RatioYmin, RatioYmax float64 // Ratio Y-axis range (default: hplot default). LegPosTop, LegPosLeft bool // Legend position (default: true, false) // contains filtered or unexported fields }
func NewVariable ¶
func NewVariable(name string, tFunc TreeFunc, nBins int, xMin, xMax float64, opts ...VariableOptions) *Variable
NewVariable creates a new variable value with default settings. The TreeFunc object should returns either a float64 or a []float64. Any other returned type will panic.
Example ¶
package main import ( "github.com/rmadar/tree-gonalyzer/ana" ) func main() { // Variable 'name' corresponding to the branch 'branchF64' // to be histogrammed with 100 bins between 0 and 1 ana.NewVariable("name", ana.TreeVarF64("branchF64"), 100, 0, 100) }
Output:
type VariableOptions ¶
type VariableOptions func(cfg *config)
VariableOptions encodes various settings to pass to a Variable type, as arguments of ana.NewVariable().
func WithAxisLabels ¶
func WithAxisLabels(xlab, ylab string) VariableOptions
WithAxisLabels sets the x- and y-axis label.
func WithLegLeft ¶
func WithLegLeft(left bool) VariableOptions
WithLegLeft sets the legend left/right position on the plot.
func WithLegTop ¶
func WithLegTop(top bool) VariableOptions
WithLegTop sets the legend top/bottom position on the plot.
func WithRatioYRange ¶
func WithRatioYRange(min, max float64) VariableOptions
WithRatioYRange sets the y-axis min and max for the ratio plot.
func WithSaveName ¶
func WithSaveName(n string) VariableOptions
WithSaveName sets the file name of the plot.
func WithTickFormats ¶
func WithTickFormats(xticks, yticks string) VariableOptions
WithTickFormats sets the x- and y-axis labels.
func WithXRange ¶
func WithXRange(min, max float64) VariableOptions
WithXRange sets the x-axis min and max.
func WithYRange ¶
func WithYRange(min, max float64) VariableOptions
WithYRange sets the y-axis min and max.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package featuring a realistic example of analysis using ana package.
|
Package featuring a realistic example of analysis using ana package. |
Package allowing to benchmark performances of the ana package.
|
Package allowing to benchmark performances of the ana package. |