File indexing completed on 2025-08-03 08:20:52
0001 #include "packet_iddigitizerv3.h"
0002
0003 #include <string.h>
0004
0005 using namespace std;
0006
0007
0008 #define coutfl std::cout << __FILE__<< " " << __LINE__ << " "
0009 #define cerrfl std::cerr << __FILE__<< " " << __LINE__ << " "
0010
0011
0012 Packet_iddigitizerv3::Packet_iddigitizerv3(PACKET_ptr data)
0013 :Packet_w4 (data)
0014 {
0015
0016 _broken = 0;
0017
0018 if ( getHitFormat() > 160 && getHitFormat() <= 190)
0019 {
0020 _nsamples = getHitFormat() - 160;
0021 }
0022 _nchannels = 0;
0023 _nr_modules = 0;
0024
0025 _evtnr = 0;
0026 _module_address = 0;
0027 _xmit_clock = 0;
0028 _AnyChannelisSuppressed = false;
0029
0030 for ( int i = 0; i < NR_FEMS; i++)
0031 {
0032 _fem_slot[i] = 0;
0033 _fem_evtnr[i] = 0;
0034 _fem_clock[i] = 0;
0035 _fem_checksum_MSB[i] = 0;
0036 _fem_checksum_LSB[i] = 0;
0037 _fem_calculated_checksum_MSB[i] = 0;
0038 _fem_calculated_checksum_LSB[i] = 0;
0039
0040 }
0041
0042 _is_decoded = 0;
0043
0044 }
0045
0046
0047 Packet_iddigitizerv3::~Packet_iddigitizerv3()
0048 {
0049
0050 }
0051
0052 int Packet_iddigitizerv3::decode ()
0053 {
0054
0055 if (_is_decoded ) return 0;
0056 _is_decoded = 1;
0057
0058 unsigned int *k;
0059
0060
0061
0062
0063 unsigned int *SubeventData = (unsigned int *) findPacketDataStart(packet);
0064
0065 int dlength = getDataLength();
0066
0067 k = SubeventData;
0068
0069
0070 for (int i = 0; i < 32; i++)
0071 {
0072 for (int j = 0; j < 4*64; j++)
0073 {
0074 adc[i][j] = 0;
0075 }
0076 }
0077
0078 if ( dlength < 6 )
0079 {
0080 _broken = 1;
0081 return 0;
0082 }
0083
0084
0085
0086
0087
0088
0089
0090
0091 if ( (k[0] >> 28) != 0x8) return 1;
0092 if ( (k[1] >> 28) != 0x9) return 1;
0093 if ( (k[2] >> 28) != 0x9) return 1;
0094 if ( (k[3] >> 28) != 0x9) return 1;
0095 if ( (k[4] >> 28) != 0x9) return 1;
0096
0097 _evtnr = (k[0] & 0xffff);
0098 _clock_rollover = (k[1] & 0xffff);
0099 _evtrollover = (k[2] & 0xffff);
0100 _module_address = (k[3] & 0xffff);
0101 _xmit_clock = (k[4] & 0xffff);
0102
0103 _evtnr = (_evtrollover << 16) + _evtnr;
0104 _xmit_clock = (_clock_rollover << 16) + _xmit_clock;
0105
0106 int fem_nr = 0;
0107
0108 for (int fem_index = 5; fem_index < dlength ; )
0109 {
0110
0111 if ( k[fem_index] == 0xa000ffff)
0112 {
0113
0114
0115 unsigned int i = decode_FEM ( &k[fem_index], fem_nr, dlength - fem_index);
0116 if ( i == 0)
0117 {
0118
0119 _broken = 2;
0120 break;
0121 }
0122 fem_nr++;
0123 if ( fem_nr >= NR_FEMS)
0124 {
0125 _broken = 3;
0126 return 1;
0127 }
0128 fem_index += i;
0129
0130 }
0131 else
0132 {
0133 _broken = 4;
0134 return 1;
0135 }
0136 }
0137
0138
0139 return 0;
0140 }
0141
0142
0143 unsigned int Packet_iddigitizerv3::decode_FEM ( unsigned int *k, const int fem_nr, const int len)
0144 {
0145 int NFEM = fem_nr;
0146 int CHNL = 0;
0147 int index_channel = NFEM*64;
0148 int index_sample = 0;
0149 int index_parity = 0;
0150
0151
0152
0153
0154
0155 if ( k[0] != 0xa000ffff) return 0;
0156
0157 _fem_slot[fem_nr] = k[1] & 0xffff;
0158 _fem_evtnr[fem_nr] = k[2] & 0xffff;
0159 _fem_clock[fem_nr] = k[3] & 0xffff;
0160
0161 _nr_modules++;
0162 _nchannels += 64;
0163
0164 int index;
0165 int corrected_index_channel;
0166
0167
0168
0169
0170
0171
0172
0173
0174 for ( index = 4; index < len;)
0175 {
0176 int word_classifier = k[index] >> 28;
0177
0178 if ( (k[index] >> 28) == 0xe)
0179 {
0180 corrected_index_channel = index_channel^1;
0181 isZeroSuppressed[corrected_index_channel] = true;
0182 _AnyChannelisSuppressed = true;
0183 pre_post[0][corrected_index_channel] = (k[index] & 0x3fff);
0184 pre_post[1][corrected_index_channel] = ((k[index]>>14) & 0x3fff);
0185
0186
0187 index++;
0188 index_channel++;
0189 }
0190
0191 else if ( word_classifier == 0x1)
0192 {
0193
0194
0195
0196 NFEM = (k[index] >> 6) & 0x7;
0197 CHNL = k[index] & 0x3f;
0198
0199 if (NFEM != fem_nr || NFEM >= NR_FEMS)
0200 {
0201
0202 _broken = 5;
0203 return 0;
0204 }
0205
0206 index_sample = 0;
0207 index_parity = 0;
0208 index_channel = NFEM*64+CHNL;
0209 corrected_index_channel = index_channel^1;
0210
0211
0212
0213 if ( (k[index+1] >> 28) == 0x3)
0214 {
0215 index++;
0216 for ( int c = 0; c < ( _nsamples/2 + 1) ; c++)
0217 {
0218 if ( (k[index] >> 28) == 0x3)
0219 {
0220
0221
0222 adc[index_sample++][corrected_index_channel] = k[index] & 0x3fff;
0223 adc[index_sample++][corrected_index_channel] = (k[index] >> 14) & 0x3fff;
0224 isZeroSuppressed[corrected_index_channel] = false;
0225
0226
0227 }
0228 else if ( (k[index] >> 28) == 0xe)
0229 {
0230 pre_post[0][corrected_index_channel] = (k[index] & 0x3fff);
0231 pre_post[1][corrected_index_channel] = ((k[index]>>14) & 0x3fff);
0232
0233
0234 }
0235 else
0236 {
0237
0238 coutfl << "wrong tag! " << hex << (k[index] >> 28) << dec << " at index " << index << endl;
0239 }
0240 index++;
0241 }
0242 }
0243 else
0244 {
0245 coutfl << "unknown case: word classifier " << hex << "0x" << word_classifier << " next word 0x" << (k[index+1] >> 28) << dec << endl;
0246 _broken = 2;
0247 return 0;
0248 }
0249
0250
0251 index_channel++;
0252 }
0253
0254 else if ( word_classifier == 0xb)
0255 {
0256 if ( index_parity == 0)
0257 {
0258 _fem_checksum_MSB[NFEM] = (k[index] & 0xffff);
0259 index_parity++;
0260 index++;
0261 }
0262 else
0263 {
0264 _fem_checksum_LSB[NFEM] = (k[index] & 0xffff);
0265 index++;
0266 break;
0267 }
0268 if ( index >= len) break;
0269 }
0270 else
0271 {
0272 coutfl << "unknown word classifier " << hex << "0x" << word_classifier << dec << endl;
0273 _broken = 2;
0274 return 0;
0275 }
0276 }
0277 return index;
0278 }
0279
0280
0281 int Packet_iddigitizerv3::iValue(const int sample, const int ch)
0282 {
0283 decode();
0284
0285 if (_broken) return 0;
0286
0287 if ( sample >= _nsamples || sample < 0
0288 || ch >= _nchannels || ch < 0 ) return 0;
0289
0290 return adc[sample][ch];
0291 return 0;
0292 }
0293
0294 long long Packet_iddigitizerv3::lValue(const int n, const char *what)
0295 {
0296
0297 decode();
0298
0299 if (_broken) return 0;
0300
0301 if ( strcmp(what,"CLOCK") == 0 )
0302 {
0303 return _xmit_clock;
0304 }
0305
0306 if ( strcmp(what,"EVTNR") == 0 )
0307 {
0308 return _evtnr;
0309 }
0310
0311 return 0;
0312 }
0313
0314
0315 int Packet_iddigitizerv3::iValue(const int n, const char *what)
0316 {
0317
0318 decode();
0319
0320 if (_broken) return 0;
0321
0322
0323
0324
0325
0326
0327 if ( strcmp(what,"EVTNR") == 0 )
0328 {
0329 return _evtnr;
0330 }
0331
0332 if ( strcmp(what,"SAMPLES") == 0 )
0333 {
0334 return _nsamples;
0335 }
0336
0337 if ( strcmp(what,"NRMODULES") == 0 )
0338 {
0339 return _nr_modules;
0340 }
0341
0342
0343 if ( strcmp(what,"CHANNELS") == 0 )
0344 {
0345 return _nchannels;
0346 }
0347
0348 if ( strcmp(what,"MODULEADDRESS") == 0 )
0349 {
0350 return _module_address;
0351 }
0352
0353
0354 if ( strcmp(what,"FEMSLOT") == 0 )
0355 {
0356 if ( n < 0 || n >= _nr_modules) return 0;
0357 return _fem_slot[n];
0358 }
0359
0360 if ( strcmp(what,"FEMEVTNR") == 0 )
0361 {
0362 if ( n < 0 || n >= _nr_modules) return 0;
0363 return _fem_evtnr[n];
0364 }
0365
0366 if ( strcmp(what,"FEMCLOCK") == 0 )
0367 {
0368 if ( n < 0 || n >= _nr_modules) return 0;
0369 return _fem_clock[n];
0370 }
0371
0372 if ( strcmp(what,"CHECKSUMMSB") == 0 )
0373 {
0374 if ( n < 0 || n >= _nr_modules) return 0;
0375 return _fem_checksum_MSB[n];
0376 }
0377
0378 if ( strcmp(what,"CHECKSUMLSB") == 0 )
0379 {
0380 if ( n < 0 || n >= _nr_modules) return 0;
0381 return _fem_checksum_LSB[n];
0382 }
0383
0384 if ( strcmp(what,"CALCCHECKSUMMSB") == 0 )
0385 {
0386 if ( n < 0 || n >= _nr_modules) return 0;
0387 return _fem_calculated_checksum_MSB[n];
0388 }
0389
0390 if ( strcmp(what,"CALCCHECKSUMLSB") == 0 )
0391 {
0392 if ( n < 0 || n >= _nr_modules) return 0;
0393 return _fem_calculated_checksum_LSB[n];
0394 }
0395
0396
0397
0398 if ( strcmp(what,"EVENCHECKSUMOK") == 0 )
0399 {
0400 return -1;
0401 }
0402
0403 if ( strcmp(what,"ODDCHECKSUMOK") == 0 )
0404 {
0405 return -1;
0406 }
0407
0408 if ( strcmp(what,"CHECKSUMOK") == 0 )
0409 {
0410 return -1;
0411 }
0412
0413 if ( strcmp(what,"PRE") == 0 )
0414 {
0415 if ( n < 0 || n >= _nchannels ) return 0;
0416 return pre_post[0][n];
0417 }
0418
0419 if ( strcmp(what,"POST") == 0 )
0420 {
0421 if ( n < 0 || n >= _nchannels ) return 0;
0422 return pre_post[1][n];
0423 }
0424
0425 if ( strcmp(what,"SUPPRESSED") == 0 )
0426 {
0427 if ( n < 0 || n >= _nchannels ) return 0;
0428 if ( isZeroSuppressed[n] ) return 1;
0429 return 0;
0430 }
0431
0432
0433 return 0;
0434
0435 }
0436
0437 void Packet_iddigitizerv3::dump ( OSTREAM& os )
0438 {
0439 identify(os);
0440
0441 decode();
0442
0443 if ( _broken)
0444 {
0445 os << " *** Corrupt packet " << std::endl;
0446 return;
0447 }
0448
0449 os << "Evt Nr: " << lValue(0,"EVTNR") << std::endl;
0450 os << "Clock: 0x" << std::hex << lValue(0,"CLOCK") << std::dec << std::endl;
0451 os << "Nr Modules: " << iValue(0,"NRMODULES") << std::endl;
0452 os << "Channels: " << iValue(0,"CHANNELS") << std::endl;
0453 os << "Samples: " << iValue(0,"SAMPLES") << std::endl;
0454
0455 os << "Mod. Addr: " << hex << "0x" << iValue(0,"MODULEADDRESS") << dec << std::endl;
0456
0457 os << "FEM Slot: ";
0458 for ( int i = 0; i < iValue(0,"NRMODULES"); i++) os << setw(8) << iValue(i,"FEMSLOT");
0459 os << std::endl;
0460
0461 os << "FEM Evt nr: ";
0462 for ( int i = 0; i < iValue(0,"NRMODULES"); i++) os << setw(8) << iValue(i,"FEMEVTNR");
0463 os << std::endl;
0464
0465 os << "FEM Clock: ";
0466 for ( int i = 0; i < iValue(0,"NRMODULES"); i++) os << "0x" << std::hex << setw(4) << iValue(i,"FEMCLOCK") << " " << std::dec;
0467 os << std::endl;
0468
0469 char oldFill=os.fill('0');
0470
0471 os << "FEM Checksum LSB: ";
0472 for ( int i = 0; i < iValue(0,"NRMODULES"); i++)
0473 {
0474 os << "0x" << hex << setw(4) << iValue(i,"CHECKSUMLSB") << " " << dec;
0475 }
0476 os << std::endl;
0477
0478
0479
0480
0481
0482
0483
0484
0485 os << "FEM Checksum MSB: ";
0486 for ( int i = 0; i < iValue(0,"NRMODULES"); i++)
0487 {
0488 os << "0x" << hex << setw(4) << iValue(i,"CHECKSUMMSB") << " "<< dec;
0489 }
0490 os << std::endl;
0491
0492
0493
0494
0495
0496
0497
0498
0499 os.fill(oldFill);
0500 os << endl;
0501
0502 for ( int c = 0; c < _nchannels; c++)
0503 {
0504 if ( iValue(c,"SUPPRESSED") )
0505 {
0506 os << setw(4) << c << " |-";
0507 }
0508 else
0509 {
0510 os << setw(4) << c << " | ";
0511 }
0512
0513
0514 os << hex;
0515
0516 os << setw(6) << iValue(c, "PRE");
0517 os << setw(6) << iValue(c, "POST") << " | " ;
0518
0519 if ( ! iValue(c,"SUPPRESSED") )
0520 {
0521 for ( int s = 0; s < _nsamples; s++)
0522 {
0523 os << setw(6) << iValue(s,c);
0524 }
0525 }
0526 os << dec << endl;
0527 }
0528
0529 }