//*-- Author : Walter Karig
//*-- Modified : 03/05/2005 by Ilse Koenig
//*-- Modified : 16/09/2003 by T.Wojcik
//*-- Modified : 24/11/2002 by Dusan Zovinec
//*-- Modified : 18/12/2001 by Ilse Koenig
//*-- Modified : 29/11/2000 by Ilse Koenig
//*-- Modified : 13/11/2000 by M. Golubeva
//*-- Modified : 05/06/98 by Manuel Sanchez

using namespace std;
#include "htboxunpacker.h"
#include "hstartdef.h"
#include "hcategory.h"
#include "hevent.h"
#include "hldsubevt.h"
#include "hades.h"
#include "htboxchan.h"
#include "hspectrometer.h"
#include "hdetector.h"
#include "hdebug.h"
#include "heventheader.h"
#include "hdatasource.h"
#include <iostream>
#include <iomanip>
#include <stdlib.h>

ClassImp(HTBoxUnpacker)

//_HADES_CLASS_DESCRIPTION 
//////////////////////////////////////////////////////////////////
//
// HTBoxUnpacker
//
// Unpacker used to read Scalers data from .hld files
// Fills the TBox category.
//
//////////////////////////////////////////////////////////////////

 HTBoxUnpacker::HTBoxUnpacker(Int_t id) {
  // Constructor
  // Input: subevent id
  subEvtId=id;
  tboxCat=0;
}

 Bool_t HTBoxUnpacker::init(void) {
  // Creates the TBox category for the scalers, if not yet existing
  tboxCat=(HCategory*)gHades->getCurrentEvent()->getCategory(catTBoxChan);
  if (!tboxCat) {
    tboxCat=gHades->getSetup()->getDetector("TBox")->buildCategory(catTBoxChan);
    if (tboxCat) gHades->getCurrentEvent()->addCategory(catTBoxChan,tboxCat,"TBox");
    else return kFALSE;
  }
  loc.set(2,0,0);
  return kTRUE;
}

 Int_t HTBoxUnpacker::execute() {
  // Unpacks the scaler data and fills the TBox data category
#if DEBUG_LEVEL>4
  gDebuger->enterFunc("HTBoxUnpacker::execute\n");
#endif
  if (!(gHades->isCalibration())) {  // no calibration event, nothing to be done for scalers
    return 1;
  }
  Bool_t bIsOld      = kFALSE;
  Int_t nEvtId       = 0; //Evt Id
  Int_t nEvt         = 0; //Evt number
  UInt_t uOldCalType = 0;
  UInt_t uTrigbits   = 0;
  UInt_t uBlockSize  = 0; //Number of data words in one block
  UInt_t uBoardType  = 0; // 1 - Struck, 0 - TDC
  UInt_t uStruck     = 0; // scaler or latch
  UInt_t* uTmp       = NULL;
  UInt_t uWordCount  = 0;
  if (subEvtId==412) {
    if (pSubEvt) {
      UInt_t* data = pSubEvt->getData();
      UInt_t* end  = pSubEvt->getEnd();
      #if DEBUG_LEVEL>4
         printf("Next SubEvt. data between: %p and %p\n",data,end);
         pSubEvt->dumpIt();
      #endif
      nEvtId=gHades->getCurrentEvent()->getHeader()->getId();
      nEvt=gHades->getCurrentEvent()->getHeader()->getEventSeqNumber();
      // only in old data
      uOldCalType=(*data & 0xf00);
      uTmp=data;
      bIsOld=gHades->getCurrentEvent()->getHeader()->isOldDAQ();
      // Loop over all data words
      while (++data<end && *data!=0x0) {
        #if DEBUG_LEVEL>2
           printf("Data word: %p\n",*data);
        #endif
        // nEvtId==5 (calibration event) and no TIP-block header indicate
        // old data scheme
        if (nEvtId==5 && (*(data) == 0x8000000) && bIsOld && uOldCalType==0x900) {
          // There is no TIP header - go back one word
          data--;
          data = fillScaler(data,&uTrigbits,kTRUE);
        } else {
          // Scan for TIP-block header ( TYPE 0 )
          if (((*data >>24) & 0x6)==0) {
            uBlockSize=(*data) & 0x0000003ff;
            uBoardType=(*data >> 12 ) & 0x1;
            uStruck   =(*data >> 10 ) & 0x3f;
            #if DEBUG_LEVEL>4
              cout<<"Struck "<<uStruck <<" BoardType:"<< uBoardType<<endl;
            #endif
            // latch or scaler
            if (uBoardType==1) {
              if (uStruck == SCALER){
                uTrigbits=uTrigbits | 0x100;
                data=fillScaler(data,&uTrigbits,kFALSE,SCALER);
              } else if (uStruck == SCALER_JAN04){
                data=fillScaler(data,&uTrigbits,kFALSE,SCALER_JAN04);
              } else if (uStruck == LATCH) {
                data = skipLatch(data);
              } else if (uStruck == DEBUG) {
                data+=uBlockSize;
                continue;
              } else {
                Error("execute","Unknown type=%i",uStruck);
              }
            } else if (uBoardType!=0) {  // 0 = tdc header
              Error("execute","Unknown BoardType=%i",uBoardType);
            }
          } else if (((*data>>24) & 0x6)==2) {  // Scan for TDC header
            // Found valid TDC header
            uBlockSize=((*data) >>  8) & 0xff;
            // Check if also trailer exists
            if ((*(data + uBlockSize+1) >>24 & 0x6)!=4) {
              Error("execute","Header found but no trailer!!");
              continue;
            }
            // Check trigger tag in the trailer
            if ((*(data+uBlockSize+1)&0xff)!=((UInt_t)pSubEvt->getTrigNr()&0xFF)) {
	      Error("execute","Trigger tag mismatch: EventSeqNumber= %i! Skip event...",nEvt);
	    }
            uTmp=data;
            uWordCount=0;
            while (++data && data<(uTmp + uBlockSize+1) && *data!=0x0) {
              uWordCount++;
            }
            if (uWordCount!=uBlockSize) {
              Error("execute()","Found %i but expecting % words!!!",
                    uWordCount,uBlockSize);
            }
          } else if (((*data>>24) & 0x6)==6) {
            #if DEBUG_LEVEL>2
               Error("execute()","Evt: %i, Invalid Data Word! Type: %d,Skipping 0x%08x",
                     nEvt,((*data>>24) & 0x6),*data);
               pSubEvt->dumpIt();
            #endif
          } else if (((*data>>24) & 0x6)==0) {
              Error("execute()","Evt: %i, Data follow, but no header",nEvt);
          } else {
            Error("execute()","Evt: %i, Unknow raw data type %i",
                  nEvt,((*data>>24) & 0x6));
          }
        }
      } // end data
    } // pSubEvt
  } else if(subEvtId==416) {   // New data structures since aug04
    if (pSubEvt) {
      UInt_t* data = pSubEvt->getData();
      UInt_t* end  = pSubEvt->getEnd();
      #if DEBUG_LEVEL>4
         printf("Next SubEvt. data between: %p and %p\n",data,end);
         pSubEvt->dumpIt();
      #endif
      nEvtId=gHades->getCurrentEvent()->getHeader()->getId();
      nEvt=gHades->getCurrentEvent()->getHeader()->getEventSeqNumber();
      //Loop over all data words
      while (++data<end && *data!=0x0) {
        #if DEBUG_LEVEL>2
           printf("Data word: %p\n",*data);
        #endif
        //Scan for TIP-block header Scalers have always TIP-Block
        if (((*data >>24) & 0x6)==0 && (((*data) &  0x3fffff )!=0)) {
          uBlockSize = (*data) & 0x0000003ff;
          uBoardType = (*data >> 10 ) & 0x3f;
          #if DEBUG_LEVEL>4
             printf("BoardType: %d\n ",uBoardType);
          #endif
          //new scaler aug04
          if (uBoardType==SCALER_AUG04) {
            #if DEBUG_LEVEL>4
               printf("Total scalers block size is :%d \n",uBlockSize);
            #endif
            UInt_t* pScalerTrailer=0;
            UInt_t uScalerSize=0;
            UInt_t uScalerTotalSize=0;
            UInt_t* pScalerHeader = 0;
            Int_t nScalerCounts=0;
            Int_t nScalerCountsTotal=0;
            //Count valid scaler blocks, for correct scaler numbering
            while( uScalerTotalSize < uBlockSize ) {
              //Here should be trailer
              pScalerTrailer = data+uBlockSize-uScalerTotalSize;
              uScalerSize=((*pScalerTrailer) & 0x7fffff)/4;
              //and header
              pScalerHeader =  pScalerTrailer-uScalerSize+1;
              uScalerTotalSize = uScalerTotalSize+uScalerSize;
              if ((*pScalerHeader &  0x3fffff )==0) {
                nScalerCounts++;
              } else {
                data+=uBlockSize;
                break; //return to main loop
              }
            }
            nScalerCountsTotal=nScalerCounts;
            //printf("Found %d scaler(s)n",nScalerCounts);
            #if DEBUG_LEVEL>2
               printf("Found %d scaler(s)\n",nScalerCounts);
            #endif
            //Clear variables and fill scalers
            pScalerTrailer=0;
            uScalerSize=0;
            uScalerTotalSize=0;
            pScalerHeader = 0;
            nScalerCounts=0;
            //Loop over all scalers data
            clearScalData();
            while( uScalerTotalSize < uBlockSize ){
              //Here should be trailer
              pScalerTrailer = data+uBlockSize-uScalerTotalSize;
              uScalerSize=((*pScalerTrailer) & 0x7fffff)/4;
              //and header
              pScalerHeader =  pScalerTrailer-uScalerSize+1;
              uScalerTotalSize = uScalerTotalSize+uScalerSize;
              #if DEBUG_LEVEL>4
                 printf("Scaler header 0x%08x trailer 0x%08x\n",
                        *pScalerHeader,*pScalerTrailer);
              #endif
              if ((*pScalerHeader &  0x3fffff )==0) {
                #if DEBUG_LEVEL>4
                   printf("Found valid scaler header and trailer\n");
                   printf("Size of scaler is %d\n",
                          ((*pScalerTrailer) & 0x7fffff)/4-2);
                #endif						
                fillScalerData(nScalerCountsTotal-nScalerCounts-1,pScalerHeader,uScalerSize-2);
                nScalerCounts++;
              } else {
                printf("No valid SIS header for scalers found. Data may be corrupted. Skipping it.\n");
                data+=uBlockSize;
                break; //return to main loop
              }
            }
            //Fill tboxchan with all scaler data
            fillScalers(nScalerCounts);
            data+=uBlockSize;
          } else if (uBoardType!=0) {
            Error("execute","Unknown BoardType=%i",uBoardType);
          }
        } else if (((*data>>24) & 0x6)==2) {  // tdc
          uBlockSize = ( (*data) >> 8   ) & 0xff;
          //Check if also trailer exists
          if ((*(data + uBlockSize+1) >>24 & 0x6)!=4) {
            Error("execute","Header found but no trailer!!");
            continue;
          }
          //Check trigger tag in the trailer
          if ((*(data+uBlockSize+1)&0xff)!=((UInt_t)pSubEvt->getTrigNr()&0xFF)) {
	    Error("execute","Trigger tag mismatch: EventSeqNumber= %i! Skip event...",nEvt);
	    if(!gHades->getForceNoSkip()) return kDsSkip;
          }
          uTmp=data;
          uWordCount=0;
          while( ++data && data<(uTmp + uBlockSize+1) && *data!=0x0 ){
            uWordCount++;
          }
          if (uWordCount!=uBlockSize) {
            Error("execute()","Found %i but expecting % words!!!",
                  uWordCount,uBlockSize);
          }
        } else if (((*data) &  0x3fffff )==0) {  // SIS3829 header for latch
          UInt_t uGeo = (*data)>>27 &0x1F;
          //Latch should have one data word, zero is also possible
          #if DEBUG_LEVEL>4
             printf("Trying to find the size \n");
          #endif
          UInt_t* pLatchTmp=data;
          if (++pLatchTmp && ((*pLatchTmp)>>27 &0x1F)==uGeo) {
            Warning("execute()","Empty LATCH !!!!!!");
          } else if (!(++pLatchTmp && ((*pLatchTmp)>>27 &0x1F)==uGeo) ) {
            Error("execute()","Wrong latch data!");
          }
          data=pLatchTmp;
        } else if ( ((*data>>24) & 0x6)==6 ) {
          #if DEBUG_LEVEL>2
            Error("execute()","Evt: %i, Invalid Data Word! Type: %d,Skipping 0x%08x",
                  nEvt,((*data>>24) & 0x6),*data);
            pSubEvt->dumpIt();
          #endif
        } else if (((*data>>24) & 0x6)==0) {
          Error("execute()","Evt: %i, Data follow, but no header",nEvt);
        } else {
          Error("execute()","Evt: %i, Unknow raw data type %i",
                nEvt,((*data>>24) & 0x6));
        }
      }  // end data
    }
  } //end new data structures
  #if DEBUG_LEVEL>4
     gDebuger->leaveFunc("HTBoxUnpacker::execute\n");
  #endif
  return 1;
}

 UInt_t* HTBoxUnpacker::fillScaler(UInt_t* pData,UInt_t* uTrigbits,Bool_t bOld,Int_t nType){
  // Function for filling scaler data
  // returns the pointer to the next data word
  HTBoxChan* ptboxchan = 0;
  UInt_t uWordCount    = 0;
  UInt_t* uTmp         = NULL;
  UInt_t uBlockSize    = 0; //Number of data words in one block
  Int_t nCountBox      = 0;
  // set 9th bit to 1 when calibration event
  *uTrigbits = *uTrigbits | 0x100;
  uBlockSize = (*pData) & 0x0000003ff;
  clearScalData();
  //Check header
  if (bOld) {
    //In old data no TIP-header and no size information
    //header+32 data words + trailer = 34
    //printf("Old datan");
    uBlockSize=34; //MAX VALUE
  }
  #if DEBUG_LEVEL>2
     printf("Scaler data 0x%08x Size: %d\n",*pData,uBlockSize);
  #endif
  if (*++pData == 0x08000000 || nType==SCALER_JAN04) {
    //Header exists, check trailer
    //new data structure ???
    //since nov04  no header/trailer
#warning FIXME scaler trailer !!!!
    if (!bOld && (*(pData+uBlockSize-1)>>24)!=0x8 && nType!=SCALER_JAN04) {
      Error("fillScaler","Header found but no trailer!!");
      clearScalData();
      return pSubEvt->getEnd();
    } else {
      //read scaler
      uTmp=pData;
      if (nType==SCALER_JAN04) { //No header!!!
        uTmp=pData;
        pData--;
      }
      uWordCount=0;
      nCountBox=0;
      while (++pData && pData<uTmp+uBlockSize && (*pData>>8) != 0x80000) {
        uWordCount++;
        if(nCountBox < 32) {
          if ((*pData & 0xff000000) != 0x0) {
             scalData[nCountBox] = 0x0;
          } else {
            //printf("scalData %dn",(*pData & 0xffffff));
            scalData[nCountBox] = (*pData & 0xffffff);
          }
          nCountBox++;
        } else {
          Error("fillScaler","Evt %d. Too many data words for scaler",
                gHades->getCurrentEvent()->getHeader()->getEventSeqNumber());
          clearScalData();
          return pSubEvt->getEnd();
        }
      }
      if (!bOld && ((nType==SCALER_JAN04 &&  uWordCount!=uBlockSize) || (nType!=SCALER_JAN04 && uWordCount!=(uBlockSize-2)))) {
        Error("fillScaler",
              "Found %i but expecting %i words!!!", uWordCount,uBlockSize);
        return pSubEvt->getEnd();
      }
      if (nType==SCALER_JAN04) pData--; //no trailer
    }
    if(tboxCat) {
      for (Int_t i=0; i<8; i++) {
        ptboxchan=(HTBoxChan*)tboxCat->getNewSlot(loc);
        if(!ptboxchan) continue;
        ptboxchan = new(ptboxchan) HTBoxChan;
        ptboxchan->set(i,scalData[i],scalData[i+8],scalData[i+16],scalData[i+24]);
      }
    }
  } else {
    Error("fillScaler",
          "Header for scaler data %p not found!",*pData);
  }
  return pData;
}

 void HTBoxUnpacker::fillScalerData(Int_t n,UInt_t* pScalerData,Int_t nSize){
  // Used since aug04 data
  for (Int_t i=0;i<nSize;i++) {
    pScalerData++;
    scalData[n*32 + i] = (*pScalerData & 0xffffffff);
  }
}

 void HTBoxUnpacker::fillScalers(Int_t nScalerCounts) {
  //Function for filling TBoxChan category for given number of scalers
  HTBoxChan* ptboxchan = NULL;
  if (tboxCat) {
    for (Int_t i=0;i<8;i++) {
      ptboxchan=(HTBoxChan*)tboxCat->getNewSlot(loc);
      if (!ptboxchan) {
        printf("Can not get new slot for HTBoxChann");
        continue;
      } else {
        ptboxchan = new(ptboxchan) HTBoxChan;
        for (Int_t s=0;s<nScalerCounts;s++){
          ptboxchan->set(i,scalData[i+s*32],
          scalData[i+s*32+8],
          scalData[i+s*32+16],
          scalData[i+s*32+24],s);
        }
      }
    }
  }
}

 UInt_t* HTBoxUnpacker::skipLatch(UInt_t* pData) {
  // Skips the latch data in old readout schema used before aug04
  // Returns the pointer to the next data word
  UInt_t uWordCount    = 0;
  UInt_t* uTmp         = NULL;
  UInt_t uBlockSize    = 0; //Number of data words in one block.
  uBlockSize = (*pData) & 0x0000003ff;
  //Check header
  #if DEBUG_LEVEL>2
     printf("Latch data 0x%08x Size: %d\n",*pData,uBlockSize);
  #endif
  if (*++pData == 0x8000000) {
    //check trailer
#warning FIXME  latch trailer !!!!
    if ((*(pData+uBlockSize-1)>>24)!=0x8) {
      Error("skipLatch","Header found but no trailer!!");
      clearScalData();
    } else {
      //read latch
      uTmp=pData;
      uWordCount=0;
      while (++pData && pData<uTmp+uBlockSize-1 && *pData!=0x0) {
        uWordCount++;
        if (uWordCount== 1){  //Only one word for latch!
          //printf("Latch data 0x%08x n",*pData);
        } else {
          Error("skipLatch","Too many data words for Latch!!!!");
          return pSubEvt->getEnd();
        }
      }
      if (uWordCount!=(uBlockSize-2)) {  //-header -trailer
        Error("skipLatch()",
              "Found %i but expecting %i words!!!", uWordCount,uBlockSize);
        return pSubEvt->getEnd();
      }
    }
  } else{
    Error("skipLatch",
          "Header for latch data not found!");
    return pData;
  }
  return pData;
}


ROOT page - Class index - Class Hierarchy - Top of the page

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.