ATLAS Offline Software
SCT_ReadoutData.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
8 #include "Identifier/Identifier.h"
9 
10 #include <algorithm>
11 
12 // Helper functions to indicate whether a barrel module is modified.
13 // The following modules have extra routing on one side or the other
14 // 20220170200653 -> 169922560 has link0 modified
15 // 20220170200113 -> 170801152 has link0 modified
16 // 20220170200941 -> 170983424 has link1 modified
17 // 20220330200701 -> 172556288 has link0 modified
18 // 20220330200637 -> 172621824 has link0 modified
19 // 20220170200183 -> 173268992 has link1 modified
20 // 20220330200606 -> 174301184 has link1 modified
21 // 20220330200209 -> 174342144 has link0 modified
22 // 20220330200505 -> 174610432 has link0 modified
23 // 20220330200117 -> 174962688 has link0 modified
24 // 20220330200693 -> 175015936 has link1 modified
25 
26 static bool modified0(Identifier moduleId) {
27  return ((moduleId==169922560) or (moduleId==170801152) or (moduleId==172556288) or (moduleId==172621824) or
28  (moduleId==174342144) or (moduleId==174610432) or (moduleId==174962688));
29 }
30 
31 static bool modified1(Identifier moduleId) {
32  return ((moduleId==170983424) or (moduleId==173268992) or (moduleId==174301184) or (moduleId==175015936));
33 }
34 
35 using namespace SCT_Parameters;
36 
37 // Constructor
39  : AthMessaging (msgSvc, "SCT_ReadoutData")
40 {
41 }
42 
43 void SCT_ReadoutData::setModuleType(const Identifier& moduleId, int bec) {
44  // Set module type as per the ModuleType enum
45  if (std::abs(bec) == 2) {
47  } else if (modified0(moduleId)) {
49  } else if (modified1(moduleId)) {
51  } else {
53  }
54 }
55 
57  // Set Chip mapping depending on module type
58 
59  // Clear between calls and reserve space for the 12 chips
60  m_chipMap.clear();
61  m_chipMap.reserve(12);
62 
63  if (m_type == BARREL) {
64  m_chipMap.emplace_back(Chip1, Chip2, None , None);
65  m_chipMap.emplace_back(Chip2, Chip3, Chip0, Chip11);
66  m_chipMap.emplace_back(Chip3, Chip4, Chip1, Chip0);
67  m_chipMap.emplace_back(Chip4, Chip5, Chip2, Chip1);
68  m_chipMap.emplace_back(Chip5, None , Chip3, Chip2);
69  m_chipMap.emplace_back(None, Chip7, Chip4, Chip3);
70  m_chipMap.emplace_back(Chip7, Chip8, None, None);
71  m_chipMap.emplace_back(Chip8, Chip9, Chip6, Chip5);
72  m_chipMap.emplace_back(Chip9, Chip10, Chip7, Chip6);
73  m_chipMap.emplace_back(Chip10, Chip11, Chip8, Chip7);
74  m_chipMap.emplace_back(Chip11, None, Chip9, Chip8);
75  m_chipMap.emplace_back(None, Chip1, Chip10, Chip9);
76  } else if (m_type == MODIFIED_0) {
77  m_chipMap.emplace_back(Chip1, Chip2, Chip5, None);
78  m_chipMap.emplace_back(Chip2, Chip3, Chip0, Chip11);
79  m_chipMap.emplace_back(Chip3, Chip4, Chip1, Chip0);
80  m_chipMap.emplace_back(Chip4, Chip5, Chip2, Chip1);
81  m_chipMap.emplace_back(Chip5, None, Chip3, Chip2);
82  m_chipMap.emplace_back(Chip0, Chip7, Chip4, Chip3);
83  m_chipMap.emplace_back(Chip7, Chip8, None, None);
84  m_chipMap.emplace_back(Chip8, Chip9, Chip6, Chip5);
85  m_chipMap.emplace_back(Chip9, Chip10, Chip7, Chip6);
86  m_chipMap.emplace_back(Chip10, Chip11, Chip8, Chip7);
87  m_chipMap.emplace_back(Chip11, None, Chip9, Chip8);
88  m_chipMap.emplace_back(None, Chip1, Chip10, Chip9);
89  } else if (m_type == MODIFIED_1) {
90  m_chipMap.emplace_back(Chip1, Chip2, None, None);
91  m_chipMap.emplace_back(Chip2, Chip3, Chip0, Chip11);
92  m_chipMap.emplace_back(Chip3, Chip4, Chip1, Chip0);
93  m_chipMap.emplace_back(Chip4, Chip5, Chip2, Chip1);
94  m_chipMap.emplace_back(Chip5, None , Chip3, Chip2);
95  m_chipMap.emplace_back(None, Chip7, Chip4, Chip3);
96  m_chipMap.emplace_back(Chip7, Chip8, Chip11, None);
97  m_chipMap.emplace_back(Chip8, Chip9, Chip6, Chip5);
98  m_chipMap.emplace_back(Chip9, Chip10, Chip7, Chip6);
99  m_chipMap.emplace_back(Chip10, Chip11, Chip8, Chip7);
100  m_chipMap.emplace_back(Chip11, None, Chip9, Chip8);
101  m_chipMap.emplace_back(Chip6, Chip1, Chip10, Chip9);
102  } else if (m_type == ENDCAP) {
103  m_chipMap.emplace_back(Chip1, Chip2, Chip11, None);
104  m_chipMap.emplace_back(Chip2, Chip3, Chip0, Chip11);
105  m_chipMap.emplace_back(Chip3, Chip4, Chip1, Chip0);
106  m_chipMap.emplace_back(Chip4, Chip5, Chip2, Chip1);
107  m_chipMap.emplace_back(Chip5, None, Chip3, Chip2);
108  m_chipMap.emplace_back(Chip6, Chip7, Chip4, Chip3);
109  m_chipMap.emplace_back(Chip7, Chip8, Chip5, None);
110  m_chipMap.emplace_back(Chip8, Chip9, Chip6, Chip5);
111  m_chipMap.emplace_back(Chip9, Chip10, Chip7, Chip6);
112  m_chipMap.emplace_back(Chip10, Chip11, Chip8, Chip7);
113  m_chipMap.emplace_back(Chip11, None, Chip9, Chip8);
114  m_chipMap.emplace_back(Chip0, Chip1, Chip10, Chip9);
115  }
116 }
117 
119  // Follow the chips for each link to determine which chips are in the readout
120  // and if readout is sane.
121 
122  // Follow chip from the start chip for each side
123  const SCT_Chip& startChip{m_chips->at(link*6)};
124  bool linkSane{followReadoutUpstream(link, startChip)};
125 
126  if (not linkSane) {
127  std::vector<int>& chipsOnThisLink{(link==0) ? m_chipsOnLink0 : m_chipsOnLink1};
128 
129  // Remove chips in that link from the readout
130  for (const int linkItr: chipsOnThisLink) setChipOut(m_chips->at(linkItr));
131 
132  // We do not have ERROR/FAILURE if the readout is not sane as it possibly only affects one of the SCT modules
133  ATH_MSG_WARNING("Readout for link " << link << " not sane");
134  }
135 }
136 
138  // Does the chip have a correctly connected input
139 
140  // The chip must not be an end
141  if (chip.isEnd()) return false;
142 
143  int inChipId{inputChip(chip)};
144 
145  // The port the chip is listening on should be mapped to an input (if the chip is not an end)
146  // Otherwise it'll never get to an end giving a timeout
147  if (inChipId == None) {
148  ATH_MSG_WARNING("Chip " << chip.id() << " is not an end but port " << chip.inPort() << " is not mapped to anything");
149  return false;
150  }
151 
152  // The mapped chip should be talking on the same port as this chip is listening (if the chip is not an end)
153  // Again, otherwise it'll never get to an end giving a timeout
154  const std::vector<SCT_Chip>& chips = *m_chips;
155  if (chips.at(inChipId).outPort()!=chip.inPort()) {
156  ATH_MSG_WARNING("Chip" << chip.id() << " is not an end and is listening on Port " << chip.inPort() << " but nothing is talking to it");
157  return false;
158  }
159  return true;
160 }
161 
163  // Is something talking to a chip which is configured as an end
164  // (can possibly happen as chips must be talking to something)
165 
166  // Is chip actually an end
167  if (not chip.isEnd()) return false;
168 
169  // Is anything trying to talk to the end.
170  const std::vector<SCT_Chip>& chips = *m_chips;
171  for (const SCT_Chip& thisChip: chips) {
172  if (outputChip(thisChip) == chip.id()) {
173  ATH_MSG_WARNING("Chip " << chip.id() << " is configured as end but something is trying to talk to it");
174  return true;
175  }
176  }
177  return false;
178 }
179 
181  // Mask chip (is set mask to 0 0 0 0) if not in readout
182  // If the readout of a particular link is not sane mask all chips on that link
183  for (SCT_Chip& thisChip: *m_chips) {
184  if (not isChipReadOut(thisChip)) {
185  ATH_MSG_DEBUG("Masking chip " << thisChip.id());
186  uint32_t masked{0};
187  thisChip.initializeMaskFromInts(masked, masked, masked, masked);
188  }
189  }
190 }
191 
192 bool SCT_ReadoutData::followReadoutUpstream(int link, const SCT_Chip& chip, int remainingDepth) {
193  // Follow the readout upstream (to input side). Will return true if the readout is sane
194  // The "error" cases are only warnings since they possibly only affect one module of the SCT
195  // Have we gone though all 12 chips -> infinite loop
196  if (remainingDepth < 0) {
197  ATH_MSG_WARNING("Infinite loop detected in readout");
198  return false;
199  }
200 
201  // Can the chip be a master
202  if (chip.canBeMaster()) {
203 
204  if (chip.id()==link*6) {
205  ATH_MSG_DEBUG("Link " << link << " is " << (m_linkActive[link] ? "ENABLED" : "DISABLED"));
206  }
207 
208  // Is the link enabled. If not the readout is still sane so return true
209  if (not m_linkActive[link]) return true;
210 
211  // Is the chip actually configured as a master
212  if (chip.isMaster()) {
213  ATH_MSG_DEBUG("MasterChip");
214  // Chip will be set in readout below
215  } else if (chip.id() == link*6) {
216  // Link is active but the master position for THAT link does not contain a master
217  // This can happen if everything is readout via other link, therefore the readout is still sane.
218 
219  ATH_MSG_DEBUG("Link " << link << " is enabled but chip " << chip.id() << " is not a master");
220 
221  return true;
222  }
223  }
224 
225  ATH_MSG_DEBUG("Looking at chip " << chip.id());
226 
227  // Is a slave chip mistakenly configured as a master
228  if (chip.slaveConfiguredAsMaster()) {
229  ATH_MSG_WARNING("Found master chip in slave position " << chip.id());
230  return false;
231  }
232 
233  // The chip is in the readout (this doesn't mean the readout necessarily is sane).
234  setChipIn(chip, link);
235 
236  // Is the chip configured as an end (can be master and end)
237  if (chip.isEnd()) {
238  ATH_MSG_DEBUG("End Chip");
239 
240  // End chip is in readout and readout is sane
241  return true;
242  }
243 
244  // Find the next chip if there is one connected
245  if (not hasConnectedInput(chip)) return false;
246  const SCT_Chip& nextChip{m_chips->at(inputChip(chip))};
247  return followReadoutUpstream(link, nextChip, remainingDepth-1);
248 }
249 
250 bool SCT_ReadoutData::isLinkStandard(int link) const {
251  // Is the readout for a particular link standard
252  // (i.e link active and 0-5 through link 0 or 6-11 through link 1)
253 
254  // First, the link must be active
255  if (not m_linkActive[link]) return false;
256 
257  const std::vector<int>& chipsOnThisLink{(link==0) ? m_chipsOnLink0 : m_chipsOnLink1};
258 
259  // Then it must have six chips being readout ...
260  if (chipsOnThisLink.size()!=6) return false;
261 
262  // ... in the correct order
263  int ichip{link*6};
264  for (int linkItr: chipsOnThisLink) {
265  if (linkItr!=ichip) return false;
266  ++ichip;
267  }
268 
269  return true;
270 }
271 
272 void SCT_ReadoutData::printStatus(const Identifier& moduleId) const {
273  // Print status for module (a la online) and whether it is standard or not
274  if (not msgLvl(MSG::DEBUG)) return;
275 
276  bool standard{isLinkStandard(0) and isLinkStandard(1)};
277 
278  msg(MSG::DEBUG) << "Readout status " << moduleId << ": "
279  << ((m_type == SCT_Parameters::ENDCAP) ? "ENDCAP" : "")
280  << ((m_type == SCT_Parameters::BARREL) ? "BARREL" : "")
281  << ((m_type == SCT_Parameters::MODIFIED_0) ? "MOD_0" : "")
282  << ((m_type == SCT_Parameters::MODIFIED_1) ? "MOD_1" : "");
283  msg(MSG::DEBUG) << " Link0 = " << std::boolalpha << m_linkActive[0] << " (";
284 
285  if (m_chipsOnLink0.empty()) {
286  msg(MSG::DEBUG) << "X";
287  } else {
288  for (unsigned int ilink0{0}; ilink0 < m_chipsOnLink0.size(); ++ilink0) {
289  msg(MSG::DEBUG) << m_chipsOnLink0.at(ilink0) << " ";
290  }
291  }
292 
293  msg(MSG::DEBUG) << ") Link1 = " << std::boolalpha << m_linkActive[1] << " (";
294 
295  if (m_chipsOnLink1.empty()) {
296  msg(MSG::DEBUG) << "X";
297  } else {
298  for (unsigned int ilink1{0}; ilink1 < m_chipsOnLink1.size(); ++ilink1) {
299  msg(MSG::DEBUG) << m_chipsOnLink1.at(ilink1) << " ";
300  }
301  }
302 
303  msg(MSG::DEBUG) << ") " << (standard ? "Standard" : "Non-standard") << endmsg;
304 }
305 
306 void SCT_ReadoutData::setChips(std::vector<SCT_Chip>& chips) {
307  // Set the chips and sort in order of ID
308  std::sort(chips.begin(), chips.end(), [](SCT_Chip& a, SCT_Chip& b) { return a.id() < b.id(); });
309  m_chips = &chips;
310 }
311 
312 void SCT_ReadoutData::setLinkStatus(bool link0ok, bool link1ok) {
313  // Set link status
314  m_linkActive[0] = link0ok;
315  m_linkActive[1] = link1ok;
316 }
317 
319  // Set all chips out of readout and clear both links to start
320  m_chipInReadout.reset();
321  m_chipsOnLink0.clear();
322  m_chipsOnLink1.clear();
323 }
SCT_ReadoutData::checkLink
void checkLink(int link)
Check which chips are in the readout for a particular link and if the readout is sane.
Definition: SCT_ReadoutData.cxx:118
SCT_Parameters::Chip1
@ Chip1
Definition: SCT_PortMap.h:18
SCT_Parameters::Chip4
@ Chip4
Definition: SCT_PortMap.h:18
SCT_ReadoutData::isEndBeingTalkedTo
bool isEndBeingTalkedTo(const SCT_Chip &chip) const
Chip is an end but is being talked to.
Definition: SCT_ReadoutData.cxx:162
SCT_ReadoutData::m_chipInReadout
std::bitset< SCT_Parameters::NChips > m_chipInReadout
Bitset indicating whether a chip is readout or not.
Definition: SCT_ReadoutData.h:122
SCT_Chip::id
short id() const
Chip Id.
Definition: SCT_Chip.h:42
AthMsgStreamMacros.h
SCT_ReadoutData::clearChipReadout
void clearChipReadout()
Set all chips out of readout and clear both links to start.
Definition: SCT_ReadoutData.cxx:318
ParticleGun_SamplingFraction.bec
int bec
Definition: ParticleGun_SamplingFraction.py:89
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
SCT_ReadoutData::setChipIn
void setChipIn(const SCT_Chip &chip, int link)
Set chip in readout and which link it is on.
Definition: SCT_ReadoutData.h:64
SCT_ReadoutData::m_chipsOnLink0
std::vector< int > m_chipsOnLink0
The chips read out on link 0.
Definition: SCT_ReadoutData.h:124
SCT_Chip
Class which stores infomration on the SCT chips: id, config, mask.
Definition: SCT_Chip.h:27
SCT_ReadoutData::setChips
void setChips(std::vector< SCT_Chip > &chips)
Set SCT_Chip vectors.
Definition: SCT_ReadoutData.cxx:306
SCT_ReadoutData::inputChip
SCT_Parameters::ChipType inputChip(const SCT_Chip &chip) const
Find the ID of the input chip for chip.
Definition: SCT_ReadoutData.h:54
SCT_Parameters::Chip11
@ Chip11
Definition: SCT_PortMap.h:18
SCT_ReadoutData::isLinkStandard
bool isLinkStandard(int link) const
is the readout for a particular link sane
Definition: SCT_ReadoutData.cxx:250
SCT_Parameters::Chip3
@ Chip3
Definition: SCT_PortMap.h:18
SCT_Parameters::ENDCAP
@ ENDCAP
Definition: SCT_ReadoutData.h:33
SCT_Chip::isEnd
bool isEnd() const
Is chip an end.
Definition: SCT_Chip.h:48
SCT_Parameters::MODIFIED_1
@ MODIFIED_1
Definition: SCT_ReadoutData.h:33
SCT_Parameters::BARREL
@ BARREL
Definition: SCT_ReadoutData.h:33
SCT_Chip::canBeMaster
bool canBeMaster() const
Can chip be a master (i.e position 0 or 6)
Definition: SCT_Chip.h:52
SCT_ReadoutData::m_chips
std::vector< SCT_Chip > * m_chips
Private data.
Definition: SCT_ReadoutData.h:119
ENDCAP
@ ENDCAP
Definition: TRTRadiatorParameters.h:10
SCT_ReadoutData::SCT_ReadoutData
SCT_ReadoutData(IMessageSvc *msgSvc=nullptr)
Definition: SCT_ReadoutData.cxx:38
SCT_ReadoutData::followReadoutUpstream
bool followReadoutUpstream(int link, const SCT_Chip &chip, int remainingDepth=12)
Follow the readout to the input side.
Definition: SCT_ReadoutData.cxx:192
AthMessaging::msgLvl
bool msgLvl(const MSG::Level lvl) const
Test the output level.
Definition: AthMessaging.h:151
SCT_ReadoutData::setModuleType
void setModuleType(const Identifier &moduleId, int bec)
Set the module type.
Definition: SCT_ReadoutData.cxx:43
StdJOSetup.msgSvc
msgSvc
Provide convenience handles for various services.
Definition: StdJOSetup.py:36
SCT_Parameters::Chip0
@ Chip0
Definition: SCT_PortMap.h:18
SCT_Chip::isMaster
bool isMaster() const
Is chip a master.
Definition: SCT_Chip.h:50
SCT_ReadoutData::m_chipMap
std::vector< SCT_PortMap > m_chipMap
Vector of port mapping from the chips in an SCT module.
Definition: SCT_ReadoutData.h:120
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
SCT_Parameters::MODIFIED_0
@ MODIFIED_0
Definition: SCT_ReadoutData.h:33
SCT_Parameters::Chip2
@ Chip2
Definition: SCT_PortMap.h:18
SCT_ReadoutData::setLinkStatus
void setLinkStatus(bool link0ok, bool link1ok)
Set link status.
Definition: SCT_ReadoutData.cxx:312
AthMessaging
Class to provide easy MsgStream access and capabilities.
Definition: AthMessaging.h:55
SCT_Parameters::Chip6
@ Chip6
Definition: SCT_PortMap.h:18
SCT_ReadoutData::hasConnectedInput
bool hasConnectedInput(const SCT_Chip &chip) const
Chip has a correctly connected input.
Definition: SCT_ReadoutData.cxx:137
AthMessaging::msg
MsgStream & msg() const
The standard message stream.
Definition: AthMessaging.h:164
SCT_Parameters::Chip5
@ Chip5
Definition: SCT_PortMap.h:18
SCT_ReadoutData::m_linkActive
bool m_linkActive[2]
Links status for link 0 and 1.
Definition: SCT_ReadoutData.h:121
SCT_Chip::inPort
short inPort() const
Active input port.
Definition: SCT_Chip.h:44
SCT_Parameters::Chip7
@ Chip7
Definition: SCT_PortMap.h:18
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
SCT_ReadoutData::setChipMap
void setChipMap()
Fill the chip mapping.
Definition: SCT_ReadoutData.cxx:56
TrackCorrType::None
@ None
SCT_Parameters::Chip9
@ Chip9
Definition: SCT_PortMap.h:18
SCT_ReadoutData::outputChip
SCT_Parameters::ChipType outputChip(const SCT_Chip &chip) const
Find the ID of the output chip for chip.
Definition: SCT_ReadoutData.h:59
a
TList * a
Definition: liststreamerinfos.cxx:10
SCT_Parameters::Chip10
@ Chip10
Definition: SCT_PortMap.h:18
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
SCT_Parameters::Chip8
@ Chip8
Definition: SCT_PortMap.h:18
DEBUG
#define DEBUG
Definition: page_access.h:11
SCT_Chip::slaveConfiguredAsMaster
bool slaveConfiguredAsMaster() const
Is this a slave chip mistakenly configured as a master.
Definition: SCT_Chip.h:55
SCT_ReadoutData::maskChipsNotInReadout
void maskChipsNotInReadout()
Mask the chips that are not in the readout.
Definition: SCT_ReadoutData.cxx:180
SCT_Parameters
Enums for chip type.
Definition: SCT_PortMap.h:17
BARREL
@ BARREL
Definition: TRTRadiatorParameters.h:10
SCT_ReadoutData::isChipReadOut
bool isChipReadOut(const SCT_Chip &chip) const
Test if chip is in readout or not.
Definition: SCT_ReadoutData.h:76
SCT_ReadoutData::printStatus
void printStatus(const Identifier &moduleId) const
Print readout status.
Definition: SCT_ReadoutData.cxx:272
SCT_ReadoutData.h
SCT_ReadoutData::m_type
SCT_Parameters::ModuleType m_type
The type of this module (Barrel, Modified Barrel (0 or 1), Endcap)
Definition: SCT_ReadoutData.h:123
SCT_ReadoutData::setChipOut
void setChipOut(const SCT_Chip &chip)
Set chip out of readout and reset link.
Definition: SCT_ReadoutData.h:71
SCT_ReadoutData::m_chipsOnLink1
std::vector< int > m_chipsOnLink1
Definition: SCT_ReadoutData.h:125
Identifier
Definition: IdentifierFieldParser.cxx:14