File indexing completed on 2025-08-05 08:16:14
0001 #include "intt_pool.h"
0002
0003 #include <Event/packet.h>
0004
0005 #include <algorithm> // for max
0006 #include <cstring>
0007 #include <iomanip> // for operator<<, setw, setfill
0008
0009 using namespace std;
0010
0011 #define coutfl std::cout << __FILE__ << " " << __LINE__ << " "
0012 #define cerrfl std::cerr << __FILE__ << " " << __LINE__ << " "
0013
0014 enum ITEM
0015 {
0016 F_BCO = 1,
0017 F_FEE,
0018 F_CHANNEL_ID,
0019 F_CHIP_ID,
0020 F_ADC,
0021 F_FPHX_BCO,
0022 F_FULL_FPHX,
0023 F_FULL_ROC,
0024 F_AMPLITUDE,
0025 F_EVENT_COUNTER,
0026 F_DATAWORD
0027 };
0028
0029 intt_pool::intt_pool(const unsigned int depth, const unsigned int low_mark)
0030 : _required_depth(depth)
0031 , _low_mark(low_mark)
0032 {
0033
0034 for (int fee = 0; fee < MAX_FEECOUNT; fee++)
0035 {
0036 last_index[fee] = 0;
0037 }
0038 packetData = new unsigned int[depth + 2*16384];
0039 _allocated_size=depth + 2*16384;
0040
0041 }
0042
0043 intt_pool::~intt_pool()
0044 {
0045 if (_allocated_size) { delete [] packetData;
0046 }
0047 }
0048
0049 int intt_pool::addPacket(Packet *p)
0050 {
0051
0052
0053 if (_myPacketid == -1)
0054 {
0055 _myPacketid = p->getIdentifier();
0056 }
0057 else
0058 {
0059 if (_myPacketid != p->getIdentifier())
0060 {
0061 cerrfl << " received packet " << p->getIdentifier() << " for pool for id " << _myPacketid << std::endl;
0062 return -1;
0063 }
0064 }
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 int nw;
0078
0079 p->fillIntArray( (int *) &packetData[writeindex], p->getDataLength(), &nw, "DATA");
0080
0081 writeindex += nw;
0082
0083
0084
0085 return 0;
0086 }
0087
0088 unsigned int intt_pool::rawValue(const int fee, const int index)
0089 {
0090 if (fee < 0 || fee >= MAX_FEECOUNT)
0091 {
0092 return 0;
0093 }
0094 if (index < 0 || (unsigned int) index >= fee_data[fee].size())
0095 {
0096 return 0;
0097 }
0098 return fee_data[fee][index];
0099 }
0100
0101
0102 int intt_pool::iValue(const int i, const int j, const char * what)
0103 {
0104
0105
0106 if ( strcmp(what,"FEELIST") == 0)
0107 {
0108
0109 unsigned long long BCO = lValue(i,"BCOLIST");
0110 if ( BCO == 0)
0111 {
0112 return -1;
0113 }
0114 unsigned int uj = j;
0115 if ( j < 0 || uj >=FEEs_by_BCO[BCO].size() )
0116 {
0117 return -1;
0118 }
0119 auto it = FEEs_by_BCO[BCO].cbegin();
0120 for (unsigned int k = 0; k< uj; k++)
0121 {
0122 ++it;
0123 }
0124 return *it;
0125 }
0126
0127 int fee = i;
0128 int index=j;
0129
0130 if ( fee < 0 || fee >= MAX_FEECOUNT)
0131 {
0132 return 0;
0133 }
0134
0135 if ( index < 0 || (unsigned int) index >= fee_data[fee].size() )
0136 {
0137 return 0;
0138 }
0139
0140 intt_decode();
0141 return fee_data[fee][index];
0142 }
0143
0144
0145
0146
0147 int intt_pool::iValue(const int fee, const char *what)
0148 {
0149
0150 intt_decode();
0151
0152 if (strcmp(what, "FEE_LENGTH") == 0)
0153 {
0154 if (fee < 0 || fee >= MAX_FEECOUNT)
0155 {
0156 return 0;
0157 }
0158 return fee_data[fee].size();
0159 }
0160
0161 unsigned int ibco = fee;
0162 if ( strcmp(what,"NR_FEES") == 0)
0163 {
0164 unsigned long long BCO = lValue(ibco, "BCOLIST");
0165 if ( BCO == 0)
0166 {
0167 return 0;
0168 }
0169 return FEEs_by_BCO[BCO].size();
0170 }
0171
0172 if (strcmp(what, "UNIQUE_FEES") == 0)
0173 {
0174 return FEE_List.size();
0175 }
0176
0177 if (strcmp(what, "FEE_ID") == 0)
0178 {
0179 unsigned int ufee = fee;
0180 if (ufee > FEE_List.size())
0181 {
0182 return -1;
0183 }
0184 auto it = FEE_List.begin();
0185 for (unsigned int k = 0; k < ufee; k++)
0186 {
0187 ++it;
0188 }
0189 return *it;
0190 }
0191
0192 if (strcmp(what, "FEE_BCOS") == 0)
0193 {
0194 if (fee < 0 || fee >= MAX_FEECOUNT)
0195 {
0196 return 0;
0197 }
0198 return BCOs_by_FEE[fee].size();
0199 }
0200
0201
0202
0203 int hit = fee;
0204
0205 if (strcmp(what, "NR_HITS") == 0)
0206 {
0207 return intt_hits.size();
0208 }
0209
0210 if ( strcmp(what,"NR_BCOS") == 0)
0211 {
0212 return BCO_List.size();
0213 }
0214
0215 if (strcmp(what, "ADC") == 0)
0216 {
0217 return iValue(hit, F_ADC);
0218 }
0219
0220 else if (strcmp(what, "AMPLITUDE") == 0)
0221 {
0222 return iValue(hit, F_AMPLITUDE);
0223 }
0224
0225 if (strcmp(what, "CHIP_ID") == 0)
0226 {
0227 return iValue(hit, F_CHIP_ID);
0228 }
0229
0230 if (strcmp(what, "CHANNEL_ID") == 0)
0231 {
0232 return iValue(hit, F_CHANNEL_ID);
0233 }
0234
0235 if (strcmp(what, "FULL_FPHX") == 0)
0236 {
0237 return iValue(hit, F_FULL_FPHX);
0238 }
0239
0240 if (strcmp(what, "FEE") == 0)
0241 {
0242 return iValue(hit, F_FEE);
0243 }
0244
0245 if (strcmp(what, "FPHX_BCO") == 0)
0246 {
0247 return iValue(hit, F_FPHX_BCO);
0248 }
0249
0250
0251
0252
0253
0254
0255 if (strcmp(what, "FULL_ROC") == 0)
0256 {
0257 return iValue(hit, F_FULL_ROC);
0258 }
0259
0260 if (strcmp(what, "EVENT_COUNTER") == 0)
0261 {
0262 return iValue(hit, F_EVENT_COUNTER);
0263 }
0264
0265 if (strcmp(what, "DATAWORD") == 0)
0266 {
0267 return iValue(hit, F_DATAWORD);
0268 }
0269
0270 return 0;
0271 }
0272
0273 long long intt_pool::lValue(const int hit, const int field)
0274 {
0275 intt_decode();
0276 if (hit < 0 || hit >= (int) intt_hits.size())
0277 {
0278 return 0;
0279 }
0280
0281
0282 switch (field)
0283 {
0284 case F_BCO:
0285 return intt_hits[hit]->bco;
0286 break;
0287
0288 default:
0289 coutfl << "Unknown field " << field << std::endl;
0290 break;
0291 }
0292
0293 return 0;
0294 }
0295
0296 long long intt_pool::lValue(const int hit, const char *what)
0297 {
0298 intt_decode();
0299
0300 if (strcmp(what, "BCO") == 0)
0301 {
0302 return lValue(hit, F_BCO);
0303 }
0304
0305 unsigned int i= hit;
0306 if ( strcmp(what,"BCOLIST") == 0)
0307 {
0308 if ( hit < 0 || i >= BCO_List.size()) { return 0;
0309 }
0310 auto it = BCO_List.cbegin();
0311 for (unsigned int j = 0; j< i; j++) { ++it;
0312 }
0313 return *it;
0314 }
0315
0316 return 0;
0317 }
0318
0319
0320 long long intt_pool::lValue(const int fee, const int i, const char *what)
0321 {
0322 unsigned int ui= i;
0323 if ( strcmp(what,"BCOVAL") == 0)
0324 {
0325 if (BCOs_by_FEE[fee].size() == 0)
0326 {
0327 return -1;
0328 }
0329 if (ui > BCOs_by_FEE[fee].size())
0330 {
0331 return -1;
0332 }
0333 auto it = BCOs_by_FEE[fee].cbegin();
0334 for (unsigned int j = 0; j < ui; j++)
0335 {
0336 ++it;
0337 }
0338 return *it;
0339 }
0340 return 0;
0341 }
0342
0343
0344
0345 unsigned int intt_pool::min_depth() const
0346 {
0347 return writeindex - currentpos;
0348 }
0349
0350 int intt_pool::iValue(const int hit, const int field)
0351 {
0352 intt_decode();
0353 if (hit < 0 || hit >= (int) intt_hits.size())
0354 {
0355 return 0;
0356 }
0357
0358 switch (field)
0359 {
0360 case F_FEE:
0361 return intt_hits[hit]->fee;
0362 break;
0363
0364 case F_CHANNEL_ID:
0365 return intt_hits[hit]->channel_id;
0366 break;
0367
0368 case F_CHIP_ID:
0369 return intt_hits[hit]->chip_id;
0370 break;
0371
0372 case F_ADC:
0373 return intt_hits[hit]->adc;
0374 break;
0375
0376 case F_FPHX_BCO:
0377 return intt_hits[hit]->FPHX_BCO;
0378 break;
0379
0380 case F_FULL_FPHX:
0381 return intt_hits[hit]->full_FPHX;
0382 break;
0383
0384 case F_FULL_ROC:
0385 return intt_hits[hit]->full_ROC;
0386 break;
0387
0388 case F_AMPLITUDE:
0389 return intt_hits[hit]->amplitude;
0390 break;
0391
0392 case F_EVENT_COUNTER:
0393 return intt_hits[hit]->event_counter;
0394 break;
0395
0396 case F_DATAWORD:
0397 return intt_hits[hit]->word;
0398 break;
0399
0400 default:
0401 coutfl << "Unknown field " << field << std::endl;
0402 break;
0403 }
0404
0405 return 0;
0406 }
0407
0408 bool intt_pool::depth_ok() const
0409 {
0410 if (verbosity > 5)
0411 {
0412 std::cout << "current Pool depth " << writeindex - currentpos
0413 << " required depth: " << _required_depth
0414 << std::endl;
0415 }
0416 return ( min_depth() >= _required_depth);
0417 }
0418
0419 int intt_pool::next()
0420 {
0421 _is_decoded = 0;
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432 std::vector<intt_hit *>::const_iterator hit_itr;
0433
0434
0435
0436 for (hit_itr = intt_hits.begin(); hit_itr != intt_hits.end(); ++hit_itr)
0437 {
0438
0439 delete (*hit_itr);
0440 }
0441
0442 intt_hits.clear();
0443 BCO_List.clear();
0444
0445 for(auto& [x, feelist] : FEEs_by_BCO)
0446 {
0447 feelist.clear();
0448 }
0449 for(auto& [x,bcolist] : BCOs_by_FEE)
0450 {
0451 bcolist.clear();
0452 }
0453
0454 FEEs_by_BCO.clear();
0455 BCOs_by_FEE.clear();
0456
0457
0458
0459
0460 unsigned int l = (writeindex - currentpos) * sizeof(unsigned int);
0461 memcpy(packetData, &packetData[currentpos], l);
0462 writeindex -= currentpos;
0463 currentpos = 0;
0464
0465
0466
0467 return 0;
0468 }
0469
0470
0471 int intt_pool::intt_decode ()
0472 {
0473
0474 if ( _is_decoded) { return 0;
0475 }
0476 _is_decoded = 1;
0477
0478
0479
0480
0481 unsigned int payload_length = writeindex - _low_mark;
0482
0483
0484 unsigned int index = currentpos;
0485
0486
0487 unsigned int *buffer = &packetData[currentpos];
0488
0489 while ( index < payload_length -1)
0490 {
0491
0492 while ( (buffer[index] & 0xff00ffff ) != 0xf000caf0 )
0493 {
0494 coutfl << "skipping at " << index << " values " << hex << buffer[index] << dec << endl;
0495 index++;
0496 if (index >= payload_length)
0497 {
0498 coutfl << " reached end at " << index << " values " << hex << buffer[index] << dec << endl;
0499
0500 return -1;
0501 }
0502 }
0503
0504
0505 unsigned short fee = ( buffer[index] >> 20U ) & 0xfU;
0506 unsigned short len = ( (buffer[index] >> 16U) & 0xfU) >>1U;
0507
0508 index++;
0509
0510
0511
0512 for ( int i = 0; i < len ; i++)
0513 {
0514
0515 fee_data[fee].push_back(buffer[index++]);
0516 }
0517
0518 if ( payload_length - index < 100 && buffer[index-1] == 0xcafeff80 )
0519 {
0520
0521 break;
0522 }
0523
0524 }
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540 currentpos = index;
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559 for ( int fee = 0 ; fee < MAX_FEECOUNT ; fee++)
0560 {
0561
0562 int end_here = fee_data[fee].size() -1;
0563
0564 for (; end_here > 0; end_here--)
0565 {
0566
0567 if ( fee_data[fee][end_here] == 0xcafeff80 )
0568 {
0569
0570 break;
0571 }
0572 }
0573
0574
0575
0576
0577
0578
0579
0580
0581 int header_found = 0;
0582
0583 std::vector<unsigned int> hitlist;
0584 int j = 0;
0585
0586
0587 while ( j < end_here )
0588 {
0589
0590
0591 if (! header_found && (fee_data[fee][j] & 0xff00ffff )!= 0xad00cade )
0592 {
0593 j++;
0594 continue;
0595 }
0596 header_found = 1;
0597
0598
0599
0600
0601 if ( end_here -j >=3 )
0602 {
0603 for ( int k = 0; k < 3; k++) { hitlist.push_back(fee_data[fee][j++]);
0604 }
0605 }
0606 else
0607 {
0608 coutfl << " Warning - index is " << j << " and size is " << end_here << endl;
0609 j+= end_here -j +1;
0610 }
0611
0612
0613 while ( j <= end_here )
0614 {
0615
0616
0617 if ( ( fee_data[fee][j] & 0xff00ffff ) == 0xad00cade )
0618 {
0619 header_found = 0;
0620 j--;
0621
0622 coutfl << "calling decode for FEE " << fee << " with size " << hitlist.size() << endl;
0623 intt_decode_hitlist (hitlist, fee);
0624 hitlist.clear();
0625 break;
0626 }
0627
0628
0629 if ( fee_data[fee][j] == 0xcafeff80 )
0630 {
0631
0632
0633 intt_decode_hitlist (hitlist, fee);
0634 hitlist.clear();
0635 j++;
0636 break;
0637 }
0638
0639 hitlist.push_back(fee_data[fee][j]);
0640
0641 j++;
0642 }
0643 }
0644
0645 hitlist.clear();
0646
0647
0648 fee_data[fee].erase(fee_data[fee].begin(), fee_data[fee].begin() + j);
0649
0650
0651
0652
0653
0654
0655 }
0656
0657 return 0;
0658 }
0659
0660 unsigned long long intt_pool::calcBCO(unsigned int *hitlist) const
0661 {
0662 unsigned long long BCO = 0;
0663 unsigned long long l = 0;
0664
0665 l = hitlist[0];
0666 BCO |= (((l >> 16U) & 0xffU) << 32U);
0667 l = hitlist[1];
0668 BCO |= ((l & 0xffffU) << 16U);
0669 BCO |= ((l >> 16U) & 0xffffU);
0670 return BCO;
0671 }
0672
0673
0674 int intt_pool::intt_decode_hitlist(std::vector<unsigned int> &hitlist, const int fee)
0675 {
0676
0677
0678
0679
0680
0681
0682
0683
0684 if (hitlist.size() < 3)
0685 {
0686 coutfl << "hitlist too short " << std::endl;
0687 return 1;
0688 }
0689
0690 unsigned long long BCO = 0;
0691 unsigned long long l = 0;
0692
0693 l = hitlist[0];
0694 BCO |= (((l >> 16U) & 0xffU) << 32U);
0695 l = hitlist[1];
0696 BCO |= ((l & 0xffffU) << 16U);
0697 BCO |= ((l >> 16U) & 0xffffU);
0698
0699 unsigned int event_counter = 0;
0700 l = hitlist[2];
0701 event_counter |= ((l & 0xffffU) << 16U);
0702 event_counter |= ((l >> 16U) & 0xffffU);
0703
0704 FEE_List.insert(fee);
0705 BCO_List.insert(BCO);
0706 FEEs_by_BCO[BCO].insert(fee);
0707 BCOs_by_FEE[fee].insert(BCO);
0708
0709
0710 for (unsigned int i = 3; i < hitlist.size(); i++)
0711 {
0712 unsigned int x = hitlist[i];
0713 intt_hit *hit = new intt_hit;
0714 hit->event_counter = event_counter;
0715 hit->fee = fee;
0716 hit->bco = BCO;
0717 hit->channel_id = (x >> 16U) & 0x7fU;
0718 hit->chip_id = (x >> 23U) & 0x3fU;
0719 hit->adc = (x >> 29U) & 0x7U;
0720
0721 hit->FPHX_BCO = x & 0x7fU;
0722 hit->full_FPHX = (x >> 7U) & 0x1U;
0723 hit->full_ROC = (x >> 8U) & 0x1U;
0724 hit->amplitude = (x >> 9U) & 0x3fU;
0725 hit->word = x;
0726
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741
0742 intt_hits.push_back(hit);
0743
0744 }
0745
0746
0747
0748
0749
0750 auto it = BCO_List.end();
0751 it--;
0752
0753
0754
0755
0756
0757
0758 return 0;
0759 }
0760
0761
0762 void intt_pool::dump ( OSTREAM& os )
0763 {
0764
0765
0766 intt_decode();
0767
0768
0769
0770 os << " Number of unique BCOs: " << iValue(0, "NR_BCOS") << endl;
0771 for ( int b = 0; b < iValue(0, "NR_BCOS"); b++)
0772 {
0773 os << " BCO " << setw(3) << b << ": 0x" << hex << lValue(b, "BCOLIST") << dec << " number of FEEs for this BCO " << setw(3) << iValue(b,"NR_FEES") << endl;
0774 os << " Number of unique FEEs: ";
0775
0776 for ( int i = 0; i < iValue(b, "NR_FEES"); i++)
0777 {
0778 os << " " << setw(3) << iValue(b, i, "FEELIST");
0779 }
0780 os << endl;
0781 }
0782
0783 os << " Number of hits: " << iValue(0, "NR_HITS") << endl;
0784
0785
0786 os << " # FEE BCO chip_BCO chip_id channel_id ADC full_phx full_ROC Ampl." << endl;
0787
0788 for ( int i = 0; i < iValue(0, "NR_HITS"); i++)
0789 {
0790 os << setw(4) << i << " "
0791 << setw(5) << iValue(i, F_FEE) << " "
0792 << hex << setw(11) << lValue(i, F_BCO) << dec << " "
0793 << hex << setw(2) << "0x" << iValue(i,F_FPHX_BCO) << dec << " "
0794 << setw(5) << iValue(i,F_CHIP_ID) << " "
0795 << setw(9) << iValue(i,F_CHANNEL_ID) << " "
0796 << setw(5) << iValue(i,F_ADC) << " "
0797 << setw(5) << iValue(i,F_FULL_FPHX) << " "
0798 << setw(9) << iValue(i,F_FULL_ROC)
0799 << setw(8) << iValue(i,F_AMPLITUDE)
0800 << " "
0801 << "0x" << setw(8) << hex << setfill('0') << iValue(i,F_DATAWORD)
0802 << setfill(' ') << dec << endl;
0803
0804 }
0805 os << endl;
0806
0807 }
0808