Newer
Older
/**
\class TIBlobModule
\ingroup Decoders
\brief Decoder module to pull information out of the TI blob that is read in each ROC.
The TI blob is identified by a bank with the tag 4.
*/
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#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;
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
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)