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