1 #include <TClonesArray.h>
2 #include "AliITSURecoLayer.h"
3 #include "AliITSUGeomTGeo.h"
4 #include "AliITSsegmentation.h"
5 #include "AliITSUAux.h"
6 #include "AliITSUClusterPix.h"
8 using namespace AliITSUAux;
11 ClassImp(AliITSURecoLayer)
14 //______________________________________________________
15 AliITSURecoLayer::AliITSURecoLayer(const char* name)
36 SetNameTitle(name,name);
39 //______________________________________________________
40 AliITSURecoLayer::AliITSURecoLayer(const char* name, Int_t activeID, AliITSUGeomTGeo* gm)
61 SetNameTitle(name,name);
65 //______________________________________________________
66 AliITSURecoLayer::~AliITSURecoLayer()
74 //______________________________________________________
75 void AliITSURecoLayer::Print(Option_t* opt) const
78 printf("Lr %-15s %d (act:%+d), NSens: %4d | MaxStep:%.2f ",GetName(),GetID(),GetActiveID(),GetNSensors(),fMaxStep);
79 printf("%6.3f<R<%6.3f | %+8.3f<Z<%+8.3f dZ:%6.3f\n",fRMin,fRMax,fZMin,fZMax,fSensDZInv>0 ? 1/fSensDZInv : 0);
80 TString opts = opt; opts.ToLower();
81 if (opts.Contains("sn")) for (int i=0;i<GetNSensors();i++) GetSensor(i)->Print(opt);
84 //______________________________________________________
85 void AliITSURecoLayer::Build()
87 // build internal structures
88 if (fActiveID<0) return;
89 fNLadders = fITSGeom->GetNLadders(fActiveID);
90 fNSensInLadder = fITSGeom->GetNDetectors(fActiveID);
91 fNSensors = fNLadders*fNSensInLadder;
92 fSensors = new AliITSURecoSens*[fNSensors];
93 const AliITSsegmentation* kSegm = fITSGeom->GetSegmentation(fActiveID);
95 // name layer according its active id, detector type and segmentation tyoe
97 const TGeoHMatrix* mt2l;
100 double phiTF,rTF, loc[3]={0,0,0},glo[3];
102 fPhiLadMin = new Double_t[fNLadders];
103 fPhiLadMax = new Double_t[fNLadders];
105 fDPhiLadInv = fNLadders/TwoPi();
107 for (int ild=0;ild<fNLadders;ild++) {
108 fPhiLadMin[ild] = 1e9;
109 fPhiLadMax[ild] = -1e9;
111 for (int idt=0;idt<fNSensInLadder;idt++) {
112 AliITSURecoSens* sens = new AliITSURecoSens(fNSensors++);
113 fSensors[ild*fNSensInLadder+idt] = sens;
115 double phiMin=1e9,phiMax=-1e9,zMin=1e9,zMax=-1e9;
116 mmod = *fITSGeom->GetMatrix(fActiveID,ild,idt);
117 for (int ix=0;ix<2;ix++) {
118 loc[0] = (ix-0.5)*kSegm->Dx(); // +-DX/2
119 for (int iy=0;iy<2;iy++) {
120 loc[1] = (iy-0.5)*kSegm->Dy(); // +-DY/2
121 for (int iz=0;iz<2;iz++) {
122 loc[2] = (iz-0.5)*kSegm->Dz(); // +-DZ/2
124 mmod.LocalToMaster(loc,glo);
125 double phi = ATan2(glo[1],glo[0]);
126 double r = glo[0]*glo[0] + glo[1]*glo[1];
127 if (fRMin>r) fRMin = r;
128 if (fRMax<r) fRMax = r;
130 if (phiMin>1e8) phiMin=phi;
131 else if (!OKforPhiMin(phiMin,phi)) phiMin=phi;
132 if (phiMax<-1e8) phiMax=phi;
133 else if (!OKforPhiMax(phiMax,phi)) phiMax=phi;
134 if (glo[2]>zMax) zMax=glo[2];
135 if (glo[2]<zMin) zMin=glo[2];
139 sens->SetBoundaries(phiMin,phiMax,zMin,zMax);
140 mt2l = fITSGeom->GetMatrixT2L(fActiveID,ild,idt);
142 loc[0]=loc[1]=loc[2]=0;
143 mmod.LocalToMaster(loc,glo);
144 rTF = Sqrt(glo[0]*glo[0] + glo[1]*glo[1]); // tracking params (misaligned)
145 phiTF = ATan2(glo[1],glo[0]);
149 sens->SetPhiTF(phiTF);
151 if (fPhiLadMin[ild]>1e8) fPhiLadMin[ild] = phiMin;
152 else if (!OKforPhiMin(fPhiLadMin[ild],phiMin)) fPhiLadMin[ild] = phiMin;
153 if (fPhiLadMax[ild]<-1e8) fPhiLadMax[ild] = phiMax;
154 else if (!OKforPhiMax(fPhiLadMax[ild],phiMax)) fPhiLadMax[ild] = phiMax;
155 if (fZMin>zMin) fZMin = zMin;
156 if (fZMax<zMax) fZMax = zMax;
158 if (idt>0) fSensDZInv += zMax - GetSensor(ild,idt-1)->GetZMax(); // z interval to previous
164 fR = 0.5*(fRMin+fRMax);
165 double dz = fNSensInLadder>0 ? fSensDZInv/(fNSensInLadder-1)/fNLadders : fZMax-fZMin;
168 const int kNBId[3][3] = {
169 {AliITSURecoSens::kNghbBL,AliITSURecoSens::kNghbB,AliITSURecoSens::kNghbBR},
170 {AliITSURecoSens::kNghbL, -1 ,AliITSURecoSens::kNghbR },
171 {AliITSURecoSens::kNghbTL,AliITSURecoSens::kNghbT,AliITSURecoSens::kNghbTR}
174 // add neighbours info
175 double zTol = 0.45*dz, phiTol = 0.45*TwoPi()/fNLadders;
176 for (int ild=0;ild<fNLadders;ild++) {
177 for (int idt=0;idt<fNSensInLadder;idt++) {
178 AliITSURecoSens* sens = GetSensor(ild,idt);
180 for (int ils=-1;ils<=1;ils++) {
181 int ildN = ild+ils; // ladders of neighbouring sensors
182 if (ildN<0) ildN = fNLadders-1; else if (ildN==fNLadders) ildN = 0;
183 for (int ids=-1;ids<=1;ids++) {
185 if (idtN<0 || idtN==fNSensInLadder || (ids==0&&ils==0)) continue;
186 AliITSURecoSens* sensN = GetSensor(ildN,idtN); // potential neighbor
187 int neighbID = ildN*fNSensInLadder+idtN;
189 int zType = 1; // side
190 if (sens->GetZMin()-zTol > sensN->GetZMax()) continue; // too large distance
191 if (sensN->GetZMin()-zTol > sens->GetZMax() ) continue; // too large distance
192 if (sens->GetZMin()-zTol>sensN->GetZMin()) zType = 0; // bottom
193 else if (sensN->GetZMin()-zTol>sens->GetZMin()) zType = 2; // top
197 double phiTstMn = sensN->GetPhiMin()-phiTol;
198 BringTo02Pi(phiTstMn);
199 if (!OKforPhiMax(sens->GetPhiMax(),phiTstMn)) continue; // too large angle
200 double phiTstMx = sensN->GetPhiMax()+phiTol;
201 BringTo02Pi(phiTstMx);
202 if (!OKforPhiMin(sens->GetPhiMin(),phiTstMx)) continue; // too large angle
204 phiTstMn = sensN->GetPhiMin()+phiTol;
205 BringTo02Pi(phiTstMn);
206 phiTstMx = sensN->GetPhiMax()-phiTol;
207 BringTo02Pi(phiTstMx);
208 if (!OKforPhiMax(sens->GetPhiMax(),phiTstMx)) phiType = 0; // left
209 else if (!OKforPhiMin(sens->GetPhiMin(),phiTstMn)) phiType = 2; // right
211 sens->SetNeighborID(kNBId[zType][phiType], neighbID);
219 //______________________________________________________
220 Int_t AliITSURecoLayer::FindSensors(const double* impPar, AliITSURecoSens *sensors[AliITSURecoSens::kNNeighbors])
222 // find sensors having intersection with track
223 // impPar contains: lab phi of track, dphi, labZ, dz
224 double z = impPar[2];
225 if (z>fZMax+impPar[3]) return 0; // outside of Z coverage
227 if (z<-impPar[3]) return 0; // outside of Z coverage
228 int sensInLad = int(z*fSensDZInv);
229 if (sensInLad<0) sensInLad = 0;
230 else if (sensInLad>=fNSensInLadder) sensInLad = fNSensInLadder-1;
232 double phi = impPar[0] - fPhiOffs;
234 int ladID = int(phi*fDPhiLadInv); // ladder id
237 AliITSURecoSens* sensN,*sens = GetSensor(ladID*fNSensInLadder+sensInLad);
238 sensors[nsens++] = sens;
240 double zMn=impPar[2]-impPar[3], zMx=impPar[2]+impPar[3], phiMn=impPar[0]-impPar[1], phiMx=impPar[0]+impPar[1];
244 sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbR)); // neighbor on the right (smaller phi)
245 if (sensN && OKforPhiMin(phiMn,sensN->GetPhiMax())) sensors[nsens++] = sensN;
247 sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbTR)); // neighbor on the top right (smaller phi, larger Z)
248 if (sensN && OKforPhiMin(phiMn,sensN->GetPhiMax()) && sensN->GetZMin()<zMx) sensors[nsens++] = sensN;
250 sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbT)); // neighbor on the top (larger Z)
251 if (sensN && sensN->GetZMin()<zMx) sensors[nsens++] = sensN;
253 sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbTL)); // neighbor on the top left (larger Z, larger phi)
254 if (sensN && OKforPhiMax(phiMx,sensN->GetPhiMin()) && sensN->GetZMin()<zMx) sensors[nsens++] = sensN;
256 sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbL)); // neighbor on the left (larger phi)
257 if (sensN && OKforPhiMax(phiMx,sensN->GetPhiMin())) sensors[nsens++] = sensN;
259 sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbBL)); // neighbor on the bottom left (smaller Z, larger phi)
260 if (sensN && OKforPhiMax(phiMx,sensN->GetPhiMin()) && sensN->GetZMax()>zMn) sensors[nsens++] = sensN;
262 sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbB)); // neighbor on the bottom (smaller Z)
263 if (sensN && sensN->GetZMax()>zMn) sensors[nsens++] = sensN;
265 sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbBR)); // neighbor on the bottom right (smaller Z, smaller phi)
266 if (sensN && OKforPhiMin(phiMn,sensN->GetPhiMax()) && sensN->GetZMax()>zMn) sensors[nsens++] = sensN;
271 //______________________________________________________
272 void AliITSURecoLayer::ProcessClusters(Int_t mode)
274 // register in each sensor of the layer its cluster.
275 // the clusters of the layer must be sorted per sensor
276 int ncl = fClusters->GetEntriesFast();
278 for (int i=fNSensors;i--;) GetSensor(i)->SetNClusters(0);
279 AliITSURecoSens* curSens = 0;
280 for (int icl=0;icl<ncl;icl++) {
281 AliITSUClusterPix* cl = (AliITSUClusterPix*) fClusters->UncheckedAt(icl);
283 int vID = cl->GetVolumeId();
284 if (vID<curSensID) {AliFatal("Clusters are not sorted in increasing sensorID");}
286 if (curSens) curSens->ProcessClusters(mode); // prepare clusters for reconstruction
287 curSens = GetSensor(vID - fITSGeom->GetFirstModIndex(fActiveID));
289 curSens->SetFirstClusterId(icl);
291 curSens->IncNClusters();
293 if (curSens) curSens->ProcessClusters(mode); // last sensor was not processed yet
297 //______________________________________________________
298 Bool_t AliITSURecoLayer::IsEqual(const TObject* obj) const
300 // check if layers are equal in R
301 const AliITSURecoLayer* lr = (const AliITSURecoLayer*)obj;
302 return Abs(lr->GetR()-GetR())<1e-6 ? kTRUE : kFALSE;
305 //______________________________________________________
306 Int_t AliITSURecoLayer::Compare(const TObject* obj) const
308 // compare two layers
309 const AliITSURecoLayer* lr = (const AliITSURecoLayer*)obj;
310 double dr = GetR() - lr->GetR();
311 if (Abs(dr)<1e-6) return 0;