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=nextPad->GetPadNumber();
153 if(candidate->fQMax>cluster->fQMax){
154 cluster->fQMax = candidate->fQMax;
157 //setting the matched pad to used
158 nextPad->fUsedClusterCandidates[candidateNumber]=1;
160 if(nextPadToRead<(Int_t)fNumberOfPadsInRow[fRowOfFirstCandidate]){
161 nextPad=fRowPadVector[fRowOfFirstCandidate][nextPadToRead];
162 ComparePads(nextPad,cluster,nextPadToRead);
175 void AliHLTTPCKryptonClusterFinder::FindRowClusters()
177 // see header file for function documentation
179 AliHLTTPCClusters* tmpCandidate=NULL;
180 for(UInt_t row=5;row<fNumberOfRows-5;row++){
181 fRowOfFirstCandidate=row;
182 for(UInt_t pad=5;pad<fNumberOfPadsInRow[row]-1-5;pad++){
183 AliHLTTPCPad *tmpPad=fRowPadVector[row][pad];
184 for(size_t candidate=0;candidate<tmpPad->fClusterCandidates.size();candidate++){
185 if(tmpPad->fUsedClusterCandidates[candidate]){
188 if((Int_t)tmpPad->fClusterCandidates[candidate].fMean<100 || (Int_t)tmpPad->fClusterCandidates[candidate].fMean>AliHLTTPCTransform::GetNTimeBins()-100){
191 tmpCandidate=&tmpPad->fClusterCandidates[candidate];
192 tmpCandidate->fFirstPad=pad;
193 UInt_t tmpTotalCharge=tmpCandidate->fTotalCharge;
195 ComparePads(fRowPadVector[row][pad+1],tmpCandidate,pad+1);
196 if(tmpCandidate->fTotalCharge>tmpTotalCharge){
198 tmpCandidate->fRowNumber= tmpCandidate->fRowNumber*tmpCandidate->fTotalCharge;
199 // tmpCandidate->fPad = tmpCandidate->fPad*tmpCandidate->fTotalCharge;
200 fClusters.push_back(*tmpCandidate);
206 HLTDebug("Found %d normal clusters.",fClusters.size());
209 void AliHLTTPCKryptonClusterFinder::FindKryptonClusters()
212 if(fClusters.size()<2){
215 for(UInt_t i=0; i<fClusters.size();i++){
216 AliHLTTPCClusters * tmpCluster=&fClusters[i];
217 if(tmpCluster->fFlags==99){//quickfix to check if a cluster is used already
221 UInt_t prevRow=tmpCluster->fRowNumber/tmpCluster->fTotalCharge;
223 if((Int_t)tmpCluster->fQMax>fMaxQOfCluster){
224 fMaxQOfCluster = tmpCluster->fQMax;
227 //adds "normal" clusters belonging to the krypton cluster
228 for(UInt_t j=i+1;j<fClusters.size();j++){
229 AliHLTTPCClusters * nextCluster=&fClusters[j];
231 if(nextCluster->fFlags==99){//quickfix to check if a cluster is used already
234 if(prevRow == (UInt_t)(nextCluster->fRowNumber/nextCluster->fTotalCharge)-1){//Checks if the row numbers are ok (next to eachother)
235 if(abs((Int_t)(tmpCluster->fPad/tmpCluster->fTotalCharge) - (Int_t)(nextCluster->fPad/nextCluster->fTotalCharge))<3){ // checks if the pad numbers are ok
236 if(abs((Int_t)tmpCluster->fMean-(Int_t)nextCluster->fMean)<2){
237 tmpCluster->fMean=nextCluster->fMean;
238 tmpCluster->fTotalCharge+=nextCluster->fTotalCharge;
239 tmpCluster->fRowNumber+=nextCluster->fRowNumber;
240 tmpCluster->fPad+=nextCluster->fPad;
241 tmpCluster->fTime+=nextCluster->fTime;
242 if((Int_t)nextCluster->fQMax>fMaxQOfCluster){
243 fMaxQOfCluster = nextCluster->fQMax;
248 if(tmpCluster->fFlags!=99){//means that this is the first time normal clusters match
249 CheckForCandidateOnPreviousRow(tmpCluster);
252 if(tmpCluster->fFirstPad>1){
255 if(tmpCluster->fLastMergedPad+2<(UInt_t)AliHLTTPCTransform::GetNPads(prevRow)){
259 for(UInt_t ap = tmpCluster->fFirstPad -minFirst; ap<=tmpCluster->fLastMergedPad+maxFirst; ap++){
260 fHWAddressVector.push_back((AliHLTUInt16_t)fDigitReader->GetAltroBlockHWaddr(tmpCluster->fRowNumber/tmpCluster->fTotalCharge-AliHLTTPCTransform::GetFirstRow(fCurrentPatch),ap));
266 if(nextCluster->fFirstPad>1){
269 if(nextCluster->fLastMergedPad+2<(UInt_t)AliHLTTPCTransform::GetNPads(prevRow+1)){
272 for(UInt_t ap = nextCluster->fFirstPad-minNext; ap<=nextCluster->fLastMergedPad+maxNext; ap++){
273 fHWAddressVector.push_back((AliHLTUInt16_t)fDigitReader->GetAltroBlockHWaddr(nextCluster->fRowNumber/nextCluster->fTotalCharge-AliHLTTPCTransform::GetFirstRow(fCurrentPatch),ap));
274 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);
277 prevRow=nextCluster->fRowNumber/nextCluster->fTotalCharge;
278 nextCluster->fFlags=99;
279 tmpCluster->fFlags=99;
280 if(j!=fClusters.size()-1){
287 if(tmpCluster->fFlags==99){
288 //adds a clustercandidate on next row if present TODO
289 /* if(tmpCluster->fFlags==99){
290 for(Int_t p=-1;p<2;p++){
291 AliHLTTPCPad *padAfter=fRowPadVector[tmpCluster->fRowNumber+1][tmpCluster->fPad+p];
292 for(UInt_t c=0;c<padAfter->fClusterCandidates.size();c++)
293 if(abs((Int_t)tmpCluster->fMean - (Int_t)padAfter->fClusterCandidates[c].fMean)<2){
294 tmpCluster->fTotalCharge+=padAfter->fClusterCandidates[c].fTotalCharge;
296 }//end add clustercandidate if present
300 //convert the (AliHLTClusters) cluster to spacepointdata and add it to the output array.
301 if (fNKryptonClusters*sizeof(AliHLTTPCSpacePointData)>=fMaxOutputSize*sizeof(AliHLTUInt32_t)) {
302 HLTWarning("Buffer too small too add more spacepoints: %d of %d byte(s) already used",fNKryptonClusters*sizeof(AliHLTTPCSpacePointData) , fMaxOutputSize*sizeof(AliHLTUInt32_t));
305 if(tmpCluster->fTotalCharge>10){
306 Float_t xyz[3]={0,0,0};
309 AliHLTTPCTransform::Slice2Sector(fCurrentSlice, (Int_t)(tmpCluster->fRowNumber/tmpCluster->fTotalCharge), thissector, thisrow);
310 AliHLTTPCTransform::Raw2Local(xyz, thissector, thisrow,(Float_t)(tmpCluster->fPad/tmpCluster->fTotalCharge),(Float_t)(tmpCluster->fTime/tmpCluster->fTotalCharge));
311 fSpacePointData[fNKryptonClusters].fID = fCurrentSlice*10 +fCurrentPatch;
312 fSpacePointData[fNKryptonClusters].fX = xyz[0];
313 fSpacePointData[fNKryptonClusters].fY = xyz[1];
314 fSpacePointData[fNKryptonClusters].fZ = xyz[2];
315 fSpacePointData[fNKryptonClusters].fCharge = tmpCluster->fTotalCharge;
316 fSpacePointData[fNKryptonClusters].fQMax = tmpCluster->fQMax;
317 fSpacePointData[fNKryptonClusters].fPadRow = tmpCluster->fRowNumber/tmpCluster->fTotalCharge;
318 HLTDebug("Krypton cluster found");
319 HLTDebug("xyz=[%f,%f,%f]",fSpacePointData[fNKryptonClusters].fX,fSpacePointData[fNKryptonClusters].fY,fSpacePointData[fNKryptonClusters].fZ);
320 HLTDebug("TotalCharge = %d and QMax = %d",fSpacePointData[fNKryptonClusters].fCharge,fSpacePointData[fNKryptonClusters].fQMax);
326 }//end add "normal" clusters belonging to the krypton cluster
328 //resets the candidates for every pad and the fClusters(row clusters)
329 for(UInt_t row=0;row<fNumberOfRows;row++){
330 for(UInt_t pad=0;pad<fNumberOfPadsInRow[row];pad++){
331 fRowPadVector[row][pad]->fClusterCandidates.clear();
337 void AliHLTTPCKryptonClusterFinder::CheckForCandidateOnPreviousRow(AliHLTTPCClusters *tmpCluster){
338 if(tmpCluster->fRowNumber>1){
339 for(Int_t p=-1;p<2;p++){
340 if(tmpCluster->fPad+p>0 && tmpCluster->fPad+p<fNumberOfPadsInRow[tmpCluster->fRowNumber/tmpCluster->fTotalCharge-1]){
341 if(tmpCluster->fTotalCharge==0){
342 HLTDebug("Charge of tmpCluster in AliHLTTPCKryptonClusterFinder::CheckForCandidateOnPreviousRow is 0");
345 if((Int_t)(tmpCluster->fRowNumber/tmpCluster->fTotalCharge-1-AliHLTTPCTransform::GetFirstRow(fCurrentPatch))<0){
346 HLTDebug("AliHLTTPCKryptonClusterFinder::CheckForCandidateOnPreviousRow: Rownumber is below 0");
349 if(tmpCluster->fRowNumber/tmpCluster->fTotalCharge-1-AliHLTTPCTransform::GetFirstRow(fCurrentPatch)>fNumberOfRows){
350 HLTDebug("AliHLTTPCKryptonClusterFinder::CheckForCandidateOnPreviousRow: Rownumber is too high");
353 AliHLTTPCPad *prevPad=fRowPadVector[tmpCluster->fRowNumber/tmpCluster->fTotalCharge-1-AliHLTTPCTransform::GetFirstRow(fCurrentPatch)][tmpCluster->fPad/tmpCluster->fTotalCharge+p];
354 for(UInt_t i=0;i<prevPad->fClusterCandidates.size();i++){
355 if(abs((Int_t)prevPad->fClusterCandidates[i].fMean - (Int_t)tmpCluster->fMean)<2 && prevPad->fUsedClusterCandidates[i]==0){
356 tmpCluster->fTotalCharge += prevPad->fClusterCandidates[i].fTotalCharge;
357 fHWAddressVector.push_back((AliHLTUInt16_t)fDigitReader->GetAltroBlockHWaddr(tmpCluster->fRowNumber/tmpCluster->fTotalCharge-1-AliHLTTPCTransform::GetFirstRow(fCurrentPatch),tmpCluster->fPad/tmpCluster->fTotalCharge+p));
358 // fHWAddressVector.push_back((AliHLTUInt16_t)fDigitReader->GetAltroBlockHWaddr(prevPad->GetRowNumber(),prevPad->GetPadNumber()));
359 HLTDebug("Pushing back hw address %d",fDigitReader->GetAltroBlockHWaddr(tmpCluster->fRowNumber/tmpCluster->fTotalCharge-1-AliHLTTPCTransform::GetFirstRow(fCurrentPatch),tmpCluster->fPad/tmpCluster->fTotalCharge+p));
367 void AliHLTTPCKryptonClusterFinder::SetSelection(Int_t minRow, Int_t maxRow){
368 fSelectionMinRowNumber=minRow;
369 fSelectionMaxRowNumber=maxRow;