StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StPxlRawHitMaker.cxx
1 
6 /***************************************************************************
7  *
8  * $Id: StPxlRawHitMaker.cxx,v 1.12 2017/08/28 17:05:16 dongx Exp $
9  *
10  * Author: Jan Rusnak, Qiu Hao, Jan 2013, according codes from Xiangming Sun
11  ***************************************************************************
12  *
13  * Description:
14  * Read pixel raw hits from daq format. One raw hit is one fired pixel.
15  * More information at
16  * https://www.star.bnl.gov/protected/heavy/qiuh/HFT/software/PXL_software.pdf
17  *
18  ***************************************************************************
19  *
20  * $Log: StPxlRawHitMaker.cxx,v $
21  * Revision 1.12 2017/08/28 17:05:16 dongx
22  * Append rawHits to StPxlRawHitCollection only if exists - for simu/embedding
23  *
24  * Revision 1.11 2016/03/03 07:36:09 qiuh
25  * fix bug on row number, should use last row information FOR THE SAME SENSOR
26  *
27  * Revision 1.10 2015/05/15 05:31:44 qiuh
28  * add c in wrong sector/ladder/sensor/row/column warning
29  *
30  * Revision 1.9 2014/05/29 22:55:28 qiuh
31  * print warnings for wrong rows / columns and deserialization errors only when debug > 2
32  *
33  * Revision 1.8 2014/05/08 15:10:49 smirnovd
34  * PXL DB dataset has been renamed to avoid conflict with StPxlDbMaker's name
35  *
36  * Revision 1.7 2014/04/05 05:20:08 qiuh
37  * add Jtag file version print-out and some more warnings for data format errors
38  *
39  * Revision 1.6 2014/04/01 15:29:24 qiuh
40  * add single hot pixel masking
41  *
42  * Revision 1.5 2014/01/28 19:29:44 qiuh
43  * *** empty log message ***
44  *
45  *
46  **************************************************************************/
47 
48 #include "StPxlRawHitMaker.h"
49 #include "StPxlRawHit.h"
50 #include "StPxlRawHitCollection.h"
51 #include "StMessMgr.h"
52 #include "StRtsTable.h"
53 #include "StPxlDbMaker/StPxlDb.h"
54 #include "tables/St_pxlControl_Table.h"
55 ClassImp(StPxlRawHitMaker)
56 
57 StPxlRawHitMaker::StPxlRawHitMaker(const Char_t *name) : StRTSBaseMaker("pxl", name)
58 {
59  mPxlRawHitCollection = 0;
60  mJtagFileVersion = 0;
61 }
62 //_______________________________________________
63 void StPxlRawHitMaker::Clear(const Option_t *)
64 {
66  delete mPxlRawHitCollection;
68  }
69  return StMaker::Clear();
70 }
71 //_______________________________________________
72 Int_t StPxlRawHitMaker::InitRun(Int_t runumber)
73 {
74  TObjectSet *pxlDbDataSet = (TObjectSet *)GetDataSet("pxl_db");
75  if (pxlDbDataSet) {
76  mPxlDb = (StPxlDb *)pxlDbDataSet->GetObject();
77  assert(mPxlDb);
78  }
79  else {
80  LOG_ERROR << "InitRun : no pxlDb" << endm;
81  return kStErr;
82  }
83 
84  const pxlControl_st *pxlControlTable = mPxlDb->pxlControl();
85  mHeaderLength = pxlControlTable[0].headerLength;
86  mHardwareIdPosition = pxlControlTable[0].hardwareIdPosition;
87  mHeaderToken = pxlControlTable[0].headerToken;
88  mSeparatorToken = pxlControlTable[0].separatorToken;
89  mEndToken = pxlControlTable[0].endToken;
90  mChipIdStartBit = pxlControlTable[0].chipIdStartBit;
91  mChipIdEndBit = pxlControlTable[0].chipIdEndBit;
92  mChipIdPow = pxlControlTable[0].chipIdPow;
93  mOverflowBit = pxlControlTable[0].overflowBit;
94  mRowOrColumnFlagBit = pxlControlTable[0].rowOrColumnFlagBit;
95  mCodingStartBit = pxlControlTable[0].codingStartBit;
96  mCodingEndBit = pxlControlTable[0].codingEndBit;
97  mDataStartBit = pxlControlTable[0].dataStartBit;
98  mDataEndBit = pxlControlTable[0].dataEndBit;
99  mSensorGoodStatusMin = pxlControlTable[0].sensorGoodStatusMin;
100  mSensorGoodStatusMax = pxlControlTable[0].sensorGoodStatusMax;
101  mRowColumnGoodStatus = pxlControlTable[0].rowColumnGoodStatus;
102  mDummyState = pxlControlTable[0].dummyState;
103 
104  return kStOk;
105 }
106 //_______________________________________________
108 {
109  LOG_INFO << "StPxlRawHitMaker::Make()" << endm;
110 
111  // prepare output data collection
112  TObjectSet* pxlRawHitDataSet = (TObjectSet*)GetDataSet("pxlRawHit");
113 
114  if (!pxlRawHitDataSet)
115  {
116  LOG_INFO << " pxlRawHitCollection does NOT exist! Create a new one! " << endm;
118  ToWhiteBoard("pxlRawHit", mPxlRawHitCollection);
119  } else
120  {
121  LOG_INFO << " pxlRawHitCollection exists! Append raw hits to this collection!" << endm;
122  mPxlRawHitCollection = (StPxlRawHitCollection*)pxlRawHitDataSet->GetObject();
123  LOG_INFO << " Before RTS unpacking. Number of PxlRawHits = " << mPxlRawHitCollection->numberOfRawHits() << endm;
124  }
125 
126  // input data loop (should be 10 loops for 10 sectors normally)
127  StRtsTable *rts_table = 0;
128  while ( (rts_table = GetNextDaqElement("pxl/raw")) ) {
129  mSectorData = (UInt_t *)rts_table->At(0);
130  mSectorDataLength = rts_table->GetNRows();
131 
132  if (Debug() > 1) {
133  LOG_INFO << "Found pxl sector raw data at " << hex << mSectorData << dec << " length in byte: " << mSectorDataLength << " in UInt_t: " << mSectorDataLength / sizeof(UInt_t) << endm;
134  }
135 
137 
138  decodeHitsData();
139  }
140 
141  LOG_INFO << " Finishing PxlRawHitMaker. Number of PxlRawHits = " << mPxlRawHitCollection->numberOfRawHits() << endm;
142 
143  return kStOk;
144 }
145 //_______________________________________________
147 {
148  LOG_INFO << "Jtag file version: "<<mJtagFileVersion<<endm;
149  return StMaker::Finish();
150 }
151 //_______________________________________________
153 {
154  int index = 0;
155  mSector = 0;
156  mHeaderData = 0;
157  mHitsData = 0;
158  mHitsDataLength = 0;
159  mTrailerData = 0;
160  mTrailerDataLength = 0;
161 
162  if (mSectorDataLength == 0 || !mSectorData) {
163  LOG_WARN << "no sector data" << endm;
164  return;
165  }
166 
167  // check header token and get pointer to header data block
168  if (mSectorData[0] != mHeaderToken) {
169  LOG_WARN << "no pxl sector header token" << endm;
170  return;
171  }
172  else {
173  if (Debug() > 1) {
174  LOG_INFO << "sector data header token correct: 0x" << hex << mSectorData[0] << dec << endm;
175  }
176  }
177 
178  mHeaderData = mSectorData + index;
179  index += mHeaderLength;
180 
181  mSector = mHeaderData[mHardwareIdPosition] & 0xf;
182  if (mSector > kNumberOfPxlSectors || mSector < 1) {
183  LOG_WARN << "wrong sector number: " << mSector << endm;
184  return;
185  }
186 
187  mJtagFileVersion = mHeaderData[mHardwareIdPosition] >> 16;
188 
189  for(int i=0; i<32; i++)
190  {
191  if(mHeaderData[8] >> i && Debug() > 2)
192  {
193  LOG_WARN << "sector "<<mSector<<" sensor "<<i+1<<" deserialization error!" << endm;
194  }
195  }
196 
197  for(int i=0; i<8; i++)
198  {
199  if(mHeaderData[9] >> i && Debug() > 2)
200  {
201  LOG_WARN << "sector "<<mSector<<" sensor "<<i+33<<" deserialization error!" << endm;
202  }
203  }
204 
205  if(mHeaderData[9] >> 8)
206  {
207  LOG_WARN << "sector "<<mSector<<" event memory 1 overflow!" << endm;
208  }
209 
210  if(mHeaderData[9] >> 9)
211  {
212  LOG_WARN << "sector "<<mSector<<" event memory 2 overflow!" << endm;
213  }
214 
215  for(int i=0; i<32; i++)
216  {
217  if(mHeaderData[10] >> i)
218  {
219  LOG_WARN << "sector "<<mSector<<" sensor "<<i+1<<" trailer or event length error!" << endm;
220  }
221  }
222 
223  for(int i=0; i<8; i++)
224  {
225  if(mHeaderData[11] >> i)
226  {
227  LOG_WARN << "sector "<<mSector<<" sensor "<<i+33<<" trailer or event length error!" << endm;
228  }
229  }
230 
231  // get hits data block length
232  mHitsDataLength = getHitsDataLength();
233  if (Debug() > 1) {
234  LOG_INFO << "sector: " << mSector << " HitsDataLength: " << mHitsDataLength << endm;
235  }
236  index ++;
237 
238  // get pointer to hits data block
239  mHitsData = mSectorData + index;
240 
241  index += mHitsDataLength;
242 
243  // check separater at the end of hits data block
244  if (mSectorData[index] == mSeparatorToken) {
245  if (Debug() > 1) {
246  LOG_INFO << "sector data separator token correct: 0x" << hex << mSectorData[index] << dec << endm;
247  }
248  }
249  else {
250  LOG_WARN << "sector data separator token wrong: 0x" << hex << mSectorData[index] << dec << endm;
251  mHitsData = 0;
252  mHitsDataLength = 0;
253  return;
254  }
255  index++;
256 
257  // check end token and get pointer to trailer data block
258  if (mSectorData[mSectorDataLength / sizeof(UInt_t) - 1] == mEndToken) {
259  if (Debug() > 1) {
260  LOG_INFO << "sector data end token corret: 0x" << hex << mSectorData[mSectorDataLength / sizeof(UInt_t) - 1] << dec << endm;
261  }
262  }
263  else {
264  LOG_WARN << "sector data end token wrong: 0x" << hex << mSectorData[mSectorDataLength / sizeof(UInt_t) - 1] << dec << endm;
265  return;
266  }
267 
268  mTrailerData = mSectorData + index;
269  mTrailerDataLength = mSectorDataLength / sizeof(UInt_t) - 1 - index;
270 
271 }
272 //_______________________________________________
274 {
275  UInt_t a = 0;
276  a = *(mHeaderData + mHeaderLength);
277  return (a >> 16) + (a & 0xffff);
278 }
279 //_______________________________________________
281 {
282  if (mHitsDataLength == 0 || !mHitsData) {
283  LOG_WARN << "no hits data" << endm;
284  return;
285  }
286 
287  mOverFlowCount = 0;
288  // decode hits data block word by word
289  for (Int_t i = 0; i < mHitsDataLength; i++) {
290  decodeWord(mHitsData[i]);
291  }
292  if (Debug() > 1) {
293  LOG_INFO << "sector: " << mSector << " overflow count: " << mOverFlowCount << endm;
294  }
295 }
296 //_______________________________________________
298 {
299  int val1 = val >> 16; // higher 16 bits
300  int val0 = val & (0xffff); // lower 16 bits
301 
302  // get ladder and sensor from chip id = (ladder-1)*10+sensor-1
303  int chip_id = mid(mChipIdStartBit, mChipIdEndBit, val0) + mid(mChipIdStartBit, mChipIdEndBit, val1) * mChipIdPow;
304  if (chip_id < 1 || chip_id > kNumberOfPxlLaddersPerSector * kNumberOfPxlSensorsPerLadder) {
305  LOG_WARN << "wrong chip id: " << chip_id << endm;
306  return;
307  }
308  mLadder = (chip_id - 1) / 10 + 1;
309  mSensor = (chip_id - 1) % 10 + 1;
310 
311  int row_flag0 = elementGetBit(val0, mRowOrColumnFlagBit); // determine whether the lower 16 bits is for row or for column
312  int row_flag1 = elementGetBit(val1, mRowOrColumnFlagBit); // determine whether the higher 16 bits is for row or for column
313 
314  // decode the lower 16 bits
315  if (row_flag0 == 1) {
316  // decode for row number
317  decodeState0(val0);
318  }
319  else {
320  // check sensor status, if good, decode for column number and fill raw hits
322  (mPxlDb->sensorStatus(mSector, mLadder, mSensor) <= mSensorGoodStatusMax ) )
323  decodeStateN(val0);
324  }
325 
326  // decode the higher 16 bits
327  if (row_flag1 == 1) {
328  // decode for row number
329  decodeState0(val1);
330  }
331  else {
332  // check sensor status, if good, decode for column number and fill raw hits
334  (mPxlDb->sensorStatus(mSector, mLadder, mSensor) <= mSensorGoodStatusMax ) )
335  decodeStateN(val1);
336  }
337 }
338 //_______________________________________________
339 UInt_t StPxlRawHitMaker::mid(Int_t start, Int_t end, UInt_t input)
340 {
341  // decode the bits between "start" and "end" in the "input" word
342  UInt_t buf;
343  buf = input << (32 - end);
344  buf = buf >> (32 - end);
345  return buf >> start;
346 }
347 //_______________________________________________
348 Int_t StPxlRawHitMaker::elementGetBit(UInt_t data, Int_t position)
349 {
350  // get the bit at "position" of "data" word
351  UInt_t sd = data >> position;
352  return sd % 2;
353 }
354 //_______________________________________________
356 {
357  // get row number
358  mRow[(mLadder-1)*kNumberOfPxlSensorsPerLadder+mSensor-1] = mid(mDataStartBit, mDataEndBit, val);
359  // check overflow
360  if (elementGetBit(val, mOverflowBit)) {
361  if (Debug() > 2) LOG_WARN << "pxl overflow at sector: " << mSector << " ladder: " << mLadder << " sensor: " << mSensor << " row: " << mRow[(mLadder-1)*kNumberOfPxlSensorsPerLadder+mSensor-1] << endm;
362  mOverFlowCount++;
363  }
364  // check row number range
365  if ((mRow[(mLadder-1)*kNumberOfPxlSensorsPerLadder+mSensor-1] >= kNumberOfPxlRowsOnSensor || mRow[(mLadder-1)*kNumberOfPxlSensorsPerLadder+mSensor-1] < 0) && Debug()>2) {
366  LOG_WARN << "wrong row: " << mRow[(mLadder-1)*kNumberOfPxlSensorsPerLadder+mSensor-1] << " at sector: " << mSector << " ladder: " << mLadder << " sensor: " << mSensor << endm;
367  }
368  return 0;
369 }
370 //_______________________________________________
372 {
373  int coding = mid(mCodingStartBit, mCodingEndBit, val); // number of sequential fired columns, 0-3 for 1-4 sequential fired columns
374  mColumn = mid(mDataStartBit, mDataEndBit, val); // starting column number
375  // loop sequential fired columns and fill raw hits
376  for (int c = 0; c < coding + 1; c++) {
377  // check sector, ladder, sensor row and column range
378  if (mSector > 0 && mSector <= kNumberOfPxlSectors && mLadder > 0 && mLadder <= kNumberOfPxlLaddersPerSector && mSensor > 0 && mSensor <= kNumberOfPxlSensorsPerLadder && mRow[(mLadder-1)*kNumberOfPxlSensorsPerLadder+mSensor-1] >= 0 && mRow[(mLadder-1)*kNumberOfPxlSensorsPerLadder+mSensor-1] < kNumberOfPxlRowsOnSensor && mColumn + c < kNumberOfPxlColumnsOnSensor && mColumn + c >= 0) {
379  // check raw and column status and hot pixels
380  if (mPxlDb->rowStatus(mSector, mLadder, mSensor, mRow[(mLadder-1)*kNumberOfPxlSensorsPerLadder+mSensor-1]) == mRowColumnGoodStatus
382  && (!mPxlDb->pixelHot(mSector, mLadder, mSensor, mRow[(mLadder-1)*kNumberOfPxlSensorsPerLadder+mSensor-1], mColumn + c))) {
383  // fill raw hit
384  StPxlRawHit pxlRawHit;
385  pxlRawHit.setSector(mSector);
386  pxlRawHit.setLadder(mLadder);
387  pxlRawHit.setSensor(mSensor);
388  pxlRawHit.setRow(mRow[(mLadder-1)*kNumberOfPxlSensorsPerLadder+mSensor-1]);
389  pxlRawHit.setColumn(mColumn + c);
390  pxlRawHit.setIdTruth(0);
391  if (Debug() > 4) pxlRawHit.print();
392 
393  mPxlRawHitCollection->addRawHit(pxlRawHit);
394  }
395  }
396  else if (mColumn != mDummyState && Debug() > 2) { // 1023: dummy state when the last state from a sensor ends on the lower 16 bits of a 32-bit word
397  LOG_WARN << "wrong sector/ladder/sensor/row/column: " << mSector << "/" << mLadder << "/" << mSensor << "/" << mRow[(mLadder-1)*kNumberOfPxlSensorsPerLadder+mSensor-1] << "/" << mColumn <<"+"<<c<< endm;
398  }
399  }
400  return 0;
401 }
Int_t decodeStateN(Int_t val)
decoding mainly to get fired column numbers in the current row
Int_t elementGetBit(UInt_t data, Int_t position)
get the bit at &quot;position&quot; of &quot;data&quot; word
Short_t mOverflowBit
bit for row overflow (more fired columns than can be read)
StRtsTable * GetNextDaqElement(const char *elementPath)
Query the STAR production chain for the DAQ data.
Int_t mLadder
ladder 1-4
Short_t mDummyState
dummy state when the last state from a sensor ends on the lower 16 bits of a 32-bit word ...
Class StRTSBaseMaker - is an abstract StMaker to define the interface to access the DAQ data from the...
Int_t mSensor
sensor 1-10
Int_t mColumn
column 0-959
void decodeSectorData()
decode data of a sector
Short_t mDataEndBit
end bit for &quot;data&quot;, which can be row or column number, depending on rowOrColumnFlag ...
void setIdTruth(Int_t idTruth)
set idTruth
Definition: StPxlRawHit.cxx:83
Short_t mChipIdStartBit
start bit for chip id
Short_t mRowColumnGoodStatus
row and column good status
void setSensor(Int_t sensor)
set sensor
Definition: StPxlRawHit.cxx:68
Int_t mRow[40]
row 0-927, data from 40 sensors on a sector is mixed, need to keep 40 current row numbers ...
const pxlControl_st * pxlControl()
Definition: StPxlDb.h:130
virtual void Clear(Option_t *option="")
User defined functions.
Definition: StMaker.cxx:634
void setLadder(Int_t ladder)
set ladder
Definition: StPxlRawHit.cxx:63
Short_t mCodingEndBit
end bit for &quot;coding&quot;, which means how many sequential fired columns
UInt_t mid(Int_t start, Int_t end, UInt_t input)
decode the bits between &quot;start&quot; and &quot;end&quot; in the &quot;input&quot; word
void setColumn(Int_t column)
set column
Definition: StPxlRawHit.cxx:78
UInt_t * mSectorData
pointers and lengths for data blocks
Int_t mJtagFileVersion
Jtag configure file version.
Int_t pixelHot(Int_t sector, Int_t ladder, Int_t sensor, Int_t row, Int_t column) const
1: hot; 0: good
Definition: StPxlDb.cxx:181
Short_t mHardwareIdPosition
position for hardware id, including sector number
virtual Long_t GetNRows() const
Returns the number of the used rows for the wrapped table.
Definition: TTable.cxx:1388
Short_t mChipIdEndBit
end bit for chip id
Short_t mChipIdPow
chipId = mChipIdPow*chipIdFromHigher16Bits+chipIdFromLower16Bits
void setSector(Int_t sector)
set sector
Definition: StPxlRawHit.cxx:58
Short_t mCodingStartBit
start bit for &quot;coding&quot;, which means how many sequential fired columns
void addRawHit(const StPxlRawHit &rawHit)
add a raw hit to the collection
Int_t mSector
current sector, ladder, sensor, row, column that is being worked on
Short_t mHeaderLength
decoding control paramters according to firmware
Short_t mDataStartBit
start bit for &quot;data&quot;, which can be row or column number, depending on rowOrColumnFlag ...
Int_t sensorStatus(Int_t sector, Int_t ladder, Int_t sensor) const
status for sensor/row/column
Definition: StPxlDb.cxx:163
Int_t getHitsDataLength()
get length of the hits data block
Int_t rowStatus(Int_t sector, Int_t ladder, Int_t sensor, Int_t row) const
1: good status
Definition: StPxlDb.cxx:169
Int_t mOverFlowCount
count for overflow rows
Int_t decodeState0(Int_t val)
decoding mainly to get the row number for the following fired columns
void print()
print all information
Definition: StPxlRawHit.cxx:88
Short_t mRowOrColumnFlagBit
bit for rowOrColumnFlag, which determine whether &quot;data&quot; is row or column number
void decodeHitsData()
decode the hits data block of a sector
Int_t columnStatus(Int_t sector, Int_t ladder, Int_t sensor, Int_t column) const
1: good status
Definition: StPxlDb.cxx:175
virtual Int_t Finish()
Definition: StMaker.cxx:776
const void * At(Int_t i) const
Returns a pointer to the i-th row of the table.
Definition: TTable.cxx:303
Short_t mSensorGoodStatusMin
sensor good status range
StPxlDb * mPxlDb
pxl db structure containing geometry, db information and so on
virtual TObject * GetObject() const
The depricated method (left here for the sake of the backward compatibility)
Definition: TObjectSet.h:56
void setRow(Int_t row)
set row
Definition: StPxlRawHit.cxx:73
Definition: Stypes.h:44
Definition: Stypes.h:41
StPxlRawHitCollection * mPxlRawHitCollection
generated raw hit collection
Int_t numberOfRawHits(Int_t sector, Int_t ladder, Int_t sensor)
number of raw hits in a sensor
void decodeWord(UInt_t val)
decode a word (32 bits)