ATLAS Offline Software
Loading...
Searching...
No Matches
TileROD_Decoder.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Implementation of TileROD_Decoder class
6
7// Tile includes
11#include "TileEvent/TileCell.h"
16
17// Atlas includes
20
21#include <algorithm>
22#include <iomanip>
23#include <sstream>
24#include <atomic>
25#include <arpa/inet.h>
26
27#define DO_NOT_USE_MUON_TAG true
28
29static const InterfaceID IID_ITileROD_Decoder("TileROD_Decoder", 1, 0);
30
31bool chan_order (TileRawData * a, TileRawData * b) { return (a->adc_HWID() < b->adc_HWID()); }
32bool chan_order1 (const TileFastRawChannel& a, const TileFastRawChannel& b) { return (a.channel() < b.channel()); }
33
34inline unsigned char qbitfun(float t, float a, float b) { return ((t!=0.0F) ? ((t>a && t<b) ? TileCell::MASK_AMPL+TileCell::MASK_TIME : TileCell::MASK_AMPL) : 0); }
35
38
39TileROD_Decoder::TileROD_Decoder(const std::string& type, const std::string& name,
40 const IInterface* parent)
41 : AthAlgTool(type, name, parent)
44 , m_of2Default(true)
46 , m_ErrorCounter (0)
47 , m_hid2re(nullptr)
48 , m_hid2reHLT(nullptr)
49 , m_maxChannels(TileCalibUtils::MAX_CHAN)
51 , m_runPeriod(0){
52
53 declareInterface<TileROD_Decoder>(this);
54
55 for (std::atomic<const uint32_t*>& p : m_OFPtrs) {
56 p = nullptr;
57 }
58}
59
62 if (run < 0) run = m_fullTileRODs;
63 if (run >= 4444444) { // FIXME: should put correct run number here, once it is known
64 m_ampMinThresh_pC = m_ampMinThresh * (25. / 4095.);
65 m_ampMinThresh_MeV = m_ampMinThresh * (25. / 4095. / 1.05 * 1000.);
66 } else {
67 m_ampMinThresh_pC = m_ampMinThresh * (12.5 / 1023.);
68 m_ampMinThresh_MeV = m_ampMinThresh * (12.5 / 1023. / 1.05 * 1000.);
69 }
70 }
71 ATH_MSG_DEBUG("in TileROD_Decoder::updateAmpThreshold, m_ampMinThresh = " << m_ampMinThresh);
72 ATH_MSG_DEBUG("in TileROD_Decoder::updateAmpThreshold, m_ampMinThresh_MeV = " << m_ampMinThresh_MeV);
73 ATH_MSG_DEBUG("in TileROD_Decoder::updateAmpThreshold, m_ampMinThresh_pC = " << m_ampMinThresh_pC);
74}
75
82
83const InterfaceID& TileROD_Decoder::interfaceID() {
85}
86
87void TileROD_Decoder::printWarningCounter(bool printIfNoWarning) {
88 if (printIfNoWarning || m_WarningCounter > 0) {
89 ATH_MSG_WARNING( "Found " << m_WarningCounter << " warnings in decoding words");
90 }
91}
92
93void TileROD_Decoder::printErrorCounter(bool printIfNoError) {
94 if (printIfNoError || m_ErrorCounter > 0) {
95 ATH_MSG_WARNING( "Found " << m_ErrorCounter << " errors in decoding words");
96 }
97}
98
102
106
108
109 m_rc2bytes5.setVerbose(m_verbose);
110 m_rc2bytes2.setVerbose(m_verbose);
111 m_rc2bytes.setVerbose(m_verbose);
112 m_d2Bytes.setVerbose(m_verbose);
113
114 // retrieve TileHWID helper from det store
115 ATH_CHECK( detStore()->retrieve(m_tileHWID, "TileHWID") );
116 ATH_CHECK( m_hid2RESrcIDKey.initialize() );
117
119 //=== get TileCondToolOfcCool
120 ATH_CHECK( m_tileCondToolOfcCool.retrieve() );
121
122 //=== get TileToolTiming
123 ATH_CHECK( m_tileToolTiming.retrieve() );
124 }
125 else {
126 m_tileCondToolOfcCool.disable();
127 m_tileToolTiming.disable();
128 }
129
130 //=== get TileCondToolEmscale
131 ATH_CHECK( m_tileToolEmscale.retrieve(DisableTool{m_tileToolEmscale.empty()}) );
132
133 //=== get TileBadChanTool
134 if ( m_tileBadChanTool.empty() ) {
135 m_tileBadChanTool.disable();
136 } else {
137 ATH_CHECK( m_tileBadChanTool.retrieve() );
138 }
139
140 // Tile cabling service
141 ATH_CHECK( m_cablingSvc.retrieve() );
142 const TileCablingService *cablingService = m_cablingSvc->cablingService();
143 m_maxChannels = cablingService->getMaxChannels();
144 m_runPeriod = cablingService->runPeriod();
145 std::ostringstream os;
146 if (m_runPeriod==3) {
147 if ( m_demoFragIDs.empty() ) {
148 std::vector<int> v = { 0x10d }; // LBA14 is demonstrator in RUN3
149 m_demoFragIDs = v;
150 }
151 os << " in RUN3";
152 }
153
154 if ( !m_demoFragIDs.empty() ) {
156 os << " (frag IDs):";
157 for (int fragID : m_demoFragIDs) {
158 if (fragID>0)
159 os << " 0x" << std::hex << fragID << std::dec;
160 else
161 os << " " << fragID;
162 }
163 ATH_MSG_INFO("Enable channel remapping for demonstrator modules" << os.str());
164 }
165
166 m_Rw2Cell[0].reserve(m_maxChannels);
167 m_Rw2Cell[1].reserve(m_maxChannels);
170 m_Rw2Pmt[0].reserve(m_maxChannels);
171 m_Rw2Pmt[1].reserve(m_maxChannels);
174
175
176 ATH_CHECK( m_L2Builder.retrieve(DisableTool{m_L2Builder.empty()}) );
177
179
180 // Initialize
181 this->m_hashFunc.initialize(m_tileHWID);
182
183 this->initHid2reHLT();
184
185 // prepare remapping from channel numbers in demonstrator to channel numbers in legacy drawers
186 if (!m_demoFragIDs.empty()) {
187 for (int i=0; i<24; ++i) {
188 m_demoChanLB.push_back(i);
189 m_demoChanEB.push_back(i);
190 }
191 for (int i=24; i<48; i+=3) {
192 m_demoChanLB.push_back(i+2);
193 m_demoChanLB.push_back(i+1);
194 m_demoChanLB.push_back(i);
195 }
196 m_demoChanEB.push_back(31);
197 m_demoChanEB.push_back(32);
198 m_demoChanEB.push_back(30);
199 m_demoChanEB.push_back(35);
200 m_demoChanEB.push_back(33);
201 m_demoChanEB.push_back(34);
202 m_demoChanEB.push_back(38);
203 m_demoChanEB.push_back(37);
204 m_demoChanEB.push_back(41);
205 m_demoChanEB.push_back(40);
206 m_demoChanEB.push_back(39);
207 m_demoChanEB.push_back(36);
208 for (int i=24; i<30; ++i) {
209 m_demoChanEB.push_back(i);
210 }
211 for (int i=42; i<48; ++i) {
212 m_demoChanEB.push_back(i);
213 }
214 }
215
216 return StatusCode::SUCCESS;
217}
218
219
221 for (unsigned int i = 0; i < 4; ++i) {
222 m_Rw2Cell[i].clear();
223 m_Rw2Pmt[i].clear();
224 }
228 return StatusCode::SUCCESS;
229}
230
231// check if bit is set
232bool TileROD_Decoder::checkBit(const uint32_t* p, int chan) const {
233 // chan = (0,47)
234 int a = chan / 32;
235 int r = chan % 32;
236 // a = (0,1), r = ( 0, 31 )
237 return *(p + a) & (1 << r);
238
239}
240
246void TileROD_Decoder::unpack_frag0(uint32_t version,
247 uint32_t sizeOverhead,
248 DigitsMetaData_t& digitsMetaData,
249 const uint32_t* p, pDigiVec & pDigits,
250 int frag_id, int drawer_type) const {
251 int gain = 0;
252 int n;
253
254 // pointer to current data word
255 const uint32_t *data;
256 // current chip #
257 int chip;
258 // channel #
259 int channel;
260
261 // first word is full frag size, first two words are not data
262 int size = *(p) - sizeOverhead;
263 // second word is frag ID (0x100-0x4ff) and frag type
264 int frag = (frag_id>0) ? frag_id : *(p + 1) & 0xFFFF;
265 bool remap = (drawer_type > 0) || std::binary_search(m_demoFragIDs.begin(), m_demoFragIDs.end(), frag);
266 const std::vector<int> & chmap = (frag<0x300) ? m_demoChanLB : m_demoChanEB;
267
268 // Position of first data word, ignore 2 frag header words
269 data = p + 2;
270
271 uint32_t all00 = TileFragStatus::ALL_00;
272 uint32_t allFF = TileFragStatus::ALL_FF;
273
274 for (int i = 0; i < size; ++i) {
275 uint32_t w = data[i];
276 if (allFF && w!=0xFFFFFFFF) {
278 if (all00 == TileFragStatus::ALL_OK) break;
279 }
280 if (all00 && w != 0) {
282 if (allFF == TileFragStatus::ALL_OK) break;
283 }
284 }
285
286 uint32_t status = (all00 | allFF);
287 digitsMetaData[6].push_back( status );
288
289 // check that fragment is not dummy
291 return; // nothing reasonable found
292 }
293
294 // if (msgLvl(MSG::VERBOSE))
295 // msg(MSG::VERBOSE) << "version=" << version << " size: " << (*p) << " " << size;
296 if (sizeOverhead == 2 && (version == 0x2 || version == 0x1)) { /* can not guess number of samples from size */
297 if (size > 178 && size < 205)
298 size = 179; /* we expect this number (9+2)*16+2 */
299 else if (size > 274 && size < 405) size = 275; /* we expect this number (7*2+3)*16+2 */
300 ++data; // ignore first word coming from drawer
301 }
302
303 // if (msgLvl(MSG::VERBOSE))
304 // msg(MSG::VERBOSE) << size << endmsg;
305
306 // number of chips in the data, only 16 is expected
307 int chipCount = 16;
308 // one chip contains 3 channels
309 int channelCount = chipCount * 3;
310 // size of 'block'. In normal mode one block is header and chipCount words with samples and CRC word
311 // In calib mode one block is header word, <chipCount> low gain samples, header, <chipCount> high gain and CRC word
312 int blockSize = size / chipCount;
313 // deplacement of high gain samples in calib mode
314 int gainOffset = 0;
315 // calculate number of words per chip including header and excluding CRC
316 int wordsPerChip = 0;
317 // number of data words per chip, excluding header and CRC
318 int dataWordsPerChip = 0;
319 // real number of channels and chips
320 // int channelCountReal,chipCountReal;
321
322 // Digitizer mode doesn't change between events
323 static std::atomic<int> savedDigiMode = -1;
324
325 int digiMode = savedDigiMode;
326
327 if (digiMode < 0 && size > 0) { // try to find digi mode until good mode is found
328 digiMode = m_d2Bytes.getDigiMode(data, chipCount, blockSize);
329 savedDigiMode = digiMode;
330 }
331
332 if (digiMode > 0 || (digiMode < 0 && blockSize == 17)) {
333 // calibration mode
334 // 2X number of chips
335 // chipCount <<= 1;
336 // channelCount = chipCount*3;
337
338 // lengt with header and without CRC
339 wordsPerChip = (blockSize - 1) / 2;
340 // lengt without header and CRC
341 dataWordsPerChip = wordsPerChip - 1;
342
343 //channelCountReal = channelCount/2;
344 //chipCountReal = chipCount/2;
345
346 gainOffset = wordsPerChip;
347 } else {
348 // assume normal mode
349 // block contains one CRC word
350 wordsPerChip = blockSize - 1;
351 // one header word
352 dataWordsPerChip = wordsPerChip - 1;
353
354 // channelCountReal = channelCount;
355 // chipCountReal = chipCount;
356 }
357
358 if (msgLvl(MSG::VERBOSE)) {
359 msg(MSG::VERBOSE) << "Unpacking TileDigits, ID=0x" << MSG::hex << frag
360 << ", size=" << MSG::dec << size << endmsg;
361
362 msg(MSG::VERBOSE) << " chips=" << chipCount << endmsg;
363 msg(MSG::VERBOSE) << " channels=" << channelCount << endmsg;
364 msg(MSG::VERBOSE) << " block size=" << blockSize << endmsg;
365 msg(MSG::VERBOSE) << " words/chip=" << wordsPerChip << endmsg;
366 msg(MSG::VERBOSE) << " data/chip=" << dataWordsPerChip << endmsg;
367 msg(MSG::VERBOSE) << " gain offs=" << gainOffset << endmsg;
368 msg(MSG::VERBOSE) << " mode=" << digiMode << endmsg;
369 }
370
371 if (size == 0) {
372 ATH_MSG_VERBOSE( "Size is 0, no digits extracted" );
373 return;
374 }
375
376 TileDigits *td;
377 HWIdentifier drawerID = m_tileHWID->drawer_id(frag);
378 HWIdentifier adcID;
379 std::array< std::vector<float>, 3 > digiVec;
380
381 // take BCID from chip header with good parity
382 uint32_t bcid = m_d2Bytes.getBCID(data, chipCount, blockSize);
383
384 if (gainOffset > 0) {
385 // calibration mode
386 pDigits.reserve(96);
387 std::vector<uint32_t>& chipHeaderLow = digitsMetaData[2];
388 std::vector<uint32_t>& chipCRCLow = digitsMetaData[3];
389 std::vector<uint32_t>& chipHeaderHigh = digitsMetaData[4];
390 std::vector<uint32_t>& chipCRCHigh = digitsMetaData[5];
391
392 // loop through all chips
393 for (chip = 0; chip < chipCount; ++chip) {
394 ATH_MSG_VERBOSE( "Unpacking calib data for chip " << chip );
395
396 // Extract low gain digits for fragment
397 digiVec = m_d2Bytes.getDigits(data + 1, dataWordsPerChip);
398
399 for (n = 0; n < 3; ++n) {
400 // calc channel #
401 channel = chip * 3 + n;
402 if (remap) channel = chmap[channel];
403 // create ID
404 adcID = m_tileHWID->adc_id(drawerID, channel, TileHWID::LOWGAIN);
405
406 td = new TileDigits(adcID, digiVec[n]);
407 pDigits.push_back(td);
408
409 }
410 if (remap) std::sort(pDigits.end()-3,pDigits.end(),chan_order);
411
412 // Extract high gain digits for fragment
413 digiVec = m_d2Bytes.getDigits(data + 1 + gainOffset, dataWordsPerChip);
414
415 for (n = 0; n < 3; ++n) {
416 // calc channel #
417 channel = chip * 3 + n;
418 if (remap) channel = chmap[channel];
419 // create ID
420 adcID = m_tileHWID->adc_id(drawerID, channel, TileHWID::HIGHGAIN);
421
422 td = new TileDigits(adcID, digiVec[n]);
423 pDigits.push_back(td);
424
425 }
426 if (remap) std::sort(pDigits.end()-3,pDigits.end(),chan_order);
427
428 // store metadata
429 chipHeaderLow.push_back(*data);
430 chipCRCLow.push_back(*(data + gainOffset - 1));
431 chipHeaderHigh.push_back(*(data + gainOffset));
432 chipCRCHigh.push_back(*(data + blockSize - 1));
433
434 // next block
435 data += blockSize;
436 }
437 } else {
438 // Normal mode
439 pDigits.reserve(pDigits.size() + 48);
440 std::vector<uint32_t>& chipHeader = digitsMetaData[2];
441 std::vector<uint32_t>& chipCRC = digitsMetaData[3];
442
443 // loop through all chips
444 for (chip = 0; chip < chipCount; ++chip) {
445 // Extract digits for fragment
446 digiVec = m_d2Bytes.getDigits(data + 1, dataWordsPerChip);
447
448 ATH_MSG_VERBOSE( "Header $" << MSG::hex << (*data)
449 << " CRC $" << *(data + blockSize - 1) );
450
451 for (n = 0; n < 3; ++n) {
452 // calc channel #
453 channel = chip * 3 + n;
454 if (remap) channel = chmap[channel];
455 // get gain from chip header
456 gain = m_d2Bytes.getGain(data, n);
457 // create ID
458 adcID = m_tileHWID->adc_id(drawerID, channel, gain);
459 td = new TileDigits(adcID, digiVec[n]);
460
461 ATH_MSG_VERBOSE( "Frag: $" << MSG::hex << frag << MSG::dec
462 << " G:" << gain
463 << " C:" << channel
464 << " BCID: " << MSG::hex << m_d2Bytes.getBCID(data, chipCount, blockSize) << MSG::dec
465 << " Data={" << (int) digiVec[n][0]
466 << "," << (int) digiVec[n][1]
467 << "," << (int) digiVec[n][2]
468 << "," << (int) digiVec[n][3]
469 << "," << (int) digiVec[n][4]
470 << "," << (int) digiVec[n][5]
471 << "," << (int) digiVec[n][6] << "}" );
472
473
474 pDigits.push_back(td);
475
476 }
477
478 // store some metadata, first word in chip is header, last is CRC
479 chipHeader.push_back(*data);
480 chipCRC.push_back(*(data + blockSize - 1));
481
482 // go to next block
483 data += blockSize;
484 }
485 if (remap) std::sort(pDigits.end()-channelCount,pDigits.end(),chan_order);
486 }
487
488 int extra = size - (data - p) + 2;
489
490 // check size of fragment - we expect 2 extra words (DMU mask and CRC) or more!
491 if (extra < 2) {
493 ATH_MSG_WARNING( "Too short fragment ! Expected at least " << MSG::dec << (data - p)
494 << " data words, while size from header is " << size
495 << " data words (plus " << sizeOverhead << " words overhead)" );
496 }
497 }
498
499 if (msgLvl(MSG::VERBOSE)) {
500 msg(MSG::VERBOSE) << "Trailer 0x" << MSG::hex
501 << data[0] << " 0x" << data[1];
502 for (int i = 2; i < extra; ++i) {
503 msg(MSG::VERBOSE) << " 0x" << data[i];
504 }
505 msg(MSG::VERBOSE) << MSG::dec << endmsg;
506
507 // check frag trailer
508 if (extra > 0) {
509 if ((data[0] & 0xffff) != (data[0] >> 16)) {
510 msg(MSG::VERBOSE) << MSG::hex << "Trailer numbers do not match: "
511 << data[0] << MSG::dec << endmsg;
512 } else {
513 if ((data[0] & 0xffff) == 0xffff)
514 msg(MSG::VERBOSE) << "Found barrel trailer" << endmsg;
515 else if ((data[0] & 0xffff) == 0xfff)
516 msg(MSG::VERBOSE) << "Found extended barrel trailer" << endmsg;
517 else
518 msg(MSG::VERBOSE) << MSG::hex << "Unexpected trailer number: "
519 << (data[0] & 0xffff) << MSG::dec << endmsg;
520 }
521 }
522
523 // check CRC trailer
524 if (extra > 1) {
525 if ((data[1] & 0xffff) != (data[1] >> 16)) {
526 msg(MSG::VERBOSE) << "Trailer CRC numbers do not match" << endmsg;
527 } else {
528 msg(MSG::VERBOSE) << MSG::hex << "Found CRC 0x" << (data[1] & 0xffff)
529 << MSG::dec << endmsg;
530 }
531 }
532 }
533
534 // store metadata for this collection
535 // size, fragID, BCID, DMU Mask, CRC and other extra words
536 digitsMetaData[0].push_back(size);
537 digitsMetaData[0].push_back(frag);
538 digitsMetaData[0].push_back(bcid);
539 for (int i = 0; i < extra; ++i) {
540 digitsMetaData[1].push_back(data[i]);
541 }
542 if (sizeOverhead == 2 && (version == 0x2 || version == 0x1)) { // keep also first skipped word
543 digitsMetaData[1].push_back(p[2]);
544 }
545
546 if (dataWordsPerChip > 15) { // can not be true !!!
547 savedDigiMode = -1; // check again digiMode in next fragment
548 }
549}
550
551void TileROD_Decoder::unpack_frag1(uint32_t /* version */,
552 uint32_t sizeOverhead,
553 DigitsMetaData_t& digitsMetaData,
554 const uint32_t* p,
555 pDigiVec & pDigits,
556 int frag_id, int drawer_type) const {
557 // first word is full frag size, first two words are not data
558 int size = *(p) - sizeOverhead;
559 // second word is frag ID (0x100-0x4ff) and frag1 type (old and new version).
560 int frag = (frag_id>0) ? frag_id : *(p + 1) & 0xFFFF;
561 bool remap = (drawer_type > 0) || std::binary_search(m_demoFragIDs.begin(), m_demoFragIDs.end(), frag);
562 const std::vector<int> & chmap = (frag<0x300) ? m_demoChanLB : m_demoChanEB;
563 int frag1version = (*(p + 1) >> 31) & 0x1;
564 int nbchanformat1 = ((*(p + 1)) >> 24) & 0x3F;
565
566 // store metadata for this collection
567 // size, fragID, BCID
568 digitsMetaData[0].push_back(size);
569 digitsMetaData[0].push_back(frag);
570 digitsMetaData[0].push_back(0);
571
572 if (frag1version == 0) { //Old version
573 p += 2; // 2 words so far
574
575 int nsamp = (*(p) >> 8) & 0x0F; // find number of samples in first data word
576 int words_per_chan = nsamp + 1; // one extra 16bit word with channel number
577 int nchan = 2 * size / words_per_chan;
578
579 if (2 * size != nchan * words_per_chan || nchan <= 0 || nchan > 48) {
581 ATH_MSG_WARNING( "Digi frag type=1 fragId=0x" << MSG::hex << frag << MSG::dec
582 << " Nsamp=" << nsamp
583 << " Nchan=" << nchan
584 << " Wrong Size=" << size );
585 }
586 return;
587 }
588
589 HWIdentifier drawerID = m_tileHWID->drawer_id(frag);
590 std::vector<float> digiVec(nsamp);
591 pDigits.reserve(nchan);
592
593 const uint16_t* p16 = reinterpret_cast<const uint16_t *>(p);
594
595 for (int ch = 0; ch < nchan; ++ch) {
596
597 int channel = (*p16) & 0xFF;
598 if (remap) channel = chmap[channel];
599 int nsamp1 = (*(p16) >> 8) & 0x0F;
600 int gain = (*p16) >> 15;
601 ++p16;
602
603 for (int samp = 0; samp < nsamp; ++samp) {
604 digiVec[samp] = *p16++;
605 }
606
607 if (channel < 48 && nsamp1 == nsamp) {
608 HWIdentifier adcID = m_tileHWID->adc_id(drawerID, channel, gain);
609 TileDigits * td = new TileDigits(adcID, digiVec);
610 pDigits.push_back(td);
611 } else {
613 ATH_MSG_WARNING( "Digi frag type=1 fragId=0x" << MSG::hex << frag << MSG::dec
614 << " CHind=" << ch
615 << " channel=" << channel
616 << " nsamp=" << nsamp1 << "/" << nsamp );
617 }
618 }
619
620 if (msgLvl(MSG::VERBOSE)) {
621 msg(MSG::VERBOSE) << MSG::hex << "Frag: $" << frag << MSG::dec
622 << " G:" << gain
623 << " C:" << channel
624 << " Data={";
625 for (int samp = 0; samp < nsamp; ++samp) {
626 msg(MSG::VERBOSE) << " " << (int) digiVec[samp];
627 }
628 msg(MSG::VERBOSE) << "} " << MSG::hex;
629 for (int samp = 0; samp < nsamp / 2 + 1; ++samp) {
630 msg(MSG::VERBOSE) << (int) *p++ << " ";
631 }
632 msg(MSG::VERBOSE) << MSG::dec << endmsg;
633 }
634 }
635 } //End of old version
636
637 else if (frag1version == 1) { //New version
638 p += 2; // 2 words so far
639
640 int nsamp = 7; // New frag1 only for 7 samples
641 int SizeOfFrag1 = size * 2; // Number of 16 bit words
642 int nbchanformat2 = (SizeOfFrag1 - (3 * nbchanformat1)) / 5;
643
644 int nchan = nbchanformat1 + nbchanformat2;
645
646 if ((nchan) > 48 || ((nbchanformat1 * 3) + (nbchanformat2 * 5) > SizeOfFrag1)) {
648 ATH_MSG_WARNING( "Digi frag type=1 fragId=0x" << MSG::hex << frag << MSG::dec
649 << " frag1Version=" << frag1version
650 << " Nsamp=" << nsamp
651 << " NchanFormat1=" << nbchanformat1
652 << " NchanFormat2=" << nbchanformat2
653 << " Wrong Size=" << size);
654 }
655 return;
656 }
657
658 HWIdentifier drawerID = m_tileHWID->drawer_id(frag);
659 std::vector<float> digiVec(nsamp);
660 pDigits.reserve(nchan);
661 pDigiVec sDigits(48);
662
663 int ptr16index = 1;
664 int channel = 0;
665 uint16_t word1 = 0;
666 uint16_t word2 = 0;
667 uint16_t word3 = 0;
668 uint16_t word4 = 0;
669 uint16_t word5 = 0;
670
671 for (int chf1 = 0; chf1 < nbchanformat1; ++chf1) {
672 if (ptr16index == 1)
673 channel = ((*p >> 26) & 0x3F);
674 else
675 channel = ((*p >> 10) & 0x3F);
676 if (remap) channel = chmap[channel];
677
678 int gain = 1;
679
680 if (ptr16index == 1) {
681 word1 = (uint16_t) ((*p >> 16) & 0xFFFF);
682 word2 = (uint16_t) (*p & 0xFFFF);
683 word3 = (uint16_t) ((*(p + 1) >> 16) & 0xFFFF);
684 ptr16index = 0;
685 }
686
687 else if (ptr16index == 0) {
688 word1 = (uint16_t) (*p & 0xFFFF);
689 word2 = (uint16_t) ((*(p + 1) >> 16) & 0xFFFF);
690 word3 = (uint16_t) (*(p + 1) & 0xFFFF);
691 ptr16index = 1;
692 }
693
694 uint16_t Smin = (word1 & 0x3FF);
695
696 digiVec[0] = ((word3 >> 4) & 0xF) + Smin;
697 digiVec[1] = ((word3 >> 0) & 0xF) + Smin;
698 digiVec[2] = ((word3 >> 8) & 0xF) + Smin;
699 digiVec[3] = ((word3 >> 12) & 0xF) + Smin;
700 digiVec[4] = ((word2 >> 4) & 0xF) + Smin;
701 digiVec[5] = ((word2 >> 0) & 0xF) + Smin;
702 digiVec[6] = ((word2 >> 8) & 0xF) + Smin;
703
704 HWIdentifier adcID = m_tileHWID->adc_id(drawerID, channel, gain);
705 TileDigits * td = new TileDigits(adcID, digiVec);
706 sDigits.at(channel) = td;
707 p += 1 + ptr16index;
708
709 if (msgLvl(MSG::VERBOSE)) {
710 msg(MSG::VERBOSE) << MSG::hex << "Frag: $" << frag << MSG::dec
711 << " G:" << gain
712 << " C:" << channel
713 << " Data={";
714 for (int samp = 0; samp < 7; ++samp) {
715 msg(MSG::VERBOSE) << " " << (int) digiVec[samp];
716 }
717 msg(MSG::VERBOSE) << "} " << MSG::hex
718 << " WORD1: " << word1
719 << " WORD2: " << word2
720 << " WORD3: " << word3 << MSG::dec << endmsg;
721 }
722 }
723
724 for (int chf2 = 0; chf2 < nbchanformat2; ++chf2) {
725 if (ptr16index == 1)
726 channel = ((*p) & 0x3F);
727 else
728 channel = ((*(p + 1) >> 16) & 0x3F);
729 if (remap) channel = chmap[channel];
730
731 if (ptr16index == 1) {
732 word1 = (uint16_t) ((*p >> 16) & 0xFFFF);
733 word2 = (uint16_t) ((*p) & 0xFFFF);
734 word3 = (uint16_t) ((*(p + 1) >> 16) & 0xFFFF);
735 word4 = (uint16_t) (*(p + 1) & 0xFFFF);
736 word5 = (uint16_t) ((*(p + 2) >> 16) & 0xFFFF);
737 ptr16index = 0;
738 } else if (ptr16index == 0) {
739 word1 = (uint16_t) ((*p) & 0xFFFF);
740 word2 = (uint16_t) ((*(p + 1) >> 16) & 0xFFFF);
741 word3 = (uint16_t) (*(p + 1) & 0xFFFF);
742 word4 = (uint16_t) ((*(p + 2) >> 16) & 0xFFFF);
743 word5 = (uint16_t) (*(p + 2) & 0xFFFF);
744 ptr16index = 1;
745 }
746
747 int gain = ((word2 >> 6) & 0x1);
748
749 digiVec[0] = ((word1 << 9) & 0x200) + ((word2 >> 7) & 0x1FF);
750 digiVec[1] = (word1 >> 1) & 0x3FF;
751 digiVec[2] = (word4 << 5 & 0x3E0) + ((word1 >> 11) & 0x1F);
752 digiVec[3] = (word4 >> 5) & 0x3FF;
753 digiVec[4] = ((word3 << 1) & 0x3FE) + ((word4 >> 15) & 0x1);
754 digiVec[5] = ((word5 << 7) & 0x380) + ((word3 >> 9) & 0x7F);
755 digiVec[6] = (word5 >> 3) & 0x3FF;
756
757 HWIdentifier adcID = m_tileHWID->adc_id(drawerID, channel, gain);
758 TileDigits * td = new TileDigits(adcID, digiVec);
759 sDigits.at(channel) = td;
760 p += (2 + ptr16index);
761
762 if (msgLvl(MSG::VERBOSE)) {
763 msg(MSG::VERBOSE) << MSG::hex << "Frag: $" << frag << MSG::dec
764 << " G:" << gain
765 << " C:" << channel
766 << " Data={";
767 for (int samp = 0; samp < nsamp; ++samp) {
768 msg(MSG::VERBOSE) << " " << (int) digiVec[samp];
769 }
770 msg(MSG::VERBOSE) << "} " << MSG::hex
771 << " WORD1: " << word1
772 << " WORD2: " << word2
773 << " WORD3: " << word3
774 << " WORD4: " << word4
775 << " WORD5: " << word5 << MSG::dec << endmsg;
776 }
777
778 }
779 for (uint i = 0; i < sDigits.size(); i++) {
780 TileDigits * td = sDigits.at(i);
781 if (td) pDigits.push_back(td);
782 }
783 } //End of new version
784
785}
786
787void TileROD_Decoder::unpack_frag2(uint32_t /* version */,
788 uint32_t sizeOverhead,
789 const uint32_t* p,
790 pRwChVec & pChannel,
791 int frag_id, int /* drawer_type */) const {
792 // first word is frag size
793 int count = *(p);
794 // second word is frag ID and frag type
795 int frag = (frag_id>0) ? frag_id : *(p + 1) & 0xFFFF;
796
797 // ATH_MSG_VERBOSE( "Unpacking TileRawChannels, ID=" << frag << " size=" << count );
798
799 // ATH_MSG_VERBOSE( "first 2 words " << MSG::hex
800 // << " 0x" << *p
801 // << " 0x" << *(p+1)
802 // << MSG::dec );
803
804 p += 2; // 2 words so far
805 int wc = sizeOverhead; // can be 2 or 3 words
806
807 HWIdentifier drawerID = m_tileHWID->drawer_id(frag);
809
810 for (unsigned int ch = 0; ch < m_maxChannels; ++ch) {
811 unsigned int w = (*p);
812
813 int gain = m_rc2bytes2.gain(w);
814 HWIdentifier adcID = m_tileHWID->adc_id(drawerID, ch, gain);
815
816 if (w != 0) { // skip invalid channels
817 rc = new TileRawChannel(adcID, m_rc2bytes2.amplitude(w), m_rc2bytes2.time(w),
818 m_rc2bytes2.quality(w));
819 } else {
820 rc = new TileRawChannel(adcID, 0.0, -100.0, 31);
821 }
822
823 pChannel.push_back(rc);
824
825 // ATH_MSG_VERBOSE(" frag 0x" << MSG::hex << frag
826 // << MSG::dec << " ch " << ch
827 // << " " << MSG::hex << w << MSG::dec
828 // << " " << gain
829 // << " " << m_rc2bytes2.amplitude(w)
830 // << " " << m_rc2bytes2.time(w)
831 // << " " << m_rc2bytes2.quality(w) );
832
833 ++wc;
834 ++p;
835 }
836
837 if (wc != count) {
838 // check word count
840 ATH_MSG_WARNING( "unpack_frag2 => Incorrect word count: "
841 << wc << " != " << count );
842 }
843 assert(0);
844 // return;
845 }
846
847 return;
848}
849
850void TileROD_Decoder::unpack_frag3(uint32_t /* version */,
851 uint32_t sizeOverhead,
852 const uint32_t* p,
853 pRwChVec & pChannel,
854 int frag_id, int /* drawer_type */) const {
855 // first word is frag size
856 int count = *(p);
857 // second word is frag ID and frag type
858 int frag = (frag_id>0) ? frag_id : *(p + 1) & 0xFFFF;
859
860 // ATH_MSG_VERBOSE( "first 4 words " << MSG::hex
861 // << " 0x" << *p
862 // << " 0x" << *(p+1)
863 // << " 0x" << *(p+2)
864 // << " 0x" << *(p+3) << MSG::dec );
865
866 // followed by 2 map words
867 const uint32_t* pMap = p + 2;
868
869 const short* p16 = reinterpret_cast<const short *>(p);
870
871 p16 = p16 + 8; // 8 16bit words so far
872 short wc16 = 4 + sizeOverhead * 2; // can be 8 or 10 (if overhead is 3 words)
873
874 HWIdentifier drawerID = m_tileHWID->drawer_id(frag);
876
877 for (unsigned int ch = 0; ch < m_maxChannels; ++ch) {
878 if (checkBit(pMap, ch)) {
879 int gain = m_rc2bytes.gain(*p16);
880 HWIdentifier adcID = m_tileHWID->adc_id(drawerID, ch, gain);
881
882 rc = new TileRawChannel(adcID
883 , m_rc2bytes.amplitude(*p16)
884 , m_rc2bytes.time(*(p16 + 1))
885 , m_rc2bytes.quality(*(p16 + 2)));
886 pChannel.push_back(rc);
887
888 ATH_MSG_VERBOSE( " frag 0x" << MSG::hex << frag << MSG::dec
889 << " ch " << ch << " " << MSG::hex
890 << "0x" << *p16 << *(p16+1) << *(p16+2) << MSG::dec
891 << " " << gain
892 << " " << m_rc2bytes.amplitude(*p16)
893 << " " << m_rc2bytes.time(*(p16+1))
894 << " " << m_rc2bytes.quality(*(p16+2)) );
895
896 wc16 = wc16 + 3;
897 p16 = p16 + 3;
898 } // channel present
899 } // all bits, done with this frag
900
901 if (wc16 % 2 == 1) {
902 ++wc16; // align
903 ++p16;
904 }
905 if (wc16 != 2 * count) {
906 // check word count
908 ATH_MSG_WARNING( "unpack_frag3 => Incorrect word count: "
909 << wc16 << " != 2*" << count );
910 }
911 assert(0);
912 // return;
913 }
914
915 return;
916}
917
918void TileROD_Decoder::unpack_frag4(uint32_t /* version */,
919 uint32_t sizeOverhead,
920 unsigned int unit,
921 RawChannelMetaData_t& rawchannelMetaData,
922 const uint32_t* p,
923 pRwChVec & pChannel,
924 int frag_id, int drawer_type) const
925{
926 // first word is frag size
927 int count = *(p);
928 // second word is frag ID and frag type
929 int frag = (frag_id>0) ? frag_id : *(p + 1) & 0xFFFF;
930 bool remap = (drawer_type > 0) || std::binary_search(m_demoFragIDs.begin(), m_demoFragIDs.end(), frag);
931 const std::vector<int> & chmap = (frag<0x300) ? m_demoChanLB : m_demoChanEB;
932
933 // ATH_MSG_VERBOSE( "Unpacking TileRawChannels, ID=" << frag << " size=" << count <<s);
934
935 // ATH_MSG_VERBOSE( "first 2 words " << MSG::hex
936 // << " 0x" << *p
937 // << " 0x" << *(p+1) << MSG::dec );
938
939 p += 2; // 2 words so far
940 int wc = sizeOverhead; // can be 2 or 3 words
941
942 HWIdentifier drawerID = m_tileHWID->drawer_id(frag);
944 uint32_t all00 = TileFragStatus::ALL_00;
945 uint32_t allFF = TileFragStatus::ALL_FF;
946
947 for (unsigned int ch = 0; ch < m_maxChannels; ++ch) {
948 unsigned int w = (*p);
949
950 int gain = m_rc2bytes4.gain(w);
951 int ch1 = (remap) ? chmap[ch] : ch;
952 HWIdentifier adcID = m_tileHWID->adc_id(drawerID, ch1, gain);
953
954 if (allFF && w!=0xFFFFFFFF) allFF = TileFragStatus::ALL_OK;
955 if (w != 0) { // skip invalid channels
956 if (all00) all00 = TileFragStatus::ALL_OK;
957 rc = new TileRawChannel(adcID
958 , m_rc2bytes4.amplitude(w, unit)
959 , m_rc2bytes4.time(w)
960 , m_rc2bytes4.quality(w));
961 } else {
962 rc = new TileRawChannel(adcID, 0.0, -100., 31);
963 }
964
965 pChannel.push_back(rc);
966
967 // ATH_MSG_VERBOSE( MSG::hex << " frag 0x" << frag << MSG::dec
968 // << " ch " << ch
969 // << " 0x" << MSG::hex << w << MSG::dec
970 // << " " << gain
971 // << " " << m_rc2bytes4.amplitude(w)
972 // << " " << m_rc2bytes4.time(w)
973 // << " " << m_rc2bytes4.quality(w) );
974
975 ++wc;
976 ++p;
977 }
978 if (remap) std::sort(pChannel.end()-m_maxChannels,pChannel.end(),chan_order);
979
980 rawchannelMetaData[6].push_back( all00 | allFF );
981
982 if (wc > count) {
983 // check word count
985 ATH_MSG_WARNING( "unpack_frag4 => Incorrect word count: "
986 << wc << " != " << count );
987 }
988 assert(0);
989 // return;
990 // } else if (wc < count) {
991 // ATH_MSG_VERBOSE("unpack_frag4 => extra " << count-wc << " words in frag" );
992 }
993
994 return;
995}
996
997void TileROD_Decoder::unpack_frag5(uint32_t /* version */,
998 uint32_t sizeOverhead,
999 unsigned int unit,
1000 DigitsMetaData_t& digitsMetaData,
1001 const uint32_t* p, pDigiVec & pDigits,
1002 pRwChVec & pChannel,
1003 int frag_id, int drawer_type) const
1004{
1005 // first word is frag size
1006 int count = *(p);
1007 // second word is frag ID and frag type
1008 int frag = (frag_id>0) ? frag_id : *(p + 1) & 0xFFFF;
1009 bool remap = (drawer_type > 0) || std::binary_search(m_demoFragIDs.begin(), m_demoFragIDs.end(), frag);
1010 const std::vector<int> & chmap = (frag<0x300) ? m_demoChanLB : m_demoChanEB;
1011 int size_L2 = (*(p + 1) >> (32 - 2 - 3)) & 0x7;
1012
1013 // store metadata for this collection
1014 // size, fragID, BCID
1015 digitsMetaData[0].push_back(count);
1016 digitsMetaData[0].push_back(frag);
1017 digitsMetaData[0].push_back(0);
1018
1020 const uint32_t* ptrFrag = reinterpret_cast<const uint32_t*> (p - 1); // begin of fragment
1021 const uint32_t* ptrOFW = getOFW(frag, unit); // get OF Weights
1022 m_rc2bytes5.unpack(ptrOFW, ptrFrag, ChanData);
1023
1024 int wc = sizeOverhead; // can be 2 or 3 words
1025 int bc = (size_L2 * 32 + 48) / 8; // size_L2 + BadBits
1026
1027 HWIdentifier drawerID = m_tileHWID->drawer_id(frag);
1028
1029 std::vector<float> digiVec(7);
1030 if (m_useFrag5Raw) pDigits.reserve(pDigits.size() + 48);
1031 if (m_useFrag5Reco) pChannel.reserve(pChannel.size() + 48);
1032
1033 for (int ch = 0; ch < 48; ++ch) {
1034 int size = m_rc2bytes5.get_size_code(ChanData[ch].code);
1035 int gain = ChanData[ch].gain;
1036 int ch1 = (remap) ? chmap[ch] : ch;
1037 HWIdentifier adcID = m_tileHWID->adc_id(drawerID, ch1, gain);
1038
1039 if (m_useFrag5Raw) {
1040 for (int i = 0; i < 7; ++i) digiVec[i] = ChanData[ch].s[i];
1041 TileDigits* td = new TileDigits(adcID, digiVec);
1042 pDigits.push_back(td);
1043 }
1044
1045 if (m_useFrag5Reco) {
1046 int format = m_rc2bytes5.get_format(ChanData[ch].code);
1047 int quality = m_rc2bytes5.get_quality(ChanData[ch].bad, format);
1048 float ene = ChanData[ch].ene;
1049 float time = ChanData[ch].time;
1050
1051 TileRawChannel* rc = new TileRawChannel(adcID, ene, time, quality);
1052 pChannel.push_back(rc);
1053 }
1054 bc += size;
1055 }
1056 if (remap) {
1057 std::sort(pDigits.end()-m_maxChannels,pDigits.end(),chan_order);
1058 std::sort(pChannel.end()-m_maxChannels,pChannel.end(),chan_order);
1059 }
1060
1061 wc += (bc + 3) / 4;
1062 if (wc > count) {
1063 // check word count
1064 if ((m_ErrorCounter++) < m_maxErrorPrint) {
1065 ATH_MSG_WARNING( " unpack_frag5 => Incorrect word count: "
1066 << wc << " != " << count );
1067 }
1068 assert(0);
1069 // return;
1070 } else if (wc < count) {
1071 if ((m_ErrorCounter++) < m_maxErrorPrint) {
1072 ATH_MSG_WARNING( "unpack_frag5 => extra " << count - wc
1073 << " words in frag" );
1074 ATH_MSG_WARNING( " count = " << count
1075 << " wc = " << wc
1076 << " bc = " << bc
1077 << " words in frag" );
1078 }
1079 }
1080 return;
1081}
1082
1083std::vector<uint32_t> TileROD_Decoder::get_correct_data(const uint32_t* p) const {
1084
1085 uint32_t size = (*p) - 1; // The size of fragment - start of the Tile subfragment (in v3format it is 0xff1234ff)
1086
1087 std::vector<uint32_t> data;
1088 data.reserve(size);
1089 const uint32_t* data_end = p + size;
1090
1091 // The first 2 words (size and fragmentID with type) are correct (just copy)
1092 data.push_back(*p);
1093 data.push_back(*(++p));
1094
1095 ++p;
1096 while (p < data_end) {
1097 uint32_t ppr_size = (*p) - 2; // The size of PPr packet
1098 // The first 2 words (FELIX header) of each MD fragment are correct (just copy)
1099 data.push_back(*(p));
1100 data.push_back(*(++p));
1101
1102 ++p;
1103 std::for_each(p, p + ppr_size, [&data] (uint32_t v) {
1104 data.push_back((ntohs(v >> 16) << 16) | (ntohs(v & 0xFFFF)));
1105 });
1106
1107 p += ppr_size;
1108 }
1109
1110 return data;
1111}
1112
1113void TileROD_Decoder::unpack_frag6(uint32_t /*version*/,
1114 uint32_t sizeOverhead,
1115 DigitsMetaData_t& digitsMetaData,
1116 const uint32_t* p, pDigiVec & pDigits,
1117 int frag_id, int drawer_type) const
1118{
1119 int size = *(p)- sizeOverhead;
1120 const uint32_t* data = p+2; // pointer to current data word Position of first data word,
1121 // second word is frag ID (0x100-0x4ff) and frag type
1122 int frag = (frag_id>0) ? frag_id : *(p + 1) & 0xFFFF; /* (*(data +3)>>16) & 0xFF;*/
1123 bool remap = (drawer_type > 0) || std::binary_search(m_demoFragIDs.begin(), m_demoFragIDs.end(), frag);
1124 const std::vector<int> & chmap = (frag<0x300) ? m_demoChanLB : m_demoChanEB;
1125
1126 HWIdentifier adcID;
1127 HWIdentifier drawerID = m_tileHWID->drawer_id(frag);
1128
1129 uint32_t all00 = TileFragStatus::ALL_00;
1130 uint32_t allFF = TileFragStatus::ALL_FF;
1131
1132 for (int i = 0; i < size; ++i) {
1133 uint32_t w = data[i];
1134 if (allFF && w!=0xFFFFFFFF) {
1135 allFF = TileFragStatus::ALL_OK;
1136 if (all00 == TileFragStatus::ALL_OK) break;
1137 }
1138 if (all00 && w != 0) {
1139 all00 = TileFragStatus::ALL_OK;
1140 if (allFF == TileFragStatus::ALL_OK) break;
1141 }
1142 }
1143
1144 uint32_t status = (all00 | allFF);
1145 digitsMetaData[6].push_back( status );
1146
1147 // check that fragment is not dummy
1149 ATH_MSG_WARNING("FRAG6: Suppress dummy fragment!!!");
1150 return; // nothing reasonable found
1151 }
1152
1153 using Tile = TileCalibUtils;
1154 unsigned int moduleID[Tile::MAX_MINIDRAWER] = {0};
1155 unsigned int runType[Tile::MAX_MINIDRAWER] = {0};
1156
1157 unsigned int runNumber[Tile::MAX_MINIDRAWER] = {0};
1158
1159 unsigned int pedestalHi[Tile::MAX_MINIDRAWER] = {0};
1160 unsigned int pedestalLo[Tile::MAX_MINIDRAWER] = {0};
1161
1162 unsigned int chargeInjected[Tile::MAX_MINIDRAWER] = {0};
1163 unsigned int timeInjected[Tile::MAX_MINIDRAWER] = {0};
1164 unsigned int capacitor[Tile::MAX_MINIDRAWER] = {0};
1165
1166 uint32_t bcid[Tile::MAX_MINIDRAWER] = {0};
1167 uint32_t l1id[Tile::MAX_MINIDRAWER] = {0};
1168
1169 uint32_t ecr[Tile::MAX_MINIDRAWER] = {0};
1170 uint32_t bcr[Tile::MAX_MINIDRAWER] = {0};
1171
1172 uint32_t fragmentID[Tile::MAX_MINIDRAWER] = {0};
1173 uint32_t packetVersion[Tile::MAX_MINIDRAWER] = {0};
1174
1175 int version = 0;
1176
1177 int mdFragmentSize = (*data) & 0xFFFF;
1178 int sampleNumber = mdFragmentSize / Tile::MAX_MINIDRAWER_CHAN;
1179
1180 std::vector<std::vector<std::vector<float>>> samples(Tile::MAX_GAIN,
1181 std::vector<std::vector<float>>(Tile::MAX_CHAN,
1182 std::vector<float>(sampleNumber)));
1183
1184 const uint32_t* const end_data = data + size;
1185 while (data < end_data) {
1186 if (*data == 0x12345678 ) {
1187 mdFragmentSize = (*(data - 2)) & 0xFFFF;
1188
1189 if ((++data < end_data)) {
1190
1191 version = (((*data >> 16) & 0xFFFF) == 0) ? 1 : 0;
1192 int mdSizeOverhead = (version == 0) ? 10 : 11;
1193 int delta = mdFragmentSize - (sampleNumber * Tile::MAX_MINIDRAWER_CHAN + mdSizeOverhead);
1194 if (delta != 0) {
1195 ATH_MSG_WARNING( "FRAG6: Unexpected MD fragment size " << mdFragmentSize << " => "
1196 << sampleNumber << " samples will be unpacked and last "
1197 << delta << " words will be ignored ");
1198 }
1199
1200 unsigned int miniDrawer = -1;
1201
1202 // check trailer
1203 const uint32_t* trailer = data + mdFragmentSize - 4;
1204 if (trailer < end_data && *trailer == 0x87654321) {
1205
1206 unsigned int paramsSize = 3;
1207 if (version == 0) {
1208 unsigned int fragSize = *data & 0xFF;
1209 paramsSize = (*data >> 8 ) & 0xFF;
1210
1211 miniDrawer = *(data + 4) & 0xFF;
1212
1213 moduleID[miniDrawer] = (*data >> 16) & 0xFF;
1214 runType[miniDrawer] = (*data >> 24) & 0xFF;
1215 if (fragSize != sampleNumber * Tile::MAX_MINIDRAWER_CHAN) {
1216 ATH_MSG_WARNING("FRAG6: Minidrawer [" << miniDrawer
1217 << "] has unexpected fragment size: " << fragSize
1218 << " correct value for " << sampleNumber
1219 << " samples is " << sampleNumber * Tile::MAX_MINIDRAWER_CHAN);
1220 }
1221
1222 if (paramsSize == 3){
1223 runNumber[miniDrawer] = *(++data);
1224
1225 pedestalLo[miniDrawer] = *(++data) & 0xFFF;
1226 pedestalHi[miniDrawer] = (*data >> 12 ) & 0xFFF;
1227
1228 chargeInjected[miniDrawer] = *(++data) & 0xFFF;
1229 timeInjected[miniDrawer] = (*data >> 12) & 0xFF;
1230 capacitor[miniDrawer] = (*data >> 20) & 0x1;
1231 } else {
1232
1233 ATH_MSG_WARNING("FRAG6: Minidrawer [" << miniDrawer
1234 << "] has unexpected number of parameter words: " << paramsSize
1235 << " => ignore them !!!");
1236 data += paramsSize;
1237 }
1238
1239 bcid[miniDrawer] = (*(++data) >> 16) & 0xFFFF;
1240 l1id[miniDrawer] = *(++data) & 0xFFFFFF;
1241 ecr[miniDrawer] = (*data >> 24) & 0xFF;
1242
1243 } else {
1244
1245 miniDrawer = *(data + 1) & 0xFF;
1246
1247 packetVersion[miniDrawer] = (*data) & 0xFF;
1248 fragmentID[miniDrawer] = (*data >> 8) & 0xFF;
1249
1250 bcid[miniDrawer] = (*(++data) >> 8) & 0xFFF;
1251 moduleID[miniDrawer] = (*data >> 20) & 0xFFF;
1252
1253 l1id[miniDrawer] = *(++data) & 0xFFFFFF;
1254 ecr[miniDrawer] = (*data >> 24) & 0xFF;
1255
1256 bcr[miniDrawer] = *(++data);
1257
1258
1259 if (packetVersion[miniDrawer] == 1) {
1260 pedestalLo[miniDrawer] = *(++data) & 0xFFF;
1261 pedestalHi[miniDrawer] = (*data >> 12 ) & 0xFFF;
1262 runType[miniDrawer] = (*data >> 24) & 0xFF;
1263
1264 runNumber[miniDrawer] = *(++data);
1265 } else {
1266 runNumber[miniDrawer] = *(++data);
1267
1268 pedestalLo[miniDrawer] = *(++data) & 0xFFF;
1269 pedestalHi[miniDrawer] = (*data >> 12 ) & 0xFFF;
1270 runType[miniDrawer] = (*data >> 24) & 0xFF;
1271 }
1272
1273 chargeInjected[miniDrawer] = *(++data) & 0xFFF;
1274 timeInjected[miniDrawer] = (*data >> 12) & 0xFF;
1275 capacitor[miniDrawer] = (*data >> 20) & 0x1;
1276 }
1277
1278 if (msgLvl(MSG::VERBOSE)) {
1279 msg(MSG::VERBOSE) << "FRAG6: Found MD[" << miniDrawer << "] fragment"
1280 << ", Run type: " << runType[miniDrawer]
1281 << ", Module ID: " << moduleID[miniDrawer]
1282 << ", BCID: " << bcid[miniDrawer]
1283 << ", L1ID: " << l1id[miniDrawer]
1284 << ", ECR: " << ecr[miniDrawer];
1285 if (version) {
1286 msg(MSG::VERBOSE) << ", BCR: " << bcr[miniDrawer]
1287 << ", Packet version: " << packetVersion[miniDrawer]
1288 << ", Fragment ID: " << fragmentID[miniDrawer];
1289 }
1290
1291 msg(MSG::VERBOSE) << endmsg;
1292
1293 if (paramsSize == 3) {
1294 msg(MSG::VERBOSE) << "FRAG6: MD[" << miniDrawer << "] Parameters:"
1295 << " Run number: " << runNumber[miniDrawer]
1296 << ", Ppedestal Lo: " << pedestalLo[miniDrawer]
1297 << ", Ppedestal Hi: " << pedestalHi[miniDrawer]
1298 << ", Charge injected: " << chargeInjected[miniDrawer]
1299 << ", Time injected: " << timeInjected[miniDrawer]
1300 << ", Capacitor: " << capacitor[miniDrawer] << endmsg;
1301 }
1302 }
1303
1304 const uint16_t* sample = reinterpret_cast<const uint16_t *> (++data);
1305
1306 for (int gain = 1; gain > -1; --gain) { // HG seems to be first
1307 int start_channel(miniDrawer * Tile::MAX_MINIDRAWER_CHAN);
1308 int end_channel(start_channel + Tile::MAX_MINIDRAWER_CHAN);
1309 for (int channel = start_channel; channel < end_channel; ++channel) {
1310
1311 for (int samplesIdx = 0; samplesIdx<sampleNumber; ++samplesIdx) {
1312 samples[gain][channel][samplesIdx] = (*sample & 0x0FFF);
1313 ++sample;
1314 }
1315
1316 }
1317 }
1318
1319 data = ++trailer;
1320
1321 } else {
1322 ATH_MSG_WARNING("FRAG6: Not found correct MD[" << miniDrawer << "] fragment trailer: => skip it!!!");
1323 }
1324 }
1325 } else {
1326 ++data;
1327 }
1328 }
1329
1330 pDigits.reserve(Tile::MAX_GAIN * Tile::MAX_CHAN);
1331
1332 // always two gains
1333 for (unsigned int gain = 0; gain < Tile::MAX_GAIN; ++gain) {
1334 // always 48 channels
1335 for (unsigned int channel = 0; channel < Tile::MAX_CHAN; ++channel) {
1336 int ch1 = (remap) ? chmap[channel] : channel;
1337
1338 adcID = m_tileHWID->adc_id(drawerID, ch1, gain);
1339 std::vector<float> digiVec(&samples[gain][channel][0], &samples[gain][channel][sampleNumber]);
1340 pDigits.push_back(new TileDigits(adcID, digiVec));
1341
1342 ATH_MSG_VERBOSE("FRAG6: " << (std::string) *(pDigits.back()));
1343 }
1344 if (remap) std::sort(pDigits.end() - Tile::MAX_CHAN, pDigits.end(), chan_order);
1345 }
1346
1347 digitsMetaData[1].insert(digitsMetaData[1].end(), &l1id[0], &l1id[Tile::MAX_MINIDRAWER]);
1348 digitsMetaData[1].insert(digitsMetaData[1].end(), &bcid[0], &bcid[Tile::MAX_MINIDRAWER]);
1349 digitsMetaData[1].insert(digitsMetaData[1].end(), &moduleID[0], &moduleID[Tile::MAX_MINIDRAWER]);
1350 digitsMetaData[1].insert(digitsMetaData[1].end(), &runType[0], &runType[Tile::MAX_MINIDRAWER]);
1351 digitsMetaData[1].insert(digitsMetaData[1].end(), &runNumber[0], &runNumber[Tile::MAX_MINIDRAWER]);
1352 digitsMetaData[1].insert(digitsMetaData[1].end(), &pedestalLo[0], &pedestalLo[Tile::MAX_MINIDRAWER]);
1353 digitsMetaData[1].insert(digitsMetaData[1].end(), &pedestalHi[0], &pedestalHi[Tile::MAX_MINIDRAWER]);
1354 digitsMetaData[1].insert(digitsMetaData[1].end(), &chargeInjected[0], &chargeInjected[Tile::MAX_MINIDRAWER]);
1355 digitsMetaData[1].insert(digitsMetaData[1].end(), &timeInjected[0], &timeInjected[Tile::MAX_MINIDRAWER]);
1356 digitsMetaData[1].insert(digitsMetaData[1].end(), &capacitor[0], &capacitor[Tile::MAX_MINIDRAWER]);
1357 digitsMetaData[1].insert(digitsMetaData[1].end(), &ecr[0], &ecr[Tile::MAX_MINIDRAWER]);
1358 if (version) {
1359 digitsMetaData[1].insert(digitsMetaData[1].end(), &bcr[0], &bcr[Tile::MAX_MINIDRAWER]);
1360 digitsMetaData[1].insert(digitsMetaData[1].end(), &packetVersion[0], &packetVersion[Tile::MAX_MINIDRAWER]);
1361 digitsMetaData[1].insert(digitsMetaData[1].end(), &fragmentID[0], &fragmentID[Tile::MAX_MINIDRAWER]);
1362 }
1363}
1364
1365void TileROD_Decoder::unpack_fragA(uint32_t /* version */,
1366 RawChannelMetaData_t& rawchannelMetaData,
1367 const uint32_t* p,
1368 pRwChVec & /* pChannel */,
1369 int /* frag_id */, int drawer_type) const {
1370 // second word is frag ID and frag type
1371 int size = *(p);
1372 p += 2; // 2 words so far
1373
1374 unsigned int w;
1375
1376 // Global CRC
1377 w = (*p);
1378 rawchannelMetaData[0].push_back(w & 0xFFFF);
1379 if (w >> 31 & 0x1) //most significant bit is 1. It means that it is a fragment containing the DSP BCID
1380 rawchannelMetaData[0].push_back((w >> 16) & 0x7FFF); //DSP BCID
1381 else
1382 rawchannelMetaData[0].push_back(0xDEAD); //0xDEAD if it is not filled
1383 ++p;
1384
1385 if (drawer_type == 2) {
1386 ATH_MSG_WARNING("Demo->Legacy remapping for Ext.Barrel not yet implemented for DQ fragment");
1387 }
1388
1389 for (int i = 0; i < (size - 4); ++i) {
1390 w = (*p);
1391 rawchannelMetaData[i + 1].push_back(w & 0xFFFF);
1392 rawchannelMetaData[i + 1].push_back(w >> 16);
1393 ++p;
1394 }
1395
1396 return;
1397}
1398
1399void TileROD_Decoder::unpack_fragAHLT(uint32_t /* version */, const uint32_t* p, uint16_t rob_bcid,
1400 uint16_t& mask, int /* frag_id */, int drawer_type) const {
1401 // first word is full frag size, including header
1402 int size = *(p);
1403 if (size < 9) return;
1404
1405 // second word is frag ID (0x100-0x4ff) and frag type
1406 uint16_t frag = (*(++p)) & 0xfff;
1407
1408 const uint16_t* w = reinterpret_cast<const uint16_t*> (++p); // Jump to first DQ word
1409 /* order of 16bit DQ words in DQ fragment
1410 ---------------------
1411 | Global CRC
1412 | DSP BCID
1413 | BCID checks
1414 | Mem parity err
1415 | Single strobe err
1416 | Double strobe err
1417 | Head format err
1418 | Head parity err
1419 | Sample format err
1420 | Sample parity err
1421 | FE chip mask err
1422 | ROD chip mask err
1423 ---------------------
1424 */
1425 if ((*w++) & 0x1) {
1426 mask = 0xffff;
1427 return;
1428 } // bad CRC
1429 mask = *w++; // BCID in DSP, can be zero (i.e. not set)
1430 if (mask != rob_bcid && mask > 0) {
1431 mask = 0xffff;
1432 return;
1433 } // BCIDs do not match - wrong event
1434
1435 mask = *w++; // bcid checks, one bit per DMU
1436 if (mask & 0x0002) {
1437 mask = 0xffff;
1438 return;
1439 } // second DMU is bad - everything is bad
1440
1441 if (drawer_type == 2) {
1442 ATH_MSG_WARNING("Demo->Legacy remapping for Ext.Barrel not yet implemented for DQ fragment");
1443 }
1444
1445 if (mask & 0x00F0) { // at least one error in second motherboard, where we don't expect errors in ext.barrel
1446 uint16_t BCIDerr = mask;
1447 int n_badMB = 0;
1448 if (frag > 0x2FF) { // do not count non-existing DMUs in EB
1449 if ((frag == 0x30E) || frag == 0x411) {
1450 BCIDerr &= 0x3cff;
1451 } else {
1452 BCIDerr &= 0x3cfe;
1453 }
1454 }
1455 while (BCIDerr) {
1456 if (BCIDerr & 0xF) ++n_badMB;
1457 BCIDerr >>= 4;
1458 }
1459 if (n_badMB == 4) { // BCID errors in all 4 motherboards - assume that all DMUs are bad
1460 mask = 0xffff;
1461 return;
1462 }
1463 }
1464
1465 mask |= *w++; // memory
1466
1467 w += 2; // Ignore 2 guys - strobe
1468 uint16_t fe_mask = *w++; // head format
1469 fe_mask |= *w++; // head parity
1470 fe_mask |= *w++; // sample format
1471 fe_mask |= *w++; // sample parity
1472
1473 if (fe_mask) { // something is wrong in data format - FE mask can not be used
1474 mask |= fe_mask;
1475 w++;
1476 } else { // real FE mask is valid only if there are no format or parity errors
1477 fe_mask = *w++;
1478 if ((frag > 0x2FF)) { // I am in extended barrel
1479 if ((frag == 0x30E) || frag == 0x411) fe_mask <<= 1; // shift by one DMU in EBA15 EBC18
1480 fe_mask = (fe_mask & 0xFF) | ((fe_mask & 0xF00) << 2); // shift upper half by two DMUs
1481 }
1482 mask |= ~fe_mask; // fe chip mask (inverted logic!)
1483 }
1484
1485 mask |= ~(*w); // rod chip mask (inverted logic!)
1486
1487 return;
1488}
1489
1490void TileROD_Decoder::unpack_frag10(uint32_t /* version */, const uint32_t* p,
1491 TileL2Container & pL2,
1492 int frag_id, int /* drawer_type */) const {
1493 // MTag-MET fragment 0x10 (staging mode)
1494
1495 // second word is frag ID and frag type
1496 int size = *(p);
1497 int frag = (frag_id>0) ? frag_id : *(p + 1) & 0xFFFF;
1498
1499 int nDrawer[2];
1500 nDrawer[0] = frag & 0x3F;
1501 nDrawer[1] = (frag & 0xFC0) >> 6;
1502
1503 p += 2; // 2 words so far
1504
1505 uint32_t w;
1506 uint32_t Mu_energy0;
1507 uint32_t Mu_energy1;
1508 uint32_t Mu_energy2;
1509 uint32_t Mu_pattern;
1510 uint32_t Mu_drawer;
1511 uint32_t Mu_quality;
1512
1513 std::vector<float> sumE[2];
1514 std::vector<unsigned int> word[2];
1515 std::vector<float> eta[2];
1516 std::vector<float> energy0[2];
1517 std::vector<float> energy1[2];
1518 std::vector<float> energy2[2];
1519 std::vector<unsigned int> quality[2];
1520
1521
1522 constexpr float eta_LB[9] = {
1523 ((0.00f + 2 * 0.05f) / 3), // D0, BC1, A1
1524 ((0.20f + 2 * 0.15f) / 3), // D1, BC2, A2
1525 ((0.20f + 2 * 0.25f) / 3), // D1, BC3, A3
1526 ((0.40f + 2 * 0.35f) / 3), // D2, BC4, A4
1527 ((0.40f + 2 * 0.45f) / 3), // D2, BC5, A5
1528 ((0.40f + 2 * 0.55f) / 3), // D2, BC6, A6
1529 ((0.60f + 2 * 0.55f) / 3), // D3, BC6, A6
1530 ((0.60f + 2 * 0.65f) / 3), // D3, BC7, A7
1531 ((0.60f + 2 * 0.75f) / 3) // D3, BC8, A8
1532 };
1533
1534 constexpr float eta_EB[17] = {
1535 ((1.00f + 1.05f + 1.15f) / 3), // D5, B11, A12
1536 ((1.00f + 1.15f + 1.15f) / 3), // D5, B12, A12
1537 ((1.00f + 1.15f + 1.25f) / 3), // D5, B12, A13
1538 ((1.00f + 1.25f + 1.15f) / 3), // D5, B13, A12
1539 ((1.00f + 1.25f + 1.25f) / 3), // D5, B13, A13
1540 ((1.00f + 1.25f + 1.35f) / 3), // D5, B13, A14
1541 ((1.20f + 1.05f + 1.15f) / 3), // D6, B11, A12
1542 ((1.20f + 1.15f + 1.15f) / 3), // D6, B12, A12
1543 ((1.20f + 1.15f + 1.25f) / 3), // D6, B12, A13
1544 ((1.20f + 1.25f + 1.15f) / 3), // D6, B13, A12
1545 ((1.20f + 1.25f + 1.25f) / 3), // D6, B13, A13
1546 ((1.20f + 1.25f + 1.35f) / 3), // D6, B13, A14
1547 ((1.20f + 1.35f + 1.25f) / 3), // D6, B14, A13
1548 ((1.20f + 1.35f + 1.35f) / 3), // D6, B14, A14
1549 ((1.20f + 1.35f + 1.45f) / 3), // D6, B14, A15
1550 ((1.20f + 1.45f + 1.35f) / 3), // D6, B15, A14
1551 ((1.20f + 1.45f + 1.45f) / 3) // D6, B15, A15
1552 };
1553
1554 // Transverse energy - 2 words
1555 sumE[0].push_back((float) ((int32_t) (*p++) - 9000));
1556 sumE[1].push_back((float) ((int32_t) (*p++) - 9000));
1557
1558 // Muon tagging
1559
1560 int NMuons = (int) (size - 5) / 2;
1561
1562 for (int mu = 0; mu < NMuons; ++mu) {
1563
1564 w = (*p);
1565
1566 Mu_energy2 = w & 0x1FFFFFF; // 25 bits
1567 Mu_pattern = (w >> 25) & 0x1F; // 5 bits
1568 Mu_drawer = (w >> 30) & 1; // 1 bit
1569 Mu_quality = w >> 31; // 1 bit
1570
1571 word[Mu_drawer].push_back(w);
1572
1573 w = *(p + 1);
1574
1575 Mu_energy0 = w & 0xFFFF; // 16 bits
1576 Mu_energy1 = w >> 16; // 16 bits
1577
1578 word[Mu_drawer].push_back(w);
1579
1580 // Muon eta coordinate
1581 switch (frag >> 12) {
1582 case 1:
1583 eta[Mu_drawer].push_back(eta_LB[Mu_pattern]);
1584 break;
1585 case 2:
1586 eta[Mu_drawer].push_back(-eta_LB[Mu_pattern]);
1587 break;
1588 case 3:
1589 eta[Mu_drawer].push_back(eta_EB[Mu_pattern]);
1590 break;
1591 case 4:
1592 eta[Mu_drawer].push_back(-eta_EB[Mu_pattern]);
1593 break;
1594 default:
1595 ATH_MSG_WARNING("Unknown fragment: " << (frag >> 8));
1596 break;
1597 }
1598
1599 // Energy deposited in TileCal by the muon (MeV)
1600 energy0[Mu_drawer].push_back(Mu_energy0 / 2.);
1601 energy1[Mu_drawer].push_back(Mu_energy1 / 2.);
1602 energy2[Mu_drawer].push_back(Mu_energy2 / 2.);
1603
1604 // Muon quality factor
1605 quality[Mu_drawer].push_back(Mu_quality);
1606
1607 p += 2;
1608 }
1609
1610 for (unsigned int i = 0; i < 2; ++i) {
1611
1612 // frag ID
1613 int fragId = (((frag & 0xF000) >> 4) | nDrawer[i]);
1614
1615 // store sumEt
1616 (*pL2[m_hashFunc(fragId)]).setEt(std::move(sumE[i]));
1617
1618 // store Muon data
1619 (*pL2[m_hashFunc(fragId)]).setMu(std::move(eta[i]), std::move(energy0[i]), std::move(energy1[i]), std::move(energy2[i]),
1620 std::move(quality[i]), std::move(word[i]));
1621 }
1622
1623 return;
1624}
1625
1626void TileROD_Decoder::unpack_frag11(uint32_t /* version */, const uint32_t* p,
1627 TileL2Container & pL2,
1628 int frag_id, int /* drawer_type */) const {
1629 // MTag-MET fragment 0x11 (full mode)
1630
1631 // second word is frag ID and frag type
1632 int size = *(p);
1633 int frag = (frag_id>0) ? frag_id : *(p + 1) & 0xFFFF;
1634
1635 p += 2; // 2 words so far
1636
1637 uint32_t w;
1638 uint32_t Mu_energy0;
1639 uint32_t Mu_energy1;
1640 uint32_t Mu_energy2;
1641 uint32_t Mu_pattern;
1642 //uint32_t Mu_drawer;
1643 uint32_t Mu_quality;
1644
1645 std::vector<unsigned int> word;
1646 std::vector<float> eta;
1647 std::vector<float> energy0;
1648 std::vector<float> energy1;
1649 std::vector<float> energy2;
1650 std::vector<unsigned int> quality;
1651
1652 constexpr float eta_LB[9] = {
1653 ((0.00f + 2 * 0.05f) / 3), // D0, BC1, A1
1654 ((0.20f + 2 * 0.15f) / 3), // D1, BC2, A2
1655 ((0.20f + 2 * 0.25f) / 3), // D1, BC3, A3
1656 ((0.40f + 2 * 0.35f) / 3), // D2, BC4, A4
1657 ((0.40f + 2 * 0.45f) / 3), // D2, BC5, A5
1658 ((0.40f + 2 * 0.55f) / 3), // D2, BC6, A6
1659 ((0.60f + 2 * 0.55f) / 3), // D3, BC6, A6
1660 ((0.60f + 2 * 0.65f) / 3), // D3, BC7, A7
1661 ((0.60f + 2 * 0.75f) / 3) // D3, BC8, A8
1662 };
1663
1664 constexpr float eta_EB[17] = {
1665 ((1.00f + 1.05f + 1.15f) / 3), // D5, B11, A12
1666 ((1.00f + 1.15f + 1.15f) / 3), // D5, B12, A12
1667 ((1.00f + 1.15f + 1.25f) / 3), // D5, B12, A13
1668 ((1.00f + 1.25f + 1.15f) / 3), // D5, B13, A12
1669 ((1.00f + 1.25f + 1.25f) / 3), // D5, B13, A13
1670 ((1.00f + 1.25f + 1.35f) / 3), // D5, B13, A14
1671 ((1.20f + 1.05f + 1.15f) / 3), // D6, B11, A12
1672 ((1.20f + 1.15f + 1.15f) / 3), // D6, B12, A12
1673 ((1.20f + 1.15f + 1.25f) / 3), // D6, B12, A13
1674 ((1.20f + 1.25f + 1.15f) / 3), // D6, B13, A12
1675 ((1.20f + 1.25f + 1.25f) / 3), // D6, B13, A13
1676 ((1.20f + 1.25f + 1.35f) / 3), // D6, B13, A14
1677 ((1.20f + 1.35f + 1.25f) / 3), // D6, B14, A13
1678 ((1.20f + 1.35f + 1.35f) / 3), // D6, B14, A14
1679 ((1.20f + 1.35f + 1.45f) / 3), // D6, B14, A15
1680 ((1.20f + 1.45f + 1.35f) / 3), // D6, B15, A14
1681 ((1.20f + 1.45f + 1.45f) / 3) // D6, B15, A15
1682 };
1683
1684 // Transverse energy
1685 std::vector<float> sumE(1, (float) ((int32_t) (*p++) - 9000));
1686 (*pL2[m_hashFunc(frag)]).setEt(std::move(sumE));
1687
1688 // Muon tagging
1689
1690 int NMuons = (int) (size - 4) / 2;
1691
1692 for (int mu = 0; mu < NMuons; ++mu) {
1693
1694 w = (*p);
1695
1696 Mu_energy2 = w & 0x1FFFFFF; // 25 bits
1697 Mu_pattern = (w >> 25) & 0x1F; // 5 bits
1698 //Mu_drawer = (w >> 30) & 1; // 1 bit
1699 Mu_quality = w >> 31; // 1 bit
1700
1701 word.push_back(w);
1702
1703 w = *(p + 1);
1704
1705 Mu_energy0 = w & 0xFFFF; // 16 bits
1706 Mu_energy1 = w >> 16; // 16 bits
1707
1708 word.push_back(w);
1709
1710 // Muon eta coordinate
1711 switch (frag >> 8) {
1712 case 1:
1713 eta.push_back(eta_LB[Mu_pattern]);
1714 break;
1715 case 2:
1716 eta.push_back(-eta_LB[Mu_pattern]);
1717 break;
1718 case 3:
1719 eta.push_back(eta_EB[Mu_pattern]);
1720 break;
1721 case 4:
1722 eta.push_back(-eta_EB[Mu_pattern]);
1723 break;
1724 default:
1725 ATH_MSG_WARNING("Unknown fragment: " << (frag >> 8));
1726 break;
1727 }
1728
1729 // Energy deposited in TileCal by the muon (MeV)
1730 energy0.push_back(Mu_energy0 / 2.);
1731 energy1.push_back(Mu_energy1 / 2.);
1732 energy2.push_back(Mu_energy2 / 2.);
1733
1734 // Muon quality factor
1735 quality.push_back(Mu_quality);
1736
1737 p += 2;
1738 }
1739
1740 (*pL2[m_hashFunc(frag)]).setMu(std::move(eta), std::move(energy0),
1741 std::move(energy1), std::move(energy2), std::move(quality), std::move(word));
1742
1743 return;
1744}
1745
1746void TileROD_Decoder::unpack_frag12(uint32_t /* version */, const uint32_t* p,
1747 TileL2Container & pL2,
1748 int frag_id, int /* drawer_type */) const {
1749 // MTag fragment 0x12 (staging mode)
1750
1751 // second word is frag ID and frag type
1752 int size = *(p);
1753 int frag = (frag_id>0) ? frag_id : *(p + 1) & 0xFFFF;
1754
1755 int nDrawer[2];
1756 nDrawer[0] = frag & 0x3F;
1757 nDrawer[1] = (frag & 0xFC0) >> 6;
1758
1759 p += 2; // 2 words so far
1760
1761 uint32_t w;
1762 uint32_t Mu_energy0;
1763 uint32_t Mu_energy1;
1764 uint32_t Mu_energy2;
1765 uint32_t Mu_pattern;
1766 uint32_t Mu_drawer;
1767 uint32_t Mu_quality;
1768
1769 std::vector<unsigned int> word[2];
1770 std::vector<float> eta[2];
1771 std::vector<float> energy0[2];
1772 std::vector<float> energy1[2];
1773 std::vector<float> energy2[2];
1774 std::vector<unsigned int> quality[2];
1775
1776 constexpr float eta_LB[9] = {
1777 ((0.00f + 2 * 0.05f) / 3), // D0, BC1, A1
1778 ((0.20f + 2 * 0.15f) / 3), // D1, BC2, A2
1779 ((0.20f + 2 * 0.25f) / 3), // D1, BC3, A3
1780 ((0.40f + 2 * 0.35f) / 3), // D2, BC4, A4
1781 ((0.40f + 2 * 0.45f) / 3), // D2, BC5, A5
1782 ((0.40f + 2 * 0.55f) / 3), // D2, BC6, A6
1783 ((0.60f + 2 * 0.55f) / 3), // D3, BC6, A6
1784 ((0.60f + 2 * 0.65f) / 3), // D3, BC7, A7
1785 ((0.60f + 2 * 0.75f) / 3) // D3, BC8, A8
1786 };
1787
1788 constexpr float eta_EB[17] = {
1789 ((1.00f + 1.05f + 1.15f) / 3), // D5, B11, A12
1790 ((1.00f + 1.15f + 1.15f) / 3), // D5, B12, A12
1791 ((1.00f + 1.15f + 1.25f) / 3), // D5, B12, A13
1792 ((1.00f + 1.25f + 1.15f) / 3), // D5, B13, A12
1793 ((1.00f + 1.25f + 1.25f) / 3), // D5, B13, A13
1794 ((1.00f + 1.25f + 1.35f) / 3), // D5, B13, A14
1795 ((1.20f + 1.05f + 1.15f) / 3), // D6, B11, A12
1796 ((1.20f + 1.15f + 1.15f) / 3), // D6, B12, A12
1797 ((1.20f + 1.15f + 1.25f) / 3), // D6, B12, A13
1798 ((1.20f + 1.25f + 1.15f) / 3), // D6, B13, A12
1799 ((1.20f + 1.25f + 1.25f) / 3), // D6, B13, A13
1800 ((1.20f + 1.25f + 1.35f) / 3), // D6, B13, A14
1801 ((1.20f + 1.35f + 1.25f) / 3), // D6, B14, A13
1802 ((1.20f + 1.35f + 1.35f) / 3), // D6, B14, A14
1803 ((1.20f + 1.35f + 1.45f) / 3), // D6, B14, A15
1804 ((1.20f + 1.45f + 1.35f) / 3), // D6, B15, A14
1805 ((1.20f + 1.45f + 1.45f) / 3) // D6, B15, A15
1806 };
1807
1808 int NMuons = (int) (size - 3) / 2;
1809
1810 for (int mu = 0; mu < NMuons; ++mu) {
1811
1812 w = (*p);
1813
1814 Mu_energy2 = w & 0x1FFFFFF; // 25 bits
1815 Mu_pattern = (w >> 25) & 0x1F; // 5 bits
1816 Mu_drawer = (w >> 30) & 1; // 1 bit
1817 Mu_quality = w >> 31; // 1 bit
1818
1819 word[Mu_drawer].push_back(w);
1820
1821 w = *(p + 1);
1822
1823 Mu_energy0 = w & 0xFFFF; // 16 bits
1824 Mu_energy1 = w >> 16; // 16 bits
1825
1826 word[Mu_drawer].push_back(w);
1827
1828 // Muon eta coordinate
1829 switch (frag >> 12) {
1830 case 1:
1831 eta[Mu_drawer].push_back(eta_LB[Mu_pattern]);
1832 break;
1833 case 2:
1834 eta[Mu_drawer].push_back(-eta_LB[Mu_pattern]);
1835 break;
1836 case 3:
1837 eta[Mu_drawer].push_back(eta_EB[Mu_pattern]);
1838 break;
1839 case 4:
1840 eta[Mu_drawer].push_back(-eta_EB[Mu_pattern]);
1841 break;
1842 default:
1843 ATH_MSG_WARNING("Unknown fragment: " << (frag >> 8));
1844 break;
1845 }
1846
1847 // Energy deposited in TileCal by the muon (MeV)
1848 energy0[Mu_drawer].push_back(Mu_energy0 / 2.);
1849 energy1[Mu_drawer].push_back(Mu_energy1 / 2.);
1850 energy2[Mu_drawer].push_back(Mu_energy2 / 2.);
1851
1852 // Muon quality factor
1853 quality[Mu_drawer].push_back(Mu_quality);
1854
1855 p += 2;
1856 }
1857
1858 for (unsigned int i = 0; i < 2; ++i) {
1859
1860 // frag ID
1861 int fragId = (((frag & 0xF000) >> 4) | nDrawer[i]);
1862
1863 (*pL2[m_hashFunc(fragId)]).setMu(std::move(eta[i]), std::move(energy0[i]), std::move(energy1[i]), std::move(energy2[i]),
1864 std::move(quality[i]), std::move(word[i]));
1865
1866 }
1867
1868 return;
1869}
1870
1871void TileROD_Decoder::unpack_frag13(uint32_t /* version */, const uint32_t* p,
1872 TileL2Container & pL2,
1873 int frag_id, int /* drawer_type */) const {
1874 // MTag fragment 0x13 (full mode)
1875
1876 // second word is frag ID and frag type
1877 int size = *(p);
1878 int frag = (frag_id>0) ? frag_id : *(p + 1) & 0xFFFF;
1879
1880 p += 2; // 2 words so far
1881
1882 uint32_t w;
1883 uint32_t Mu_energy0;
1884 uint32_t Mu_energy1;
1885 uint32_t Mu_energy2;
1886 uint32_t Mu_pattern;
1887 //uint32_t Mu_drawer;
1888 uint32_t Mu_quality;
1889
1890 std::vector<unsigned int> word;
1891 std::vector<float> eta;
1892 std::vector<float> energy0;
1893 std::vector<float> energy1;
1894 std::vector<float> energy2;
1895 std::vector<unsigned int> quality;
1896
1897 constexpr float eta_LB[9] = {
1898 ((0.00f + 2 * 0.05f) / 3), // D0, BC1, A1
1899 ((0.20f + 2 * 0.15f) / 3), // D1, BC2, A2
1900 ((0.20f + 2 * 0.25f) / 3), // D1, BC3, A3
1901 ((0.40f + 2 * 0.35f) / 3), // D2, BC4, A4
1902 ((0.40f + 2 * 0.45f) / 3), // D2, BC5, A5
1903 ((0.40f + 2 * 0.55f) / 3), // D2, BC6, A6
1904 ((0.60f + 2 * 0.55f) / 3), // D3, BC6, A6
1905 ((0.60f + 2 * 0.65f) / 3), // D3, BC7, A7
1906 ((0.60f + 2 * 0.75f) / 3) // D3, BC8, A8
1907 };
1908
1909 constexpr float eta_EB[17] = {
1910 ((1.00f + 1.05f + 1.15f) / 3), // D5, B11, A12
1911 ((1.00f + 1.15f + 1.15f) / 3), // D5, B12, A12
1912 ((1.00f + 1.15f + 1.25f) / 3), // D5, B12, A13
1913 ((1.00f + 1.25f + 1.15f) / 3), // D5, B13, A12
1914 ((1.00f + 1.25f + 1.25f) / 3), // D5, B13, A13
1915 ((1.00f + 1.25f + 1.35f) / 3), // D5, B13, A14
1916 ((1.20f + 1.05f + 1.15f) / 3), // D6, B11, A12
1917 ((1.20f + 1.15f + 1.15f) / 3), // D6, B12, A12
1918 ((1.20f + 1.15f + 1.25f) / 3), // D6, B12, A13
1919 ((1.20f + 1.25f + 1.15f) / 3), // D6, B13, A12
1920 ((1.20f + 1.25f + 1.25f) / 3), // D6, B13, A13
1921 ((1.20f + 1.25f + 1.35f) / 3), // D6, B13, A14
1922 ((1.20f + 1.35f + 1.25f) / 3), // D6, B14, A13
1923 ((1.20f + 1.35f + 1.35f) / 3), // D6, B14, A14
1924 ((1.20f + 1.35f + 1.45f) / 3), // D6, B14, A15
1925 ((1.20f + 1.45f + 1.35f) / 3), // D6, B15, A14
1926 ((1.20f + 1.45f + 1.45f) / 3) // D6, B15, A15
1927 };
1928
1929 int NMuons = (int) (size - 3) / 2;
1930
1931 for (int mu = 0; mu < NMuons; ++mu) {
1932
1933 w = (*p);
1934
1935 Mu_energy2 = w & 0x1FFFFFF; // 25 bits
1936 Mu_pattern = (w >> 25) & 0x1F; // 5 bits
1937 //Mu_drawer = (w >> 30) & 1; // 1 bit
1938 Mu_quality = w >> 31; // 1 bit
1939
1940 word.push_back(w);
1941
1942 w = *(p + 1);
1943
1944 Mu_energy0 = w & 0xFFFF; // 16 bits
1945 Mu_energy1 = w >> 16; // 16 bits
1946
1947 word.push_back(w);
1948
1949 // Muon eta coordinate
1950 switch (frag >> 8) {
1951 case 1:
1952 eta.push_back(eta_LB[Mu_pattern]);
1953 break;
1954 case 2:
1955 eta.push_back(-eta_LB[Mu_pattern]);
1956 break;
1957 case 3:
1958 eta.push_back(eta_EB[Mu_pattern]);
1959 break;
1960 case 4:
1961 eta.push_back(-eta_EB[Mu_pattern]);
1962 break;
1963 default:
1964 ATH_MSG_WARNING("Unknown fragment: " << (frag >> 8));
1965 break;
1966 }
1967
1968 // Energy deposited in TileCal by the muon (MeV)
1969 energy0.push_back(Mu_energy0 / 2.);
1970 energy1.push_back(Mu_energy1 / 2.);
1971 energy2.push_back(Mu_energy2 / 2.);
1972
1973 // Muon quality factor
1974 quality.push_back(Mu_quality);
1975
1976 p += 2;
1977 }
1978
1979 (*pL2[m_hashFunc(frag)]).setMu(std::move(eta), std::move(energy0),
1980 std::move(energy1), std::move(energy2), std::move(quality), std::move(word));
1981
1982 return;
1983}
1984
1985void TileROD_Decoder::unpack_frag14(uint32_t /* version */, const uint32_t* p,
1986 TileL2Container & pL2,
1987 int frag_id, int /* drawer_type */) const {
1988 // Met fragment 0x14 (staging mode) - obsolete, now sumEt is part of frag4/frag5
1989
1990 // second word is frag ID and frag type
1991 int frag = (frag_id>0) ? frag_id : *(p + 1) & 0xFFFF;
1992
1993 int nDrawer[2];
1994 nDrawer[0] = frag & 0x3F;
1995 nDrawer[1] = (frag & 0xFC0) >> 6;
1996
1997 p += 2; // 2 words somethingm far
1998
1999 for (unsigned int i = 0; i < 2; ++i) {
2000
2001 int fragId = (((frag & 0xF000) >> 4) | nDrawer[i]);
2002
2003 float sumE = (float) ((int32_t) (*p) - 9000);
2004 (*pL2[m_hashFunc(fragId)]).setEt(std::vector<float>{sumE});
2005
2006 ++p;
2007 }
2008
2009 return;
2010}
2011
2012void TileROD_Decoder::unpack_frag15(uint32_t /* version */, const uint32_t* p,
2013 TileL2Container & pL2,
2014 int frag_id, int /* drawer_type */) const {
2015 // Met fragment 0x15 (full mode) - obsolete, now sumEt is part of frag4/frag5
2016
2017 // second word is frag ID and frag type
2018 int frag = (frag_id>0) ? frag_id : *(p + 1) & 0xFFFF;
2019
2020 p += 2; // 2 words so far
2021
2022 std::vector<float> sumE(1);
2023
2024 sumE[0] = (float) ((int32_t) (*p) - 9000);
2025 (*pL2[m_hashFunc(frag)]).setEt(std::move(sumE));
2026
2027 return;
2028}
2029
2030void TileROD_Decoder::unpack_frag16(uint32_t version, const uint32_t* p,
2031 TileLaserObject & laserObject) const {
2032
2033 //frag ID
2034
2035 //int frag = *(p+1) & 0xFFFF;
2036 //int type = *(p+1) >>16;
2037
2038 // pointer to current data word
2039 const uint32_t *pData;
2040
2041 //position of first data word, skip the first two words of the header fragment
2042
2043 pData = p + 2;
2044
2045 int counter = 0;
2046
2047 counter = *pData;
2048
2049 ++pData;
2050
2051 int reqAmp = 0;
2052 int filt = 0;
2053 //int rawfilt=0;
2054 //int status=0;
2055 bool errorFlag = false;
2056
2057 if ((*pData & 0xFF000000) == 0x20000000) {
2058
2059 if (version == 1) {
2060
2061 reqAmp = *pData & 0xFFFF;
2062
2063 } else {
2064
2065 reqAmp = *pData & 0xFFFF;
2066
2067 // rawfilt = (*pData >>16) & 0xF;
2068
2069 if (version == 2) {
2070 filt = (((*pData >> 16) & 7) ^ 7) + 2;
2071 } else {
2072 filt = 9 - (((*pData >> 17) & 1) * 4 + ((*pData >> 18) & 1) * 2 + ((*pData >> 19) & 1));
2073 }
2074
2075 if (((*pData >> 16) & 1) == 1) filt = 0; // Filter wheel moving
2076
2077 if (filt > 8) filt -= 8;
2078 }
2079 //status = (*pData >>20) & 0xF;
2080
2081 } else {
2082 errorFlag = true;
2084 ATH_MSG_WARNING( "In decoding word 20" );
2085 }
2086
2087 ++pData;
2088
2089 //int delay=0;
2090 int measAmp = 0;
2091
2092 if ((*pData & 0xFF000000) == 0x21000000) {
2093
2094 measAmp = *pData & 0xFFF;
2095 //delay = (*pData >>12) & 0xFFF;
2096
2097 } else {
2098 errorFlag = true;
2100 ATH_MSG_WARNING( "In decoding word 21" );
2101 }
2102
2103 ++pData;
2104
2105 //int status1=0;
2106 int tdc1 = 0;
2107 int tdc2 = 0;
2108
2109 if ((*pData & 0xFF000000) == 0x22000000) {
2110
2111 if (version == 1) {
2112
2113 tdc1 = (*pData >> 16) & 0xF;
2114 tdc2 = (*pData >> 20) & 0xF;
2115 } else {
2116
2117 tdc1 = *pData & 0xFFFF;
2118
2119 }
2120
2121 } else {
2122 errorFlag = true;
2124 ATH_MSG_WARNING( "In decoding word 22" );
2125
2126 }
2127
2128 ++pData;
2129
2130 //int status2=0;
2131 //int tdc2=0;
2132
2133 if ((*pData & 0xFF000000) == 0x23000000) {
2134
2135 if (version == 1) {
2136
2137 tdc2 = (*pData >> 12) & 0xFFF;
2138 tdc1 = *pData & 0xFFF;
2139
2140 } else {
2141
2142 tdc2 = *pData & 0xFFFF;
2143
2144 //status2 = (*pData >>16) & 0xFF;
2145 }
2146
2147 } else {
2148 errorFlag = true;
2150 ATH_MSG_WARNING( "In decoding word 23" );
2151 }
2152
2153 ++pData;
2154
2155 int chan0 = 0;
2156 int chan1 = 0;
2157
2158 if ((*pData & 0xFF000000) == 0x44000000) {
2159
2160 chan0 = 4095 - (*pData & 0xFFF);
2161 chan1 = 4095 - ((*pData >> 12) & 0xFFF);
2162
2163 } else {
2164 errorFlag = true;
2166 ATH_MSG_WARNING( "In decoding word 24" );
2167 }
2168
2169 ++pData;
2170
2171 int chan2 = 0;
2172 int chan3 = 0;
2173
2174 if ((*pData & 0xFF000000) == 0x45000000) {
2175
2176 chan2 = 4095 - (*pData & 0xFFF);
2177 chan3 = 4095 - ((*pData >> 12) & 0xFFF);
2178
2179 } else {
2180 errorFlag = true;
2182 ATH_MSG_WARNING( "In decoding word 25" );
2183 }
2184
2185 ++pData;
2186
2187 int chan4 = 0;
2188 int chan5 = 0;
2189
2190 if ((*pData & 0xFF000000) == 0x46000000) {
2191
2192 chan4 = 4095 - (*pData & 0xFFF);
2193 chan5 = 4095 - ((*pData >> 12) & 0xFFF);
2194
2195 } else {
2196 errorFlag = true;
2198 ATH_MSG_WARNING( "In decoding word 26" );
2199 }
2200
2201 ++pData;
2202
2203 //int chan6=0;
2204 //int chan7=0;
2205
2206 if ((*pData & 0xFF000000) == 0x47000000) {
2207
2208 //chan6 = 4095 - (*pData & 0xFFF);
2209 //chan7 = 4095 - ((*pData >>12) & 0xFFF);
2210
2211 } else {
2212 errorFlag = true;
2214 ATH_MSG_WARNING( "In decoding word 27" );
2215 }
2216
2217 ++pData;
2218
2219 int meanPed_diode1 = 0;
2220 int rmsPed_diode1 = 0;
2221
2222 double MeanPed_diode1 = 0;
2223 double RmsPed_diode1 = 0;
2224
2225 rmsPed_diode1 = *pData & 0xFFFF;
2226 meanPed_diode1 = (*pData >> 16) & 0xFFFF;
2227
2228 MeanPed_diode1 = static_cast<double>(meanPed_diode1) * 0.1;
2229
2230 RmsPed_diode1 = static_cast<double>(rmsPed_diode1) * 0.01;
2231
2232 ++pData;
2233
2234 int meanPed_diode2 = 0;
2235 int rmsPed_diode2 = 0;
2236
2237 double MeanPed_diode2 = 0;
2238 double RmsPed_diode2 = 0;
2239
2240 rmsPed_diode2 = *pData & 0xFFFF;
2241 meanPed_diode2 = (*pData >> 16) & 0xFFFF;
2242
2243 MeanPed_diode2 = static_cast<double>(meanPed_diode2) * 0.1;
2244
2245 RmsPed_diode2 = static_cast<double>(rmsPed_diode2) * 0.01;
2246
2247 ++pData;
2248
2249 int meanPed_diode3 = 0;
2250 int rmsPed_diode3 = 0;
2251
2252 double MeanPed_diode3 = 0;
2253 double RmsPed_diode3 = 0;
2254
2255 rmsPed_diode3 = *pData & 0xFFFF;
2256 meanPed_diode3 = (*pData >> 16) & 0xFFFF;
2257
2258 MeanPed_diode3 = static_cast<double>(meanPed_diode3) * 0.1;
2259
2260 RmsPed_diode3 = static_cast<double>(rmsPed_diode3) * 0.01;
2261
2262 ++pData;
2263
2264 int meanPed_diode4 = 0;
2265 int rmsPed_diode4 = 0;
2266
2267 double MeanPed_diode4 = 0;
2268 double RmsPed_diode4 = 0;
2269
2270 rmsPed_diode4 = *pData & 0xFFFF;
2271 meanPed_diode4 = (*pData >> 16) & 0xFFFF;
2272
2273 MeanPed_diode4 = static_cast<double>(meanPed_diode4) * 0.1;
2274
2275 RmsPed_diode4 = static_cast<double>(rmsPed_diode4) * 0.01;
2276
2277 ++pData;
2278
2279 int meanPed_pmt1 = 0;
2280 int rmsPed_pmt1 = 0;
2281
2282 double MeanPed_pmt1 = 0;
2283 double RmsPed_pmt1 = 0;
2284
2285 rmsPed_pmt1 = *pData & 0xFFFF;
2286 meanPed_pmt1 = (*pData >> 16) & 0xFFFF;
2287
2288 MeanPed_pmt1 = static_cast<double>(meanPed_pmt1) * 0.1;
2289
2290 RmsPed_pmt1 = static_cast<double>(rmsPed_pmt1) * 0.01;
2291
2292 ++pData;
2293
2294 int meanPed_pmt2 = 0;
2295 int rmsPed_pmt2 = 0;
2296
2297 double MeanPed_pmt2 = 0;
2298 double RmsPed_pmt2 = 0;
2299
2300 rmsPed_pmt2 = *pData & 0xFFFF;
2301 meanPed_pmt2 = (*pData >> 16) & 0xFFFF;
2302
2303 MeanPed_pmt2 = static_cast<double>(meanPed_pmt2) * 0.1;
2304
2305 RmsPed_pmt2 = static_cast<double>(rmsPed_pmt2) * 0.01;
2306
2307 ++pData;
2308
2309 time_t lastPedMeas = *pData;
2310 //struct tm *time = localtime(&lastPedMeas);
2311 //printf("Date is %d/%02d/%02d\n", time->tm_year+1900, time->tm_mon+1, time->tm_mday);
2312 //printf("Time is %02d:%02d\n", time->tm_hour, time->tm_min);
2313
2314 ++pData;
2315
2316 int meanAlpha_diode1 = 0;
2317 int rmsAlpha_diode1 = 0;
2318
2319 double MeanAlpha_diode1 = 0;
2320 double RmsAlpha_diode1 = 0;
2321
2322 rmsAlpha_diode1 = *pData & 0xFFFF;
2323 meanAlpha_diode1 = (*pData >> 16) & 0xFFFF;
2324
2325 MeanAlpha_diode1 = static_cast<double>(meanAlpha_diode1) * 0.1;
2326
2327 RmsAlpha_diode1 = static_cast<double>(rmsAlpha_diode1) * 0.01;
2328
2329 ++pData;
2330
2331 int meanAlpha_diode2 = 0;
2332 int rmsAlpha_diode2 = 0;
2333
2334 double MeanAlpha_diode2 = 0;
2335 double RmsAlpha_diode2 = 0;
2336
2337 rmsAlpha_diode2 = *pData & 0xFFFF;
2338 meanAlpha_diode2 = (*pData >> 16) & 0xFFFF;
2339
2340 MeanAlpha_diode2 = static_cast<float>(meanAlpha_diode2) * 0.1;
2341
2342 RmsAlpha_diode2 = static_cast<float>(rmsAlpha_diode2) * 0.01;
2343
2344 ++pData;
2345
2346 // ATH_MSG_VERBOSE( "Diode 2 value is " << MeanAlpha_diode2 );
2347
2348 int meanAlpha_diode3 = 0;
2349 int rmsAlpha_diode3 = 0;
2350
2351 double MeanAlpha_diode3 = 0;
2352 double RmsAlpha_diode3 = 0;
2353
2354 rmsAlpha_diode3 = *pData & 0xFFFF;
2355 meanAlpha_diode3 = (*pData >> 16) & 0xFFFF;
2356
2357 MeanAlpha_diode3 = static_cast<double>(meanAlpha_diode3) * 0.1;
2358
2359 RmsAlpha_diode3 = static_cast<double>(rmsAlpha_diode3) * 0.01;
2360
2361 ++pData;
2362
2363 int meanAlpha_diode4 = 0;
2364 int rmsAlpha_diode4 = 0;
2365
2366 double MeanAlpha_diode4 = 0;
2367 double RmsAlpha_diode4 = 0;
2368
2369 rmsAlpha_diode4 = *pData & 0xFFFF;
2370 meanAlpha_diode4 = (*pData >> 16) & 0xFFFF;
2371
2372 MeanAlpha_diode4 = static_cast<double>(meanAlpha_diode4) * 0.1;
2373
2374 RmsAlpha_diode4 = static_cast<double>(rmsAlpha_diode4) * 0.01;
2375
2376 ++pData;
2377
2378 time_t lastAlphaMeas = *pData;
2379 //tm *Time = localtime(&lastAlphaMeas);
2380 //printf("Date is %d/%02d/%02d\n", Time->tm_year+1900, Time->tm_mon+1, Time->tm_mday);
2381 //printf("Time is %02d:%02d\n", Time->tm_hour, Time->tm_min);
2382
2383 ++pData;
2384
2385 if (version > 1) {
2386
2387 //int pedAlpha_diode1=0;
2388 //int pedRMSAlpha_diode1=0;
2389
2390 //double PedAlpha_diode1=0;
2391 //double PedRMSAlpha_diode1=0;
2392
2393 //pedRMSAlpha_diode1 = *pData & 0xFFFF ;
2394 //pedAlpha_diode1 = (*pData >> 16) & 0xFFFF;
2395
2396 //PedAlpha_diode1 = static_cast<double>(pedAlpha_diode1)/10;
2397
2398 //PedRMSAlpha_diode1 = static_cast<double>(pedRMSAlpha_diode1)/100;
2399
2400 ++pData;
2401
2402 //int pedAlpha_diode2=0;
2403 //int pedRMSAlpha_diode2=0;
2404
2405 //double PedAlpha_diode2=0;
2406 //double PedRMSAlpha_diode2=0;
2407
2408 //pedRMSAlpha_diode2 = *pData & 0xFFFF ;
2409 //pedAlpha_diode2 = (*pData >> 16) & 0xFFFF;
2410
2411 //PedAlpha_diode2 = static_cast<double>(pedAlpha_diode2)/10;
2412
2413 //PedRMSAlpha_diode2 = static_cast<double>(pedRMSAlpha_diode2)/100;
2414
2415 ++pData;
2416
2417 //int pedAlpha_diode3=0;
2418 //int pedRMSAlpha_diode3=0;
2419
2420 //double PedAlpha_diode3=0;
2421 //double PedRMSAlpha_diode3=0;
2422
2423 //pedRMSAlpha_diode3 = *pData & 0xFFFF ;
2424 //pedAlpha_diode3 = (*pData >> 16) & 0xFFFF;
2425
2426 //PedAlpha_diode3 = static_cast<double>(pedAlpha_diode3)/10;
2427
2428 //PedRMSAlpha_diode3 = static_cast<double>(pedRMSAlpha_diode3)/100;
2429
2430 ++pData;
2431
2432 //int pedAlpha_diode4=0;
2433 //int pedRMSAlpha_diode4=0;
2434
2435 //double PedAlpha_diode4=0;
2436 //double PedRMSAlpha_diode4=0;
2437
2438 //pedRMSAlpha_diode4 = *pData & 0xFFFF ;
2439 //pedAlpha_diode4 = (*pData >> 16) & 0xFFFF;
2440
2441 //PedAlpha_diode4 = static_cast<double>(pedAlpha_diode4)/10;
2442
2443 //PedRMSAlpha_diode4 = static_cast<double>(pedRMSAlpha_diode4)/100;
2444
2445 ++pData;
2446
2447 //time_t lastAlphaPedMeas = *pData;
2448
2449 ++pData;
2450 }
2451
2452 int diodeTemp = 0;
2453 int seconds1 = 0;
2454
2455 double DiodeTemp = 0;
2456
2457 diodeTemp = *pData & 0xFFF;
2458 seconds1 = (*pData >> 12) & 0xFFFFF;
2459
2460 DiodeTemp = static_cast<double>(diodeTemp) * 0.1;
2461
2462 ++pData;
2463
2464 int boxTemp = 0;
2465 int seconds2 = 0;
2466
2467 double BoxTemp = 0;
2468
2469 boxTemp = *pData & 0xFFF;
2470 seconds2 = (*pData >> 12) & 0xFFFFF;
2471
2472 BoxTemp = static_cast<double>(boxTemp) * 0.1;
2473
2474 ++pData;
2475
2476 int hum = 0;
2477 int seconds3 = 0;
2478
2479 double Hum = 0;
2480
2481 hum = *pData & 0xFFF;
2482 seconds3 = (*pData >> 12) & 0xFFFFF;
2483
2484 Hum = static_cast<double>(hum) * 0.1;
2485
2486 ++pData;
2487
2488 int gasFlow = 0;
2489 int seconds4 = 0;
2490
2491 double GasFlow = 0;
2492
2493 gasFlow = *pData & 0xFFF;
2494 seconds4 = (*pData >> 12) & 0xFFFFF;
2495
2496 GasFlow = static_cast<double>(gasFlow) * 0.1;
2497
2498 ++pData;
2499
2500 int PLCstatus = 0;
2501 //int seconds5 =0;
2502
2503 PLCstatus = *pData & 0xFFF;
2504 //seconds5 = (*pData >> 12) & 0xFFFFF;
2505 int alphaPos = PLCstatus & 0x7;
2506 int LVdiodes = (PLCstatus >> 0x3) & 0x1;
2507 int HVpmts = (PLCstatus >> 0x4) & 0x3;
2508 int shutter = (PLCstatus >> 0x6) & 0x3;
2509 int interLock = (PLCstatus >> 0x8) & 0x1;
2510 int alarm = (PLCstatus >> 0x9) & 0x7;
2511
2512 laserObject.setPmt(0, chan4, tdc1, MeanPed_pmt1, RmsPed_pmt1, 0);
2513
2514 laserObject.setPmt(1, chan5, tdc2, MeanPed_pmt2, RmsPed_pmt2, 0);
2515
2516 laserObject.setDiode(0, chan0, MeanPed_diode1, RmsPed_diode1, MeanAlpha_diode1, RmsAlpha_diode1, 0, 0, 0);
2517
2518 laserObject.setDiode(1, chan1, MeanPed_diode2, RmsPed_diode2, MeanAlpha_diode2, RmsAlpha_diode2, 0, 0, 0);
2519
2520 laserObject.setDiode(2, chan2, MeanPed_diode3, RmsPed_diode3, MeanAlpha_diode3, RmsAlpha_diode3, 0, 0, 0);
2521
2522 laserObject.setDiode(3, chan3, MeanPed_diode4, RmsPed_diode4, MeanAlpha_diode4, RmsAlpha_diode4, 0, 0, 0);
2523
2524 laserObject.setControl(DiodeTemp, seconds1, BoxTemp, seconds2, GasFlow, seconds4, Hum, seconds3, lastPedMeas, lastAlphaMeas);
2525
2526 laserObject.setLaser(counter, reqAmp, measAmp, filt, 0, 1);
2527
2528 laserObject.setPLC(alphaPos, LVdiodes, HVpmts, shutter, interLock, alarm);
2529
2530 if (errorFlag) m_ErrorCounter++;
2531} // unpack_frag16
2532
2533void TileROD_Decoder::unpack_frag17(uint32_t /* version */,
2534 uint32_t sizeOverhead,
2535 const uint32_t* p,
2536 TileLaserObject & laserObject) const
2537{
2538 // first word is full frag size, first two words are not data
2539 int size = *(p);
2540 // second word is frag ID and frag type
2541 //int frag = *(p + 1) & 0xFFFF;
2542 //position of first data word, skip the first two words of the header fragment
2543 //const uint32_t *pData = p+2;
2544
2545 bool debug = msgLvl(MSG::DEBUG);
2546
2547 if (true) {
2548 int maxn=size+2-sizeOverhead;
2549 for(int n=0; n<maxn; ++n){
2550 ATH_MSG_DEBUG("WORD " << n << " (" << n+11 << ") : (DEC) " << p[n] << " (HEX) 0x" << MSG::hex << p[n] << MSG::dec );
2551 }
2552 }
2553
2554 // p[2] 00 00 00 tt Daq Type
2555 // p[3] nn nn nn nn Laser Count
2556 // p[4] rr rr mm mm rrrr = Requested Intensity mmmm = measured intensity
2557 // p[5] t0 0f dd dd t= timeout (bit 31 and 30) f = filter dddd = Delay Slama
2558 // [[6] 00 00 ll ll Linearity DAC Value
2559
2560 ATH_MSG_DEBUG("SETTING DAQ TYPE IN DECODER = " << MSG::hex << "0x" << int(p[2]) << " " << MSG::dec << int(p[2]));
2561
2562 int countr = p[3];
2563 int idiode = (p[4]>>16);
2564 int intensity = (p[4]&0xFFFF);
2565 int filter = (p[5]>>16) & 0x000F;
2566 bool qdctimeout = !((p[5]>>31) & 0x1);
2567 bool tdctimeout = !((p[5]>>30) & 0x1);
2568
2569 int timing = (p[5] & 0xFFFF);
2570 int daqtyp = p[2];
2571
2572 laserObject.setLaser(countr, idiode, intensity, filter, timing, 2);
2573 laserObject.setControl(-99,-99,-99,-99,-99,-99,-99,-99,-99,-99);
2574 laserObject.setPLC(-99,-99,-99,-99,-99,-99);
2575 laserObject.setDaqType(daqtyp);
2576 laserObject.setTimeouts(qdctimeout, tdctimeout);
2577
2578
2579 if(laserObject.isLASERII()) ATH_MSG_DEBUG("LASERII VERSION IS " << laserObject.getVersion());
2580 else ATH_MSG_DEBUG("LASERI VERSION IS " << laserObject.getVersion());
2581
2582 ATH_MSG_DEBUG("laserObject.setLaser: " << MSG::dec << "COUNTER=" << countr << " | "
2583 << "I_DIODE=" << idiode << " | "
2584 << "FILTERN=" << filter << " | "
2585 << "TIMINGD=" << timing << " | "
2586 << "DAQTYPE=" << daqtyp );
2587
2588 int las[32];
2589 double ped[32];
2590 double std[32];
2591
2592 // ATTENTION: note that HG has even index (0,2,4,...) in las[], ped[], std[] arrays
2593 static const int HG=0;
2594 static const int LG=1;
2595
2596 const uint32_t *word = p+7; // move to 7th word
2597 int adc=0;
2598 // decode 32 ADC half-words (16 low & high channels)
2599 while (adc<31) {
2600 // ll ll hh hh ADC Channel 1 & 0 (Low & High Gain)
2601 las[adc++] = 8500 - ((*word) & 0xFFFF);
2602 las[adc++] = 8500 - ((*word) >> 16);
2603 ++word;
2604 }
2605 // TDC word immediately after ADC words
2606 // aa aa bb bb aaaa = TDC N1 bbbb = TDC N0
2607 int TDC0 = (*word) & 0xFFFF;
2608 int TDC1 = (*word) >> 16;
2609
2610 if (size>130) {
2611
2612 uint32_t sum[32];
2613 uint64_t ssq[32];
2614
2615 // p[128] Nb event
2616 double nevt = double(p[128]);
2617 if(p[128]==0 || (p[128]==3072 && p[32]<21504000) ) {
2618 nevt=1024.; // HAS TO BE REMOVED!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2619 ATH_MSG_DEBUG("Nevents= " << p[128] << " => assuming 1024");
2620 }
2621
2622 if (nevt>0) {
2623
2624 word = p+32; // jump to 32th word
2625
2626 // decode sums for 16 channels (6 words per channel)
2627 for(int channel=0;channel<16;++channel) {
2628
2629 // Sum Xi channel 0
2630 // Sum Xi channel 1
2631 // Sum Xi2 LSB channel 0
2632 // Sum Xi2 MSB channel 0
2633 // Sum Xi2 LSB channel 1
2634 // Sum Xi2 MSB channel 1
2635
2636 sum[channel*2+HG] = *(word++);
2637 sum[channel*2+LG] = *(word++);
2638
2639 uint32_t lsb0 = *(word++);
2640 uint32_t msb0 = *(word++);
2641 uint32_t lsb1 = *(word++);
2642 uint32_t msb1 = *(word++);
2643 uint64_t MSB0 = (uint64_t) msb0 << 32;
2644 uint64_t MSB1 = (uint64_t) msb1 << 32;
2645 uint64_t SSQ0 = MSB0 | lsb0;
2646 uint64_t SSQ1 = MSB1 | lsb1;
2647
2648 ssq[channel*2+HG] = SSQ0;
2649 ssq[channel*2+LG] = SSQ1;
2650
2651 // COMPUTE MEAN AND STANDARD DEVIATION
2652 ped[channel*2+HG] = double(sum[channel*2+HG])/nevt;
2653 ped[channel*2+LG] = double(sum[channel*2+LG])/nevt;
2654
2655 std[channel*2+HG] = double(ssq[channel*2+HG])/nevt - ped[channel*2+HG]*ped[channel*2+HG];
2656 std[channel*2+LG] = double(ssq[channel*2+LG])/nevt - ped[channel*2+LG]*ped[channel*2+LG];
2657 if (std[channel*2+HG]>0.0) std[channel*2+HG] = sqrt(std[channel*2+HG]);
2658 if (std[channel*2+LG]>0.0) std[channel*2+LG] = sqrt(std[channel*2+LG]);
2659
2660 // PLEASE NOTE THAT LG EQUALS 1 WHEN TILEID::LOWGAIN EQUALS 0
2661 // HG EQUALS 0 WHEN TILEID::HIGHGAIN EQUALS 1
2662 // THIS CONFUSING INDEXING IS TAKEN CARE OF IN THE FOLLOWING TWO LINES AND WILL *NOT*
2663 // BE PROPAGATED FURTHER DOWN THE CHAIN. THIS MEANS THAT AFTER THIS LG=0 AND HG=1
2664 laserObject.setCalibType(int(p[31]));
2665 laserObject.setCalib(channel,int(p[31]), double(sum[channel*2+LG]), double(ssq[channel*2+LG]), nevt, TileID::LOWGAIN);
2666 laserObject.setCalib(channel,int(p[31]), double(sum[channel*2+HG]), double(ssq[channel*2+HG]), nevt, TileID::HIGHGAIN);
2667
2668 // DEBUGGING OUTPUT
2669 if(debug){
2670 ATH_MSG_DEBUG("PED CHAN=" << channel << " GAIN=LG" << " TYPE=" << laserObject.getType(channel,TileID::LOWGAIN,0) << " MEAN=" << laserObject.getMean(channel,TileID::LOWGAIN,0) << " SIGMA=" << laserObject.getSigma(channel,TileID::LOWGAIN,0) << " N=" << laserObject.getN(channel,TileID::LOWGAIN,0) << " isSet?=" << laserObject.isSet(channel,TileID::LOWGAIN,0) );
2671 ATH_MSG_DEBUG("PED CHAN=" << channel << " GAIN=HG" << " TYPE=" << laserObject.getType(channel,TileID::HIGHGAIN,0) << " MEAN=" << laserObject.getMean(channel,TileID::HIGHGAIN,0) << " SIGMA=" << laserObject.getSigma(channel,TileID::HIGHGAIN,0) << " N=" << laserObject.getN(channel,TileID::HIGHGAIN,0) << " isSet?=" << laserObject.isSet(channel,TileID::HIGHGAIN,0) );
2672
2673 ATH_MSG_DEBUG("PED CHAN=" << channel << " GAIN=LG" << " TYPE=" << laserObject.getType(channel,TileID::LOWGAIN,1) << " MEAN=" << laserObject.getMean(channel,TileID::LOWGAIN,1) << " SIGMA=" << laserObject.getSigma(channel,TileID::LOWGAIN,1) << " N=" << laserObject.getN(channel,TileID::LOWGAIN,1) << " isSet?=" << laserObject.isSet(channel,TileID::LOWGAIN,1) );
2674 ATH_MSG_DEBUG("PED CHAN=" << channel << " GAIN=HG" << " TYPE=" << laserObject.getType(channel,TileID::HIGHGAIN,1) << " MEAN=" << laserObject.getMean(channel,TileID::HIGHGAIN,1) << " SIGMA=" << laserObject.getSigma(channel,TileID::HIGHGAIN,1) << " N=" << laserObject.getN(channel,TileID::HIGHGAIN,1) << " isSet?=" << laserObject.isSet(channel,TileID::HIGHGAIN,1) );
2675
2676 ATH_MSG_DEBUG("LED CHAN=" << channel << " GAIN=LG" << " TYPE=" << laserObject.getType(channel,TileID::LOWGAIN,2) << " MEAN=" << laserObject.getMean(channel,TileID::LOWGAIN,2) << " SIGMA=" << laserObject.getSigma(channel,TileID::LOWGAIN,2) << " N=" << laserObject.getN(channel,TileID::LOWGAIN,2) << " isSet?=" << laserObject.isSet(channel,TileID::LOWGAIN,2) );
2677 ATH_MSG_DEBUG("LED CHAN=" << channel << " GAIN=HG" << " TYPE=" << laserObject.getType(channel,TileID::HIGHGAIN,2) << " MEAN=" << laserObject.getMean(channel,TileID::HIGHGAIN,2) << " SIGMA=" << laserObject.getSigma(channel,TileID::HIGHGAIN,2) << " N=" << laserObject.getN(channel,TileID::HIGHGAIN,2) << " isSet?=" << laserObject.isSet(channel,TileID::HIGHGAIN,2) );
2678
2679 ATH_MSG_DEBUG("ALP CHAN=" << channel << " GAIN=LG" << " TYPE=" << laserObject.getType(channel,TileID::LOWGAIN,3) << " MEAN=" << laserObject.getMean(channel,TileID::LOWGAIN,3) << " SIGMA=" << laserObject.getSigma(channel,TileID::LOWGAIN,3) << " N=" << laserObject.getN(channel,TileID::LOWGAIN,3) << " isSet?=" << laserObject.isSet(channel,TileID::LOWGAIN,3) );
2680 ATH_MSG_DEBUG("ALP CHAN=" << channel << " GAIN=HG" << " TYPE=" << laserObject.getType(channel,TileID::HIGHGAIN,3) << " MEAN=" << laserObject.getMean(channel,TileID::HIGHGAIN,3) << " SIGMA=" << laserObject.getSigma(channel,TileID::HIGHGAIN,3) << " N=" << laserObject.getN(channel,TileID::HIGHGAIN,3) << " isSet?=" << laserObject.isSet(channel,TileID::HIGHGAIN,3) );
2681
2682 ATH_MSG_DEBUG(MSG::hex << msb0 << " + " << lsb0 << " => " << SSQ0 <<
2683 MSG::dec << " >>> D" << channel << "(HG)"
2684 << " SUMX/N="
2685 << sum[channel*2+HG]
2686 << " / " << nevt
2687 << " = "
2688 << ped[channel*2+HG]
2689 << " SUMX2/N="
2690 << ssq[channel*2+HG]
2691 << " / " << nevt
2692 << " => STD="
2693 << std[channel*2+0]);
2694 ATH_MSG_DEBUG(MSG::hex << msb1 << " + " << lsb1 << " => " << SSQ1 <<
2695 MSG::dec << " >>> D" << channel << "(LG)"
2696 << " SUMX/N="
2697 << sum[channel*2+LG]
2698 << " / " << nevt
2699 << " = "
2700 << ped[channel*2+LG]
2701 << " SUMX2/N="
2702 << ssq[channel*2+LG]
2703 << " / " << nevt
2704 << " => STD="
2705 << std[channel*2+LG]);
2706 } // IF
2707
2708 ped[channel*2+0] = 8500. - ped[channel*2+0];
2709 ped[channel*2+1] = 8500. - ped[channel*2+1];
2710 }
2711
2712 } else { // nevt == 0
2713 ATH_MSG_DEBUG("WARNING NEVT=0");
2714 memset(ped,0,sizeof(ped));
2715 memset(std,0,sizeof(std));
2716 }
2717
2718 if (debug) {
2719 for(int channel=0;channel<16;++channel){
2720 ATH_MSG_DEBUG("HG CHANNEL " << channel << ": sig=" << las[HG+channel*2] << " ped=" << ped[HG+channel*2] << "+/-" << std[HG+channel*2]);
2721 ATH_MSG_DEBUG("LG CHANNEL " << channel << ": sig=" << las[LG+channel*2] << " ped=" << ped[LG+channel*2] << "+/-" << std[LG+channel*2]);
2722 }
2723 }
2724
2725 } else { // short fragment
2726 ATH_MSG_DEBUG("SHORT FRAGMENT, size=" << p[0] << " type=0x" << MSG::hex << p[1] << MSG::dec);
2727 memset(ped,0,sizeof(ped));
2728 memset(std,0,sizeof(std));
2729 }
2730
2731 // ATTENTION: note that HG has even index (0,2,4,...) in las[], ped[], std[] arrays
2732
2733 // STORE PMT INFORMATION
2734 //PMT1
2735 laserObject.setPmt(0,las[HG+10*2],TDC0,laserObject.getMean(10,TileID::HIGHGAIN,0),laserObject.getSigma(10,TileID::HIGHGAIN,0),TileID::HIGHGAIN);
2736 laserObject.setPmt(0,las[LG+10*2],TDC0,laserObject.getMean(10,TileID::LOWGAIN,0), laserObject.getSigma(10,TileID::LOWGAIN,0), TileID::LOWGAIN);
2737 //PMT2
2738 laserObject.setPmt(1,las[HG+14*2],TDC1,laserObject.getMean(14,TileID::HIGHGAIN,0),laserObject.getSigma(14,TileID::HIGHGAIN,0),TileID::HIGHGAIN);
2739 laserObject.setPmt(1,las[LG+14*2],TDC1,laserObject.getMean(14,TileID::LOWGAIN,0), laserObject.getSigma(14,TileID::LOWGAIN,0), TileID::LOWGAIN);
2740
2741 // STORE DIODE INFORMATION
2742 for(int diode=0;diode<10;++diode){
2743 laserObject.setDiode(diode,las[HG+diode*2],laserObject.getMean( diode,TileID::HIGHGAIN,0),
2744 laserObject.getSigma(diode,TileID::HIGHGAIN,0),
2745 laserObject.getMean( diode,TileID::HIGHGAIN,3),
2746 laserObject.getSigma(diode,TileID::HIGHGAIN,3),0.,0.,TileID::HIGHGAIN);
2747 laserObject.setDiode(diode,las[LG+diode*2],laserObject.getMean( diode,TileID::LOWGAIN,0),
2748 laserObject.getSigma(diode,TileID::LOWGAIN,0),
2749 laserObject.getMean( diode,TileID::LOWGAIN,3),
2750 laserObject.getSigma(diode,TileID::LOWGAIN,3),0.,0.,TileID::LOWGAIN);
2751 } // FOR
2752 laserObject.setDiode(10,las[HG+22],laserObject.getMean( 11,TileID::HIGHGAIN,0),
2753 laserObject.getSigma(11,TileID::HIGHGAIN,0),
2754 laserObject.getMean( 11,TileID::HIGHGAIN,3),
2755 laserObject.getSigma(11,TileID::HIGHGAIN,3),0.,0.,TileID::HIGHGAIN); // EXTERNAL CIS 0 HG
2756 laserObject.setDiode(10,las[LG+22],laserObject.getMean( 11,TileID::LOWGAIN,0),
2757 laserObject.getSigma(11,TileID::LOWGAIN,0),
2758 laserObject.getMean( 11,TileID::LOWGAIN,3),
2759 laserObject.getSigma(11,TileID::LOWGAIN,3),0.,0.,TileID::LOWGAIN); // EXTERNAL CIS 0 LG
2760 laserObject.setDiode(11,las[HG+24],laserObject.getMean( 12,TileID::HIGHGAIN,0),
2761 laserObject.getSigma(12,TileID::HIGHGAIN,0),
2762 laserObject.getMean( 12,TileID::HIGHGAIN,3),
2763 laserObject.getSigma(12,TileID::HIGHGAIN,3),0.,0.,TileID::HIGHGAIN); // INTERNAL CIS HG
2764 laserObject.setDiode(11,las[LG+24],laserObject.getMean( 12,TileID::LOWGAIN,0),
2765 laserObject.getSigma(12,TileID::LOWGAIN,0),
2766 laserObject.getMean( 12,TileID::LOWGAIN,3),
2767 laserObject.getSigma(12,TileID::LOWGAIN,3),0.,0.,TileID::LOWGAIN); // INTERNAL CIS LG
2768 laserObject.setDiode(12,las[HG+26],laserObject.getMean( 13,TileID::HIGHGAIN,0),
2769 laserObject.getSigma(13,TileID::HIGHGAIN,0),
2770 laserObject.getMean( 13,TileID::HIGHGAIN,3),
2771 laserObject.getSigma(13,TileID::HIGHGAIN,3),0.,0.,TileID::HIGHGAIN); // PHOTODIODE PHOCAL HG
2772 laserObject.setDiode(12,las[LG+26],laserObject.getMean( 13,TileID::LOWGAIN,0),
2773 laserObject.getSigma(13,TileID::LOWGAIN,0),
2774 laserObject.getMean( 13,TileID::LOWGAIN,3),
2775 laserObject.getSigma(13,TileID::LOWGAIN,3),0.,0.,TileID::LOWGAIN); // PHOTODIODE PHOCAL LG
2776 laserObject.setDiode(13,las[HG+30],laserObject.getMean( 15,TileID::HIGHGAIN,0),
2777 laserObject.getSigma(15,TileID::HIGHGAIN,0),
2778 laserObject.getMean( 15,TileID::HIGHGAIN,3),
2779 laserObject.getSigma(15,TileID::HIGHGAIN,3),0.,0.,TileID::HIGHGAIN); // EXTERNAL CIS HG
2780 laserObject.setDiode(13,las[LG+30],laserObject.getMean( 15,TileID::LOWGAIN,0),
2781 laserObject.getSigma(15,TileID::LOWGAIN,0),
2782 laserObject.getMean( 15,TileID::LOWGAIN,3),
2783 laserObject.getSigma(15,TileID::LOWGAIN,3),0.,0.,TileID::LOWGAIN); // EXTERNAL CIS LG
2784
2785} // unpack_frag17
2786
2787
2788void TileROD_Decoder::unpack_brod(uint32_t /* version */,
2789 uint32_t sizeOverhead,
2790 const uint32_t* p,
2791 pBeamVec & pBeam,
2792 int frag_id) const
2793{
2794 // first word is frag size
2795 int count = *(p);
2796 // second word is frag ID and frag type
2797 uint32_t idAndType = *(p + 1);
2798 int bs_frag = idAndType & 0xFFFF;
2799 bool is16ChannelType = (idAndType >> 16) & 1; // V775N, V792N
2800 bool is32ChannelType = (idAndType >> 17) & 1; // V775, V792
2801
2802 p += 2; // 2 words so far
2803 int datasize = count - sizeOverhead; // can be 2 or 3 words less
2804
2805 if (msgLvl(MSG::VERBOSE)) {
2806 msg(MSG::VERBOSE) << "Unpacking Beam Elements, ID=0x" << MSG::hex << frag_id << " BS frag=0x" << bs_frag
2807 << ", size=" << MSG::dec << datasize;
2808 for (int ch = 0; ch < datasize; ++ch) {
2809 if (0 == ch % 8) msg(MSG::VERBOSE) << endmsg;
2810 msg(MSG::VERBOSE) << p[ch] << " ";
2811 }
2812 msg(MSG::VERBOSE) << endmsg;
2813 }
2814
2815 if (datasize <= 0) return;
2816
2817 int frag = (frag_id>=0) ? frag_id : bs_frag;
2818 frag &= 0xff; // reset upper byte, because it's different in 2003 and 2004
2819 HWIdentifier drawerID = m_tileHWID->drawer_id(frag);
2821
2822 switch (bs_frag) {
2823
2824 /* ************************************************************************************* */
2825 /* LeCroy 1176 16bit 1ns TDC FRAG in Tile Beam crate or in Common Beam crate */
2826 case BEAM_TDC_FRAG:
2827 case COMMON_TDC1_FRAG:
2828 case COMMON_TDC2_FRAG: {
2829 if (!(is16ChannelType || is32ChannelType)) {
2830 uint32_t prev = 0xFF;
2831 std::vector<uint32_t> adc;
2832 for (int c = 0; c < datasize; ++c) {
2833 uint32_t time = *p & 0xFFFF;
2834 uint32_t flag = *p >> 16;
2835 uint32_t chan = (flag >> 1) & 0x0F;
2836 uint32_t bad = (flag >> 5) & 0x01;
2837 if (!bad) {
2838 if (prev != 0xFF) {
2839 HWIdentifier adcID = m_tileHWID->adc_id(drawerID, prev, 0);
2840 rc = new TileBeamElem(adcID, adc);
2841 pBeam.push_back(rc);
2842 adc.clear();
2843 }
2844 prev = chan;
2845 }
2846 adc.push_back(time);
2847 ++p;
2848 }
2849 if (prev != 0xFF) {
2850 HWIdentifier adcID = m_tileHWID->adc_id(drawerID, prev, 0);
2851 rc = new TileBeamElem(adcID, adc);
2852 pBeam.push_back(rc);
2853 }
2854 break;
2855 }
2856 // Fall through to default
2857 [[fallthrough]]; // silent the warning on fall through
2858 }
2859
2860 /* ************************************************************************************* */
2861 /* CAEN V775 or V775N 12 bit TDC (1count=35psec) in common beam crate */
2862 case COMMON_TOF_FRAG: {
2863
2864 uint32_t prev = 0xFF;
2865 std::vector<uint32_t> adc;
2866 for (int c = 0; c < datasize; ++c) {
2867 uint32_t chan = is16ChannelType ? (*p >> 17) & 0x3FF // take 10 bits, but 6 upper bits should be 0
2868 : (*p >> 16) & 0x7FF; // take 11 bits, but 6 upper bits should be 0
2869 if (chan > 31) {
2870 continue; // skip header or end of block
2871 }
2872 uint32_t time = *p & 0x1FFF; // uppermost bit is overflow flag
2873 if (prev != chan && ((is16ChannelType && chan < 16) || (is32ChannelType && chan < 32))) {
2874 if (prev != 0xFF) { // channel >= 32 can be only in corrupted data
2875 HWIdentifier adcID = m_tileHWID->adc_id(drawerID, prev, 0);
2876 rc = new TileBeamElem(adcID, adc);
2877 pBeam.push_back(rc);
2878 adc.clear();
2879 }
2880 prev = chan;
2881 }
2882 adc.push_back(time);
2883 ++p;
2884 }
2885 if ((is16ChannelType && prev < 16) || (is32ChannelType && prev < 32)) {
2886 HWIdentifier adcID = m_tileHWID->adc_id(drawerID, prev, 0);
2887 rc = new TileBeamElem(adcID, adc);
2888 pBeam.push_back(rc);
2889 }
2890 }
2891 break;
2892
2893 /* ************************************************************************************* */
2894 /* ADDERS FRAG */
2895 case ADD_FADC_FRAG: {
2896
2897 uint32_t val, channel[16][16];
2898 int nmodule = 4, nchan, nsamp, ch;
2899
2900 nchan = nmodule * 4;
2901 nsamp = datasize / nmodule;
2902
2903 ATH_MSG_VERBOSE(" Adders: nmod=" << nmodule << ", nchan=" << nchan
2904 << ", nsamp=" << nsamp);
2905
2906 if (nmodule * nsamp == datasize) {
2907 /* Unpack DATA */
2908 for (int m = 0; m < nmodule; ++m) {
2909 /* extract all samples for 4 channels in the module */
2910 for (int s = 0; s < nsamp; ++s) {
2911 val = *p;
2912 for (int c = 0; c < 4; ++c) {
2913 ch = m * 4 + c;
2914 if (ch < nchan)
2915 channel[ch][s] = val & 0xFF;
2916 val >>= 8;
2917 }
2918 ++p;
2919 }
2920 }
2921 /* ***** */
2922 for (ch = 0; ch < nchan; ++ch) {
2923 HWIdentifier adcID = m_tileHWID->adc_id(drawerID, ch, 0);
2924 std::vector<uint32_t> adc;
2925 adc.reserve(nsamp);
2926 for (int s = 0; s < nsamp; ++s) {
2927 adc.push_back(channel[ch][s]);
2928 }
2929 rc = new TileBeamElem(adcID, adc);
2930 pBeam.push_back(rc);
2931 }
2932 } else {
2933 ATH_MSG_WARNING("unpack_brod => Unexpected Adders size: " << MSG::dec
2934 << datasize);
2935 return;
2936 }
2937 } break;
2938
2939#ifndef LASER_OBJ_FRAG
2940#define LASER_OBJ_FRAG 0x016
2941#endif
2942#ifndef LASER2_OBJ_FRAG
2943#define LASER2_OBJ_FRAG 0x017
2944#endif
2945
2946 case LASER_OBJ_FRAG:
2947 case LASER2_OBJ_FRAG: {
2948
2949 std::vector<uint32_t> digits;
2950 for (int ch = 0; ch < datasize; ++ch) {
2951 digits.push_back((*p));
2952 ++p;
2953 }
2954 HWIdentifier adcID = m_tileHWID->adc_id(drawerID, 0, 0);
2955 rc = new TileBeamElem(adcID, digits);
2956 pBeam.push_back(rc);
2957 }
2958 break;
2959
2960 /* ************************************************************************************* */
2961 /* CAEN V792 or V792N 12 bit ADC in common beam crate */
2962 case COMMON_ADC1_FRAG:
2963 case COMMON_ADC2_FRAG: {
2964
2965 if (is16ChannelType || is32ChannelType) {
2966 uint32_t prev = 0xFF;
2967 std::vector<uint32_t> adc;
2968 for (int c = 0; c < datasize; ++c) {
2969 uint32_t chan = is16ChannelType ? (*p >> 17) & 0x3FF // take 10 bits, but 6 upper bits should be 0
2970 : (*p >> 16) & 0x7FF; // take 11 bits, but 6 upper bits should be 0
2971
2972 if (chan > 31) {
2973 continue; // skip header or end of block
2974 }
2975 uint32_t amplitude = *p & 0x1FFF; // uppermost bit is overflow flag
2976 if (prev != chan && ((is16ChannelType && chan < 16) || (is32ChannelType && chan < 32))) {
2977 if (prev != 0xFF) { // channel >= 32 can be only in corrupted data
2978 HWIdentifier adcID = m_tileHWID->adc_id(drawerID, prev, 0);
2979 rc = new TileBeamElem(adcID, adc);
2980 pBeam.push_back(rc);
2981 adc.clear();
2982 }
2983 prev = chan;
2984 }
2985 adc.push_back(amplitude);
2986 ++p;
2987 }
2988 if ((is16ChannelType && prev < 16) || (is32ChannelType && prev < 32)) {
2989 HWIdentifier adcID = m_tileHWID->adc_id(drawerID, prev, 0);
2990 rc = new TileBeamElem(adcID, adc);
2991 pBeam.push_back(rc);
2992 }
2993 break;
2994 }
2995 // Fall through to default
2996 [[fallthrough]]; // silent the warning on fall through
2997 }
2998
2999 /* ************************************************************************************* */
3000 /* OTHER FRAGS: ONE WORD = ONE CHANNEL */
3001 default: {
3002
3003 int chmax = (datasize > 16) ? 15 : datasize;
3004 for (int ch = 0; ch < chmax; ++ch) {
3005 HWIdentifier adcID = m_tileHWID->adc_id(drawerID, ch, 0);
3006 rc = new TileBeamElem(adcID, (*p));
3007 pBeam.push_back(rc);
3008 ++p;
3009 }
3010 if (chmax != datasize) {
3011 std::vector<uint32_t> digits;
3012 for (int ch = chmax; ch < datasize; ++ch) {
3013 digits.push_back((*p));
3014 ++p;
3015 }
3016 HWIdentifier adcID = m_tileHWID->adc_id(drawerID, chmax, 0);
3017 rc = new TileBeamElem(adcID, digits);
3018 pBeam.push_back(rc);
3019 }
3020 }
3021 break;
3022 }
3023
3024 return;
3025}
3026
3027StatusCode TileROD_Decoder::convert(const RawEvent* re, TileL2Container* L2Cnt) const {
3028
3029 ATH_MSG_DEBUG( "Reading L2 data from ByteStream" );
3030
3031 if (!re) {
3032 ATH_MSG_FATAL( "RawEvent passed to 'convert'-function is a null pointer!" );
3033 return StatusCode::FAILURE;
3034 }
3035
3036 //bool eValid = re->check_tree();
3037 //if (! eValid) return StatusCode::FAILURE;
3038
3039 // const VDETF& vdetf = re->compounds(); //Get subdetector fragements from the raw event.
3040 uint32_t total_sub = re->nchildren();
3041
3042 if (msgLvl(MSG::VERBOSE)) {
3043 msg(MSG::VERBOSE) << "Full Event: " << endmsg;
3044 msg(MSG::VERBOSE) << MSG::hex << "Full source ID: " << re->source_id()
3045 << MSG::dec << endmsg;
3046 msg(MSG::VERBOSE) << "Fragment size in words: " << re->fragment_size_word() << endmsg;
3047 msg(MSG::VERBOSE)<< "# of rob frags: " << total_sub << endmsg;
3048 }
3049
3050 for (uint32_t i_rob = 0; i_rob < total_sub; ++i_rob) {
3051 const uint32_t* p_rob;
3052 re->child(p_rob, i_rob);
3053 const eformat::ROBFragment<const uint32_t*> robFrag(p_rob);
3054
3055 eformat::helper::SourceIdentifier id = eformat::helper::SourceIdentifier(robFrag.source_id());
3056 unsigned int subDetId = id.subdetector_id();
3057
3058 if (subDetId >= 0x50 && subDetId < 0x60) { //Select Tile-Subdetectors
3059 fillCollectionL2(&robFrag, *L2Cnt);
3060 }
3061 }
3062
3063 // Debug
3064
3065 if (msgLvl(MSG::VERBOSE)) {
3066 msg(MSG::VERBOSE) << "convertL2: " << L2Cnt->size()
3067 << " TileL2 objects created" << endmsg;
3069 TileL2Container::const_iterator last = L2Cnt->end();
3070
3071 int num = 0;
3072 for (; ind != last; ++ind) {
3073 msg(MSG::VERBOSE) << "Ind " << num++ << " " << (std::string) (*(*ind)) << endmsg;
3074 }
3075 }
3076
3077 return StatusCode::SUCCESS;
3078}
3079
3081 uint32_t version = rob->rod_version() & 0xFFFF;
3082
3083 uint32_t error = 0;
3084 uint32_t wc = 0;
3085 uint32_t size = data_size(rob, error);
3086 const uint32_t * p = get_data(rob);
3087 int fragmin = 0xFFF, fragmax = -1;
3088
3089 int counter = 0;
3090
3091 uint32_t sizeOverhead = 2;
3092 if (size) {
3093 bool V3format = (*(p) == 0xff1234ff); // additional frag marker since Sep 2005
3094 if (!V3format && version>0xff) {
3095 V3format = true;
3097 ATH_MSG_WARNING("fillCollectionL2( corrupted frag separator 0x" << MSG::hex << (*p) << " instead of 0xff1234ff in ROB 0x" << rob->rod_source_id() << MSG::dec );
3098 }
3099 if (V3format) {
3100 ++p; // skip frag marker
3101 sizeOverhead = 3;
3102 } else {
3103 sizeOverhead = 2;
3104 }
3105 }
3106
3108
3109 int DataType = 0;
3110 while (wc < size) { // iterator over all words in a ROD
3111
3112 // first word is frag size
3113 uint32_t count = *(p);
3114 // second word is frag ID and frag type
3115 uint32_t idAndType = *(p + 1);
3116 uint32_t bs_frag_id = idAndType & 0xFFFF;
3117 int frag = hid2re->getOfflineFragID(bs_frag_id);
3118 if (frag<0) frag = bs_frag_id;
3119 const std::vector<uint32_t> & drawer_info = hid2re->getDrawerInfo(frag);
3120 int drawer_type = drawer_info.size()>2 ? static_cast<int>(drawer_info[2]) : -1;
3121 if (frag < fragmin) fragmin = frag;
3122 if (frag > fragmax) fragmax = frag;
3123 DataType = (idAndType & 0x30000000) >> 28;
3124
3125 int type = (*(p + 1) >> 16) & 0xFF;
3126
3127 if (count < sizeOverhead || count > size - wc) {
3128 int cnt = 0;
3129 for (; wc < size; ++wc, ++cnt, ++p) {
3130 if ((*p) == 0xff1234ff) {
3131 ++cnt;
3132 ++wc;
3133 ++p;
3134 break;
3135 }
3136 }
3137 if ((m_ErrorCounter++) < m_maxErrorPrint) {
3138 msg(MSG::WARNING) << "Frag " << MSG::hex << "0x" << frag
3139 << MSG::dec << " has unexpected size: " << count;
3140 if (wc < size) {
3141 msg(MSG::WARNING) << " skipping " << cnt << " words to the next frag" << endmsg;
3142 } else {
3143 msg(MSG::WARNING) << " ignoring " << cnt << " words till the end of ROD frag" << endmsg;
3144 }
3145 }
3146 continue;
3147 }
3148
3149 if (type == 4) { // frag4 which contains sum Et at the end
3150
3151 if (unpack_frag4L2(version, sizeOverhead, p, v, frag, drawer_type)) {
3152 counter++;
3153 }
3154
3155 } else if (type == 5 && m_useFrag5Reco) { // new fragment which contains sum Et
3156
3157 if (unpack_frag5L2(version, p, v, frag, drawer_type)) {
3158 counter++;
3159 }
3160
3161 } else if ((type >> 4) == 1) { // all frags 0x10-0x15 are MET or MTag frags
3162
3163 counter++;
3164
3165 switch (type) {
3166
3167 case 0x10:
3168 unpack_frag10(version, p, v, frag, drawer_type);
3169 break;
3170 case 0x11:
3171 unpack_frag11(version, p, v, frag, drawer_type);
3172 break;
3173 case 0x12:
3174 unpack_frag12(version, p, v, frag, drawer_type);
3175 break;
3176 case 0x13:
3177 unpack_frag13(version, p, v, frag, drawer_type);
3178 break;
3179 case 0x14:
3180 unpack_frag14(version, p, v, frag, drawer_type);
3181 break;
3182 case 0x15:
3183 unpack_frag15(version, p, v, frag, drawer_type);
3184 break;
3185
3186 default:
3187 int frag = *(p + 1) & 0xFFFF;
3188 ATH_MSG_WARNING( "Unknown frag type=" << type << " for frag=" << frag << " bs_frag=" << bs_frag_id);
3189 assert(0);
3190 break;
3191 }
3192 }
3193
3194 p += count;
3195 wc += count;
3196 }
3197
3198 if (wc != size) {
3199 // check word count
3200 if ((m_ErrorCounter++) < m_maxErrorPrint) {
3201 ATH_MSG_WARNING( "Incorrect ROD size: " << wc << " words instead of " << size );
3202 }
3203 assert(0);
3204 // return;
3205 }
3206
3207 if (DataType >= 3 && counter == 0 && !m_L2Builder.empty()) {
3208 if (m_L2Builder->process(fragmin, fragmax, &v).isFailure()) {
3209 ATH_MSG_ERROR( "Failure in " << m_L2Builder );
3210 return;
3211 }
3212 }
3213
3214 return;
3215}
3216
3218 uint32_t error = 0;
3219 uint32_t size = data_size(rob, error);
3220 const uint32_t * p = get_data(rob);
3221 const uint32_t ROB_to_decode = ((*p) & 0xFFFF); // Multiply by two
3222 const uint32_t virtualROBJump = ((*p) >> 16) >> 2; // Divide by four (four drawer-1ROB)
3223 if (size < ROB_to_decode * virtualROBJump + 1) {
3224 ATH_MSG_ERROR( "Declared size =" << size
3225 << "; virtualROBJump=" << virtualROBJump
3226 << "; ROB_to_decode=" << ROB_to_decode );
3227 return;
3228 }
3229 p++; // Jump first word
3230
3232
3233 std::vector<float> sumE(3, 0.0);
3234 uint32_t idAndType, bs_frag_id;
3235 int frag, hash, unit;
3236
3237 for (size_t irob = 0; irob < ROB_to_decode; ++irob) {
3238 for (size_t drawInRob = 0; drawInRob < virtualROBJump; ++drawInRob) {
3239
3240 idAndType = *(p++);
3241 bs_frag_id = idAndType & 0xFFF;
3242 frag = hid2re->getOfflineFragID(bs_frag_id);
3243 if (frag<0) frag = bs_frag_id;
3244
3245 hash = m_hashFunc(frag);
3246 if (hash > -1) {
3247 unit = (idAndType >> (32 - 2)) & 0x3;
3248 sumE[0] = Frag5_unpack_bin2sum(unit, (int)(*(p++)));
3249 sumE[1] = Frag5_unpack_bin2sum(unit, (int)(*(p++)));
3250 sumE[2] = Frag5_unpack_bin2sum(unit, (int)(*(p++)));
3251
3252 (v[hash])->setEt(std::vector<float>(sumE)); //copy since looping
3253 } else {
3254 p += 3;
3255 }
3256 } // End of drawInRob loop
3257 } // End of rob loop
3258
3259}
3260
3261StatusCode TileROD_Decoder::convertLaser(const RawEvent* re, TileLaserObject* laserObject) const {
3262
3263 ATH_MSG_DEBUG( "Reading TileLaser data from ByteStream" );
3264
3265 setLaserVersion(*laserObject);
3266
3267 if (!re) {
3268 ATH_MSG_FATAL( "RawEvent passed to 'convert'-function is a null pointer!" );
3269 return StatusCode::FAILURE;
3270 }
3271
3272 //bool eValid = re->check_tree();
3273 //if (! eValid) return StatusCode::FAILURE;
3274
3275 // const VDETF& vdetf = re->compounds(); //Get subdetector fragments from the raw event.
3276 uint32_t total_sub = re->nchildren();
3277
3278 if (msgLvl(MSG::VERBOSE)) {
3279 msg(MSG::VERBOSE) << "Full Event: " << endmsg;
3280 msg(MSG::VERBOSE) << MSG::hex << "Full source ID: " << re->source_id() << MSG::dec << endmsg;
3281 msg(MSG::VERBOSE) << "Fragment size in words: " << re->fragment_size_word() << endmsg;
3282 msg(MSG::VERBOSE) << "# of rob frags: " << total_sub << endmsg;
3283 }
3284
3285 for (uint32_t i_rob = 0; i_rob < total_sub; ++i_rob) {
3286 const uint32_t* p_rob;
3287 re->child(p_rob, i_rob);
3288 const eformat::ROBFragment<const uint32_t*> robFrag(p_rob);
3289
3290 eformat::helper::SourceIdentifier id = eformat::helper::SourceIdentifier(
3291 robFrag.rod_source_id());
3292 unsigned int subDetId = id.subdetector_id();
3293
3294 if (subDetId >= 0x50 && subDetId < 0x60) { //Select Tile-Subdetectors
3295 fillTileLaserObj(&robFrag, *laserObject);
3296 }
3297 }
3298
3299 return StatusCode::SUCCESS;
3300} // end of convertLaser()
3301
3303 // v.setBCID(-999); // TileLaserObject default tag -> Laser only if BCID != -999
3304
3305 uint32_t version = rob->rod_version() & 0xFFFF;
3306
3307 uint32_t error = 0;
3308 uint32_t wc = 0;
3309 uint32_t size = data_size(rob, error);
3310 const uint32_t * p = get_data(rob);
3311
3312 ATH_MSG_DEBUG(" Version = " << version <<
3313 " wc = " << wc <<
3314 " size = " << size <<
3315 " pointer = " << p );
3316
3317 if (!size) {
3318 ATH_MSG_DEBUG(" Nothing to unpack");
3319 return;
3320 }
3321
3322 uint32_t sizeOverhead = 2;
3323 bool V3format = (*(p) == 0xff1234ff); // additional frag marker since Sep 2005
3324 if (!V3format && version>0) {
3325 V3format = true;
3327 ATH_MSG_WARNING("fillTileLaserObj: corrupted frag separator 0x" << MSG::hex << (*p) << " instead of 0xff1234ff in ROB 0x" << rob->rod_source_id() << MSG::dec );
3328 }
3329 if (V3format) {
3330 ++p; // skip frag marker
3331 sizeOverhead = 3;
3332 } else {
3333 sizeOverhead = 2;
3334 }
3335
3336 if(V3format) ATH_MSG_DEBUG("tile flag found! size overhead = " << sizeOverhead);
3337 else ATH_MSG_DEBUG("tile flag not found! size overhead = " << sizeOverhead);
3338
3339 while (wc < size) { // iterator over all words in a ROD
3340 // first word is frag size
3341 uint32_t count = *(p);
3342 // second word is frag ID and frag type
3343 int frag = *(p + 1) & 0xFFFF;
3344 int type = *(p + 1) >> 16;
3345
3346 ATH_MSG_DEBUG( wc << " / " << size << " HEX = 0x" << MSG::hex << count << " DEC = " << MSG::dec << count << " ( FRAG , TYPE ) = " << frag << " , " << type );
3347
3348 if (count < sizeOverhead || count > size - wc) {
3349 int cnt = 0;
3350 for (; wc < size; ++wc, ++cnt, ++p) {
3351 if ((*p) == 0xff1234ff) {
3352 ATH_MSG_DEBUG( "DATA POINTER: HEX = " << MSG::hex << (*p) << " DEC = " << MSG::dec << (*p) );
3353 ++cnt;
3354 ++wc;
3355 ++p;
3356 break;
3357 }
3358 }
3359 if ((m_ErrorCounter++) < m_maxErrorPrint) {
3360 msg(MSG::WARNING) << "Frag: " << MSG::hex << "0x" << frag << MSG::dec
3361 << " has unexpected size: " << count;
3362 if (wc < size) {
3363 msg(MSG::WARNING) << " skiping " << cnt << " words to the next frag" << endmsg;
3364 } else {
3365 msg(MSG::WARNING) << " ignoring " << cnt << " words till the end of ROD frag" << endmsg;
3366 }
3367 }
3368 continue;
3369 }
3370
3371 ATH_MSG_DEBUG( "DECODER" << " " << "FRAG=" << frag << " TYPE=" << type << " SIZE=" << size << " FOUND!" );
3372
3373 if (frag == 0x16 && type == 0x20){
3374
3375 const int LASTROD_BCID = rob->rod_bc_id();
3376 v.setBCID(LASTROD_BCID);
3377
3378 if (size>29){
3379 ATH_MSG_DEBUG("UNPACKING FRAG16");
3380 unpack_frag16(version, p, v);
3381 } else if (size>24) {
3382 ATH_MSG_DEBUG("UNPACKING NEW FRAG16");
3383 unpack_frag17(version, sizeOverhead, p, v);
3384 }
3385 }
3386
3387 if (frag == 0x17 && type == 0x20){
3388
3389 const int LASTROD_BCID = rob->rod_bc_id();
3390 v.setBCID(LASTROD_BCID);
3391
3392 ATH_MSG_DEBUG("UNPACKING FRAG17");
3393 unpack_frag17(version, sizeOverhead, p, v);
3394 } // IF
3395
3396 p += count;
3397 wc += count;
3398 }
3399
3400 if (wc != size) {
3401 // check word count
3402 if ((m_ErrorCounter++) < m_maxErrorPrint) {
3403 ATH_MSG_WARNING("Incorrect ROD size: " << wc << " words instead of " << size );
3404 }
3405 assert(0);
3406 // return;
3407 }
3408} //end of FillLaserObj
3409
3412 D0CellsHLT & d0cells,
3413 TileCellCollection * MBTS,
3414 const TileHid2RESrcID* hid2reHLT) const
3415{
3416 uint32_t version = rob->rod_version() & 0xFFFF;
3417 // Resets error flag
3418 uint32_t error = 0x0;
3419
3420 // figure out which fragment we want to unpack
3421 TileRawChannelCollection::ID frag_id = v.identify();
3422 const std::vector<uint32_t> & drawer_info = hid2reHLT->getDrawerInfo(frag_id);
3423 int bs_frag_id = drawer_info.size()>1 ? static_cast<int>(drawer_info[1]) : frag_id;
3424 int drawer_type = drawer_info.size()>2 ? static_cast<int>(drawer_info[2]) : -1;
3425
3426 /*
3427 if (frag_id < 0x100) { // BEAM ROD frag - nothing to do
3428 m_error|=0x10000;
3429 return;
3430 }
3431 */
3432
3433 uint32_t wc = 0;
3434 uint32_t size = data_size(rob, error);
3435 const uint32_t * p = get_data(rob);
3436 // prepare bcid with one extra bit set for comparison with bcid in DQ fragment
3437 uint16_t rob_bcid = ((rob->rod_bc_id() & 0x7FFF) | 0x8000);
3438
3439 uint32_t sizeOverhead = 2;
3440 if (size) {
3441 bool V3format = (*(p) == 0xff1234ff); // additional frag marker since Sep 2005
3442 if (!V3format && version>0xff) {
3443 V3format = true;
3445 ATH_MSG_WARNING("fillCollectionHLT: corrupted frag separator 0x" << MSG::hex << (*p) << " instead of 0xff1234ff in ROB 0x" << rob->rod_source_id() << MSG::dec );
3446 }
3447 if (V3format) {
3448 ++p; // skip frag marker
3449 sizeOverhead = 3;
3450 } else {
3451 sizeOverhead = 2;
3452 }
3453 }
3454 bool of2 = m_of2Default;
3455 bool correctAmplitude = false;
3457 uint16_t DQuality = 0x0;
3458 bool fragFound = false;
3459 bool DQfragMissing = true;
3460
3461 FRwChVec pChannel;
3462 pChannel.reserve (m_maxChannels);
3463
3464 while (wc < size) { // iterator over all words in a ROD
3465
3466 // first word is frag size
3467 uint32_t count = *(p);
3468 // second word is frag ID (16 bits) frag type (8 bits) and additional flags
3469 uint32_t idAndType = *(p + 1);
3470 int frag = (idAndType & 0xFFFF);
3471 int type = (idAndType & 0xFF0000) >> 16;
3472
3473 if (count < sizeOverhead || count > size - wc) {
3474 int cnt = 0;
3475 for (; wc < size; ++wc, ++cnt, ++p) {
3476 if ((*p) == 0xff1234ff) {
3477 ++cnt;
3478 ++wc;
3479 ++p;
3480 break;
3481 }
3482 }
3483 if ((m_ErrorCounter++) < m_maxErrorPrint) {
3484 msg(MSG::WARNING) << "Frag: " << MSG::hex << "0x" << frag << MSG::dec
3485 << " has unexpected size: " << count;
3486 if (wc < size) {
3487 msg(MSG::WARNING) << " skipping " << cnt << " words to the next frag" << endmsg;
3488 } else {
3489 msg(MSG::WARNING) << " ignoring " << cnt << " words till the end of ROD frag" << endmsg;
3490 }
3491 }
3492 error |= 0x10000;
3493 continue;
3494 }
3495
3496 //if (frag == frag_id && ((type > 1 && type < 6) || type==0xa)) { // proper fragment found - unpack it
3497 if (frag == bs_frag_id) { // proper fragment found - unpack it
3498
3499 switch (type) {
3500 case 2:
3501 fragFound = true;
3502 DQfragMissing = false;
3503 correctAmplitude = false;
3504 unpack_frag2HLT(version, sizeOverhead, p, pChannel, frag_id, drawer_type);
3505 break;
3506 case 3:
3507 fragFound = true;
3508 DQfragMissing = false;
3509 correctAmplitude = false;
3510 unpack_frag3HLT(version, sizeOverhead, p, pChannel, frag_id, drawer_type);
3511 break;
3512 case 4:
3513 if (!m_ignoreFrag4HLT && !fragFound) {
3514 fragFound = true;
3515 int unit = (idAndType & 0xC0000000) >> 30;
3516
3517 int DataType = (idAndType & 0x30000000) >> 28;
3518
3519 if (DataType < 3) { // real data
3520
3521 of2 = ((idAndType & 0x4000000) != 0);
3522 int nIter = (idAndType & 0x3000000) >> 24;
3523 correctAmplitude = (!nIter); // automatic detection of nIter
3524 rChUnit = (TileRawChannelUnit::UNIT) (unit + TileRawChannelUnit::OnlineOffset); // Online units in real data
3525
3526 } else { // simulated data
3527
3528 DQfragMissing = false;
3529 correctAmplitude = false;
3530 rChUnit = (TileRawChannelUnit::UNIT) (unit); // Offline units in simulated data
3531 if (!m_demoFragIDs.empty()) {
3532 ATH_MSG_WARNING("DemoFragIDs is not supported in MC"); // No demonstator cabling in MC
3533 }
3534 }
3535
3536 unpack_frag4HLT(version, sizeOverhead, unit, p, pChannel, frag_id, drawer_type);
3537 }
3538 break;
3539
3540 case 5:
3541 if (!fragFound) {
3542 fragFound = true;
3543 int unit = (idAndType & 0xC0000000) >> 30;
3544
3545 of2 = ((idAndType & 0x4000000) != 0);
3546 correctAmplitude = true; // fragment 5 will appear only if there is no iterations, so correction required
3548
3549 unpack_frag5HLT(version, sizeOverhead, unit, p, pChannel, frag_id, drawer_type);
3550 }
3551 break;
3552
3553 case 0xa:
3554 DQfragMissing = false;
3555 unpack_fragAHLT(version, p, rob_bcid, DQuality, frag_id, drawer_type);
3556 break;
3557
3558 default:
3559 // Just ignore it
3560 break;
3561 }
3562 }
3563 p += count;
3564 wc += count;
3565 }
3566
3567 bool masked_drawer = m_checkMaskedDrawers ? m_tileBadChanTool->isDrawerMasked(frag_id) : false;
3568
3569 if (DQfragMissing && !masked_drawer) error |= 0x40000;
3570
3571 if (fragFound) {
3572 if (masked_drawer) DQuality = 0x0;
3573 error |= make_copyHLT(of2, rChUnit, correctAmplitude,
3574 pChannel, v, DQuality, d0cells, MBTS);
3575 } else if (!masked_drawer) error |= 0x20000;
3576
3577 return error;
3578}
3579
3582 bool correctAmplitude,
3583 const FRwChVec & pChannel,
3585 const uint16_t DQuality,
3586 D0CellsHLT & d0cells,
3587 TileCellCollection * MBTS) const
3588{
3589 typedef FRwChVec::const_iterator ITERATOR;
3590 // int gain = 0;
3591 float ener, time, qual = 0;
3592 TileCell* pCell;
3593 std::vector<TileCell*> cell2Double;
3594 cell2Double.reserve(23);
3595
3596 uint32_t error = 0;
3597
3598 if (DQuality == 0xffff) error |= 0x80000;
3599
3600 TileRawChannelCollection::ID frag_id = (v.identify() & 0x0FFF);
3601 int ros = (frag_id >> 8);
3602 int drawer = (frag_id & 0x3F);
3603 int drawerIdx = TileCalibUtils::getDrawerIdx(ros, drawer);
3604 unsigned int channelIdx;
3605 unsigned int adcIdx;
3606 bool recalibrate = (rChUnit != TileRawChannelUnit::OnlineMegaElectronVolts && rChUnit != TileRawChannelUnit::MegaElectronVolts);
3607
3608 int sec = ros - 1; // 0-3 for barrel +/- and EB +/-
3609
3610 if (pChannel.size() > 0) { // convert raw channels to cells
3611
3612 // Zero all cell energies
3613 /*
3614 for (unsigned int cell = 0; cell < v.size(); ++cell) {
3615 ((TileCell*) v[cell])->setEnergy_nonvirt(0.0F, 0.0F, 0, CaloGain::INVALIDGAIN);
3616 ((TileCell*) v[cell])->setTime_nonvirt(-100.0F); // Just to mark a non-initialized cell
3617 ((TileCell*) v[cell])->setQuality_nonvirt(static_cast<unsigned char>(255), 0, 0);
3618 ((TileCell*) v[cell])->setQuality_nonvirt(static_cast<unsigned char>(255), 0, 1);
3619 }
3620 */
3621
3622 for (TileCell* cell : v) {
3623 cell->setEnergy_nonvirt(0.0F, 0.0F, 0, CaloGain::INVALIDGAIN);
3624 cell->setTime_nonvirt(-100.0F); // Just to mark a non-initialized cell
3625 cell->setQuality_nonvirt(static_cast<unsigned char>(255), 0, 0);
3626 cell->setQuality_nonvirt(static_cast<unsigned char>(255), 0, 1);
3627 }
3628
3629
3630 int idxraw = drawer * m_maxChannels;
3631
3632 ITERATOR rawItr = pChannel.begin();
3633 ITERATOR end = pChannel.end();
3634
3635 if (sec < 2) { // special treatment of first PMT in pos/neg barrel which belongs to D0 cell
3636 idxraw = 0;
3637 channelIdx = rawItr->channel();
3638 bool no_dmu_mask = true;
3639 if (DQuality) {
3640 if (DQuality >> (channelIdx / 3) & 0x1) no_dmu_mask = false;
3641 }
3642
3643 adcIdx = rawItr->adc();
3644 qual = rawItr->quality();
3645 bool do_mask = false;
3646 if ((qual < QUALITY_THRESHOLD) && no_dmu_mask) {
3647 ener = rawItr->amplitude();
3648 time = rawItr->time();
3649 // FIXME:: To speed up HLT processing we keep OnlineMegaElectronVolts
3650 // but this means that we can end up with different units (online or offline)
3651 if (recalibrate && ener!=0.0F) {
3652 ener = m_tileToolEmscale->channelCalib(drawerIdx, channelIdx, adcIdx, ener, rChUnit,
3654 }
3655 // parabolic correction for good but slightly out-of-time signals
3656 if (correctAmplitude) {
3657 if (time<m_allowedTimeMin || time>m_allowedTimeMax) {
3658 ener = 0.0F;
3659 time = 0.0F;
3660 } else if (ener > m_ampMinThresh_MeV
3661 && time > m_timeMinThresh
3662 && time < m_timeMaxThresh) {
3663 ener *= TileRawChannelBuilder::correctAmp(time,of2);
3664 }
3665 }
3666 } else {
3667 // ignore energy from bad channel
3668 ener = 0.0F;
3669 time = 0.0F;
3670 do_mask = true;
3671 }
3672
3673 if (sec > 0) { // sec=1 - negative
3674 d0cells.m_D0channeg[drawer].set(channelIdx, adcIdx, ener, time, qual);
3675 d0cells.m_D0Existneg[drawer] = true;
3676 d0cells.m_D0Maskneg[drawer] = do_mask;
3677 } else { // sec=0 - positive
3678 d0cells.m_D0chanpos[drawer].set(channelIdx, adcIdx, ener, time, qual);
3679 d0cells.m_D0Existpos[drawer] = true;
3680 d0cells.m_D0Maskpos[drawer] = do_mask;
3681 }
3682 ++rawItr; // done with first channel in barrel, go to second
3683 ++idxraw;
3684 }
3685
3686 int MBTS_chan=((ros>2)?-1:43);
3687
3688 for (; rawItr != end; ++rawItr) {
3689 const TileFastRawChannel* rawPtr = &*rawItr;
3690 const int rw2cell = m_Rw2Cell[sec][idxraw];
3691 if (rw2cell != -1) {
3692 // Get Variables
3693 pCell = v[rw2cell];
3694 channelIdx = rawPtr->channel();
3695 bool no_dmu_mask = true;
3696 if (DQuality) {
3697 if (DQuality >> (channelIdx / 3) & 0x1) no_dmu_mask = false;
3698 }
3699 adcIdx = rawPtr->adc();
3700 qual = rawPtr->quality();
3701 time = 0.0F;
3702 if (no_dmu_mask && (qual < QUALITY_THRESHOLD)) {
3703 // gain = adcIdx;
3704 ener = rawPtr->amplitude();
3705 time = rawPtr->time();
3706 // FIXME:: To speed up HLT processing we keep OnlineMegaElectronVolts
3707 // but this means that we can end up with different units (online or offline)
3708 if (recalibrate && ener!=0.0F) {
3709 ener = m_tileToolEmscale->channelCalib(drawerIdx, channelIdx, adcIdx, ener, rChUnit,
3711 }
3712 // parabolic correction for good but slightly out-of-time signals
3713 if (correctAmplitude) {
3714 if (time<m_allowedTimeMin || time>m_allowedTimeMax) {
3715 ener = 0.0F;
3716 time = 0.0F;
3717 } else if (ener > m_ampMinThresh_MeV
3718 && time > m_timeMinThresh
3719 && time < m_timeMaxThresh) {
3720 ener *= TileRawChannelBuilder::correctAmp(time,of2);
3721 }
3722 }
3723 unsigned char qbit = qbitfun(time,m_allowedTimeMin,m_allowedTimeMax);
3724 if (pCell->time() != -100.0F) pCell->setTime(time, m_Rw2Pmt[sec][idxraw]);
3725 else pCell->setTime_nonvirt(time);
3726
3727 pCell->setQuality_nonvirt(std::min(255, abs((int) qual)), qbit, m_Rw2Pmt[sec][idxraw]);
3728 pCell->addEnergy(ener, m_Rw2Pmt[sec][idxraw], adcIdx);
3729
3730 if (pCell->caloDDE()->onl2() == TileHWID::NOT_VALID_HASH)
3731 pCell->setQuality_nonvirt(0, 0, 1);
3732
3733 } else if (pCell->caloDDE()->onl2() != TileHWID::NOT_VALID_HASH) {
3734 pCell->addEnergy(0.0F, m_Rw2Pmt[sec][idxraw], 0U);
3735 pCell->setQuality_nonvirt((unsigned char) 255, 0, m_Rw2Pmt[sec][idxraw]);
3736 cell2Double.push_back(pCell); // have to double later
3737 } else { // Mask it here for Gap
3738 // (pCell)->setEnergy_nonvirt(0.0F, 0.0F, 0, CaloGain::INVALIDGAIN);
3739 pCell->setTime_nonvirt(0.0F);
3740 pCell->setQuality_nonvirt(static_cast<unsigned char>(qual), 0, 1);
3741 }
3742 } else if (MBTS_chan<0) MBTS_chan=rawPtr->channel();// end of if
3743 ++idxraw;
3744 //if ( DQuality ) idxraw1++;
3745 } // End of for TileRawChannel
3746
3747 if (MBTS_chan==4) { // assign zero energy and high gain to second PMT in special C10
3748 pCell = v[m_Rw2Cell[sec][5]]; // find cell with channel 5 connected
3749 pCell->addEnergy(0., 1-m_Rw2Pmt[sec][5], 1);
3750 }
3751
3752 if (MBTS && MBTS_chan >= 0) {
3753 auto it = m_mapMBTS.find (frag_id);
3754 unsigned int idx = it != m_mapMBTS.end() ? it->second : 0u;
3755 if (idx < (*MBTS).size()) { // MBTS present (always last channel)
3756 TileCell* pCell = (*MBTS)[idx];
3757 const TileFastRawChannel& rawCh = pChannel[MBTS_chan];
3758 channelIdx = rawCh.channel();
3759 adcIdx = rawCh.adc();
3760 float ener = rawCh.amplitude();
3761 float time = rawCh.time();
3762 float qual = rawCh.quality();
3763 if (qual < QUALITY_THRESHOLD) {
3764 if (rChUnit==TileRawChannelUnit::MegaElectronVolts) { // go back to pC - not standard configuration
3765 ener /= m_tileToolEmscale->channelCalib(drawerIdx, channelIdx, adcIdx, 1.0, // calibrate to PicoCoulombs
3767 } else {
3768 ener = m_tileToolEmscale->channelCalib(drawerIdx, channelIdx, adcIdx, ener, // calibrate to PicoCoulombs
3770 }
3771 // parabolic correction for good but slightly out-of-time signals
3772 if (correctAmplitude) {
3773 if (time<m_allowedTimeMin || time>m_allowedTimeMax) {
3774 ener = 0.0F;
3775 time = 0.0F;
3776 } else if (ener > m_ampMinThresh_pC
3777 && time > m_timeMinThresh
3778 && time < m_timeMaxThresh) {
3779 ener *= TileRawChannelBuilder::correctAmp(time,of2);
3780 }
3781 }
3782 } else {
3783 // ignore energy from bad channel
3784 ener = 0.0F;
3785 time = -100.0F;
3786 }
3787 pCell->setEnergy(ener, 0.0F);
3788 pCell->setTime_nonvirt(time);
3789 unsigned char qbit = qbitfun(time,m_allowedTimeMin,m_allowedTimeMax);
3790 pCell->setQuality_nonvirt(std::min(255, abs((int) qual)), qbit, 0);
3791 } // End of if idx
3792
3793 } // End of if MBTS
3794
3795 } // end of if vec<TileRawChannel>::size > 0)
3796
3797 for (std::vector<TileCell*>::const_iterator d_it = cell2Double.begin();
3798 d_it != cell2Double.end(); ++d_it) {
3799
3800 // int gain = 0;
3801 // if ((*d_it)->gain1() == 1 || (*d_it)->gain2() == 1) gain = 1;
3802 int gain = (*d_it)->gain1() | (*d_it)->gain2();
3803 unsigned char qual = (*d_it)->qual1() & (*d_it)->qual2();
3804
3805 float ener = (*d_it)->e();
3806 float time = (*d_it)->time();
3807 unsigned char qbit = qbitfun(time,m_allowedTimeMin,m_allowedTimeMax);
3808
3809 (*d_it)->setEnergy_nonvirt(ener, ener, gain, gain);
3810 (*d_it)->setQuality_nonvirt(qual, qbit, 0);
3811 (*d_it)->setQuality_nonvirt(qual, qbit, 1);
3812 if (time == -100.0F) (*d_it)->setTime_nonvirt(0.0F);
3813 }
3814
3815 return error;
3816}
3817
3818void TileROD_Decoder::unpack_frag2HLT(uint32_t /* version */,
3819 unsigned sizeOverhead,
3820 const uint32_t* p,
3821 FRwChVec & pChannel,
3822 int /* frag_id */, int /* drawer_type */) const
3823{
3824 // first word is frag size
3825 int count = *(p);
3826
3827 p += 2; // 2 words so far
3828 int wc = sizeOverhead; // can be 2 or 3 words
3829
3830 for (unsigned int ch = 0; ch < m_maxChannels; ++ch) {
3831 unsigned int w = (*p);
3832
3833 if (w != 0) { // skip invalid channels
3834
3835 pChannel.emplace_back(ch
3836 , m_rc2bytes2.gain(w)
3837 , m_rc2bytes2.amplitude(w)
3838 , m_rc2bytes2.time(w)
3839 , m_rc2bytes2.quality(w));
3840
3841 } else {
3842 pChannel.emplace_back(ch, 1U, 0.0F, 0.0F, 0.0F);
3843 }
3844 ++wc;
3845 ++p;
3846 }
3847
3848 if (wc != count) {
3849 // check word count
3850 if ((m_ErrorCounter++) < m_maxErrorPrint) {
3851 ATH_MSG_WARNING("Incorrect word count: " << wc << " != " << count );
3852 }
3853 assert(0);
3854 // return;
3855 }
3856
3857 return;
3858}
3859
3860void TileROD_Decoder::unpack_frag3HLT(uint32_t /* version */,
3861 uint32_t sizeOverhead,
3862 const uint32_t* p,
3863 FRwChVec & pChannel,
3864 int /* frag_id */, int /* drawer_type */) const
3865{
3866 // first word is frag size
3867 int count = *(p);
3868 // second word is frag ID and frag type
3869
3870 // ATH_MSG_VERBOSE( "first 4 words " << MSG::hex
3871 // << " 0x" << *p
3872 // << " 0x" << *(p+1)
3873 // << " 0x" << *(p+2)
3874 // << " 0x" << *(p+3) << MSG::dec );
3875
3876 // followed by 2 map words
3877 const uint32_t* pMap = p + 2;
3878
3879 const short* p16 = reinterpret_cast<const short *>(p);
3880
3881 p16 = p16 + 8; // 8 16bit words so far
3882 short wc16 = 4 + sizeOverhead * 2; // can be 8 or 10 (if overhead is 3 words)
3883
3884 for (unsigned int ch = 0U; ch < 48U; ++ch) {
3885 if (checkBit(pMap, ch)) {
3886
3887 pChannel.emplace_back(ch
3888 , m_rc2bytes.gain(*p16)
3889 , m_rc2bytes.amplitude(*p16)
3890 , m_rc2bytes.time(*(p16 + 1))
3891 , m_rc2bytes.quality(*(p16 + 2)));
3892
3893 // ATH_MSG_VERBOSE(" frag 0x" << MSG::hex << frag << MSG::dec
3894 // << " ch " << ch
3895 // << " " << MSG::hex << "0x" << *p16 << *(p16+1) << *(p16+2) << MSG::dec
3896 // << " " << gain
3897 // << " " << m_rc2bytes.amplitude(*p16)
3898 // << " " << m_rc2bytes.time(*(p16+1))
3899 // << " " << m_rc2bytes.quality(*(p16+2)) );
3900
3901 wc16 = wc16 + 3;
3902 p16 = p16 + 3;
3903 } // channel present
3904 else {
3905 pChannel.emplace_back(ch, 1U, 0.0F, 0.0F, 0.0F);
3906 }
3907 } // all bits, done with this frag
3908
3909 if (wc16 % 2 == 1) {
3910 ++wc16; // align
3911 ++p16;
3912 }
3913 if (wc16 != 2 * count) {
3914 // check word count
3915 if ((m_ErrorCounter++) < m_maxErrorPrint) {
3916 ATH_MSG_WARNING( "unpack_frag3HLT => Incorrect wordcount: "
3917 << wc16 << " != 2*" << count );
3918 }
3919 assert(0);
3920 // return;
3921 }
3922
3923 return;
3924}
3925
3926void TileROD_Decoder::unpack_frag4HLT(uint32_t /* version */,
3927 uint32_t sizeOverhead,
3928 unsigned int unit,
3929 const uint32_t* p,
3930 FRwChVec & pChannel,
3931 int frag_id, int drawer_type) const
3932{
3933 // first word is frag size
3934 int count = *(p);
3935 // second word is frag ID and frag type
3936 int frag = (frag_id>0) ? frag_id : *(p + 1) & 0xFFFF;
3937 bool remap = (drawer_type > 0) || std::binary_search(m_demoFragIDs.begin(), m_demoFragIDs.end(), frag);
3938 const std::vector<int> & chmap = (frag<0x300) ? m_demoChanLB : m_demoChanEB;
3939
3940 p += 2; // 2 words so far
3941 int wc = sizeOverhead; // can be 2 or 3 words
3942 for (unsigned int ch = 0U; ch < m_maxChannels; ++ch) {
3943 unsigned int ch1 = (remap) ? chmap[ch] : ch;
3944 unsigned int w = (*p);
3945 if (w != 0) { // skip invalid channels
3946 pChannel.emplace_back(ch1
3947 , m_rc2bytes4.gain(w)
3948 , m_rc2bytes4.amplitude(w, unit)
3949 , m_rc2bytes4.time(w)
3950 , m_rc2bytes4.quality(w));
3951
3952 } else {
3953 pChannel.emplace_back(ch1, 1U, 0.0F, 0.0F, 0.0F);
3954 }
3955 ++wc;
3956 ++p;
3957 }
3958 if (remap) std::sort(pChannel.end()-m_maxChannels,pChannel.end(),chan_order1);
3959
3960 if (wc > count) {
3961 // check word count
3962 if ((m_ErrorCounter++) < m_maxErrorPrint) {
3963 ATH_MSG_WARNING( "unpack_frag4HLT => Incorrect word count: "
3964 << wc << " != " << count );
3965 }
3966 assert(0);
3967 // return;
3968 }
3969
3970 return;
3971}
3972
3973void TileROD_Decoder::unpack_frag5HLT(uint32_t /* version */,
3974 uint32_t sizeOverhead,
3975 unsigned int unit,
3976 const uint32_t* p,
3977 FRwChVec & pChannel,
3978 int frag_id, int drawer_type) const
3979{
3980 // first word is frag size
3981 int count = *(p);
3982 // second word is frag ID and frag type
3983 int frag = (frag_id>0) ? frag_id : *(p + 1) & 0xFFFF;
3984 bool remap = (drawer_type > 0) || std::binary_search(m_demoFragIDs.begin(), m_demoFragIDs.end(), frag);
3985 const std::vector<int> & chmap = (frag<0x300) ? m_demoChanLB : m_demoChanEB;
3986 int size_L2 = (*(p + 1) >> (32 - 2 - 3)) & 0x7;
3987
3988 p += 2; // 2 words so far
3989 int wc = sizeOverhead; // can be 2 or 3 words
3990 const uint16_t* ptr_bad = reinterpret_cast<const uint16_t*> (p + 48 + size_L2); // Reco + Size_L2
3991 uint16_t bad_bits[3] = { ptr_bad[1], ptr_bad[0], ptr_bad[3] };
3992
3993 uint32_t code;
3994 int fmt, bad, gain(0), ene_bin(0), time_bin(0), quality;
3995 unsigned int w;
3996 float ene(0.0), time(0.0);
3997
3998 unsigned int ch = 0U;
3999 for (unsigned int i = 0U; i < 3U; ++i) {
4000 uint16_t bad16 = ~bad_bits[i]; // note inversion here
4001 for (unsigned int j = 0U; j < 16U; ++j) {
4002 w = (*p);
4003
4004 code = w >> 24;
4005 fmt = m_rc2bytes5.m_FormatLookup[code];
4006 Frag5_unpack_reco_bin(w, code, gain, ene_bin, time_bin);
4007 Frag5_unpack_bin2reco(unit, gain, ene_bin, ene, time_bin, time);
4008 //m_rc2bytes5.unpack_reco(w, fmt, gain, ene, time);
4009
4010 bad = (bad16 & 0x1);
4011 bad16 >>= 1;
4012 quality = m_rc2bytes5.get_quality(bad, fmt);
4013 unsigned int ch1 = (remap) ? chmap[ch] : ch;
4014 pChannel.emplace_back(ch1, gain, ene, time, quality);
4015
4016 ++ch;
4017 ++wc;
4018 ++p;
4019 }
4020 }
4021 if (remap) std::sort(pChannel.end()-m_maxChannels,pChannel.end(),chan_order1);
4022
4023 if (wc > count) {
4024 // check word count
4025 if ((m_ErrorCounter++) < m_maxErrorPrint) {
4026 ATH_MSG_WARNING( "unpack_frag5HLT => Incorrect word count: "
4027 << wc << " != " << count );
4028 }
4029 assert(0);
4030 // return;
4031 }
4032
4033 return;
4034}
4035
4036bool TileROD_Decoder::unpack_frag4L2(uint32_t /* version */,
4037 uint32_t sizeOverhead,
4038 const uint32_t* p,
4039 TileL2Container & pL2,
4040 int frag_id, int /* drawer_type */) const {
4041 // first word is frag size
4042 int size = *(p);
4043 // second word is frag ID and frag type
4044 uint32_t idAndType = *(p + 1);
4045 int frag = (frag_id>0) ? frag_id : idAndType & 0xFFFF;
4046 int unit = (idAndType >> (32 - 2)) & 0x3;
4047
4048#ifdef DO_NOT_USE_MUON_TAG
4049
4050 p += 50; // offset 50: 2 words in header and 48 channels after
4051
4052#else
4053
4054 // this part should be very similar to unpack_frag4HLT - it reads amplitude from DSP
4055 // and then uses vector of 48 amplitudes to calculate Muon tags
4056 // but since nobody is using Tile Muon tags in L2 trigger
4057 // this part is not implemented
4058
4059 p+=50;// offset 50: 2 words in header and 48 channels after
4060
4061#endif
4062
4063 int size_L2 = size - sizeOverhead - 48;
4064 if (size_L2 > 0) {
4065
4066 std::vector<float> sumE;
4067 sumE.reserve(size_L2);
4068 while (size_L2--) {
4069 sumE.push_back(Frag5_unpack_bin2sum(unit, (int)(*(p++))));
4070 }
4071 (*pL2[m_hashFunc(frag)]).setEt(std::move(sumE));
4072
4073 return true;
4074
4075 } else {
4076
4077 return false; // indicate that there is no sumEt info in the fragment
4078 }
4079}
4080
4081bool TileROD_Decoder::unpack_frag5L2(uint32_t /* version */, const uint32_t* p,
4082 TileL2Container & pL2,
4083 int frag_id, int /* drawer_type */) const {
4084 // second word is frag ID and frag type
4085 uint32_t idAndType = *(p + 1);
4086 int frag = (frag_id>0) ? frag_id : idAndType & 0xFFFF;
4087 int unit = (idAndType >> (32 - 2)) & 0x3;
4088 int size_L2 = (idAndType >> (32 - 2 - 3)) & 0x7;
4089
4090#ifdef DO_NOT_USE_MUON_TAG
4091
4092 p += 50; // offset 50: 2 words in header and 48 channels after
4093
4094#else
4095
4096 // this part is very similar to unpack_frag5HLT - it reads amplitude from DSP
4097 // and then uses vector of 48 amplitudes to calculate Muon tags
4098 // all this is written only for tests and will not be used actually,
4099 // since nobody is using Tile Muon tags in L2 trigger
4100
4101 p+=2;// 2 words so far
4102
4103 int drawer = (frag & 0x3F);
4104 int ros = (frag >> 8);
4105 int drawerIdx = TileCalibUtils::getDrawerIdx(ros,drawer);
4107 bool recalibrate = (onlUnit != TileRawChannelUnit::OnlineMegaElectronVolts);
4108 float E_MeV[48];
4109 int Gain[48];
4110 bool bad[48];
4111
4112 uint16_t* ptr_bad = (uint16_t*)(p + 48 + size_L2);// Reco + Size_L2
4113 uint16_t bad_bits[3] = {ptr_bad[1], ptr_bad[0], ptr_bad[3]};
4114
4115 uint32_t code;
4116 int fmt, gain(0), ene_bin(0), time_bin(0);
4117 unsigned int w;
4118 float ene(0.0), time(0.0);
4119
4120 int ch = 0;
4121 for (int i = 0; i < 3; ++i) {
4122 uint16_t bad16 = ~bad_bits[i]; // note inversion here
4123 for (int j = 0; j < 16; ++j) {
4124 w = (*p);
4125
4126 code = w >> 24;
4127 fmt = m_rc2bytes5.m_FormatLookup[code];
4128 Frag5_unpack_reco_bin(w, code, gain, ene_bin, time_bin);
4129 Frag5_unpack_bin2reco(unit, gain, ene_bin, ene, time_bin, time);
4130 //m_rc2bytes5.unpack_reco(w, fmt, gain, ene, time);
4131
4132 bad[ch] = (bad16 & 0x1); bad16 >>= 1;
4133 Gain[ch] = gain;
4134 if (recalibrate)
4135 E_MeV[ch] = m_tileToolEmscale->channelCalib(drawerIdx, ch, gain, ene, onlUnit, TileRawChannelUnit::MegaElectronVolts);
4136 else
4137 E_MeV[ch] = ene;
4138
4139 ++ch;
4140 ++p;
4141 }
4142 }
4143
4144 std::vector<double> EtaMuons;
4145 std::vector<double> EMuons0;
4146 std::vector<double> EMuons1;
4147 std::vector<double> EMuons2;
4148 std::vector<unsigned int> qf;
4149 std::vector<unsigned int> word;
4150
4151 switch (ros) {
4152 case TileHWID::BARREL_POS: m_L2Builder->MTagLB(ros,drawer,E_MeV,Gain,bad,EtaMuons,EMuons0,EMuons1,EMuons2,qf,word); break;
4153 case TileHWID::BARREL_NEG: m_L2Builder->MTagLB(ros,drawer,E_MeV,Gain,bad,EtaMuons,EMuons0,EMuons1,EMuons2,qf,word); break;
4154 case TileHWID::EXTBAR_POS: m_L2Builder->MTagEB(ros,drawer,E_MeV,Gain,bad,EtaMuons,EMuons0,EMuons1,EMuons2,qf,word); break;
4155 case TileHWID::EXTBAR_NEG: m_L2Builder->MTagEB(ros,drawer,E_MeV,Gain,bad,EtaMuons,EMuons0,EMuons1,EMuons2,qf,word); break;
4156 default: ATH_MSG_WARNING( "unpack_frag5L2: incorrect ros value: " << ros );
4157 }
4158
4159 (*pL2[m_hashFunc(frag)]).setMu(std::move(EtaMuons), std::move(EMuons0),
4160 std::move(EMuons1), std::move(EMuons2), std::move(qf), std::move(word));
4161
4162#endif
4163
4164 if (size_L2 > 0) {
4165
4166 std::vector<float> sumE;
4167 sumE.reserve(size_L2);
4168 while (size_L2--) {
4169 sumE.push_back(Frag5_unpack_bin2sum(unit, (int)(*(p++))));
4170 }
4171 (*pL2[m_hashFunc(frag)]).setEt(std::move(sumE));
4172
4173 return true;
4174
4175 } else {
4176
4177 return false; // indicate that there is no sumEt info in the fragment
4178 }
4179}
4180
4182 for (int i = 0; i < 64; ++i) {
4183 m_D0Existneg[i] = false;
4184 m_D0Existpos[i] = false;
4185 m_D0Maskneg[i] = false;
4186 m_D0Maskpos[i] = false;
4187 m_cells[i] = nullptr;
4188 }
4189}
4190
4192 TileCellCollection & v) const
4193{
4194 TileRawChannelCollection::ID frag_id = (v.identify() & 0x0FFF);
4195 int ros = (frag_id >> 8);
4196 bool barrel ( (ros==1) || (ros==2) );
4197 if ( !barrel ) return; // Only in barrel
4198 int drawer = (frag_id & 0xFF);
4199 TileCell* pCell = d0cells.m_cells[drawer];
4200 if ( !pCell ) return;
4201
4202 if (d0cells.m_D0Maskpos[drawer] && d0cells.m_D0Maskneg[drawer]) {
4203
4204 // both channels are bad - mask whole cell
4205 (pCell)->setEnergy_nonvirt(0.0F, 0.0F, 0, 0);
4206 (pCell)->setTime_nonvirt(0.0F);
4207 (pCell)->setQuality_nonvirt(static_cast<unsigned char>(255), 0, 0);
4208 (pCell)->setQuality_nonvirt(static_cast<unsigned char>(255), 0, 1);
4209
4210 } else if (d0cells.m_D0Maskpos[drawer]) {
4211
4212 // first(positive) channel is bad, second(negative) is good
4213 float amp2 = d0cells.m_D0channeg[drawer].amplitude();
4214 float time2 = d0cells.m_D0channeg[drawer].time();
4215 int gain2 = d0cells.m_D0channeg[drawer].adc();
4216 unsigned char qual2 = d0cells.m_D0channeg[drawer].quality();
4217 unsigned char qbit2 = qbitfun(time2,m_allowedTimeMin,m_allowedTimeMax);
4218
4219 (pCell)->setEnergy(amp2, amp2, gain2, gain2);
4220 (pCell)->setTime(time2);
4221 (pCell)->setQuality(qual2, qbit2, 0);
4222 (pCell)->setQuality(qual2, qbit2, 1);
4223
4224 } else {
4225
4226 // first(positive) channel is good
4227 float amp1 = d0cells.m_D0chanpos[drawer].amplitude();
4228 float time1 = d0cells.m_D0chanpos[drawer].time();
4229 int gain1 = d0cells.m_D0chanpos[drawer].adc();
4230 unsigned char qual1 = d0cells.m_D0chanpos[drawer].quality();
4231 unsigned char qbit1 = qbitfun(time1,m_allowedTimeMin,m_allowedTimeMax);
4232
4233 if (d0cells.m_D0Maskneg[drawer]) {
4234
4235 // second channel is bad, first is good
4236 (pCell)->setEnergy(amp1, amp1, gain1, gain1);
4237 (pCell)->setTime(time1);
4238 (pCell)->setQuality(qual1, qbit1, 0);
4239 (pCell)->setQuality(qual1, qbit1, 1);
4240
4241 } else {
4242
4243 // second(negative) channel is good
4244 float amp2 = d0cells.m_D0channeg[drawer].amplitude();
4245 float time2 = d0cells.m_D0channeg[drawer].time();
4246 int gain2 = d0cells.m_D0channeg[drawer].adc();
4247 unsigned char qual2 = d0cells.m_D0channeg[drawer].quality();
4248 unsigned char qbit2 = qbitfun(time2,m_allowedTimeMin,m_allowedTimeMax);
4249
4250 // both channels are good
4251 (pCell)->setEnergy(amp1, amp2, gain1, gain2);
4252 (pCell)->setTime(time1);
4253 (pCell)->setTime(time2, 1);
4254 (pCell)->setQuality(qual1, qbit1, 0);
4255 (pCell)->setQuality(qual2, qbit2, 1);
4256 }
4257 }
4258}
4259
4260void TileROD_Decoder::loadMBTS(std::map<unsigned int, unsigned int>& mapMBTS, int MBTS_channel) {
4261 m_mapMBTS = mapMBTS;
4262 m_MBTS_channel = MBTS_channel;
4263 return;
4264}
4265
4267 if (m_hid2re) return;
4268
4269 ATH_MSG_DEBUG( "initHid2re() for run " << m_fullTileRODs );
4270
4271 m_hid2re = new TileHid2RESrcID(m_tileHWID,m_fullTileRODs); // setting normal frag2RODmap and map dedicated to TMDB
4272
4273 // Check whether we want to overwrite default ROB IDs
4274
4275 SmartIF<IProperty> propertyServer{service("ByteStreamCnvSvc")};
4276 if (propertyServer) {
4277
4278 std::vector<std::string> vecProp;
4279 StringArrayProperty vecProperty("ROD2ROBmap", vecProp);
4280
4281 if (propertyServer->getProperty(&vecProperty).isSuccess()) {
4282
4283 if (vecProperty.value().size() % 2 == 1) {
4284 ATH_MSG_DEBUG( "Length of ROD2ROBmap is and odd value, "
4285 << " means that we'll scan event for all fragments to create proper map" );
4286
4287 SmartIF<IROBDataProviderSvc> robSvc{service("ROBDataProviderSvc")};
4288 if (robSvc) {
4289 const eformat::FullEventFragment<const uint32_t*> * event = robSvc->getEvent(Gaudi::Hive::currentContext());
4290 try {
4291 event->check_tree();
4292 m_hid2re->setROD2ROBmap(event, m_of2Default, msg());
4293 } catch (...) {
4294 ATH_MSG_DEBUG( "Bad event, mapping might be incomplete! " );
4295 // bad event, but process anyhow (well, till next bug report )
4296 m_hid2re->setROD2ROBmap(event, m_of2Default, msg());
4297 }
4298 }
4299 } else if (vecProperty.value().size() == 0) {
4300 ATH_MSG_DEBUG( "Length of ROD2ROBmap vector is zero, "
4301 << " means that predefined mapping for run " << m_fullTileRODs << " will be used " );
4302 } else {
4303 ATH_MSG_DEBUG( "Apply additional remapping for " << vecProperty.value().size()/2 << " fragments from jobOptions ");
4304 m_hid2re->setROD2ROBmap(vecProperty.value(), msg());
4305 }
4306 }
4307 }
4308
4309 m_hid2re->printSpecial(msg());
4310}
4311
4313 if (m_hid2reHLT) return;
4314
4315 ATH_MSG_DEBUG( "initHid2reHLT() for run " << m_fullTileRODs );
4316
4317 m_hid2reHLT = new TileHid2RESrcID(m_tileHWID,m_fullTileRODs); // setting a frag2RODmap and map dedicated to TMDB
4318}
4319
4320const uint32_t*
4321TileROD_Decoder::getOFW(int fragId, int unit) const
4322{
4323 if (unit >> 2) {
4324 ATH_MSG_WARNING( "Wrong online reconstruction units for getOFW: unit=" << unit
4325 << " => assume unit=" << (unit & 3) );
4326 unit &= 3;
4327 }
4328
4329 uint32_t drawerIdx = TileCalibUtils::getDrawerIdxFromFragId(fragId);
4330 size_t id = (drawerIdx << 2 | unit);
4331 const uint32_t* ofptr = m_OFPtrs[id];
4332 if (ofptr) {
4333 return ofptr;
4334 }
4335
4336 std::lock_guard<std::mutex> lock (m_OFWeightMutex);
4337 ofptr = m_OFPtrs[id];
4338 if (ofptr) {
4339 return ofptr;
4340 }
4341
4342 const EventContext &ctx = Gaudi::Hive::currentContext();
4343
4344 std::vector<uint32_t>& ofw = m_OFWeights[id];
4345
4346 ATH_MSG_DEBUG("getOFC fragId: 0x" << MSG::hex << fragId << MSG::dec << " Unit: " << unit);
4349
4350 bool of2 = true;
4351 std::vector<double> a(7), b(7), c(7), g(7), dg(7);
4352
4353 for (int ch = 0; ch < 48; ++ch) {
4354 for (int gain = 0; gain < 2; ++gain) {
4355 float phase = -m_tileToolTiming->getSignalPhase(drawerIdx, ch, gain);
4357 if (m_tileCondToolOfcCool->getOfcWeights(drawerIdx, ch, gain, phase, of2, weights, ctx).isFailure())
4358 {
4359 ATH_MSG_ERROR( "getOfcWeights fails" );
4360 return nullptr;
4361 }
4362
4363 double calib = m_tileToolEmscale->channelCalibOnl(drawerIdx, ch, gain, 1.0, chan_unit);
4364
4365 if (unit != 0 && gain) calib *= 64.0;
4366
4367 for (int i = 0; i < 7; ++i) {
4368 a[i] = weights.w_a[i];
4369 b[i] = weights.w_b[i];
4370 c[i] = weights.w_c[i];
4371 g[i] = weights.g[i];
4372 dg[i] = weights.dg[i];
4373 }
4374 Format6(a, b, c, g, dg
4375 , ch // channel
4376 , 0 // phase = 0 poskol'ku ne ponyal kak okruglyat'
4377 , calib // calibration
4378 , ofw
4379 , false // verbose
4380 );
4381 } // gain
4382 } // ch
4383
4384 ofptr = m_OFPtrs[id] = ofw.data();
4385
4386 return ofptr;
4387}
4388
4389/* TMDB dedicated functions will have a group of functions for each dedicated container
4390
4391
4392Each container has 2/3 methods associated
4393 - fill :
4394 - unpacking : decode words
4395*/
4396
4398
4399 ATH_MSG_DEBUG( " TileROD_Decoder::fillCollection_TileMuRcv_Digi " );
4400
4401 int wc = 0;
4402 bool b_sof = false;
4403 bool b_digiTmdb = false;
4404
4405 uint32_t version = rob->rod_version() & 0xFFFF;
4406 uint32_t sourceid = rob->rod_source_id();
4407 int size = rob->rod_ndata();
4408
4409 uint32_t sfrag_version = 0x0;
4410 uint32_t sfrag_type = 0x0;
4411 int sfrag_size = 0;
4412
4413 const uint32_t *p = get_data(rob);
4414
4415 ATH_MSG_DEBUG( " Trying DECODER over source ID: "<<MSG::hex<<" 0x"<<sourceid<<MSG::dec<<" size of full fragment: "<<size );
4416
4417 while ( wc < size ) { // iterator over all words for a robid
4418 // first word is the start of the tile subfragment in v3format it is 0xff1234ff
4419 if ((*p) == 0xff1234ff) b_sof=true;
4420
4421 ATH_MSG_DEBUG( " Start of sub-fragment word: "<<MSG::hex<<(*p)<<MSG::dec<<" false/true: "<<b_sof );
4422
4423 if (b_sof) {
4424 // second word is frag size
4425 sfrag_size = *(p+1);
4426 // third word is frag version (16-bits) + type (16-bits)
4427 sfrag_version = *(p+2) & 0xFFFF;
4428 sfrag_type = *(p+2) >> 16;
4429 b_sof = false;
4430 }
4431
4432 if (sfrag_type==0x40) {
4433 b_digiTmdb = true;
4434 ATH_MSG_DEBUG( MSG::hex<<" DECODER sub-fragment VERSION= 0x"<<sfrag_version<<" TYPE= 0x"<<sfrag_type<< MSG::dec<<" SIZE="<<sfrag_size<<" FOUND! " );
4435 // type and version are identified and we move to the end of the loop
4436 wc += size-wc;
4437 p += 3;
4438 } else {
4439 // carry on looping to search for 0x40
4440 wc++;
4441 p++;
4442 }
4443 }
4444
4445 if ( b_digiTmdb ) {
4446 // the TMDB raw channel 0x40
4447 uint32_t collID = coll.identify();
4448 unpack_frag40( collID, version, p, sfrag_size-3, coll);
4449 }
4450
4451 //delete_vec(digi);
4452
4453 return;
4454
4455}
4456
4458
4459 ATH_MSG_DEBUG( " TileROD_Decoder::fillCollection_TileMuRcv_RawChannel " );
4460
4461 int wc = 0;
4462 bool b_sof = false;
4463 bool b_rcTmdb = false;
4464
4465 uint32_t version = rob->rod_version() & 0xFFFF;
4466 uint32_t sourceid = rob->rod_source_id();
4467 int size = rob->rod_ndata();
4468 int offset = 0;
4469
4470 uint32_t sfrag_version = 0x0;
4471 uint32_t sfrag_type = 0x0;
4472 int sfrag_size = 0;
4473
4474 const uint32_t *p = get_data(rob);
4475
4476 ATH_MSG_DEBUG( " Trying DECODER over source ID: "<<MSG::hex<<" 0x"<<sourceid<<MSG::dec<<" size of full fragment: "<<size );
4477
4478 while ( wc < size ) { // iterator over all words in a robid
4479 // first word is the start of the tile subfragment in v3format it is 0xff1234ff
4480 if ((*p) == 0xff1234ff) b_sof=true;
4481 ATH_MSG_DEBUG( " Start of sub-fragment word : "<<MSG::hex<< (*p)<<MSG::dec<<" false/true : "<<b_sof );
4482 // if at the start of the fragment than we should find more information about this (sub-)fragment in the following two words
4483 if (b_sof) {
4484 // second word is frag size
4485 sfrag_size = *(p+1);
4486 // third word is frag version (16-bits) + type (16-bits)
4487 sfrag_version = *(p+2) & 0xFFFF;
4488 sfrag_type = *(p+2) >> 16;
4489 b_sof=false;
4490 }
4491 // for tmdb we will start to have a fragment with three sub-fragments ordered as 0x40 0x41 0x42
4492 // we investigate if there are any of type 0x40 before going on 0x41
4493 // like this the loop is faster since we can access the size of this sub-fragment
4494 //
4495 if (sfrag_type==0x40) {
4496 ATH_MSG_DEBUG(MSG::hex<<" DECODER sub-fragment VERSION= 0x"<<sfrag_version<<" TYPE= 0x"<<sfrag_type<<MSG::dec<<" SIZE="<<sfrag_size<<" FOUND! Keep on looking for 0x41.");
4497 offset = sfrag_size;
4498 wc += offset;
4499 p += offset;
4500 } else if (sfrag_type==0x41) {
4501 b_rcTmdb = true;
4502 ATH_MSG_DEBUG(MSG::hex<<" DECODER sub-fragment VERSION= 0x"<<sfrag_version<<" TYPE= 0x"<<sfrag_type<<MSG::dec<<" SIZE="<<sfrag_size<<" FOUND!");
4503 // type and version are identified and we move to the end of the loop
4504 wc += size-wc;
4505 p+=3;
4506 } else {
4507 ATH_MSG_DEBUG(MSG::hex<<" DECODER sub-fragment VERSION= 0x"<<sfrag_version<<" TYPE= 0x"<<sfrag_type<<MSG::dec<<" SIZE="<<sfrag_size<<" FOUND!");
4508 // carry on looping to search for 0x41
4509 wc++;
4510 p++;
4511 }
4512 }
4513
4514 if ( b_rcTmdb ) {
4515 // the TMDB raw channel 0x41
4516 //
4517 uint32_t collID = coll.identify();
4518 unpack_frag41( collID, version, p, sfrag_size-3, coll);
4519 }
4520
4521 //delete_vec(rc);
4522
4523return;
4524}
4525
4526
4528
4529 ATH_MSG_DEBUG( "TileROD_Decoder::fillCollection_FELIX_Digi" );
4530
4531 uint32_t version = rob->rod_version() & 0xFFFF;
4532 uint32_t sizeOverhead = 3; // Sub fragment marker, size, and (id + type)
4533
4535
4536 // initialize meta data storage
4537 DigitsMetaData_t digitsMetaData(9);
4538 RawChannelMetaData_t rawchannelMetaData;
4539
4540 pDigiVec pDigits;
4541 pRwChVec pChannel;
4542
4543 uint32_t error = 0;
4544 uint32_t size = data_size(rob, error);
4545 const uint32_t* data = get_data(rob);
4546 const uint32_t* const end_data = data + size;
4547
4548 int frag_id = coll.identify();
4549 const std::vector<uint32_t> & drawer_info = hid2re->getDrawerInfo(frag_id);
4550 int bs_frag_id = drawer_info.size()>1 ? static_cast<int>(drawer_info[1]) : frag_id;
4551 int drawer_type = drawer_info.size()>2 ? static_cast<int>(drawer_info[2]) : -1;
4552
4553 while (data < end_data) { // iterator over all words for a robid
4554 // first word is the start of the tile subfragment in v3format it is 0xff1234ff
4555 if ((*data) == 0xff1234ff) {
4556 uint32_t count = *(data + 1); // first word is frag size
4557 uint32_t idAndType = *(data + 2); // second word is frag ID and frag type
4558 int frag = (idAndType & 0x0FFF); // remove the offset
4559 int type = (idAndType>>16)& 0xFF; // note special mask, we ignore one digit, keep only 0x10, 0x20, 0x30, ...
4560 if (type == 0x06 && (frag == bs_frag_id)) {
4561 ++data;
4562 ATH_MSG_DEBUG( MSG::hex << "Found FELIX sub-fragment ID=0x" << frag
4563 <<" type=0x" << type << MSG::dec
4564 << " size=" << count );
4565 std::vector<uint32_t> correct_data = get_correct_data(data);
4566 unpack_frag6(version, sizeOverhead, digitsMetaData, correct_data.data(), pDigits, frag_id, drawer_type);
4567 // store metadata for this collection
4568 // size, fragID, BCID
4569 digitsMetaData[0].push_back(count);
4570 digitsMetaData[0].push_back(frag);
4571 digitsMetaData[0].push_back(0);
4572 break;
4573 } else {
4574 // carry on looping to search for 0x60
4575 data += count;
4576 }
4577 }
4578 ++data;
4579 }
4580
4581 uint32_t bsflags = 0;
4584
4585 make_copy(bsflags, rChType, rChUnit, digitsMetaData, rawchannelMetaData,
4586 rob, pDigits, pChannel, coll, nullptr);
4587
4588}
4589
4590
4591
4593{
4594
4595 ATH_MSG_DEBUG( " TileROD_Decoder::convertTMDBDecision " );
4596
4597 if (!re) {
4598 ATH_MSG_FATAL( "RawEvent passed to 'convert'-function is a null pointer!" );
4599 return StatusCode::FAILURE;
4600 }
4601
4602 uint32_t total_sub = re->nchildren();
4603
4604 for (uint32_t i_rob = 0; i_rob < total_sub; ++i_rob) {
4605 const uint32_t* p_rob;
4606 re->child(p_rob, i_rob);
4607 const eformat::ROBFragment<const uint32_t*> robFrag(p_rob);
4608
4609 //eformat::helper::SourceIdentifier id = eformat::helper::SourceIdentifier(robFrag.source_id());
4610 uint32_t sourceid = robFrag.source_id();
4611 uint32_t modid = sourceid >> 16;
4612 //ATH_MSG_VERBOSE( MSG::hex<<" sourceId: 0x"<< robFrag.source_id() <<MSG::dec );
4613
4614 if ((modid == 0x51 || modid == 0x52 || modid == 0x53 || modid == 0x54) && (sourceid & 0xf00)) {
4615 fillContainer_TileMuRcv_Decision(&robFrag, *tileMuRcv);
4616 }
4617 }
4618
4619 return StatusCode::SUCCESS;
4620}
4621
4623
4624 ATH_MSG_DEBUG( "TileROD_Decoder::fillContainer_TileMuRcv_Decision" );
4625
4626 int wc = 0;
4627 bool b_sof = false;
4628 bool b_deciTmdb = false;
4629
4630 uint32_t version = rob->rod_version() & 0xFFFF;
4631 uint32_t sourceid = rob->rod_source_id();
4632 int size = rob->rod_ndata();
4633 int offset = 0;
4634
4635 uint32_t sfrag_version = 0x0;
4636 uint32_t sfrag_type = 0x0;
4637 int sfrag_size = 0;
4638
4639 const uint32_t *p = get_data(rob);
4640 std::vector<const uint32_t *> pFragTmdb;
4641
4642 ATH_MSG_DEBUG( " Trying DECODER over source ID: " << MSG::hex
4643 << " 0x" << sourceid << MSG::dec
4644 << " full fragment size " << size );
4645
4646 while ( wc < size ) { // iterator over all words in a ROD
4647 // first word is the start of the tile subfragment in v3format it is 0xff1234ff
4648 if ((*p) == 0xff1234ff) b_sof=true;
4649
4650 ATH_MSG_DEBUG( " start of sub-fragment word : " << MSG::hex << (*p) << MSG::dec << " false/true : " << b_sof );
4651
4652 if (b_sof) {
4653 // second word is frag size
4654 sfrag_size = *(p + 1);
4655 // third word is frag version [31-16] and type [15-0]
4656 sfrag_version = *(p + 2) & 0xFFFF;
4657 sfrag_type = *(p + 2) >> 16;
4658 b_sof = false;
4659 }
4660 // for tmdb we will start to have three sub-fragments ordered as 0x40 0x41 0x42
4661 // we investigate if there are any of type 0x40,0x41 before going on 0x42
4662 // like this the loop is faster since we can access the size of this two sub-fragments
4663 if (sfrag_type == 0x40) {
4664 ATH_MSG_DEBUG( MSG::hex << " DECODER sub-fragment VERSION=" << sfrag_version
4665 << " TYPE=" << sfrag_type << MSG::dec
4666 << " SIZE=" << sfrag_size
4667 << " FOUND! Keep on looking for 0x42.");
4668 offset = sfrag_size;
4669 wc += offset;
4670 p += offset;
4671 } else if (sfrag_type == 0x41) {
4672 ATH_MSG_DEBUG( MSG::hex << " DECODER sub-fragment VERSION=" << sfrag_version
4673 << " TYPE=" << sfrag_type << MSG::dec
4674 <<" SIZE=" << sfrag_size
4675 << " FOUND! Keep on looking for 0x42.");
4676 offset = sfrag_size;
4677 wc += offset;
4678 p += offset;
4679 } else if (sfrag_type == 0x42) {
4680 b_deciTmdb = true;
4681 ATH_MSG_DEBUG( MSG::hex << " DECODER sub-fragment VERSION=" << sfrag_version
4682 << " TYPE=" << sfrag_type << MSG::dec
4683 << " SIZE=" <<sfrag_size << " FOUND!");
4684 wc += size - wc;
4685 p += 3;
4686 } else {
4687 ++p;
4688 ++wc;
4689 }
4690 }
4691 // the TMDB result 0x42
4692 //
4693 if (b_deciTmdb) unpack_frag42( sourceid, version, p, sfrag_size-3, cont);
4694
4695return;
4696}
4697
4698void TileROD_Decoder::unpack_frag40(uint32_t collid, uint32_t version, const uint32_t* p, int datasize,
4699 TileDigitsCollection &coll) const {
4700
4701 int ros = (collid >> 8);
4702 int drawer = collid & 0xff;
4703 HWIdentifier drawerID = m_tileHWID->drawer_id(ros, drawer);
4704 int nsamp = 7; // assume fixed number of samples for the moment
4705 int nmod = (ros > 2) ? 8 : 4; // we have 8 modules per fragment in ext.barrel, 4 modules in barrel
4706 int nchan = 4 * datasize / nmod / nsamp; // factor 4 because in one 32-bit word we have 4 samples
4707
4708 int nsamp1 = nsamp - 1;
4709
4710 std::vector<float> digits(nsamp);
4711
4712 // Each 32 bit word is made of four 8-bit words each a ADC of a sample like
4713 //
4714 // 32nd bit -> | 37/D6R | 38/D6L | 16/D5R | 17/D5L | <- 1st bit
4715 //
4716 // First come 8 words (M0->M7) with sample 0 and so forth i.e. the digits for the first module are placed by words: {0,8,16,24,32,40,48}.
4717 // Note that order of samples is inversed with respect to time line,
4718 // i.e. first sample from data should go to the last sample in TileDigits vector
4719
4720 int wpos = (collid % nmod) * nchan; // location of first sample for given channel in given module
4721 int jump = nchan * nmod; // distance between samples for one channel in number of bytes
4722 const unsigned char * adc = reinterpret_cast<const unsigned char *>(p);
4723
4724 for (int i = 0; i < nchan; ++i) {
4725 for (int j = 0; j < nsamp; ++j) {
4726 digits[nsamp1 - j] = adc[wpos + jump * j];
4727 }
4728 ++wpos;
4729 HWIdentifier adcID = m_tileHWID->adc_id(drawerID, i, TileID::LOWGAIN);
4730 TileDigits *digitmp = new TileDigits(adcID, digits);
4731 coll.push_back(digitmp);
4732 }
4733
4734 if (msgLvl(MSG::DEBUG)) {
4735 msg(MSG::DEBUG) << "TileROD_Decoder::unpack_frag40 frag: 0x" << MSG::hex << collid << MSG::dec
4736 << " version: " << version << endmsg;
4737
4738 int pos = coll.size() - nchan;
4739 const char * strchannel[13] = { " d5L ", " d5R ", " d6L ", " d6R ",
4740 " xxx ", " d0x ", " d1L ", " d1R ", " d2L ", " d2R ", " d3L ", " d3R ", " xxx " };
4741 int nchmax = (ros > 2) ? 4 : 8;
4742 for (int i = 0; i < nchan; ++i) {
4743 const std::vector<float> & sample = coll.at(pos + i)->samples();
4744 std::stringstream ss;
4745 for (const auto & val : sample) {
4746 ss << std::setw(5) << int(val);
4747 }
4748 msg(MSG::DEBUG) << " ros:" << ros
4749 << " drawer:" << drawer
4750 << " ch:" << i << strchannel[std::min(i, nchmax)+nchmax-4] << ss.str() << endmsg;
4751 }
4752 }
4753
4754 return;
4755}
4756
4757void TileROD_Decoder::unpack_frag41( uint32_t collid, uint32_t version, const uint32_t* p, int datasize, TileRawChannelCollection &coll ) const {
4758
4759 int ros=(collid>>8);
4760 int drawer=collid&0xff;
4761 HWIdentifier drawerID = m_tileHWID->drawer_id(ros,drawer);
4762 float calFactorADC2MeV = 1.0;
4763
4764 int nmod = (ros>2)?8:4; // we have 8 modules per fragment in ext.barrel, 4 modules in barrel
4765 int nchan = datasize / nmod;
4766
4767 int wpos = (collid % nmod) * nchan;
4768
4769 if (version == 0) {
4770
4771 // Each 32 bit word is an energy of a channel pmt
4772 //
4773 // 32nd bit -> | 17/D5L | <- 1st bit
4774 // 32nd bit -> | 16/D5R | <- 1st bit
4775 // 32nd bit -> | 37/D6L | <- 1st bit
4776 // 32nd bit -> | 38/D6R | <- 1st bit
4777 //
4778 // Each 4 words respect a module.
4779
4780 const int32_t * pp = reinterpret_cast<const int32_t *>(p);
4781 pp += wpos;
4782 for (int i = 0; i < nchan; ++i) {
4783 HWIdentifier adcID = m_tileHWID->adc_id(drawerID, i, TileID::LOWGAIN);
4784 TileRawChannel *rctmp = new TileRawChannel(adcID, (*pp) * calFactorADC2MeV, 0., 0.);
4785 coll.push_back(rctmp);
4786 ++pp;
4787 }
4788
4789 } else {
4790
4791 // Each 32 bit word is made of two 16-bit words each a energy of a channel pmt
4792 //
4793 // 32nd bit -> | 16/D5R | 17/D5L | <- 1st bit
4794 // 32nd bit -> | 38/D6R | 37/D6L | <- 1st bit
4795 //
4796 // Each 2 words respect a module.
4797
4798 nchan *= 2; // change number of channels calculated before assuming 16 bits for channel
4799 const int16_t * pp = reinterpret_cast<const int16_t *>(p);
4800 pp += wpos;
4801 for (int i = 0; i < nchan; ++i) {
4802 HWIdentifier adcID = m_tileHWID->adc_id(drawerID, i, TileID::LOWGAIN);
4803 TileRawChannel *rctmp = new TileRawChannel(adcID, (*pp) * calFactorADC2MeV, 0., 0.);
4804 coll.push_back(rctmp);
4805 ++pp;
4806 }
4807 }
4808
4809 if (msgLvl(MSG::DEBUG)) {
4810 msg(MSG::DEBUG) << " TileROD_Decoder::unpack_frag41 frag: 0x" << MSG::hex << collid << MSG::dec
4811 << " version: " << version << endmsg;
4812
4813 int nbits = (version == 0) ? 32 : 16;
4814 msg(MSG::DEBUG) << " position of " << nbits << "-bit word inside sub-fragment 0x41: " << wpos << endmsg;
4815 int pos = coll.size() - nchan;
4816 const char * strchannel[13] = { " d5L ", " d5R ", " d6L ", " d6R ",
4817 " xxx ", " d0x ", " d1L ", " d1R ", " d2L ", " d2R ", " d3L ", " d3R ", " xxx " };
4818 int nchmax = (ros > 2) ? 4 : 8;
4819 for (int i = 0; i < nchan; ++i) {
4820 msg(MSG::DEBUG) << " ros:" << ros
4821 << " drawer:" << drawer
4822 << " ch:" << i << strchannel[std::min(i, nchmax)+nchmax-4] << coll.at(pos + i)->amplitude() << endmsg;
4823 }
4824 }
4825
4826 return;
4827}
4828
4829void TileROD_Decoder::unpack_frag42( uint32_t sourceid, uint32_t version, const uint32_t* p, int datasize, TileMuonReceiverContainer &v ) const {
4830
4831 // == RUN 2 ==
4832 // results are hold in 3 16-bit words.
4833 //
4834 // 32nd bit -> | results2 || results1 | <- 1st bit
4835 // | 0x0 || results3 |
4836 //
4837 // 32nd bit -> | m-5 | m-4 | m-3 | m-2 || m-2 | m-1 | m-0 | 0x0 | <- 1st bit
4838 // | 0x0 || 0x0 | m-7 | m-6 | m-5 |
4839 //
4840 // each 4 bit word is
4841 // 0 1 2 3 <-- in Obj
4842 // | d56h | d56l | d6h | d6l |
4843 // bit3 bit2 bit1 bit0
4844 //
4845 // bit-3 -> result.at(0)
4846 // bit-2 .
4847 // bit-1 .
4848 // bit-0 -> result.at(3)
4849 //
4850 // == RUN 3 ==
4851 // results are hold in 3 16-bit words.
4852 //
4853 // 32nd bit -> | results2 [16:31] || results1 [0:15] | <- 1st bit
4854 // 32nd bit -> | 0x0 [16:31] || results3 [0:15] | <- 1st bit
4855 //
4856 // 32nd bit -> | bcid1 [12:15] | m-5 | m-4 | m-3 | m-2 || bcid0 [12:15] | m-3 | m-2 | m-1 | m-0 | <- 1st bit
4857 // | 0x0 [16:31] || bcid2 [12:15] | m-7 | m-6 | m-5 | m-4 |
4858 //
4859 // For each module m-X there is a 3-bit word with the results for a threshold
4860 //
4861 // | d5+d6 | d6 | d5 |
4862 // | bit2 | bit1 | bit0 |
4863 //
4864
4865 int nbit=0;
4866 int nmod=0;
4867 uint32_t word=0x0;
4868 uint32_t bcid=0x0;
4869
4870 int drawer = (sourceid & 0xf0000) >> 8; // get ROS number from source ID
4871 if (drawer<0x300) { // barrel
4872 nbit = 4;
4873 nmod = 4;
4874 drawer |= ((sourceid & 0x0000f) << 2);
4875 word = (datasize > 0) ? p[0] : 0; // just use first word, although expect all zeros for the moment
4876 } else { // extended barrel
4877 nbit = 4;
4878 nmod = 8;
4879 drawer |= ((sourceid & 0x0000f) << 3);
4880 if (datasize > 1) {
4881 if (m_runPeriod<=2) {
4882 word = (p[1] << 20) | ((p[0] >> 8) & 0xff000) | ((p[0] >> 4) & 0xfff);
4883 } else {
4884 word = ((p[1] & 0xfff) << 12) | (p[0] & 0xfff);
4885 // keeping all 12 bits of information (just for cross check) |bcid2|bcid1|bcid0|
4886 bcid = ((p[1] >> 4) & 0xf00) | ((p[0] >> 24) & 0xf0) | ((p[0] >> 12) & 0xf);
4887 }
4888 }
4889 }
4890
4891 drawer |= (bcid<<16) ;
4892
4893 std::vector<bool> result(nbit);
4894 for (int j = 0; j < nmod; ++j) { // loop over modules
4895 for (int k = nbit-1; k >= 0; --k) { // loop over bits of one module in inversed order
4896 if (m_runPeriod<=2) {
4897 result[k] = (word & 1);
4898 word >>= 1;
4899 } else {
4900 if (k==0) {
4901 result[k]=0;
4902 } else {
4903 result[k] = (word & 1);
4904 word >>= 1;
4905 }
4906 }
4907 }
4908 TileMuonReceiverObj * obj = new TileMuonReceiverObj(drawer, result);
4909 v.push_back(obj);
4910 ++drawer;
4911 }
4912
4913 if (msgLvl(MSG::DEBUG)) {
4914 if (m_runPeriod<=2) msg(MSG::DEBUG) << "TMDB version for RUN2 simulation (2014)" <<endmsg;
4915 else msg(MSG::DEBUG) << "TMDB version for RUN3 simulation (2020)" <<endmsg;
4916
4917 msg(MSG::DEBUG) << " TileROD_Decoder::unpack_frag42 source ID: 0x" << MSG::hex << sourceid << MSG::dec
4918 << " version: " << version << " bcid | drawer " << MSG::hex << drawer << endmsg;
4919
4920 for (size_t j = v.size() - nmod; j < v.size(); ++j) {
4921 const std::vector<bool> & r = v[j]->GetDecision();
4922 std::stringstream ss;
4923 for (const bool val : r) {
4924 ss << std::setw(2) << val;
4925 }
4926 msg(MSG::DEBUG) << MSG::hex << "0x" << v[j]->GetID() << MSG::dec << ss.str() << endmsg;
4927 }
4928 }
4929
4930 return;
4931}
4932
const boost::regex re(r_e)
Scalar eta() const
pseudorapidity method
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
OFFLINE_FRAGMENTS_NAMESPACE::PointerType DataType
Helpers for checking error return status codes and reporting errors.
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
unsigned int uint
static Double_t a
static Double_t ss
static Double_t rc
const bool debug
OFFLINE_FRAGMENTS_NAMESPACE::FullEventFragment RawEvent
data type for reading raw event
Definition RawEvent.h:37
TileContainer< TileMuonReceiverObj > TileMuonReceiverContainer
TileContainer< TileL2 > TileL2Container
bool Format6(const std::vector< double > &a, const std::vector< double > &b, const std::vector< double > &c, const std::vector< double > &g, const std::vector< double > &h, unsigned int channel_index, int phase, double calibration, std::vector< unsigned int > &OFC, bool verbose)
Format6.
Definition TileOFC.cxx:270
static const InterfaceID IID_ITileROD_Decoder("TileROD_Decoder", 1, 0)
unsigned char qbitfun(float t, float a, float b)
#define LASER2_OBJ_FRAG
bool chan_order1(const TileFastRawChannel &a, const TileFastRawChannel &b)
bool chan_order(TileRawData *a, TileRawData *b)
const float QUALITY_THRESHOLD
#define Frag5_unpack_reco_bin(w, code, gain, amp, time)
unpack_reco_bin
#define Frag5_unpack_bin2sum(unit, amp_bin)
unpack_bin2sum
#define Frag5_unpack_bin2reco(unit, gain, amp_bin, amp, time_bin, time)
unpack_bin2reco
#define LASER_OBJ_FRAG
Definition TileTBFrag.h:49
#define COMMON_TDC2_FRAG
Definition TileTBFrag.h:47
#define COMMON_ADC1_FRAG
Definition TileTBFrag.h:43
#define COMMON_ADC2_FRAG
Definition TileTBFrag.h:44
#define COMMON_TDC1_FRAG
Definition TileTBFrag.h:46
#define BEAM_TDC_FRAG
Definition TileTBFrag.h:23
#define COMMON_TOF_FRAG
Definition TileTBFrag.h:45
#define ADD_FADC_FRAG
Definition TileTBFrag.h:29
const char *const fmt
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
const ServiceHandle< StoreGateSvc > & detStore() const
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
float time() const
get time (data member)
Definition CaloCell.h:368
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
Definition CaloCell.h:321
IdentifierHash onl2() const
cell online identifier 2
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
const T * at(size_type n) const
Access an element, as an rvalue.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
const_iterator end() const noexcept
const_iterator begin() const noexcept
size_type size() const noexcept
int getMaxChannels(void) const
Static class providing several utility functions and constants.
static unsigned int getDrawerIdxFromFragId(unsigned int fragId)
Returns a drawer hash from fragId This function assumes drawer context (i.e.
static const unsigned int MAX_DRAWER
Number of drawers in ROS 1-4.
static unsigned int getDrawerIdx(unsigned int ros, unsigned int drawer)
Returns a drawer hash.
void setQuality_nonvirt(unsigned char qual, unsigned char qbit, int pmt)
Definition TileCell.h:272
void addEnergy(float e, int pmt, int gain)
set energy and gain for one PMT
Definition TileCell.cxx:145
void setTime_nonvirt(float t)
Definition TileCell.h:244
virtual void setEnergy(float ene) override final
set total energy, reset eneDiff to zero (final override of CaloCell method)
Definition TileCell.cxx:123
virtual void setTime(float t) override final
set cell time, reset timeDiff
Definition TileCell.h:251
@ MASK_AMPL
Definition TileCell.h:65
@ MASK_TIME
Definition TileCell.h:67
void set(unsigned int channel, unsigned int adc, float amplitude, float time, float quality)
unsigned int adc(void) const
float time(void) const
float quality(void) const
float amplitude(void) const
unsigned int channel(void) const
TYPE
initialize
@ BARREL_POS
Definition TileHWID.h:68
@ EXTBAR_NEG
Definition TileHWID.h:71
@ BARREL_NEG
Definition TileHWID.h:69
@ EXTBAR_POS
Definition TileHWID.h:70
@ HIGHGAIN
Definition TileHWID.h:73
@ LOWGAIN
Definition TileHWID.h:72
@ NOT_VALID_HASH
Definition TileHWID.h:314
const std::vector< uint32_t > & getDrawerInfo(int frag_id) const
void setDaqType(const unsigned int daqtype)
int getType(int chan, int gain, int type) const
void setCalib(int chan, int type, double sumXinQDC, double sumX2inQDC, int nevts, int gain)
void setPmt(const unsigned int pmt, const int pmAdc, const int tdc, const double pmPedestal, const double pmSigmaPedestal, const unsigned int gain)
void setCalibType(int type)
int getN(int chan, int gain, int type) const
double getMean(int chan, int gain, int type) const
void setTimeouts(const bool qdc, const bool tdc)
void setDiode(const unsigned int diode, const int diodeAdc, const double diodePedestal, const double diodeSigmaPedestal, const double alpha, const double sigmaAlpha, const double pedestalAlpha, const double sigmaPedAlpha, const unsigned int gain)
void setPLC(const int alphaPos, const double LVdiodes, const double HVpmts, const int shutter, const int interlock, const int alarm)
void setControl(const double pumpDiodeTemp, const int timeLastMeasP, const double diodeBoxTemp, const int timeLastMeasD, const double gasFlux, const int timeLastMeasG, const double humidity, const int timeLastMeasH, const time_t lastPedMeas, const time_t lastAlphaMeas)
bool isLASERII() const
bool isSet(int chan, int gain, int type) const
int getVersion() const
void setLaser(const int Counter, const int diodeCurrOrd, const int diodeCurrMeas, const int filtNumber, const int timingDelay, const int version)
double getSigma(int chan, int gain, int type) const
void unpack_frag11(uint32_t version, const uint32_t *p, TileL2Container &v, int fragID, int demoType) const
unpack_frag11 decodes tile subfragment type 0x11.
std::vector< int > m_Rw2Pmt[4]
void make_copy(uint32_t bsflags, TileFragHash::TYPE rChType, TileRawChannelUnit::UNIT rChUnit, DigitsMetaData_t &digitsMetaData, RawChannelMetaData_t &rawchannelMetaData, const ROBData *rob, pDigiVec &pDigits, pRwChVec &pChannel, TileBeamElemCollection &v, TileBeamElemContainer *container) const
uint32_t fillCollectionHLT(const ROBData *rob, TileCellCollection &v, D0CellsHLT &d0cells, TileCellCollection *MBTS, const TileHid2RESrcID *hid2reHLT) const
std::vector< int > m_demoChanEB
void mergeD0cellsHLT(const D0CellsHLT &d0cells, TileCellCollection &) const
float m_ampMinThresh_pC
correct amplitude if it's above amplitude threshold (in pC)
Gaudi::Property< float > m_allowedTimeMin
void fillTileLaserObj(const ROBData *rob, TileLaserObject &v) const
void unpack_frag14(uint32_t version, const uint32_t *p, TileL2Container &v, int fragID, int demoType) const
unpack_frag14 decodes tile subfragment type 0x14.
SG::ReadCondHandleKey< TileHid2RESrcID > m_hid2RESrcIDKey
TileHid2RESrcID * m_hid2re
StatusCode convert(const RawEvent *re, TileL2Container *L2Cnt) const
void unpack_frag42(uint32_t sourceid, uint32_t version, const uint32_t *p, int size, TileMuonReceiverContainer &v) const
std::vector< uint32_t > get_correct_data(const uint32_t *p) const
void unpack_frag5(uint32_t version, uint32_t sizeOverhead, unsigned int unit, DigitsMetaData_t &digitsMetaData, const uint32_t *p, pDigiVec &pDigits, pRwChVec &pChannel, int fragID, int demoType) const
unpack_frag5 decodes tile subfragment type 0x4.
void unpack_frag15(uint32_t version, const uint32_t *p, TileL2Container &v, int fragID, int demoType) const
unpack_frag15 decodes tile subfragment type 0x15.
std::vector< TileDigits * > pDigiVec
void unpack_frag12(uint32_t version, const uint32_t *p, TileL2Container &v, int fragID, int demoType) const
unpack_frag12 decodes tile subfragment type 0x12.
void updateAmpThreshold(int run=-1)
void unpack_frag41(uint32_t collid, uint32_t version, const uint32_t *p, int size, TileRawChannelCollection &coll) const
static const InterfaceID & interfaceID()
AlgTool InterfaceID.
uint32_t make_copyHLT(bool of2, TileRawChannelUnit::UNIT rChUnit, bool correctAmplitude, const FRwChVec &pChannel, TileCellCollection &v, const uint16_t DQuality, D0CellsHLT &d0cells, TileCellCollection *MBTS) const
friend class TileHid2RESrcID
Gaudi::Property< int > m_maxWarningPrint
void fillContainer_TileMuRcv_Decision(const ROBData *rob, TileMuonReceiverContainer &v) const
Gaudi::Property< int > m_maxErrorPrint
void unpack_frag3(uint32_t version, uint32_t sizeOverhead, const uint32_t *p, pRwChVec &pChannel, int fragID, int demoType) const
unpack_frag3 decodes tile subfragment type 0x3.
void unpack_frag4(uint32_t version, uint32_t sizeOverhead, unsigned int unit, RawChannelMetaData_t &rawchannelMetaData, const uint32_t *p, pRwChVec &pChannel, int fragID, int demoType) const
unpack_frag4 decodes tile subfragment type 0x4.
void unpack_frag4HLT(uint32_t version, uint32_t sizeOverhead, unsigned int unit, const uint32_t *p, FRwChVec &pChannel, int fragID, int demoType) const
unpack_frag4HLT decodes tile subfragment type 0x4 for the high level trigger (HLT).
TileRawChannel2Bytes5 m_rc2bytes5
void unpack_frag1(uint32_t version, uint32_t sizeOverhead, DigitsMetaData_t &digitsMetaData, const uint32_t *p, pDigiVec &pDigits, int fragID, int demoType) const
unpack_frag1 decodes tile subfragment type 0x1.
void unpack_frag10(uint32_t version, const uint32_t *p, TileL2Container &v, int fragID, int demoType) const
unpack_frag10 decodes tile subfragment type 0x10.
void fillCollectionL2(const ROBData *rob, TileL2Container &v) const
const TileHWID * m_tileHWID
std::vector< std::vector< uint32_t > > RawChannelMetaData_t
Gaudi::Property< float > m_ampMinThresh
Gaudi::Property< float > m_timeMinThresh
Gaudi::Property< bool > m_useFrag5Reco
std::map< unsigned int, unsigned int > m_mapMBTS
std::mutex m_OFWeightMutex
TileRawChannel2Bytes m_rc2bytes
void printWarningCounter(bool printIfNoWarning)
std::vector< TileFastRawChannel > FRwChVec
TileRawChannel2Bytes4 m_rc2bytes4
void loadMBTS(std::map< unsigned int, unsigned int > &mapMBTS, int MBTS_channel)
ToolHandle< TileL2Builder > m_L2Builder
TileDigits2Bytes m_d2Bytes
bool unpack_frag4L2(uint32_t version, uint32_t sizeOverhead, const uint32_t *p, TileL2Container &v, int fragID, int demoType) const
unpack_frag4L2 decodes tile subfragment type 0x4 and extract transverse energy from this fragment
unsigned int m_maxChannels
ToolHandle< TileCondToolOfcCool > m_tileCondToolOfcCool
std::vector< int > m_Rw2Cell[4]
Gaudi::Property< float > m_allowedTimeMax
void unpack_frag6(uint32_t version, uint32_t sizeOverhead, DigitsMetaData_t &digitsMetaData, const uint32_t *p, pDigiVec &pDigits, int fragID, int demoType) const
unpack_frag6 decodes tile subfragment type 0x6.
TileHid2RESrcID * m_hid2reHLT
void fillCollection_TileMuRcv_RawChannel(const ROBData *rob, TileRawChannelCollection &v) const
Gaudi::Property< std::vector< int > > m_demoFragIDs
void unpack_frag16(uint32_t version, const uint32_t *p, TileLaserObject &v) const
unpack_frag16 decodes tile subfragment type 0x16 or 0x20.
virtual StatusCode finalize()
void unpack_fragAHLT(uint32_t version, const uint32_t *p, uint16_t rob_bcid, uint16_t &mask, int fragID, int demoType) const
unpack_fragAHLT decodes tile subfragment type 0XA.
void unpack_frag2(uint32_t version, uint32_t sizeOverhead, const uint32_t *p, pRwChVec &pChannel, int fragID, int demoType) const
unpack_frag2 decodes tile subfragment type 0x2.
std::vector< int > m_list_of_masked_drawers
virtual ~TileROD_Decoder()
destructor
const uint32_t * get_data(const ROBData *rob) const
TileFragHash m_hashFunc
Gaudi::Property< bool > m_verbose
StatusCode convertTMDBDecision(const RawEvent *re, TileMuonReceiverContainer *tileMuRcv) const
std::atomic< int > m_ErrorCounter
void unpack_frag40(uint32_t collid, uint32_t version, const uint32_t *p, int size, TileDigitsCollection &coll) const
unpacking methods dedicated to the TMDB ROD format sub-fragments 0x40 0x41 0x42
ToolHandle< ITileBadChanTool > m_tileBadChanTool
std::vector< std::vector< uint32_t > > DigitsMetaData_t
void unpack_frag17(uint32_t version, uint32_t sizeOverhead, const uint32_t *p, TileLaserObject &v) const
unpack_frag17 decodes tile subfragment type 0x17 or 0x20.
std::vector< TileRawChannel * > pRwChVec
void fillCollectionL2ROS(const ROBData *rob, TileL2Container &v) const
void fillCollection_TileMuRcv_Digi(const ROBData *rob, TileDigitsCollection &v) const
bool checkBit(const uint32_t *p, int chan) const
check the bitmap for a channel
void unpack_frag3HLT(uint32_t version, uint32_t sizeOverhead, const uint32_t *p, FRwChVec &pChannel, int fragID, int demoType) const
unpack_frag3HLT decodes tile subfragment type 0x3 for the high level trigger (HLT).
ToolHandle< TileCondToolEmscale > m_tileToolEmscale
void printErrorCounter(bool printIfNoError)
void unpack_frag5HLT(uint32_t version, uint32_t sizeOverhead, unsigned int unit, const uint32_t *p, FRwChVec &pChannel, int fragID, int demoType) const
unpack_frag5HLT decodes tile subfragment type 0x5 for the high level trigger (HLT).
Gaudi::Property< float > m_timeMaxThresh
void unpack_frag0(uint32_t version, uint32_t sizeOverhead, DigitsMetaData_t &digitsMetaData, const uint32_t *p, pDigiVec &pDigits, int fragID, int demoType) const
unpack_frag0 decodes tile subfragment type 0x0.
virtual StatusCode initialize()
std::vector< TileBeamElem * > pBeamVec
bool unpack_frag5L2(uint32_t version, const uint32_t *p, TileL2Container &v, int fragID, int demoType) const
unpack_frag5L2 decodes tile subfragment type 0x5 and extract transverse energy from this fragment
TileROD_Decoder(const std::string &type, const std::string &name, const IInterface *parent)
constructor
void setLaserVersion(TileLaserObject &laserObject) const
ToolHandle< TileCondToolTiming > m_tileToolTiming
float m_ampMinThresh_MeV
correct amplitude if it's above amplitude threshold (in MeV)
Gaudi::Property< bool > m_useFrag5Raw
Gaudi::Property< unsigned int > m_fullTileRODs
ServiceHandle< TileCablingSvc > m_cablingSvc
uint32_t data_size(const ROBData *rob, uint32_t &error) const
void unpack_frag13(uint32_t version, const uint32_t *p, TileL2Container &v, int fragID, int demoType) const
unpack_frag13 decodes tile subfragment type 0x13.
eformat::ROBFragment< const uint32_t * > ROBData
convert ROD Data words into either TileCell or TileRawChannel.
Gaudi::Property< bool > m_ignoreFrag4HLT
std::vector< int > m_demoChanLB
const uint32_t * getOFW(int fragId, int unit) const
getOFW returns Optimal Filtering Weights for Frag5 decoder loaded from COOL for correspondent units.
TileRawChannel2Bytes2 m_rc2bytes2
std::atomic< int > m_WarningCounter
StatusCode convertLaser(const RawEvent *re, TileLaserObject *TileLaserObj) const
void fillCollection_FELIX_Digi(const ROBData *rob, TileDigitsCollection &v) const
void unpack_brod(uint32_t version, uint32_t sizeOverhead, const uint32_t *p, pBeamVec &pBeam, int fragID) const
unpack_brod decodes all ancillary tile subfragments coming from beam ROD at the testbeam or LASTROD i...
Gaudi::Property< bool > m_suppressDummyFragments
void unpack_frag2HLT(uint32_t version, uint32_t sizeOverhead, const uint32_t *p, FRwChVec &pChannel, int fragID, int demoType) const
unpack_frag2HLT decodes tile subfragment type 0x2 for the high level trigger (HLT).
void unpack_fragA(uint32_t version, RawChannelMetaData_t &rawchannelMetaData, const uint32_t *p, pRwChVec &pChannel, int fragID, int demoType) const
unpack_fragA decodes tile subfragment type 0XA.
static double correctAmp(double phase, bool of2=true)
Amplitude correction factor according to the time when using weights for tau=0 without iterations.
int r
Definition globals.cxx:22
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146
std::map< std::string, std::string > remap
list of directories to be explicitly remapped
Definition hcg.cxx:95
@ INVALIDGAIN
Definition CaloGain.h:18
Definition run.py:1
STL namespace.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
TileFastRawChannel m_D0channeg[64]
TileFastRawChannel m_D0chanpos[64]