ATLAS Offline Software
Loading...
Searching...
No Matches
MuonAlignmentCondAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
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
21MuonAlignmentCondAlg::MuonAlignmentCondAlg(const std::string& name, ISvcLocator* pSvcLocator) :
22 AthCondAlgorithm(name, pSvcLocator) {
23
24}
25
27 ATH_MSG_DEBUG("Initilalizing");
28 if (!m_loadALines && !m_loadBLines) {
29 ATH_MSG_ERROR("There's no point in setting up this algorithm if neither A or B Lines shall be processed");
30 return StatusCode::FAILURE;
31 }
32 ATH_MSG_INFO("In initialize ---- # of folders registered is " << m_alignKeys.size());
33 // Read Handles Keys
34 ATH_CHECK(m_alignKeys.initialize(m_readFromJSON.value().empty()));
35 // Write Handles
38 ATH_CHECK(m_idHelperSvc.retrieve());
39 return StatusCode::SUCCESS;
40}
41
42StatusCode MuonAlignmentCondAlg::execute(const EventContext& ctx) const {
43 ATH_MSG_DEBUG("execute " << name());
44
45 if (m_loadALines) {
47 if (writeALineHandle.isValid()) {
48 ATH_MSG_DEBUG("CondHandle " << writeALineHandle.fullKey() << " is already valid."
49 << ". In theory this should not be called, but may happen"
50 << " if multiple concurrent events are being processed out of order.");
51 return StatusCode::SUCCESS;
52 }
53 }
55 // =======================
56 // Write BLine Cond Handle
57 // =======================
58 if (m_loadBLines) {
60 if (writeBLineHandle.isValid()) {
61 ATH_MSG_DEBUG("CondHandle " << writeBLineHandle.fullKey() << " is already valid."
62 << ". In theory this should not be called, but may happen"
63 << " if multiple concurrent events are being processed out of order.");
64 return StatusCode::SUCCESS;
65 }
66 }
68 std::unique_ptr<ALineContainer> writeALineCdo{std::make_unique<ALineContainer>()};
69 std::unique_ptr<BLineContainer> writeBLineCdo{std::make_unique<BLineContainer>()};
70
72 ATH_CHECK(loadCoolFolder(ctx, key, *writeALineCdo, *writeBLineCdo));
73 }
74 if (!m_readFromJSON.value().empty()) {
75 std::ifstream inStream{PathResolverFindCalibFile(m_readFromJSON)};
76 if (!inStream.good()) {
77 ATH_MSG_FATAL("No such file or directory");
78 return StatusCode::FAILURE;
79 }
80 nlohmann::json lines;
81 inStream >> lines;
82 ATH_CHECK(parseDataFromJSON(lines, *writeALineCdo, *writeBLineCdo));
83 }
84 ATH_CHECK(writeContainer(ctx, m_writeALineKey, std::move(writeALineCdo)));
85 ATH_CHECK(writeContainer(ctx, m_writeBLineKey, std::move(writeBLineCdo)));
86
87 return StatusCode::SUCCESS;
88}
89template <class ContType>
90 StatusCode MuonAlignmentCondAlg::writeContainer(const EventContext& ctx,
92 std::unique_ptr<ContType>&& container) const {
93 if (writeKey.empty()) {
94 ATH_MSG_DEBUG("The key of type "<<typeid(ContType).name()<<" is not set. Assume that nothing shall be written.");
95 return StatusCode::SUCCESS;
96 }
97 SG::WriteCondHandle<ContType> writeHandle{writeKey, ctx};
98 writeHandle.addDependency(EventIDRange(IOVInfiniteRange::infiniteTime()));
102 if (!readHandle.isValid()){
103 ATH_MSG_FATAL("Failed to load alignment folder "<<key.fullKey());
104 return StatusCode::FAILURE;
105 }
106 ATH_MSG_INFO("Attach new dependency from <"<<readHandle.key()<<"> to the "<<typeid(ContType).name()<<". IOV: "<<readHandle.getRange());
107 writeHandle.addDependency(readHandle);
108 }
109 ATH_CHECK(writeHandle.record(std::move(container)));
110 return StatusCode::SUCCESS;
111}
112StatusCode MuonAlignmentCondAlg::loadCoolFolder(const EventContext& ctx,
114 ALineContainer& writeALineCdo,
115 BLineContainer& writeBLineCdo) const {
116
118 if (!readHandle.isValid()){
119 ATH_MSG_FATAL("Failed to load alignment folder "<<key.fullKey());
120 return StatusCode::FAILURE;
121 }
122 ATH_MSG_VERBOSE("Load constants from folder "<<key.key());
123 // unpack the strings in the collection and update the
124 // ALlineContainer in TDS
125 for (CondAttrListCollection::const_iterator itr = readHandle->begin(); itr != readHandle->end(); ++itr) {
126 const coral::AttributeList& atr = itr->second;
127 std::string data{};
128 if (atr["data"].specification().type() == typeid(coral::Blob)) {
129 ATH_MSG_VERBOSE("Loading data as a BLOB, uncompressing...");
131 ATH_MSG_FATAL("Cannot uncompress BLOB! Aborting...");
132 return StatusCode::FAILURE;
133 }
134 } else {
135 data = *(static_cast<const std::string*>((atr["data"]).addressOfData()));
136 }
137 nlohmann::json lines;
138
139 // new format -----------------------------------
140 if (m_newFormat2020) {
141 nlohmann::json j = nlohmann::json::parse(data);
142 lines = j["corrections"];
143 }
144 // old format -----------------------------------
145 else {
146 ATH_CHECK(loadDataFromLegacy(data, lines, true));
147 }
148 ATH_CHECK(parseDataFromJSON(lines, writeALineCdo, writeBLineCdo));
149 }
150 return StatusCode::SUCCESS;
151}
152
153StatusCode MuonAlignmentCondAlg::parseDataFromJSON(const nlohmann::json& lines,
154 ALineContainer& writeALineCdo,
155 BLineContainer& writeBLineCdo) const{
156 // loop over corrections ------------------------
157 for (auto& corr : lines.items()) {
158 nlohmann::json line = corr.value();
159
161 const std::string stationType = line["typ"];
162 const int stationPhi = line["jff"];
163 const int stationEta = line["jzz"];
164 const int multiLayer = line["job"];
165 Identifier id{0};
167 if (stationType[0] == 'M') {
168 if (!m_idHelperSvc->hasMM()) {
169 ATH_MSG_VERBOSE("No Mms defined skipping: "<<stationType<<","<<","<<stationEta<<","<<stationPhi<<","<<multiLayer);
170 continue;
171 }
172 id = m_idHelperSvc->mmIdHelper().channelID(stationType, stationEta, stationPhi, multiLayer, 1, 1);
173 } else if (stationType[0] == 'S') {
174 if (!m_idHelperSvc->hasSTGC()) {
175 ATH_MSG_VERBOSE("No sTgcs defined skipping: "<<stationType<<","<<","<<stationEta<<","<<stationPhi<<","<<multiLayer);
176 continue;
177 }
178 id = m_idHelperSvc->stgcIdHelper().elementID(stationType, stationEta, stationPhi);
179 id = m_idHelperSvc->stgcIdHelper().multilayerID(id, multiLayer);
180 } else if (stationType[0] == 'T') {
182 if (!m_idHelperSvc->hasTGC()) {
183 ATH_MSG_VERBOSE("No Tgcs defined skipping: "<<stationType<<","<<","<<stationEta<<","<<stationPhi);
184 continue;
185 }
186 int stPhi = MuonGM::stationPhiTGC(stationType, stationPhi, stationEta);
187 int stEta = stationEta > 0 ? 1 : -1;
188 if (multiLayer != 0) {
189 // this should become the default now
190 stEta = stationEta > 0 ? multiLayer: - multiLayer;
191 }
192 id = m_idHelperSvc->tgcIdHelper().elementID(stationType, stEta, stPhi);
193 } else if (stationType[0] == 'C') {
194 if (!m_idHelperSvc->hasCSC()) {
195 ATH_MSG_VERBOSE("No Cscs defined skipping: "<<stationType<<","<<","<<stationEta<<","<<stationPhi);
196 continue;
197 }
198 id = m_idHelperSvc->cscIdHelper().elementID(stationType, stationEta, stationPhi);
199 } else if (stationType.substr(0, 3) == "BML" && std::abs(stationEta) == 7) {
200 if (!m_idHelperSvc->hasRPC()) {
201 ATH_MSG_VERBOSE("No Rpcs defined skipping "<<stationType<<","<<","<<stationEta<<","<<stationPhi);
202 continue;
203 }
204 // rpc case
205 id = m_idHelperSvc->rpcIdHelper().elementID(stationType, stationEta, stationPhi, 1);
206 } else if (m_idHelperSvc->hasMDT()) {
207 bool isValid = false;
208 id = m_idHelperSvc->mdtIdHelper().elementID(stationType, stationEta, stationPhi, isValid);
209 if (!isValid) {
210 ATH_MSG_WARNING("Invalid MDT station " << stationType
211 << " eta " << stationEta
212 << " phi " << stationPhi);
213 continue;
214 }
215 } else {
216 continue;
217 }
218 ALinePar newALine{};
219 newALine.setIdentifier(id);
220 newALine.setAmdbId(stationType, stationEta, stationPhi, multiLayer);
221 newALine.setParameters(line["svalue"], line["zvalue"], line["tvalue"],
222 line["tsv"], line["tzv"], line["ttv"]);
223 auto aLineInsert = writeALineCdo.insert(newALine);
224 if (newALine && !aLineInsert.second) {
225 ATH_MSG_WARNING("Failed to insert A line "<<newALine<<" for "<<m_idHelperSvc->toString(id)
226 <<" because "<<(*aLineInsert.first)<<" has been added before");
227 }
228 ATH_MSG_VERBOSE("Inserted new a Line "<<newALine<<" "<<m_idHelperSvc->toString(id));
229
230 if (line.find("bz") == line.end()) {
231 continue;
232 }
233 BLinePar newBLine{};
234 newBLine.setParameters(line["bz"], line["bp"], line["bn"],
235 line["sp"], line["sn"], line["tw"],
236 line["pg"], line["tr"], line["eg"],
237 line["ep"], line["en"]);
238 newBLine.setIdentifier(id);
239 newBLine.setAmdbId(stationType, stationEta, stationPhi, multiLayer);
240 ATH_MSG_VERBOSE(" HardwareChamberName " << static_cast<std::string>(line["hwElement"]));
241 auto bLineInsert = writeBLineCdo.insert(newBLine);
242 if (newBLine && !bLineInsert.second){
243 ATH_MSG_WARNING("Failed to insert B line "<<newBLine<<" for "<<m_idHelperSvc->toString(id)
244 <<" because "<<(*bLineInsert.first)<<" has been added before.");
245 }
246 }
247 return StatusCode::SUCCESS;
248}
249
250StatusCode MuonAlignmentCondAlg::loadDataFromLegacy(const std::string& data, nlohmann::json& json,
251 bool loadBLines) const {
252
253 // Parse corrections
254 constexpr std::string_view delimiter{"\n"};
255
256 json = nlohmann::json::array();
257 auto lines = CxxUtils::tokenize(data, delimiter);
258 for (const std::string& blobline : lines) {
259 nlohmann::json line;
260 constexpr std::string_view delimiter{":"};
261 const auto tokens = CxxUtils::tokenize(blobline, delimiter);
262
263 // Check if tokens is not empty
264 if (tokens.empty()) {
265 ATH_MSG_FATAL("Empty string retrieved from DB in folder ");
266 return StatusCode::FAILURE;
267 }
268 const std::string_view &type = tokens[0];
269 // Parse line
270 if (type[0] == '#') {
271 continue;
272 }
273 //#: Corr line is counter typ, jff, jzz, job, * Chamber information
274 //#: svalue, zvalue, tvalue, tsv, tzv, ttv, * A lines
275 //#: bz, bp, bn, sp, sn, tw, pg, tr, eg, ep, en * B lines
276 //#: chamber * Chamber name
277 //.... example
278 // 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
279 // 0.000000 0.026 -0.353 0.000000 0.070000 0.012000 -0.012 EMS1A08
280
281 if (type.compare(0, 4, "Corr") == 0) {
282 constexpr std::string_view delimiter{" "};
283 auto tokens = CxxUtils::tokenize(blobline, delimiter);
284 if (tokens.size() != 25) {
285 ATH_MSG_FATAL("Invalid length in string retrieved. String length is " << tokens.size());
286 return StatusCode::FAILURE;
287 }
288 // Start parsing
289 int ival = 1;
290 // Station Component identification
291 line["typ"] = std::string(tokens[ival++]);
292 line["jff"] = CxxUtils::atoi(tokens[ival++]);
293 line["jzz"] = CxxUtils::atoi(tokens[ival++]);
294 line["job"] = CxxUtils::atoi(tokens[ival++]);
295
296 // A-line
297 line["svalue"] = CxxUtils::atof(tokens[ival++]);
298 line["zvalue"] = CxxUtils::atof(tokens[ival++]);
299 line["tvalue"] = CxxUtils::atof(tokens[ival++]);
300
301 line["tsv"] = CxxUtils::atof(tokens[ival++]);
302 line["tzv"] = CxxUtils::atof(tokens[ival++]);
303 line["ttv"] = CxxUtils::atof(tokens[ival++]);
304
305 // B-line
306 if (loadBLines) {
307 line["bz"] = CxxUtils::atof(tokens[ival++]);
308 line["bp"] = CxxUtils::atof(tokens[ival++]);
309 line["bn"] = CxxUtils::atof(tokens[ival++]);
310 line["sp"] = CxxUtils::atof(tokens[ival++]);
311 line["sn"] = CxxUtils::atof(tokens[ival++]);
312 line["tw"] = CxxUtils::atof(tokens[ival++]);
313 line["pg"] = CxxUtils::atof(tokens[ival++]);
314 line["tr"] = CxxUtils::atof(tokens[ival++]);
315 line["eg"] = CxxUtils::atof(tokens[ival++]);
316 line["ep"] = CxxUtils::atof(tokens[ival++]);
317 line["en"] = CxxUtils::atof(tokens[ival++]);
318
319 line["xAtlas"] = CxxUtils::atof(tokens[ival++]);
320 line["yAtlas"] = CxxUtils::atof(tokens[ival++]);
321
322 // ChamberName (hardware convention)
323 line["hwElement"] = std::string(tokens[ival++]);
324 }
325 json.push_back(std::move(line));
326 }
327 }
328 return StatusCode::SUCCESS;
329}
#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
Base class for conditions algorithms.
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.
virtual StatusCode execute(const EventContext &ctx) const override
SG::WriteCondHandleKey< BLineContainer > m_writeBLineKey
virtual StatusCode initialize() override
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 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...
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Gaudi::Property< std::string > m_readFromJSON
Load the alignment parameters from a JSON file.
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
Gaudi::Property< bool > m_newFormat2020
SG::ReadCondHandleKeyArray< CondAttrListCollection > m_alignKeys
MuonAlignmentCondAlg(const std::string &name, ISvcLocator *pSvcLocator)
StatusCode parseDataFromJSON(const nlohmann::json &lines, ALineContainer &writeALineCdo, BLineContainer &writeBLineCdo) const
Parse the JSON blob to fill the A & B Line containers.
Gaudi::Property< bool > m_loadBLines
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)
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.