2 //**************************************************************************
3 //* This file is property of and copyright by the ALICE HLT Project *
4 //* ALICE Experiment at CERN, All rights reserved. *
6 //* Primary Authors: Kenneth Aamodt <kenneth.aamodt@student.uib.no> *
7 //* for The ALICE HLT Project. *
9 //* Permission to use, copy, modify and distribute this software and its *
10 //* documentation strictly for non-commercial purposes is hereby granted *
11 //* without fee, provided that the above copyright notice appears in all *
12 //* copies and that both the copyright notice and this permission notice *
13 //* appear in the supporting documentation. The authors make no claims *
14 //* about the suitability of this software for any purpose. It is *
15 //* provided "as is" without express or implied warranty. *
16 //**************************************************************************
18 /** @file AliHLTTPCKryptonClusterFinder.cxx
19 @author Kenneth Aamodt, Kalliopi Kanaki
21 @brief Krypton Cluster Finder for the TPC
24 #include "AliHLTTPCDigitReader.h"
25 #include "AliHLTTPCKryptonClusterFinder.h"
26 #include "AliHLTTPCTransform.h"
27 #include "AliHLTTPCPad.h"
28 #include "AliHLTTPCClusters.h"
30 #include "AliHLTTPCSpacePointData.h"
37 ClassImp(AliHLTTPCKryptonClusterFinder)
39 AliHLTTPCKryptonClusterFinder::AliHLTTPCKryptonClusterFinder()
40 : AliHLTTPCClusterFinder(),
45 fSelectionMinRowNumber(0),
46 fSelectionMaxRowNumber(0),
53 AliHLTTPCKryptonClusterFinder::~AliHLTTPCKryptonClusterFinder(){
56 void AliHLTTPCKryptonClusterFinder::ReBunch(const UInt_t *bunchData , Int_t bunchSize){
57 fTimebinsInBunch.clear();
58 fIndexOfBunchStart.clear();
59 Bool_t newBunch=kTRUE;
60 Int_t currentBunchNumber=-1;
61 for(Int_t i=0;i<bunchSize;i++){
64 fIndexOfBunchStart.push_back(i);
65 fTimebinsInBunch.push_back(1);
72 fTimebinsInBunch[currentBunchNumber]++;
81 void AliHLTTPCKryptonClusterFinder::ReadDataUnsorted(void* ptr,unsigned long size)
87 if(!fVectorInitialized){
91 fHWAddressVector.clear();
94 fDigitReader->InitBlock(fPtr,fSize,fFirstRow,fLastRow,fCurrentPatch,fCurrentSlice);
96 while(fDigitReader->NextChannel()){
97 UInt_t row=fDigitReader->GetRow();
98 UInt_t pad=fDigitReader->GetPad();
100 fRowPadVector[row][pad]->ClearCandidates();
102 while(fDigitReader->NextBunch()){
103 if(fDigitReader->GetBunchSize()>1){
104 const UInt_t *bunchData= fDigitReader->GetSignals();
106 ReBunch(bunchData,fDigitReader->GetBunchSize());
107 Int_t rebunchCount=fIndexOfBunchStart.size();
109 for(Int_t r=0;r<rebunchCount;r++){
110 UInt_t time = fDigitReader->GetTime()+fIndexOfBunchStart[r];
111 AliHLTTPCClusters candidate;
112 candidate.fTotalCharge=0;
114 if(fTimebinsInBunch[r]>2){
115 for(Int_t i=0;i<fTimebinsInBunch[r];i++){
116 candidate.fTotalCharge+=bunchData[i + fIndexOfBunchStart[r]];
117 candidate.fTime += time*bunchData[i + fIndexOfBunchStart[r]];
118 candidate.fTime2 += time*time*bunchData[i + fIndexOfBunchStart[r]];
119 if(bunchData[i + fIndexOfBunchStart[r]]>candidate.fQMax){
120 candidate.fQMax = bunchData[i + fIndexOfBunchStart[r]];
124 if(candidate.fTotalCharge>0){
125 candidate.fMean=candidate.fTime/candidate.fTotalCharge;
126 candidate.fPad=candidate.fTotalCharge*pad;
127 candidate.fPad2=candidate.fPad*pad;
128 candidate.fLastMergedPad=pad;
129 candidate.fRowNumber=row+fDigitReader->GetRowOffset();
131 if(candidate.fTotalCharge>10 && candidate.fMean<924){
132 fRowPadVector[row][pad]->AddClusterCandidate(candidate);
141 Bool_t AliHLTTPCKryptonClusterFinder::ComparePads(AliHLTTPCPad *nextPad,AliHLTTPCClusters* cluster,Int_t nextPadToRead){
142 //Checking if we have a match on the next pad
143 for(UInt_t candidateNumber=0;candidateNumber<nextPad->fClusterCandidates.size();candidateNumber++){
144 AliHLTTPCClusters *candidate =&nextPad->fClusterCandidates[candidateNumber];
145 if(cluster->fMean-candidate->fMean==1 || candidate->fMean-cluster->fMean==1 || cluster->fMean-candidate->fMean==0){
146 cluster->fMean=candidate->fMean;
147 cluster->fTotalCharge+=candidate->fTotalCharge;
148 cluster->fTime += candidate->fTime;
149 cluster->fTime2 += candidate->fTime2;
150 cluster->fPad+=candidate->fPad;
151 cluster->fPad2=candidate->fPad2;
152 cluster->fLastMergedPad=candidate->fPad/candidate->fTotalCharge;
154 if(candidate->fQMax>cluster->fQMax){
155 cluster->fQMax = candidate->fQMax;
158 //setting the matched pad to used
159 nextPad->fUsedClusterCandidates[candidateNumber]=1;
161 if(nextPadToRead<(Int_t)fNumberOfPadsInRow[fRowOfFirstCandidate]){
162 nextPad=fRowPadVector[fRowOfFirstCandidate][nextPadToRead];
163 ComparePads(nextPad,cluster,nextPadToRead);
176 void AliHLTTPCKryptonClusterFinder::FindRowClusters()
178 // see header file for function documentation
180 AliHLTTPCClusters* tmpCandidate=NULL;
181 for(UInt_t row=5;row<fNumberOfRows-5;row++){
182 fRowOfFirstCandidate=row;
183 for(UInt_t pad=5;pad<fNumberOfPadsInRow[row]-1-5;pad++){
184 AliHLTTPCPad *tmpPad=fRowPadVector[row][pad];
185 for(size_t candidate=0;candidate<tmpPad->fClusterCandidates.size();candidate++){
186 if(tmpPad->fUsedClusterCandidates[candidate]){
189 if((Int_t)tmpPad->fClusterCandidates[candidate].fMean<100 || (Int_t)tmpPad->fClusterCandidates[candidate].fMean>AliHLTTPCTransform::GetNTimeBins()-100){
192 tmpCandidate=&tmpPad->fClusterCandidates[candidate];
193 tmpCandidate->fFirstPad=pad;
194 UInt_t tmpTotalCharge=tmpCandidate->fTotalCharge;
196 ComparePads(fRowPadVector[row][pad+1],tmpCandidate,pad+1);
197 if(tmpCandidate->fTotalCharge>tmpTotalCharge){
199 tmpCandidate->fRowNumber= tmpCandidate->fRowNumber*tmpCandidate->fTotalCharge;
200 // tmpCandidate->fPad = tmpCandidate->fPad*tmpCandidate->fTotalCharge;
201 fClusters.push_back(*tmpCandidate);
207 HLTDebug("Found %d normal clusters.",fClusters.size());
210 void AliHLTTPCKryptonClusterFinder::FindKryptonClusters()
213 if(fClusters.size()<2){
216 for(UInt_t i=0; i<fClusters.size();i++){
217 AliHLTTPCClusters * tmpCluster=&fClusters[i];
218 if(tmpCluster->fFlags==99){//quickfix to check if a cluster is used already
222 UInt_t prevRow=tmpCluster->fRowNumber/tmpCluster->fTotalCharge;
224 if((Int_t)tmpCluster->fQMax>fMaxQOfCluster){
225 fMaxQOfCluster = tmpCluster->fQMax;
228 //adds "normal" clusters belonging to the krypton cluster
229 for(UInt_t j=i+1;j<fClusters.size();j++){
230 AliHLTTPCClusters * nextCluster=&fClusters[j];
232 if(nextCluster->fFlags==99){//quickfix to check if a cluster is used already
235 if(prevRow == (UInt_t)(nextCluster->fRowNumber/nextCluster->fTotalCharge)-1){//Checks if the row numbers are ok (next to eachother)
236 if(abs((Int_t)(tmpCluster->fPad/tmpCluster->fTotalCharge) - (Int_t)(nextCluster->fPad/nextCluster->fTotalCharge))<3){ // checks if the pad numbers are ok
237 if(abs((Int_t)tmpCluster->fMean-(Int_t)nextCluster->fMean)<2){
238 tmpCluster->fMean=nextCluster->fMean;
239 tmpCluster->fTotalCharge+=nextCluster->fTotalCharge;
240 tmpCluster->fRowNumber+=nextCluster->fRowNumber;
241 tmpCluster->fPad+=nextCluster->fPad;
242 tmpCluster->fTime+=nextCluster->fTime;
243 if((Int_t)nextCluster->fQMax>fMaxQOfCluster){
244 fMaxQOfCluster = nextCluster->fQMax;
248 if(tmpCluster->fFlags!=99){//means that this is the first time normal clusters match
249 CheckForCandidateOnPreviousRow(tmpCluster);
250 for(UInt_t ap = tmpCluster->fFirstPad ; ap<=tmpCluster->fLastMergedPad ; ap++){
251 fHWAddressVector.push_back((AliHLTUInt16_t)fDigitReader->GetAltroBlockHWaddr(nextCluster->fRowNumber/nextCluster->fTotalCharge-AliHLTTPCTransform::GetFirstRow(fCurrentPatch),ap));
252 // fHWAddressVector.push_back((AliHLTUInt16_t)fDigitReader->GetAltroBlockHWaddr(tmpCluster->fRowNumber,ap));
256 for(UInt_t ap = nextCluster->fFirstPad ; ap<=nextCluster->fLastMergedPad ; ap++){
257 fHWAddressVector.push_back((AliHLTUInt16_t)fDigitReader->GetAltroBlockHWaddr(nextCluster->fRowNumber/nextCluster->fTotalCharge-AliHLTTPCTransform::GetFirstRow(fCurrentPatch),ap));
258 HLTDebug("Pushing back hw address %d from row: %d and Pad: %d",fDigitReader->GetAltroBlockHWaddr(nextCluster->fRowNumber/nextCluster->fTotalCharge-AliHLTTPCTransform::GetFirstRow(fCurrentPatch),ap),nextCluster->fRowNumber/nextCluster->fTotalCharge,ap);
261 prevRow=nextCluster->fRowNumber/nextCluster->fTotalCharge;
262 nextCluster->fFlags=99;
263 tmpCluster->fFlags=99;
264 if(j!=fClusters.size()-1){
271 if(tmpCluster->fFlags==99){
272 //adds a clustercandidate on next row if present TODO
273 /* if(tmpCluster->fFlags==99){
274 for(Int_t p=-1;p<2;p++){
275 AliHLTTPCPad *padAfter=fRowPadVector[tmpCluster->fRowNumber+1][tmpCluster->fPad+p];
276 for(UInt_t c=0;c<padAfter->fClusterCandidates.size();c++)
277 if(abs((Int_t)tmpCluster->fMean - (Int_t)padAfter->fClusterCandidates[c].fMean)<2){
278 tmpCluster->fTotalCharge+=padAfter->fClusterCandidates[c].fTotalCharge;
280 }//end add clustercandidate if present
284 //convert the (AliHLTClusters) cluster to spacepointdata and add it to the output array.
285 if (fNKryptonClusters*sizeof(AliHLTTPCSpacePointData)>=fMaxOutputSize*sizeof(AliHLTUInt32_t)) {
286 HLTWarning("Buffer too small too add more spacepoints: %d of %d byte(s) already used",fNKryptonClusters*sizeof(AliHLTTPCSpacePointData) , fMaxOutputSize*sizeof(AliHLTUInt32_t));
289 if(tmpCluster->fTotalCharge>10){
290 Float_t xyz[3]={0,0,0};
293 AliHLTTPCTransform::Slice2Sector(fCurrentSlice, (Int_t)(tmpCluster->fRowNumber/tmpCluster->fTotalCharge), thissector, thisrow);
294 AliHLTTPCTransform::Raw2Local(xyz, thissector, thisrow,(Float_t)(tmpCluster->fPad/tmpCluster->fTotalCharge),(Float_t)(tmpCluster->fTime/tmpCluster->fTotalCharge));
295 fSpacePointData[fNKryptonClusters].fX = xyz[0];
296 fSpacePointData[fNKryptonClusters].fY = xyz[1];
297 fSpacePointData[fNKryptonClusters].fZ = xyz[2];
298 fSpacePointData[fNKryptonClusters].fCharge = tmpCluster->fTotalCharge;
299 fSpacePointData[fNKryptonClusters].fMaxQ = tmpCluster->fQMax;
300 fSpacePointData[fNKryptonClusters].fPadRow = tmpCluster->fRowNumber/tmpCluster->fTotalCharge;
301 HLTDebug("Krypton cluster found");
302 HLTDebug("xyz=[%f,%f,%f]",fSpacePointData[fNKryptonClusters].fX,fSpacePointData[fNKryptonClusters].fY,fSpacePointData[fNKryptonClusters].fZ);
303 HLTDebug("TotalCharge = %d and QMax = %d",fSpacePointData[fNKryptonClusters].fCharge,fSpacePointData[fNKryptonClusters].fMaxQ);
309 }//end add "normal" clusters belonging to the krypton cluster
311 //resets the candidates for every pad and the fClusters(row clusters)
312 for(UInt_t row=0;row<fNumberOfRows;row++){
313 for(UInt_t pad=0;pad<fNumberOfPadsInRow[row];pad++){
314 fRowPadVector[row][pad]->fClusterCandidates.clear();
320 void AliHLTTPCKryptonClusterFinder::CheckForCandidateOnPreviousRow(AliHLTTPCClusters *tmpCluster){
321 if(tmpCluster->fRowNumber>1){
322 for(Int_t p=-1;p<2;p++){
323 if(tmpCluster->fPad+p>0 && tmpCluster->fPad+p<fNumberOfPadsInRow[tmpCluster->fRowNumber/tmpCluster->fTotalCharge-1]){
324 if(tmpCluster->fTotalCharge==0){
325 HLTFatal("Charge of tmpCluster in AliHLTTPCKryptonClusterFinder::CheckForCandidateOnPreviousRow is 0");
328 if(tmpCluster->fRowNumber/tmpCluster->fTotalCharge-1-AliHLTTPCTransform::GetFirstRow(fCurrentPatch)<0){
329 HLTFatal("AliHLTTPCKryptonClusterFinder::CheckForCandidateOnPreviousRow: Rownumber is below 0");
332 if(tmpCluster->fRowNumber/tmpCluster->fTotalCharge-1-AliHLTTPCTransform::GetFirstRow(fCurrentPatch)>fNumberOfRows){
333 HLTFatal("AliHLTTPCKryptonClusterFinder::CheckForCandidateOnPreviousRow: Rownumber is too high");
336 AliHLTTPCPad *prevPad=fRowPadVector[tmpCluster->fRowNumber/tmpCluster->fTotalCharge-1-AliHLTTPCTransform::GetFirstRow(fCurrentPatch)][tmpCluster->fPad/tmpCluster->fTotalCharge+p];
337 for(UInt_t i=0;i<prevPad->fClusterCandidates.size();i++){
338 if(abs((Int_t)prevPad->fClusterCandidates[i].fMean - (Int_t)tmpCluster->fMean)<2 && prevPad->fUsedClusterCandidates[i]==0){
339 tmpCluster->fTotalCharge += prevPad->fClusterCandidates[i].fTotalCharge;
340 fHWAddressVector.push_back((AliHLTUInt16_t)fDigitReader->GetAltroBlockHWaddr(tmpCluster->fRowNumber/tmpCluster->fTotalCharge-1-AliHLTTPCTransform::GetFirstRow(fCurrentPatch),tmpCluster->fPad/tmpCluster->fTotalCharge+p));
341 // fHWAddressVector.push_back((AliHLTUInt16_t)fDigitReader->GetAltroBlockHWaddr(prevPad->GetRowNumber(),prevPad->GetPadNumber()));
342 HLTDebug("Pushing back hw address %d",fDigitReader->GetAltroBlockHWaddr(tmpCluster->fRowNumber/tmpCluster->fTotalCharge-1-AliHLTTPCTransform::GetFirstRow(fCurrentPatch),tmpCluster->fPad/tmpCluster->fTotalCharge+p));
350 void AliHLTTPCKryptonClusterFinder::SetSelection(Int_t minRow, Int_t maxRow){
351 fSelectionMinRowNumber=minRow;
352 fSelectionMaxRowNumber=maxRow;