ATLAS Offline Software
Loading...
Searching...
No Matches
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)
22 : IEFlowCellEOverPTool(type, name, 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
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}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
std::string PathResolverFindCalibDirectory(const std::string &logical_file_name)
IEFlowCellEOverPTool(const std::string &type, const std::string &name, const IInterface *parent)
std::vector< int > m_firstIntBinLowerBoundaries
StatusCode initialize()
std::vector< double > m_etaBinLowerBoundaries
StatusCode fillBinnedParameters(eflowEEtaBinnedParameters *binnedParameters) const
std::vector< int > m_caloLayerBins
std::vector< double > m_energyBinLowerBoundaries
PFCellEOverPTool(const std::string &type, const std::string &name, const IInterface *parent)
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...
static const std::string & name(LAYER layer)
Inherits from eflowEEtaBinBase.
void setFudgeStdDev(int energyBin, int etaBin, eflowFirstIntENUM j1st, double fudgeStdDev)
void setFudgeMean(int energyBin, int etaBin, eflowFirstIntENUM j1st, double fudgeMean)
void initialise(const std::vector< double > &eBinBounds, const std::vector< double > &etaBinBounds, bool useAbsEta=true)
void setShapeParam(int energyBin, int etaBin, eflowFirstIntENUM j1st, eflowCaloENUM layer, int paramNumber, double shapeParam)