7 #include <AliITSUSegmentationPix.h>
8 #include "AliITSUClusterizer.h"
9 #include "AliITSUClusterPix.h"
10 #include "AliITSUGeomTGeo.h"
11 #include "AliITSUSegmentationPix.h"
12 #include "AliITSdigit.h"
13 #include "AliITSURecoParam.h"
14 #include "AliITSUAux.h"
15 using namespace TMath;
16 using namespace AliITSUAux;
18 ClassImp(AliITSUClusterizer)
20 //______________________________________________________________________________
21 AliITSUClusterizer::AliITSUClusterizer(Int_t initNRow)
23 ,fAllowDiagonalClusterization(kFALSE)
27 ,fInputDigitsReadIndex(0)
36 ,fDigitFreelistBptrFirst(0)
37 ,fDigitFreelistBptrLast(0)
46 //______________________________________________________________________________
47 void AliITSUClusterizer::SetSegmentation(const AliITSUSegmentationPix *segm)
49 // attach segmentation, if needed, reinitialize array
51 SetNRow(fSegm->GetNRow()); // reinitialize if needed
55 //______________________________________________________________________________
56 void AliITSUClusterizer::SetNRow(Int_t nr)
59 int nrOld = GetUniqueID();
60 if (nrOld>=nr) return;
62 while (fDigitFreelistBptrFirst) {
63 AliITSUClusterizerClusterDigit *next = fDigitFreelistBptrFirst[kDigitChunkSize-1].fNext;
64 delete[] fDigitFreelistBptrFirst;
65 fDigitFreelistBptrFirst=next;
67 delete[] fPartFreelistBptr;
68 delete[] fCandFreelistBptr;
70 fPartFreelist=fPartFreelistBptr = new AliITSUClusterizerClusterPart[nr+1];
71 fCandFreelist=fCandFreelistBptr = new AliITSUClusterizerClusterCand[nr+1];
72 for (int i=0;i<nr;++i) {
73 fPartFreelistBptr[i].fNextInRow = &fPartFreelistBptr[i+1];
74 fCandFreelistBptr[i].fNext = &fCandFreelistBptr[i+1];
78 //______________________________________________________________________________
79 AliITSUClusterizer::~AliITSUClusterizer()
82 while (fDigitFreelistBptrFirst) {
83 AliITSUClusterizerClusterDigit *next = fDigitFreelistBptrFirst[kDigitChunkSize-1].fNext;
84 delete[] fDigitFreelistBptrFirst;
85 fDigitFreelistBptrFirst=next;
87 delete[] fPartFreelistBptr;
88 delete[] fCandFreelistBptr;
91 //______________________________________________________________________________
92 AliITSUClusterizer::AliITSUClusterizerClusterDigit* AliITSUClusterizer::AllocDigitFreelist()
95 AliITSUClusterizerClusterDigit *tmp = new AliITSUClusterizerClusterDigit[kDigitChunkSize];
96 for (int i=0;i<kDigitChunkSize-2;++i) tmp[i].fNext=&tmp[i+1];
97 tmp[kDigitChunkSize-2].fNext=0;
98 tmp[kDigitChunkSize-1].fNext=0;
99 if (!fDigitFreelistBptrFirst) fDigitFreelistBptrFirst=tmp;
100 else fDigitFreelistBptrLast[kDigitChunkSize-1].fNext=tmp;
101 fDigitFreelistBptrLast=tmp;
105 //______________________________________________________________________________
106 AliITSUClusterizer::AliITSUClusterizerClusterDigit* AliITSUClusterizer::NextDigit()
109 if (fInputDigitsReadIndex<fInputDigits->GetEntriesFast()) {
110 AliITSdigit *tmp=static_cast<AliITSdigit*>(fInputDigits->UncheckedAt(fInputDigitsReadIndex++));
111 AliITSUClusterizerClusterDigit *digit=AllocDigit();
119 //______________________________________________________________________________
120 void AliITSUClusterizer::AttachPartToCand(AliITSUClusterizerClusterCand *cand,AliITSUClusterizerClusterPart *part)
123 part->fParent = cand;
124 part->fPrevInCluster = 0;
125 part->fNextInCluster = cand->fFirstPart;
126 if (cand->fFirstPart) cand->fFirstPart->fPrevInCluster = part;
127 cand->fFirstPart=part;
130 //______________________________________________________________________________
131 void AliITSUClusterizer::MergeCands(AliITSUClusterizerClusterCand *a,AliITSUClusterizerClusterCand *b)
133 // merge cluster parts
134 AliITSUClusterizerClusterPart *ipart=b->fFirstPart;
135 AliITSUClusterizerClusterPart *jpart;
139 } while ((ipart=ipart->fNextInCluster));
140 jpart->fNextInCluster=a->fFirstPart;
141 jpart->fNextInCluster->fPrevInCluster=jpart;
142 a->fFirstPart=b->fFirstPart;
144 b->fLastDigit->fNext=a->fFirstDigit;
145 a->fFirstDigit=b->fFirstDigit;
149 //______________________________________________________________________________
150 void AliITSUClusterizer::Transform(AliITSUClusterPix *cluster,AliITSUClusterizerClusterCand *cand)
152 // convert set of digits to cluster data in LOCAL frame
153 const double k1to12 = 1./12;
154 static int maxLbinDigit = AliITSdigit::GetNTracks();
158 cand->fLastDigit->fNext=0;
159 double x=0,z=0,xmn=1e9,xmx=-1e9,zmn=1e9,zmx=-1e9,px=0,pz=0;
162 for (AliITSUClusterizerClusterDigit *idigit=cand->fFirstDigit;idigit;idigit=idigit->fNext) {
163 AliITSdigit* dig = idigit->fDigit;
164 fSegm->DetToLocal(dig->GetCoord2(),dig->GetCoord1(),cx,cz); // center of pixel
166 // account for possible diod shift
167 double ddx,ddz, dx=fSegm->Dpx(dig->GetCoord2()), dz=fSegm->Dpz(dig->GetCoord1());
168 fSegm->GetDiodShift(dig->GetCoord2(),dig->GetCoord1(),ddx,ddz);
170 charge += dig->GetSignal();
183 for(Int_t dlab=0;dlab<maxLbinDigit;dlab++){
184 Int_t digitlab = (dig->GetTracks())[dlab];
185 if(digitlab<0) continue;
193 double dx = xmx-xmn, dz = zmx-zmn;
196 x *= fac; // mean coordinates
198 px *= fac; // mean pitch
203 x -= fLorAngCorrection; // LorentzAngle correction
207 cluster->SetSigmaZ2(nz>1 ? dz*dz*k1to12 : pz*pz*k1to12);
208 cluster->SetSigmaY2(nx>1 ? dx*dx*k1to12 : px*px*k1to12);
209 cluster->SetSigmaYZ(0);
210 cluster->SetFrameLoc();
211 cluster->SetNxNzN(nx,nz,n);
212 cluster->SetQ(charge); // note: this is MC info
216 int nl = Min(kMaxLabInCluster,fNLabels);
217 for (int i=nl;i--;) cluster->SetLabel(fCurrLabels[i],i);
221 cluster->SetVolumeId(fVolID);
222 // printf("mod %d: (%.4lf,%.4lf)cm\n",fVolID,x,z);
225 //______________________________________________________________________________
226 void AliITSUClusterizer::CloseCand(AliITSUClusterizerClusterCand *cand)
229 AliITSUClusterPix *cluster = (AliITSUClusterPix*)NextCluster();
230 Transform(cluster,cand);
231 DeallocDigits(cand->fFirstDigit,cand->fLastDigit);
235 //______________________________________________________________________________
236 void AliITSUClusterizer::ClosePart(AliITSUClusterizerClusterPart *part)
238 // finish cluster part
239 AliITSUClusterizerClusterCand *cand=part->fParent;
240 DetachPartFromCand(cand,part);
242 if (!cand->fFirstPart) CloseCand(cand);
245 //______________________________________________________________________________
246 void AliITSUClusterizer::CloseRemainingParts(AliITSUClusterizerClusterPart *part)
248 // finish what is left
250 AliITSUClusterizerClusterPart *next=part->fNextInRow;
256 //______________________________________________________________________________
257 void AliITSUClusterizer::Clusterize()
259 // main algo for MC clustererization
262 AliITSUClusterizerClusterDigit *iDigit=NextDigit();
263 AliITSUClusterizerClusterPart *iPrevRowBegin=0;
264 AliITSUClusterizerClusterPart *iNextRowBegin=0;
265 AliITSUClusterizerClusterPart *iPrevRow=0;
266 AliITSUClusterizerClusterPart *iNextRow=0;
269 if (iDigit->fDigit->GetCoord2()!=lastV) {
271 if (iNextRow) iNextRow->fNextInRow=0;
272 if (iPrevRowBegin) CloseRemainingParts(iPrevRowBegin);
273 if (iDigit->fDigit->GetCoord2()==lastV+1) {
274 iPrevRowBegin=iNextRowBegin;
275 iPrevRow =iNextRowBegin;
278 // there was an empty row
279 CloseRemainingParts(iNextRowBegin);
285 lastV=iDigit->fDigit->GetCoord2();
287 // skip cluster parts before this digit
288 int limCol = iDigit->fDigit->GetCoord1()-fAllowDiagonalClusterization;
289 while (iPrevRow && iPrevRow->fUEnd < limCol) {
290 iPrevRow=iPrevRow->fNextInRow;
292 // find the longest continous line of digits [iDigit,pDigit]=[iDigit,jDigit)
293 AliITSUClusterizerClusterCand *cand=AllocCand();
294 AliITSUClusterizerClusterDigit *pDigit=iDigit;
295 AliITSUClusterizerClusterDigit *jDigit=NextDigit();
297 cand->fFirstDigit=cand->fLastDigit=iDigit; // NB: first diggit is attached differently
299 Int_t lastU =iDigit->fDigit->GetCoord1();
300 Int_t lastU1=lastU+1;
301 while (jDigit && jDigit->fDigit->GetCoord1()==lastU1 && jDigit->fDigit->GetCoord2()==lastV) {
304 AttachDigitToCand(cand,pDigit);
307 if (!fAllowDiagonalClusterization) --lastU1;
308 AliITSUClusterizerClusterPart *part=AllocPart();
309 part->fUBegin=lastU ;
311 AttachPartToCand(cand,part);
312 // merge all cluster candidates of the previous line touching this one,
313 // advance to the last one, but keep that one the next active one
314 AliITSUClusterizerClusterPart *jPrevRow=iPrevRow;
315 while (jPrevRow && jPrevRow->fUBegin<=lastU1) {
316 if (jPrevRow->fParent!=cand) {
317 MergeCands(jPrevRow->fParent,cand);
319 cand=jPrevRow->fParent;
322 jPrevRow=jPrevRow->fNextInRow;
325 iNextRow->fNextInRow=part;
331 // remove remaining cluster parts
332 CloseRemainingParts(iPrevRowBegin);
333 if (iNextRow) iNextRow->fNextInRow=0;
334 CloseRemainingParts(iNextRowBegin);
338 //______________________________________________________________________________
339 void AliITSUClusterizer::PrepareLorentzAngleCorrection(Double_t bz)
341 // calculate parameters for Lorentz Angle correction. Must be called
342 // after setting segmentation and recoparams
343 fLorAngCorrection = 0.5*fRecoParam->GetTanLorentzAngle(fLayerID)*bz/kNominalBz*fSegm->Dy();
346 //______________________________________________________________________
347 void AliITSUClusterizer::CheckLabels()
349 // Tries to find mother's labels
351 if (fNLabels<1) return;
352 AliRunLoader *rl = AliRunLoader::Instance();
354 TTree *trK=(TTree*)rl->TreeK();
357 static int labS[kMaxLabels];
358 static float kine[kMaxLabels];
359 Int_t nlabels = fNLabels;
360 Int_t ntracks = gAlice->GetMCApp()->GetNtrack();
361 for (Int_t i=fNLabels;i--;) labS[i] = fCurrLabels[i];
363 for (Int_t i=0;i<nlabels;i++) {
364 Int_t label = labS[i];
365 if (label>=ntracks) continue;
366 TParticle *part=(TParticle*)gAlice->GetMCApp()->Particle(label);
367 kine[i] = part->Energy() - part->GetCalcMass(); // kinetic energy
368 if (kine[i] < 0.02) { // reduce soft particles from the same cluster
369 Int_t m=part->GetFirstMother();
370 if (m<0) continue; // primary
372 if (part->GetStatusCode()>0) continue;
374 // if the parent is within the same cluster, assign parent's label
375 for (int j=0;j<nlabels;j++) if (labS[j]==m) { labS[i] = m; break;}
379 if (nlabels>kMaxLabInCluster) { // only 3 labels are stored in cluster, sort in decreasing momentum
380 static int ind[kMaxLabels],labSS[kMaxLabels];
381 TMath::Sort(nlabels,kine,ind);
382 for (int i=nlabels;i--;) labSS[i] = labS[i];
383 for (int i=nlabels;i--;) labS[i] = labSS[ind[i]];
386 //compress labels -- if multi-times the same
387 for (Int_t i=0;i<nlabels;i++) fCurrLabels[i]=-2;
390 for (int i=0;i<nlabels;i++) {
391 for (j=fNLabels;j--;) if (labS[i]==fCurrLabels[j]) break; // the label already there
392 if (j<0) fCurrLabels[fNLabels++] = labS[i];