2abbee518c6069b5ed592a1ede1e52db1c81a9d1
[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 "AliHLTMUONClustersBlockStruct.h"
39 #include "AliHLTMUONChannelsBlockStruct.h"
40 #include "AliHLTMUONUtils.h"
41 #include "AliRawDataHeader.h"
42 #include <cassert>
43
44
45 const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkDetectorId = 0xA00;
46 const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkDDLOffSet = 0;
47 const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkNofDDL = 20;
48 const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkDDLHeaderSize = 8;
49 const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkLutLine = 59648 + 1;
50 const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkMaxNofDataPerDetElem = 3000;
51 const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkNofDetElemInDDL[20] =   {  2,   2,   2,   2, 
52                                                                               2,   2,   2,   2,
53                                                                               36,  36,  36,  36,
54                                                                               26,  26,  26,  26,
55                                                                               26,  26,  26,  26};        
56 const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkMinDetElemIdInDDL[20] = {  100, 101, 200, 201,
57                                                                               300, 301, 400, 401,
58                                                                               505, 501, 510, 500,
59                                                                               707, 700, 807, 800,
60                                                                               907, 900,1007,1000};      
61
62
63 AliHLTMUONHitReconstructor::AliHLTMUONHitReconstructor() :
64         AliHLTLogging(),
65         fHLTMUONDecoder(),
66         fkBlockHeaderSize(8),
67         fkDspHeaderSize(8),
68         fkBuspatchHeaderSize(4),
69         fDCCut(-1),
70         fPadData(NULL),
71         fkLookUpTableData(NULL),
72         fRecPoints(NULL),
73         fRecPointsCount(NULL),
74         fMaxRecPointsCount(0),
75         fClusters(NULL),
76         fClusterCount(0),
77         fMaxClusters(0),
78         fGenerateClusterInfo(false),
79         fNewClusterId(0),
80         fDDL(-1),
81         fChannels(NULL),
82         fChannelCount(0),
83         fMaxChannels(0),
84         fGenerateChannelInfo(false),
85         fMaxChannelMult(6),
86         fCentralCountB(0),
87         fCentralCountNB(0),
88         fDigitPerDDL(0),
89         fDataCountListPerDetElem(NULL),
90         fNofDataInDetElem(NULL),
91         fCentralChargeB(NULL),
92         fCentralChargeNB(NULL),
93         fRecX(NULL),
94         fRecY(NULL),
95         fAvgChargeX(NULL),
96         fAvgChargeY(NULL),
97         fTotChargeX(NULL),
98         fTotChargeY(NULL),
99         fNofBChannel(NULL),
100         fNofNBChannel(NULL),
101         fNofYNeighbour(NULL),
102         fkIdToEntry(),
103         fkMaxEntryPerBusPatch(0),
104         fRecoveryMode(kDontTryRecover)
105 {
106         /// Default constructor
107         
108         fkBlockHeaderSize    = 8;
109         fkDspHeaderSize      = 8;
110         fkBuspatchHeaderSize = 4;
111         
112         try
113         {
114                 fPadData = new AliHLTMUONPad[fgkLutLine];
115         }
116         catch (const std::bad_alloc&)
117         {
118                 HLTError("Dynamic memory allocation failed for fPadData in constructor.");
119                 throw;
120         }
121         
122         fPadData[0].fDetElemId = 0;
123         fPadData[0].fIX = 0 ;
124         fPadData[0].fIY = 0 ;
125         fPadData[0].fRealX = 0.0 ;
126         fPadData[0].fRealY = 0.0 ;
127         fPadData[0].fRealZ = 0.0 ;
128         fPadData[0].fHalfPadSize = 0.0 ;
129         fPadData[0].fPlane = 0 ;
130         fPadData[0].fCharge = 0 ;
131         fPadData[0].fBusPatch = -1;
132         fPadData[0].fRawData = 0 ;
133         
134         bzero(fGetIdTotalData, 336*237*2*sizeof(int));
135 }
136
137
138 AliHLTMUONHitReconstructor::~AliHLTMUONHitReconstructor()
139 {
140         /// Default destructor
141         
142         if (fPadData)
143         {
144                 delete [] fPadData;
145                 fPadData = NULL;
146         }
147         
148         if (fClusters != NULL)
149         {
150                 delete [] fClusters;
151         }
152         if (fChannels != NULL)
153         {
154                 delete [] fChannels;
155         }
156 }
157
158
159 void AliHLTMUONHitReconstructor::SetLookUpTable(
160                 const AliHLTMUONHitRecoLutRow* lookupTable,
161                 const IdManuChannelToEntry* idToEntry,
162                 const MaxEntryPerBusPatch* maxEntryPerBP
163         )
164 {
165         /// Sets the Lookup table (LUT) containing the position of each pad with
166         /// electronic channel associated with it. Also the appropriate manu
167         /// channel ID mapping to LUT row is also set.
168
169         assert( lookupTable != NULL );
170         assert( idToEntry != NULL );
171         assert( maxEntryPerBP != NULL );
172         
173         fkLookUpTableData = lookupTable;
174         fkIdToEntry = idToEntry;
175         fkMaxEntryPerBusPatch = maxEntryPerBP;
176 }
177
178 bool AliHLTMUONHitReconstructor::DeInitDetElemInDDLArray()
179 {
180   /// Deinitialisation
181
182         if (fDataCountListPerDetElem)
183         {
184                 delete [] fDataCountListPerDetElem;
185                 fDataCountListPerDetElem = NULL;
186         }
187
188         if (fNofDataInDetElem)
189         {
190                 delete [] fNofDataInDetElem;
191                 fNofDataInDetElem = NULL;
192         }
193
194   return true;
195 }
196
197 bool AliHLTMUONHitReconstructor::InitDetElemInDDLArray()
198 {
199
200   ///Initialisation
201
202   if(GetkNofDetElemInDDL(fDDL)==-1){
203     HLTError("Check if the DDLNumber(AliHLTInt32_t value) is Set before this method");
204     return false;
205   }
206   
207   try{
208     fDataCountListPerDetElem = new AliHLTUInt16_t*[GetkNofDetElemInDDL(fDDL)];
209   }catch (const std::bad_alloc&){
210     HLTError("Dynamic memory allocation failed in constructor : fDataCountListPerDetElem");
211     throw;
212   }
213
214   for( Int_t idet=0;idet<GetkNofDetElemInDDL(fDDL);idet++)
215     try{
216       fDataCountListPerDetElem[idet] = new AliHLTUInt16_t[fgkMaxNofDataPerDetElem];
217     }catch (const std::bad_alloc&){
218       HLTError("Dynamic memory allocation failed in constructor : fDataCountListPerDetElem[%d]",idet);
219       throw;
220     }
221   
222   try{
223     fNofDataInDetElem = new AliHLTUInt16_t[GetkNofDetElemInDDL(fDDL)];
224   }catch (const std::bad_alloc&){
225     HLTError("Dynamic memory allocation failed in constructor : fDataCountListPerDetElem");
226     throw;
227   }
228
229   for( Int_t idet=0;idet<GetkNofDetElemInDDL(fDDL);idet++)
230     fNofDataInDetElem[idet] = 0;
231   
232   return true;
233 }
234
235 void AliHLTMUONHitReconstructor::TryRecover(ERecoveryMode mode)
236 {
237         /// Sets if the decoder should enable the error recovery logic.
238         
239         // Here we setup the various flags to control exactly how the DDL raw data
240         // decoder will behave and what output is generated during errors.
241         fRecoveryMode = mode;
242         switch (mode)
243         {
244         case kRecoverFull:
245                 fHLTMUONDecoder.TryRecover(true);
246                 fHLTMUONDecoder.ExitOnError(false);
247                 fHLTMUONDecoder.GetHandler().WarnOnly(true);
248                 fHLTMUONDecoder.GetHandler().PrintParityErrorAsWarning(true);
249                 break;
250         case kRecoverJustSkip:
251                 fHLTMUONDecoder.TryRecover(false);
252                 fHLTMUONDecoder.ExitOnError(false);
253                 fHLTMUONDecoder.GetHandler().WarnOnly(true);
254                 fHLTMUONDecoder.GetHandler().PrintParityErrorAsWarning(true);
255                 break;
256         case kRecoverFromParityErrorsOnly:
257                 fHLTMUONDecoder.TryRecover(false);
258                 fHLTMUONDecoder.ExitOnError(false);
259                 fHLTMUONDecoder.GetHandler().WarnOnly(false);
260                 fHLTMUONDecoder.GetHandler().PrintParityErrorAsWarning(true);
261                 break;
262         default:
263                 fRecoveryMode = kDontTryRecover;
264                 fHLTMUONDecoder.TryRecover(false);
265                 fHLTMUONDecoder.ExitOnError(true);
266                 fHLTMUONDecoder.GetHandler().WarnOnly(false);
267                 fHLTMUONDecoder.GetHandler().PrintParityErrorAsWarning(false);
268                 break;
269         }
270 }
271
272
273 bool AliHLTMUONHitReconstructor::Run(
274                 AliHLTUInt32_t* rawData,
275                 AliHLTUInt32_t rawDataSize,
276                 AliHLTMUONRecHitStruct* const recHit,
277                 AliHLTUInt32_t& nofHit
278         ) 
279 {
280   // main function called by HLTReconstructor to perform DHLT Hitreconstruction 
281
282   fRecPoints = recHit;
283   fMaxRecPointsCount = nofHit;
284   fRecPointsCount = &nofHit;
285   *fRecPointsCount = 0;
286   fDigitPerDDL = 0;
287   fClusterCount = 0;
288   fChannelCount = 0;
289   HLTDebug("Decoding for DDL : %d",fDDL);
290   if(GetkMinDetElemIdInDDL(fDDL) == -1 or GetkNofDetElemInDDL(fDDL)==-1){
291     HLTError("DDL value fDDL : %d, out of range",fDDL);
292   }
293   if (not DecodeDDL(rawData, rawDataSize)) {
294     // Dont need to log any message again. Already done so in DecodeDDL.
295     return false;
296   }
297
298   if (fDigitPerDDL == 1)
299   {
300     // There are no digits to process so stop here.
301     return true;
302   }
303   
304   // Allocate fClusters and fChannels if required to do so and only if the allocated
305   // size of the arrays is too small.
306   try
307   {
308     if (fGenerateClusterInfo and fMaxClusters < fMaxRecPointsCount)
309     {
310       if (fClusters != NULL)
311       {
312         delete [] fClusters;
313         fMaxClusters = 0;
314       }
315       fClusters = new AliHLTMUONClusterStruct[fMaxRecPointsCount];
316       fMaxClusters = fMaxRecPointsCount;
317     }
318     if (fGenerateChannelInfo and fMaxChannels < fMaxRecPointsCount*fMaxChannelMult)
319     {
320       if (fChannels != NULL)
321       {
322         delete [] fChannels;
323         fMaxChannels = 0;
324       }
325       fChannels = new AliHLTMUONChannelStruct[fMaxRecPointsCount*fMaxChannelMult];
326       fMaxChannels = fMaxRecPointsCount*fMaxChannelMult;
327     }
328   }
329   catch(const std::bad_alloc&)
330   {
331     HLTError("Could not allocate memory for the extra cluster and channel information.");
332     return false;
333   }
334
335   if (not FindRecHits()) {
336     HLTError("Failed to generate RecHits");
337     return false;
338   }
339
340   return true;
341 }
342
343
344 bool AliHLTMUONHitReconstructor::FillClusterData(
345                 AliHLTMUONClusterStruct* clusters, AliHLTUInt32_t& nofClusters
346         )
347 {
348         /// Fills the output clusters array with extra cluster information.
349         
350         bool sizeOk = fClusterCount <= nofClusters;
351         AliHLTUInt32_t n = sizeOk ? fClusterCount : nofClusters;
352         memcpy(clusters, fClusters, sizeof(AliHLTMUONClusterStruct)*n);
353         nofClusters = n;
354         return sizeOk;
355 }
356
357
358 bool AliHLTMUONHitReconstructor::FillChannelData(
359                 AliHLTMUONChannelStruct* channels, AliHLTUInt32_t& nofChannels
360         )
361 {
362         /// Fills the output channels array with extra channel information for each cluster.
363         
364         bool sizeOk = fChannelCount <= nofChannels;
365         AliHLTUInt32_t n = sizeOk ? fChannelCount : nofChannels;
366         memcpy(channels, fChannels, sizeof(AliHLTMUONChannelStruct)*n);
367         nofChannels = n;
368         return sizeOk;
369 }
370
371
372 bool AliHLTMUONHitReconstructor::DecodeDDL(AliHLTUInt32_t* rawData,AliHLTUInt32_t rawDataSize)
373 {
374   //function to decode Raw Data 
375
376   AliHLTMUONRawDecoder& handler = reinterpret_cast<AliHLTMUONRawDecoder&>(fHLTMUONDecoder.GetHandler());
377   UInt_t bufferSize = UInt_t(rawDataSize*sizeof(AliHLTUInt32_t));
378
379   handler.SetDCCut(fDCCut);
380   handler.SetPadData(fPadData);
381   handler.SetLookUpTable(fkLookUpTableData);
382   handler.SetIdManuChannelToEntry(fkIdToEntry);
383   handler.DDLNumber(fDDL);
384   handler.SetNofFiredDetElemId(fNofDataInDetElem);
385   handler.SetMaxFiredPerDetElem(fDataCountListPerDetElem);
386   handler.SetMaxEntryPerBusPatch(fkMaxEntryPerBusPatch);
387  
388   if (not fHLTMUONDecoder.Decode(rawData,bufferSize))
389   {
390         switch (TryRecover())
391         {
392         case kRecoverFull:
393                 // Do not print the following warning for option "-dontprintparityerrors" if there
394                 // were only parity errors.
395                 if (fHLTMUONDecoder.GetHandler().NonParityErrorFound() or
396                     (fHLTMUONDecoder.GetHandler().ParityErrorFound() and not fHLTMUONDecoder.GetHandler().DontPrintParityErrors())
397                    )
398                 {
399                         HLTWarning("There was a problem with the raw data."
400                                 " Recovered as much data as possible."
401                                 " Will continue processing the next event."
402                         );
403                 }
404                 break;
405         case kRecoverJustSkip:
406                 if (fHLTMUONDecoder.GetHandler().NonParityErrorFound() or
407                     (fHLTMUONDecoder.GetHandler().ParityErrorFound() and not fHLTMUONDecoder.GetHandler().DontPrintParityErrors())
408                    )
409                 {
410                         HLTWarning("There was a problem with the raw data."
411                                 " Skipped corrupted data structures."
412                                 " Will continue processing the next event."
413                         );
414                 }
415                 break;
416         case kRecoverFromParityErrorsOnly:
417                 if (fHLTMUONDecoder.GetHandler().NonParityErrorFound())
418                 {
419                         HLTError("Failed to decode the tracker DDL raw data.");
420                         return false;
421                 }
422                 if (not fHLTMUONDecoder.GetHandler().DontPrintParityErrors())
423                 {
424                         assert( fHLTMUONDecoder.GetHandler().ParityErrorFound() );
425                         HLTWarning("Found parity errors in the raw data,"
426                                 " but will continue processing."
427                         );
428                 }
429                 break;
430         default:
431                 HLTError("Failed to decode the tracker DDL raw data.");
432                 return false;
433         }
434   }
435
436   fDigitPerDDL = handler.GetDataCount();
437
438   // fMaxFiredPerDetElem[fNofFiredDetElem-1] = handler.GetDataCount();
439   
440   // HLTDebug("fNofFiredDetElem : %d, NofDigits %d and max reco point limit is : %d, nofDetElems : %d",
441   //         fNofFiredDetElem,fDigitPerDDL,fMaxRecPointsCount,fNofFiredDetElem);
442
443   // for(int iDet=0; iDet<TMath::Max(fNofFiredDetElem,130); iDet++)
444   //   HLTDebug("NofCount (fMaxFiredPerDetElem) in iDet %d is : %d", iDet, fMaxFiredPerDetElem[iDet]);
445   
446   // if(fNofFiredDetElem>129){
447   //   HLTError("Number of fired detection elements is %d, which is more than 129.", fNofFiredDetElem);
448   //   return false;
449   // }
450   
451   if(fDigitPerDDL == 1){
452     HLTDebug("An Empty DDL file was found.");
453   }
454   
455   return true;
456 }
457
458
459 bool AliHLTMUONHitReconstructor::FindRecHits()
460 {
461   // fuction that calls hit reconstruction detector element-wise.
462
463   assert( fCentralChargeB == NULL );
464   assert( fCentralChargeNB == NULL );
465   assert( fRecX == NULL );
466   assert( fRecY == NULL );
467   assert( fAvgChargeX == NULL );
468   assert( fAvgChargeY == NULL );
469   assert( fTotChargeX == NULL );
470   assert( fTotChargeY == NULL );
471   assert( fNofBChannel == NULL );
472   assert( fNofNBChannel == NULL );
473   assert( fNofYNeighbour == NULL );
474   
475   bool resultOk = false;
476   
477
478
479   for(int iDet=0; iDet< GetkNofDetElemInDDL(fDDL) ; iDet++)
480   {
481     fCentralCountB = 0;
482     fCentralCountNB = 0;
483
484     try
485     {
486       fCentralChargeB = new int[fNofDataInDetElem[iDet]];
487       HLTDebug("Allocated fCentralChargeB with %d elements.", fNofDataInDetElem[iDet]);
488       fCentralChargeNB = new int[fNofDataInDetElem[iDet]];
489       HLTDebug("Allocated fCentralChargeNB with %d elements.", fNofDataInDetElem[iDet]);
490       resultOk = true;
491     }
492     catch(const std::bad_alloc&)
493     {
494       HLTError("Dynamic memory allocation failed for fCentralChargeNB and fCentralChargeB");
495       resultOk = false;
496       //break; Do not break. Might have smaller memory requirements in the next iteration.
497     }
498
499     // Continue processing, but check if everything is OK as we do, otherwise
500     // do not execute the next steps.
501     if (resultOk)
502     {
503       HLTDebug("Finding central hists for nofDigit  : %d, to in iDet  : %4d and min detelem : %4d",
504                  fNofDataInDetElem[iDet],iDet,GetkMinDetElemIdInDDL(fDDL));
505       FindCentralHits(iDet);
506       
507       HLTDebug("For iDet : %d, Found fCentralCountB : %d, fCentralCountNB : %d",iDet,fCentralCountB,fCentralCountNB);
508       if(fCentralCountB==0 or fCentralCountNB==0)
509       {
510         HLTDebug("There is no fired pad in bending/nonbending plane...skipping this detection element");
511         if (fCentralChargeB != NULL)
512         {
513           delete [] fCentralChargeB;
514           HLTDebug("Released fCentralChargeB array.");
515           fCentralChargeB = NULL;
516         }
517         if (fCentralChargeNB != NULL)
518         {
519           delete [] fCentralChargeNB;
520           HLTDebug("Released fCentralChargeNB array.");
521           fCentralChargeNB = NULL;
522         }
523         continue;
524       }
525     }
526
527     if (resultOk)
528     {
529       try
530       {
531         fRecY = new float[fCentralCountB];
532         HLTDebug("Allocated fRecY with %d elements.", fCentralCountB);
533         fRecX = new float[fCentralCountNB];
534         HLTDebug("Allocated fRecX with %d elements.", fCentralCountNB);
535         fAvgChargeY = new float[fCentralCountB];
536         HLTDebug("Allocated fAvgChargeY with %d elements.", fCentralCountB);
537         fAvgChargeX = new float[fCentralCountNB];
538         HLTDebug("Allocated fAvgChargeX with %d elements.", fCentralCountNB);
539         fTotChargeY = new float[fCentralCountB];
540         HLTDebug("Allocated fTotChargeY with %d elements.", fCentralCountB);
541         fTotChargeX = new float[fCentralCountNB];
542         HLTDebug("Allocated fTotChargeX with %d elements.", fCentralCountNB);
543         fNofBChannel = new int[fCentralCountB];
544         HLTDebug("Allocated fNofBChannel with %d elements.", fCentralCountB);
545         fNofNBChannel = new int[fCentralCountNB];
546         HLTDebug("Allocated fNofNBChannel with %d elements.", fCentralCountNB);
547         fNofYNeighbour = new int[fCentralCountB];
548         HLTDebug("Allocated fNofBChannel with %d elements.", fCentralCountB);
549         resultOk = true;
550       }
551       catch(const std::bad_alloc&){
552         HLTError("Dynamic memory allocation failed for internal arrays.");
553         resultOk = false;
554         //break; Must not break, this will prevent calling delete and memory cleanup, i.e. memory leak.
555       }
556     }
557
558     if (resultOk) RecXRecY();
559     
560     if (resultOk)
561     {
562       if(fDDL<8)
563         resultOk = MergeQuadRecHits();
564       else
565         resultOk = MergeSlatRecHits();
566     }
567     
568     // minimum value in loop is 1 because dataCount in ReadDDL starts from 1 instead of 0;
569     for(int i=0;i<fNofDataInDetElem[iDet];i++)
570       fGetIdTotalData[fPadData[fDataCountListPerDetElem[iDet][i]].fIX]
571         [fPadData[fDataCountListPerDetElem[iDet][i]].fIY]
572         [fPadData[fDataCountListPerDetElem[iDet][i]].fPlane] = 0;
573
574     // Make sure to release any memory that was allocated.
575     if (fCentralChargeB != NULL)
576     {
577       delete [] fCentralChargeB;
578       HLTDebug("Released fCentralChargeB array.");
579       fCentralChargeB = NULL;
580     }
581     if (fCentralChargeNB != NULL)
582     {
583       delete [] fCentralChargeNB;
584       HLTDebug("Released fCentralChargeNB array.");
585       fCentralChargeNB = NULL;
586     }
587     if (fRecX != NULL)
588     {
589       delete [] fRecX;
590       HLTDebug("Released fRecX array.");
591       fRecX = NULL;
592     }
593     if (fRecY != NULL)
594     {
595       delete [] fRecY;
596       HLTDebug("Released fRecY array.");
597       fRecY = NULL;
598     }
599     if (fAvgChargeX != NULL)
600     {
601       delete [] fAvgChargeX;
602       HLTDebug("Released fAvgChargeX array.");
603       fAvgChargeX = NULL;
604     }
605     if (fAvgChargeY != NULL)
606     {
607       delete [] fAvgChargeY;
608       HLTDebug("Released fAvgChargeY array.");
609       fAvgChargeY = NULL;
610     }
611     if (fTotChargeX != NULL)
612     {
613       delete [] fTotChargeX;
614       HLTDebug("Released fTotChargeX array.");
615       fTotChargeX = NULL;
616     }
617     if (fTotChargeY != NULL)
618     {
619       delete [] fTotChargeY;
620       HLTDebug("Released fTotChargeY array.");
621       fTotChargeY = NULL;
622     }
623     if (fNofBChannel != NULL)
624     {
625       delete [] fNofBChannel;
626       HLTDebug("Released fNofBChannel array.");
627       fNofBChannel = NULL;
628     }
629     if (fNofNBChannel != NULL)
630     {
631       delete [] fNofNBChannel;
632       HLTDebug("Released fNofNBChannel array.");
633       fNofNBChannel = NULL;
634     }
635     if (fNofYNeighbour != NULL)
636     {
637       delete [] fNofYNeighbour;
638       HLTDebug("Released fNofYNeighbour array.");
639       fNofYNeighbour = NULL;
640     }
641   }
642
643   Clear();  // clear internal arrays.
644
645   return resultOk;
646 }
647
648
649 void AliHLTMUONHitReconstructor::FindCentralHits(int iDet)
650 {
651   // to find central hit associated with each cluster
652
653   assert( fCentralChargeB != NULL );
654   assert( fCentralChargeNB != NULL );
655
656   int b,nb;
657   int idManuChannelCentral;
658   bool hasFind;
659   int iPad = 0;
660
661   for(int iEntry=0;iEntry<fNofDataInDetElem[iDet];iEntry++){
662
663     iPad = fDataCountListPerDetElem[iDet][iEntry];
664
665     //if(fPadData[iPad].fDetElemId==102)
666     HLTDebug("iPad : %d, detElem : %d, fCentralCountB : %d, fCentralCountNB : %d",iPad,fPadData[iPad].fDetElemId,fCentralCountB,fCentralCountNB);
667
668     fGetIdTotalData[fPadData[iPad].fIX]
669       [fPadData[iPad].fIY]
670       [fPadData[iPad].fPlane] = iPad ;
671
672     if(fPadData[iPad].fCharge <= fDCCut ) continue;
673     
674     if(fPadData[iPad].fPlane == 0 ){//&& fPadData[iPad].fIY > (0+1) && fPadData[iPad].fIY < (79 - 1)){
675       //if(fPadData[iPad].fIY > 0){
676       if(fCentralCountB>0){
677         hasFind = false;
678         for(b = 0;b<fCentralCountB;b++){
679           idManuChannelCentral = fCentralChargeB[b];
680           if(fPadData[iPad].fIX == fPadData[idManuChannelCentral].fIX
681              &&
682              (fPadData[iPad].fIY 
683               == fPadData[idManuChannelCentral].fIY + 1 
684               ||
685               fPadData[iPad].fIY 
686               == fPadData[idManuChannelCentral].fIY + 2 
687               ||
688               fPadData[iPad].fIY 
689               == fPadData[idManuChannelCentral].fIY - 2 
690               ||
691               fPadData[iPad].fIY 
692               == fPadData[idManuChannelCentral].fIY - 1)){
693             
694             hasFind = true;
695             if(fPadData[iPad].fCharge > fPadData[idManuChannelCentral].fCharge){
696               fCentralChargeB[b] = iPad;
697             }// if condn on pad charge
698           }// if condon on pad position
699         }// for loop over b
700         if(!hasFind){
701           fCentralChargeB[fCentralCountB] = iPad;
702           fCentralCountB++;
703         }
704       }
705       else{
706         fCentralChargeB[fCentralCountB] = iPad;
707         fCentralCountB++;
708       }// check the size of centralHitB
709       for(b = 0;b<fCentralCountB;b++){
710         idManuChannelCentral = fCentralChargeB[b];
711       }
712       //}// if cond on iY > 2 (to avoid edge value pb)
713     }// B/Nb checking
714     else{
715       if(fCentralCountNB>0){
716         hasFind = false;
717         for(nb = 0;nb<fCentralCountNB;nb++){
718           idManuChannelCentral = fCentralChargeNB[nb];
719           if(fPadData[iPad].fIY == fPadData[idManuChannelCentral].fIY
720              &&
721              (fPadData[iPad].fIX 
722               == fPadData[idManuChannelCentral].fIX + 1 
723               ||
724               fPadData[iPad].fIX
725               == fPadData[idManuChannelCentral].fIX + 2
726               ||
727               fPadData[iPad].fIX
728               == fPadData[idManuChannelCentral].fIX - 2
729               ||
730               fPadData[iPad].fIX
731               == fPadData[idManuChannelCentral].fIX - 1)){
732             
733             hasFind = true;       
734             if(fPadData[iPad].fCharge > fPadData[idManuChannelCentral].fCharge){
735               fCentralChargeNB[nb] = iPad;
736             }// if condn over to find higher charge
737           }// if condn over to find position
738         }// for loop over presently all nb values
739         if(!hasFind){
740           fCentralChargeNB[fCentralCountNB] = iPad;
741           fCentralCountNB++;
742         }
743       }// centralHitNB size test
744       else{
745         fCentralChargeNB[fCentralCountNB] = iPad;
746         fCentralCountNB++;
747       }// centralHitNB size test
748       
749     }// fill for bending and nonbending hit
750   }// detElemId loop
751
752 }
753
754 void AliHLTMUONHitReconstructor::RecXRecY()
755 {
756   // find reconstructed X and Y for each plane separately
757
758   assert( fRecX != NULL );
759   assert( fRecY != NULL );
760   assert( fAvgChargeX != NULL );
761   assert( fAvgChargeY != NULL );
762   assert( fTotChargeX != NULL );
763   assert( fTotChargeY != NULL );
764   assert( fNofBChannel != NULL );
765   assert( fNofNBChannel != NULL );
766   assert( fNofYNeighbour  != NULL );
767
768   int b,nb;
769   int idCentral;
770   int idLower = 0;
771   int idUpper = 0;
772   int idRight = 0;
773   int idLeft = 0;
774   
775   for(b=0;b<fCentralCountB;b++){
776     idCentral = fCentralChargeB[b];
777
778     if(fPadData[idCentral].fIY==0)
779       idLower = 0;
780     else
781       idLower = fGetIdTotalData[fPadData[idCentral].fIX][fPadData[idCentral].fIY-1][0];
782     
783     if(fPadData[idCentral].fIY==236)
784       idUpper = 0;
785     else
786       idUpper = fGetIdTotalData[fPadData[idCentral].fIX][fPadData[idCentral].fIY+1][0];
787
788     
789     fTotChargeY[b] = (fPadData[idCentral].fCharge + fPadData[idUpper].fCharge + fPadData[idLower].fCharge);
790     if(fTotChargeY[b]==0.0) continue;
791     fAvgChargeY[b] = fTotChargeY[b]/3.0 ;
792
793     fRecY[b] = (fPadData[idCentral].fRealY*fPadData[idCentral].fCharge
794                +
795                 fPadData[idUpper].fRealY*fPadData[idUpper].fCharge
796                +
797                 fPadData[idLower].fRealY*fPadData[idLower].fCharge
798                 )/fTotChargeY[b];//(fPadData[idCentral].fCharge + fPadData[idUpper].fCharge + fPadData[idLower].fCharge) ;
799     
800     fNofBChannel[b] = 0;
801     fNofYNeighbour[b] = 0;
802     if(fPadData[idLower].fCharge>0.0){
803       fNofBChannel[b]++ ;
804       fNofYNeighbour[b]++;
805     }
806     if(fPadData[idCentral].fCharge>0.0)
807       fNofBChannel[b]++ ;
808     if(fPadData[idUpper].fCharge>0.0){
809       fNofBChannel[b]++ ;
810       fNofYNeighbour[b]++;
811     }
812
813     HLTDebug("detelem : %d, Y charge : lower : %f, middle : %f, upper : %f",fPadData[idCentral].fDetElemId,fPadData[idLower].fCharge,
814             fPadData[idCentral].fCharge,fPadData[idUpper].fCharge);
815
816     //collect left coloumn
817     if((fPadData[idCentral].fIX-1)>=0){
818       
819       idLeft = fGetIdTotalData[fPadData[idCentral].fIX-1][fPadData[idCentral].fIY][0];
820       
821       if(fPadData[idLeft].fIY==0)
822         idLower = 0;
823       else
824         idLower = fGetIdTotalData[fPadData[idLeft].fIX][fPadData[idLeft].fIY-1][0];
825       
826       if(fPadData[idLeft].fIY==236)
827         idUpper = 0;
828       else
829         idUpper = fGetIdTotalData[fPadData[idLeft].fIX][fPadData[idLeft].fIY+1][0];
830
831       fTotChargeY[b] += (fPadData[idLeft].fCharge + fPadData[idUpper].fCharge + fPadData[idLower].fCharge);
832
833       if(fPadData[idLower].fCharge>0.0)
834         fNofBChannel[b]++ ;
835       if(fPadData[idLeft].fCharge>0.0)
836         fNofBChannel[b]++ ;
837       if(fPadData[idUpper].fCharge>0.0)
838         fNofBChannel[b]++ ;
839
840     }
841     ////////////////////////////////////////////////////
842
843     //collect right coloumn
844     if((fPadData[idCentral].fIX+1)<=335){
845
846       idRight = fGetIdTotalData[fPadData[idCentral].fIX+1][fPadData[idCentral].fIY][0];
847     
848       if(fPadData[idRight].fIY==0)
849         idLower = 0;
850       else
851         idLower = fGetIdTotalData[fPadData[idRight].fIX][fPadData[idRight].fIY-1][0];
852       
853       if(fPadData[idRight].fIY==236)
854         idUpper = 0;
855       else
856         idUpper = fGetIdTotalData[fPadData[idRight].fIX][fPadData[idRight].fIY+1][0];
857   
858       fTotChargeY[b] += (fPadData[idRight].fCharge + fPadData[idUpper].fCharge + fPadData[idLower].fCharge);
859
860       if(fPadData[idLower].fCharge>0.0)
861         fNofBChannel[b]++ ;
862       if(fPadData[idRight].fCharge>0.0)
863         fNofBChannel[b]++ ;
864       if(fPadData[idUpper].fCharge>0.0)
865         fNofBChannel[b]++ ;
866
867     }
868     //////////////////////////////////////////////////////////////////////////////////
869     HLTDebug("RecY[%d] : %f, nofChannel : %d, detelem : %d",b,fRecY[b],fNofBChannel[b],fPadData[idCentral].fDetElemId);
870    
871   }
872       
873   for(nb=0;nb<fCentralCountNB;nb++){
874     idCentral = fCentralChargeNB[nb];
875
876     if(fPadData[idCentral].fIX==0)
877       idLeft = 0;
878     else
879       idLeft = fGetIdTotalData[fPadData[idCentral].fIX-1][fPadData[idCentral].fIY][1];
880     
881     if(fPadData[idCentral].fIX==335)
882       idRight = 0 ;
883     else
884       idRight = fGetIdTotalData[fPadData[idCentral].fIX+1][fPadData[idCentral].fIY][1];
885
886     fTotChargeX[nb] = (fPadData[idCentral].fCharge + fPadData[idRight].fCharge + fPadData[idLeft].fCharge);
887     if(fTotChargeX[nb]==0.0) continue;
888     fAvgChargeX[nb] = fTotChargeX[nb]/3.0 ;
889     
890     fRecX[nb] = (fPadData[idCentral].fRealX*fPadData[idCentral].fCharge
891                  +
892                  fPadData[idRight].fRealX*fPadData[idRight].fCharge
893                  +
894                  fPadData[idLeft].fRealX*fPadData[idLeft].fCharge
895                  )/fTotChargeX[nb];//(fPadData[idCentral].fCharge + fPadData[idRight].fCharge + fPadData[idLeft].fCharge);
896     
897
898     fNofNBChannel[nb] = 0;
899     if(fPadData[idLeft].fCharge>0.0)
900       fNofNBChannel[nb]++ ;
901     if(fPadData[idCentral].fCharge>0.0)
902       fNofNBChannel[nb]++ ;
903     if(fPadData[idRight].fCharge>0.0)
904       fNofNBChannel[nb]++ ;
905     
906     HLTDebug("detelem : %d, X charge left : %f, middle : %f, right : %f",fPadData[idCentral].fDetElemId,fPadData[idLeft].fCharge,
907             fPadData[idCentral].fCharge,fPadData[idRight].fCharge);
908
909
910     // lower row 
911     if((fPadData[idCentral].fIY-1)>=0){
912
913       idLower = fGetIdTotalData[fPadData[idCentral].fIX][fPadData[idCentral].fIY-1][1];
914       
915       if(fPadData[idLower].fIX==0)
916         idLeft = 0;
917       else
918         idLeft = fGetIdTotalData[fPadData[idLower].fIX-1][fPadData[idLower].fIY][1];
919     
920       if(fPadData[idLower].fIX==335)
921         idRight = 0 ;
922       else
923         idRight = fGetIdTotalData[fPadData[idLower].fIX+1][fPadData[idLower].fIY][1];
924
925       fTotChargeX[nb] += (fPadData[idLower].fCharge + fPadData[idRight].fCharge + fPadData[idLeft].fCharge);
926
927       if(fPadData[idLeft].fCharge>0.0)
928         fNofNBChannel[nb]++ ;
929       if(fPadData[idLower].fCharge>0.0)
930         fNofNBChannel[nb]++ ;
931       if(fPadData[idRight].fCharge>0.0)
932         fNofNBChannel[nb]++ ;
933
934     }
935     ////////////////////////////////////////////////////////////
936
937     // Upper row
938     if((fPadData[idCentral].fIY+1)<=236){
939
940       idUpper = fGetIdTotalData[fPadData[idCentral].fIX][fPadData[idCentral].fIY+1][1];
941
942       if(fPadData[idUpper].fIX==0)
943         idLeft = 0;
944       else
945         idLeft = fGetIdTotalData[fPadData[idUpper].fIX-1][fPadData[idUpper].fIY][1];
946       
947       if(fPadData[idUpper].fIX==335)
948         idRight = 0 ;
949       else
950         idRight = fGetIdTotalData[fPadData[idUpper].fIX+1][fPadData[idUpper].fIY][1];
951       
952       fTotChargeX[nb] += (fPadData[idUpper].fCharge + fPadData[idRight].fCharge + fPadData[idLeft].fCharge);
953       
954       if(fPadData[idLeft].fCharge>0.0)
955         fNofNBChannel[nb]++ ;
956       if(fPadData[idRight].fCharge>0.0)
957         fNofNBChannel[nb]++ ;
958       if(fPadData[idRight].fCharge>0.0)
959         fNofNBChannel[nb]++ ;
960
961     }
962     ////////////////////////////////////////////////////////////
963
964     HLTDebug("RecX[%d] : %f, nofChannel : %d",nb,fRecX[nb],fNofNBChannel[nb]);
965
966    
967
968   }
969 }
970
971
972 bool AliHLTMUONHitReconstructor::MergeQuadRecHits()
973 {
974   // Merge reconstructed hits first over same plane then bending plane with non-bending plane
975
976   assert( fRecX != NULL );
977   assert( fRecY != NULL );
978   assert( fAvgChargeX != NULL );
979   assert( fAvgChargeY != NULL );
980   assert( fTotChargeX != NULL );
981   assert( fTotChargeY != NULL );
982   assert( fNofBChannel != NULL );
983   assert( fNofNBChannel != NULL );
984   assert( fNofYNeighbour  != NULL );
985
986   int idCentralB=0,idCentralNB=0 ;
987   float padCenterXB;
988   float padCenterYNB;
989   float diffX,diffY;
990   float minPadArea;
991   float halfPadLengthX,halfPadLengthY;
992   bool *isMergedY = new bool[fCentralCountB];
993   bool *isMergedX = new bool[fCentralCountNB];
994   float outsideSpacePoint = 1000000.0 ; /// A space point outside the detector
995
996   // MERGE Bending Plane hits, which are placed side by side
997   for(int i=0;i<fCentralCountB-1;i++){
998     isMergedY[i] = false;
999     if(fRecY[i] != outsideSpacePoint){
1000       for(int j=i+1;j<fCentralCountB;j++){
1001                  
1002         if(fCentralChargeB[i]==fCentralChargeB[j]){
1003           fRecY[j] = outsideSpacePoint;
1004           continue;
1005         }
1006         else if(
1007            (
1008             fPadData[fCentralChargeB[i]].fIY == fPadData[fCentralChargeB[j]].fIY
1009             )
1010            &&
1011            (
1012             fPadData[fCentralChargeB[i]].fIX == fPadData[fCentralChargeB[j]].fIX + 1
1013             ||
1014             fPadData[fCentralChargeB[i]].fIX == fPadData[fCentralChargeB[j]].fIX - 1
1015             )
1016            &&
1017            fRecY[j] != outsideSpacePoint
1018            &&
1019            fRecY[i] != outsideSpacePoint
1020            ){
1021
1022           if(fAvgChargeY[i] > fAvgChargeY[j]){
1023             fRecY[i] = (fRecY[i]*fAvgChargeY[i] + fRecY[j]*fAvgChargeY[j]
1024                         )/(fAvgChargeY[i] + fAvgChargeY[j]);
1025             fRecY[j] = outsideSpacePoint;
1026           }
1027           else{
1028             fRecY[j] = (fRecY[i]*fAvgChargeY[i] + fRecY[j]*fAvgChargeY[j]
1029                         )/(fAvgChargeY[i] + fAvgChargeY[j]);
1030             fRecY[i] = outsideSpacePoint;
1031
1032           }// search for higher charge
1033         }//pad position
1034       }//j for loop
1035     }//if fRecY[i] != outsideSpacePoint
1036   }// i for loop
1037   isMergedY[fCentralCountB-1] = false;
1038   
1039   // MERGE Non Bending Plane hits, which are placed side by side
1040   for(int i=0;i<fCentralCountNB-1;i++){
1041     isMergedX[i] = false;
1042     if(fRecX[i] != outsideSpacePoint){
1043       for(int j=i+1;j<fCentralCountNB;j++){
1044
1045         if(fCentralChargeNB[i]==fCentralChargeNB[j]){
1046           fRecX[j] = outsideSpacePoint;
1047           continue;
1048         }
1049         else if(
1050            (
1051             fPadData[fCentralChargeNB[i]].fIX == fPadData[fCentralChargeNB[j]].fIX
1052             )
1053            &&
1054            (
1055             fPadData[fCentralChargeNB[i]].fIY == fPadData[fCentralChargeNB[j]].fIY + 1
1056             ||
1057             fPadData[fCentralChargeNB[i]].fIY == fPadData[fCentralChargeNB[j]].fIY - 1
1058             )
1059            &&
1060            fRecX[j] != outsideSpacePoint
1061            &&
1062            fRecX[i] != outsideSpacePoint
1063            ){
1064
1065           if(fAvgChargeX[i] > fAvgChargeX[j]){
1066             fRecX[i] = (fRecX[i]*fAvgChargeX[i] + fRecX[j]*fAvgChargeX[j]
1067                        )/(fAvgChargeX[i] + fAvgChargeX[j]);
1068             fRecX[j] = outsideSpacePoint;
1069           }
1070           else{
1071             fRecX[j] = (fRecX[i]*fAvgChargeX[i] + fRecX[j]*fAvgChargeX[j]
1072                        )/(fAvgChargeX[i] + fAvgChargeX[j]);
1073             fRecX[i] = outsideSpacePoint;
1074           }// search for higher charge
1075         }//pad position
1076       }//j for loop
1077     }//if fRecX[i] != outsideSpacePoint
1078   }// i for loop
1079   isMergedX[fCentralCountNB-1] = false;
1080   
1081   // Merge bending Plane hits with Non Bending
1082   for(int b=0;b<fCentralCountB;b++){
1083     if(fRecY[b]!=outsideSpacePoint){
1084       idCentralB = fCentralChargeB[b];
1085       padCenterXB = fPadData[idCentralB].fRealX; 
1086       
1087       halfPadLengthX = fPadData[idCentralB].fHalfPadSize ;
1088
1089       for(int nb=0;nb<fCentralCountNB;nb++){
1090         if(fRecX[nb]!=outsideSpacePoint){
1091           idCentralNB = fCentralChargeNB[nb];
1092
1093           padCenterYNB = fPadData[idCentralNB].fRealY;
1094
1095           halfPadLengthY = fPadData[idCentralNB].fHalfPadSize ;
1096
1097           if(fabsf(fRecX[nb]) > fabsf(padCenterXB))
1098             diffX = fabsf(fRecX[nb]) -  fabsf(padCenterXB);
1099           else
1100             diffX = fabsf(padCenterXB) -  fabsf(fRecX[nb]);
1101           
1102           if(fabsf(padCenterYNB)>fabsf(fRecY[b]))
1103             diffY = fabsf(padCenterYNB) - fabsf(fRecY[b]);
1104           else
1105             diffY =  fabsf(fRecY[b]) - fabsf(padCenterYNB);
1106
1107           if(diffX < halfPadLengthX && diffY < halfPadLengthY ){//&& fPadData[idCentralB].fIY != 0){
1108             
1109             isMergedY[b] = true;
1110             isMergedX[nb] = true;
1111             
1112             if(fNofYNeighbour[b]==2){
1113               if(fPadData[idCentralB].fDetElemId<104)
1114                 fRecY[b] += 0.02*sin(14.5*(fRecY[b] - fPadData[idCentralB].fRealY)) ;
1115               else if(fPadData[idCentralB].fDetElemId>=200 && fPadData[idCentralB].fDetElemId<204)
1116                 fRecY[b] += 0.02*sin(14.0*(fRecY[b] - fPadData[idCentralB].fRealY)) ;
1117               else
1118                 fRecY[b] += 0.025*sin(12.0*(fRecY[b] - fPadData[idCentralB].fRealY)) ;
1119             }
1120             
1121             if(fPadData[idCentralNB].fDetElemId<204)
1122               fRecX[nb] += 0.095*sin(10.5*(fRecX[nb] - fPadData[idCentralNB].fRealX)) ;
1123             else //if(fPadData[idCentralNB].fDetElemId>=300 && fPadData[idCentralNB].fDetElemId<404)
1124               fRecX[nb] += 0.085*sin(9.0*(fRecX[nb] - fPadData[idCentralNB].fRealX)) ;
1125             
1126             
1127             // First check that we have not overflowed the buffer.
1128             if((*fRecPointsCount) == fMaxRecPointsCount){
1129               HLTWarning("Number of RecHits (i.e. %d) exceeds the max number of RecHit limit %d."
1130                         " Output buffer is too small.",
1131                        (*fRecPointsCount),fMaxRecPointsCount
1132               );
1133               delete [] isMergedY;
1134               delete [] isMergedX;
1135               return true;
1136             }
1137
1138             AliHLTUInt32_t idflags = AliHLTMUONUtils::PackRecHitFlags(
1139                  (fPadData[idCentralB].fDetElemId / 100) - 1,
1140                  fPadData[idCentralB].fDetElemId
1141               );
1142             fRecPoints[(*fRecPointsCount)].fFlags = idflags;
1143             fRecPoints[(*fRecPointsCount)].fX = fRecX[nb];
1144             fRecPoints[(*fRecPointsCount)].fY = fRecY[b];
1145             fRecPoints[(*fRecPointsCount)].fZ = fPadData[idCentralB].fRealZ;
1146             
1147             if (fGenerateClusterInfo)
1148             {
1149               if (fClusterCount >= fMaxClusters)
1150               {
1151                 HLTError("Ran out of space in internal cluster array of size %d.", fMaxClusters);
1152                 delete [] isMergedY;
1153                 delete [] isMergedX;
1154                 return false;
1155               }
1156               
1157               fClusters[fClusterCount].fId = (fNewClusterId << 5) | fDDL;
1158               
1159               // Increment the cluster ID and warp it around at 0x03FFFFFF since
1160               // the bottom 5 bits are filled with the source DDL number and the
1161               // sign bit in fClusters[fClusterCount].fId must be positive.
1162               fNewClusterId = (fNewClusterId + 1) & 0x03FFFFFF;
1163               
1164               fClusters[fClusterCount].fHit = fRecPoints[(*fRecPointsCount)];
1165               fClusters[fClusterCount].fDetElemId = fPadData[idCentralB].fDetElemId;
1166               fClusters[fClusterCount].fNchannelsB = fNofBChannel[b];
1167               fClusters[fClusterCount].fNchannelsNB = fNofNBChannel[nb];
1168               fClusters[fClusterCount].fChargeB = fTotChargeY[b];
1169               fClusters[fClusterCount].fChargeNB = fTotChargeX[nb];
1170               fClusterCount++;
1171             }
1172             
1173             if (fGenerateChannelInfo)
1174             {
1175               // 3 by 3 pad structure around the central pad for the 2 planes.
1176               int pad[2][3][3] = {{
1177                   {0,      0,      0},
1178                   {0, idCentralB,  0},
1179                   {0,      0,      0}
1180                 },{
1181                   {0,      0,      0},
1182                   {0, idCentralNB, 0},
1183                   {0,      0,      0}
1184               }};
1185               
1186               // Find the pad index numbers for the central pads and the pads surrounding them.
1187               // All these pads would have contributed to the cluster as long as their charge is != 0.
1188               if (fPadData[idCentralB].fIY > 0)
1189                 pad[0][0][1] = fGetIdTotalData[fPadData[idCentralB].fIX][fPadData[idCentralB].fIY-1][0];
1190               if (fPadData[idCentralB].fIY < 236)
1191                 pad[0][2][1] = fGetIdTotalData[fPadData[idCentralB].fIX][fPadData[idCentralB].fIY+1][0];
1192               if (fPadData[idCentralB].fIX > 0)
1193               {
1194                 int idLeft = fGetIdTotalData[fPadData[idCentralB].fIX-1][fPadData[idCentralB].fIY][0];
1195                 pad[0][1][0] = idLeft;
1196                 if (fPadData[idLeft].fIY > 0)
1197                   pad[0][0][0] = fGetIdTotalData[fPadData[idLeft].fIX][fPadData[idLeft].fIY-1][0];
1198                 if (fPadData[idLeft].fIY < 236)
1199                   pad[0][2][0] = fGetIdTotalData[fPadData[idLeft].fIX][fPadData[idLeft].fIY+1][0];
1200               }
1201               if (fPadData[idCentralB].fIX < 335)
1202               {
1203                 int idRight = fGetIdTotalData[fPadData[idCentralB].fIX+1][fPadData[idCentralB].fIY][0];
1204                 pad[0][1][2] = idRight;
1205                 if (fPadData[idRight].fIY > 0)
1206                   pad[0][0][2] = fGetIdTotalData[fPadData[idRight].fIX][fPadData[idRight].fIY-1][0];
1207                 if (fPadData[idRight].fIY < 236)
1208                   pad[0][2][2] = fGetIdTotalData[fPadData[idRight].fIX][fPadData[idRight].fIY+1][0];
1209               }
1210               
1211               if (fPadData[idCentralNB].fIX > 0)
1212                 pad[1][1][0] = fGetIdTotalData[fPadData[idCentralNB].fIX-1][fPadData[idCentralNB].fIY][1];
1213               if (fPadData[idCentralNB].fIX < 335)
1214                 pad[1][1][2] = fGetIdTotalData[fPadData[idCentralNB].fIX+1][fPadData[idCentralNB].fIY][1];
1215               if (fPadData[idCentralNB].fIY > 0)
1216               {
1217                 int idLower = fGetIdTotalData[fPadData[idCentralNB].fIX][fPadData[idCentralNB].fIY-1][1];
1218                 pad[1][0][1] = idLower;
1219                 if (fPadData[idLower].fIX > 0)
1220                   pad[1][0][0] = fGetIdTotalData[fPadData[idLower].fIX-1][fPadData[idLower].fIY][1];
1221                 if (fPadData[idLower].fIX < 335)
1222                   pad[1][0][2] = fGetIdTotalData[fPadData[idLower].fIX+1][fPadData[idLower].fIY][1];
1223               }
1224               if (fPadData[idCentralNB].fIY < 236)
1225               {
1226                 int idUpper = fGetIdTotalData[fPadData[idCentralNB].fIX][fPadData[idCentralNB].fIY+1][1];
1227                 pad[1][2][1] = idUpper;
1228                 if (fPadData[idUpper].fIX > 0)
1229                   pad[1][2][0] = fGetIdTotalData[fPadData[idUpper].fIX-1][fPadData[idUpper].fIY][1];
1230                 if (fPadData[idUpper].fIX < 335)
1231                   pad[1][2][2] = fGetIdTotalData[fPadData[idUpper].fIX+1][fPadData[idUpper].fIY][1];
1232               }
1233               
1234               AliHLTInt32_t clusterId = fGenerateClusterInfo ? fClusters[fClusterCount-1].fId : -1;
1235               
1236               // Now generate the pad structures from all the pad indices found above.
1237               for (int i = 0; i < 2; i++)
1238               for (int j = 0; j < 3; j++)
1239               for (int k = 0; k < 3; k++)
1240               {
1241                 AliHLTMUONPad& p = fPadData[pad[i][j][k]];
1242                 // Skip pads that have zero charge because they would not have
1243                 // contributed to the cluster.
1244                 if (p.fCharge <= 0) continue;
1245                 
1246                 UShort_t manuId; UChar_t channelId; UShort_t adc;
1247                 AliHLTMUONRawDecoder::UnpackADC(p.fRawData, manuId, channelId, adc);
1248                 
1249                 fChannels[fChannelCount].fClusterId = clusterId;
1250                 fChannels[fChannelCount].fBusPatch = p.fBusPatch;
1251                 fChannels[fChannelCount].fManu = manuId;
1252                 fChannels[fChannelCount].fChannelAddress = channelId;
1253                 fChannels[fChannelCount].fSignal = adc;
1254                 fChannels[fChannelCount].fRawDataWord = p.fRawData;
1255                 fChannelCount++;
1256               }
1257             }
1258
1259             HLTDebug("Part 1 : Reconstructed hit (X,Y,Z) : (%f,%f,%f)",
1260                      fRecPoints[(*fRecPointsCount)].fX,
1261                      fRecPoints[(*fRecPointsCount)].fY,
1262                      fRecPoints[(*fRecPointsCount)].fZ
1263             );
1264             (*fRecPointsCount)++;
1265           }//if lies wihtin 5.0 mm
1266         }// condn over fRecX ! = 0.0
1267       }// loop over NB side
1268     }// condn on fRecY[b] !=  0.0
1269   }// loop over B side;
1270   
1271   //Hit only in bending plane and in zone 1 which has not merged and which has number of channels > 2 are considered as valid hits
1272   for(int b=0;b<fCentralCountB;b++){
1273     if(fRecY[b]!=outsideSpacePoint and !isMergedY[b] and fNofBChannel[b]>2){
1274       idCentralB = fCentralChargeB[b];
1275       
1276       minPadArea = (fPadData[idCentralB].fDetElemId < 204) ? 10.0*2.0*0.315*10.0*2.0*0.21 : 10.0*2.0*0.375*10.0*2.0*0.25 ;
1277
1278       if(TMath::Abs(400.0*fPadData[idCentralB].fHalfPadSize*fPadData[idCentralB].fPadSizeXY - minPadArea)> 1.0e-5) continue;
1279       
1280       if(fNofYNeighbour[b]==2){
1281         if(fPadData[idCentralB].fDetElemId<104)
1282           fRecY[b] += 0.02*sin(14.5*(fRecY[b] - fPadData[idCentralB].fRealY)) ;
1283         else if(fPadData[idCentralB].fDetElemId>=200 && fPadData[idCentralB].fDetElemId<204)
1284           fRecY[b] += 0.02*sin(14.0*(fRecY[b] - fPadData[idCentralB].fRealY)) ;
1285         else
1286           fRecY[b] += 0.025*sin(12.0*(fRecY[b] - fPadData[idCentralB].fRealY)) ;
1287       }
1288       
1289       padCenterXB = fPadData[idCentralB].fRealX; 
1290       // if(fPadData[idCentralB].fDetElemId<204)
1291       //        padCenterXB += 0.095*sin(10.5*(padCenterXB - fPadData[idCentralB].fRealX)) ;
1292       // else //if(fPadData[idCentralNB].fDetElemId>=300 && fPadData[idCentralNB].fDetElemId<404)
1293       //        padCenterXB += 0.085*sin(9.0*(padCenterXB - fPadData[idCentralB].fRealX)) ;
1294             
1295       // First check that we have not overflowed the buffer.
1296       if((*fRecPointsCount) == fMaxRecPointsCount){
1297         HLTWarning("Number of RecHits (i.e. %d) exceeds the max number of RecHit limit %d."
1298                  " Output buffer is too small.",
1299                  (*fRecPointsCount),fMaxRecPointsCount
1300                  );
1301         delete [] isMergedY;
1302         delete [] isMergedX;
1303         return true;
1304       }
1305       
1306       AliHLTUInt32_t idflags = AliHLTMUONUtils::PackRecHitFlags(
1307                  (fPadData[idCentralB].fDetElemId / 100) - 1,
1308                  fPadData[idCentralB].fDetElemId
1309               );
1310       fRecPoints[(*fRecPointsCount)].fFlags = idflags;
1311       fRecPoints[(*fRecPointsCount)].fX = padCenterXB;
1312       fRecPoints[(*fRecPointsCount)].fY = fRecY[b];
1313       fRecPoints[(*fRecPointsCount)].fZ = fPadData[idCentralB].fRealZ;
1314             
1315       if (fGenerateClusterInfo)
1316         {
1317           if (fClusterCount >= fMaxClusters)
1318             {
1319               HLTError("Ran out of space in internal cluster array of size %d.", fMaxClusters);
1320               delete [] isMergedY;
1321               delete [] isMergedX;
1322               return false;
1323             }
1324               
1325           fClusters[fClusterCount].fId = (fNewClusterId << 5) | fDDL;
1326               
1327           // Increment the cluster ID and warp it around at 0x03FFFFFF since
1328           // the bottom 5 bits are filled with the source DDL number and the
1329           // sign bit in fClusters[fClusterCount].fId must be positive.
1330           fNewClusterId = (fNewClusterId + 1) & 0x03FFFFFF;
1331           
1332           fClusters[fClusterCount].fHit = fRecPoints[(*fRecPointsCount)];
1333           fClusters[fClusterCount].fDetElemId = fPadData[idCentralB].fDetElemId;
1334           fClusters[fClusterCount].fNchannelsB = fNofBChannel[b];
1335           fClusters[fClusterCount].fNchannelsNB = fNofBChannel[b];
1336           fClusters[fClusterCount].fChargeB = fTotChargeY[b];
1337           fClusters[fClusterCount].fChargeNB = fTotChargeY[b];
1338           fClusterCount++;
1339         }
1340       
1341       if (fGenerateChannelInfo)
1342         {
1343           // 3 by 3 pad structure around the central pad for the 2 planes.
1344           int pad[2][3][3] = {{
1345               {0,      0,      0},
1346               {0, idCentralB,  0},
1347               {0,      0,      0}
1348             },{
1349               {0,      0,      0},
1350               {0,      0     , 0},
1351               {0,      0,      0}
1352             }};
1353           
1354           // Find the pad index numbers for the central pads and the pads surrounding them.
1355           // All these pads would have contributed to the cluster as long as their charge is != 0.
1356           if (fPadData[idCentralB].fIY > 0)
1357             pad[0][0][1] = fGetIdTotalData[fPadData[idCentralB].fIX][fPadData[idCentralB].fIY-1][0];
1358           if (fPadData[idCentralB].fIY < 236)
1359             pad[0][2][1] = fGetIdTotalData[fPadData[idCentralB].fIX][fPadData[idCentralB].fIY+1][0];
1360           if (fPadData[idCentralB].fIX > 0)
1361             {
1362               int idLeft = fGetIdTotalData[fPadData[idCentralB].fIX-1][fPadData[idCentralB].fIY][0];
1363               pad[0][1][0] = idLeft;
1364               if (fPadData[idLeft].fIY > 0)
1365                 pad[0][0][0] = fGetIdTotalData[fPadData[idLeft].fIX][fPadData[idLeft].fIY-1][0];
1366               if (fPadData[idLeft].fIY < 236)
1367                 pad[0][2][0] = fGetIdTotalData[fPadData[idLeft].fIX][fPadData[idLeft].fIY+1][0];
1368             }
1369           if (fPadData[idCentralB].fIX < 335)
1370             {
1371               int idRight = fGetIdTotalData[fPadData[idCentralB].fIX+1][fPadData[idCentralB].fIY][0];
1372               pad[0][1][2] = idRight;
1373               if (fPadData[idRight].fIY > 0)
1374                 pad[0][0][2] = fGetIdTotalData[fPadData[idRight].fIX][fPadData[idRight].fIY-1][0];
1375               if (fPadData[idRight].fIY < 236)
1376                 pad[0][2][2] = fGetIdTotalData[fPadData[idRight].fIX][fPadData[idRight].fIY+1][0];
1377             }
1378
1379           // For hits only in bending plane no need to copy the information to the non-bending side
1380           // for(int i=0;i<3;i++)
1381           //   for(int j=0;j<3;j++)
1382           //     pad[1][i][j] = pad[0][i][j];
1383
1384               
1385           AliHLTInt32_t clusterId = fGenerateClusterInfo ? fClusters[fClusterCount-1].fId : -1;
1386           
1387           // Now generate the pad structures from all the pad indices found above.
1388           for (int i = 0; i < 1; i++)
1389             for (int j = 0; j < 3; j++)
1390               for (int k = 0; k < 3; k++)
1391                 {
1392                   AliHLTMUONPad& p = fPadData[pad[i][j][k]];
1393                   // Skip pads that have zero charge because they would not have
1394                   // contributed to the cluster.
1395                   if (p.fCharge <= 0) continue;
1396                   
1397                   UShort_t manuId; UChar_t channelId; UShort_t adc;
1398                   AliHLTMUONRawDecoder::UnpackADC(p.fRawData, manuId, channelId, adc);
1399                   
1400                   fChannels[fChannelCount].fClusterId = clusterId;
1401                   fChannels[fChannelCount].fBusPatch = p.fBusPatch;
1402                   fChannels[fChannelCount].fManu = manuId;
1403                   fChannels[fChannelCount].fChannelAddress = channelId;
1404                   fChannels[fChannelCount].fSignal = adc;
1405                   fChannels[fChannelCount].fRawDataWord = p.fRawData;
1406                   fChannelCount++;
1407                 }
1408         }
1409       
1410       HLTDebug("Part 2 : Reconstructed hit (X,Y,Z) : (%f,%f,%f)",
1411                fRecPoints[(*fRecPointsCount)].fX,
1412                fRecPoints[(*fRecPointsCount)].fY,
1413                fRecPoints[(*fRecPointsCount)].fZ
1414                );
1415       (*fRecPointsCount)++;
1416
1417     }// condn on fRecY[b] !=  0.0
1418   }// loop over B side;
1419
1420
1421   //Hit only in non-bending plane and in zone 1 which has not merged and which has number of channels > 2 are considered as valid hits
1422   for(int nb=0;nb<fCentralCountNB;nb++){
1423
1424     idCentralNB = fCentralChargeNB[nb];
1425     if(fRecX[nb]!=outsideSpacePoint and !isMergedX[nb] and fNofNBChannel[nb]>2){
1426       
1427       minPadArea = (fPadData[idCentralNB].fDetElemId < 204) ? 10.0*2.0*0.315*10.0*2.0*0.21 : 10.0*2.0*0.375*10.0*2.0*0.25 ;
1428
1429       if(TMath::Abs(400.0*fPadData[idCentralNB].fHalfPadSize*fPadData[idCentralNB].fPadSizeXY - minPadArea)> 1.0e-5) continue;
1430       
1431       padCenterYNB = fPadData[idCentralNB].fRealY;
1432       
1433       
1434       // if(fPadData[idCentralNB].fDetElemId<104)
1435       //        padCenterYNB += 0.02*sin(14.5*(padCenterYNB - fPadData[idCentralNB].fRealY)) ;
1436       // else if(fPadData[idCentralNB].fDetElemId>=200 && fPadData[idCentralNB].fDetElemId<204)
1437       //        padCenterYNB += 0.02*sin(14.0*(padCenterYNB - fPadData[idCentralNB].fRealY)) ;
1438       // else
1439       //        padCenterYNB += 0.025*sin(12.0*(padCenterYNB - fPadData[idCentralNB].fRealY)) ;
1440       
1441       
1442       if(fPadData[idCentralNB].fDetElemId<204)
1443         fRecX[nb] += 0.095*sin(10.5*(fRecX[nb] - fPadData[idCentralNB].fRealX)) ;
1444       else //if(fPadData[idCentralNB].fDetElemId>=300 && fPadData[idCentralNB].fDetElemId<404)
1445         fRecX[nb] += 0.085*sin(9.0*(fRecX[nb] - fPadData[idCentralNB].fRealX)) ;
1446       
1447       
1448       // First check that we have not overflowed the buffer.
1449       if((*fRecPointsCount) == fMaxRecPointsCount){
1450         HLTWarning("Number of RecHits (i.e. %d) exceeds the max number of RecHit limit %d."
1451                  " Output buffer is too small.",
1452                  (*fRecPointsCount),fMaxRecPointsCount
1453                  );
1454         delete [] isMergedY;
1455         delete [] isMergedX;
1456         return true;
1457       }
1458
1459       AliHLTUInt32_t idflags = AliHLTMUONUtils::PackRecHitFlags(
1460                  (fPadData[idCentralNB].fDetElemId / 100) - 1,
1461                  fPadData[idCentralNB].fDetElemId
1462               );
1463       fRecPoints[(*fRecPointsCount)].fFlags = idflags;
1464       fRecPoints[(*fRecPointsCount)].fX = fRecX[nb];
1465       fRecPoints[(*fRecPointsCount)].fY = padCenterYNB;
1466       fRecPoints[(*fRecPointsCount)].fZ = fPadData[idCentralNB].fRealZ;
1467       
1468       if (fGenerateClusterInfo)
1469         {
1470           if (fClusterCount >= fMaxClusters)
1471             {
1472               HLTError("Ran out of space in internal cluster array of size %d.", fMaxClusters);
1473               delete [] isMergedY;
1474               delete [] isMergedX;
1475               return false;
1476             }
1477           
1478           fClusters[fClusterCount].fId = (fNewClusterId << 5) | fDDL;
1479           
1480           // Increment the cluster ID and warp it around at 0x03FFFFFF since
1481           // the bottom 5 bits are filled with the source DDL number and the
1482           // sign bit in fClusters[fClusterCount].fId must be positive.
1483           fNewClusterId = (fNewClusterId + 1) & 0x03FFFFFF;
1484               
1485           fClusters[fClusterCount].fHit = fRecPoints[(*fRecPointsCount)];
1486           fClusters[fClusterCount].fDetElemId = fPadData[idCentralNB].fDetElemId;
1487           fClusters[fClusterCount].fNchannelsB = fNofNBChannel[nb];
1488           fClusters[fClusterCount].fNchannelsNB = fNofNBChannel[nb];
1489           fClusters[fClusterCount].fChargeB = fTotChargeX[nb];
1490           fClusters[fClusterCount].fChargeNB = fTotChargeX[nb];
1491           fClusterCount++;
1492         }
1493       
1494       if (fGenerateChannelInfo)
1495         {
1496           // 3 by 3 pad structure around the central pad for the 2 planes.
1497           int pad[2][3][3] = {{
1498               {0,      0,      0},
1499               {0,      0,      0},
1500               {0,      0,      0}
1501                 },{
1502               {0,      0,      0},
1503               {0, idCentralNB, 0},
1504               {0,      0,      0}
1505             }};
1506               
1507           // Find the pad index numbers for the central pads and the pads surrounding them.
1508           // All these pads would have contributed to the cluster as long as their charge is != 0.
1509               
1510           if (fPadData[idCentralNB].fIX > 0)
1511             pad[1][1][0] = fGetIdTotalData[fPadData[idCentralNB].fIX-1][fPadData[idCentralNB].fIY][1];
1512           if (fPadData[idCentralNB].fIX < 335)
1513             pad[1][1][2] = fGetIdTotalData[fPadData[idCentralNB].fIX+1][fPadData[idCentralNB].fIY][1];
1514           if (fPadData[idCentralNB].fIY > 0)
1515             {
1516               int idLower = fGetIdTotalData[fPadData[idCentralNB].fIX][fPadData[idCentralNB].fIY-1][1];
1517               pad[1][0][1] = idLower;
1518               if (fPadData[idLower].fIX > 0)
1519                 pad[1][0][0] = fGetIdTotalData[fPadData[idLower].fIX-1][fPadData[idLower].fIY][1];
1520               if (fPadData[idLower].fIX < 335)
1521                 pad[1][0][2] = fGetIdTotalData[fPadData[idLower].fIX+1][fPadData[idLower].fIY][1];
1522             }
1523           if (fPadData[idCentralNB].fIY < 236)
1524             {
1525               int idUpper = fGetIdTotalData[fPadData[idCentralNB].fIX][fPadData[idCentralNB].fIY+1][1];
1526                 pad[1][2][1] = idUpper;
1527                 if (fPadData[idUpper].fIX > 0)
1528                   pad[1][2][0] = fGetIdTotalData[fPadData[idUpper].fIX-1][fPadData[idUpper].fIY][1];
1529                 if (fPadData[idUpper].fIX < 335)
1530                   pad[1][2][2] = fGetIdTotalData[fPadData[idUpper].fIX+1][fPadData[idUpper].fIY][1];
1531             }
1532
1533           // For hits only in non-bending plane no need to copy the information to the bending side
1534           // for(int i=0;i<3;i++)
1535           //   for(int j=0;j<3;j++)
1536           //     pad[0][i][j] = pad[1][i][j];
1537           
1538               
1539           AliHLTInt32_t clusterId = fGenerateClusterInfo ? fClusters[fClusterCount-1].fId : -1;
1540           
1541           // Now generate the pad structures from all the pad indices found above.
1542           for (int i = 1; i < 2; i++)
1543             for (int j = 0; j < 3; j++)
1544               for (int k = 0; k < 3; k++)
1545                 {
1546                   AliHLTMUONPad& p = fPadData[pad[i][j][k]];
1547                   // Skip pads that have zero charge because they would not have
1548                   // contributed to the cluster.
1549                   if (p.fCharge <= 0) continue;
1550                   
1551                   UShort_t manuId; UChar_t channelId; UShort_t adc;
1552                   AliHLTMUONRawDecoder::UnpackADC(p.fRawData, manuId, channelId, adc);
1553                   
1554                   fChannels[fChannelCount].fClusterId = clusterId;
1555                   fChannels[fChannelCount].fBusPatch = p.fBusPatch;
1556                   fChannels[fChannelCount].fManu = manuId;
1557                   fChannels[fChannelCount].fChannelAddress = channelId;
1558                   fChannels[fChannelCount].fSignal = adc;
1559                   fChannels[fChannelCount].fRawDataWord = p.fRawData;
1560                   fChannelCount++;
1561                 }
1562         }
1563       
1564       HLTDebug("Part 3 : Reconstructed hit (X,Y,Z) : (%f,%f,%f), detelemId : %d",
1565                  fRecPoints[(*fRecPointsCount)].fX,
1566                  fRecPoints[(*fRecPointsCount)].fY,
1567                  fRecPoints[(*fRecPointsCount)].fZ,
1568                  fPadData[idCentralNB].fDetElemId
1569                  );
1570       (*fRecPointsCount)++;
1571     }//if lies wihtin 5.0 mm
1572   }// condn over fRecX ! = 0.0
1573
1574   delete [] isMergedY;
1575   delete [] isMergedX;
1576   
1577   return true;
1578 }
1579
1580 bool AliHLTMUONHitReconstructor::MergeSlatRecHits()
1581 {
1582   // Merge reconstructed hits first over same plane then bending plane with non-bending plane
1583
1584   assert( fRecX != NULL );
1585   assert( fRecY != NULL );
1586   assert( fAvgChargeX != NULL );
1587   assert( fAvgChargeY != NULL );
1588   assert( fTotChargeX != NULL );
1589   assert( fTotChargeY != NULL );
1590   assert( fNofBChannel != NULL );
1591   assert( fNofNBChannel != NULL );
1592   assert( fNofYNeighbour  != NULL );
1593
1594   int idCentralB,idCentralNB ;
1595   float padCenterXB;
1596   float padCenterYNB;
1597   float diffX,diffY;
1598   float halfPadLengthX,halfPadLengthY;
1599   bool *isMergedY = new bool[fCentralCountB];
1600   bool *isMergedX = new bool[fCentralCountNB];
1601   float outsideSpacePoint = 1000000.0 ; /// A space point outside the detector
1602
1603   // MERGE Bending Plane hits, which are placed side by side
1604   for(int i=0;i<fCentralCountB-1;i++){
1605     isMergedY[i] = false;
1606     if(fRecY[i] != outsideSpacePoint){
1607       for(int j=i+1;j<fCentralCountB;j++){
1608                  
1609         if(fCentralChargeB[i]==fCentralChargeB[j]){
1610           fRecY[j] = outsideSpacePoint;
1611           continue;
1612         }
1613         else if(
1614            (
1615             fPadData[fCentralChargeB[i]].fIY == fPadData[fCentralChargeB[j]].fIY
1616             )
1617            &&
1618            (
1619             fPadData[fCentralChargeB[i]].fIX == fPadData[fCentralChargeB[j]].fIX + 1
1620             ||
1621             fPadData[fCentralChargeB[i]].fIX == fPadData[fCentralChargeB[j]].fIX - 1
1622             )
1623            &&
1624            fRecY[j] != outsideSpacePoint
1625            &&
1626            fRecY[i] != outsideSpacePoint
1627            ){
1628
1629           if(fAvgChargeY[i] > fAvgChargeY[j]){
1630             fRecY[i] = (fRecY[i]*fAvgChargeY[i] + fRecY[j]*fAvgChargeY[j]
1631                         )/(fAvgChargeY[i] + fAvgChargeY[j]);
1632             fRecY[j] = outsideSpacePoint;
1633           }
1634           else{
1635             fRecY[j] = (fRecY[i]*fAvgChargeY[i] + fRecY[j]*fAvgChargeY[j]
1636                         )/(fAvgChargeY[i] + fAvgChargeY[j]);
1637             fRecY[i] = outsideSpacePoint;
1638
1639           }// search for higher charge
1640         }//pad position
1641       }//j for loop
1642     }//if fRecY[i] != outsideSpacePoint
1643   }// i for loop
1644   isMergedY[fCentralCountB-1] = false;
1645   
1646   // MERGE Non Bending Plane hits, which are placed side by side
1647   for(int i=0;i<fCentralCountNB-1;i++){
1648     isMergedX[i] = false;
1649     if(fRecX[i] != 0.0){
1650       for(int j=i+1;j<fCentralCountNB;j++){
1651
1652         if(fCentralChargeNB[i]==fCentralChargeNB[j]){
1653           fRecX[j] = outsideSpacePoint;
1654           continue;
1655         }
1656         else if(
1657            (
1658             fPadData[fCentralChargeNB[i]].fIX == fPadData[fCentralChargeNB[j]].fIX
1659             )
1660            &&
1661            (
1662             fPadData[fCentralChargeNB[i]].fIY == fPadData[fCentralChargeNB[j]].fIY + 1
1663             ||
1664             fPadData[fCentralChargeNB[i]].fIY == fPadData[fCentralChargeNB[j]].fIY - 1
1665             )
1666            &&
1667            fRecX[j] != outsideSpacePoint
1668            &&
1669            fRecX[i] != outsideSpacePoint
1670            ){
1671
1672           if(fAvgChargeX[i] > fAvgChargeX[j]){
1673             fRecX[i] = (fRecX[i]*fAvgChargeX[i] + fRecX[j]*fAvgChargeX[j]
1674                        )/(fAvgChargeX[i] + fAvgChargeX[j]);
1675             fRecX[j] = outsideSpacePoint;
1676           }
1677           else{
1678             fRecX[j] = (fRecX[i]*fAvgChargeX[i] + fRecX[j]*fAvgChargeX[j]
1679                        )/(fAvgChargeX[i] + fAvgChargeX[j]);
1680             fRecX[i] = outsideSpacePoint;
1681           }// search for higher charge
1682         }//pad position
1683       }//j for loop
1684     }//if fRecX[i] != outsideSpacePoint
1685   }// i for loop
1686   isMergedX[fCentralCountNB-1] = false;
1687
1688   // Merge bending Plane hits with Non Bending
1689   for(int b=0;b<fCentralCountB;b++){
1690     if(fRecY[b]!=outsideSpacePoint){
1691       idCentralB = fCentralChargeB[b];
1692       padCenterXB = fPadData[idCentralB].fRealX; 
1693       
1694       halfPadLengthX = fPadData[idCentralB].fHalfPadSize ;
1695
1696       for(int nb=0;nb<fCentralCountNB;nb++){
1697         if(fRecX[nb]!=outsideSpacePoint){
1698           idCentralNB = fCentralChargeNB[nb];
1699
1700           padCenterYNB = fPadData[idCentralNB].fRealY;
1701
1702           halfPadLengthY = fPadData[idCentralNB].fHalfPadSize ;
1703
1704           if(fabsf(fRecX[nb]) > fabsf(padCenterXB))
1705             diffX = fabsf(fRecX[nb]) -  fabsf(padCenterXB);
1706           else
1707             diffX = fabsf(padCenterXB) -  fabsf(fRecX[nb]);
1708           
1709           if(fabsf(padCenterYNB)>fabsf(fRecY[b]))
1710             diffY = fabsf(padCenterYNB) - fabsf(fRecY[b]);
1711           else
1712             diffY =  fabsf(fRecY[b]) - fabsf(padCenterYNB);
1713
1714           if(diffX < halfPadLengthX && diffY < halfPadLengthY ){//&& fPadData[idCentralB].fIY != 0){
1715             
1716             isMergedY[b] = true;
1717             isMergedX[nb] = true;
1718             
1719             if(fNofYNeighbour[b]==2){
1720               fRecY[b] += 0.025*sin(12.0*(fRecY[b] - fPadData[idCentralB].fRealY)) ;
1721             }
1722             
1723             fRecX[nb] += 0.075*sin(9.5*(fRecX[nb] - fPadData[idCentralNB].fRealX)) ;
1724             
1725             
1726             // First check that we have not overflowed the buffer.
1727             if((*fRecPointsCount) == fMaxRecPointsCount){
1728               HLTWarning("Number of RecHits (i.e. %d) exceeds the max number of RecHit limit %d."
1729                         " Output buffer is too small.",
1730                        (*fRecPointsCount),fMaxRecPointsCount
1731               );
1732               delete [] isMergedY;
1733               delete [] isMergedX;
1734               return true;
1735             }
1736
1737             AliHLTUInt32_t idflags = AliHLTMUONUtils::PackRecHitFlags(
1738                  (fPadData[idCentralB].fDetElemId / 100) - 1,
1739                  fPadData[idCentralB].fDetElemId
1740               );
1741             fRecPoints[(*fRecPointsCount)].fFlags = idflags;
1742             fRecPoints[(*fRecPointsCount)].fX = fRecX[nb];
1743             fRecPoints[(*fRecPointsCount)].fY = fRecY[b];
1744             fRecPoints[(*fRecPointsCount)].fZ = fPadData[idCentralB].fRealZ;
1745             
1746             if (fGenerateClusterInfo)
1747             {
1748               if (fClusterCount >= fMaxClusters)
1749               {
1750                 HLTError("Ran out of space in internal cluster array of size %d.", fMaxClusters);
1751                 delete [] isMergedY;
1752                 delete [] isMergedX;
1753                 return false;
1754               }
1755               
1756               fClusters[fClusterCount].fId = (fNewClusterId << 5) | fDDL;
1757               
1758               // Increment the cluster ID and warp it around at 0x03FFFFFF since
1759               // the bottom 5 bits are filled with the source DDL number and the
1760               // sign bit in fClusters[fClusterCount].fId must be positive.
1761               fNewClusterId = (fNewClusterId + 1) & 0x03FFFFFF;
1762               
1763               fClusters[fClusterCount].fHit = fRecPoints[(*fRecPointsCount)];
1764               fClusters[fClusterCount].fDetElemId = fPadData[idCentralB].fDetElemId;
1765               fClusters[fClusterCount].fNchannelsB = fNofBChannel[b];
1766               fClusters[fClusterCount].fNchannelsNB = fNofNBChannel[nb];
1767               fClusters[fClusterCount].fChargeB = fTotChargeY[b];
1768               fClusters[fClusterCount].fChargeNB = fTotChargeX[nb];
1769               fClusterCount++;
1770             }
1771             
1772             if (fGenerateChannelInfo)
1773             {
1774               // 3 by 3 pad structure around the central pad for the 2 planes.
1775               int pad[2][3][3] = {{
1776                   {0,      0,      0},
1777                   {0, idCentralB,  0},
1778                   {0,      0,      0}
1779                 },{
1780                   {0,      0,      0},
1781                   {0, idCentralNB, 0},
1782                   {0,      0,      0}
1783               }};
1784               
1785               // Find the pad index numbers for the central pads and the pads surrounding them.
1786               // All these pads would have contributed to the cluster as long as their charge is != 0.
1787               if (fPadData[idCentralB].fIY > 0)
1788                 pad[0][0][1] = fGetIdTotalData[fPadData[idCentralB].fIX][fPadData[idCentralB].fIY-1][0];
1789               if (fPadData[idCentralB].fIY < 236)
1790                 pad[0][2][1] = fGetIdTotalData[fPadData[idCentralB].fIX][fPadData[idCentralB].fIY+1][0];
1791               if (fPadData[idCentralB].fIX > 0)
1792               {
1793                 int idLeft = fGetIdTotalData[fPadData[idCentralB].fIX-1][fPadData[idCentralB].fIY][0];
1794                 pad[0][1][0] = idLeft;
1795                 if (fPadData[idLeft].fIY > 0)
1796                   pad[0][0][0] = fGetIdTotalData[fPadData[idLeft].fIX][fPadData[idLeft].fIY-1][0];
1797                 if (fPadData[idLeft].fIY < 236)
1798                   pad[0][2][0] = fGetIdTotalData[fPadData[idLeft].fIX][fPadData[idLeft].fIY+1][0];
1799               }
1800               if (fPadData[idCentralB].fIX < 335)
1801               {
1802                 int idRight = fGetIdTotalData[fPadData[idCentralB].fIX+1][fPadData[idCentralB].fIY][0];
1803                 pad[0][1][2] = idRight;
1804                 if (fPadData[idRight].fIY > 0)
1805                   pad[0][0][2] = fGetIdTotalData[fPadData[idRight].fIX][fPadData[idRight].fIY-1][0];
1806                 if (fPadData[idRight].fIY < 236)
1807                   pad[0][2][2] = fGetIdTotalData[fPadData[idRight].fIX][fPadData[idRight].fIY+1][0];
1808               }
1809               
1810               if (fPadData[idCentralNB].fIX > 0)
1811                 pad[1][1][0] = fGetIdTotalData[fPadData[idCentralNB].fIX-1][fPadData[idCentralNB].fIY][1];
1812               if (fPadData[idCentralNB].fIX < 335)
1813                 pad[1][1][2] = fGetIdTotalData[fPadData[idCentralNB].fIX+1][fPadData[idCentralNB].fIY][1];
1814               if (fPadData[idCentralNB].fIY > 0)
1815               {
1816                 int idLower = fGetIdTotalData[fPadData[idCentralNB].fIX][fPadData[idCentralNB].fIY-1][1];
1817                 pad[1][0][1] = idLower;
1818                 if (fPadData[idLower].fIX > 0)
1819                   pad[1][0][0] = fGetIdTotalData[fPadData[idLower].fIX-1][fPadData[idLower].fIY][1];
1820                 if (fPadData[idLower].fIX < 335)
1821                   pad[1][0][2] = fGetIdTotalData[fPadData[idLower].fIX+1][fPadData[idLower].fIY][1];
1822               }
1823               if (fPadData[idCentralNB].fIY < 236)
1824               {
1825                 int idUpper = fGetIdTotalData[fPadData[idCentralNB].fIX][fPadData[idCentralNB].fIY+1][1];
1826                 pad[1][2][1] = idUpper;
1827                 if (fPadData[idUpper].fIX > 0)
1828                   pad[1][2][0] = fGetIdTotalData[fPadData[idUpper].fIX-1][fPadData[idUpper].fIY][1];
1829                 if (fPadData[idUpper].fIX < 335)
1830                   pad[1][2][2] = fGetIdTotalData[fPadData[idUpper].fIX+1][fPadData[idUpper].fIY][1];
1831               }
1832               
1833               AliHLTInt32_t clusterId = fGenerateClusterInfo ? fClusters[fClusterCount-1].fId : -1;
1834               
1835               // Now generate the pad structures from all the pad indices found above.
1836               for (int i = 0; i < 2; i++)
1837               for (int j = 0; j < 3; j++)
1838               for (int k = 0; k < 3; k++)
1839               {
1840                 AliHLTMUONPad& p = fPadData[pad[i][j][k]];
1841                 // Skip pads that have zero charge because they would not have
1842                 // contributed to the cluster.
1843                 if (p.fCharge <= 0) continue;
1844                 
1845                 UShort_t manuId; UChar_t channelId; UShort_t adc;
1846                 AliHLTMUONRawDecoder::UnpackADC(p.fRawData, manuId, channelId, adc);
1847                 
1848                 fChannels[fChannelCount].fClusterId = clusterId;
1849                 fChannels[fChannelCount].fBusPatch = p.fBusPatch;
1850                 fChannels[fChannelCount].fManu = manuId;
1851                 fChannels[fChannelCount].fChannelAddress = channelId;
1852                 fChannels[fChannelCount].fSignal = adc;
1853                 fChannels[fChannelCount].fRawDataWord = p.fRawData;
1854                 fChannelCount++;
1855               }
1856             }
1857
1858             HLTDebug("Part 4(Slat) : Reconstructed hit (X,Y,Z) : (%f,%f,%f)",
1859                      fRecPoints[(*fRecPointsCount)].fX,
1860                      fRecPoints[(*fRecPointsCount)].fY,
1861                      fRecPoints[(*fRecPointsCount)].fZ
1862             );
1863             (*fRecPointsCount)++;
1864           }//if lies wihtin 5.0 mm
1865         }// condn over fRecX ! = 0.0
1866       }// loop over NB side
1867     }// condn on fRecY[b] !=  0.0
1868   }// loop over B side;
1869   
1870   
1871   delete [] isMergedY;
1872   delete [] isMergedX;
1873   return true;
1874 }
1875
1876
1877 void AliHLTMUONHitReconstructor::Clear()
1878 {
1879   // function to clear internal arrays.
1880
1881   HLTDebug("Clearing fPadData and fNofDataInDetElem buffers.");
1882
1883
1884   for(int iPad=1;iPad<fDigitPerDDL;iPad++){
1885     fGetIdTotalData[fPadData[iPad].fIX][fPadData[iPad].fIY][fPadData[iPad].fPlane] = 0;
1886     fPadData[iPad].fDetElemId = 0;
1887     fPadData[iPad].fIX = 0 ;
1888     fPadData[iPad].fIY = 0 ;
1889     fPadData[iPad].fRealX = 0.0 ;
1890     fPadData[iPad].fRealY = 0.0 ;
1891     fPadData[iPad].fRealZ = 0.0 ;
1892     fPadData[iPad].fHalfPadSize = -1 ;
1893     fPadData[iPad].fPlane = 0 ;
1894     fPadData[iPad].fCharge = 0 ;
1895     fPadData[iPad].fBusPatch = -1;
1896     fPadData[iPad].fRawData = 0;
1897   }  
1898
1899   for( Int_t idet=0;idet<GetkNofDetElemInDDL(fDDL);idet++)
1900     fNofDataInDetElem[idet] = 0;
1901   
1902   // for(int i=0;i<130;i++)
1903   //   fMaxFiredPerDetElem[i] = 0;
1904 }
1905
1906
1907 AliHLTInt32_t AliHLTMUONHitReconstructor::GetkNofDetElemInDDL(Int_t iDDL)
1908 {
1909         /// Returns the number of detection elements for a DDL.
1910         
1911         if(iDDL>=0 && iDDL<=19)
1912                 return fgkNofDetElemInDDL[iDDL];
1913         else
1914                 return -1;
1915 }
1916
1917
1918 AliHLTInt32_t AliHLTMUONHitReconstructor::GetkMinDetElemIdInDDL(Int_t iDDL)
1919 {
1920         /// Returns the first detection element ID for a DDL.
1921         
1922         if(iDDL>=0 && iDDL<=19)
1923                 return fgkMinDetElemIdInDDL[iDDL];
1924         else
1925                 return -1;
1926 }
1927
1928
1929 AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::AliHLTMUONRawDecoder() :
1930         fkBufferStart(NULL),
1931         fBusPatchId(0),
1932         fDCCut(-1),
1933         fPadData(NULL),
1934         fkLookUpTableData(NULL),
1935         fkIdToEntry(),
1936         fkMaxEntryPerBusPatch(),
1937         fDDL(-1),
1938         fDataCount(1),
1939         fPrevDetElemId(0),
1940         fPadCharge(0),
1941         fCharge(0.0),
1942         fIdManuChannel(0x0),
1943         fLutEntry(0),
1944         fDataCountListPerDetElem(NULL),
1945         fNofDataInDetElem(NULL),
1946         fWarnOnly(false),
1947         fSkipParityErrors(false),
1948         fDontPrintParityErrors(false),
1949         fPrintParityErrorAsWarning(false),
1950         fParityErrorFound(false),
1951         fNonParityErrorFound(false),
1952         fIsMuchNoisy(false)
1953 {
1954         // ctor
1955 }
1956
1957
1958 AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::~AliHLTMUONRawDecoder()
1959 {
1960         // dtor
1961 }
1962
1963
1964 void AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::OnNewBuffer(const void* buffer, UInt_t /*bufferSize*/)
1965 {
1966         /// Called for every new raw DDL data payload being processed.
1967         /// Just clears internal counters.
1968         /// \param buffer  The pointer to the raw data buffer.
1969
1970         assert( buffer != NULL );
1971         fkBufferStart = buffer;
1972         // dataCount starts from 1 because the 0-th element of fPadData is used as null value.
1973         fDataCount = 1;
1974         for( Int_t idet=0;idet<GetkNofDetElemInDDL(fDDL);idet++)
1975           fNofDataInDetElem[idet] = 0;
1976         fPrevDetElemId = 0;
1977         fParityErrorFound = false;
1978         fNonParityErrorFound = false;
1979 };
1980
1981
1982 void AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::OnError(ErrorCode code, const void* location)
1983 {
1984         /// Called if there was an error detected in the raw DDL data.
1985         /// Logs an error message.
1986         /// \param code  The error code describing the problem.
1987         /// \param location  A pointer to the location in the raw data buffer
1988         ///      where the problem was found.
1989         
1990         if (code == kParityError)
1991         {
1992                 fParityErrorFound = true;
1993         }
1994         else
1995         {
1996                 fNonParityErrorFound = true;
1997         }
1998         if (fDontPrintParityErrors and code == kParityError) return;
1999         
2000         long bytepos = long(location) - long(fkBufferStart) + sizeof(AliRawDataHeader);
2001         if (fWarnOnly or (fPrintParityErrorAsWarning and code == kParityError))
2002         {
2003                 HLTWarning("There is a problem with decoding the raw data."
2004                         " %s (Error code: %d, at byte %d). Trying to recover from corrupt data.",
2005                         ErrorCodeToMessage(code), code, bytepos
2006                 );
2007         }
2008         else
2009         {
2010                 HLTError("There is a problem with decoding the raw data. %s (Error code: %d, at byte %d)",
2011                         ErrorCodeToMessage(code), code, bytepos
2012                 );
2013         }
2014 };
2015
2016 void  AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::OnNewBusPatch(const AliMUONBusPatchHeaderStruct* header, const void* /*data*/) 
2017 {
2018   // operation to perform on new data
2019   fBusPatchId = int(header->fBusPatchId);
2020   MaxEntryPerBusPatch& maxEntryPerBusPatch 
2021     = * const_cast<MaxEntryPerBusPatch*>(fkMaxEntryPerBusPatch);
2022   fIsMuchNoisy = false;
2023   if(AliHLTInt32_t(header->fLength)> maxEntryPerBusPatch[fBusPatchId])
2024     fIsMuchNoisy = true;
2025   
2026 };
2027
2028 void AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::OnData(UInt_t dataWord, bool parityError)
2029 {
2030   //function to arrange the decoded Raw Data
2031
2032   if (fSkipParityErrors and parityError) return;
2033   
2034   if(fIsMuchNoisy) return;
2035
2036   fIdManuChannel = 0x0;
2037   fIdManuChannel = (fIdManuChannel|fBusPatchId)<<17;
2038   fIdManuChannel |= (dataWord >> 12) & 0x1FFFF;
2039   
2040   IdManuChannelToEntry& idToEntry = * const_cast<IdManuChannelToEntry*>(fkIdToEntry);
2041   fLutEntry = idToEntry[fIdManuChannel];
2042   if(fLutEntry==0)
2043   {
2044     HLTDebug("Failed to find a valid LUT entry.");
2045     return;
2046   }
2047   fPadCharge = int(((unsigned short)(dataWord & 0xFFF)) - fkLookUpTableData[fLutEntry].fPed);
2048   
2049   fCharge = 0;    
2050   if(fPadCharge > 2.0*fkLookUpTableData[fLutEntry].fSigma){  // (charge > 4) is due cut out the noise level                     
2051       
2052     fPadData[fDataCount].fDetElemId = fkLookUpTableData[fLutEntry].fDetElemId;
2053     fPadData[fDataCount].fIX = AliHLTInt32_t(AliHLTUInt32_t(fkLookUpTableData[fLutEntry].fIX) % 336);  // modulus protectes against overflow.
2054     fPadData[fDataCount].fIY = AliHLTInt32_t(AliHLTUInt32_t(fkLookUpTableData[fLutEntry].fIY) % 237);  // modulus protectes against overflow.
2055     fPadData[fDataCount].fRealX = fkLookUpTableData[fLutEntry].fRealX;
2056     fPadData[fDataCount].fRealY = fkLookUpTableData[fLutEntry].fRealY;
2057     fPadData[fDataCount].fRealZ = fkLookUpTableData[fLutEntry].fRealZ;
2058     fPadData[fDataCount].fHalfPadSize = fkLookUpTableData[fLutEntry].fHalfPadSize;
2059     fPadData[fDataCount].fPadSizeXY = fkLookUpTableData[fLutEntry].fPadSizeXY;
2060     fPadData[fDataCount].fPlane = fkLookUpTableData[fLutEntry].fPlane & 0x1;  // The mask makes sure the plane value is within range.
2061     fPadData[fDataCount].fBusPatch = fBusPatchId;
2062     fPadData[fDataCount].fRawData = dataWord;
2063     
2064     if ( fPadCharge < fkLookUpTableData[fLutEntry].fThres ) {
2065       fCharge = (fkLookUpTableData[fLutEntry].fA0)*fPadCharge;
2066     }else{
2067       fCharge = (fkLookUpTableData[fLutEntry].fA0)*(fkLookUpTableData[fLutEntry].fThres) 
2068         + (fkLookUpTableData[fLutEntry].fA0)*(fPadCharge-fkLookUpTableData[fLutEntry].fThres) 
2069         + (fkLookUpTableData[fLutEntry].fA1)*(fPadCharge-fkLookUpTableData[fLutEntry].fThres)*(fPadCharge-fkLookUpTableData[fLutEntry].fThres);
2070     }
2071     
2072     fPadData[fDataCount].fCharge = fCharge;
2073     
2074     if(fkLookUpTableData[fLutEntry].fDetElemId/100 == 6){
2075       fDataCountListPerDetElem[
2076                                ((fkLookUpTableData[fLutEntry].fDetElemId-(GetkMinDetElemIdInDDL(fDDL)+100))%GetkNofDetElemInDDL(fDDL) 
2077                                 + GetkNofDetElemInDDL(fDDL)/2)
2078                                ]
2079         [fNofDataInDetElem[((fkLookUpTableData[fLutEntry].fDetElemId-(GetkMinDetElemIdInDDL(fDDL)+100))%GetkNofDetElemInDDL(fDDL) 
2080                             + GetkNofDetElemInDDL(fDDL)/2)
2081                            ]++] = fDataCount;
2082     }else{
2083       fDataCountListPerDetElem[(fkLookUpTableData[fLutEntry].fDetElemId-GetkMinDetElemIdInDDL(fDDL))%GetkNofDetElemInDDL(fDDL)]
2084         [fNofDataInDetElem[(fkLookUpTableData[fLutEntry].fDetElemId-GetkMinDetElemIdInDDL(fDDL))%GetkNofDetElemInDDL(fDDL)]++] = fDataCount;
2085     }
2086     
2087     // if(fkLookUpTableData[fLutEntry].fDetElemId != fPrevDetElemId){
2088     //   if((*fNofFiredDetElem)>0){
2089     //  fMaxFiredPerDetElem[(*fNofFiredDetElem)-1] = fDataCount;
2090     //   }
2091     
2092     //   HLTDebug("detElem : %d, prevDetElem : %d, datacount : %d, maxFiredPerDetElem[%d] : %d",
2093     //            fkLookUpTableData[fLutEntry].fDetElemId,fPrevDetElemId,fDataCount,
2094     //            ((*fNofFiredDetElem)-1),fMaxFiredPerDetElem[(*fNofFiredDetElem)-1]
2095     //         );
2096     
2097     //   (*fNofFiredDetElem)++;
2098     //   fPrevDetElemId =  fkLookUpTableData[fLutEntry].fDetElemId ;
2099     // }
2100     
2101     //if(fPadData[fDataCount].fDetElemId==102)
2102     
2103     HLTDebug("%x, fLutEntry : %d, id : %d, (fDDL,buspatch,detele,plane) : (%2d,%4d,%4d,%1d) (manu,channel) : (%4d,%2d) \n(iX,iY) : (%3d,%3d) (X,Y) : (%f, %f, %f), adc : %d, charge : %f, ped : %f, sigma : %f, padsize : %f",
2104                fkLookUpTableData,fLutEntry,fIdManuChannel,fDDL,
2105                fBusPatchId,fPadData[fDataCount].fDetElemId,fPadData[fDataCount].fPlane,
2106              ((dataWord >> 18) & 0x7FF),((dataWord >> 12) & 0x3F),
2107              fPadData[fDataCount].fIX,fPadData[fDataCount].fIY,
2108              fPadData[fDataCount].fRealX,fPadData[fDataCount].fRealY,fPadData[fDataCount].fRealZ,
2109              (dataWord & 0xFFF),fPadData[fDataCount].fCharge,fkLookUpTableData[fLutEntry].fPed,fkLookUpTableData[fLutEntry].fSigma,
2110              fkLookUpTableData[fLutEntry].fHalfPadSize);
2111     
2112     // HLTDebug("%x, fLutEntry : %d, buspatch : %d, detele : %d, id : %d, manu : %d, channel : %d, iX : %d, iY: %d, (X,Y) : (%f, %f, %f), charge : %f, padsize : %f, plane : %d, ped : %f, sigma : %f",
2113     //       fkLookUpTableData,fLutEntry,fBusPatchId,fPadData[fDataCount].fDetElemId,
2114     //       fIdManuChannel,((dataWord >> 18) & 0x7FF),((dataWord >> 12) & 0x3F),
2115     //       fPadData[fDataCount].fIX,fPadData[fDataCount].fIY,
2116     //       fPadData[fDataCount].fRealX,fPadData[fDataCount].fRealY,fPadData[fDataCount].fRealZ,
2117     //       fPadData[fDataCount].fCharge,fkLookUpTableData[fLutEntry].fHalfPadSize,fPadData[fDataCount].fPlane,fkLookUpTableData[fLutEntry].fPed,fkLookUpTableData[fLutEntry].fSigma);
2118     
2119     fDataCount++;
2120   }// if charge is more than DC Cut limit condition
2121   
2122 }