ATLAS Offline Software
Loading...
Searching...
No Matches
MdtAsBuiltCondAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4#include <fstream>
11#include "GeoModelKernel/throwExcept.h"
12
13MdtAsBuiltCondAlg::MdtAsBuiltCondAlg(const std::string& name, ISvcLocator* pSvcLocator):
14 AthCondAlgorithm{name, pSvcLocator} {}
15
17 ATH_CHECK(m_readKey.initialize(m_readFromJSON.value().empty()));
18 ATH_CHECK(m_writeKey.initialize());
19 ATH_CHECK(m_idHelperSvc.retrieve());
20 if (!m_readFromJSON.value().empty()){
21 ATH_MSG_INFO("Load Mdt as built parameters from JSON "<<m_readFromJSON);
22 } else {
23 ATH_MSG_INFO("Load Mdt as-built from COOL <"<<m_readKey.key()<<">");
24 }
25 return StatusCode::SUCCESS;
26}
27
28StatusCode MdtAsBuiltCondAlg::execute(const EventContext& ctx) const {
30 if (writeHandle.isValid()) {
31 ATH_MSG_DEBUG("CondHandle " << writeHandle.fullKey() << " is already valid."
32 << ". In theory this should not be called, but may happen"
33 << " if multiple concurrent events are being processed out of order.");
34 return StatusCode::SUCCESS;
35 }
36 writeHandle.addDependency(EventIDRange(IOVInfiniteRange::infiniteTime()));
37 std::unique_ptr<MdtAsBuiltContainer> writeCdo{std::make_unique<MdtAsBuiltContainer>()};
38
40 if (!m_readFromJSON.value().empty()) {
41 std::ifstream inStream{PathResolverFindCalibFile(m_readFromJSON)};
42 if (!inStream.good()) {
43 ATH_MSG_FATAL("No such file or directory");
44 return StatusCode::FAILURE;
45 }
46 nlohmann::json lines;
47 inStream >> lines;
48 ATH_CHECK(parseDataFromJSON(lines, *writeCdo));
49 }
50 if (!m_readKey.empty()) {
52 if (!readHandle.isValid()){
53 ATH_MSG_FATAL("Failed to retrieve "<<m_readKey.fullKey());
54 return StatusCode::FAILURE;
55 }
56 writeHandle.addDependency(readHandle);
57
58 for (CondAttrListCollection::const_iterator itr = readHandle->begin(); itr != readHandle->end(); ++itr) {
59 const coral::AttributeList& atr = itr->second;
60 const std::string data{*(static_cast<const std::string*>((atr["data"]).addressOfData()))};
61 nlohmann::json lines;
62 if (m_newFormat2020) {
63 nlohmann::json j = nlohmann::json::parse(data);
64 lines = j["corrections"];
65 } else {
67 }
68 ATH_CHECK(parseDataFromJSON(lines, *writeCdo));
69 }
70 }
71 ATH_CHECK(writeHandle.record(std::move(writeCdo)));
72 ATH_MSG_INFO("Saved successfully Mdt as built "<<m_writeKey.fullKey()<<" with validity range "<<writeHandle.getRange());
73 return StatusCode::SUCCESS;
74}
75
76StatusCode MdtAsBuiltCondAlg::parseDataFromJSON(const nlohmann::json& lines,
77 MdtAsBuiltContainer& asBuilt) const{
78
79 // loop over corrections ------------------------
80 for (auto& corr : lines.items()) {
81 nlohmann::json line = corr.value();
83 const std::string stationType = line["typ"];
84 const int stationPhi = line["jff"];
85 const int stationEta = line["jzz"];
86 bool is_valid{false};
87 const Identifier id = m_idHelperSvc->mdtIdHelper().elementID(stationType, stationEta, stationPhi, is_valid);
88 if (!is_valid) {
89 ATH_MSG_FATAL("The AMDB identifier "<<stationType<<", "<<stationEta<<", "<<stationPhi<<" does not seem to be a MDT one");
90 return StatusCode::FAILURE;
91 }
92 MdtAsBuiltPar xPar{};
94 xPar.setAmdbId(stationType, stationEta, stationPhi, 0);
95 xPar.setIdentifier(id);
96 using multilayer_t = MdtAsBuiltPar::multilayer_t;
97 using tubeSide_t = MdtAsBuiltPar::tubeSide_t;
98 for (const multilayer_t ml : {multilayer_t::ML1, multilayer_t::ML2}){
99 for (const tubeSide_t side : {tubeSide_t::POS, tubeSide_t::NEG}){
100 std::stringstream prefix{};
101 prefix<<"Ml"<<(static_cast<unsigned>(ml) + 1);
102 prefix<<(side == tubeSide_t::POS? "Pos" : "Neg")<<"TubeSide";
103 auto getValue = [&prefix,&line, this](const std::string& val) -> float{
104 const std::string itrName = prefix.str()+val;
105 if (line.find(itrName) == line.end()) {
106 ATH_MSG_ERROR("JSON does not contain "<<itrName);
107 THROW_EXCEPTION("Bad JSON key");
108 }
109 return line[prefix.str()+val];
110 };
111 xPar.setAlignmentParameters(ml, side, getValue("y0"), getValue("z0"),
112 getValue("alpha"), getValue("ypitch"),
113 getValue("zpitch"),getValue("stagg"));
114 }
115 }
116 auto itr_pair = asBuilt.insert(xPar);
117 if (!itr_pair.second){
118 ATH_MSG_FATAL("Failed to insert "<<xPar<<" because the place in memory is already occupied by "
119 <<(*itr_pair.first));
120 return StatusCode::FAILURE;
121 }
122 ATH_MSG_VERBOSE("Added "<<(*itr_pair.first)<<" to the container");
123 }
124 return StatusCode::SUCCESS;
125}
126
127StatusCode MdtAsBuiltCondAlg::legacyFormatToJSON(const std::string& data,
128 nlohmann::json& jsonDump) const {
129
130 // Parse corrections
131 constexpr std::string_view delimiter{"\n"};
132 auto lines = CxxUtils::tokenize(data, delimiter);
133 unsigned int nLines{0};
134 for (const std::string& blobline : lines) {
135 ++nLines;
136 constexpr std::string_view delimiter{":"};
137 auto tokens = CxxUtils::tokenize(blobline, delimiter);
138 // Check if tokens is not empty
139 if (tokens.empty()) {
140 ATH_MSG_FATAL("Empty string retrieved from DB in folder " << m_readKey.fullKey());
141 return StatusCode::FAILURE;
142 }
143 const std::string_view &type = tokens[0];
144 // Parse line
145 if (type[0] == '#') {
146 // skip it
147 continue;
148 }
149
150 if (type.compare(0, 4, "Corr") == 0) {
151 nlohmann::json newLine;
152 ATH_CHECK(setFromAscii(std::string(blobline), newLine));
153 jsonDump.push_back(newLine);
154 }
155 }
156 ATH_MSG_VERBOSE("Decoded "<<nLines<<" new ascii lines");
157 return StatusCode::SUCCESS;
158}
159
160
161StatusCode MdtAsBuiltCondAlg::setFromAscii(const std::string& asciiData,
162 nlohmann::json& newChannel) const {
163 std::istringstream in(asciiData);
164
165 std::string tok;
166 if (!((in >> tok) && (tok == "Corr:"))) {
167 ATH_MSG_FATAL(__FILE__<<":"<<__LINE__<<" Failed to parse line "<<asciiData);
168 return StatusCode::FAILURE;
169 }
170 std::string typ{};
171 int jff{0}, jzz{0};
172 if (!(in >> typ >> jff >> jzz)) {
173 ATH_MSG_FATAL(__FILE__<<":"<<__LINE__<<" Failed to parse line "<<asciiData);
174 return StatusCode::FAILURE;
175 }
176 newChannel["typ"] = typ;
177 newChannel["jff"] = jff;
178 newChannel["jzz"] = jzz;
179 using multilayer_t = MdtAsBuiltPar::multilayer_t;
180 using tubeSide_t = MdtAsBuiltPar::tubeSide_t;
181 std::array<int, static_cast<unsigned>(multilayer_t::NMLTYPES)> stagg{};
182 if (!(in >> stagg[static_cast<unsigned>(multilayer_t::ML1)]
183 >> stagg[static_cast<unsigned>(multilayer_t::ML2)])) {
184 ATH_MSG_FATAL(__FILE__<<":"<<__LINE__<<" Failed to parse line "<<asciiData);
185 return StatusCode::FAILURE;
186 }
187 for (const multilayer_t ml : {multilayer_t::ML1, multilayer_t::ML2}){
188 for (const tubeSide_t side : {tubeSide_t::POS, tubeSide_t::NEG}){
189 std::stringstream prefix{};
190 prefix<<"Ml"<<(static_cast<unsigned>(ml) + 1);
191 prefix<<(side == tubeSide_t::POS? "Pos" : "Neg")<<"TubeSide";
192 auto dumpValue = [&prefix, &newChannel](const std::string& field, const float val) {
193 newChannel[prefix.str()+field] = val;
194 } ;
195
196 float y0{0.f}, z0{0.f}, alpha{0.f}, ypitch{0.f}, zpitch{0.f};
197 if (!(in >> y0 >> z0 >> alpha >> ypitch >> zpitch)){
198 ATH_MSG_FATAL(__FILE__<<":"<<__LINE__<<" Failed to parse line "<<asciiData);
199 return StatusCode::FAILURE;
200 }
201 dumpValue("y0", y0);
202 dumpValue("z0", z0);
203 dumpValue("alpha", alpha);
204 dumpValue("ypitch", ypitch);
205 dumpValue("zpitch", zpitch);
206 dumpValue("stagg", stagg[static_cast<unsigned int>(ml)]);
207 }
208 }
209 return StatusCode::SUCCESS;
210}
#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_DEBUG(x)
std::set< MdtAsBuiltPar, std::less<> > MdtAsBuiltContainer
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Base class for conditions algorithms.
ChanAttrListMap::const_iterator const_iterator
static EventIDRange infiniteTime()
Produces an EventIDRange that is inifinite in Time and invalid in RunLumi.
SG::WriteCondHandleKey< MdtAsBuiltContainer > m_writeKey
StatusCode legacyFormatToJSON(const std::string &bloblines, nlohmann::json &lines) const
StatusCode setFromAscii(const std::string &asciiData, nlohmann::json &newChannel) const
Gaudi::Property< std::string > m_readFromJSON
Load the alignment parameters from a JSON file.
MdtAsBuiltCondAlg(const std::string &name, ISvcLocator *pSvcLocator)
virtual StatusCode initialize() override
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
SG::ReadCondHandleKey< CondAttrListCollection > m_readKey
Gaudi::Property< bool > m_newFormat2020
StatusCode parseDataFromJSON(const nlohmann::json &lines, MdtAsBuiltContainer &asBuilt) const
virtual StatusCode execute(const EventContext &ctx) const override
Container classifier the MDT as-built parameters See parameter description in http://atlas-muon-align...
multilayer_t
MDT multi-layer index.
void setAlignmentParameters(multilayer_t iML, tubeSide_t iTubeSide, float y0, float z0, float alpha, float ypitch, float zpitch, int stagg)
Set the alignment parameters for a ML and a tube side.
tubeSide_t
MDT tube side.
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)
void addDependency(const EventIDRange &range)
const EventIDRange & getRange() const
StatusCode record(const EventIDRange &range, T *t)
record handle, with explicit range DEPRECATED
const DataObjID & fullKey() const
std::vector< std::string > tokenize(const std::string &the_str, std::string_view delimiters)
Splits the string into smaller substrings.
#define THROW_EXCEPTION(MESSAGE)
Definition throwExcept.h:10