Skip to content
Snippets Groups Projects
TIBlobModule.cxx 5.08 KiB
Newer Older
  • Learn to ignore specific revisions
  • /////////////////////////////////////////////////////////////////////
    //
    //   TIBlob
    //   author Stephen Wood
    //
    //   Decoder module to pull information out of the TI blob that
    //   read in each ROC.
    //
    /////////////////////////////////////////////////////////////////////
    
    #include "TIBlobModule.h"
    #include "THaSlotData.h"
    #include <iostream>
    
    using namespace std;
    
    namespace Decoder {
    
      Module::TypeIter_t TIBlobModule::fgThisType =
        DoRegister( ModuleType( "Decoder::TIBlobModule" , 4 ));
    
      TIBlobModule::TIBlobModule(Int_t crate, Int_t slot) : PipeliningModule(crate, slot) {
        fDebugFile=0;
        Init();
      }
    
      TIBlobModule::~TIBlobModule() {
      }
    
      void TIBlobModule::Init() {
        Module::Init();
        fNumChan=NTICHAN;
        for (Int_t i=0; i<fNumChan; i++) fData.push_back(0);
    #if defined DEBUG && defined WITH_DEBUG
        // This will make a HUGE output
        delete fDebugFile; fDebugFile = 0;
        fDebugFile = new ofstream;
        fDebugFile->open(string("TIBlob_debug.txt"));
    #endif
        //fDebugFile=0;
        Clear();
        IsInit = kTRUE;
        
        fName = "TIBlob";
      }
    
      Int_t TIBlobModule::LoadSlot(THaSlotData *sldat, const UInt_t* evbuffer, const UInt_t *pstop) {
        // the 3-arg verison of LoadSlot
    
        std::vector< UInt_t > evb;
        while(evbuffer < pstop) evb.push_back(*evbuffer++);
    
        // Note, methods SplitBuffer, GetNextBlock are defined in PipeliningModule
        // SplitBuffer needs to be modified a bit for the TI
    
        SplitBuffer(evb);
        return LoadThisBlock(sldat, GetNextBlock());
      }
    
      Int_t TIBlobModule::LoadSlot(THaSlotData *sldat, const UInt_t *evbuffer, Int_t pos, Int_t len) {
        // the 4-arg verison of LoadSlot.  Let it call the 3-arg version.
        // Do we need this or is it historical?
    
        return LoadSlot(sldat, evbuffer+pos, evbuffer+pos+len);
      }
    
      Int_t TIBlobModule::LoadNextEvBuffer(THaSlotData *sldat) {
        // Note, GetNextBlock belongs to PipeliningModule
        return LoadThisBlock(sldat, GetNextBlock());
      }
    
      Int_t TIBlobModule::LoadThisBlock(THaSlotData *sldat, std::vector< UInt_t>evbuffer) {
    
        // Fill data structures of this class using the event buffer of one "event".
        // An "event" is defined in the traditional way -- a scattering from a target, etc.
        
        Clear();
    
        // Only interpret data if fSlot agrees with the slot in the headers
        
        Int_t evlen = evbuffer.size();
        if(evlen>0) {
          // The first word might be a filler word
    
          Int_t ifill = (((evbuffer[0]>>27)&0x1F) == 0x1F) ? 1 : 0;
    
          if (evlen>=5+ifill) {// Need at least two headers and the trailer and 2 data words
    	UInt_t header1=evbuffer[ifill];
    	Int_t slot_blk_hdr=(header1 >> 22) & 0x1F;  // Slot number (set by VME64x backplane), mask 5 bits
    	if(fSlot != slot_blk_hdr) {
    	  return evlen;
    	}
    	fData[0] = (evbuffer[2+ifill]>>24)&0xFF; // Trigger type
    	fData[1] = evbuffer[3+ifill];		 // Trigger number
    	fData[2] = (evlen>5+ifill) ? evbuffer[4+ifill] : 0; // Trigger time
    	//      cout << "TIBlob Slot " << fSlot << ": ";
    	for(Int_t i=0;i<3;i++) {
    	  sldat->loadData(i, fData[i], fData[i]);
    	  //	cout << " " << fData[i];
    	}
    	//      cout << endl;
          }
        }
          
        return evlen;
    
      }
    
      Int_t TIBlobModule::SplitBuffer(std::vector< UInt_t > codabuffer ) {
    
        // Split a CODA buffer into blocks.   A block is data from a traditional physics event.
        // In MultiBlock Mode, a pipelining module can have several events in each CODA buffer.
        // If block level is 1, then the buffer is a traditional physics event.
        // If finding >1 block, this will set fMultiBlockMode = kTRUE
    
        // Copied from PipeliningModule and customized for TI
    
        std::vector<UInt_t > oneEventBuffer;
        eventblock.clear();
        fBlockIsDone = kFALSE;
        //    Int_t eventnum = 1;
        //    Int_t evt_num_modblock;
    
        //    if ((fFirstTime == kFALSE) && (IsMultiBlockMode() == kFALSE)) {
          eventblock.push_back(codabuffer);
          index_buffer=1;
          return 1;
          //    }
          //    return 0;
        // The rest of this is only use if we are in multiblock mode
        // It still needs to be developed.
    #if 0
        int debug=1;
    
        Int_t slot_blk_hdr, slot_evt_hdr, slot_blk_trl;
        Int_t iblock_num, nblock_events, nwords_inblock, evt_num;
        Int_t BlockStart=0;
    
        slot_blk_hdr = 0;
        slot_evt_hdr = 0;
        slot_blk_trl = 0;
        nblock_events = 0;
    
        if(codabuffer.size() > 2) {	// Need at least the two headers and the trailer
          UInt_t header1=codabuffer[0];
          UInt_t header2=codabuffer[1];
    
          if((header1&0xF8000000)==0x80000000 &&
    	 (header1&0xF8000000)==0xF8000000) {	// Header words
    	slot_blk_hdr = (header1 >> 22) & 0x1F;  // Slot number (set by VME64x backplane), mask 5 bits
    	// iblock_num = (data >> 8) & 0x3FF;
    	nblock_events = header1 & 0xFF;
    	if(nblock_events > 1) fMultiBlockMode = kTRUE;
    	UInt_t i=2;
    	while(i+1 < codabuffer.size()) {
    	  // This should be event header
    	  
          
    ...
    #endif
    }
    
    
      /* Does anything use this method */
    UInt_t TIBlobModule::GetData(Int_t chan) const {
      if (chan < 0 || chan > fNumChan) return 0;
      return fData[chan];
    }
    
    void TIBlobModule::Clear(const Option_t* opt) {
      VmeModule::Clear(opt);
      for (Int_t i=0; i<fNumChan; i++) fData[i]=0;
    }
    
    }
    
    ClassImp(Decoder::TIBlobModule)