Calculate custom histograms
Prerequisites and goal
Complete the selection exercise and be comfortable rebuilding C++. The goal is to calculate observables that do not exist as input branches, starting with the invariant mass of the best dimuon candidate.
Generate the app
From the analysis root:
python3 tea/create.py --type task4_histogrammer --name llp_histogrammer
This creates apps/llp_histogrammer.cpp and configs/llp_histogrammer.py from the current DAS exercise templates.
Define calculated histograms
In configs/llp_histogrammer.py, complete histParams:
histParams = (
("Dimuon", "minv", 100, 0, 100, ""),
("Dimuon", "logLxy", 70, -4, 3, ""),
)
Keep the TightMuons, LooseMuons, and LooseElectrons collections internally consistent with the event cuts. Set:
process = "tta_mAlp-12GeV_ctau-1e2mm"
inputFilePath = f"{base_path}/{process}/output_0.root"
histogramsOutputFilePath = f"../results/tutorial/histograms/{process}/after_selections.root"
Fill the variables
The generated app already converts an Event to NanoEvent and retrieves GetBestDimuonVertex(). Its HistogramsHandler::Fill names must match the config-generated names:
histogramsHandler->Fill("Dimuon_minv", bestDimuon->GetInvariantMass());
Add the displacement observable using methods implemented by NanoDimuonVertex; consult the header in tea/libs/extensions/include/NanoDimuonVertex.hpp for the exact current method rather than guessing it.
Build and run
source tea/build.sh
cd bin
./llp_histogrammer --config llp_histogrammer.py
Expected output
The ROOT file under results/tutorial/histograms/tta_mAlp-12GeV_ctau-1e2mm/ should contain the declared dimuon histograms and a cut flow. Confirm that the histograms have entries and physically sensible ranges.