Apply the PU profile reweighting to the simulation.
47 cout << __func__ <<
' ' << slice <<
" start" << endl;
50 auto tIn = flow.GetInputTree(
inputs, slice);
51 auto [fOut, tOut] = flow.GetOutput(output);
55 auto isMC = metainfo.Get<
bool>(
"flags",
"isMC");
56 if (!
isMC) BOOST_THROW_EXCEPTION(
DE::BadInput(
"Only MC may be used as input.",
57 make_unique<TFile>(
inputs.front().c_str() )) );
59 auto genEvt = flow.GetBranchReadOnly<GenEvent>(
"genEvent");
60 auto recEvt = flow.GetBranchReadOnly<RecEvent>(
"recEvent");
61 auto pu = flow.GetBranchReadOnly<PileUp >(
"pileup" );
62 auto genJets = flow.GetBranchReadWrite<vector<GenJet>>(
"genJets");
63 auto recJets = flow.GetBranchReadWrite<vector<RecJet>>(
"recJets");
66 ControlPlots raw(
"raw");
67 bool applySyst = steering &
DT::syst;
68 vector<ControlPlots> calib { ControlPlots(
"nominal") };
70 metainfo.Set<
string>(
"variations", RecEvent::WeightVar,
"PU" +
SysUp);
71 metainfo.Set<
string>(
"variations", RecEvent::WeightVar,
"PU" +
SysDown);
73 calib.push_back(ControlPlots(
"PU" +
SysUp));
74 calib.push_back(ControlPlots(
"PU" +
SysDown));
77 auto turnon_file =
config.get<fs::path>(
"corrections.normalisation.turnons");
78 auto DataProf =
config.get<fs::path>(
"corrections.PUprofile.Data");
79 auto MCprof =
config.get<fs::path>(
"corrections.PUprofile.MC");
80 for (
auto& file: {turnon_file, DataProf, MCprof})
81 if (!fs::exists(file))
82 BOOST_THROW_EXCEPTION( fs::filesystem_error(
"Input file could not be found",
83 file, make_error_code(errc::no_such_file_or_directory)));
86 pt::read_info(turnon_file.c_str(), turnons);
88 auto fMCprof = TFile::Open(MCprof.c_str(),
"READ"),
89 fDataProf = TFile::Open(DataProf.c_str(),
"READ");
90 map<float, PUprofile::Correction> corrections;
91 auto maxWeight =
config.get<
float>(
"corrections.PUprofile.maxWeight");
92 for (
auto& turnon: turnons) {
93 auto threshold = atoi(turnon.first.c_str());
94 auto trigger = [
threshold](
const char * variation,
bool global) {
95 return global ? Form(
"%s/intPU" , variation)
96 : Form(
"%s/HLT_PFJet%d/intPU", variation,
threshold);
98 auto pt = turnon.second.get_value<
float>();
99 PUprofile::Correction correction(fMCprof, fDataProf, trigger, maxWeight);
100 corrections.insert( {
pt, correction} );
102 const bool hasZB = fDataProf->GetDirectory(
"nominal/ZB") &&
dynamic_cast<TH1*
>(fDataProf->Get(
"nominal/ZB/intPU"))->Integral() > 0;
105 auto trigger = [](
const char * variation,
bool global) {
106 return global ? Form(
"%s/intPU" , variation)
107 : Form(
"%s/ZB/intPU", variation);
109 PUprofile::Correction correction(fMCprof, fDataProf, trigger, maxWeight);
110 corrections.insert( {0, correction} );
115 metainfo.Set<fs::path>(
"corrections",
"normalisation",
"turnons", turnon_file);
116 metainfo.Set<fs::path>(
"corrections",
"PUprofile",
"Data", DataProf);
117 metainfo.Set<fs::path>(
"corrections",
"PUprofile",
"MC", MCprof);
118 metainfo.Set<
float>(
"corrections",
"PUprofile",
"maxWeight", maxWeight);
120 PileUp::r3.SetSeed(metainfo.Seed<756347956>(slice));
121 for (
DT::Looper looper(tIn); looper(); ++looper) {
125 int intpu = pu->intpu;
126 auto weight_raw = recEvt->weights.front();
129 auto pt0 = corrections.begin()->first;
130 auto InTk = [](
const auto& jet) {
return jet.AbsRap() < 3.0; };
131 auto leadRecJetInTk = find_if(recJets->begin(), recJets->end(), InTk);
132 if (leadRecJetInTk != recJets->end())
133 pt0 = leadRecJetInTk->CorrPt();
135 auto leadGenJetInTk = find_if(genJets->begin(), genJets->end(), InTk);
136 if (leadGenJetInTk != genJets->end())
137 pt0 = leadGenJetInTk->p4.Pt();
140 auto it = find_if(corrections.rbegin(), prev(corrections.rend()),
141 [&pt0](
const auto& th_corr) { return pt0 > th_corr.first; });
142 const auto& correction = it->second;
143 cout << pt0 <<
' ' << it->first << endl;
146 auto nominal_correction = correction(intpu,
'0');
147 recEvt->weights *= nominal_correction;
149 auto weight_nominal = recEvt->weights.front();
152 raw (*genJets, genEvt->weights.front());
153 calib.front()(*genJets, genEvt->weights.front());
156 raw (*recJets, genEvt->weights.front() * weight_raw );
157 calib.front()(*recJets, genEvt->weights.front() * weight_nominal);
161 auto weight_upper = weight_raw*correction(intpu,
'+'),
162 weight_lower = weight_raw*correction(intpu,
'-');
163 recEvt->weights.push_back(Weight{weight_upper});
164 recEvt->weights.push_back(Weight{weight_lower});
165 calib.at(1)(*genJets, genEvt->weights.front());
166 calib.at(2)(*genJets, genEvt->weights.front());
167 calib.at(1)(*recJets, genEvt->weights.front() * weight_upper);
168 calib.at(2)(*recJets, genEvt->weights.front() * weight_lower);
172 if (steering &
DT::fill) tOut->Fill();
175 auto d = fOut->mkdir(
"corrections");
176 for (
auto& correction: corrections) {
179 auto it = turnons.begin();
180 while (it != turnons.end()) {
181 if (it->second.get_value<
int>() ==
threshold)
break;
186 if (it != turnons.end()) {
187 auto dd = d->mkdir(Form(
"HLT_PFJet%d", atoi(it->first.c_str())));
188 bool reset = slice.second > 0;
189 correction.second.Write(dd,
reset);
192 auto dd = d->mkdir(
"ZB");
193 bool reset = slice.second > 0;
194 correction.second.Write(dd,
reset);
202 metainfo.Set<
bool>(
"git",
"complete",
true);
204 cout << __func__ <<
' ' << slice <<
" end" << endl;