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