3 // Author: Constantin Loizides <mailto:loizides@ikf.uni-frankfurt.de>
4 //*-- Copyright & copy ALICE HLT Group
5 /** \class AliL3VHDLClusterFinder
7 //____________________________________________________
8 // AliL3VHDLClusterFinder
10 // The current VHDL cluster finder for HLT
13 // Most important parameters:
14 // fThreshold - threshold for noise clusters
15 // fMatch - length in time for overlapping sequences
19 #include "AliL3StandardIncludes.h"
20 #include "AliL3RootTypes.h"
21 #include "AliL3Logging.h"
22 #include "AliL3AltroMemHandler.h"
25 #include "AliL3VHDLClusterFinder.h"
32 ClassImp(AliL3VHDLClusterFinder)
34 AliL3VHDLClusterFinder::AliL3VHDLClusterFinder()
36 // default constructor
51 fdeb=fopen("vhdlclusterfinder.debug","w");
56 AliL3VHDLClusterFinder::~AliL3VHDLClusterFinder()
64 void AliL3VHDLClusterFinder::ProcessDigits()
66 //Loop over data like the analyzer of the VHDL code
68 UShort_t rrow=0,rtime=0;
70 UShort_t *charges=new UShort_t[kn];
77 //loop over input data
78 while(fAltromem.ReadSequence(rrow,rpad,rtime,i,&charges)){
80 cout << "Padrow " << (int)rrow << " pad " << (int)rpad << " time " <<(int)rtime << " charges ";
81 for(UChar_t ii=0;ii<i;ii++) cout << (int)charges[ii] << " ";
85 fprintf(fdeb,"ProcessDigits: Input Data: %d %d %d charges:",(int)rrow,(int)rpad,(int)rtime);
86 for(UChar_t ii=0;ii<i;ii++) fprintf(fdeb," %d",(int)charges[ii]);
94 //calculate sequence values
98 Int_t charge=0,lcharge=0;
99 Bool_t falling=kFALSE;
102 if((falling)&&(charge>lcharge)){
112 } else if(charge<lcharge) falling=kTRUE;
115 fMT+=(rtime-sl)*charge;
116 fST+=(rtime-sl)*(rtime-sl)*charge;
120 } //end loop over sequence
122 } else { /* no deconvolution */
123 for(UChar_t ii=0;ii<i;ii++){
125 fMT+=(rtime-ii)*charges[ii];
126 fST+=(rtime-ii)*(rtime-ii)*charges[ii];
138 i=kn; //store size of charges array
141 //flush everything left
143 while(fOP!=fFP) OutputMemory();
146 void AliL3VHDLClusterFinder::MakeSequence(){
147 // makes the sequence
151 Int_t sp=fNPad*fNPad*fTC;
153 fSeq.fTotalCharge=fTC;
163 fSeq.fChargeFalling=0;
164 if(fDeconvPad) fSeq.fLastCharge=fTC;
165 else fSeq.fLastCharge=0;
168 void AliL3VHDLClusterFinder::ProcessSequence()
170 // processes the sequence
171 if(fNRow!=fRow) FlushMemory();
172 else if(fNPad==fPad+1) PrepareMemory();
173 else if(fNPad!=fPad) FlushMemory();
175 //store new row and pad values
180 fprintf(fdeb,"ProcessSequence: Mean=%d TC=%d ",fSeq.fMean,fSeq.fTotalCharge);
183 CompareSeq(); //merge or insert
186 void AliL3VHDLClusterFinder::PrepareMemory()
188 // prepares the memory
190 fprintf(fdeb,"PrepareMemory %d %d %d\n",fRP,fEP,fWP);
196 void AliL3VHDLClusterFinder::FlushMemory()
198 // flushes the memory
200 fprintf(fdeb,"FlushMemory %d %d %d %d\n",fFP,fRP,fEP,fWP);
207 void AliL3VHDLClusterFinder::CompareSeq()
209 // compares sequences
211 Int_t diff=fSeqs[fPList[fRP]].fMean-fSeq.fMean;
213 if(diff>fMatch){ //no match
214 IncRPointer(); //cluster finished
216 } else if(diff<-fMatch){ //no match
217 break; //insert new cluster
218 } else { //match found, merge it
224 InsertSeq(); //start new cluster
227 void AliL3VHDLClusterFinder::MergeSeq()
231 fprintf(fdeb,"merged with Mean=%d TC=%d (new Merge=%d) %d %d\n",fSeqs[fPList[fRP]].fMean,fSeqs[fPList[fRP]].fTotalCharge,fSeqs[fPList[fRP]].fMerge+1,fRow,fPad);
233 if(fSeqs[fPList[fRP]].fRow!=fSeq.fRow){
234 LOG(AliL3Log::kWarning,"AliL3VHDLClusterFinder::","Memory Check")
235 <<"Sequences can be merged on the same rows only."<<ENDLOG;
237 if(fSeqs[fPList[fRP]].fLastPad+1!=fSeq.fLastPad){
238 LOG(AliL3Log::kWarning,"AliL3VHDLClusterFinder::","Memory Check")
239 <<"Sequences can be merged on consecutive pads only."<<ENDLOG;
243 if(fSeq.fTotalCharge > fSeqs[fPList[fRP]].fLastCharge){
244 if(fSeqs[fPList[fRP]].fChargeFalling){ //The previous pad was falling
246 InsertSeq(); //start a new cluster
250 else fSeqs[fPList[fRP]].fChargeFalling = 1;
252 fSeqs[fPList[fRP]].fLastCharge = fSeq.fTotalCharge;
255 fSeqs[fPList[fRP]].fMean=fSeq.fMean; //take the new mean
256 fSeqs[fPList[fRP]].fLastPad=fSeq.fLastPad;
257 fSeqs[fPList[fRP]].fTotalCharge+=fSeq.fTotalCharge;
258 fSeqs[fPList[fRP]].fPad+=fSeq.fPad;
259 fSeqs[fPList[fRP]].fTime+=fSeq.fTime;
260 fSeqs[fPList[fRP]].fPad2+=fSeq.fPad2;
261 fSeqs[fPList[fRP]].fTime2+=fSeq.fTime2;
262 fSeqs[fPList[fRP]].fMerge+=1;
264 fPList[fWP]=fPList[fRP];
265 fPList[fRP]=N_clmem; //mark it to be free
271 void AliL3VHDLClusterFinder::InsertSeq()
275 fprintf(fdeb,"inserted %d %d\n",fRow,fPad);
277 NextFreeIndex(); //get next index
278 fSeqs[fFirst]=fSeq; //store data
279 fPList[fWP]=fFirst; //store index
283 void AliL3VHDLClusterFinder::OutputMemory()
286 Float_t mtime=0,mpad=0;
287 Float_t mtime2=0,mpad2=0;
293 UInt_t index=fPList[fOP];
295 //cout << fOP << " - " << fFP << " - " << index << endl;
297 if(index>=N_clmem) return; //nothing to do
298 //if(index>=N_clmem) continue; //nothing to do
300 tc=fSeqs[index].fTotalCharge;
301 mno=fSeqs[index].fMerge;
302 row=fSeqs[index].fRow;
304 mtime=(Float_t)(fSeqs[index].fTime)/tc;
305 mtime2=sqrt((Float_t)(fSeqs[index].fTime2)/tc-mtime*mtime);
308 mpad=(Float_t)(fSeqs[index].fPad)/tc;
309 mpad2=sqrt((Float_t)(fSeqs[index].fPad2)/tc-mpad*mpad);
312 if(mno<fMinMerge){ //noise cluster
314 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);
321 if(tc<fThreshold){ //total charge below threshold
323 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);
331 fprintf(fdeb,"OutputMemory %d: Row %d Pad %.3f Time %.3f TC %d Merge %d\n",fNClusters,row,mpad,mtime,tc,mno);
335 cout<<"WriteCluster: padrow "<<row<<" pad "<<mpad<< " +- "<<mpad2<<" time "<<mtime<<" +- "<<mtime2<<" charge "<<tc<<endl;
342 void AliL3VHDLClusterFinder::FreeSeq(UShort_t i)
344 // frees the sequence
346 IncPointer(fLast,1,N_clmem);
349 void AliL3VHDLClusterFinder::Clear()
352 fFirst=0; //first list pointer
353 fLast=0; //last list pointer
355 fWP=0; //write pointer
356 fRP=0; //read pointer
357 fEP=0; //end read pointer
358 fFP=0; //end flush pointer
359 fOP=0; //output pointer
371 for(UInt_t i=0;i<N_mem;i++) fPList[i]=N_clmem;
372 for(UInt_t i=0;i<N_clmem;i++) ClearSeq(i);
375 void AliL3VHDLClusterFinder::ClearSeq(UShort_t i){
379 fSeqs[i].fTotalCharge=0;
388 void AliL3VHDLClusterFinder::IncPointer(UShort_t &p, Short_t add, UShort_t N){
389 // increments pointer by 'add' in a circular buffer
392 if(pp>=N) p=UShort_t(pp-N);
393 else if(pp<0) p=UShort_t(pp+N);
397 void AliL3VHDLClusterFinder::IncRPointer(){
398 // increments pointer fRP
402 void AliL3VHDLClusterFinder::IncWPointer(){
403 // increments pointer fWP
407 LOG(AliL3Log::kWarning,"AliL3VHDLClusterFinder::IncWPointer","Memory Check")
408 <<"Write pointer overwrites output pointer."<<ENDLOG;
412 void AliL3VHDLClusterFinder::NextFreeIndex(){
413 // finds next free index
414 IncPointer(fFirst,1,N_clmem);
416 LOG(AliL3Log::kFatal,"AliL3VHDLClusterFinder::GetFreeIndex","Memory Check")
417 <<"No space left in sequence list: "<<fFirst<<"=="<<fLast<<ENDLOG;
422 void AliL3ClustFinderNew::WriteClusters(Int_t n_clusters,ClusterData *list)
425 Int_t thisrow,thissector;
426 UInt_t counter = fNClusters;
428 for(int j=0; j<n_clusters; j++)
430 if(!list[j].fFlags) continue; //discard 1 pad clusters
431 if(list[j].fTotalCharge < fThreshold) continue; //noise cluster
434 Float_t fpad =(Float_t)list[j].fPad /(Float_t)list[j].fTotalCharge;
435 Float_t fpad2=fXYErr;
436 Float_t ftime =(Float_t)list[j].fTime /(Float_t)list[j].fTotalCharge;
437 Float_t ftime2=fZErr;
440 fpad2=(Float_t)list[j].fPad2/(Float_t)list[j].fTotalCharge - fpad*fpad;
442 ftime2=(Float_t)list[j].fTime2/(Float_t)list[j].fTotalCharge - ftime*ftime;
443 ftime2 = sqrt(ftime2);
447 cout<<"WriteCluster: padrow "<<fCurrentRow<<" pad "<<fpad << "+-"<<fpad2<<" time "<<ftime<<"+-"<<ftime2<<" charge "<<list[j].fTotalCharge<<endl;
449 AliL3Transform::Slice2Sector(fCurrentSlice,fCurrentRow,thissector,thisrow);
450 AliL3Transform::Raw2Local(xyz,thissector,thisrow,fpad,ftime);
451 if(xyz[0]==0) LOG(AliL3Log::kError,"AliL3ClustFinder","Cluster Finder")
452 <<AliL3Log::kDec<<"Zero cluster"<<ENDLOG;
453 if(fNClusters >= fMaxNClusters)
455 LOG(AliL3Log::kError,"AliL3ClustFinder::WriteClusters","Cluster Finder")
456 <<AliL3Log::kDec<<"Too many clusters"<<ENDLOG;
459 fSpacePointData[counter].fCharge = list[j].fTotalCharge;
460 fSpacePointData[counter].fX = xyz[0];
461 fSpacePointData[counter].fY = xyz[1];
462 fSpacePointData[counter].fZ = xyz[2];
463 fSpacePointData[counter].fPadRow = fCurrentRow;
464 fSpacePointData[counter].fXYErr = fpad2;
465 fSpacePointData[counter].fZErr = ftime2;
466 fSpacePointData[counter].fID = counter
467 +((fCurrentSlice&0x7f)<<25)+((fCurrentPatch&0x7)<<22);//Uli