ATLAS Offline Software
Loading...
Searching...
No Matches
TileDQstatusTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4/*
5 */
12
13
14#include "TileDQstatusTool.h"
23#include <CLHEP/Random/RandomEngine.h>
24#include <CLHEP/Random/RandFlat.h>
25#include "GaudiKernel/EventContext.h"
27
35 const std::string& name,
36 const IInterface* parent)
37 : base_class (type, name, parent)
38{
39}
40
41
46{
47 ATH_CHECK( detStore()->retrieve(m_tileHWID, "TileHWID") );
48
49 ATH_CHECK( m_badChannelsKey.initialize() );
50
51 if (m_simulateTrips) {
52 ATH_CHECK( m_athRNGSvc.retrieve() );
53 }
54
55 return StatusCode::SUCCESS;
56}
57
58
67StatusCode
68TileDQstatusTool::makeStatus (const EventContext& ctx,
69 const TileRawChannelContainer* rawChannelContainer,
70 const TileDigitsContainer* tileDigitsContainer,
71 const TileBeamElemContainer* tileBeamElemContainer,
72 TileDQstatus& dqstatus) const
73{
74 dqstatus.setAllGood();
75 dqstatus.setRODBCID (ctx.eventID().bunch_crossing_id());
76
78 ATH_CHECK( badChannels.isValid() );
79
80 ATH_CHECK( doBeamElem (tileBeamElemContainer, dqstatus) );
81
82 if (rawChannelContainer != nullptr) {
83 if (tileDigitsContainer != nullptr) {
84 bool isCalib = false;
85 bool incomplete = false;
86 for (const TileDigitsCollection* coll : *tileDigitsContainer) {
87 incomplete |= (coll->size() < 48);
88
89 if (coll->size() > 0) {
90 int dsize = (*(coll->begin()))->NtimeSamples();
91 if (4 < dsize && dsize < 15) { // don't use strange fragments
92 isCalib |= coll->isCalibMode();
93 }
94 }
95
96 int frag = coll->identify();
97 int partition = (frag >> 8);
98 int drawer = (frag & 0x3F);
99
100 std::vector < uint32_t > data = coll->getFragChipHeaderWords();
101 unsigned int dataSize = std::min(16u, (unsigned int) data.size());
102 for (unsigned int dmu = 0; dmu < dataSize; ++dmu) {
103 if (data[dmu] == 0xFFFFFFFF)
104 dqstatus.setEmptyEvent(partition, drawer, dmu, 0, 1);
105 }
106
107 data = coll->getFragChipHeaderWordsHigh();
108 dataSize = std::min(16u, (unsigned int) data.size());
109 for (unsigned int dmu = 0; dmu < dataSize; ++dmu) {
110 if (data[dmu] == 0xFFFFFFFF)
111 dqstatus.setEmptyEvent(partition, drawer, dmu, 1, 1);
112 }
113 }
114 dqstatus.setIncompleteDigits (incomplete);
115 dqstatus.setCalibMode (isCalib);
116 dqstatus.setBiGain (isCalib);
117 }
118
119 TileFragHash::TYPE RChType = rawChannelContainer->get_type();
120 if (RChType != TileFragHash::OptFilterDsp
122 {
123 ATH_MSG_DEBUG("RawChannelContainer didn't come from BS - don't check DQ flags");
124 ATH_MSG_DEBUG("RChType = " << RChType);
125 } else {
126 for (const TileRawChannelCollection *coll : *rawChannelContainer) {
127
128 int frag = coll->identify();
129 ATH_MSG_VERBOSE("RCh collection 0x" << MSG::hex << frag << MSG::dec
130 << " size=" << coll->size());
131
132 unsigned short existingDMUs = 0xFFFF;
133 if (frag > 0x2ff) { // do not count non-existing DMUs in EB
134 // do not count non-existing DMUs in EBA15 or EBC18
135 existingDMUs = (frag == 0x30E || frag == 0x411) ? 0x3CFE : 0x3CFF;
136 }
137
138 unsigned short wrongBCID(0);
139 unsigned short fragBCID = coll->getFragBCID();
140 if (fragBCID & existingDMUs) {
141
142 int drawer = (frag & 0x3F); // range 0-63
143 int ros = frag >> 8; // range 1-4
144
145 for (unsigned int channel = 0; channel < TileCalibUtils::MAX_CHAN; ++channel) {
146 HWIdentifier channel_id = m_tileHWID->channel_id(ros, drawer, channel);
147 if (badChannels->getChannelStatus(channel_id).isWrongBCID()) {
148 int dmu = channel / 3;
149 if (dmu == 1) {
150 // If BCID in 2nd DMU is wrong then there is no sence
151 // to check BCID in other DMUs because they are compared with this one.
152 // So it is assumed that BCID in all DMU are wrong.
153 wrongBCID = 0xFFFF & existingDMUs;
154 break;
155 }
156
157 wrongBCID |= (1U << dmu);
158 }
159 }
160
161 fragBCID &= ~wrongBCID;
162 }
163
164 dqstatus.fillArrays(coll, tileDigitsContainer, 0, fragBCID);
165 dqstatus.fillArrays(coll, tileDigitsContainer, 1, fragBCID);
166 }
167 if (dqstatus.nonZeroCounter() == 0) {
168 ATH_MSG_DEBUG("all DQ elements are empty - don't check DQ flags");
169 dqstatus.setAllGood();
170 } else {
171 ATH_MSG_DEBUG("BiGain mode: " << ((dqstatus.isBiGain()) ? "true" : "false"));
172 }
173 }
174 } else if (tileDigitsContainer != nullptr) {
175 bool isCalib = false;
176 bool incomplete = false;
177 for (const TileDigitsCollection* coll : *tileDigitsContainer) {
178 incomplete |= (coll->size() < 48);
179
180 if (coll->size() > 0) {
181 int dsize = (*(coll->begin()))->NtimeSamples();
182 if (4 < dsize && dsize < 15) { // don't use strange fragments
183 isCalib |= coll->isCalibMode();
184 }
185 }
186 }
187 dqstatus.setIncompleteDigits (incomplete);
188 dqstatus.setCalibMode (isCalib);
189 dqstatus.setBiGain (isCalib);
190 }
191
192 if (m_simulateTrips) {
193 ATHRNG::RNGWrapper* wrapper = m_athRNGSvc->getEngine (this, this->name());
194 wrapper->setSeed (this->name(), ctx);
195 CLHEP::HepRandomEngine* engine = wrapper->getEngine (ctx);
196 double rndmVec[TileCalibUtils::MAX_DRAWER];
197 const std::vector<float> defaultTripsProbs(TileCalibUtils::MAX_DRAWER, 0.0F);
198 const std::vector<std::vector<float>>& tripsProbs = badChannels->getTripsProbabilities();
199 for (unsigned int partition = 1; partition < TileCalibUtils::MAX_ROS; ++partition) {
200 CLHEP::RandFlat::shootArray (engine, TileCalibUtils::MAX_DRAWER, rndmVec);
201 const std::vector<float>& trips = tripsProbs.size() ? tripsProbs.at(partition - 1) : defaultTripsProbs;
202 dqstatus.fillTrips(partition, trips, rndmVec, this->msg());
203 }
204 }
205
206 dqstatus.setFilled (true);
207 return StatusCode::SUCCESS;
208}
209
210
216StatusCode
218 TileDQstatus& dqstatus) const
219{
220 if (!tileBeamElemContainer) {
221 return StatusCode::SUCCESS;
222 }
223
224 uint32_t* cispar = dqstatus.cispar();
225
226 for (const TileBeamElemCollection* coll : *tileBeamElemContainer) {
227 int frag = coll->identify();
228
229 if (dqstatus.trigType() == 0 && coll->getLvl1Type() != 0) {
230 // take it from the ROD header
231 // make negative to distinguish from TileCal internal trig types
232 dqstatus.setTrigType (- coll->getLvl1Type());
233 }
234
235 switch (frag) {
236
237 case LASE_PTN_FRAG: {
238
239 TileBeamElemCollection::const_iterator beamItr = coll->begin();
240 TileBeamElemCollection::const_iterator lastBeam = coll->end();
241
242 if (beamItr != lastBeam) {
243 std::vector < uint32_t > digits = (*beamItr)->get_digits();
244
245 if (digits.size() > 0) {
246 uint32_t laserFlag = digits[0];
247 if (laserFlag & 0xFF00)
248 dqstatus.setTrigType (laserFlag >> 8);
249 }
250 }
251 }
252 break;
253
254 case DIGI_PAR_FRAG: {
255 dqstatus.setRODBCID (coll->getRODBCID());
256
257 for (const TileBeamElem* elem : *coll) {
258 HWIdentifier id = elem->adc_HWID();
259 std::vector < uint32_t > digits = elem->get_digits();
260 int cha = m_tileHWID->channel(id);
261
262 if (cha < 15) {
263 if (digits.size() > 0) {
264 cispar[cha] = digits[0];
265 ATH_MSG_VERBOSE("cispar [" << cha << "] = " << cispar[cha]);
266 }
267 }
268 else if (cha == 15) {
269 int siz = 15 + digits.size();
270 if (siz > 110)
271 siz = 110;
272 for (int i = 15; i < siz; ++i) {
273 cispar[i] = digits[i - 15];
274 ATH_MSG_VERBOSE("cispar [" << i << "] = " << cispar[i]);
275 }
276 switch (cispar[16]) {
277
278 case 0x02: {
279 int aux_ext = cispar[17];
280 cispar[17] = (aux_ext & 0x00ff); // dac
281 cispar[18] = (aux_ext >> 8) & 0x00ff; // 00
282 cispar[19] = (aux_ext >> 16) & 0x00ff; // 00
283 cispar[20] = (aux_ext >> 24) & 0x00ff; // small/large cap
284 }
285 break;
286
287 case 0x07: {
288 bool badpar = ((cispar[16] == cispar[17]) || (cispar[17] == cispar[18]));
289 int aux_ext = cispar[18];
290 cispar[18] = (aux_ext & 0x00ff) - 1; // pmt ext cispar starts from 1
291 cispar[19] = (aux_ext >> 8) & 0x00ff; // tower
292 cispar[20] = (aux_ext >> 16) & 0x00ff; // drawer
293
294 if (badpar || (aux_ext>>24)!=0 || cispar[18]>5 || cispar[19]>15 || cispar[20]>63) {
295 ATH_MSG_WARNING("bad cispar[16,17,18]: " << cispar[16] << " " << cispar[17] << " " << aux_ext
296 << " drawer,tower,pmt: " << cispar[20] << " " << cispar[19] << " " << (int)cispar[18]);
297 cispar[16] += 0x100; // flag bad events
298 cispar[18] = 5;
299 cispar[19] = 0xff;
300 cispar[20] = 0xff;
301 }
302
303 if (cispar[16] != cispar[17]) {
304 // Warning: nonportable.
305 union {
306 unsigned int i;
307 float f;
308 } chargeCnv;
309 chargeCnv.i = cispar[17];
310 cispar[17] = chargeCnv.f;
311 }
312 }
313 break;
314 }
315 }
316 }
317 }
318 break;
319
320 case LASER_OBJ_FRAG: {
321
322 dqstatus.setRODBCID (coll->getRODBCID());
323
324 // laspar isn't actually used by anything.
325 // Leave commented out for now.
326#if 0
327 TileBeamElemCollection::const_iterator beamItr = (*collItr)->begin();
328 TileBeamElemCollection::const_iterator lastBeam = (*collItr)->end();
329
330 if (beamItr != lastBeam) { // one channel is expected, check that it's really there
331
332 std::vector < uint32_t > digits = (*beamItr)->get_digits();
333 int cha = std::min(32, (int) digits.size());
334
335 while (--cha >= 0) {
336 m_laspar[cha] = digits[cha];
337 ATH_MSG_VERBOSE("laspar [" << cha << "] = " << m_laspar[cha]);
338 }
339 }
340#endif
341 }
342 break;
343
344 case COIN_TRIG1_FRAG:
345 case COIN_TRIG2_FRAG:
346 case COIN_TRIG3_FRAG:
347 case COIN_TRIG4_FRAG:
348 case COIN_TRIG5_FRAG:
349 case COIN_TRIG6_FRAG:
350 case COIN_TRIG7_FRAG:
351 case COIN_TRIG8_FRAG: {
352 // coincTrig is not actually used by anything now.
353 // Leave commented out.
354#if 0
355 unsigned int board = frag - COIN_TRIG1_FRAG;
356 // make sure that we have enough space
357 if (board >= m_coincTrig.size()) {
358 m_coincTrig.resize(board + 1);
359 }
360
361 TileBeamElemCollection::const_iterator beamItr = (*collItr)->begin();
362 TileBeamElemCollection::const_iterator lastBeam = (*collItr)->end();
363
364 // loop over 4 integer words for one board
365 for (; beamItr != lastBeam; ++beamItr) {
366
367 HWIdentifier id = (*beamItr)->adc_HWID();
368 std::vector < uint32_t > digits = (*beamItr)->get_digits();
369 uint32_t amplitude = (digits.size() > 0) ? digits[0] : 0;
370 int cha = m_tileHWID->channel(id);
371
372 if (cha < 3) {
373 int idx = cha * 32;
374 for (int ibit = 0; ibit < 32; ++ibit) {
375 m_coincTrig[board].trig[idx++] = (amplitude >> ibit) & 1;
376 }
377 } else if (cha == 3) {
378 m_coincTrig[board].amp = amplitude;
379 }
380 }
381#endif
382 }
383 break;
384
385 default:
386 break;
387 }
388 }
389
390 return StatusCode::SUCCESS;
391}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
bool isCalib()
Construct a TileDQstatus object.
Information produced by TileDQstatusAlg (used to be done by TileBeamInfoProvider).
#define COIN_TRIG4_FRAG
Definition TileTBFrag.h:35
#define COIN_TRIG2_FRAG
Definition TileTBFrag.h:33
#define LASER_OBJ_FRAG
Definition TileTBFrag.h:49
#define COIN_TRIG7_FRAG
Definition TileTBFrag.h:38
#define COIN_TRIG5_FRAG
Definition TileTBFrag.h:36
#define COIN_TRIG8_FRAG
Definition TileTBFrag.h:39
#define COIN_TRIG6_FRAG
Definition TileTBFrag.h:37
#define LASE_PTN_FRAG
Definition TileTBFrag.h:27
#define COIN_TRIG3_FRAG
Definition TileTBFrag.h:34
#define DIGI_PAR_FRAG
Definition TileTBFrag.h:41
#define COIN_TRIG1_FRAG
Definition TileTBFrag.h:32
A wrapper class for event-slot-local random engines.
Definition RNGWrapper.h:56
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
Definition RNGWrapper.h:169
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
Definition RNGWrapper.h:134
DataModel_detail::const_iterator< DataVector > const_iterator
Standard const_iterator.
Definition DataVector.h:838
static const unsigned int MAX_ROS
Number of ROSs.
static const unsigned int MAX_DRAWER
Number of drawers in ROS 1-4.
static const unsigned int MAX_CHAN
Number of channels in drawer.
SG::ReadCondHandleKey< TileBadChannels > m_badChannelsKey
Name of TileBadChannels in condition store.
TileDQstatusTool(const std::string &type, const std::string &name, const IInterface *parent)
Standard Gaudi tool constructor.
Gaudi::Property< bool > m_simulateTrips
virtual StatusCode makeStatus(const EventContext &ctx, const TileRawChannelContainer *rawChannelContainer, const TileDigitsContainer *tileDigitsContainer, const TileBeamElemContainer *tileBeamElemContainer, TileDQstatus &dqstatus) const override
Make a new TileDQstatus object.
const TileHWID * m_tileHWID
Tile ID helper.
virtual StatusCode initialize() override
Gaudi initialize method.
StatusCode doBeamElem(const TileBeamElemContainer *tileBeamElemContainer, TileDQstatus &dqstatus) const
Process BeamElemContainer.
ServiceHandle< IAthRNGSvc > m_athRNGSvc
Class that holds Data Quality fragment information and provides functions to extract the data quality...
void fillArrays(const TileRawChannelCollection *coll, const TileDigitsContainer *digitsCnt, int gain, unsigned short fragBCID)
parses DQ fragments and fill error arrays for event
bool nonZeroCounter() const
returns True if there are any errors in event
void setCalibMode(uint32_t calibMode)
void setFilled(bool filled)
sets flag that DQ status instance has been filled for this event
void setBiGain(bool biGain)
sets flag of gain mode of run
int trigType() const
Trigger type.
void fillTrips(unsigned int partition, const std::vector< float > &trips, double *rndmVec, MsgStream &msg)
void setRODBCID(uint32_t BCID)
sets the ROD BCID stored and used in DQStatus
void setIncompleteDigits(bool incomplete)
void setTrigType(int trigType)
void setEmptyEvent(int partition, int drawer, int dmu, int gain, int isEmpty)
sets flag that DMU sent an empty event (0xFFFFFFFF)
const uint32_t * cispar() const
CIS parameters.
bool isBiGain() const
returns gain mode of run
void setAllGood()
mark all channels/ADC's as DQ good
TYPE
initialize
MsgStream & msg
Definition testRead.cxx:32