ATLAS Offline Software
Loading...
Searching...
No Matches
AlignmentCondAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "AlignmentCondAlg.h"
6
7#include <fstream>
8#include <map>
9#include <string>
13#include "CoralBase/Attribute.h"
14#include "CoralBase/AttributeListSpecification.h"
15#include "GaudiKernel/ConcurrencyFlags.h"
20
21namespace Muon{
23 ATH_MSG_DEBUG("Initilalizing");
24 if (!m_loadALines && !m_loadBLines) {
25 ATH_MSG_ERROR("There's no point in setting up this algorithm if neither A or B Lines shall be processed");
26 return StatusCode::FAILURE;
27 }
28 ATH_MSG_INFO("In initialize ---- # of folders registered is " << m_alignKeys.size());
29 // Read Handles Keys
30 ATH_CHECK(m_alignKeys.initialize(m_readFromJSON.value().empty()));
31 // Write Handles
34 ATH_CHECK(m_idHelperSvc.retrieve());
35 return StatusCode::SUCCESS;
36}
37
38StatusCode AlignmentCondAlg::execute(const EventContext& ctx) const {
39 ATH_MSG_DEBUG("execute " << name());
40
41 if (m_loadALines) {
42 SG::WriteCondHandle writeALineHandle{m_writeALineKey, ctx};
43 if (writeALineHandle.isValid()) {
44 ATH_MSG_DEBUG("CondHandle " << writeALineHandle.fullKey() << " is already valid."
45 << ". In theory this should not be called, but may happen"
46 << " if multiple concurrent events are being processed out of order.");
47 return StatusCode::SUCCESS;
48 }
49 }
51 // =======================
52 // Write BLine Cond Handle
53 // =======================
54 if (m_loadBLines) {
55 SG::WriteCondHandle writeBLineHandle{m_writeBLineKey, ctx};
56 if (writeBLineHandle.isValid()) {
57 ATH_MSG_DEBUG("CondHandle " << writeBLineHandle.fullKey() << " is already valid."
58 << ". In theory this should not be called, but may happen"
59 << " if multiple concurrent events are being processed out of order.");
60 return StatusCode::SUCCESS;
61 }
62 }
64 auto writeALineCdo{std::make_unique<ALineContainer>()};
65 auto writeBLineCdo{std::make_unique<BLineContainer>()};
66
68 ATH_CHECK(loadCoolFolder(ctx, key, *writeALineCdo, *writeBLineCdo));
69 }
70 if (!m_readFromJSON.value().empty()) {
71 std::ifstream inStream{PathResolverFindCalibFile(m_readFromJSON)};
72 if (!inStream.good()) {
73 ATH_MSG_FATAL("No such file or directory");
74 return StatusCode::FAILURE;
75 }
76 nlohmann::json lines;
77 inStream >> lines;
78 ATH_CHECK(parseDataFromJSON(lines, *writeALineCdo, *writeBLineCdo));
79 }
80 ATH_CHECK(writeContainer(ctx, m_writeALineKey, std::move(writeALineCdo)));
81 ATH_CHECK(writeContainer(ctx, m_writeBLineKey, std::move(writeBLineCdo)));
82
83 return StatusCode::SUCCESS;
84}
85template <class ContType>
86 StatusCode AlignmentCondAlg::writeContainer(const EventContext& ctx,
88 std::unique_ptr<ContType>&& container) const {
89 if (writeKey.empty()) {
90 ATH_MSG_DEBUG("The key of type "<<typeid(ContType).name()<<" is not set. Assume that nothing shall be written.");
91 return StatusCode::SUCCESS;
92 }
93 SG::WriteCondHandle writeHandle{writeKey, ctx};
94 writeHandle.addDependency(EventIDRange(IOVInfiniteRange::infiniteTime()));
97 SG::ReadCondHandle readHandle{key, ctx};
98 if (!readHandle.isValid()){
99 ATH_MSG_FATAL("Failed to load alignment folder "<<key.fullKey());
100 return StatusCode::FAILURE;
101 }
102 ATH_MSG_INFO("Attach new dependency from <"<<readHandle.key()<<"> to the "<<typeid(ContType).name()<<". IOV: "<<readHandle.getRange());
103 writeHandle.addDependency(readHandle);
104 }
105 ATH_CHECK(writeHandle.record(std::move(container)));
106 return StatusCode::SUCCESS;
107}
108StatusCode AlignmentCondAlg::loadCoolFolder(const EventContext& ctx,
110 ALineContainer& writeALineCdo,
111 BLineContainer& writeBLineCdo) const {
112
113 SG::ReadCondHandle readHandle{key, ctx};
114 if (!readHandle.isValid()){
115 ATH_MSG_FATAL("Failed to load alignment folder "<<key.fullKey());
116 return StatusCode::FAILURE;
117 }
118 ATH_MSG_VERBOSE("Load constants from folder "<<key.key());
119 // unpack the strings in the collection and update the
120 // ALlineContainer in TDS
121 for (CondAttrListCollection::const_iterator itr = readHandle->begin(); itr != readHandle->end(); ++itr) {
122 const coral::AttributeList& atr = itr->second;
123 std::string data{};
124 if (atr["data"].specification().type() == typeid(coral::Blob)) {
125 ATH_MSG_VERBOSE("Loading data as a BLOB, uncompressing...");
127 ATH_MSG_FATAL("Cannot uncompress BLOB! Aborting...");
128 return StatusCode::FAILURE;
129 }
130 } else {
131 data = *(static_cast<const std::string*>((atr["data"]).addressOfData()));
132 }
133 nlohmann::json lines;
134
135 // new format -----------------------------------
136 if (m_newFormat2020) {
137 nlohmann::json j = nlohmann::json::parse(data);
138 lines = j["corrections"];
139 }
140 // old format -----------------------------------
141 else {
142 ATH_CHECK(loadDataFromLegacy(data, lines, true));
143 }
144 ATH_CHECK(parseDataFromJSON(lines, writeALineCdo, writeBLineCdo));
145 }
146 return StatusCode::SUCCESS;
147}
148
149StatusCode AlignmentCondAlg::parseDataFromJSON(const nlohmann::json& lines,
150 ALineContainer& writeALineCdo,
151 BLineContainer& writeBLineCdo) const{
152 // loop over corrections ------------------------
153 for (auto& corr : lines.items()) {
154 nlohmann::json line = corr.value();
155
157 const std::string stationType = line["typ"];
158 const int stationPhi = line["jff"];
159 const int stationEta = line["jzz"];
160 const int multiLayer = line["job"];
161 Identifier id{0};
163 if (stationType[0] == 'M') {
164 if (!m_idHelperSvc->hasMM()) {
165 ATH_MSG_VERBOSE("No Mms defined skipping: "<<stationType<<","<<","<<stationEta<<","<<stationPhi<<","<<multiLayer);
166 continue;
167 }
168 id = m_idHelperSvc->mmIdHelper().channelID(stationType, stationEta, stationPhi, multiLayer, 1, 1);
169 } else if (stationType[0] == 'S') {
170 if (!m_idHelperSvc->hasSTGC()) {
171 ATH_MSG_VERBOSE("No sTgcs defined skipping: "<<stationType<<","<<","<<stationEta<<","<<stationPhi<<","<<multiLayer);
172 continue;
173 }
174 id = m_idHelperSvc->stgcIdHelper().elementID(stationType, stationEta, stationPhi);
175 id = m_idHelperSvc->stgcIdHelper().multilayerID(id, multiLayer);
176 } else if (stationType[0] == 'T') {
178 if (!m_idHelperSvc->hasTGC()) {
179 ATH_MSG_VERBOSE("No Tgcs defined skipping: "<<stationType<<","<<","<<stationEta<<","<<stationPhi);
180 continue;
181 }
182 int stPhi = MuonGM::stationPhiTGC(stationType, stationPhi, stationEta);
183 int stEta = stationEta > 0 ? 1 : -1;
184 if (multiLayer != 0) {
185 // this should become the default now
186 stEta = stationEta > 0 ? multiLayer: - multiLayer;
187 }
188 id = m_idHelperSvc->tgcIdHelper().elementID(stationType, stEta, stPhi);
189 } else if (stationType[0] == 'C') {
190 if (!m_idHelperSvc->hasCSC()) {
191 ATH_MSG_VERBOSE("No Cscs defined skipping: "<<stationType<<","<<","<<stationEta<<","<<stationPhi);
192 continue;
193 }
194 id = m_idHelperSvc->cscIdHelper().elementID(stationType, stationEta, stationPhi);
195 } else if (stationType.substr(0, 3) == "BML" && std::abs(stationEta) == 7) {
196 if (!m_idHelperSvc->hasRPC()) {
197 ATH_MSG_VERBOSE("No Rpcs defined skipping "<<stationType<<","<<","<<stationEta<<","<<stationPhi);
198 continue;
199 }
200 // rpc case
201 id = m_idHelperSvc->rpcIdHelper().elementID(stationType, stationEta, stationPhi, 1);
202 } else if (m_idHelperSvc->hasMDT()) {
203 bool isValid = false;
204 id = m_idHelperSvc->mdtIdHelper().elementID(stationType, stationEta, stationPhi, isValid);
205 if (!isValid) {
206 ATH_MSG_WARNING("Invalid MDT station " << stationType
207 << " eta " << stationEta
208 << " phi " << stationPhi);
209 continue;
210 }
211 } else {
212 continue;
213 }
214 ALinePar newALine{};
215 newALine.setIdentifier(id);
216 newALine.setAmdbId(stationType, stationEta, stationPhi, multiLayer);
217 newALine.setParameters(line["svalue"], line["zvalue"], line["tvalue"],
218 line["tsv"], line["tzv"], line["ttv"]);
219 auto aLineInsert = writeALineCdo.insert(newALine);
220 if (newALine && !aLineInsert.second) {
221 ATH_MSG_WARNING("Failed to insert A line "<<newALine<<" for "<<m_idHelperSvc->toString(id)
222 <<" because "<<(*aLineInsert.first)<<" has been added before");
223 }
224 ATH_MSG_VERBOSE("Inserted new a Line "<<newALine<<" "<<m_idHelperSvc->toString(id));
225
226 if (line.find("bz") == line.end()) {
227 continue;
228 }
229 BLinePar newBLine{};
230 newBLine.setParameters(line["bz"], line["bp"], line["bn"],
231 line["sp"], line["sn"], line["tw"],
232 line["pg"], line["tr"], line["eg"],
233 line["ep"], line["en"]);
234 newBLine.setIdentifier(id);
235 newBLine.setAmdbId(stationType, stationEta, stationPhi, multiLayer);
236 ATH_MSG_VERBOSE(" HardwareChamberName " << static_cast<std::string>(line["hwElement"]));
237 auto bLineInsert = writeBLineCdo.insert(newBLine);
238 if (newBLine && !bLineInsert.second){
239 ATH_MSG_WARNING("Failed to insert B line "<<newBLine<<" for "<<m_idHelperSvc->toString(id)
240 <<" because "<<(*bLineInsert.first)<<" has been added before.");
241 }
242 }
243 return StatusCode::SUCCESS;
244}
245
246StatusCode AlignmentCondAlg::loadDataFromLegacy(const std::string& data, nlohmann::json& json,
247 bool loadBLines) const {
248
249 // Parse corrections
250 constexpr std::string_view delimiter{"\n"};
251
252 json = nlohmann::json::array();
253 auto lines = CxxUtils::tokenize(data, delimiter);
254 for (const std::string& blobline : lines) {
255 nlohmann::json line;
256 constexpr std::string_view delimiter{":"};
257 const auto tokens = CxxUtils::tokenize(blobline, delimiter);
258
259 // Check if tokens is not empty
260 if (tokens.empty()) {
261 ATH_MSG_FATAL("Empty string retrieved from DB in folder ");
262 return StatusCode::FAILURE;
263 }
264 const std::string_view &type = tokens[0];
265 // Parse line
266 if (type[0] == '#') {
267 continue;
268 }
269 //#: Corr line is counter typ, jff, jzz, job, * Chamber information
270 //#: svalue, zvalue, tvalue, tsv, tzv, ttv, * A lines
271 //#: bz, bp, bn, sp, sn, tw, pg, tr, eg, ep, en * B lines
272 //#: chamber * Chamber name
273 //.... example
274 // Corr: EMS 4 1 0 2.260 3.461 28.639 -0.002402 -0.002013 0.000482 -0.006 -0.013 -0.006000 0.000000
275 // 0.000000 0.026 -0.353 0.000000 0.070000 0.012000 -0.012 EMS1A08
276
277 if (type.compare(0, 4, "Corr") == 0) {
278 constexpr std::string_view delimiter{" "};
279 auto tokens = CxxUtils::tokenize(blobline, delimiter);
280 if (tokens.size() != 25) {
281 ATH_MSG_FATAL("Invalid length in string retrieved. String length is " << tokens.size());
282 return StatusCode::FAILURE;
283 }
284 // Start parsing
285 int ival = 1;
286 // Station Component identification
287 line["typ"] = std::string(tokens[ival++]);
288 line["jff"] = CxxUtils::atoi(tokens[ival++]);
289 line["jzz"] = CxxUtils::atoi(tokens[ival++]);
290 line["job"] = CxxUtils::atoi(tokens[ival++]);
291
292 // A-line
293 line["svalue"] = CxxUtils::atof(tokens[ival++]);
294 line["zvalue"] = CxxUtils::atof(tokens[ival++]);
295 line["tvalue"] = CxxUtils::atof(tokens[ival++]);
296
297 line["tsv"] = CxxUtils::atof(tokens[ival++]);
298 line["tzv"] = CxxUtils::atof(tokens[ival++]);
299 line["ttv"] = CxxUtils::atof(tokens[ival++]);
300
301 // B-line
302 if (loadBLines) {
303 line["bz"] = CxxUtils::atof(tokens[ival++]);
304 line["bp"] = CxxUtils::atof(tokens[ival++]);
305 line["bn"] = CxxUtils::atof(tokens[ival++]);
306 line["sp"] = CxxUtils::atof(tokens[ival++]);
307 line["sn"] = CxxUtils::atof(tokens[ival++]);
308 line["tw"] = CxxUtils::atof(tokens[ival++]);
309 line["pg"] = CxxUtils::atof(tokens[ival++]);
310 line["tr"] = CxxUtils::atof(tokens[ival++]);
311 line["eg"] = CxxUtils::atof(tokens[ival++]);
312 line["ep"] = CxxUtils::atof(tokens[ival++]);
313 line["en"] = CxxUtils::atof(tokens[ival++]);
314
315 line["xAtlas"] = CxxUtils::atof(tokens[ival++]);
316 line["yAtlas"] = CxxUtils::atof(tokens[ival++]);
317
318 // ChamberName (hardware convention)
319 line["hwElement"] = std::string(tokens[ival++]);
320 }
321 json.push_back(std::move(line));
322 }
323 }
324 return StatusCode::SUCCESS;
325}
326}
#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_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
bool isValid(const T &p)
Av: we implement here an ATLAS-sepcific convention: all particles which are 99xxxxx are fine.
Definition AtlasPID.h:878
This file defines the class for a collection of AttributeLists where each one is associated with a ch...
std::set< ALinePar, std::less<> > ALineContainer
std::set< BLinePar, std::less<> > BLineContainer
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
nlohmann::json json
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
void setParameters(float s, float z, float t, float rotS, float rotZ, float rotT)
Definition ALinePar.cxx:26
void setParameters(float bz, float bp, float bn, float sp, float sn, float tw, float pg, float tr, float eg, float ep, float en)
Cast the parameter to an unsigned int.
Definition BLinePar.cxx:26
ChanAttrListMap::const_iterator const_iterator
static EventIDRange infiniteTime()
Produces an EventIDRange that is inifinite in Time and invalid in RunLumi.
void setIdentifier(const Identifier &id)
Setters and getters for the Athena Identifier.
void setAmdbId(const std::string &stName, int stEta, int stPhi, int stJob)
AMDB identifiers. They're often not the same as the ATLAS ones (TGCs)
Gaudi::Property< bool > m_newFormat2020
StatusCode loadCoolFolder(const EventContext &ctx, const SG::ReadCondHandleKey< CondAttrListCollection > &key, ALineContainer &writeALineCdo, BLineContainer &writeBLineCdo) const
Retrieves the alignment parameters from a COOL folder.
Gaudi::Property< bool > m_loadALines
StatusCode parseDataFromJSON(const nlohmann::json &lines, ALineContainer &writeALineCdo, BLineContainer &writeBLineCdo) const
Parse the JSON blob to fill the A & B Line containers.
StatusCode loadDataFromLegacy(const std::string &data, nlohmann::json &json, bool loadBLines) const
Load the Alignment data from the legacy format where the channels are parsed line wise The data is th...
StatusCode writeContainer(const EventContext &ctx, const SG::WriteCondHandleKey< ContType > &writeKey, std::unique_ptr< ContType > &&container) const
Attaches the dependencies of the Alignment keys onto the A & Bline container.
SG::WriteCondHandleKey< ALineContainer > m_writeALineKey
SG::ReadCondHandleKeyArray< CondAttrListCollection > m_alignKeys
Gaudi::Property< bool > m_loadBLines
virtual StatusCode initialize() override
virtual StatusCode execute(const EventContext &ctx) const override
Gaudi::Property< std::string > m_readFromJSON
Load the alignment parameters from a JSON file.
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
SG::WriteCondHandleKey< BLineContainer > m_writeBLineKey
const std::string & key() const
const EventIDRange & getRange()
bool empty() const
Test if the key is blank.
void addDependency(const EventIDRange &range)
StatusCode record(const EventIDRange &range, T *t)
record handle, with explicit range DEPRECATED
const DataObjID & fullKey() const
bool readBlobAsString(const coral::Blob &, std::string &)
std::vector< std::string > tokenize(const std::string &the_str, std::string_view delimiters)
Splits the string into smaller substrings.
double atof(std::string_view str)
Converts a string into a double / float.
int atoi(std::string_view str)
Helper functions to unpack numbers decoded in string into integers and doubles The strings are requir...
int stationPhiTGC(std::string_view stName, int fi, int zi_input)
Converts the AMDB phi index to the Identifier phi Index.
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.