Apply the PU profile reweighting to the simulation.
47 cout << __func__ <<
' ' << slice <<
" start" << endl;
51 auto tOut = unique_ptr<TTree>(tIn->CloneTree(0));
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 RecEvent * recEvt =
nullptr;
60 GenEvent * genEvt =
nullptr;
61 PileUp * pu =
nullptr;
62 tIn->SetBranchAddress(
"recEvent", &recEvt);
64 tIn->SetBranchAddress(
"genEvent", &genEvt);
65 tIn->SetBranchAddress(
"pileup", &pu);
67 vector<RecJet> * recJets =
nullptr;
68 vector<GenJet> * genJets =
nullptr;
69 tIn->SetBranchAddress(
"recJets", &recJets);
70 tIn->SetBranchAddress(
"genJets", &genJets);
73 ControlPlots raw(
"raw");
74 bool applySyst = steering &
DT::syst;
75 vector<ControlPlots> calib { ControlPlots(
"nominal") };
77 metainfo.Set<
string>(
"variations", RecEvent::WeightVar,
"PU" +
SysUp);
78 metainfo.Set<
string>(
"variations", RecEvent::WeightVar,
"PU" +
SysDown);
80 calib.push_back(ControlPlots(
"PU" +
SysUp));
81 calib.push_back(ControlPlots(
"PU" +
SysDown));
84 auto turnon_file =
config.get<fs::path>(
"corrections.normalisation.turnons");
85 auto DataProf =
config.get<fs::path>(
"corrections.PUprofile.Data");
86 auto MCprof =
config.get<fs::path>(
"corrections.PUprofile.MC");
87 for (
auto& file: {turnon_file, DataProf, MCprof})
88 if (!fs::exists(file))
89 BOOST_THROW_EXCEPTION( fs::filesystem_error(
"Input file could not be found",
90 file, make_error_code(errc::no_such_file_or_directory)));
93 pt::read_info(turnon_file.c_str(), turnons);
95 auto fMCprof = TFile::Open(MCprof.c_str(),
"READ"),
96 fDataProf = TFile::Open(DataProf.c_str(),
"READ");
97 map<float, PUprofile::Correction> corrections;
98 auto maxWeight =
config.get<
float>(
"corrections.PUprofile.maxWeight");
99 for (
auto& turnon: turnons) {
100 auto threshold = atoi(turnon.first.c_str());
101 auto trigger = [
threshold](
const char * variation,
bool global) {
102 return global ? Form(
"%s/intPU" , variation)
103 : Form(
"%s/HLT_PFJet%d/intPU", variation,
threshold);
105 auto pt = turnon.second.get_value<
float>();
106 PUprofile::Correction correction(fMCprof, fDataProf, trigger, maxWeight);
107 corrections.insert( {
pt, correction} );
109 const bool hasZB = fDataProf->GetDirectory(
"nominal/ZB") &&
dynamic_cast<TH1*
>(fDataProf->Get(
"nominal/ZB/intPU"))->Integral() > 0;
112 auto trigger = [](
const char * variation,
bool global) {
113 return global ? Form(
"%s/intPU" , variation)
114 : Form(
"%s/ZB/intPU", variation);
116 PUprofile::Correction correction(fMCprof, fDataProf, trigger, maxWeight);
117 corrections.insert( {0, correction} );
122 metainfo.Set<fs::path>(
"corrections",
"normalisation",
"turnons", turnon_file);
123 metainfo.Set<fs::path>(
"corrections",
"PUprofile",
"Data", DataProf);
124 metainfo.Set<fs::path>(
"corrections",
"PUprofile",
"MC", MCprof);
125 metainfo.Set<
float>(
"corrections",
"PUprofile",
"maxWeight", maxWeight);
127 PileUp::r3.SetSeed(metainfo.Seed<756347956>(slice));
128 for (
DT::Looper looper(tIn, slice); looper(); ++looper) {
132 int intpu = pu->intpu;
133 auto weight_raw = recEvt->weights.front();
136 auto pt0 = corrections.begin()->first;
137 auto InTk = [](
const auto& jet) {
return jet.AbsRap() < 3.0; };
138 auto leadRecJetInTk = find_if(recJets->begin(), recJets->end(), InTk);
139 if (leadRecJetInTk != recJets->end())
140 pt0 = leadRecJetInTk->CorrPt();
142 auto leadGenJetInTk = find_if(genJets->begin(), genJets->end(), InTk);
143 if (leadGenJetInTk != genJets->end())
144 pt0 = leadGenJetInTk->p4.Pt();
147 auto it = find_if(corrections.rbegin(), prev(corrections.rend()),
148 [&pt0](
const auto& th_corr) { return pt0 > th_corr.first; });
149 const auto& correction = it->second;
150 cout << pt0 <<
' ' << it->first << endl;
153 auto nominal_correction = correction(intpu,
'0');
154 recEvt->weights *= nominal_correction;
156 auto weight_nominal = recEvt->weights.front();
159 raw (*genJets, genEvt->weights.front());
160 calib.front()(*genJets, genEvt->weights.front());
163 raw (*recJets, genEvt->weights.front() * weight_raw );
164 calib.front()(*recJets, genEvt->weights.front() * weight_nominal);
168 auto weight_upper = weight_raw*correction(intpu,
'+'),
169 weight_lower = weight_raw*correction(intpu,
'-');
170 recEvt->weights.push_back(Weight{weight_upper});
171 recEvt->weights.push_back(Weight{weight_lower});
172 calib.at(1)(*genJets, genEvt->weights.front());
173 calib.at(2)(*genJets, genEvt->weights.front());
174 calib.at(1)(*recJets, genEvt->weights.front() * weight_upper);
175 calib.at(2)(*recJets, genEvt->weights.front() * weight_lower);
179 if (steering &
DT::fill) tOut->Fill();
182 auto d = fOut->mkdir(
"corrections");
183 for (
auto& correction: corrections) {
186 auto it = turnons.begin();
187 while (it != turnons.end()) {
188 if (it->second.get_value<
int>() ==
threshold)
break;
193 if (it != turnons.end()) {
194 auto dd = d->mkdir(Form(
"HLT_PFJet%d", atoi(it->first.c_str())));
195 bool reset = slice.second > 0;
196 correction.second.Write(dd,
reset);
199 auto dd = d->mkdir(
"ZB");
200 bool reset = slice.second > 0;
201 correction.second.Write(dd,
reset);
205 raw.Write(fOut.get());
209 metainfo.Set<
bool>(
"git",
"complete",
true);
213 cout << __func__ <<
' ' << slice <<
" end" << endl;