{
"cells": [
{
"cell_type": "markdown",
"id": "625df4ee",
"metadata": {},
"source": [
"# hist102_NanoAODDimuonAnalysis\n",
"Show how NanoAOD files can be processed with RDataFrame and RHist.\n",
"\n",
"This tutorial is based on df102_NanoAODDimuonAnalysis.C.\n",
"It illustrates how NanoAOD files can be processed with ROOT\n",
"dataframes. The NanoAOD-like input files are filled with 66 mio. events\n",
"from CMS OpenData containing muon candidates part of 2012 dataset\n",
"([DOI: 10.7483/OPENDATA.CMS.YLIC.86ZZ](http://opendata.cern.ch/record/6004)\n",
"and [DOI: 10.7483/OPENDATA.CMS.M5AD.Y3V3](http://opendata.cern.ch/record/6030)).\n",
"The macro matches muon pairs and produces an histogram of the dimuon mass\n",
"spectrum showing resonances up to the Z mass.\n",
"Note that the bump at 30 GeV is not a resonance but a trigger effect.\n",
"\n",
"More details about the dataset can be found on\n",
"[the CERN Open Data portal](http://opendata.web.cern.ch/record/12341).\n",
"\n",
"\n",
"\n",
"\n",
"**Author:** Stefan Wunsch (KIT, CERN), the ROOT Team \n",
"This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Tuesday, May 19, 2026 at 08:13 PM."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "471dc07c",
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"%%cpp -d\n",
"#include \n",
"#include \n",
"#include \n",
"#include \n",
"#include \n",
"#include \n",
"#include \n",
"#include \n",
"\n",
"using namespace ROOT::VecOps;"
]
},
{
"cell_type": "markdown",
"id": "4681e25c",
"metadata": {},
"source": [
"Enable multi-threading"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7d6406fb",
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"ROOT::EnableImplicitMT();"
]
},
{
"cell_type": "markdown",
"id": "9ce32b12",
"metadata": {},
"source": [
"Create dataframe from NanoAOD files"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "526f8d98",
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"ROOT::RDataFrame df(\"Events\", \"root://eospublic.cern.ch//eos/opendata/cms/derived-data/AOD2NanoAODOutreachTool/\"\n",
" \"Run2012BC_DoubleMuParked_Muons.root\");"
]
},
{
"cell_type": "markdown",
"id": "10930acd",
"metadata": {},
"source": [
"For simplicity, select only events with exactly two muons and require opposite charge"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ef6baaf8",
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"auto df_2mu = df.Filter(\"nMuon == 2\", \"Events with exactly two muons\");\n",
"auto df_os = df_2mu.Filter(\"Muon_charge[0] != Muon_charge[1]\", \"Muons with opposite charge\");"
]
},
{
"cell_type": "markdown",
"id": "1f0a4d42",
"metadata": {},
"source": [
"Compute invariant mass of the dimuon system"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "613bb0e3",
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"auto df_mass = df_os.Define(\"Dimuon_mass\", InvariantMass, {\"Muon_pt\", \"Muon_eta\", \"Muon_phi\", \"Muon_mass\"});"
]
},
{
"cell_type": "markdown",
"id": "0db35ed8",
"metadata": {},
"source": [
"Make histogram of dimuon mass spectrum"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bbeaab1b",
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"auto hist = df_mass.Hist(30000, {0.25, 300}, \"Dimuon_mass\");"
]
},
{
"cell_type": "markdown",
"id": "2a642ac6",
"metadata": {},
"source": [
"Request cut-flow report"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f0113b13",
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"auto report = df.Report();"
]
},
{
"cell_type": "markdown",
"id": "89032567",
"metadata": {},
"source": [
"Convert histogram to TH1, set title and axis labels"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "611ea423",
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"auto h = ROOT::Experimental::Hist::ConvertToTH1D(*hist);\n",
"h->SetName(\"Dimuon_mass\");\n",
"h->SetTitle(\"Dimuon mass;m_{#mu#mu} (GeV);N_{Events}\");"
]
},
{
"cell_type": "markdown",
"id": "26d063fb",
"metadata": {},
"source": [
"Produce plot"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "eeae6d51",
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"gStyle->SetOptStat(0);\n",
"gStyle->SetTextFont(42);\n",
"auto c = new TCanvas(\"c\", \"\", 800, 700);\n",
"c->SetLogx();\n",
"c->SetLogy();\n",
"\n",
"h->GetXaxis()->SetTitleSize(0.04);\n",
"h->GetYaxis()->SetTitleSize(0.04);\n",
"h->DrawClone();\n",
"\n",
"TLatex label;\n",
"label.SetNDC(true);\n",
"label.DrawLatex(0.175, 0.740, \"#eta\");\n",
"label.DrawLatex(0.205, 0.775, \"#rho,#omega\");\n",
"label.DrawLatex(0.270, 0.740, \"#phi\");\n",
"label.DrawLatex(0.400, 0.800, \"J/#psi\");\n",
"label.DrawLatex(0.415, 0.670, \"#psi'\");\n",
"label.DrawLatex(0.485, 0.700, \"Y(1,2,3S)\");\n",
"label.DrawLatex(0.755, 0.680, \"Z\");\n",
"label.SetTextSize(0.040);\n",
"label.DrawLatex(0.100, 0.920, \"#bf{CMS Open Data}\");\n",
"label.SetTextSize(0.030);\n",
"label.DrawLatex(0.630, 0.920, \"#sqrt{s} = 8 TeV, L_{int} = 11.6 fb^{-1}\");\n",
"\n",
"c->SaveAs(\"hist102_dimuon_spectrum.pdf\");"
]
},
{
"cell_type": "markdown",
"id": "0aaf4e5b",
"metadata": {},
"source": [
"Print cut-flow report"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "87306b40",
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"report->Print();"
]
},
{
"cell_type": "markdown",
"id": "95a757d0",
"metadata": {},
"source": [
"Draw all canvases "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "11153618",
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"%jsroot on\n",
"gROOT->GetListOfCanvases()->Draw()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "ROOT C++",
"language": "c++",
"name": "root"
},
"language_info": {
"codemirror_mode": "text/x-c++src",
"file_extension": ".C",
"mimetype": " text/x-c++src",
"name": "c++"
}
},
"nbformat": 4,
"nbformat_minor": 5
}