ATLAS Offline Software
Loading...
Searching...
No Matches
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
26static 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
31static bool modified1(Identifier moduleId) {
32 return ((moduleId==170983424) or (moduleId==173268992) or (moduleId==174301184) or (moduleId==175015936));
33}
34
35using namespace SCT_Parameters;
36
37// Constructor
39 : AthMessaging (msgSvc, "SCT_ReadoutData")
40{
41}
42
43void 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
192bool 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
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
272void 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
306void 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
312void 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}
#define endmsg
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
static Double_t a
static bool modified1(Identifier moduleId)
static bool modified0(Identifier moduleId)
Header file for the SCT_ReadoutData class.
MsgStream & msg() const
The standard message stream.
bool msgLvl(const MSG::Level lvl) const
Test the output level.
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
Class which stores infomration on the SCT chips: id, config, mask.
Definition SCT_Chip.h:27
short inPort() const
Active input port.
Definition SCT_Chip.h:44
bool isMaster() const
Is chip a master.
Definition SCT_Chip.h:50
bool isEnd() const
Is chip an end.
Definition SCT_Chip.h:48
bool canBeMaster() const
Can chip be a master (i.e position 0 or 6)
Definition SCT_Chip.h:52
short id() const
Chip Id.
Definition SCT_Chip.h:42
bool slaveConfiguredAsMaster() const
Is this a slave chip mistakenly configured as a master.
Definition SCT_Chip.h:55
void clearChipReadout()
Set all chips out of readout and clear both links to start.
bool isChipReadOut(const SCT_Chip &chip) const
Test if chip is in readout or not.
void setModuleType(const Identifier &moduleId, int bec)
Set the module type.
SCT_Parameters::ChipType inputChip(const SCT_Chip &chip) const
Find the ID of the input chip for chip.
std::vector< int > m_chipsOnLink1
bool hasConnectedInput(const SCT_Chip &chip) const
Chip has a correctly connected input.
void setLinkStatus(bool link0ok, bool link1ok)
Set link status.
bool m_linkActive[2]
Links status for link 0 and 1.
void setChipIn(const SCT_Chip &chip, int link)
Set chip in readout and which link it is on.
std::bitset< SCT_Parameters::NChips > m_chipInReadout
Bitset indicating whether a chip is readout or not.
std::vector< SCT_PortMap > m_chipMap
Vector of port mapping from the chips in an SCT module.
bool followReadoutUpstream(int link, const SCT_Chip &chip, int remainingDepth=12)
Follow the readout to the input side.
SCT_ReadoutData(IMessageSvc *msgSvc=nullptr)
void setChipMap()
Fill the chip mapping.
void maskChipsNotInReadout()
Mask the chips that are not in the readout.
void setChipOut(const SCT_Chip &chip)
Set chip out of readout and reset link.
std::vector< int > m_chipsOnLink0
The chips read out on link 0.
void checkLink(int link)
Check which chips are in the readout for a particular link and if the readout is sane.
void setChips(std::vector< SCT_Chip > &chips)
Set SCT_Chip vectors.
SCT_Parameters::ModuleType m_type
The type of this module (Barrel, Modified Barrel (0 or 1), Endcap)
bool isEndBeingTalkedTo(const SCT_Chip &chip) const
Chip is an end but is being talked to.
bool isLinkStandard(int link) const
is the readout for a particular link sane
SCT_Parameters::ChipType outputChip(const SCT_Chip &chip) const
Find the ID of the output chip for chip.
void printStatus(const Identifier &moduleId) const
Print readout status.
std::vector< SCT_Chip > * m_chips
Private data.
Enums for chip type.
Definition SCT_PortMap.h:17
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.