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