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"
35 ClassImp(AliHLTTPCKryptonClusterFinder)
37 AliHLTTPCKryptonClusterFinder::AliHLTTPCKryptonClusterFinder()
38 : AliHLTTPCClusterFinder(),
41 fHKryptonSpectrumFullPatch(NULL),
42 fHKryptonSpectrumSelection(NULL),
43 fHNumberOfKryptonClusters(NULL),
44 fHNumberOfKryptonClustersSelection(NULL),
45 fHMaxQofKryptonClusterLast1000(NULL),
46 fHMaxQofKryptonClusterSelection(NULL),
47 fStartBinKryptonSpectrum(0),
48 fEndBinKryptonSpectrum(3000),
51 fStartBinNumberOfKryptonClusters(0),
52 fEndBinNumberOfKryptonClusters(1000),
53 fSelectionMinRowNumber(0),
54 fSelectionMaxRowNumber(0),
57 fNumberOfKryptonClusters(0),
58 fNumberOfKryptonClustersBin(0),
59 fHistogramsInitialized(kFALSE)
64 AliHLTTPCKryptonClusterFinder::~AliHLTTPCKryptonClusterFinder(){
65 if(fHKryptonSpectrumFullPatch){
66 delete fHKryptonSpectrumFullPatch;
67 fHKryptonSpectrumFullPatch=NULL;
69 if(fHKryptonSpectrumSelection){
70 delete fHKryptonSpectrumSelection;
71 fHKryptonSpectrumSelection=NULL;
73 if(fHNumberOfKryptonClusters){
74 delete fHNumberOfKryptonClusters;
75 fHNumberOfKryptonClusters=NULL;
77 if(fHMaxQofKryptonClusterLast1000){
78 delete fHMaxQofKryptonClusterLast1000;
79 fHMaxQofKryptonClusterLast1000=NULL;
81 if(fHMaxQofKryptonClusterSelection){
82 delete fHMaxQofKryptonClusterSelection;
83 fHMaxQofKryptonClusterSelection=NULL;
87 void AliHLTTPCKryptonClusterFinder::ReBunch(const UInt_t *bunchData , Int_t bunchSize){
88 fTimebinsInBunch.clear();
89 fIndexOfBunchStart.clear();
90 Bool_t newBunch=kTRUE;
91 Int_t currentBunchNumber=-1;
92 for(Int_t i=0;i<bunchSize;i++){
95 fIndexOfBunchStart.push_back(i);
96 fTimebinsInBunch.push_back(1);
103 fTimebinsInBunch[currentBunchNumber]++;
112 void AliHLTTPCKryptonClusterFinder::ReadDataUnsorted(void* ptr,unsigned long size)
115 fPtr = (UChar_t*)ptr;
118 if(!fVectorInitialized){
119 InitializePadArray();
122 fDigitReader->InitBlock(fPtr,fSize,fFirstRow,fLastRow,fCurrentPatch,fCurrentSlice);
124 while(fDigitReader->NextChannel()){
125 UInt_t row=fDigitReader->GetRow();
126 UInt_t pad=fDigitReader->GetPad();
128 fRowPadVector[row][pad]->ClearCandidates();
130 while(fDigitReader->NextBunch()){
131 if(fDigitReader->GetBunchSize()>1){
132 const UInt_t *bunchData= fDigitReader->GetSignals();
134 ReBunch(bunchData,fDigitReader->GetBunchSize());
135 Int_t rebunchCount=fIndexOfBunchStart.size();
137 for(Int_t r=0;r<rebunchCount;r++){
138 UInt_t time = fDigitReader->GetTime()+fIndexOfBunchStart[r];
139 AliHLTTPCClusters candidate;
140 candidate.fTotalCharge=0;
141 candidate.fChargeFalling=0;//PS This variable will store teh maximum charge of the candidate, used later. Keep this in mind
142 if(fTimebinsInBunch[r]>2){
143 for(Int_t i=0;i<fTimebinsInBunch[r];i++){
144 candidate.fTotalCharge+=bunchData[i + fIndexOfBunchStart[r]];
145 candidate.fTime += time*bunchData[i + fIndexOfBunchStart[r]];
146 candidate.fTime2 += time*time*bunchData[i + fIndexOfBunchStart[r]];
147 if(bunchData[i + fIndexOfBunchStart[r]]>candidate.fChargeFalling){
148 candidate.fChargeFalling = bunchData[i + fIndexOfBunchStart[r]];
152 if(candidate.fTotalCharge>0){
153 candidate.fMean=candidate.fTime/candidate.fTotalCharge;
154 candidate.fPad=candidate.fTotalCharge*pad;
155 candidate.fPad2=candidate.fPad*pad;
156 candidate.fLastMergedPad=pad;
157 candidate.fRowNumber=row+fDigitReader->GetRowOffset();
159 if(candidate.fTotalCharge>10 && candidate.fMean<924){
160 fRowPadVector[row][pad]->AddClusterCandidate(candidate);
169 Bool_t AliHLTTPCKryptonClusterFinder::ComparePads(AliHLTTPCPad *nextPad,AliHLTTPCClusters* cluster,Int_t nextPadToRead){
170 //Checking if we have a match on the next pad
171 for(UInt_t candidateNumber=0;candidateNumber<nextPad->fClusterCandidates.size();candidateNumber++){
172 AliHLTTPCClusters *candidate =&nextPad->fClusterCandidates[candidateNumber];
173 if(cluster->fMean-candidate->fMean==1 || candidate->fMean-cluster->fMean==1 || cluster->fMean-candidate->fMean==0){
174 cluster->fMean=candidate->fMean;
175 cluster->fTotalCharge+=candidate->fTotalCharge;
176 cluster->fTime += candidate->fTime;
177 cluster->fTime2 += candidate->fTime2;
178 cluster->fPad+=candidate->fPad;
179 cluster->fPad2=candidate->fPad2;
180 cluster->fLastMergedPad=candidate->fPad;
182 if(candidate->fChargeFalling>cluster->fChargeFalling){
183 cluster->fChargeFalling = candidate->fChargeFalling;
186 //setting the matched pad to used
187 nextPad->fUsedClusterCandidates[candidateNumber]=1;
189 if(nextPadToRead<(Int_t)fNumberOfPadsInRow[fRowOfFirstCandidate]){
190 nextPad=fRowPadVector[fRowOfFirstCandidate][nextPadToRead];
191 ComparePads(nextPad,cluster,nextPadToRead);
204 void AliHLTTPCKryptonClusterFinder::FindRowClusters()
206 // see header file for function documentation
208 AliHLTTPCClusters* tmpCandidate=NULL;
209 for(UInt_t row=5;row<fNumberOfRows-5;row++){
210 fRowOfFirstCandidate=row;
211 for(UInt_t pad=5;pad<fNumberOfPadsInRow[row]-1-5;pad++){
212 AliHLTTPCPad *tmpPad=fRowPadVector[row][pad];
213 for(size_t candidate=0;candidate<tmpPad->fClusterCandidates.size();candidate++){
214 if(tmpPad->fUsedClusterCandidates[candidate]){
217 if((Int_t)tmpPad->fClusterCandidates[candidate].fMean<100 || (Int_t)tmpPad->fClusterCandidates[candidate].fMean>AliHLTTPCTransform::GetNTimeBins()-100){
220 tmpCandidate=&tmpPad->fClusterCandidates[candidate];
221 UInt_t tmpTotalCharge=tmpCandidate->fTotalCharge;
223 ComparePads(fRowPadVector[row][pad+1],tmpCandidate,pad+1);
224 if(tmpCandidate->fTotalCharge>tmpTotalCharge){
226 tmpCandidate->fPad=tmpCandidate->fPad/tmpCandidate->fTotalCharge;
227 fClusters.push_back(*tmpCandidate);
233 HLTDebug("Found %d normal clusters.",fClusters.size());
236 void AliHLTTPCKryptonClusterFinder::FindKryptonClusters()
238 if(fClusters.size()<2){
242 for(UInt_t i=0; i<fClusters.size();i++){
243 AliHLTTPCClusters * tmpCluster=&fClusters[i];
244 if(tmpCluster->fFlags==99){//quickfix to check if a cluster is used already
247 if((Int_t)tmpCluster->fChargeFalling>fMaxQOfCluster){
248 fMaxQOfCluster = tmpCluster->fChargeFalling;
251 //adds "normal" clusters belonging to the krypton cluster
252 for(UInt_t j=i+1;j<fClusters.size();j++){
253 AliHLTTPCClusters * nextCluster=&fClusters[j];
255 if(nextCluster->fFlags==99){//quickfix to check if a cluster is used already
259 if(tmpCluster->fRowNumber==nextCluster->fRowNumber-1){//Checks if the row numbers are ok (next to eachother)
260 if(abs((Int_t)(tmpCluster->fPad) - (Int_t)(nextCluster->fPad))<3){ // checks if the pad numbers are ok
261 if(abs((Int_t)tmpCluster->fMean-(Int_t)nextCluster->fMean)<2){
262 tmpCluster->fMean=nextCluster->fMean;
263 tmpCluster->fTotalCharge+=nextCluster->fTotalCharge;
264 tmpCluster->fPad=nextCluster->fPad;
266 if((Int_t)nextCluster->fChargeFalling>fMaxQOfCluster){
267 fMaxQOfCluster = nextCluster->fChargeFalling;
270 if(tmpCluster->fFlags!=99){//means that this is the first time normal clusters match
271 CheckForCandidateOnPreviousRow(tmpCluster);
273 tmpCluster->fRowNumber=nextCluster->fRowNumber;
274 nextCluster->fFlags=99;
275 tmpCluster->fFlags=99;
276 if(j!=fClusters.size()-1){
284 if(tmpCluster->fFlags==99){
285 //adds a clustercandidate on next row if present TODO
286 /* if(tmpCluster->fFlags==99){
287 for(Int_t p=-1;p<2;p++){
288 AliHLTTPCPad *padAfter=fRowPadVector[tmpCluster->fRowNumber+1][tmpCluster->fPad+p];
289 for(UInt_t c=0;c<padAfter->fClusterCandidates.size();c++)
290 if(abs((Int_t)tmpCluster->fMean - (Int_t)padAfter->fClusterCandidates[c].fMean)<2){
291 tmpCluster->fTotalCharge+=padAfter->fClusterCandidates[c].fTotalCharge;
293 }//end add clustercandidate if present
295 fHMaxQofKryptonClusterLast1000->Fill(fMaxQOfClusterBin,fMaxQOfCluster);
297 if(fMaxQOfClusterBin>fEndBinMaxQ){
300 fHKryptonSpectrumFullPatch->Fill(tmpCluster->fTotalCharge);
301 fHNumberOfKryptonClusters->Fill(fNumberOfKryptonClustersBin);
302 if(fNumberOfKryptonClustersBin>fEndBinNumberOfKryptonClusters){
303 fNumberOfKryptonClustersBin=0;
306 fHKryptonSpectrumSelection
307 fHNumberOfKryptonClustersSelection
308 fHMaxQofKryptonClusterSelection
310 HLTInfo("Krypton cluster found, charge: %d in patch number: %d",tmpCluster->fTotalCharge,fCurrentPatch);
316 }//end add "normal" clusters belonging to the krypton cluster
317 fNumberOfKryptonClustersBin++;
319 //resets the candidates for every pad and the fClusters(row clusters)
320 for(UInt_t row=5;row<fNumberOfRows-5;row++){
321 for(UInt_t pad=5;pad<fNumberOfPadsInRow[row]-1-5;pad++){
322 fRowPadVector[row][pad]->fClusterCandidates.clear();
328 void AliHLTTPCKryptonClusterFinder::CheckForCandidateOnPreviousRow(AliHLTTPCClusters *tmpCluster){
329 if(tmpCluster->fRowNumber>1){
330 for(Int_t p=-1;p<2;p++){
331 if(tmpCluster->fPad+p>0 && tmpCluster->fPad+p<fNumberOfPadsInRow[tmpCluster->fRowNumber-1]){
332 AliHLTTPCPad *prevPad=fRowPadVector[tmpCluster->fRowNumber-1-AliHLTTPCTransform::GetFirstRow(fCurrentPatch)][tmpCluster->fPad+p];
333 for(UInt_t i=0;i<prevPad->fClusterCandidates.size();i++){
334 if(abs((Int_t)prevPad->fClusterCandidates[i].fMean - (Int_t)tmpCluster->fMean)<2 && prevPad->fUsedClusterCandidates[i]==0){
335 tmpCluster->fTotalCharge += prevPad->fClusterCandidates[i].fTotalCharge;
343 void AliHLTTPCKryptonClusterFinder::InitializeHistograms(){
346 if(fHistogramsInitialized){
350 TString sliceStr("-Slice_");
351 sliceStr+=fCurrentSlice;
352 TString patchStr("-Patch_");
353 patchStr+=fCurrentPatch;
355 TString namefKryptonSpectrumFullPatch("KryptonSpectrumFullPatch"+sliceStr+patchStr);
356 TString namefKryptonSpectrumSelection = "KryptonSpectrumSelection"+sliceStr+patchStr;
357 TString namefNumberOfKryptonClusters = "NumberOfKryptonClusters"+sliceStr+patchStr;
358 TString namefNumberOfKryptonClustersSelection = "NumberOfKryptonClustersSelection"+sliceStr+patchStr;
359 TString namefMaxQLast1000 = "MaxQ"+sliceStr+patchStr;
360 TString namefMaxQSelection = "MaxQSelection"+sliceStr+patchStr;
362 fHKryptonSpectrumFullPatch = new TH1F(namefKryptonSpectrumFullPatch,namefKryptonSpectrumFullPatch,fEndBinKryptonSpectrum-fStartBinKryptonSpectrum,fStartBinKryptonSpectrum,fEndBinKryptonSpectrum);
364 fHKryptonSpectrumSelection = new TH1F(namefKryptonSpectrumSelection,namefKryptonSpectrumSelection,fEndBinKryptonSpectrum-fStartBinKryptonSpectrum,fStartBinKryptonSpectrum,fEndBinKryptonSpectrum);
366 fHNumberOfKryptonClusters = new TH1F(namefNumberOfKryptonClusters,namefNumberOfKryptonClusters,fEndBinNumberOfKryptonClusters-fStartBinNumberOfKryptonClusters,fStartBinNumberOfKryptonClusters,fEndBinNumberOfKryptonClusters);
368 fHNumberOfKryptonClustersSelection = new TH1F(namefNumberOfKryptonClustersSelection,namefNumberOfKryptonClustersSelection,fEndBinNumberOfKryptonClusters-fStartBinNumberOfKryptonClusters,fStartBinNumberOfKryptonClusters,fEndBinNumberOfKryptonClusters);
370 fHMaxQofKryptonClusterLast1000 = new TH1F(namefMaxQLast1000,namefMaxQLast1000,fEndBinMaxQ-fStartBinMaxQ,fStartBinMaxQ,fEndBinMaxQ);
372 fHMaxQofKryptonClusterSelection = new TH1F(namefMaxQSelection,namefMaxQSelection,fEndBinMaxQ-fStartBinMaxQ,fStartBinMaxQ,fEndBinMaxQ);
374 fHistogramsInitialized=kTRUE;
377 void AliHLTTPCKryptonClusterFinder::ResetHistograms(TString histoName){
379 if (histoName.CompareTo("KryptonSpectrumFullPatch")==0){
380 fHKryptonSpectrumFullPatch->Reset();
382 if (histoName.CompareTo("KryptonSpectrumSelection")==0){
383 fHKryptonSpectrumSelection->Reset();
385 if (histoName.CompareTo("NumberOfKryptonClusters")==0){
386 fHNumberOfKryptonClusters->Reset();
388 if (histoName.CompareTo("NumberOfKryptonClustersSelection")==0){
389 fHNumberOfKryptonClustersSelection->Reset();
391 if (histoName.CompareTo("MaxQ")==0){
392 fHMaxQofKryptonClusterLast1000->Reset();
394 if (histoName.CompareTo("MaxQSelection")==0){
395 fHMaxQofKryptonClusterSelection->Reset();
397 if (histoName.CompareTo("All")==0){
398 fHKryptonSpectrumFullPatch->Reset();
399 fHKryptonSpectrumSelection->Reset();
400 fHNumberOfKryptonClusters->Reset();
401 fHNumberOfKryptonClustersSelection->Reset();
402 fHMaxQofKryptonClusterLast1000->Reset();
403 fHMaxQofKryptonClusterSelection->Reset();
407 void AliHLTTPCKryptonClusterFinder::SetSelection(Int_t minRow, Int_t maxRow){
408 fSelectionMinRowNumber=minRow;
409 fSelectionMaxRowNumber=maxRow;
412 void AliHLTTPCKryptonClusterFinder::GetHistogramObjectArray(TObjArray & histos){
415 histos.Add(fHKryptonSpectrumFullPatch);
416 histos.Add(fHKryptonSpectrumSelection);
417 histos.Add(fHNumberOfKryptonClusters);
418 histos.Add(fHNumberOfKryptonClustersSelection);
419 histos.Add(fHMaxQofKryptonClusterLast1000);
420 histos.Add(fHMaxQofKryptonClusterSelection);
424 void AliHLTTPCKryptonClusterFinder::WriteHistograms(TString filename){
426 TFile file(filename,"recreate");
427 fHKryptonSpectrumFullPatch->Write();
428 fHKryptonSpectrumSelection->Write();
429 fHNumberOfKryptonClusters->Write();
430 fHNumberOfKryptonClustersSelection->Write();
431 fHMaxQofKryptonClusterLast1000->Write();
432 fHMaxQofKryptonClusterSelection->Write();