ATLAS Offline Software
Loading...
Searching...
No Matches
TileROD_Encoder.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_Encoder class
6
8
13#include "TileEvent/TileL2.h"
16
17#include <iomanip>
18#include <sstream>
19#include <algorithm>
20#include <cassert>
21#include <cmath>
22
23
24namespace {
25
26// Helper to fill a vectorr of uint32_t with packed int16_t values.
27class ShortVecAdapter
28{
29public:
30 ShortVecAdapter (std::vector<uint32_t>& v)
31 : m_v (v) {}
32 void push_back (int16_t x)
33 {
34 if (m_offset) {
35 m_v.back() |= (x << 16);
36 m_offset = false;
37 }
38 else {
39 m_v.push_back (x);
40 m_offset = true;
41 }
42 }
43 void align()
44 {
45 m_offset = false;
46 }
47
48private:
49 std::vector<uint32_t>& m_v;
50 bool m_offset = false;
51};
52
53}
54
55
57 AthMessaging ("TileROD_Encoder"),
58 m_tileHWID(0),
59 m_verbose(false),
60 m_type(0),
61 m_unitType(0),
62 m_rChUnit(0),
64 m_runPeriod(0){
65}
66
67
68void TileROD_Encoder::setTileHWID(const TileHWID* tileHWID, bool verbose, unsigned int type) {
69 m_tileHWID = tileHWID;
71 m_type = type;
72 m_unitType = (m_type << 16);
73
74 switch (type) {
75 case 4:
76 m_rc2bytes4.setVerbose(verbose);
77 break;
78 case 5:
79 m_rc2bytes5.setVerbose(verbose);
80 break;
81 case 3:
82 m_rc2bytes3.setVerbose(verbose);
83 break;
84 case 2:
85 m_rc2bytes2.setVerbose(verbose);
86 break;
87 default:
88 break;
89 }
90}
91
92void TileROD_Encoder::setTileHWID(const TileHWID* tileHWID, int runPeriod) {
93 m_tileHWID = tileHWID;
94 m_runPeriod = runPeriod;
95}
96
98
99 unsigned int OFType = (unsigned int) type;
100 if (OFType > 7) {
101 OFType = 0;
102 ATH_MSG_ERROR( "setTypeAndUnit Incorrect raw data type =" << type
103 << " using type=0 instead " );
104 }
105
106 unsigned int rChUnit = (unsigned int) unit % (unsigned int) TileRawChannelUnit::OnlineOffset;
107
108 // make sure that we use frag type 4 for units which are not ADC counts
109 if (rChUnit != 0 && m_type < 4) m_type = 4;
110 if (m_type == 4) { // new fragments have non-zero upper byte
111 // 8 upper bits:
112 // UUPPSTTT
113 // 31,30 - units
114 // 29,28 - pulse type ( = 3 for simulated data)
115 // 27 - 7(=0) or 9(=1) samples (assume 7 samples for now)
116 // 24,25,26 - OF type
117 // next 8 bits - frag type ( 2,3,4, ... )
118 m_unitType = (rChUnit << 30) | (3 << 28) | (0 << 27) | (OFType << 24) | (m_type << 16);
119 m_rChUnit = rChUnit;
120 } else if (m_type == 5) {
121 // 8 upper bits:
122 // UULLLTTT
123 // 31,30 - units
124 // 29,28,27 - length of Level2 part ( = 3 - sumEt, sumEz, sumE )
125 // 24,25,26 - OF type
126 m_unitType = (rChUnit << 30) | (3 << 27) | (OFType << 24) | (m_type << 16);
127 m_rChUnit = rChUnit;
128 }
129
130}
131
132void TileROD_Encoder::setMaxChannels(int maxChannels) {
133 m_maxChannels = maxChannels;
134}
135
136
139
140void TileROD_Encoder::fillROD(std::vector<uint32_t>& v) {
141 switch (m_type) {
142 case 4:
143 fillROD4(v);
144 break;
145 case 5:
146 fillROD5(v);
147 break;
148 case 3:
149 fillROD3(v);
150 break;
151 case 2:
152 fillROD2(v);
153 break;
154 case 1:
155 fillROD1(v);
156 break;
157 case 0x10:
158 fillROD10(v);
159 break;
160 case 0x12:
161 fillROD12(v);
162 break;
163 default:
164 ATH_MSG_ERROR( "fillROD -> Unknown packing type " << m_type );
165 assert(0);
166 break;
167 // return;
168 }
169}
170
171
172void TileROD_Encoder::fillROD10(std::vector<uint32_t>& v) {
173
174 int currentFrag(-1);
175 std::vector<uint32_t>::size_type start = 0;
176
177 int NMuons1 = 0, NMuons2 = 0, frag = 0;
178
179 for (const TileL2* l2 : m_vTileL2) {
180
181 int ros = ((l2->identify()) | 0xff) >> 8;
182 int drawer = (l2->identify()) & 0xff;
183
184 if ((drawer % 2) == 0) frag = 0x00100000 + (ros << 12) + ((drawer + 1) << 6) + drawer;
185
186 if (frag != currentFrag) { // superdrawer is even
187
188 currentFrag = frag;
189
190 // fragment marker
191 v.push_back(0xff1234ff);
192
193 // fragment size (variable depending on the number of muons found)
194 v.push_back(5);
195
196 // fragment ID
197 v.push_back(frag);
198
199 // first word after fragment header
200 start = v.size();
201
202 // reserve 2 words for Et
203 for (int i = 0; i < 2; ++i)
204 v.push_back(0);
205
206 // Et superdrawer #1
207 int wet = (int) round(l2->sumEt());
208 v[start] = (unsigned int) (wet + 9000); // shift by 9000 to be compatible with frag 0x10 format
209
210 // MTag superdrawer #1
211 NMuons1 = l2->NMuons();
212 for (int i = 0; i < 2 * NMuons1; ++i)
213 v.push_back(l2->val(i));
214
215 } else { // superdrawer is odd
216
217 // Et superdrawer #2
218 int wet = (int) round(l2->sumEt());
219 v[start + 1] = (unsigned int) (wet + 9000); // shift by 9000 to be compatible with frag 0x10 format
220
221 // MTag superdrawer #2
222 NMuons2 = l2->NMuons();
223 for (int i = 0; i < 2 * NMuons2; ++i)
224 v.push_back(l2->val(i));
225
226 // re-write fragment size
227 // start should be >= 3 here, but coverity can't prove it.
228 //coverity[INTEGER_OVERFLOW]
229 v[start - 2] = 5 + 2 * NMuons1 + 2 * NMuons2;
230
231 }
232
233 }
234
235 //assert(0);
236}
237
238void TileROD_Encoder::fillROD12(std::vector<uint32_t>& v) {
239
240 int currentFrag(-1);
241 std::vector<uint32_t>::size_type start = 0;
242
243 int frag = 0;
244
245 for (const TileL2* l2 : m_vTileL2) {
246
247 int ros = (l2->identify()) >> 8;
248 int drawer = (l2->identify()) & 0xff;
249
250 if ((drawer % 2) == 0)
251 frag = 0x120000 + (ros << 12) + ((drawer + 1) << 6) + drawer;
252 else
253 frag = 0x120000 + (ros << 12) + (drawer << 6) + (drawer - 1);
254
255 if (frag != currentFrag) { // superdrawer is even
256
257 currentFrag = frag;
258
259 // fragment marker
260 v.push_back(0xff1234ff);
261
262 // fragment size (variable depending on the number of muons found)
263 v.push_back(3);
264
265 // fragment ID
266 v.push_back(frag);
267
268 // first word after fragment header
269 start = v.size();
270 }
271
272 // MTag data
273 int Ndata = l2->Ndata();
274 if (Ndata) {
275 for (int i = 0; i < Ndata; ++i)
276 v.push_back(l2->val(i));
277
278 // re-write fragment size
279 // start should be >= 3 here, but coverity can't prove it.
280 //coverity[INTEGER_OVERFLOW]
281 v[start - 2] += Ndata;
282 }
283 }
284
285 //assert(0);
286}
287
288void TileROD_Encoder::fillROD2(std::vector<uint32_t>& v) {
289 //std::sort(m_vTileRC.begin(), m_vTileRC.end(), m_order);
290
291 int currentFrag(-1);
292 std::vector<uint32_t>::size_type start = 0;
293
294 for (const TileFastRawChannel* rc : m_vTileRC) {
295
296 int frag = rc->frag() | m_unitType; // FRAG TYPE in upper half of the word
297
298 if (frag != currentFrag) {
299 currentFrag = frag;
300
301 // very first word is size of the fragment, which is 50 words
302 v.push_back(50);
303 // next word is frag ID
304 v.push_back(frag);
305
306 // remember where is the first channel
307 start = v.size();
308 // reserve maximum number of channels in a drawer words
309 // for all channels in the drawer
310 v.resize(start + m_maxChannels, 0);
311
312 }
313
314 // FIXME:: protection against both low and high gain amplitude
315 // for the same raw channel,
316 // if this is the case all channels should have both
317 // low and high gain and we should use different fragment type
318
319 int chan = rc->channel();
320 int gain = rc->adc();
321 if (chan < m_maxChannels) {
322 v[start + chan] = m_rc2bytes2.getWord(rc, gain);
323 }
324
325 } // end of all TileRawChannel
326
327 // dumpROD (v) ;
328
329 return;
330}
331
332void TileROD_Encoder::fillROD3(std::vector<uint32_t>& v) {
333 ShortVecAdapter v16 (v);
334
335 //std::sort(m_vTileRC.begin(), m_vTileRC.end(), m_order);
336
337 int currentFrag(-1);
338 bool first = true;
339 std::vector<uint32_t>::size_type head = 0;
340 std::vector<uint32_t>::size_type count = 0;
341
342 std::vector<short> vshort;
343
344 for (const TileFastRawChannel* rc : m_vTileRC) {
345
346
347 int frag = rc->frag() | m_unitType; // FRAG TYPE in upper half of the word
348 int chan = rc->channel();
349 int gain = rc->adc();
350
351 if (frag != currentFrag) {
352 currentFrag = frag;
353 // a new frag
354 if (!first) {
355 // close the current frag
356 v16.align();
357 // inclusive word (32bit) for this frag
358 v[count] = v.size();
359 } else
360 first = false;
361
362 // very first word is size of the fragment
363 // remember where it is
364 count = v.size();
365 v.push_back(0);
366 // add frag ID
367 v.push_back(frag);
368
369 // remember where map starts
370 head = v.size();
371 // 2 words (64 bits) for channel map
372 v.push_back(0);
373 v.push_back(0);
374 }
375
376 // FIXME:: protection against both low and high gain amplitude
377 // for the same raw channel,
378 // if this is the case all channels should have both
379 // low and high gain and we should use different fragment type
380
381 if (checkBit(&(v[head]), chan)) {
382 // the same channel with another gain already exists, ignore second one
383 } else {
384 vshort.clear();
385 m_rc2bytes3.getBytes(rc, gain, vshort);
386 for (short x : vshort)
387 v16.push_back (x);
388 // set bitmap for this channel
389 setBit(&(v[head]), chan);
390 }
391
392 } // end of all TileRawChannel
393
394 if (!first) {
395 // close the last Frag
396 v16.align();
397 // inclusive word (32bit) for this frag
398 v[count] = v.size();
399 }
400
401 // dumpROD (v) ;
402
403 return;
404}
405
406void TileROD_Encoder::fillROD4(std::vector<uint32_t>& v) {
407 //std::sort(m_vTileRC.begin(), m_vTileRC.end(), m_order);
408
409 int currentFrag(-1);
410 std::vector<uint32_t>::size_type start = 0;
411
412 for (const TileFastRawChannel* rc : m_vTileRC) {
413
414 int frag = rc->frag() | m_unitType; // FRAG TYPE in upper half of the word
415
416 if (frag != currentFrag) {
417 currentFrag = frag;
418
419 // very first word is start fragment identifier
420 v.push_back(0xff1234ff);
421 // next word is frag size:
422 // (maximum number of channels in a drawer) + ...
423 // ... + (6 = start frag + frag size + frag ID + 3 sumE words)
424 v.push_back(m_maxChannels + 6);
425 // next word is frag ID
426 v.push_back(frag);
427
428 // remember where is the first channel
429 start = v.size();
430
431 // reserve (maximum number of channels in a drawer) words
432 // for all channels in the drawer and 3 sumE words
433 v.resize(start + m_maxChannels + 3, 0);
434
435 }
436
437 // FIXME:: protection against both low and high gain amplitude
438 // for the same raw channel,
439 // if this is the case all channels should have both
440 // low and high gain and we should use different fragment type
441
442 int chan = rc->channel();
443 int gain = rc->adc();
444 if (chan < m_maxChannels) {
445 v[start + chan] = m_rc2bytes4.getWord(*rc, m_rChUnit, gain);
446 }
447
448 } // end of all TileRawChannel
449
450 // dumpROD (v) ;
451
452 return;
453}
454
455void TileROD_Encoder::fillRODL2(std::vector<uint32_t>& v) {
456
457 std::map<int, const TileL2*> l2_map;
458
459 for (const TileL2* l2 : m_vTileL2) {
460 l2_map[l2->identify()] = l2;
461 //std::cout << "l2 id=0x"<<std::hex<<l2->identify()<<std::dec<<std::endl;
462 }
463
464 std::vector<uint32_t>::size_type start = 3;
465
466 while (start <= v.size()) {
467 uint32_t size = v[start - 2];
468 uint32_t fragtype = v[start - 1];
469 int type = (fragtype >> 16) & 0xFF;
470 //std::cout <<std::hex<<"frag 0x"<<fragtype<<std::dec<<" size "<<size<<std::endl;
471 if ((type == 4 && size > 53) || (type == 5 && ((fragtype >> 27) & 7) > 2)) {
472 int frag = fragtype & 0xFFFF;
473 std::map<int, const TileL2*>::const_iterator l2_it = l2_map.find(frag);
474 if (l2_it != l2_map.end()) {
475 int unit = (fragtype >> 30);
476 const TileL2* l2 = l2_it->second;
477 int et = round(l2->sumEt() * AMPLITUDE_FACTOR5_HG[unit]);
478 v[start + 48] = (uint32_t) et;
479 int ez = round(l2->sumEz() * AMPLITUDE_FACTOR5_HG[unit]);
480 v[start + 49] = (uint32_t) ez;
481 int e = round(l2->sumE() * AMPLITUDE_FACTOR5_HG[unit]);
482 v[start + 50] = (uint32_t) e;
483 //std::cout << "Found "<<et<<","<<ez<<","<<e<<std::endl;
484 }
485 }
486 start += size;
487 }
488
489 if (msgLvl(MSG::VERBOSE)) dumpROD(v);
490
491 return;
492}
493
494void TileROD_Encoder::fillROD1(std::vector<uint32_t>& v) {
495
496 std::sort(m_vTileDigi.begin(), m_vTileDigi.end(), m_order);
497
498 int currentFrag = -1, pos = 0, size = 0;
499 for (const TileDigits* digi : m_vTileDigi) {
500
501 HWIdentifier adcID = digi->adc_HWID();
502 int frag = m_tileHWID->frag(adcID) | (0x01 << 16); // FRAG TYPE = 1 in upper half of the word
503 if (frag != currentFrag) {
504 if (currentFrag != -1) v[pos] = size;
505 currentFrag = frag;
506 // first word is start of fragment identifier
507 v.push_back(0xFF1234FF);
508 // next word is frag size
509 pos = v.size();
510 v.push_back(0);
511 // next word is frag ID
512 v.push_back(frag);
513 size = 3;
514 }
515 size += m_Digi2bytes.getBytes(digi, m_tileHWID, v);
516 }
517 if (currentFrag != -1) v[pos] = size;
518 return;
519}
520
521void TileROD_Encoder::fillROD5(std::vector<uint32_t>& /* v */) {
522 ATH_MSG_ERROR( "fillROD5 -> store raw channels in frag5 - not yet implemented " );
523}
524
525void TileROD_Encoder::fillROD5D(std::vector<uint32_t>& /* v */) {
526 ATH_MSG_ERROR( "fillROD5D -> store digits in frag5 - not yet implemented " );
527}
528
529// == START of TMDB Encoders: Digits, Raw Channel, Decision
530
531// TMDB Digits
532
533void TileROD_Encoder::fillRODTileMuRcvDigi(std::vector<uint32_t>& v) {
534
535 ATH_MSG_DEBUG( "TMDB encoding sub-fragment 0x40: loop over " << m_vTileDigi.size() << " objects" );
536
537 // sub-fragment marker
538 //
539 v.push_back(0xff1234ff);
540
541 // sub-fragment size
542 // set the size for the sub-fragment (3 [header] + 8 [# 32bit word/digit/pmt/module] x N [# digit/pmt/module])
543 uint32_t size = m_vTileDigi.size() * 7; // assume 7 samples
544 size = (size+3)>>2; // convert numner of bytes into number of 32bit words
545 v.push_back(3+size);
546 uint savepos=v.size()-1;
547
548 // type & version: the version is a 16-bit number and is set by fixing the 3th hexadecimal digit (8-12 in bits) to 5 and leaving all other free
549 //
550 uint32_t verfrag = 0x500;
551 uint32_t type_version = (0x40 << 16) + verfrag;
552 v.push_back(type_version);
553
554 v.resize(v.size()+size); // prepare place for extra words
555
556 // counters and temporary words
557 //
558 int word8bit_cnt = 0;// number of 8bit words collected 1..4
559 int wc = 0;// number of blocks of 7 32-bit words saved in ROD fragment 1..8
560 int chc = 0;// number of digits inside the tile digits collection
561 int nwc = (m_vTileDigi.size() + 3)>>2; // convert number of channels into number of 4-byte blocks
562 uint nsamp = 7;
563 uint32_t word[7];
564 memset(word, 0, sizeof(word));
565
566 for (const TileDigits* digi : m_vTileDigi) {
567
568 if (wc==nwc) {
569 ATH_MSG_WARNING( "Too many channels per fragment for TMDB frag 0x40 - ignoring all the rest" );
570 break;
571 }
572
573 // Get identifier(s) and digits for later usage
574 //
575 std::vector<float> digits = digi->samples();
576 nsamp = digits.size();
577 if (nsamp>7) {
578 ATH_MSG_WARNING( "Too many samples in digits for TMDB frag 0x40, using first 7 instead of "<<nsamp );
579 nsamp=7;
580 digits.resize(nsamp);
581 }
582
583 // Digits from TMDB come to fragment in the reverse order i.e. s1->s7 ... s7->s1
584 //
585 std::reverse(digits.begin(),digits.end());
586
587 // Define two counters: (a) to count for the 8bit sub-fragments (each word has 4 8bit sub-fragments)
588 // (b) to count for the 32bit words (each digit has 7 32bit words)
589 //
590 // | s(i)-m(j)-d6r | s(i)-m(j)-d6l | s(i)-m(j)-d5r | s(i)-m(j)-d5l |
591 //
592 int shift = word8bit_cnt * 8;
593 for ( uint i=0; i<nsamp; ++i ) {
594 word[i] += ((int) digits[i]) << shift;
595 }
596
597 if (msgLvl(MSG::DEBUG)) {
598 HWIdentifier hwid = digi->adc_HWID();
599 int ros = m_tileHWID->ros(hwid);
600 int drawer = m_tileHWID->drawer(hwid);
601 int channel = m_tileHWID->channel(hwid);
602 const char * strchannel[5] = {" d5L "," d5R "," d6L "," d6R ", " xxx "};
603 int j=std::min(channel,4);
604 if (ros<3) j=4;
605 for ( uint i=0; i<nsamp; ++i ) {
606 msg(MSG::DEBUG) << ros << "/" << drawer << "/" << channel << strchannel[j]
607 <<"\tSample "<<7-i<<" bits |" << std::setfill('0') << std::setw(2)
608 << shift << "-" << std::setw(2) << shift+7 << std::setfill('0')
609 << "| of 32-bit word "<<3 + nwc*i + wc<<" "<<digits[i]
610 <<" "<<MSG::hex<<word[i]<<MSG::dec << endmsg;
611 }
612 }
613
614 ++word8bit_cnt;
615
616 // When word8bit_cnt=4 a set of 32bit words word[0..6] are completed and are saved at a position inside the ROD fragment vector:
617 //
618 // 1st 32 bit word holds : | digit0 pmt3 mod0 | digit0 pmt2 mod0 | digit0 pmt1 mod0 | digit0 pmt0 mod0 |
619 // 2nd 32 bit word holds : | digit0 pmt3 mod1 | digit0 pmt2 mod1 | digit0 pmt1 mod1 | digit0 pmt0 mod1 |
620 // ...
621 // 8th 32 bit word holds : | digit0 pmt3 mod7 | digit0 pmt2 mod7 | digit0 pmt1 mod7 | digit0 pmt0 mod7 |
622 // ...
623 //
624 // word8bit_cnt is reset to 0 and a new set of words[0..6] is restarted.
625 //
626 if ( word8bit_cnt == 4 ) {
627 for ( uint i=0; i<nsamp; ++i ) {
628 v.at( 3 + nwc*i + wc ) = word[i];
629 }
630 ++wc;
631 word8bit_cnt=0;
632 memset(word, 0, sizeof(word));
633 }
634 ++chc;
635 }
636
637 if ( word8bit_cnt != 0 && wc<nwc ) { // some extra channels
638 ATH_MSG_WARNING( "Unexpected number of channels for TMDB frag 0x40" << wc*4 + word8bit_cnt );
639 for ( uint i=0; i<nsamp; ++i ) {
640 v.at( 3 + nwc*i + wc ) = word[i];
641 }
642 ++wc;
643 word8bit_cnt=0;
644 memset(word, 0 ,sizeof(word));
645 }
646
647 v.at(savepos)=3+size; // not actually needed - size was already set correctly
648
649 ATH_MSG_DEBUG( "Check version and counters: "<<MSG::hex<< verfrag <<MSG::dec<<" "<< chc <<" "<< wc << " save in position: " << savepos );
650
651 // dump fragment
652 //
653 if (msgLvl(MSG::VERBOSE)) {
654 msg(MSG::VERBOSE) << "Check content of ROD fragment after including sub-fragment (0x40)... " << v.size() << endmsg;
655 for (size_t i=0; i<v.size(); ++i)
656 msg(MSG::VERBOSE) << i << "\t" << v.at(i) << MSG::hex << " 0x" << v.at(i) << MSG::dec << endmsg;
657 }
658
659 return;
660}
661
662// TMDB Raw Channel
663
664void TileROD_Encoder::fillRODTileMuRcvRawChannel(std::vector<uint32_t>& v) {
665
666 ATH_MSG_DEBUG( "TMDB encoding sub-fragment 0x41: loop over " << m_vTileRC.size() << " objects" );
667
668 const float TMDB_AMPLITUDE_FACTOR = 1.0;
669
670 // sub-fragment marker
671 //
672 v.push_back(0xff1234ff);
673
674 // sub-fragment size
675 //
676 v.push_back(3);
677 uint savepos=v.size()-1;
678
679 // type & version: the version is a 16-bit number and is set by fixing the 3th hexadecimal digit (8-12 in bits) to 5 and leaving all other free
680 //
681 uint32_t verfrag = 0x500;
682 // FIXME: for the moment (July 2015) we use 32-bit packing only, so we hide 16-bit version under ifdef
683 // if we decide to use 16-bit version, additional flag for encoder should be passed from top-level algorithm
684#ifdef ALLOW16BIT
685 if (use_16bit_packing) verfrag += 2;
686 int32_t word16 = 0x0;
687#endif
688 uint32_t type_version = (0x41 << 16) + verfrag;
689 v.push_back(type_version);
690
691 // counters and temporary words
692 //
693 int wc = 0;
694 int chc = 0;
695 uint32_t word = 0x0;
696
697 for (const TileFastRawChannel* rc : m_vTileRC) {
698
699 // energies of individual pmts 2 words per module | d5r(16) | d5l(17) |
700 // | d6r(37) | d6l(38) |
701 //
702 float f_amp = rc -> amplitude();
703 int32_t i_amp = lround(f_amp*TMDB_AMPLITUDE_FACTOR) ;
704
705 // FIXME: for the moment (July 2015) we use 32-bit packing only, so we hide 16-bit version under ifdef
706#ifdef ALLOW16BIT
707 switch (verfrag){
708 case 0x502:
709 // 2's complement (binary conversion for negative numbers)
710 // x in R and bin_x the binary conversion of x ; (if x<0) then bin_x = 0xffff - abs(x) + 1 (else) bin_x = abs(x)
711 //
712 // v0 : - Feb'15: each 32-bit words holds a cell of a module 16-bit for left side PMT 16 bit for right side pmt
713 //
714 // 1st 32 bit word holds : | d5r m0 | d5l m0 |
715 // 2nd 32 bit word holds : | d6r m0 | d6l m0 |
716 // ...
717 // 7th 32 bit word holds : | d5r m3 | d5l m3 |
718 // 8th 32 bit word holds : | d6r m3 | d6l m3 |
719 // ...
720 // - While reading the FPGA it was noticed a longer word coming out larger that 16-bit
721 // - Keep this (for now) just for history but it may be that later we understand better the FPGA output
722 //
723 //limit to the range of 16-bit integer
724 if (i_amp>0x7FFF) word16 = 0x7FFF;
725 else if (i_amp<-0x8000) word16 = -0x8000;
726 else word16 = i_amp;
727
728 if (chc&1) {
729 word |= word16 << 16;
730 v.push_back(word);
731 ++wc;
732 } else {
733 word = word16 & 0xFFFF;
734 }
735 break;
736
737 //case 0x500:
738 default:
739#else
740 {
741#endif
742 // vMay'15 current version each 32-bit word is a channel
743 word = (uint32_t)i_amp;
744 v.push_back(word);
745 ++wc;
746 }
747
748 if (msgLvl(MSG::DEBUG)) {
749 int frag_id = rc->frag();
750 int drawer = (frag_id&0xFF);
751 int ros = frag_id>>8;
752 int channel = rc->channel();
753 const char * strchannel[5] = {" d5L "," d5R "," d6L "," d6R ", " xxx "};
754 int j=std::min(channel,4);
755 if (ros<3) j=4;
756 msg(MSG::DEBUG) << ros << "/" << drawer << "/" << channel << strchannel[j]
757 <<"\tAmp " << f_amp << " " << i_amp << " "
758 <<" ch cnt " << chc << " word cnt " << wc
759 << " word 0x" <<MSG::hex<< word <<MSG::dec<<endmsg;
760 }
761
762 ++chc;
763 }
764
765 // FIXME: for the moment (July 2015) we use 32-bit packing only, so we hide 16-bit version under ifdef
766#ifdef ALLOW16BIT
767 if (verfrag==0x502 && wc*2 != chc) { // odd number of channels for 16-bit frags
768 v.push_back(word); // saving last channel
769 ++wc;
770 }
771#endif
772
773 v.at(savepos)=3+wc;
774
775 ATH_MSG_DEBUG("Check version and counters: "<<MSG::hex<< verfrag <<MSG::dec<<" "<< chc <<" "<< wc <<" save in position: "<< savepos );
776
777 if (msgLvl(MSG::VERBOSE)) {
778 msg(MSG::VERBOSE) << "Check content of ROD fragment after including sub-fragment (0x41)... "<< m_vTileRC.size() <<" "<< v.size() << endmsg;
779 for (size_t i=0; i<v.size(); ++i) {
780 msg(MSG::VERBOSE) << i <<"\t"<< v.at(i) << MSG::hex << " 0x" << v.at(i) << MSG::dec << endmsg;
781 }
782 }
783 return;
784}
785
786// TMDB Decision
787
788void TileROD_Encoder::fillRODTileMuRcvObj(std::vector<uint32_t>& v) {
789
790 // this is the subfragment type 0x42
791
792 ATH_MSG_INFO( "TMDB encoding sub-fragment 0x42: loop over " << m_vTileMuRcvObj.size() << " objects" );
793
794 // sub-fragment marker
795 //
796 v.push_back(0xff1234ff);
797
798 // type & version
799 //
800 v.push_back(5);
801 uint savepos = v.size()-1;
802 uint32_t verfrag = 0x500;
803 uint32_t type_version = (0x42 << 16) + verfrag;
804 v.push_back(type_version);
805
806 // counters and temporary words
807 //
808 int wc = 0;
809 int chc= 0;
810 uint32_t result1 = 0x0;
811 uint32_t result2 = 0x0;
812 uint32_t result3 = 0x0;
813
814 switch (m_runPeriod) {
815
816 case 2:// RUN2
817
818 msg(MSG::INFO) << "Going trough RUN2 encoding procedure for TMDB data" << endmsg;
819
820 for (const TileMuonReceiverObj* tmurcv : m_vTileMuRcvObj) {
821
822 // VERSION RUN2: results are hold in 3 16-bit words. Two 32 bit words.
823 //
824 // 32nd bit -> | results2 || results1 | <- 1st bit
825 // | 0x0 || results3 |
826 //
827 // 32nd bit -> | m-5 | m-4 | m-3 | m-2 || m-2 | m-1 | m-0 | 0x0 | <- 1st bit
828 // | 0x0 || 0x0 | m-7 | m-6 | m-5 |
829 //
830 // each 4 bit word is
831 //
832 // 0 1 2 3 <-- in Obj
833 // | d56h | d56l | d6h | d6l |
834 // bit3 bit2 bit1 bit0
835 //
836
837 int modid = tmurcv->identify() & 0xff;
838
839 const std::vector<bool> & slin = tmurcv->GetDecision();
840 int imax = std::min((int)slin.size(),4);
841 uint32_t word4b = 0x0;
842 for (int i=0;i<imax;++i){
843 if (slin[i]) word4b |= 1 << (3-i);
844 }
845
846 if (msgLvl(MSG::INFO)) {
847 std::stringstream ss;
848 for (const bool val : slin) {
849 ss<<std::setw(2)<<val;
850 }
851 msg(MSG::INFO) << "Result for module: "<<modid<<" in TMDB board "<<modid%8<<MSG::hex<<": 0x"<<word4b<<MSG::dec<<" from "<<ss.str() << endmsg;
852 }
853
854 switch (modid%8) {
855 case 0: result1 |= word4b << 4 ; break;
856 case 1: result1 |= word4b << 8 ; break;
857 case 2: result1 |= word4b << 12 ; result2 |= word4b; break;
858 case 3: result2 |= word4b << 4 ; break;
859 case 4: result2 |= word4b << 8 ; break;
860 case 5: result2 |= word4b << 12 ; result3 |= word4b; break;
861 case 6: result3 |= word4b << 4 ; break;
862 case 7: result3 |= word4b << 8 ; break;
863 }
864 ++chc;
865 }
866
867 ATH_MSG_INFO( "Summary : "<<MSG::hex<<" Results 1: 0x"<<result1<<" Results 2: 0x"<<result2<<" Results 3: 0x"<<result3<< MSG::dec );
868
869 v.push_back( result1 | (result2 << 16) ); ++wc;// | 5 4 3 2 | 2 1 0 - |
870 v.push_back( result3 ); ++wc; // | - - - - | - 7 6 5 | '-' means free/not set/0x0
871 v.at(savepos)=3+wc;
872
873 break;
874
875 case 3:// RUN3
876
877 msg(MSG::INFO) << "Going trough RUN3 encoding procedure for TMDB data" << endmsg;
878
879 for (const TileMuonReceiverObj* tmurcv : m_vTileMuRcvObj) {
880 // VERSION RUN3: results are hold in two 32-bit word to cover a TMDB board holding 8 TileCal modules.
881 //
882 // 32nd bit -> | results2 [16:31] || results1 [0:15] | <- 1st bit
883 // 32nd bit -> | 0x0 [16:31] || results3 [0:15] | <- 1st bit
884 //
885 // 32nd bit -> | 0x0 [12:15] | m-5 | m-4 | m-3 | m-2 || 0x0 [12:15] | m-3 | m-2 | m-1 | m-0 | <- 1st bit
886 // | 0x0 [16:31] || 0x0 [12:15] | m-7 | m-6 | m-5 | m-4 |
887 //
888 // For each module m-X there is a 3-bit word with the result for a threshold
889 //
890 // | d5+d6 | d6 | d5 |
891 // | bit2 | bit1 | bit0 |
892 //
893
894 // counters and temporary words
895 //
896
897/*
898 *
899 * Comment on implementation...
900 * In Athena the container size is kept to 4. It is fully used for run2 but for run3 the first position is left empty.
901 * The most significative bit is placed in first position [0] of a container so the position reverse while encoding.
902 *
903 * */
904
905 int modid = tmurcv->identify() & 0xff;
906 const std::vector<bool> & slin = tmurcv->GetDecision();
907 int imax = std::min((int)slin.size(),4);
908 uint32_t word3b = 0x0;
909 for (int i=1;i<imax;++i) {
910 // slin d56 d6 d5
911 // word3b bit2 bit1 bit0
912 // bit 4 is always 0 since iteration starts at 1
913 if (slin[i]) word3b |= 1 << (3-i);
914 }
915
916 switch (modid%8) {
917 case 0: result1 |= word3b ; break;
918 case 1: result1 |= word3b << 3 ; break;
919 case 2: result1 |= word3b << 6 ; result2 |= word3b ; break;
920 case 3: result1 |= word3b << 9 ; result2 |= word3b << 3 ; break;
921 case 4: result2 |= word3b << 6 ; result3 |= word3b ; break;
922 case 5: result2 |= word3b << 9 ; result3 |= word3b << 3 ; break;
923 case 6: result3 |= word3b << 6 ; break;
924 case 7: result3 |= word3b << 9 ; break;
925 }
926 ++chc;
927 }
928
929 ATH_MSG_INFO( "Summary : "<<MSG::hex<<" Results 1: 0x"<<result1<<" Results 2: 0x"<<result2<<" Results 3: 0x"<<result3<< MSG::dec );
930
931 v.push_back( result1 | (result2 << 16) ); ++wc;
932 v.push_back( result3 ); ++wc;
933 v.at(savepos) = 3+wc;
934
935 break;
936
937 case 0://not defined
938 ATH_MSG_INFO("Tile Muon Decision Board (TMDB) fragment versions are only available for RUN2 and RUN3");
939 break;
940 }
941 if (msgLvl(MSG::INFO)){
942 msg(MSG::INFO) << "Check version and counters: "<<MSG::hex<<verfrag<<MSG::dec<<" "<<chc<<" "<<wc<<" save in position: "<<savepos<<endmsg;
943 msg(MSG::INFO) << "Check content of ROD fragment after including sub-fragment (0x42)... " << v.size() << endmsg;
944 for (size_t i=0; i<v.size(); ++i) {
945 msg(MSG::INFO) << i << "\t" << v.at(i) << MSG::hex << " 0x" << v.at(i) << MSG::dec << endmsg;
946 }
947 }
948 return;
949}
950
951// == END of TMDB Encoders
952
953// set the bit accordingly.
954// the bits are used when reading TileROD_Decoder::checkBit
955void TileROD_Encoder::setBit(uint32_t* p, int chan) {
956// chan = (0,47)
957 int a = chan / 32;
958 int r = chan % 32;
959// a = (0,1), r = ( 0, 31 )
960 *(p + a) |= (1 << r);
961 return;
962}
963
964// check if bit is set
965bool TileROD_Encoder::checkBit(const uint32_t* p, int chan) {
966// chan = (0,47)
967 int a = chan / 32;
968 int r = chan % 32;
969// a = (0,1), r = ( 0, 31 )
970 return *(p + a) & (1 << r);
971
972}
973
974void TileROD_Encoder::dumpROD(const std::vector<uint32_t>& v) {
975 msg(MSG::VERBOSE) << " Dump of Tile ROD block, size = " << v.size() << endmsg;
976
977 int count = 0, newCount = 3;
978 for (const uint32_t data : v) {
979 if (count == 0) {
980 msg(MSG::VERBOSE) << "Frag delim = 0x" << std::hex << data << std::dec << endmsg;
981 } else if (count == -1) {
982 newCount = data;
983 msg(MSG::VERBOSE) << "Word count = " << newCount << endmsg;
984 } else if (count == -2) {
985 count += newCount;
986 msg(MSG::VERBOSE) << "Frag ID = 0x" << std::hex << data << std::dec << endmsg;
987 } else {
988 msg(MSG::VERBOSE) << " WORD[" << newCount - count << "] = "
989 << data << " = 0x" << std::hex << data
990 << std::dec << endmsg;
991 }
992 --count;
993 }
994}
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
#define endmsg
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
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
int imax(int i, int j)
const double AMPLITUDE_FACTOR5_HG[4]
#define x
MsgStream & msg() const
The standard message stream.
bool msgLvl(const MSG::Level lvl) const
Test the output level.
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
Static class providing several utility functions and constants.
TYPE
initialize
Helper class for TileCal online (hardware) identifiers.
Definition TileHWID.h:49
Class to store TileMuId and Et quantities computed at the TileCal ROD DSPs.
Definition TileL2.h:33
void fillRODTileMuRcvObj(std::vector< uint32_t > &v)
unsigned int m_unitType
void setMaxChannels(int maxChannels)
set maximum number of channels in a drawer
std::vector< const TileDigits * > m_vTileDigi
const TileHWID * m_tileHWID
void fillROD5(std::vector< uint32_t > &v)
std::vector< const TileL2 * > m_vTileL2
void fillROD10(std::vector< uint32_t > &v)
convert all TileL2s in the current list to a vector of 32bit words
TileRawChannel2Bytes4 m_rc2bytes4
unsigned int m_type
TileRawChannel2Bytes m_rc2bytes3
void fillROD5D(std::vector< uint32_t > &v)
void fillROD(std::vector< uint32_t > &v)
convert all TileRawChannels in the current list to a vector of 32bit words
TileRawChannel2Bytes2 m_rc2bytes2
void setTypeAndUnit(TileFragHash::TYPE type, TileRawChannelUnit::UNIT unit)
set OF algorigtm type and amplitude units for a drawer
void fillRODTileMuRcvRawChannel(std::vector< uint32_t > &v)
void fillRODL2(std::vector< uint32_t > &v)
void setBit(uint32_t *p, int chan)
set the bitmap for a channel
TileROD_Encoder()
constructor
void fillROD12(std::vector< uint32_t > &v)
TileRawDataOrdering m_order
void setTileHWID(const TileHWID *tileHWID, bool verbose, unsigned int type=4)
set all necessary parameters for the encoder
bool checkBit(const uint32_t *p, int chan)
check the bitmap for a channel
TileRawChannel2Bytes5 m_rc2bytes5
std::vector< const TileFastRawChannel * > m_vTileRC
void fillROD1(std::vector< uint32_t > &v)
convert all TileDigits in the current list to a vector of 32bit words
void fillROD2(std::vector< uint32_t > &v)
std::vector< const TileMuonReceiverObj * > m_vTileMuRcvObj
void fillROD3(std::vector< uint32_t > &v)
TileDigits2Bytes m_Digi2bytes
void fillRODTileMuRcvDigi(std::vector< uint32_t > &v)
convert the TMDB objects into a vector of 32bit words: 8bit words/digit, 16bit words/RC,...
void fillROD4(std::vector< uint32_t > &v)
unsigned int m_rChUnit
void dumpROD(const std::vector< uint32_t > &v)
dump contents of the ROD fragment
std::string head(std::string s, const std::string &pattern)
head of a string
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
bool verbose
Definition hcg.cxx:73
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
void reverse(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of reverse for DataVector/List.
Extra patterns decribing particle interation process.