1 /**************************************************************************
2 * This file is property of and copyright by the ALICE HLT Project *
3 * All rights reserved. *
6 * Indranil Das <indra.das@saha.ac.in> *
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 **************************************************************************/
19 ///////////////////////////////////////////////
20 //Author : Indranil Das, SINP, INDIA
21 // Sukalyan Chattopadhyay, SINP, INDIA
23 //Email : indra.das@saha.ac.in
24 // sukalyan.chattopadhyay@saha.ac.in
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
34 /////////////////////////////////////////////////
36 #include "AliHLTMUONHitReconstructor.h"
37 #include "AliHLTMUONRecHitsBlockStruct.h"
42 const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkDetectorId = 0xA00;
43 const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkDDLOffSet = 12;
44 const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkNofDDL = 8;
45 const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkDDLHeaderSize = 8;
46 const AliHLTInt32_t AliHLTMUONHitReconstructor::fgkLutLine = 59648 + 1;
49 AliHLTMUONHitReconstructor::AliHLTMUONHitReconstructor() :
54 fkBuspatchHeaderSize(4),
57 fLookUpTableData(NULL),
59 fRecPointsCount(NULL),
60 fMaxRecPointsCount(0),
64 fCentralChargeB(NULL),
65 fCentralChargeNB(NULL),
75 /// Default constructor
77 fkBlockHeaderSize = 8;
79 fkBuspatchHeaderSize = 4;
83 fPadData = new AliHLTMUONPad[fgkLutLine];
85 catch (const std::bad_alloc&)
87 HLTError("Dynamic memory allocation failed for fPadData in constructor.");
91 fPadData[0].fDetElemId = 0;
94 fPadData[0].fRealX = 0.0 ;
95 fPadData[0].fRealY = 0.0 ;
96 fPadData[0].fRealZ = 0.0 ;
97 fPadData[0].fHalfPadSize = 0.0 ;
98 fPadData[0].fPlane = -1 ;
99 fPadData[0].fCharge = 0 ;
101 bzero(fGetIdTotalData, 336*237*2*sizeof(int));
105 AliHLTMUONHitReconstructor::~AliHLTMUONHitReconstructor()
107 /// Default destructor
117 void AliHLTMUONHitReconstructor::SetLookUpTable(
118 const AliHLTMUONHitRecoLutRow* lookupTable,
119 const IdManuChannelToEntry* idToEntry
122 /// Sets the Lookup table (LUT) containing the position of each pad with
123 /// electronic channel associated with it. Also the appropriate manu
124 /// channel ID mapping to LUT row is also set.
126 assert( lookupTable != NULL );
127 assert( idToEntry != NULL );
129 fIdToEntry = idToEntry;
130 fLookUpTableData = lookupTable;
134 bool AliHLTMUONHitReconstructor::Run(
135 const AliHLTUInt32_t* rawData,
136 AliHLTUInt32_t rawDataSize,
137 AliHLTMUONRecHitStruct* recHit,
138 AliHLTUInt32_t& nofHit
141 // main function called by HLTReconstructor to perform DHLT Hitreconstruction
144 fMaxRecPointsCount = nofHit;
145 fRecPointsCount = &nofHit;
146 *fRecPointsCount = 0;
149 if (not DecodeDDL(rawData, rawDataSize)) {
150 // Dont need to log any message again. Already done so in DecodeDDL.
154 if (fDigitPerDDL == 1)
156 // There are no digits to process so stop here.
160 if (not FindRecHits()) {
161 HLTError("Failed to generate RecHits");
169 bool AliHLTMUONHitReconstructor::DecodeDDL(const AliHLTUInt32_t* rawData,AliHLTUInt32_t rawDataSize)
171 //function to decode Raw Data
173 AliHLTMUONRawDecoder& handler = reinterpret_cast<AliHLTMUONRawDecoder&>(fHLTMUONDecoder.GetHandler());
174 UInt_t bufferSize = UInt_t(rawDataSize*sizeof(AliHLTUInt32_t));
176 handler.SetDCCut(fDCCut);
177 handler.SetPadData(fPadData);
178 handler.SetLookUpTable(fLookUpTableData);
179 handler.SetIdManuChannelToEntry(fIdToEntry);
180 handler.SetNofFiredDetElemId(fNofFiredDetElem);
181 handler.SetMaxFiredPerDetElem(fMaxFiredPerDetElem);
183 if(!fHLTMUONDecoder.Decode(rawData,bufferSize))
186 fDigitPerDDL = handler.GetDataCount();
187 fMaxFiredPerDetElem[fNofFiredDetElem-1] = handler.GetDataCount();
189 if(fDigitPerDDL == 1){
190 HLTInfo("An Empty DDL File found");
197 bool AliHLTMUONHitReconstructor::FindRecHits()
199 // fuction that calls hit reconstruction detector element-wise.
201 assert( fCentralChargeB == NULL );
202 assert( fCentralChargeNB == NULL );
203 assert( fRecX == NULL );
204 assert( fRecY == NULL );
205 assert( fAvgChargeX == NULL );
206 assert( fAvgChargeY == NULL );
207 assert( fNofBChannel == NULL );
208 assert( fNofNBChannel == NULL );
210 bool resultOk = false;
212 for(int iDet=0; iDet<fNofFiredDetElem ; iDet++)
219 fCentralChargeB = new int[fMaxFiredPerDetElem[iDet]];
220 HLTDebug("Allocated fCentralChargeB with %d elements.", fMaxFiredPerDetElem[iDet]);
221 fCentralChargeNB = new int[fMaxFiredPerDetElem[iDet]];
222 HLTDebug("Allocated fCentralChargeNB with %d elements.", fMaxFiredPerDetElem[iDet]);
225 catch(const std::bad_alloc&)
227 HLTError("Dynamic memory allocation failed for fCentralChargeNB and fCentralChargeB");
231 // Continue processing, but check if everything is OK as we do, otherwise
232 // do not execute the next steps.
236 FindCentralHits(fMaxFiredPerDetElem[iDet-1],fMaxFiredPerDetElem[iDet]);
238 // minimum value is 1 because dataCount in ReadDDL starts from 1 instead of 0;
239 FindCentralHits(1,fMaxFiredPerDetElem[iDet]);
243 fRecY = new float[fCentralCountB];
244 HLTDebug("Allocated fRecY with %d elements.", fCentralCountB);
245 fRecX = new float[fCentralCountNB];
246 HLTDebug("Allocated fRecX with %d elements.", fCentralCountNB);
247 fAvgChargeY = new float[fCentralCountB];
248 HLTDebug("Allocated fAvgChargeY with %d elements.", fCentralCountB);
249 fAvgChargeX = new float[fCentralCountNB];
250 HLTDebug("Allocated fAvgChargeX with %d elements.", fCentralCountNB);
251 fNofBChannel = new int[fCentralCountB];
252 HLTDebug("Allocated fNofBChannel with %d elements.", fCentralCountB);
253 fNofNBChannel = new int[fCentralCountNB];
254 HLTDebug("Allocated fNofNBChannel with %d elements.", fCentralCountNB);
257 catch(const std::bad_alloc&){
258 HLTError("Dynamic memory allocation failed for internal arrays.");
263 if (resultOk) RecXRecY();
266 resultOk = MergeRecHits();
271 // minimum value in loop is 1 because dataCount in ReadDDL starts from 1 instead of 0;
272 for(int i=1;i<fMaxFiredPerDetElem[iDet];i++)
273 fGetIdTotalData[fPadData[i].fIX][fPadData[i].fIY][fPadData[i].fPlane] = 0;
275 for(int i=fMaxFiredPerDetElem[iDet-1];i<fMaxFiredPerDetElem[iDet];i++)
276 fGetIdTotalData[fPadData[i].fIX][fPadData[i].fIY][fPadData[i].fPlane] = 0;
279 // Make sure to release any memory that was allocated.
280 if (fCentralChargeB != NULL)
282 delete [] fCentralChargeB;
283 HLTDebug("Released fCentralChargeB array.");
284 fCentralChargeB = NULL;
286 if (fCentralChargeNB != NULL)
288 delete [] fCentralChargeNB;
289 HLTDebug("Released fCentralChargeNB array.");
290 fCentralChargeNB = NULL;
295 HLTDebug("Released fRecX array.");
301 HLTDebug("Released fRecY array.");
304 if (fAvgChargeX != NULL)
306 delete [] fAvgChargeX;
307 HLTDebug("Released fAvgChargeX array.");
310 if (fAvgChargeY != NULL)
312 delete [] fAvgChargeY;
313 HLTDebug("Released fAvgChargeY array.");
316 if (fNofBChannel != NULL)
318 delete [] fNofBChannel;
319 HLTDebug("Released fNofBChannel array.");
322 if (fNofNBChannel != NULL)
324 delete [] fNofNBChannel;
325 HLTDebug("Released fNofNBChannel array.");
326 fNofNBChannel = NULL;
330 Clear(); // clear internal arrays.
336 void AliHLTMUONHitReconstructor::FindCentralHits(int minPadId, int maxPadId)
338 // to find central hit associated with each cluster
340 assert( fCentralChargeB != NULL );
341 assert( fCentralChargeNB != NULL );
344 int idManuChannelCentral;
347 for(int iPad=minPadId;iPad<maxPadId;iPad++){
349 fGetIdTotalData[fPadData[iPad].fIX]
351 [fPadData[iPad].fPlane] = iPad ;
353 if(fPadData[iPad].fPlane == 0 ){//&& fPadData[iPad].fIY > (0+1) && fPadData[iPad].fIY < (79 - 1)){
354 //if(fPadData[iPad].fIY > 0){
355 if(fCentralCountB>0){
357 for(b = 0;b<fCentralCountB;b++){
358 idManuChannelCentral = fCentralChargeB[b];
359 if(fPadData[iPad].fIX == fPadData[idManuChannelCentral].fIX
362 == fPadData[idManuChannelCentral].fIY + 1
365 == fPadData[idManuChannelCentral].fIY + 2
368 == fPadData[idManuChannelCentral].fIY - 2
371 == fPadData[idManuChannelCentral].fIY - 1)){
374 if(fPadData[iPad].fCharge > fPadData[idManuChannelCentral].fCharge){
375 fCentralChargeB[b] = iPad;
376 }// if condn on pad charge
377 }// if condon on pad position
380 fCentralChargeB[fCentralCountB] = iPad;
385 fCentralChargeB[fCentralCountB] = iPad;
387 }// check the size of centralHitB
388 for(b = 0;b<fCentralCountB;b++){
389 idManuChannelCentral = fCentralChargeB[b];
391 //}// if cond on iY > 2 (to avoid edge value pb)
394 if(fCentralCountNB>0){
396 for(nb = 0;nb<fCentralCountNB;nb++){
397 idManuChannelCentral = fCentralChargeNB[nb];
398 if(fPadData[iPad].fIY == fPadData[idManuChannelCentral].fIY
401 == fPadData[idManuChannelCentral].fIX + 1
404 == fPadData[idManuChannelCentral].fIX + 2
407 == fPadData[idManuChannelCentral].fIX - 2
410 == fPadData[idManuChannelCentral].fIX - 1)){
413 if(fPadData[iPad].fCharge > fPadData[idManuChannelCentral].fCharge){
414 fCentralChargeNB[nb] = iPad;
415 }// if condn over to find higher charge
416 }// if condn over to find position
417 }// for loop over presently all nb values
419 fCentralChargeNB[fCentralCountNB] = iPad;
422 }// centralHitNB size test
424 fCentralChargeNB[fCentralCountNB] = iPad;
426 }// centralHitNB size test
428 }// fill for bending and nonbending hit
434 void AliHLTMUONHitReconstructor::RecXRecY()
436 // find reconstructed X and Y for each plane separately
438 assert( fRecX != NULL );
439 assert( fRecY != NULL );
440 assert( fAvgChargeX != NULL );
441 assert( fAvgChargeY != NULL );
442 assert( fNofBChannel != NULL );
443 assert( fNofNBChannel != NULL );
452 for(b=0;b<fCentralCountB;b++){
453 idCentral = fCentralChargeB[b];
455 if(fPadData[idCentral].fIY==0)
458 idLower = fGetIdTotalData[fPadData[idCentral].fIX][fPadData[idCentral].fIY-1][0];
460 if(fPadData[idCentral].fIX==236)
463 idUpper = fGetIdTotalData[fPadData[idCentral].fIX][fPadData[idCentral].fIY+1][0];
466 fRecY[b] = (fPadData[idCentral].fRealY*fPadData[idCentral].fCharge
468 fPadData[idUpper].fRealY*fPadData[idUpper].fCharge
470 fPadData[idLower].fRealY*fPadData[idLower].fCharge
471 )/(fPadData[idCentral].fCharge + fPadData[idUpper].fCharge + fPadData[idLower].fCharge) ;
473 fAvgChargeY[b] = (fPadData[idCentral].fCharge + fPadData[idUpper].fCharge + fPadData[idLower].fCharge)/3.0 ;
476 if(fPadData[idLower].fCharge>0)
478 if(fPadData[idCentral].fCharge>0)
480 if(fPadData[idUpper].fCharge>0)
483 HLTDebug("lower : %d, middle : %d, upper : %d, nofChannel : %d",fPadData[idLower].fCharge,
484 fPadData[idCentral].fCharge,fPadData[idUpper].fCharge,fNofBChannel[b]);
486 HLTDebug("RecY[%d] : %f",b,fRecY[b]);
489 for(nb=0;nb<fCentralCountNB;nb++){
490 idCentral = fCentralChargeNB[nb];
492 if(fPadData[idCentral].fIX==0)
495 idLeft = fGetIdTotalData[fPadData[idCentral].fIX-1][fPadData[idCentral].fIY][1];
497 if(fPadData[idCentral].fIX==335)
500 idRight = fGetIdTotalData[fPadData[idCentral].fIX+1][fPadData[idCentral].fIY][1];
502 fRecX[nb] = (fPadData[idCentral].fRealX*fPadData[idCentral].fCharge
504 fPadData[idRight].fRealX*fPadData[idRight].fCharge
506 fPadData[idLeft].fRealX*fPadData[idLeft].fCharge
507 )/(fPadData[idCentral].fCharge + fPadData[idRight].fCharge + fPadData[idLeft].fCharge);
510 fAvgChargeX[nb] = (fPadData[idCentral].fCharge + fPadData[idRight].fCharge + fPadData[idLeft].fCharge)/3.0 ;
513 fNofNBChannel[nb] = 0;
514 if(fPadData[idLeft].fCharge>0)
515 fNofNBChannel[nb]++ ;
516 if(fPadData[idCentral].fCharge>0)
517 fNofNBChannel[nb]++ ;
518 if(fPadData[idRight].fCharge>0)
519 fNofNBChannel[nb]++ ;
521 HLTDebug("left : %d, middle : %d, right : %d, nofChannel : %d",fPadData[idLeft].fCharge,
522 fPadData[idCentral].fCharge,fPadData[idRight].fCharge,fNofNBChannel[nb]);
524 HLTDebug("RecX[%d] : %f",nb,fRecX[nb]);
530 bool AliHLTMUONHitReconstructor::MergeRecHits()
532 // Merge reconstructed hits first over same plane then bending plane with non-bending plane
534 assert( fRecX != NULL );
535 assert( fRecY != NULL );
536 assert( fAvgChargeX != NULL );
537 assert( fAvgChargeY != NULL );
538 assert( fNofBChannel != NULL );
539 assert( fNofNBChannel != NULL );
541 int idCentralB,idCentralNB ;
545 float halfPadLengthX,halfPadLengthY;
547 // MERGE Bending Plane hits, which are placed side by side
548 for(int i=0;i<fCentralCountB-1;i++){
550 for(int j=i+1;j<fCentralCountB;j++){
552 if(fCentralChargeB[i]==fCentralChargeB[j]){
558 fPadData[fCentralChargeB[i]].fIY == fPadData[fCentralChargeB[j]].fIY
562 fPadData[fCentralChargeB[i]].fIX == fPadData[fCentralChargeB[j]].fIX + 1
564 fPadData[fCentralChargeB[i]].fIX == fPadData[fCentralChargeB[j]].fIX - 1
572 if(fAvgChargeY[i] > fAvgChargeY[j]){
573 fRecY[i] = (fRecY[i]*fAvgChargeY[i] + fRecY[j]*fAvgChargeY[j]
574 )/(fAvgChargeY[i] + fAvgChargeY[j]);
578 fRecY[j] = (fRecY[i]*fAvgChargeY[i] + fRecY[j]*fAvgChargeY[j]
579 )/(fAvgChargeY[i] + fAvgChargeY[j]);
582 }// search for higher charge
585 }//if fRecY[i] != 0.0
588 // MERGE Non Bending Plane hits, which are place side by side
589 for(int i=0;i<fCentralCountNB-1;i++){
591 for(int j=i+1;j<fCentralCountNB;j++){
593 if(fCentralChargeNB[i]==fCentralChargeNB[j]){
599 fPadData[fCentralChargeNB[i]].fIX == fPadData[fCentralChargeNB[j]].fIX
603 fPadData[fCentralChargeNB[i]].fIY == fPadData[fCentralChargeNB[j]].fIY + 1
605 fPadData[fCentralChargeNB[i]].fIY == fPadData[fCentralChargeNB[j]].fIY - 1
613 if(fAvgChargeX[i] > fAvgChargeX[j]){
614 fRecX[i] = (fRecX[i]*fAvgChargeX[i] + fRecX[j]*fAvgChargeX[j]
615 )/(fAvgChargeX[i] + fAvgChargeX[j]);
619 fRecX[j] = (fRecX[i]*fAvgChargeX[i] + fRecX[j]*fAvgChargeX[j]
620 )/(fAvgChargeX[i] + fAvgChargeX[j]);
622 }// search for higher charge
625 }//if fRecX[i] != 0.0
628 // Merge bending Plane hits with Non Bending
629 for(int b=0;b<fCentralCountB;b++){
631 idCentralB = fCentralChargeB[b];
632 padCenterXB = fPadData[idCentralB].fRealX;
634 halfPadLengthX = fPadData[idCentralB].fIY ;
636 for(int nb=0;nb<fCentralCountNB;nb++){
638 idCentralNB = fCentralChargeNB[nb];
640 padCenterYNB = fPadData[idCentralNB].fRealY;
642 halfPadLengthY = fPadData[idCentralNB].fHalfPadSize ;
644 if(fabsf(fRecX[nb]) > fabsf(padCenterXB))
645 diffX = fabsf(fRecX[nb]) - fabsf(padCenterXB);
647 diffX = fabsf(padCenterXB) - fabsf(fRecX[nb]);
649 if(fabsf(padCenterYNB)>fabsf(fRecY[b]))
650 diffY = fabsf(padCenterYNB) - fabsf(fRecY[b]);
652 diffY = fabsf(fRecY[b]) - fabsf(padCenterYNB);
654 if(diffX < halfPadLengthX && diffY < halfPadLengthY ){//&& fPadData[idCentralB].fIY != 0){
656 if(fNofBChannel[b]==3)
657 fRecY[b] += 0.025*sin(12.0*(fRecY[b] - fPadData[idCentralB].fRealY)) ;
659 fRecX[nb] += 0.075*sin(9.5*(fRecX[nb] - fPadData[idCentralNB].fRealX)) ;
661 // First check that we have not overflowed the buffer.
662 if((*fRecPointsCount) == fMaxRecPointsCount){
663 HLTError("Number of RecHit (i.e. %d) exceeds the max number of RecHit limit %d.",(*fRecPointsCount),fMaxRecPointsCount);
667 //fRecPoints[(*fRecPointsCount)].fId = idCentralB;
668 fRecPoints[(*fRecPointsCount)].fX = fRecX[nb];
669 fRecPoints[(*fRecPointsCount)].fY = fRecY[b];
670 fRecPoints[(*fRecPointsCount)].fZ = fPadData[idCentralB].fRealZ;
671 // fRecPoints[(*fRecPointsCount)].fXCenter = fPadData[idCentralNB].fRealX;
672 // fRecPoints[(*fRecPointsCount)].fYCenter = fPadData[idCentralB].fRealY;
673 // fRecPoints[(*fRecPointsCount)].fNofBChannel = fNofBChannel[b];
674 // fRecPoints[(*fRecPointsCount)].fNofNBChannel = fNofNBChannel[nb];
675 // fRecPoints[(*fRecPointsCount)].fDetElemId = (AliHLTUInt32_t)fPadData[idCentralB].fDetElemId;
676 (*fRecPointsCount)++;
677 }//if lies wihtin 5.0 mm
678 }// condn over fRecX ! = 0.0
679 }// loop over NB side
680 }// condn on fRecY[b] != 0.0
681 }// loop over B side;
687 void AliHLTMUONHitReconstructor::Clear()
689 // function to clear internal arrays.
691 for(int iPad=1;iPad<fDigitPerDDL;iPad++){
692 fGetIdTotalData[fPadData[iPad].fIX][fPadData[iPad].fIY][fPadData[iPad].fPlane] = 0;
693 fPadData[iPad].fDetElemId = 0;
694 fPadData[iPad].fIX = 0 ;
695 fPadData[iPad].fIY = 0 ;
696 fPadData[iPad].fRealX = 0.0 ;
697 fPadData[iPad].fRealY = 0.0 ;
698 fPadData[iPad].fRealZ = 0.0 ;
699 fPadData[iPad].fHalfPadSize = -1 ;
700 fPadData[iPad].fPlane = -1 ;
701 fPadData[iPad].fCharge = 0 ;
704 for(int i=0;i<13;i++)
705 fMaxFiredPerDetElem[i] = 0;
709 AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::AliHLTMUONRawDecoder() :
714 fLookUpTableData(NULL),
715 fNofFiredDetElem(NULL),
716 fMaxFiredPerDetElem(NULL),
729 AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::~AliHLTMUONRawDecoder()
735 void AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::OnNewBuffer(const void* buffer, UInt_t /*bufferSize*/)
737 /// Called for every new raw DDL data payload being processed.
738 /// Just clears internal counters.
739 /// \param buffer The pointer to the raw data buffer.
741 assert( buffer != NULL );
742 fBufferStart = buffer;
743 // dataCount starts from 1 because the 0-th element of fPadData is used as null value.
745 *fNofFiredDetElem = 0;
750 void AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::OnError(ErrorCode code, const void* location)
752 /// Called if there was an error detected in the raw DDL data.
753 /// Logs an error message.
754 /// \param code The error code describing the problem.
755 /// \param location A pointer to the location in the raw data buffer
756 /// where the problem was found.
758 long bytepos = long(location) - long(fBufferStart) + sizeof(AliRawDataHeader);
759 HLTError("There is a problem with decoding the raw data. %s (Error code: %d, at byte %d)",
760 ErrorCodeToMessage(code), code, bytepos
765 void AliHLTMUONHitReconstructor::AliHLTMUONRawDecoder::OnData(UInt_t dataWord, bool /*parityError*/)
767 //function to arrange the decoded Raw Data
769 fIdManuChannel = 0x0;
770 fIdManuChannel = (fIdManuChannel|fBusPatchId)<<17;
771 fIdManuChannel |= (dataWord >> 12) & 0x1FFFF;
773 IdManuChannelToEntry& idToEntry = * const_cast<IdManuChannelToEntry*>(fIdToEntry);
774 fLutEntry = idToEntry[fIdManuChannel];
775 fPadCharge = int(((unsigned short)(dataWord & 0xFFF)) - fLookUpTableData[fLutEntry].fPed);
778 if(fPadCharge > fDCCut && fPadCharge > 5.0*fLookUpTableData[fLutEntry].fSigma){ // (charge > 4) is due cut out the noise level
780 fPadData[fDataCount].fDetElemId = fLookUpTableData[fLutEntry].fDetElemId;
781 fPadData[fDataCount].fIX = fLookUpTableData[fLutEntry].fIX;
782 fPadData[fDataCount].fIY = fLookUpTableData[fLutEntry].fIY;
783 fPadData[fDataCount].fRealX = fLookUpTableData[fLutEntry].fRealX;
784 fPadData[fDataCount].fRealY = fLookUpTableData[fLutEntry].fRealY;
785 fPadData[fDataCount].fRealZ = fLookUpTableData[fLutEntry].fRealZ;
786 fPadData[fDataCount].fHalfPadSize = fLookUpTableData[fLutEntry].fHalfPadSize;
787 fPadData[fDataCount].fPlane = fLookUpTableData[fLutEntry].fPlane;
789 if ( fPadCharge < fLookUpTableData[fLutEntry].fThres ) {
790 fCharge = (fLookUpTableData[fLutEntry].fA0)*fPadCharge;
792 fCharge = (fLookUpTableData[fLutEntry].fA0)*(fLookUpTableData[fLutEntry].fThres)
793 + (fLookUpTableData[fLutEntry].fA0)*(fPadCharge-fLookUpTableData[fLutEntry].fThres)
794 + (fLookUpTableData[fLutEntry].fA1)*(fPadCharge-fLookUpTableData[fLutEntry].fThres)*(fPadCharge-fLookUpTableData[fLutEntry].fThres);
797 fPadData[fDataCount].fCharge = fCharge;
799 if(fLookUpTableData[fLutEntry].fDetElemId != fPrevDetElemId){
800 if((*fNofFiredDetElem)>0){
801 fMaxFiredPerDetElem[(*fNofFiredDetElem)-1] = fDataCount;
803 (*fNofFiredDetElem)++;
804 fPrevDetElemId = fLookUpTableData[fLutEntry].fDetElemId ;
807 // 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",
808 // fBusPatchId,fPadData[fDataCount].fDetElemId,
809 // fIdManuChannel,((dataWord >> 18) & 0x7FF),((dataWord >> 12) & 0x3F),
810 // fPadData[fDataCount].fIX,fPadData[fDataCount].fIY,
811 // fPadData[fDataCount].fRealX,fPadData[fDataCount].fRealY,
812 // fPadData[fDataCount].fCharge,fPadData[fDataCount].fHalfPadSize,fPadData[fDataCount].fPlane);
815 }// if charge is more than DC Cut limit condition