{
"cells": [
{
"cell_type": "markdown",
"id": "14aadc33",
"metadata": {},
"source": [
"# testUnfold5c\n",
"Test program for the classes TUnfoldDensity and TUnfoldBinning.\n",
"\n",
"A toy test of the TUnfold package\n",
"\n",
"This is an example of unfolding a two-dimensional distribution\n",
"also using an auxiliary measurement to constrain some background\n",
"\n",
"The example comprises several macros\n",
" - testUnfold5a.C create root files with TTree objects for\n",
" signal, background and data\n",
" - write files testUnfold5_signal.root\n",
" testUnfold5_background.root\n",
" testUnfold5_data.root\n",
"\n",
" - testUnfold5b.C create a root file with the TUnfoldBinning objects\n",
" - write file testUnfold5_binning.root\n",
"\n",
" - testUnfold5c.C loop over trees and fill histograms based on the\n",
" TUnfoldBinning objects\n",
" - read testUnfold5_binning.root\n",
" testUnfold5_signal.root\n",
" testUnfold5_background.root\n",
" testUnfold5_data.root\n",
"\n",
" - write testUnfold5_histograms.root\n",
"\n",
" - testUnfold5d.C run the unfolding\n",
" - read testUnfold5_histograms.root\n",
" - write testUnfold5_result.root\n",
" testUnfold5_result.ps\n",
"\n",
"\n",
" **Version 17.6, in parallel to changes in TUnfold**\n",
"\n",
"#### History:\n",
" - Version 17.5, updated for reading binning from XML file\n",
" - Version 17.4, updated for reading binning from XML file\n",
" - Version 17.3, updated for reading binning from XML file\n",
" - Version 17.2, updated for reading binning from XML file\n",
" - Version 17.1, in parallel to changes in TUnfold\n",
" - Version 17.0 example for multi-dimensional unfolding\n",
"\n",
" This file is part of TUnfold.\n",
"\n",
" TUnfold is free software: you can redistribute it and/or modify\n",
" it under the terms of the GNU General Public License as published by\n",
" the Free Software Foundation, either version 3 of the License, or\n",
" (at your option) any later version.\n",
"\n",
" TUnfold is distributed in the hope that it will be useful,\n",
" but WITHOUT ANY WARRANTY; without even the implied warranty of\n",
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n",
" GNU General Public License for more details.\n",
"\n",
" You should have received a copy of the GNU General Public License\n",
" along with TUnfold. If not, see .\n",
"\n",
"\n",
"\n",
"**Author:** Stefan Schmitt DESY, 14.10.2008 \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:11 PM."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "468452fc",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:11:26.092343Z",
"iopub.status.busy": "2026-05-19T20:11:26.092231Z",
"iopub.status.idle": "2026-05-19T20:11:26.098979Z",
"shell.execute_reply": "2026-05-19T20:11:26.098537Z"
}
},
"outputs": [],
"source": [
"%%cpp -d\n",
"#include \n",
"#include \n",
"#include \n",
"#include \n",
"#include \n",
"#include \n",
"#ifndef READ_BINNING_CINT\n",
"#include \n",
"#include \n",
"#include \"TUnfoldBinningXML.h\"\n",
"#else\n",
"#include \"TUnfoldBinning.h\"\n",
"#endif\n",
"\n",
"using std::cout;"
]
},
{
"cell_type": "markdown",
"id": "0b3b84c8",
"metadata": {},
"source": [
"switch on histogram errors"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "eb70b360",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:11:26.100463Z",
"iopub.status.busy": "2026-05-19T20:11:26.100349Z",
"iopub.status.idle": "2026-05-19T20:11:26.413397Z",
"shell.execute_reply": "2026-05-19T20:11:26.412881Z"
}
},
"outputs": [],
"source": [
"TH1::SetDefaultSumw2();"
]
},
{
"cell_type": "markdown",
"id": "7a82895c",
"metadata": {},
"source": [
"=======================================================\n",
"Step 1: open file to save histograms and binning schemes"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "d6f8e6e3",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:11:26.415562Z",
"iopub.status.busy": "2026-05-19T20:11:26.415440Z",
"iopub.status.idle": "2026-05-19T20:11:26.618515Z",
"shell.execute_reply": "2026-05-19T20:11:26.618026Z"
}
},
"outputs": [],
"source": [
"TFile *outputFile=new TFile(\"testUnfold5_histograms.root\",\"recreate\");"
]
},
{
"cell_type": "markdown",
"id": "32a97c28",
"metadata": {},
"source": [
"=======================================================\n",
"Step 2: read binning from XML\n",
"and save them to output file"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "e4c4c9c6",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:11:26.620546Z",
"iopub.status.busy": "2026-05-19T20:11:26.620424Z",
"iopub.status.idle": "2026-05-19T20:11:26.824019Z",
"shell.execute_reply": "2026-05-19T20:11:26.823543Z"
}
},
"outputs": [],
"source": [
"#ifdef READ_BINNING_CINT\n",
"TFile *binningSchemes=new TFile(\"testUnfold5_binning.root\");\n",
"#endif\n",
"\n",
"TUnfoldBinning *detectorBinning,*generatorBinning;"
]
},
{
"cell_type": "markdown",
"id": "c7e02b4f",
"metadata": {},
"source": [
"read binning schemes in XML format"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "06b940c7",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:11:26.826032Z",
"iopub.status.busy": "2026-05-19T20:11:26.825911Z",
"iopub.status.idle": "2026-05-19T20:11:27.041098Z",
"shell.execute_reply": "2026-05-19T20:11:27.040549Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"TUnfoldBinning \"detector\" has 360 bins [1,361] nTH1x=360\n",
" TUnfoldBinning \"detectordistribution\" has 360 bins [1,361] nTH1x=360\n",
" distribution: 360 bins\n",
" \"pt\" nbin=8 plus overflow\n",
" \"eta\" nbin=10\n",
" \"discriminator\" nbin=4\n",
"TUnfoldBinning \"generator\" has 115 bins [1,116] nTH1x=115\n",
" TUnfoldBinning \"signal\" has 25 bins [1,26] nTH1x=25\n",
" distribution: 25 bins\n",
" \"ptgen\" nbin=3 plus underflow plus overflow\n",
" \"etagen\" nbin=3 plus underflow plus overflow\n",
" TUnfoldBinning \"background\" has 90 bins [26,116] nTH1x=90\n",
" distribution: 90 bins\n",
" \"ptrec\" nbin=8 plus overflow\n",
" \"etarec\" nbin=10\n"
]
}
],
"source": [
"#ifndef READ_BINNING_CINT\n",
"TDOMParser parser;\n",
"Int_t error=parser.ParseFile(\"testUnfold5binning.xml\");\n",
"if(error) cout<<\"error=\"<GetObject(\"detector\",detectorBinning);\n",
"binningSchemes->GetObject(\"generator\",generatorBinning);\n",
"\n",
"delete binningSchemes;\n",
"#endif\n",
"outputFile->WriteTObject(detectorBinning);\n",
"outputFile->WriteTObject(generatorBinning);\n",
"\n",
"if(detectorBinning) {\n",
" detectorBinning->PrintStream(cout);\n",
"} else {\n",
" cout<<\"could not read 'detector' binning\\n\";\n",
"}\n",
"if(generatorBinning) {\n",
" generatorBinning->PrintStream(cout);\n",
"} else {\n",
" cout<<\"could not read 'generator' binning\\n\";\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "ac9502da",
"metadata": {},
"source": [
"pointers to various nodes in the binning scheme"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "5d69bb7d",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:11:27.043335Z",
"iopub.status.busy": "2026-05-19T20:11:27.043202Z",
"iopub.status.idle": "2026-05-19T20:11:27.246831Z",
"shell.execute_reply": "2026-05-19T20:11:27.245797Z"
}
},
"outputs": [],
"source": [
"const TUnfoldBinning *detectordistribution=\n",
" detectorBinning->FindNode(\"detectordistribution\");\n",
"\n",
"const TUnfoldBinning *signalBinning=\n",
" generatorBinning->FindNode(\"signal\");\n",
"\n",
"const TUnfoldBinning *bgrBinning=\n",
" generatorBinning->FindNode(\"background\");"
]
},
{
"cell_type": "markdown",
"id": "a41f5742",
"metadata": {},
"source": [
"write binning schemes to output file"
]
},
{
"cell_type": "markdown",
"id": "1fe790fd",
"metadata": {},
"source": [
"=======================================================\n",
"Step 3: book and fill data histograms"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "54e56ca8",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:11:27.257132Z",
"iopub.status.busy": "2026-05-19T20:11:27.256996Z",
"iopub.status.idle": "2026-05-19T20:11:27.474820Z",
"shell.execute_reply": "2026-05-19T20:11:27.463272Z"
}
},
"outputs": [],
"source": [
"Float_t etaRec,ptRec,discr,etaGen,ptGen;\n",
"Int_t istriggered,issignal;\n",
"\n",
"TH1 *histDataReco=detectorBinning->CreateHistogram(\"histDataReco\");\n",
"TH1 *histDataTruth=generatorBinning->CreateHistogram(\"histDataTruth\");\n",
"histDataReco->SetDirectory(outputFile);\n",
"histDataTruth->SetDirectory(outputFile);\n",
"\n",
"TFile *dataFile=new TFile(\"testUnfold5_data.root\");\n",
"TTree *dataTree=(TTree *) dataFile->Get(\"data\");\n",
"\n",
"if(!dataTree) {\n",
" cout<<\"could not read 'data' tree\\n\";\n",
"}\n",
"\n",
"dataTree->ResetBranchAddresses();\n",
"dataTree->SetBranchAddress(\"etarec\",&etaRec);\n",
"dataTree->SetBranchAddress(\"ptrec\",&ptRec);\n",
"dataTree->SetBranchAddress(\"discr\",&discr);"
]
},
{
"cell_type": "markdown",
"id": "fa3ab7fb",
"metadata": {},
"source": [
"for real data, only the triggered events are available"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "0e575fcc",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:11:27.483409Z",
"iopub.status.busy": "2026-05-19T20:11:27.483272Z",
"iopub.status.idle": "2026-05-19T20:11:27.697179Z",
"shell.execute_reply": "2026-05-19T20:11:27.696538Z"
}
},
"outputs": [],
"source": [
"dataTree->SetBranchAddress(\"istriggered\",&istriggered);"
]
},
{
"cell_type": "markdown",
"id": "9c932ef6",
"metadata": {},
"source": [
"data truth parameters"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "ae2ce897",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:11:27.699264Z",
"iopub.status.busy": "2026-05-19T20:11:27.699009Z",
"iopub.status.idle": "2026-05-19T20:11:27.904007Z",
"shell.execute_reply": "2026-05-19T20:11:27.903445Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"loop over data events\n"
]
}
],
"source": [
"dataTree->SetBranchAddress(\"etagen\",&etaGen);\n",
"dataTree->SetBranchAddress(\"ptgen\",&ptGen);\n",
"dataTree->SetBranchAddress(\"issignal\",&issignal);\n",
"dataTree->SetBranchStatus(\"*\",true);\n",
"\n",
"\n",
"cout<<\"loop over data events\\n\";\n",
"\n",
"for(Int_t ievent=0;ieventGetEntriesFast();ievent++) {\n",
" if(dataTree->GetEntry(ievent)<=0) break;\n",
" // fill histogram with reconstructed quantities\n",
" if(istriggered) {\n",
" Int_t binNumber=\n",
" detectordistribution->GetGlobalBinNumber(ptRec,etaRec,discr);\n",
" histDataReco->Fill(binNumber);\n",
" }\n",
" // fill histogram with data truth parameters\n",
" if(issignal) {\n",
" // signal has true eta and pt\n",
" Int_t binNumber=signalBinning->GetGlobalBinNumber(ptGen,etaGen);\n",
" histDataTruth->Fill(binNumber);\n",
" } else {\n",
" // background only has reconstructed pt and eta\n",
" Int_t binNumber=bgrBinning->GetGlobalBinNumber(ptRec,etaRec);\n",
" histDataTruth->Fill(binNumber);\n",
" }\n",
"}\n",
"\n",
"delete dataTree;\n",
"delete dataFile;"
]
},
{
"cell_type": "markdown",
"id": "501dab5a",
"metadata": {},
"source": [
"=======================================================\n",
"Step 4: book and fill histogram of migrations\n",
"it receives events from both signal MC and background MC"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "2630b89c",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:11:27.905856Z",
"iopub.status.busy": "2026-05-19T20:11:27.905726Z",
"iopub.status.idle": "2026-05-19T20:11:28.790618Z",
"shell.execute_reply": "2026-05-19T20:11:28.789922Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"loop over MC signal events\n",
"loop over MC background events\n"
]
}
],
"source": [
"TH2 *histMCGenRec=TUnfoldBinning::CreateHistogramOfMigrations\n",
" (generatorBinning,detectorBinning,\"histMCGenRec\");\n",
"histMCGenRec->SetDirectory(outputFile);\n",
"\n",
"TFile *signalFile=new TFile(\"testUnfold5_signal.root\");\n",
"TTree *signalTree=(TTree *) signalFile->Get(\"signal\");\n",
"\n",
"if(!signalTree) {\n",
" cout<<\"could not read 'signal' tree\\n\";\n",
"}\n",
"\n",
"signalTree->ResetBranchAddresses();\n",
"signalTree->SetBranchAddress(\"etarec\",&etaRec);\n",
"signalTree->SetBranchAddress(\"ptrec\",&ptRec);\n",
"signalTree->SetBranchAddress(\"discr\",&discr);\n",
"signalTree->SetBranchAddress(\"istriggered\",&istriggered);\n",
"signalTree->SetBranchAddress(\"etagen\",&etaGen);\n",
"signalTree->SetBranchAddress(\"ptgen\",&ptGen);\n",
"signalTree->SetBranchStatus(\"*\",true);\n",
"\n",
"cout<<\"loop over MC signal events\\n\";\n",
"\n",
"for(Int_t ievent=0;ieventGetEntriesFast();ievent++) {\n",
" if(signalTree->GetEntry(ievent)<=0) break;\n",
"\n",
" // bin number on generator level for signal\n",
" Int_t genBin=signalBinning->GetGlobalBinNumber(ptGen,etaGen);\n",
"\n",
" // bin number on reconstructed level\n",
" // bin number 0 corresponds to non-reconstructed events\n",
" Int_t recBin=0;\n",
" if(istriggered) {\n",
" recBin=detectordistribution->GetGlobalBinNumber(ptRec,etaRec,discr);\n",
" }\n",
" histMCGenRec->Fill(genBin,recBin);\n",
"}\n",
"\n",
"delete signalTree;\n",
"delete signalFile;\n",
"\n",
"TFile *bgrFile=new TFile(\"testUnfold5_background.root\");\n",
"TTree *bgrTree=(TTree *) bgrFile->Get(\"background\");\n",
"\n",
"if(!bgrTree) {\n",
" cout<<\"could not read 'background' tree\\n\";\n",
"}\n",
"\n",
"bgrTree->ResetBranchAddresses();\n",
"bgrTree->SetBranchAddress(\"etarec\",&etaRec);\n",
"bgrTree->SetBranchAddress(\"ptrec\",&ptRec);\n",
"bgrTree->SetBranchAddress(\"discr\",&discr);\n",
"bgrTree->SetBranchAddress(\"istriggered\",&istriggered);\n",
"bgrTree->SetBranchStatus(\"*\",true);\n",
"\n",
"cout<<\"loop over MC background events\\n\";\n",
"\n",
"for(Int_t ievent=0;ieventGetEntriesFast();ievent++) {\n",
" if(bgrTree->GetEntry(ievent)<=0) break;\n",
"\n",
" // here, for background only reconstructed quantities are known\n",
" // and only the reconstructed events are relevant\n",
" if(istriggered) {\n",
" // bin number on generator level for background\n",
" Int_t genBin=bgrBinning->GetGlobalBinNumber(ptRec,etaRec);\n",
" // bin number on reconstructed level\n",
" Int_t recBin=detectordistribution->GetGlobalBinNumber\n",
" (ptRec,etaRec,discr);\n",
" histMCGenRec->Fill(genBin,recBin);\n",
" }\n",
"}\n",
"\n",
"delete bgrTree;\n",
"delete bgrFile;\n",
"\n",
"outputFile->Write();\n",
"delete outputFile;"
]
},
{
"cell_type": "markdown",
"id": "52297548",
"metadata": {},
"source": [
"Draw all canvases "
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "a7ae01e4",
"metadata": {
"collapsed": false,
"execution": {
"iopub.execute_input": "2026-05-19T20:11:28.812362Z",
"iopub.status.busy": "2026-05-19T20:11:28.812211Z",
"iopub.status.idle": "2026-05-19T20:11:29.015897Z",
"shell.execute_reply": "2026-05-19T20:11:29.015274Z"
}
},
"outputs": [],
"source": [
"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
}