ATLAS Offline Software
Loading...
Searching...
No Matches
SCT_CablingCondAlgFromText.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
13
14//package includes
17
18//indet includes
20
21//Athena includes
22#include "Identifier/Identifier.h"
25
26// Gaudi include
27#include "GaudiKernel/EventIDRange.h"
28
29//STL
30#include <iostream>
31#include <fstream>
32
33//Constants at file scope
34static const std::string atlasTableSignature{"Rod Fibre Bec LayerDisk Eta Phi Side RobId Sn"};
35static const int disabledFibre{255};
36
37//utility functions in file scope
38namespace {
39 //report if string s1 contains s2
40 bool
41 contains(const std::string& s1, const std::string& s2) {
42 return (s1.find(s2) not_eq std::string::npos);
43 }
44 //fast forward to a line in the file containing the signature string, and return that line
45 //or the empty string if the end of file was reached first.
46 std::string
47 fastForward(std::ifstream& theFile, const std::string& signature) {
48 std::string inString;
49 bool found{false}, endOfFile{false};
50 do {
51 std::getline(theFile, inString);
52 found=contains(inString, signature);
53 endOfFile = theFile.eof();
54 } while ((not found) and (not endOfFile));
55 return found ? (inString) : (std::string{""});
56 }
57}//end of anonymous namespace
58
59// Constructor
60SCT_CablingCondAlgFromText::SCT_CablingCondAlgFromText(const std::string& name, ISvcLocator* pSvcLocator):
61 AthCondAlgorithm(name, pSvcLocator)
62{
63}
64
65//
66StatusCode
68 ATH_MSG_INFO("The SCT data file for cabling, " << m_source.value() << ", will be searched.");
69 m_source = PathResolver::find_file(m_source.value(), "DATAPATH");
70 if (m_source.value().empty()) {
71 ATH_MSG_FATAL("The SCT data file for cabling, " << m_source.value() << ", was not found.");
72 return StatusCode::FAILURE;
73 }
74 ATH_MSG_INFO("Reading cabling from " << m_source.value());
75
76 // SCT_ID
77 ATH_CHECK(detStore()->retrieve(m_idHelper, "SCT_ID"));
78
79 // Write Cond Handle
80 ATH_CHECK(m_writeKey.initialize());
81
82 return StatusCode::SUCCESS;
83}
84
85//
86StatusCode
88 return StatusCode::SUCCESS;
89}
90
91//
92StatusCode
93SCT_CablingCondAlgFromText::execute(const EventContext& ctx) const {
94 // Write Cond Handle
96 if (writeHandle.isValid()) {
97 ATH_MSG_DEBUG("CondHandle " << writeHandle.fullKey() << " is already valid."
98 << ". In theory this should not be called, but may happen"
99 << " if multiple concurrent events are being processed out of order.");
100 return StatusCode::SUCCESS;
101 }
102
103 // Construct the output Cond Object and fill it in
104 std::unique_ptr<SCT_CablingData> writeCdo{std::make_unique<SCT_CablingData>()};
105
106 Identifier offlineId;
107 IdentifierHash offlineIdHash;
108 unsigned int onlineId;
109 int robid{0};
110 std::ifstream fromDataFile{m_source.value().c_str()};
111 if (not fromDataFile) {
112 ATH_MSG_FATAL("The cable mapping file could not be opened: " << m_source.value());
113 return StatusCode::FAILURE;
114 }
115 std::string inString;
116 bool endOfFile{false};
117 inString=fastForward(fromDataFile, atlasTableSignature);
118 if (inString.empty()) {
119 ATH_MSG_FATAL("The end of the datafile was reached before an identifier mapping was found");
120 return StatusCode::FAILURE;
121 }
122 //next line should be the identifier table, start reading it
123 bool endOfTable{false};
124 unsigned int numEntries{0};
125 std::vector<IdentifierHash> disabledFibres;
126 do {
127 std::getline(fromDataFile, inString);
128 if (contains(inString, "- ")) continue;
129 endOfTable=contains(inString, "</textList>");
130 std::istringstream dataLine(inString);
131 if (not endOfTable) {
132 int rod,link,barrelOrEndcap,layer,phi,eta,side,robidFromfile;
133 std::string sn,Link;
134 //enable exceptions on the stream in case there are bad conversions
135 dataLine.exceptions(std::ios_base::badbit|std::ios_base::failbit);
136 try {
137 dataLine>>rod>>Link>>barrelOrEndcap>>layer>>eta>>phi>>side>>std::hex>>robidFromfile>>std::dec>>sn;
138 offlineId = m_idHelper->wafer_id(barrelOrEndcap,layer,phi,eta,side);
139 offlineIdHash = m_idHelper->wafer_hash(offlineId);
140 } catch (const std::ios_base::failure&) {
141 ATH_MSG_ERROR("An error occurred while reading the cabling file " << m_source.value()
142 << ", it may be badly formatted in the following line: \n" << inString);
143 continue;
144 }
145 // Check Link variable looks OK
146 // The maximum value of an int is 2147483647 in decimal and 0x7fffffff in hexadecimal.
147 if (Link.empty() or Link.size()>10) {
148 ATH_MSG_ERROR("An error occurred while reading the cabling file " << m_source.value()
149 << ", Link (" << Link << ") cannot be converted to an integer");
150 continue;
151 }
152 // Let's Get the Online Id From the link and the ROD
153 link = std::stoi(Link, nullptr, 0); // 0 means the base used in deterimed by the format in the sequence
154 if (link<0) {
155 ATH_MSG_ERROR("link " << link << " seems invalid. This was obtained from Link " << Link << ". Will not be used.");
156 continue;
157 }
158 if (link==disabledFibre) {
159 ATH_MSG_DEBUG(sn << ": Disabled fibre encountered in text file. Will attempt to place identifier using the other fibre.");
160 offlineId = m_idHelper->wafer_id(barrelOrEndcap,layer,phi,eta,side);
161 offlineIdHash = m_idHelper->wafer_hash(offlineId);
162 disabledFibres.push_back(offlineIdHash);
163 continue;
164 }
165 robid = robidFromfile;
166 onlineId = (robid & 0xFFFFFF) | (link << 24);
167 //std::cout << " " << offlineIdHash << " " << std::hex << onlineId << " " << std::dec << sn << std::endl;
168 bool success{insert(offlineIdHash, onlineId, SCT_SerialNumber(sn), writeCdo.get())};
169 if (not success) {
170 ATH_MSG_ERROR("Insertion of fibre failed, " << offlineIdHash << ", " << std::hex << onlineId << std::dec << " " << sn);
171 } else {
172 numEntries++;
173 }
174 }//end of 'if not end of table'
175 endOfFile = fromDataFile.eof();
176 } while ((not endOfTable) and (not endOfFile));
177
178 //************************************************************************************
179 // For the disabled fibres
180 //************************************************************************************
181 std::string plural{(disabledFibres.size()==1) ? " was" : "s were"};
182 ATH_MSG_INFO(disabledFibres.size() << " disabled fibre" << plural << " found.");
183 if (not disabledFibres.empty()) {
184 int s,os;
185 std::vector<IdentifierHash>::const_iterator it{disabledFibres.begin()};
186 for (;it not_eq disabledFibres.end();++it) {
187 IdentifierHash offlineIdHash{*it};
188 //even hashes are on side 0, hashes start from 0
189 s=offlineIdHash % 2; //1 or zero
190 os = 1-s; //other side, i.e. the enabled one
191 //find the hash for the other side: if its odd, subtract 1; if its even, add 1.
192 IdentifierHash otherIdHash{offlineIdHash + (s ? -1 : 1)};
193 //and its online id
194 onlineId=writeCdo->getOnlineIdFromHash(otherIdHash);
195 int link{static_cast<int>((onlineId>>24) & 0x7F)};
196 bool cableSwapped{(link % 2)!=os}; //if its odd and side is zero, or its even and side is 1.
197 //now find the newlink by incrementing or decrementing the link number from the other side, according to whether we are on
198 //side 0 or side 1 and which order the cabling is going in general (swapped or not swapped)
199 int newlink{(s == 0) ? (link - 1) : (link +1)}; //assumes normal unswapped ordering
200 if (cableSwapped) newlink = (s == 0) ? (link+1) : (link-1); //assumes swapped ordering
201 int newOnlineId{static_cast<int>((onlineId & 0xFFFFFF)|(newlink << 24))};
202 ATH_MSG_DEBUG("new: " << std::hex << newOnlineId);
203 //start entering for the disabled fibre:
204 SCT_SerialNumber sn{writeCdo->getSerialNumberFromHash(offlineIdHash)};
205 bool success{insert(offlineIdHash, newOnlineId, sn, writeCdo.get())};
206 if (not success) {
207 ATH_MSG_ERROR("Insertion of disabled fibre failed, " << offlineIdHash << ", " << std::hex << newOnlineId << std::dec << " " << sn.str());
208 } else {
209 numEntries++;
210 }
211 }
212 }
213 ATH_MSG_INFO(numEntries << " entries were made to the identifier map.");
214
215 // Define validity of the output cond obbject and record it
216 const EventIDBase start{EventIDBase::UNDEFNUM, EventIDBase::UNDEFEVT, 0, 0, EventIDBase::UNDEFNUM, EventIDBase::UNDEFNUM};
217 const EventIDBase stop{EventIDBase::UNDEFNUM, EventIDBase::UNDEFEVT, EventIDBase::UNDEFNUM-1, EventIDBase::UNDEFNUM-1, EventIDBase::UNDEFNUM, EventIDBase::UNDEFNUM};
218 const EventIDRange rangeW{start, stop};
219 if (writeHandle.record(rangeW, std::move(writeCdo)).isFailure()) {
220 ATH_MSG_FATAL("Could not record SCT_CablingData " << writeHandle.key()
221 << " with EventRange " << rangeW
222 << " into Conditions Store");
223 return StatusCode::FAILURE;
224 }
225 ATH_MSG_INFO("recorded new CDO " << writeHandle.key() << " with range " << rangeW << " into Conditions Store");
226
227 return (numEntries==0) ? (StatusCode::FAILURE) : (StatusCode::SUCCESS);
228}
229
230//
231bool
233 if (not sn.isWellFormed()) {
234 ATH_MSG_FATAL("Serial number is not in correct format");
235 return false;
236 }
237 if (not hash.is_valid()) {
238 ATH_MSG_FATAL("Invalid hash: " << hash);
239 return false;
240 }
241 // Check if the pointer of derived conditions object is valid.
242 if (data==nullptr) {
243 ATH_MSG_FATAL("Pointer of derived conditions object is null");
244 return false;
245 }
246
247 if (not data->setHashForOnlineId(hash, onlineId)) return false;
248 if (not data->setOnlineIdForHash(onlineId, hash)) return false;
249
250 bool successfulInsert{data->setHashForSerialNumber(hash, sn)};
251 successfulInsert &= data->setSerialNumberForHash(sn, hash);
252 // in this form, the data->getHashEntries() will be half the number of hashes
253 if (successfulInsert) {
254 data->setRod(onlineId.rod()); //move this here so insertion only happens for valid onlineId, hash
255 }
256 return true;
257}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#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_DEBUG(x)
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
static const int disabledFibre
static const std::string atlasTableSignature
Fills an SCT cabling object from a plain text source.
Header file for utility functions used in SCT cabling code.
This is an Identifier helper class for the SCT subdetector.
const ServiceHandle< StoreGateSvc > & detStore() const
Base class for conditions algorithms.
This is a "hash" representation of an Identifier.
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
bool insert(const IdentifierHash &hash, const SCT_OnlineId &onlineId, const SCT_SerialNumber &sn, SCT_CablingData *data) const
SCT_CablingCondAlgFromText(const std::string &name, ISvcLocator *svc)
virtual StatusCode initialize() override
virtual StatusCode finalize() override
virtual StatusCode execute(const EventContext &ctx) const override
SG::WriteCondHandleKey< SCT_CablingData > m_writeKey
A class to hold the data necessary for SCT_CablingTool.
SCT_OnlineId is a class to hold an online id number and provide check on validity,...
std::uint32_t rod() const
Return the rod/rob Id.
SCT_SerialNumber is a class to hold a serial number and provide check on validity,...
std::string str() const
Full serial number as a string.
bool isWellFormed() const
Cursory check on whether the serial number is well formed N.B.
const std::string & key() const
StatusCode record(const EventIDRange &range, T *t)
record handle, with explicit range DEPRECATED
const DataObjID & fullKey() const
STL class.
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition hcg.cxx:114
STL namespace.