1 /**************************************************************************
2 * This file is property of and copyright by the ALICE HLT Project *
3 * All rights reserved. *
6 * Indranil Das <indra.das@saha.ac.in> *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
19 /**********************************************************************
20 Created on : 16/05/2007
21 Purpose : This class is supposed to read the tracker DDL files and
22 give the output AliMUONCoreTriggerRecord
23 Author : Indranil Das, HEP Division, SINP
24 Email : indra.das@saha.ac.in | indra.ehep@gmail.com
25 **********************************************************************/
29 // The trigger reconstructor class is designed to deal the rawdata inputfiles
30 // to findout the the reconstructed hits at the trigger DDL. The output is send
31 // to the output block for further processing.
33 // Author : Indranil Das ( indra.das@saha.ac.in || indra.ehep@gmail.com )
37 #include "AliHLTMUONTriggerReconstructor.h"
38 #include "AliHLTMUONUtils.h"
39 #include "AliHLTMUONConstants.h"
40 #include "AliHLTMUONCalculations.h"
44 const int AliHLTMUONTriggerReconstructor::fgkDetectorId = 0xB00;
45 const int AliHLTMUONTriggerReconstructor::fgkDDLOffSet = 20 ;
46 const int AliHLTMUONTriggerReconstructor::fgkNofDDL = 2 ;
48 const int AliHLTMUONTriggerReconstructor::fgkDDLHeaderSize = 8;
49 const int AliHLTMUONTriggerReconstructor::fgkEvenLutSize = 2602351 + 1;
50 const int AliHLTMUONTriggerReconstructor::fgkOddLutSize = 2528735 + 1;
52 const int AliHLTMUONTriggerReconstructor::fgkLutLine = 10496;
54 const int AliHLTMUONTriggerReconstructor::fgkMinIdUnique[2] = {819616, 862288};
55 const int AliHLTMUONTriggerReconstructor::fgkMaxIdUnique[2] = {3421966, 3391022};
57 const float AliHLTMUONTriggerReconstructor::fgkHalfPadSizeXB[3] = {8.5, 17.0, 25.5};
58 const float AliHLTMUONTriggerReconstructor::fgkHalfPadSizeYNB[2] = {25.5, 34.0};
60 const int AliHLTMUONTriggerReconstructor::fgkDetElem = 9*4 ; // 9 detele per half chamber
63 AliHLTMUONTriggerReconstructor::AliHLTMUONTriggerReconstructor() :
64 fLookUpTableData(NULL),
65 fMaxRecPointsCount(0),
74 AliHLTMUONTriggerReconstructor::~AliHLTMUONTriggerReconstructor()
77 if (fLookUpTableData != NULL)
78 delete [] fLookUpTableData;
81 bool AliHLTMUONTriggerReconstructor::SetRegToLocCardMap(RegToLoc* regToLoc)
83 if(!memcpy(fRegToLocCard,regToLoc,128*sizeof(RegToLoc)))
86 for(int i=0;i<128;i++){
87 HLTDebug("DDL : %d, reg : %d, loc : %d",fRegToLocCard[i].fTrigDDL,
88 fRegToLocCard[i].fRegId,fRegToLocCard[i].fLocId);
94 bool AliHLTMUONTriggerReconstructor::LoadLookUpTable(AliHLTMUONHitReconstructor::DHLTLut* lookUpTableData, int lookUpTableId)
96 if(lookUpTableId<fgkDDLOffSet || lookUpTableId>= fgkDDLOffSet + fgkNofDDL){
97 HLTError("DDL number is out of range (must be %d<=iDDL<%d)",fgkDDLOffSet,fgkDDLOffSet+fgkNofDDL);
101 fDDLId = lookUpTableId;
103 int lutSize = ((lookUpTableId%2)==0) ? fgkEvenLutSize : fgkOddLutSize ;
104 int nofLutLine = fgkLutLine ;
105 fIdOffSet = fgkMinIdUnique[lookUpTableId%2];
109 fLookUpTableData = new AliHLTMUONHitReconstructor::DHLTLut[lutSize];
111 memset(fLookUpTableData,-1,lutSize*sizeof(AliHLTMUONHitReconstructor::DHLTLut));
113 for(int i=0; i<nofLutLine; i++){
115 detUniqueId = lookUpTableData[i].fIdManuChannel - fIdOffSet + 1;
116 fLookUpTableData[detUniqueId].fIdManuChannel = lookUpTableData[i].fIdManuChannel - fIdOffSet;
117 fLookUpTableData[detUniqueId].fIX = lookUpTableData[i].fIX ;
118 fLookUpTableData[detUniqueId].fIY = lookUpTableData[i].fIY ;
119 fLookUpTableData[detUniqueId].fRealX = lookUpTableData[i].fRealX ;
120 fLookUpTableData[detUniqueId].fRealY = lookUpTableData[i].fRealY ;
121 fLookUpTableData[detUniqueId].fRealZ = lookUpTableData[i].fRealZ ;
122 fLookUpTableData[detUniqueId].fPcbZone = lookUpTableData[i].fPcbZone ;
123 fLookUpTableData[detUniqueId].fPlane = lookUpTableData[i].fPlane ;
129 bool AliHLTMUONTriggerReconstructor::Run(
130 const AliHLTUInt32_t* rawData,
131 // TODO: if we are not checking rawDataSize then it means we are
132 // not parsing the raw data safely or checking for corruption carefully.
133 // This must be fixed at some point.
134 AliHLTUInt32_t /*rawDataSize*/,
135 AliHLTMUONTriggerRecordStruct* trigRecord,
136 AliHLTUInt32_t& nofTrigRec,
137 bool suppressPartialTrigs
140 fMaxRecPointsCount = nofTrigRec;
142 // nofTrigRec now becomes the output of how many trigger records were found.
150 int reg_output,reg_phys_trig_occur ;
151 int iLocIndex,loc,locDec,triggY,sign,loDev,triggX;
152 int iRegLoc = 0, locId = 0;
153 short pattern[2][4]; // 2 stands for two cathode planes and 4 stands for 4 chambers
155 Int_t offset,ithSwitch,secondLocation,idetElemId;
157 int shiftIndex = 10 - 6 - 1; // the one comes due to indexing from zero
160 int globalcard_data_occurance = (rawData[index]>>10)&0x1; //Set to 1 if global info present in DDL else set to 0
161 int version = (rawData[index]>>12)&0xFF; // software version
162 int serial_number = (rawData[index]>>20)&0xF; // serial number set to 0xF
164 int phys_trig_occur = (rawData[index]>>30)&0x1; // 1 for physics trigger, 0 for software trigger
166 HLTDebug("globalcard_data_occurance %d, version %d, serial_number %d, phys_trig_occur %d",
167 globalcard_data_occurance,version,serial_number,phys_trig_occur
170 if(!phys_trig_occur) // for software trigger
171 index += 8 ;// corresponding to scalar words
173 index += 1 ; // To skip the separator 0xDEADFACE
175 index += 4 ; // corresponding to global input
177 index += 1 ; // reaches to global output
179 if((fDDLId - AliHLTMUONTriggerReconstructor::fgkDDLOffSet) == 0){ //if globalData is present in DDL 0 (presummed may be changed)
181 int singleLpt = rawData[index] & 0x1;
182 int singleHpt = (rawData[index] >> 1) & 0x1;
184 int pairUnlikeLpt = (rawData[index] >> 4) & 0x1;
185 int pairUnlikeHpt = (rawData[index] >> 5) & 0x1;
187 int pairLikeLpt = (rawData[index] >> 2) & 0x1;
188 int pairLikeHpt = (rawData[index] >> 3) & 0x1;
190 HLTDebug("singleLpt : %x, singleHpt : %x, pairUnlikeLpt : %x, pairUnlikeHpt : %x, pairLikeLpt : %x, pairLikeHpt : %x",
191 singleLpt,singleHpt,pairUnlikeLpt,pairUnlikeHpt,pairLikeLpt,pairLikeHpt
196 index += 10; // corresponds to scalar words
198 index += 1; // separator 0xDEADBEEF
200 for (int iReg = 0; iReg < 8; iReg++) {
201 index += 1; // DARC Status Word
202 index += 1; // Regeional Word
203 reg_output = rawData[index] & 0xFF;
204 reg_phys_trig_occur = ( rawData[index] >> 31) & 0x1;
206 index += 2; // 2 words for regional input
208 index += 1; // L0 counter
210 if(!reg_phys_trig_occur)
213 index += 1; // end of Regeonal header 0xBEEFFACE
215 for(int iLoc = 0; iLoc < 16 ; iLoc++){
219 loc = (rawData[index+5] >> 19) & 0xF ;
221 locDec = (rawData[index+5] >> 15) & 0xF;
222 triggY = (rawData[index+5] >> 14) & 0x1;
223 sign = (rawData[index+5] >> 9) & 0x1;
224 loDev = (rawData[index+5] >> 5) & 0xF ;
225 triggX = (loDev >> 4 & 0x1 ) && !(loDev & 0xF);
227 if( locDec != 0x9 ){ // check for Dec
229 iRegLoc = iReg*16 + iLoc;
230 locId = fRegToLocCard[iRegLoc].fLocId;
232 if(locId<=234){ // to avoid the copy locCards
235 pattern[0][0] = rawData[index] & 0xFFFF; // x-strip pattern for chamber 0
236 pattern[0][1] = (rawData[index] >> 16) & 0xFFFF; // x-strip pattern for chamber 1
238 pattern[0][2] = rawData[index] & 0xFFFF;
239 pattern[0][3] = (rawData[index] >> 16) & 0xFFFF;
242 pattern[1][0] = rawData[index] & 0xFFFF; // y-strip pattern for chamber 0
243 pattern[1][1] = (rawData[index] >> 16) & 0xFFFF; // y-strip pattern for chamber 0
245 pattern[1][2] = rawData[index] & 0xFFFF;
246 pattern[1][3] = (rawData[index] >> 16) & 0xFFFF;
248 if (pattern[0][0] || pattern[0][1] || pattern[0][2] || pattern[0][3]
249 || pattern[1][0] || pattern[1][1] || pattern[1][2] || pattern[1][3]
252 if (nofTrigRec == fMaxRecPointsCount) {
253 HLTError("Output buffer is overflowed maximum assiged arraysize : %d, present array index : %d",
254 fMaxRecPointsCount, nofTrigRec
259 HLTDebug("iReg: %d, iLoc :%d, locId : %d,X : %x, %x, %x, %x ...Y : %x, %x, %x, %x",
260 iReg,iLoc,locId,pattern[0][0],pattern[0][1],pattern[0][2],pattern[0][3],
261 pattern[1][0],pattern[1][1],pattern[1][2],pattern[1][3]
264 // hitset indicates which hits on chambers 7 to 10 have been found and filled.
265 bool hitset[4] = {false, false, false, false};
267 for(int iChamber = 0; iChamber < 4 ; iChamber++){ //4 chambers per DDL
268 for(int iPlane = 0; iPlane < 2 ; iPlane++){// 2 cathode plane
269 if(pattern[iPlane][iChamber]){
270 detElemId = fRegToLocCard[iRegLoc].fDetElemId[iChamber];
272 HLTDebug("\tdetElemId : %d\n",detElemId);
274 for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy) {
275 if ((pattern[iPlane][iChamber] >> ibitxy) & 0x1) {
277 // not quite sure about this
279 ithSwitch = (fRegToLocCard[iRegLoc].fSwitch >> shiftIndex) & 0x1;
280 if (iPlane && ithSwitch) offset = -8;
282 secondLocation = ibitxy + offset;
284 idetElemId = detElemId%1000;
289 secondLocation &= 0xF;
292 lutAddress = (lutAddress|idetElemId)<<1;
293 lutAddress = (lutAddress|iPlane)<<8;
294 lutAddress = (lutAddress|locId)<<4;
295 lutAddress |= secondLocation;
297 lutAddress -= fIdOffSet;
299 if(fLookUpTableData[lutAddress+1].fIdManuChannel == -1) //skip uninitialized values
302 hitset[iChamber] = true;
305 trigRecord[nofTrigRec].fHit[iChamber].fX = fLookUpTableData[lutAddress+1].fRealX;
309 trigRecord[nofTrigRec].fHit[iChamber].fY = fLookUpTableData[lutAddress+1].fRealY;
310 trigRecord[nofTrigRec].fHit[iChamber].fZ = fLookUpTableData[lutAddress+1].fRealZ;
313 HLTDebug("\t Hit Found fo ich : %d, iPlane : %d, detelem %d, id : %d, at (%lf, %lf, %lf) cm",
314 iChamber,fLookUpTableData[lutAddress+1].fPlane,detElemId,fLookUpTableData[lutAddress+1].fIdManuChannel,
315 fLookUpTableData[lutAddress+1].fRealX,
316 fLookUpTableData[lutAddress+1].fRealY,
317 fLookUpTableData[lutAddress+1].fRealZ
322 }//pattern maching is found
329 // Make sure the hits that are not set, get set to a nil value.
330 for (int i = 0; i < 4; i++)
334 trigRecord[nofTrigRec].fHit[i]
335 = AliHLTMUONConstants::NilRecHitStruct();
339 trigRecord[nofTrigRec].fId = fTrigRecId;
341 // Increment trigger record Id and keep it positive.
342 //TODO: handle the wrapparound better.
343 if (fTrigRecId < 0x7FFFFFFF)
348 AliHLTMUONRecHitStruct* hit1 = NULL;
350 hit1 = &trigRecord[nofTrigRec].fHit[0];
352 hit1 = &trigRecord[nofTrigRec].fHit[1];
353 AliHLTMUONRecHitStruct* hit2 = NULL;
355 hit2 = &trigRecord[nofTrigRec].fHit[2];
357 hit2 = &trigRecord[nofTrigRec].fHit[3];
359 if (hit1 != NULL and hit2 != NULL)
361 // Calculate the momentum and fill in the flags and momentum fields.
362 AliHLTMUONCalculations::ComputeMomentum(
367 trigRecord[nofTrigRec].fPx = AliHLTMUONCalculations::Px();
368 trigRecord[nofTrigRec].fPy = AliHLTMUONCalculations::Py();
369 trigRecord[nofTrigRec].fPz = AliHLTMUONCalculations::Pz();
371 trigRecord[nofTrigRec].fFlags =
372 AliHLTMUONUtils::PackTriggerRecordFlags(
373 AliHLTMUONCalculations::Sign(),
379 else if ((hit1 != NULL or hit2 != NULL) and not suppressPartialTrigs)
381 trigRecord[nofTrigRec].fPx = 0;
382 trigRecord[nofTrigRec].fPy = 0;
383 trigRecord[nofTrigRec].fPz = 0;
385 trigRecord[nofTrigRec].fFlags =
386 AliHLTMUONUtils::PackTriggerRecordFlags(
394 //int xPos = rawData[index] & 0x1F;
395 //int dev = (rawData[index]>>5) & 0x1F;
396 //int yPos = (rawData[index]>>10) & 0xF;
399 }// if any non zero pattern found
401 index += 1 ; // the last word, important one
405 if(!reg_phys_trig_occur)
408 index += 1; // end of local Data 0xCAFEFADE
410 HLTDebug("iReg %d, iLoc %d, locId : %d, trigY %x, triggX %x, loDev %x, dec %x, sign %x,rawData : %x",
411 iReg,iLoc,locId,triggY,triggX,loDev,dec,sign, rawData[index]);
413 index = iLocIndex + 6; //important to reset the index counter for fake locids like 235