3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Anders Vestbo, Constantin Loizides *
8 //* Developers: Kenneth Aamodt <kenneth.aamodt@student.uib.no> *
10 //* for The ALICE HLT Project. *
12 //* Permission to use, copy, modify and distribute this software and its *
13 //* documentation strictly for non-commercial purposes is hereby granted *
14 //* without fee, provided that the above copyright notice appears in all *
15 //* copies and that both the copyright notice and this permission notice *
16 //* appear in the supporting documentation. The authors make no claims *
17 //* about the suitability of this software for any purpose. It is *
18 //* provided "as is" without express or implied warranty. *
19 //**************************************************************************
21 // @file AliHLTTPCClusterFinder.cxx
22 // @author Kenneth Aamodt, Kalliopi Kanaki
24 // @brief Cluster Finder for the TPC
27 #include "AliHLTTPCDigitReader.h"
28 #include "AliHLTTPCLogging.h"
29 #include "AliHLTTPCClusterFinder.h"
30 #include "AliHLTTPCSpacePointData.h"
31 #include "AliHLTTPCPad.h"
35 #include "AliTPCcalibDB.h"
36 #include "AliTPCTransform.h"
37 #include "AliTPCParam.h"
43 ClassImp(AliHLTTPCClusterFinder)
45 AliHLTTPCClusterFinder::AliHLTTPCClusterFinder()
47 fClustersHWAddressVector(),
49 fSpacePointData(NULL),
57 fFillRawClusters(kFALSE),
71 fVectorInitialized(kFALSE),
76 fNumberOfPadsInRow(NULL),
78 fRowOfFirstCandidate(0),
79 fDoPadSelection(kFALSE),
81 fLastTimeBin(AliHLTTPCTransform::GetNTimeBins()),
82 fTotalChargeOfPreviousClusterCandidate(0),
83 fChargeOfCandidatesFalling(kFALSE),
87 fOfflineTransform(NULL),
88 fOfflineTPCParam( NULL ),
89 fOfflineTPCRecoParam(*AliTPCRecoParam::GetHLTParam()),
95 //uptate the transform class
97 fOfflineTransform = AliTPCcalibDB::Instance()->GetTransform();
98 if(!fOfflineTransform){
99 HLTError("AliHLTTPCClusterFinder()::UpdateCAlibDB:: Offline transform not in AliTPCcalibDB.");
102 fOfflineTransform->SetCurrentRecoParam(&fOfflineTPCRecoParam);
105 fOfflineTPCParam = AliTPCcalibDB::Instance()->GetParameters();
106 if( !fOfflineTPCParam ){
107 HLTError("AliHLTTPCClusterFinder()::UpdateCAlibDB:: Offline TPC parameters not in AliTPCcalibDB.");
109 fOfflineTPCParam->Update();
110 fOfflineTPCParam->ReadGeoMatrices();
115 AliHLTTPCClusterFinder::~AliHLTTPCClusterFinder(){
116 // see header file for class documentation
119 if(fVectorInitialized){
120 DeInitializePadArray();
122 if(fNumberOfPadsInRow){
123 delete [] fNumberOfPadsInRow;
124 fNumberOfPadsInRow=NULL;
128 void AliHLTTPCClusterFinder::InitSlice(Int_t slice,Int_t patch,Int_t nmaxpoints){
129 // see header file for class documentation
133 fMaxNClusters = nmaxpoints;
134 fCurrentSlice = slice;
135 fCurrentPatch = patch;
136 fFirstRow=AliHLTTPCTransform::GetFirstRow(patch);
137 fLastRow=AliHLTTPCTransform::GetLastRow(patch);
140 fClustersMCInfo.clear();
142 fClusterMCVector.clear();
143 fRawClusters.clear();
146 void AliHLTTPCClusterFinder::InitializePadArray(){
147 // see header file for class documentation
149 if(fCurrentPatch>5||fCurrentPatch<0){
150 HLTFatal("Patch is not set");
154 HLTDebug("Patch number=%d",fCurrentPatch);
156 fFirstRow = AliHLTTPCTransform::GetFirstRow(fCurrentPatch);
157 fLastRow = AliHLTTPCTransform::GetLastRow(fCurrentPatch);
159 fNumberOfRows=fLastRow-fFirstRow+1;
160 fNumberOfPadsInRow= new UInt_t[fNumberOfRows];
162 memset( fNumberOfPadsInRow, 0, sizeof(Int_t)*(fNumberOfRows));
164 fRowPadVector.clear();
166 for(UInt_t i=0;i<fNumberOfRows;i++){
167 fNumberOfPadsInRow[i]=AliHLTTPCTransform::GetNPads(i+fFirstRow);
168 AliHLTTPCPadVector tmpRow;
169 for(UInt_t j=0;j<=fNumberOfPadsInRow[i];j++){
170 AliHLTTPCPad *tmpPad = new AliHLTTPCPad(2);
172 tmpRow.push_back(tmpPad);
174 fRowPadVector.push_back(tmpRow);
176 fVectorInitialized=kTRUE;
179 Int_t AliHLTTPCClusterFinder::DeInitializePadArray(){
180 // see header file for class documentation
182 if( fVectorInitialized ){
183 for(UInt_t i=0;i<fNumberOfRows;i++){
184 for(UInt_t j=0;j<=fNumberOfPadsInRow[i];j++){
185 delete fRowPadVector[i][j];
186 fRowPadVector[i][j]=NULL;
188 fRowPadVector[i].clear();
190 fRowPadVector.clear();
191 delete[] fNumberOfPadsInRow;
192 fNumberOfPadsInRow = 0;
194 fVectorInitialized=kFALSE;
199 void AliHLTTPCClusterFinder::SetOutputArray(AliHLTTPCSpacePointData *pt){
200 // see header file for class documentation
201 //set pointer to output
202 fSpacePointData = pt;
206 void AliHLTTPCClusterFinder::ReadDataUnsorted(void* ptr,unsigned long size){
207 // see header file for class documentation
209 fPtr = (UChar_t*)ptr;
212 if(!fVectorInitialized){
213 InitializePadArray();
216 if (fDigitReader->InitBlock(fPtr,fSize,fFirstRow,fLastRow,fCurrentPatch,fCurrentSlice)<0) {
217 HLTError("failed setting up digit reader (InitBlock)");
221 while(fDigitReader->NextChannel()){
222 UInt_t row=fDigitReader->GetRow();
223 UInt_t pad=fDigitReader->GetPad();
225 if(row>=fRowPadVector.size()){
226 HLTError("Row number is to large: %d, max is %d",row,fRowPadVector.size()-1);
229 if(pad>=fRowPadVector[row].size()){
230 HLTError("Pad number is to large: %d, max is %d",pad,fRowPadVector[row].size());
234 while(fDigitReader->NextBunch()){
235 if(fDigitReader->GetBunchSize()>1){//to remove single timebin values, this will have to change at some point
236 UInt_t time = fDigitReader->GetTime();
237 if((Int_t)time>=fFirstTimeBin && (Int_t)time+fDigitReader->GetBunchSize()<=fLastTimeBin){
238 // Kenneth: 20-04-09. The following if have been added because of inconsistency in the 40 bit decoder and the 32 bit decoder.
239 // GetSignals() in the 40 bit decoder returns an array of UInt_t while the 32 bit one returns UShort_t
240 // The same is true for the function ReadDataUnsortedDeconvoluteTime() below.
241 // In addition the signals are organized in the opposite direction
243 const UShort_t *bunchData= fDigitReader->GetSignalsShort();
244 AliHLTTPCClusters candidate;
245 for(Int_t i=fDigitReader->GetBunchSize()-1;i>=0;i--){
246 candidate.fTotalCharge+=bunchData[i];
247 candidate.fTime += time*bunchData[i];
248 candidate.fTime2 += time*time*bunchData[i];
249 if(bunchData[i]>candidate.fQMax){
250 candidate.fQMax=bunchData[i];
254 if(candidate.fTotalCharge>0){
255 candidate.fMean=candidate.fTime/candidate.fTotalCharge;
256 candidate.fPad=candidate.fTotalCharge*pad;
257 candidate.fPad2=candidate.fPad*pad;
258 candidate.fLastMergedPad=pad;
259 candidate.fRowNumber=row+fDigitReader->GetRowOffset();
261 if(fRowPadVector[row][pad] != NULL){
262 fRowPadVector[row][pad]->AddClusterCandidate(candidate);
266 const UInt_t *bunchData= fDigitReader->GetSignals();
267 AliHLTTPCClusters candidate;
268 const AliHLTTPCDigitData* digits = NULL;
269 if(fDoMC && (digits = fDigitReader->GetBunchDigits())!=NULL){
270 for(Int_t i=0;i<fDigitReader->GetBunchSize();i++){
271 candidate.fTotalCharge+=bunchData[i];
272 candidate.fTime += time*bunchData[i];
273 candidate.fTime2 += time*time*bunchData[i];
274 if(bunchData[i]>candidate.fQMax){
275 candidate.fQMax=bunchData[i];
277 fMCDigits.push_back(digits[i]);
282 for(Int_t i=0;i<fDigitReader->GetBunchSize();i++){
283 candidate.fTotalCharge+=bunchData[i];
284 candidate.fTime += time*bunchData[i];
285 candidate.fTime2 += time*time*bunchData[i];
286 if(bunchData[i]>candidate.fQMax){
287 candidate.fQMax=bunchData[i];
292 if(candidate.fTotalCharge>0){
293 candidate.fMean=candidate.fTime/candidate.fTotalCharge;
294 candidate.fPad=candidate.fTotalCharge*pad;
295 candidate.fPad2=candidate.fPad*pad;
296 candidate.fLastMergedPad=pad;
297 candidate.fRowNumber=row+fDigitReader->GetRowOffset();
299 if(fRowPadVector[row][pad] != NULL){
300 fRowPadVector[row][pad]->AddClusterCandidate(candidate);
302 fRowPadVector[row][pad]->AddCandidateDigits(fMCDigits);
313 void AliHLTTPCClusterFinder::ReadDataUnsortedDeconvoluteTime(void* ptr,unsigned long size){
314 // see header file for class documentation
317 fPtr = (UChar_t*)ptr;
320 if(!fVectorInitialized){
321 InitializePadArray();
324 if (fDigitReader->InitBlock(fPtr,fSize,fFirstRow,fLastRow,fCurrentPatch,fCurrentSlice)<0) {
325 HLTError("failed setting up digit reader (InitBlock)");
329 while(fDigitReader->NextChannel()){
330 UInt_t row=fDigitReader->GetRow();
331 UInt_t pad=fDigitReader->GetPad();
333 while(fDigitReader->NextBunch()){
334 if(fDigitReader->GetBunchSize()>1){//to remove single timebin values, this will have to change at some point
335 UInt_t time = fDigitReader->GetTime();
336 if((Int_t)time>=fFirstTimeBin && (Int_t)time+fDigitReader->GetBunchSize()<=fLastTimeBin){
337 Int_t indexInBunchData=0;
338 Bool_t moreDataInBunch=kFALSE;
340 Bool_t signalFalling=kFALSE;
342 // Kenneth: 20-04-09. The following if have been added because of inconsistency in the 40 bit decoder and the 32 bit decoder.
343 // GetSignals() in the 40 bit decoder returns an array of UInt_t while the 32 bit one returns UShort_t
344 // The same is true for the function ReadDataUnsorted() above.
345 // In addition the signals are organized in the opposite direction
347 indexInBunchData = fDigitReader->GetBunchSize()-1;
348 const UShort_t *bunchData= fDigitReader->GetSignalsShort();
351 AliHLTTPCClusters candidate;
352 //for(Int_t i=indexInBunchData;i<fDigitReader->GetBunchSize();i++){
353 for(Int_t i=indexInBunchData;i>=0;i--){
355 // Checks if one need to deconvolute the signals
356 if(bunchData[i]>prevSignal && signalFalling==kTRUE){
357 if(i<fDigitReader->GetBunchSize()-1){ // means there are more than one signal left in the bunch
358 moreDataInBunch=kTRUE;
364 // Checks if the signal is 0, then quit processing the data.
365 if(bunchData[i]==0 && i<fDigitReader->GetBunchSize()-1){//means we have 0 data fom the rcu, might happen depending on the configuration settings
366 moreDataInBunch=kTRUE;
371 if(prevSignal>bunchData[i]){//means the peak of the signal has been reached and deconvolution will happen if the signal rise again.
374 candidate.fTotalCharge+=bunchData[i];
375 candidate.fTime += time*bunchData[i];
376 candidate.fTime2 += time*time*bunchData[i];
377 if(bunchData[i]>candidate.fQMax){
378 candidate.fQMax=bunchData[i];
380 prevSignal=bunchData[i];
384 if(candidate.fTotalCharge>0){
385 candidate.fMean=candidate.fTime/candidate.fTotalCharge;
386 candidate.fPad=candidate.fTotalCharge*pad;
387 candidate.fPad2=candidate.fPad*pad;
388 candidate.fLastMergedPad=pad;
389 candidate.fRowNumber=row+fDigitReader->GetRowOffset();
391 fRowPadVector[row][pad]->AddClusterCandidate(candidate);
392 if(indexInBunchData<fDigitReader->GetBunchSize()-1){
393 moreDataInBunch=kFALSE;
395 }while(moreDataInBunch);
398 const UInt_t *bunchData= fDigitReader->GetSignals();
400 AliHLTTPCClusters candidate;
401 const AliHLTTPCDigitData* digits = fDigitReader->GetBunchDigits();
402 if(fDoMC) fMCDigits.clear();
404 for(Int_t i=indexInBunchData;i<fDigitReader->GetBunchSize();i++){
405 // Checks if one need to deconvolute the signals
406 if(bunchData[i]>prevSignal && signalFalling==kTRUE){
407 if(i<fDigitReader->GetBunchSize()-1){ // means there are more than one signal left in the bunch
408 moreDataInBunch=kTRUE;
414 // Checks if the signal is 0, then quit processing the data.
415 if(bunchData[i]==0 && i<fDigitReader->GetBunchSize()-1){//means we have 0 data fom the rcu, might happen depending on the configuration settings
416 moreDataInBunch=kTRUE;
421 if(prevSignal>bunchData[i]){//means the peak of the signal has been reached and deconvolution will happen if the signal rise again.
424 candidate.fTotalCharge+=bunchData[i];
425 candidate.fTime += time*bunchData[i];
426 candidate.fTime2 += time*time*bunchData[i];
427 if(bunchData[i]>candidate.fQMax){
428 candidate.fQMax=bunchData[i];
430 if( fDoMC ) fMCDigits.push_back(digits[i]);
432 prevSignal=bunchData[i];
436 if(candidate.fTotalCharge>0){
437 candidate.fMean=candidate.fTime/candidate.fTotalCharge;
438 candidate.fPad=candidate.fTotalCharge*pad;
439 candidate.fPad2=candidate.fPad*pad;
440 candidate.fLastMergedPad=pad;
441 candidate.fRowNumber=row+fDigitReader->GetRowOffset();
443 fRowPadVector[row][pad]->AddClusterCandidate(candidate);
445 fRowPadVector[row][pad]->AddCandidateDigits(fMCDigits);
448 if(indexInBunchData<fDigitReader->GetBunchSize()-1){
449 moreDataInBunch=kFALSE;
451 }while(moreDataInBunch);
459 Bool_t AliHLTTPCClusterFinder::ComparePads(AliHLTTPCPad *nextPad,AliHLTTPCClusters* cluster,Int_t nextPadToRead){
460 // see header file for class documentation
462 //Checking if we have a match on the next pad
463 for(UInt_t candidateNumber=0;candidateNumber<nextPad->fClusterCandidates.size();candidateNumber++){
464 if(nextPad->fUsedClusterCandidates[candidateNumber] == 1){
467 AliHLTTPCClusters *candidate =&nextPad->fClusterCandidates[candidateNumber];
468 // if(cluster->fMean-candidate->fMean==1 || candidate->fMean-cluster->fMean==1 || cluster->fMean-candidate->fMean==0){
470 if( abs((Int_t)(cluster->fMean - candidate->fMean)) <= fTimeMeanDiff ){
472 if(candidate->fTotalCharge<fTotalChargeOfPreviousClusterCandidate){//peak is reached
473 fChargeOfCandidatesFalling=kTRUE;
475 if(candidate->fTotalCharge>fTotalChargeOfPreviousClusterCandidate && fChargeOfCandidatesFalling==kTRUE){//we have deconvolution
479 cluster->fMean=candidate->fMean;
480 cluster->fTotalCharge+=candidate->fTotalCharge;
481 cluster->fTime += candidate->fTime;
482 cluster->fTime2 += candidate->fTime2;
483 cluster->fPad+=candidate->fPad;
484 cluster->fPad2+=candidate->fPad2;
485 cluster->fLastMergedPad=candidate->fPad;
486 if(candidate->fQMax>cluster->fQMax){
487 cluster->fQMax=candidate->fQMax;
490 FillMCClusterVector(nextPad->GetCandidateDigits(candidateNumber));
494 UInt_t rowNo = nextPad->GetRowNumber();
495 UInt_t padNo = nextPad->GetPadNumber();
497 fRowPadVector[rowNo][padNo-2]->fSelectedPad=kTRUE;
498 fRowPadVector[rowNo][padNo-2]->fHWAddress=(AliHLTUInt16_t)fDigitReader->GetAltroBlockHWaddr(rowNo,padNo-2);
500 fRowPadVector[rowNo][padNo-1]->fSelectedPad=kTRUE;// quick solution to set the first pad to selected
501 fRowPadVector[rowNo][padNo-1]->fHWAddress=(AliHLTUInt16_t)fDigitReader->GetAltroBlockHWaddr(rowNo,padNo-1);
502 fRowPadVector[rowNo][padNo]->fSelectedPad=kTRUE;
503 fRowPadVector[rowNo][padNo]->fHWAddress=(AliHLTUInt16_t)fDigitReader->GetAltroBlockHWaddr(rowNo,padNo);
506 //setting the matched pad to used
507 nextPad->fUsedClusterCandidates[candidateNumber]=1;
509 if(nextPadToRead<(Int_t)fNumberOfPadsInRow[fRowOfFirstCandidate]){
510 nextPad=fRowPadVector[fRowOfFirstCandidate][nextPadToRead];
511 ComparePads(nextPad,cluster,nextPadToRead);
521 Int_t AliHLTTPCClusterFinder::FillHWAddressList(AliHLTUInt16_t *hwaddlist, Int_t maxHWadd){
522 // see header file for class documentation
525 for(UInt_t row=0;row<fNumberOfRows;row++){
526 for(UInt_t pad=0;pad<fNumberOfPadsInRow[row]-1;pad++){
527 if(fRowPadVector[row][pad]->fSelectedPad){
528 if(counter<maxHWadd){
529 hwaddlist[counter]=(AliHLTUInt16_t)fRowPadVector[row][pad]->fHWAddress;
533 HLTWarning("To many hardwareaddresses, skip adding");
543 Int_t AliHLTTPCClusterFinder::FillOutputMCInfo(AliHLTTPCClusterMCLabel * outputMCInfo, Int_t maxNumberOfClusterMCInfo){
544 // see header file for class documentation
548 for(UInt_t mc=0;mc<fClustersMCInfo.size();mc++){
549 if(counter<maxNumberOfClusterMCInfo){
550 outputMCInfo[counter] = fClustersMCInfo[mc];
554 HLTWarning("To much MCInfo has been added (no more space), skip adding");
560 Int_t AliHLTTPCClusterFinder::FillOutputRaw(AliHLTTPCRawCluster* rawClusters, unsigned sizeInByte) const
562 // fill the raw clusters
563 if (fRawClusters.size()*sizeof(AliHLTTPCRawCluster)>sizeInByte) {
564 HLTError("not enough space to write raw clusters");
567 memcpy(rawClusters, &fRawClusters[0], fRawClusters.size()*sizeof(AliHLTTPCRawCluster));
568 return fRawClusters.size();
571 void AliHLTTPCClusterFinder::FindClusters(){
572 // see header file for function documentation
574 AliHLTTPCClusters* tmpCandidate=NULL;
575 for(UInt_t row=0;row<fNumberOfRows;row++){
576 fRowOfFirstCandidate=row;
577 for(UInt_t pad=0;pad<fNumberOfPadsInRow[row];pad++){
578 AliHLTTPCPad *tmpPad=fRowPadVector[row][pad];
579 for(size_t candidate=0;candidate<tmpPad->fClusterCandidates.size();candidate++){
580 if(tmpPad->fUsedClusterCandidates[candidate]){
583 tmpCandidate=&tmpPad->fClusterCandidates[candidate];
584 UInt_t tmpTotalCharge=tmpCandidate->fTotalCharge;
587 fClusterMCVector.clear();
588 FillMCClusterVector(tmpPad->GetCandidateDigits(candidate));
591 ComparePads(fRowPadVector[row][pad+1],tmpCandidate,pad+1);
592 if(tmpCandidate->fTotalCharge>tmpTotalCharge){
594 fClusters.push_back(*tmpCandidate);
596 //sort the vector (large->small) according to weight and remove elements above 2 (keep 0 1 and 2)
597 sort(fClusterMCVector.begin(),fClusterMCVector.end(), CompareWeights );
598 AliHLTTPCClusterMCLabel tmpClusterMCInfo;
600 AliHLTTPCClusterMCWeight zeroMC;
604 if(fClusterMCVector.size()>0){
605 tmpClusterMCInfo.fClusterID[0]=fClusterMCVector.at(0);
608 tmpClusterMCInfo.fClusterID[0]=zeroMC;
611 if(fClusterMCVector.size()>1){
612 tmpClusterMCInfo.fClusterID[1]=fClusterMCVector.at(1);
615 tmpClusterMCInfo.fClusterID[1]=zeroMC;
618 if(fClusterMCVector.size()>2){
619 tmpClusterMCInfo.fClusterID[2]=fClusterMCVector.at(2);
622 tmpClusterMCInfo.fClusterID[2]=zeroMC;
625 fClustersMCInfo.push_back(tmpClusterMCInfo);
630 tmpPad->ClearCandidates();
632 fRowPadVector[row][fNumberOfPadsInRow[row]]->ClearCandidates();
635 HLTInfo("Found %d clusters.",fClusters.size());
637 //TODO: Change so it stores AliHLTTPCSpacePointData directly, instead of this copying
639 AliClusterData * clusterlist = new AliClusterData[fClusters.size()]; //Clusterlist
640 for(unsigned int i=0;i<fClusters.size();i++){
641 clusterlist[i].fTotalCharge = fClusters[i].fTotalCharge;
642 clusterlist[i].fPad = fClusters[i].fPad;
643 clusterlist[i].fPad2 = fClusters[i].fPad2;
644 clusterlist[i].fTime = fClusters[i].fTime;
645 clusterlist[i].fTime2 = fClusters[i].fTime2;
646 clusterlist[i].fMean = fClusters[i].fMean;
647 clusterlist[i].fFlags = fClusters[i].fFlags;
648 clusterlist[i].fChargeFalling = fClusters[i].fChargeFalling;
649 clusterlist[i].fLastCharge = fClusters[i].fLastCharge;
650 clusterlist[i].fLastMergedPad = fClusters[i].fLastMergedPad;
651 clusterlist[i].fRow = fClusters[i].fRowNumber;
652 clusterlist[i].fQMax = fClusters[i].fQMax;
655 WriteClusters(fClusters.size(),clusterlist);
656 delete [] clusterlist;
658 if( fReleaseMemory ) DeInitializePadArray();// call this when the -releaseMemory flag is set
662 Bool_t AliHLTTPCClusterFinder::UpdateCalibDB(){
665 AliTPCcalibDB::Instance()->Update();
669 //uptate the transform class
671 fOfflineTransform = AliTPCcalibDB::Instance()->GetTransform();
672 if(!fOfflineTransform){
673 HLTError("AliHLTTPCClusterFinder()::UpdateCAlibDB:: Offline transform not in AliTPCcalibDB.");
677 fOfflineTransform->SetCurrentRecoParam(&fOfflineTPCRecoParam);
680 fOfflineTPCParam = AliTPCcalibDB::Instance()->GetParameters();
681 if( !fOfflineTPCParam ){
682 HLTError("AliHLTTPCClusterFinder()::UpdateCAlibDB:: Offline TPC parameters not in AliTPCcalibDB.");
685 fOfflineTPCParam->Update();
686 fOfflineTPCParam->ReadGeoMatrices();
692 //---------------------------------- Under this line the old sorted clusterfinder functions can be found --------------------------------
695 void AliHLTTPCClusterFinder::PrintClusters(){
696 // see header file for class documentation
698 for(size_t i=0;i<fClusters.size();i++){
699 HLTInfo("Cluster number: %d",i);
700 HLTInfo("Row: %d \t Pad: %d",fClusters[i].fRowNumber,fClusters[i].fPad/fClusters[i].fTotalCharge);
701 HLTInfo("Total Charge: %d",fClusters[i].fTotalCharge);
702 HLTInfo("fPad: %d",fClusters[i].fPad);
703 HLTInfo("PadError: %d",fClusters[i].fPad2);
704 HLTInfo("TimeMean: %d",fClusters[i].fTime/fClusters[i].fTotalCharge);
705 HLTInfo("TimeError: %d",fClusters[i].fTime2);
706 HLTInfo("EndOfCluster:");
710 void AliHLTTPCClusterFinder::FillMCClusterVector(vector<AliHLTTPCDigitData> *digitData){
711 // see header file for class documentation
712 if( !digitData ) return;
713 for(UInt_t d=0;d<digitData->size();d++){
714 Int_t nIDsInDigit = (digitData->at(d).fTrackID[0]>=0) + (digitData->at(d).fTrackID[1]>=0) + (digitData->at(d).fTrackID[2]>=0);
715 for(Int_t id=0; id<3; id++){
716 if(digitData->at(d).fTrackID[id]>=0){
717 Bool_t matchFound = kFALSE;
718 AliHLTTPCClusterMCWeight mc;
719 mc.fMCID = digitData->at(d).fTrackID[id];
720 mc.fWeight = ((Float_t)digitData->at(d).fCharge)/nIDsInDigit;
721 for(UInt_t i=0;i<fClusterMCVector.size();i++){
722 if(mc.fMCID == fClusterMCVector.at(i).fMCID){
723 fClusterMCVector.at(i).fWeight += mc.fWeight;
727 if(matchFound == kFALSE){
728 fClusterMCVector.push_back(mc);
736 void AliHLTTPCClusterFinder::Read(void* ptr,unsigned long size){
738 fPtr = (UChar_t*)ptr;
742 void AliHLTTPCClusterFinder::ProcessDigits(){
743 // see header file for class documentation
746 bool readValue = true;
749 UShort_t time=0,newTime=0;
750 UInt_t pad=0,newPad=0;
751 AliHLTTPCSignal_t charge=0;
755 // initialize block for reading packed data
756 iResult=fDigitReader->InitBlock(fPtr,fSize,fFirstRow,fLastRow,fCurrentPatch,fCurrentSlice);
757 if (iResult<0) return;
759 readValue = fDigitReader->Next();
761 // Matthias 08.11.2006 the following return would cause termination without writing the
762 // ClusterData and thus would block the component. I just want to have the commented line
763 // here for information
764 //if (!readValue)return;
766 pad = fDigitReader->GetPad();
767 time = fDigitReader->GetTime();
768 fCurrentRow = fDigitReader->GetRow();
770 if ( fCurrentPatch >= 2 ) // Outer sector, patches 2, 3, 4, 5
771 rowOffset = AliHLTTPCTransform::GetFirstRow( 2 );
773 fCurrentRow += rowOffset;
775 UInt_t lastpad = 123456789;
776 const UInt_t kPadArraySize=5000;
777 const UInt_t kClusterListSize=10000;
778 AliClusterData *pad1[kPadArraySize]; //2 lists for internal memory=2pads
779 AliClusterData *pad2[kPadArraySize]; //2 lists for internal memory=2pads
780 AliClusterData clusterlist[kClusterListSize]; //Clusterlist
782 AliClusterData **currentPt; //List of pointers to the current pad
783 AliClusterData **previousPt; //List of pointers to the previous pad
786 UInt_t nprevious=0,ncurrent=0,ntotal=0;
788 /* quick implementation of baseline calculation and zero suppression
789 open a pad object for each pad and delete it after processing.
790 later a list of pad objects with base line history can be used
791 The whole thing only works if we really get unprocessed raw data, if
792 the data is already zero suppressed, there might be gaps in the time
795 Int_t gatingGridOffset=50;
797 gatingGridOffset=fFirstTimeBin;
799 AliHLTTPCPad baseline(gatingGridOffset, AliHLTTPCTransform::GetNTimeBins());
800 // just to make later conversion to a list of objects easier
801 AliHLTTPCPad* pCurrentPad=NULL;
803 if (fSignalThreshold>=0) {
804 pCurrentPad=&baseline;
805 baseline.SetThreshold(fSignalThreshold);
808 while ( readValue!=0 && iResult>=0){ // Reads through all digits in block
815 if(currentPt == pad2){
823 nprevious = ncurrent;
825 if(pad != lastpad+1){
826 //this happens if there is a pad with no signal.
827 nprevious = ncurrent = 0;
832 Bool_t newcluster = kTRUE;
833 UInt_t seqcharge=0,seqaverage=0,seqerror=0;
834 AliHLTTPCSignal_t lastcharge=0;
835 UInt_t bLastWasFalling=0;
840 redo: //This is a goto.
851 while(iResult>=0){ //Loop over time bins of current pad
852 // read all the values for one pad at once to calculate the base line
854 if (!pCurrentPad->IsStarted()) {
855 //HLTDebug("reading data for pad %d, padrow %d", fDigitReader->GetPad(), fDigitReader->GetRow()+rowOffset);
856 pCurrentPad->SetID(fDigitReader->GetRow()+rowOffset,fDigitReader->GetPad());
857 if ((pCurrentPad->StartEvent())>=0) {
859 if ((fDigitReader->GetRow()+rowOffset)!=pCurrentPad->GetRowNumber()) break;
860 if (fDigitReader->GetPad()!=pCurrentPad->GetPadNumber()) break;
861 pCurrentPad->SetRawData(fDigitReader->GetTime(), fDigitReader->GetSignal());
862 //HLTDebug("set raw data to pad: bin %d charge %d", fDigitReader->GetTime(), fDigitReader->GetSignal());
863 } while ((readValue = fDigitReader->Next())!=0);
865 pCurrentPad->CalculateBaseLine(AliHLTTPCTransform::GetNTimeBins()/2);
866 if (pCurrentPad->Next(kTRUE/*do zero suppression*/)==0) {
867 //HLTDebug("no data available after zero suppression");
868 pCurrentPad->StopEvent();
869 pCurrentPad->ResetHistory();
872 time=pCurrentPad->GetCurrentPosition();
873 if (time>pCurrentPad->GetSize()) {
874 HLTError("invalid time bin for pad");
880 Float_t occupancy=pCurrentPad->GetOccupancy();
881 //HLTDebug("pad %d occupancy level: %f", pCurrentPad->GetPadNumber(), occupancy);
882 if ( occupancy < fOccupancyLimit ) {
883 charge = pCurrentPad->GetCorrectedData();
886 //HLTDebug("ignoring pad %d with occupancy level %f", pCurrentPad->GetPadNumber(), occupancy);
889 charge = fDigitReader->GetSignal();
891 //HLTDebug("get next charge value: position %d charge %d", time, charge);
895 if (fDigitReader->GetRow() == 90){
896 ///// LOG(AliHLTTPCLog::kFatal,"AliHLTTPCClusterFinder::Row","row90") << "PAD=" << fDigitReader->GetPad() << " TIME=" << fDigitReader->GetTime()
897 // << " SIGNAL=" << fDigitReader->GetSignal() << ENDLOG;
901 if(time >= AliHLTTPCTransform::GetNTimeBins()){
902 HLTWarning("Pad %d: Timebin (%d) out of range (%d)", pad, time, AliHLTTPCTransform::GetNTimeBins());
907 //Get the current ADC-value
910 //Check if the last pixel in the sequence is smaller than this
911 if(charge > lastcharge){
917 else bLastWasFalling = 1; //last pixel was larger than this
921 //Sum the total charge of this sequence
923 seqaverage += time*charge;
924 seqerror += time*time*charge;
928 if((pCurrentPad->Next(kTRUE/*do zero suppression*/))==0) {
929 pCurrentPad->StopEvent();
930 pCurrentPad->ResetHistory();
932 newPad = fDigitReader->GetPad();
933 newTime = fDigitReader->GetTime();
934 newRow = fDigitReader->GetRow() + rowOffset;
939 newPad=pCurrentPad->GetPadNumber();
940 newTime=pCurrentPad->GetCurrentPosition();
941 newRow=pCurrentPad->GetRowNumber();
943 readValue = fDigitReader->Next();
944 //Check where to stop:
945 if(!readValue) break; //No more value
947 newPad = fDigitReader->GetPad();
948 newTime = fDigitReader->GetTime();
949 newRow = fDigitReader->GetRow() + rowOffset;
952 if(newPad != pad)break; //new pad
953 if(newTime != time+1) break; //end of sequence
956 // pad = newpad; is equal
959 }//end loop over sequence
961 //HLTDebug("ended time bin sequence loop: seqcharge=%d readValue=%d", seqcharge, readValue);
962 //HLTDebug("pad=%d newpad=%d current row=%d newrow=%d", pad, newPad, fCurrentRow, newRow);
964 // with active zero suppression zero values are possible
968 //Calculate mean of sequence:
971 seqmean = seqaverage/seqcharge;
973 LOG(AliHLTTPCLog::kFatal,"AliHLTTPCClusterFinder::ProcessRow","Data")
974 <<"Error in data given to the cluster finder"<<ENDLOG;
979 //Calculate mean in pad direction:
980 Int_t padmean = seqcharge*pad;
981 Int_t paderror = pad*padmean;
983 //Compare with results on previous pad:
984 for(UInt_t p=0; p<nprevious && p<kPadArraySize && ncurrent<kPadArraySize; p++){
986 //dont merge sequences on the same pad twice
987 if(previousPt[p]->fLastMergedPad==pad) continue;
989 Int_t difference = seqmean - previousPt[p]->fMean;
990 if(difference < -fMatch) break;
992 if(difference <= fMatch){ //There is a match here!!
993 AliClusterData *local = previousPt[p];
996 if(seqcharge > local->fLastCharge){
997 if(local->fChargeFalling){ //The previous pad was falling
998 break; //create a new cluster
1001 else local->fChargeFalling = 1;
1002 local->fLastCharge = seqcharge;
1005 //Don't create a new cluster, because we found a match
1006 newcluster = kFALSE;
1008 //Update cluster on current pad with the matching one:
1009 local->fTotalCharge += seqcharge;
1010 local->fPad += padmean;
1011 local->fPad2 += paderror;
1012 local->fTime += seqaverage;
1013 local->fTime2 += seqerror;
1014 local->fMean = seqmean;
1015 local->fFlags++; //means we have more than one pad
1016 local->fLastMergedPad = pad;
1018 currentPt[ncurrent] = local;
1022 } //Checking for match at previous pad
1023 } //Loop over results on previous pad.
1025 if(newcluster && ncurrent<kPadArraySize){
1026 //Start a new cluster. Add it to the clusterlist, and update
1027 //the list of pointers to clusters in current pad.
1028 //current pad will be previous pad on next pad.
1030 //Add to the clusterlist:
1031 AliClusterData *tmp = &clusterlist[ntotal];
1032 tmp->fTotalCharge = seqcharge;
1033 tmp->fPad = padmean;
1034 tmp->fPad2 = paderror;
1035 tmp->fTime = seqaverage;
1036 tmp->fTime2 = seqerror;
1037 tmp->fMean = seqmean;
1038 tmp->fFlags = 0; //flags for single pad clusters
1039 tmp->fLastMergedPad = pad;
1042 tmp->fChargeFalling = 0;
1043 tmp->fLastCharge = seqcharge;
1046 //Update list of pointers to previous pad:
1047 currentPt[ncurrent] = &clusterlist[ntotal];
1053 if(newbin >= 0) goto redo;
1055 // to prevent endless loop
1056 if(time >= AliHLTTPCTransform::GetNTimeBins()){
1057 HLTWarning("Timebin (%d) out of range (%d)", time, AliHLTTPCTransform::GetNTimeBins());
1062 if(!readValue) break; //No more value
1064 if (ntotal>=kClusterListSize || ncurrent>=kPadArraySize) {
1065 HLTWarning("pad array size exceeded ntotal=%d ncurrent=%d, skip rest of the data", ntotal, ncurrent);
1069 if(fCurrentRow != newRow){
1070 WriteClusters(ntotal,clusterlist);
1072 lastpad = 123456789;
1080 fCurrentRow = newRow;
1086 } // END while(readValue)
1088 WriteClusters(ntotal,clusterlist);
1090 HLTInfo("ClusterFinder found %d clusters in slice %d patch %d", fNClusters, fCurrentSlice, fCurrentPatch);
1094 void AliHLTTPCClusterFinder::WriteClusters(Int_t nclusters,AliClusterData *list){
1095 // see header file for class documentation
1097 //write cluster to output pointer
1098 Int_t thisrow=-1,thissector=-1;
1099 UInt_t counter = fNClusters;
1101 if (fFillRawClusters) {
1102 fRawClusters.resize(nclusters);
1105 for(int j=0; j<nclusters; j++)
1110 if(!list[j].fFlags){
1112 if(j+(Int_t)fClustersMCInfo.size()-nclusters >=0 && j+fClustersMCInfo.size()-nclusters < fClustersMCInfo.size()){
1113 fClustersMCInfo.erase(fClustersMCInfo.begin()+j+fClustersMCInfo.size()-nclusters); // remove the mc info for this cluster since it is not taken into account
1116 continue; //discard single pad clusters
1118 if(list[j].fTotalCharge < fThreshold){
1120 if(j+(Int_t)fClustersMCInfo.size()-nclusters >=0 && j+fClustersMCInfo.size()-nclusters < fClustersMCInfo.size()){
1121 fClustersMCInfo.erase(fClustersMCInfo.begin()+j+fClustersMCInfo.size()-nclusters); // remove the mc info for this cluster since it is not taken into account
1124 continue; //noise cluster
1127 Float_t fpad =(Float_t)list[j].fPad / list[j].fTotalCharge;
1128 Float_t fpad2=fXYErr*fXYErr; //fixed given error
1129 Float_t ftime =(Float_t)list[j].fTime / list[j].fTotalCharge;
1130 Float_t ftime2=fZErr*fZErr; //fixed given error
1135 fCurrentRow=list[j].fRow;
1139 if(fCalcerr) { //calc the errors, otherwice take the fixed error
1140 Int_t patch = AliHLTTPCTransform::GetPatch(fCurrentRow);
1141 UInt_t q2=list[j].fTotalCharge*list[j].fTotalCharge;
1142 // Float_t sy2=list[j].fPad2 * list[j].fTotalCharge - list[j].fPad * list[j].fPad;
1143 Float_t sy2=(Float_t)list[j].fPad2 * list[j].fTotalCharge - (Float_t)list[j].fPad * list[j].fPad;
1145 LOG(AliHLTTPCLog::kError,"AliHLTTPCClusterFinder::WriteClusters","Cluster width")
1146 <<"zero charge "<< list[j].fTotalCharge <<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
1151 LOG(AliHLTTPCLog::kError,"AliHLTTPCClusterFinder::WriteClusters","Cluster width")
1152 <<"SigmaY2 negative "<<sy2<<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
1156 fpad2 = (sy2 + 1./12)*AliHLTTPCTransform::GetPadPitchWidth(patch)*AliHLTTPCTransform::GetPadPitchWidth(patch);
1158 fpad2*=0.108; //constants are from offline studies
1164 // Float_t sz2=list[j].fTime2*list[j].fTotalCharge - list[j].fTime*list[j].fTime;
1165 Float_t sz2=(Float_t)list[j].fTime2*list[j].fTotalCharge - (Float_t)list[j].fTime*list[j].fTime;
1168 LOG(AliHLTTPCLog::kError,"AliHLTTPCClusterFinder::WriteClusters","Cluster width")
1169 <<"SigmaZ2 negative "<<sz2<<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
1173 ftime2 = (sz2 + 1./12)*AliHLTTPCTransform::GetZWidth()*AliHLTTPCTransform::GetZWidth();
1175 ftime2 *= 0.169; //constants are from offline studies
1183 HLTInfo("WriteCluster: padrow %d pad %d +- %d time +- %d charge %d",fCurrentRow, fpad, fpad2, ftime, ftime2, list[j].fTotalCharge);
1185 if (fFillRawClusters && fRawClusters.size()>(unsigned)counter) {
1186 fRawClusters[counter].SetPadRow(fCurrentRow);
1187 fRawClusters[counter].SetPad(fpad);
1188 fRawClusters[counter].SetTime(ftime);
1191 AliHLTTPCTransform::Slice2Sector(fCurrentSlice,fCurrentRow,thissector,thisrow);
1193 if(fOfflineTransform == NULL){
1194 AliHLTTPCTransform::Raw2Local(xyz,thissector,thisrow,fpad,ftime);
1196 if(xyz[0]==0) LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinder","Cluster Finder")
1197 <<AliHLTTPCLog::kDec<<"Zero cluster"<<ENDLOG;
1198 if(fNClusters >= fMaxNClusters)
1200 LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinder::WriteClusters","Cluster Finder")
1201 <<AliHLTTPCLog::kDec<<"Too many clusters "<<fNClusters<<ENDLOG;
1205 fSpacePointData[counter].fX = xyz[0];
1206 // fSpacePointData[counter].fY = xyz[1];
1207 if(fCurrentSlice<18){
1208 fSpacePointData[counter].fY = xyz[1];
1211 fSpacePointData[counter].fY = -1*xyz[1];
1213 fSpacePointData[counter].fZ = xyz[2];
1216 Double_t x[3]={thisrow,fpad+.5,ftime};
1217 Int_t iSector[1]={thissector};
1218 fOfflineTransform->Transform(x,iSector,0,1);
1219 double y[3] = {x[0], x[1], x[2] };
1221 if( fOfflineTPCParam && thissector<fOfflineTPCParam->GetNSector() ){
1222 TGeoHMatrix *alignment = fOfflineTPCParam->GetClusterMatrix( thissector );
1223 if ( alignment ) alignment->LocalToMaster( x, y);
1226 fSpacePointData[counter].fX = y[0];
1227 fSpacePointData[counter].fY = y[1];
1228 fSpacePointData[counter].fZ = y[2];
1233 fSpacePointData[counter].fCharge = list[j].fTotalCharge;
1234 fSpacePointData[counter].fPadRow = fCurrentRow;
1235 fSpacePointData[counter].fSigmaY2 = fpad2;
1236 fSpacePointData[counter].fSigmaZ2 = ftime2;
1238 fSpacePointData[counter].fQMax = list[j].fQMax;
1240 fSpacePointData[counter].SetUsed(kFALSE); // only used / set in AliHLTTPCDisplay
1241 fSpacePointData[counter].SetTrackNumber(-1); // only used / set in AliHLTTPCDisplay
1243 Int_t patch=fCurrentPatch;
1244 if(patch==-1) patch=0; //never store negative patch number
1245 fSpacePointData[counter].SetID( fCurrentSlice, patch, counter );
1247 if (fFillRawClusters && fRawClusters.size()>(unsigned)counter) {
1248 fRawClusters[counter].SetSigmaY2(fSpacePointData[counter].fSigmaY2);
1249 fRawClusters[counter].SetSigmaZ2(fSpacePointData[counter].fSigmaZ2);
1250 fRawClusters[counter].SetCharge(fSpacePointData[counter].fCharge);
1251 fRawClusters[counter].SetQMax(fSpacePointData[counter].fQMax);
1256 GetTrackID((Int_t)rint(fpad),(Int_t)rint(ftime),trackID);
1258 fSpacePointData[counter].fTrackID[0] = trackID[0];
1259 fSpacePointData[counter].fTrackID[1] = trackID[1];
1260 fSpacePointData[counter].fTrackID[2] = trackID[2];
1269 // STILL TO FIX ----------------------------------------------------------------------------
1272 void AliHLTTPCClusterFinder::GetTrackID(Int_t pad,Int_t time,Int_t *trackID) const {
1273 // see header file for class documentation
1276 AliHLTTPCDigitRowData *rowPt = (AliHLTTPCDigitRowData*)fDigitRowData;
1278 trackID[0]=trackID[1]=trackID[2]=-2;
1279 for(Int_t i=fFirstRow; i<=fLastRow; i++){
1280 if(rowPt->fRow < (UInt_t)fCurrentRow){
1281 AliHLTTPCMemHandler::UpdateRowPointer(rowPt);
1284 AliHLTTPCDigitData *digPt = (AliHLTTPCDigitData*)rowPt->fDigitData;
1285 for(UInt_t j=0; j<rowPt->fNDigit; j++){
1286 Int_t cpad = digPt[j].fPad;
1287 Int_t ctime = digPt[j].fTime;
1288 if(cpad != pad) continue;
1289 if(ctime != time) continue;
1291 trackID[0] = digPt[j].fTrackID[0];
1292 trackID[1] = digPt[j].fTrackID[1];
1293 trackID[2] = digPt[j].fTrackID[2];
1304 void AliHLTTPCClusterFinder::WriteClusters(Int_t nclusters,AliHLTTPCClusters *list){//This is used when using the AliHLTTPCClusters class for cluster data
1305 // see header file for class documentation
1307 //write cluster to output pointer
1308 Int_t thisrow,thissector;
1309 UInt_t counter = fNClusters;
1311 if (fFillRawClusters) {
1312 fRawClusters.resize(nclusters);
1315 for(int j=0; j<nclusters; j++)
1317 if(!list[j].fFlags) continue; //discard single pad clusters
1318 if(list[j].fTotalCharge < fThreshold) continue; //noise cluster
1321 Float_t fpad =(Float_t)list[j].fPad / list[j].fTotalCharge;
1322 Float_t fpad2=fXYErr*fXYErr; //fixed given error
1323 Float_t ftime =(Float_t)list[j].fTime / list[j].fTotalCharge;
1324 Float_t ftime2=fZErr*fZErr; //fixed given error
1327 if(fCalcerr) { //calc the errors, otherwice take the fixed error
1328 Int_t patch = AliHLTTPCTransform::GetPatch(fCurrentRow);
1329 UInt_t q2=list[j].fTotalCharge*list[j].fTotalCharge;
1330 Float_t sy2=list[j].fPad2 * list[j].fTotalCharge - list[j].fPad * list[j].fPad;
1333 LOG(AliHLTTPCLog::kError,"AliHLTTPCClusterFinder::WriteClusters","Cluster width")
1334 <<"SigmaY2 negative "<<sy2<<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
1338 fpad2 = (sy2 + 1./12)*AliHLTTPCTransform::GetPadPitchWidth(patch)*AliHLTTPCTransform::GetPadPitchWidth(patch);
1340 fpad2*=0.108; //constants are from offline studies
1346 Float_t sz2=list[j].fTime2*list[j].fTotalCharge - list[j].fTime*list[j].fTime;
1349 LOG(AliHLTTPCLog::kError,"AliHLTTPCClusterFinder::WriteClusters","Cluster width")
1350 <<"SigmaZ2 negative "<<sz2<<" on row "<<fCurrentRow<<" "<<fpad<<" "<<ftime<<ENDLOG;
1354 ftime2 = (sz2 + 1./12)*AliHLTTPCTransform::GetZWidth()*AliHLTTPCTransform::GetZWidth();
1356 ftime2 *= 0.169; //constants are from offline studies
1364 HLTInfo("WriteCluster: padrow %d pad %d +- %d time +- %d charge %d",fCurrentRow, fpad, fpad2, ftime, ftime2, list[j].fTotalCharge);
1366 if (fFillRawClusters && fRawClusters.size()>(unsigned)counter) {
1367 fRawClusters[counter].SetPadRow(fCurrentRow);
1368 fRawClusters[counter].SetPad(fpad);
1369 fRawClusters[counter].SetTime(ftime);
1372 AliHLTTPCTransform::Slice2Sector(fCurrentSlice,fCurrentRow,thissector,thisrow);
1373 AliHLTTPCTransform::Raw2Local(xyz,thissector,thisrow,fpad,ftime);
1375 if(xyz[0]==0) LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinder","Cluster Finder")
1376 <<AliHLTTPCLog::kDec<<"Zero cluster"<<ENDLOG;
1377 if(fNClusters >= fMaxNClusters)
1379 LOG(AliHLTTPCLog::kError,"AliHLTTPCClustFinder::WriteClusters","Cluster Finder")
1380 <<AliHLTTPCLog::kDec<<"Too many clusters "<<fNClusters<<ENDLOG;
1384 fSpacePointData[counter].fX = xyz[0];
1385 // fSpacePointData[counter].fY = xyz[1];
1386 if(fCurrentSlice<18){
1387 fSpacePointData[counter].fY = xyz[1];
1390 fSpacePointData[counter].fY = -1*xyz[1];
1392 fSpacePointData[counter].fZ = xyz[2];
1396 fSpacePointData[counter].fCharge = list[j].fTotalCharge;
1397 fSpacePointData[counter].fPadRow = fCurrentRow;
1398 fSpacePointData[counter].fSigmaY2 = fpad2;
1399 fSpacePointData[counter].fSigmaZ2 = ftime2;
1401 fSpacePointData[counter].fQMax = list[j].fQMax;
1403 fSpacePointData[counter].SetUsed(kFALSE); // only used / set in AliHLTTPCDisplay
1404 fSpacePointData[counter].SetTrackNumber(-1); // only used / set in AliHLTTPCDisplay
1406 Int_t patch=fCurrentPatch;
1407 if(patch==-1) patch=0; //never store negative patch number
1408 fSpacePointData[counter].SetID( fCurrentSlice, patch, counter );
1410 if (fFillRawClusters && fRawClusters.size()>(unsigned)counter) {
1411 fRawClusters[counter].SetSigmaY2(fSpacePointData[counter].fSigmaY2);
1412 fRawClusters[counter].SetSigmaZ2(fSpacePointData[counter].fSigmaZ2);
1413 fRawClusters[counter].SetCharge(fSpacePointData[counter].fCharge);
1414 fRawClusters[counter].SetQMax(fSpacePointData[counter].fQMax);
1419 GetTrackID((Int_t)rint(fpad),(Int_t)rint(ftime),trackID);
1421 fSpacePointData[counter].fTrackID[0] = trackID[0];
1422 fSpacePointData[counter].fTrackID[1] = trackID[1];
1423 fSpacePointData[counter].fTrackID[2] = trackID[2];