|
DAS
3.0
Das Analysis System
|
|
void | getHLTJetResponse (const vector< fs::path > &inputs, const fs::path &output, const pt::ptree &config, const int steering, const DT::Slice slice={1, 0}) |
|
unique_ptr< TH3 > | makeRespHist (TString name, TString study) |
|
void | applyDataNormalisation (const vector< fs::path > &inputs, const fs::path &output, const pt::ptree &config, const int steering, const DT::Slice slice={1, 0}) |
|
void | reset (Weights &wgts, const double v=0) |
|
float | GetNormFactor (const fs::path &f_sumWgts, const float xsec) |
|
void | applyMClumi (const vector< fs::path > &inputs, const fs::path &output, const pt::ptree &config, const int steering, const DT::Slice slice={1, 0}) |
|
void | applyNormFactor (const vector< fs::path > &inputs, const fs::path &output, const pt::ptree &config, const int steering, const DT::Slice slice={1, 0}) |
|
void | getSumWeights (const vector< fs::path > &inputs, const fs::path &output, const pt::ptree &config, const int steering, const DT::Slice slice={1, 0}) |
|
std::vector< DAS::RecJet >::iterator | phaseSel (std::vector< DAS::RecJet > &recjets) |
|
std::ostream & | operator<< (std::ostream &Stream, const TriggerLumi &tr_lu) |
|
float | getPrescale (Trigger *trigger, size_t indx) |
|
void | getTriggerCurves (const vector< fs::path > &inputs, const fs::path &output, const pt::ptree &config, const int steering, const DT::Slice slice={1, 0}) |
|
void | getTriggerTurnons (const fs::path &input, const fs::path &outputRoot, const fs::path &outputTxt, const pt::ptree &config, const int steering) |
|
DAS::FourVector | match (const DAS::FourVector &jet, const std::vector< DAS::FourVector > *hltJets) |
|
float | GetX (TF1 *f) |
|
template<typename STREAM > |
TF1 * | FitTriggerEfficiency (int trigger, TH1 *h, STREAM &Stream, int from, const char *options="NQERS") |
|
template<typename STREAM > |
float | GetTriggerEfficiency (int trigger, TH1 *h, STREAM &Stream, float from, float minEff) |
|
◆ anonymous enum
Enumerator |
---|
WEIGHT | use the weights
|
SIGN | use the sign
|
CUTOFF | apply a selection on the weight
|
◆ applyDataNormalisation()
void DAS::Normalisation::applyDataNormalisation |
( |
const vector< fs::path > & |
inputs, |
|
|
const fs::path & |
output, |
|
|
const pt::ptree & |
config, |
|
|
const int |
steering, |
|
|
const DT::Slice |
slice = {1,0} |
|
) |
| |
Apply the the kinematic selection, ensuring that events in the dataset have fired a trigger and correcting the weight of the events with the associated trigger prescales, trigger efficiency, and total luminosity. The weight $\frac{ \text{Prescale} * \mathcal{L}^{-1} }{ \epsilon_\text{trigger} } $ is applied by event. The argument 'strategy' defines the selection criterion of the events and the calculation of the weight (see functor in applyDataNormalisation.h).
- Todo:
- add lumi unc variations
- Todo:
- revisit the logic (having inputs modified + a return object may be confusing)
- Todo:
- reimplement the logic to avoid a selection on the weight
- Parameters
-
inputs | input ROOT files (n-tuple) |
output | output ROOT file (n-tuple) |
config | config handled with `Darwin::Tools::Options` |
steering | parameters obtained from explicit options |
slice | number and index of slice |
51 cout << __func__ <<
' ' << slice <<
" start" << endl;
55 auto tOut = unique_ptr<TTree>(tIn->CloneTree(0));
59 auto isMC = metainfo.Get<
bool>(
"flags",
"isMC");
61 BOOST_THROW_EXCEPTION(
DE::BadInput(
"Only real data may be used as input.", metainfo) );
63 RecEvent *
event =
nullptr;
64 Trigger * trigger =
nullptr;
65 tIn->SetBranchAddress(
"recEvent", &event);
66 tIn->SetBranchAddress(
"jetTrigger", &trigger);
67 vector<FourVector> * hltJets =
nullptr;
68 vector<RecJet> * recJets =
nullptr;
69 tIn->SetBranchAddress(
"hltJets", &hltJets);
70 tIn->SetBranchAddress(
"recJets", &recJets);
72 int year = metainfo.Get<
int>(
"flags",
"year");
75 auto lumi_file =
config.get<fs::path>(
"corrections.normalisation.luminosities" ),
76 unc_file =
config.get<fs::path>(
"corrections.normalisation.uncertainties"),
77 turnon_file =
config.get<fs::path>(
"corrections.normalisation.turnons" ),
78 efficiencies =
config.get<fs::path>(
"corrections.normalisation.efficiencies" );
79 auto strategy =
config.get<
string>(
"corrections.normalisation.strategy"),
80 method =
config.get<
string>(
"corrections.normalisation.method" );
81 Functor normalisation(lumi_file, turnon_file, efficiencies, strategy,
method,
year);
82 LumiUnc lumi_unc(unc_file,
year);
85 bool applySyst = steering &
DT::syst;
87 for (
string source: lumi_unc.sources)
88 metainfo.Set<
string>(
"variations", RecEvent::WeightVar,
source);
92 ControlPlots corrNoTrigEff(
"corrNoTrigEff");
94 vector<ControlPlots> corr { ControlPlots(
"nominal") };
95 TList * ev_wgts = metainfo.List(
"variations", RecEvent::WeightVar);
96 for (TObject * obj: *ev_wgts) {
97 auto name =
dynamic_cast<TObjString*
>(obj)->GetString();
98 corr.push_back(ControlPlots(
name));
103 for (
DT::Looper looper(tIn, slice); looper(); ++looper) {
110 if (recJets->size() == 0)
continue;
112 RecJet leadingJet = normalisation(*event, *recJets, *hltJets, *trigger);
113 cout <<
"leadingJet: " << leadingJet << endl;
118 if (event->weights.front() <= 0)
continue;
119 if (steering &
DT::fill) tOut->Fill();
121 float evtWgts =
event->weights.front();
122 float efficiency = normalisation.eff(leadingJet);
124 cout <<
"evtWgts = " << evtWgts <<
'\n'
125 <<
"efficiency = " << efficiency << endl;
126 if (efficiency <= 0)
continue;
128 corrNoTrigEff(*recJets, evtWgts*efficiency);
129 for (
size_t i = 0; i < corr.size(); ++i)
130 corr.at(i)(*recJets,
event->weights.at(i));
135 for (
auto& jet: *recJets) {
136 float y = jet.AbsRap();
137 float w =
event->weights.front();
138 normalisation.eff.contribs.at(normalisation.ibit)->Fill(jet.CorrPt(), y,
w);
143 corrNoTrigEff.Write(fOut.get());
144 for (
size_t i = 0; i < corr.size(); ++i)
145 corr.at(i).Write(fOut.get());
146 TDirectory * controlplots = fOut->mkdir(
"controlplots");
148 for (TH2 * h: normalisation.eff.contribs) {
149 h->SetDirectory(controlplots);
153 metainfo.Set<
bool>(
"git",
"complete",
true);
157 cout << __func__ <<
' ' << slice <<
" stop" << endl;
◆ applyMClumi()
void DAS::Normalisation::applyMClumi |
( |
const vector< fs::path > & |
inputs, |
|
|
const fs::path & |
output, |
|
|
const pt::ptree & |
config, |
|
|
const int |
steering, |
|
|
const DT::Slice |
slice = {1,0} |
|
) |
| |
Normalise with sum of weights (to be computed) and cross section (given)
- Note
- A cut-off for events with hard scale above 5 TeV is applied, since these events are not realistic
- Todo:
- Events with scale > 5TeV are removed because Pythia used to generate too many of them. Check that this is still needed and that the cut is still appropriate.
- Parameters
-
inputs | input ROOT files (n-tuple) |
output | output ROOT file (n-tuple) |
config | config handled with `Darwin::Tools::Options` |
steering | parameters obtained from explicit options |
slice | number and index of slice |
69 cout << __func__ <<
' ' << slice <<
" start" << endl;
73 auto tOut = unique_ptr<TTree>(tIn->CloneTree(0));
77 auto isMC = metainfo.Get<
bool>(
"flags",
"isMC");
78 if (!
isMC) BOOST_THROW_EXCEPTION(
DE::BadInput(
"Only MC may be used as input.",
79 make_unique<TFile>(
inputs.front().c_str() )) );
82 auto f_sumWgts =
config.get<fs::path>(
"corrections.MCnormalisation.sumWgts");
83 auto xsection =
config.get<
float>(
"corrections.MCnormalisation.xsection");
85 metainfo.Set<fs::path>(
"corrections",
"MCnormalisation",
"sumWgts", f_sumWgts);
86 metainfo.Set<
float>(
"corrections",
"MCnormalisation",
"xsection", xsection);
89 RecEvent * recEvt =
nullptr;
90 GenEvent * genEvt =
nullptr;
92 tIn->SetBranchAddress(
"recEvent", &recEvt);
94 tIn->SetBranchAddress(
"genEvent", &genEvt);
95 tIn->SetBranchAddress(
"pileup", &
pileup);
96 vector<GenJet> *
genjets =
nullptr;
97 vector<RecJet> *
recjets =
nullptr;
99 tIn->SetBranchAddress(
"recJets", &
recjets);
101 tIn->SetBranchAddress(
"genJets", &
genjets);
105 ControlPlots plots(
"controlplots");
107 for (
DT::Looper looper(tIn, slice); looper(); ++looper) {
113 if (genEvt->hard_scale > 5000 )
continue;
116 if (genEvt->weights.size() != 1 || recEvt->weights.size() != 1)
119 BOOST_THROW_EXCEPTION(
DE::AnomalousEvent(
"Unexpected jet energy scale variations", tIn) );
122 genEvt->weights.front() *= factor;
123 if (steering &
DT::fill) tOut->Fill();
127 plots(*
genjets, genEvt->weights.front() );
129 plots(*
recjets, genEvt->weights.front() * recEvt->weights.front());
132 metainfo.Set<
bool>(
"git",
"complete",
true);
136 plots.Write(fOut.get());
138 cout << __func__ <<
' ' << slice <<
" stop" << endl;
◆ applyNormFactor()
void DAS::Normalisation::applyNormFactor |
( |
const vector< fs::path > & |
inputs, |
|
|
const fs::path & |
output, |
|
|
const pt::ptree & |
config, |
|
|
const int |
steering, |
|
|
const DT::Slice |
slice = {1,0} |
|
) |
| |
Multiplies the gen weight of every event by a factor provided on the command line.
- Parameters
-
inputs | input ROOT files (n-tuple) |
output | output ROOT file (n-tuple) |
config | config handled with `Darwin::Tools::Options` |
steering | parameters obtained from explicit options |
slice | number and index of slice |
44 cout << __func__ <<
' ' << slice <<
" start" << endl;
48 auto tOut = unique_ptr<TTree>(tIn->CloneTree(0));
52 auto isMC = metainfo.Get<
bool>(
"flags",
"isMC");
53 if (!
isMC) BOOST_THROW_EXCEPTION(
DE::BadInput(
"Only MC may be used as input.",
54 make_unique<TFile>(
inputs.front().c_str() )) );
56 const float factor =
config.get<
float>(
"corrections.normFactor");
57 metainfo.Set<
float>(
"corrections",
"normFactor", factor);
60 GenEvent * evnt =
nullptr;
61 tIn->SetBranchAddress(
"genEvent", &evnt);
63 for (
DT::Looper looper(tIn, slice); looper(); ++looper) {
68 if (evnt->weights.size() != 1)
72 for (
auto&
weight: evnt->weights) {
79 metainfo.Set<
bool>(
"git",
"complete",
true);
83 cout << __func__ <<
' ' << slice <<
" stop" << endl;
◆ FitTriggerEfficiency()
TF1* DAS::Normalisation::FitTriggerEfficiency |
( |
int |
trigger, |
|
|
TH1 * |
h, |
|
|
STREAM & |
Stream, |
|
|
int |
from, |
|
|
const char * |
options = "NQERS" |
|
) |
| |
Fit the trigger efficiency with sigmoid function in [trigger, 3* trigger], where trigger is the HLT pt threshold.
The sigmoid function is defined as follows:
\epsilon (p_T) = a + 0.5 \times (1-a) \times \left( 1 + \erf \left( \frac{p_T - \mu}{\sigma} \right) \right)
where a, $\mu$ and $\sigma$ are the three parameters.
NOTE:
- the output is very sensitive to the fit range
- unclear if/how JES uncertainties should be taken into account
- Parameters
-
trigger | trigger HLT threshold |
h | efficiency histogram |
Stream | `cout` or file |
from | last turnon, to know from where the ref is efficient |
options | fit options for TF1 function |
56 int mbin = h->GetXaxis()->FindBin( from),
57 Mbin = h->GetXaxis()->FindBin(3*from);
58 float m = h->GetBinLowEdge(mbin+1), M = h->GetBinLowEdge(Mbin);
59 for (
int bin = 0; bin <= mbin; ++bin) {
60 h->SetBinContent(bin, 0);
61 h->SetBinError (bin, 0);
63 for (
int bin = Mbin+1; bin <= h->GetNbinsX()+1; ++bin) {
64 h->SetBinContent(bin, 0);
65 h->SetBinError (bin, 0);
68 cout <<
"Fitting trigger " << trigger <<
" from " << m <<
" to " << M << endl;
71 TF1 *
f =
new TF1(Form(
"sigmoid%d", trigger),
72 "[0]+0.5*(1-[0])*(1+erf((x-[1])/[2]))",
75 f->SetParNames(
"a",
"#mu",
"#sigma");
78 f->SetParameter(0,0.1);
79 f->SetParLimits(0,0,0.9);
81 f->SetParameter(1,1.1*trigger);
82 f->SetParLimits(1,m,M);
84 f->SetParameter(2,10);
85 f->SetParLimits(2,1,150);
90 float turnon =
GetX(
f);
92 Stream << trigger <<
'\t' << turnon <<
'\n';
◆ getHLTJetResponse()
void DAS::Normalisation::getHLTJetResponse |
( |
const vector< fs::path > & |
inputs, |
|
|
const fs::path & |
output, |
|
|
const pt::ptree & |
config, |
|
|
const int |
steering, |
|
|
const DT::Slice |
slice = {1,0} |
|
) |
| |
Get HLT single-jet response in bins of kinematics in real data. The output can be used as input to fitJetResponse to determine and understand the deviations from the Gaussian expectations, which prevent from fitting the trigger efficiency with the error function.
- Parameters
-
inputs | input ROOT files (n-tuples) |
output | name of output ROOT file (histograms) |
config | config file from `DTOptions` |
steering | steering parameters from `DTOptions` |
slice | slices for running |
49 cout << __func__ <<
' ' << slice <<
" start" << endl;
53 auto tOut = unique_ptr<TTree>(tIn->CloneTree(0));
57 auto isMC = metainfo.Get<
bool>(
"flags",
"isMC");
59 BOOST_THROW_EXCEPTION(
DE::BadInput(
"Only DATA may be used as input.", metainfo) );
61 RecEvent * rEv =
nullptr;
62 tIn->SetBranchAddress(
"recEvent", &rEv);
64 vector<RecJet> *
recjets =
nullptr;
65 vector<FourVector> * hltjets =
nullptr;
66 tIn->SetBranchAddress(
"recJets", &
recjets);
67 tIn->SetBranchAddress(
"hltJets", &hltjets);
69 unique_ptr<TH3> inclResp =
makeRespHist(
"inclusive",
"HLT");
71 for (
DT::Looper looper(tIn, slice); looper(); ++looper) {
75 auto recWgt = rEv->weights.front();
80 auto pthlt = hltjet.Pt();
82 int pthltbin = inclResp->GetXaxis()->FindBin(pthlt);
83 double hlt_lowedge = inclResp->GetXaxis()->GetBinLowEdge(pthltbin);
89 inclResp->Fill(pthlt, yrec,
response, recWgt);
95 inclResp->SetDirectory(fOut.get());
96 inclResp->SetTitle(
"Response");
97 inclResp->Write(
"Response");
100 metainfo.Set<
bool>(
"git",
"complete",
true);
103 cout << __func__ <<
' ' << slice <<
" end" << endl;
◆ GetNormFactor()
float DAS::Normalisation::GetNormFactor |
( |
const fs::path & |
f_sumWgts, |
|
|
const float |
xsec |
|
) |
| |
Retrieve the sum of the weights obtained with getSumWeights
and combines it with the input cross section to calculate the normalisation factor.
- Parameters
-
f_sumWgts | file containing the hist |
xsec | cross section value |
40 if (!fs::exists(f_sumWgts))
41 BOOST_THROW_EXCEPTION( fs::filesystem_error(f_sumWgts.string() +
" not found"s,
42 make_error_code(errc::no_such_file_or_directory)) );
43 unique_ptr<TFile>
f(TFile::Open(f_sumWgts.c_str()));
44 auto h = unique_ptr<TH2>(
f->Get<TH2>(
"hSumWgt"));
45 auto sumw = h->Integral(0, -1,
48 BOOST_THROW_EXCEPTION(
DE::BadInput(
"Negative sum of weights.", h) );
50 BOOST_THROW_EXCEPTION( invalid_argument(
"Negative cross section.") );
51 auto factor = xsec/sumw;
52 cout << xsec <<
'/' << sumw <<
'=' << factor << endl;
◆ getPrescale()
float DAS::Normalisation::getPrescale |
( |
Trigger * |
trigger, |
|
|
size_t |
indx |
|
) |
| |
99 float preHLT = trigger->PreHLT[indx];
100 float preL1min = trigger->PreL1min[indx];
101 float preL1max = trigger->PreL1max[indx];
102 assert(preL1min == preL1max);
103 float prescale = preHLT * preL1min;
◆ getSumWeights()
void DAS::Normalisation::getSumWeights |
( |
const vector< fs::path > & |
inputs, |
|
|
const fs::path & |
output, |
|
|
const pt::ptree & |
config, |
|
|
const int |
steering, |
|
|
const DT::Slice |
slice = {1,0} |
|
) |
| |
Sum the weights from ROOT n-tuple. Mostly useful for MC to estimate the effective number of events, which is necessary to normalise.
The histogram is filled in a way so that it can be used for two purposes:
- provide a distribution of the weights and choose a max weight,
- extract the normalisation factor by takaing its integral.
- Note
- The values beyond
maxAbsValue
are filled a 2nd time in the overflow with the opposite weight. The truncated sum of the weights is then obtained from the integral by including the overflow.
- Parameters
-
inputs | input ROOT files (n-tuple) |
output | output ROOT file (histograms) |
config | config handled with `Darwin::Tools::Options` |
steering | parameters obtained from explicit options |
slice | number and index of slice |
48 cout << __func__ <<
' ' << slice <<
" start" << endl;
52 auto tOut = unique_ptr<TTree>(tIn->CloneTree(0));
56 auto isMC = metainfo.Get<
bool>(
"flags",
"isMC");
57 if (!
isMC) BOOST_THROW_EXCEPTION(
DE::BadInput(
"Only MC may be used as input.",
58 make_unique<TFile>(
inputs.front().c_str() )) );
60 const auto maxAbsValue =
config.get<
float>(
"corrections.weights.maxAbsValue");
61 const auto mode =
config.get<
string>(
"corrections.weights.mode");
63 cout <<
"maxAbsValue = " << maxAbsValue << endl;
65 GenEvent * evnt =
nullptr;
66 tIn->SetBranchAddress(
"genEvent", &evnt);
68 TString title =
";log_{10}(w);sign;#sum_{i=1}^{events} w_{i}";
69 if (maxAbsValue > 0) title = Form(
"w < %d", maxAbsValue);
70 auto h = make_unique<TH2D>(
"hSumWgt", title, 100, 3, 40,
72 const double overflow = h->GetXaxis()->GetXmax()+1.;
76 else if (mode ==
"signOnly") wm =
SIGN;
77 else if (mode !=
"count" )
78 BOOST_THROW_EXCEPTION( invalid_argument(mode +
" is unknown") );
80 if (maxAbsValue > 0) wm |=
CUTOFF;
82 cout <<
"wm = " << bitset<8>(wm) << endl;
85 cout << setw(20) <<
"w"
87 << setw(20) <<
"x [log10(abs(w))]"
88 << setw(20) <<
"y [sign]"
89 << setw(20) <<
"z [eff. weight]" << endl;
91 for (
DT::Looper looper(tIn, slice); looper(); ++looper) {
95 const double w = evnt->weights.front();
96 if (
w == 0.)
continue;
99 BOOST_THROW_EXCEPTION( runtime_error(
"Infinite or NaN weight:"s +
w) );
105 const double absw = std::abs(
w),
108 double z = wm &
WEIGHT ? absw : 1;
109 if (wm &
SIGN) z = copysign(z,
w);
111 cout << setw(20) <<
w
115 << setw(20) << z << endl;
120 cerr <<
orange <<
"Warning: a good weight is being filled in the overflow.\n" <<
def;
125 if ((wm &
CUTOFF) && absw >= maxAbsValue)
126 h->Fill(overflow, y, -z);
129 metainfo.Set<
bool>(
"git",
"complete",
true);
134 cout << __func__ <<
' ' << slice <<
" end" << endl;
◆ getTriggerCurves()
void DAS::Normalisation::getTriggerCurves |
( |
const vector< fs::path > & |
inputs, |
|
|
const fs::path & |
output, |
|
|
const pt::ptree & |
config, |
|
|
const int |
steering, |
|
|
const DT::Slice |
slice = {1,0} |
|
) |
| |
Get trigger curves from the data n-tuples.
- Todo:
- fix error
- Todo:
- fix error
- Parameters
-
inputs | input ROOT file (n-tuple) |
output | output ROOT file (n-tuple) |
config | config handled with `Darwin::Tools::options` |
steering | parameters obtained from explicit options |
slice | number and index of slice |
122 auto tOut = unique_ptr<TTree>(tIn->CloneTree(0));
127 const auto usePrescales =
config.get<
bool>(
"corrections.normalisation.use_prescales");
128 metainfo.Set<
bool>(
"corrections",
"normalisation",
"use_prescales", usePrescales);
130 auto lumi_file =
config.get<fs::path>(
"corrections.normalisation.luminosities");
131 pt::ptree triggers_lumi;
132 pt::read_info(lumi_file.string(), triggers_lumi);
133 for (
auto const& trigger_lumi: triggers_lumi)
134 thresholds.push_back(stoi(trigger_lumi.first));
136 metainfo.Set<fs::path>(
"corrections",
"normalisation",
"luminosities", lumi_file);
138 Trigger * trigger =
nullptr;
139 tIn->SetBranchAddress(
"jetTrigger", &trigger);
141 vector<RecJet> *
recjets =
nullptr;
142 vector<FourVector> * hltjets =
nullptr;
143 tIn->SetBranchAddress(
"recJets", &
recjets);
144 tIn->SetBranchAddress(
"hltJets", &hltjets);
146 map<TString, size_t> methods {
148 {
"emulationShift", 2},
153 TH1 * Deta =
new TH1F(
"deta",
"; #Delta #eta; nevt", 200, -5, 5);
154 TH1 * Dphi =
new TH1F(
"dphi",
"; #Delta #phi; nevt", 200, -M_PI, M_PI);
155 TH1 * dR =
new TH1F(
"dR" ,
"; #Delta R; nevt" , 200, 0, 10);
157 map<TString, map<int, Efficiency>> curves;
158 for (
auto method: methods)
161 cout <<
method.first <<
'\t' << t <<
'\n';
162 curves[
method.first].insert( {t, Efficiency(
method.first, t)} );
166 for (
DT::Looper looper(tIn, slice); looper(); ++looper) {
171 size_t nbits = trigger->Bit.size();
173 BOOST_THROW_EXCEPTION(
DE::AnomalousEvent( Form(
"nbits = %ld < thresholds.size() = %ld",
177 if (
recjets->size() == 0)
continue;
179 for (
const RecJet& pfjet: *
recjets){
183 Deta->Fill(pfjet.p4.Eta() - hltjet.Eta(), pfjet.weights.front());
184 Dphi->Fill(DeltaPhi(pfjet.p4,hltjet), pfjet.weights.front());
185 dR->Fill(DeltaR(pfjet.p4, hltjet), pfjet.weights.front());
186 pt_correlation->Fill(pfjet.CorrPt(), hltjet.Pt(), pfjet.weights.front());
193 if (leadingInTk ==
recjets->end())
continue;
196 pfjet0 *= leadingInTk->scales.front();
202 for (
auto method: methods) {
204 if (
method.first.Contains(
"TnP"))
continue;
205 size_t shift =
method.second;
207 for (
size_t i = shift; i <
thresholds.size(); ++i) {
210 auto& eff = curves.at(
method.first).at(t);
212 eff.hAll->Fill(pfjet0.Pt(), hltjet0.Pt());
215 if (!trigger->Bit[i-shift])
continue;
216 eff.hFired->Fill(pfjet0.Pt(), hltjet0.Pt());
218 if (hltjet0.Pt() <
thresholds.at(i-shift))
continue;
219 eff.hFiredThreshold->Fill(pfjet0.Pt(), hltjet0.Pt());
221 float wgt = usePrescales ?
getPrescale(trigger, i-shift) : 1;
222 bool fired = hltjet0.Pt() > t;
223 eff.Fill(pfjet0, fired, wgt*
recjets->front().weights.front());
225 eff.hHLTmap->Fill( pfjet0.Phi(),pfjet0.Eta(),wgt*
recjets->front().weights.front() );
230 for (
size_t i = 0; i <
thresholds.size(); ++i) {
233 auto& eff = curves.at(
"TnP").at(t);
235 eff.hAll->Fill(pfjet0.Pt(), hltjet0.Pt());
238 if (!trigger->Bit[i])
240 eff.hFired->Fill(pfjet0.Pt(), hltjet0.Pt());
247 if (DeltaPhi(
recjets->at(0).p4,
recjets->at(1).p4) < 2.4)
continue;
250 const double pt0 =
recjets->at(0).CorrPt(),
253 if (pt2 > 0.15*(pt0 + pt1))
258 static TRandom3 Rand( metainfo.Seed<10989678>(slice));
259 double r = Rand.Uniform();
264 pfprobe =
recjets->at(iprobe).p4;
266 float pfprobe_wgt =
recjets->at(iprobe).weights.front();
267 float pftag_wgt =
recjets->at(itag).weights.front();
269 pftag *=
recjets->at(itag ).scales.front();
270 pfprobe *=
recjets->at(iprobe).scales.front();
273 if (std::abs(
recjets->at(itag).p4.Eta()) > 1.3)
continue;
284 if (hlttag.Pt() > t) {
285 eff.hFiredThreshold->Fill(pfjet0.Pt(), hltjet0.Pt());
288 bool fired = hltprobe.Pt() > t;
290 float wgt = usePrescales ?
getPrescale(trigger, i) : 1;
291 eff.Fill(pfprobe, fired, wgt * pftag_wgt * pfprobe_wgt);
292 eff.hHLTmap->Fill( pfjet0.Phi(),pfjet0.Eta(),wgt*
recjets->front().weights.front() );
297 cout <<
"Writing to file" << endl;
298 for (
auto&
method: curves) {
300 auto d = fOut->mkdir(
method.first);
301 for (
auto& curve:
method.second)
302 curve.second.Write(d);
308 pt_correlation->Write();
310 metainfo.Set<
bool>(
"git",
"complete",
true);
◆ GetTriggerEfficiency()
float DAS::Normalisation::GetTriggerEfficiency |
( |
int |
trigger, |
|
|
TH1 * |
h, |
|
|
STREAM & |
Stream, |
|
|
float |
from, |
|
|
float |
minEff |
|
) |
| |
DON'T fit the trigger efficiency but just find the first bin above threshold
- Todo:
- Where does the factor 6 come from?
- Parameters
-
trigger | trigger HLT threshold |
h | efficiency histogram |
Stream | `cout` or file |
from | last turnon, to know from where the ref is efficient |
minEff | min efficiency (e.g. different for barrel and forward region) |
107 int mbin = h->GetXaxis()->FindBin( from),
108 Mbin = h->GetXaxis()->FindBin(6*from);
109 for (
int bin = 0; bin < mbin; ++bin) {
110 h->SetBinContent(bin, 0);
111 h->SetBinError (bin, 0);
113 for (
int bin = Mbin+1; bin <= h->GetNbinsX()+1; ++bin) {
114 h->SetBinContent(bin, 0);
115 h->SetBinError (bin, 0);
117 for (
int bin = mbin; bin <= Mbin; ++bin) {
118 float content = h->GetBinContent(bin);
119 if (content < minEff)
continue;
120 float turnon = h->GetBinLowEdge(bin);
121 Stream << trigger <<
'\t' << turnon <<
'\n';
◆ getTriggerTurnons()
void DAS::Normalisation::getTriggerTurnons |
( |
const fs::path & |
input, |
|
|
const fs::path & |
outputRoot, |
|
|
const fs::path & |
outputTxt, |
|
|
const pt::ptree & |
config, |
|
|
const int |
steering |
|
) |
| |
Get the trigger turn-on points from the trigger curves.
- Todo:
- Use metainfo
- Todo:
- Get year from metainfo?
- Todo:
- Get lumis from metainfo?
- Todo:
- implement a more general logic to use only rapidity <3 turnons to determine the overall turnon
- Parameters
-
input | input ROOT file (n-tuple) |
outputRoot | output ROOT file with efficiency |
outputTxt | output text file with turn-ons |
config | config handled with `Darwin::Tools::options` |
steering | parameters obtained from explicit options |
46 cout << __func__ <<
" start" << endl;
55 cout << setw(10) <<
"trigger";
56 for (
auto yBin:
yBins) cout << setw(18) << yBin;
59 pt::ptree triggers_lumi;
60 auto lumi_file =
config.get<fs::path>(
"corrections.normalisation.luminosities");
61 pt::read_info(lumi_file.c_str(), triggers_lumi);
62 vector<int> triggerThresholds;
63 for (
auto trigger_lumi: triggers_lumi)
64 triggerThresholds.push_back(stoi(trigger_lumi.first));
66 auto fIn = make_unique<TFile>(
input.c_str(),
"READ");
67 map<int, int> turnonsFinal;
68 TIter Next(fIn->GetListOfKeys()) ;
70 TString defMethod =
"TnP";
71 while ( (
key =
dynamic_cast<TKey*
>(Next())) ) {
72 if (TString(
key->ReadObj()->ClassName()) != TString(
"TDirectoryFile"))
76 auto dIn =
dynamic_cast<TDirectory*
>(
key->ReadObj());
78 int lastturnon = triggerThresholds.front();
81 TString
method = dIn->GetName();
85 auto dOut = fOut->mkdir(
method);
87 TIter Next2(dIn->GetListOfKeys()) ;
88 while ( (
key =
dynamic_cast<TKey*
>(Next2())) ) {
89 if (TString(
key->ReadObj()->ClassName()) != TString(
"TDirectoryFile"))
93 auto ddIn =
dynamic_cast<TDirectory*
>(
key->ReadObj());
95 TString trigName = ddIn->GetName();
96 assert(trigName.Contains(
"HLT"));
99 auto ddOut = dOut->mkdir(trigName);
101 trigName.ReplaceAll(
"HLT",
"");
102 int trigger = trigName.Atoi();
103 if (
method ==
"TnP" && trigger < triggerThresholds.at(0))
continue;
104 if (
method ==
"emulation" && trigger < triggerThresholds.at(1))
continue;
105 if (
method ==
"emulationShift" && trigger < triggerThresholds.at(2))
continue;
106 cout << setw(10) << trigger;
108 auto h2 = unique_ptr<TH2>(ddIn->Get<TH2>(
"test"));
110 auto den = unique_ptr<TH2>(ddIn->Get<TH2>(
"ref"));
111 h2->Divide(h2.get(), den.get(), 1, 1,
"B");
116 h2->SetDirectory(ddOut);
117 h2->SetName(
"efficiency");
119 vector<int> turnonsNow;
120 for (
int y = 1; y <= h2->GetNbinsY(); ++y) {
123 auto h1 = unique_ptr<TH1>(h2->ProjectionX(Form(
"efficiency_ybin%d", y), y, y));
125 static ostream bitBucket(0);
139 float from = h1->GetBinLowEdge(h1->FindBin(lastturnon)+1);
141 h1->SetTitle(Form(
"%d (%.3f)", turnon,
threshold));
142 h1->SetDirectory(dOut);
144 turnonsNow.push_back(turnon);
149 auto maxturnon = max_element(turnonsNow.begin(), turnonsNow.begin()+6);
150 h2->SetTitle(Form(
"%d", *maxturnon));
152 for (
auto turnon: turnonsNow) {
153 if (turnon == *maxturnon) cout <<
"\x1B[32m\e[1m";
154 if (turnon < 0) cout <<
"\x1B[31m\e[1m";
155 cout << setw(18) << turnon;
156 cout <<
"\x1B[30m\e[0m";
162 turnonsFinal[trigger] = *maxturnon;
164 defMethod =
"emulation";
165 lastturnon = *maxturnon;
167 if (lastturnon == -1) {
168 cerr <<
"Didn't find any turnon for trigger " << trigger <<
'\n';
169 lastturnon = trigger;
174 pt::ptree turnon_file;
175 for (
auto& turnon: turnonsFinal)
176 turnon_file.put<
int>(to_string(turnon.first), turnon.second);
177 pt::write_info(outputTxt.string(), turnon_file);
179 cout << __func__ <<
" end" << endl;
◆ GetX()
float DAS::Normalisation::GetX |
( |
TF1 * |
f | ) |
|
Replaces TF1::GetX() which does not return the same value when run after compilation or in interactive mode...
Principle: just scan the pt axis with step = 1 until eff > 0.995
22 double m = 0, M = 7000;
25 for (
float pt = m;
pt < M; ++
pt)
29 cerr <<
"No threshold was found from " << m <<
" to " << M <<
".\nAborting.\n";
◆ makeRespHist()
unique_ptr<TH3> DAS::Normalisation::makeRespHist |
( |
TString |
name, |
|
|
TString |
study |
|
) |
| |
Create TH3 histograms for the Jet response and HLT response.
- Parameters
-
name | abitrary name |
study | expecting JER or HLT |
25 static int nResBins = 200;
26 static auto resBins =
getBinning(nResBins, 0, 2);
30 static const char * axistitles =
";p_{T}^{HLT};|#eta^{rec}|;#frac{p_{T}^{rec}}{p_{T}^{HLT bin low edge}}";
31 static const vector<double> HLT_binning = {40., 60., 80., 140., 200., 260., 320., 400., 450., 500.};
32 static int nHLTbins = HLT_binning.size()-1;
33 h = make_unique<TH3D>(
name, axistitles,
34 nHLTbins, HLT_binning.data(),
36 nResBins, resBins.data());
38 else if (study ==
"JER"){
41 static const char * axistitles =
";p_{T}^{gen};|#eta^{rec}|;#frac{p_{T}^{rec}}{p_{T}^{gen}}";
42 h = make_unique<TH3D>(
name, axistitles,
45 nResBins, resBins.data());
48 h->SetDirectory(
nullptr);
◆ match()
8 for (
const auto& hltjet: *hltJets){
9 using ROOT::Math::VectorUtil::DeltaR;
10 if (DeltaR(hltjet, jet) < 0.3)
◆ operator<<()
std::ostream& DAS::Normalisation::operator<< |
( |
std::ostream & |
Stream, |
|
|
const TriggerLumi & |
tr_lu |
|
) |
| |
25 Stream << tr_lu.pt <<
'\t' << tr_lu.turnon <<
'\t' << tr_lu.weight <<
'\t' << 1./tr_lu.weight;
◆ phaseSel()
10 auto leadingInTk =
recjets.begin();
11 while (leadingInTk !=
recjets.end()
12 && std::abs(leadingInTk->Rapidity()) >= 3.0)
◆ reset()
void DAS::Normalisation::reset |
( |
Weights & |
wgts, |
|
|
const double |
v = 0 |
|
) |
| |
|
inline |
28 {
std::fill(wgts.begin(), wgts.end(), Weight{v,0}); }
◆ nThresholds
◆ threshold
const float threshold = 0.995 |
◆ thresholds
vector<double> thresholds |
name
Definition: DYToLL_M-50_13TeV_pythia8_cff_GEN_SIM_RECOBEFMIX_DIGI_L1_DIGI2RAW_L1Reco_RECO.py:48
std::vector< DAS::RecJet >::iterator phaseSel(std::vector< DAS::RecJet > &recjets)
Definition: PhaseSelection.h:9
method
Definition: Core-gitclone-lastrun.txt:5
cerr
Definition: Ntupliser_cfg.py:93
static const std::vector< double > y_edges
Definition: binnings.h:36
options
Definition: DYToLL_M-50_13TeV_pythia8_cff_GEN_SIM_RECOBEFMIX_DIGI_L1_DIGI2RAW_L1Reco_RECO.py:41
pt
Definition: jmarExample.py:19
static bool verbose
Definition: Step.h:40
vector< double > thresholds
Definition: getTriggerCurves.cc:44
static const char * def
Definition: Step.h:36
FourVector p4
raw four-momentum directly after reconstruction
Definition: PhysicsObject.h:47
int nThresholds
Definition: getTriggerCurves.cc:45
int year
Definition: Ntupliser_cfg.py:63
source
Definition: DYToLL_M-50_13TeV_pythia8_cff_GEN_SIM_RECOBEFMIX_DIGI_L1_DIGI2RAW_L1Reco_RECO.py:39
static const std::vector< double > pt_JERC_edges
Definition: common.h:17
static const std::vector< double > pt_edges
Definition: binnings.h:33
f
Definition: Ntupliser_cfg.py:252
string key
Definition: jercExample.py:109
std::vector< double > getBinning(int nBins, float first, float last)
Definition: common.h:53
static const float w
Definition: common.h:51
@ SIGN
use the sign
Definition: getSumWeights.cc:29
unique_ptr< TH3 > makeRespHist(TString name, TString study)
Create TH3 histograms for the Jet response and HLT response.
Definition: MakeResponseHistos.h:20
float AbsRap(const Uncertainties::Variation &=Uncertainties::nominal) const
absolute rapidity
Definition: PhysicsObject.h:54
genjets
Definition: Ntupliser_cfg.py:268
DAS::RecJet recjet
Definition: classes.h:15
DAS::Weight weight
Definition: classes.h:11
@ WEIGHT
use the weights
Definition: getSumWeights.cc:28
config
Definition: Ntupliser_cfg.py:260
static const char * orange
Definition: colours.h:6
input
Definition: DYToLL_M-50_13TeV_pythia8_cff_GEN_SIM_RECOBEFMIX_DIGI_L1_DIGI2RAW_L1Reco_RECO.py:35
recjets
Definition: Ntupliser_cfg.py:269
static const std::vector< double > abseta_edges
JERC binning (taken from JERCProtoLab repo, /macros/common_info/common_binning.hpp)
Definition: common.h:22
float CorrPt(size_t i=0) const
corrected transverse momentum
Definition: PhysicsObject.h:52
static const int nPtBins
Definition: binnings.h:39
DAS::PileUp pileup
Definition: classes.h:27
bool branchExists(const TTreePtr &tree, TString brName)
Definition: toolbox.h:27
string isMC
Definition: Ntupliser_cfg.py:59
const float threshold
Definition: sigmoid.h:14
def inputs
Definition: jercExample.py:118
DAS::FourVector match(const DAS::FourVector &jet, const std::vector< DAS::FourVector > *hltJets)
Definition: match.h:7
Generic exception for problematic event (during event loop).
Definition: exceptions.h:48
float GetNormFactor(const fs::path &f_sumWgts, const float xsec)
Definition: applyMClumi.cc:37
ROOT::Math::LorentzVector< ROOT::Math::PtEtaPhiM4D< float > > FourVector
Definition: PhysicsObject.h:15
static const int nPtJERCbins
Definition: common.h:18
float GetTriggerEfficiency(int trigger, TH1 *h, STREAM &Stream, float from, float minEff)
Definition: sigmoid.h:101
@ CUTOFF
apply a selection on the weight
Definition: getSumWeights.cc:30
float getPrescale(Trigger *trigger, size_t indx)
Definition: getTriggerCurves.cc:97
Definition: applyJERsmearing.cc:41
#define DT_GetOutput(output)
Definition: FileUtils.h:222
static const int nYbins
Definition: binnings.h:38
float GetX(TF1 *f)
Definition: sigmoid.h:20
static const std::vector< TString > yBins
Definition: binnings.h:44
static const int nAbsEtaBins
Definition: common.h:23