]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/MUON/OnlineAnalysis/AliHLTMUONHitReconstructor.cxx
Improving documentation and macros.
[u/mrichter/AliRoot.git] / HLT / MUON / OnlineAnalysis / AliHLTMUONHitReconstructor.cxx
CommitLineData
b12fe461 1/**************************************************************************
960d54ad 2 * This file is property of and copyright by the ALICE HLT Project *
3 * All rights reserved. *
b12fe461 4 * *
960d54ad 5 * Primary Authors: *
6 * Indranil Das <indra.das@saha.ac.in> *
b12fe461 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 *
960d54ad 13 * about the suitability of this software for any purpose. It is *
b12fe461 14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
16
1d8ae082 17// $Id$
b12fe461 18
19///////////////////////////////////////////////
20//Author : Indranil Das, SINP, INDIA
21// Sukalyan Chattopadhyay, SINP, INDIA
22//
b12fe461 23//Email : indra.das@saha.ac.in
24// sukalyan.chattopadhyay@saha.ac.in
baff881d 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/////////////////////////////////////////////////
b12fe461 35
5c561c5b 36#include "AliHLTMUONHitReconstructor.h"
baff881d 37#include "AliHLTMUONRecHitsBlockStruct.h"
83d66053 38#include "AliHLTMUONClustersBlockStruct.h"
39#include "AliHLTMUONChannelsBlockStruct.h"
a090ff22 40#include "AliHLTMUONUtils.h"
13f09bc1 41#include <cstring>
84ab1541 42#include <strings.h>
b12fe461 43
44
ee3678d3 45const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkDetectorId = 0xA00;
46const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkDDLOffSet = 12;
47const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkNofDDL = 8;
48const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkDDLHeaderSize = 8;
49const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkLutLine = 59648 + 1;
50
51
52AliHLTMUONHitReconstructor::AliHLTMUONHitReconstructor() :
53 AliHLTLogging(),
54 fHLTMUONDecoder(),
55 fkBlockHeaderSize(8),
56 fkDspHeaderSize(8),
57 fkBuspatchHeaderSize(4),
ffc1a6f6 58 fDCCut(-1),
ee3678d3 59 fPadData(NULL),
60 fLookUpTableData(NULL),
61 fRecPoints(NULL),
62 fRecPointsCount(NULL),
63 fMaxRecPointsCount(0),
83d66053 64 fClusters(NULL),
65 fClusterCount(0),
66 fMaxClusters(0),
67 fGenerateClusterInfo(false),
68 fNewClusterId(0),
69 fDDL(0),
70 fChannels(NULL),
71 fChannelCount(0),
72 fMaxChannels(0),
73 fGenerateChannelInfo(false),
74 fMaxChannelMult(6),
ee3678d3 75 fCentralCountB(0),
76 fCentralCountNB(0),
ee3678d3 77 fDigitPerDDL(0),
78 fCentralChargeB(NULL),
79 fCentralChargeNB(NULL),
80 fRecX(NULL),
81 fRecY(NULL),
82 fAvgChargeX(NULL),
83 fAvgChargeY(NULL),
83d66053 84 fTotChargeX(NULL),
85 fTotChargeY(NULL),
ee3678d3 86 fNofBChannel(NULL),
87 fNofNBChannel(NULL),
aa1eea98 88 fNofYNeighbour(NULL),
ee3678d3 89 fNofFiredDetElem(0),
a9afae73 90 fIdToEntry(),
83d66053 91 fMaxEntryPerBusPatch(0),
a9afae73 92 fRecoveryMode(kDontTryRecover)
b12fe461 93{
ee3678d3 94 /// Default constructor
95
96 fkBlockHeaderSize = 8;
97 fkDspHeaderSize = 8;
98 fkBuspatchHeaderSize = 4;
99
100 try
101 {
102 fPadData = new AliHLTMUONPad[fgkLutLine];
103 }
104 catch (const std::bad_alloc&)
105 {
878cb83d 106 HLTError("Dynamic memory allocation failed for fPadData in constructor.");
ee3678d3 107 throw;
108 }
109
110 fPadData[0].fDetElemId = 0;
111 fPadData[0].fIX = 0 ;
112 fPadData[0].fIY = 0 ;
113 fPadData[0].fRealX = 0.0 ;
114 fPadData[0].fRealY = 0.0 ;
115 fPadData[0].fRealZ = 0.0 ;
116 fPadData[0].fHalfPadSize = 0.0 ;
117 fPadData[0].fPlane = -1 ;
118 fPadData[0].fCharge = 0 ;
66622a82 119 fPadData[0].fBusPatch = -1;
120 fPadData[0].fRawData = 0 ;
ee3678d3 121
122 bzero(fGetIdTotalData, 336*237*2*sizeof(int));
b12fe461 123}
124
125
b12fe461 126AliHLTMUONHitReconstructor::~AliHLTMUONHitReconstructor()
127{
ee3678d3 128 /// Default destructor
129
93a75941 130 if (fPadData)
ee3678d3 131 {
132 delete [] fPadData;
133 fPadData = NULL;
134 }
83d66053 135
136 if (fClusters != NULL)
137 {
138 delete [] fClusters;
139 }
140 if (fChannels != NULL)
141 {
142 delete [] fChannels;
143 }
b12fe461 144}
145
b12fe461 146
93a75941 147void AliHLTMUONHitReconstructor::SetLookUpTable(
148 const AliHLTMUONHitRecoLutRow* lookupTable,
83d66053 149 const IdManuChannelToEntry* idToEntry,
150 const MaxEntryPerBusPatch* maxEntryPerBP
93a75941 151 )
b12fe461 152{
93a75941 153 /// Sets the Lookup table (LUT) containing the position of each pad with
154 /// electronic channel associated with it. Also the appropriate manu
155 /// channel ID mapping to LUT row is also set.
b12fe461 156
93a75941 157 assert( lookupTable != NULL );
158 assert( idToEntry != NULL );
83d66053 159 assert( maxEntryPerBP != NULL );
93a75941 160
93a75941 161 fLookUpTableData = lookupTable;
83d66053 162 fIdToEntry = idToEntry;
163 fMaxEntryPerBusPatch = maxEntryPerBP;
b12fe461 164}
165
166
a9afae73 167void AliHLTMUONHitReconstructor::TryRecover(ERecoveryMode mode)
a5d4696f 168{
169 /// Sets if the decoder should enable the error recovery logic.
170
a9afae73 171 // Here we setup the various flags to control exactly how the DDL raw data
172 // decoder will behave and what output is generated during errors.
173 fRecoveryMode = mode;
174 switch (mode)
175 {
176 case kRecoverFull:
177 fHLTMUONDecoder.TryRecover(true);
178 fHLTMUONDecoder.ExitOnError(false);
179 fHLTMUONDecoder.GetHandler().WarnOnly(true);
180 fHLTMUONDecoder.GetHandler().PrintParityErrorAsWarning(true);
181 break;
182 case kRecoverJustSkip:
183 fHLTMUONDecoder.TryRecover(false);
184 fHLTMUONDecoder.ExitOnError(false);
185 fHLTMUONDecoder.GetHandler().WarnOnly(true);
186 fHLTMUONDecoder.GetHandler().PrintParityErrorAsWarning(true);
187 break;
188 case kRecoverFromParityErrorsOnly:
189 fHLTMUONDecoder.TryRecover(false);
190 fHLTMUONDecoder.ExitOnError(false);
191 fHLTMUONDecoder.GetHandler().WarnOnly(false);
192 fHLTMUONDecoder.GetHandler().PrintParityErrorAsWarning(true);
193 break;
194 default:
195 fRecoveryMode = kDontTryRecover;
196 fHLTMUONDecoder.TryRecover(false);
197 fHLTMUONDecoder.ExitOnError(true);
198 fHLTMUONDecoder.GetHandler().WarnOnly(false);
199 fHLTMUONDecoder.GetHandler().PrintParityErrorAsWarning(false);
200 break;
201 }
a5d4696f 202}
203
204
29486e5a 205bool AliHLTMUONHitReconstructor::Run(
206 const AliHLTUInt32_t* rawData,
207 AliHLTUInt32_t rawDataSize,
208 AliHLTMUONRecHitStruct* recHit,
209 AliHLTUInt32_t& nofHit
210 )
211{
b12fe461 212 // main function called by HLTReconstructor to perform DHLT Hitreconstruction
213
29486e5a 214 fRecPoints = recHit;
215 fMaxRecPointsCount = nofHit;
216 fRecPointsCount = &nofHit;
b12fe461 217 *fRecPointsCount = 0;
ee3678d3 218 fDigitPerDDL = 0;
83d66053 219 fClusterCount = 0;
220 fChannelCount = 0;
b12fe461 221
ee3678d3 222 if (not DecodeDDL(rawData, rawDataSize)) {
223 // Dont need to log any message again. Already done so in DecodeDDL.
b12fe461 224 return false;
225 }
ee3678d3 226
227 if (fDigitPerDDL == 1)
13f09bc1 228 {
229 // There are no digits to process so stop here.
230 return true;
231 }
83d66053 232
233 // Allocate fClusters and fChannels if required to do so and only if the allocated
234 // size of the arrays is too small.
235 try
236 {
237 if (fGenerateClusterInfo and fMaxClusters < fMaxRecPointsCount)
238 {
239 if (fClusters != NULL)
240 {
241 delete [] fClusters;
242 fMaxClusters = 0;
243 }
244 fClusters = new AliHLTMUONClusterStruct[fMaxRecPointsCount];
245 fMaxClusters = fMaxRecPointsCount;
246 }
247 if (fGenerateChannelInfo and fMaxChannels < fMaxRecPointsCount*fMaxChannelMult)
248 {
249 if (fChannels != NULL)
250 {
251 delete [] fChannels;
252 fMaxChannels = 0;
253 }
254 fChannels = new AliHLTMUONChannelStruct[fMaxRecPointsCount*fMaxChannelMult];
255 fMaxChannels = fMaxRecPointsCount*fMaxChannelMult;
256 }
257 }
258 catch(const std::bad_alloc&)
259 {
260 HLTError("Could not allocate memory for the extra cluster and channel information.");
261 return false;
262 }
b12fe461 263
13f09bc1 264 if (not FindRecHits()) {
960d54ad 265 HLTError("Failed to generate RecHits");
b12fe461 266 return false;
267 }
ee3678d3 268
b12fe461 269 return true;
270}
271
272
83d66053 273bool AliHLTMUONHitReconstructor::FillClusterData(
274 AliHLTMUONClusterStruct* clusters, AliHLTUInt32_t& nofClusters
275 )
276{
277 /// Fills the output clusters array with extra cluster information.
278
279 bool sizeOk = fClusterCount <= nofClusters;
280 AliHLTUInt32_t n = sizeOk ? fClusterCount : nofClusters;
281 memcpy(clusters, fClusters, sizeof(AliHLTMUONClusterStruct)*n);
282 nofClusters = n;
283 return sizeOk;
284}
285
286
287bool AliHLTMUONHitReconstructor::FillChannelData(
288 AliHLTMUONChannelStruct* channels, AliHLTUInt32_t& nofChannels
289 )
290{
291 /// Fills the output channels array with extra channel information for each cluster.
292
293 bool sizeOk = fChannelCount <= nofChannels;
294 AliHLTUInt32_t n = sizeOk ? fChannelCount : nofChannels;
295 memcpy(channels, fChannels, sizeof(AliHLTMUONChannelStruct)*n);
296 nofChannels = n;
297 return sizeOk;
298}
299
300
ee3678d3 301bool AliHLTMUONHitReconstructor::DecodeDDL(const AliHLTUInt32_t* rawData,AliHLTUInt32_t rawDataSize)
b12fe461 302{
ee3678d3 303 //function to decode Raw Data
304
305 AliHLTMUONRawDecoder& handler = reinterpret_cast<AliHLTMUONRawDecoder&>(fHLTMUONDecoder.GetHandler());
306 UInt_t bufferSize = UInt_t(rawDataSize*sizeof(AliHLTUInt32_t));
307
308 handler.SetDCCut(fDCCut);
309 handler.SetPadData(fPadData);
310 handler.SetLookUpTable(fLookUpTableData);
311 handler.SetIdManuChannelToEntry(fIdToEntry);
312 handler.SetNofFiredDetElemId(fNofFiredDetElem);
313 handler.SetMaxFiredPerDetElem(fMaxFiredPerDetElem);
83d66053 314 handler.SetMaxEntryPerBusPatch(fMaxEntryPerBusPatch);
ee3678d3 315
316 if(!fHLTMUONDecoder.Decode(rawData,bufferSize))
a5d4696f 317 {
a9afae73 318 switch (TryRecover())
a5d4696f 319 {
a9afae73 320 case kRecoverFull:
a5d4696f 321 HLTWarning("There was a problem with the raw data."
322 " Recovered as much data as possible."
a9afae73 323 " Will continue processing the next event."
a5d4696f 324 );
a9afae73 325 break;
326 case kRecoverJustSkip:
327 HLTWarning("There was a problem with the raw data."
328 " Skipped corrupted data structures."
329 " Will continue processing the next event."
330 );
331 break;
332 case kRecoverFromParityErrorsOnly:
333 if (fHLTMUONDecoder.GetHandler().NonParityErrorFound())
334 {
335 HLTError("Failed to decode the tracker DDL raw data.");
336 return false;
337 }
338 HLTWarning("Found parity errors in the raw data,"
339 " but will continue processing."
340 );
341 break;
342 default:
343 HLTError("Failed to decode the tracker DDL raw data.");
a5d4696f 344 return false;
345 }
346 }
960d54ad 347
ee3678d3 348 fDigitPerDDL = handler.GetDataCount();
349 fMaxFiredPerDetElem[fNofFiredDetElem-1] = handler.GetDataCount();
90af8855 350
351 HLTDebug("fNofFiredDetElem : %d, NofDigits %d and max reco point limit is : %d, nofDetElems : %d",
352 fNofFiredDetElem,fDigitPerDDL,fMaxRecPointsCount,fNofFiredDetElem);
353
354 for(int iDet=0; iDet<TMath::Max(fNofFiredDetElem,130); iDet++)
355 HLTDebug("NofCount (fMaxFiredPerDetElem) in iDet %d is : %d", iDet, fMaxFiredPerDetElem[iDet]);
356
357 if(fNofFiredDetElem>129){
358 HLTError("Number of fired detection elements is %d, which is more than 129.", fNofFiredDetElem);
359 return false;
360 }
361
ee3678d3 362 if(fDigitPerDDL == 1){
90af8855 363 HLTDebug("An Empty DDL file was found.");
13f09bc1 364 }
90af8855 365
b12fe461 366 return true;
b12fe461 367}
368
960d54ad 369
ee3678d3 370bool AliHLTMUONHitReconstructor::FindRecHits()
b12fe461 371{
878cb83d 372 // fuction that calls hit reconstruction detector element-wise.
373
374 assert( fCentralChargeB == NULL );
375 assert( fCentralChargeNB == NULL );
376 assert( fRecX == NULL );
377 assert( fRecY == NULL );
378 assert( fAvgChargeX == NULL );
379 assert( fAvgChargeY == NULL );
83d66053 380 assert( fTotChargeX == NULL );
381 assert( fTotChargeY == NULL );
878cb83d 382 assert( fNofBChannel == NULL );
383 assert( fNofNBChannel == NULL );
aa1eea98 384 assert( fNofYNeighbour == NULL );
878cb83d 385
386 bool resultOk = false;
90af8855 387
388 HLTDebug("Number of fired detection elements = %d.", fNofFiredDetElem);
b12fe461 389
878cb83d 390 for(int iDet=0; iDet<fNofFiredDetElem ; iDet++)
391 {
392 fCentralCountB = 0;
393 fCentralCountNB = 0;
ee3678d3 394
878cb83d 395 try
396 {
ee3678d3 397 fCentralChargeB = new int[fMaxFiredPerDetElem[iDet]];
878cb83d 398 HLTDebug("Allocated fCentralChargeB with %d elements.", fMaxFiredPerDetElem[iDet]);
ee3678d3 399 fCentralChargeNB = new int[fMaxFiredPerDetElem[iDet]];
878cb83d 400 HLTDebug("Allocated fCentralChargeNB with %d elements.", fMaxFiredPerDetElem[iDet]);
401 resultOk = true;
ee3678d3 402 }
878cb83d 403 catch(const std::bad_alloc&)
404 {
405 HLTError("Dynamic memory allocation failed for fCentralChargeNB and fCentralChargeB");
406 resultOk = false;
90af8855 407 //break; Do not break. Might have smaller memory requirements in the next iteration.
ee3678d3 408 }
409
878cb83d 410 // Continue processing, but check if everything is OK as we do, otherwise
411 // do not execute the next steps.
412 if (resultOk)
413 {
414 if(iDet>0)
90af8855 415 {
416 HLTDebug("Finding central hists from fMaxFiredPerDetElem[%d] : %d, to fMaxFiredPerDetElem[%d] : %d.",
417 iDet-1, fMaxFiredPerDetElem[iDet-1], iDet, fMaxFiredPerDetElem[iDet]
418 );
878cb83d 419 FindCentralHits(fMaxFiredPerDetElem[iDet-1],fMaxFiredPerDetElem[iDet]);
90af8855 420 }
878cb83d 421 else
90af8855 422 {
423 HLTDebug("Finding central hists from fMaxFiredPerDetElem[1] : %d, to fMaxFiredPerDetElem[%d] : %d.",
424 fMaxFiredPerDetElem[1], iDet, fMaxFiredPerDetElem[iDet]
425 );
878cb83d 426 // minimum value is 1 because dataCount in ReadDDL starts from 1 instead of 0;
427 FindCentralHits(1,fMaxFiredPerDetElem[iDet]);
90af8855 428 }
429
430 HLTDebug("Found fCentralCountB : %d, fCentralCountNB : %d",fCentralCountB,fCentralCountNB);
431 if(fCentralCountB==0 or fCentralCountNB==0)
432 {
433 HLTDebug("There is no fired pad in bending/nonbending plane...skipping this detection element");
434 if (fCentralChargeB != NULL)
435 {
436 delete [] fCentralChargeB;
437 HLTDebug("Released fCentralChargeB array.");
438 fCentralChargeB = NULL;
439 }
440 if (fCentralChargeNB != NULL)
441 {
442 delete [] fCentralChargeNB;
443 HLTDebug("Released fCentralChargeNB array.");
444 fCentralChargeNB = NULL;
445 }
446 continue;
447 }
448 }
878cb83d 449
90af8855 450 if (resultOk)
451 {
878cb83d 452 try
453 {
454 fRecY = new float[fCentralCountB];
455 HLTDebug("Allocated fRecY with %d elements.", fCentralCountB);
456 fRecX = new float[fCentralCountNB];
457 HLTDebug("Allocated fRecX with %d elements.", fCentralCountNB);
458 fAvgChargeY = new float[fCentralCountB];
459 HLTDebug("Allocated fAvgChargeY with %d elements.", fCentralCountB);
460 fAvgChargeX = new float[fCentralCountNB];
461 HLTDebug("Allocated fAvgChargeX with %d elements.", fCentralCountNB);
83d66053 462 fTotChargeY = new float[fCentralCountB];
463 HLTDebug("Allocated fTotChargeY with %d elements.", fCentralCountB);
464 fTotChargeX = new float[fCentralCountNB];
465 HLTDebug("Allocated fTotChargeX with %d elements.", fCentralCountNB);
878cb83d 466 fNofBChannel = new int[fCentralCountB];
467 HLTDebug("Allocated fNofBChannel with %d elements.", fCentralCountB);
468 fNofNBChannel = new int[fCentralCountNB];
469 HLTDebug("Allocated fNofNBChannel with %d elements.", fCentralCountNB);
aa1eea98 470 fNofYNeighbour = new int[fCentralCountB];
471 HLTDebug("Allocated fNofBChannel with %d elements.", fCentralCountB);
878cb83d 472 resultOk = true;
473 }
474 catch(const std::bad_alloc&){
475 HLTError("Dynamic memory allocation failed for internal arrays.");
476 resultOk = false;
90af8855 477 //break; Must not break, this will prevent calling delete and memory cleanup, i.e. memory leak.
878cb83d 478 }
ee3678d3 479 }
480
878cb83d 481 if (resultOk) RecXRecY();
482 if (resultOk)
483 {
484 resultOk = MergeRecHits();
485 }
90af8855 486
487 if(iDet==0)
878cb83d 488 {
90af8855 489 // minimum value in loop is 1 because dataCount in ReadDDL starts from 1 instead of 0;
490 for(int i=1;i<fMaxFiredPerDetElem[iDet];i++)
491 fGetIdTotalData[fPadData[i].fIX][fPadData[i].fIY][fPadData[i].fPlane] = 0;
492 }
493 else
494 {
495 for(int i=fMaxFiredPerDetElem[iDet-1];i<fMaxFiredPerDetElem[iDet];i++)
496 fGetIdTotalData[fPadData[i].fIX][fPadData[i].fIY][fPadData[i].fPlane] = 0;
b12fe461 497 }
ee3678d3 498
878cb83d 499 // Make sure to release any memory that was allocated.
500 if (fCentralChargeB != NULL)
501 {
502 delete [] fCentralChargeB;
503 HLTDebug("Released fCentralChargeB array.");
13f09bc1 504 fCentralChargeB = NULL;
505 }
878cb83d 506 if (fCentralChargeNB != NULL)
507 {
508 delete [] fCentralChargeNB;
509 HLTDebug("Released fCentralChargeNB array.");
13f09bc1 510 fCentralChargeNB = NULL;
511 }
878cb83d 512 if (fRecX != NULL)
513 {
514 delete [] fRecX;
515 HLTDebug("Released fRecX array.");
516 fRecX = NULL;
517 }
518 if (fRecY != NULL)
519 {
520 delete [] fRecY;
521 HLTDebug("Released fRecY array.");
522 fRecY = NULL;
523 }
524 if (fAvgChargeX != NULL)
525 {
526 delete [] fAvgChargeX;
527 HLTDebug("Released fAvgChargeX array.");
528 fAvgChargeX = NULL;
529 }
530 if (fAvgChargeY != NULL)
531 {
532 delete [] fAvgChargeY;
533 HLTDebug("Released fAvgChargeY array.");
534 fAvgChargeY = NULL;
535 }
83d66053 536 if (fTotChargeX != NULL)
537 {
538 delete [] fTotChargeX;
539 HLTDebug("Released fTotChargeX array.");
540 fTotChargeX = NULL;
541 }
542 if (fTotChargeY != NULL)
543 {
544 delete [] fTotChargeY;
545 HLTDebug("Released fTotChargeY array.");
546 fTotChargeY = NULL;
547 }
878cb83d 548 if (fNofBChannel != NULL)
549 {
550 delete [] fNofBChannel;
551 HLTDebug("Released fNofBChannel array.");
552 fNofBChannel = NULL;
553 }
554 if (fNofNBChannel != NULL)
555 {
556 delete [] fNofNBChannel;
557 HLTDebug("Released fNofNBChannel array.");
558 fNofNBChannel = NULL;
559 }
aa1eea98 560 if (fNofYNeighbour != NULL)
561 {
562 delete [] fNofYNeighbour;
563 HLTDebug("Released fNofYNeighbour array.");
564 fNofYNeighbour = NULL;
565 }
b12fe461 566 }
ee3678d3 567
878cb83d 568 Clear(); // clear internal arrays.
b12fe461 569
878cb83d 570 return resultOk;
b12fe461 571}
572
960d54ad 573
b12fe461 574void AliHLTMUONHitReconstructor::FindCentralHits(int minPadId, int maxPadId)
575{
576 // to find central hit associated with each cluster
577
878cb83d 578 assert( fCentralChargeB != NULL );
579 assert( fCentralChargeNB != NULL );
580
b12fe461 581 int b,nb;
582 int idManuChannelCentral;
583 bool hasFind;
ee3678d3 584
b12fe461 585 for(int iPad=minPadId;iPad<maxPadId;iPad++){
ee3678d3 586
587 fGetIdTotalData[fPadData[iPad].fIX]
588 [fPadData[iPad].fIY]
589 [fPadData[iPad].fPlane] = iPad ;
83d66053 590
591 if(fPadData[iPad].fCharge <= fDCCut ) continue;
b12fe461 592
ee3678d3 593 if(fPadData[iPad].fPlane == 0 ){//&& fPadData[iPad].fIY > (0+1) && fPadData[iPad].fIY < (79 - 1)){
594 //if(fPadData[iPad].fIY > 0){
b12fe461 595 if(fCentralCountB>0){
596 hasFind = false;
597 for(b = 0;b<fCentralCountB;b++){
598 idManuChannelCentral = fCentralChargeB[b];
ee3678d3 599 if(fPadData[iPad].fIX == fPadData[idManuChannelCentral].fIX
b12fe461 600 &&
ee3678d3 601 (fPadData[iPad].fIY
b12fe461 602 == fPadData[idManuChannelCentral].fIY + 1
603 ||
ee3678d3 604 fPadData[iPad].fIY
b12fe461 605 == fPadData[idManuChannelCentral].fIY + 2
606 ||
ee3678d3 607 fPadData[iPad].fIY
b12fe461 608 == fPadData[idManuChannelCentral].fIY - 2
609 ||
ee3678d3 610 fPadData[iPad].fIY
b12fe461 611 == fPadData[idManuChannelCentral].fIY - 1)){
612
613 hasFind = true;
ee3678d3 614 if(fPadData[iPad].fCharge > fPadData[idManuChannelCentral].fCharge){
615 fCentralChargeB[b] = iPad;
b12fe461 616 }// if condn on pad charge
617 }// if condon on pad position
618 }// for loop over b
619 if(!hasFind){
ee3678d3 620 fCentralChargeB[fCentralCountB] = iPad;
b12fe461 621 fCentralCountB++;
622 }
623 }
624 else{
ee3678d3 625 fCentralChargeB[fCentralCountB] = iPad;
b12fe461 626 fCentralCountB++;
627 }// check the size of centralHitB
628 for(b = 0;b<fCentralCountB;b++){
629 idManuChannelCentral = fCentralChargeB[b];
630 }
631 //}// if cond on iY > 2 (to avoid edge value pb)
632 }// B/Nb checking
633 else{
634 if(fCentralCountNB>0){
635 hasFind = false;
636 for(nb = 0;nb<fCentralCountNB;nb++){
637 idManuChannelCentral = fCentralChargeNB[nb];
ee3678d3 638 if(fPadData[iPad].fIY == fPadData[idManuChannelCentral].fIY
b12fe461 639 &&
ee3678d3 640 (fPadData[iPad].fIX
b12fe461 641 == fPadData[idManuChannelCentral].fIX + 1
642 ||
ee3678d3 643 fPadData[iPad].fIX
b12fe461 644 == fPadData[idManuChannelCentral].fIX + 2
645 ||
ee3678d3 646 fPadData[iPad].fIX
b12fe461 647 == fPadData[idManuChannelCentral].fIX - 2
648 ||
ee3678d3 649 fPadData[iPad].fIX
b12fe461 650 == fPadData[idManuChannelCentral].fIX - 1)){
651
652 hasFind = true;
ee3678d3 653 if(fPadData[iPad].fCharge > fPadData[idManuChannelCentral].fCharge){
654 fCentralChargeNB[nb] = iPad;
b12fe461 655 }// if condn over to find higher charge
656 }// if condn over to find position
657 }// for loop over presently all nb values
658 if(!hasFind){
ee3678d3 659 fCentralChargeNB[fCentralCountNB] = iPad;
b12fe461 660 fCentralCountNB++;
661 }
662 }// centralHitNB size test
663 else{
ee3678d3 664 fCentralChargeNB[fCentralCountNB] = iPad;
b12fe461 665 fCentralCountNB++;
666 }// centralHitNB size test
667
668 }// fill for bending and nonbending hit
669 }// detElemId loop
ee3678d3 670
b12fe461 671}
672
878cb83d 673void AliHLTMUONHitReconstructor::RecXRecY()
b12fe461 674{
675 // find reconstructed X and Y for each plane separately
878cb83d 676
677 assert( fRecX != NULL );
678 assert( fRecY != NULL );
679 assert( fAvgChargeX != NULL );
680 assert( fAvgChargeY != NULL );
83d66053 681 assert( fTotChargeX != NULL );
682 assert( fTotChargeY != NULL );
878cb83d 683 assert( fNofBChannel != NULL );
684 assert( fNofNBChannel != NULL );
aa1eea98 685 assert( fNofYNeighbour != NULL );
878cb83d 686
b12fe461 687 int b,nb;
688 int idCentral;
689 int idLower = 0;
690 int idUpper = 0;
691 int idRight = 0;
692 int idLeft = 0;
ee3678d3 693
b12fe461 694 for(b=0;b<fCentralCountB;b++){
695 idCentral = fCentralChargeB[b];
ee3678d3 696
b12fe461 697 if(fPadData[idCentral].fIY==0)
698 idLower = 0;
699 else
700 idLower = fGetIdTotalData[fPadData[idCentral].fIX][fPadData[idCentral].fIY-1][0];
83d66053 701
702 if(fPadData[idCentral].fIY==236)
b12fe461 703 idUpper = 0;
704 else
705 idUpper = fGetIdTotalData[fPadData[idCentral].fIX][fPadData[idCentral].fIY+1][0];
706
707 fRecY[b] = (fPadData[idCentral].fRealY*fPadData[idCentral].fCharge
708 +
ee3678d3 709 fPadData[idUpper].fRealY*fPadData[idUpper].fCharge
b12fe461 710 +
ee3678d3 711 fPadData[idLower].fRealY*fPadData[idLower].fCharge
712 )/(fPadData[idCentral].fCharge + fPadData[idUpper].fCharge + fPadData[idLower].fCharge) ;
713
714 fAvgChargeY[b] = (fPadData[idCentral].fCharge + fPadData[idUpper].fCharge + fPadData[idLower].fCharge)/3.0 ;
83d66053 715 fTotChargeY[b] = (fPadData[idCentral].fCharge + fPadData[idUpper].fCharge + fPadData[idLower].fCharge);
83d66053 716
ee3678d3 717 fNofBChannel[b] = 0;
aa1eea98 718 fNofYNeighbour[b] = 0;
719 if(fPadData[idLower].fCharge>0){
ee3678d3 720 fNofBChannel[b]++ ;
aa1eea98 721 fNofYNeighbour[b]++;
722 }
ee3678d3 723 if(fPadData[idCentral].fCharge>0)
724 fNofBChannel[b]++ ;
aa1eea98 725 if(fPadData[idUpper].fCharge>0){
ee3678d3 726 fNofBChannel[b]++ ;
aa1eea98 727 fNofYNeighbour[b]++;
728 }
83d66053 729
730 //collect left coloumn
731 if((fPadData[idCentral].fIX-1)>=0){
732
733 idLeft = fGetIdTotalData[fPadData[idCentral].fIX-1][fPadData[idCentral].fIY][0];
734
735 if(fPadData[idLeft].fIY==0)
736 idLower = 0;
737 else
738 idLower = fGetIdTotalData[fPadData[idLeft].fIX][fPadData[idLeft].fIY-1][0];
739
740 if(fPadData[idLeft].fIY==236)
741 idUpper = 0;
742 else
743 idUpper = fGetIdTotalData[fPadData[idLeft].fIX][fPadData[idLeft].fIY+1][0];
ee3678d3 744
83d66053 745 fTotChargeY[b] += (fPadData[idLeft].fCharge + fPadData[idUpper].fCharge + fPadData[idLower].fCharge);
83d66053 746
747 if(fPadData[idLower].fCharge>0)
748 fNofBChannel[b]++ ;
749 if(fPadData[idLeft].fCharge>0)
750 fNofBChannel[b]++ ;
751 if(fPadData[idUpper].fCharge>0)
752 fNofBChannel[b]++ ;
753
754 }
755 ////////////////////////////////////////////////////
756
757 //collect right coloumn
758 if((fPadData[idCentral].fIX+1)<=335){
759
760 idRight = fGetIdTotalData[fPadData[idCentral].fIX+1][fPadData[idCentral].fIY][0];
761
762 if(fPadData[idRight].fIY==0)
763 idLower = 0;
764 else
765 idLower = fGetIdTotalData[fPadData[idRight].fIX][fPadData[idRight].fIY-1][0];
766
767 if(fPadData[idRight].fIY==236)
768 idUpper = 0;
769 else
770 idUpper = fGetIdTotalData[fPadData[idRight].fIX][fPadData[idRight].fIY+1][0];
771
83d66053 772 fTotChargeY[b] += (fPadData[idRight].fCharge + fPadData[idUpper].fCharge + fPadData[idLower].fCharge);
83d66053 773
774 if(fPadData[idLower].fCharge>0)
775 fNofBChannel[b]++ ;
776 if(fPadData[idRight].fCharge>0)
777 fNofBChannel[b]++ ;
778 if(fPadData[idUpper].fCharge>0)
779 fNofBChannel[b]++ ;
780
781 }
782 //////////////////////////////////////////////////////////////////////////////////
783
784
785 HLTDebug("lower : %d, middle : %d, upper : %d, nofChannel : %d",fPadData[idLower].fCharge,
786 fPadData[idCentral].fCharge,fPadData[idUpper].fCharge,fNofBChannel[b]);
ee3678d3 787
788 HLTDebug("RecY[%d] : %f",b,fRecY[b]);
b12fe461 789 }
790
791 for(nb=0;nb<fCentralCountNB;nb++){
792 idCentral = fCentralChargeNB[nb];
793
794 if(fPadData[idCentral].fIX==0)
795 idLeft = 0;
796 else
797 idLeft = fGetIdTotalData[fPadData[idCentral].fIX-1][fPadData[idCentral].fIY][1];
798
799 if(fPadData[idCentral].fIX==335)
800 idRight = 0 ;
801 else
802 idRight = fGetIdTotalData[fPadData[idCentral].fIX+1][fPadData[idCentral].fIY][1];
803
804 fRecX[nb] = (fPadData[idCentral].fRealX*fPadData[idCentral].fCharge
805 +
806 fPadData[idRight].fRealX*fPadData[idRight].fCharge
807 +
808 fPadData[idLeft].fRealX*fPadData[idLeft].fCharge
809 )/(fPadData[idCentral].fCharge + fPadData[idRight].fCharge + fPadData[idLeft].fCharge);
810
811
ee3678d3 812 fAvgChargeX[nb] = (fPadData[idCentral].fCharge + fPadData[idRight].fCharge + fPadData[idLeft].fCharge)/3.0 ;
83d66053 813 fTotChargeX[nb] = (fPadData[idCentral].fCharge + fPadData[idRight].fCharge + fPadData[idLeft].fCharge);
66622a82 814
ee3678d3 815 fNofNBChannel[nb] = 0;
816 if(fPadData[idLeft].fCharge>0)
817 fNofNBChannel[nb]++ ;
818 if(fPadData[idCentral].fCharge>0)
819 fNofNBChannel[nb]++ ;
820 if(fPadData[idRight].fCharge>0)
821 fNofNBChannel[nb]++ ;
822
83d66053 823 // lower row
824 if((fPadData[idCentral].fIY-1)>=0){
825
826 idLower = fGetIdTotalData[fPadData[idCentral].fIX][fPadData[idCentral].fIY-1][1];
827
828 if(fPadData[idLower].fIX==0)
829 idLeft = 0;
830 else
831 idLeft = fGetIdTotalData[fPadData[idLower].fIX-1][fPadData[idLower].fIY][1];
832
833 if(fPadData[idLower].fIX==335)
834 idRight = 0 ;
835 else
836 idRight = fGetIdTotalData[fPadData[idLower].fIX+1][fPadData[idLower].fIY][1];
837
83d66053 838 fTotChargeX[nb] += (fPadData[idLower].fCharge + fPadData[idRight].fCharge + fPadData[idLeft].fCharge);
83d66053 839
840 if(fPadData[idLeft].fCharge>0)
841 fNofNBChannel[nb]++ ;
842 if(fPadData[idLower].fCharge>0)
843 fNofNBChannel[nb]++ ;
844 if(fPadData[idRight].fCharge>0)
845 fNofNBChannel[nb]++ ;
846
847 }
848 ////////////////////////////////////////////////////////////
849
850 // Upper row
851 if((fPadData[idCentral].fIY+1)<=236){
852
853 idUpper = fGetIdTotalData[fPadData[idCentral].fIX][fPadData[idCentral].fIY+1][1];
854
855 if(fPadData[idUpper].fIX==0)
856 idLeft = 0;
857 else
858 idLeft = fGetIdTotalData[fPadData[idUpper].fIX-1][fPadData[idUpper].fIY][1];
859
860 if(fPadData[idUpper].fIX==335)
861 idRight = 0 ;
862 else
863 idRight = fGetIdTotalData[fPadData[idUpper].fIX+1][fPadData[idUpper].fIY][1];
864
83d66053 865 fTotChargeX[nb] += (fPadData[idUpper].fCharge + fPadData[idRight].fCharge + fPadData[idLeft].fCharge);
83d66053 866
867 if(fPadData[idLeft].fCharge>0)
868 fNofNBChannel[nb]++ ;
869 if(fPadData[idRight].fCharge>0)
870 fNofNBChannel[nb]++ ;
871 if(fPadData[idRight].fCharge>0)
872 fNofNBChannel[nb]++ ;
873
874 }
875 ////////////////////////////////////////////////////////////
876
877
878 HLTDebug("left : %d, middle : %d, right : %d, nofChannel : %d",fPadData[idLeft].fCharge,
879 fPadData[idCentral].fCharge,fPadData[idRight].fCharge,fNofNBChannel[nb]);
ee3678d3 880
881 HLTDebug("RecX[%d] : %f",nb,fRecX[nb]);
66622a82 882
ee3678d3 883
b12fe461 884 }
b12fe461 885}
886
960d54ad 887
b12fe461 888bool AliHLTMUONHitReconstructor::MergeRecHits()
889{
890 // Merge reconstructed hits first over same plane then bending plane with non-bending plane
891
878cb83d 892 assert( fRecX != NULL );
893 assert( fRecY != NULL );
894 assert( fAvgChargeX != NULL );
895 assert( fAvgChargeY != NULL );
83d66053 896 assert( fTotChargeX != NULL );
897 assert( fTotChargeY != NULL );
878cb83d 898 assert( fNofBChannel != NULL );
899 assert( fNofNBChannel != NULL );
aa1eea98 900 assert( fNofYNeighbour != NULL );
878cb83d 901
b12fe461 902 int idCentralB,idCentralNB ;
903 float padCenterXB;
904 float padCenterYNB;
905 float diffX,diffY;
906 float halfPadLengthX,halfPadLengthY;
907
908 // MERGE Bending Plane hits, which are placed side by side
909 for(int i=0;i<fCentralCountB-1;i++){
910 if(fRecY[i] != 0.0){
911 for(int j=i+1;j<fCentralCountB;j++){
912
913 if(fCentralChargeB[i]==fCentralChargeB[j]){
914 fRecY[j] = 0.0;
915 continue;
916 }
917 else if(
918 (
919 fPadData[fCentralChargeB[i]].fIY == fPadData[fCentralChargeB[j]].fIY
920 )
921 &&
922 (
923 fPadData[fCentralChargeB[i]].fIX == fPadData[fCentralChargeB[j]].fIX + 1
924 ||
925 fPadData[fCentralChargeB[i]].fIX == fPadData[fCentralChargeB[j]].fIX - 1
926 )
927 &&
928 fRecY[j] != 0.0
929 &&
930 fRecY[i] != 0.0
931 ){
932
933 if(fAvgChargeY[i] > fAvgChargeY[j]){
934 fRecY[i] = (fRecY[i]*fAvgChargeY[i] + fRecY[j]*fAvgChargeY[j]
935 )/(fAvgChargeY[i] + fAvgChargeY[j]);
936 fRecY[j] = 0.0;
937 }
938 else{
939 fRecY[j] = (fRecY[i]*fAvgChargeY[i] + fRecY[j]*fAvgChargeY[j]
940 )/(fAvgChargeY[i] + fAvgChargeY[j]);
941 fRecY[i] = 0.0;
942
943 }// search for higher charge
944 }//pad position
945 }//j for loop
946 }//if fRecY[i] != 0.0
947 }// i for loop
b12fe461 948
66622a82 949 // MERGE Non Bending Plane hits, which are placed side by side
b12fe461 950 for(int i=0;i<fCentralCountNB-1;i++){
951 if(fRecX[i] != 0.0){
952 for(int j=i+1;j<fCentralCountNB;j++){
953
954 if(fCentralChargeNB[i]==fCentralChargeNB[j]){
955 fRecX[j] = 0.0;
956 continue;
957 }
958 else if(
959 (
960 fPadData[fCentralChargeNB[i]].fIX == fPadData[fCentralChargeNB[j]].fIX
961 )
962 &&
963 (
964 fPadData[fCentralChargeNB[i]].fIY == fPadData[fCentralChargeNB[j]].fIY + 1
965 ||
966 fPadData[fCentralChargeNB[i]].fIY == fPadData[fCentralChargeNB[j]].fIY - 1
967 )
968 &&
969 fRecX[j] != 0.0
970 &&
971 fRecX[i] != 0.0
972 ){
973
974 if(fAvgChargeX[i] > fAvgChargeX[j]){
975 fRecX[i] = (fRecX[i]*fAvgChargeX[i] + fRecX[j]*fAvgChargeX[j]
976 )/(fAvgChargeX[i] + fAvgChargeX[j]);
977 fRecX[j] = 0.0;
978 }
979 else{
980 fRecX[j] = (fRecX[i]*fAvgChargeX[i] + fRecX[j]*fAvgChargeX[j]
981 )/(fAvgChargeX[i] + fAvgChargeX[j]);
982 fRecX[i] = 0.0;
983 }// search for higher charge
984 }//pad position
985 }//j for loop
986 }//if fRecX[i] != 0.0
987 }// i for loop
988
b12fe461 989 // Merge bending Plane hits with Non Bending
b12fe461 990 for(int b=0;b<fCentralCountB;b++){
991 if(fRecY[b]!=0.0){
992 idCentralB = fCentralChargeB[b];
993 padCenterXB = fPadData[idCentralB].fRealX;
994
ee3678d3 995 halfPadLengthX = fPadData[idCentralB].fIY ;
b12fe461 996
997 for(int nb=0;nb<fCentralCountNB;nb++){
998 if(fRecX[nb]!=0.0){
999 idCentralNB = fCentralChargeNB[nb];
1000
1001 padCenterYNB = fPadData[idCentralNB].fRealY;
1002
ee3678d3 1003 halfPadLengthY = fPadData[idCentralNB].fHalfPadSize ;
b12fe461 1004
1005 if(fabsf(fRecX[nb]) > fabsf(padCenterXB))
1006 diffX = fabsf(fRecX[nb]) - fabsf(padCenterXB);
1007 else
1008 diffX = fabsf(padCenterXB) - fabsf(fRecX[nb]);
1009
1010 if(fabsf(padCenterYNB)>fabsf(fRecY[b]))
1011 diffY = fabsf(padCenterYNB) - fabsf(fRecY[b]);
1012 else
1013 diffY = fabsf(fRecY[b]) - fabsf(padCenterYNB);
1014
1015 if(diffX < halfPadLengthX && diffY < halfPadLengthY ){//&& fPadData[idCentralB].fIY != 0){
1016
aa1eea98 1017 if(fNofYNeighbour[b]==2){
1018 if(fPadData[idCentralB].fDetElemId<104)
1019 fRecY[b] += 0.02*sin(14.5*(fRecY[b] - fPadData[idCentralB].fRealY)) ;
1020 else if(fPadData[idCentralB].fDetElemId>=200 && fPadData[idCentralB].fDetElemId<204)
1021 fRecY[b] += 0.02*sin(14.0*(fRecY[b] - fPadData[idCentralB].fRealY)) ;
1022 else
1023 fRecY[b] += 0.025*sin(12.0*(fRecY[b] - fPadData[idCentralB].fRealY)) ;
1024 }
1025
1026 if(fPadData[idCentralNB].fDetElemId<204)
1027 fRecX[nb] += 0.095*sin(10.5*(fRecX[nb] - fPadData[idCentralNB].fRealX)) ;
1028 else if(fPadData[idCentralNB].fDetElemId>=300 && fPadData[idCentralNB].fDetElemId<404)
1029 fRecX[nb] += 0.085*sin(9.0*(fRecX[nb] - fPadData[idCentralNB].fRealX)) ;
1030 else
1031 fRecX[nb] += 0.075*sin(9.5*(fRecX[nb] - fPadData[idCentralNB].fRealX)) ;
ee3678d3 1032
ee3678d3 1033
29486e5a 1034 // First check that we have not overflowed the buffer.
1035 if((*fRecPointsCount) == fMaxRecPointsCount){
90af8855 1036 HLTError("Number of RecHits (i.e. %d) exceeds the max number of RecHit limit %d."
1037 " Output buffer is too small.",
1038 (*fRecPointsCount),fMaxRecPointsCount
1039 );
29486e5a 1040 return false;
1041 }
a090ff22 1042
1043 AliHLTUInt32_t idflags = AliHLTMUONUtils::PackRecHitFlags(
1044 (fPadData[idCentralB].fDetElemId / 100) - 1,
1045 fPadData[idCentralB].fDetElemId
1046 );
1047 fRecPoints[(*fRecPointsCount)].fFlags = idflags;
b12fe461 1048 fRecPoints[(*fRecPointsCount)].fX = fRecX[nb];
1049 fRecPoints[(*fRecPointsCount)].fY = fRecY[b];
1050 fRecPoints[(*fRecPointsCount)].fZ = fPadData[idCentralB].fRealZ;
83d66053 1051
1052 if (fGenerateClusterInfo)
1053 {
1054 if (fClusterCount >= fMaxClusters)
1055 {
1056 HLTError("Ran out of space in internal cluster array of size %d.", fMaxClusters);
1057 return false;
1058 }
1059
1060 fClusters[fClusterCount].fId = (fNewClusterId << 5) | fDDL;
1061
1062 // Increment the cluster ID and warp it around at 0x03FFFFFF since
1063 // the bottom 5 bits are filled with the source DDL number and the
1064 // sign bit in fClusters[fClusterCount].fId must be positive.
1065 fNewClusterId = (fNewClusterId + 1) & 0x03FFFFFF;
1066
1067 fClusters[fClusterCount].fHit = fRecPoints[(*fRecPointsCount)];
1068 fClusters[fClusterCount].fDetElemId = fPadData[idCentralB].fDetElemId;
66622a82 1069 fClusters[fClusterCount].fNchannelsB = fNofBChannel[b];
1070 fClusters[fClusterCount].fNchannelsNB = fNofNBChannel[nb];
1071 fClusters[fClusterCount].fChargeB = fTotChargeY[b];
1072 fClusters[fClusterCount].fChargeNB = fTotChargeX[nb];
83d66053 1073 fClusterCount++;
1074 }
1075
1076 if (fGenerateChannelInfo)
1077 {
66622a82 1078 // 3 by 3 pad structure around the central pad for the 2 planes.
1079 int pad[2][3][3] = {{
1080 {0, 0, 0},
1081 {0, idCentralB, 0},
1082 {0, 0, 0}
1083 },{
1084 {0, 0, 0},
1085 {0, idCentralNB, 0},
1086 {0, 0, 0}
1087 }};
1088
1089 // Find the pad index numbers for the central pads and the pads surrounding them.
1090 // All these pads would have contributed to the cluster as long as their charge is != 0.
1091 if (fPadData[idCentralB].fIY > 0)
1092 pad[0][0][1] = fGetIdTotalData[fPadData[idCentralB].fIX][fPadData[idCentralB].fIY-1][0];
1093 if (fPadData[idCentralB].fIY < 236)
1094 pad[0][2][1] = fGetIdTotalData[fPadData[idCentralB].fIX][fPadData[idCentralB].fIY+1][0];
1095 if (fPadData[idCentralB].fIX > 0)
1096 {
1097 int idLeft = fGetIdTotalData[fPadData[idCentralB].fIX-1][fPadData[idCentralB].fIY][0];
1098 pad[0][1][0] = idLeft;
1099 if (fPadData[idLeft].fIY > 0)
1100 pad[0][0][0] = fGetIdTotalData[fPadData[idLeft].fIX][fPadData[idLeft].fIY-1][0];
1101 if (fPadData[idLeft].fIY < 236)
1102 pad[0][2][0] = fGetIdTotalData[fPadData[idLeft].fIX][fPadData[idLeft].fIY+1][0];
1103 }
1104 if (fPadData[idCentralB].fIX < 335)
1105 {
1106 int idRight = fGetIdTotalData[fPadData[idCentralB].fIX+1][fPadData[idCentralB].fIY][0];
1107 pad[0][1][2] = idRight;
1108 if (fPadData[idRight].fIY > 0)
1109 pad[0][0][2] = fGetIdTotalData[fPadData[idRight].fIX][fPadData[idRight].fIY-1][0];
1110 if (fPadData[idRight].fIY < 236)
1111 pad[0][2][2] = fGetIdTotalData[fPadData[idRight].fIX][fPadData[idRight].fIY+1][0];
1112 }
1113
1114 if (fPadData[idCentralNB].fIX > 0)
1115 pad[1][1][0] = fGetIdTotalData[fPadData[idCentralNB].fIX-1][fPadData[idCentralNB].fIY][1];
1116 if (fPadData[idCentralNB].fIX < 335)
1117 pad[1][1][2] = fGetIdTotalData[fPadData[idCentralNB].fIX+1][fPadData[idCentralNB].fIY][1];
1118 if (fPadData[idCentralNB].fIY > 0)
1119 {
1120 int idLower = fGetIdTotalData[fPadData[idCentralNB].fIX][fPadData[idCentralNB].fIY-1][1];
1121 pad[1][0][1] = idLower;
1122 if (fPadData[idLower].fIX > 0)
1123 pad[1][0][0] = fGetIdTotalData[fPadData[idLower].fIX-1][fPadData[idLower].fIY][1];
1124 if (fPadData[idLower].fIX < 335)
1125 pad[1][0][2] = fGetIdTotalData[fPadData[idLower].fIX+1][fPadData[idLower].fIY][1];
1126 }
1127 if (fPadData[idCentralNB].fIY < 236)
1128 {
1129 int idUpper = fGetIdTotalData[fPadData[idCentralNB].fIX][fPadData[idCentralNB].fIY+1][1];
1130 pad[1][2][1] = idUpper;
1131 if (fPadData[idUpper].fIX > 0)
1132 pad[1][2][0] = fGetIdTotalData[fPadData[idUpper].fIX-1][fPadData[idUpper].fIY][1];
1133 if (fPadData[idUpper].fIX < 335)
1134 pad[1][2][2] = fGetIdTotalData[fPadData[idUpper].fIX+1][fPadData[idUpper].fIY][1];
1135 }
1136
1137 AliHLTInt32_t clusterId = fGenerateClusterInfo ? fClusters[fClusterCount-1].fId : -1;
1138
1139 // Now generate the pad structures from all the pad indices found above.
1140 for (int i = 0; i < 2; i++)
1141 for (int j = 0; j < 3; j++)
1142 for (int k = 0; k < 3; k++)
1143 {
1144 AliHLTMUONPad& p = fPadData[pad[i][j][k]];
1145 // Skip pads that have zero charge because they would not have
1146 // contributed to the cluster.
1147 if (p.fCharge <= 0) continue;
1148
1149 UShort_t manuId; UChar_t channelId; UShort_t adc;
1150 AliHLTMUONRawDecoder::UnpackADC(p.fRawData, manuId, channelId, adc);
1151
1152 fChannels[fChannelCount].fClusterId = clusterId;
1153 fChannels[fChannelCount].fBusPatch = p.fBusPatch;
1154 fChannels[fChannelCount].fManu = manuId;
1155 fChannels[fChannelCount].fChannelAddress = channelId;
1156 fChannels[fChannelCount].fSignal = adc;
1157 fChannels[fChannelCount].fRawDataWord = p.fRawData;
1158 fChannelCount++;
1159 }
83d66053 1160 }
1161
90af8855 1162 HLTDebug("Reconstructed hit (X,Y,Z) : (%f,%f,%f)",
1163 fRecPoints[(*fRecPointsCount)].fX,
1164 fRecPoints[(*fRecPointsCount)].fY,
1165 fRecPoints[(*fRecPointsCount)].fZ
1166 );
b12fe461 1167 (*fRecPointsCount)++;
b12fe461 1168 }//if lies wihtin 5.0 mm
1169 }// condn over fRecX ! = 0.0
1170 }// loop over NB side
1171 }// condn on fRecY[b] != 0.0
1172 }// loop over B side;
1173
b12fe461 1174 return true;
1175}
13f09bc1 1176
1177
1178void AliHLTMUONHitReconstructor::Clear()
1179{
878cb83d 1180 // function to clear internal arrays.
ee3678d3 1181
90af8855 1182 HLTDebug("Clearing fPadData and fMaxFiredPerDetElem buffers.");
1183
ee3678d3 1184 for(int iPad=1;iPad<fDigitPerDDL;iPad++){
1185 fGetIdTotalData[fPadData[iPad].fIX][fPadData[iPad].fIY][fPadData[iPad].fPlane] = 0;
1186 fPadData[iPad].fDetElemId = 0;
1187 fPadData[iPad].fIX = 0 ;
1188 fPadData[iPad].fIY = 0 ;
1189 fPadData[iPad].fRealX = 0.0 ;
1190 fPadData[iPad].fRealY = 0.0 ;
1191 fPadData[iPad].fRealZ = 0.0 ;
1192 fPadData[iPad].fHalfPadSize = -1 ;
1193 fPadData[iPad].fPlane = -1 ;
1194 fPadData[iPad].fCharge = 0 ;
66622a82 1195 fPadData[iPad].fBusPatch = -1;
1196 fPadData[iPad].fRawData = 0;
13f09bc1 1197 }
1198
90af8855 1199 for(int i=0;i<130;i++)
13f09bc1 1200 fMaxFiredPerDetElem[i] = 0;
ee3678d3 1201}
1202
1203
1204AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::AliHLTMUONRawDecoder() :
1205 fBufferStart(NULL),
a6b16447 1206 fBusPatchId(0),
ffc1a6f6 1207 fDCCut(-1),
a6b16447 1208 fPadData(NULL),
1209 fLookUpTableData(NULL),
1210 fNofFiredDetElem(NULL),
1211 fMaxFiredPerDetElem(NULL),
1212 fIdToEntry(),
83d66053 1213 fMaxEntryPerBusPatch(),
a6b16447 1214 fDataCount(1),
1215 fPrevDetElemId(0),
1216 fPadCharge(0),
1217 fCharge(0.0),
1218 fIdManuChannel(0x0),
a5d4696f 1219 fLutEntry(0),
a9afae73 1220 fWarnOnly(false),
1221 fSkipParityErrors(false),
1222 fDontPrintParityErrors(false),
1223 fPrintParityErrorAsWarning(false),
83d66053 1224 fNonParityErrorFound(false),
1225 fIsMuchNoisy(false)
ee3678d3 1226{
1227 // ctor
1228}
1229
1230
1231AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::~AliHLTMUONRawDecoder()
1232{
1233 // dtor
1234}
1235
93a75941 1236
878cb83d 1237void AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::OnNewBuffer(const void* buffer, UInt_t /*bufferSize*/)
1238{
1239 /// Called for every new raw DDL data payload being processed.
1240 /// Just clears internal counters.
1241 /// \param buffer The pointer to the raw data buffer.
1242
1243 assert( buffer != NULL );
1244 fBufferStart = buffer;
1245 // dataCount starts from 1 because the 0-th element of fPadData is used as null value.
1246 fDataCount = 1;
1247 *fNofFiredDetElem = 0;
1248 fPrevDetElemId = 0 ;
a9afae73 1249 fNonParityErrorFound = false;
878cb83d 1250};
1251
1252
1253void AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::OnError(ErrorCode code, const void* location)
1254{
1255 /// Called if there was an error detected in the raw DDL data.
1256 /// Logs an error message.
1257 /// \param code The error code describing the problem.
1258 /// \param location A pointer to the location in the raw data buffer
1259 /// where the problem was found.
1260
a9afae73 1261 if (code != kParityError) fNonParityErrorFound = true;
1262 if (fDontPrintParityErrors and code == kParityError) return;
1263
878cb83d 1264 long bytepos = long(location) - long(fBufferStart) + sizeof(AliRawDataHeader);
a9afae73 1265 if (fWarnOnly or (fPrintParityErrorAsWarning and code == kParityError))
1266 {
1267 HLTWarning("There is a problem with decoding the raw data."
1268 " %s (Error code: %d, at byte %d). Trying to recover from corrupt data.",
1269 ErrorCodeToMessage(code), code, bytepos
1270 );
1271 }
1272 else
1273 {
1274 HLTError("There is a problem with decoding the raw data. %s (Error code: %d, at byte %d)",
1275 ErrorCodeToMessage(code), code, bytepos
1276 );
1277 }
878cb83d 1278};
1279
1280
a9afae73 1281void AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::OnData(UInt_t dataWord, bool parityError)
ee3678d3 1282{
1283 //function to arrange the decoded Raw Data
1284
a9afae73 1285 if (fSkipParityErrors and parityError) return;
1286
83d66053 1287 if(fIsMuchNoisy) return;
1288
ee3678d3 1289 fIdManuChannel = 0x0;
1290 fIdManuChannel = (fIdManuChannel|fBusPatchId)<<17;
1291 fIdManuChannel |= (dataWord >> 12) & 0x1FFFF;
1292
93a75941 1293 IdManuChannelToEntry& idToEntry = * const_cast<IdManuChannelToEntry*>(fIdToEntry);
1294 fLutEntry = idToEntry[fIdManuChannel];
90af8855 1295 if(fLutEntry==0)
1296 {
1297 HLTDebug("Failed to find a valid LUT entry.");
1298 return;
1299 }
ee3678d3 1300 fPadCharge = int(((unsigned short)(dataWord & 0xFFF)) - fLookUpTableData[fLutEntry].fPed);
1301
1302 fCharge = 0;
83d66053 1303 if(fPadCharge > 5.0*fLookUpTableData[fLutEntry].fSigma){ // (charge > 4) is due cut out the noise level
ee3678d3 1304
1305 fPadData[fDataCount].fDetElemId = fLookUpTableData[fLutEntry].fDetElemId;
1306 fPadData[fDataCount].fIX = fLookUpTableData[fLutEntry].fIX;
1307 fPadData[fDataCount].fIY = fLookUpTableData[fLutEntry].fIY;
1308 fPadData[fDataCount].fRealX = fLookUpTableData[fLutEntry].fRealX;
1309 fPadData[fDataCount].fRealY = fLookUpTableData[fLutEntry].fRealY;
1310 fPadData[fDataCount].fRealZ = fLookUpTableData[fLutEntry].fRealZ;
1311 fPadData[fDataCount].fHalfPadSize = fLookUpTableData[fLutEntry].fHalfPadSize;
1312 fPadData[fDataCount].fPlane = fLookUpTableData[fLutEntry].fPlane;
66622a82 1313 fPadData[fDataCount].fBusPatch = fBusPatchId;
1314 fPadData[fDataCount].fRawData = dataWord;
ee3678d3 1315
1316 if ( fPadCharge < fLookUpTableData[fLutEntry].fThres ) {
1317 fCharge = (fLookUpTableData[fLutEntry].fA0)*fPadCharge;
1318 }else{
1319 fCharge = (fLookUpTableData[fLutEntry].fA0)*(fLookUpTableData[fLutEntry].fThres)
1320 + (fLookUpTableData[fLutEntry].fA0)*(fPadCharge-fLookUpTableData[fLutEntry].fThres)
1321 + (fLookUpTableData[fLutEntry].fA1)*(fPadCharge-fLookUpTableData[fLutEntry].fThres)*(fPadCharge-fLookUpTableData[fLutEntry].fThres);
1322 }
1323
1324 fPadData[fDataCount].fCharge = fCharge;
1325
1326 if(fLookUpTableData[fLutEntry].fDetElemId != fPrevDetElemId){
1327 if((*fNofFiredDetElem)>0){
1328 fMaxFiredPerDetElem[(*fNofFiredDetElem)-1] = fDataCount;
1329 }
90af8855 1330
1331 HLTDebug("detElem : %d, prevDetElem : %d, datacount : %d, maxFiredPerDetElem[%d] : %d",
1332 fLookUpTableData[fLutEntry].fDetElemId,fPrevDetElemId,fDataCount,
1333 ((*fNofFiredDetElem)-1),fMaxFiredPerDetElem[(*fNofFiredDetElem)-1]
1334 );
1335
ee3678d3 1336 (*fNofFiredDetElem)++;
1337 fPrevDetElemId = fLookUpTableData[fLutEntry].fDetElemId ;
1338 }
1339
83d66053 1340 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",
1341 fLookUpTableData,fLutEntry,fBusPatchId,fPadData[fDataCount].fDetElemId,
1342 fIdManuChannel,((dataWord >> 18) & 0x7FF),((dataWord >> 12) & 0x3F),
1343 fPadData[fDataCount].fIX,fPadData[fDataCount].fIY,
1344 fPadData[fDataCount].fRealX,fPadData[fDataCount].fRealY,fPadData[fDataCount].fRealZ,
1345 fPadData[fDataCount].fCharge,fLookUpTableData[fLutEntry].fHalfPadSize,fPadData[fDataCount].fPlane,fLookUpTableData[fLutEntry].fPed,fLookUpTableData[fLutEntry].fSigma);
ee3678d3 1346
90af8855 1347 fDataCount++;
ee3678d3 1348 }// if charge is more than DC Cut limit condition
1349
13f09bc1 1350}