This is an example of unfolding a two-dimensional distribution also using an auxiliary measurement to constrain some background
#include <iostream>
#include <cmath>
using std::cout;
class ToyEvent {
public:
void GenerateDataEvent(
TRandom *rnd);
void GenerateSignalEvent(
TRandom *rnd);
void GenerateBgrEvent(
TRandom *rnd);
inline Double_t GetPtRec(
void)
const {
return fPtRec; }
inline Double_t GetEtaRec(
void)
const {
return fEtaRec; }
inline Double_t GetDiscriminator(
void)
const {
return fDiscriminator; }
inline Bool_t IsTriggered(
void)
const {
return fIsTriggered; }
if(IsSignal()) return fPtGen;
else return -1.0;
}
if(IsSignal()) return fEtaGen;
else return 999.0;
}
inline Bool_t IsSignal(
void)
const {
return fIsSignal; }
protected:
void GenerateSignalKinematics(TRandom *rnd,
Bool_t isData);
void GenerateBgrKinematics(TRandom *rnd,
Bool_t isData);
void GenerateReco(TRandom *rnd);
};
void testUnfold5a()
{
const Int_t neventData = 20000;
Float_t etaRec,ptRec,discr,etaGen,ptGen;
Int_t istriggered,issignal;
TFile *dataFile=
new TFile(
"testUnfold5_data.root",
"recreate");
dataTree->
Branch(
"etarec",&etaRec,
"etarec/F");
dataTree->
Branch(
"ptrec",&ptRec,
"ptrec/F");
dataTree->
Branch(
"discr",&discr,
"discr/F");
dataTree->
Branch(
"istriggered",&istriggered,
"istriggered/I");
dataTree->
Branch(
"etagen",&etaGen,
"etagen/F");
dataTree->
Branch(
"ptgen",&ptGen,
"ptgen/F");
dataTree->
Branch(
"issignal",&issignal,
"issignal/I");
cout<<"fill data tree\n";
Int_t nEvent=0,nTriggered=0;
while(nTriggered<neventData) {
ToyEvent event;
event.GenerateDataEvent(g_rnd);
etaRec=event.GetEtaRec();
ptRec=event.GetPtRec();
discr=event.GetDiscriminator();
istriggered=event.IsTriggered() ? 1 : 0;
etaGen=event.GetEtaGen();
ptGen=event.GetPtGen();
issignal=event.IsSignal() ? 1 : 0;
if(!(nEvent%100000)) cout<<" data event "<<nEvent<<"\n";
if(istriggered) nTriggered++;
nEvent++;
}
delete dataTree;
delete dataFile;
TFile *signalFile=
new TFile(
"testUnfold5_signal.root",
"recreate");
signalTree->
Branch(
"etarec",&etaRec,
"etarec/F");
signalTree->
Branch(
"ptrec",&ptRec,
"ptrec/F");
signalTree->
Branch(
"discr",&discr,
"discr/F");
signalTree->
Branch(
"istriggered",&istriggered,
"istriggered/I");
signalTree->
Branch(
"etagen",&etaGen,
"etagen/F");
signalTree->
Branch(
"ptgen",&ptGen,
"ptgen/F");
cout<<"fill signal tree\n";
for(int ievent=0;ievent<neventSignalMC;ievent++) {
ToyEvent event;
event.GenerateSignalEvent(g_rnd);
etaRec=event.GetEtaRec();
ptRec=event.GetPtRec();
discr=event.GetDiscriminator();
istriggered=event.IsTriggered() ? 1 : 0;
etaGen=event.GetEtaGen();
ptGen=event.GetPtGen();
if(!(ievent%100000)) cout<<" signal event "<<ievent<<"\n";
}
delete signalTree;
delete signalFile;
TFile *bgrFile=
new TFile(
"testUnfold5_background.root",
"recreate");
bgrTree->
Branch(
"etarec",&etaRec,
"etarec/F");
bgrTree->
Branch(
"ptrec",&ptRec,
"ptrec/F");
bgrTree->
Branch(
"discr",&discr,
"discr/F");
bgrTree->
Branch(
"istriggered",&istriggered,
"istriggered/I");
cout<<"fill background tree\n";
for(int ievent=0;ievent<neventBgrMC;ievent++) {
ToyEvent event;
event.GenerateBgrEvent(g_rnd);
etaRec=event.GetEtaRec();
ptRec=event.GetPtRec();
discr=event.GetDiscriminator();
istriggered=event.IsTriggered() ? 1 : 0;
if(!(ievent%100000)) cout<<" background event "<<ievent<<"\n";
}
delete bgrTree;
delete bgrFile;
}
Double_t ToyEvent::kDataSignalFraction=0.8;
void ToyEvent::GenerateDataEvent(
TRandom *rnd) {
fIsSignal=rnd->
Uniform()<kDataSignalFraction;
if(IsSignal()) {
GenerateSignalKinematics(rnd,
kTRUE);
} else {
GenerateBgrKinematics(rnd,
kTRUE);
}
GenerateReco(rnd);
}
void ToyEvent::GenerateSignalEvent(
TRandom *rnd) {
fIsSignal=true;
GenerateSignalKinematics(rnd,
kFALSE);
GenerateReco(rnd);
}
void ToyEvent::GenerateBgrEvent(
TRandom *rnd) {
fIsSignal=false;
GenerateBgrKinematics(rnd,
kFALSE);
GenerateReco(rnd);
}
void ToyEvent::GenerateSignalKinematics(
TRandom *rnd,
Bool_t isData) {
if(isData) {
e_T0=0.6;
e_n=2.5;
e_T0_eta=0.05;
e_n_eta=-0.05;
eta_p2=1.5;
}
if(eta_p2>0.0) {
if(rnd->
Uniform()>=0.5) fEtaGen= -fEtaGen;
} else {
fEtaGen=rnd->
Uniform(-etaMax,etaMax);
}
}
void ToyEvent::GenerateBgrKinematics(
TRandom *rnd,
Bool_t isData) {
fPtGen=0.0;
fEtaGen=0.0;
fPtRec=rnd->
Exp(isData ? 2.5 : 2.5);
}
void ToyEvent::GenerateReco(
TRandom *rnd) {
if(fIsSignal) {
Double_t eGen=fPtGen*(expEta+1./expEta);
*eGen;
do {
eRec=rnd->
Gaus(eGen,sigmaE);
} while(eRec<=0.0);
fEtaRec=rnd->
Gaus(fEtaGen,sigmaEta);
fPtRec=eRec/(expEta+1./expEta);
do {
Double_t tauDiscr=0.08-0.04/(1.+fPtRec/10.0);
fDiscriminator=1.0-rnd->
Exp(tauDiscr)+rnd->
Gaus(0.,sigmaDiscr);
} while((fDiscriminator<=0.)||(fDiscriminator>=1.));
} else {
do {
Double_t tauDiscr=0.15-0.05/(1.+fPtRec/5.0)+0.1*fEtaRec;
fDiscriminator=rnd->
Exp(tauDiscr)+rnd->
Gaus(0.,sigmaDiscr);
} while((fDiscriminator<=0.)||(fDiscriminator>=1.));
}
}
int Int_t
Signed integer 4 bytes (int).
bool Bool_t
Boolean (0=false, 1=true) (bool).
double Double_t
Double 8 bytes.
float Float_t
Float 4 bytes (float).
A file, usually with extension .root, that stores data and code in the form of serialized objects in ...
Random number generator class based on M.
This is the base class for the ROOT Random number generators.
virtual Double_t Gaus(Double_t mean=0, Double_t sigma=1)
Samples a random number from the standard Normal (Gaussian) Distribution with the given mean and sigm...
virtual Double_t Exp(Double_t tau)
Returns an exponential deviate.
virtual Double_t Uniform(Double_t x1=1)
Returns a uniform deviate on the interval (0, x1).
A TTree represents a columnar dataset.
virtual Int_t Fill()
Fill all branches.
TBranch * Branch(const char *name, T *obj, Int_t bufsize=32000, Int_t splitlevel=99)
Add a new branch, and infer the data type from the type of obj being passed.
Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0) override
Write this object to the current directory.
T etaMax()
Function providing the maximum possible value of pseudorapidity for a non-zero rho,...
Double_t Exp(Double_t x)
Returns the base-e exponential function of x, which is e raised to the power x.
Double_t Sqrt(Double_t x)
Returns the square root of x.
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
This file is part of TUnfold.
TUnfold is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
TUnfold is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with TUnfold. If not, see http://www.gnu.org/licenses/.