The trigger reconstructor component now generates the correct data format.
[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
39 const int AliHLTMUONTriggerReconstructor::fgkDetectorId = 0xB00;
40 const int AliHLTMUONTriggerReconstructor::fgkDDLOffSet = 20 ;
41 const int AliHLTMUONTriggerReconstructor::fgkNofDDL = 2 ;
42
43 const int AliHLTMUONTriggerReconstructor::fgkDDLHeaderSize = 8;
44 const int AliHLTMUONTriggerReconstructor::fgkEvenLutSize = 2602351 + 1; 
45 const int AliHLTMUONTriggerReconstructor::fgkOddLutSize = 2528735 + 1;
46
47 const int AliHLTMUONTriggerReconstructor::fgkLutLine = 10496;
48
49 const int AliHLTMUONTriggerReconstructor::fgkMinIdManuChannel[2] = {819616, 862288};
50 const int AliHLTMUONTriggerReconstructor::fgkMaxIdManuChannel[2] = {3421966, 3391022};
51
52 const float AliHLTMUONTriggerReconstructor::fgkHalfPadSizeXB[3] = {8.5, 17.0, 25.5};
53 const float AliHLTMUONTriggerReconstructor::fgkHalfPadSizeYNB[2] = {25.5, 34.0};
54
55 const int AliHLTMUONTriggerReconstructor::fgkDetElem = 9*4 ; // 9 detele per half chamber
56
57
58 AliHLTMUONTriggerReconstructor::AliHLTMUONTriggerReconstructor()
59   :
60   fPadData(NULL),
61   fLookUpTableData(NULL),
62   fRecPoints(NULL),
63   fRecPointsCount(NULL),
64   fMaxRecPointsCount(0),
65   fMaxFiredPerDetElem(),
66   fDetElemToDataId(),
67   fDDLId(0),
68   fIdOffSet(0)
69 {
70   // ctor 
71   
72   if(AliHLTMUONTriggerReconstructor::fgkEvenLutSize > AliHLTMUONTriggerReconstructor::fgkOddLutSize){
73     fPadData = new AliHLTMUONHitReconstructor::DHLTPad[AliHLTMUONTriggerReconstructor::fgkEvenLutSize];
74   }
75   else{
76     fPadData = new AliHLTMUONHitReconstructor::DHLTPad[AliHLTMUONTriggerReconstructor::fgkOddLutSize];
77   }
78
79   bzero(fGetIdTotalData,104*64*2*sizeof(int));
80 }
81
82
83 AliHLTMUONTriggerReconstructor::~AliHLTMUONTriggerReconstructor()
84 {
85   // dtor
86   delete []fPadData;
87   delete []fLookUpTableData;
88 }
89
90 bool AliHLTMUONTriggerReconstructor::SetRegToLocCardMap(RegToLoc* regToLoc)
91 {
92   if(!memcpy(fRegToLocCard,regToLoc,128*sizeof(RegToLoc)))
93     return false;
94
95   for(int i=0;i<128;i++){
96     HLTDebug("DDL : %d, reg : %d, loc : %d",fRegToLocCard[i].fTrigDDL,
97             fRegToLocCard[i].fRegId,fRegToLocCard[i].fLocId);
98   }
99
100   return true;
101 }
102
103 bool AliHLTMUONTriggerReconstructor::LoadLookUpTable(AliHLTMUONHitReconstructor::DHLTLut* lookUpTableData, int lookUpTableId)
104 {
105   if(lookUpTableId<fgkDDLOffSet || lookUpTableId>= fgkDDLOffSet + fgkNofDDL){
106     HLTError("DDL number is out of range (must be %d<=iDDL<%d)",fgkDDLOffSet,fgkDDLOffSet+fgkNofDDL);
107     return false;
108   }
109   
110   fDDLId = lookUpTableId;
111
112   int lutSize = ((lookUpTableId%2)==0) ? fgkEvenLutSize : fgkOddLutSize ;
113   int nofLutLine = fgkLutLine ;
114   fIdOffSet = fgkMinIdManuChannel[lookUpTableId%2];
115
116   int detManuChannelId;
117
118   fLookUpTableData = new AliHLTMUONHitReconstructor::DHLTLut[lutSize];
119
120   memset(fLookUpTableData,-1,lutSize*sizeof(AliHLTMUONHitReconstructor::DHLTLut));
121
122   for(int i=0; i<nofLutLine; i++){
123
124     detManuChannelId = lookUpTableData[i].fIdManuChannel - fIdOffSet + 1;
125     fLookUpTableData[detManuChannelId].fIdManuChannel = lookUpTableData[i].fIdManuChannel - fIdOffSet;
126     fLookUpTableData[detManuChannelId].fIX = lookUpTableData[i].fIX ;
127     fLookUpTableData[detManuChannelId].fIY = lookUpTableData[i].fIY ;
128     fLookUpTableData[detManuChannelId].fRealX = lookUpTableData[i].fRealX ;
129     fLookUpTableData[detManuChannelId].fRealY = lookUpTableData[i].fRealY ;
130     fLookUpTableData[detManuChannelId].fRealZ = lookUpTableData[i].fRealZ ;
131     fLookUpTableData[detManuChannelId].fPcbZone = lookUpTableData[i].fPcbZone ;
132     fLookUpTableData[detManuChannelId].fPlane = lookUpTableData[i].fPlane ;
133   }
134   return true;
135
136   return true;
137 }
138
139 bool AliHLTMUONTriggerReconstructor::Run(
140                 const AliHLTUInt32_t* rawData,
141                 AliHLTUInt32_t rawDataSize,
142                 AliHLTMUONTriggerRecordStruct* trigRecord,
143                 AliHLTUInt32_t& nofTrigRec
144         )
145 {
146
147   fRecPoints = trigRecord;
148   fMaxRecPointsCount = nofTrigRec;
149   fRecPointsCount = &nofTrigRec;
150   *fRecPointsCount = 0;
151   fMaxFiredPerDetElem.clear();
152   fDetElemToDataId.clear();
153
154   fPadData[0].fDetElemId = 0;
155   fPadData[0].fBuspatchId = 0;
156   fPadData[0].fIdManuChannel = 0;
157   fPadData[0].fIX = 0 ;
158   fPadData[0].fIY = 0 ;
159   fPadData[0].fRealX = 0.0 ;
160   fPadData[0].fRealY = 0.0 ;
161   fPadData[0].fRealZ = 0.0 ;
162   fPadData[0].fPlane = -1 ;
163   fPadData[0].fPcbZone = -1 ;
164   fPadData[0].fCharge = 0 ;
165   
166   if(!ReadDDL(rawData, rawDataSize)){
167     HLTError("Failed to read the complete DDL file\n");
168     return false;
169   }
170
171   if(!FindTrigHits()){
172     HLTError("Failed to generate RecHits\n");
173     return false;
174   }
175     
176   return true;
177 }
178
179
180 bool AliHLTMUONTriggerReconstructor::ReadDDL(
181                 const AliHLTUInt32_t* rawData,
182                 AliHLTUInt32_t rawDataSize
183         )
184 {
185
186   int idManuChannel ;
187   
188   int index = 0;
189   int dataCount = 0;
190   int detElemId = 0 ;
191   int reg_output,reg_phys_trig_occur ;
192   int iLocIndex,loc,locDec,triggY,sign,loDev,triggX;
193   int iRegLoc, locId ;
194   short pattern[2][4]; // 2 stands for two cathode planes and 4 stands for 4 chambers
195
196   Int_t offset,ithSwitch,secondLocation,idetElemId;
197
198   int shiftIndex = 10 - 6 - 1; // the one comes due to indexing from zero
199
200   DataIdIndex dataIndex;
201 #ifdef DEBUG
202   int globalcard_data_occurance = (rawData[index]>>10)&0x1; //Set to 1 if global info present in DDL else set to 0 
203   int version = (rawData[index]>>12)&0xFF; // software version
204   int serial_number =  (rawData[index]>>20)&0xF; // serial number set to 0xF 
205 #endif
206   int phys_trig_occur = (rawData[index]>>30)&0x1; // 1 for physics trigger, 0 for software trigger
207   
208   HLTDebug("globalcard_data_occurance  %d, version  %d, serial_number  %d, phys_trig_occur  %d",
209          globalcard_data_occurance,version,serial_number,phys_trig_occur);
210
211   if(!phys_trig_occur) // for software trigger
212     index += 8 ;// corresponding to scalar words
213   
214   index += 1 ; // To skip the separator 0xDEADFACE
215   
216   index += 4 ; // corresponding to global input
217   
218   index += 1 ; // reaches to global output
219   
220   if((fDDLId - AliHLTMUONTriggerReconstructor::fgkDDLOffSet) == 0){ //if globalData is present in DDL 0 (presummed may be changed)
221 #ifdef DEBUG
222     int singleLpt = rawData[index] & 0x1;
223     int singleHpt = (rawData[index] >> 1) & 0x1;
224     
225     int pairUnlikeLpt = (rawData[index] >> 4)  & 0x1;
226     int pairUnlikeHpt = (rawData[index] >> 5)  & 0x1;
227     
228     int pairLikeLpt = (rawData[index] >> 2)  & 0x1;
229     int pairLikeHpt = (rawData[index] >> 3)  & 0x1;
230 #endif
231     HLTDebug("singleLpt : %x, singleHpt : %x, pairUnlikeLpt : %x, pairUnlikeHpt : %x, pairLikeLpt : %x, pairLikeHpt : %x",
232              singleLpt,singleHpt,pairUnlikeLpt,pairUnlikeHpt,pairLikeLpt,pairLikeHpt);
233   }
234
235   if(!phys_trig_occur)
236     index += 10 ;// corresponds to scalar words
237
238   index += 1; // separator 0xDEADBEEF 
239
240   for (int iReg = 0; iReg < 8; iReg++) {
241     index += 1; // DARC Status Word
242     index += 1; // Regeional Word
243     reg_output = rawData[index] & 0xFF;
244     reg_phys_trig_occur = ( rawData[index] >> 31) & 0x1;
245     
246     index += 2; // 2 words for regional input
247     
248     index += 1; // L0 counter
249     
250     if(!reg_phys_trig_occur)
251       index += 10;
252     
253     index += 1 ; // end of Regeonal header 0xBEEFFACE
254
255     for(int iLoc = 0; iLoc < 16 ; iLoc++){
256
257       iLocIndex = index ;      
258
259       loc = (rawData[index+5] >> 19) &  0xF ;
260       
261       locDec = (rawData[index+5] >> 15) & 0xF;
262       triggY = (rawData[index+5] >> 14) & 0x1 ;
263       sign = (rawData[index+5] >> 9) & 0x1;
264       loDev = (rawData[index+5] >> 5) & 0xF ;
265       triggX = (loDev >> 4 & 0x1 ) && !(loDev & 0xF) ;
266
267       if( locDec != 0x9 ){ // check for Dec
268         
269         iRegLoc = iReg*16 + iLoc;
270         locId = fRegToLocCard[iRegLoc].fLocId ; 
271         
272         if(locId<=234){ // to avoid the copy locCards
273           
274           index += 1;
275           pattern[0][0] = rawData[index] & 0xFFFF; // x-strip pattern for chaber 0 
276           pattern[0][1] = (rawData[index] >> 16) & 0xFFFF; // x-strip pattern for chaber 1
277           index += 1; 
278           pattern[0][2] = rawData[index] & 0xFFFF; 
279           pattern[0][3] = (rawData[index] >> 16) & 0xFFFF; 
280           
281           index += 1;
282           pattern[1][0] = rawData[index] & 0xFFFF; // y-strip pattern for chaber 0
283           pattern[1][1] = (rawData[index] >> 16) & 0xFFFF; // y-strip pattern for chaber 0 
284           index += 1; 
285           pattern[1][2] = rawData[index] & 0xFFFF; 
286           pattern[1][3] = (rawData[index] >> 16) & 0xFFFF; 
287           
288           if(pattern[0][0] || pattern[0][1] || pattern[0][2] || pattern[0][3]
289              || pattern[1][0] || pattern[1][1] || pattern[1][2] || pattern[1][3]
290              ){
291
292             HLTDebug("iReg: %d, iLoc :%d, locId : %d,X : %x, %x, %x, %x ...Y : %x, %x, %x, %x",
293                     iReg,iLoc,locId,pattern[0][0],pattern[0][1],pattern[0][2],pattern[0][3],
294                     pattern[1][0],pattern[1][1],pattern[1][2],pattern[1][3]);
295
296             for(int iChamber = 0; iChamber < 4 ; iChamber++){ //4 chambers per DDL 
297               for(int iPlane = 0; iPlane < 2 ; iPlane++){// 2 cathode plane
298                 if(pattern[iPlane][iChamber]){
299                   detElemId = fRegToLocCard[iRegLoc].fDetElemId[iChamber];
300                   HLTDebug("\tdetElemId : %d\n",detElemId);
301                   for (Int_t ibitxy = 0; ibitxy < 16; ++ibitxy) {
302                     if ((pattern[iPlane][iChamber] >> ibitxy) & 0x1) {
303           
304                       // not quite sure about this
305                       offset = 0;
306                       ithSwitch = (fRegToLocCard[iRegLoc].fSwitch >> shiftIndex) & 0x1;
307                       if (iPlane && ithSwitch) offset = -8;
308                       
309                       secondLocation = ibitxy + offset;
310                       
311                       idetElemId = detElemId%1000;
312
313                       idetElemId &= 0x1FF ;
314                       iPlane &= 0x1 ;
315                       locId &= 0xFF ;
316                       secondLocation &= 0xF ;
317                       
318                       idManuChannel &= 0x0;
319                       idManuChannel = (idManuChannel|idetElemId)<<1;  
320                       idManuChannel = (idManuChannel|iPlane)<<8;  
321                       idManuChannel = (idManuChannel|locId)<<4 ;
322                       idManuChannel |= secondLocation  ;
323
324                       idManuChannel -= fIdOffSet ;
325                       
326                       if(fLookUpTableData[idManuChannel+1].fIdManuChannel == -1) //skip uninitialized values
327                         continue;
328
329                       fPadData[idManuChannel].fDetElemId = detElemId;
330                       fPadData[idManuChannel].fIdManuChannel = idManuChannel;
331                       fPadData[idManuChannel].fIX = fLookUpTableData[idManuChannel+1].fIX;
332                       fPadData[idManuChannel].fIY = fLookUpTableData[idManuChannel+1].fIY;
333                       fPadData[idManuChannel].fRealX = fLookUpTableData[idManuChannel+1].fRealX;
334                       fPadData[idManuChannel].fRealY = fLookUpTableData[idManuChannel+1].fRealY;
335                       fPadData[idManuChannel].fRealZ = fLookUpTableData[idManuChannel+1].fRealZ;
336                       fPadData[idManuChannel].fPcbZone = fLookUpTableData[idManuChannel+1].fPcbZone;
337                       fPadData[idManuChannel].fPlane = fLookUpTableData[idManuChannel+1].fPlane;
338                       HLTDebug("\t Hit Found fo ich : %d, iPlane : %d, detelem %d, id : %d, at (%lf, %lf, %lf) cm"
339                               ,iChamber,fLookUpTableData[idManuChannel+1].fPlane,detElemId,fLookUpTableData[idManuChannel+1].fIdManuChannel,
340                               fPadData[idManuChannel].fRealX,
341                               fPadData[idManuChannel].fRealY,fPadData[idManuChannel].fRealZ);
342                               
343                       if(fMaxFiredPerDetElem[detElemId] == 0){
344                         DataIdIndex first;
345                         first.push_back(idManuChannel);
346                         fDetElemToDataId[detElemId] = first;
347                       }else{
348                         dataIndex =  fDetElemToDataId[detElemId];
349                         dataIndex.push_back(idManuChannel);
350                         fDetElemToDataId[detElemId] = dataIndex;
351                       }
352
353                       fMaxFiredPerDetElem[detElemId] = fMaxFiredPerDetElem[detElemId] + 1;
354
355                       dataCount ++;
356                       
357                     }//pattern maching is found 
358                   }// loop of ibitxy
359                 }// if pattern
360               }// iplane
361             }// ichamber
362             
363           }// if any non zero pattern found
364
365
366           index += 1 ; // skipping the last word though it is important
367           
368         }// if locId <=234
369       }// Dec Condn
370         
371       
372       if(!reg_phys_trig_occur)
373          index += 45;
374         
375       index += 1; // end of local Data 0xCAFEFADE
376
377       HLTDebug("iReg %d, iLoc %d, locId : %d, trigY %x, triggX %x, loDev %x, dec %x, sign %x,rawData : %x",
378                iReg,iLoc,locId,triggY,triggX,loDev,dec,sign, rawData[index]);
379
380       index = iLocIndex + 6 ; //important to reset the index counter for fake locids like 235 
381       
382      }// iLoc loop
383      
384   }// iReg Loop
385
386   return true;
387 }
388
389 bool AliHLTMUONTriggerReconstructor::FindTrigHits() 
390 {
391
392   map<int,DataIdIndex>::iterator it;
393
394   for(it = fDetElemToDataId.begin(); it != fDetElemToDataId.end(); it++){
395     HLTDebug("Nof data found in Detelem : %d = %d",it->first,(it->second).size());
396     if(!MergeTrigHits(it->second))
397       return false;
398   }// loop over detection element
399
400   DataIdIndex dataIndex;
401   for(it = fDetElemToDataId.begin(); it != fDetElemToDataId.end(); it++){
402     dataIndex = it->second;
403     for(size_t i=0;i<dataIndex.size();i++){
404       fPadData[dataIndex.at(i)].fDetElemId = 0;
405       fPadData[dataIndex.at(i)].fBuspatchId = 0;
406       fPadData[dataIndex.at(i)].fIdManuChannel = 0;
407       fPadData[dataIndex.at(i)].fIX = 0 ;
408       fPadData[dataIndex.at(i)].fIY = 0 ;
409       fPadData[dataIndex.at(i)].fRealX = 0.0 ;
410       fPadData[dataIndex.at(i)].fRealY = 0.0 ;
411       fPadData[dataIndex.at(i)].fRealZ = 0.0 ;
412       fPadData[dataIndex.at(i)].fPlane = -1 ;
413       fPadData[dataIndex.at(i)].fPcbZone = -1 ;
414       fPadData[dataIndex.at(i)].fCharge = 0 ;
415     }// data per detelem loop  
416   }//detelem loop
417   
418   return true;
419 }
420
421 bool AliHLTMUONTriggerReconstructor::MergeTrigHits(DataIdIndex& dataIndex)
422 {
423   int idManuChannelB, idManuChannelNB;
424   float halfPadLengthX,halfPadLengthY;
425   float diffX,diffY;
426
427   HLTDebug("\tThe bending plane hits are :");
428   for(size_t iPad=0;iPad<dataIndex.size();iPad++){
429     idManuChannelB   = dataIndex.at(iPad);
430     if(fPadData[idManuChannelB].fPlane == 0){
431       HLTDebug("\t detelem :%d, pcbzone : %d, (%f, %f, %f) cm",fPadData[idManuChannelB].fDetElemId,fPadData[idManuChannelB].fPcbZone,fPadData[idManuChannelB].fRealX,
432               fPadData[idManuChannelB].fRealY,fPadData[idManuChannelB].fRealZ);
433     }
434   }
435
436   HLTDebug("\tThe non-bending plane hits are :");
437   for(size_t jPad=0;jPad<dataIndex.size();jPad++){
438     idManuChannelNB   = dataIndex.at(jPad);
439     if(fPadData[idManuChannelNB].fPlane == 1){
440       HLTDebug("\t detelem :%d, pcbzone : %d,(%f, %f, %f) cm",fPadData[idManuChannelNB].fDetElemId,fPadData[idManuChannelNB].fPcbZone,fPadData[idManuChannelNB].fRealX,
441               fPadData[idManuChannelNB].fRealY,fPadData[idManuChannelNB].fRealZ);
442     }
443   }
444
445
446   for(size_t iPad=0;iPad<dataIndex.size();iPad++){
447     idManuChannelB   = dataIndex.at(iPad);
448     if(fPadData[idManuChannelB].fPlane == 0){
449       
450       halfPadLengthX = AliHLTMUONTriggerReconstructor::fgkHalfPadSizeXB[fPadData[idManuChannelB].fPcbZone] ;
451
452       for(size_t jPad=0;jPad<dataIndex.size();jPad++){
453         idManuChannelNB   = dataIndex.at(jPad);;
454         if(fPadData[idManuChannelNB].fPlane == 1){
455           
456           halfPadLengthY = AliHLTMUONTriggerReconstructor::fgkHalfPadSizeYNB[fPadData[idManuChannelNB].fPcbZone] ;
457           
458           if(fabsf(fPadData[idManuChannelNB].fRealX) > fabsf(fPadData[idManuChannelB].fRealX))
459             diffX = fabsf(fPadData[idManuChannelNB].fRealX) - fabsf(fPadData[idManuChannelB].fRealX);
460           else
461             diffX = fabsf(fPadData[idManuChannelB].fRealX) - fabsf(fPadData[idManuChannelNB].fRealX) ;
462
463           
464           if(fabsf(fPadData[idManuChannelNB].fRealY) > fabsf(fPadData[idManuChannelB].fRealY))
465             diffY = fabsf(fPadData[idManuChannelNB].fRealY) - fabsf(fPadData[idManuChannelB].fRealY);
466           else
467             diffY = fabsf(fPadData[idManuChannelB].fRealY) - fabsf(fPadData[idManuChannelNB].fRealY) ;
468           HLTDebug("\tdiffX %f,  halfPadLengthX %f,  diffY  %f, halfPadLengthY  %f\n",diffX,halfPadLengthX,diffY,halfPadLengthY);
469
470           if(diffX < halfPadLengthX + 1.0 && diffY < halfPadLengthY + 1.0 ){// added redundancy of 1.0 cm due to the pb of geometrical segmentation 
471
472             AliHLTMUONRecHitStruct hit;
473             hit.fX = fPadData[idManuChannelNB].fRealX;
474             hit.fY = fPadData[idManuChannelB].fRealY;
475             hit.fZ = fPadData[idManuChannelNB].fRealZ;
476
477             fRecPoints[(*fRecPointsCount)].fHit[0] = hit;
478             fRecPoints[(*fRecPointsCount)].fId = fPadData[idManuChannelB].fDetElemId ;
479             
480             (*fRecPointsCount)++;
481             if((*fRecPointsCount) == fMaxRecPointsCount){
482               HLTFatal("Nof RecHit (i.e. %d) exceeds the max nof RecHit limit %d\n",(*fRecPointsCount),fMaxRecPointsCount);
483               return false;
484             }
485
486             HLTDebug("\t\t\tdetelem : %d, x %f, y %f, z %f\n",fPadData[idManuChannelB].fDetElemId,fPadData[idManuChannelNB].fRealX,
487                    fPadData[idManuChannelB].fRealY,fPadData[idManuChannelB].fRealZ);
488           }
489           
490         }//condn for non-bending plane
491       }//for loop for non-bending plane
492
493     }// condn for bending plane
494   }// for loop for bending plane
495
496   return true;
497 }
498