ATLAS Offline Software
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 
14 //package includes
16 #include "SCT_CablingUtilities.h"
17 
18 //indet includes
19 #include "InDetIdentifier/SCT_ID.h"
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
34 static const std::string atlasTableSignature{"Rod Fibre Bec LayerDisk Eta Phi Side RobId Sn"};
35 static const int disabledFibre{255};
36 
37 //utility functions in file scope
38 namespace {
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
60 SCT_CablingCondAlgFromText::SCT_CablingCondAlgFromText(const std::string& name, ISvcLocator* pSvcLocator):
61  AthReentrantAlgorithm(name, pSvcLocator)
62 {
63 }
64 
65 //
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
81 
82  return StatusCode::SUCCESS;
83 }
84 
85 //
88  return StatusCode::SUCCESS;
89 }
90 
91 //
93 SCT_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 //
231 bool
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 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
SCT_CablingCondAlgFromText::m_idHelper
const SCT_ID * m_idHelper
Definition: SCT_CablingCondAlgFromText.h:55
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
SCT_CablingUtilities.h
ReadCellNoiseFromCoolCompare.s1
s1
Definition: ReadCellNoiseFromCoolCompare.py:378
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
SCT_ID.h
This is an Identifier helper class for the SCT subdetector. This class is a factory for creating comp...
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:64
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
PathResolver::find_file
static std::string find_file(const std::string &logical_file_name, const std::string &search_path, SearchType search_type=LocalSearch)
Definition: PathResolver.cxx:251
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:14
SCT_OnlineId
Definition: SCT_OnlineId.h:22
skel.it
it
Definition: skel.GENtoEVGEN.py:423
PixelModuleFeMask_create_db.stop
int stop
Definition: PixelModuleFeMask_create_db.py:76
AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
SCT_CablingCondAlgFromText::insert
bool insert(const IdentifierHash &hash, const SCT_OnlineId &onlineId, const SCT_SerialNumber &sn, SCT_CablingData *data) const
Definition: SCT_CablingCondAlgFromText.cxx:232
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:83
TRT::Hit::side
@ side
Definition: HitInfo.h:83
SCT_CablingCondAlgFromText::finalize
virtual StatusCode finalize() override
Definition: SCT_CablingCondAlgFromText.cxx:87
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
SCT_CablingCondAlgFromText::m_source
StringProperty m_source
Definition: SCT_CablingCondAlgFromText.h:52
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
SCT_CablingCondAlgFromText.h
Fills an SCT cabling object from a plain text source.
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
contains
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition: hcg.cxx:111
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
SCT_ID::wafer_hash
IdentifierHash wafer_hash(const Identifier &wafer_id) const
wafer hash from id - optimized
Definition: SCT_ID.h:492
SCT_CablingCondAlgFromText::initialize
virtual StatusCode initialize() override
Definition: SCT_CablingCondAlgFromText.cxx:67
RunTileMonitoring.rod
rod
Definition: RunTileMonitoring.py:134
ReadFromCoolCompare.os
os
Definition: ReadFromCoolCompare.py:231
SCT_CablingCondAlgFromText::m_writeKey
SG::WriteCondHandleKey< SCT_CablingData > m_writeKey
Definition: SCT_CablingCondAlgFromText.h:53
PathResolver.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
IdentifierHash.h
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
SCT_SerialNumber
Definition: SCT_SerialNumber.h:22
SCT_CablingData
Definition: SCT_CablingData.h:35
SCT_CablingCondAlgFromText::execute
virtual StatusCode execute(const EventContext &ctx) const override
Definition: SCT_CablingCondAlgFromText.cxx:93
CondAlgsOpts.found
int found
Definition: CondAlgsOpts.py:101
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:109
SCT_SerialNumber::isWellFormed
bool isWellFormed() const
Cursory check on whether the serial number is well formed N.B.
Definition: SCT_SerialNumber.cxx:81
ReadCellNoiseFromCoolCompare.s2
s2
Definition: ReadCellNoiseFromCoolCompare.py:379
SCT_CablingCondAlgFromText::SCT_CablingCondAlgFromText
SCT_CablingCondAlgFromText(const std::string &name, ISvcLocator *svc)
Definition: SCT_CablingCondAlgFromText.cxx:60
SCT_ID::wafer_id
Identifier wafer_id(int barrel_ec, int layer_disk, int phi_module, int eta_module, int side) const
For a single side of module.
Definition: SCT_ID.h:464
IdentifierHash
Definition: IdentifierHash.h:38
SG::WriteCondHandle
Definition: WriteCondHandle.h:26
SCT_OnlineId::rod
std::uint32_t rod() const
Return the rod/rob Id.
Definition: SCT_OnlineId.cxx:59