ATLAS Offline Software
Loading...
Searching...
No Matches
PileupReweightingTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 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("UnrepresentedDataWarningThreshold",
59 "Suppress the unrepresented-data WARNING when the"
60 " unrepresented fraction is below this value."
61 " Default 0 means always warn (preserving the"
62 " existing behaviour).");
63 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");
64 declareProperty("UseRunDependentPrescaleWeight",m_useRunDependentPrescaleWeight=false,"If true, prescale weights in the getCombinedWeight method with Trigger string are determined with the specific random run number");
65 declareProperty("DataScaleFactor",m_dataScaleFactorX=1./1.03);
66 declareProperty("UsePeriodConfig",m_usePeriodConfig="auto","Use this period configuration when in config generating mode. Set to 'auto' to auto-detect");
67 declareProperty("IgnoreBadChannels",m_ignoreBadChannels=true,"If true, will ignore channels with too much unrepresented data, printing a warning for them");
68 declareProperty("DataScaleFactorUP",m_upVariation=1./0.99,"Set to a value representing the 'up' fluctuation - will report a PRW_DATASF uncertainty to Systematic Registry");
69 declareProperty("DataScaleFactorDOWN",m_downVariation=1./1.07,"Set to a value representing the 'down' fluctuation - will report a PRW_DATASF uncertainty to Systematic Registry");
70 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");
71 declareProperty("PeriodAssignments", m_customPeriods={284500,222222,324300,300000,324300,344495,310000,344496,367384,410000,422633,440613,450000,450360,461002,470000,473235,486706,495000,497924,999999}, "Specify period number assignments to run numbers ranges - this is usually an expert option");
72 declareProperty("GRLTool", m_grlTool, "If you provide a GoodRunsListSelectionTool, any information from lumicalc files will be automatically filtered" );
73 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)");
74
75#ifdef XAOD_STANDALONE
77 "The tool to compute the weight in the sumOfWeights" );
78#else
79 declareProperty( "WeightTool", m_weightTool,
80 "The tool to compute the weight in the sumOfWeights" );
81#endif
82
83#ifndef XAOD_STANDALONE
84 //attached update handler to the outputlevel property, so we can pass changes on to the underlying tool
85 auto props = getProperties();
86 for( Gaudi::Details::PropertyBase* prop : props ) {
87 if( prop->name() != "OutputLevel" ) {
88 continue;
89 }
90 prop->declareUpdateHandler( &PileupReweightingTool::updateHandler, this );
91 break;
92 }
93#endif
94}
95
96#ifndef XAOD_STANDALONE
97//rootcore can't do this yet!
98void PileupReweightingTool::updateHandler(Gaudi::Details::PropertyBase& /*p*/) {
99 // commenting this out as it doesn't compile anymore
100 // leaving it to domain expert to decide whether to keep or remove it
101 // //call the original update handler
102 // this->msg_update_handler(p);
103 EnableDebugging(this->msgLvl(MSG::DEBUG));
104}
105#endif
106
107bool PileupReweightingTool::runLbnOK(Int_t runNbr, Int_t lbn) {
108 if(m_grlTool.empty()) return true;
109 return m_grlTool->passRunLB(runNbr,lbn);
110}
111
112bool PileupReweightingTool::passTriggerBeforePrescale(const TString& trigger) const {
113 if(m_tdt.empty()) return TPileupReweighting::passTriggerBeforePrescale(trigger);
114 ATH_MSG_VERBOSE("Checking tdt decision of " << trigger);
115 //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
116 //but for now we just assume it's a rerun
117 //if it's not rerun, all we will get back here is the TAP result
118 return m_tdt->isPassed( trigger.Data() , TrigDefs::Physics | TrigDefs::allowResurrectedDecision ); // Definitions in TrigDecisionInterface/Conditions.h
119}
120
122 CP::SystematicSet sys = affectingSystematics(); return sys.find( systematic ) != sys.end();
123}
124
126 CP::SystematicSet result;
127 if(m_upVariation) result.insert( m_systUp );
128 if(m_downVariation) result.insert( m_systDown );
129 return result;
130}
131
135
137 if(systConfig.find( m_systUp ) != systConfig.end() && systConfig.find( m_systDown ) != systConfig.end()) {
138 ATH_MSG_ERROR("Errr... what the!? You're trying to do both PRW_DATASF directions at the same time!!!??");
139 return StatusCode::FAILURE;
140 }
141 if(systConfig.find( m_systUp ) != systConfig.end()) {
142 if(!m_upTool) { ATH_MSG_ERROR("Requested up variation of PRW_DATASF, but not configured to do this :-("); return StatusCode::FAILURE; }
143 m_activeTool = m_upTool.get();
144 }
145 else if(systConfig.find( m_systDown ) != systConfig.end() ) {
146 if(!m_downTool) { ATH_MSG_ERROR("Requested down variation of PRW_DATASF, but not configured to do this :-("); return StatusCode::FAILURE; }
147 m_activeTool = m_downTool.get();
148 }
149 else m_activeTool = this;
150 return StatusCode::SUCCESS;
151}
152
153
154float PileupReweightingTool::getCorrectedAverageInteractionsPerCrossing( const xAOD::EventInfo& eventInfo, bool includeDataScaleFactor ) {
156 return eventInfo.averageInteractionsPerCrossing(); //no correction needed for MC
157 }
158 float out = CP::TPileupReweighting::GetLumiBlockMu(eventInfo.runNumber(),eventInfo.lumiBlock());
159 if(out<0) return out; //will be -1
160 return out * ( (includeDataScaleFactor) ? m_activeTool->GetDataScaleFactor() : 1.);
161}
162
163float PileupReweightingTool::getCorrectedActualInteractionsPerCrossing( const xAOD::EventInfo& eventInfo, bool includeDataScaleFactor ) {
164 float result = 1.;
165 const float actualInteractions = eventInfo.actualInteractionsPerCrossing();
167 return actualInteractions; //no correction needed for MC
168 }
169 float correctedMu = CP::TPileupReweighting::GetLumiBlockMu(eventInfo.runNumber(),eventInfo.lumiBlock());
170 if(correctedMu<0) return correctedMu; //will be -1
171 if ( const auto avg = eventInfo.averageInteractionsPerCrossing(); avg != 0.){
172 result = actualInteractions * (correctedMu/avg) * ( (includeDataScaleFactor) ? m_activeTool->GetDataScaleFactor() : 1.);
173 }
174 return result;
175}
176
177
179
181
182 //set debugging if debugging is on:
183 EnableDebugging(this->msgLvl(MSG::DEBUG));
184 PrintInfo(msgLvl(MSG::INFO));
185
186 //convert custom periods vector to a vector of vectors (length 3) ...
187 std::vector<std::vector<int>> customPeriods;
188 for(auto& num : m_customPeriods) {
189 if(customPeriods.size()==0 || customPeriods.back().size()==3) customPeriods.resize(customPeriods.size()+1);
190 customPeriods.back().push_back(num);
191 }
192
193 for(auto& period : customPeriods) {
194 if(period.size()!=3) {
195 ATH_MSG_FATAL("Recevied period with " << period.size() << " numbers. Period configuration requires 3 numbers: periodNumber, startNumber, endNumber");
196 return StatusCode::FAILURE;
197 }
198 AddPeriod(period[0],period[1],period[2]);
199 }
200
201 //see if we need variations
202 if(m_upVariation && (m_prwFiles.size()+m_toolLumicalcFiles.size())!=0) {
203 m_upTool.reset( new TPileupReweighting((name()+"_upVariation").c_str()) );
204 m_upTool->PrintInfo(msgLvl(MSG::INFO));
205 m_upTool->SetParentTool(this);
206 m_upTool->CopyProperties(this);
207 m_upTool->SetDataScaleFactors(m_upVariation);
208 for(auto& period : customPeriods) m_upTool->AddPeriod(period[0],period[1],period[2]); //already checked sizes above
209 }
210 if(m_downVariation && (m_prwFiles.size()+m_toolLumicalcFiles.size())!=0) {
211 m_downTool.reset( new TPileupReweighting((name()+"_downVariation").c_str()) );
212 m_downTool->PrintInfo(msgLvl(MSG::INFO));
213 m_downTool->SetParentTool(this);
214 m_downTool->CopyProperties(this);
215 m_downTool->SetDataScaleFactors(m_downVariation);
216 for(auto& period : customPeriods) m_downTool->AddPeriod(period[0],period[1],period[2]); //already checked sizes above
217 }
218
219 SetDefaultChannel(m_defaultChannel); //handled in GetDefaultChannel method now! if(m_upTool) m_upTool->SetDefaultChannel(m_defaultChannel); if(m_downTool) m_downTool->SetDefaultChannel(m_defaultChannel);
220
221
222 //should we set the period config (file maker mode)
223 if(m_prwFiles.size()+m_toolLumicalcFiles.size()==0) {
224 m_inConfigMode=true;
225 ATH_MSG_INFO("In Config file making mode.");
226 if(m_usePeriodConfig!="auto" && m_usePeriodConfig!="") {
228 }
229#ifndef XAOD_STANDALONE
230 //retrieve histsvc now, otherwise it wont get correctly configured by the time it's used in the finalize ... so it seems
231 ServiceHandle<ITHistSvc> histSvc("THistSvc",name());
232 CHECK( histSvc.retrieve() );
233#endif
234 } else {
235 //have we any prw to load
236 if(m_prwFiles.size() && m_usePeriodConfig=="auto") {
237 //will override the input config period assignments, will assume PRW is so standardized by r21 that we know best!
239 if(m_upTool) m_upTool->IgnoreConfigFilePeriods(true);
240 if(m_downTool) m_downTool->IgnoreConfigFilePeriods(true);
241 UsePeriodConfig("MC16"); //hardcoded period assignments
242 if(m_upTool) m_upTool->UsePeriodConfig("MC16");
243 if(m_downTool) m_downTool->UsePeriodConfig("MC16");
244 }
245
246 for(unsigned int j=0;j<m_prwFiles.size();j++) {
247 ATH_MSG_VERBOSE("Locating File: " << m_prwFiles[j]);
248 std::string file = PathResolverFindCalibFile(m_prwFiles[j]);
249 if(file=="") { ATH_MSG_ERROR("Unable to find the PRW Config file: " << m_prwFiles[j]); return StatusCode::FAILURE; }
250 ATH_MSG_VERBOSE("Adding Config file: " << file);
251 /*m_tool->*/AddConfigFile(file.c_str());
252 if(m_upTool) m_upTool->AddConfigFile(file.c_str());
253 if(m_downTool) m_downTool->AddConfigFile(file.c_str());
254 }
255
256 //have we any lumicalc files to load? .. if we do and had no prwFiles then the user must specify the period configuration
257 if(m_toolLumicalcFiles.size()>0 && m_prwFiles.size()==0) {
258 if(m_usePeriodConfig!="auto" && m_usePeriodConfig!="") {
259 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!");
261 ATH_MSG_ERROR("Unrecognised PeriodConfig: " << m_usePeriodConfig); return StatusCode::FAILURE;
262 }
263 m_noWeightsMode=true; //will stop the prw weight being decorated in apply method
264 if(m_upTool) m_upTool->UsePeriodConfig(m_usePeriodConfig);
265 if(m_downTool) m_downTool->UsePeriodConfig(m_usePeriodConfig);
266 } else {
267 ATH_MSG_WARNING("No config files provided, but " << m_toolLumicalcFiles.size() << " lumicalc file provided. Assuming a period config of MC16 ");
268 UsePeriodConfig("MC16");
269 m_noWeightsMode=true; //will stop the prw weight being decorated in apply method
270 if(m_upTool) m_upTool->UsePeriodConfig("MC16");
271 if(m_downTool) m_downTool->UsePeriodConfig("MC16");
272 }
273 }
274
275 for(unsigned int j=0;j<m_toolLumicalcFiles.size();j++) {
276 //see if there's a trigger at the end of the filename .. format is "file:trigger"
277 TString myFile = m_toolLumicalcFiles[j];
278 TString myTrigger = (myFile.Contains(':')) ? TString(myFile(myFile.Last(':')+1,myFile.Length()-myFile.Last(':'))) : TString("None");
279 myFile = (myFile.Contains(':')) ? TString(myFile(0,myFile.Last(':'))) : myFile;
280 ATH_MSG_VERBOSE("Locating File: " << myFile);
281 std::string file = PathResolverFindCalibFile(myFile.Data());
282 if(file=="") { ATH_MSG_ERROR("Unable to find the Lumicalc file: " << myFile); return StatusCode::FAILURE; }
283 /*m_tool->*/AddLumiCalcFile(file.c_str(),myTrigger);
284 if(m_upTool) m_upTool->AddLumiCalcFile(file.c_str(),myTrigger);
285 if(m_downTool) m_downTool->AddLumiCalcFile(file.c_str(),myTrigger);
286 }
287 }
288
289 //register ourselves with the systematic registry!
291 if( registry.registerSystematics( *this ) != StatusCode::SUCCESS ) return StatusCode::FAILURE;
292
293
294 //delay initializing underlying tool until first usage, just in case user wants to do any advanced initialization options
295
296 ATH_MSG_DEBUG("Retrieving weight tool...");
297 StatusCode sc = m_weightTool.retrieve();
298 if (sc != StatusCode::SUCCESS) {
299 ATH_MSG_ERROR(" " << m_weightTool->name() << " could not be retrieved.");
300 return sc;
301 }
302 else {
303 ATH_MSG_DEBUG(" " << m_weightTool->name() << " retrieved.");
304 m_weightTool->print();
305 }
306
307 return StatusCode::SUCCESS;
308}
309
311 if(m_inConfigMode) {
312#ifndef XAOD_STANDALONE
313 if(m_configStream=="") {
314 //write the prw config files
315 std::string nameWithoutParent = this->name().substr(this->name().find(".")+1);
316 TString fileName = TString::Format("%s.prw.root", nameWithoutParent.c_str());
317 /*m_tool->*/WriteToFile(fileName);
318 } else {
319 //write to the histsvc stream instead ...
320
321 ServiceHandle<ITHistSvc> histSvc("THistSvc",name());
322 CHECK( histSvc.retrieve() );
323
324 TTree *outTreeMC=0;
325 TTree *outTreeData=0;
326 Int_t channel = 0;UInt_t runNumber = 0;
327 std::vector<UInt_t> pStarts;
328 std::vector<UInt_t> pEnds;
329 std::vector<UInt_t>* pStartsPtr = &pStarts;
330 std::vector<UInt_t>* pEndsPtr = &pEnds;
331 Char_t histName[150];
332
333
334 //loop over periods ... periods only get entry in table if they have an input histogram
335 for(auto period : m_periods) {
336 if(!period.second) continue; //should never happen, but just in case!
337 if(period.first<0) continue; //avoid the global run number
338 if(period.first != period.second->id) continue; //skips redirects
339 runNumber = period.first;
340 pStarts.clear();
341 pEnds.clear();
342 if(period.second->subPeriods.size()==0) {
343 pStarts.push_back(period.second->start); pEnds.push_back(period.second->end);
344 }
345 else {
346 for(auto subp : period.second->subPeriods) {
347 pStarts.push_back(subp->start); pEnds.push_back(subp->end);
348 }
349 }
350 for(auto& inHist : period.second->inputHists) {
351 channel = inHist.first;
352 TH1* hist = inHist.second.release();
353 strncpy(histName,hist->GetName(),sizeof(histName)-1);
354 CHECK( histSvc->regHist(TString::Format("/%s/PileupReweighting/%s",m_configStream.c_str(),hist->GetName()).Data(),hist) );
355 if(!outTreeMC) {
356 outTreeMC = new TTree("MCPileupReweighting","MCPileupReweighting");
357 outTreeMC->Branch("Channel",&channel);
358 outTreeMC->Branch("RunNumber",&runNumber);
359 outTreeMC->Branch("PeriodStarts",&pStartsPtr);
360 outTreeMC->Branch("PeriodEnds",&pEndsPtr);
361 outTreeMC->Branch("HistName",&histName,"HistName/C");
362 CHECK( histSvc->regTree(TString::Format("/%s/PileupReweighting/%s",m_configStream.c_str(),outTreeMC->GetName()).Data(),outTreeMC) );
363 }
364 outTreeMC->Fill();
365 }
366 }
367
368 //loop over data
369 for(auto& run : m_runs) {
370 runNumber = run.first;
371 if(run.second.inputHists.find("None")==run.second.inputHists.end()) continue;
372
373 TH1* hist = run.second.inputHists["None"].release();
374 strncpy(histName,hist->GetName(),sizeof(histName)-1);
375 CHECK( histSvc->regHist(TString::Format("/%s/PileupReweighting/%s",m_configStream.c_str(),hist->GetName()).Data(),hist) );
376 if(!outTreeData) {
377 outTreeData = new TTree("DataPileupReweighting","DataPileupReweighting");
378 outTreeData->Branch("RunNumber",&runNumber);
379 outTreeData->Branch("HistName",&histName,"HistName/C");
380 CHECK( histSvc->regTree(TString::Format("/%s/PileupReweighting/%s",m_configStream.c_str(),outTreeData->GetName()).Data(),outTreeData) );
381 }
382 outTreeData->Fill();
383 }
384
385 Info("WriteToFile", "Successfully generated config file to stream: %s",m_configStream.c_str());
386 Info("WriteToFile", "Happy Reweighting :-)");
387
388 }
389
390#else
391 //write the prw config files
392 std::string nameWithoutParent = this->name().substr(this->name().find(".")+1);
393 TString fileName = TString::Format("%s.prw.root", nameWithoutParent.c_str());
394 /*m_tool->*/WriteToFile(fileName);
395#endif
396 }
397
398 m_upTool.reset(); m_downTool.reset();
399
400 return StatusCode::SUCCESS;
401}
402
404 return m_activeTool->GetPRWHash(eventInfo.runNumber(), eventInfo.mcChannelNumber(), eventInfo.averageInteractionsPerCrossing() );
405}
406
408float PileupReweightingTool::getCombinedWeight( const xAOD::EventInfo& eventInfo, bool correctUnrepresented ) {
409 float weight = m_activeTool->GetCombinedWeight( eventInfo.runNumber(), eventInfo.mcChannelNumber(), eventInfo.averageInteractionsPerCrossing() );
410 if(correctUnrepresented && m_unrepresentedDataAction==2)
411 weight *= getUnrepresentedDataWeight( eventInfo );
412 return weight;
413}
414
415float PileupReweightingTool::getCombinedWeight( const xAOD::EventInfo& eventInfo, Double_t x, Double_t y, bool correctUnrepresented ) {
416 float weight = m_activeTool->GetCombinedWeight( eventInfo.runNumber(), eventInfo.mcChannelNumber(), x, y );
417 if(correctUnrepresented && m_unrepresentedDataAction==2)
418 weight *= getUnrepresentedDataWeight( eventInfo );
419 return weight;
420}
421
424 return m_activeTool->GetUnrepresentedDataWeight( eventInfo.runNumber(), eventInfo.mcChannelNumber() );
425}
426
427
429int PileupReweightingTool::getRandomRunNumber( const xAOD::EventInfo& eventInfo , bool mu_dependent) {
431 tool->SetRandomSeed(314159+eventInfo.mcChannelNumber()*2718+eventInfo.eventNumber()); //to make randomization repeatable
432 if(mu_dependent) return tool->GetRandomRunNumber( eventInfo.runNumber(), eventInfo.averageInteractionsPerCrossing() );
433 else return tool->GetRandomRunNumber( eventInfo.runNumber() );
434}
435
437 return fill(eventInfo,eventInfo.averageInteractionsPerCrossing(),0);
438}
439
440int PileupReweightingTool::fill( const xAOD::EventInfo& eventInfo, Double_t x, Double_t y) {
441
442 //auto-detect the period config if necessary
443 if(m_usePeriodConfig=="auto" && !m_doneConfigs[eventInfo.runNumber()]) { //try autodetect based on runnum of first event ...
444 //if data, we only need to ensure a binning is done ... for now, we assume the MC15 binning
446 if(!m_emptyHistogram) { SetUniformBinning(100,0,100.); } //use a default binning
447 } else {
448 switch(eventInfo.runNumber()) {
449 case 212272: UsePeriodConfig("MC14_8TeV");break;
450 case 222222: UsePeriodConfig("MC14_13TeV");break;
451 case 222510: case 222525: case 222526: case 284500: UsePeriodConfig("MC15"); break;
452 }
453 if(eventInfo.runNumber()>284500) UsePeriodConfig("Run2"); //this is the automatic period config, allows any run numbers to be added
454 }
455 m_doneConfigs[eventInfo.runNumber()] = true;
456 }
457
458 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);
459
460}
461
462StatusCode PileupReweightingTool::apply(const xAOD::EventInfo& eventInfo, bool mu_dependent) {
463
464 if(m_inConfigMode) {
465 fill( eventInfo );
466 return StatusCode::SUCCESS;
467 }
468
469 SG::Decorator<float> corrAvgIntPerXingDec(m_prefix+"corrected_averageInteractionsPerCrossing");
471 if(!corrAvgIntPerXingDec.isAvailable(eventInfo))
472 corrAvgIntPerXingDec(eventInfo) = getCorrectedAverageInteractionsPerCrossing(eventInfo,false);
473 return StatusCode::SUCCESS;
474 }
475
476 //just copy the value over for MC
477 if(!corrAvgIntPerXingDec.isAvailable(eventInfo))
478 corrAvgIntPerXingDec(eventInfo) = eventInfo.averageInteractionsPerCrossing();
479
480 //decorate with random run number etc
481 SG::Decorator<unsigned int> rrnDec(m_prefix+"RandomRunNumber");
482 SG::ConstAccessor<unsigned int> rrnAcc(rrnDec.auxid());
483 if(!rrnDec.isAvailable(eventInfo)){
484 unsigned int rrn = getRandomRunNumber( eventInfo, mu_dependent );
485 rrnDec(eventInfo) = (rrn==0) ? getRandomRunNumber(eventInfo, false) : rrn;
486 }
487 SG::Decorator<unsigned int> rlbnDec(m_prefix+"RandomLumiBlockNumber");
488 SG::Decorator<unsigned int> rlbnAcc(rlbnDec.auxid());
489 if(!rlbnDec.isAvailable(eventInfo))
490 rlbnDec(eventInfo) = (rrnAcc(eventInfo)==0) ? 0 : /*m_tool->*/GetRandomLumiBlockNumber( rrnAcc(eventInfo) );
491 SG::Decorator<ULong64_t> prwHashDec(m_prefix+"PRWHash");
492 if(!prwHashDec.isAvailable(eventInfo))
493 prwHashDec(eventInfo) = getPRWHash( eventInfo );
494
495 //decorate with standard PileupWeight
496 SG::Decorator<float> puWeightDec(m_prefix+"PileupWeight");
497 SG::ConstAccessor<float> puWeightAcc(puWeightDec.auxid());
498 if(!m_noWeightsMode && !puWeightDec.isAvailable(eventInfo))
499 puWeightDec(eventInfo) = getCombinedWeight(eventInfo, true);
500
501 ATH_MSG_VERBOSE("PileupWeight = " << puWeightAcc(eventInfo) << " RandomRunNumber = " << rrnAcc(eventInfo) << " RandomLumiBlockNumber = " << rlbnAcc(eventInfo));
502
503 return StatusCode::SUCCESS;
504}
505
506float PileupReweightingTool::getDataWeight(const xAOD::EventInfo& eventInfo, const TString& trigger, bool mu_dependent) {
507
509 ATH_MSG_WARNING("Requesting Data Weight is not intended for simulated events. Returning 1.");
510 return 1; //no data weights for simulated events
511 }
512
513 if(!mu_dependent) return /*m_tool->*/m_activeTool->GetDataWeight(eventInfo.runNumber(), trigger);
514
515 double correctedMu = getCorrectedAverageInteractionsPerCrossing(eventInfo,false);
516 if(correctedMu<0) {
517 ATH_MSG_ERROR("Unrecognised run+lumiblock number (" << eventInfo.runNumber() << "," << eventInfo.lumiBlock() << ") ... please ensure your lumicalc files are complete! Returning 1.");
518 return 1;
519 }
520
521 return /*m_tool->*/m_activeTool->GetDataWeight( eventInfo.runNumber(), trigger, correctedMu/*use the 'correct' mu instead of the one from the file!!*/ );
522
523}
524
525float PileupReweightingTool::getPrescaleWeight( const xAOD::EventInfo& eventInfo , const TString& trigger, bool mu_dependent ) {
526 //need to use the random run number ... only used to pick the subperiod, but in run2 so far we only have one subperiod
527 SG::ConstAccessor<unsigned int> rrnAcc (m_prefix+"RandomRunNumber");
528 unsigned int randomRunNum = rrnAcc.withDefault (eventInfo, 0);
529 if (randomRunNum == 0) {
530 randomRunNum = getRandomRunNumber( eventInfo, mu_dependent );
531 }
532 if(!mu_dependent) return m_activeTool->GetPrescaleWeight(randomRunNum, trigger);
533 return m_activeTool->GetPrescaleWeight( randomRunNum, trigger, getCorrectedAverageInteractionsPerCrossing(eventInfo,false) /*use the 'correct' mu instead of the one from the file!!*/, m_useRunDependentPrescaleWeight /*run-dependent*/ );
534}
535
536float PileupReweightingTool::getCombinedWeight( const xAOD::EventInfo& eventInfo , const TString& trigger, bool mu_dependent, bool correctUnrepresented ) {
537 float out = getCombinedWeight(eventInfo, correctUnrepresented);
538 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
539
540 out *= getPrescaleWeight(eventInfo, trigger, mu_dependent);
541 return out;
542}
543
544
545} // 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.
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:140
Select isolated Photons, Electrons and Muons.
SG::Decorator< T, ALLOC > Decorator
Helper class to provide type-safe access to aux data, specialized for JaggedVecElt.
Definition AuxElement.h:576
EventInfo_v1 EventInfo
Definition of the latest event info version.
TFile * file
int run(int argc, char *argv[])