#include #include "AliITSURecoLayer.h" #include "AliITSsegmentation.h" #include "AliITSUAux.h" #include "AliITSUClusterPix.h" #include "AliITSUGeomTGeo.h" #include "AliLog.h" using namespace AliITSUAux; using namespace TMath; ClassImp(AliITSURecoLayer) //______________________________________________________ AliITSURecoLayer::AliITSURecoLayer(const char* name) :fActiveID(-1) ,fNSensors(0) ,fNSensInLadder(0) ,fNLadders(0) ,fR(0) ,fRMax(0) ,fRMin(0) ,fZMax(0) ,fZMin(0) ,fPhiLadMax(0) ,fPhiLadMin(0) ,fPhiOffs(0) ,fSensDZInv(0) ,fDPhiLadInv(0) ,fMaxStep(0.5) ,fSensors(0) ,fITSGeom(0) ,fClusters(0) { // def. c-tor SetNameTitle(name,name); } //______________________________________________________ AliITSURecoLayer::AliITSURecoLayer(const char* name, Int_t activeID, AliITSUGeomTGeo* gm) :fActiveID(activeID) ,fNSensors(0) ,fNSensInLadder(0) ,fNLadders(0) ,fR(0) ,fRMax(0) ,fRMin(0) ,fZMax(0) ,fZMin(0) ,fPhiLadMax(0) ,fPhiLadMin(0) ,fPhiOffs(0) ,fSensDZInv(0) ,fDPhiLadInv(0) ,fMaxStep(0.5) ,fSensors(0) ,fITSGeom(gm) ,fClusters(0) { // def. c-tor SetNameTitle(name,name); Build(); } //______________________________________________________ AliITSURecoLayer::~AliITSURecoLayer() { // def. d-tor delete[] fSensors; delete[] fPhiLadMax; delete[] fPhiLadMin; if (GetOwnsClusterArray()) delete fClusters; } //______________________________________________________ void AliITSURecoLayer::Print(Option_t* opt) const { //print printf("Lr %-15s %d (act:%+d), NSens: %4d | MaxStep:%.2f ",GetName(),GetID(),GetActiveID(),GetNSensors(),fMaxStep); printf("%6.3f0 ? 1/fSensDZInv : 0); TString opts = opt; opts.ToLower(); if (opts.Contains("sn")) for (int i=0;iPrint(opt); } //______________________________________________________ void AliITSURecoLayer::Build() { // build internal structures const double kSafeR = 0.05; // safety margin for Rmin,Rmax of the layer if (fActiveID<0) return; fNLadders = fITSGeom->GetNLadders(fActiveID); fNSensInLadder = fITSGeom->GetNDetectors(fActiveID); fNSensors = fNLadders*fNSensInLadder; fSensors = new AliITSURecoSens*[fNSensors]; const AliITSsegmentation* kSegm = fITSGeom->GetSegmentation(fActiveID); // // name layer according its active id, detector type and segmentation tyoe TGeoHMatrix mmod; const TGeoHMatrix* mt2l; fRMin=fZMin=1e9; fRMax=fZMax=-1e9; double phiTF,rTF, loc[3]={0,0,0},glo[3]; fNSensors = 0; fPhiLadMin = new Double_t[fNLadders]; fPhiLadMax = new Double_t[fNLadders]; fSensDZInv = 0; fDPhiLadInv = fNLadders/TwoPi(); // for (int ild=0;ildGetMatrixSens(fActiveID,ild,idt); for (int ix=0;ix<2;ix++) { loc[0] = (ix-0.5)*kSegm->Dx(); // +-DX/2 for (int iy=0;iy<2;iy++) { loc[1] = (iy-0.5)*kSegm->Dy(); // +-DY/2 for (int iz=0;iz<2;iz++) { loc[2] = (iz-0.5)*kSegm->Dz(); // +-DZ/2 // mmod.LocalToMaster(loc,glo); double phi = ATan2(glo[1],glo[0]); double r = glo[0]*glo[0] + glo[1]*glo[1]; if (fRMin>r) fRMin = r; if (fRMax1e8) phiMin=phi; else if (!OKforPhiMin(phiMin,phi)) phiMin=phi; if (phiMax<-1e8) phiMax=phi; else if (!OKforPhiMax(phiMax,phi)) phiMax=phi; if (glo[2]>zMax) zMax=glo[2]; if (glo[2]SetBoundaries(phiMin,phiMax,zMin,zMax); mt2l = fITSGeom->GetMatrixT2L(fActiveID,ild,idt); mmod.Multiply(mt2l); loc[0]=loc[1]=loc[2]=0; mmod.LocalToMaster(loc,glo); rTF = Sqrt(glo[0]*glo[0] + glo[1]*glo[1]); // tracking params (misaligned) phiTF = ATan2(glo[1],glo[0]); BringTo02Pi(phiTF); // sens->SetXTF(rTF); sens->SetPhiTF(phiTF); // if (fPhiLadMin[ild]>1e8) fPhiLadMin[ild] = phiMin; else if (!OKforPhiMin(fPhiLadMin[ild],phiMin)) fPhiLadMin[ild] = phiMin; if (fPhiLadMax[ild]<-1e8) fPhiLadMax[ild] = phiMax; else if (!OKforPhiMax(fPhiLadMax[ild],phiMax)) fPhiLadMax[ild] = phiMax; if (fZMin>zMin) fZMin = zMin; if (fZMax0) fSensDZInv += zMax - GetSensor(ild,idt-1)->GetZMax(); // z interval to previous } } // fRMin = Sqrt(fRMin); fRMax = Sqrt(fRMax); fR = 0.5*(fRMin+fRMax); fRMin -= kSafeR; fRMax += kSafeR; double dz = fNSensInLadder>0 ? fSensDZInv/(fNSensInLadder-1)/fNLadders : fZMax-fZMin; fSensDZInv = 1./dz; const int kNBId[3][3] = { {AliITSURecoSens::kNghbBL,AliITSURecoSens::kNghbB,AliITSURecoSens::kNghbBR}, {AliITSURecoSens::kNghbL, -1 ,AliITSURecoSens::kNghbR }, {AliITSURecoSens::kNghbTL,AliITSURecoSens::kNghbT,AliITSURecoSens::kNghbTR} }; // add neighbours info double zTol = 0.45*dz, phiTol = 0.45*TwoPi()/fNLadders; for (int ild=0;ildGetZMin()-zTol > sensN->GetZMax()) continue; // too large distance if (sensN->GetZMin()-zTol > sens->GetZMax() ) continue; // too large distance if (sens->GetZMin()-zTol>sensN->GetZMin()) zType = 0; // bottom else if (sensN->GetZMin()-zTol>sens->GetZMin()) zType = 2; // top // int phiType = 1; double phiTstMn = sensN->GetPhiMin()-phiTol; BringTo02Pi(phiTstMn); if (!OKforPhiMax(sens->GetPhiMax(),phiTstMn)) continue; // too large angle double phiTstMx = sensN->GetPhiMax()+phiTol; BringTo02Pi(phiTstMx); if (!OKforPhiMin(sens->GetPhiMin(),phiTstMx)) continue; // too large angle // phiTstMn = sensN->GetPhiMin()+phiTol; BringTo02Pi(phiTstMn); phiTstMx = sensN->GetPhiMax()-phiTol; BringTo02Pi(phiTstMx); if (!OKforPhiMax(sens->GetPhiMax(),phiTstMx)) phiType = 0; // left else if (!OKforPhiMin(sens->GetPhiMin(),phiTstMn)) phiType = 2; // right // sens->SetNeighborID(kNBId[zType][phiType], neighbID); } // phi scan } // z scan } // sensors } // ladders // } //______________________________________________________ Int_t AliITSURecoLayer::FindSensors(const double* impPar, AliITSURecoSens *sensors[AliITSURecoSens::kNNeighbors]) { // find sensors having intersection with track // impPar contains: lab phi of track, dphi, labZ, dz // double z = impPar[2]; if (z>fZMax+impPar[3]) return 0; // outside of Z coverage z -= fZMin; if (z<-impPar[3]) return 0; // outside of Z coverage int sensInLad = int(z*fSensDZInv); if (sensInLad<0) sensInLad = 0; else if (sensInLad>=fNSensInLadder) sensInLad = fNSensInLadder-1; // double phi = impPar[0] - fPhiOffs; BringTo02Pi(phi); int ladID = int(phi*fDPhiLadInv); // ladder id int nsens = 0; // AliITSURecoSens* sensN,*sens = GetSensor(ladID*fNSensInLadder+sensInLad); sensors[nsens++] = sens; // // check neighbours double zMn=impPar[2]-impPar[3], zMx=impPar[2]+impPar[3], phiMn=impPar[0]-impPar[1], phiMx=impPar[0]+impPar[1]; BringTo02Pi(phiMn); BringTo02Pi(phiMx); // sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbR)); // neighbor on the right (smaller phi) if (sensN && OKforPhiMin(phiMn,sensN->GetPhiMax())) sensors[nsens++] = sensN; // sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbTR)); // neighbor on the top right (smaller phi, larger Z) if (sensN && OKforPhiMin(phiMn,sensN->GetPhiMax()) && sensN->GetZMin()GetNeighborID(AliITSURecoSens::kNghbT)); // neighbor on the top (larger Z) if (sensN && sensN->GetZMin()GetNeighborID(AliITSURecoSens::kNghbTL)); // neighbor on the top left (larger Z, larger phi) if (sensN && OKforPhiMax(phiMx,sensN->GetPhiMin()) && sensN->GetZMin()GetNeighborID(AliITSURecoSens::kNghbL)); // neighbor on the left (larger phi) if (sensN && OKforPhiMax(phiMx,sensN->GetPhiMin())) sensors[nsens++] = sensN; // sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbBL)); // neighbor on the bottom left (smaller Z, larger phi) if (sensN && OKforPhiMax(phiMx,sensN->GetPhiMin()) && sensN->GetZMax()>zMn) sensors[nsens++] = sensN; // sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbB)); // neighbor on the bottom (smaller Z) if (sensN && sensN->GetZMax()>zMn) sensors[nsens++] = sensN; // sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbBR)); // neighbor on the bottom right (smaller Z, smaller phi) if (sensN && OKforPhiMin(phiMn,sensN->GetPhiMax()) && sensN->GetZMax()>zMn) sensors[nsens++] = sensN; // return nsens; } //*/ /* Int_t AliITSURecoLayer::FindSensors(const double* impPar, AliITSURecoSens *sensors[AliITSURecoSens::kNNeighbors],int mcLab) { // find sensors having intersection with track // impPar contains: lab phi of track, dphi, labZ, dz //tmp>>> int nFnd = 0; int fndSens[50]; if (mcLab>=0) { // find correct sensors from MC info int ncl = GetNClusters(); for (int icl=ncl;icl--;) { AliCluster* cl = GetCluster(icl); for (int ilb=0;ilb<3;ilb++) { if (cl->GetLabel(ilb)<0) break; if (cl->GetLabel(ilb)==mcLab) {fndSens[nFnd++] = cl->GetVolumeId(); break;} } } if (nFnd>0) { Int_t layS,ladS,sensS; for (int is=0;isGetModuleId(fndSens[is],layS,ladS,sensS); printf("SNMC#%d(%d): %d %d %d | ",is,mcLab,layS,ladS,sensS); GetSensorFromID(fndSens[is])->Print(); } } } //tmp<<< double z = impPar[2]; if (z>fZMax+impPar[3]) { if (nFnd>0) printf("MissedSens!!!\n"); return 0; // outside of Z coverage } z -= fZMin; if (z<-impPar[3]) { if (nFnd>0) printf("MissedSens!!!\n"); return 0; // outside of Z coverage } int sensInLad = int(z*fSensDZInv); if (sensInLad<0) sensInLad = 0; else if (sensInLad>=fNSensInLadder) sensInLad = fNSensInLadder-1; // double phi = impPar[0] - fPhiOffs; BringTo02Pi(phi); int ladID = int(phi*fDPhiLadInv); // ladder id int nsens = 0; // AliITSURecoSens* sensN,*sens = GetSensor(ladID*fNSensInLadder+sensInLad); sensors[nsens++] = sens; // // check neighbours double zMn=impPar[2]-impPar[3], zMx=impPar[2]+impPar[3], phiMn=impPar[0]-impPar[1], phiMx=impPar[0]+impPar[1]; BringTo02Pi(phiMn); BringTo02Pi(phiMx); // sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbR)); // neighbor on the right (smaller phi) if (sensN && OKforPhiMin(phiMn,sensN->GetPhiMax())) sensors[nsens++] = sensN; // sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbTR)); // neighbor on the top right (smaller phi, larger Z) if (sensN && OKforPhiMin(phiMn,sensN->GetPhiMax()) && sensN->GetZMin()GetNeighborID(AliITSURecoSens::kNghbT)); // neighbor on the top (larger Z) if (sensN && sensN->GetZMin()GetNeighborID(AliITSURecoSens::kNghbTL)); // neighbor on the top left (larger Z, larger phi) if (sensN && OKforPhiMax(phiMx,sensN->GetPhiMin()) && sensN->GetZMin()GetNeighborID(AliITSURecoSens::kNghbL)); // neighbor on the left (larger phi) if (sensN && OKforPhiMax(phiMx,sensN->GetPhiMin())) sensors[nsens++] = sensN; // sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbBL)); // neighbor on the bottom left (smaller Z, larger phi) if (sensN && OKforPhiMax(phiMx,sensN->GetPhiMin()) && sensN->GetZMax()>zMn) sensors[nsens++] = sensN; // sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbB)); // neighbor on the bottom (smaller Z) if (sensN && sensN->GetZMax()>zMn) sensors[nsens++] = sensN; // sensN = GetSensor(sens->GetNeighborID(AliITSURecoSens::kNghbBR)); // neighbor on the bottom right (smaller Z, smaller phi) if (sensN && OKforPhiMin(phiMn,sensN->GetPhiMax()) && sensN->GetZMax()>zMn) sensors[nsens++] = sensN; // if (mcLab>=0) { Int_t layS,ladS,sensS; printf("Found %d sensors for phi %.3f : %.3f | Z %.4f %.4f\n", nsens,phiMn,phiMx,zMn,zMx); for (int is=0;isGetModuleId(sensors[is]->GetID()+fITSGeom->GetFirstModIndex(fActiveID),layS,ladS,sensS); printf("*SNF#%d: %d %d %d | ",is,layS,ladS,sensS); sensors[is]->Print(); } for (int ism=0;ismGetEntriesFast(); int curSensID = -1; for (int i=fNSensors;i--;) GetSensor(i)->SetNClusters(0); AliITSURecoSens* curSens = 0; for (int icl=0;iclUncheckedAt(icl); cl->GoToFrameTrk(); int vID = cl->GetVolumeId(); if (vIDcurSensID) { if (curSens) curSens->ProcessClusters(mode); // prepare clusters for reconstruction curSens = GetSensor(vID - fITSGeom->GetFirstModIndex(fActiveID)); curSensID = vID; curSens->SetFirstClusterId(icl); } curSens->IncNClusters(); } if (curSens) curSens->ProcessClusters(mode); // last sensor was not processed yet // } //______________________________________________________ Bool_t AliITSURecoLayer::IsEqual(const TObject* obj) const { // check if layers are equal in R const AliITSURecoLayer* lr = (const AliITSURecoLayer*)obj; return Abs(lr->GetR()-GetR())<1e-6 ? kTRUE : kFALSE; } //______________________________________________________ Int_t AliITSURecoLayer::Compare(const TObject* obj) const { // compare two layers const AliITSURecoLayer* lr = (const AliITSURecoLayer*)obj; double dr = GetR() - lr->GetR(); if (Abs(dr)<1e-6) return 0; return dr>0 ? 1:-1; // } //_________________________________________________________________ AliITSURecoSens* AliITSURecoLayer::GetSensorFromID(Int_t i) const { // get sensor from its global id i -= fITSGeom->GetFirstModIndex(fActiveID); if (i<0||i>=fNSensors) AliFatal(Form("Sensor with id=%d is not in layer %d",i+fITSGeom->GetFirstModIndex(fActiveID),fActiveID)); return (AliITSURecoSens*)fSensors[i]; }