Cleaning up generation and reading back of lookup tables. Also moved core generation...
[u/mrichter/AliRoot.git] / HLT / MUON / OnlineAnalysis / AliHLTMUONHitReconstructor.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 //Author : Indranil Das, SINP, INDIA
21 //         Sukalyan Chattopadhyay, SINP, INDIA
22 //         
23 //Email :  indra.das@saha.ac.in
24 //         sukalyan.chattopadhyay@saha.ac.in 
25 //
26 // This class implements a hit reconstruction algorithm for the dimuon
27 // high level trigger.
28 // The algorithm finds 3 pad clusters by looking for unique pads with a charge
29 // above a certain threshold. A centre of gravity type calculation is applied
30 // to the three pads forming the cluster to find the hit's X or Y coordinate
31 // along the non-bending and bending planes individually.
32 // The sepperate X and Y coordinates are then merged to give the full coordinate
33 // of the hit.
34 /////////////////////////////////////////////////
35
36 #include "AliHLTMUONHitReconstructor.h"
37 #include "AliHLTMUONRecHitsBlockStruct.h"
38 #include <cstring>
39 #include <strings.h>
40
41
42 const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkDetectorId = 0xA00;
43 const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkDDLOffSet = 12;
44 const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkNofDDL = 8;
45 const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkDDLHeaderSize = 8;
46 const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkLutLine = 59648 + 1;
47
48
49 AliHLTMUONHitReconstructor::AliHLTMUONHitReconstructor() :
50         AliHLTLogging(),
51         fHLTMUONDecoder(),
52         fkBlockHeaderSize(8),
53         fkDspHeaderSize(8),
54         fkBuspatchHeaderSize(4),
55         fDCCut(0),
56         fPadData(NULL),
57         fLookUpTableData(NULL),
58         fRecPoints(NULL),
59         fRecPointsCount(NULL),
60         fMaxRecPointsCount(0),
61         fCentralCountB(0),
62         fCentralCountNB(0),
63         fDigitPerDDL(0),
64         fCentralChargeB(NULL),
65         fCentralChargeNB(NULL),
66         fRecX(NULL),
67         fRecY(NULL),
68         fAvgChargeX(NULL),
69         fAvgChargeY(NULL),
70         fNofBChannel(NULL),
71         fNofNBChannel(NULL),
72         fNofFiredDetElem(0),
73         //fDebugLevel(0),  //TODO: remove
74         fIdToEntry()
75 {
76         /// Default constructor
77         
78         fkBlockHeaderSize    = 8;
79         fkDspHeaderSize      = 8;
80         fkBuspatchHeaderSize = 4;
81         
82         try
83         {
84                 fPadData = new AliHLTMUONPad[fgkLutLine];
85         }
86         catch (const std::bad_alloc&)
87         {
88                 HLTError("Dynamic memory allocation failed for AliHLTMUONHitReconstructor::fPadData in constructor.");
89                 throw;
90         }
91         
92         fPadData[0].fDetElemId = 0;
93         fPadData[0].fIX = 0 ;
94         fPadData[0].fIY = 0 ;
95         fPadData[0].fRealX = 0.0 ;
96         fPadData[0].fRealY = 0.0 ;
97         fPadData[0].fRealZ = 0.0 ;
98         fPadData[0].fHalfPadSize = 0.0 ;
99         fPadData[0].fPlane = -1 ;
100         fPadData[0].fCharge = 0 ;
101         
102         bzero(fGetIdTotalData, 336*237*2*sizeof(int));
103 }
104
105
106 AliHLTMUONHitReconstructor::~AliHLTMUONHitReconstructor()
107 {
108         /// Default destructor
109         
110         if (fPadData)
111         {
112                 delete [] fPadData;
113                 fPadData = NULL;
114         }
115 }
116
117
118 void AliHLTMUONHitReconstructor::SetLookUpTable(
119                 const AliHLTMUONHitRecoLutRow* lookupTable,
120                 const IdManuChannelToEntry* idToEntry
121         )
122 {
123         /// Sets the Lookup table (LUT) containing the position of each pad with
124         /// electronic channel associated with it. Also the appropriate manu
125         /// channel ID mapping to LUT row is also set.
126
127         assert( lookupTable != NULL );
128         assert( idToEntry != NULL );
129         
130         fIdToEntry = idToEntry;
131         fLookUpTableData = lookupTable;
132 }
133
134
135 bool AliHLTMUONHitReconstructor::Run(
136                 const AliHLTUInt32_t* rawData,
137                 AliHLTUInt32_t rawDataSize,
138                 AliHLTMUONRecHitStruct* recHit,
139                 AliHLTUInt32_t& nofHit
140         ) 
141 {
142   // main function called by HLTReconstructor to perform DHLT Hitreconstruction 
143
144   fRecPoints = recHit;
145   fMaxRecPointsCount = nofHit;
146   fRecPointsCount = &nofHit;
147   *fRecPointsCount = 0;
148   fDigitPerDDL = 0;
149
150   if (not DecodeDDL(rawData, rawDataSize)) {
151     // Dont need to log any message again. Already done so in DecodeDDL.
152     return false;
153   }
154
155   if (fDigitPerDDL == 1)
156   {
157     // There are no digits to process so stop here.
158     return true;
159   }
160
161   if (not FindRecHits()) {
162     HLTError("Failed to generate RecHits");
163     Clear();
164     return false;
165   }
166
167   return true;
168 }
169
170
171 bool AliHLTMUONHitReconstructor::DecodeDDL(const AliHLTUInt32_t* rawData,AliHLTUInt32_t rawDataSize)
172 {
173   //function to decode Raw Data 
174
175   AliHLTMUONRawDecoder& handler = reinterpret_cast<AliHLTMUONRawDecoder&>(fHLTMUONDecoder.GetHandler());
176   UInt_t bufferSize = UInt_t(rawDataSize*sizeof(AliHLTUInt32_t));
177
178   handler.SetDCCut(fDCCut);
179   handler.SetPadData(fPadData);
180   handler.SetLookUpTable(fLookUpTableData);
181   handler.SetIdManuChannelToEntry(fIdToEntry);
182   handler.SetNofFiredDetElemId(fNofFiredDetElem);
183   handler.SetMaxFiredPerDetElem(fMaxFiredPerDetElem);
184  
185   if(!fHLTMUONDecoder.Decode(rawData,bufferSize))
186     return false;
187
188   fDigitPerDDL = handler.GetDataCount();
189   fMaxFiredPerDetElem[fNofFiredDetElem-1] = handler.GetDataCount();
190     
191   if(fDigitPerDDL == 1){
192     HLTInfo("An Empty DDL File found");
193   }
194     
195   return true;
196 }
197
198
199 bool AliHLTMUONHitReconstructor::FindRecHits()
200 {
201   // fuction that calls hit reconstruction detector element-wise   
202
203   for(int iDet=0; iDet<fNofFiredDetElem ; iDet++){
204     
205     fCentralCountB = 0 ;
206     fCentralCountNB = 0 ;
207
208     
209     try{
210       fCentralChargeB = new int[fMaxFiredPerDetElem[iDet]];
211       fCentralChargeNB = new int[fMaxFiredPerDetElem[iDet]];
212     }
213     catch(const std::bad_alloc&){
214       HLTError("Dynamic memory allocation failed for AliHLTMUONHitReconstructor::fCentralChargeNB and fCentralChargeB");
215       return false;
216     }
217
218     if(iDet>0)
219       FindCentralHits(fMaxFiredPerDetElem[iDet-1],fMaxFiredPerDetElem[iDet]);
220     else
221       FindCentralHits(1,fMaxFiredPerDetElem[iDet]); // minimum value is 1 because dataCount in ReadDDL starts from 1 instead of 0;
222
223     if(!RecXRecY()){
224       HLTError("Failed to find RecX and RecY hits\n");
225       return false;
226     }
227
228
229     if(!MergeRecHits()){
230       HLTError("Failed to merge hits\n");
231       return false;
232     }
233
234
235     if(iDet==0)
236       for(int i=1;i<fMaxFiredPerDetElem[iDet];i++) // minimum value is 1 because dataCount in ReadDDL starts from 1 instead of 0;
237         fGetIdTotalData[fPadData[i].fIX][fPadData[i].fIY][fPadData[i].fPlane] = 0;
238     else
239       for(int i=fMaxFiredPerDetElem[iDet-1];i<fMaxFiredPerDetElem[iDet];i++)
240         fGetIdTotalData[fPadData[i].fIX][fPadData[i].fIY][fPadData[i].fPlane] = 0;
241
242
243
244     if(fCentralChargeB){
245       delete []fCentralChargeB;
246       fCentralChargeB = NULL;
247     }
248     
249     if(fCentralChargeNB){
250       delete []fCentralChargeNB;
251       fCentralChargeNB = NULL;
252     }
253
254
255   }
256
257   for(int iPad=1;iPad<fDigitPerDDL;iPad++){
258     fGetIdTotalData[fPadData[iPad].fIX][fPadData[iPad].fIY][fPadData[iPad].fPlane] = 0;
259     fPadData[iPad].fDetElemId = 0;
260     fPadData[iPad].fIX = 0 ;
261     fPadData[iPad].fIY = 0 ;
262     fPadData[iPad].fRealX = 0.0 ;
263     fPadData[iPad].fRealY = 0.0 ;
264     fPadData[iPad].fRealZ = 0.0 ;
265     fPadData[iPad].fHalfPadSize = 0.0 ;
266     fPadData[iPad].fPlane = -1 ;
267     fPadData[iPad].fCharge = 0 ;
268   }  
269   
270   for(int i=0;i<13;i++)
271     fMaxFiredPerDetElem[i] = 0;
272
273   Clear();
274
275   return true;
276 }
277
278
279 void AliHLTMUONHitReconstructor::FindCentralHits(int minPadId, int maxPadId)
280 {
281   // to find central hit associated with each cluster
282
283   int b,nb;
284   int idManuChannelCentral;
285   bool hasFind;
286
287   for(int iPad=minPadId;iPad<maxPadId;iPad++){
288
289     fGetIdTotalData[fPadData[iPad].fIX]
290       [fPadData[iPad].fIY]
291       [fPadData[iPad].fPlane] = iPad ;
292     
293     if(fPadData[iPad].fPlane == 0 ){//&& fPadData[iPad].fIY > (0+1) && fPadData[iPad].fIY < (79 - 1)){
294       //if(fPadData[iPad].fIY > 0){
295       if(fCentralCountB>0){
296         hasFind = false;
297         for(b = 0;b<fCentralCountB;b++){
298           idManuChannelCentral = fCentralChargeB[b];
299           if(fPadData[iPad].fIX == fPadData[idManuChannelCentral].fIX
300              &&
301              (fPadData[iPad].fIY 
302               == fPadData[idManuChannelCentral].fIY + 1 
303               ||
304               fPadData[iPad].fIY 
305               == fPadData[idManuChannelCentral].fIY + 2 
306               ||
307               fPadData[iPad].fIY 
308               == fPadData[idManuChannelCentral].fIY - 2 
309               ||
310               fPadData[iPad].fIY 
311               == fPadData[idManuChannelCentral].fIY - 1)){
312             
313             hasFind = true;
314             if(fPadData[iPad].fCharge > fPadData[idManuChannelCentral].fCharge){
315               fCentralChargeB[b] = iPad;
316             }// if condn on pad charge
317           }// if condon on pad position
318         }// for loop over b
319         if(!hasFind){
320           fCentralChargeB[fCentralCountB] = iPad;
321           fCentralCountB++;
322         }
323       }
324       else{
325         fCentralChargeB[fCentralCountB] = iPad;
326         fCentralCountB++;
327       }// check the size of centralHitB
328       for(b = 0;b<fCentralCountB;b++){
329         idManuChannelCentral = fCentralChargeB[b];
330       }
331       //}// if cond on iY > 2 (to avoid edge value pb)
332     }// B/Nb checking
333     else{
334       if(fCentralCountNB>0){
335         hasFind = false;
336         for(nb = 0;nb<fCentralCountNB;nb++){
337           idManuChannelCentral = fCentralChargeNB[nb];
338           if(fPadData[iPad].fIY == fPadData[idManuChannelCentral].fIY
339              &&
340              (fPadData[iPad].fIX 
341               == fPadData[idManuChannelCentral].fIX + 1 
342               ||
343               fPadData[iPad].fIX
344               == fPadData[idManuChannelCentral].fIX + 2
345               ||
346               fPadData[iPad].fIX
347               == fPadData[idManuChannelCentral].fIX - 2
348               ||
349               fPadData[iPad].fIX
350               == fPadData[idManuChannelCentral].fIX - 1)){
351             
352             hasFind = true;       
353             if(fPadData[iPad].fCharge > fPadData[idManuChannelCentral].fCharge){
354               fCentralChargeNB[nb] = iPad;
355             }// if condn over to find higher charge
356           }// if condn over to find position
357         }// for loop over presently all nb values
358         if(!hasFind){
359           fCentralChargeNB[fCentralCountNB] = iPad;
360           fCentralCountNB++;
361         }
362       }// centralHitNB size test
363       else{
364         fCentralChargeNB[fCentralCountNB] = iPad;
365         fCentralCountNB++;
366       }// centralHitNB size test
367       
368     }// fill for bending and nonbending hit
369   }// detElemId loop
370
371 }
372
373
374 bool AliHLTMUONHitReconstructor::RecXRecY()
375 {
376   // find reconstructed X and Y for each plane separately
377   int b,nb;
378   int idCentral;
379   int idLower = 0;
380   int idUpper = 0;
381   int idRight = 0;
382   int idLeft = 0;
383
384   try{
385     fRecY = new float[fCentralCountB];
386     fRecX = new float[fCentralCountNB];
387     
388     fAvgChargeY = new float[fCentralCountB];
389     fAvgChargeX = new float[fCentralCountNB];
390     
391     fNofBChannel = new int[fCentralCountB];
392     fNofNBChannel = new int[fCentralCountNB];
393   }
394   catch(const std::bad_alloc&){
395     HLTError("Dynamic memory allocation failed for AliHLTMUONHitReconstructor::fRecY and others at method RecXRecY()");
396     return false;
397   }
398   
399   for(b=0;b<fCentralCountB;b++){
400     idCentral = fCentralChargeB[b];
401
402     if(fPadData[idCentral].fIY==0)
403       idLower = 0;
404     else
405       idLower = fGetIdTotalData[fPadData[idCentral].fIX][fPadData[idCentral].fIY-1][0];
406
407     if(fPadData[idCentral].fIX==236)
408       idUpper = 0;
409     else
410       idUpper = fGetIdTotalData[fPadData[idCentral].fIX][fPadData[idCentral].fIY+1][0];
411
412
413     fRecY[b] = (fPadData[idCentral].fRealY*fPadData[idCentral].fCharge
414                +
415                 fPadData[idUpper].fRealY*fPadData[idUpper].fCharge
416                +
417                 fPadData[idLower].fRealY*fPadData[idLower].fCharge
418                 )/(fPadData[idCentral].fCharge + fPadData[idUpper].fCharge + fPadData[idLower].fCharge) ;
419     
420     fAvgChargeY[b] = (fPadData[idCentral].fCharge + fPadData[idUpper].fCharge + fPadData[idLower].fCharge)/3.0 ;
421     
422     fNofBChannel[b] = 0;
423     if(fPadData[idLower].fCharge>0)
424       fNofBChannel[b]++ ;
425     if(fPadData[idCentral].fCharge>0)
426       fNofBChannel[b]++ ;
427     if(fPadData[idUpper].fCharge>0)
428       fNofBChannel[b]++ ;
429
430     HLTDebug("lower : %d, middle : %d, upper : %d, nofChannel : %d",fPadData[idLower].fCharge,
431             fPadData[idCentral].fCharge,fPadData[idUpper].fCharge,fNofBChannel[b]);
432
433     HLTDebug("RecY[%d] : %f",b,fRecY[b]);
434   }
435       
436   for(nb=0;nb<fCentralCountNB;nb++){
437     idCentral = fCentralChargeNB[nb];
438
439     if(fPadData[idCentral].fIX==0)
440       idLeft = 0;
441     else
442       idLeft = fGetIdTotalData[fPadData[idCentral].fIX-1][fPadData[idCentral].fIY][1];
443     
444     if(fPadData[idCentral].fIX==335)
445       idRight = 0 ;
446     else
447       idRight = fGetIdTotalData[fPadData[idCentral].fIX+1][fPadData[idCentral].fIY][1];
448
449     fRecX[nb] = (fPadData[idCentral].fRealX*fPadData[idCentral].fCharge
450                  +
451                  fPadData[idRight].fRealX*fPadData[idRight].fCharge
452                  +
453                  fPadData[idLeft].fRealX*fPadData[idLeft].fCharge
454                  )/(fPadData[idCentral].fCharge + fPadData[idRight].fCharge + fPadData[idLeft].fCharge);
455     
456
457     fAvgChargeX[nb] = (fPadData[idCentral].fCharge + fPadData[idRight].fCharge + fPadData[idLeft].fCharge)/3.0 ;
458     
459     
460     fNofNBChannel[nb] = 0;
461     if(fPadData[idLeft].fCharge>0)
462       fNofNBChannel[nb]++ ;
463     if(fPadData[idCentral].fCharge>0)
464       fNofNBChannel[nb]++ ;
465     if(fPadData[idRight].fCharge>0)
466       fNofNBChannel[nb]++ ;
467
468     HLTDebug("left : %d, middle : %d, right : %d, nofChannel : %d",fPadData[idLeft].fCharge,
469             fPadData[idCentral].fCharge,fPadData[idRight].fCharge,fNofNBChannel[nb]);
470
471     HLTDebug("RecX[%d] : %f",nb,fRecX[nb]);
472
473   }
474
475   return true;
476   
477 }
478
479
480 bool AliHLTMUONHitReconstructor::MergeRecHits()
481 {
482   // Merge reconstructed hits first over same plane then bending plane with non-bending plane
483
484   int idCentralB,idCentralNB ;
485   float padCenterXB;
486   float padCenterYNB;
487   float diffX,diffY;
488   float halfPadLengthX,halfPadLengthY;
489
490   // MERGE Bending Plane hits, which are placed side by side
491   for(int i=0;i<fCentralCountB-1;i++){
492     if(fRecY[i] != 0.0){
493       for(int j=i+1;j<fCentralCountB;j++){
494                  
495         if(fCentralChargeB[i]==fCentralChargeB[j]){
496           fRecY[j] = 0.0;
497           continue;
498         }
499         else if(
500            (
501             fPadData[fCentralChargeB[i]].fIY == fPadData[fCentralChargeB[j]].fIY
502             )
503            &&
504            (
505             fPadData[fCentralChargeB[i]].fIX == fPadData[fCentralChargeB[j]].fIX + 1
506             ||
507             fPadData[fCentralChargeB[i]].fIX == fPadData[fCentralChargeB[j]].fIX - 1
508             )
509            &&
510            fRecY[j] != 0.0
511            &&
512            fRecY[i] != 0.0
513            ){
514
515           if(fAvgChargeY[i] > fAvgChargeY[j]){
516             fRecY[i] = (fRecY[i]*fAvgChargeY[i] + fRecY[j]*fAvgChargeY[j]
517                         )/(fAvgChargeY[i] + fAvgChargeY[j]);
518             fRecY[j] = 0.0;
519           }
520           else{
521             fRecY[j] = (fRecY[i]*fAvgChargeY[i] + fRecY[j]*fAvgChargeY[j]
522                         )/(fAvgChargeY[i] + fAvgChargeY[j]);
523             fRecY[i] = 0.0;
524
525           }// search for higher charge
526         }//pad position
527       }//j for loop
528     }//if fRecY[i] != 0.0
529   }// i for loop
530   
531   // MERGE Non Bending Plane hits, which are place side by side
532   for(int i=0;i<fCentralCountNB-1;i++){
533     if(fRecX[i] != 0.0){
534       for(int j=i+1;j<fCentralCountNB;j++){
535
536         if(fCentralChargeNB[i]==fCentralChargeNB[j]){
537           fRecX[j] = 0.0;
538           continue;
539         }
540         else if(
541            (
542             fPadData[fCentralChargeNB[i]].fIX == fPadData[fCentralChargeNB[j]].fIX
543             )
544            &&
545            (
546             fPadData[fCentralChargeNB[i]].fIY == fPadData[fCentralChargeNB[j]].fIY + 1
547             ||
548             fPadData[fCentralChargeNB[i]].fIY == fPadData[fCentralChargeNB[j]].fIY - 1
549             )
550            &&
551            fRecX[j] != 0.0
552            &&
553            fRecX[i] != 0.0
554            ){
555
556           if(fAvgChargeX[i] > fAvgChargeX[j]){
557             fRecX[i] = (fRecX[i]*fAvgChargeX[i] + fRecX[j]*fAvgChargeX[j]
558                        )/(fAvgChargeX[i] + fAvgChargeX[j]);
559             fRecX[j] = 0.0;
560           }
561           else{
562             fRecX[j] = (fRecX[i]*fAvgChargeX[i] + fRecX[j]*fAvgChargeX[j]
563                        )/(fAvgChargeX[i] + fAvgChargeX[j]);
564             fRecX[i] = 0.0;
565           }// search for higher charge
566         }//pad position
567       }//j for loop
568     }//if fRecX[i] != 0.0
569   }// i for loop
570
571   // Merge bending Plane hits with Non Bending
572   for(int b=0;b<fCentralCountB;b++){
573     if(fRecY[b]!=0.0){
574       idCentralB = fCentralChargeB[b];
575       padCenterXB = fPadData[idCentralB].fRealX; 
576       
577       halfPadLengthX = fPadData[idCentralB].fIY ;
578
579       for(int nb=0;nb<fCentralCountNB;nb++){
580         if(fRecX[nb]!=0.0){
581           idCentralNB = fCentralChargeNB[nb];
582
583           padCenterYNB = fPadData[idCentralNB].fRealY;
584
585           halfPadLengthY = fPadData[idCentralNB].fHalfPadSize ;
586
587           if(fabsf(fRecX[nb]) > fabsf(padCenterXB))
588             diffX = fabsf(fRecX[nb]) -  fabsf(padCenterXB);
589           else
590             diffX = fabsf(padCenterXB) -  fabsf(fRecX[nb]);
591           
592           if(fabsf(padCenterYNB)>fabsf(fRecY[b]))
593             diffY = fabsf(padCenterYNB) - fabsf(fRecY[b]);
594           else
595             diffY =  fabsf(fRecY[b]) - fabsf(padCenterYNB);
596
597           if(diffX < halfPadLengthX && diffY < halfPadLengthY ){//&& fPadData[idCentralB].fIY != 0){
598
599             if(fNofBChannel[b]==3)
600               fRecY[b] += 0.025*sin(12.0*(fRecY[b] - fPadData[idCentralB].fRealY)) ;
601             
602             fRecX[nb] += 0.075*sin(9.5*(fRecX[nb] - fPadData[idCentralNB].fRealX)) ;
603             
604             // First check that we have not overflowed the buffer.
605             if((*fRecPointsCount) == fMaxRecPointsCount){
606               HLTError("Nof RecHit (i.e. %d) exceeds the max nof RecHit limit %d\n",(*fRecPointsCount),fMaxRecPointsCount);
607               return false;
608             }
609             
610             //fRecPoints[(*fRecPointsCount)].fId = idCentralB;
611             fRecPoints[(*fRecPointsCount)].fX = fRecX[nb];
612             fRecPoints[(*fRecPointsCount)].fY = fRecY[b];
613             fRecPoints[(*fRecPointsCount)].fZ = fPadData[idCentralB].fRealZ;
614 //          fRecPoints[(*fRecPointsCount)].fXCenter = fPadData[idCentralNB].fRealX;
615 //          fRecPoints[(*fRecPointsCount)].fYCenter = fPadData[idCentralB].fRealY;
616 //          fRecPoints[(*fRecPointsCount)].fNofBChannel = fNofBChannel[b];
617 //          fRecPoints[(*fRecPointsCount)].fNofNBChannel = fNofNBChannel[nb];
618 //          fRecPoints[(*fRecPointsCount)].fDetElemId = (AliHLTUInt32_t)fPadData[idCentralB].fDetElemId;
619             (*fRecPointsCount)++;
620           }//if lies wihtin 5.0 mm
621         }// condn over fRecX ! = 0.0
622       }// loop over NB side
623     }// condn on fRecY[b] !=  0.0
624   }// loop over B side;
625
626   if(fRecX){
627     delete []fRecX;
628     fRecX = NULL;
629   }
630
631   if(fRecY){
632     delete []fRecY;
633     fRecY = NULL;
634   }
635
636   if(fAvgChargeX){
637     delete []fAvgChargeX;
638     fAvgChargeX = NULL;
639   }
640
641   if(fAvgChargeY){
642     delete []fAvgChargeY;
643     fAvgChargeY = NULL;
644   }
645
646   if(fNofBChannel){
647     delete []fNofBChannel;
648     fNofBChannel = NULL;
649   }
650
651   if(fNofNBChannel){
652     delete []fNofNBChannel;
653     fNofNBChannel = NULL;
654   }
655
656   return true;
657 }
658
659
660 void AliHLTMUONHitReconstructor::Clear()
661 {
662   // function to clear internal arrays and release the allocated memory.
663
664   for(int iPad=1;iPad<fDigitPerDDL;iPad++){
665     fGetIdTotalData[fPadData[iPad].fIX][fPadData[iPad].fIY][fPadData[iPad].fPlane] = 0;
666     fPadData[iPad].fDetElemId = 0;
667     fPadData[iPad].fIX = 0 ;
668     fPadData[iPad].fIY = 0 ;
669     fPadData[iPad].fRealX = 0.0 ;
670     fPadData[iPad].fRealY = 0.0 ;
671     fPadData[iPad].fRealZ = 0.0 ;
672     fPadData[iPad].fHalfPadSize = -1 ;
673     fPadData[iPad].fPlane = -1 ;
674     fPadData[iPad].fCharge = 0 ;
675   }  
676   
677   for(int i=0;i<13;i++)
678     fMaxFiredPerDetElem[i] = 0;
679
680   if(fCentralChargeB){
681     delete []fCentralChargeB;
682     fCentralChargeB = NULL;
683   }
684
685   if(fCentralChargeNB){
686     delete []fCentralChargeNB;
687     fCentralChargeNB = NULL;
688   }
689
690   if(fRecX){
691     delete []fRecX;
692     fRecX = NULL;
693   }
694
695   if(fRecY){
696     delete []fRecY;
697     fRecY = NULL;
698   }
699
700   if(fAvgChargeX){
701     delete []fAvgChargeX;
702     fAvgChargeX = NULL;
703   }
704
705   if(fAvgChargeY){
706     delete []fAvgChargeY;
707     fAvgChargeY = NULL;
708   }
709
710   if(fNofBChannel){
711     delete []fNofBChannel;
712     fNofBChannel = NULL;
713   }
714
715   if(fNofNBChannel){
716     delete []fNofNBChannel;
717     fNofNBChannel = NULL;
718   }
719
720 }
721
722
723 AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::AliHLTMUONRawDecoder() :
724         fBufferStart(NULL),
725         fBusPatchId(0),
726         fDCCut(0),
727         fPadData(NULL),
728         fLookUpTableData(NULL),
729         fNofFiredDetElem(NULL),
730         fMaxFiredPerDetElem(NULL),
731         fIdToEntry(),
732         fDataCount(1),
733         fPrevDetElemId(0),
734         fPadCharge(0),
735         fCharge(0.0),
736         fIdManuChannel(0x0),
737         fLutEntry(0)
738 {
739         // ctor
740 }
741
742
743 AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::~AliHLTMUONRawDecoder()
744 {
745         // dtor
746 }
747
748
749 void AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::OnData(UInt_t dataWord, bool /*parityError*/)
750 {
751   //function to arrange the decoded Raw Data
752
753   fIdManuChannel = 0x0;
754   fIdManuChannel = (fIdManuChannel|fBusPatchId)<<17;
755   fIdManuChannel |= (dataWord >> 12) & 0x1FFFF;
756   
757   IdManuChannelToEntry& idToEntry = * const_cast<IdManuChannelToEntry*>(fIdToEntry);
758   fLutEntry = idToEntry[fIdManuChannel];
759   fPadCharge = int(((unsigned short)(dataWord & 0xFFF)) - fLookUpTableData[fLutEntry].fPed);
760   
761   fCharge = 0;    
762   if(fPadCharge > fDCCut && fPadCharge > 5.0*fLookUpTableData[fLutEntry].fSigma){  // (charge > 4) is due cut out the noise level                       
763       
764     fPadData[fDataCount].fDetElemId = fLookUpTableData[fLutEntry].fDetElemId;
765     fPadData[fDataCount].fIX = fLookUpTableData[fLutEntry].fIX;
766     fPadData[fDataCount].fIY = fLookUpTableData[fLutEntry].fIY;
767     fPadData[fDataCount].fRealX = fLookUpTableData[fLutEntry].fRealX;
768     fPadData[fDataCount].fRealY = fLookUpTableData[fLutEntry].fRealY;
769     fPadData[fDataCount].fRealZ = fLookUpTableData[fLutEntry].fRealZ;
770     fPadData[fDataCount].fHalfPadSize = fLookUpTableData[fLutEntry].fHalfPadSize;
771     fPadData[fDataCount].fPlane = fLookUpTableData[fLutEntry].fPlane;
772     
773     if ( fPadCharge < fLookUpTableData[fLutEntry].fThres ) {
774       fCharge = (fLookUpTableData[fLutEntry].fA0)*fPadCharge;
775     }else{
776       fCharge = (fLookUpTableData[fLutEntry].fA0)*(fLookUpTableData[fLutEntry].fThres) 
777         + (fLookUpTableData[fLutEntry].fA0)*(fPadCharge-fLookUpTableData[fLutEntry].fThres) 
778         + (fLookUpTableData[fLutEntry].fA1)*(fPadCharge-fLookUpTableData[fLutEntry].fThres)*(fPadCharge-fLookUpTableData[fLutEntry].fThres);
779     }
780     
781     fPadData[fDataCount].fCharge = fCharge;
782     
783     if(fLookUpTableData[fLutEntry].fDetElemId != fPrevDetElemId){
784       if((*fNofFiredDetElem)>0){
785         fMaxFiredPerDetElem[(*fNofFiredDetElem)-1] = fDataCount;
786       }
787       (*fNofFiredDetElem)++;
788       fPrevDetElemId =  fLookUpTableData[fLutEntry].fDetElemId ;
789     }
790     
791 //     HLTDebug("buspatch : %d, detele : %d, id : %d, manu : %d, channel : %d, iX : %d, iY: %d, (X,Y) : (%f, %f), charge : %d, padsize : %f, plane : %d",
792 //           fBusPatchId,fPadData[fDataCount].fDetElemId,
793 //           fIdManuChannel,((dataWord >> 18) & 0x7FF),((dataWord >> 12) & 0x3F),
794 //           fPadData[fDataCount].fIX,fPadData[fDataCount].fIY,
795 //           fPadData[fDataCount].fRealX,fPadData[fDataCount].fRealY,
796 //           fPadData[fDataCount].fCharge,fPadData[fDataCount].fHalfPadSize,fPadData[fDataCount].fPlane);
797     
798       fDataCount ++;
799   }// if charge is more than DC Cut limit condition
800   
801 }