Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-03 08:20:36

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   //  coutfl << "hit  for fee " << fee << "  size " << hitlist.size()  << endl;
0037   
0038   // for ( unsigned int i = 0; i < hitlist.size(); i++)
0039   //   {
0040   //     coutfl << setw(3) << i << " " << hex << hitlist[i] << dec << endl;
0041   //   }
0042   // cout << endl;
0043 
0044   if ( hitlist.size() < 3)
0045     {
0046       //coutfl << "hitlist too short " << hitlist.size() << endl;
0047       return 1;
0048     }
0049     
0050   unsigned long long BCO = 0;
0051   unsigned long long l = 0;
0052   
0053   // we assemble the BCO from 1 byte from hitlist[0]
0054   l = hitlist[0];
0055   BCO |= ( ((l >> 16 ) & 0xff) << 32);
0056   // and 8 bytes from hitlist[1]
0057   l = hitlist[1];
0058   BCO |= ( (l & 0xffff) << 16);
0059   BCO |= ( (l >> 16) & 0xffff);
0060 
0061   unsigned int event_counter =hitlist[2];
0062   //  coutfl << "pushing back  0x" << hex << BCO << dec << " fee = " << fee << " hitlist size  = " << hitlist.size() << endl;
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;  // 7bits
0077       hit->chip_id    = (x >> 23) & 0x3f;  // 6
0078       hit->adc        = (x >> 29) & 0x7;   // 3
0079       
0080       hit->FPHX_BCO   = x  & 0x7f;
0081       hit->full_FPHX  = (x >> 7) & 0x1;   // 1
0082       hit->full_ROC   = (x >> 8) & 0x1;   // 1
0083       hit->amplitude  = (x >> 9) & 0x3f;   // 1
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       // find the "ba" index
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       //coutfl << "found start at index " << index << " values " << hex << buffer[index] << dec << " fee: " << fee << " len: " << len << endl;
0124       index++;
0125 
0126       for ( int i = 0; i < len ; i++)
0127     {
0128       //coutfl << "adding to ladder " << fee << "  " << hex << buffer[index] << dec << endl;
0129       fee_data[fee].push_back(buffer[index++]);
0130     }
0131     }
0132 
0133   // for ( int fee = 0; fee < MAX_FEECOUNT; fee++)
0134   //   {
0135   //     for ( unsigned int i = 0; i < fee_data[fee].size(); i++)
0136   //    {
0137   //      coutfl << setw(3) << fee << "  " << hex << fee_data[fee][i] << dec << endl;
0138   //    }
0139   //     cout << endl;
0140   //   }
0141   
0142 
0143 
0144   for ( int fee = 0 ; fee < MAX_FEECOUNT ; fee++)
0145     {
0146 
0147       unsigned int j;
0148 
0149       // for ( j = 0;  j <  fee_data[fee].size(); j++)
0150       //    {
0151       //      coutfl << "fee " << fee << "  " << j << " found code 0x" << hex << fee_data[fee][j] << dec << endl;
0152       //    }
0153 
0154 
0155       //      int go_on = 0;
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       //skip until we have found the first header
0165       if (! header_found &&  (fee_data[fee][j] & 0xff00ffff )!= 0xad00cade )
0166         {
0167           j++;
0168           continue;
0169         }
0170       header_found = 1;
0171 
0172       // here j points to a "cade" word
0173 
0174       // push back the cdae word, the BCO, and event counter
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           //coutfl << " Warning - index is " << j << " and size is " << fee_data[fee].size() << endl;
0182           j+= fee_data[fee].size() -j;
0183         }
0184 
0185       // ok, now let's go until we hit the end, or hit the next header, or a footer
0186       while ( j < fee_data[fee].size() )
0187         {
0188           
0189           // we break here if find the next header or a footer
0190           if ( ( fee_data[fee][j] & 0xff00ffff ) == 0xad00cade )
0191         {
0192           header_found  = 0;
0193           j--;
0194           // we have a full hitlist in the vector here
0195           //coutfl << "calling decode with size " << hitlist.size() << endl;
0196           intt_decode_hitlist (hitlist, fee);
0197           hitlist.clear();
0198           break;
0199         }
0200           
0201           
0202           if ( fee_data[fee][j] == 0xcafeff80 )
0203         {
0204           // we have a full hitlist in the vector here
0205           //          coutfl << "calling decode with size " << hitlist.size() << endl;
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       //      coutfl << "calling decode with size " << hitlist.size() << endl;
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   //coutfl << "do we get called? " << endl;
0292   
0293   // so here we have the index i of the BCO, and the position j of that FEE
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   //  unsigned int i= hit; //  we compare with size() later that is unsigned
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   //the new API "get the number of fees associated with the BCO i
0353   // we do not have an i or lValue that would take an long long argument
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       //eturn FEE_List.size();
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; //  size() is unsigned
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   //  os << "number_of_hits: " << iValue(0, "NR_HITS") << endl;
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   //n = (n >> 16) & 0x0000ffff | (n << 16) & 0xffff0000;
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       //      cout << "in crc " << hex << x << dec << endl;
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