1 //*-- Author : Anders Strand Vestbo <mailto:vestbo@fi.uib.no>
3 //*-- Copyright © ASV
7 #include "AliL3Logging.h"
8 #include "AliL3ClustFinder.h"
9 #include "AliL3Transform.h"
10 #include "AliL3DigitData.h"
11 #include "AliL3SpacePointData.h"
18 ClassImp(AliL3ClustFinder)
20 AliL3ClustFinder::AliL3ClustFinder()
29 AliL3ClustFinder::AliL3ClustFinder(AliL3Transform *transform)
32 fTransform = transform;
40 AliL3ClustFinder::~AliL3ClustFinder()
46 void AliL3ClustFinder::SetTransformer( AliL3Transform *transform )
48 fTransform = transform;
52 void AliL3ClustFinder::InitSlice(Int_t slice,Int_t patch,Int_t firstrow, Int_t lastrow,Int_t nmaxpoints)
55 fMaxNClusters = nmaxpoints;
56 fCurrentSlice = slice;
57 fCurrentPatch = patch;
63 void AliL3ClustFinder::InitSlice(Int_t slice,Int_t patch,Int_t nmaxpoints)
66 fMaxNClusters = nmaxpoints;
67 fCurrentSlice = slice;
68 fCurrentPatch = patch;
71 void AliL3ClustFinder::SetOutputArray(AliL3SpacePointData *pt)
77 void AliL3ClustFinder::Read(UInt_t ndigits,AliL3DigitRowData *ptr)
79 fNDigitRowData = ndigits;
84 void AliL3ClustFinder::ProcessDigits()
86 //Loop over rows, and call processrow
89 AliL3DigitRowData *tempPt = (AliL3DigitRowData*)fDigitRowData;
91 for(Int_t i=fFirstRow; i<=fLastRow; i++)
95 Byte_t *tmp = (Byte_t*)tempPt;
96 Int_t size = sizeof(AliL3DigitRowData) + tempPt->fNDigit*sizeof(AliL3DigitData);
98 tempPt = (AliL3DigitRowData*)tmp;
101 LOG(AliL3Log::kInformational,"AliL3ClustFinder","Cluster Finder")
102 <<AliL3Log::kDec<<"ClusterFinder found "<<fNClusters<<" clusters"<<ENDLOG;
105 void AliL3ClustFinder::ProcessRow(AliL3DigitRowData* tempPt)
108 Int_t cl_found,trackID[3];
111 //Reserve array for found clusters:
113 bzero((char *)aliresx,5000*sizeof(resx));
117 // UInt_t pres1[2500],pres2[2500];
121 resx *rr = &rr_local;
123 //Set variables for each row:
124 Int_t pres_cou1,pres_cou2;
127 pres_cou1=pres_cou2=0;
132 //variables for each pad:
136 Int_t cl_counter=0,rows;
139 UInt_t last_pad = 123456789;
141 //Loop over digits in this row:
142 for(start=0; start<tempPt->fNDigit; start++)
144 AliL3DigitData *bins = tempPt->fDigitData;
146 if(bins[start].fPad!=last_pad)
149 last_pad=bins[start].fPad;
175 Int_t last_falling=0;
184 if(cl_counter>MAX_C) {LOG(AliL3Log::kWarning,"AliL3ClustFinder::ProcessRow","Cluster Finder")
185 <<AliL3Log::kDec<<"Too many clusters"<<ENDLOG; return;} //too many clusters
191 //this is a goto label:
193 //divide sequenz in two in case there is a change in slope:
203 //ok, create a new cluster:
209 last_falling=flags=0;
218 //block to introduce new variables:
223 //Loop over this sequenz:
227 //Int_t start_temp=start;
230 aa=bins[start].fCharge;
235 //Check if the last pixel in this sequenz is bigger or smaller than this:
248 //sum of total charge of this cluster on this pad
250 //this one is needed to determine the mean over all pads:
251 //av += start * (aa);
252 av+=bins[start].fTime*(aa);
254 if((bins[start+1].fTime)!=(bins[start].fTime+1) ||
255 ((bins[start+1].fPad)!=(bins[start].fPad))) break;
259 }//block of new variables
263 if(start_new>0) flags = FLAG_DOUBLE_T;
265 //calculate mean in time direction for this sequenz:
268 //mean=cog for this sequenz:
276 //get the pointer to results on previous pad(s)
279 //Center of gravity in pad direction
280 //tmp_charge=charge*bins[start-1].fPad;
281 tmp_charge=charge*bins[start].fPad;
283 //compare with prevously stored results (previous pads)
284 for(int k=0; k<pres_cou1; k++)
286 //variable to store difference:
289 //structure that contains means (+more) of last pads(s)
293 rr_tmp = (resx *) *ri;
295 //difference between mean and mean on previous pads
301 //goto next mean on previous pad
304 //is there a matching cluster on previous pad:
307 //ok, we got a new one, so we will add the new and the old
310 //Add this function somewhere
311 memcpy7((UInt_t *)rr,(UInt_t *)rr_tmp);
313 /* in case we found another sequenz-section on this pad
314 don't loop over all sequenzes on last pad but start
315 where we found a matching candidate for this sequenz-
316 section, adjust upper limit (=pres_cou1)*/
322 if(charge>rr->scharge)
326 //previous state was falling
327 flags |= FLAG_DOUBLE_PAD;
328 rr_tmp->flags |= flags;
329 //and create a new one
339 //don't create a new one
342 //store the pointer to the matched in "2"
343 // r2[pres_cou2++] = (UInt_t) rr_tmp;
344 r2[pres_cou2++] = rr_tmp;
346 //calculate and fill the new means, charge etc. in rr_tmp
347 //charge on this pad to determine whether we cut in pad direction
348 rr->scharge = charge;
349 //unset FLAG_ONEPAD since we have at least 2 pads
350 rr->flags &= (~FLAG_ONEPAD);
351 //summ the charges for de/dx
352 rr->charge += charge;
353 //calculate mean in pad direction
354 rr->pad += tmp_charge;
355 //calculate mean in time direction
357 //store the mean of this sequenz on this pad
360 //Copy it back to storage
361 memcpy7((UInt_t *)rr_tmp,(UInt_t *)rr);
363 //we found a matching one so stop looping over pads on previous pad
366 }//matching cluster on previous pads
367 }//loop: means on previous pad
369 //here we create from scratch new clusters
372 //store this one beacuse it is the first
373 // r2[pres_cou2++]= (UInt_t )r;
376 mstore((UInt_t *)r,av,tmp_charge,charge,flags|FLAG_ONEPAD,mean,trackID);
383 //maybe we still have to do something
384 if(start_new>=0) goto redo;
387 }//end of loop over digits
390 //number of clusters found
391 cl_found = r-aliresx;
393 //tot_cl_found+=cl_found;
395 //there was something on this padrow
398 WriteClusters(cl_found,aliresx);
402 void AliL3ClustFinder::memcpy7(UInt_t *dst, UInt_t *src)
412 void AliL3ClustFinder::mstore(UInt_t *r,UInt_t av,UInt_t pad,UInt_t ch,UInt_t flags,UInt_t mean,Int_t *trackID)
414 resx *rr = (resx *) r;
424 rr->trackID[0]=trackID[0];
425 rr->trackID[1]=trackID[1];
426 rr->trackID[2]=trackID[2];
430 void AliL3ClustFinder::WriteClusters(Int_t ncl,resx *r)
433 if(fNClusters >= fMaxNClusters)
435 LOG(AliL3Log::kError,"AliL3ClustFinder::WriteClusters","Cluster Finder")
436 <<AliL3Log::kDec<<"Too many clusters"<<ENDLOG;
440 Int_t thisrow,thissector;
441 UInt_t counter = fNClusters;
443 if(!fXYErr || !fZErr)
445 LOG(AliL3Log::kError,"AliL3ClustFinder::WriteClusters","Cluster Errors")
446 <<"No Errors"<<ENDLOG;
450 for(int j=0; j<ncl; j++)
452 if(r[j].flags & FLAG_ONEPAD) continue; //discard 1 pad clusters
453 if(r[j].charge < fThreshold) continue; //noise cluster
456 Float_t fpad=(Float_t)r[j].pad/(Float_t)r[j].charge;
457 Float_t ftime=(Float_t)r[j].t/(Float_t)r[j].charge;
459 fTransform->Slice2Sector(fCurrentSlice,fCurrentRow,thissector,thisrow);
460 //if(fCurrentRow > 54) {thisrow = fCurrentRow-55; thissector = fCurrentSlice+36;}
461 //else {thisrow = fCurrentRow; thissector = fCurrentSlice;}
462 fTransform->Raw2Local(xyz,thissector,thisrow,fpad,ftime);
463 if(xyz[0]==0) LOG(AliL3Log::kError,"AliL3ClustFinder","Cluster Finder")
464 <<AliL3Log::kDec<<"Zero cluster"<<ENDLOG;
465 if(fNClusters >= fMaxNClusters)
467 LOG(AliL3Log::kError,"AliL3ClustFinder::WriteClusters","Cluster Finder")
468 <<AliL3Log::kDec<<"Too many clusters"<<ENDLOG;
471 fSpacePointData[counter].fX = xyz[0];
472 fSpacePointData[counter].fY = xyz[1];
473 fSpacePointData[counter].fZ = xyz[2];
474 fSpacePointData[counter].fPadRow = fCurrentRow;
475 fSpacePointData[counter].fXYErr = fXYErr;
476 fSpacePointData[counter].fZErr = fZErr;
477 fSpacePointData[counter].fID = counter
478 +((fCurrentSlice&0x7f)<<25)+((fCurrentPatch&0x7)<<22);