ATLAS Offline Software
PFCellEOverPTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
8 
9 #include "GaudiKernel/SystemOfUnits.h"
10 
12 #include <nlohmann/json.hpp>
13 
14 #include <vector>
15 #include <iomanip>
16 #include <fstream>
17 #include <sstream>
18 
20  const std::string& name,
21  const IInterface* parent)
23 {
24 
25  declareInterface<IEFlowCellEOverPTool>(this);
26 
27 }
28 
30 
31  std::string path;
33 
34  ATH_MSG_INFO("Using reference file location " + path);
35 
36  std::ifstream binBoundariesFile(path+"binBoundaries.json");
37  nlohmann::json json_binBoundaries;
38  binBoundariesFile >> json_binBoundaries;
39 
40  //whilst for calo layers and first interaction regions we want to lookup the full set of bin values
41  auto fillBinValues = [](auto && binBoundaries, const nlohmann::json &json_binBoundaries, const std::string &binName){
42  if (json_binBoundaries.contains(binName)){
43  for (auto binBoundary : json_binBoundaries[binName]) binBoundaries.push_back(binBoundary);
44  return true;
45  }
46  else return false;
47  };
48 
49  bool filledBins = false;
50  std::string energyBinBoundaries = "energyBinBoundaries";
51  std::string etaBinBoundaries = "etaBinBoundaries";
52  std::string firstIntBinBoundaries = "firstIntBinBoundaries";
53  std::string caloLayerBinBoundaries = "caloLayerBinBoundaries";
54 
55  //here we verify we can load in the bin boundaries - if not we return a FAILURE code
56  //because particle flow cannot run correctly without these being loaded
57  filledBins = fillBinValues(m_energyBinLowerBoundaries, json_binBoundaries, energyBinBoundaries);
58  if (!filledBins) {
59  ATH_MSG_ERROR("Could not bin boundaries in json file: " << energyBinBoundaries);
60  return StatusCode::FAILURE;
61  }
62  //remove the last bin boundary - the e/p derivation code measures e/p in an energy range and our json
63  //contains the bin boundaries as usded by the e/p derivation code:
64  //https://gitlab.cern.ch/atlas-jetetmiss/pflow/commontools/EOverPTools/-/blob/0dee81d8823be1fd725af2cfe62391bcb904b683/EoverpNtupleAnalysis/Run_EoverP_Comparison.py#L100
65  //But e.g if the last pair if boundaries are 40 and 100 GeV we measure e/p between those values, but we
66  //want to allow any track with e > 40 GeV to find an e/p reference value.
67  //Note the same issue cannot occur for eta, calo layer or first interaction region bins
68  //because there is a hard upper limit from the detector geometry - so a track can never
69  //e.g have an eta above the final eta bin boundary
70  m_energyBinLowerBoundaries.pop_back();
71  filledBins = fillBinValues(m_etaBinLowerBoundaries, json_binBoundaries, etaBinBoundaries);
72  if (!filledBins) {
73  ATH_MSG_ERROR("Could not bin boundaries in json file: " << etaBinBoundaries);
74  return StatusCode::FAILURE;
75  }
76  filledBins = fillBinValues(m_firstIntBinLowerBoundaries, json_binBoundaries, firstIntBinBoundaries);
77  if (!filledBins) {
78  ATH_MSG_ERROR("Could not bin boundaries in json file: " << firstIntBinBoundaries);
79  return StatusCode::FAILURE;
80  }
81  filledBins = fillBinValues(m_caloLayerBins, json_binBoundaries, caloLayerBinBoundaries);
82  if (!filledBins) {
83  ATH_MSG_ERROR("Could not bin boundaries in json file: " << caloLayerBinBoundaries);
84  return StatusCode::FAILURE;
85  }
86 
87  ATH_MSG_DEBUG("Energy bin boundaries: " << m_energyBinLowerBoundaries);
88  ATH_MSG_DEBUG("Eta bin boundaries: " << m_etaBinLowerBoundaries);
89  ATH_MSG_DEBUG("First interaction region bin boundaries: " << m_firstIntBinLowerBoundaries);
90  ATH_MSG_DEBUG("Calo layer bin boundaries: " << m_caloLayerBins);
91 
92  return StatusCode::SUCCESS;
93 }
94 
96 
97  if (binnedParameters) {
98 
99  //The energy values in the json files are in GeV, but in athena we work in MeV
100  //so the energy values used by binnedParameters are converted to MeV
101  std::vector<double> energyBinLowerBoundaries_GeV;
102  for (auto energyBin : m_energyBinLowerBoundaries) energyBinLowerBoundaries_GeV.push_back(energyBin*Gaudi::Units::GeV);
103  binnedParameters->initialise(energyBinLowerBoundaries_GeV, m_etaBinLowerBoundaries);
104 
105  std::string path;
107 
108  std::ifstream inputFile_eoverp(path+"eOverP.json");
109  nlohmann::json json_eoverp;
110  inputFile_eoverp >> json_eoverp;
111 
112  std::ifstream inputFile_cellOrdering(path+"cellOrdering.json");
113  nlohmann::json json_cellOrdering;
114  inputFile_cellOrdering >> json_cellOrdering;
115 
116  //Loop over energy, eta and first int bins
117  //For each combination we set the e/p mean and width from the json file values
118  int energyBinCounter = -1;
119  for (auto thisEBin : m_energyBinLowerBoundaries){
120  energyBinCounter++;
121  std::stringstream currentEBinStream;
122  currentEBinStream << std::fixed << std::setprecision(0) << thisEBin;
123  std::string currentEBin = currentEBinStream.str();
124  int etaBinCounter = -1;
125  for (auto thisEtaBin : m_etaBinLowerBoundaries){
126  etaBinCounter++;
127  std::stringstream currentEtaBinStream;
128  currentEtaBinStream << std::fixed << std::setprecision(1) << thisEtaBin;
129  std::string currentEtaBin = currentEtaBinStream.str();
130  for (auto thisFirstIntRegionBin_Int : m_firstIntBinLowerBoundaries){
131  //enum version is used for the calls to binnedParameters APIs
132  auto thisFirstIntRegionBin = static_cast<eflowFirstIntRegions::J1STLAYER>(thisFirstIntRegionBin_Int);
133  //and string version is used to lookup values from the json file
134  std::string currentFirstIntBin = std::to_string(thisFirstIntRegionBin_Int);
135  std::string eOverPBin = "energyBinLowerBound_"+currentEBin+"_etaBinLowerBound_"+currentEtaBin+"_firstIntBinLowerBound_"+currentFirstIntBin;
136  if (json_eoverp.contains(eOverPBin+"_mean")){
137  binnedParameters->setFudgeMean(energyBinCounter,etaBinCounter,thisFirstIntRegionBin,json_eoverp[eOverPBin+"_mean"]);
138  ATH_MSG_DEBUG("Setting mean for bin " << eOverPBin << " to " << json_eoverp[eOverPBin+"_mean"]);
139  }
140  //DEBUG because this is expected to happen for some combinations (e.g HEC calo layers for tracks in the barrel)
141  else ATH_MSG_DEBUG("No mean found for bin " << eOverPBin);
142  if (json_eoverp.contains(eOverPBin+"_sigma")){
143  binnedParameters->setFudgeStdDev(energyBinCounter,etaBinCounter,thisFirstIntRegionBin,json_eoverp[eOverPBin+"_sigma"]);
144  ATH_MSG_DEBUG("Setting sigma for bin " << eOverPBin << " to " << json_eoverp[eOverPBin+"_sigma"]);
145  }
146  else ATH_MSG_DEBUG("No sigma found for bin " << eOverPBin);
147  for (auto thisLayerBin : m_caloLayerBins){
148  eflowCalo::LAYER thisLayerBinEnum = static_cast<eflowCalo::LAYER>(thisLayerBin);
149  std::string currentLayerBin = eflowCalo::name(thisLayerBinEnum);
150  std::string cellOrderingBin = eOverPBin + "_caloLayer_"+std::to_string(thisLayerBin);
151  if (json_cellOrdering.contains(cellOrderingBin+"_norm1")){
152  binnedParameters->setShapeParam(energyBinCounter,etaBinCounter,thisFirstIntRegionBin,thisLayerBinEnum,NORM1,json_cellOrdering[cellOrderingBin+"_norm1"]);
153  ATH_MSG_DEBUG("Setting norm1 for bin " << cellOrderingBin << " to " << json_cellOrdering[cellOrderingBin+"_norm1"]);
154  }
155  else ATH_MSG_DEBUG("No norm1 found for bin " << cellOrderingBin);
156  if (json_cellOrdering.contains(cellOrderingBin+"_sigma1")){
157  binnedParameters->setShapeParam(energyBinCounter,etaBinCounter,thisFirstIntRegionBin,thisLayerBinEnum,WIDTH1,json_cellOrdering[cellOrderingBin+"_sigma1"]);
158  ATH_MSG_DEBUG("Setting sigma1 for bin " << cellOrderingBin << " to " << json_cellOrdering[cellOrderingBin+"_sigma1"]);
159  }
160  else ATH_MSG_DEBUG("No sigma1 found for bin " << cellOrderingBin);
161  if (json_cellOrdering.contains(cellOrderingBin+"_norm2")){
162  binnedParameters->setShapeParam(energyBinCounter,etaBinCounter,thisFirstIntRegionBin,thisLayerBinEnum,NORM2,json_cellOrdering[cellOrderingBin+"_norm2"]);
163  ATH_MSG_DEBUG("Setting norm2 for bin " << cellOrderingBin << " to " << json_cellOrdering[cellOrderingBin+"_norm2"]);
164  }
165  else ATH_MSG_DEBUG("No norm2 found for bin " << cellOrderingBin);
166  if (json_cellOrdering.contains(cellOrderingBin+"_sigma2")){
167  binnedParameters->setShapeParam(energyBinCounter,etaBinCounter,thisFirstIntRegionBin,thisLayerBinEnum,WIDTH2,json_cellOrdering[cellOrderingBin+"_sigma2"]);
168  ATH_MSG_DEBUG("Setting sigma2 for bin " << cellOrderingBin << " to " << json_cellOrdering[cellOrderingBin+"_sigma2"]);
169  }
170  else ATH_MSG_DEBUG("No sigma2 found for bin " << cellOrderingBin);
171  }
172  }
173  }
174  }
175  }
176 
177  return StatusCode::SUCCESS;
178 
179 }
180 
182  return StatusCode::SUCCESS;
183 }
eflowCaloRegions.h
GeV
#define GeV
Definition: PhysicsAnalysis/TauID/TauAnalysisTools/Root/HelperFunctions.cxx:17
eflowCalo::name
static const std::string & name(LAYER layer)
Definition: eflowCaloRegions.cxx:53
eflowEEtaBinnedParameters
Inherits from eflowEEtaBinBase.
Definition: eflowEEtaBinnedParameters.h:56
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:128
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
json
nlohmann::json json
Definition: HistogramDef.cxx:9
IEFlowCellEOverPTool
Pure virtual base class, from which concrete classes inherit and define reference e/p mean and widths...
Definition: IEFlowCellEOverPTool.h:30
IEFlowCellEOverPTool::WIDTH2
@ WIDTH2
Definition: IEFlowCellEOverPTool.h:49
IEFlowCellEOverPTool::NORM2
@ NORM2
Definition: IEFlowCellEOverPTool.h:49
IEFlowCellEOverPTool::WIDTH1
@ WIDTH1
Definition: IEFlowCellEOverPTool.h:49
PFCellEOverPTool::m_etaBinLowerBoundaries
std::vector< double > m_etaBinLowerBoundaries
Definition: PFCellEOverPTool.h:30
PFCellEOverPTool::m_referenceFileLocation
Gaudi::Property< std::string > m_referenceFileLocation
Location for e/p and cell ordering reference files (set to null value so one cannot use a wrong refer...
Definition: PFCellEOverPTool.h:35
PathResolverFindCalibDirectory
std::string PathResolverFindCalibDirectory(const std::string &logical_file_name)
Definition: PathResolver.cxx:432
PFCellEOverPTool.h
PFCellEOverPTool::finalize
StatusCode finalize()
Definition: PFCellEOverPTool.cxx:181
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
PFCellEOverPTool::m_caloLayerBins
std::vector< int > m_caloLayerBins
Definition: PFCellEOverPTool.h:32
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
test_pyathena.parent
parent
Definition: test_pyathena.py:15
PFCellEOverPTool::fillBinnedParameters
StatusCode fillBinnedParameters(eflowEEtaBinnedParameters *binnedParameters) const
Definition: PFCellEOverPTool.cxx:95
eflowEEtaBinnedParameters::setFudgeStdDev
void setFudgeStdDev(int energyBin, int etaBin, eflowFirstIntENUM j1st, double fudgeStdDev)
Definition: eflowEEtaBinnedParameters.h:69
eflowEEtaBinnedParameters::setFudgeMean
void setFudgeMean(int energyBin, int etaBin, eflowFirstIntENUM j1st, double fudgeMean)
Definition: eflowEEtaBinnedParameters.h:63
eflowEEtaBinnedParameters::initialise
void initialise(const std::vector< double > &eBinBounds, const std::vector< double > &etaBinBounds, bool useAbsEta=true)
Definition: eflowEEtaBinnedParameters.cxx:33
PathResolver.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
eflowEEtaBinnedParameters::setShapeParam
void setShapeParam(int energyBin, int etaBin, eflowFirstIntENUM j1st, eflowCaloENUM layer, int paramNumber, double shapeParam)
Definition: eflowEEtaBinnedParameters.h:75
eflowCalo::LAYER
LAYER
Definition: eflowCaloRegions.h:36
PFCellEOverPTool::m_energyBinLowerBoundaries
std::vector< double > m_energyBinLowerBoundaries
Definition: PFCellEOverPTool.h:29
PFCellEOverPTool::initialize
StatusCode initialize()
Definition: PFCellEOverPTool.cxx:29
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
PFCellEOverPTool::PFCellEOverPTool
PFCellEOverPTool(const std::string &type, const std::string &name, const IInterface *parent)
Definition: PFCellEOverPTool.cxx:19
PFCellEOverPTool::m_firstIntBinLowerBoundaries
std::vector< int > m_firstIntBinLowerBoundaries
Definition: PFCellEOverPTool.h:31
IEFlowCellEOverPTool::NORM1
@ NORM1
Definition: IEFlowCellEOverPTool.h:49
histSizes.filledBins
def filledBins(h)
Definition: histSizes.py:11
eflowEEtaBinnedParameters.h
eflowFirstIntRegions::J1STLAYER
J1STLAYER
Definition: eflowCaloRegions.h:58