HYDRA_development_version
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
htoftrb3unpacker.cc
Go to the documentation of this file.
1 //_HADES_CLASS_DESCRIPTION
2 /////////////////////////////////////////////////////////////
3 //
4 // HTofTrb3Unpacker
5 //
6 // Class for unpacking TRB3 data and filling
7 // the Tof Raw category
8 //
9 // Basic subevent decoding and eventual TDC corrections are
10 // performed by decode function in the base class
11 // see: /base/datasource/htrb3unpacker.h
12 //
13 /////////////////////////////////////////////////////////////
14 
15 #include "hades.h"
16 #include "hcategory.h"
17 #include "hdebug.h"
18 #include "hevent.h"
19 #include "heventheader.h"
20 #include "hldsource.h"
21 #include "hldsubevt.h"
22 #include "hruntimedb.h"
23 #include "hspectrometer.h"
24 #include "htofdetector.h"
25 #include "htofraw.h"
26 #include "htofrawsim.h"
27 #include "htoftrb3lookup.h"
28 #include "htoftrb3unpacker.h"
29 #include "tofdef.h"
30 #include "htrbnetunpacker.h"
31 
32 #include <iostream>
33 
34 using namespace std;
35 
37 
38 // JAM: this little switch will enable that we also take single leading edges into account
39 //#define TOF_USE_LEADING_WITHOUT_TRAILING_EDGES 1
40 
41 // JAM: this little switch will enable that we also take single trailing edges into account
42 //#define TOF_USE_TRAILING_WITHOUT_LEADING_EDGES 1
43 
44 // switch on filtering of tdc messages with first time window as defined below
45 //#define TOF_USE_TIME_WINDOW 1
46 
47 // first time window to filter out some unusable hits. units are nanoseconds relative to trigger (channel 0)
48 #define TOF_TIME_MIN -300.0
49 #define TOF_TIME_MAX 1500.0
50 // TODO: optionally put this into some parameter container.
51 Bool_t HTofTrb3Unpacker::fHasPrintedTDC = kFALSE;
52 
53 HTofTrb3Unpacker::HTofTrb3Unpacker(vector<UInt_t>& ids) : HTrb3TdcUnpacker(ids),
54  fLookup(0), fTimeRef(kTRUE), fTimeShift(0.) {
55  // constructor
56  pRawCat = NULL;
57 }
58 
59 Bool_t HTofTrb3Unpacker::init(void) {
60  // creates the raw category and gets the pointer to the TRB3 lookup table
61 
63  if (!det) {
64  Error("init", "No TOF Detector found.");
65  return kFALSE;
66  }
67 
68  if(gHades->getEmbeddingMode()==0) {
69  pRawCat=gHades->getSetup()->getDetector("Tof")->buildCategory(catTofRaw);
70  } else {
71  pRawCat=((HTofDetector*)(gHades->getSetup()->getDetector("Tof")))->buildMatrixCategory("HTofRawSim",0.5F);
72  }
73  if (!pRawCat) return kFALSE;
74 
75  gHades->getCurrentEvent ()->addCategory (catTofRaw, pRawCat, "Tof");
76 
77  fLoc.set(3, 0, 0, 0);
78 
79  fLookup = (HTofTrb3Lookup*) (gHades->getRuntimeDb()->getContainer("TofTrb3Lookup"));
80  if (!fLookup) {
81  Error("init", "No Pointer to parameter container TofTrb3Lookup.");
82  return kFALSE;
83  }
84 
85  if (NULL == trbNetUnpacker) {
86  if (gHades->getDataSource()) {
87  HDataSource* source = gHades->getDataSource();
88  if (source->InheritsFrom("HldSource")) {
89  trbNetUnpacker =
90  ((HldSource *) gHades->getDataSource())->getTrbNetUnpacker();
91  } else {
92  Warning("init",
93  "DataSource not inherited from HldSource! trbNetUnpacker == 0 ");
94  }
95  } else {
96  Warning("init",
97  "Could not retrieve DataSource! trbNetUnpacker == 0 ");
98  }
99  }
100 
101  if (!trbNetUnpacker->init()) {
102  Error("init()", "Failed to initialize HTrbNetUnpacker!");
103  return kFALSE;
104  }
105 
106  return kTRUE;
107 }
108 
110 {
111  // Called in the beginning of each run, used here to initialize TDC unpacker
112  // if TDCs processors are not yet created, use parameter to instantiate them
113  // if auto register TDC feature is used in setup of unpackers (by setting
114  // setMinAddress()+setMaxAddress() manually)
115 
116  if (numTDC() == 0 ) // configure the tdcs only the first time we come here (do not if autoregister is used):
117  {
118  if (fMinAddress == 0 && fMaxAddress == 0)
119  {
120  // here evaluate which subevents are configured in lookup table:
121  Int_t numTDC = fLookup->getSize();
122  Int_t offset = fLookup->getArrayOffset() ;
123  for (Int_t slot = 0; slot < numTDC; ++slot) {
124 
125  Int_t trbnetaddress = offset+slot;
126 
127  HTofTrb3LookupBoard* tdc = fLookup->getBoard(trbnetaddress);
128  if(tdc){
129  Int_t nChan = tdc->getSize();
130  if (trbnetaddress) {
131  Int_t tindex = addTDC(trbnetaddress,nChan);
132  Info("reinit", "Added TDC 0x%04x with %d channels from HTofTrb3Lookup to map index %d",
133  trbnetaddress, nChan,tindex);
134  }
135  }
136  }
137 
138  // set the expected range for the automatic adding of TDC structures:
139 
140  setMinAddress(fLookup->getArrayOffset());
141  setMaxAddress(fLookup->getArrayOffset() + fLookup->getSize());
142  fUseTDCFromLookup = kTRUE; // do not use auto register if set in
143  fHasPrintedTDC = kTRUE;
144 
145  } else {
146  Info("reinit", "TDCs will be added in auto register mode between min address 0x%04x and max address 0x%04x!",fMinAddress,fMaxAddress);
147  }
148  }
149  // we do not call reinit of superclass, since we do not use tdc calibration parameters in hydra anymore!
150  return kTRUE;
151 }
152 
154 
155 
156 
157  if (gHades->isCalibration()) {
158  //calibration event
159  return 1;
160  }
161 
162  if (gHades->getCurrentEvent()->getHeader()->getId() == 0xe) {
163  //scaler event
164  return 1;
165  }
166 
167  // if there is no data, do not try to analyze it
168  // pSubEvt - make sure that there is something for decoding
169  if (!pSubEvt)
170  return 1;
171 
172  Int_t nEvt = gHades->getCurrentEvent()->getHeader()->getEventSeqNumber();
173 
174  // decodes the subevent and fill arrays, see: htrb3unpacker.h
175  if (!decode()) {
176  Error("decode",
177  "subsubevent decoding failed!!! Evt Nr : %i SubEvtId: %x", nEvt,
178  getSubEvtId());
179  return -1;
180  }
181 
182  // correct for reference time here!
183  // we don't check for proper time reference correction
184  // to avoid event skipping
185  // this must be done better in future but now is a good workaround
186 
187  if (fTimeRef) {
188  correctRefTimeCh(REFCHAN);
189  }
190 
191  const Double_t timeUnit=1e9;
192 
193 
194  for (UInt_t ntdc = 0; ntdc < numActiveTDC(); ntdc++) {
195  HTrb3TdcUnpacker::TDC* tdc = getActiveTDC(ntdc);
196 
197  // check the lookup table
198  HTofTrb3LookupBoard *board = fLookup->getBoard(tdc->getTrbAddr());
199  if (!board) {
200  if (debugFlag > 0)
201  Warning("execute",
202  "Evt Nr : %i SubEvId: %x (%i) unpacked but TDC Board 0x%x not in lookup table",
203  nEvt, getSubEvtId(), getSubEvtId(), tdc->getTrbAddr());
204  continue;
205  }
206 
207  // fill the raw category for RPC detector
208  for (UInt_t i = 0; i < tdc->numChannels(); i++) {
209  if(REFCHAN == i) continue;
210 
211  HTrb3TdcUnpacker::ChannelRec& theRecord = tdc->getCh(i);
212 
213 // ignore channels without rising hits already here
214 #ifndef TOF_USE_TRAILING_WITHOUT_LEADING_EDGES
215  if (theRecord.rising_mult < 1)
216  continue;
217 #endif
218  HTofTrb3LookupChan *chan = board->getChannel(i);
219  if (chan == 0) {
220  Warning("execute", "Missing channel %u in lookup table", i);
221  continue;
222  }
223  chan->getAddress(fLoc[0], fLoc[1], fLoc[2]);
224 
225  // if channel not connected in lookup-table, ignore it
226  if (fLoc[0] < 0) { // empty slot default is -1
227  continue;
228  }
229  /*
230  // exclude all not defined and broken channels
231  if (!chan->isDefinedChannel() || chan->isBrokenChannel())
232  continue;
233  */
234 
235  //if (chan->getSide() == 'n' ) continue; // not connected
236 
237 #ifdef TOF_USE_TIME_WINDOW
238  // later we may get this from parameter container or other setup file. For the moment fix it
239  Double_t tmin = TOF_TIME_MIN;
240  Double_t tmax = TOF_TIME_MAX;
241 #endif
242  UInt_t lix = 0;
243  for (lix = 0; lix < theRecord.rising_mult; ++lix) {
244  Double_t tm0 = theRecord.rising_tm[lix] * timeUnit;
245  if (debugFlag > 0)
246  Warning("execute", "JJJJ current hit leading: tm0:%e, apply time shift:%e", tm0, fTimeShift);
247  tm0 +=fTimeShift;
248 
249 #ifdef TOF_USE_TIME_WINDOW
250  if ((tm0 < tmin) || (tm0 > tmax)) {
251  if (debugFlag > 0)
252  Warning("execute",
253  "JJJJ Rejecting leading hit outside tmin:%e or tmax:%e",
254  tmin, tmax);
255  continue; // leading edge outside the time window
256  }
257 
258 #endif
259  // now look for corresponding trailing edge:
260  if (lix < theRecord.falling_mult) {
261  Double_t tm1 = theRecord.falling_tm[lix] * timeUnit;
262  if (debugFlag > 0)
263  Warning("execute", "JJJJ current hit falling: tm1:%e, apply time shift:%e",
264  tm1, fTimeShift);
265  tm1 +=fTimeShift;
266 
267 
268 #ifdef TOF_USE_TIME_WINDOW
269  if ((tm1 < tmin) || (tm1 > tmax)) {
270  if (debugFlag > 0)
271  Warning("execute",
272  "JJJJ Rejecting trailing hit outside tmin:%e or tmax:%e",
273  tmin, tmax);
274 
275 #ifdef TOF_USE_LEADING_WITHOUT_TRAILING_EDGES
276  tm1=0.0; // still we take incomplete leading edge
277 #else
278  continue; // skip both leading and trailing
279 #endif
280  } // if ((tm1 < tmin) || (tm1 > tmax))
281 
282 
283 #endif
284  //
285  // TODO: optional filter out hits that do not fulfill the time threshold parameter
286  //Double_t tot=tm1-tm0;
287  // however, this can be also done in subsequent calibrator object
288 
289 /////// ACCEPTED HITS ARE HERE //////////////////////////////////
290  // regular case with leading/trailing edges of ChannelRec in order
291  if (addRawHit(tm0, tm1, chan) != 0)
292  continue; // we will skip this if this channel is not mapped to detector cell
293 
294 ////////// END ACCEPTED HITS/////////////////////////////////////
295  } // if lix<theRecord.falling_mul
296  else {
297 #ifdef TOF_USE_LEADING_WITHOUT_TRAILING_EDGES
298  // here we treat hist with only leading edges, no corresponding trailing edge
299  // such hit will deliver tot width of -1
300  if(addRawHit(tm0, 0.0, chan)!=0)
301  continue;
302 #endif
303  }
304  } // for lix
305 
306 ////////////// optional now check for single trailing edges?
307 #ifdef TOF_USE_TRAILING_WITHOUT_LEADING_EDGES
308 
309  for (UInt_t tix=lix; tix< theRecord.falling_mult; ++tix)
310  {
311  Double_t tm1=theRecord.falling_tm[tix] * timeUnit;
312 
313 #ifdef TOF_USE_TIME_WINDOW
314  if ((tm1 < tmin) || (tm1 > tmax)) {
315 
316  if (debugFlag > 0)
317  Warning("execute",
318  "JJJJ Rejecting trailing hit outside tmin:%e or tmax:%e",
319  tmin, tmax);
320  continue;
321 #endif
322 
323  if(addRawHit(0.0, tm1, chan)!=0)
324  continue;
325  }
326  ////////////////////
327 #endif
328 /////////////// end single trailing edges
329 
330 
331  } // loop over TDC channels
332  } // loop over TDC
333  return 1;
334 }
335 
336 Int_t HTofTrb3Unpacker::addRawHit(Double_t t_leading, Double_t t_trailing,HTofTrb3LookupChan *chan)
337 {
338 
339  // from here we got access to TDC channel and should map it to RPC channel
340  HTofRaw* raw = (HTofRaw*) pRawCat->getObject(fLoc);
341 
342  if (!raw) {
343  raw = (HTofRaw *) pRawCat->getSlot(fLoc);
344  if(gHades->getEmbeddingMode()==0) {
345  raw = new (raw) HTofRaw;
346  } else{
347  raw=new (raw) HTofRawSim;
348  }
349 
350  if(raw){
351  raw->setSector((Char_t)fLoc[0]);
352  raw->setModule((Char_t)fLoc[1]);
353  raw->setCell((Char_t)fLoc[2]);
354 
355  } else {
356  if (debugFlag > 0)
357  Warning("addRawHit()", "Can't get slot sec=%i, column=%i, cell=%i",
358  fLoc[0], fLoc[1],fLoc[2]);
359  return -1;
360  }
361  }
362 
363  Char_t side = chan->getSide();
364 
365  if(side=='r') {
366  raw->setRightTime(t_leading);
367  raw->setRightCharge(t_trailing - t_leading);
368  } else if (side=='l') {
369  raw->setLeftTime(t_leading);
370  raw->setLeftCharge(t_trailing - t_leading);
371  }
372 
373 
374 
375  if (debugFlag > 1)
376  Warning("addRawHit",
377  "ADDING hit for sec:%d column:%d cell:%d tm0:%e tm1:%e",
378  fLoc[0], fLoc[1], fLoc[2], t_leading, t_trailing);
379  return 0;
380 }
virtual Bool_t addCategory(Cat_t aCat, HCategory *cat, Option_t opt[])=0
void setLeftCharge(Float_t aleftQ)
Definition: htofraw.h:77
void setLeftTime(Float_t aleftT)
Definition: htofraw.h:69
UInt_t getEventSeqNumber(void)
Definition: heventheader.h:132
Int_t getEmbeddingMode()
Definition: hades.h:98
UInt_t getId(void)
Definition: heventheader.h:134
void setModule(Char_t m)
Definition: htofraw.h:36
void getAddress(Int_t &s, Int_t &m, Int_t &c, Char_t &t)
HRichPadSignal & raw
HDataSource * getDataSource(void) const
Definition: hades.h:124
Definition: htofraw.h:7
Int_t getArrayOffset()
HRuntimeDb * getRuntimeDb(void)
Definition: hades.h:111
HEvent *& getCurrentEvent(void)
Definition: hades.cc:422
static Bool_t fHasPrintedTDC
virtual HEventHeader * getHeader(void) const
Definition: hevent.h:36
ClassImp(HDbColumn) HDbColumn
Definition: hdbcolumn.cc:18
void setRightCharge(Float_t arightQ)
Definition: htofraw.h:73
HTofTrb3Lookup * fLookup
HTofTrb3LookupBoard * getBoard(Int_t trbnetAddress)
HTofTrb3LookupChan * getChannel(Int_t c)
HSpectrometer * getSetup(void)
Definition: hades.h:112
HDetector * getDetector(const Char_t *name)
virtual HCategory * buildCategory(Cat_t)
Definition: hdetector.h:37
void setSector(Char_t s)
Definition: htofraw.h:35
void setCell(Char_t c)
Definition: htofraw.h:37
Hades * gHades
Definition: hades.cc:1213
HTofTrb3Unpacker(vector< UInt_t > &ids)
HParSet * getContainer(const Text_t *)
Definition: hruntimedb.cc:124
Int_t addRawHit(Double_t t_leading, Double_t t_trailing, HTofTrb3LookupChan *chan)
#define TOF_TIME_MAX
const Cat_t catTofRaw
Definition: tofdef.h:6
#define TOF_TIME_MIN
Bool_t isCalibration()
Definition: hades.cc:276
void setRightTime(Float_t arightT)
Definition: htofraw.h:65