]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/MUON/OnlineAnalysis/AliHLTMUONTriggerReconstructor.cxx
5ccea27921ad70e628e9594e1ffdf041f1ea3f92
[u/mrichter/AliRoot.git] / HLT / MUON / OnlineAnalysis / AliHLTMUONTriggerReconstructor.cxx
1 /**************************************************************************
2  * This file is property of and copyright by the ALICE HLT Project        * 
3  * All rights reserved.                                                   *
4  *                                                                        *
5  * Primary Authors:                                                       *
6  *   Indranil Das <indra.das@saha.ac.in>                                  *
7  *                                                                        *
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  **************************************************************************/
16
17 /* $Id$ */
18
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 **********************************************************************/
26
27 ///*
28 //
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.
32 //
33 //  Author : Indranil Das ( indra.das@saha.ac.in || indra.ehep@gmail.com )
34 // 
35 //*/
36
37 #include "AliHLTMUONTriggerReconstructor.h"
38 #include "AliHLTMUONUtils.h"
39 #include "AliHLTMUONConstants.h"
40 #include "AliHLTMUONCalculations.h"
41 #include <vector>
42 #include <cassert>
43
44 const int AliHLTMUONTriggerReconstructor::fgkDetectorId = 0xB00;
45 const int AliHLTMUONTriggerReconstructor::fgkDDLOffSet = 20 ;
46 const int AliHLTMUONTriggerReconstructor::fgkNofDDL = 2 ;
47
48 const int AliHLTMUONTriggerReconstructor::fgkDDLHeaderSize = 8;
49 const int AliHLTMUONTriggerReconstructor::fgkEvenLutSize = 2602351 + 1; 
50 const int AliHLTMUONTriggerReconstructor::fgkOddLutSize = 2528735 + 1;
51
52 const int AliHLTMUONTriggerReconstructor::fgkLutLine = 10496;
53
54 const int AliHLTMUONTriggerReconstructor::fgkMinIdUnique[2] = {819616, 862288};
55 const int AliHLTMUONTriggerReconstructor::fgkMaxIdUnique[2] = {3421966, 3391022};
56
57 const float AliHLTMUONTriggerReconstructor::fgkHalfPadSizeXB[3] = {8.5, 17.0, 25.5};
58 const float AliHLTMUONTriggerReconstructor::fgkHalfPadSizeYNB[2] = {25.5, 34.0};
59
60 const int AliHLTMUONTriggerReconstructor::fgkDetElem = 9*4 ; // 9 detele per half chamber
61
62
63 AliHLTMUONTriggerReconstructor::AliHLTMUONTriggerReconstructor() :
64         fLookUpTableData(NULL),
65         fMaxRecPointsCount(0),
66         fDDLId(0),
67         fIdOffSet(0),
68         fTrigRecId(0)
69 {
70         // ctor
71 }
72
73
74 AliHLTMUONTriggerReconstructor::~AliHLTMUONTriggerReconstructor()
75 {
76         // dtor
77         if (fLookUpTableData != NULL)
78                 delete [] fLookUpTableData;
79 }
80
81 bool AliHLTMUONTriggerReconstructor::SetRegToLocCardMap(RegToLoc* regToLoc)
82 {
83   if(!memcpy(fRegToLocCard,regToLoc,128*sizeof(RegToLoc)))
84     return false;
85
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);
89   }
90
91   return true;
92 }
93
94 bool AliHLTMUONTriggerReconstructor::LoadLookUpTable(AliHLTMUONHitReconstructor::DHLTLut* lookUpTableData, int lookUpTableId)
95 {
96   if(lookUpTableId<fgkDDLOffSet || lookUpTableId>= fgkDDLOffSet + fgkNofDDL){
97     HLTError("DDL number is out of range (must be %d<=iDDL<%d)",fgkDDLOffSet,fgkDDLOffSet+fgkNofDDL);
98     return false;
99   }
100   
101   fDDLId = lookUpTableId;
102
103   int lutSize = ((lookUpTableId%2)==0) ? fgkEvenLutSize : fgkOddLutSize ;
104   int nofLutLine = fgkLutLine ;
105   fIdOffSet = fgkMinIdUnique[lookUpTableId%2];
106
107   int detUniqueId;
108
109   fLookUpTableData = new AliHLTMUONHitReconstructor::DHLTLut[lutSize];
110
111   memset(fLookUpTableData,-1,lutSize*sizeof(AliHLTMUONHitReconstructor::DHLTLut));
112
113   for(int i=0; i<nofLutLine; i++){
114
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 ;
124   }
125   
126   return true;
127 }
128
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
138         )
139 {
140   fMaxRecPointsCount = nofTrigRec;
141   
142   // nofTrigRec now becomes the output of how many trigger records were found.
143   nofTrigRec = 0;
144   
145   int lutAddress;
146   
147   int index = 0;
148   int dataCount = 0;
149   int detElemId = 0 ;
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
154
155   Int_t offset,ithSwitch,secondLocation,idetElemId;
156
157   int shiftIndex = 10 - 6 - 1; // the one comes due to indexing from zero
158
159 #ifdef __DEBUG
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 
163 #endif
164   int phys_trig_occur = (rawData[index]>>30)&0x1; // 1 for physics trigger, 0 for software trigger
165   
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
168   );
169
170   if(!phys_trig_occur) // for software trigger
171     index += 8 ;// corresponding to scalar words
172   
173   index += 1 ; // To skip the separator 0xDEADFACE
174   
175   index += 4 ; // corresponding to global input
176   
177   index += 1 ; // reaches to global output
178   
179   if((fDDLId - AliHLTMUONTriggerReconstructor::fgkDDLOffSet) == 0){ //if globalData is present in DDL 0 (presummed may be changed)
180 #ifdef __DEBUG
181     int singleLpt = rawData[index] & 0x1;
182     int singleHpt = (rawData[index] >> 1) & 0x1;
183     
184     int pairUnlikeLpt = (rawData[index] >> 4)  & 0x1;
185     int pairUnlikeHpt = (rawData[index] >> 5)  & 0x1;
186     
187     int pairLikeLpt = (rawData[index] >> 2)  & 0x1;
188     int pairLikeHpt = (rawData[index] >> 3)  & 0x1;
189 #endif
190     HLTDebug("singleLpt : %x, singleHpt : %x, pairUnlikeLpt : %x, pairUnlikeHpt : %x, pairLikeLpt : %x, pairLikeHpt : %x",
191              singleLpt,singleHpt,pairUnlikeLpt,pairUnlikeHpt,pairLikeLpt,pairLikeHpt
192     );
193   }
194
195   if(!phys_trig_occur)
196     index += 10; // corresponds to scalar words
197
198   index += 1; // separator 0xDEADBEEF 
199
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;
205     
206     index += 2; // 2 words for regional input
207     
208     index += 1; // L0 counter
209     
210     if(!reg_phys_trig_occur)
211       index += 10;
212     
213     index += 1; // end of Regeonal header 0xBEEFFACE
214
215     for(int iLoc = 0; iLoc < 16 ; iLoc++){
216
217       iLocIndex = index;      
218
219       loc = (rawData[index+5] >> 19) &  0xF ;
220       
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);
226
227       if( locDec != 0x9 ){ // check for Dec
228         
229         iRegLoc = iReg*16 + iLoc;
230         locId = fRegToLocCard[iRegLoc].fLocId; 
231         
232         if(locId<=234){ // to avoid the copy locCards
233           
234           index += 1;
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
237           index += 1; 
238           pattern[0][2] = rawData[index] & 0xFFFF; 
239           pattern[0][3] = (rawData[index] >> 16) & 0xFFFF; 
240           
241           index += 1;
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 
244           index += 1; 
245           pattern[1][2] = rawData[index] & 0xFFFF; 
246           pattern[1][3] = (rawData[index] >> 16) & 0xFFFF; 
247
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]
250              )
251           {
252             if (nofTrigRec == fMaxRecPointsCount) {
253               HLTError("Output buffer is overflowed maximum assiged arraysize : %d, present array index : %d",
254                        fMaxRecPointsCount, nofTrigRec
255               );
256               return false;
257             }
258
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]
262             );
263
264             // hitset indicates which hits on chambers 7 to 10 have been found and filled.
265             bool hitset[4] = {false, false, false, false};
266
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];
271                   
272                   HLTDebug("\tdetElemId : %d\n",detElemId);
273                   
274                   for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy) {
275                     if ((pattern[iPlane][iChamber] >> ibitxy) & 0x1) {
276           
277                       // not quite sure about this
278                       offset = 0;
279                       ithSwitch = (fRegToLocCard[iRegLoc].fSwitch >> shiftIndex) & 0x1;
280                       if (iPlane && ithSwitch) offset = -8;
281                       
282                       secondLocation = ibitxy + offset;
283                       
284                       idetElemId = detElemId%1000;
285
286                       idetElemId &= 0x1FF;
287                       iPlane &= 0x1;
288                       locId &= 0xFF;
289                       secondLocation &= 0xF;
290                       
291                       lutAddress &= 0x0;
292                       lutAddress = (lutAddress|idetElemId)<<1;  
293                       lutAddress = (lutAddress|iPlane)<<8;  
294                       lutAddress = (lutAddress|locId)<<4;
295                       lutAddress |= secondLocation;
296
297                       lutAddress -= fIdOffSet;
298                       
299                       if(fLookUpTableData[lutAddress+1].fIdManuChannel == -1) //skip uninitialized values
300                         continue;
301                         
302                       hitset[iChamber] = true;
303                       if (iPlane == 0)
304                       {      
305                         trigRecord[nofTrigRec].fHit[iChamber].fX = fLookUpTableData[lutAddress+1].fRealX;
306                       }
307                       else
308                       {
309                         trigRecord[nofTrigRec].fHit[iChamber].fY = fLookUpTableData[lutAddress+1].fRealY;
310                         trigRecord[nofTrigRec].fHit[iChamber].fZ = fLookUpTableData[lutAddress+1].fRealZ;
311                       } 
312                         
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
318                       );
319                       
320                       dataCount++;
321                       
322                     }//pattern maching is found 
323                   }// loop of ibitxy
324                 }// if pattern
325               }// iplane
326             }// ichamber
327             
328               {
329                 // Make sure the hits that are not set, get set to a nil value.
330                 for (int i = 0; i < 4; i++)
331                 {
332                         if (not hitset[i])
333                         {
334                                 trigRecord[nofTrigRec].fHit[i]
335                                         = AliHLTMUONConstants::NilRecHitStruct();
336                         }
337                 }
338
339                 trigRecord[nofTrigRec].fId = fTrigRecId;
340             
341                 // Increment trigger record Id and keep it positive.
342                 //TODO: handle the wrapparound better.
343                 if (fTrigRecId < 0x7FFFFFFF)
344                         fTrigRecId++;
345                 else
346                         fTrigRecId = 0;
347                 
348                 AliHLTMUONRecHitStruct* hit1 = NULL;
349                 if (hitset[0])
350                         hit1 = &trigRecord[nofTrigRec].fHit[0];
351                 else if (hitset[1])
352                         hit1 = &trigRecord[nofTrigRec].fHit[1];
353                 AliHLTMUONRecHitStruct* hit2 = NULL;
354                 if (hitset[2])
355                         hit2 = &trigRecord[nofTrigRec].fHit[2];
356                 else if (hitset[3])
357                         hit2 = &trigRecord[nofTrigRec].fHit[3];
358                 
359                 if (hit1 != NULL and hit2 != NULL)
360                 {
361                         // Calculate the momentum and fill in the flags and momentum fields.
362                         AliHLTMUONCalculations::ComputeMomentum(
363                                         hit1->fX,
364                                         hit1->fY, hit2->fY,
365                                         hit1->fZ, hit2->fZ
366                                 );
367                         trigRecord[nofTrigRec].fPx = AliHLTMUONCalculations::Px();
368                         trigRecord[nofTrigRec].fPy = AliHLTMUONCalculations::Py();
369                         trigRecord[nofTrigRec].fPz = AliHLTMUONCalculations::Pz();
370
371                         trigRecord[nofTrigRec].fFlags =
372                                 AliHLTMUONUtils::PackTriggerRecordFlags(
373                                         AliHLTMUONCalculations::Sign(),
374                                         hitset
375                                 );
376                         
377                         nofTrigRec++;
378                 }
379                 else if ((hit1 != NULL or hit2 != NULL) and not suppressPartialTrigs)
380                 {
381                         trigRecord[nofTrigRec].fPx = 0;
382                         trigRecord[nofTrigRec].fPy = 0;
383                         trigRecord[nofTrigRec].fPz = 0;
384
385                         trigRecord[nofTrigRec].fFlags =
386                                 AliHLTMUONUtils::PackTriggerRecordFlags(
387                                         kSignUnknown,
388                                         hitset
389                                 );
390                         
391                         nofTrigRec++;
392                 }
393             
394                 //int xPos = rawData[index] & 0x1F;
395                 //int dev = (rawData[index]>>5) & 0x1F;
396                 //int yPos = (rawData[index]>>10) & 0xF;
397             }
398           
399           }// if any non zero pattern found
400
401           index += 1 ; // the last word, important one
402         }// if locId <=234
403       }// Dec Condn
404
405       if(!reg_phys_trig_occur)
406          index += 45;
407         
408       index += 1; // end of local Data 0xCAFEFADE
409
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]);
412
413       index = iLocIndex + 6; //important to reset the index counter for fake locids like 235 
414       
415      }// iLoc loop
416      
417   }// iReg Loop
418
419   return true;
420 }