Back to home page

sPhenix code displayed by LXR

 
 

    


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

0001 #include "oncsSub_iddreamv0.h"
0002 #include <string.h>
0003 #include <iostream>
0004 #include <iomanip>
0005 #include <vector>
0006 
0007 #include <arpa/inet.h>  // for htons
0008 
0009 
0010 using namespace std;
0011 
0012 oncsSub_iddreamv0::oncsSub_iddreamv0(subevtdata_ptr data)
0013   :oncsSubevent_w4 (data)
0014 {
0015 
0016   _is_decoded = 0;
0017   
0018 
0019   swapped_array = 0;
0020 }
0021 
0022 oncsSub_iddreamv0::~oncsSub_iddreamv0()
0023 {
0024 
0025   if (swapped_array) delete [] swapped_array; 
0026 
0027   std::map <int,  FEU_decoded_data *>::iterator it;
0028       
0029   for ( it=feu_map.begin() ; it != feu_map.end(); ++it)
0030     {
0031       FEU_decoded_data *fd = it->second;
0032       delete fd;
0033     }
0034 }
0035 
0036 
0037 int oncsSub_iddreamv0::iValue ( const int i,const char * what)
0038 {
0039   int nw;
0040   decode (&nw);
0041 
0042   
0043   if ( strcmp(what,"NR_FEU") == 0 )
0044     {
0045       return feu_map.size();
0046     }
0047 
0048   if ( strcmp(what,"FEU_ID") == 0 )
0049     {
0050       unsigned ii = i;
0051       if ( ii >= feu_map.size() ) return 0;
0052       
0053       std::map <int,  FEU_decoded_data *>::const_iterator it = feu_map.begin();
0054       
0055       for ( int k =0; k < i; k++) ++it;
0056     
0057       FEU_decoded_data *fd = it->second;
0058       
0059       //      cout << __FILE__ << " " << __LINE__ << " returning feu_id= " << fd->_feu_id  << endl;
0060 
0061       return fd->_feu_id;
0062     }
0063 
0064   
0065   FEU_decoded_data * fd = feu_map[i];
0066   if ( !fd ) return 0;
0067 
0068   if ( strcmp(what,"SAMPLES") == 0 )
0069     {
0070       return fd->_nr_samples+1; 
0071     }
0072 
0073   if ( strcmp(what,"NR_DREAM") == 0 )
0074     {
0075       return fd->_nr_dreams; 
0076     }
0077   
0078   if ( strcmp(what,"PEDSUBTRACTED") == 0 )
0079     {
0080       return  fd->_feu_P; 
0081     }
0082 
0083   if ( strcmp(what,"COMMONNOISE") == 0 )
0084     {
0085       return  fd->_feu_C; 
0086     }
0087   
0088   if ( strcmp(what,"ZEROSUPPRESSED") == 0 )
0089     {
0090       return  fd->_feu_Z; 
0091     }
0092 
0093 
0094   
0095   return 0;
0096 }
0097 
0098 
0099 int oncsSub_iddreamv0::iValue(const int feu_id, const int dreamchip, const char *what)
0100 {
0101   
0102   
0103   if ( dreamchip < 0 || dreamchip > 7) return 0;
0104 
0105   FEU_decoded_data * fd = feu_map[feu_id];
0106   if ( !fd ) return 0;
0107   
0108   
0109   if ( strcmp(what,"DREAM_ENABLED") == 0 )
0110     {
0111       return fd->_dream_enabled[dreamchip];
0112     }
0113   
0114 
0115   return 0;
0116 }
0117 
0118 
0119 int oncsSub_iddreamv0::iValue(const int channel, const int sample)
0120 {
0121   //  int dream = channel/64;
0122   //int ch = channel%64;
0123   //return iValue(dream,ch,sample);
0124   return 0;
0125 }
0126 
0127 
0128 int oncsSub_iddreamv0::iValue(const int feu_id, const int channel, const int sample)
0129 {
0130 
0131   int nw;
0132   decode (&nw);
0133 
0134   FEU_decoded_data * fd = feu_map[feu_id];
0135   if ( !fd ) return 0;
0136   
0137   int dreamchip = channel/64;
0138   int ch = channel%64;
0139 
0140   
0141   if (! fd->_dream_enabled[dreamchip]) return 0;
0142 
0143   if ( dreamchip < 0 || dreamchip >=8 ) return 0;
0144   if ( sample < 0 || sample > 254) return 0;
0145 
0146   return fd->samples[dreamchip][ch][sample];
0147 }
0148 
0149 
0150 void  oncsSub_iddreamv0::dump ( OSTREAM& os )
0151 {
0152   identify(os);
0153   int i;
0154   int nw;
0155   decode (&nw);
0156 
0157   os << "Nr of FEUs:         " << setw(4) << iValue(0,"NR_FEU") <<endl;
0158   for ( i = 0; i < iValue(0,"NR_FEU"); i++)
0159     {
0160       int id = iValue(i,"FEU_ID");
0161       os << "FEU_ID:              " << setw(4) << i << setw(4) << id << endl;
0162       os << " DreamChips:         " << setw(4) << iValue(id,"NR_DREAM") << "  enabled:  ";
0163       for (int dream = 0; dream < 8; dream++)
0164     {
0165       if ( iValue(id, dream,"DREAM_ENABLED") )
0166         {
0167           os << " 1 ";
0168         }
0169       else
0170         {
0171           os << " X ";
0172         }
0173     }
0174       os << endl;
0175       os << " Nr of samples:      " << setw(4) << iValue(id,"SAMPLES") <<endl;
0176       os << " Pedestal subtracted " << setw(4) << iValue(id,"PEDSUBTRACTED") <<endl;
0177       os << " Zero suppressed     " << setw(4) << iValue(id,"ZEROSUPPRESSED") <<endl;
0178       os << " Common Noise supp.  " << setw(4) << iValue(id,"COMMONNOISE") <<endl;
0179       
0180   
0181       for (int dream = 0; dream < 8; dream++)
0182     {
0183       if ( iValue(id,dream,"DREAM_ENABLED") )
0184         {
0185           os << "                                      ---- Dream chip " << dream << " ---- " << endl;
0186           os << " ch-> " ;
0187           for (int channel = 0; channel < 32; channel ++)
0188         {
0189           os << setw(5) << channel;
0190         }
0191           os << endl;
0192           os << "smple|" ;
0193           for (int channel = 32; channel < 64; channel ++)
0194         {
0195           os << setw(5) << channel;
0196         }
0197           os << endl;
0198       
0199           os << "-----+-" ;
0200           for (int channel = 0; channel < 32; channel ++)
0201         {
0202           os << "----+";
0203         }
0204           os << endl;
0205       
0206           for (int sample = 0; sample < iValue(id,"SAMPLES"); sample ++)
0207         {
0208           os << setw(4) << sample << " |";
0209           
0210           for (int channel = 0; channel < 32; channel ++)
0211             {
0212               int xx = iValue(id, dream*64 + channel, sample);
0213               os << setw(5) << xx;
0214             }
0215           os << endl;
0216           os << "    - ";
0217           for (int channel = 32; channel < 64; channel ++)
0218             {
0219               os << setw(5) << iValue(id, dream*64 +channel, sample);
0220             }
0221           os << endl;
0222         }
0223           os << endl;
0224         }
0225     }
0226       
0227     }
0228 }
0229 
0230 int *oncsSub_iddreamv0::decode ( int *nwout)
0231 {
0232   if ( _is_decoded) return 0;
0233   _is_decoded = 1;  // mark this as done already
0234   
0235 
0236 
0237   unsigned short *d = (unsigned short *) &SubeventHdr->data;  // here begins the payload
0238   int dlength =  2 * (getLength()-4 - getPadding() );
0239 
0240   swapped_array = new unsigned short[dlength];
0241 
0242   int array_position = 0;
0243   for ( int i = 0; i < dlength; i++)
0244     {
0245       if (  d[i] == 0xaabb &&  d[i+1] == 0xccdd )
0246     {
0247       int len    = ntohs(d[i+3]) /2;
0248       //      cout << __FILE__ << " " << __LINE__ << " new packet, feu_id= " << feu_id << " len = " << len << endl;
0249       i+=4;
0250       for ( int k = 0; k < len; k++)
0251         {
0252           swapped_array[array_position++] = ntohs(d[i+k]);
0253         }
0254       i+= len-1;
0255     }
0256     }
0257 
0258   int arraylength = array_position;
0259 
0260   int status = decode_payload(swapped_array, arraylength);
0261   if (status) cerr << __FILE__ << " " << __LINE__ << " error status from decode_payload " << status << endl;
0262 
0263   *nwout = 0;
0264   return 0;
0265 }
0266 
0267   
0268 int oncsSub_iddreamv0::decode_payload ( unsigned short *d, const int size) 
0269 {
0270 
0271   FEU_decoded_data *fd = 0;
0272 
0273   int nwpacket_index = 0;  // this is supposed to point to the network packet start
0274   int index = 0;
0275   int feu_index = 0;
0276   int dream_index = 0;
0277   int dream_data_length = 0;
0278 
0279 
0280   int event_id;
0281   int time_stamp;
0282 
0283   int sample_id =-1;
0284   int fine_tstp; 
0285   int old_eventid = -1;
0286 
0287   int dream_id;
0288   int feu_id;
0289   
0290   while ( nwpacket_index + 4 < size)
0291     {
0292 
0293       feu_index = nwpacket_index;
0294       
0295       // skip leading 0's
0296       while ( d[feu_index] == 0 ) feu_index++;
0297 
0298       // FEU header
0299       index = feu_index;  
0300       if ( (d[index] & 0x7000) == 0x6000)  // word 0 
0301     {
0302       feu_id = d[index] & 0xff;
0303       
0304       // do we know this FEU?
0305       if ( ! feu_map.count(feu_id) )
0306         {
0307           //          cout << __FILE__ << " " << __LINE__ << " new feu_id= " << feu_id << " added" << endl;
0308           feu_map[feu_id] = fd = new FEU_decoded_data;
0309           fd->_feu_id = feu_id;
0310           fd->_feu_P = 0;
0311           fd->_feu_C = 0;
0312           fd->_feu_Z = 0;
0313           fd->_nr_samples = 0;
0314           fd->_nr_dreams = 0;
0315           memset (fd->samples, 0,  8*64*255*sizeof(int) );
0316           memset (fd->cellids, 0,  8*64*sizeof(unsigned long long) );
0317         }
0318       else
0319         {
0320           fd = feu_map[feu_id];
0321         }
0322 
0323       fd->_feu_P  = ( d[index] >>  8) & 0x1;
0324       fd->_feu_C  = ( d[index] >>  9) & 0x1;
0325       fd->_feu_Z  = ( d[index] >> 10) & 0x1;
0326 
0327     }  // word 0
0328       
0329       index = feu_index+1;                  // word 1
0330       if ( (d[index] & 0x7000) == 0x6000)
0331     {
0332       event_id = d[index] & 0xfff;
0333       if ( old_eventid < 0)
0334         {
0335           old_eventid  = event_id;
0336         }
0337       else
0338         {
0339           if (old_eventid  != event_id)  cerr << __FILE__ << " " << __LINE__ << " feu eventid= " << event_id << " others " << old_eventid << endl;
0340         }
0341     }
0342       
0343       index = feu_index+2;                  // word 2
0344       if ( (d[index] & 0x7000) == 0x6000)
0345     {
0346       time_stamp = d[index] & 0xfff;
0347     }
0348       
0349       index = feu_index+3;                  // word 3
0350       if ( (d[index] & 0x7000) == 0x6000)
0351     {
0352       sample_id = ( d[index]>> 3) & 0x1ff;
0353       if ( sample_id > fd->_nr_samples) fd->_nr_samples = sample_id;  // and update the max sample nr as needed
0354       fine_tstp = ( d[index]) & 0x7;
0355     }
0356       //      cout << __FILE__ << " " << __LINE__ <<  " FEU id " << feu_id << " event id " << event_id << " sample id " <<  sample_id << " maxsample " << fd->_nr_samples << endl;
0357 
0358       time_stamp = ( time_stamp<<3)  | fine_tstp;
0359 
0360       index = feu_index+4 ;
0361       if (  (d[index] & 0x6000) == 0x6000 )  // do we have the optional header?
0362     {
0363       //      cout << __FILE__ << " " << __LINE__ <<  " skipping opt  header event id " << event_id << " sample id " <<  sample_id << endl;
0364       index += 4;      // skip if so
0365     }
0366       
0367       // done with FEU hdr -----
0368 
0369 
0370       // We will maintain dream_index as the index to the deam chip data start 
0371 
0372       
0373       dream_index = index;
0374       int done_with_this_feu = 0;
0375 
0376       if ( fd->_feu_Z )   // zero_suppressed data
0377     {
0378       //  cout << __FILE__ << " " << __LINE__ << "  " << hex << (d[index] & 0x7fff) << dec << endl;
0379       while( ( d[index] & 0x6000) != 0x6000 )  // test if x11x == end marker
0380         {
0381           dream_id = ( d[index] >> 6 ) & 0x7;
0382           int channel_id =    d[index]  & 0x3f;
0383           int channel_value = d[index+1] & 0xfff;
0384 
0385           // cout << __FILE__ << " " << __LINE__ << "  " << hex << (d[index] & 0x7fff) << dec
0386           //       << " dreamchip " << setw(5) << dream_id
0387           //       << " channel id " << setw(5) << channel_id
0388           //       << " channel val " << setw(5) << channel_value << endl;
0389 
0390           fd->samples[dream_id][channel_id][sample_id] = channel_value;
0391 
0392           if ( ! fd->_dream_enabled[dream_id] ) fd->_nr_dreams++;          // this is a dream id we hadn't seen before
0393           fd->_dream_enabled[dream_id] = 1;                           // mark it as "seen"
0394           index += 2;
0395         }
0396       //      cout << __FILE__ << " " << __LINE__ << "  " << hex << (d[index] & 0x7fff) << dec << endl;
0397       index += 2;
0398 
0399       nwpacket_index = dream_index = index;
0400     }
0401       
0402       else   // not Zero-suppressed data 
0403     {
0404 
0405       while( ! done_with_this_feu)
0406         {
0407           // first, we figure out where it ends. It should end 74 words in, but we better check.
0408           // we first check that dream_index + 68 has a dream header tag, and that +73 shows the same
0409           // dream id as our header here. 
0410           
0411           if ( ( d[dream_index + 68 ] & 0x6000) == 0x4000 )
0412         {
0413           dream_id = (d[dream_index+3] >> 9) & 0x7;
0414           int trailer_dream_id = (d[dream_index+73] >> 9) & 0x7;
0415           //          cout << __FILE__ << " " << __LINE__ << " dream_id= " << dream_id   <<  " trailer_dream_id= " << trailer_dream_id << endl;
0416           
0417           if (  dream_id == trailer_dream_id )   // all ok
0418             {
0419               dream_data_length = 74;
0420             }
0421           else
0422             {
0423               return -1;
0424             }
0425           
0426           if ( ! fd->_dream_enabled[dream_id] ) fd->_nr_dreams++;          // this is a dream id we hadn't seen before
0427           fd->_dream_enabled[dream_id] = 1;                           // mark it as "seen"
0428           if ( sample_id > fd->_nr_samples) fd->_nr_samples = sample_id;  // and update the max sample nr as needed
0429           
0430           decode_dream( fd, &d[dream_index], dream_data_length, sample_id);
0431           
0432           dream_index += dream_data_length;
0433           
0434         }
0435           else
0436         {
0437           // cout << __FILE__ << " " << __LINE__ << " FEU trailer reached " << endl;
0438           nwpacket_index = dream_index + 2;
0439           //  cout << __FILE__ << " " << __LINE__ << " EoE " <<  (( d[dream_index] >> 11) & 1) << " length  "  << (d[dream_index] & 0x7ff) <<dec << endl;
0440           done_with_this_feu = 1;
0441         }
0442         }
0443     }
0444     }
0445   return 0;
0446 }
0447 
0448 int oncsSub_iddreamv0::decode_dream( FEU_decoded_data *fd, unsigned short *d, const int size, const unsigned int sample_nr)
0449 {
0450   unsigned long long cell_id;
0451   unsigned long long trigger_id;
0452 
0453   unsigned int dream_id;
0454 
0455   
0456   dream_id = (d[3] >> 9) & 0x7;
0457 
0458   if ( dream_id >=8) return -1;       // can have only 0...7
0459   if ( sample_nr >= 254 ) return -2;  // sample id 0...255 max
0460 
0461   trigger_id =  (d[0] & 0xfff) << 24;
0462   trigger_id |= (d[1] & 0xfff) << 12;
0463   trigger_id |= (d[2] & 0xfff);
0464 
0465   cell_id =  (d[70] & 0xfff) << 24;
0466   cell_id |= (d[71] & 0xfff) << 12;
0467   cell_id |= (d[72] & 0xfff);
0468 
0469   
0470   fd->cellids [dream_id][sample_nr] = cell_id; 
0471 
0472   
0473   for ( int i = 0; i < 64; i++)
0474     {
0475       fd->samples[dream_id][i][sample_nr] = d[4+i] & 0xfff; 
0476     }
0477 
0478   return 0;
0479 }
0480