HYDRA_development_version
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
hrichunpacker.cc
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // $Id: $
4 //
5 //*-- Author : Martin Jurkovic <martin.jurkovic@ph.tum.de>
6 //*-- Revised : Martin Jurkovic <martin.jurkovic@ph.tum.de> 2010
7 //
8 //_HADES_CLASS_DESCRIPTION
9 //////////////////////////////////////////////////////////////////////////////
10 //
11 // HRichUnpacker
12 //
13 //
14 //////////////////////////////////////////////////////////////////////////////
15 
16 
17 #include "TRandom.h"
18 
19 #include "hades.h"
20 #include "hcategory.h"
21 #include "hdatasource.h"
22 #include "hdetector.h"
23 #include "hevent.h"
24 #include "heventheader.h"
25 #include "hldsource.h"
26 #include "hldsubevt.h"
27 #include "hlocation.h"
28 #include "hrichcal.h"
29 #include "hrichcalsim.h"
30 #include "hrichdetector.h"
31 #include "hrichmappingpar.h"
32 #include "hrichunpacker.h"
33 #include "hruntimedb.h"
34 #include "hspectrometer.h"
35 #include "richdef.h"
36 
37 #include <iostream>
38 
40 
41 const UInt_t HRichUnpacker::kHubDebugId = 0x5555;
42 const UInt_t HRichUnpacker::kADCZero = 0x2000;
43 
45  Int_t strtEvt)
46  : HldUnpack()
47 {
48 
49  fRichId = richId;
50  fStartEvt = strtEvt;
51  fSecMisMatchCntr = 0;
52  fEventNr = -1;
53 
54  fpCalCat = NULL;
55  fpMapPar = NULL;
56 
57 }
58 
59 Bool_t HRichUnpacker::init(void)
60 {
61 // Initialize input parameter containers and build output categories
62 
63  HRichDetector* pRichDet = static_cast<HRichDetector*>(gHades->getSetup()->getDetector("Rich"));
64 
65  if (NULL == trbNetUnpacker) {
66  if (gHades->getDataSource()) {
67  HDataSource* source = gHades->getDataSource();
68  if (source->InheritsFrom("HldSource")) {
69  trbNetUnpacker = ((HldSource *)gHades->getDataSource())->getTrbNetUnpacker();
70  } else {
71  Warning("init", "DataSource not inherited from HldSource! trbNetUnpacker == 0 ");
72  }
73  } else {
74  Warning("init", "Could not retrieve Datasource! trbNetUnpacker == 0 ");
75  }
76  }
77 
78 
79 // Output categories
81  if (NULL == fpCalCat) {
82  if (0 == gHades->getEmbeddingMode()) {
83  fpCalCat = pRichDet->buildCategory(catRichCal);
84  } else {
85  fpCalCat = pRichDet->buildMatrixCat("HRichCalSim", 1);
86  }
87  if (NULL == fpCalCat) {
88  Error("init", "Can not build HRichCal category.");
89  return kFALSE;
90  } else {
92  }
93  }
94 
95 // Input parameter containers
96  HRuntimeDb* rtdb = gHades->getRuntimeDb();
97  fpMapPar = static_cast<HRichMappingPar*>(rtdb->getContainer("RichMappingParameters"));
98 
99  return kTRUE;
100 }
101 
103 {
104 
105  UInt_t sourceSector = 10;
106  Int_t col = 0;
107  Int_t row = 0;
108  DHeader dHeader;
109  HLocation loc;
110  loc.set(3, 0, 0, 0);
112 
113  if (NULL == pSubEvt) {
115 #if DEBUG_LEVEL > 0
116  Warning("execute", "EvtId: 0x%x, Unpacker 0x%x ==> no data", gHades->getCurrentEvent()->getHeader()->getId(), fRichId);
117 #endif
118  }
119  return 1;
120  }
121 
122  if (fEventNr >= fStartEvt) {
123 
124  // decode the header first
125  for (UInt_t i = 0; i < pSubEvt->getDataLen(); i++) {
126  // Check for pedding word first (skip)
127  if (0xaaaaaaaa == pSubEvt->getData()[i]) {
128  continue;
129  }
130 
131  // decode subsub_event and its header
132  dHeader.getEvent(pSubEvt->getData()[i]);
133  if (0 == dHeader.getSize()) {
134  // no data im subsubevent
135  continue;
136  }
137 
138  // check for debug info data type
139  if (kHubDebugId == dHeader.getSource()) {
140 #if DEBUG_LEVEL > 2
141  Info("execute", "Only debug info will follow, skiping.");
142 #endif
143  decodeTrbNet((pSubEvt->getData() + i), fRichId);
144  i += (dHeader.getSize());
145  continue;
146  }
147 
148  // After decoding and checking the header jump to the next data word
149  i++;
150 
151  // Each data source (in this case ADC module) is uniquely assigned to a specific sector
152  if ((dHeader.getSource() & 0xf) > 4 ||
153  (dHeader.getSource() & 0xff00) != 0x3000) {
154  Error("execute", "Wrong ADSM number: 0x%x", dHeader.getSource());
155  }
156  sourceSector = (dHeader.getSource() >> 4) & 0xf;
157 
158  // Read the sub-sub event
159  for (UInt_t j = 0; j < dHeader.getSize(); j++, i++) {
160  // Check for debug word (skip)
161  if (0 != ((pSubEvt->getData()[i] >> 31) & 0x01)) {
162 #if DEBUG_LEVEL > 2
163  Info("execute", "debug info %x", pSubEvt->getData()[i]);
164 #endif
165  continue;
166  }
167 
168  // Fill the data structure
169  fDataWord.charge = (pSubEvt->getData()[i] >> RICH_CHARGE_OFFSET) & RICH_CHARGE_MASK;
170  fDataWord.channel = (pSubEvt->getData()[i] >> RICH_CHANNEL_OFFSET) & RICH_CHANNEL_MASK;
171  fDataWord.apv = (pSubEvt->getData()[i] >> RICH_APV_OFFSET) & RICH_APV_MASK;
172  fDataWord.adc = (pSubEvt->getData()[i] >> RICH_ADC_OFFSET) & RICH_ADC_MASK ;
173  fDataWord.sector = (pSubEvt->getData()[i] >> RICH_SECTOR_OFFSET) & RICH_SECTOR_MASK;
174 
175  if (1 == fDataWord.channel % 2) {
176  continue;
177  }
178 
179  // Check if the HW address is in reasonable range
181  (fDataWord.adc >= RICH_MAX_ADCS) ||
182  (fDataWord.apv >= RICH_MAX_APVS) ||
184  Error("execute", "Evt %i SubEvtId %x Source %x: Wrong address (sec,adc,apv,ch) = (%i,%i,%i,%i)",
186  continue;
187  }
188 
189  // Check sector consistency
190  if (fDataWord.sector != sourceSector) {
192  Error("execute", "Evt %i SubEvtId %x Source %x: Unpacked sector %i differs from assigned sector %i (0x%x)",
193  fEventNr, fRichId, dHeader.getSource(), fDataWord.sector, sourceSector, pSubEvt->getData()[i]);
194  continue;
195  }
196 
197  // Check if the apv channel is connected to a pad and get SW coordinates (row,col).
198  if (kFALSE == fpMapPar->getSWAddress(getAddress(fDataWord), row, col)) {
199 #if DEBUG_LEVEL > 4
200  Error("execute", "Evt %i SubEvtId %x Source %x: addr: %x: APV channel (sec,adc,apv,ch) = (%i,%i,%i,%i) is unconnected.",
202  cerr << "printDataWord says:" << endl;
204  cerr << "printMapping says:" << endl;
206 #endif
207  continue;
208  }
209 
210  loc.setOffset(col);
211  loc.setIndex(1, row);
212  loc.setIndex(0, fDataWord.sector);
213 
214  // APV data are already calibrated. To the ADC value a random nb
215  // [0;1] is added to account for the cut-off in the ADC
216  Float_t charge = static_cast<Float_t>(fDataWord.charge - kADCZero) + gRandom->Rndm();
217  HRichCal* pCell = NULL;
218  if (charge > 0.0) {
219  pCell = static_cast<HRichCal*>(fpCalCat->getSlot(loc));
220  if (NULL != pCell) {
221  if (0 == gHades->getEmbeddingMode()) {
222  pCell = new(pCell) HRichCal(loc[0], loc[1], loc[2]);
223  } else {
224  pCell = new(pCell) HRichCalSim(loc[0], loc[1], loc[2]);
225  }
226  pCell->setCharge(charge);
227  pCell->setEventNr(fEventNr);
228  } else {
229  Error("Execute", "getSlot(loc) returned NULL! (sec,row,col) = (%i,%i,%i), addr: 0x%x (%i,%i)", loc[0], loc[1], loc[2], getAddress(fDataWord), row, col);
230  }
231  }
232  } // end of unpacking subsub event
233 
234  // rewind by one data word
235  i--;
236 
237  } // end of unpacking sub event
238  } // end of start event condition
239  return 1;
240 }
241 
243 {
244 #if DEBUG_LEVEL > 1
245  cerr << "SubEvtId:" << fRichId << " RICH: Number of evts processed: " << fEventNr << endl;
246  cerr << "SubEvtId:" << fRichId << " RICH: Sector mismatch errors: " << fSecMisMatchCntr << endl;
247 #endif
248  return kTRUE;
249 }
250 
252 {
253  cout << "*****************************************************************************" << endl;
254  cout << "Event Nr: " << fEventNr << endl;
255  cout << " SEC: " << addr.sector
256  << " ADC: " << addr.adc
257  << " APV: " << addr.apv
258  << " CH: " << addr.channel
259  << " CHRG: " << addr.charge << endl;
260 }
261 
263 {
264  Int_t row = -1;
265  Int_t col = -1;
266 
267  cout << "Event Nr: " << fEventNr << endl;
268  cout << "isValidAddress: " << fpMapPar->getSWAddress(getAddress(addr), row, col) << endl;
269  cout << "Col: " << col << endl;
270  cout << "Row: " << row << endl;
271  cout << "*****************************************************************************" << endl;
272 }
273 
274 
276 {
277  reset();
278 }
279 
281 {
282  fSize = 0;
283  fSource = 0;
284 }
285 
286 void DHeader::getEvent(UInt_t word)
287 {
288  fSize = (word >> 16) & 0xffff;
289  fSource = word & 0xffff;
290 }
291 
293 {
294  Info("dump", "%c size: 0x%04x source: 0x%04x\n", '%', fSize, fSource);
295 }
virtual Bool_t addCategory(Cat_t aCat, HCategory *cat, Option_t opt[])=0
#define RICH_CHARGE_OFFSET
Definition: richdef.h:28
#define RICH_MAX_SECTORS
Definition: richdef.h:4
#define RICH_MAX_CHANNELS
Definition: richdef.h:10
UInt_t getEventSeqNumber(void)
Definition: heventheader.h:132
Int_t getEmbeddingMode()
Definition: hades.h:98
HCategory * fpCalCat
structure for channel address
Definition: hrichunpacker.h:46
UInt_t getId(void)
Definition: heventheader.h:134
#define RICH_APV_MASK
Definition: richdef.h:20
UInt_t fSecMisMatchCntr
start unpacking with event #
Definition: hrichunpacker.h:36
static const UInt_t kHubDebugId
Definition: hrichunpacker.h:30
UInt_t getSize() const
#define RICH_SECTOR_OFFSET
Definition: richdef.h:24
HRichMappingPar * fpMapPar
Definition: hrichunpacker.h:47
HDataSource * getDataSource(void) const
Definition: hades.h:124
UInt_t getSource() const
HRuntimeDb * getRuntimeDb(void)
Definition: hades.h:111
HEvent *& getCurrentEvent(void)
Definition: hades.cc:422
static const UInt_t kADCZero
Identification of debug "subsubevent".
Definition: hrichunpacker.h:31
Bool_t finalize()
virtual HEventHeader * getHeader(void) const
Definition: hevent.h:36
ClassImp(HDbColumn) HDbColumn
Definition: hdbcolumn.cc:18
Int_t execute(void)
void getEvent(UInt_t word)
void reset()
UInt_t fStartEvt
current event #
Definition: hrichunpacker.h:35
Int_t getAddress(const DataWord &addr) const
Definition: hrichunpacker.h:73
#define RICH_CHANNEL_MASK
Definition: richdef.h:21
HSpectrometer * getSetup(void)
Definition: hades.h:112
HDetector * getDetector(const Char_t *name)
HCategory * buildMatrixCat(const Text_t *classname, const Float_t fillRate)
UInt_t fEventNr
current event #
Definition: hrichunpacker.h:34
#define RICH_CHARGE_MASK
Definition: richdef.h:22
Bool_t getSWAddress(Int_t address, Int_t &row, Int_t &col)
#define RICH_APV_OFFSET
Definition: richdef.h:26
HCategory * buildCategory(Cat_t cat)
Hades * gHades
Definition: hades.cc:1213
void setEventNr(Int_t e)
Definition: hrichcal.h:175
#define RICH_MAX_APVS
Definition: richdef.h:9
UInt_t fSource
Definition: hrichunpacker.h:89
void printMapping(const DataWord &addr)
HParSet * getContainer(const Text_t *)
Definition: hruntimedb.cc:124
#define RICH_ADC_MASK
Definition: richdef.h:19
void printDataWord(const DataWord &addr)
virtual HCategory * getCategory(Cat_t aCat)=0
void dump()
struct HRichUnpacker::DataWord fDataWord
UInt_t fSize
Definition: hrichunpacker.h:88
Bool_t init(void)
#define RICH_MAX_ADCS
Definition: richdef.h:8
#define RICH_SECTOR_MASK
Definition: richdef.h:18
#define RICH_CHANNEL_OFFSET
Definition: richdef.h:27
const Cat_t catRichCal
Definition: richdef.h:40
#define RICH_ADC_OFFSET
Definition: richdef.h:25
void setCharge(Float_t q)
Definition: hrichcal.h:139
UInt_t fRichId
ADC module ZERO offset.
Definition: hrichunpacker.h:33