diff --git a/Makefile b/Makefile index a3f35cb7f02f2ce1c9302762e0ab2636ac1f8c39..a14dc6f8b92b1a8b10efd6eca14b47e98f7c17f1 100644 --- a/Makefile +++ b/Makefile @@ -221,7 +221,7 @@ $(LINKDEF): $(LINKDEF)_preamble $(LINKDEF)_postamble $(SRC) @cat $(LINKDEF)_preamble > $(LINKDEF) @echo $(SRC) | tr ' ' '\n' | sed -e "s|src/|#pragma link C++ class |" | sed -e "s|.cxx|+;|" >> $(LINKDEF) @cat $(LINKDEF)_postamble >> $(LINKDEF) - @sed -e "s/class Scaler/class Decoder::Scaler/" $(LINKDEF) > $(LINKDEF)_tmp + @sed -e "s/class Scaler/class Decoder::Scaler/" -e "s/class TIBlobModule/class Decoder::TIBlobModule/" $(LINKDEF) > $(LINKDEF)_tmp @mv $(LINKDEF)_tmp $(LINKDEF) install: all diff --git a/SConscript.py b/SConscript.py index 0afd3d2513851fd7407ce6221a3e47eccc340798..46600761952cdd3652f32cb80baa8c1a4bc77eab 100644 --- a/SConscript.py +++ b/SConscript.py @@ -21,7 +21,7 @@ for hcheaderfile in hcheadersbase: basefilename = filename.rsplit('.',1) newbasefilename = basefilename[0].rsplit('/',1) # Assume filenames beginning with Scaler are decoder classes - if newbasefilename[1][:6] == 'Scaler': + if newbasefilename[1][:6] == 'Scaler' or newbasefilename[1] == "TIBlobModule": cmd1 = "echo '#pragma link C++ class Decoder::%s+;' >> src/HallC_LinkDef.h" % newbasefilename[1] else: cmd1 = "echo '#pragma link C++ class %s+;' >> src/HallC_LinkDef.h" % newbasefilename[1] diff --git a/src/TIBlobModule.cxx b/src/TIBlobModule.cxx new file mode 100644 index 0000000000000000000000000000000000000000..074bd3950291ca1814e4441dbaea6ed091648d5b --- /dev/null +++ b/src/TIBlobModule.cxx @@ -0,0 +1,175 @@ +///////////////////////////////////////////////////////////////////// +// +// 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) diff --git a/src/TIBlobModule.h b/src/TIBlobModule.h new file mode 100644 index 0000000000000000000000000000000000000000..4450456b4518692cdc2702cb11b7fba7f4159da3 --- /dev/null +++ b/src/TIBlobModule.h @@ -0,0 +1,55 @@ +#ifndef TIBlobModule_ +#define TIBlobModule_ + + +///////////////////////////////////////////////////////////////////// +// +// TIBlobModule +// TI Trigger information +// This version just pulls out +// Trigger type +// Event number (just bottum 32 bits) +// 4ns clock +// +///////////////////////////////////////////////////////////////////// + +#include "PipeliningModule.h" + +namespace Decoder { + +class TIBlobModule : public PipeliningModule { + +public: + + TIBlobModule() : PipeliningModule() {} + TIBlobModule(Int_t crate, Int_t slot); + virtual ~TIBlobModule(); + + using Module::GetData; + using Module::LoadSlot; + + virtual UInt_t GetData(Int_t chan) const; + virtual void Init(); + virtual void Clear(const Option_t *opt=""); + virtual Int_t Decode(const UInt_t*) { return 0; } + virtual Int_t LoadSlot(THaSlotData *sldat, const UInt_t *evbuffer, const UInt_t *pstop ); + virtual Int_t LoadSlot(THaSlotData *sldat, const UInt_t* evbuffer, Int_t pos, Int_t len); + Int_t LoadNextEvBuffer(THaSlotData *sldat); + Int_t LoadThisBlock(THaSlotData *sldat, std::vector<UInt_t > evb); + + protected: + Int_t SplitBuffer(std::vector< UInt_t > bigbuffer); + + private: + + static const size_t NTICHAN = 3; + + static TypeIter_t fgThisType; + ClassDef(TIBlobModule,0) // TIBlob of a module; + +}; + +} + +#endif +