2 // Original: AliHLTClustFinderNew.cxx,v 1.29 2005/06/14 10:55:21 cvetan Exp
4 //**************************************************************************
5 //* This file is property of and copyright by the ALICE HLT Project *
6 //* ALICE Experiment at CERN, All rights reserved. *
8 //* Primary Authors: Anders Vestbo, Constantin Loizides *
9 //* Developers: Kenneth Aamodt <kenneth.aamodt@student.uib.no> *
11 //* for The ALICE HLT Project. *
13 //* Permission to use, copy, modify and distribute this software and its *
14 //* documentation strictly for non-commercial purposes is hereby granted *
15 //* without fee, provided that the above copyright notice appears in all *
16 //* copies and that both the copyright notice and this permission notice *
17 //* appear in the supporting documentation. The authors make no claims *
18 //* about the suitability of this software for any purpose. It is *
19 //* provided "as is" without express or implied warranty. *
20 //**************************************************************************
22 // @file AliHLTTPCClusterFinder.cxx
23 // @author Kenneth Aamodt, Kalliopi Kanaki
25 // @brief Cluster Finder for the TPC
28 #include "AliHLTTPCDigitReader.h"
29 #include "AliHLTTPCRootTypes.h"
30 #include "AliHLTTPCLogging.h"
31 #include "AliHLTTPCClusterFinder.h"
32 #include "AliHLTTPCSpacePointData.h"
33 #include "AliHLTTPCMemHandler.h"
34 #include "AliHLTTPCPad.h"
38 #include "AliTPCcalibDB.h"
39 #include "AliTPCTransform.h"
40 #include "AliTPCParam.h"
46 ClassImp(AliHLTTPCClusterFinder)
48 AliHLTTPCClusterFinder::AliHLTTPCClusterFinder()
50 fClustersHWAddressVector(),
52 fSpacePointData(NULL),
60 fFillRawClusters(kFALSE),
74 fVectorInitialized(kFALSE),
79 fNumberOfPadsInRow(NULL),
81 fRowOfFirstCandidate(0),
82 fDoPadSelection(kFALSE),
84 fLastTimeBin(AliHLTTPCTransform::GetNTimeBins()),
85 fTotalChargeOfPreviousClusterCandidate(0),
86 fChargeOfCandidatesFalling(kFALSE),
90 fOfflineTransform(NULL),
91 fOfflineTPCParam( NULL ),
92 fOfflineTPCRecoParam(*AliTPCRecoParam::GetHLTParam()),
98 //uptate the transform class
100 fOfflineTransform = AliTPCcalibDB::Instance()->GetTransform();
101 if(!fOfflineTransform){
102 HLTError("AliHLTTPCClusterFinder()::UpdateCAlibDB:: Offline transform not in AliTPCcalibDB.");
105 fOfflineTransform->SetCurrentRecoParam(&fOfflineTPCRecoParam);
108 fOfflineTPCParam = AliTPCcalibDB::Instance()->GetParameters();
109 if( !fOfflineTPCParam ){
110 HLTError("AliHLTTPCClusterFinder()::UpdateCAlibDB:: Offline TPC parameters not in AliTPCcalibDB.");
112 fOfflineTPCParam->Update();
113 fOfflineTPCParam->ReadGeoMatrices();
118 AliHLTTPCClusterFinder::~AliHLTTPCClusterFinder(){
119 // see header file for class documentation
122 if(fVectorInitialized){
123 DeInitializePadArray();
125 if(fNumberOfPadsInRow){
126 delete [] fNumberOfPadsInRow;
127 fNumberOfPadsInRow=NULL;
131 void AliHLTTPCClusterFinder::InitSlice(Int_t slice,Int_t patch,Int_t nmaxpoints){
132 // see header file for class documentation
136 fMaxNClusters = nmaxpoints;
137 fCurrentSlice = slice;
138 fCurrentPatch = patch;
139 fFirstRow=AliHLTTPCTransform::GetFirstRow(patch);
140 fLastRow=AliHLTTPCTransform::GetLastRow(patch);
143 fClustersMCInfo.clear();
145 fClusterMCVector.clear();
146 fRawClusters.clear();
149 void AliHLTTPCClusterFinder::InitializePadArray(){
150 // see header file for class documentation
152 if(fCurrentPatch>5||fCurrentPatch<0){
153 HLTFatal("Patch is not set");
157 HLTDebug("Patch number=%d",fCurrentPatch);
159 fFirstRow = AliHLTTPCTransform::GetFirstRow(fCurrentPatch);
160 fLastRow = AliHLTTPCTransform::GetLastRow(fCurrentPatch);
162 fNumberOfRows=fLastRow-fFirstRow+1;
163 fNumberOfPadsInRow= new UInt_t[fNumberOfRows];
165 memset( fNumberOfPadsInRow, 0, sizeof(Int_t)*(fNumberOfRows));
167 fRowPadVector.clear();
169 for(UInt_t i=0;i<fNumberOfRows;i++){
170 fNumberOfPadsInRow[i]=AliHLTTPCTransform::GetNPads(i+fFirstRow);
171 AliHLTTPCPadVector tmpRow;
172 for(UInt_t j=0;j<=fNumberOfPadsInRow[i];j++){
173 AliHLTTPCPad *tmpPad = new AliHLTTPCPad(2);
175 tmpRow.push_back(tmpPad);
177 fRowPadVector.push_back(tmpRow);
179 fVectorInitialized=kTRUE;
182 Int_t AliHLTTPCClusterFinder::DeInitializePadArray(){
183 // see header file for class documentation
185 if( fVectorInitialized ){
186 for(UInt_t i=0;i<fNumberOfRows;i++){
187 for(UInt_t j=0;j<=fNumberOfPadsInRow[i];j++){
188 delete fRowPadVector[i][j];
189 fRowPadVector[i][j]=NULL;
191 fRowPadVector[i].clear();
193 fRowPadVector.clear();
194 delete[] fNumberOfPadsInRow;
195 fNumberOfPadsInRow = 0;
197 fVectorInitialized=kFALSE;
202 void AliHLTTPCClusterFinder::SetOutputArray(AliHLTTPCSpacePointData *pt){
203 // see header file for class documentation
204 //set pointer to output
205 fSpacePointData = pt;
209 void AliHLTTPCClusterFinder::ReadDataUnsorted(void* ptr,unsigned long size){
210 // see header file for class documentation
212 fPtr = (UChar_t*)ptr;
215 if(!fVectorInitialized){
216 InitializePadArray();
219 if (fDigitReader->InitBlock(fPtr,fSize,fFirstRow,fLastRow,fCurrentPatch,fCurrentSlice)<0) {
220 HLTError("failed setting up digit reader (InitBlock)");
224 while(fDigitReader->NextChannel()){
225 UInt_t row=fDigitReader->GetRow();
226 UInt_t pad=fDigitReader->GetPad();
228 if(row>=fRowPadVector.size()){
229 HLTError("Row number is to large: %d, max is %d",row,fRowPadVector.size()-1);
232 if(pad>=fRowPadVector[row].size()){
233 HLTError("Pad number is to large: %d, max is %d",pad,fRowPadVector[row].size());
237 while(fDigitReader->NextBunch()){
238 if(fDigitReader->GetBunchSize()>1){//to remove single timebin values, this will have to change at some point
239 UInt_t time = fDigitReader->GetTime();
240 if((Int_t)time>=fFirstTimeBin && (Int_t)time+fDigitReader->GetBunchSize()<=fLastTimeBin){
241 // Kenneth: 20-04-09. The following if have been added because of inconsistency in the 40 bit decoder and the 32 bit decoder.
242 // GetSignals() in the 40 bit decoder returns an array of UInt_t while the 32 bit one returns UShort_t
243 // The same is true for the function ReadDataUnsortedDeconvoluteTime() below.
244 // In addition the signals are organized in the opposite direction
246 const UShort_t *bunchData= fDigitReader->GetSignalsShort();
247 AliHLTTPCClusters candidate;
248 for(Int_t i=fDigitReader->GetBunchSize()-1;i>=0;i--){
249 candidate.fTotalCharge+=bunchData[i];
250 candidate.fTime += time*bunchData[i];
251 candidate.fTime2 += time*time*bunchData[i];
252 if(bunchData[i]>candidate.fQMax){
253 candidate.fQMax=bunchData[i];
257 if(candidate.fTotalCharge>0){
258 candidate.fMean=candidate.fTime/candidate.fTotalCharge;
259 candidate.fPad=candidate.fTotalCharge*pad;
260 candidate.fPad2=candidate.fPad*pad;
261 candidate.fLastMergedPad=pad;
262 candidate.fRowNumber=row+fDigitReader->GetRowOffset();
264 if(fRowPadVector[row][pad] != NULL){
265 fRowPadVector[row][pad]->AddClusterCandidate(candidate);
269 const UInt_t *bunchData= fDigitReader->GetSignals();
270 AliHLTTPCClusters candidate;
271 const AliHLTTPCDigitData* digits = NULL;
272 if(fDoMC && (digits = fDigitReader->GetBunchDigits())!=NULL){
273 for(Int_t i=0;i<fDigitReader->GetBunchSize();i++){
274 candidate.fTotalCharge+=bunchData[i];
275 candidate.fTime += time*bunchData[i];
276 candidate.fTime2 += time*time*bunchData[i];
277 if(bunchData[i]>candidate.fQMax){
278 candidate.fQMax=bunchData[i];
280 fMCDigits.push_back(digits[i]);
285 for(Int_t i=0;i<fDigitReader->GetBunchSize();i++){
286 candidate.fTotalCharge+=bunchData[i];
287 candidate.fTime += time*bunchData[i];
288 candidate.fTime2 += time*time*bunchData[i];
289 if(bunchData[i]>candidate.fQMax){
290 candidate.fQMax=bunchData[i];
295 if(candidate.fTotalCharge>0){
296 candidate.fMean=candidate.fTime/candidate.fTotalCharge;
297 candidate.fPad=candidate.fTotalCharge*pad;
298 candidate.fPad2=candidate.fPad*pad;
299 candidate.fLastMergedPad=pad;
300 candidate.fRowNumber=row+fDigitReader->GetRowOffset();
302 if(fRowPadVector[row][pad] != NULL){
303 fRowPadVector[row][pad]->AddClusterCandidate(candidate);
305 fRowPadVector[row][pad]->AddCandidateDigits(fMCDigits);
316 void AliHLTTPCClusterFinder::ReadDataUnsortedDeconvoluteTime(void* ptr,unsigned long size){
317 // see header file for class documentation
320 fPtr = (UChar_t*)ptr;
323 if(!fVectorInitialized){
324 InitializePadArray();
327 if (fDigitReader->InitBlock(fPtr,fSize,fFirstRow,fLastRow,fCurrentPatch,fCurrentSlice)<0) {
328 HLTError("failed setting up digit reader (InitBlock)");
332 while(fDigitReader->NextChannel()){
333 UInt_t row=fDigitReader->GetRow();
334 UInt_t pad=fDigitReader->GetPad();
336 while(fDigitReader->NextBunch()){
337 if(fDigitReader->GetBunchSize()>1){//to remove single timebin values, this will have to change at some point
338 UInt_t time = fDigitReader->GetTime();
339 if((Int_t)time>=fFirstTimeBin && (Int_t)time+fDigitReader->GetBunchSize()<=fLastTimeBin){
340 Int_t indexInBunchData=0;
341 Bool_t moreDataInBunch=kFALSE;
343 Bool_t signalFalling=kFALSE;
345 // Kenneth: 20-04-09. The following if have been added because of inconsistency in the 40 bit decoder and the 32 bit decoder.
346 // GetSignals() in the 40 bit decoder returns an array of UInt_t while the 32 bit one returns UShort_t
347 // The same is true for the function ReadDataUnsorted() above.
348 // In addition the signals are organized in the opposite direction
350 indexInBunchData = fDigitReader->GetBunchSize()-1;
351 const UShort_t *bunchData= fDigitReader->GetSignalsShort();
354 AliHLTTPCClusters candidate;
355 //for(Int_t i=indexInBunchData;i<fDigitReader->GetBunchSize();i++){
356 for(Int_t i=indexInBunchData;i>=0;i--){
358 // Checks if one need to deconvolute the signals
359 if(bunchData[i]>prevSignal && signalFalling==kTRUE){
360 if(i<fDigitReader->GetBunchSize()-1){ // means there are more than one signal left in the bunch
361 moreDataInBunch=kTRUE;
367 // Checks if the signal is 0, then quit processing the data.
368 if(bunchData[i]==0 && i<fDigitReader->GetBunchSize()-1){//means we have 0 data fom the rcu, might happen depending on the configuration settings
369 moreDataInBunch=kTRUE;
374 if(prevSignal>bunchData[i]){//means the peak of the signal has been reached and deconvolution will happen if the signal rise again.
377 candidate.fTotalCharge+=bunchData[i];
378 candidate.fTime += time*bunchData[i];
379 candidate.fTime2 += time*time*bunchData[i];
380 if(bunchData[i]>candidate.fQMax){
381 candidate.fQMax=bunchData[i];
383 prevSignal=bunchData[i];
387 if(candidate.fTotalCharge>0){
388 candidate.fMean=candidate.fTime/candidate.fTotalCharge;
389 candidate.fPad=candidate.fTotalCharge*pad;
390 candidate.fPad2=candidate.fPad*pad;
391 candidate.fLastMergedPad=pad;
392 candidate.fRowNumber=row+fDigitReader->GetRowOffset();
394 fRowPadVector[row][pad]->AddClusterCandidate(candidate);
395 if(indexInBunchData<fDigitReader->GetBunchSize()-1){
396 moreDataInBunch=kFALSE;
398 }while(moreDataInBunch);
401 const UInt_t *bunchData= fDigitReader->GetSignals();
403 AliHLTTPCClusters candidate;
404 const AliHLTTPCDigitData* digits = fDigitReader->GetBunchDigits();
405 if(fDoMC) fMCDigits.clear();
407 for(Int_t i=indexInBunchData;i<fDigitReader->GetBunchSize();i++){
408 // Checks if one need to deconvolute the signals
409 if(bunchData[i]>prevSignal && signalFalling==kTRUE){
410 if(i<fDigitReader->GetBunchSize()-1){ // means there are more than one signal left in the bunch
411 moreDataInBunch=kTRUE;
417 // Checks if the signal is 0, then quit processing the data.
418 if(bunchData[i]==0 && i<fDigitReader->GetBunchSize()-1){//means we have 0 data fom the rcu, might happen depending on the configuration settings
419 moreDataInBunch=kTRUE;
424 if(prevSignal>bunchData[i]){//means the peak of the signal has been reached and deconvolution will happen if the signal rise again.
427 candidate.fTotalCharge+=bunchData[i];
428 candidate.fTime += time*bunchData[i];
429 candidate.fTime2 += time*time*bunchData[i];
430 if(bunchData[i]>candidate.fQMax){
431 candidate.fQMax=bunchData[i];
433 if( fDoMC ) fMCDigits.push_back(digits[i]);
435 prevSignal=bunchData[i];
439 if(candidate.fTotalCharge>0){
440 candidate.fMean=candidate.fTime/candidate.fTotalCharge;
441 candidate.fPad=candidate.fTotalCharge*pad;
442 candidate.fPad2=candidate.fPad*pad;
443 candidate.fLastMergedPad=pad;
444 candidate.fRowNumber=row+fDigitReader->GetRowOffset();
446 fRowPadVector[row][pad]->AddClusterCandidate(candidate);
448 fRowPadVector[row][pad]->AddCandidateDigits(fMCDigits);
451 if(indexInBunchData<fDigitReader->GetBunchSize()-1){
452 moreDataInBunch=kFALSE;
454 }while(moreDataInBunch);
462 Bool_t AliHLTTPCClusterFinder::ComparePads(AliHLTTPCPad *nextPad,AliHLTTPCClusters* cluster,Int_t nextPadToRead){
463 // see header file for class documentation
465 //Checking if we have a match on the next pad
466 for(UInt_t candidateNumber=0;candidateNumber<nextPad->fClusterCandidates.size();candidateNumber++){
467 if(nextPad->fUsedClusterCandidates[candidateNumber] == 1){
470 AliHLTTPCClusters *candidate =&nextPad->fClusterCandidates[candidateNumber];
471 // if(cluster->fMean-candidate->fMean==1 || candidate->fMean-cluster->fMean==1 || cluster->fMean-candidate->fMean==0){
473 if( abs((Int_t)(cluster->fMean - candidate->fMean)) <= fTimeMeanDiff ){
475 if(candidate->fTotalCharge<fTotalChargeOfPreviousClusterCandidate){//peak is reached
476 fChargeOfCandidatesFalling=kTRUE;
478 if(candidate->fTotalCharge>fTotalChargeOfPreviousClusterCandidate && fChargeOfCandidatesFalling==kTRUE){//we have deconvolution
482 cluster->fMean=candidate->fMean;
483 cluster->fTotalCharge+=candidate->fTotalCharge;
484 cluster->fTime += candidate->fTime;
485 cluster->fTime2 += candidate->fTime2;
486 cluster->fPad+=candidate->fPad;
487 cluster->fPad2+=candidate->fPad2;
488 cluster->fLastMergedPad=candidate->fPad;
489 if(candidate->fQMax>cluster->fQMax){
490 cluster->fQMax=candidate->fQMax;
493 FillMCClusterVector(nextPad->GetCandidateDigits(candidateNumber));
497 UInt_t rowNo = nextPad->GetRowNumber();
498 UInt_t padNo = nextPad->GetPadNumber();
500 fRowPadVector[rowNo][padNo-2]->fSelectedPad=kTRUE;
501 fRowPadVector[rowNo][padNo-2]->fHWAddress=(AliHLTUInt16_t)fDigitReader->GetAltroBlockHWaddr(rowNo,padNo-2);
503 fRowPadVector[rowNo][padNo-1]->fSelectedPad=kTRUE;// quick solution to set the first pad to selected
504 fRowPadVector[rowNo][padNo-1]->fHWAddress=(AliHLTUInt16_t)fDigitReader->GetAltroBlockHWaddr(rowNo,padNo-1);
505 fRowPadVector[rowNo][padNo]->fSelectedPad=kTRUE;
506 fRowPadVector[rowNo][padNo]->fHWAddress=(AliHLTUInt16_t)fDigitReader->GetAltroBlockHWaddr(rowNo,padNo);
509 //setting the matched pad to used
510 nextPad->fUsedClusterCandidates[candidateNumber]=1;
512 if(nextPadToRead<(Int_t)fNumberOfPadsInRow[fRowOfFirstCandidate]){
513 nextPad=fRowPadVector[fRowOfFirstCandidate][nextPadToRead];
514 ComparePads(nextPad,cluster,nextPadToRead);
524 Int_t AliHLTTPCClusterFinder::FillHWAddressList(AliHLTUInt16_t *hwaddlist, Int_t maxHWadd){
525 // see header file for class documentation
528 for(UInt_t row=0;row<fNumberOfRows;row++){
529 for(UInt_t pad=0;pad<fNumberOfPadsInRow[row]-1;pad++){
530 if(fRowPadVector[row][pad]->fSelectedPad){
531 if(counter<maxHWadd){
532 hwaddlist[counter]=(AliHLTUInt16_t)fRowPadVector[row][pad]->fHWAddress;
536 HLTWarning("To many hardwareaddresses, skip adding");
546 Int_t AliHLTTPCClusterFinder::FillOutputMCInfo(AliHLTTPCClusterMCLabel * outputMCInfo, Int_t maxNumberOfClusterMCInfo){
547 // see header file for class documentation
551 for(UInt_t mc=0;mc<fClustersMCInfo.size();mc++){
552 if(counter<maxNumberOfClusterMCInfo){
553 outputMCInfo[counter] = fClustersMCInfo[mc];
557 HLTWarning("To much MCInfo has been added (no more space), skip adding");
563 Int_t AliHLTTPCClusterFinder::FillOutputRaw(AliHLTTPCRawCluster* rawClusters, unsigned sizeInByte) const
565 // fill the raw clusters
566 if (fRawClusters.size()*sizeof(AliHLTTPCRawCluster)>sizeInByte) {
567 HLTError("not enough space to write raw clusters");
570 memcpy(rawClusters, &fRawClusters[0], fRawClusters.size()*sizeof(AliHLTTPCRawCluster));
571 return fRawClusters.size();
574 void AliHLTTPCClusterFinder::FindClusters(){
575 // see header file for function documentation
577 AliHLTTPCClusters* tmpCandidate=NULL;
578 for(UInt_t row=0;row<fNumberOfRows;row++){
579 fRowOfFirstCandidate=row;
580 for(UInt_t pad=0;pad<fNumberOfPadsInRow[row];pad++){
581 AliHLTTPCPad *tmpPad=fRowPadVector[row][pad];
582 for(size_t candidate=0;candidate<tmpPad->fClusterCandidates.size();candidate++){
583 if(tmpPad->fUsedClusterCandidates[candidate]){
586 tmpCandidate=&tmpPad->fClusterCandidates[candidate];
587 UInt_t tmpTotalCharge=tmpCandidate->fTotalCharge;
590 fClusterMCVector.clear();
591 FillMCClusterVector(tmpPad->GetCandidateDigits(candidate));
594 ComparePads(fRowPadVector[row][pad+1],tmpCandidate,pad+1);
595 if(tmpCandidate->fTotalCharge>tmpTotalCharge){
597 fClusters.push_back(*tmpCandidate);
599 //sort the vector (large->small) according to weight and remove elements above 2 (keep 0 1 and 2)
600 sort(fClusterMCVector.begin(),fClusterMCVector.end(), CompareWeights );
601 AliHLTTPCClusterMCLabel tmpClusterMCInfo;
603 AliHLTTPCClusterMCWeight zeroMC;
607 if(fClusterMCVector.size()>0){
608 tmpClusterMCInfo.fClusterID[0]=fClusterMCVector.at(0);
611 tmpClusterMCInfo.fClusterID[0]=zeroMC;
614 if(fClusterMCVector.size()>1){
615 tmpClusterMCInfo.fClusterID[1]=fClusterMCVector.at(1);
618 tmpClusterMCInfo.fClusterID[1]=zeroMC;
621 if(fClusterMCVector.size()>2){
622 tmpClusterMCInfo.fClusterID[2]=fClusterMCVector.at(2);
625 tmpClusterMCInfo.fClusterID[2]=zeroMC;
628 fClustersMCInfo.push_back(tmpClusterMCInfo);
633 tmpPad->ClearCandidates();
635 fRowPadVector[row][fNumberOfPadsInRow[row]]->ClearCandidates();
638 HLTInfo("Found %d clusters.",fClusters.size());
640 //TODO: Change so it stores AliHLTTPCSpacePointData directly, instead of this copying
642 AliClusterData * clusterlist = new AliClusterData[fClusters.size()]; //Clusterlist
643 for(unsigned int i=0;i<fClusters.size();i++){
644 clusterlist[i].fTotalCharge = fClusters[i].fTotalCharge;
645 clusterlist[i].fPad = fClusters[i].fPad;
646 clusterlist[i].fPad2 = fClusters[i].fPad2;
647 clusterlist[i].fTime = fClusters[i].fTime;
648 clusterlist[i].fTime2 = fClusters[i].fTime2;
649 clusterlist[i].fMean = fClusters[i].fMean;
650 clusterlist[i].fFlags = fClusters[i].fFlags;
651 clusterlist[i].fChargeFalling = fClusters[i].fChargeFalling;
652 clusterlist[i].fLastCharge = fClusters[i].fLastCharge;
653 clusterlist[i].fLastMergedPad = fClusters[i].fLastMergedPad;
654 clusterlist[i].fRow = fClusters[i].fRowNumber;
655 clusterlist[i].fQMax = fClusters[i].fQMax;
658 WriteClusters(fClusters.size(),clusterlist);
659 delete [] clusterlist;
661 if( fReleaseMemory ) DeInitializePadArray();// call this when the -releaseMemory flag is set
665 Bool_t AliHLTTPCClusterFinder::UpdateCalibDB(){
668 AliTPCcalibDB::Instance()->Update();
672 //uptate the transform class
674 fOfflineTransform = AliTPCcalibDB::Instance()->GetTransform();
675 if(!fOfflineTransform){
676 HLTError("AliHLTTPCClusterFinder()::UpdateCAlibDB:: Offline transform not in AliTPCcalibDB.");
680 fOfflineTransform->SetCurrentRecoParam(&fOfflineTPCRecoParam);
683 fOfflineTPCParam = AliTPCcalibDB::Instance()->GetParameters();
684 if( !fOfflineTPCParam ){
685 HLTError("AliHLTTPCClusterFinder()::UpdateCAlibDB:: Offline TPC parameters not in AliTPCcalibDB.");
688 fOfflineTPCParam->Update();
689 fOfflineTPCParam->ReadGeoMatrices();
695 //---------------------------------- Under this line the old sorted clusterfinder functions can be found --------------------------------
698 void AliHLTTPCClusterFinder::PrintClusters(){
699 // see header file for class documentation
701 for(size_t i=0;i<fClusters.size();i++){
702 HLTInfo("Cluster number: %d",i);
703 HLTInfo("Row: %d \t Pad: %d",fClusters[i].fRowNumber,fClusters[i].fPad/fClusters[i].fTotalCharge);
704 HLTInfo("Total Charge: %d",fClusters[i].fTotalCharge);
705 HLTInfo("fPad: %d",fClusters[i].fPad);
706 HLTInfo("PadError: %d",fClusters[i].fPad2);
707 HLTInfo("TimeMean: %d",fClusters[i].fTime/fClusters[i].fTotalCharge);
708 HLTInfo("TimeError: %d",fClusters[i].fTime2);
709 HLTInfo("EndOfCluster:");
713 void AliHLTTPCClusterFinder::FillMCClusterVector(vector<AliHLTTPCDigitData> *digitData){
714 // see header file for class documentation
715 if( !digitData ) return;
716 for(UInt_t d=0;d<digitData->size();d++){
717 Int_t nIDsInDigit = (digitData->at(d).fTrackID[0]>=0) + (digitData->at(d).fTrackID[1]>=0) + (digitData->at(d).fTrackID[2]>=0);
718 for(Int_t id=0; id<3; id++){
719 if(digitData->at(d).fTrackID[id]>=0){
720 Bool_t matchFound = kFALSE;
721 AliHLTTPCClusterMCWeight mc;
722 mc.fMCID = digitData->at(d).fTrackID[id];
723 mc.fWeight = ((Float_t)digitData->at(d).fCharge)/nIDsInDigit;
724 for(UInt_t i=0;i<fClusterMCVector.size();i++){
725 if(mc.fMCID == fClusterMCVector.at(i).fMCID){
726 fClusterMCVector.at(i).fWeight += mc.fWeight;
730 if(matchFound == kFALSE){
731 fClusterMCVector.push_back(mc);
739 void AliHLTTPCClusterFinder::Read(void* ptr,unsigned long size){
741 fPtr = (UChar_t*)ptr;
745 void AliHLTTPCClusterFinder::ProcessDigits(){
746 // see header file for class documentation
749 bool readValue = true;
752 UShort_t time=0,newTime=0;
753 UInt_t pad=0,newPad=0;
754 AliHLTTPCSignal_t charge=0;
758 // initialize block for reading packed data
759 iResult=fDigitReader->InitBlock(fPtr,fSize,fFirstRow,fLastRow,fCurrentPatch,fCurrentSlice);
760 if (iResult<0) return;
762 readValue = fDigitReader->Next();
764 // Matthias 08.11.2006 the following return would cause termination without writing the
765 // ClusterData and thus would block the component. I just want to have the commented line
766 // here for information
767 //if (!readValue)return;
769 pad = fDigitReader->GetPad();
770 time = fDigitReader->GetTime();
771 fCurrentRow = fDigitReader->GetRow();
773 if ( fCurrentPatch >= 2 ) // Outer sector, patches 2, 3, 4, 5
774 rowOffset = AliHLTTPCTransform::GetFirstRow( 2 );
776 fCurrentRow += rowOffset;
778 UInt_t lastpad = 123456789;
779 const UInt_t kPadArraySize=5000;
780 const UInt_t kClusterListSize=10000;
781 AliClusterData *pad1[kPadArraySize]; //2 lists for internal memory=2pads
782 AliClusterData *pad2[kPadArraySize]; //2 lists for internal memory=2pads
783 AliClusterData clusterlist[kClusterListSize]; //Clusterlist
785 AliClusterData **currentPt; //List of pointers to the current pad
786 AliClusterData **previousPt; //List of pointers to the previous pad
789 UInt_t nprevious=0,ncurrent=0,ntotal=0;
791 /* quick implementation of baseline calculation and zero suppression
792 open a pad object for each pad and delete it after processing.
793 later a list of pad objects with base line history can be used
794 The whole thing only works if we really get unprocessed raw data, if
795 the data is already zero suppressed, there might be gaps in the time
798 Int_t gatingGridOffset=50;
800 gatingGridOffset=fFirstTimeBin;
802 AliHLTTPCPad baseline(gatingGridOffset, AliHLTTPCTransform::GetNTimeBins());
803 // just to make later conversion to a list of objects easier
804 AliHLTTPCPad* pCurrentPad=NULL;
806 if (fSignalThreshold>=0) {
807 pCurrentPad=&baseline;
808 baseline.SetThreshold(fSignalThreshold);
811 while ( readValue!=0 && iResult>=0){ // Reads through all digits in block
818 if(currentPt == pad2){
826 nprevious = ncurrent;
828 if(pad != lastpad+1){
829 //this happens if there is a pad with no signal.
830 nprevious = ncurrent = 0;
835 Bool_t newcluster = kTRUE;
836 UInt_t seqcharge=0,seqaverage=0,seqerror=0;
837 AliHLTTPCSignal_t lastcharge=0;
838 UInt_t bLastWasFalling=0;
843 redo: //This is a goto.
854 while(iResult>=0){ //Loop over time bins of current pad
855 // read all the values for one pad at once to calculate the base line
857 if (!pCurrentPad->IsStarted()) {
858 //HLTDebug("reading data for pad %d, padrow %d", fDigitReader->GetPad(), fDigitReader->GetRow()+rowOffset);
859 pCurrentPad->SetID(fDigitReader->GetRow()+rowOffset,fDigitReader->GetPad());
860 if ((pCurrentPad->StartEvent())>=0) {
862 if ((fDigitReader->GetRow()+rowOffset)!=pCurrentPad->GetRowNumber()) break;
863 if (fDigitReader->GetPad()!=pCurrentPad->GetPadNumber()) break;
864 pCurrentPad->SetRawData(fDigitReader->GetTime(), fDigitReader->GetSignal());
865 //HLTDebug("set raw data to pad: bin %d charge %d", fDigitReader->GetTime(), fDigitReader->GetSignal());
866 } while ((readValue = fDigitReader->Next())!=0);
868 pCurrentPad->CalculateBaseLine(AliHLTTPCTransform::GetNTimeBins()/2);
869 if (pCurrentPad->Next(kTRUE/*do zero suppression*/)==0) {
870 //HLTDebug("no data available after zero suppression");
871 pCurrentPad->StopEvent();
872 pCurrentPad->ResetHistory();
875 time=pCurrentPad->GetCurrentPosition();
876 if (time>pCurrentPad->GetSize()) {
877 HLTError("invalid time bin for pad");
883 Float_t occupancy=pCurrentPad->GetOccupancy();
884 //HLTDebug("pad %d occupancy level: %f", pCurrentPad->GetPadNumber(), occupancy);
885 if ( occupancy < fOccupancyLimit ) {
886 charge = pCurrentPad->GetCorrectedData();
889 //HLTDebug("ignoring pad %d with occupancy level %f", pCurrentPad->GetPadNumber(), occupancy);
892 charge = fDigitReader->GetSignal();
894 //HLTDebug("get next charge value: position %d charge %d", time, charge);
898 if (fDigitReader->GetRow() == 90){
899 ///// LOG(AliHLTTPCLog::kFatal,"AliHLTTPCClusterFinder::Row","row90") << "PAD=" << fDigitReader->GetPad() << " TIME=" << fDigitReader->GetTime()
900 // << " SIGNAL=" << fDigitReader->GetSignal() << ENDLOG;
904 if(time >= AliHLTTPCTransform::GetNTimeBins()){
905 HLTWarning("Pad %d: Timebin (%d) out of range (%d)", pad, time, AliHLTTPCTransform::GetNTimeBins());
910 //Get the current ADC-value
913 //Check if the last pixel in the sequence is smaller than this
914 if(charge > lastcharge){
920 else bLastWasFalling = 1; //last pixel was larger than this
924 //Sum the total charge of this sequence
926 seqaverage += time*charge;
927 seqerror += time*time*charge;
931 if((pCurrentPad->Next(kTRUE/*do zero suppression*/))==0) {
932 pCurrentPad->StopEvent();
933 pCurrentPad->ResetHistory();
935 newPad = fDigitReader->GetPad();
936 newTime = fDigitReader->GetTime();
937 newRow = fDigitReader->GetRow() + rowOffset;
942 newPad=pCurrentPad->GetPadNumber();
943 newTime=pCurrentPad->GetCurrentPosition();
944 newRow=pCurrentPad->GetRowNumber();
946 readValue = fDigitReader->Next();
947 //Check where to stop:
948 if(!readValue) break; //No more value
950 newPad = fDigitReader->GetPad();
951 newTime = fDigitReader->GetTime();
952 newRow = fDigitReader->GetRow() + rowOffset;
955 if(newPad != pad)break; //new pad
956 if(newTime != time+1) break; //end of sequence
959 // pad = newpad; is equal
962 }//end loop over sequence
964 //HLTDebug("ended time bin sequence loop: seqcharge=%d readValue=%d", seqcharge, readValue);
965 //HLTDebug("pad=%d newpad=%d current row=%d newrow=%d", pad, newPad, fCurrentRow, newRow);
967 // with active zero suppression zero values are possible
971 //Calculate mean of sequence:
974 seqmean = seqaverage/seqcharge;
976 LOG(AliHLTTPCLog::kFatal,"AliHLTTPCClusterFinder::ProcessRow","Data")
977 <<"Error in data given to the cluster finder"<<ENDLOG;
982 //Calculate mean in pad direction:
983 Int_t padmean = seqcharge*pad;
984 Int_t paderror = pad*padmean;
986 //Compare with results on previous pad:
987 for(UInt_t p=0; p<nprevious && p<kPadArraySize && ncurrent<kPadArraySize; p++){
989 //dont merge sequences on the same pad twice
990 if(previousPt[p]->fLastMergedPad==pad) continue;
992 Int_t difference = seqmean - previousPt[p]->fMean;
993 if(difference < -fMatch) break;
995 if(difference <= fMatch){ //There is a match here!!
996 AliClusterData *local = previousPt[p];
999 if(seqcharge > local->fLastCharge){
1000 if(local->fChargeFalling){ //The previous pad was falling
1001 break; //create a new cluster
1004 else local->fChargeFalling = 1;
1005 local->fLastCharge = seqcharge;
1008 //Don't create a new cluster, because we found a match
1009 newcluster = kFALSE;
1011 //Update cluster on current pad with the matching one:
1012 local->fTotalCharge += seqcharge;
1013 local->fPad += padmean;
1014 local->fPad2 += paderror;
1015 local->fTime += seqaverage;
1016 local->fTime2 += seqerror;
1017 local->fMean = seqmean;
1018 local->fFlags++; //means we have more than one pad
1019 local->fLastMergedPad = pad;
1021 currentPt[ncurrent] = local;
1025 } //Checking for match at previous pad
1026 } //Loop over results on previous pad.
1028 if(newcluster && ncurrent<kPadArraySize){
1029 //Start a new cluster. Add it to the clusterlist, and update
1030 //the list of pointers to clusters in current pad.
1031 //current pad will be previous pad on next pad.
1033 //Add to the clusterlist:
1034 AliClusterData *tmp = &clusterlist[ntotal];
1035 tmp->fTotalCharge = seqcharge;
1036 tmp->fPad = padmean;
1037 tmp->fPad2 = paderror;
1038 tmp->fTime = seqaverage;
1039 tmp->fTime2 = seqerror;
1040 tmp->fMean = seqmean;
1041 tmp->fFlags = 0; //flags for single pad clusters
1042 tmp->fLastMergedPad = pad;
1045 tmp->fChargeFalling = 0;
1046 tmp->fLastCharge = seqcharge;
1049 //Update list of pointers to previous pad:
1050 currentPt[ncurrent] = &clusterlist[ntotal];
1056 if(newbin >= 0) goto redo;
1058 // to prevent endless loop
1059 if(time >= AliHLTTPCTransform::GetNTimeBins()){
1060 HLTWarning("Timebin (%d) out of range (%d)", time, AliHLTTPCTransform::GetNTimeBins());
1065 if(!readValue) break; //No more value
1067 if (ntotal>=kClusterListSize || ncurrent>=kPadArraySize) {
1068 HLTWarning("pad array size exceeded ntotal=%d ncurrent=%d, skip rest of the data", ntotal, ncurrent);
1072 if(fCurrentRow != newRow){
1073 WriteClusters(ntotal,clusterlist);
1075 lastpad = 123456789;
1083 fCurrentRow = newRow;
1089 } // END while(readValue)
1091 WriteClusters(ntotal,clusterlist);
1093 HLTInfo("ClusterFinder found %d clusters in slice %d patch %d", fNClusters, fCurrentSlice, fCurrentPatch);
1097 void AliHLTTPCClusterFinder::WriteClusters(Int_t nclusters,AliClusterData *list){
1098 // see header file for class documentation
1100 //write cluster to output pointer
1101 Int_t thisrow=-1,thissector=-1;
1102 UInt_t counter = fNClusters;
1104 if (fFillRawClusters) {
1105 fRawClusters.resize(nclusters);
1108 for(int j=0; j<nclusters; j++)
1113 if(!list[j].fFlags){
1115 if(j+(Int_t)fClustersMCInfo.size()-nclusters >=0 && j+fClustersMCInfo.size()-nclusters < fClustersMCInfo.size()){
1116 fClustersMCInfo.erase(fClustersMCInfo.begin()+j+fClustersMCInfo.size()-nclusters); // remove the mc info for this cluster since it is not taken into account
1119 continue; //discard single pad clusters
1121 if(list[j].fTotalCharge < fThreshold){
1123 if(j+(Int_t)fClustersMCInfo.size()-nclusters >=0 && j+fClustersMCInfo.size()-nclusters < fClustersMCInfo.size()){
1124 fClustersMCInfo.erase(fClustersMCInfo.begin()+j+fClustersMCInfo.size()-nclusters); // remove the mc info for this cluster since it is not taken into account
1127 continue; //noise cluster
1130 Float_t fpad =(Float_t)list[j].fPad / list[j].fTotalCharge;
1131 Float_t fpad2=fXYErr*fXYErr; //fixed given error
1132 Float_t ftime =(Float_t)list[j].fTime / list[j].fTotalCharge;
1133 Float_t ftime2=fZErr*fZErr; //fixed given error
1138 fCurrentRow=list[j].fRow;
1142 if(fCalcerr) { //calc the errors, otherwice take the fixed error
1143 Int_t patch = AliHLTTPCTransform::GetPatch(fCurrentRow);
1144 UInt_t q2=list[j].fTotalCharge*list[j].fTotalCharge;
1145 // Float_t sy2=list[j].fPad2 * list[j].fTotalCharge - list[j].fPad * list[j].fPad;
1146 Float_t sy2=(Float_t)list[j].fPad2 * list[j].fTotalCharge - (Float_t)list[j].fPad * list[j].fPad;
1148 LOG(AliHLTTPCLog::kError,"AliHLTTPCClusterFinder::WriteClusters","Cluster width")
1149 <<"zero charge "<< list[j].fTotalCharge <<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
1154 LOG(AliHLTTPCLog::kError,"AliHLTTPCClusterFinder::WriteClusters","Cluster width")
1155 <<"SigmaY2 negative "<<sy2<<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
1159 fpad2 = (sy2 + 1./12)*AliHLTTPCTransform::GetPadPitchWidth(patch)*AliHLTTPCTransform::GetPadPitchWidth(patch);
1161 fpad2*=0.108; //constants are from offline studies
1167 // Float_t sz2=list[j].fTime2*list[j].fTotalCharge - list[j].fTime*list[j].fTime;
1168 Float_t sz2=(Float_t)list[j].fTime2*list[j].fTotalCharge - (Float_t)list[j].fTime*list[j].fTime;
1171 LOG(AliHLTTPCLog::kError,"AliHLTTPCClusterFinder::WriteClusters","Cluster width")
1172 <<"SigmaZ2 negative "<<sz2<<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
1176 ftime2 = (sz2 + 1./12)*AliHLTTPCTransform::GetZWidth()*AliHLTTPCTransform::GetZWidth();
1178 ftime2 *= 0.169; //constants are from offline studies
1186 HLTInfo("WriteCluster: padrow %d pad %d +- %d time +- %d charge %d",fCurrentRow, fpad, fpad2, ftime, ftime2, list[j].fTotalCharge);
1188 if (fFillRawClusters && fRawClusters.size()>(unsigned)counter) {
1189 fRawClusters[counter].SetPadRow(fCurrentRow);
1190 fRawClusters[counter].SetPad(fpad);
1191 fRawClusters[counter].SetTime(ftime);
1194 AliHLTTPCTransform::Slice2Sector(fCurrentSlice,fCurrentRow,thissector,thisrow);
1196 if(fOfflineTransform == NULL){
1197 AliHLTTPCTransform::Raw2Local(xyz,thissector,thisrow,fpad,ftime);
1199 if(xyz[0]==0) LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinder","Cluster Finder")
1200 <<AliHLTTPCLog::kDec<<"Zero cluster"<<ENDLOG;
1201 if(fNClusters >= fMaxNClusters)
1203 LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinder::WriteClusters","Cluster Finder")
1204 <<AliHLTTPCLog::kDec<<"Too many clusters "<<fNClusters<<ENDLOG;
1208 fSpacePointData[counter].fX = xyz[0];
1209 // fSpacePointData[counter].fY = xyz[1];
1210 if(fCurrentSlice<18){
1211 fSpacePointData[counter].fY = xyz[1];
1214 fSpacePointData[counter].fY = -1*xyz[1];
1216 fSpacePointData[counter].fZ = xyz[2];
1219 Double_t x[3]={thisrow,fpad+.5,ftime};
1220 Int_t iSector[1]={thissector};
1221 fOfflineTransform->Transform(x,iSector,0,1);
1222 double y[3] = {x[0], x[1], x[2] };
1224 if( fOfflineTPCParam && thissector<fOfflineTPCParam->GetNSector() ){
1225 TGeoHMatrix *alignment = fOfflineTPCParam->GetClusterMatrix( thissector );
1226 if ( alignment ) alignment->LocalToMaster( x, y);
1229 fSpacePointData[counter].fX = y[0];
1230 fSpacePointData[counter].fY = y[1];
1231 fSpacePointData[counter].fZ = y[2];
1236 fSpacePointData[counter].fCharge = list[j].fTotalCharge;
1237 fSpacePointData[counter].fPadRow = fCurrentRow;
1238 fSpacePointData[counter].fSigmaY2 = fpad2;
1239 fSpacePointData[counter].fSigmaZ2 = ftime2;
1241 fSpacePointData[counter].fQMax = list[j].fQMax;
1243 fSpacePointData[counter].SetUsed(kFALSE); // only used / set in AliHLTTPCDisplay
1244 fSpacePointData[counter].SetTrackNumber(-1); // only used / set in AliHLTTPCDisplay
1246 Int_t patch=fCurrentPatch;
1247 if(patch==-1) patch=0; //never store negative patch number
1248 fSpacePointData[counter].SetID( fCurrentSlice, patch, counter );
1250 if (fFillRawClusters && fRawClusters.size()>(unsigned)counter) {
1251 fRawClusters[counter].SetSigmaY2(fSpacePointData[counter].fSigmaY2);
1252 fRawClusters[counter].SetSigmaZ2(fSpacePointData[counter].fSigmaZ2);
1253 fRawClusters[counter].SetCharge(fSpacePointData[counter].fCharge);
1254 fRawClusters[counter].SetQMax(fSpacePointData[counter].fQMax);
1259 GetTrackID((Int_t)rint(fpad),(Int_t)rint(ftime),trackID);
1261 fSpacePointData[counter].fTrackID[0] = trackID[0];
1262 fSpacePointData[counter].fTrackID[1] = trackID[1];
1263 fSpacePointData[counter].fTrackID[2] = trackID[2];
1272 // STILL TO FIX ----------------------------------------------------------------------------
1275 void AliHLTTPCClusterFinder::GetTrackID(Int_t pad,Int_t time,Int_t *trackID) const {
1276 // see header file for class documentation
1279 AliHLTTPCDigitRowData *rowPt = (AliHLTTPCDigitRowData*)fDigitRowData;
1281 trackID[0]=trackID[1]=trackID[2]=-2;
1282 for(Int_t i=fFirstRow; i<=fLastRow; i++){
1283 if(rowPt->fRow < (UInt_t)fCurrentRow){
1284 AliHLTTPCMemHandler::UpdateRowPointer(rowPt);
1287 AliHLTTPCDigitData *digPt = (AliHLTTPCDigitData*)rowPt->fDigitData;
1288 for(UInt_t j=0; j<rowPt->fNDigit; j++){
1289 Int_t cpad = digPt[j].fPad;
1290 Int_t ctime = digPt[j].fTime;
1291 if(cpad != pad) continue;
1292 if(ctime != time) continue;
1294 trackID[0] = digPt[j].fTrackID[0];
1295 trackID[1] = digPt[j].fTrackID[1];
1296 trackID[2] = digPt[j].fTrackID[2];
1307 void AliHLTTPCClusterFinder::WriteClusters(Int_t nclusters,AliHLTTPCClusters *list){//This is used when using the AliHLTTPCClusters class for cluster data
1308 // see header file for class documentation
1310 //write cluster to output pointer
1311 Int_t thisrow,thissector;
1312 UInt_t counter = fNClusters;
1314 if (fFillRawClusters) {
1315 fRawClusters.resize(nclusters);
1318 for(int j=0; j<nclusters; j++)
1320 if(!list[j].fFlags) continue; //discard single pad clusters
1321 if(list[j].fTotalCharge < fThreshold) continue; //noise cluster
1324 Float_t fpad =(Float_t)list[j].fPad / list[j].fTotalCharge;
1325 Float_t fpad2=fXYErr*fXYErr; //fixed given error
1326 Float_t ftime =(Float_t)list[j].fTime / list[j].fTotalCharge;
1327 Float_t ftime2=fZErr*fZErr; //fixed given error
1330 if(fCalcerr) { //calc the errors, otherwice take the fixed error
1331 Int_t patch = AliHLTTPCTransform::GetPatch(fCurrentRow);
1332 UInt_t q2=list[j].fTotalCharge*list[j].fTotalCharge;
1333 Float_t sy2=list[j].fPad2 * list[j].fTotalCharge - list[j].fPad * list[j].fPad;
1336 LOG(AliHLTTPCLog::kError,"AliHLTTPCClusterFinder::WriteClusters","Cluster width")
1337 <<"SigmaY2 negative "<<sy2<<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
1341 fpad2 = (sy2 + 1./12)*AliHLTTPCTransform::GetPadPitchWidth(patch)*AliHLTTPCTransform::GetPadPitchWidth(patch);
1343 fpad2*=0.108; //constants are from offline studies
1349 Float_t sz2=list[j].fTime2*list[j].fTotalCharge - list[j].fTime*list[j].fTime;
1352 LOG(AliHLTTPCLog::kError,"AliHLTTPCClusterFinder::WriteClusters","Cluster width")
1353 <<"SigmaZ2 negative "<<sz2<<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
1357 ftime2 = (sz2 + 1./12)*AliHLTTPCTransform::GetZWidth()*AliHLTTPCTransform::GetZWidth();
1359 ftime2 *= 0.169; //constants are from offline studies
1367 HLTInfo("WriteCluster: padrow %d pad %d +- %d time +- %d charge %d",fCurrentRow, fpad, fpad2, ftime, ftime2, list[j].fTotalCharge);
1369 if (fFillRawClusters && fRawClusters.size()>(unsigned)counter) {
1370 fRawClusters[counter].SetPadRow(fCurrentRow);
1371 fRawClusters[counter].SetPad(fpad);
1372 fRawClusters[counter].SetTime(ftime);
1375 AliHLTTPCTransform::Slice2Sector(fCurrentSlice,fCurrentRow,thissector,thisrow);
1376 AliHLTTPCTransform::Raw2Local(xyz,thissector,thisrow,fpad,ftime);
1378 if(xyz[0]==0) LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinder","Cluster Finder")
1379 <<AliHLTTPCLog::kDec<<"Zero cluster"<<ENDLOG;
1380 if(fNClusters >= fMaxNClusters)
1382 LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinder::WriteClusters","Cluster Finder")
1383 <<AliHLTTPCLog::kDec<<"Too many clusters "<<fNClusters<<ENDLOG;
1387 fSpacePointData[counter].fX = xyz[0];
1388 // fSpacePointData[counter].fY = xyz[1];
1389 if(fCurrentSlice<18){
1390 fSpacePointData[counter].fY = xyz[1];
1393 fSpacePointData[counter].fY = -1*xyz[1];
1395 fSpacePointData[counter].fZ = xyz[2];
1399 fSpacePointData[counter].fCharge = list[j].fTotalCharge;
1400 fSpacePointData[counter].fPadRow = fCurrentRow;
1401 fSpacePointData[counter].fSigmaY2 = fpad2;
1402 fSpacePointData[counter].fSigmaZ2 = ftime2;
1404 fSpacePointData[counter].fQMax = list[j].fQMax;
1406 fSpacePointData[counter].SetUsed(kFALSE); // only used / set in AliHLTTPCDisplay
1407 fSpacePointData[counter].SetTrackNumber(-1); // only used / set in AliHLTTPCDisplay
1409 Int_t patch=fCurrentPatch;
1410 if(patch==-1) patch=0; //never store negative patch number
1411 fSpacePointData[counter].SetID( fCurrentSlice, patch, counter );
1413 if (fFillRawClusters && fRawClusters.size()>(unsigned)counter) {
1414 fRawClusters[counter].SetSigmaY2(fSpacePointData[counter].fSigmaY2);
1415 fRawClusters[counter].SetSigmaZ2(fSpacePointData[counter].fSigmaZ2);
1416 fRawClusters[counter].SetCharge(fSpacePointData[counter].fCharge);
1417 fRawClusters[counter].SetQMax(fSpacePointData[counter].fQMax);
1422 GetTrackID((Int_t)rint(fpad),(Int_t)rint(ftime),trackID);
1424 fSpacePointData[counter].fTrackID[0] = trackID[0];
1425 fSpacePointData[counter].fTrackID[1] = trackID[1];
1426 fSpacePointData[counter].fTrackID[2] = trackID[2];