Analysis Workflow

From raw ROOT trees to physics histograms.

The Recipe-Based Architecture

RAD utilizes an AnalysisManager that compartmentalizes your code into Recipes (C++ Lambdas). This ensures execution safety, multi-threading stability, and keeps your analysis logic incredibly clean.

1Setup & Candidates

Initialize the Analysis Manager, set your beam parameters, and assign your track roles before generating combinations.

// 1. Enable Parallel Processing ROOT::EnableImplicitMT(8); // 2. Initialize the Manager AnalysisManager<HepMCElectro, KinematicsProcElectro> mgr{ "Jpsi_Analysis", // Analysis Name "hepmc3_tree", // Tree Name "data.root" // Input File }; mgr.SetOutputDir("output"); auto& reaction = mgr.Reaction(); reaction.SetupMC(); // 3. Map Particle Roles reaction.SetBeamElectronIndex(0); reaction.SetBeamIonIndex(1); reaction.SetScatElectronIndex(2); reaction.SetParticleIndex("p", 3); reaction.SetParticleIndex("ele", 4); reaction.SetParticleIndex("pos", 5); // 4. Expand into unique combinations & add data stream reaction.MakeCombinations(); mgr.AddStream(rad::MC());

2The Topology Recipe

Define how intermediate particles are constructed (Sums/Diffs) and what physics variables to calculate for every combination.

// 5. The Topology Lambda (Injected to all CPU threads) auto topology_recipe = [](KinematicsProcElectro& p) { // A. Reconstruct J/psi -> e+ e- (Vector Sum) p.Creator().Sum("Jpsi", {{"ele", "pos"}}); // Or reconstruct missing tracks (Vector Diff) // p.Creator().Diff("miss", {{rad::consts::BeamEle(), rad::consts::BeamIon()}, {rad::consts::ScatEle(), "Jpsi", "p"}}); // B. Assign Groups p.SetMesonParticles({"Jpsi"}); p.SetBaryonParticles({"p"}); // C. Calculate Invariant Masses p.Mass("MassJ", {"Jpsi"}); // D. Standard Calculations & Angles p.RegisterCalc("tb", rad::physics::TBot); p.ParticleTheta({{"scat_ele", "Jpsi", "p"}}); p.ParticleP({{"scat_ele", "Jpsi", "p"}}); };

3Histograms & Execution

Define your plots targeting the variables created above, configure the manager, and run the lazy evaluation.

// 6. The Histogram Recipe auto histogram_recipe = [](rad::histo::Histogrammer& h) { // Args: Name, Title/Axes, Bins, Min, Max, Target Column h.Create("MassJ", "Invariant Mass J/psi; Mass [GeV]", 100, 2.0, 4.0, "MassJ"); h.Create2D("hPvsTheta", "P vs Theta", 100, 0.0, 10.0, 100, 0.0, 3.14, "p_pmag", "p_theta"); }; // 7. Inject Recipes into the Manager mgr.ConfigureKinematics(topology_recipe); mgr.ConfigureHistograms(histogram_recipe); // 8. Trigger Lazy Evaluation (The Event Loop) mgr.Snapshot(); // Prepares the flat TTree mgr.Run(); // Executes RDataFrame!