File indexing completed on 2025-08-03 08:20:47
0001 #include "oncsSub_idinttv0.h"
0002
0003 #include <string.h>
0004 #include <stdint.h>
0005
0006 #define coutfl cout << __FILE__<< " " << __LINE__ << " "
0007 #define cerrfl cerr << __FILE__<< " " << __LINE__ << " "
0008
0009 using namespace std;
0010
0011 oncsSub_idinttv0::oncsSub_idinttv0(subevtdata_ptr data)
0012 :oncsSubevent_w2 (data)
0013 {
0014
0015 _is_decoded = 0;
0016
0017 }
0018
0019
0020 oncsSub_idinttv0::~oncsSub_idinttv0()
0021 {
0022 std::vector<intt_hit*>::const_iterator hit_itr;
0023
0024 for ( hit_itr = intt_hits.begin(); hit_itr != intt_hits.end(); ++hit_itr)
0025 {
0026 delete (*hit_itr);
0027 }
0028 intt_hits.clear();
0029
0030 }
0031
0032
0033 int oncsSub_idinttv0::intt_decode_hitlist (std::vector<unsigned int> &hitlist , const int fee)
0034 {
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 if ( hitlist.size() < 3)
0045 {
0046
0047 return 1;
0048 }
0049
0050 unsigned long long BCO = 0;
0051 unsigned long long l = 0;
0052
0053
0054 l = hitlist[0];
0055 BCO |= ( ((l >> 16 ) & 0xff) << 32);
0056
0057 l = hitlist[1];
0058 BCO |= ( (l & 0xffff) << 16);
0059 BCO |= ( (l >> 16) & 0xffff);
0060
0061 unsigned int event_counter =hitlist[2];
0062
0063
0064 BCO_List.insert(BCO);
0065
0066 FEE_BCO_Association[BCO].insert(fee);
0067
0068
0069 for (unsigned int i = 3; i < hitlist.size(); i++)
0070 {
0071 unsigned int x = hitlist[i];
0072 intt_hit * hit= new intt_hit;
0073 hit->event_counter = event_counter;
0074 hit->fee = fee;
0075 hit->bco = BCO;
0076 hit->channel_id = (x >> 16) & 0x7f;
0077 hit->chip_id = (x >> 23) & 0x3f;
0078 hit->adc = (x >> 29) & 0x7;
0079
0080 hit->FPHX_BCO = x & 0x7f;
0081 hit->full_FPHX = (x >> 7) & 0x1;
0082 hit->full_ROC = (x >> 8) & 0x1;
0083 hit->amplitude = (x >> 9) & 0x3f;
0084 hit->word = x;
0085
0086 intt_hits.push_back(hit);
0087 }
0088
0089 return 0;
0090 }
0091
0092 int oncsSub_idinttv0::intt_decode ()
0093 {
0094
0095 if (_is_decoded ) return 0;
0096 _is_decoded = 1;
0097
0098 unsigned int payload_length = ( getLength() - SEVTHEADERLENGTH) - getPadding() ;
0099
0100 unsigned int index = 0;
0101
0102
0103 unsigned int *buffer = ( unsigned int *) &SubeventHdr->data;
0104
0105 while ( index < payload_length)
0106 {
0107
0108 while ( (buffer[index] & 0xff00ffff ) != 0xf000caf0 )
0109 {
0110 coutfl << "skipping at " << index << " values " << hex << buffer[index] << dec << endl;
0111 index++;
0112 if (index >= payload_length)
0113 {
0114 coutfl << " reached end at " << index << " values " << hex << buffer[index] << dec << endl;
0115 _broken = 1;
0116 return -1;
0117 }
0118 }
0119
0120
0121 unsigned short fee = ( buffer[index] >> 20 ) & 0xf;
0122 unsigned short len = ( (buffer[index] >> 16) & 0xf) >>1;
0123
0124 index++;
0125
0126 for ( int i = 0; i < len ; i++)
0127 {
0128
0129 fee_data[fee].push_back(buffer[index++]);
0130 }
0131 }
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144 for ( int fee = 0 ; fee < MAX_FEECOUNT ; fee++)
0145 {
0146
0147 unsigned int j;
0148
0149
0150
0151
0152
0153
0154
0155
0156 int header_found = 0;
0157
0158 std::vector<unsigned int> hitlist;
0159 j = 0;
0160
0161 while ( j < fee_data[fee].size() )
0162 {
0163
0164
0165 if (! header_found && (fee_data[fee][j] & 0xff00ffff )!= 0xad00cade )
0166 {
0167 j++;
0168 continue;
0169 }
0170 header_found = 1;
0171
0172
0173
0174
0175 if ( fee_data[fee].size() -j >=3 )
0176 {
0177 for ( int k = 0; k < 3; k++) hitlist.push_back(fee_data[fee][j++]);
0178 }
0179 else
0180 {
0181
0182 j+= fee_data[fee].size() -j;
0183 }
0184
0185
0186 while ( j < fee_data[fee].size() )
0187 {
0188
0189
0190 if ( ( fee_data[fee][j] & 0xff00ffff ) == 0xad00cade )
0191 {
0192 header_found = 0;
0193 j--;
0194
0195
0196 intt_decode_hitlist (hitlist, fee);
0197 hitlist.clear();
0198 break;
0199 }
0200
0201
0202 if ( fee_data[fee][j] == 0xcafeff80 )
0203 {
0204
0205
0206 intt_decode_hitlist (hitlist, fee);
0207 hitlist.clear();
0208 j++;
0209 break;
0210 }
0211
0212 hitlist.push_back(fee_data[fee][j]);
0213
0214 j++;
0215 }
0216 }
0217
0218
0219 intt_decode_hitlist (hitlist, fee);
0220 hitlist.clear();
0221
0222 }
0223 return 0;
0224 }
0225
0226 enum ITEM
0227 {
0228 F_BCO = 1,
0229 F_FEE,
0230 F_CHANNEL_ID,
0231 F_CHIP_ID,
0232 F_ADC,
0233 F_FPHX_BCO,
0234 F_FULL_FPHX,
0235 F_FULL_ROC,
0236 F_AMPLITUDE,
0237 F_DATAWORD
0238 };
0239
0240
0241 int oncsSub_idinttv0::iValue(const int hit, const int field)
0242 {
0243 intt_decode();
0244 if ( hit < 0 || hit >= (int) intt_hits.size()) return 0;
0245
0246 switch (field)
0247 {
0248 case F_FEE:
0249 return intt_hits[hit]->fee;
0250 break;
0251
0252 case F_CHANNEL_ID:
0253 return intt_hits[hit]->channel_id;
0254 break;
0255
0256 case F_CHIP_ID:
0257 return intt_hits[hit]->chip_id;
0258 break;
0259
0260 case F_ADC:
0261 return intt_hits[hit]->adc;
0262 break;
0263
0264 case F_FPHX_BCO:
0265 return intt_hits[hit]->FPHX_BCO;
0266 break;
0267
0268 case F_FULL_FPHX:
0269 return intt_hits[hit]->full_FPHX;
0270 break;
0271
0272 case F_FULL_ROC:
0273 return intt_hits[hit]->full_ROC;
0274 break;
0275
0276 case F_AMPLITUDE:
0277 return intt_hits[hit]->amplitude;
0278 break;
0279
0280 case F_DATAWORD:
0281 return intt_hits[hit]->word;
0282 break;
0283
0284 }
0285
0286 return 0;
0287 }
0288
0289 int oncsSub_idinttv0::iValue(const int i, const int j, const char * what)
0290 {
0291
0292
0293
0294 if ( strcmp(what,"FEELIST") == 0)
0295 {
0296
0297 unsigned long long BCO = lValue(i,"BCOLIST");
0298 if ( BCO == 0) return -1;
0299 unsigned int uj = j;
0300 if ( j < 0 || uj >=FEE_BCO_Association[BCO].size() )
0301 {
0302 return -1;
0303 }
0304 auto it = FEE_BCO_Association[BCO].cbegin();
0305 for (unsigned int k = 0; k< uj; k++) ++it;
0306 return *it;
0307 }
0308
0309 int fee = i;
0310 int index=j;
0311
0312 if ( fee < 0 || fee >= MAX_FEECOUNT) return 0;
0313
0314 if ( index < 0 || (unsigned int) index >= fee_data[fee].size() ) return 0;
0315 intt_decode();
0316 return fee_data[fee][index];
0317
0318
0319 }
0320
0321 long long oncsSub_idinttv0::lValue(const int hit, const int field)
0322 {
0323 intt_decode();
0324 if ( hit < 0 || hit >= (int) intt_hits.size()) return 0;
0325
0326 switch (field)
0327 {
0328 case F_BCO:
0329 return intt_hits[hit]->bco;
0330 break;
0331 }
0332
0333 return 0;
0334 }
0335
0336
0337 int oncsSub_idinttv0::iValue(const int hit, const char *what)
0338 {
0339
0340 intt_decode();
0341
0342 if ( strcmp(what,"NR_HITS") == 0)
0343 {
0344 return intt_hits.size();
0345 }
0346
0347 if ( strcmp(what,"NR_BCOS") == 0)
0348 {
0349 return BCO_List.size();
0350 }
0351
0352
0353
0354 if ( strcmp(what,"NR_FEES") == 0)
0355 {
0356 unsigned long long BCO = lValue(hit,"BCOLIST");
0357 if ( BCO == 0) return 0;
0358 return FEE_BCO_Association[BCO].size();
0359
0360 }
0361
0362 if ( strcmp(what,"FEE_LENGTH") == 0)
0363 {
0364 if ( hit < 0 || hit >= MAX_FEECOUNT) return 0;
0365 return fee_data[hit].size();
0366 }
0367
0368
0369 else if ( strcmp(what,"ADC") == 0)
0370 {
0371 return iValue(hit,F_ADC);
0372 }
0373
0374 else if ( strcmp(what,"AMPLITUDE") == 0)
0375 {
0376 return iValue(hit,F_AMPLITUDE);
0377 }
0378
0379 if ( strcmp(what,"CHIP_ID") == 0)
0380 {
0381 return iValue(hit,F_CHIP_ID);
0382 }
0383
0384 if ( strcmp(what,"CHANNEL_ID") == 0)
0385 {
0386 return iValue(hit,F_CHANNEL_ID);
0387 }
0388
0389 if ( strcmp(what,"FULL_FPHX") == 0)
0390 {
0391 return iValue(hit,F_FULL_FPHX);
0392 }
0393
0394 if ( strcmp(what,"FEE") == 0)
0395 {
0396 return iValue(hit,F_FEE);
0397 }
0398
0399 if ( strcmp(what,"FPHX_BCO") == 0)
0400 {
0401 return iValue(hit,F_FPHX_BCO);
0402 }
0403
0404 if ( strcmp(what,"FULL_FPHX") == 0)
0405 {
0406 return iValue(hit,F_FULL_FPHX);
0407 }
0408
0409 if ( strcmp(what,"FULL_ROC") == 0)
0410 {
0411 return iValue(hit,F_FULL_ROC);
0412 }
0413
0414 if ( strcmp(what,"DATAWORD") == 0)
0415 {
0416 return iValue(hit,F_DATAWORD);
0417 }
0418
0419
0420
0421
0422
0423
0424 return 0;
0425 }
0426
0427 long long oncsSub_idinttv0::lValue(const int hit, const char *what)
0428 {
0429 intt_decode();
0430
0431 if ( strcmp(what,"BCO") == 0)
0432 {
0433 return lValue(hit,F_BCO);
0434 }
0435
0436 unsigned int i= hit;
0437 if ( strcmp(what,"BCOLIST") == 0)
0438 {
0439 if ( hit < 0 || i >= BCO_List.size()) return 0;
0440 auto it = BCO_List.cbegin();
0441 for (unsigned int j = 0; j< i; j++) ++it;
0442 return *it;
0443 }
0444
0445 return 0;
0446 }
0447
0448
0449 void oncsSub_idinttv0::dump ( OSTREAM& os )
0450 {
0451
0452
0453 intt_decode();
0454 identify(os);
0455
0456 os << " Number of unique BCOs: " << iValue(0, "NR_BCOS") << endl;
0457 for ( int b = 0; b < iValue(0, "NR_BCOS"); b++)
0458 {
0459 os << " BCO " << setw(3) << b << ": 0x" << hex << lValue(b, "BCOLIST") << dec << " number of FEEs for this BCO " << setw(3) << iValue(b,"NR_FEES") << endl;
0460 os << " Number of unique FEEs: ";
0461 for ( int i = 0; i < iValue(b, "NR_FEES"); i++)
0462 {
0463 os << " " << setw(3) << iValue(b, i, "FEELIST");
0464 }
0465 os << endl;
0466 }
0467
0468 os << " Number of hits: " << iValue(0, "NR_HITS") << endl;
0469
0470
0471 os << " # FEE BCO chip_BCO chip_id channel_id ADC full_phx full_ROC Ampl." << endl;
0472
0473 for ( int i = 0; i < iValue(0, "NR_HITS"); i++)
0474 {
0475 os << setw(4) << i << " "
0476 << setw(5) << iValue(i, F_FEE) << " "
0477 << hex << setw(11) << lValue(i, F_BCO) << dec << " "
0478 << hex << setw(2) << "0x" << iValue(i,F_FPHX_BCO) << dec << " "
0479 << setw(5) << iValue(i,F_CHIP_ID) << " "
0480 << setw(9) << iValue(i,F_CHANNEL_ID) << " "
0481 << setw(5) << iValue(i,F_ADC) << " "
0482 << setw(5) << iValue(i,F_FULL_FPHX) << " "
0483 << setw(9) << iValue(i,F_FULL_ROC)
0484 << setw(8) << iValue(i,F_AMPLITUDE)
0485 << " "
0486 << "0x" << setw(8) << hex << setfill('0') << iValue(i,F_DATAWORD)
0487 << setfill(' ') << dec << endl;
0488
0489 }
0490 os << endl;
0491
0492 }
0493
0494
0495 unsigned short oncsSub_idinttv0::reverseBits(const unsigned short x) const
0496 {
0497 unsigned short n = x;
0498 n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa);
0499 n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc);
0500 n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0);
0501 n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00);
0502
0503 return n;
0504 }
0505
0506
0507
0508 unsigned short oncsSub_idinttv0::crc16(const unsigned int fee, const unsigned int index, const int l) const
0509 {
0510 int len = l;
0511 int i = index;
0512 unsigned short crc = 0xffff;
0513
0514 while (len--)
0515 {
0516 unsigned short x = fee_data[fee].at(i++);
0517
0518 crc ^= reverseBits( x);
0519 for (unsigned short k = 0; k < 16; k++)
0520 {
0521 crc = crc & 1 ? (crc >> 1) ^ 0xa001 : crc >> 1;
0522 }
0523 }
0524 crc = reverseBits(crc);
0525 return crc;
0526 }
0527