ATLAS Offline Software
Loading...
Searching...
No Matches
JepByteStreamV1Tool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
5
6#include <numeric>
7#include <set>
8#include <utility>
9
10#include "GaudiKernel/IInterface.h"
11#include "GaudiKernel/MsgStream.h"
12#include "GaudiKernel/StatusCode.h"
13
15
25
26#include "CmmEnergySubBlock.h"
27#include "CmmJetSubBlock.h"
28#include "CmmSubBlock.h"
29#include "JemJetElement.h"
30#include "JemSubBlockV1.h"
32#include "L1CaloSrcIdMap.h"
33#include "L1CaloSubBlock.h"
34#include "L1CaloUserHeader.h"
35#include "ModifySlices.h"
36
37#include "JepByteStreamV1Tool.h"
38
39namespace LVL1BS {
40
41// Interface ID
42
43static const InterfaceID IID_IJepByteStreamV1Tool("JepByteStreamV1Tool", 1, 1);
44
46{
48}
49
50// Constructor
51
53 const std::string& name,
54 const IInterface* parent)
55 : AthAlgTool(type, name, parent),
56 m_jemMaps("LVL1::JemMappingTool/JemMappingTool"),
57 m_errorTool("LVL1BS::L1CaloErrorByteStreamTool/L1CaloErrorByteStreamTool"),
58 m_channels(44), m_crates(2), m_modules(16),
59 m_subDetector(eformat::TDAQ_CALO_JET_PROC_DAQ)
60{
61 declareInterface<JepByteStreamV1Tool>(this);
62
63 declareProperty("JemMappingTool", m_jemMaps,
64 "Crate/Module/Channel to Eta/Phi/Layer mapping tool");
65 declareProperty("ErrorTool", m_errorTool,
66 "Tool to collect errors for monitoring");
67
68 declareProperty("CrateOffsetHw", m_crateOffsetHw = 12,
69 "Offset of JEP crate numbers in bytestream");
70 declareProperty("CrateOffsetSw", m_crateOffsetSw = 0,
71 "Offset of JEP crate numbers in RDOs");
72 declareProperty("SlinksPerCrate", m_slinks = 4,
73 "The number of S-Links per crate");
74
75 // Properties for reading bytestream only
76 declareProperty("ROBSourceIDs", m_sourceIDsProp,
77 "ROB fragment source identifiers");
78
79 // Properties for writing bytestream only
80 declareProperty("DataVersion", m_version = 1,
81 "Format version number in sub-block header");
82 declareProperty("DataFormat", m_dataFormat = 1,
83 "Format identifier (0-1) in sub-block header");
84 declareProperty("SimulSlices", m_dfltSlices = 1,
85 "The number of slices in the simulation");
86 declareProperty("ForceSlices", m_forceSlices = 0,
87 "If >0, the number of slices in bytestream");
88 declareProperty("CrateMin", m_crateMin = 0,
89 "Minimum crate number, allows partial output");
90 declareProperty("CrateMax", m_crateMax = m_crates - 1,
91 "Maximum crate number, allows partial output");
92
93}
94
95// Destructor
96
100
101// Initialize
102
103
105{
106 ATH_MSG_INFO ("Initializing " << name());
107
108 ATH_CHECK( m_jemMaps.retrieve() );
109 ATH_CHECK( m_errorTool.retrieve() );
110 ATH_CHECK( m_byteStreamCnvSvc.retrieve() );
111
112 return StatusCode::SUCCESS;
113}
114
115// Finalize
116
118{
119 return StatusCode::SUCCESS;
120}
121
122// Conversion bytestream to jet elements
123
125 const std::string& sgKey,
126 const IROBDataProviderSvc::VROBFRAG& robFrags,
127 DataVector<LVL1::JetElement>* const jeCollection) const
128{
129 JetElementData data (jeCollection);
130 return convertBs(sgKey, robFrags, data);
131}
132
133// Conversion bytestream to jet hits
134
136 const std::string& sgKey,
137 const IROBDataProviderSvc::VROBFRAG& robFrags,
138 DataVector<LVL1::JEMHits>* const hitCollection) const
139{
140 JetHitsData data (hitCollection);
141 return convertBs(sgKey, robFrags, data);
142}
143
144// Conversion bytestream to energy sums
145
147 const std::string& sgKey,
148 const IROBDataProviderSvc::VROBFRAG& robFrags,
149 DataVector<LVL1::JEMEtSums>* const etCollection) const
150{
151 EnergySumsData data (etCollection);
152 return convertBs(sgKey, robFrags, data);
153}
154
155// Conversion bytestream to CMM hits
156
158 const std::string& sgKey,
159 const IROBDataProviderSvc::VROBFRAG& robFrags,
160 DataVector<LVL1::CMMJetHits>* const hitCollection) const
161{
162 CmmHitsData data (hitCollection);
163 return convertBs(sgKey, robFrags, data);
164}
165
166// Conversion bytestream to CMM energy sums
167
169 const std::string& sgKey,
170 const IROBDataProviderSvc::VROBFRAG& robFrags,
171 DataVector<LVL1::CMMEtSums>* const etCollection) const
172{
173 CmmSumsData data (etCollection);
174 return convertBs(sgKey, robFrags, data);
175}
176
177// Conversion of JEP container to bytestream
178
180{
181 const bool debug = msgLvl(MSG::DEBUG);
182 if (debug) msg(MSG::DEBUG);
183
184 // Get the event assembler
186 ATH_CHECK( m_byteStreamCnvSvc->getFullEventAssembler (fea,
187 "JepByteStreamV1") );
188 const uint16_t minorVersion = m_srcIdMap.minorVersionPreLS1();
189 fea->setRodMinorVersion(minorVersion);
190
191 // Pointer to ROD data vector
192
194
195 // Jet element key provider
196 LVL1::JetElementKey elementKey;
197
198 // Set up the container maps
199
200 // Jet element map
201 ConstJetElementMap jeMap;
202 setupJeMap(jep->JetElements(), jeMap, elementKey);
203
204 // Jet hits map
205 ConstJetHitsMap hitsMap;
206 setupHitsMap(jep->JetHits(), hitsMap);
207
208 // Energy sums map
209 ConstEnergySumsMap etMap;
210 setupEtMap(jep->EnergySums(), etMap);
211
212 // CMM hits map
213 ConstCmmHitsMap cmmHitsMap;
214 setupCmmHitsMap(jep->CmmHits(), cmmHitsMap);
215
216 // CMM energy sums map
217 ConstCmmSumsMap cmmEtMap;
218 setupCmmEtMap(jep->CmmSums(), cmmEtMap);
219
220 // Loop over data
221
222 const bool neutralFormat = m_dataFormat == L1CaloSubBlock::NEUTRAL;
223 const int modulesPerSlink = m_modules / m_slinks;
224 int timeslices = 1;
225 int trigJem = 0;
226 int timeslicesNew = 1;
227 int trigJemNew = 0;
228 for (int crate = m_crateMin; crate <= m_crateMax; ++crate) {
229 const int hwCrate = crate + m_crateOffsetHw;
230
231 for (int module = 0; module < m_modules; ++module) {
232
233 // Pack required number of modules per slink
234
235 if (module % modulesPerSlink == 0) {
236 const int daqOrRoi = 0;
237 const int slink = module / modulesPerSlink;
238 if (debug) {
239 msg() << "Treating crate " << hwCrate
240 << " slink " << slink << endmsg;
241 }
242 // Get number of JEM slices and triggered slice offset
243 // for this slink
244 if ( ! slinkSlices(crate, module, modulesPerSlink,
245 timeslices, trigJem,
246 jeMap,
247 hitsMap,
248 etMap,
249 cmmHitsMap,
250 cmmEtMap,
251 elementKey))
252 {
253 msg(MSG::ERROR) << "Inconsistent number of slices or "
254 << "triggered slice offsets in data for crate "
255 << hwCrate << " slink " << slink << endmsg;
256 return StatusCode::FAILURE;
257 }
258 timeslicesNew = (m_forceSlices) ? m_forceSlices : timeslices;
259 trigJemNew = ModifySlices::peak(trigJem, timeslices, timeslicesNew);
260 if (debug) {
261 msg() << "Data Version/Format: " << m_version
262 << " " << m_dataFormat << endmsg
263 << "Slices/offset: " << timeslices << " " << trigJem;
264 if (timeslices != timeslicesNew) {
265 msg() << " modified to " << timeslicesNew << " " << trigJemNew;
266 }
267 msg() << endmsg;
268 }
269 L1CaloUserHeader userHeader;
270 userHeader.setJem(trigJemNew);
271 const uint32_t rodIdJem = m_srcIdMap.getRodID(hwCrate, slink, daqOrRoi,
273 theROD = fea->getRodData(rodIdJem);
274 theROD->push_back(userHeader.header());
275 }
276 if (debug) msg() << "Module " << module << endmsg;
277
278 // Create a sub-block for each slice (except Neutral format)
279
280 // Vector for current JEM sub-blocks
282
283 for (int slice = 0; slice < timeslicesNew; ++slice) {
284 JemSubBlockV1* const subBlock = new JemSubBlockV1();
285 subBlock->setJemHeader(m_version, m_dataFormat, slice,
286 hwCrate, module, timeslicesNew);
287 jemBlocks.push_back(subBlock);
288 if (neutralFormat) break;
289 }
290
291 // Find jet elements corresponding to each eta/phi pair and fill
292 // sub-blocks
293
294 for (int chan = 0; chan < m_channels; ++chan) {
295 double eta = 0.;
296 double phi = 0.;
297 int layer = 0;
298 if (m_jemMaps->mapping(crate, module, chan, eta, phi, layer)) {
299 const LVL1::JetElement* const je = findJetElement(eta, phi, jeMap, elementKey);
300 if (je ) {
301 std::vector<int> emData;
302 std::vector<int> hadData;
303 std::vector<int> emErrors;
304 std::vector<int> hadErrors;
305 ModifySlices::data(je->emEnergyVec(), emData, timeslicesNew);
306 ModifySlices::data(je->hadEnergyVec(), hadData, timeslicesNew);
307 ModifySlices::data(je->emErrorVec(), emErrors, timeslicesNew);
308 ModifySlices::data(je->hadErrorVec(), hadErrors, timeslicesNew);
309 for (int slice = 0; slice < timeslicesNew; ++slice) {
310 const LVL1::DataError emErrBits(emErrors[slice]);
311 const LVL1::DataError hadErrBits(hadErrors[slice]);
312 const int index = ( neutralFormat ) ? 0 : slice;
313 JemSubBlockV1* const subBlock = jemBlocks[index];
314 const JemJetElement jetEle(chan, emData[slice], hadData[slice],
315 emErrBits.get(LVL1::DataError::Parity),
316 hadErrBits.get(LVL1::DataError::Parity),
317 emErrBits.get(LVL1::DataError::LinkDown) +
318 (hadErrBits.get(LVL1::DataError::LinkDown) << 1));
319 subBlock->fillJetElement(slice, jetEle);
320 }
321 }
322 }
323 }
324
325 // Add jet hits and energy subsums
326
327 const LVL1::JEMHits* const hits = findJetHits(crate, module, hitsMap);
328 if (hits) {
329 std::vector<unsigned int> vec;
330 ModifySlices::data(hits->JetHitsVec(), vec, timeslicesNew);
331 for (int slice = 0; slice < timeslicesNew; ++slice) {
332 const int index = ( neutralFormat ) ? 0 : slice;
333 JemSubBlockV1* const subBlock = jemBlocks[index];
334 subBlock->setJetHits(slice, vec[slice]);
335 }
336 }
337 const LVL1::JEMEtSums* const et = findEnergySums(crate, module, etMap);
338 if (et) {
339 std::vector<unsigned int> exVec;
340 std::vector<unsigned int> eyVec;
341 std::vector<unsigned int> etVec;
342 ModifySlices::data(et->ExVec(), exVec, timeslicesNew);
343 ModifySlices::data(et->EyVec(), eyVec, timeslicesNew);
344 ModifySlices::data(et->EtVec(), etVec, timeslicesNew);
345 for (int slice = 0; slice < timeslicesNew; ++slice) {
346 const int index = ( neutralFormat ) ? 0 : slice;
347 JemSubBlockV1* const subBlock = jemBlocks[index];
348 subBlock->setEnergySubsums(slice, exVec[slice], eyVec[slice],
349 etVec[slice]);
350 }
351 }
352
353 // Pack and write the sub-blocks
354
356 for (pos = jemBlocks.begin(); pos != jemBlocks.end(); ++pos) {
357 JemSubBlockV1* const subBlock = *pos;
358 if ( !subBlock->pack()) {
359 msg(MSG::ERROR) << "JEM sub-block packing failed" << endmsg;
360 return StatusCode::FAILURE;
361 }
362 if (debug) {
363 msg() << "JEM sub-block data words: "
364 << subBlock->dataWords() << endmsg;
365 }
366 subBlock->write(theROD);
367 }
368 }
369
370 // Append CMMs to last S-Link of the crate
371
372 // Create a sub-block for each slice (except Neutral format)
373
374 // Vector for current CMM-Energy sub-blocks
375 DataVector<CmmEnergySubBlock> cmmEnergyBlocks;
376 // Vector for current CMM-Jet sub-blocks
377 DataVector<CmmJetSubBlock> cmmJetBlocks;
378
379 const int summing = (crate == m_crates - 1) ? CmmSubBlock::SYSTEM
381 for (int slice = 0; slice < timeslicesNew; ++slice) {
382 CmmEnergySubBlock* const enBlock = new CmmEnergySubBlock();
383 const int cmmEnergyVersion = 2; // with Missing-ET-Sig
384 enBlock->setCmmHeader(cmmEnergyVersion, m_dataFormat, slice, hwCrate,
386 CmmSubBlock::LEFT, timeslicesNew);
387 cmmEnergyBlocks.push_back(enBlock);
388 CmmJetSubBlock* const jetBlock = new CmmJetSubBlock();
389 jetBlock->setCmmHeader(m_version, m_dataFormat, slice, hwCrate,
390 summing, CmmSubBlock::CMM_JET,
391 CmmSubBlock::RIGHT, timeslicesNew);
392 cmmJetBlocks.push_back(jetBlock);
393 if (neutralFormat) break;
394 }
395
396 // CMM-Energy
397
398 int maxDataID = static_cast<int>(LVL1::CMMEtSums::MAXID);
399 for (int dataID = 0; dataID < maxDataID; ++dataID) {
400 int source = dataID;
401 if (dataID >= m_modules) {
402 if (summing == CmmSubBlock::CRATE &&
403 dataID != LVL1::CMMEtSums::LOCAL) continue;
404 // coverity[mixed_enums : FALSE]
405 // coverity[switch_on_enum : FALSE]
406 // coverity[first_enum_type : FALSE]
407 switch (dataID) {
410 break;
413 break;
416 break;
420 break;
421 default:
422 continue;
423 }
424 }
425 const LVL1::CMMEtSums* const sums = findCmmSums(crate, dataID, cmmEtMap);
426 if ( sums ) {
427 std::vector<unsigned int> ex;
428 std::vector<unsigned int> ey;
429 std::vector<unsigned int> et;
430 std::vector<int> exErr;
431 std::vector<int> eyErr;
432 std::vector<int> etErr;
433 ModifySlices::data(sums->ExVec(), ex, timeslicesNew);
434 ModifySlices::data(sums->EyVec(), ey, timeslicesNew);
435 ModifySlices::data(sums->EtVec(), et, timeslicesNew);
436 ModifySlices::data(sums->ExErrorVec(), exErr, timeslicesNew);
437 ModifySlices::data(sums->EyErrorVec(), eyErr, timeslicesNew);
438 ModifySlices::data(sums->EtErrorVec(), etErr, timeslicesNew);
439 for (int slice = 0; slice < timeslicesNew; ++slice) {
440 const LVL1::DataError exErrBits(exErr[slice]);
441 const LVL1::DataError eyErrBits(eyErr[slice]);
442 const LVL1::DataError etErrBits(etErr[slice]);
443 int exError = exErrBits.get(LVL1::DataError::Parity);
444 int eyError = eyErrBits.get(LVL1::DataError::Parity);
445 int etError = etErrBits.get(LVL1::DataError::Parity);
446 if (dataID == LVL1::CMMEtSums::LOCAL ||
447 dataID == LVL1::CMMEtSums::REMOTE ||
448 dataID == LVL1::CMMEtSums::TOTAL) {
449 exError = (exError << 1) + exErrBits.get(LVL1::DataError::Overflow);
450 eyError = (eyError << 1) + eyErrBits.get(LVL1::DataError::Overflow);
451 etError = (etError << 1) + etErrBits.get(LVL1::DataError::Overflow);
452 }
453 const int index = ( neutralFormat ) ? 0 : slice;
454 CmmEnergySubBlock* const subBlock = cmmEnergyBlocks[index];
455 if (dataID == LVL1::CMMEtSums::MISSING_ET_MAP) {
456 subBlock->setMissingEtHits(slice, et[slice]);
457 } else if (dataID == LVL1::CMMEtSums::SUM_ET_MAP) {
458 subBlock->setSumEtHits(slice, et[slice]);
459 } else if (dataID == LVL1::CMMEtSums::MISSING_ET_SIG_MAP) {
460 subBlock->setMissingEtSigHits(slice, et[slice]);
461 } else {
462 subBlock->setSubsums(slice, source,
463 ex[slice], ey[slice], et[slice],
464 exError, eyError, etError);
465 }
466 }
467 }
468 }
470 pos = cmmEnergyBlocks.begin();
471 for (; pos != cmmEnergyBlocks.end(); ++pos) {
472 CmmEnergySubBlock* const subBlock = *pos;
473 if ( !subBlock->pack()) {
474 msg(MSG::ERROR) << "CMM-Energy sub-block packing failed" << endmsg;
475 return StatusCode::FAILURE;
476 }
477 if (debug) {
478 msg() << "CMM-Energy sub-block data words: "
479 << subBlock->dataWords() << endmsg;
480 }
481 subBlock->write(theROD);
482 }
483
484 // CMM-Jet
485
486 maxDataID = static_cast<int>(LVL1::CMMJetHits::MAXID);
487 for (int dataID = 0; dataID < maxDataID; ++dataID) {
488 int source = dataID;
489 if (dataID >= m_modules) {
490 if (summing == CmmSubBlock::CRATE &&
492 dataID != LVL1::CMMJetHits::LOCAL_FORWARD) continue;
493 // coverity[mixed_enums : FALSE]
494 // coverity[switch_on_enum : FALSE]
495 // coverity[first_enum_type : FALSE]
496 switch (dataID) {
499 break;
502 break;
505 break;
508 break;
511 break;
514 break;
516 break;
517 default:
518 continue;
519 }
520 }
521 const LVL1::CMMJetHits* const ch = findCmmHits(crate, dataID, cmmHitsMap);
522 if ( ch ) {
523 std::vector<unsigned int> hits;
524 std::vector<int> errs;
525 ModifySlices::data(ch->HitsVec(), hits, timeslicesNew);
526 ModifySlices::data(ch->ErrorVec(), errs, timeslicesNew);
527 for (int slice = 0; slice < timeslicesNew; ++slice) {
528 const LVL1::DataError errBits(errs[slice]);
529 const int index = ( neutralFormat ) ? 0 : slice;
530 CmmJetSubBlock* const subBlock = cmmJetBlocks[index];
531 if (dataID == LVL1::CMMJetHits::ET_MAP) {
532 subBlock->setJetEtMap(slice, hits[slice]);
533 } else {
534 subBlock->setJetHits(slice, source, hits[slice],
536 }
537 }
538 }
539 }
541 jos = cmmJetBlocks.begin();
542 for (; jos != cmmJetBlocks.end(); ++jos) {
543 CmmJetSubBlock* const subBlock = *jos;
544 if ( !subBlock->pack()) {
545 msg(MSG::ERROR) << "CMM-Jet sub-block packing failed" << endmsg;
546 return StatusCode::FAILURE;
547 }
548 if (debug) {
549 msg() << "CMM-Jet sub-block data words: "
550 << subBlock->dataWords() << endmsg;
551 }
552 subBlock->write(theROD);
553 }
554 }
555
556 return StatusCode::SUCCESS;
557}
558
559// Return reference to vector with all possible Source Identifiers
560
561std::vector<uint32_t> JepByteStreamV1Tool::makeSourceIDs() const
562{
563 std::vector<uint32_t> sourceIDs;
564
565 if (!m_sourceIDsProp.empty()) {
567 }
568 else {
569 const int maxCrates = m_crates + m_crateOffsetHw;
570 const int maxSlinks = m_srcIdMap.maxSlinks();
571 for (int hwCrate = m_crateOffsetHw; hwCrate < maxCrates; ++hwCrate)
572 {
573 for (int slink = 0; slink < maxSlinks; ++slink)
574 {
575 const int daqOrRoi = 0;
576 const uint32_t rodId = m_srcIdMap.getRodID(hwCrate, slink, daqOrRoi,
578 const uint32_t robId = m_srcIdMap.getRobID(rodId);
579 sourceIDs.push_back(robId);
580 }
581 }
582 }
583 return sourceIDs;
584}
585
586const std::vector<uint32_t>& JepByteStreamV1Tool::sourceIDs() const
587{
588 static const std::vector<uint32_t> sourceIDs = makeSourceIDs();
589 return sourceIDs;
590}
591
592// Convert bytestream to given container type
593
595 const std::string& sgKey,
596 const IROBDataProviderSvc::VROBFRAG& robFrags,
598{
599 LocalData ld;
600
601 // Check if overlap jet element channels wanted
602 const std::string flag("Overlap");
603 const std::string::size_type pos = sgKey.find(flag);
604 ld.coreOverlap =
605 (pos == std::string::npos || pos != sgKey.length() - flag.length()) ? 0 : 1;
606
607 const bool debug = msgLvl(MSG::DEBUG);
608 if (debug) msg(MSG::DEBUG);
609
610 // JemSubBlock for unpacking
611 JemSubBlockV1 jemSubBlock;
612 // CmmEnergySubBlock for unpacking
613 CmmEnergySubBlock cmmEnergySubBlock;
614 // CmmJetSubBlock for unpacking
615 CmmJetSubBlock cmmJetSubBlock;
616
617 // Loop over ROB fragments
618
619 int robCount = 0;
620 std::set<uint32_t> dupCheck;
621 ROBIterator rob = robFrags.begin();
622 ROBIterator robEnd = robFrags.end();
623 for (; rob != robEnd; ++rob) {
624
625 if (debug) {
626 ++robCount;
627 msg() << "Treating ROB fragment " << robCount << endmsg;
628 }
629
630 // Skip fragments with ROB status errors
631
632 uint32_t robid = (*rob)->source_id();
633 if ((*rob)->nstatus() > 0) {
634 ROBPointer robData;
635 (*rob)->status(robData);
636 if (*robData != 0) {
637 m_errorTool->robError(robid, *robData);
638 if (debug) msg() << "ROB status error - skipping fragment" << endmsg;
639 continue;
640 }
641 }
642
643 // Skip duplicate fragments
644
645 if (!dupCheck.insert(robid).second) {
647 if (debug) msg() << "Skipping duplicate ROB fragment" << endmsg;
648 continue;
649 }
650
651 // Unpack ROD data (slinks)
652
653 RODPointer payloadBeg;
654 RODPointer payload;
655 RODPointer payloadEnd;
656 (*rob)->rod_data(payloadBeg);
657 payloadEnd = payloadBeg + (*rob)->rod_ndata();
658 payload = payloadBeg;
659 if (payload == payloadEnd) {
660 if (debug) msg() << "ROB fragment empty" << endmsg;
661 continue;
662 }
663
664 // Check identifier
665 const uint32_t sourceID = (*rob)->rod_source_id();
666 if (m_srcIdMap.getRobID(sourceID) != robid ||
667 m_srcIdMap.subDet(sourceID) != m_subDetector ||
668 m_srcIdMap.daqOrRoi(sourceID) != 0 ||
669 m_srcIdMap.slink(sourceID) >= m_slinks ||
670 m_srcIdMap.crate(sourceID) < m_crateOffsetHw ||
671 m_srcIdMap.crate(sourceID) >= m_crateOffsetHw + m_crates) {
673 if (debug) {
674 msg() << "Wrong source identifier in data: ROD "
675 << MSG::hex << sourceID << " ROB " << robid
676 << MSG::dec << endmsg;
677 }
678 continue;
679 }
680
681 // Check minor version
682 const int minorVersion = (*rob)->rod_version() & 0xffff;
683 if (minorVersion > m_srcIdMap.minorVersionPreLS1()) {
684 if (debug) msg() << "Skipping post-LS1 data" << endmsg;
685 continue;
686 }
687 const int rodCrate = m_srcIdMap.crate(sourceID);
688 if (debug) {
689 msg() << "Treating crate " << rodCrate
690 << " slink " << m_srcIdMap.slink(sourceID) << endmsg;
691 }
692
693 // First word should be User Header
694 if ( !L1CaloUserHeader::isValid(*payload) ) {
696 if (debug) msg() << "Invalid or missing user header" << endmsg;
697 continue;
698 }
699 L1CaloUserHeader userHeader(*payload);
700 userHeader.setVersion(minorVersion);
701 const int headerWords = userHeader.words();
702 if (headerWords != 1) {
704 if (debug) msg() << "Unexpected number of user header words: "
705 << headerWords << endmsg;
706 continue;
707 }
708 for (int i = 0; i < headerWords; ++i) ++payload;
709 // triggered slice offsets
710 int trigJem = userHeader.jem();
711 int trigCmm = userHeader.jepCmm();
712 if (debug) {
713 msg() << "Minor format version number: " << MSG::hex
714 << minorVersion << MSG::dec << endmsg
715 << "JEM triggered slice offset: " << trigJem << endmsg
716 << "CMM triggered slice offset: " << trigCmm << endmsg;
717 }
718 if (trigJem != trigCmm) {
719 const int newTrig = (trigJem > trigCmm) ? trigJem : trigCmm;
720 trigJem = newTrig;
721 trigCmm = newTrig;
722 if (debug) msg() << "Changed both offsets to " << newTrig << endmsg;
723 }
724
725 // Loop over sub-blocks
726
727 ld.rodErr = L1CaloSubBlock::ERROR_NONE;
728 while (payload != payloadEnd) {
729
731 if (debug) msg() << "Unexpected data sequence" << endmsg;
733 break;
734 }
735 if (CmmSubBlock::cmmBlock(*payload)) {
736 // CMMs
738 cmmJetSubBlock.clear();
739 payload = cmmJetSubBlock.read(payload, payloadEnd);
740 if (cmmJetSubBlock.crate() != rodCrate) {
741 if (debug) msg() << "Inconsistent crate number in ROD source ID"
742 << endmsg;
744 break;
745 }
746 if (data.m_collection == CMM_HITS) {
747 decodeCmmJet(&cmmJetSubBlock, trigCmm, static_cast<CmmHitsData&>(data), ld);
748 if (ld.rodErr != L1CaloSubBlock::ERROR_NONE) {
749 if (debug) msg() << "decodeCmmJet failed" << endmsg;
750 break;
751 }
752 }
753 } else if (CmmSubBlock::cmmType(*payload) == CmmSubBlock::CMM_ENERGY) {
754 cmmEnergySubBlock.clear();
755 payload = cmmEnergySubBlock.read(payload, payloadEnd);
756 if (cmmEnergySubBlock.crate() != rodCrate) {
757 if (debug) msg() << "Inconsistent crate number in ROD source ID"
758 << endmsg;
760 break;
761 }
762 if (data.m_collection == CMM_SUMS) {
763 decodeCmmEnergy(&cmmEnergySubBlock, trigCmm, static_cast<CmmSumsData&>(data), ld);
764 if (ld.rodErr != L1CaloSubBlock::ERROR_NONE) {
765 if (debug) msg() << "decodeCmmEnergy failed" << endmsg;
766 break;
767 }
768 }
769 } else {
770 if (debug) msg() << "Invalid CMM type in module field" << endmsg;
772 break;
773 }
774 } else {
775 // JEM
776 jemSubBlock.clear();
777 payload = jemSubBlock.read(payload, payloadEnd);
778 if (jemSubBlock.crate() != rodCrate) {
779 if (debug) msg() << "Inconsistent crate number in ROD source ID"
780 << endmsg;
782 break;
783 }
784 if (data.m_collection == JET_ELEMENTS || data.m_collection == JET_HITS ||
785 data.m_collection == ENERGY_SUMS) {
786 decodeJem(&jemSubBlock, trigJem, data, ld);
787 if (ld.rodErr != L1CaloSubBlock::ERROR_NONE) {
788 if (debug) msg() << "decodeJem failed" << endmsg;
789 break;
790 }
791 }
792 }
793 }
794 if (ld.rodErr != L1CaloSubBlock::ERROR_NONE)
795 m_errorTool->rodError(robid, ld.rodErr);
796 }
797
798 return StatusCode::SUCCESS;
799}
800
801// Unpack CMM-Energy sub-block
802
804 int trigCmm,
806 LocalData& ld) const
807{
808 const bool debug = msgLvl(MSG::DEBUG);
809 if (debug) msg(MSG::DEBUG);
810
811 const int hwCrate = subBlock->crate();
812 const int module = subBlock->cmmPosition();
813 const int firmware = subBlock->cmmFirmware();
814 const int summing = subBlock->cmmSumming();
815 const int timeslices = subBlock->timeslices();
816 const int sliceNum = subBlock->slice();
817 if (debug) {
818 msg() << "CMM-Energy: Crate " << hwCrate
819 << " Module " << module
820 << " Firmware " << firmware
821 << " Summing " << summing
822 << " Total slices " << timeslices
823 << " Slice " << sliceNum << endmsg;
824 }
825 if (timeslices <= trigCmm) {
826 if (debug) msg() << "Triggered CMM slice from header "
827 << "inconsistent with number of slices: "
828 << trigCmm << ", " << timeslices << endmsg;
830 return;
831 }
832 if (timeslices <= sliceNum) {
833 if (debug) msg() << "Total slices inconsistent with slice number: "
834 << timeslices << ", " << sliceNum << endmsg;
836 return;
837 }
838 // Unpack sub-block
839 if (subBlock->dataWords() && !subBlock->unpack()) {
840 if (debug) {
841 std::string errMsg(subBlock->unpackErrorMsg());
842 msg() << "CMM-Energy sub-block unpacking failed: " << errMsg << endmsg;
843 }
844 ld.rodErr = subBlock->unpackErrorCode();
845 return;
846 }
847
848 // Retrieve required data
849
850 const bool neutralFormat = subBlock->format() == L1CaloSubBlock::NEUTRAL;
851 const int crate = hwCrate - m_crateOffsetHw;
852 const int swCrate = crate + m_crateOffsetSw;
853 const int maxSid = static_cast<int>(CmmEnergySubBlock::MAX_SOURCE_ID);
854 LVL1::DataError derr;
856 const int ssError = derr.error();
857 const int sliceBeg = ( neutralFormat ) ? 0 : sliceNum;
858 const int sliceEnd = ( neutralFormat ) ? timeslices : sliceNum + 1;
859 for (int slice = sliceBeg; slice < sliceEnd; ++slice) {
860
861 // Energy sums
862
863 for (int source = 0; source < maxSid; ++source) {
864 int dataID = source;
865 if (source >= m_modules) {
866 if (summing == CmmSubBlock::CRATE &&
867 source != CmmEnergySubBlock::LOCAL) continue;
868 switch (source) {
870 dataID = LVL1::CMMEtSums::LOCAL;
871 break;
874 break;
876 dataID = LVL1::CMMEtSums::TOTAL;
877 break;
878 default:
879 continue;
880 }
881 }
882 const unsigned int ex = subBlock->ex(slice, source);
883 const unsigned int ey = subBlock->ey(slice, source);
884 const unsigned int et = subBlock->et(slice, source);
885 int exErr = subBlock->exError(slice, source);
886 int eyErr = subBlock->eyError(slice, source);
887 int etErr = subBlock->etError(slice, source);
888 LVL1::DataError exErrBits(ssError);
889 LVL1::DataError eyErrBits(ssError);
890 LVL1::DataError etErrBits(ssError);
891 if (dataID == LVL1::CMMEtSums::LOCAL ||
892 dataID == LVL1::CMMEtSums::REMOTE ||
893 dataID == LVL1::CMMEtSums::TOTAL) {
894 exErrBits.set(LVL1::DataError::Overflow, exErr);
895 exErrBits.set(LVL1::DataError::Parity, exErr >> 1);
896 eyErrBits.set(LVL1::DataError::Overflow, eyErr);
897 eyErrBits.set(LVL1::DataError::Parity, eyErr >> 1);
898 etErrBits.set(LVL1::DataError::Overflow, etErr);
899 etErrBits.set(LVL1::DataError::Parity, etErr >> 1);
900 } else {
901 exErrBits.set(LVL1::DataError::Parity, exErr);
902 eyErrBits.set(LVL1::DataError::Parity, eyErr);
903 etErrBits.set(LVL1::DataError::Parity, etErr);
904 }
905 exErr = exErrBits.error();
906 eyErr = eyErrBits.error();
907 etErr = etErrBits.error();
908 if (ex || ey || et || exErr || eyErr || etErr) {
909 LVL1::CMMEtSums* sums = findCmmSums(data, crate, dataID);
910 if ( ! sums ) { // create new CMM energy sums
911 ld.exVec.assign(timeslices, 0);
912 ld.eyVec.assign(timeslices, 0);
913 ld.etVec.assign(timeslices, 0);
914 ld.exErrVec.assign(timeslices, 0);
915 ld.eyErrVec.assign(timeslices, 0);
916 ld.etErrVec.assign(timeslices, 0);
917 ld.exVec[slice] = ex;
918 ld.eyVec[slice] = ey;
919 ld.etVec[slice] = et;
920 ld.exErrVec[slice] = exErr;
921 ld.eyErrVec[slice] = eyErr;
922 ld.etErrVec[slice] = etErr;
923 auto sumsp =
924 std::make_unique<LVL1::CMMEtSums>(swCrate, dataID, ld.etVec, ld.exVec, ld.eyVec,
925 ld.etErrVec, ld.exErrVec, ld.eyErrVec, trigCmm);
926 const int key = crate * 100 + dataID;
927 data.m_cmmEtMap.insert(std::make_pair(key, sumsp.get()));
928 data.m_cmmEtCollection->push_back(std::move(sumsp));
929 } else {
930 ld.exVec = sums->ExVec();
931 ld.eyVec = sums->EyVec();
932 ld.etVec = sums->EtVec();
933 ld.exErrVec = sums->ExErrorVec();
934 ld.eyErrVec = sums->EyErrorVec();
935 ld.etErrVec = sums->EtErrorVec();
936 const int nsl = ld.exVec.size();
937 if (timeslices != nsl) {
938 if (debug) msg() << "Inconsistent number of slices in sub-blocks"
939 << endmsg;
941 return;
942 }
943 if (ld.exVec[slice] != 0 || ld.eyVec[slice] != 0 || ld.etVec[slice] != 0 ||
944 ld.exErrVec[slice] != 0 || ld.eyErrVec[slice] != 0 ||
945 ld.etErrVec[slice] != 0) {
946 if (debug) msg() << "Duplicate data for slice " << slice << endmsg;
948 return;
949 }
950 ld.exVec[slice] = ex;
951 ld.eyVec[slice] = ey;
952 ld.etVec[slice] = et;
953 ld.exErrVec[slice] = exErr;
954 ld.eyErrVec[slice] = eyErr;
955 ld.etErrVec[slice] = etErr;
956 sums->addEx(ld.exVec, ld.exErrVec);
957 sums->addEy(ld.eyVec, ld.eyErrVec);
958 sums->addEt(ld.etVec, ld.etErrVec);
959 }
960 }
961 }
962
963 // Hit maps - store as Et
964
965 if (summing == CmmSubBlock::SYSTEM) {
966 const unsigned int missEt = subBlock->missingEtHits(slice);
967 if ( missEt || ssError ) {
968 const int dataID = LVL1::CMMEtSums::MISSING_ET_MAP;
969 LVL1::CMMEtSums* map = findCmmSums(data, crate, dataID);
970 if ( ! map ) {
971 ld.etVec.assign(timeslices, 0);
972 ld.etErrVec.assign(timeslices, 0);
973 ld.etVec[slice] = missEt;
974 ld.etErrVec[slice] = ssError;
975 auto mapp =
976 std::make_unique<LVL1::CMMEtSums>(swCrate, dataID,
977 ld.etVec, ld.etVec, ld.etVec,
978 ld.etErrVec, ld.etErrVec, ld.etErrVec, trigCmm);
979 const int key = crate * 100 + dataID;
980 data.m_cmmEtMap.insert(std::make_pair(key, mapp.get()));
981 data.m_cmmEtCollection->push_back(std::move(mapp));
982 } else {
983 ld.etVec = map->EtVec();
984 ld.etErrVec = map->EtErrorVec();
985 const int nsl = ld.etVec.size();
986 if (timeslices != nsl) {
987 if (debug) msg() << "Inconsistent number of slices in sub-blocks"
988 << endmsg;
990 return;
991 }
992 if (ld.etVec[slice] != 0 || ld.etErrVec[slice] != 0) {
993 if (debug) msg() << "Duplicate data for slice " << slice << endmsg;
995 return;
996 }
997 ld.etVec[slice] = missEt;
998 ld.etErrVec[slice] = ssError;
999 map->addEx(ld.etVec, ld.etErrVec);
1000 map->addEy(ld.etVec, ld.etErrVec);
1001 map->addEt(ld.etVec, ld.etErrVec);
1002 }
1003 }
1004 const unsigned int sumEt = subBlock->sumEtHits(slice);
1005 if ( sumEt || ssError ) {
1006 const int dataID = LVL1::CMMEtSums::SUM_ET_MAP;
1007 LVL1::CMMEtSums* map = findCmmSums(data, crate, dataID);
1008 if ( ! map ) {
1009 ld.etVec.assign(timeslices, 0);
1010 ld.etErrVec.assign(timeslices, 0);
1011 ld.etVec[slice] = sumEt;
1012 ld.etErrVec[slice] = ssError;
1013 auto mapp =
1014 std::make_unique<LVL1::CMMEtSums>(swCrate, dataID,
1015 ld.etVec, ld.etVec, ld.etVec,
1016 ld.etErrVec, ld.etErrVec, ld.etErrVec, trigCmm);
1017 const int key = crate * 100 + dataID;
1018 data.m_cmmEtMap.insert(std::make_pair(key, mapp.get()));
1019 data.m_cmmEtCollection->push_back(std::move(mapp));
1020 } else {
1021 ld.etVec = map->EtVec();
1022 ld.etErrVec = map->EtErrorVec();
1023 const int nsl = ld.etVec.size();
1024 if (timeslices != nsl) {
1025 if (debug) msg() << "Inconsistent number of slices in sub-blocks"
1026 << endmsg;
1027 ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
1028 return;
1029 }
1030 if (ld.etVec[slice] != 0 || ld.etErrVec[slice] != 0) {
1031 if (debug) msg() << "Duplicate data for slice " << slice << endmsg;
1033 return;
1034 }
1035 ld.etVec[slice] = sumEt;
1036 ld.etErrVec[slice] = ssError;
1037 map->addEx(ld.etVec, ld.etErrVec);
1038 map->addEy(ld.etVec, ld.etErrVec);
1039 map->addEt(ld.etVec, ld.etErrVec);
1040 }
1041 }
1042 if (subBlock->version() > 1) {
1043 const unsigned int missEtSig = subBlock->missingEtSigHits(slice);
1044 if ( missEtSig || ssError ) {
1045 const int dataID = LVL1::CMMEtSums::MISSING_ET_SIG_MAP;
1046 LVL1::CMMEtSums* map = findCmmSums(data, crate, dataID);
1047 if ( ! map ) {
1048 ld.etVec.assign(timeslices, 0);
1049 ld.etErrVec.assign(timeslices, 0);
1050 ld.etVec[slice] = missEtSig;
1051 ld.etErrVec[slice] = ssError;
1052 auto mapp =
1053 std::make_unique<LVL1::CMMEtSums>(swCrate, dataID,
1054 ld.etVec, ld.etVec, ld.etVec,
1055 ld.etErrVec, ld.etErrVec, ld.etErrVec, trigCmm);
1056 const int key = crate * 100 + dataID;
1057 data.m_cmmEtMap.insert(std::make_pair(key, mapp.get()));
1058 data.m_cmmEtCollection->push_back(std::move(mapp));
1059 } else {
1060 ld.etVec = map->EtVec();
1061 ld.etErrVec = map->EtErrorVec();
1062 const int nsl = ld.etVec.size();
1063 if (timeslices != nsl) {
1064 if (debug) msg() << "Inconsistent number of slices in sub-blocks"
1065 << endmsg;
1066 ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
1067 return;
1068 }
1069 if (ld.etVec[slice] != 0 || ld.etErrVec[slice] != 0) {
1070 if (debug) msg() << "Duplicate data for slice "
1071 << slice << endmsg;
1073 return;
1074 }
1075 ld.etVec[slice] = missEtSig;
1076 ld.etErrVec[slice] = ssError;
1077 map->addEx(ld.etVec, ld.etErrVec);
1078 map->addEy(ld.etVec, ld.etErrVec);
1079 map->addEt(ld.etVec, ld.etErrVec);
1080 }
1081 }
1082 }
1083 }
1084 }
1085
1086 return;
1087}
1088
1089// Unpack CMM-Jet sub-block
1090
1093 LocalData& ld) const
1094{
1095 const bool debug = msgLvl(MSG::DEBUG);
1096 if (debug) msg(MSG::DEBUG);
1097
1098 const int hwCrate = subBlock->crate();
1099 const int module = subBlock->cmmPosition();
1100 const int firmware = subBlock->cmmFirmware();
1101 const int summing = subBlock->cmmSumming();
1102 const int timeslices = subBlock->timeslices();
1103 const int sliceNum = subBlock->slice();
1104 if (debug) {
1105 msg() << "CMM-Jet: Crate " << hwCrate
1106 << " Module " << module
1107 << " Firmware " << firmware
1108 << " Summing " << summing
1109 << " Total slices " << timeslices
1110 << " Slice " << sliceNum << endmsg;
1111 }
1112 if (timeslices <= trigCmm) {
1113 if (debug) msg() << "Triggered CMM slice from header "
1114 << "inconsistent with number of slices: "
1115 << trigCmm << ", " << timeslices << endmsg;
1116 ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
1117 return;
1118 }
1119 if (timeslices <= sliceNum) {
1120 if (debug) msg() << "Total slices inconsistent with slice number: "
1121 << timeslices << ", " << sliceNum << endmsg;
1122 ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
1123 return;
1124 }
1125 // Unpack sub-block
1126 if (subBlock->dataWords() && !subBlock->unpack()) {
1127 if (debug) {
1128 std::string errMsg(subBlock->unpackErrorMsg());
1129 msg() << "CMM-Jet sub-block unpacking failed: " << errMsg << endmsg;
1130 }
1131 ld.rodErr = subBlock->unpackErrorCode();
1132 return;
1133 }
1134
1135 // Retrieve required data
1136
1137 const bool neutralFormat = subBlock->format() == L1CaloSubBlock::NEUTRAL;
1138 const int crate = hwCrate - m_crateOffsetHw;
1139 const int swCrate = crate + m_crateOffsetSw;
1140 const int maxSid = static_cast<int>(CmmJetSubBlock::MAX_SOURCE_ID);
1141 LVL1::DataError derr;
1142 derr.set(LVL1::DataError::SubStatusWord, subBlock->subStatus());
1143 const int ssError = derr.error();
1144 const int sliceBeg = ( neutralFormat ) ? 0 : sliceNum;
1145 const int sliceEnd = ( neutralFormat ) ? timeslices : sliceNum + 1;
1146 for (int slice = sliceBeg; slice < sliceEnd; ++slice) {
1147
1148 // Jet hit counts
1149
1150 for (int source = 0; source < maxSid; ++source) {
1151 int dataID = source;
1152 if (source >= m_modules) {
1153 if (summing == CmmSubBlock::CRATE &&
1154 source != CmmJetSubBlock::LOCAL_MAIN &&
1155 source != CmmJetSubBlock::LOCAL_FORWARD) continue;
1156 // coverity[mixed_enums : FALSE]
1157 // coverity[switch_on_enum : FALSE]
1158 // coverity[first_enum_type : FALSE]
1159 switch (source) {
1162 break;
1165 break;
1168 break;
1171 break;
1174 break;
1177 break;
1178 default:
1179 continue;
1180 }
1181 }
1182 const unsigned int hits = subBlock->jetHits(slice, source);
1183 LVL1::DataError errBits(ssError);
1185 subBlock->jetHitsError(slice, source));
1186 const int err = errBits.error();
1187 if (hits || err) {
1188 LVL1::CMMJetHits* jh = findCmmHits(data, crate, dataID);
1189 if ( ! jh ) { // create new CMM hits
1190 ld.hitsVec.assign(timeslices, 0);
1191 ld.errVec.assign(timeslices, 0);
1192 ld.hitsVec[slice] = hits;
1193 ld.errVec[slice] = err;
1194 auto jhp =
1195 std::make_unique<LVL1::CMMJetHits>(swCrate, dataID, ld.hitsVec, ld.errVec, trigCmm);
1196 const int key = crate * 100 + dataID;
1197 data.m_cmmHitsMap.insert(std::make_pair(key, jhp.get()));
1198 data.m_cmmHitCollection->push_back(std::move(jhp));
1199 } else {
1200 ld.hitsVec = jh->HitsVec();
1201 ld.errVec = jh->ErrorVec();
1202 const int nsl = ld.hitsVec.size();
1203 if (timeslices != nsl) {
1204 if (debug) msg() << "Inconsistent number of slices in sub-blocks"
1205 << endmsg;
1206 ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
1207 return;
1208 }
1209 if (ld.hitsVec[slice] != 0 || ld.errVec[slice] != 0) {
1210 if (debug) msg() << "Duplicate data for slice " << slice << endmsg;
1212 return;
1213 }
1214 ld.hitsVec[slice] = hits;
1215 ld.errVec[slice] = err;
1216 jh->addHits(ld.hitsVec, ld.errVec);
1217 }
1218 }
1219 }
1220
1221 // Hit map - store as hits
1222
1223 if (summing == CmmSubBlock::SYSTEM) {
1224 const unsigned int etMap = subBlock->jetEtMap(slice);
1225 if ( etMap || ssError ) {
1226 const int dataID = LVL1::CMMJetHits::ET_MAP;
1227 LVL1::CMMJetHits* map = findCmmHits(data, crate, dataID);
1228 if ( ! map ) {
1229 ld.hitsVec.assign(timeslices, 0);
1230 ld.errVec.assign(timeslices, 0);
1231 ld.hitsVec[slice] = etMap;
1232 ld.errVec[slice] = ssError;
1233 auto mapp =
1234 std::make_unique<LVL1::CMMJetHits>(swCrate, dataID, ld.hitsVec, ld.errVec, trigCmm);
1235 const int key = crate * 100 + dataID;
1236 data.m_cmmHitsMap.insert(std::make_pair(key, mapp.get()));
1237 data.m_cmmHitCollection->push_back(std::move(mapp));
1238 } else {
1239 ld.hitsVec = map->HitsVec();
1240 ld.errVec = map->ErrorVec();
1241 const int nsl = ld.hitsVec.size();
1242 if (timeslices != nsl) {
1243 if (debug) msg() << "Inconsistent number of slices in sub-blocks"
1244 << endmsg;
1245 ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
1246 return;
1247 }
1248 if (ld.hitsVec[slice] != 0 || ld.errVec[slice] != 0) {
1249 if (debug) msg() << "Duplicate data for slice " << slice << endmsg;
1251 return;
1252 }
1253 ld.hitsVec[slice] = etMap;
1254 ld.errVec[slice] = ssError;
1255 map->addHits(ld.hitsVec, ld.errVec);
1256 }
1257 }
1258 }
1259 }
1260
1261 return;
1262}
1263
1264// Unpack JEM sub-block
1265
1268 LocalData& ld) const
1269{
1270 const bool debug = msgLvl(MSG::DEBUG);
1271 const bool verbose = msgLvl(MSG::VERBOSE);
1272 if (debug) msg(MSG::DEBUG);
1273
1274 const int hwCrate = subBlock->crate();
1275 const int module = subBlock->module();
1276 const int timeslices = subBlock->timeslices();
1277 const int sliceNum = subBlock->slice();
1278 if (debug) {
1279 msg() << "JEM: Crate " << hwCrate
1280 << " Module " << module
1281 << " Total slices " << timeslices
1282 << " Slice " << sliceNum << endmsg;
1283 }
1284 if (timeslices <= trigJem) {
1285 if (debug) msg() << "Triggered JEM slice from header "
1286 << "inconsistent with number of slices: "
1287 << trigJem << ", " << timeslices << endmsg;
1288 ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
1289 return;
1290 }
1291 if (timeslices <= sliceNum) {
1292 if (debug) msg() << "Total slices inconsistent with slice number: "
1293 << timeslices << ", " << sliceNum << endmsg;
1294 ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
1295 return;
1296 }
1297 // Unpack sub-block
1298 if (subBlock->dataWords() && !subBlock->unpack()) {
1299 if (debug) {
1300 std::string errMsg(subBlock->unpackErrorMsg());
1301 msg() << "JEM sub-block unpacking failed: " << errMsg << endmsg;
1302 }
1303 ld.rodErr = subBlock->unpackErrorCode();
1304 return;
1305 }
1306
1307 // Retrieve required data
1308
1309 const bool neutralFormat = subBlock->format() == L1CaloSubBlock::NEUTRAL;
1310 const int crate = hwCrate - m_crateOffsetHw;
1311 const int swCrate = crate + m_crateOffsetSw;
1312 LVL1::DataError derr;
1313 derr.set(LVL1::DataError::SubStatusWord, subBlock->subStatus());
1314 const int ssError = derr.error();
1315 std::vector<int> dummy(timeslices);
1316 const int sliceBeg = ( neutralFormat ) ? 0 : sliceNum;
1317 const int sliceEnd = ( neutralFormat ) ? timeslices : sliceNum + 1;
1318 for (int slice = sliceBeg; slice < sliceEnd; ++slice) {
1319
1320 if (data.m_collection == JET_ELEMENTS) {
1321 JetElementData& jedata = static_cast<JetElementData&>(data);
1322
1323 // Loop over jet element channels and fill jet elements
1324
1325 for (int chan = 0; chan < m_channels; ++chan) {
1326 const JemJetElement jetEle(subBlock->jetElement(slice, chan));
1327 if (jetEle.data() || ssError) {
1328 double eta = 0.;
1329 double phi = 0.;
1330 int layer = 0;
1331 if (m_jemMaps->mapping(crate, module, chan, eta, phi, layer)) {
1332 if (layer == ld.coreOverlap) {
1333 LVL1::JetElement* je = findJetElement(jedata, eta, phi, ld.elementKey);
1334 if ( ! je ) { // create new jet element
1335 const unsigned int key = ld.elementKey.jeKey(phi, eta);
1336 auto jep =
1337 std::make_unique<LVL1::JetElement>(phi, eta, dummy, dummy, key,
1338 dummy, dummy, dummy, trigJem);
1339 je = jep.get();
1340 jedata.m_jeMap.insert(std::make_pair(key, jep.get()));
1341 jedata.m_jeCollection->push_back(std::move(jep));
1342 } else {
1343 const std::vector<int>& emEnergy(je->emEnergyVec());
1344 const std::vector<int>& hadEnergy(je->hadEnergyVec());
1345 const std::vector<int>& emError(je->emErrorVec());
1346 const std::vector<int>& hadError(je->hadErrorVec());
1347 const int nsl = emEnergy.size();
1348 if (timeslices != nsl) {
1349 if (debug) {
1350 msg() << "Inconsistent number of slices in sub-blocks"
1351 << endmsg;
1352 }
1353 ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
1354 return;
1355 }
1356 if (emEnergy[slice] != 0 || hadEnergy[slice] != 0 ||
1357 emError[slice] != 0 || hadError[slice] != 0) {
1358 if (debug) msg() << "Duplicate data for slice "
1359 << slice << endmsg;
1361 return;
1362 }
1363 }
1364 LVL1::DataError emErrBits(ssError);
1365 LVL1::DataError hadErrBits(ssError);
1366 const int linkError = jetEle.linkError();
1367 emErrBits.set(LVL1::DataError::Parity, jetEle.emParity());
1368 emErrBits.set(LVL1::DataError::LinkDown, linkError);
1369 hadErrBits.set(LVL1::DataError::Parity, jetEle.hadParity());
1370 hadErrBits.set(LVL1::DataError::LinkDown, linkError >> 1);
1371 je->addSlice(slice, jetEle.emData(), jetEle.hadData(),
1372 emErrBits.error(), hadErrBits.error(),
1373 linkError);
1374 }
1375 } else if (verbose && jetEle.data()) {
1376 msg(MSG::VERBOSE) << "Non-zero data but no channel mapping for channel "
1377 << chan << endmsg;
1378 msg(MSG::DEBUG);
1379 }
1380 } else if (verbose) {
1381 msg(MSG::VERBOSE) << "No jet element data for channel "
1382 << chan << " slice " << slice << endmsg;
1383 msg(MSG::DEBUG);
1384 }
1385 }
1386 } else if (data.m_collection == JET_HITS) {
1387 JetHitsData& jhdata = static_cast<JetHitsData&>(data);
1388
1389 // Get jet hits
1390
1391 const unsigned int hits = subBlock->jetHits(slice);
1392 if (hits) {
1393 LVL1::JEMHits* jh = findJetHits(jhdata, crate, module);
1394 if ( ! jh ) { // create new jet hits
1395 ld.hitsVec.assign(timeslices, 0);
1396 ld.hitsVec[slice] = hits;
1397 auto jhp =
1398 std::make_unique<LVL1::JEMHits>(swCrate, module, ld.hitsVec, trigJem);
1399 jhdata.m_hitsMap.insert(std::make_pair(crate * m_modules + module, jhp.get()));
1400 jhdata.m_hitCollection->push_back(std::move(jhp));
1401 } else {
1402 ld.hitsVec = jh->JetHitsVec();
1403 const int nsl = ld.hitsVec.size();
1404 if (timeslices != nsl) {
1405 if (debug) {
1406 msg() << "Inconsistent number of slices in sub-blocks"
1407 << endmsg;
1408 }
1409 ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
1410 return;
1411 }
1412 if (ld.hitsVec[slice] != 0) {
1413 if (debug) msg() << "Duplicate data for slice "
1414 << slice << endmsg;
1416 return;
1417 }
1418 ld.hitsVec[slice] = hits;
1419 jh->addJetHits(ld.hitsVec);
1420 }
1421 } else if (verbose) {
1422 msg(MSG::VERBOSE) << "No jet hits data for crate/module/slice "
1423 << hwCrate << "/" << module << "/" << slice
1424 << endmsg;
1425 msg(MSG::DEBUG);
1426 }
1427 } else if (data.m_collection == ENERGY_SUMS) {
1428 EnergySumsData& sumdata = static_cast<EnergySumsData&>(data);
1429
1430 // Get energy subsums
1431
1432 const unsigned int ex = subBlock->ex(slice);
1433 const unsigned int ey = subBlock->ey(slice);
1434 const unsigned int et = subBlock->et(slice);
1435 if (ex | ey | et) {
1436 LVL1::JEMEtSums* sums = findEnergySums(sumdata, crate, module);
1437 if ( ! sums ) { // create new energy sums
1438 ld.exVec.assign(timeslices, 0);
1439 ld.eyVec.assign(timeslices, 0);
1440 ld.etVec.assign(timeslices, 0);
1441 ld.exVec[slice] = ex;
1442 ld.eyVec[slice] = ey;
1443 ld.etVec[slice] = et;
1444 auto sumsp =
1445 std::make_unique<LVL1::JEMEtSums>(swCrate, module, ld.etVec, ld.exVec, ld.eyVec,
1446 trigJem);
1447 sumdata.m_etMap.insert(std::make_pair(crate * m_modules + module, sumsp.get()));
1448 sumdata.m_etCollection->push_back(std::move(sumsp));
1449 } else {
1450 ld.exVec = sums->ExVec();
1451 ld.eyVec = sums->EyVec();
1452 ld.etVec = sums->EtVec();
1453 const int nsl = ld.exVec.size();
1454 if (timeslices != nsl) {
1455 if (debug) {
1456 msg() << "Inconsistent number of slices in sub-blocks"
1457 << endmsg;
1458 }
1459 ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
1460 return;
1461 }
1462 if (ld.exVec[slice] != 0 || ld.eyVec[slice] != 0 || ld.etVec[slice] != 0) {
1463 if (debug) msg() << "Duplicate data for slice "
1464 << slice << endmsg;
1466 return;
1467 }
1468 ld.exVec[slice] = ex;
1469 ld.eyVec[slice] = ey;
1470 ld.etVec[slice] = et;
1471 sums->addEx(ld.exVec);
1472 sums->addEy(ld.eyVec);
1473 sums->addEt(ld.etVec);
1474 }
1475 } else if (verbose) {
1476 msg(MSG::VERBOSE) << "No energy sums data for crate/module/slice "
1477 << hwCrate << "/" << module << "/" << slice
1478 << endmsg;
1479 msg(MSG::DEBUG);
1480 }
1481 }
1482 }
1483 return;
1484}
1485
1486// Find a jet element given eta, phi
1487
1488const
1490 const double phi,
1491 const ConstJetElementMap& jeMap,
1492 LVL1::JetElementKey& elementKey) const
1493{
1494 const unsigned int key = elementKey.jeKey(phi, eta);
1495 ConstJetElementMap::const_iterator mapIter = jeMap.find(key);
1496 if (mapIter != jeMap.end()) return mapIter->second;
1497 return nullptr;
1498}
1499
1501 const double eta,
1502 const double phi,
1503 LVL1::JetElementKey& elementKey) const
1504{
1505 const unsigned int key = elementKey.jeKey(phi, eta);
1506 JetElementMap::const_iterator mapIter = data.m_jeMap.find(key);
1507 if (mapIter != data.m_jeMap.end()) return mapIter->second;
1508 return nullptr;
1509}
1510
1511// Find jet hits for given crate, module
1512
1513const
1515 const int module,
1516 const ConstJetHitsMap& hitsMap) const
1517{
1518 ConstJetHitsMap::const_iterator mapIter = hitsMap.find(crate * m_modules + module);
1519 if (mapIter != hitsMap.end()) return mapIter->second;
1520 return nullptr;
1521}
1522
1524 const int crate,
1525 const int module) const
1526{
1527 JetHitsMap::const_iterator mapIter = data.m_hitsMap.find(crate * m_modules + module);
1528 if (mapIter != data.m_hitsMap.end()) return mapIter->second;
1529 return nullptr;
1530}
1531
1532// Find energy sums for given crate, module
1533
1534const
1536 const int module,
1537 const ConstEnergySumsMap& etMap) const
1538{
1539 ConstEnergySumsMap::const_iterator mapIter = etMap.find(crate * m_modules + module);
1540 if (mapIter != etMap.end()) return mapIter->second;
1541 return nullptr;
1542}
1543
1545 const int crate,
1546 const int module) const
1547{
1548 EnergySumsMap::const_iterator mapIter = data.m_etMap.find(crate * m_modules + module);
1549 if (mapIter != data.m_etMap.end()) return mapIter->second;
1550 return nullptr;
1551}
1552
1553// Find CMM hits for given crate, dataID
1554
1555const
1557 const int dataID,
1558 const ConstCmmHitsMap& cmmHitsMap) const
1559{
1560 ConstCmmHitsMap::const_iterator mapIter = cmmHitsMap.find(crate * 100 + dataID);
1561 if (mapIter != cmmHitsMap.end()) return mapIter->second;
1562 return nullptr;
1563}
1564
1566 const int crate,
1567 const int dataID) const
1568{
1569 CmmHitsMap::const_iterator mapIter = data.m_cmmHitsMap.find(crate * 100 + dataID);
1570 if (mapIter != data.m_cmmHitsMap.end()) return mapIter->second;
1571 return nullptr;
1572}
1573
1574// Find CMM energy sums for given crate, module, dataID
1575
1576const
1578 const int dataID,
1579 const ConstCmmSumsMap& cmmEtMap) const
1580{
1581 ConstCmmSumsMap::const_iterator mapIter = cmmEtMap.find(crate * 100 + dataID);
1582 if (mapIter != cmmEtMap.end()) return mapIter->second;
1583 return nullptr;
1584}
1585
1587 const int crate,
1588 const int dataID) const
1589{
1590 CmmSumsMap::const_iterator mapIter = data.m_cmmEtMap.find(crate * 100 + dataID);
1591 if (mapIter != data.m_cmmEtMap.end()) return mapIter->second;
1592 return nullptr;
1593}
1594
1595// Set up jet element map
1596
1598 const jeCollection,
1599 ConstJetElementMap& jeMap,
1600 LVL1::JetElementKey& elementKey) const
1601{
1602 jeMap.clear();
1603 if (jeCollection) {
1604 JetElementCollection::const_iterator pos = jeCollection->begin();
1605 JetElementCollection::const_iterator pose = jeCollection->end();
1606 for (; pos != pose; ++pos) {
1607 const LVL1::JetElement* je = *pos;
1608 const unsigned int key = elementKey.jeKey(je->phi(), je->eta());
1609 jeMap.insert(std::make_pair(key, je));
1610 }
1611 }
1612}
1613
1614
1615// Set up jet hits map
1616
1618 const hitCollection,
1619 ConstJetHitsMap& hitsMap) const
1620{
1621 hitsMap.clear();
1622 if (hitCollection) {
1623 JetHitsCollection::const_iterator pos = hitCollection->begin();
1624 JetHitsCollection::const_iterator pose = hitCollection->end();
1625 for (; pos != pose; ++pos) {
1626 const LVL1::JEMHits* const hits = *pos;
1627 const int crate = hits->crate() - m_crateOffsetSw;
1628 const int key = m_modules * crate + hits->module();
1629 hitsMap.insert(std::make_pair(key, hits));
1630 }
1631 }
1632}
1633
1634// Set up energy sums map
1635
1637 const etCollection,
1638 ConstEnergySumsMap& etMap) const
1639{
1640 etMap.clear();
1641 if (etCollection) {
1642 EnergySumsCollection::const_iterator pos = etCollection->begin();
1643 EnergySumsCollection::const_iterator pose = etCollection->end();
1644 for (; pos != pose; ++pos) {
1645 const LVL1::JEMEtSums* const sums = *pos;
1646 const int crate = sums->crate() - m_crateOffsetSw;
1647 const int key = m_modules * crate + sums->module();
1648 etMap.insert(std::make_pair(key, sums));
1649 }
1650 }
1651}
1652
1653// Set up CMM hits map
1654
1656 const hitCollection,
1657 ConstCmmHitsMap& cmmHitsMap) const
1658{
1659 cmmHitsMap.clear();
1660 if (hitCollection) {
1661 CmmHitsCollection::const_iterator pos = hitCollection->begin();
1662 CmmHitsCollection::const_iterator pose = hitCollection->end();
1663 for (; pos != pose; ++pos) {
1664 const LVL1::CMMJetHits* const hits = *pos;
1665 const int crate = hits->crate() - m_crateOffsetSw;
1666 const int key = crate * 100 + hits->dataID();
1667 cmmHitsMap.insert(std::make_pair(key, hits));
1668 }
1669 }
1670}
1671
1672// Set up CMM energy sums map
1673
1675 const etCollection,
1676 ConstCmmSumsMap& cmmEtMap) const
1677{
1678 cmmEtMap.clear();
1679 if (etCollection) {
1680 CmmSumsCollection::const_iterator pos = etCollection->begin();
1681 CmmSumsCollection::const_iterator pose = etCollection->end();
1682 for (; pos != pose; ++pos) {
1683 const LVL1::CMMEtSums* const sums = *pos;
1684 const int crate = sums->crate() - m_crateOffsetSw;
1685 const int key = crate * 100 + sums->dataID();
1686 cmmEtMap.insert(std::make_pair(key, sums));
1687 }
1688 }
1689}
1690
1691// Get number of slices and triggered slice offset for next slink
1692
1693bool JepByteStreamV1Tool::slinkSlices(const int crate, const int module,
1694 const int modulesPerSlink,
1695 int& timeslices,
1696 int& trigJem,
1697 const ConstJetElementMap& jeMap,
1698 const ConstJetHitsMap& hitsMap,
1699 const ConstEnergySumsMap& etMap,
1700 const ConstCmmHitsMap& cmmHitsMap,
1701 const ConstCmmSumsMap& cmmEtMap,
1702 LVL1::JetElementKey& elementKey) const
1703{
1704 int slices = -1;
1705 int trigJ = m_dfltSlices / 2;
1706 for (int mod = module; mod < module + modulesPerSlink; ++mod) {
1707 for (int chan = 0; chan < m_channels; ++chan) {
1708 double eta = 0.;
1709 double phi = 0.;
1710 int layer = 0;
1711 if ( !m_jemMaps->mapping(crate, mod, chan, eta, phi, layer)) continue;
1712 const LVL1::JetElement* const je = findJetElement(eta, phi, jeMap, elementKey);
1713 if ( !je ) continue;
1714 const int numdat = 5;
1715 std::vector<int> sums(numdat);
1716 std::vector<int> sizes(numdat);
1717 sums[0] = std::accumulate((je->emEnergyVec()).begin(),
1718 (je->emEnergyVec()).end(), 0);
1719 sums[1] = std::accumulate((je->hadEnergyVec()).begin(),
1720 (je->hadEnergyVec()).end(), 0);
1721 sums[2] = std::accumulate((je->emErrorVec()).begin(),
1722 (je->emErrorVec()).end(), 0);
1723 sums[3] = std::accumulate((je->hadErrorVec()).begin(),
1724 (je->hadErrorVec()).end(), 0);
1725 sums[4] = std::accumulate((je->linkErrorVec()).begin(),
1726 (je->linkErrorVec()).end(), 0);
1727 sizes[0] = (je->emEnergyVec()).size();
1728 sizes[1] = (je->hadEnergyVec()).size();
1729 sizes[2] = (je->emErrorVec()).size();
1730 sizes[3] = (je->hadErrorVec()).size();
1731 sizes[4] = (je->linkErrorVec()).size();
1732 const int peak = je->peak();
1733 for (int i = 0; i < numdat; ++i) {
1734 if (sums[i] == 0) continue;
1735 if (slices < 0) {
1736 slices = sizes[i];
1737 trigJ = peak;
1738 } else if (slices != sizes[i] || trigJ != peak) return false;
1739 }
1740 }
1741 const LVL1::JEMHits* const hits = findJetHits(crate, mod, hitsMap);
1742 if (hits) {
1743 const unsigned int sum = std::accumulate((hits->JetHitsVec()).begin(),
1744 (hits->JetHitsVec()).end(), 0);
1745 if (sum) {
1746 const int size = (hits->JetHitsVec()).size();
1747 const int peak = hits->peak();
1748 if (slices < 0) {
1749 slices = size;
1750 trigJ = peak;
1751 } else if (slices != size || trigJ != peak) return false;
1752 }
1753 }
1754 const LVL1::JEMEtSums* const et = findEnergySums(crate, mod, etMap);
1755 if (et) {
1756 const int numdat = 3;
1757 std::vector<unsigned int> sums(numdat);
1758 std::vector<int> sizes(numdat);
1759 sums[0] = std::accumulate((et->ExVec()).begin(),
1760 (et->ExVec()).end(), 0);
1761 sums[1] = std::accumulate((et->EyVec()).begin(),
1762 (et->EyVec()).end(), 0);
1763 sums[2] = std::accumulate((et->EtVec()).begin(),
1764 (et->EtVec()).end(), 0);
1765 sizes[0] = (et->ExVec()).size();
1766 sizes[1] = (et->EyVec()).size();
1767 sizes[2] = (et->EtVec()).size();
1768 const int peak = et->peak();
1769 for (int i = 0; i < numdat; ++i) {
1770 if (sums[i] == 0) continue;
1771 if (slices < 0) {
1772 slices = sizes[i];
1773 trigJ = peak;
1774 } else if (slices != sizes[i] || trigJ != peak) return false;
1775 }
1776 }
1777 }
1778 // CMM last slink of crate
1779 if (module / modulesPerSlink == m_slinks - 1) {
1780 const int maxDataID1 = LVL1::CMMJetHits::MAXID;
1781 const int maxDataID2 = LVL1::CMMEtSums::MAXID;
1782 const int maxDataID = (maxDataID1 > maxDataID2) ? maxDataID1 : maxDataID2;
1783 for (int dataID = 0; dataID < maxDataID; ++dataID) {
1784 const int numdat = 6;
1785 std::vector<unsigned int> sums(numdat);
1786 std::vector<int> sizes(numdat);
1787 const LVL1::CMMJetHits* hits = 0;
1788 if (dataID < maxDataID1) hits = findCmmHits(crate, dataID, cmmHitsMap);
1789 if (hits) {
1790 sums[0] = std::accumulate((hits->HitsVec()).begin(),
1791 (hits->HitsVec()).end(), 0);
1792 sums[1] = std::accumulate((hits->ErrorVec()).begin(),
1793 (hits->ErrorVec()).end(), 0);
1794 sizes[0] = (hits->HitsVec()).size();
1795 sizes[1] = (hits->ErrorVec()).size();
1796 const int peak = hits->peak();
1797 for (int i = 0; i < 2; ++i) {
1798 if (sums[i] == 0) continue;
1799 if (slices < 0) {
1800 slices = sizes[i];
1801 trigJ = peak;
1802 } else if (slices != sizes[i] || trigJ != peak) return false;
1803 }
1804 }
1805 const LVL1::CMMEtSums* et = 0;
1806 if (dataID < maxDataID2) et = findCmmSums(crate, dataID, cmmEtMap);
1807 if (et) {
1808 sums[0] = std::accumulate((et->ExVec()).begin(),
1809 (et->ExVec()).end(), 0);
1810 sums[1] = std::accumulate((et->EyVec()).begin(),
1811 (et->EyVec()).end(), 0);
1812 sums[2] = std::accumulate((et->EtVec()).begin(),
1813 (et->EtVec()).end(), 0);
1814 sums[3] = std::accumulate((et->ExErrorVec()).begin(),
1815 (et->ExErrorVec()).end(), 0);
1816 sums[4] = std::accumulate((et->EyErrorVec()).begin(),
1817 (et->EyErrorVec()).end(), 0);
1818 sums[5] = std::accumulate((et->EtErrorVec()).begin(),
1819 (et->EtErrorVec()).end(), 0);
1820 sizes[0] = (et->ExVec()).size();
1821 sizes[1] = (et->EyVec()).size();
1822 sizes[2] = (et->EtVec()).size();
1823 sizes[3] = (et->ExErrorVec()).size();
1824 sizes[4] = (et->EyErrorVec()).size();
1825 sizes[5] = (et->EtErrorVec()).size();
1826 const int peak = et->peak();
1827 for (int i = 0; i < numdat; ++i) {
1828 if (sums[i] == 0) continue;
1829 if (slices < 0) {
1830 slices = sizes[i];
1831 trigJ = peak;
1832 } else if (slices != sizes[i] || trigJ != peak) return false;
1833 }
1834 }
1835 }
1836 }
1837 if (slices < 0) slices = m_dfltSlices;
1838 timeslices = slices;
1839 trigJem = trigJ;
1840 return true;
1841}
1842
1843} // end namespace
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
std::vector< size_t > vec
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
const bool debug
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
Derived DataVector<T>.
Definition DataVector.h:795
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
value_type push_back(value_type pElem)
Add an element to the end of the collection.
DataModel_detail::iterator< DataVector > iterator
Standard iterator.
Definition DataVector.h:842
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
Template class for assembling a full atlas raw event from subfragments.
void setRodMinorVersion(uint16_t m)
change the ROD minor version
std::vector< uint32_t > RODDATA
ROD data as a vector of unsigned int.
RODDATA * getRodData(uint32_t id)
get a block of ROD data
std::vector< const ROBF * > VROBFRAG
Sub-Block class for CMM-Energy data.
int exError(int slice, int source) const
Return Ex subsum error for given JEM or source ID.
void setMissingEtSigHits(int slice, unsigned int map)
Store Missing-ET-Sig Hits map.
unsigned int ey(int slice, int source) const
Return Ey subsum for given JEM or source ID.
unsigned int et(int slice, int source) const
Return Et subsum for given JEM or source ID.
void setSumEtHits(int slice, unsigned int map)
Store Sum-Et Hits map.
void clear()
Clear all data.
unsigned int sumEtHits(int slice) const
Return Sum-Et Hits map.
int eyError(int slice, int source) const
Return Ey subsum error for given JEM or source ID.
unsigned int missingEtSigHits(int slice) const
Return Missing-ET-Sig Hits map.
void setSubsums(int slice, int source, unsigned int ex, unsigned int ey, unsigned int et, int exError, int eyError, int etError)
Store energy subsums and errors for given JEM or source ID.
unsigned int missingEtHits(int slice) const
Return Missing-ET Hits map.
int etError(int slice, int source) const
Return Et subsum error for given JEM or source ID.
void setMissingEtHits(int slice, unsigned int map)
Store Missing-ET Hits map.
unsigned int ex(int slice, int source) const
Return Ex subsum for given JEM or source ID.
Sub-Block class for CMM-Jet data.
unsigned int jetHits(int slice, int source) const
Return jet hit counts for given jem or source ID.
int jetHitsError(int slice, int source) const
Return jet hit error for given jem or source ID.
void setJetHits(int slice, int source, unsigned int hits, int error)
Store jet hit counts and error for given jem or source ID.
void setJetEtMap(int slice, unsigned int map)
Store jet ET map.
unsigned int jetEtMap(int slice) const
Return jet ET map.
void clear()
Clear all data.
bool unpack()
Unpack data.
static bool cmmBlock(uint32_t word)
Determine if header word corresponds to CMM.
int timeslices() const
int cmmPosition() const
Definition CmmSubBlock.h:73
void setCmmHeader(int version, int format, int slice, int crate, int summing, int firmware, int position, int timeslices)
Store CMM header.
int cmmFirmware() const
Definition CmmSubBlock.h:68
static CmmFirmwareCode cmmType(uint32_t word)
CMM differentiation (CMM_CP, CMM_JET, or CMM_ENERGY)
int cmmSumming() const
Definition CmmSubBlock.h:63
JEM jet element dataword class.
uint32_t data() const
Sub-Block class for JEM data pre-LS1.
int timeslices() const
Return number of timeslices.
void clear()
Clear all data.
void fillJetElement(int slice, const JemJetElement &jetEle)
Store jet element data.
bool pack()
Pack data.
void setJemHeader(int version, int format, int slice, int crate, int module, int timeslices)
Store JEM header.
unsigned int et(int slice) const
Return energy subsum Et.
unsigned int jetHits(int slice) const
Return jet hit counts.
JemJetElement jetElement(int slice, int channel) const
Return jet element for given channel.
unsigned int ex(int slice) const
Return energy subsum Ex.
bool unpack()
Unpack data.
void setJetHits(int slice, unsigned int hits)
Store jet hit counts.
void setEnergySubsums(int slice, unsigned int ex, unsigned int ey, unsigned int et)
Store energy subsum data.
unsigned int ey(int slice) const
Return energy subsum Ey.
const std::vector< uint32_t > & sourceIDs() const
Return reference to vector with all possible Source Identifiers.
const LVL1::CMMEtSums * findCmmSums(int crate, int dataID, const ConstCmmSumsMap &cmmEtMap) const
Find CMM energy sums for given crate, data ID.
const int m_modules
Number of JEM modules per crate.
ServiceHandle< IByteStreamCnvSvc > m_byteStreamCnvSvc
void setupCmmHitsMap(const CmmHitsCollection *hitCollection, ConstCmmHitsMap &cmmHitsMap) const
Set up CMM hits map.
DataVector< LVL1::JetElement > JetElementCollection
OFFLINE_FRAGMENTS_NAMESPACE::PointerType RODPointer
int m_slinks
Property: Number of slinks per crate when writing out bytestream.
int m_crateMax
Property: Maximum crate number when writing out bytestream.
const int m_crates
Number of crates.
const L1CaloSrcIdMap m_srcIdMap
Source ID converter.
virtual StatusCode finalize() override
DataVector< LVL1::CMMJetHits > CmmHitsCollection
void setupHitsMap(const JetHitsCollection *hitCollection, ConstJetHitsMap &hitsMap) const
Set up jet hits map.
void decodeCmmJet(CmmJetSubBlock *subBlock, int trigCmm, CmmHitsData &data, LocalData &ld) const
Unpack CMM-Jet sub-block.
void decodeJem(JemSubBlockV1 *subBlock, int trigJem, JepByteStreamToolData &data, LocalData &ld) const
Unpack JEM sub-block.
int m_crateOffsetSw
Property: Software crate number offset.
const LVL1::JEMEtSums * findEnergySums(int crate, int module, const ConstEnergySumsMap &etMap) const
Find energy sums for given crate, module.
const LVL1::CMMJetHits * findCmmHits(int crate, int dataID, const ConstCmmHitsMap &cmmHitsMap) const
Find CMM hits for given crate, data ID.
const int m_channels
Number of channels per module.
std::map< int, const LVL1::JEMEtSums * > ConstEnergySumsMap
DataVector< LVL1::JEMHits > JetHitsCollection
int m_version
Property: Sub_block header version.
int m_dataFormat
Property: Data compression format.
std::map< int, const LVL1::JEMHits * > ConstJetHitsMap
bool slinkSlices(int crate, int module, int modulesPerSlink, int &timeslices, int &trigJem, const ConstJetElementMap &jeMap, const ConstJetHitsMap &hitsMap, const ConstEnergySumsMap &etMap, const ConstCmmHitsMap &cmmHitsMap, const ConstCmmSumsMap &cmmEtMap, LVL1::JetElementKey &elementKey) const
Get number of slices and triggered slice offset for next slink.
StatusCode convert(const std::string &sgKey, const IROBDataProviderSvc::VROBFRAG &robFrags, DataVector< LVL1::JetElement > *jeCollection) const
Convert ROB fragments to jet elements.
DataVector< LVL1::CMMEtSums > CmmSumsCollection
OFFLINE_FRAGMENTS_NAMESPACE::PointerType ROBPointer
DataVector< LVL1::JEMEtSums > EnergySumsCollection
void decodeCmmEnergy(CmmEnergySubBlock *subBlock, int trigCmm, CmmSumsData &data, LocalData &ld) const
Unpack CMM-Energy sub-block.
std::map< int, const LVL1::CMMJetHits * > ConstCmmHitsMap
StatusCode convertBs(const std::string &sgKey, const IROBDataProviderSvc::VROBFRAG &robFrags, JepByteStreamToolData &data) const
Convert bytestream to given container type.
void setupJeMap(const JetElementCollection *jeCollection, ConstJetElementMap &jeMap, LVL1::JetElementKey &elementKey) const
Set up jet element map.
const LVL1::JEMHits * findJetHits(int crate, int module, const ConstJetHitsMap &hitsMap) const
Find jet hits for given crate, module.
void setupEtMap(const EnergySumsCollection *enCollection, ConstEnergySumsMap &etMap) const
Set up energy sums map.
std::vector< uint32_t > makeSourceIDs() const
int m_forceSlices
Property: Force number of slices in bytestream.
int m_crateOffsetHw
Property: Hardware crate number offset.
std::vector< uint32_t > m_sourceIDsProp
Property: ROB source IDs.
void setupCmmEtMap(const CmmSumsCollection *enCollection, ConstCmmSumsMap &cmmEtMap) const
Set up CMM energy sums map.
JepByteStreamV1Tool(const std::string &type, const std::string &name, const IInterface *parent)
const LVL1::JetElement * findJetElement(double eta, double phi, const ConstJetElementMap &jeMap, LVL1::JetElementKey &elementKey) const
Find a jet element given eta, phi.
const eformat::SubDetector m_subDetector
Sub-detector type.
std::map< int, const LVL1::CMMEtSums * > ConstCmmSumsMap
virtual StatusCode initialize() override
ToolHandle< LVL1::IL1CaloMappingTool > m_jemMaps
Property: Channel mapping tool.
static const InterfaceID & interfaceID()
AlgTool InterfaceID.
int m_crateMin
Property: Minimum crate number when writing out bytestream.
int m_dfltSlices
Property: Default number of slices in simulation.
ToolHandle< LVL1BS::L1CaloErrorByteStreamTool > m_errorTool
Property: Error collection tool.
std::map< unsigned int, const LVL1::JetElement * > ConstJetElementMap
IROBDataProviderSvc::VROBFRAG::const_iterator ROBIterator
int unpackErrorCode() const
Return the unpacking error code.
uint32_t subStatus() const
Return Sub-status word.
int dataWords() const
Return number of data words.
static SubBlockWordType wordType(uint32_t word)
Word identification.
void write(FullEventAssembler< L1CaloSrcIdMap >::RODDATA *theROD) const
Output complete packed sub-block to ROD vector.
std::string unpackErrorMsg() const
Return the unpacking error message for printing.
OFFLINE_FRAGMENTS_NAMESPACE::PointerType read(const OFFLINE_FRAGMENTS_NAMESPACE::PointerType beg, const OFFLINE_FRAGMENTS_NAMESPACE::PointerType end)
Input complete packed sub-block from ROD array.
L1Calo User Header class.
static bool isValid(uint32_t word)
Test for valid header word.
void setVersion(int minorVersion)
Set version flag.
int words() const
Return number of header words (should be one)
uint32_t header() const
Return packed header.
static void data(const std::vector< int > &oldVec, std::vector< int > &newVec, int newSlices)
Return modified data vector<int>
static int peak(int oldPeak, int oldSlices, int newSlices)
Return new triggered slice offset.
CMMEtSums object stores Et sums from the Energy CMMs.
const std::vector< int > & EtErrorVec() const
returns module ET errors
void addEx(const std::vector< unsigned int > &Ex, const std::vector< int > &ExError)
Update Ex sum.
const std::vector< int > & ExErrorVec() const
returns module Ex errors
int dataID() const
returns data ID
Definition CMMEtSums.cxx:59
void addEt(const std::vector< unsigned int > &Et, const std::vector< int > &EtError)
Add data to existing objects.
int crate() const
Data accessors.
Definition CMMEtSums.cxx:54
const std::vector< unsigned int > & EtVec() const
Access multi-slice data.
Definition CMMEtSums.cxx:94
void addEy(const std::vector< unsigned int > &Ey, const std::vector< int > &EyError)
Update Ey sum.
const std::vector< unsigned int > & ExVec() const
returns module Ex sum
Definition CMMEtSums.cxx:99
const std::vector< int > & EyErrorVec() const
returns module Ey errors
const std::vector< unsigned int > & EyVec() const
returns module Ey sum
CMMJetHits class stores Jet hit multiplicities received by and read out from the Jet CMMs.
const std::vector< int > & ErrorVec() const
returns errors
void addHits(const std::vector< unsigned int > &hits, const std::vector< int > &errors)
Add hits to existing object.
const std::vector< unsigned int > & HitsVec() const
Multi-slice accessors.
Error data.
Definition DataError.h:27
int error() const
Return the full error word.
Definition DataError.h:78
void set(ErrorBit bit, int value=1)
Set an error bit or data.
Definition DataError.cxx:28
int get(ErrorBit bit) const
Return an error bit or data.
Definition DataError.cxx:48
int module() const
returns module number
Definition JEMEtSums.cxx:52
const std::vector< unsigned int > & EyVec() const
returns module Ey sum
Definition JEMEtSums.cxx:82
void addEx(const std::vector< unsigned int > &Ex)
Update Ex sum.
Definition JEMEtSums.cxx:97
const std::vector< unsigned int > & ExVec() const
returns module Ex sum
Definition JEMEtSums.cxx:77
void addEt(const std::vector< unsigned int > &Et)
Update ET sum.
Definition JEMEtSums.cxx:92
const std::vector< unsigned int > & EtVec() const
returns module ET sum
Definition JEMEtSums.cxx:72
int crate() const
returns crate number
Definition JEMEtSums.cxx:47
void addEy(const std::vector< unsigned int > &Ey)
Update Ey sum.
const std::vector< unsigned int > & JetHitsVec() const
returns jet hits
Definition JEMHits.cxx:70
void addJetHits(const std::vector< unsigned int > &hits)
Set Jet hits.
Definition JEMHits.cxx:80
Jet/Energy Processor container for writing bytestream pre-LS1.
const DataVector< CMMEtSums > * CmmSums() const
Return pointer to CMM energy sums collection.
const DataVector< CMMJetHits > * CmmHits() const
Return pointer to CMM hit sums collection.
const DataVector< JetElement > * JetElements() const
Return pointer to jet element collection.
const DataVector< JEMHits > * JetHits() const
Return pointer to hit sums collection.
const DataVector< JEMEtSums > * EnergySums() const
Return pointer to energy sums collection.
virtual unsigned int jeKey(const xAOD::TriggerTower &tower)
returns key of passed tower
The JetElementKey object provides the key for each JetElement depending on its eta,...
Jet elements are the inputs to the Jet, ETmiss and ETsum triggers.
double eta() const
Eta of centre of JetElement.
const std::vector< int > & hadEnergyVec() const
return Had energy vector reference (all timeslices)
double phi() const
Phi of centre of JetElement.
const std::vector< int > & linkErrorVec() const
return link error vector reference (all timeslices)
void addSlice(int slice, int emEnergy, int hadEnergy, int emError, int hadError, int linkError)
add data for one timeslice.
const std::vector< int > & emErrorVec() const
return Em error vector reference (all timeslices)
int peak() const
return triggered slice offset
const std::vector< int > & hadErrorVec() const
return Had error vector reference (all timeslices)
const std::vector< int > & emEnergyVec() const
Return data for all slices.
STL class.
bool verbose
Definition hcg.cxx:73
static const InterfaceID IID_IJepByteStreamV1Tool("JepByteStreamV1Tool", 1, 1)
Definition index.py:1
Extra patterns decribing particle interation process.