ATLAS Offline Software
Loading...
Searching...
No Matches
PileupReweightingTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5
6
8
9
11
13
14// For Trigger decision conditions
16
19
20#ifndef XAOD_STANDALONE
21#include "GaudiKernel/ITHistSvc.h"
22#endif
23
24#ifdef XAOD_STANDALONE
26#endif
27
28#include "TH1.h"
29#include "TTree.h"
30
31
32namespace CP {
33
35 m_inConfigMode(false),
36 m_upTool(), m_downTool(), m_systUp("PRW_DATASF", 1 ), m_systDown("PRW_DATASF", -1),
37 m_activeTool(this),
38 m_noWeightsMode(false),
39#ifdef XAOD_STANDALONE
40 m_defaultWeightTool( new McEventWeight( "DefaultWeightTool" ) ),
41#endif // XAOD_STANDALONE
42 m_weightTool("McEventWeight/myWeightTool"),
43 m_grlTool(""), m_tdt("") {
44
46
47#ifndef XAOD_STANDALONE
48 declareProperty("ConfigOutputStream", m_configStream="", "When creating PRW config files, this is the THistSvc stream it goes into. If blank, it wont write this way");
49#endif
50
51 declareProperty("ConfigFiles", m_prwFiles, "List of prw config files"); //array of files
52 declareProperty("ConfigFilesPathPrefix", m_prwFilesPathPrefix="", "Path of additional folder structure in prw config files"); //string prefix
53 declareProperty("LumiCalcFiles", m_toolLumicalcFiles, "List of lumicalc files, in the format '<filename>:<trigger>' .. if no trigger given, 'None' is assumed"); //array of files
54 declareProperty("Prefix",m_prefix="","Prefix to attach to all decorations ... only used in the 'apply' method");
55 declareProperty("UnrepresentedDataAction",m_unrepresentedDataAction=3,"1 = remove unrepresented data, 2 = leave it there, 3 = reassign it to nearest represented bin");
56 declareProperty("UnrepresentedDataThreshold",m_unrepDataTolerance=0.05,"When unrepresented data is above this level, will require the PRW config file to be repaired");
57 declareProperty("UseMultiPeriods",m_useMultiPeriods=true,"If true, will try to treat each mc runNumber in a single mc dataset (channel) as a modelling a distinct period of data taking");
58 declareProperty("UseRunDependentPrescaleWeight",m_useRunDependentPrescaleWeight=false,"If true, prescale weights in the getCombinedWeight method with Trigger string are determined with the specific random run number");
59 declareProperty("DataScaleFactor",m_dataScaleFactorX=1./1.03);
60 declareProperty("UsePeriodConfig",m_usePeriodConfig="auto","Use this period configuration when in config generating mode. Set to 'auto' to auto-detect");
61 declareProperty("IgnoreBadChannels",m_ignoreBadChannels=true,"If true, will ignore channels with too much unrepresented data, printing a warning for them");
62 declareProperty("DataScaleFactorUP",m_upVariation=1./0.99,"Set to a value representing the 'up' fluctuation - will report a PRW_DATASF uncertainty to Systematic Registry");
63 declareProperty("DataScaleFactorDOWN",m_downVariation=1./1.07,"Set to a value representing the 'down' fluctuation - will report a PRW_DATASF uncertainty to Systematic Registry");
64 declareProperty("VaryRandomRunNumber",m_varyRunNumber=false,"If true, then when doing systematic variations, RandomRunNumber will fluctuate as well. Off by default as believed to lead to overestimated uncertainties");
65 declareProperty("PeriodAssignments", m_customPeriods={284500,222222,324300,300000,324300,344495,310000,344496,367384,410000,422633,440613,450000,450360,461002,470000,472553,999999}, "Specify period number assignments to run numbers ranges - this is usually an expert option");
66 declareProperty("GRLTool", m_grlTool, "If you provide a GoodRunsListSelectionTool, any information from lumicalc files will be automatically filtered" );
67 declareProperty("TrigDecisionTool",m_tdt, "When using the getDataWeight method, the TDT will be used to check decisions before prescale. Alternatively do expert()->SetTriggerBit('trigger',0) to flag which triggers are not fired before prescale (assumed triggers are fired if not specified)");
68
69#ifdef XAOD_STANDALONE
71 "The tool to compute the weight in the sumOfWeights" );
72#else
73 declareProperty( "WeightTool", m_weightTool,
74 "The tool to compute the weight in the sumOfWeights" );
75#endif
76
77#ifndef XAOD_STANDALONE
78 //attached update handler to the outputlevel property, so we can pass changes on to the underlying tool
79 auto props = getProperties();
80 for( Gaudi::Details::PropertyBase* prop : props ) {
81 if( prop->name() != "OutputLevel" ) {
82 continue;
83 }
84 prop->declareUpdateHandler( &PileupReweightingTool::updateHandler, this );
85 break;
86 }
87#endif
88}
89
90#ifndef XAOD_STANDALONE
91//rootcore can't do this yet!
92void PileupReweightingTool::updateHandler(Gaudi::Details::PropertyBase& /*p*/) {
93 // commenting this out as it doesn't compile anymore
94 // leaving it to domain expert to decide whether to keep or remove it
95 // //call the original update handler
96 // this->msg_update_handler(p);
97 EnableDebugging(this->msgLvl(MSG::DEBUG));
98}
99#endif
100
101bool PileupReweightingTool::runLbnOK(Int_t runNbr, Int_t lbn) {
102 if(m_grlTool.empty()) return true;
103 return m_grlTool->passRunLB(runNbr,lbn);
104}
105
106bool PileupReweightingTool::passTriggerBeforePrescale(const TString& trigger) const {
107 if(m_tdt.empty()) return TPileupReweighting::passTriggerBeforePrescale(trigger);
108 ATH_MSG_VERBOSE("Checking tdt decision of " << trigger);
109 //Note that the trigger *must* be a rerun trigger if this result is to be valid ... could check this in the trigconf is absolutely necessary
110 //but for now we just assume it's a rerun
111 //if it's not rerun, all we will get back here is the TAP result
112 return m_tdt->isPassed( trigger.Data() , TrigDefs::Physics | TrigDefs::allowResurrectedDecision ); // Definitions in TrigDecisionInterface/Conditions.h
113}
114
116 CP::SystematicSet sys = affectingSystematics(); return sys.find( systematic ) != sys.end();
117}
118
125
129
131 if(systConfig.find( m_systUp ) != systConfig.end() && systConfig.find( m_systDown ) != systConfig.end()) {
132 ATH_MSG_ERROR("Errr... what the!? You're trying to do both PRW_DATASF directions at the same time!!!??");
133 return StatusCode::FAILURE;
134 }
135 if(systConfig.find( m_systUp ) != systConfig.end()) {
136 if(!m_upTool) { ATH_MSG_ERROR("Requested up variation of PRW_DATASF, but not configured to do this :-("); return StatusCode::FAILURE; }
137 m_activeTool = m_upTool.get();
138 }
139 else if(systConfig.find( m_systDown ) != systConfig.end() ) {
140 if(!m_downTool) { ATH_MSG_ERROR("Requested down variation of PRW_DATASF, but not configured to do this :-("); return StatusCode::FAILURE; }
141 m_activeTool = m_downTool.get();
142 }
143 else m_activeTool = this;
144 return StatusCode::SUCCESS;
145}
146
147
148float PileupReweightingTool::getCorrectedAverageInteractionsPerCrossing( const xAOD::EventInfo& eventInfo, bool includeDataScaleFactor ) {
150 return eventInfo.averageInteractionsPerCrossing(); //no correction needed for MC
151 }
152 float out = CP::TPileupReweighting::GetLumiBlockMu(eventInfo.runNumber(),eventInfo.lumiBlock());
153 if(out<0) return out; //will be -1
154 return out * ( (includeDataScaleFactor) ? m_activeTool->GetDataScaleFactor() : 1.);
155}
156
157float PileupReweightingTool::getCorrectedActualInteractionsPerCrossing( const xAOD::EventInfo& eventInfo, bool includeDataScaleFactor ) {
159 return eventInfo.actualInteractionsPerCrossing(); //no correction needed for MC
160 }
161 float correctedMu = CP::TPileupReweighting::GetLumiBlockMu(eventInfo.runNumber(),eventInfo.lumiBlock());
162 if(correctedMu<0) return correctedMu; //will be -1
163 return eventInfo.actualInteractionsPerCrossing() * (correctedMu/eventInfo.averageInteractionsPerCrossing()) * ( (includeDataScaleFactor) ? m_activeTool->GetDataScaleFactor() : 1.);
164}
165
166
168
170
171 //set debugging if debugging is on:
172 EnableDebugging(this->msgLvl(MSG::DEBUG));
173 PrintInfo(msgLvl(MSG::INFO));
174
175 //convert custom periods vector to a vector of vectors (length 3) ...
176 std::vector<std::vector<int>> customPeriods;
177 for(auto& num : m_customPeriods) {
178 if(customPeriods.size()==0 || customPeriods.back().size()==3) customPeriods.resize(customPeriods.size()+1);
179 customPeriods.back().push_back(num);
180 }
181
182 for(auto& period : customPeriods) {
183 if(period.size()!=3) {
184 ATH_MSG_FATAL("Recevied period with " << period.size() << " numbers. Period configuration requires 3 numbers: periodNumber, startNumber, endNumber");
185 return StatusCode::FAILURE;
186 }
187 AddPeriod(period[0],period[1],period[2]);
188 }
189
190 //see if we need variations
191 if(m_upVariation && (m_prwFiles.size()+m_toolLumicalcFiles.size())!=0) {
192 m_upTool.reset( new TPileupReweighting((name()+"_upVariation").c_str()) );
193 m_upTool->PrintInfo(msgLvl(MSG::INFO));
194 m_upTool->SetParentTool(this);
195 m_upTool->CopyProperties(this);
196 m_upTool->SetDataScaleFactors(m_upVariation);
197 for(auto& period : customPeriods) m_upTool->AddPeriod(period[0],period[1],period[2]); //already checked sizes above
198 }
199 if(m_downVariation && (m_prwFiles.size()+m_toolLumicalcFiles.size())!=0) {
200 m_downTool.reset( new TPileupReweighting((name()+"_downVariation").c_str()) );
201 m_downTool->PrintInfo(msgLvl(MSG::INFO));
202 m_downTool->SetParentTool(this);
203 m_downTool->CopyProperties(this);
204 m_downTool->SetDataScaleFactors(m_downVariation);
205 for(auto& period : customPeriods) m_downTool->AddPeriod(period[0],period[1],period[2]); //already checked sizes above
206 }
207
208 SetDefaultChannel(m_defaultChannel); //handled in GetDefaultChannel method now! if(m_upTool) m_upTool->SetDefaultChannel(m_defaultChannel); if(m_downTool) m_downTool->SetDefaultChannel(m_defaultChannel);
209
210
211 //should we set the period config (file maker mode)
212 if(m_prwFiles.size()+m_toolLumicalcFiles.size()==0) {
213 m_inConfigMode=true;
214 ATH_MSG_INFO("In Config file making mode.");
215 if(m_usePeriodConfig!="auto" && m_usePeriodConfig!="") {
217 }
218#ifndef XAOD_STANDALONE
219 //retrieve histsvc now, otherwise it wont get correctly configured by the time it's used in the finalize ... so it seems
220 ServiceHandle<ITHistSvc> histSvc("THistSvc",name());
221 CHECK( histSvc.retrieve() );
222#endif
223 } else {
224 //have we any prw to load
225 if(m_prwFiles.size() && m_usePeriodConfig=="auto") {
226 //will override the input config period assignments, will assume PRW is so standardized by r21 that we know best!
228 if(m_upTool) m_upTool->IgnoreConfigFilePeriods(true);
229 if(m_downTool) m_downTool->IgnoreConfigFilePeriods(true);
230 UsePeriodConfig("MC16"); //hardcoded period assignments
231 if(m_upTool) m_upTool->UsePeriodConfig("MC16");
232 if(m_downTool) m_downTool->UsePeriodConfig("MC16");
233 }
234
235 for(unsigned int j=0;j<m_prwFiles.size();j++) {
236 ATH_MSG_VERBOSE("Locating File: " << m_prwFiles[j]);
237 std::string file = PathResolverFindCalibFile(m_prwFiles[j]);
238 if(file=="") { ATH_MSG_ERROR("Unable to find the PRW Config file: " << m_prwFiles[j]); return StatusCode::FAILURE; }
239 ATH_MSG_VERBOSE("Adding Config file: " << file);
240 /*m_tool->*/AddConfigFile(file.c_str());
241 if(m_upTool) m_upTool->AddConfigFile(file.c_str());
242 if(m_downTool) m_downTool->AddConfigFile(file.c_str());
243 }
244
245 //have we any lumicalc files to load? .. if we do and had no prwFiles then the user must specify the period configuration
246 if(m_toolLumicalcFiles.size()>0 && m_prwFiles.size()==0) {
247 if(m_usePeriodConfig!="auto" && m_usePeriodConfig!="") {
248 ATH_MSG_INFO("Setting up without a PRW config file, but with period config " << m_usePeriodConfig << ". You will only be able to use random run number and data weight functionality... no reweighting!");
250 ATH_MSG_ERROR("Unrecognised PeriodConfig: " << m_usePeriodConfig); return StatusCode::FAILURE;
251 }
252 m_noWeightsMode=true; //will stop the prw weight being decorated in apply method
253 if(m_upTool) m_upTool->UsePeriodConfig(m_usePeriodConfig);
254 if(m_downTool) m_downTool->UsePeriodConfig(m_usePeriodConfig);
255 } else {
256 ATH_MSG_WARNING("No config files provided, but " << m_toolLumicalcFiles.size() << " lumicalc file provided. Assuming a period config of MC16 ");
257 UsePeriodConfig("MC16");
258 m_noWeightsMode=true; //will stop the prw weight being decorated in apply method
259 if(m_upTool) m_upTool->UsePeriodConfig("MC16");
260 if(m_downTool) m_downTool->UsePeriodConfig("MC16");
261 }
262 }
263
264 for(unsigned int j=0;j<m_toolLumicalcFiles.size();j++) {
265 //see if there's a trigger at the end of the filename .. format is "file:trigger"
266 TString myFile = m_toolLumicalcFiles[j];
267 TString myTrigger = (myFile.Contains(':')) ? TString(myFile(myFile.Last(':')+1,myFile.Length()-myFile.Last(':'))) : TString("None");
268 myFile = (myFile.Contains(':')) ? TString(myFile(0,myFile.Last(':'))) : myFile;
269 ATH_MSG_VERBOSE("Locating File: " << myFile);
270 std::string file = PathResolverFindCalibFile(myFile.Data());
271 if(file=="") { ATH_MSG_ERROR("Unable to find the Lumicalc file: " << myFile); return StatusCode::FAILURE; }
272 /*m_tool->*/AddLumiCalcFile(file.c_str(),myTrigger);
273 if(m_upTool) m_upTool->AddLumiCalcFile(file.c_str(),myTrigger);
274 if(m_downTool) m_downTool->AddLumiCalcFile(file.c_str(),myTrigger);
275 }
276 }
277
278 //register ourselves with the systematic registry!
280 if( registry.registerSystematics( *this ) != StatusCode::SUCCESS ) return StatusCode::FAILURE;
281
282
283 //delay initializing underlying tool until first usage, just in case user wants to do any advanced initialization options
284
285 ATH_MSG_DEBUG("Retrieving weight tool...");
286 StatusCode sc = m_weightTool.retrieve();
287 if (sc != StatusCode::SUCCESS) {
288 ATH_MSG_ERROR(" " << m_weightTool->name() << " could not be retrieved.");
289 return sc;
290 }
291 else {
292 ATH_MSG_DEBUG(" " << m_weightTool->name() << " retrieved.");
293 m_weightTool->print();
294 }
295
296 return StatusCode::SUCCESS;
297}
298
300 if(m_inConfigMode) {
301#ifndef XAOD_STANDALONE
302 if(m_configStream=="") {
303 //write the prw config files
304 std::string nameWithoutParent = this->name().substr(this->name().find(".")+1);
305 TString fileName = TString::Format("%s.prw.root", nameWithoutParent.c_str());
306 /*m_tool->*/WriteToFile(fileName);
307 } else {
308 //write to the histsvc stream instead ...
309
310 ServiceHandle<ITHistSvc> histSvc("THistSvc",name());
311 CHECK( histSvc.retrieve() );
312
313 TTree *outTreeMC=0;
314 TTree *outTreeData=0;
315 Int_t channel = 0;UInt_t runNumber = 0;
316 std::vector<UInt_t> pStarts;
317 std::vector<UInt_t> pEnds;
318 std::vector<UInt_t>* pStartsPtr = &pStarts;
319 std::vector<UInt_t>* pEndsPtr = &pEnds;
320 Char_t histName[150];
321
322
323 //loop over periods ... periods only get entry in table if they have an input histogram
324 for(auto period : m_periods) {
325 if(!period.second) continue; //should never happen, but just in case!
326 if(period.first<0) continue; //avoid the global run number
327 if(period.first != period.second->id) continue; //skips redirects
328 runNumber = period.first;
329 pStarts.clear();
330 pEnds.clear();
331 if(period.second->subPeriods.size()==0) {
332 pStarts.push_back(period.second->start); pEnds.push_back(period.second->end);
333 }
334 else {
335 for(auto subp : period.second->subPeriods) {
336 pStarts.push_back(subp->start); pEnds.push_back(subp->end);
337 }
338 }
339 for(auto& inHist : period.second->inputHists) {
340 channel = inHist.first;
341 TH1* hist = inHist.second.release();
342 strncpy(histName,hist->GetName(),sizeof(histName)-1);
343 CHECK( histSvc->regHist(TString::Format("/%s/PileupReweighting/%s",m_configStream.c_str(),hist->GetName()).Data(),hist) );
344 if(!outTreeMC) {
345 outTreeMC = new TTree("MCPileupReweighting","MCPileupReweighting");
346 outTreeMC->Branch("Channel",&channel);
347 outTreeMC->Branch("RunNumber",&runNumber);
348 outTreeMC->Branch("PeriodStarts",&pStartsPtr);
349 outTreeMC->Branch("PeriodEnds",&pEndsPtr);
350 outTreeMC->Branch("HistName",&histName,"HistName/C");
351 CHECK( histSvc->regTree(TString::Format("/%s/PileupReweighting/%s",m_configStream.c_str(),outTreeMC->GetName()).Data(),outTreeMC) );
352 }
353 outTreeMC->Fill();
354 }
355 }
356
357 //loop over data
358 for(auto& run : m_runs) {
359 runNumber = run.first;
360 if(run.second.inputHists.find("None")==run.second.inputHists.end()) continue;
361
362 TH1* hist = run.second.inputHists["None"].release();
363 strncpy(histName,hist->GetName(),sizeof(histName)-1);
364 CHECK( histSvc->regHist(TString::Format("/%s/PileupReweighting/%s",m_configStream.c_str(),hist->GetName()).Data(),hist) );
365 if(!outTreeData) {
366 outTreeData = new TTree("DataPileupReweighting","DataPileupReweighting");
367 outTreeData->Branch("RunNumber",&runNumber);
368 outTreeData->Branch("HistName",&histName,"HistName/C");
369 CHECK( histSvc->regTree(TString::Format("/%s/PileupReweighting/%s",m_configStream.c_str(),outTreeData->GetName()).Data(),outTreeData) );
370 }
371 outTreeData->Fill();
372 }
373
374 Info("WriteToFile", "Successfully generated config file to stream: %s",m_configStream.c_str());
375 Info("WriteToFile", "Happy Reweighting :-)");
376
377 }
378
379#else
380 //write the prw config files
381 std::string nameWithoutParent = this->name().substr(this->name().find(".")+1);
382 TString fileName = TString::Format("%s.prw.root", nameWithoutParent.c_str());
383 /*m_tool->*/WriteToFile(fileName);
384#endif
385 }
386
387 m_upTool.reset(); m_downTool.reset();
388
389 return StatusCode::SUCCESS;
390}
391
393 return m_activeTool->GetPRWHash(eventInfo.runNumber(), eventInfo.mcChannelNumber(), eventInfo.averageInteractionsPerCrossing() );
394}
395
397float PileupReweightingTool::getCombinedWeight( const xAOD::EventInfo& eventInfo, bool correctUnrepresented ) {
398 float weight = m_activeTool->GetCombinedWeight( eventInfo.runNumber(), eventInfo.mcChannelNumber(), eventInfo.averageInteractionsPerCrossing() );
399 if(correctUnrepresented && m_unrepresentedDataAction==2)
400 weight *= getUnrepresentedDataWeight( eventInfo );
401 return weight;
402}
403
404float PileupReweightingTool::getCombinedWeight( const xAOD::EventInfo& eventInfo, Double_t x, Double_t y, bool correctUnrepresented ) {
405 float weight = m_activeTool->GetCombinedWeight( eventInfo.runNumber(), eventInfo.mcChannelNumber(), x, y );
406 if(correctUnrepresented && m_unrepresentedDataAction==2)
407 weight *= getUnrepresentedDataWeight( eventInfo );
408 return weight;
409}
410
413 return m_activeTool->GetUnrepresentedDataWeight( eventInfo.runNumber(), eventInfo.mcChannelNumber() );
414}
415
416
418int PileupReweightingTool::getRandomRunNumber( const xAOD::EventInfo& eventInfo , bool mu_dependent) {
420 tool->SetRandomSeed(314159+eventInfo.mcChannelNumber()*2718+eventInfo.eventNumber()); //to make randomization repeatable
421 if(mu_dependent) return tool->GetRandomRunNumber( eventInfo.runNumber(), eventInfo.averageInteractionsPerCrossing() );
422 else return tool->GetRandomRunNumber( eventInfo.runNumber() );
423}
424
426 return fill(eventInfo,eventInfo.averageInteractionsPerCrossing(),0);
427}
428
429int PileupReweightingTool::fill( const xAOD::EventInfo& eventInfo, Double_t x, Double_t y) {
430
431 //auto-detect the period config if necessary
432 if(m_usePeriodConfig=="auto" && !m_doneConfigs[eventInfo.runNumber()]) { //try autodetect based on runnum of first event ...
433 //if data, we only need to ensure a binning is done ... for now, we assume the MC15 binning
435 if(!m_emptyHistogram) { SetUniformBinning(100,0,100.); } //use a default binning
436 } else {
437 switch(eventInfo.runNumber()) {
438 case 212272: UsePeriodConfig("MC14_8TeV");break;
439 case 222222: UsePeriodConfig("MC14_13TeV");break;
440 case 222510: case 222525: case 222526: case 284500: UsePeriodConfig("MC15"); break;
441 }
442 if(eventInfo.runNumber()>284500) UsePeriodConfig("Run2"); //this is the automatic period config, allows any run numbers to be added
443 }
444 m_doneConfigs[eventInfo.runNumber()] = true;
445 }
446
447 return TPileupReweighting::Fill(eventInfo.runNumber(), eventInfo.eventType(xAOD::EventInfo::IS_SIMULATION) ? eventInfo.mcChannelNumber() : -1 /*data*/, eventInfo.eventType(xAOD::EventInfo::IS_SIMULATION) ? m_weightTool->getWeight() : 1., x, y);
448
449}
450
451StatusCode PileupReweightingTool::apply(const xAOD::EventInfo& eventInfo, bool mu_dependent) {
452
453 if(m_inConfigMode) {
454 fill( eventInfo );
455 return StatusCode::SUCCESS;
456 }
457
458 SG::Decorator<float> corrAvgIntPerXingDec(m_prefix+"corrected_averageInteractionsPerCrossing");
460 if(!corrAvgIntPerXingDec.isAvailable(eventInfo))
461 corrAvgIntPerXingDec(eventInfo) = getCorrectedAverageInteractionsPerCrossing(eventInfo,false);
462 return StatusCode::SUCCESS;
463 }
464
465 //just copy the value over for MC
466 if(!corrAvgIntPerXingDec.isAvailable(eventInfo))
467 corrAvgIntPerXingDec(eventInfo) = eventInfo.averageInteractionsPerCrossing();
468
469 //decorate with random run number etc
470 SG::Decorator<unsigned int> rrnDec(m_prefix+"RandomRunNumber");
471 SG::ConstAccessor<unsigned int> rrnAcc(rrnDec.auxid());
472 if(!rrnDec.isAvailable(eventInfo)){
473 unsigned int rrn = getRandomRunNumber( eventInfo, mu_dependent );
474 rrnDec(eventInfo) = (rrn==0) ? getRandomRunNumber(eventInfo, false) : rrn;
475 }
476 SG::Decorator<unsigned int> rlbnDec(m_prefix+"RandomLumiBlockNumber");
477 SG::Decorator<unsigned int> rlbnAcc(rlbnDec.auxid());
478 if(!rlbnDec.isAvailable(eventInfo))
479 rlbnDec(eventInfo) = (rrnAcc(eventInfo)==0) ? 0 : /*m_tool->*/GetRandomLumiBlockNumber( rrnAcc(eventInfo) );
480 SG::Decorator<ULong64_t> prwHashDec(m_prefix+"PRWHash");
481 if(!prwHashDec.isAvailable(eventInfo))
482 prwHashDec(eventInfo) = getPRWHash( eventInfo );
483
484 //decorate with standard PileupWeight
485 SG::Decorator<float> puWeightDec(m_prefix+"PileupWeight");
486 SG::ConstAccessor<float> puWeightAcc(puWeightDec.auxid());
487 if(!m_noWeightsMode && !puWeightDec.isAvailable(eventInfo))
488 puWeightDec(eventInfo) = getCombinedWeight(eventInfo, true);
489
490 ATH_MSG_VERBOSE("PileupWeight = " << puWeightAcc(eventInfo) << " RandomRunNumber = " << rrnAcc(eventInfo) << " RandomLumiBlockNumber = " << rlbnAcc(eventInfo));
491
492 return StatusCode::SUCCESS;
493}
494
495float PileupReweightingTool::getDataWeight(const xAOD::EventInfo& eventInfo, const TString& trigger, bool mu_dependent) {
496
498 ATH_MSG_WARNING("Requesting Data Weight is not intended for simulated events. Returning 1.");
499 return 1; //no data weights for simulated events
500 }
501
502 if(!mu_dependent) return /*m_tool->*/m_activeTool->GetDataWeight(eventInfo.runNumber(), trigger);
503
504 double correctedMu = getCorrectedAverageInteractionsPerCrossing(eventInfo,false);
505 if(correctedMu<0) {
506 ATH_MSG_ERROR("Unrecognised run+lumiblock number (" << eventInfo.runNumber() << "," << eventInfo.lumiBlock() << ") ... please ensure your lumicalc files are complete! Returning 1.");
507 return 1;
508 }
509
510 return /*m_tool->*/m_activeTool->GetDataWeight( eventInfo.runNumber(), trigger, correctedMu/*use the 'correct' mu instead of the one from the file!!*/ );
511
512}
513
514float PileupReweightingTool::getPrescaleWeight( const xAOD::EventInfo& eventInfo , const TString& trigger, bool mu_dependent ) {
515 //need to use the random run number ... only used to pick the subperiod, but in run2 so far we only have one subperiod
516 SG::ConstAccessor<unsigned int> rrnAcc (m_prefix+"RandomRunNumber");
517 unsigned int randomRunNum = rrnAcc.withDefault (eventInfo, 0);
518 if (randomRunNum == 0) {
519 randomRunNum = getRandomRunNumber( eventInfo, mu_dependent );
520 }
521 if(!mu_dependent) return m_activeTool->GetPrescaleWeight(randomRunNum, trigger);
522 return m_activeTool->GetPrescaleWeight( randomRunNum, trigger, getCorrectedAverageInteractionsPerCrossing(eventInfo,false) /*use the 'correct' mu instead of the one from the file!!*/, m_useRunDependentPrescaleWeight /*run-dependent*/ );
523}
524
525float PileupReweightingTool::getCombinedWeight( const xAOD::EventInfo& eventInfo , const TString& trigger, bool mu_dependent, bool correctUnrepresented ) {
526 float out = getCombinedWeight(eventInfo, correctUnrepresented);
527 if(!out) return out; //don't try to evaluate DataWeight if our PRW is 0 ... means there is no data available at that mu anyway
528
529 out *= getPrescaleWeight(eventInfo, trigger, mu_dependent);
530 return out;
531}
532
533
534} // namespace CP
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Helper class to provide constant type-safe access to aux data.
#define CHECK(...)
Evaluate an expression and check for errors.
Helper class to provide type-safe access to aux data.
static Double_t sc
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
#define y
#define x
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
bool msgLvl(const MSG::Level lvl) const
ToolHandle< Trig::ITrigDecisionTool > m_tdt
virtual int fill(const xAOD::EventInfo &eventInfo)
Call this method once per event when in config file generating mode and you want standard mu reweight...
std::unique_ptr< IWeightTool > m_defaultWeightTool
std::vector< std::string > m_prwFiles
std::vector< int > m_customPeriods
Default weight tool in standalone mode.
virtual float getDataWeight(const xAOD::EventInfo &eventInfo, const TString &trigger, bool mu_dependent)
Get the dataWeight used to 'unprescale' data collected from a given trigger combination....
virtual float getCorrectedAverageInteractionsPerCrossing(const xAOD::EventInfo &eventInfo, bool includeDataScaleFactor)
Get the mu of a lumiblock ... needed to 'correct' the number in datasets.
virtual Int_t AddPeriod(Int_t periodNumber, UInt_t start, UInt_t end)
use these methods when generating config files
virtual ULong64_t getPRWHash(const xAOD::EventInfo &eventInfo)
return the prw hash used for fast updates of weights at the post-processing level ....
virtual double getLumiBlockIntegratedLumi(const xAOD::EventInfo &eventInfo)
Get the integrated lumi of a lumiblock (in pb-1)
std::unique_ptr< CP::TPileupReweighting > m_upTool
virtual Int_t SetUniformBinning(Int_t nbinsx, Double_t xlow, Double_t xup, Int_t nbinsy=0, Double_t ylow=0, Double_t yup=0)
virtual float getCorrectedActualInteractionsPerCrossing(const xAOD::EventInfo &eventInfo, bool includeDataScaleFactor)
Get the corrected 'actual' interactions per crossing.
CP::SystematicSet affectingSystematics() const
the list of all systematics this tool can be affected by
virtual StatusCode apply(const xAOD::EventInfo &eventInfo, bool mu_dependent)
Decorates with: MC: PileupWeight (CombinedWeight[*UnrepresentedDataWeight if action=2]),...
StatusCode applySystematicVariation(const CP::SystematicSet &systConfig)
effects: configure this tool for the given list of systematic variations.
void updateHandler(Gaudi::Details::PropertyBase &)
ToolHandle< IWeightTool > m_weightTool
virtual float getPrescaleWeight(const xAOD::EventInfo &eventInfo, const TString &trigger, bool mu_dependent)
Get weight used to 'prescale' Monte Carlo for given trigger comibnation.
virtual float getCombinedWeight(const xAOD::EventInfo &eventInfo, bool correctUnrepresented)
Return combined pileup weight.
CP::SystematicVariation m_systDown
std::vector< std::string > m_toolLumicalcFiles
virtual StatusCode initialize()
Function initialising the tool.
virtual UInt_t GetRandomLumiBlockNumber(UInt_t runNumber)
Get a random lumiblock number for the given run number.
virtual bool passTriggerBeforePrescale(const TString &trigger) const
std::unique_ptr< CP::TPileupReweighting > m_downTool
virtual float getUnrepresentedDataWeight(const xAOD::EventInfo &eventInfo)
When using UnrepresentedDataAction=2, you may want to apply this additional weight to ensure sum of w...
PileupReweightingTool(const std::string &name)
Constructor for standalone usage.
CP::TPileupReweighting * m_activeTool
CP::SystematicSet recommendedSystematics() const
the list of all systematics this tool recommends to use
ToolHandle< IGoodRunsListSelectionTool > m_grlTool
std::map< int, bool > m_doneConfigs
virtual int getRandomRunNumber(const xAOD::EventInfo &eventInfo, bool mu_dependent)
Get a random run number for this MC event, using mu-dependent randomization by default ....
bool isAffectedBySystematic(const CP::SystematicVariation &systematic) const
The ISystematicsTool methods.
CP::SystematicVariation m_systUp
virtual bool runLbnOK(Int_t runNbr, Int_t lbn)
virtual StatusCode finalize()
Finalize - can call the WriteToFile for us.
This module implements the central registry for handling systematic uncertainties with CP tools.
static SystematicRegistry & getInstance()
Get the singleton instance of the registry for the curren thread.
StatusCode registerSystematics(const IReentrantSystematicsTool &tool)
effects: register all the systematics from the tool
Class to wrap a set of SystematicVariations.
const_iterator end() const
description: const iterator to the end of the set
iterator find(const SystematicVariation &sys) const
description: find an element in the set
Double_t GetLumiBlockIntegratedLumi(Int_t runNumber, UInt_t lb)
get integrated lumi for specific run and lumiblock number .
Int_t Fill(Int_t runNumber, Int_t channelNumber, Float_t w, Float_t x, Float_t y=0.)
Int_t WriteToFile(const TString &filename="")
virtual bool passTriggerBeforePrescale(const TString &trigger) const
std::map< UInt_t, Run > m_runs
void EnableDebugging(Bool_t in)
Indicate if additional debugging information should be output.
Int_t UsePeriodConfig(const TString &configName)
use a hardcoded period configuration
void SetDefaultChannel(Int_t channel, Int_t mcRunNumber=-1)
Set which channel should be used as a default when specific mc channel distributions cannot be found.
std::map< Int_t, Period * > m_periods
std::unique_ptr< TH1 > m_emptyHistogram
the empty histogram used for this weight... effectively holds the configuration of the binning
void PrintInfo(Bool_t in)
disable info
Int_t AddLumiCalcFile(const TString &fileName, const TString &trigger="None")
Int_t AddConfigFile(const TString &fileName)
Float_t GetLumiBlockMu(Int_t runNumber, UInt_t lb)
get the lumiblock mu, useful for 'updating' the mu coming from data to account for new lumitags
TPileupReweighting(const char *name="TPileupReweighting")
Standard constructor.
void IgnoreConfigFilePeriods(Bool_t in)
Should the tool ignore period assignments encoded in config file.
Helper class to provide constant type-safe access to aux data.
const_reference_type withDefault(const ELT &e, const T &deflt) const
Fetch the variable for one element, as a const reference, with a default.
Helper class to provide type-safe access to aux data.
Definition Decorator.h:59
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
SG::auxid_t auxid() const
Return the aux id for this variable.
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
uint32_t lumiBlock() const
The current event's luminosity block number.
bool eventType(EventType type) const
Check for one particular bitmask value.
float averageInteractionsPerCrossing() const
Average interactions per crossing for all BCIDs - for out-of-time pile-up.
float actualInteractionsPerCrossing() const
Average interactions per crossing for the current BCID - for in-time pile-up.
@ IS_SIMULATION
true: simulation, false: data
uint32_t runNumber() const
The current event's run number.
uint32_t mcChannelNumber() const
The MC generator's channel number.
uint64_t eventNumber() const
The current event's event number.
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:138
Select isolated Photons, Electrons and Muons.
Definition run.py:1
EventInfo_v1 EventInfo
Definition of the latest event info version.
TFile * file