ATLAS Offline Software
ParticleScaleFactorTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // ReweightUtils includes
7 
9 
11 
12 #include "TH2D.h"
13 #include "TKey.h"
14 #include "TClass.h"
15 #include "TFile.h"
16 
17 ParticleScaleFactorTool::ParticleScaleFactorTool( const std::string& name ) : asg::AsgTool( name ){
18 
19  declareProperty( "File", m_configFile = "" , "User should specify config file to read");
20 
21 }
22 
24 
25  //delete all histograms
26  for(auto& a : m_hists) {
27  for(auto& b : a.second.hists) {
28  delete b.second;
29  }
30  }
31 
32 }
33 
35 
36 
38  if(file=="") return StatusCode::FAILURE;
39 
40  TFile* f = TFile::Open(file.c_str());
41 
42  if(!f) {
43  ATH_MSG_ERROR("Could not open file " << file);
44  return StatusCode::FAILURE;
45  }
46 
47  m_affectingSysts.insert(CP::SystematicVariation("")); //add the nominal syst
48 
49  //loop over the keys in the file, we are looking for TDirectory (systematics) and TH1 (factors)
50  std::unique_ptr<TIterator> itr(f->GetListOfKeys()->MakeIterator());
51  TKey* key = 0;
52  while( (key = static_cast<TKey*>(itr->Next())) ) {
53  TClass* cl = TClass::GetClass(key->GetClassName());
54  if(!cl || !cl->InheritsFrom(TDirectory::Class())) continue;
55  ATH_MSG_DEBUG("Detected systematic " << key->GetName());
57  if(!CP::SystematicVariation(key->GetName()).parameter()) {
58  ATH_MSG_ERROR("Systematic must be of form: <string>__Xup OR <string>__Xdown ... where X is a number");
59  return StatusCode::FAILURE;
60  }
61  }
62 
63  itr->Reset();
64  while( (key = static_cast<TKey*>(itr->Next())) ) {
65  TClass* cl = TClass::GetClass(key->GetClassName());
66  if(!cl || !cl->InheritsFrom("TH1")) continue;
67 
68 
69  ATH_MSG_DEBUG("Detected scale factor " << key->GetName());
70 
71  //loop over systematics
72  for(auto& syst : m_affectingSysts) {
73  TString h = (syst==CP::SystematicVariation("")) ? std::string(key->GetName()) : syst.name()+ "/" + std::string(key->GetName());
74  TH1* hist = static_cast<TH1*>(f->Get(h));
75  if(!hist) {
76  if(!(syst==CP::SystematicVariation(""))) {
77  ATH_MSG_VERBOSE("No " << syst.name() << " variation of " << key->GetName());
78  continue; //fine, just no systematic variation
79  } else {
80  ATH_MSG_ERROR("Failed at retrieving " << key->GetName());
81  return StatusCode::FAILURE;
82  }
83  }
84  //detect particle type from title
85  xAOD::Type::ObjectType type = xAOD::Type::Other;
86  if(strcmp(hist->GetTitle(),"Electron")==0) type = xAOD::Type::Electron;
87  else if(strcmp(hist->GetTitle(),"Muon")==0) type = xAOD::Type::Muon;
88  else if(strcmp(hist->GetTitle(),"Jet")==0) type = xAOD::Type::Jet;
89  else if(strcmp(hist->GetTitle(),"Photon")==0) type = xAOD::Type::Photon;
90  else if(strcmp(hist->GetTitle(),"Tau")==0) type = xAOD::Type::Tau;
91  else {
92  ATH_MSG_ERROR("Unknown particle type: " << hist->GetTitle());
93  return StatusCode::FAILURE;
94  }
95 
96  //check all axis are labelled
97  if(strlen(hist->GetXaxis()->GetTitle())==0 ||
98  (hist->GetDimension()>1 && strlen(hist->GetYaxis()->GetTitle())==0) ||
99  (hist->GetDimension()>2 && strlen(hist->GetZaxis()->GetTitle())==0) ) {
100  ATH_MSG_ERROR("All axis of histogram " << hist->GetName() << " need to be labelled");
101  return StatusCode::FAILURE;
102  }
103  //see if nominal already present, if it is we have to 'extend' the existing histogram
104  TH1*& existHist = m_hists[type].hists[syst.name()];
105  if(existHist) {
106  ATH_MSG_DEBUG("Combining " << hist->GetTitle() << ": f(" <<
107  existHist->GetXaxis()->GetTitle() << "," << hist->GetXaxis()->GetTitle() <<
108  ") = 2*f(" << existHist->GetXaxis()->GetTitle() << ")*f(" <<
109  hist->GetXaxis()->GetTitle() << ")/[f(" << existHist->GetXaxis()->GetTitle() <<
110  ")+f(" << hist->GetXaxis()->GetTitle() << ")]");
111 
112  TH1* newHist = 0;
113  if(existHist->GetDimension()==1 && hist->GetDimension()==1) {
114  std::vector<double> binEdges1, binEdges2;
115  for(int i=1;i<=existHist->GetNbinsX()+1;i++) binEdges1.push_back(existHist->GetBinLowEdge(i));
116  for(int i=1;i<=hist->GetNbinsX()+1;i++) binEdges2.push_back(hist->GetBinLowEdge(i));
117  newHist = new TH2D("myHist","myHist",existHist->GetNbinsX(),&binEdges1[0],hist->GetNbinsX(),&binEdges2[0]);
118  newHist->SetDirectory(0);
119  newHist->GetXaxis()->SetTitle(existHist->GetTitle());
120  newHist->GetYaxis()->SetTitle(hist->GetTitle());
121  for(int i=0;i<=existHist->GetNbinsX()+1;i++) {
122  for(int j=0;j<=hist->GetNbinsX()+1;j++) {
123  double a = existHist->GetBinContent(i); double b = hist->GetBinContent(j);
124  if(a && b) newHist->SetBinContent(newHist->GetBin(i,j), 2.0 * (a*b)/(a+b) );
125  //combine error ...
126  if(!(syst==CP::SystematicVariation(""))) {
127  double da = existHist->GetBinError(i);double db = hist->GetBinError(j);
128  if(a && b) newHist->SetBinError(newHist->GetBin(i,j), 2.0 * (da*b*b + db*a*a)/((a+b)*(a+b)) );
129  }
130  }
131  }
132  delete existHist;
133  existHist = newHist;
134  } else {
135  ATH_MSG_ERROR("Unsupported scale factor reparamertization :-(");
136  return StatusCode::FAILURE;
137  }
138 
139  } else {
140  existHist = static_cast<TH1*>(hist->Clone("myHist")); existHist->SetDirectory(0);
141  //no systematic if nominal hist ...
142  //if(syst==CP::SystematicVariation("")) for(int i=0;i<(hist->GetNbinsX()+2)*(hist->GetNbinsY()+2)*(hist->GetNbinsZ()+2);i++) hist->SetBinError(i,0);
143  }
144 
145  if(syst==CP::SystematicVariation("")) {
146  for(int i=0;i<hist->GetDimension();i++) {
147  std::string axisTitle = ( i==0 ) ? hist->GetXaxis()->GetTitle() : ( (i==1) ? hist->GetYaxis()->GetTitle() : hist->GetZaxis()->GetTitle() );
148  axisTitle.erase(remove_if(axisTitle.begin(), axisTitle.end(), isspace),axisTitle.end());
149  std::function<double(const xAOD::IParticle&)> bfunc;
150  ATH_MSG_DEBUG(" Parameter " << axisTitle);
151  if(axisTitle=="pt" || axisTitle=="pt/MeV" || axisTitle=="pt[MeV]") {
152  bfunc = part_pt;
153  } else if(axisTitle == "pt/GeV" || axisTitle=="pt[GeV]") {
154  bfunc = part_pt_gev;
155  } else if(axisTitle=="eta") {
156  bfunc = part_eta;
157  } else {
158  bfunc = std::bind(part_decor, std::placeholders::_1, axisTitle);
159  }
160  m_hists[type].axisFuncs.push_back(bfunc);
161  }
162  }
163  }
164 
165 
166 
167 
168  }
169 
170  //remove the nominal syst to finish up
173  for(auto& s : tmpSet) {
174  if(s==CP::SystematicVariation("")) continue;
176  //m_affectingSysts.insert(CP::SystematicVariation(s.basename(),-1)); //add the negative fluctuation
177  }
178 
179 
180  f->Close();
181  delete f;
182  f = 0;
183 
184  if(CP::SystematicRegistry::getInstance().registerSystematics(*this) != StatusCode::SUCCESS ) return StatusCode::FAILURE;
185 
186  return StatusCode::SUCCESS;
187 }
188 
190  //check we have a hist for this particle type
191  auto histItr = m_hists.find(particle->type());
192  if(histItr==m_hists.end()) {
193  ATH_MSG_ERROR("No scale factor available for particle type: " << particle->type());
194  throw std::runtime_error(TString::Format("%s : No scale factor available for particle type %d",name().c_str(),int(particle->type())).Data());
195  }
196 
197 
198  std::pair<CP::SystematicVariation,TH1*> res = histItr->second.getHist(m_currentSyst);
199 
200  const TH1* hist = res.second;
201 
202 
203  int bin = 0;
204  switch(hist->GetDimension()) {
205  case 1: bin = hist->FindFixBin(histItr->second.axisFuncs[0](*particle)); break;
206  case 2: bin = hist->FindFixBin(histItr->second.axisFuncs[0](*particle),histItr->second.axisFuncs[1](*particle)); break;
207  case 3: bin = hist->FindFixBin(histItr->second.axisFuncs[0](*particle),histItr->second.axisFuncs[1](*particle),histItr->second.axisFuncs[2](*particle)); break;
208  }
209 
210  if(!res.first.parameter()) return hist->GetBinContent(bin); //must have been nominal;
211 
212  double nom = histItr->second.getHist(CP::SystematicVariation("")).second->GetBinContent(bin);
213  //got here so get nominal hist and do difference ...
214  return nom + (m_currentSyst.parameter()/res.first.parameter()) * (hist->GetBinContent(bin) - nom);
215 
216 
217 
218 
219 
220 }
221 
222 const std::pair<CP::SystematicVariation,TH1*> ParticleScaleFactorTool::Hists::getHist(const CP::SystematicVariation& set) const {
223  //find hist that matches basename and take the one that has the closest parameter value
224  std::pair<CP::SystematicVariation,TH1*> result(CP::SystematicVariation(""),0);
225  for(auto& s : hists) {
226  if(s.first.basename()!=set.basename()) continue;
227  if(!result.second) {result = s;}
228  else {
229  if(set.parameter()*s.first.parameter()>0) result = s;
230  }
231  }
232  if(result.second) return result;
233  //return nominal
234  auto it = hists.find(CP::SystematicVariation(""));
235  result = *it; return result;
236  //return it->second;
237 }
238 
239 
240 
242  for(auto& syst : systConfig) {
243  for(auto& s : m_affectingSysts) {
244  if(s.basename()==syst.basename()) {
245  m_currentSyst = syst; m_isNominal=false;
246  return StatusCode::SUCCESS;
247  }
248  }
249  }
251  m_isNominal = true;
252  return StatusCode::SUCCESS;
253 }
254 
255 
256 
ParticleScaleFactorTool::Hists::hists
std::map< CP::SystematicVariation, TH1 * > hists
Definition: ParticleScaleFactorTool.h:73
Trk::ParticleSwitcher::particle
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
Definition: ParticleHypothesis.h:76
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
xAOD::Electron
Electron_v1 Electron
Definition of the current "egamma version".
Definition: Event/xAOD/xAODEgamma/xAODEgamma/Electron.h:17
get_generator_info.result
result
Definition: get_generator_info.py:21
ParticleScaleFactorTool::ParticleScaleFactorTool
ParticleScaleFactorTool(const std::string &name)
Definition: ParticleScaleFactorTool.cxx:17
ParticleScaleFactorTool::applySystematicVariation
StatusCode applySystematicVariation(const CP::SystematicSet &systConfig) override
effects: configure this tool for the given list of systematic variations.
Definition: ParticleScaleFactorTool.cxx:241
ObjectType
ObjectType
Definition: BaseObject.h:11
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
plotmaker.hist
hist
Definition: plotmaker.py:148
StateLessPT_NewConfig.Format
Format
Definition: StateLessPT_NewConfig.py:146
CaloCondBlobAlgs_fillNoiseFromASCII.db
db
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:43
skel.it
it
Definition: skel.GENtoEVGEN.py:396
asg
Definition: DataHandleTestTool.h:28
CP::SystematicSet
Class to wrap a set of SystematicVariations.
Definition: SystematicSet.h:31
bin
Definition: BinsDiffFromStripMedian.h:43
ParticleScaleFactorTool::Hists::getHist
const std::pair< CP::SystematicVariation, TH1 * > getHist(const CP::SystematicVariation &set) const
Definition: ParticleScaleFactorTool.cxx:222
ParticleScaleFactorTool::part_decor
static double part_decor(const xAOD::IParticle &p, const std::string &varname)
Definition: ParticleScaleFactorTool.h:37
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
CP::SystematicVariation
Definition: SystematicVariation.h:47
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:41
ParticleScaleFactorTool::m_currentSyst
CP::SystematicVariation m_currentSyst
Definition: ParticleScaleFactorTool.h:70
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
ParticleScaleFactorTool::part_pt
static double part_pt(const xAOD::IParticle &p)
Definition: ParticleScaleFactorTool.h:34
lumiFormat.i
int i
Definition: lumiFormat.py:85
SystematicRegistry.h
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
MakeNewFileFromOldAndSubstitution.newHist
dictionary newHist
Definition: ICHEP2016/MakeNewFileFromOldAndSubstitution.py:96
ParticleScaleFactorTool::m_affectingSysts
CP::SystematicSet m_affectingSysts
Definition: ParticleScaleFactorTool.h:80
res
std::pair< std::vector< unsigned int >, bool > res
Definition: JetGroupProductTest.cxx:14
file
TFile * file
Definition: tile_monitor.h:29
hist_file_dump.f
f
Definition: hist_file_dump.py:135
xAOD::double
double
Definition: CompositeParticle_v1.cxx:159
CxxUtils::set
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
Definition: bitmask.h:232
ParticleScaleFactorTool::initialize
virtual StatusCode initialize() override
Initialize is required by AsgTool base class.
Definition: ParticleScaleFactorTool.cxx:34
PathResolver.h
PlotSFuncertainty.nom
nom
Definition: PlotSFuncertainty.py:141
CP::SystematicSet::insert
void insert(const SystematicVariation &systematic)
description: insert a systematic into the set
Definition: SystematicSet.cxx:88
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
ParticleScaleFactorTool::m_configFile
std::string m_configFile
Definition: ParticleScaleFactorTool.h:68
ParticleScaleFactorTool::m_hists
std::map< xAOD::Type::ObjectType, Hists > m_hists
Definition: ParticleScaleFactorTool.h:78
xAOD::Photon
Photon_v1 Photon
Definition of the current "egamma version".
Definition: Event/xAOD/xAODEgamma/xAODEgamma/Photon.h:17
PathResolverFindCalibFile
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Definition: PathResolver.cxx:431
Muon
struct TBPatternUnitContext Muon
CP::SystematicSet::clear
void clear()
description: clear the set
Definition: SystematicSet.cxx:119
ParticleScaleFactorTool::m_isNominal
bool m_isNominal
Definition: ParticleScaleFactorTool.h:81
a
TList * a
Definition: liststreamerinfos.cxx:10
h
ParticleScaleFactorTool.h
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
ParticleScaleFactorTool::part_eta
static double part_eta(const xAOD::IParticle &p)
Definition: ParticleScaleFactorTool.h:36
xAODType::Tau
@ Tau
The object is a tau (jet)
Definition: ObjectType.h:49
ParticleScaleFactorTool::~ParticleScaleFactorTool
~ParticleScaleFactorTool()
Definition: ParticleScaleFactorTool.cxx:23
dq_make_web_display.cl
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition: dq_make_web_display.py:26
xAOD::Jet
Jet_v1 Jet
Definition of the current "jet version".
Definition: Event/xAOD/xAODJet/xAODJet/Jet.h:17
ParticleScaleFactorTool::part_pt_gev
static double part_pt_gev(const xAOD::IParticle &p)
Definition: ParticleScaleFactorTool.h:35
CP::SystematicRegistry::getInstance
static SystematicRegistry & getInstance()
Get the singleton instance of the registry for the curren thread.
Definition: SystematicRegistry.cxx:25
ParticleScaleFactorTool::evaluate
virtual double evaluate(const xAOD::IParticle *particle) const override
returns: the value that was calculated from the xAOD::IParticle
Definition: ParticleScaleFactorTool.cxx:189
CP::SystematicVariation::parameter
float parameter() const
description: the numeric parameter contained in the subvariation(), or 0 if the subvariation can't be...
Definition: SystematicVariation.cxx:340
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37