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