3 // Author: Anders Vestbo <mailto:vestbo@fi.uib.no>
4 //*-- Copyright © ASV
8 #include "AliL3Logging.h"
9 #include "AliL3ClustFinderNew.h"
10 #include "AliL3DigitData.h"
11 #include "AliL3Transform.h"
12 #include "AliL3SpacePointData.h"
13 #include "AliL3MemHandler.h"
15 //_____________________________________________________________
16 // AliL3ClustFinderNew
18 // The current cluster finder for HLT
21 ClassImp(AliL3ClustFinderNew)
23 AliL3ClustFinderNew::AliL3ClustFinderNew()
31 AliL3ClustFinderNew::AliL3ClustFinderNew(AliL3Transform *transform)
33 fTransform = transform;
40 AliL3ClustFinderNew::~AliL3ClustFinderNew()
46 void AliL3ClustFinderNew::InitSlice(Int_t slice,Int_t patch,Int_t firstrow, Int_t lastrow,Int_t nmaxpoints)
49 fMaxNClusters = nmaxpoints;
50 fCurrentSlice = slice;
51 fCurrentPatch = patch;
58 void AliL3ClustFinderNew::InitSlice(Int_t slice,Int_t patch,Int_t nmaxpoints)
61 fMaxNClusters = nmaxpoints;
62 fCurrentSlice = slice;
63 fCurrentPatch = patch;
66 void AliL3ClustFinderNew::SetOutputArray(AliL3SpacePointData *pt)
73 void AliL3ClustFinderNew::Read(UInt_t ndigits,AliL3DigitRowData *ptr)
75 fNDigitRowData = ndigits;
80 void AliL3ClustFinderNew::ProcessDigits()
82 //Loop over rows, and call processrow
85 AliL3DigitRowData *tempPt = (AliL3DigitRowData*)fDigitRowData;
87 for(Int_t i=fFirstRow; i<=fLastRow; i++)
91 Byte_t *tmp = (Byte_t*)tempPt;
92 Int_t size = sizeof(AliL3DigitRowData) + tempPt->fNDigit*sizeof(AliL3DigitData);
94 tempPt = (AliL3DigitRowData*)tmp;
96 LOG(AliL3Log::kInformational,"AliL3ClustFinderNew::WriteClusters","Space points")
97 <<"Cluster finder found "<<fNClusters<<" clusters in slice "<<fCurrentSlice
98 <<" patch "<<fCurrentPatch<<ENDLOG;
105 void AliL3ClustFinderNew::ProcessRow(AliL3DigitRowData *tempPt)
108 UInt_t last_pad = 123456789;
110 ClusterData *pad1[2500]; //2 lists for internal memory=2pads
111 ClusterData *pad2[2500]; //2 lists for internal memory=2pads
112 ClusterData clusterlist[5000]; //Clusterlist
114 ClusterData **currentPt; //List of pointers to the current pad
115 ClusterData **previousPt; //List of pointers to the previous pad
118 UInt_t n_previous=0,n_current=0,n_total=0;
120 //Loop over sequences of this row:
121 for(UInt_t bin=0; bin<tempPt->fNDigit; bin++)
124 AliL3DigitData *data = tempPt->fDigitData;
125 if(data[bin].fPad != last_pad)
130 if(currentPt == pad2)
141 n_previous = n_current;
143 if(bin[data].fPad != last_pad+1)
145 //this happens if there is a pad with no signal.
146 n_previous = n_current = 0;
148 last_pad = data[bin].fPad;
151 Bool_t new_cluster = kTRUE;
153 UInt_t seq_charge=0,seq_average=0;
155 UInt_t last_charge=0,last_was_falling=0;
159 redo: //This is a goto.
167 last_was_falling = 0;
171 while(1) //Loop over current sequence
173 if(data[bin].fTime >= fTransform->GetNTimeBins())
175 LOG(AliL3Log::kFatal,"AliL3ClustFinderNew::ProcessRow","Digits")
176 <<"Timebin out of range "<<(Int_t)data[bin].fTime<<ENDLOG;
180 //Get the current ADC-value
181 UInt_t charge = data[bin].fCharge;
185 //Check if the last pixel in the sequence is smaller than this
186 if(charge > last_charge)
194 else last_was_falling = 1; //last pixel was larger than this
195 last_charge = charge;
198 //Sum the total charge of this sequence
199 seq_charge += charge;
200 seq_average += data[bin].fTime*charge;
202 //Check where to stop:
203 if(data[bin+1].fPad != data[bin].fPad) //new pad
205 if(data[bin+1].fTime != data[bin].fTime+1) //end of sequence
209 }//end loop over sequence
211 //Calculate mean of sequence:
214 seq_mean = seq_average/seq_charge;
217 LOG(AliL3Log::kFatal,"AliL3ClustFinderNew::ProcessRow","Data")
218 <<"Error in data given to the cluster finder"<<ENDLOG;
223 //Calculate mean in pad direction:
224 Int_t pad_mean = seq_charge*data[bin].fPad;
226 //Compare with results on previous pad:
227 for(UInt_t p=0; p<n_previous; p++)
229 Int_t difference = seq_mean - previousPt[p]->fMean;
230 if(difference < -fMatch)
233 if(difference <= fMatch)//There is a match here!!
236 ClusterData *local = previousPt[p];
239 if(seq_charge > local->fLastCharge)
241 if(local->fChargeFalling)//The previous pad was falling
243 break;//create a new cluster
247 local->fChargeFalling = 1;
248 local->fLastCharge = seq_charge;
251 //Don't create a new cluster, because we found a match
252 new_cluster = kFALSE;
254 //Update cluster on current pad with the matching one:
255 //currentPt[n_current] = previousPt[p];
257 local->fTotalCharge += seq_charge;
258 local->fPad += pad_mean;
259 local->fTime += seq_average;
260 local->fMean = seq_mean;
261 local->fFlags++; //means we have more than one pad
263 currentPt[n_current] = local;
267 }//Checking for match at previous pad
268 }//Loop over results on previous pad.
272 //Start a new cluster. Add it to the clusterlist, and update
273 //the list of pointers to clusters in current pad.
274 //current pad will be previous pad on next pad.
276 //Add to the clusterlist:
277 ClusterData *tmp = &clusterlist[n_total];
278 tmp->fTotalCharge = seq_charge;
279 tmp->fPad = pad_mean;
280 tmp->fTime = seq_average;
281 tmp->fMean = seq_mean;
282 tmp->fFlags = 0; //flags for 1 pad clusters
285 tmp->fChargeFalling = 0;
286 tmp->fLastCharge = seq_charge;
289 //Update list of pointers to previous pad:
290 currentPt[n_current] = &clusterlist[n_total];
295 if(new_bin >= 0) goto redo;
297 }//Loop over digits on this padrow
299 WriteClusters(n_total,clusterlist);
304 void AliL3ClustFinderNew::WriteClusters(Int_t n_clusters,ClusterData *list)
306 Int_t thisrow,thissector;
307 UInt_t counter = fNClusters;
309 for(int j=0; j<n_clusters; j++)
311 if(!list[j].fFlags) continue; //discard 1 pad clusters
312 if(list[j].fTotalCharge < fThreshold) continue; //noise cluster
315 Float_t fpad=(Float_t)list[j].fPad/(Float_t)list[j].fTotalCharge;
316 Float_t ftime=(Float_t)list[j].fTime/(Float_t)list[j].fTotalCharge;
317 //printf("padrow %d number of pads %d totalcharge %d\n",fCurrentRow,list[j].fFlags,list[j].fTotalCharge);
318 fTransform->Slice2Sector(fCurrentSlice,fCurrentRow,thissector,thisrow);
319 fTransform->Raw2Local(xyz,thissector,thisrow,fpad,ftime);
320 if(xyz[0]==0) LOG(AliL3Log::kError,"AliL3ClustFinder","Cluster Finder")
321 <<AliL3Log::kDec<<"Zero cluster"<<ENDLOG;
322 if(fNClusters >= fMaxNClusters)
324 LOG(AliL3Log::kError,"AliL3ClustFinder::WriteClusters","Cluster Finder")
325 <<AliL3Log::kDec<<"Too many clusters"<<ENDLOG;
328 fSpacePointData[counter].fCharge = list[j].fTotalCharge;
329 fSpacePointData[counter].fX = xyz[0];
330 fSpacePointData[counter].fY = xyz[1];
331 fSpacePointData[counter].fZ = xyz[2];
332 fSpacePointData[counter].fPadRow = fCurrentRow;
333 fSpacePointData[counter].fXYErr = fXYErr;
334 fSpacePointData[counter].fZErr = fZErr;
335 fSpacePointData[counter].fID = counter
336 +((fCurrentSlice&0x7f)<<25)+((fCurrentPatch&0x7)<<22);//uli
339 GetTrackID((Int_t)rint(fpad),(Int_t)rint(ftime),trackID);
340 //cout<<"padrow "<<fCurrentRow<<" pad "<<(Int_t)rint(fpad)<<" time "<<(Int_t)rint(ftime)<<" Trackid "<<trackID[0]<<endl;
341 fSpacePointData[counter].fTrackID[0] = trackID[0];
342 fSpacePointData[counter].fTrackID[1] = trackID[1];
343 fSpacePointData[counter].fTrackID[2] = trackID[2];
354 void AliL3ClustFinderNew::GetTrackID(Int_t pad,Int_t time,Int_t *trackID)
356 AliL3DigitRowData *rowPt = (AliL3DigitRowData*)fDigitRowData;
358 trackID[0]=trackID[1]=trackID[2]=-2;
359 //cout<<"Looking for pad "<<pad<<" time "<<time<<endl;
360 for(Int_t i=fFirstRow; i<=fLastRow; i++)
362 if(rowPt->fRow < (UInt_t)fCurrentRow)
364 AliL3MemHandler::UpdateRowPointer(rowPt);
367 AliL3DigitData *digPt = (AliL3DigitData*)rowPt->fDigitData;
368 for(UInt_t j=0; j<rowPt->fNDigit; j++)
370 Int_t cpad = digPt[j].fPad;
371 Int_t ctime = digPt[j].fTime;
372 if(cpad != pad) continue;
373 if(ctime != time) continue;
374 //if(cpad != pad && ctime != ctime) continue;
375 //cout<<"Reading row "<<fCurrentRow<<" pad "<<cpad<<" time "<<ctime<<" trackID "<<digPt[j].fTrackID[0]<<endl;
376 trackID[0] = digPt[j].fTrackID[0];
377 trackID[1] = digPt[j].fTrackID[1];
378 trackID[2] = digPt[j].fTrackID[2];
380 //cout<<"Reading trackID "<<trackID[0]<<endl;