SCC/TFndSCCRaw.cxx

00001 // @(#)fROOT/SCC:$Name:  $:$Id: TFndSCCRaw.cxx,v 1.28 2007/09/24 07:32:41 Diego_Faso Exp $
00002 // Author: Diego Faso <mailto:faso@to.infn.it>, 2006/03/03
00003 
00005 //                                                                 //
00006 //  Class for the FINUDA Slow Control Raw events decoding/encoding //
00007 //                                                                 //
00008 // This class is used in order to:                                 //
00009 //                                                                 //
00010 //  - Build the header for the complete raw event (separate array) //
00011 //  - Read the raw event for every detector                        //
00012 //  - Get DataValues (Volts-Currents-Trips) from every detector    //
00013 //  - Get message part (string) from every detector                //
00014 //  - Get miscellaneous part (string) from every detector          //
00015 //                                                                 //
00016 //  - Read the complete raw event                                  //
00017 //                                                                 //
00019 
00020 #include "TFndSCCRaw.h"
00021 #include "TROOT.h"
00022 
00023 ClassImp(TFndSCCRaw) // Manager of the Slow-Control-Manager
00024 
00025 //______________________
00026 TFndSCCRaw::TFndSCCRaw():
00027   fEvCounter(),fGlobalHdr(),fGlobalEvent(),
00028   fSingleRawData(),fDataReady(),
00029   fMsgPart(),fMiscArray(),fDatime(),
00030   fSilRecode()
00031 {
00032   
00033   /*
00034     for(Int_t i=0;i<(K_SCC_HDR_SIZE/4);i++) fGlobalHdr[i] = 0;
00035     for(Int_t slow_det=0;slow_det<K_N_SLOWS;slow_det++){
00036     for(Int_t i=0;i<K_SLOW_SOCK_LEN;i++){
00037     fSingleRawData[slow_det][i] = 0;
00038     }
00039     }
00040   */
00041 
00042   fSilRecode = new TFndSlowCntSilRecode();
00043   fEvCounter = 0;
00044 }
00045 
00046 //______________________
00047 TFndSCCRaw::~TFndSCCRaw(){
00048   
00049   delete fSilRecode;
00050 }
00051 
00052 //_________________________
00053 void TFndSCCRaw::SetSingleRawData(Int_t slow_det,UInt_t *DataArray,Int_t part){
00054   // "part" is used by SIL only (messages and data are asynchronous):
00055   //                            1: Message (or complete data)
00056   //                            2: Data
00057   //
00058   // If a SIL raw-data is received:
00059   //   - Check if header was already built
00060   //   - Write new information in header
00061   //   - Add the received part
00062   //
00063   
00065   /*
00066   if(slow_det == SIL && part ==2){ // need to re-encode SIL report string
00067     fSilRecode->SetReceivedString(DataArray);
00068     fSilRecode->ReadSilString();
00069     
00070     Printf("+++++++ SIL COMPLETE REPORT ++++++++");
00071     Printf("%s",(Char_t *) &DataArray[0]);
00072     Printf("+++++++++++++++++++++++++++++++");
00073   }
00074   */
00076   
00077   
00078   if(K_DEBUG_LEV > 0) Printf("TFndSCCRaw::SetSingleRawData called for %s (part = %d)",fSlowDetNames[slow_det].Data(),part);
00079   
00080   if(part != 1 && DataArray[0] > (UInt_t)(K_SLOW_SOCK_LEN)){
00081     Printf("TFndSCCRaw::SetSingleRawData ===> The received event is not valid (lengt = %u)",DataArray[0]);
00082     return;
00083   }
00084   
00085   
00086   if(K_DEBUG_LEV > 1) Printf("TFndSCCRaw::SetSingleRawData ===> event size = %u",DataArray[0]);
00087   
00088   
00089   if(part ==2) part = 0; // "part" is kept for backwards compatibility, but not used here
00090 
00091   UInt_t totsize = 0; // bytes
00092   UInt_t totbuf = 0; // number of U32
00093 
00094   switch(part){
00095   case 0: // all but SIL messages
00096     for(UInt_t i=0;i<DataArray[0];i++){
00097       fSingleRawData[slow_det][i] = DataArray[i];
00098       //      Printf("Checking received raw-data [%i]: %x",i,fSingleRawData[slow_det][i] = DataArray[i]);
00099     }
00100     // Check magic number
00101     if(fSingleRawData[slow_det][HdrDet_magic] != K_MAGIC_NUMBER){
00102       Printf("TFndSCCRaw::SetSingleRawData ===> Wrong magic number received (0x%x)",fSingleRawData[slow_det][HdrDet_magic]);
00103       return;
00104       if(K_DEBUG_LEV > 1) Printf("TFndSCCRaw::SetSingleRawData ===> event size = %u",fSingleRawData[slow_det][HdrDet_evlen]);
00105       for(Int_t i=0;i<K_SLOW_SOCK_LEN;i++) fSingleRawData[slow_det][i] = DataArray[i];
00106     }
00107     
00108     // Now Store Date/Time
00109     fDatime[slow_det] = TDatime(fSingleRawData[slow_det][HdrDet_systime]);
00110     StoreMessagePart(slow_det);
00111     StoreMiscPart(slow_det);
00112     fDataReady[slow_det]++;
00113     if(K_DEBUG_LEV > 0) Printf("DataReady[%d]: %d",slow_det,fDataReady[slow_det]);
00114     break;
00115   case 1: // SIL Message
00116     if(slow_det != SIL){
00117       Printf("TFndSCCRaw::SetSingleRawData (BUG) ===> case %d called, but not for \"SIL\"",part);    
00118       return;
00119     }
00120     //     if(fSingleRawData[slow_det][0] == 0){
00121     //       Info("SetSingleRawData","Leaving unchanged local raw-data ( length = 0 )");
00122     //       return;
00123     //     }
00124     
00125 
00126     //    fSilRecode->SetReceivedMessage(0); // this operation will reset any message 
00127     fSilRecode->SetReceivedMessage(DataArray);
00128     fSilRecode->UpdateMessagePart();
00129     
00130     //    Printf("===================================> ==> ===> ====> %u <====",fSingleRawData[slow_det][0]);
00131 
00132     // --- update message in local SIL-raw (the whole data is updated)
00133     totsize = (UInt_t) (*(fSilRecode->GetRawBuf()) );
00134     //    totbuf = (UInt_t) ( totsize / 4 );
00135     //     Printf(" =============================> totbuf: \"%u\"",totbuf);
00136     //     cout << "0: "; for(UInt_t is = 0; is < totbuf; is++) cout << fSingleRawData[slow_det][is] << " " ; cout << endl;
00137     
00138     memcpy(fSingleRawData[slow_det], fSilRecode->GetRawBuf() ,totsize);
00139     
00140     //     cout << "1: "; for(UInt_t is = 0; is < totbuf; is++) cout << fSingleRawData[slow_det][is] << " " ; cout << endl;
00141     
00142     
00143     //     Printf("TFndSCCRaw::SetSingleRawData ===> Message Received from \"SIL\"");
00144     //     Printf("+++++++ SIL RECEIVED MESSAGE ++++++++");
00145     //     Printf("%s",(Char_t *) &DataArray[0]);
00146     //     Printf("+++++++++++++++++++++++++++++++");
00147     
00148     // Check magic number
00149     if(fSingleRawData[slow_det][HdrDet_magic] != K_MAGIC_NUMBER){
00150       Printf("TFndSCCRaw::SetSingleRawData ===> Wrong magic number received (0x%x)",fSingleRawData[slow_det][HdrDet_magic]);
00151       return;
00152       if(K_DEBUG_LEV > 1) Printf("TFndSCCRaw::SetSingleRawData ===> event size = %u",fSingleRawData[slow_det][HdrDet_evlen]);
00153       for(Int_t i=0;i<K_SLOW_SOCK_LEN;i++) fSingleRawData[slow_det][i] = DataArray[i];
00154     }
00155     
00156     // Now Store Date/Time
00157     fDatime[slow_det] = TDatime(fSingleRawData[slow_det][HdrDet_systime]);
00158     StoreMessagePart(slow_det);
00159     StoreMiscPart(slow_det);
00160     //     fDataReady[slow_det]++;
00161     //     if(K_DEBUG_LEV > 0) Printf("DataReady[%d]: %d",slow_det,fDataReady[slow_det]);
00162     
00163     break;
00164   case 2: // SIL Data
00165     if(slow_det != SIL){
00166       Printf("TFndSCCRaw::SetSingleRawData (BUG) ===> case %d called, but not for \"SIL\"",part);    
00167       return;
00168     }
00169     Printf("TFndSCCRaw::SetSingleRawData ===> Data Received from \"SIL\"");
00170 
00171     break;
00172   default: // SIL Message
00173     Printf("TFndSCCRaw::SetSingleRawData (BUG) ===> part = %d not accepted!",part);    
00174     return;
00175   }
00176 }
00177 
00178 //_________________________
00179 void TFndSCCRaw::StoreMessagePart(Int_t slow_det){
00180 
00181   if(slow_det <0 || slow_det>HdrDet_free){
00182     Printf("TFndSCCRaw::StoreMessagePart (BUG) ===> slow_det = %d not accepted!",slow_det);
00183     return;
00184   }
00185   fMsgPart[slow_det] = "";
00186   TString TmpStr = "";
00187   //  Int_t nchars = 0;
00188   Int_t msgStart = (Int_t)((Float_t)(fSingleRawData[slow_det][HdrDet_msgoff])  / 4.);
00189   Int_t msgStop =  (Int_t)((Float_t)((fSingleRawData[slow_det][HdrDet_miscoff])-1) / 4.);
00190   if(K_DEBUG_LEV > 2) Printf("TFndSCCRaw::StoreMessagePart ===> %d - %d",msgStart,msgStop);
00191   for(Int_t i=msgStart;i<=msgStop;i++){
00192     TmpStr = (Char_t *)(&fSingleRawData[slow_det][i]);
00193     if(TmpStr.Sizeof()>4) TmpStr.Resize(4); // very important to preserve from errors due to missing end-of-line
00194     fMsgPart[slow_det]+=TmpStr;
00195     //nchars+=4;
00196     if(K_DEBUG_LEV > 2) Printf("TFndSCCRaw::StoreMessagePart ===> \"%s\" ---> \"%s\"",TmpStr.Data(),fMsgPart[slow_det].Data());
00197   } 
00198 }
00199 
00200 //_________________________
00201 void TFndSCCRaw::StoreMiscPart(Int_t slow_det){
00202 
00203   if(slow_det <0 || slow_det>HdrDet_free){
00204     Printf("TFndSCCRaw::StoreMiscPart (BUG) ===> slow_det = %d not accepted!",slow_det);
00205     return;
00206   }
00207   Int_t miscStart =  (Int_t)((Float_t)(fSingleRawData[slow_det][HdrDet_miscoff]) / 4.);
00208   Int_t N_info = (Int_t)((Float_t)(K_MISC_MAX_SIZE)/4.);
00209   for(Int_t i=0;i<N_info;i++){
00210     fMiscArray[slow_det][i] = fSingleRawData[slow_det][miscStart+i];
00211   }
00212 }
00213 
00214 //_________________________
00215 Bool_t TFndSCCRaw::IsDataReady(const Int_t &slow_det){
00216 
00217   if(slow_det <0 || slow_det>HdrDet_free){
00218     Printf("TFndSCCRaw::IsDataReady ===> slow_det = %d not accepted!",slow_det);
00219     return kFALSE;
00220   }
00221   if(!fDataReady[slow_det]){
00222     Printf("TFndSCCRaw::IsDataReady ===> Raw data still not ready for %s.",fSlowDetNames[slow_det].Data());
00223     return kFALSE;
00224   }
00225   
00226   return kTRUE;
00227 }
00228 
00229 //_________________________
00230 TString TFndSCCRaw::GetMessagePart(Int_t slow_det){
00231   // slow_det = -1  not accepted
00232   
00233   if( !IsDataReady(slow_det) && slow_det != SIL ) return 0;
00234 
00235   return fMsgPart[slow_det];
00236 }
00237 
00238 //_________________________
00239 UInt_t TFndSCCRaw::GetMiscInfo(Int_t slow_det,Int_t num){
00240   // num starts from zero
00241 
00242   if( !IsDataReady(slow_det) ) return 0;
00243 
00244   return fMiscArray[slow_det][num];
00245 }
00246 
00247 //_________________________
00248 Int_t TFndSCCRaw::GetChannelData(Int_t slow_det,Int_t ch,Bool_t &power,UInt_t &voltage,UInt_t &current,Bool_t &trip){
00249   // (one UInt_t for every channel in the data part)
00250   // The "ch" argument is the number of the selected channel (starting from 1)
00251   // return value (error code):
00252   //                            0: no error
00253   //                           -1: selected detector not supported (or data not ready)
00254   //                           -2: channel (ch) out of range
00255 
00256   if( !IsDataReady(slow_det) ) return -1;
00257 
00258   if(ch < 1 || ch > K_SLOW_N_CHANS[slow_det]){
00259     Printf("TFndSCCRaw::GetChannelData ===> channel = %d out of range (for \"%s\")!",ch,fSlowDetNames[slow_det].Data());
00260     return -2;
00261   }
00262     
00263   Int_t ch_off = (Int_t)((Float_t)(fSingleRawData[slow_det][HdrDet_dataoff]-1)/4); // end of header in units of 32 bits
00264   ch_off += ch; // add the offset to the selected channel (remember that ch starts from 1!)
00265   
00266   Printf("TFndSCCRaw::GetChannelData ===> Offset for the selected channel (units of U32): %d",ch_off);
00267   DecodeDataElement(fSingleRawData[slow_det][ch_off-1],power,voltage,current,trip);
00268   return 0;
00269 }
00270 
00271 //_________________________
00272 TString TFndSCCRaw::GetChannelName(Int_t slow_det,Int_t ch){
00273   // get channel name depending on the raw-data structure
00274 
00275   TString result = "";
00276   
00277   Bool_t second_half = kFALSE;
00278   if( ch > (UInt_t)( (K_SLOW_N_CHANS[slow_det] / 2) -1) ) second_half = kTRUE;
00279 
00280   Int_t which_quarter = 0; // 1,2,3,4
00281   UInt_t div[3] = {0};
00282   
00283   div[0] = (UInt_t)( (K_SLOW_N_CHANS[slow_det] / 4) );
00284   div[1] = (UInt_t)( (K_SLOW_N_CHANS[slow_det] / 2) );
00285   div[2] = (UInt_t)( K_SLOW_N_CHANS[slow_det] - (K_SLOW_N_CHANS[slow_det] / 4) );
00286   
00287   if( ch < div[0] ) which_quarter = 1;
00288   else if   ( ch >= div[0] && ch < div[1] ) which_quarter = 2;
00289   else if   ( ch >= div[1] && ch < div[2] ) which_quarter = 3;
00290   else which_quarter = 4;
00291 
00292   TString side = ""; 
00293   UInt_t det_ch = 0; // numbering: 1,2,3,...
00294 
00295   TString lay = ""; // needed by LMD and SIL
00296 
00297   TString sign = "";
00298   Int_t modch = 0; // needed by SIL
00299   Int_t modnum = 0; // needed by SIL
00300   
00301   switch(slow_det){
00302   case TOFI:
00303     side = (second_half) ? "P" : "E";
00304     det_ch = (UInt_t) ( ch +1 );
00305     if(second_half) det_ch -=  ( (K_SLOW_N_CHANS[slow_det] / 2 ) );
00306     result.Form("TOFI %u %s",det_ch,side.Data());
00307     break;
00308   case TOFO:
00309     side = (second_half) ? "P" : "E";
00310     det_ch = (UInt_t) ( ch +1 );
00311     if(second_half) det_ch -=  ( (K_SLOW_N_CHANS[slow_det] / 2 ) );
00312     result.Form("TOFO %u %s",det_ch,side.Data());
00313     break;
00314   case LMD:
00315     switch(which_quarter){
00316     case 1:
00317       lay = "INN";
00318       sign = "POS";
00319       break;
00320     case 2:
00321       lay = "INN";
00322       sign = "NEG";
00323       break;
00324     case 3:
00325       lay = "OUT";
00326       sign = "POS";
00327       break;
00328     case 4:
00329       lay = "OUT";
00330       sign = "NEG";
00331       break;
00332     default: 
00333       gROOT->Error("TFndSCCRaw::GetChannelName","BUG detected");
00334       gApplication->Terminate();
00335       return 0;
00336     }
00337     det_ch = (UInt_t) ( (ch + 1) -  ( (which_quarter -1) *8 ) );
00338     result.Form("LMD-%s-%s %u",lay.Data(),sign.Data(),det_ch);
00339     break;
00340   case STB:
00341     result.Form("STB Group %u",ch+1);
00342     break;
00343   case GAS:
00344     // no data part from Slow-Control
00345     break;
00346   case SIL:
00347     if(ch< 8 *6){
00348       lay = "ISIM";
00349       modnum = (ch / 6) +1;
00350     }
00351     else{
00352       lay = "OSIM";
00353       modnum = ( (ch - (7 *6) ) / 6) ;
00354     }
00355     
00356     modch = ch%6;
00357     if(modch == 0 || modch ==1) side = "PHI";
00358     else if(modch == 2 || modch ==3)  side = "ZA ";
00359     else if(modch == 4 || modch ==5)  side = "ZB ";
00360     
00361     if(ch%2 ==0) sign = "POS";
00362     else sign = "NEG";
00363 
00364     result.Form("%s %s %s %u",lay.Data(),side.Data(),sign.Data(),modnum);
00365     if(modnum < 10) result += " "; // tabbing
00366     break;
00367   case MAG:
00368     // still not supported
00369     break;
00370   default:
00371     Printf("GetChannelName","Slow control ID \"%d\" not available",slow_det);
00372     return 0;
00373   }
00374   
00375   return result;
00376 }
00377 
00378 //_________________________
00379 void TFndSCCRaw::DecodeDataElement(UInt_t entry,Bool_t &power,UInt_t &voltage,UInt_t &current,Bool_t &trip){
00380   // The "entry" binary code is splitted according to the
00381   // SlowRaw data structure:
00382   //   [MSB] ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> [LSB]
00383   //          Voltage(16 bit) + Trip(1 bit) + Current(15 bit)
00384 
00385   UInt_t p = entry & 0x80000000; // select the MSB (power)
00386   power = (Bool_t)(p>>31);
00387   UInt_t v = entry & 0x7FFF0000; // select the voltage part
00388   voltage = v>>16;
00389   UInt_t t = entry & 0x8000; // select 16th bit
00390   trip = (Bool_t)(t>>15);
00391   current = entry & 0x7FFF; // select less significative 15 bit (no need to shift)
00392 
00393 }
00394 
00395 //_________________________
00396 void TFndSCCRaw::PrintHeader(Int_t slow_det){
00397   // slow_det = -1  means "Global Header"
00398   
00399   if( !IsDataReady(slow_det) ) return;
00400 
00401   TString DetName = "";
00402   TDatime SysTime;
00403   UInt_t HdrEntries =  (UInt_t)((Float_t)(K_SCC_HDR_SIZE) / (Float_t)(4.));
00404   
00405   if(slow_det != -1){ // Single detector header
00406     if(!fSingleRawData[slow_det][0]){
00407       Printf("TFndSCCMan::PrintHeader ===> Raw data buffer for \"%s\" is empty.",fSlowDetNames[slow_det].Data());
00408       return;
00409     }
00410     for(UInt_t i=0;i<HdrEntries;i++){
00411       switch(i){
00412       case HdrDet_evlen:
00413         Printf("Event length  (Data[%u]) (%d bytes) ",i,fSingleRawData[slow_det][i]);
00414         break;
00415       case HdrDet_detname: // detector name
00416         DetName = (Char_t *)(&fSingleRawData[slow_det][i]);
00417         if(DetName.Sizeof()>4) DetName.Resize(4); // very important to preserve from errors due to missing end-of-line
00418         Printf("Detector name (Data[%u]) = %x",i,fSingleRawData[slow_det][i]);      
00419         Printf("Detector name (Data[%u]) = %s",i,DetName.Data());      
00420         break;
00421       case HdrDet_systime: // system time
00422         SysTime = TDatime(fSingleRawData[slow_det][i]);
00423         Printf("System time   (Data[%u]) = %u (%s)",i,fSingleRawData[slow_det][i],SysTime.AsString());
00424         //SysTime.Set();      
00425         //Printf("Check ==> %u (%s) ",SysTime.Convert(),SysTime.AsString());
00426         break;
00427       case HdrDet_magic: // Magic number: should be printed as Hexadecomal
00428         Printf("Magic number  (Data[%u]) = 0x%x",i,fSingleRawData[slow_det][i]);
00429         break;
00430       case HdrDet_free: // last 4 bytes are free
00431         Printf("Free space    (Data[%u]) = %u",i,fSingleRawData[slow_det][i]);
00432         break;
00433       default: Printf("Data[%u] = %u",i,fSingleRawData[slow_det][i]);
00434       }    
00435     }
00436   } // (Single detector header)
00437   // -----
00438   else{ // Global header
00439     if(!fGlobalHdr[0]){
00440       Printf("TFndSCCMan::PrintHeader ===> Global Raw data buffer for is empty.");
00441       return;
00442     }
00443     for(UInt_t i=0;i<HdrEntries;i++){
00444       switch(i){
00445       case HdrTot_EvLen:
00446         Printf("Global Event length (Data[%u]): %d bytes",i,fGlobalHdr[i]);
00447         break;
00448       case HdrTot_SysTime:
00449         SysTime = TDatime(fGlobalHdr[i]);
00450         Printf("Data[%u] = %u (%s)",i,fGlobalHdr[i],SysTime.AsString());
00451         SysTime.Set();      
00452         Printf("Check ==> %u (%s) ",SysTime.Convert(),SysTime.AsString());
00453         break;
00454       default:
00455         Printf("%s offset (Data[%u]): %d bytes",i,fGlobalHdr[i]);
00456       }
00457     }        
00458   } // (Global header)
00459   
00460   Printf("------------------------------------------");
00461 }
00462 
00463 //_________________________
00464 void TFndSCCRaw::PrintBuffer(Int_t slow_det){
00465   // slow_det = -1  not accepted
00466   
00467   if( !IsDataReady(slow_det) ) return;
00468   
00469   TString ReceivedString = "";
00470   TString CompleteString = "";
00471   UInt_t n_elements = (UInt_t)((Float_t)(fSingleRawData[slow_det][0])/4.);
00472   Printf("TFndSCCRaw::PrintBuffer ===-------------> n_elements  = %d.",n_elements);
00473   
00474   for(UInt_t i=0;i<n_elements;i++) {
00475     TThread::CancelPoint();
00476     //      cout << "fSingleRawData[slow_det][" << i << "] = " << fSingleRawData[slow_det][i] << endl;
00477     ReceivedString  = (char*)(&fSingleRawData[slow_det][i]);
00478     if(ReceivedString.Sizeof()>4) ReceivedString.Resize(4);
00479     CompleteString+=ReceivedString;
00480   }
00481   for(UInt_t i=0;i<n_elements;i++) {
00482     TThread::CancelPoint();
00483       ReceivedString  = (char*)(&fSingleRawData[slow_det][i]);
00484       if(ReceivedString.Sizeof()>4) ReceivedString.Resize(4); // limit to one byte
00485       if(K_DEBUG_LEV > 2){
00486         Printf("fSingleRawData[slow_det][%d] = %u  (\"%s\")",i,fSingleRawData[slow_det][i],ReceivedString.Data());
00487         print_binary(fSingleRawData[slow_det][i]);
00488       }
00489   }
00490   if(K_DEBUG_LEV > 2){
00491     Printf(" Complete string: \"%s\"",CompleteString.Data());
00492     Printf("   ---   ---   ---");
00493     Printf("");
00494   }
00495   
00496 }
00497 
00498 
00499 // GLOBAL EVENT MANAGEMENT
00500 //_________________________
00501 Int_t TFndSCCRaw::BuildGlobalHeader(TString &message){
00502   // return value:
00503   //              0: ok
00504   //             -1: error
00505   
00506 
00507   if(K_DEBUG_LEV > 0){
00508     Printf(" ------> Building global header");  
00509     for(Int_t slow_det = (Int_t)TOFI ; slow_det <= (Int_t)MAG ; slow_det++){ 
00510       TString d_ready = (fDataReady[slow_det]) ? "ready" : "not ready";
00511       Printf("            - Data %s for %s",d_ready.Data(),fSlowDetNames[slow_det].Data());
00512     }
00513   }
00514 
00515   TString tmp_str;
00516   // --- Following check disabled (check global header for missing detectors) 
00517   /* 
00518      Bool_t can_build = kTRUE;
00519      for(Int_t slow_det = (Int_t)TOFI ; slow_det <= (Int_t)MAG ; slow_det++){ 
00520      if( slow_det != (Int_t)MAG && !fDataReady[slow_det] )  can_build = kFALSE;    
00521      }
00522      if(!can_build){
00523      Warning("BuildGlobalHeader","some data still missing");
00524      return -1;
00525      }
00526   */
00527   // ---
00528   
00529   bzero(fGlobalHdr,sizeof(fGlobalHdr));
00530   TDatime dattim; dattim.Set();
00531 
00532   UInt_t tofi_offset = K_SCC_HDR_SIZE + 1;
00533   UInt_t tofo_offset = tofi_offset + fSingleRawData[TOFI][HdrDet_evlen];
00534   UInt_t lmd_offset  = (fDataReady[TOFO]) ?  tofo_offset + fSingleRawData[TOFO][HdrDet_evlen] : tofo_offset ;
00535   UInt_t stb_offset  = (fDataReady[LMD] ) ?  lmd_offset  + fSingleRawData[LMD][HdrDet_evlen]  : lmd_offset  ;
00536   UInt_t gas_offset  = (fDataReady[STB] ) ?  stb_offset  + fSingleRawData[STB][HdrDet_evlen]  : stb_offset  ;
00537   UInt_t sil_offset  = (fDataReady[GAS] ) ?  gas_offset  + fSingleRawData[GAS][HdrDet_evlen]  : gas_offset  ;
00538   UInt_t mag_offset  = (fDataReady[SIL] ) ?  sil_offset  + fSingleRawData[SIL][HdrDet_evlen]  : sil_offset  ;
00539   
00540 
00541   UInt_t tot_size =   (fDataReady[MAG] ) ?  mag_offset + fSingleRawData[MAG][HdrDet_evlen]  : mag_offset;
00542   if( tot_size < 2  || tot_size > K_TOT_SCC_MAX_SIZE){
00543     Error("BuildGlobalHeader","size not accepted (%u)",tot_size);
00544     tmp_str.Form("size not accepted (%u)\n",tot_size);
00545     message+=tmp_str;
00546     return -1;
00547   }
00548 
00549   tot_size -= 1; // very important: this is not an offset!!!
00550 
00551   TString sum_chk_msg ="\n ------------------------- \n";
00552   
00553   Float_t div_by_four = ((Float_t)tot_size)  / 4.;
00554   Float_t rem_by_four = div_by_four - TMath::Floor(div_by_four);  
00555   if(rem_by_four !=0 ){
00556     Error("BuildGlobalHeader","tot_size not multiple of four (%u)",tot_size);
00557     tmp_str.Form("tot_size not multiple of four (%u)\n",tot_size);
00558     message+=tmp_str;
00559     return -1; // to be enabled    
00560   }
00561 
00562 
00563   // --- DEBUG CHECK
00564   UInt_t sum_chk = K_SCC_HDR_SIZE;
00565   for(Int_t slow_det = (Int_t)TOFI ; slow_det <= (Int_t)MAG ; slow_det++){ 
00566     if(fDataReady[slow_det]) sum_chk += fSingleRawData[slow_det][HdrDet_evlen];
00567   }
00568 
00569   
00570   
00571   //  Printf("Sumcheck (Global header):");
00572   //  Printf("  - K_SCC_HDR_SIZE: %u",K_SCC_HDR_SIZE);
00573   //  Printf("  - offsets (tofi;tofo;lmd;stb;gas;sil,mag): (%u\t%u\t%u\t%u\t%u\t%u\t%u)",
00574   //              tofi_offset,tofo_offset,lmd_offset,stb_offset,gas_offset,sil_offset,mag_offset);
00575   //   Printf("  - size    (tofi;tofo;lmd;stb;gas;sil,mag): (%u\t%u\t%u\t%u\t%u\t%u\t%u)",
00576   //              fSingleRawData[TOFI][HdrDet_evlen],
00577   //              fSingleRawData[TOFO][HdrDet_evlen],
00578   //              fSingleRawData[LMD][HdrDet_evlen],
00579   //              fSingleRawData[STB][HdrDet_evlen],
00580   //              fSingleRawData[GAS][HdrDet_evlen],
00581   //              fSingleRawData[SIL][HdrDet_evlen],
00582   //              fSingleRawData[MAG][HdrDet_evlen]
00583   //              );
00584   //   Printf("  ===> tot_size: %u",tot_size);
00585   //   Printf("  ===> sum_chk: %u\n",sum_chk);
00586   //   Printf("  ===> tot_size / 4: %2f",div_by_four);
00587   //   Printf("  ===> tot_size R_4: %2f",rem_by_four);
00588   // ---
00589   
00591   sum_chk_msg += "Sumcheck (Global header):\n";
00592   tmp_str.Form("  - K_SCC_HDR_SIZE: %u\n",K_SCC_HDR_SIZE);
00593   sum_chk_msg+=tmp_str;
00594   tmp_str.Form("  - offsets (tofi;tofo;lmd;stb;gas;sil,mag): (%u\t%u\t%u\t%u\t%u\t%u\t%u)\n",
00595                tofi_offset,tofo_offset,lmd_offset,stb_offset,gas_offset,sil_offset,mag_offset);
00596   sum_chk_msg+=tmp_str;
00597   tmp_str.Form("  - size    (tofi;tofo;lmd;stb;gas;sil,mag): (%u\t%u\t%u\t%u\t%u\t%u\t%u)\n",
00598                fSingleRawData[TOFI][HdrDet_evlen],
00599                fSingleRawData[TOFO][HdrDet_evlen],
00600                fSingleRawData[LMD][HdrDet_evlen],
00601                fSingleRawData[STB][HdrDet_evlen],
00602                fSingleRawData[GAS][HdrDet_evlen],
00603                fSingleRawData[SIL][HdrDet_evlen],
00604                fSingleRawData[MAG][HdrDet_evlen]);
00605   sum_chk_msg+=tmp_str;
00606   tmp_str.Form("  ===> tot_size: %u\n",tot_size);
00607   sum_chk_msg+=tmp_str;
00608   tmp_str.Form("  ===> sum_chk: %u\n",sum_chk);
00609   sum_chk_msg+=tmp_str;
00610   tmp_str.Form("  ===> tot_size / 4: %2f\n",div_by_four);
00611   sum_chk_msg+=tmp_str;
00612   tmp_str.Form("  ===> tot_size R_4: %2f\n",rem_by_four);
00613   sum_chk_msg+=tmp_str;
00614   sum_chk_msg+="------------------------- \n\n ";
00615   if(K_DEBUG_LEV > 0)  Printf(sum_chk_msg);
00616   message+=sum_chk_msg;
00618 
00619 
00620   if(tot_size != sum_chk){
00621     Error("BuildGlobalHeader","wrong checksum: tot_size = %u; sum_chk = %u",tot_size,sum_chk);
00622     tmp_str.Form("wrong checksum: tot_size = %u; sum_chk = %u\n",tot_size,sum_chk);
00623     message+=tmp_str;
00624     return -1;
00625   }
00626  
00627 
00628   // --- check for data to be ready  
00629   if(! fDataReady[TOFI]) tofi_offset = 0;  
00630   if(! fDataReady[TOFO]) tofo_offset = 0;  
00631   if(! fDataReady[LMD]) lmd_offset = 0;  
00632   if(! fDataReady[STB]) stb_offset = 0;  
00633   if(! fDataReady[GAS]) gas_offset = 0;  
00634   if(! fDataReady[SIL]) sil_offset = 0;  
00635   if(! fDataReady[MAG]) mag_offset = 0;  
00636   //
00637 
00638   fGlobalHdr[HdrTot_EvLen] = tot_size;
00639   fGlobalHdr[HdrTot_SysTime] = (UInt_t) ( dattim.Convert() );
00640   fGlobalHdr[HdrTot_TofiOff] = tofi_offset;
00641   fGlobalHdr[HdrTot_TofoOff] = tofo_offset;
00642   fGlobalHdr[HdrTot_LmdOff] = lmd_offset;
00643   fGlobalHdr[HdrTot_StbOff] = stb_offset;
00644   fGlobalHdr[HdrTot_GasOff] = gas_offset;
00645   fGlobalHdr[HdrTot_SilOff] = sil_offset;
00646   fGlobalHdr[HdrTot_MagOff] = mag_offset; // not used
00647   fGlobalHdr[HdrTot_Magic] = 0xBABA; // filled lately
00648     
00649   message+=" ------> Global header built\n";
00650   return 0; 
00651 
00652 }
00653 
00654 //_________________________
00655 void TFndSCCRaw::PrintGlobalHeader(){
00656 
00657   if( !fGlobalHdr[HdrTot_EvLen] ){
00658     Warning("PrintGlobalHeader","NULL event size: nothing to print");
00659     return;
00660   }
00661 
00662   TString descr;
00663   for(Int_t i=HdrTot_EvLen; i<=HdrTot_Magic ; i++){
00664     switch(i){
00665     case HdrTot_EvLen  : descr = "Glob.ev length (bytes)"; break;
00666     case HdrTot_SysTime: descr = "SCC system time (unix)"; break;
00667     case HdrTot_TofiOff: descr = "TOFINO offset (bytes)"; break;
00668     case HdrTot_TofoOff: descr = "TOFONE offset (bytes)"; break;
00669     case HdrTot_LmdOff : descr = "LMD    offset (bytes)"; break;
00670     case HdrTot_StbOff : descr = "STB    offset (bytes)"; break;
00671     case HdrTot_GasOff : descr = "GAS    offset (bytes)"; break;
00672     case HdrTot_SilOff : descr = "SIL    offset (bytes)"; break;
00673     case HdrTot_MagOff : descr = "MAG    offset (bytes)"; break;
00674     case HdrTot_Magic  : descr = "Magic number [0xBABA]"; break;
00675     default:
00676       Error("PrintGlobalHeader","BUG!");
00677       gApplication->Terminate();
00678       return;
00679     }
00680     
00681     if(i == (Int_t)HdrTot_SysTime){
00682       TDatime datime;
00683       datime.Set(fGlobalHdr[i]);
00684       Printf("Glob.Hdr pos[%i] (%s): %u (%s)",i,descr.Data(), fGlobalHdr[i], datime.AsSQLString());
00685     } 
00686     else if(i == (Int_t)HdrTot_Magic) Printf("Glob.Hdr pos[%i] (%s): 0x%X",i,descr.Data(),fGlobalHdr[i]);
00687     else Printf("Glob.Hdr pos[%i] (%s): %u",i,descr.Data(),fGlobalHdr[i]);
00688     
00689   }
00690   
00691 }
00692 
00693 //_________________________
00694 Int_t TFndSCCRaw::BuildGlobalEvent(TString &message){
00695   // return value:
00696   //              0: ok
00697   //             -1: error
00698 
00699   fEvCounter++;
00700 
00701   TString tmp_str;
00702   message.Form("Building Global Event (ev %u)\n",fEvCounter);
00703 
00704   Printf(" ---> Building global event");
00705 
00706   // ---
00707   bzero(fGlobalEvent,sizeof(fGlobalEvent));
00708   Int_t h_res = BuildGlobalHeader(message);
00709   if(h_res != 0) return h_res;
00710   for(Int_t i=(Int_t)HdrTot_EvLen; i<=(Int_t)HdrTot_Magic; i++){
00711     fGlobalEvent[i] = fGlobalHdr[i];
00712     // debug line follows
00713     if(0) Printf(" *************************** i = %i; fGlobalEvent: %u ; fGlobalHdr = %u",i , fGlobalEvent[i] , fGlobalHdr[i]);
00714   }
00715   //  memcpy(&fGlobalEvent[0], fGlobalHdr, (UInt_t)(K_SCC_HDR_SIZE/4) );
00716   //
00717   if(K_DEBUG_LEV > 0) PrintGlobalHeader();
00718   // ---
00719   
00720   
00721   UInt_t tot_size    = (UInt_t) ( (Float_t)fGlobalHdr[HdrTot_EvLen] ); // bytes
00722 
00723   UInt_t tofi_offset = (UInt_t) ( (Float_t)fGlobalHdr[HdrTot_TofiOff] / 4. ) ;  // number of U32
00724   UInt_t tofo_offset = (UInt_t) ( (Float_t)fGlobalHdr[HdrTot_TofoOff] / 4. ) ;  // number of U32
00725   UInt_t lmd_offset  = (UInt_t) ( (Float_t)fGlobalHdr[HdrTot_LmdOff]  / 4. ) ;  // number of U32
00726   UInt_t stb_offset  = (UInt_t) ( (Float_t)fGlobalHdr[HdrTot_StbOff]  / 4. ) ;  // number of U32
00727   UInt_t gas_offset  = (UInt_t) ( (Float_t)fGlobalHdr[HdrTot_GasOff]  / 4. ) ;  // number of U32
00728   UInt_t sil_offset  = (UInt_t) ( (Float_t)fGlobalHdr[HdrTot_SilOff]  / 4. ) ;  // number of U32
00729   UInt_t mag_offset  = (UInt_t) ( (Float_t)fGlobalHdr[HdrTot_MagOff]  / 4. ) ;  // not used
00730 
00731   //  
00732   if(tofi_offset){
00733     if( (UInt_t) ( fGlobalHdr[HdrTot_TofiOff] + fSingleRawData[TOFI][HdrDet_evlen] )  > (tot_size+1)){
00734       Error("BuildGlobalEvent","Buffer size mismatch (%s)",fSlowDetNames[TOFI].Data());
00735       tmp_str.Form("Buffer size mismatch (%s)\n",fSlowDetNames[TOFI].Data());
00736       message+=tmp_str;
00737       return -1;
00738     }
00739     for(Int_t i=0; i<(Int_t)(fSingleRawData[TOFI][HdrDet_evlen]/4); i++)
00740       fGlobalEvent[tofi_offset+i] = fSingleRawData[TOFI][i];
00741   }
00742   else Warning("BuildGlobalEvent","%s data not available",fSlowDetNames[TOFI].Data());
00743   //
00744   if(tofo_offset){
00745     if( (UInt_t) ( fGlobalHdr[HdrTot_TofoOff] + fSingleRawData[TOFO][HdrDet_evlen] )  > (tot_size+1)){
00746       Error("BuildGlobalEvent","Buffer size mismatch (%s)",fSlowDetNames[TOFO].Data());
00747       tmp_str.Form("Buffer size mismatch (%s)\n",fSlowDetNames[TOFO].Data());
00748       message+=tmp_str;
00749       return -1;
00750     }
00751     for(Int_t i=0; i<(Int_t)(fSingleRawData[TOFO][HdrDet_evlen]/4); i++)
00752       fGlobalEvent[tofo_offset+i] = fSingleRawData[TOFO][i];
00753   }
00754   else Warning("BuildGlobalEvent","%s data not available",fSlowDetNames[TOFO].Data());
00755   //
00756   if(lmd_offset){
00757     if( (UInt_t) ( fGlobalHdr[HdrTot_LmdOff] + fSingleRawData[LMD][HdrDet_evlen] )  > (tot_size+1)){
00758       Error("BuildGlobalEvent","Buffer size mismatch (%s)",fSlowDetNames[LMD].Data());
00759       tmp_str.Form("Buffer size mismatch (%s)\n",fSlowDetNames[LMD].Data());
00760       message+=tmp_str;
00761       return -1;
00762     }
00763     for(Int_t i=0; i<(Int_t)(fSingleRawData[LMD][HdrDet_evlen]/4); i++){
00764       fGlobalEvent[lmd_offset+i] = fSingleRawData[LMD][i];
00765       //      Printf("************************** %i ; %i ===> %u  ===> %u",i,lmd_offset+i,fSingleRawData[LMD][i],fGlobalEvent[lmd_offset+i]);
00766     }
00767   }
00768   else Warning("BuildGlobalEvent","%s data not available",fSlowDetNames[LMD].Data());
00769   //
00770   if(stb_offset){
00771     if( (UInt_t) ( fGlobalHdr[HdrTot_StbOff] + fSingleRawData[STB][HdrDet_evlen] )  > (tot_size+1)){
00772       Error("BuildGlobalEvent","Buffer size mismatch (%s)",fSlowDetNames[STB].Data());
00773       tmp_str.Form("Buffer size mismatch (%s)\n",fSlowDetNames[STB].Data());
00774       message+=tmp_str;
00775       return -1;
00776     }
00777     for(Int_t i=0; i<(Int_t)(fSingleRawData[STB][HdrDet_evlen]/4); i++){
00778       fGlobalEvent[stb_offset+i] = fSingleRawData[STB][i];
00779       //      Printf("************************** %i ; %i ===> %u  ===> %u",i,stb_offset+i,fSingleRawData[STB][i],fGlobalEvent[stb_offset+i]);
00780     }
00781   }
00782   else Warning("BuildGlobalEvent","%s data not available",fSlowDetNames[STB].Data());
00783   //
00784   if(gas_offset){
00785     if( (UInt_t) ( fGlobalHdr[HdrTot_GasOff] + fSingleRawData[GAS][HdrDet_evlen] )  > (tot_size+1)){
00786       Error("BuildGlobalEvent","Buffer size mismatch (%s)",fSlowDetNames[GAS].Data());
00787       tmp_str.Form("Buffer size mismatch (%s)\n",fSlowDetNames[GAS].Data());
00788       message+=tmp_str;
00789       return -1;
00790     }
00791     for(Int_t i=0; i<(Int_t)(fSingleRawData[GAS][HdrDet_evlen]/4); i++)
00792       fGlobalEvent[gas_offset+i] = fSingleRawData[GAS][i];
00793   }
00794   else Warning("BuildGlobalEvent","%s data not available",fSlowDetNames[GAS].Data());
00795   //
00796   if(sil_offset){
00797     if( (UInt_t) ( fGlobalHdr[HdrTot_SilOff] + fSingleRawData[SIL][HdrDet_evlen] )  > (tot_size+1)){
00798       Error("BuildGlobalEvent","Buffer size mismatch (%s)",fSlowDetNames[SIL].Data());
00799       tmp_str.Form("Buffer size mismatch (%s)\n",fSlowDetNames[SIL].Data());
00800       message+=tmp_str;
00801       return -1;
00802     }
00803     for(Int_t i=0; i<(Int_t)(fSingleRawData[SIL][HdrDet_evlen]/4); i++)
00804       fGlobalEvent[sil_offset+i] = fSingleRawData[SIL][i];
00805   }
00806   else Warning("BuildGlobalEvent","%s data not available",fSlowDetNames[SIL].Data());
00807   //
00808   if(mag_offset){
00809     if( (UInt_t) ( fGlobalHdr[HdrTot_MagOff] + fSingleRawData[MAG][HdrDet_evlen] )  > (tot_size+1)){
00810       Error("BuildGlobalEvent","Buffer size mismatch (%s)",fSlowDetNames[MAG].Data());
00811       tmp_str.Form("Buffer size mismatch (%s)\n",fSlowDetNames[MAG].Data());
00812       message+=tmp_str;
00813       return -1;
00814     }
00815     for(Int_t i=0; i<(Int_t)(fSingleRawData[MAG][HdrDet_evlen]/4); i++)
00816       fGlobalEvent[mag_offset+i] = fSingleRawData[MAG][i];
00817   }
00818   else Warning("BuildGlobalEvent","%s data not available",fSlowDetNames[MAG].Data());
00819   
00820   // ---
00821   message+=" ---> Global event built\n";
00822 
00823   if(0){ // debug  lines
00824     for(Int_t i=(Int_t)HdrTot_EvLen; i<=(Int_t)HdrTot_Magic; i++){
00825       Printf(" **** i = %i; fGlobalEvent: %u ; fGlobalHdr = %u",i , fGlobalEvent[i] , fGlobalHdr[i]);
00826     }
00827   }
00828 
00829   return 0; 
00830 
00831 }

Generated on Tue Oct 16 15:40:48 2007 by  doxygen 1.5.2