ATLAS Offline Software
Loading...
Searching...
No Matches
PixelChargeLUTCalibCondAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "GaudiKernel/EventIDRange.h"
11#include "PixelConditionsData/PixelChargeCalibUtils.h" //getBecAndLayer
14
15#include <nlohmann/json.hpp>
17
18#include <fstream>
19#include <stdexcept>
20#include <memory>
21#include <sstream>
22
23
24using namespace PixelChargeCalib; //containing LegacyFitParameters etc
25
27namespace{
28 constexpr int halfModuleThreshold{8};
29} // namespace
30
31
32PixelChargeLUTCalibCondAlg::PixelChargeLUTCalibCondAlg(const std::string& name, ISvcLocator* pSvcLocator):
33 ::AthCondAlgorithm(name, pSvcLocator){
34}
35
37 ATH_MSG_DEBUG("PixelChargeLUTCalibCondAlg::initialize()");
38 ATH_CHECK(detStore()->retrieve(m_pixelID, m_pixelIDName.value()));
39 ATH_CHECK(m_pixelDetEleCollKey.initialize());
40 ATH_CHECK(m_configKey.initialize());
42 ATH_CHECK(m_writeKey.initialize());
43 return StatusCode::SUCCESS;
44}
45
46StatusCode PixelChargeLUTCalibCondAlg::execute(const EventContext& ctx) const {
47 ATH_MSG_DEBUG("PixelChargeLUTCalibCondAlg::execute()");
48
50 if (writeHandle.isValid()) {
51 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.");
52 return StatusCode::SUCCESS;
53 }
54
56 const InDetDD::SiDetectorElementCollection* elements(*pixelDetEleHandle);
57 if (not pixelDetEleHandle.isValid() or elements==nullptr) {
58 ATH_MSG_FATAL(m_pixelDetEleCollKey.fullKey() << " is not available.");
59 return StatusCode::FAILURE;
60 }
61
62 static constexpr std::array<InDetDD::PixelDiodeType, enum2uint(InDetDD::PixelDiodeType::N_DIODETYPES)> diodeTypes
64
66 const PixelModuleData *configData = *configDataHandle;
67
68 // Construct the output Cond Object and fill it in
69 std::unique_ptr<PixelChargeCalibCondData> writeCdo(std::make_unique<PixelChargeCalibCondData>(m_pixelID->wafer_hash_max()));
70
71 const EventIDBase start{EventIDBase::UNDEFNUM, EventIDBase::UNDEFEVT, 0, 0, EventIDBase::UNDEFNUM, EventIDBase::UNDEFNUM};
72 const EventIDBase stop {EventIDBase::UNDEFNUM, EventIDBase::UNDEFEVT, EventIDBase::UNDEFNUM-1, EventIDBase::UNDEFNUM-1, EventIDBase::UNDEFNUM, EventIDBase::UNDEFNUM};
73
74 EventIDRange rangeW{start, stop};
75 if (!m_readKey.empty()) {
77 const CondAttrListCollection* readCdo = *readHandle;
78 if (readCdo==nullptr) {
79 ATH_MSG_FATAL("Null pointer to the read conditions object");
80 return StatusCode::FAILURE;
81 }
82 // Get the validitiy range
83 if (not readHandle.range(rangeW)) {
84 ATH_MSG_FATAL("Failed to retrieve validity range for " << readHandle.key());
85 return StatusCode::FAILURE;
86 }
87 ATH_MSG_INFO("Size of CondAttrListCollection " << readHandle.fullKey() << " readCdo->size()= " << readCdo->size());
88 ATH_MSG_INFO("Range of input is " << rangeW);
89 std::unique_ptr<IChargeCalibrationParser> pParser{};
90
91 for (const auto & attrList : *readCdo) {
92 const CondAttrListCollection::AttributeList &payload = attrList.second;
93
94 // RUN-3 format
95 if (payload.exists("data_array") and not payload["data_array"].isNull()) {
96 ATH_MSG_DEBUG("Using LUTChargeCalibParser");
97 pParser = std::make_unique<LUTChargeCalibParser>(configData, elements, m_pixelID);
98 std::string fileName = PathResolver::find_file(m_jsonFileName, "DATAPATH");
99 if (m_inputSource == 2 && fileName.empty()) {
100 ATH_MSG_FATAL("Input file" << fileName << " not found! Change the inputSource!");
101 return StatusCode::FAILURE;
102 }
103 std::ifstream infile(fileName.c_str());
104 //Read the contents of the text file into a string
105 std::string fileContent((std::istreambuf_iterator<char>(infile)), std::istreambuf_iterator<char>());
106 const nlohmann::json & jsonData = (m_inputSource == 0 || m_inputSource == 1) ?
107 nlohmann::json::parse(payload["data_array"].data<std::string>()) :
108 nlohmann::json::parse(fileContent);
109 for (const auto &[hash, data] : jsonData.items()) {
110 const unsigned int moduleHash = std::stoul(hash);
111 IdentifierHash wafer_hash = IdentifierHash(moduleHash);
112 const InDetDD::SiDetectorElement *element = elements->getDetectorElement(wafer_hash);
113 const InDetDD::PixelModuleDesign *p_design = static_cast<const InDetDD::PixelModuleDesign*>(&element->design());
114 const ChargeCalibrationBundle & b = pParser->parse(moduleHash, data, m_inputSource);
115 if (not b.isValid){
116 ATH_MSG_FATAL("Parsing failed");
117 return StatusCode::FAILURE;
118 }
119 // Special calibration
120 if (!b.tot2Charges.empty()) {
121 writeCdo -> setTot2Charges(moduleHash, b.tot2Charges);
122 }
123 //calibration strategy
124 writeCdo -> setAllFromBundle(moduleHash, b);
125
126 // Ganged/large pixel
128 writeCdo -> setThresholds(InDetDD::PixelDiodeType::LARGE, moduleHash, b.thresholdGanged);
129 writeCdo -> setLegacyFitParameters(InDetDD::PixelDiodeType::LARGE, moduleHash, b.paramsGanged); //uses the ganged answer
130 writeCdo -> setLinearFitParameters(InDetDD::PixelDiodeType::LARGE, moduleHash, b.linGanged);
131 } else {
132 writeCdo -> setThresholds(InDetDD::PixelDiodeType::GANGED, moduleHash, b.thresholdGanged);
133 writeCdo -> setLegacyFitParameters(InDetDD::PixelDiodeType::GANGED, moduleHash, b.paramsGanged);
134 writeCdo -> setLinearFitParameters(InDetDD::PixelDiodeType::GANGED, moduleHash, b.linGanged);
135 }
136 }
137 }
138 }
139 } else {
140 for (unsigned int moduleHash{}; moduleHash < m_pixelID->wafer_hash_max(); moduleHash++) {
141 const auto & becLayer = getBecAndLayer(m_pixelID, moduleHash);
142 IdentifierHash wafer_hash = IdentifierHash(moduleHash);
143 const InDetDD::SiDetectorElement *element = elements->getDetectorElement(wafer_hash);
144 const InDetDD::PixelModuleDesign *p_design = static_cast<const InDetDD::PixelModuleDesign*>(&element->design());
145 unsigned int numFE = p_design->numberOfCircuits() < halfModuleThreshold ? p_design->numberOfCircuits() : 2 * p_design->numberOfCircuits();
146 writeCdo -> setAllFromConfigData(moduleHash, configData, becLayer, numFE);
147 }
148 }
149
150 // Scan over if the DB contents need to be overwritten.
151 // This is useful for threshold study. So far only threshold value.
152 for (unsigned int moduleHash{}; moduleHash < m_pixelID->wafer_hash_max(); moduleHash++) {
153 IdentifierHash wafer_hash = IdentifierHash(moduleHash);
154 Identifier wafer_id = m_pixelID->wafer_id(wafer_hash);
155 int barrel_ec = m_pixelID->barrel_ec(wafer_id);
156 int layer = m_pixelID->layer_disk(wafer_id);
157 const InDetDD::SiDetectorElement *element = elements->getDetectorElement(wafer_hash);
158 const InDetDD::PixelModuleDesign *p_design = static_cast<const InDetDD::PixelModuleDesign*>(&element->design());
159 // in some cases numberOfCircuits returns FEs per half-module
160 unsigned int numFE = p_design->numberOfCircuits() < halfModuleThreshold ? p_design->numberOfCircuits() : 2 * p_design->numberOfCircuits();
161 Thresholds defaults{configData->getDefaultAnalogThreshold(barrel_ec, layer), configData->getDefaultAnalogThresholdSigma(barrel_ec, layer),
162 configData->getDefaultAnalogThresholdNoise(barrel_ec, layer), configData->getDefaultInTimeThreshold(barrel_ec, layer)};
163 if (defaults.value > -0.1) {
164 for (InDetDD::PixelDiodeType type : diodeTypes) {
165 writeCdo -> setThresholds(type, moduleHash, std::vector<Thresholds>(numFE, defaults));
166 }
167 }
168 }
169
170 if (writeHandle.record(rangeW, std::move(writeCdo)).isFailure()) {
171 ATH_MSG_FATAL("Could not record PixelChargeCalibCondData " << writeHandle.key() << " with EventRange " << rangeW << " into Conditions Store");
172 return StatusCode::FAILURE;
173 }
174 ATH_MSG_INFO("recorded new CDO " << writeHandle.key() << " with range " << rangeW << " into Conditions Store");
175
176 return StatusCode::SUCCESS;
177}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
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 run4 Look-Up-Table 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 used to describe the design of a module (diode segmentation and readout scheme)
PixelReadoutTechnology getReadoutTechnology() const
int numberOfCircuits() const
Total number of circuits:
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 const SiDetectorDesign & design() const override final
access to the local description (inline):
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
virtual StatusCode initialize() override final
Gaudi::Property< std::string > m_jsonFileName
Gaudi::Property< std::string > m_pixelIDName
SG::WriteCondHandleKey< PixelChargeCalibCondData > m_writeKey
SG::ReadCondHandleKey< PixelModuleData > m_configKey
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_pixelDetEleCollKey
PixelChargeLUTCalibCondAlg(const std::string &name, ISvcLocator *pSvcLocator)
virtual StatusCode execute(const EventContext &ctx) const override final
SG::ReadCondHandleKey< CondAttrListCollection > m_readKey
int getDefaultInTimeThreshold(int barrel_ec, int layer) const
int getDefaultAnalogThreshold(int barrel_ec, int layer) const
int getDefaultAnalogThresholdNoise(int barrel_ec, int layer) 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< int, int > getBecAndLayer(const PixelID *pPixelId, IdentifierHash hash)
bundles of parameters used together in the PixelChargeCalibCondAlg