Hall A ROOT/C++ Analyzer (podd)
Loading...
Searching...
No Matches
Caen1190Module.cxx
Go to the documentation of this file.
12#include "Caen1190Module.h"
13#include "THaSlotData.h"
14#include <iostream>
15#include <sstream>
16#include <cassert>
17
18using namespace std;
19
20//#define DEBUG
21//#define WITH_DEBUG
22
23namespace Decoder {
24
25const UInt_t NTDCCHAN = 128;
26const UInt_t MAXHIT = 100;
27
29 DoRegister(ModuleType("Decoder::Caen1190Module", 1190));
30
31//_____________________________________________________________________________
33 : PipeliningModule(crate, slot)
34 , fNumHits(NTDCCHAN)
35 , fTdcData(NTDCCHAN * MAXHIT)
36 , fTdcOpt(NTDCCHAN * MAXHIT)
37 , fSlotData(nullptr)
38 , fEvBuf(nullptr)
39 , fNfill(0)
40{
42}
43
44//_____________________________________________________________________________
46{
48 fNumHits.resize(NTDCCHAN);
49 fTdcData.resize(NTDCCHAN * MAXHIT);
50 fTdcOpt.resize(NTDCCHAN * MAXHIT);
52 IsInit = true;
53 fName = "Caen TDC 1190 Module";
54}
55
56//_____________________________________________________________________________
58 const UInt_t* pstop )
59{
60 // Load from evbuffer between [evbuffer,pstop]
61
62 return LoadSlot(sldat, evbuffer, 0, pstop + 1 - evbuffer);
63}
64
65//_____________________________________________________________________________
67 UInt_t pos, UInt_t len )
68{
69 // Fill data structures of this class.
70 // Read until out of data or until Decode() says that the slot is finished.
71 // len = ndata in event, pos = word number for block header in event
72
73 fSlotData = sldat; // Used in Decode()
74 const auto* p = evbuffer + pos;
75 const auto* const q = p + len;
76 while( p != q ) {
77 if( Decode(p++) != 0 )
78 break; // global trailer found
79 }
80 return fWordsSeen = p - (evbuffer + pos);
81}
82
83//_____________________________________________________________________________
85{
86 // Interpret the data word pointed to by 'p'
87
88 Int_t glbl_trl = 0;
89 switch( *p >> 27 ) {
90 case kFiller : // buffer alignment filler word; skip
91 break;
92 case kGlobalHeader : // global header
93 tdc_data.glb_hdr_evno = (*p & 0x07ffffe0) >> 5; // bits 26-5
94 tdc_data.glb_hdr_slno = *p & 0x0000001f; // bits 4-0
95 if( tdc_data.glb_hdr_slno == fSlot ) {
96#ifdef WITH_DEBUG
97 if( fDebugFile )
98 *fDebugFile << "Caen1190Module:: 1190 GLOBAL HEADER >> data = "
99 << hex << *p << " >> event number = " << dec
100 << tdc_data.glb_hdr_evno << " >> slot number = "
101 << tdc_data.glb_hdr_slno << endl;
102#endif
103 }
104 break;
105 case kTDCHeader : // tdc header
106 if( tdc_data.glb_hdr_slno == fSlot ) {
107 tdc_data.hdr_chip_id = (*p & 0x03000000) >> 24; // bits 25-24
108 tdc_data.hdr_event_id = (*p & 0x00fff000) >> 12; // bits 23-12
109 tdc_data.hdr_bunch_id = *p & 0x00000fff; // bits 11-0
110#ifdef WITH_DEBUG
111 if( fDebugFile )
112 *fDebugFile << "Caen1190Module:: 1190 TDC HEADER >> data = "
113 << hex << *p << " >> chip id = " << dec
114 << tdc_data.hdr_chip_id << " >> event id = "
115 << tdc_data.hdr_event_id << " >> bunch_id = "
116 << tdc_data.hdr_bunch_id << endl;
117#endif
118 }
119 break;
120 case kTDCData : // tdc measurement
121 if( tdc_data.glb_hdr_slno == fSlot ) {
122 tdc_data.chan = (*p & 0x03f80000) >> 19; // bits 25-19
123 tdc_data.raw = *p & 0x0007ffff; // bits 18-0
124 tdc_data.opt = (*p & 0x04000000) >> 26; // bit 26
126#ifdef WITH_DEBUG
127 if( fDebugFile )
128 *fDebugFile << "Caen1190Module:: 1190 MEASURED DATA >> data = "
129 << hex << *p << " >> channel = " << dec
130 << tdc_data.chan << " >> edge = "
131 << tdc_data.opt << " >> raw time = "
132 << tdc_data.raw << " >> status = "
133 << tdc_data.status << endl;
134#endif
135 if( tdc_data.chan < NTDCCHAN &&
139 }
140 if( tdc_data.status != SD_OK ) return -1;
141 }
142 break;
143 case kTDCTrailer : // tdc trailer
144 if( tdc_data.glb_hdr_slno == fSlot ) {
145 tdc_data.trl_chip_id = (*p & 0x03000000) >> 24; // bits 25-24
146 tdc_data.trl_event_id = (*p & 0x00fff000) >> 12; // bits 23-12
147 tdc_data.trl_word_cnt = *p & 0x00000fff; // bits 11-0
148#ifdef WITH_DEBUG
149 if( fDebugFile )
150 *fDebugFile << "Caen1190Module:: 1190 TDC TRAILER >> data = "
151 << hex << *p << " >> chip id = " << dec
152 << tdc_data.trl_chip_id << " >> event id = "
153 << tdc_data.trl_event_id << " >> word count = "
154 << tdc_data.trl_word_cnt << endl;
155#endif
156 }
157 break;
158 case kTDCError : // tdc error
159 if( tdc_data.glb_hdr_slno == fSlot ) {
160 tdc_data.chip_nr_hd = (*p & 0x03000000) >> 24; // bits 25-24
161 tdc_data.flags = *p & 0x00007fff; // bits 14-0
162 cout << "TDC1190 Error: Slot " << tdc_data.glb_hdr_slno << ", Chip " << tdc_data.chip_nr_hd <<
163 ", Flags " << hex << tdc_data.flags << dec << " " << ", Ev #" << tdc_data.glb_hdr_evno << endl;
164#ifdef WITH_DEBUG
165 if( fDebugFile )
166 *fDebugFile << "Caen1190Module:: 1190 TDC ERROR >> data = "
167 << hex << *p << " >> chip header = " << dec
168 << tdc_data.chip_nr_hd << " >> error flags = " << hex
169 << tdc_data.flags << dec << endl;
170#endif
171 }
172 break;
173 case kTriggerTime : // extended trigger time tag
174 if( tdc_data.glb_hdr_slno == fSlot ) {
175 tdc_data.trig_time = *p & 0x7ffffff; // bits 27-0
176#ifdef WITH_DEBUG
177 if( fDebugFile )
178 *fDebugFile << "Caen1190Module:: 1190 GLOBAL TRIGGER TIME >> data = "
179 << hex << *p << " >> trigger time = " << dec
180 << tdc_data.trig_time << endl;
181#endif
182 }
183 break;
184 case kGlobalTrailer : // global trailer
185 if( tdc_data.glb_hdr_slno == fSlot ) {
186 tdc_data.glb_trl_status = (*p & 0x07000000) >> 24; // bits 24-26
187 tdc_data.glb_trl_wrd_cnt = (*p & 0x001fffe0) >> 5; // bits 20-5
188 tdc_data.glb_trl_slno = *p & 0x0000001f; // bits 4-0
189#ifdef WITH_DEBUG
190 if( fDebugFile )
191 *fDebugFile << "Caen1190Module:: 1190 GLOBAL TRAILER >> data = "
192 << hex << *p << " >> status = "
193 << tdc_data.glb_trl_status << " >> word count = " << dec
194 << tdc_data.glb_trl_wrd_cnt << " >> slot number = "
195 << tdc_data.glb_trl_slno << endl;
196#endif
197 glbl_trl = 1;
198 }
199 break;
200 default: // unknown word
201 cout << "unknown word for TDC1190: " << hex << (*p) << dec << endl;
202 cout << "according to global header ev. nr. is: " << " " << tdc_data.glb_hdr_evno << endl;
203 break;
204 }
205 return glbl_trl;
206}
207
208//_____________________________________________________________________________
210{
211 if( hit >= fNumHits[chan] ) return 0;
212 UInt_t idx = chan * MAXHIT + hit;
213 if( idx > MAXHIT * NTDCCHAN ) return 0;
214 return fTdcData[idx];
215}
216
217//_____________________________________________________________________________
219{
220 if( hit >= fNumHits[chan] ) return 0;
221 UInt_t idx = chan * MAXHIT + hit;
222 if( idx > MAXHIT * NTDCCHAN ) return 0;
223 return fTdcOpt[idx];
224}
225
226//_____________________________________________________________________________
228{
230 fNumHits.assign(NTDCCHAN, 0);
231 fTdcData.assign(NTDCCHAN * MAXHIT, 0);
232 fTdcOpt.assign(NTDCCHAN * MAXHIT, 0);
233 fNfill = 0;
234}
235
236//_____________________________________________________________________________
238 UInt_t pos, UInt_t len )
239{
240 // Load event block. If multi-block data, split the buffer into individual
241 // events. This routine is called for buffers with bank structure.
242
243 const char* const here = "LoadBank";
244
245 // Note: Clear() has been called at this point
246
247 const UInt_t MINLEN = 10;
248 if( len < MINLEN ) {
249 cerr << Here(here) << "FATAL ERROR: Bank too short. Expected >= "
250 << MINLEN << ", got " << len << " words. Skipping event." << endl;
251 // Caller neither checks error codes nor handles exceptions. Hopeless.
252 return 0;
253 }
254 // Find all the global headers for this module's slot in this bank.
255 // Unfortunately, the current data format lacks a block header/trailer
256 // and does not tell us anything about the module's idea of the block size,
257 // so we have to discover it from the data.
258 evtblk.reserve(16);
259 UInt_t cur = pos;
260 UInt_t evtnum;
261 Long64_t ihdr;
262 Long64_t itrl;
263 while( cur < pos+len &&
264 (ihdr = Find1190Word(evbuffer, cur, len+pos-cur,
265 kGlobalHeader, fSlot)) != -1 ) {
266 const UInt_t* p = evbuffer + ihdr;
267 UInt_t next_evtnum = (*p & 0x07FFFFE0) >> 5;
268 if( !evtblk.empty() ) {
269 if( next_evtnum != evtnum + 1 ) {
270 cerr << Here(here) << "WARNING: event numbers in block not "
271 "sequential, prev/next = "
272 << evtnum << "/" << next_evtnum << endl;
273 }
274 }
275 evtnum = next_evtnum;
276 evtblk.push_back(ihdr);
277 cur = ihdr + 1;
278 itrl = Find1190Word(evbuffer, cur, len+pos-cur, kGlobalTrailer, fSlot);
279 if( itrl == -1 ) {
280 cerr << Here(here)
281 << "FATAL ERROR: No global trailer found for slot " << fSlot
282 << " event " << evtnum << ", skipping block" << endl;
283 return 0;
284 }
285 p = evbuffer + itrl;
286 UInt_t nwords_trl = (*p & 0x1FFFE0) >> 5;
287 if( nwords_trl != itrl-ihdr+1 ) {
288 cerr << Here(here) << "Warning: global trailer word count mismatch, "
289 << "got " << nwords_trl << ", expected " << itrl-ihdr+1 << endl;
290 }
291 cur = itrl + 1;
292 }
293 if( evtblk.empty() ) {
294 // No global header found at all. Should not happen.
295 cerr << Here(here)
296 << "FATAL ERROR: No global header found in bank. Call expert." << endl;
297 return 0;
298 }
299 block_size = evtblk.size();
300 // TODO: cross check block size with trigger bank info
301
302 UInt_t ibeg = evtblk[0];
303 // Put position one past last global trailer at end of evtblk array
304 UInt_t iend = itrl+1;
305 evtblk.push_back(iend);
306
307 // Consume filler words, if any
308 const UInt_t* p = evbuffer + iend - 1;
309 while( ++p-evbuffer < pos+len && (*p >> 27) == kFiller ) {
310 ++fNfill;
311 }
312
313 // Multi-block event?
314 fMultiBlockMode = ( block_size > 1 );
315
316 if( fMultiBlockMode ) {
317 // Save pointer to event buffer for use in LoadNextEvBuffer
318 fEvBuf = evbuffer;
319 // Multi-block: decode first event, using event positions from evtblk[]
320 index_buffer = 0;
321 return LoadNextEvBuffer(sldat);
322
323 } else {
324 // Single block: decode, starting at global header
325 return LoadSlot(sldat, evbuffer, ibeg, iend-ibeg)
326 + fNfill;
327 }
328 // not reached
329}
330
331//_____________________________________________________________________________
333{
334 // In multi-block mode, load the next event from the current block.
335 // Returns number of words consumed
336
337 UInt_t ii = index_buffer;
338 assert( ii+1 < evtblk.size() );
339
340 // ibeg = event header, iend = one past last word of this event ( = next
341 // event header if more events pending)
342 auto ibeg = evtblk[ii], iend = evtblk[ii+1];
343 assert(ibeg > 0 && iend > ibeg); // else bug in LoadBank
344
345 assert(fEvBuf); // We should never get here without a prior call to LoadBank
346 // or after fBlockIsDone is set
347
348 // Load slot starting with event header at ibeg
349 ii = LoadSlot(sldat, fEvBuf, ibeg, iend-ibeg);
350
351 // Next cached buffer. Set flag if we've exhausted the cache.
352 ++index_buffer;
353 if( index_buffer+1 >= evtblk.size() ) {
354 fBlockIsDone = true;
355 fEvBuf = nullptr;
356 }
357
358 if( fBlockIsDone )
359 ii += fNfill; // filler words
360 return ii;
361}
362
363//_____________________________________________________________________________
364string Caen1190Module::Here( const char* function )
365{
366 // Convenience function for error messages
367 ostringstream os;
368 os << "Caen1190Module::" << function << ": slot/crate "
369 << fSlot << "/" << fCrate << ": ";
370 return os.str();
371}
372
373} // namespace Decoder
374
int Int_t
unsigned int UInt_t
uint32_t chan
const char Option_t
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
const int SD_OK
Definition THaSlotData.h:33
static const char *const here
Definition THaVar.cxx:64
float * q
virtual UInt_t LoadSlot(THaSlotData *sldat, const UInt_t *evbuffer, const UInt_t *pstop)
std::vector< UInt_t > fTdcData
virtual UInt_t LoadNextEvBuffer(THaSlotData *sldat)
virtual UInt_t GetData(UInt_t chan, UInt_t hit) const
virtual UInt_t LoadBank(THaSlotData *sldat, const UInt_t *evbuffer, UInt_t pos, UInt_t len)
std::string Here(const char *function)
std::vector< UInt_t > fNumHits
virtual Int_t Decode(const UInt_t *p)
static TypeIter_t fgThisType
virtual void Clear(Option_t *opt="")
class Decoder::Caen1190Module::tdcData tdc_data
virtual UInt_t GetOpt(UInt_t chan, UInt_t hit) const
static Long64_t Find1190Word(const uint32_t *buf, size_t start, size_t len, EDataType type, uint32_t slot)
std::vector< UInt_t > fTdcOpt
UInt_t fCrate
Definition Module.h:142
virtual void Init()
Definition Module.cxx:51
Bool_t fMultiBlockMode
Definition Module.h:152
std::ofstream * fDebugFile
Definition Module.h:156
UInt_t block_size
Definition Module.h:150
Bool_t fBlockIsDone
Definition Module.h:152
UInt_t fSlot
Definition Module.h:142
UInt_t fWordsSeen
Definition Module.h:145
TypeSet_t::iterator TypeIter_t
Definition Module.h:40
Bool_t IsInit
Definition Module.h:151
std::vector< Long64_t > evtblk
virtual void Clear(Option_t *opt="")
Int_t loadData(const char *type, UInt_t chan, UInt_t dat, UInt_t raw)
TString fName
long long Long64_t
const UInt_t MAXHIT
const UInt_t NTDCCHAN
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
STL namespace.
ClassImp(TPyArg)