2 // Author: Constantin Loizides <mailto:loizides@ikf.physik.uni-frankfurt.de>
11 #include "AliL3VHDLClusterFinder.h"
13 /** \class AliL3VHDLClusterFinder
15 //____________________________________________________
16 // AliL3VHDLClusterFinder
18 // The current VHDL cluster finder for HLT
21 // Most important parameters:
22 // fThreshold - threshold for noise clusters
23 // fMatch - length in time for overlapping sequences
26 ClassImp(AliL3VHDLClusterFinder)
28 AliL3VHDLClusterFinder::AliL3VHDLClusterFinder()
44 fdeb=fopen("vhdlclusterfinder.debug","w");
49 AliL3VHDLClusterFinder::~AliL3VHDLClusterFinder()
56 void AliL3VHDLClusterFinder::ProcessDigits()
58 //Loop over data like the analyzer of the VHDL code
60 UShort_t rrow=0,rtime=0;
62 UShort_t *charges=new UShort_t[n];
63 Int_t tc=0,mp=0,mt=0,sp=0,st=0;
70 //loop over input data
71 while(fAltromem.ReadSequence(rrow,rpad,rtime,i,&charges)){
72 tc=0;mp=0;mt=0;sp=0;st=0;
74 cout << "Padrow " << (int)rrow << " pad " << (int)rpad << " time " <<(int)rtime << " charges ";
75 for(UChar_t ii=0;ii<i;ii++) cout << (int)charges[ii] << " ";
79 fprintf(fdeb,"ProcessDigits: Input Data: %d %d %d charges:",(int)rrow,(int)rpad,(int)rtime);
80 for(UChar_t ii=0;ii<i;ii++) fprintf(fdeb," %d",(int)charges[ii]);
87 //calculate sequence values
88 //no deconvulution so far
89 for(UChar_t ii=0;ii<i;ii++){
91 mt+=(rtime-ii)*charges[ii];
92 st+=(rtime-ii)*(rtime-ii)*charges[ii];
103 if(tc!=0) fSeq.fMean=mt/tc;
108 //work on this sequence
116 i=n; //store size of charges array
119 //flush everything left
121 while(fOP!=fFP) OutputMemory();
124 void AliL3VHDLClusterFinder::ProcessSequence()
126 if(fNRow!=fRow) FlushMemory();
127 else if(fNPad==fPad+1) PrepareMemory();
128 else if(fNPad!=fPad) FlushMemory();
130 //store new row and pad values
135 fprintf(fdeb,"ProcessSequence: Mean=%d TC=%d ",fSeq.fMean,fSeq.fTotalCharge);
138 CompareSeq(); //merge or insert
141 void AliL3VHDLClusterFinder::PrepareMemory()
144 fprintf(fdeb,"PrepareMemory %d %d %d\n",fRP,fEP,fWP);
150 void AliL3VHDLClusterFinder::FlushMemory()
153 fprintf(fdeb,"FlushMemory %d %d %d %d\n",fFP,fRP,fEP,fWP);
160 void AliL3VHDLClusterFinder::CompareSeq()
164 Int_t diff=fSeqs[fPList[fRP]].fMean-fSeq.fMean;
166 if(diff>fMatch){ //no match
167 IncRPointer(); //cluster finished
169 } else if(diff<-fMatch){ //no match
170 break; //insert new cluster
172 else { //match found, merge it
178 InsertSeq(); //start new cluster
181 void AliL3VHDLClusterFinder::MergeSeq()
184 fprintf(fdeb,"merged with Mean=%d TC=%d (new Merge=%d)\n",fSeqs[fPList[fRP]].fMean,fSeqs[fPList[fRP]].fTotalCharge,fSeqs[fPList[fRP]].fMerge+1);
186 if(fSeqs[fPList[fRP]].fRow==fSeq.fRow){
187 LOG(AliL3Log::kWarning,"AliL3VHDLClusterFinder::","Memory Check")
188 <<"Sequences can be merged on the same rows only."<<ENDLOG;
190 if(fSeqs[fPList[fRP]].fLastPad+1!=fSeq.fLastPad){
191 LOG(AliL3Log::kWarning,"AliL3VHDLClusterFinder::","Memory Check")
192 <<"Sequences can be merged on consecutive pads only."<<ENDLOG;
195 fSeqs[fPList[fRP]].fMean=fSeq.fMean; //take the new mean
196 fSeqs[fPList[fRP]].fLastPad=fSeq.fLastPad;
197 fSeqs[fPList[fRP]].fTotalCharge+=fSeq.fTotalCharge;
198 fSeqs[fPList[fRP]].fPad+=fSeq.fPad;
199 fSeqs[fPList[fRP]].fTime+=fSeq.fTime;
200 fSeqs[fPList[fRP]].fPad2+=fSeq.fPad2;
201 fSeqs[fPList[fRP]].fTime2+=fSeq.fTime2;
202 fSeqs[fPList[fRP]].fMerge+=1;
204 fPList[fWP]=fPList[fRP];
205 fPList[fRP]=N_clmem; //mark it to be free
211 void AliL3VHDLClusterFinder::InsertSeq()
214 fprintf(fdeb,"inserted\n");
216 NextFreeIndex(); //get next index
217 fSeqs[fFirst]=fSeq; //store data
218 fPList[fWP]=fFirst; //store index
222 void AliL3VHDLClusterFinder::OutputMemory()
224 Float_t mtime=0,mpad=0;
225 Float_t mtime2=0,mpad2=0;
231 UInt_t index=fPList[fOP];
233 //cout << fOP << " - " << fFP << " - " << index << endl;
235 if(index>=N_clmem) return; //nothing to do
236 //if(index>=N_clmem) continue; //nothing to do
238 tc=fSeqs[index].fTotalCharge;
239 mno=fSeqs[index].fMerge;
240 row=fSeqs[index].fRow;
242 mtime=(Float_t)(fSeqs[index].fTime)/tc;
243 mtime2=sqrt((Float_t)(fSeqs[index].fTime2)/tc-mtime*mtime);
246 mpad=(Float_t)(fSeqs[index].fPad)/tc;
247 mpad2=sqrt((Float_t)(fSeqs[index].fPad2)/tc-mpad*mpad);
250 if(mno<fMinMerge){ //noise cluster
252 fprintf(fdeb,"OutputMemory %d %d: noise cluster (merge): Row %d Pad %.3f Time %.3f TC %d Merge %d\n",fOP,fFP,row,mpad,mtime,tc,mno);
259 if(tc<fThreshold){ //total charge below threshold
261 fprintf(fdeb,"OutputMemory %d %d: noise cluster (threshold): Row %d Pad %.3f Time %.3f TC %d Merge %d\n",fOP,fFP,row,mpad,mtime,tc,mno);
269 fprintf(fdeb,"OutputMemory %d: Row %d Pad %.3f Time %.3f TC %d Merge %d\n",fNClusters,row,mpad,mtime,tc,mno);
273 cout<<"WriteCluster: padrow "<<row<<" pad "<<mpad<< " +- "<<mpad2<<" time "<<mtime<<" +- "<<mtime2<<" charge "<<tc<<endl;
280 inline void AliL3VHDLClusterFinder::FreeSeq(UShort_t i)
283 IncPointer(fLast,1,N_clmem);
286 void AliL3VHDLClusterFinder::Clear()
288 fFirst=0; //first list pointer
289 fLast=0; //last list pointer
291 fWP=0; //write pointer
292 fRP=0; //read pointer
293 fEP=0; //end read pointer
294 fFP=0; //end flush pointer
295 fOP=0; //output pointer
307 for(UInt_t i=0;i<N_mem;i++) fPList[i]=N_clmem;
308 for(UInt_t i=0;i<N_clmem;i++) ClearSeq(i);
311 void AliL3VHDLClusterFinder::ClearSeq(UShort_t i){
314 fSeqs[i].fTotalCharge=0;
323 void AliL3VHDLClusterFinder::IncPointer(UShort_t &p, Short_t add, UShort_t N){
326 if(pp>=N) p=UShort_t(pp-N);
327 else if(pp<0) p=UShort_t(pp+N);
331 inline void AliL3VHDLClusterFinder::IncRPointer(){
335 inline void AliL3VHDLClusterFinder::IncWPointer(){
339 LOG(AliL3Log::kWarning,"AliL3VHDLClusterFinder::IncWPointer","Memory Check")
340 <<"Write pointer overwrites output pointer."<<ENDLOG;
344 inline void AliL3VHDLClusterFinder::NextFreeIndex(){
345 IncPointer(fFirst,1,N_clmem);
347 LOG(AliL3Log::kFatal,"AliL3VHDLClusterFinder::GetFreeIndex","Memory Check")
348 <<"No space left in sequence list: "<<fFirst<<"=="<<fLast<<ENDLOG;
353 void AliL3ClustFinderNew::WriteClusters(Int_t n_clusters,ClusterData *list)
355 Int_t thisrow,thissector;
356 UInt_t counter = fNClusters;
358 for(int j=0; j<n_clusters; j++)
360 if(!list[j].fFlags) continue; //discard 1 pad clusters
361 if(list[j].fTotalCharge < fThreshold) continue; //noise cluster
364 Float_t fpad =(Float_t)list[j].fPad /(Float_t)list[j].fTotalCharge;
365 Float_t fpad2=fXYErr;
366 Float_t ftime =(Float_t)list[j].fTime /(Float_t)list[j].fTotalCharge;
367 Float_t ftime2=fZErr;
370 fpad2=(Float_t)list[j].fPad2/(Float_t)list[j].fTotalCharge - fpad*fpad;
372 ftime2=(Float_t)list[j].fTime2/(Float_t)list[j].fTotalCharge - ftime*ftime;
373 ftime2 = sqrt(ftime2);
377 cout<<"WriteCluster: padrow "<<fCurrentRow<<" pad "<<fpad << "+-"<<fpad2<<" time "<<ftime<<"+-"<<ftime2<<" charge "<<list[j].fTotalCharge<<endl;
379 AliL3Transform::Slice2Sector(fCurrentSlice,fCurrentRow,thissector,thisrow);
380 AliL3Transform::Raw2Local(xyz,thissector,thisrow,fpad,ftime);
381 if(xyz[0]==0) LOG(AliL3Log::kError,"AliL3ClustFinder","Cluster Finder")
382 <<AliL3Log::kDec<<"Zero cluster"<<ENDLOG;
383 if(fNClusters >= fMaxNClusters)
385 LOG(AliL3Log::kError,"AliL3ClustFinder::WriteClusters","Cluster Finder")
386 <<AliL3Log::kDec<<"Too many clusters"<<ENDLOG;
389 fSpacePointData[counter].fCharge = list[j].fTotalCharge;
390 fSpacePointData[counter].fX = xyz[0];
391 fSpacePointData[counter].fY = xyz[1];
392 fSpacePointData[counter].fZ = xyz[2];
393 fSpacePointData[counter].fPadRow = fCurrentRow;
394 fSpacePointData[counter].fXYErr = fpad2;
395 fSpacePointData[counter].fZErr = ftime2;
396 fSpacePointData[counter].fID = counter
397 +((fCurrentSlice&0x7f)<<25)+((fCurrentPatch&0x7)<<22);//Uli