ATLAS Offline Software
Loading...
Searching...
No Matches
PixelChargeCalibCondAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
10#include "PixelConditionsData/ChargeCalibParameters.h" //LegacyFitParameters, LinearFitParameters, Thresholds, Resolutions
13
17#include "GaudiKernel/EventIDRange.h"
18#include <memory>
19#include <sstream>
20
21#include <nlohmann/json.hpp>
22
23#include <iostream>
24#include <fstream>
25#include <iomanip>
26
27
30
31using namespace PixelChargeCalib; //containing LegacyFitParameters etc
33
34
35
36PixelChargeCalibCondAlg::PixelChargeCalibCondAlg(const std::string& name, ISvcLocator* pSvcLocator):
37 ::AthCondAlgorithm(name, pSvcLocator){
38
39}
40
42 ATH_MSG_DEBUG("PixelChargeCalibCondAlg::initialize()");
43 ATH_CHECK(detStore()->retrieve(m_pixelID,"PixelID"));
44 ATH_CHECK(m_pixelDetEleCollKey.initialize());
45 ATH_CHECK(m_configKey.initialize());
47 ATH_CHECK(m_writeKey.initialize());
48 return StatusCode::SUCCESS;
49}
50
51StatusCode PixelChargeCalibCondAlg::execute(const EventContext& ctx) const {
52 ATH_MSG_DEBUG("PixelChargeCalibCondAlg::execute()");
53
55 if (writeHandle.isValid()) {
56 ATH_MSG_DEBUG("CondHandle " << writeHandle.fullKey() << " is already valid.. In theory this should not be called, but may happen if multiple concurrent events are being processed out of order.");
57 return StatusCode::SUCCESS;
58 }
59
61 const InDetDD::SiDetectorElementCollection* elements(*pixelDetEleHandle);
62 if (not pixelDetEleHandle.isValid() or elements==nullptr) {
63 ATH_MSG_FATAL(m_pixelDetEleCollKey.fullKey() << " is not available.");
64 return StatusCode::FAILURE;
65 }
66
67 static constexpr std::array<InDetDD::PixelDiodeType, enum2uint(InDetDD::PixelDiodeType::N_DIODETYPES)> diodeTypes
69
71 const PixelModuleData *configData = *configDataHandle;
72
73
74 // Construct the output Cond Object and fill it in
75 auto writeCdo = std::make_unique<PixelChargeCalibCondData>(m_pixelID->wafer_hash_max());
76 //
77 const EventIDBase start{EventIDBase::UNDEFNUM, EventIDBase::UNDEFEVT, 0, 0, EventIDBase::UNDEFNUM, EventIDBase::UNDEFNUM};
78 const EventIDBase stop {EventIDBase::UNDEFNUM, EventIDBase::UNDEFEVT, EventIDBase::UNDEFNUM-1, EventIDBase::UNDEFNUM-1, EventIDBase::UNDEFNUM, EventIDBase::UNDEFNUM};
79 EventIDRange rangeW{start, stop};
80 unsigned int channel_warnings=0;
81 unsigned int max_channel_warnings=10;
82 unsigned int min_invalid_channel=std::numeric_limits<unsigned int>::max();
83 unsigned int max_invalid_channel=0;
84 if (!m_readKey.empty()) {
86 const CondAttrListCollection* readCdo = *readHandle;
87 if (readCdo==nullptr) {
88 ATH_MSG_FATAL("Null pointer to the read conditions object");
89 return StatusCode::FAILURE;
90 }
91 // Get the validitiy range
92 if (not readHandle.range(rangeW)) {
93 ATH_MSG_FATAL("Failed to retrieve validity range for " << readHandle.key());
94 return StatusCode::FAILURE;
95 }
96 ATH_MSG_INFO("Size of CondAttrListCollection " << readHandle.fullKey() << " readCdo->size()= " << readCdo->size());
97 ATH_MSG_INFO("Range of input is " << rangeW);
98
99 std::unique_ptr<IChargeCalibrationParser> pParser{};
100 for (const auto & attrList : *readCdo) {
101 const CondAttrListCollection::ChanNum &channelNumber = attrList.first;
102 const CondAttrListCollection::AttributeList &payload = attrList.second;
103 // RUN-3 format
104 if (payload.exists("data_array") and not payload["data_array"].isNull()) {
105 pParser = std::make_unique<Run3ChargeCalibParser>(configData, elements, m_pixelID);
106 const nlohmann::json &jsonData = nlohmann::json::parse(payload["data_array"].data<std::string>());
107 for (const auto &[hash, data] : jsonData.items()) {
108 const unsigned int moduleHash = std::stoul(hash);
109 const ChargeCalibrationBundle & b = pParser->parse(moduleHash, data);
110 if (not b.isValid){
111 ATH_MSG_FATAL("Parsing failed");
112 return StatusCode::FAILURE;
113 }
114 writeCdo -> setAllFromBundle(moduleHash, b);
115 }
116 } else if (payload.exists("data") and not payload["data"].isNull()) { // RUN-2 format
117 pParser = std::make_unique<Run2ChargeCalibParser>(configData, elements, m_pixelID);
118 // ignore invalid channelNumbers
119 // otherwise usage of e.g. CONDBR2-HLTP-2018-03 will lead to range errors.
120 if (channelNumber >= m_pixelID->wafer_hash_max()) {
121 min_invalid_channel = std::min(min_invalid_channel,channelNumber);
122 max_invalid_channel = std::max(max_invalid_channel,channelNumber);
123 if (channel_warnings++ < max_channel_warnings) {
124 ATH_MSG_WARNING("Invalid module hash (COOL channel number: " << channelNumber << " !< " << m_pixelID->wafer_hash_max() << ")."
125 << (channel_warnings==max_channel_warnings ? " Further such warnings will not be reported." : ""));
126 }
127 continue;
128 }
129 const unsigned int moduleHash = channelNumber;
130 std::string stringStatus = payload["data"].data<std::string>();
131 const ChargeCalibrationBundle & b = pParser->parse(moduleHash, stringStatus);
132 if (not b.isValid){
133 ATH_MSG_FATAL("Parsing failed");
134 return StatusCode::FAILURE;
135 }
136 writeCdo -> setAllFromBundle(moduleHash, b);
137 } else {
138 ATH_MSG_ERROR("payload[\"data\"] does not exist for ChanNum " << channelNumber);
139 return StatusCode::FAILURE;
140 }
141 }
142 } else {
143 for (unsigned int moduleHash{}; moduleHash < m_pixelID->wafer_hash_max(); moduleHash++) {
144 IdentifierHash wafer_hash = IdentifierHash(moduleHash);
145 const auto & [barrel_ec, layer] = getBecAndLayer(m_pixelID, wafer_hash);
146 const InDetDD::SiDetectorElement *element = elements->getDetectorElement(wafer_hash);
147 const auto & [numFE, technology] = numChipsAndTechnology(element);
148 const Thresholds defaultThreshold{configData->getDefaultAnalogThreshold(barrel_ec, layer), configData->getDefaultAnalogThresholdSigma(barrel_ec, layer),
149 configData->getDefaultAnalogThresholdNoise(barrel_ec, layer), configData->getDefaultInTimeThreshold(barrel_ec, layer)};
150 const std::vector<Thresholds> allDefaultThresholds(numFE, defaultThreshold);
151 //
152 const LegacyFitParameters defaultParam{configData->getDefaultQ2TotA(), configData->getDefaultQ2TotE(), configData->getDefaultQ2TotC(), LegacyFitParameters::defaultOverflow};
153 const std::vector<LegacyFitParameters> allDefaultFitParams(numFE, defaultParam);
154 //
155 const LinearFitParameters defaultLinParam{0.0f, 0.0f};
156 const std::vector<LinearFitParameters> allDefaultLinearParams(numFE, defaultLinParam);
157 //
158 for (InDetDD::PixelDiodeType type : diodeTypes) {
159 writeCdo -> setThresholds(type, moduleHash, allDefaultThresholds);
160 writeCdo -> setLegacyFitParameters(type, moduleHash, allDefaultFitParams);
161 writeCdo -> setLinearFitParameters(type, moduleHash, allDefaultLinearParams);
162 }
163 writeCdo -> setTotResolutions(moduleHash, std::vector<Resolutions>(numFE, {0.f, 0.f}));
164 }
165 }
166 if (channel_warnings>max_channel_warnings) {
167 ATH_MSG_WARNING("Encountered " << channel_warnings << " invalid channel numbers (range " << min_invalid_channel << " .. "
168 << max_invalid_channel << " !< " << m_pixelID->wafer_hash_max() << ")");
169 }
170
171 // Scan over if the DB contents need to be overwritten.
172 // This is useful for threshold study. So far only threshold value.
173 for (unsigned int moduleHash{}; moduleHash < m_pixelID->wafer_hash_max(); moduleHash++) {
174 IdentifierHash wafer_hash = IdentifierHash(moduleHash);
175 const auto & [barrel_ec, layer] = getBecAndLayer(m_pixelID, wafer_hash);
176 const InDetDD::SiDetectorElement *element = elements->getDetectorElement(wafer_hash);
177 const auto & [numFE, technology] = numChipsAndTechnology(element);
178 Thresholds defaults{configData->getDefaultAnalogThreshold(barrel_ec, layer), configData->getDefaultAnalogThresholdSigma(barrel_ec, layer),
179 configData->getDefaultAnalogThresholdNoise(barrel_ec, layer), configData->getDefaultInTimeThreshold(barrel_ec, layer)};
180 if (defaults.value > -0.1) {
181 for (InDetDD::PixelDiodeType type : diodeTypes) {
182 writeCdo -> setThresholds(type, moduleHash, std::vector<Thresholds>(numFE, defaults));
183 }
184 }
185 }
186
187 if (writeHandle.record(rangeW, std::move(writeCdo)).isFailure()) {
188 ATH_MSG_FATAL("Could not record PixelChargeCalibCondData " << writeHandle.key() << " with EventRange " << rangeW << " into Conditions Store");
189 return StatusCode::FAILURE;
190 }
191 ATH_MSG_INFO("recorded new CDO " << writeHandle.key() << " with range " << rangeW << " into Conditions Store");
192
193 return StatusCode::SUCCESS;
194}
195
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Structs for holding charge calibration parameterisation and data.
Struct for holding vectors of charge calibration constants, with utility methods.
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
Interface to parsers which accept a string or json object and return a ChargeCalibrationBundle.
constexpr std::size_t enum2uint(T n, std::string_view callingFunctionName="")
Convert an enum class to size_t for use as an array index.
Parses a database run3 format string to a ChargeCalibrationBundle.
Parses a database run3 format string to a ChargeCalibrationBundle.
const ServiceHandle< StoreGateSvc > & detStore() const
Base class for conditions algorithms.
This class is a collection of AttributeLists where each one is associated with a channel number.
size_type size() const
number of Chan/AttributeList pairs
coral::AttributeList AttributeList
This is a "hash" representation of an Identifier.
Class to hold the SiDetectorElement objects to be put in the detector store.
const SiDetectorElement * getDetectorElement(const IdentifierHash &hash) const
Class to hold geometrical description of a silicon detector element.
virtual StatusCode initialize() override final
SG::ReadCondHandleKey< CondAttrListCollection > m_readKey
SG::ReadCondHandleKey< PixelModuleData > m_configKey
PixelChargeCalibCondAlg(const std::string &name, ISvcLocator *pSvcLocator)
SG::WriteCondHandleKey< PixelChargeCalibCondData > m_writeKey
virtual StatusCode execute(const EventContext &ctx) const override final
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_pixelDetEleCollKey
int getDefaultInTimeThreshold(int barrel_ec, int layer) const
int getDefaultAnalogThreshold(int barrel_ec, int layer) const
float getDefaultQ2TotA() const
int getDefaultAnalogThresholdNoise(int barrel_ec, int layer) const
float getDefaultQ2TotC() const
float getDefaultQ2TotE() const
int getDefaultAnalogThresholdSigma(int barrel_ec, int layer) const
bool range(EventIDRange &r)
const std::string & key() const
const DataObjID & fullKey() const
const std::string & key() const
StatusCode record(const EventIDRange &range, T *t)
record handle, with explicit range DEPRECATED
const DataObjID & fullKey() const
constexpr std::size_t enum2uint(T n, std::string_view callingFunctionName="")
Convert an enum class to size_t for use as an array index.
std::pair< size_t, InDetDD::PixelReadoutTechnology > numChipsAndTechnology(const InDetDD::SiDetectorElement *element)
std::pair< int, int > getBecAndLayer(const PixelID *pPixelId, IdentifierHash hash)
bundles of parameters used together in the PixelChargeCalibCondAlg