]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ITS/UPGRADE/AliITSUClusterizer.cxx
Increasing the Rmax of the wrapper volumes, to accommodate the IB space frames for...
[u/mrichter/AliRoot.git] / ITS / UPGRADE / AliITSUClusterizer.cxx
CommitLineData
5e375bb4 1#include <TTree.h>
6cae87c5 2#include <TFile.h>
5e375bb4 3#include <TObjArray.h>
4bac12be 4#include <TParticle.h>
5e375bb4 5#include <TMath.h>
4bac12be 6#include "AliRun.h"
7#include "AliMC.h"
5e375bb4 8#include <AliITSUSegmentationPix.h>
b69620f8 9#include "AliITSUClusterizer.h"
5e375bb4 10#include "AliITSUClusterPix.h"
11#include "AliITSUGeomTGeo.h"
12#include "AliITSUSegmentationPix.h"
13#include "AliITSdigit.h"
14#include "AliITSURecoParam.h"
889b1493 15#include "AliITSUAux.h"
5e375bb4 16using namespace TMath;
889b1493 17using namespace AliITSUAux;
b69620f8 18
19ClassImp(AliITSUClusterizer)
20
21//______________________________________________________________________________
22AliITSUClusterizer::AliITSUClusterizer(Int_t initNRow)
23: fVolID(-1)
ee58ce21 24 ,fAllowDiagonalClusterization(kFALSE)
b69620f8 25 ,fSegm(0)
5e375bb4 26 ,fRecoParam(0)
b69620f8 27 ,fInputDigits(0)
28 ,fInputDigitsReadIndex(0)
889b1493 29 ,fLayerID(0)
4bac12be 30 ,fNLabels(0)
31 ,fRawData(kFALSE)
889b1493 32 ,fLorAngCorrection(0)
b69620f8 33 ,fOutputClusters(0)
34 ,fDigitFreelist(0)
35 ,fPartFreelist(0)
36 ,fCandFreelist(0)
37 ,fDigitFreelistBptrFirst(0)
38 ,fDigitFreelistBptrLast(0)
39 ,fPartFreelistBptr(0)
40 ,fCandFreelistBptr(0)
6cae87c5 41#ifdef _ClusterTopology_
42 ,fTreeTopology(0)
43 ,fFileTopology(0)
44 ,fTopology(0)
45 ,fMinCol(0)
46 ,fMinRow(0)
47#endif //_ClusterTopology_
b69620f8 48{
49 SetUniqueID(0);
50 // c-tor
51 SetNRow(initNRow);
52}
53
54//______________________________________________________________________________
55void AliITSUClusterizer::SetSegmentation(const AliITSUSegmentationPix *segm)
56{
57 // attach segmentation, if needed, reinitialize array
58 fSegm = segm;
59 SetNRow(fSegm->GetNRow()); // reinitialize if needed
60
61}
62
63//______________________________________________________________________________
64void AliITSUClusterizer::SetNRow(Int_t nr)
65{
66 // update buffers
67 int nrOld = GetUniqueID();
68 if (nrOld>=nr) return;
69 SetUniqueID(nr);
70 while (fDigitFreelistBptrFirst) {
71 AliITSUClusterizerClusterDigit *next = fDigitFreelistBptrFirst[kDigitChunkSize-1].fNext;
72 delete[] fDigitFreelistBptrFirst;
73 fDigitFreelistBptrFirst=next;
74 }
75 delete[] fPartFreelistBptr;
76 delete[] fCandFreelistBptr;
77 //
78 fPartFreelist=fPartFreelistBptr = new AliITSUClusterizerClusterPart[nr+1];
79 fCandFreelist=fCandFreelistBptr = new AliITSUClusterizerClusterCand[nr+1];
80 for (int i=0;i<nr;++i) {
81 fPartFreelistBptr[i].fNextInRow = &fPartFreelistBptr[i+1];
82 fCandFreelistBptr[i].fNext = &fCandFreelistBptr[i+1];
83 }
84}
85
86//______________________________________________________________________________
87AliITSUClusterizer::~AliITSUClusterizer()
88{
89 // d-tor
90 while (fDigitFreelistBptrFirst) {
91 AliITSUClusterizerClusterDigit *next = fDigitFreelistBptrFirst[kDigitChunkSize-1].fNext;
92 delete[] fDigitFreelistBptrFirst;
93 fDigitFreelistBptrFirst=next;
94 }
95 delete[] fPartFreelistBptr;
96 delete[] fCandFreelistBptr;
6cae87c5 97 //
98#ifdef _ClusterTopology_
99 SaveTopologyTree();
100#endif //_ClusterTopology_
b69620f8 101}
102
103//______________________________________________________________________________
104AliITSUClusterizer::AliITSUClusterizerClusterDigit* AliITSUClusterizer::AllocDigitFreelist()
105{
106 // allocate aux space
107 AliITSUClusterizerClusterDigit *tmp = new AliITSUClusterizerClusterDigit[kDigitChunkSize];
108 for (int i=0;i<kDigitChunkSize-2;++i) tmp[i].fNext=&tmp[i+1];
109 tmp[kDigitChunkSize-2].fNext=0;
110 tmp[kDigitChunkSize-1].fNext=0;
111 if (!fDigitFreelistBptrFirst) fDigitFreelistBptrFirst=tmp;
112 else fDigitFreelistBptrLast[kDigitChunkSize-1].fNext=tmp;
113 fDigitFreelistBptrLast=tmp;
114 return tmp;
115}
116
117//______________________________________________________________________________
118AliITSUClusterizer::AliITSUClusterizerClusterDigit* AliITSUClusterizer::NextDigit()
119{
120 // get next digit
121 if (fInputDigitsReadIndex<fInputDigits->GetEntriesFast()) {
122 AliITSdigit *tmp=static_cast<AliITSdigit*>(fInputDigits->UncheckedAt(fInputDigitsReadIndex++));
123 AliITSUClusterizerClusterDigit *digit=AllocDigit();
124 digit->fDigit=tmp;
b69620f8 125 return digit;
126 }
127 else
128 return 0;
129}
130
131//______________________________________________________________________________
132void AliITSUClusterizer::AttachPartToCand(AliITSUClusterizerClusterCand *cand,AliITSUClusterizerClusterPart *part)
133{
134 // attach part
135 part->fParent = cand;
136 part->fPrevInCluster = 0;
137 part->fNextInCluster = cand->fFirstPart;
138 if (cand->fFirstPart) cand->fFirstPart->fPrevInCluster = part;
139 cand->fFirstPart=part;
140}
141
142//______________________________________________________________________________
143void AliITSUClusterizer::MergeCands(AliITSUClusterizerClusterCand *a,AliITSUClusterizerClusterCand *b)
144{
145 // merge cluster parts
146 AliITSUClusterizerClusterPart *ipart=b->fFirstPart;
147 AliITSUClusterizerClusterPart *jpart;
148 do {
149 jpart=ipart;
150 jpart->fParent=a;
151 } while ((ipart=ipart->fNextInCluster));
152 jpart->fNextInCluster=a->fFirstPart;
153 jpart->fNextInCluster->fPrevInCluster=jpart;
154 a->fFirstPart=b->fFirstPart;
155 // merge digits
156 b->fLastDigit->fNext=a->fFirstDigit;
157 a->fFirstDigit=b->fFirstDigit;
158 // DeallocCand(b);
159}
160
161//______________________________________________________________________________
5e375bb4 162void AliITSUClusterizer::Transform(AliITSUClusterPix *cluster,AliITSUClusterizerClusterCand *cand)
b69620f8 163{
5e375bb4 164 // convert set of digits to cluster data in LOCAL frame
165 const double k1to12 = 1./12;
4bac12be 166 static int maxLbinDigit = AliITSdigit::GetNTracks();
5e375bb4 167 //
4bac12be 168 fNLabels = 0;
b69620f8 169 Int_t n=0;
170 cand->fLastDigit->fNext=0;
5e375bb4 171 double x=0,z=0,xmn=1e9,xmx=-1e9,zmn=1e9,zmx=-1e9,px=0,pz=0;
172 float cx,cz;
29ad4146 173 int charge=0;
6cae87c5 174 //
b69620f8 175 for (AliITSUClusterizerClusterDigit *idigit=cand->fFirstDigit;idigit;idigit=idigit->fNext) {
4bac12be 176 AliITSdigit* dig = idigit->fDigit;
ee58ce21 177 fSegm->DetToLocal(dig->GetCoord2(),dig->GetCoord1(),cx,cz); // center of pixel
178 //
179 // account for possible diod shift
180 double ddx,ddz, dx=fSegm->Dpx(dig->GetCoord2()), dz=fSegm->Dpz(dig->GetCoord1());
181 fSegm->GetDiodShift(dig->GetCoord2(),dig->GetCoord1(),ddx,ddz);
182 //
29ad4146 183 charge += dig->GetSignal();
5e375bb4 184 x += cx;
185 z += cz;
186 if (cx<xmn) xmn=cx;
187 if (cx>xmx) xmx=cx;
188 if (cz<zmn) zmn=cz;
189 if (cz>zmx) zmx=cz;
ee58ce21 190 x += ddx*dx;
191 z += ddz*dz;
192 px += dx;
193 pz += dz;
4bac12be 194 //
195 if (!fRawData) {
196 for(Int_t dlab=0;dlab<maxLbinDigit;dlab++){
197 Int_t digitlab = (dig->GetTracks())[dlab];
198 if(digitlab<0) continue;
199 AddLabel(digitlab);
200 }
201 }
202 //
b69620f8 203 ++n;
204 }
5e375bb4 205 UChar_t nx=1,nz=1;
206 double dx = xmx-xmn, dz = zmx-zmn;
207 if (n>1) {
208 double fac=1./n;
209 x *= fac; // mean coordinates
210 z *= fac;
211 px *= fac; // mean pitch
212 pz *= fac;
213 nx = 1+Nint(dx/px);
214 nz = 1+Nint(dz/pz);
b69620f8 215 }
889b1493 216 x -= fLorAngCorrection; // LorentzAngle correction
b69620f8 217 cluster->SetX(x);
218 cluster->SetZ(z);
5e375bb4 219 cluster->SetY(0);
c8d1f258 220 cluster->SetSigmaZ2(nz>1 ? dz*dz*k1to12 : pz*pz*k1to12);
221 cluster->SetSigmaY2(nx>1 ? dx*dx*k1to12 : px*px*k1to12);
5e375bb4 222 cluster->SetSigmaYZ(0);
223 cluster->SetFrameLoc();
29ad4146 224 cluster->SetNxNzN(nx,nz,n);
225 cluster->SetQ(charge); // note: this is MC info
5e375bb4 226 //
4bac12be 227 if (!fRawData) {
228 CheckLabels();
229 int nl = Min(kMaxLabInCluster,fNLabels);
230 for (int i=nl;i--;) cluster->SetLabel(fCurrLabels[i],i);
231 }
232 //
b69620f8 233 // Set Volume id
234 cluster->SetVolumeId(fVolID);
235 // printf("mod %d: (%.4lf,%.4lf)cm\n",fVolID,x,z);
6cae87c5 236 //
237#ifdef _ClusterTopology_
238 FillClusterTopology(cand);
239#endif //_ClusterTopology_
240 //
b69620f8 241}
242
243//______________________________________________________________________________
244void AliITSUClusterizer::CloseCand(AliITSUClusterizerClusterCand *cand)
245{
246 // finish cluster
5e375bb4 247 AliITSUClusterPix *cluster = (AliITSUClusterPix*)NextCluster();
b69620f8 248 Transform(cluster,cand);
249 DeallocDigits(cand->fFirstDigit,cand->fLastDigit);
250 DeallocCand(cand);
251}
252
253//______________________________________________________________________________
254void AliITSUClusterizer::ClosePart(AliITSUClusterizerClusterPart *part)
255{
256 // finish cluster part
257 AliITSUClusterizerClusterCand *cand=part->fParent;
258 DetachPartFromCand(cand,part);
259 DeallocPart(part);
260 if (!cand->fFirstPart) CloseCand(cand);
261}
262
263//______________________________________________________________________________
264void AliITSUClusterizer::CloseRemainingParts(AliITSUClusterizerClusterPart *part)
265{
266 // finish what is left
267 while (part) {
268 AliITSUClusterizerClusterPart *next=part->fNextInRow;
269 ClosePart(part);
270 part=next;
271 }
272}
273
274//______________________________________________________________________________
275void AliITSUClusterizer::Clusterize()
276{
4bac12be 277 // main algo for MC clustererization
278 SetRawData(kFALSE);
279 //
b69620f8 280 AliITSUClusterizerClusterDigit *iDigit=NextDigit();
281 AliITSUClusterizerClusterPart *iPrevRowBegin=0;
282 AliITSUClusterizerClusterPart *iNextRowBegin=0;
283 AliITSUClusterizerClusterPart *iPrevRow=0;
284 AliITSUClusterizerClusterPart *iNextRow=0;
285 Int_t lastV=0;
6cae87c5 286 //
b69620f8 287 while (iDigit) {
4bac12be 288 if (iDigit->fDigit->GetCoord2()!=lastV) {
b69620f8 289 // NEW ROW
290 if (iNextRow) iNextRow->fNextInRow=0;
291 if (iPrevRowBegin) CloseRemainingParts(iPrevRowBegin);
4bac12be 292 if (iDigit->fDigit->GetCoord2()==lastV+1) {
b69620f8 293 iPrevRowBegin=iNextRowBegin;
294 iPrevRow =iNextRowBegin;
295 }
296 else {
297 // there was an empty row
298 CloseRemainingParts(iNextRowBegin);
299 iPrevRowBegin=0;
300 iPrevRow =0;
301 }
302 iNextRowBegin=0;
303 iNextRow =0;
4bac12be 304 lastV=iDigit->fDigit->GetCoord2();
b69620f8 305 }
306 // skip cluster parts before this digit
ee58ce21 307 int limCol = iDigit->fDigit->GetCoord1()-fAllowDiagonalClusterization;
308 while (iPrevRow && iPrevRow->fUEnd < limCol) {
b69620f8 309 iPrevRow=iPrevRow->fNextInRow;
310 }
311 // find the longest continous line of digits [iDigit,pDigit]=[iDigit,jDigit)
312 AliITSUClusterizerClusterCand *cand=AllocCand();
313 AliITSUClusterizerClusterDigit *pDigit=iDigit;
314 AliITSUClusterizerClusterDigit *jDigit=NextDigit();
315 cand->fFirstPart=0;
316 cand->fFirstDigit=cand->fLastDigit=iDigit; // NB: first diggit is attached differently
317 iDigit->fNext=0;
4bac12be 318 Int_t lastU =iDigit->fDigit->GetCoord1();
b69620f8 319 Int_t lastU1=lastU+1;
4bac12be 320 while (jDigit && jDigit->fDigit->GetCoord1()==lastU1 && jDigit->fDigit->GetCoord2()==lastV) {
b69620f8 321 pDigit=jDigit;
322 jDigit=NextDigit();
323 AttachDigitToCand(cand,pDigit);
324 ++lastU1;
325 }
ee58ce21 326 if (!fAllowDiagonalClusterization) --lastU1;
b69620f8 327 AliITSUClusterizerClusterPart *part=AllocPart();
328 part->fUBegin=lastU ;
329 part->fUEnd =lastU1;
330 AttachPartToCand(cand,part);
331 // merge all cluster candidates of the previous line touching this one,
332 // advance to the last one, but keep that one the next active one
333 AliITSUClusterizerClusterPart *jPrevRow=iPrevRow;
334 while (jPrevRow && jPrevRow->fUBegin<=lastU1) {
335 if (jPrevRow->fParent!=cand) {
336 MergeCands(jPrevRow->fParent,cand);
337 DeallocCand(cand);
338 cand=jPrevRow->fParent;
339 }
340 iPrevRow=jPrevRow;
341 jPrevRow=jPrevRow->fNextInRow;
342 }
343 if (iNextRow)
344 iNextRow->fNextInRow=part;
345 else
346 iNextRowBegin=part;
347 iNextRow=part;
348 iDigit=jDigit;
349 }
350 // remove remaining cluster parts
351 CloseRemainingParts(iPrevRowBegin);
352 if (iNextRow) iNextRow->fNextInRow=0;
353 CloseRemainingParts(iNextRowBegin);
354 return;
355}
889b1493 356
357//______________________________________________________________________________
358void AliITSUClusterizer::PrepareLorentzAngleCorrection(Double_t bz)
359{
360 // calculate parameters for Lorentz Angle correction. Must be called
361 // after setting segmentation and recoparams
362 fLorAngCorrection = 0.5*fRecoParam->GetTanLorentzAngle(fLayerID)*bz/kNominalBz*fSegm->Dy();
363}
4bac12be 364
365//______________________________________________________________________
366void AliITSUClusterizer::CheckLabels()
367{
368 // Tries to find mother's labels
369 //
370 if (fNLabels<1) return;
371 AliRunLoader *rl = AliRunLoader::Instance();
372 if(!rl) return;
373 TTree *trK=(TTree*)rl->TreeK();
374 if (!trK) return;
375 //
376 static int labS[kMaxLabels];
377 static float kine[kMaxLabels];
378 Int_t nlabels = fNLabels;
379 Int_t ntracks = gAlice->GetMCApp()->GetNtrack();
380 for (Int_t i=fNLabels;i--;) labS[i] = fCurrLabels[i];
381 //
382 for (Int_t i=0;i<nlabels;i++) {
383 Int_t label = labS[i];
384 if (label>=ntracks) continue;
385 TParticle *part=(TParticle*)gAlice->GetMCApp()->Particle(label);
386 kine[i] = part->Energy() - part->GetCalcMass(); // kinetic energy
387 if (kine[i] < 0.02) { // reduce soft particles from the same cluster
388 Int_t m=part->GetFirstMother();
389 if (m<0) continue; // primary
390 //
391 if (part->GetStatusCode()>0) continue;
392 //
393 // if the parent is within the same cluster, assign parent's label
394 for (int j=0;j<nlabels;j++) if (labS[j]==m) { labS[i] = m; break;}
395 }
396 }
397 //
398 if (nlabels>kMaxLabInCluster) { // only 3 labels are stored in cluster, sort in decreasing momentum
399 static int ind[kMaxLabels],labSS[kMaxLabels];
400 TMath::Sort(nlabels,kine,ind);
401 for (int i=nlabels;i--;) labSS[i] = labS[i];
402 for (int i=nlabels;i--;) labS[i] = labSS[ind[i]];
403 }
404 //
405 //compress labels -- if multi-times the same
406 for (Int_t i=0;i<nlabels;i++) fCurrLabels[i]=-2;
407 fNLabels = 0;
408 int j=0;
409 for (int i=0;i<nlabels;i++) {
410 for (j=fNLabels;j--;) if (labS[i]==fCurrLabels[j]) break; // the label already there
411 if (j<0) fCurrLabels[fNLabels++] = labS[i];
412 }
413 //
414}
6cae87c5 415
416//------------------------------------------------------------------------
417
418#ifdef _ClusterTopology_
419//
420//______________________________________________________________________
421void AliITSUClusterizer::FillClusterTopology(AliITSUClusterizerClusterCand *cand)
422{
423 // fill special tree with cluster topology bit pattern
424 //
425 enum {kMaxColSpan=30,kMaxRowSpan=30};
426 //
427 Int_t mnCol=999999,mxCol=0,mnRow=999999,mxRow=0;
428 for (AliITSUClusterizerClusterDigit *idigit=cand->fFirstDigit;idigit;idigit=idigit->fNext) {
429 AliITSdigit* dig = idigit->fDigit;
430 if (mnCol>dig->GetCoord1()) mnCol = dig->GetCoord1();
431 if (mxCol<dig->GetCoord1()) mxCol = dig->GetCoord1();
432 if (mnRow>dig->GetCoord2()) mnRow = dig->GetCoord2();
433 if (mxRow<dig->GetCoord2()) mxRow = dig->GetCoord2();
434 }
435 int nColSpan = mxCol-mnCol+1;
436 int nRowSpan = mxRow-mnRow+1;
437 if (nColSpan<kMaxColSpan && nRowSpan<kMaxRowSpan) {
438 fTopology.Clear();
439 fTopology.SetBitNumber(nColSpan*nRowSpan-1,kFALSE); // set the size
440 fTopology.SetUniqueID( (nRowSpan<<8) + nColSpan );
441 for (AliITSUClusterizerClusterDigit *idigit=cand->fFirstDigit;idigit;idigit=idigit->fNext) {
442 AliITSdigit* dig = idigit->fDigit;
443 fTopology.SetBitNumber( (dig->GetCoord2()-mnRow)*nColSpan + (dig->GetCoord1()-mnCol) );
444 }
445 if (!fTreeTopology) InitTopologyTree();
446 AliInfo(Form("Fill Topology, lr %d",fLayerID));
447 fMinCol = mnCol;
448 fMinRow = mnRow;
449 fTreeTopology->Fill();
450 }
451 //
452}
453
454//______________________________________________________________________
455void AliITSUClusterizer::InitTopologyTree()
456{
457 // create output tree for the topology stydy
458 if (fFileTopology || fTreeTopology) AliFatal("Topology structures are already created");
459 TDirectory* cdr = gDirectory;
460 fFileTopology = TFile::Open("clusterTopology.root","recreate");
461 fFileTopology->cd();
462 fTreeTopology = new TTree("clTop","ClusterTopology");
463 fTreeTopology->Branch("tp","TBits",&fTopology);
464 fTreeTopology->Branch("volID",&fVolID);
465 fTreeTopology->Branch("mnCol",&fMinCol);
466 fTreeTopology->Branch("mnRow",&fMinRow);
467 cdr->cd();
468}
469
470//______________________________________________________________________
471void AliITSUClusterizer::SaveTopologyTree()
472{
473 // write output tree for the topology stydy
474 AliInfo("Storing cluster topology tree");
475 if (!fFileTopology || !fTreeTopology) {AliError("Topology structures are not created"); return;}
476 fFileTopology->cd();
477 fTreeTopology->Write();
478 delete fTreeTopology;
479 fFileTopology->Close();
480 delete fFileTopology;
481 fTreeTopology = 0;
482 fFileTopology = 0;
483}
484
485#endif //_ClusterTopology_