Back to home page

sPhenix code displayed by LXR

 
 

    


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   // last_index.fill(0);
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 //  int fee, i;
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   //coutfl << " adding packet ";
0067   //p->identify();
0068 
0069 
0070   //currentpos = packetData.size();
0071   // coutfl << "at position " << currentpos << " adding " << p->getDataLength() << " words" << endl;
0072 
0073   //  packetData.resize(packetData.size() + p->getDataLength(), 0);
0074 
0075   
0076 
0077   int nw;
0078 //  int status  = p->fillIntArray( (int *) &packetData[writeindex], p->getDataLength(), &nw,  "DATA");
0079   p->fillIntArray( (int *) &packetData[writeindex], p->getDataLength(), &nw,  "DATA");
0080 
0081   writeindex += nw;
0082   //coutfl << "status = " << status << " nw: " << nw << " writeindex = " << writeindex << endl;
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   // so here we have the index i of the BCO, and the position j of that FEE
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; // it's not a fee, it's just an index for this one
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   //--if (strcmp(what, "FULL_FPHX") == 0)
0251   //--{
0252   //--  return iValue(hit, F_FULL_FPHX);
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   // NOLINTNEXTLINE(hicpp-multiway-paths-covered)
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; //  size() is unsigned
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; //  size() is unsigned
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   // for ( int fee = 0 ; fee < MAX_FEECOUNT ; fee++)
0425   //   {
0426   //     fee_data[fee].clear();
0427   //   }
0428 
0429 
0430 
0431 
0432   std::vector<intt_hit *>::const_iterator hit_itr;
0433 
0434   //  coutfl << "deleting " << intt_hits.size() << " hits"  << std::endl;
0435 
0436   for (hit_itr = intt_hits.begin(); hit_itr != intt_hits.end(); ++hit_itr)
0437   {
0438     //      coutfl << "deleting 0x" << std::hex << (*hit_itr)->bco << std::dec << std::endl;
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   // now move the remaining stuff to the start of the array
0458   //coutfl << " current_pos: " << currentpos << " writeindex " << writeindex << endl;
0459 
0460   unsigned int l = (writeindex - currentpos) * sizeof(unsigned int);
0461   memcpy(packetData, &packetData[currentpos], l);
0462   writeindex -= currentpos;
0463   currentpos = 0;
0464 
0465   //coutfl << " current_pos: " << currentpos << " writeindex " << writeindex << endl;
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 //  coutfl << " payload_length:  " << payload_length << " writeindex " << writeindex << endl;
0483 
0484   unsigned int index = currentpos;
0485   
0486 
0487   unsigned int *buffer =   &packetData[currentpos];
0488 
0489   while ( index < payload_length -1)
0490     {
0491       // find the "ba" index
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           //_broken = 1;
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       // coutfl << "found start at index " << index << " values " << hex << buffer[index+1] << dec << " fee: " << fee << " len: " << len << " BCO: 0x" << hex << calcBCO(&buffer[index+1]) << dec <<endl;
0508       index++;
0509 
0510 
0511 
0512       for ( int i = 0; i < len ; i++)
0513     {
0514       //coutfl << "adding to ladder " << fee << "  " << hex << buffer[index] << dec << endl;
0515       fee_data[fee].push_back(buffer[index++]);
0516     }
0517 
0518       if ( payload_length - index < 100  && buffer[index-1] == 0xcafeff80 )
0519     {
0520       //coutfl << " found end at index " << index-1 << " 0x" << hex << buffer[index-1] << dec << endl;
0521       break;
0522     }
0523 
0524     }
0525 
0526 
0527 
0528 
0529   //  coutfl << "fee_data: ";
0530 
0531 
0532   // for ( int fee = 0 ; fee < MAX_FEECOUNT ; fee++)
0533   //   {
0534   //     cout << fee_data[fee].size() << " ";
0535   //   }
0536   // cout << endl;
0537 
0538   //coutfl << "payload_length; " << payload_length << " index: " << index << endl;
0539 
0540   currentpos = index;
0541 
0542 
0543   // for ( int j = 0;  j <  fee_data[0].size(); j++)
0544   //   {
0545   //     coutfl << "feedata[0]  0x" << hex << fee_data[0][j] << dec << endl;
0546   //   }
0547 
0548 
0549   // for ( int fee = 0 ; fee < MAX_FEECOUNT ; fee++)
0550   //   {
0551   //     for ( int j = fee_data[fee].size() -10 ;  j <  fee_data[fee].size(); j++) 
0552   //    {
0553   //      coutfl << "feedata[" << fee << "][" << j << "]  0x" << hex << fee_data[fee][j] << dec << endl;
0554   //    }
0555   //     cout << endl;
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           //coutfl << " found feedata[" << fee << "] end at index " << end_here <<  "  0x" << hex << fee_data[fee][end_here] << dec << endl;
0570           break;
0571         }
0572     }
0573 
0574       // for ( j = 0;  j <  fee_data[fee].size(); j++)
0575       //    {
0576       //      coutfl << "fee " << fee << "  " << j << " found code 0x" << hex << fee_data[fee][j] << dec << endl;
0577       //    }
0578 
0579 
0580       //      int go_on = 0;
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       //skip until we have found the first header
0591       if (! header_found &&  (fee_data[fee][j] & 0xff00ffff )!= 0xad00cade )
0592         {
0593           j++;
0594           continue;
0595         }
0596       header_found = 1;
0597 
0598       // here j points to a "cade" word
0599 
0600       // push back the cdae word, the BCO, and event counter
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       // ok, now let's go until we hit the end, or hit the next header, or a footer
0613       while ( j <= end_here )
0614         {
0615           
0616           // we break here if find the next header or a footer
0617           if ( ( fee_data[fee][j] & 0xff00ffff ) == 0xad00cade )
0618         {
0619           header_found  = 0;
0620           j--;
0621           // we have a full hitlist in the vector here
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           // we have a full hitlist in the vector here
0632           //          coutfl << "calling decode for FEE " << fee << " with size " << hitlist.size() << endl;
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       //coutfl << " end of fee_data for FEE " << fee << " size: " << fee_data[fee].size() << " position : " << j << endl;
0647 
0648       fee_data[fee].erase(fee_data[fee].begin(), fee_data[fee].begin() + j);
0649 
0650       //coutfl << " Fee_data size now: " << fee_data[fee].size() << endl;
0651 
0652 
0653 
0654       
0655     }
0656    //coutfl << " data size: " << writeindex - currentpos << " current pos: " << currentpos << endl;
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    //  coutfl << " next hitlist, size " << hitlist.size() << " :" << std::endl;
0677 
0678    // for ( unsigned int i = 0; i < hitlist.size(); i++)
0679    //   {
0680    //     coutfl << i << " " << std::hex << hitlist[i] << std::dec << std::endl;
0681    //   }
0682    // std::cout << std::endl;
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   // unsigned int event_counter = hitlist[2];
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 //  int count = 0;
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;  // 7bits
0718     hit->chip_id = (x >> 23U) & 0x3fU;     // 6
0719     hit->adc = (x >> 29U) & 0x7U;          // 3
0720 
0721     hit->FPHX_BCO = x & 0x7fU;
0722     hit->full_FPHX = (x >> 7U) & 0x1U;   // 1
0723     hit->full_ROC = (x >> 8U) & 0x1U;    // 1
0724     hit->amplitude = (x >> 9U) & 0x3fU;  // 1
0725     hit->word = x;
0726 
0727     // if (verbosity > 1)
0728     //   {
0729     //  if (BCO > last_bco[fee])
0730     //    {
0731     //      coutfl << "fee " << fee << " old bco : 0x" << std::hex
0732     //         << last_bco[fee] << ", current: 0x" << BCO
0733     //         << std::dec << std::endl;
0734     //    }
0735     //  // std::cout << Name() << " pushing back hit for FEE " << fee << " with BCO 0x" << std::hex << BCO << std::dec
0736     //  //      << " chip " << hit->chip_id << " channel " << hit->channel_id << " hit length now " << intt_hits.size() << ", last bco: 0x" << std::hex << last_bco[fee] << std::dec << std::endl;
0737     //  last_bco[fee] = BCO;
0738     //   }
0739 
0740 
0741     //    coutfl << "count " << count << "  " << hit->bco << endl;  
0742     intt_hits.push_back(hit);
0743 //    count++;
0744   }
0745   // coutfl << "pushed back " << count  << " hits for FEE " << fee << " with BCO 0x" << std::hex << BCO << dec
0746   //     << " size of hitlist now " << intt_hits.size() << std::endl;
0747 
0748 
0749 
0750   auto it = BCO_List.end();
0751   it--;
0752 
0753   //  coutfl << " last BCO value: 0x" << hex << *(it) << dec << endl;
0754 
0755 
0756 
0757 
0758   return 0;
0759 }
0760 
0761 
0762 void  intt_pool::dump ( OSTREAM& os )
0763 {
0764 
0765   //  os << "number_of_hits: " << iValue(0, "NR_HITS") << endl;
0766   intt_decode();
0767   // identify(os);
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