1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 /* $Id: AliITSUSegmentationPix.cxx 47180 2011-02-08 09:42:29Z masera $ */
17 #include <TGeoManager.h>
18 #include <TGeoVolume.h>
20 #include <TObjArray.h>
24 #include "AliITSUGeomTGeo.h"
25 #include "AliITSUSegmentationPix.h"
26 using namespace TMath;
28 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
29 // Segmentation class for pixels //
30 // Questions to solve: are guardrings needed and do they belong to the sensor or to the chip in TGeo //
31 // At the moment assume that the local coord syst. is located at bottom left corner //
32 // of the ACTIVE matrix. If the guardring to be accounted in the local coords, in //
33 // the Z and X conversions one needs to first subtract the fGuardLft and fGuardBot //
34 // from the local Z,X coordinates //
36 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
38 ClassImp(AliITSUSegmentationPix)
40 const char* AliITSUSegmentationPix::fgkSegmListName = "ITSUSegmentations";
42 //_____________________________________________________________________________RS
43 AliITSUSegmentationPix::AliITSUSegmentationPix(UInt_t id, int nchips,int ncol,int nrow,
44 float pitchX,float pitchZ,
46 float pitchLftC,float pitchRgtC,
47 float edgL,float edgR,float edgT,float edgB)
48 : AliITSsegmentation()
53 ,fShiftXLoc(0.5*(edgT-edgB))
54 ,fShiftZLoc(0.5*(edgR-edgL))
59 ,fPitchZLftCol(pitchLftC<0 ? pitchZ:pitchLftC)
60 ,fPitchZRgtCol(pitchRgtC<0 ? pitchZ:pitchRgtC)
63 ,fNColPerChip(nchips>0 ? ncol/nchips:0)
72 // Default constructor, sizes in cm
73 if (nchips) SetUniqueID( AliITSUGeomTGeo::ComposeChipTypeID(id) );
74 fChipDZ = (fNColPerChip-2)*fPitchZ + fPitchZLftCol + fPitchZRgtCol;;
75 fDxActive = fNRow*fPitchX;
76 fDzActive = fNChips*fChipDZ;
77 SetDetSize( fDxActive + fGuardTop+fGuardBot,
78 fDzActive + fGuardLft+fGuardRgt,
83 //_____________________________________________________________________________RS
84 AliITSUSegmentationPix::~AliITSUSegmentationPix()
87 delete[] fDiodShidtMatX;
88 delete[] fDiodShidtMatZ;
92 //_____________________________________________________________________________RS
93 void AliITSUSegmentationPix::GetPadIxz(Float_t x,Float_t z,Int_t &ix,Int_t &iz) const
95 // Returns pixel coordinates (ix,iz) for given coordinates (x,z counted from corner of col/row 0:0)
96 // expects x, z in cm.
100 if (iz<0) { AliWarning(Form("Z=%f gives col=%d ouside [%d:%d)",z,iz,0,fNCol)); iz=0; }
101 else if (iz >= fNCol) { AliWarning(Form("Z=%f gives col=%d ouside [%d:%d)",z,iz,0,fNCol)); iz= fNCol-1;}
102 if (ix<0) { AliWarning(Form("X=%f gives row=%d ouside [%d:%d)",x,ix,0,fNRow)); ix=0; }
103 else if (ix >= fNRow) { AliWarning(Form("X=%f gives row=%d ouside [%d:%d)",x,ix,0,fNRow)); ix= fNRow-1;}
107 //_____________________________________________________________________________RS
108 void AliITSUSegmentationPix::GetPadTxz(Float_t &x,Float_t &z) const
110 // local transformation of real local coordinates (x,z)
111 // expects x, z in cm (wrt corner of col/row 0:0
117 //_____________________________________________________________________________RS
118 void AliITSUSegmentationPix::GetPadCxz(Int_t ix,Int_t iz,Float_t &x,Float_t&z) const
120 // Transform from pixel to real local coordinates
121 // returns x, z in cm. wrt corner of col/row 0:0
122 x = Float_t((ix+0.5)*fPitchX);
127 //_____________________________________________________________________________RS
128 Float_t AliITSUSegmentationPix::Z2Col(Float_t z) const
130 // get column number (from 0) from local Z (wrt bottom left corner of the active matrix)
131 int chip = int(z/fChipDZ);
132 float col = chip*fNColPerChip;
134 if (z>fPitchZLftCol) col += 1+(z-fPitchZLftCol)/fPitchZ;
138 //_____________________________________________________________________________RS
139 Float_t AliITSUSegmentationPix::Col2Z(Int_t col) const
141 // convert column number (from 0) to Z coordinate wrt bottom left corner of the active matrix
142 int nchip = col/fNColPerChip;
144 float z = nchip*fChipDZ;
146 if (col<fNColPerChip-1) z += fPitchZLftCol + (col-0.5)*fPitchZ;
147 else z += fChipDZ - fPitchZRgtCol/2;
149 else z += fPitchZLftCol/2;
154 //______________________________________________________________________RS
155 AliITSUSegmentationPix& AliITSUSegmentationPix::operator=(const AliITSUSegmentationPix &src)
158 if(this==&src) return *this;
159 AliITSsegmentation::operator=(src);
162 fNColPerChip = src.fNColPerChip;
163 fNChips = src.fNChips;
164 fChipDZ = src.fChipDZ;
165 fPitchZRgtCol = src.fPitchZRgtCol;
166 fPitchZLftCol = src.fPitchZLftCol;
167 fPitchZ = src.fPitchZ;
168 fPitchX = src.fPitchX;
169 fShiftXLoc = src.fShiftXLoc;
170 fShiftZLoc = src.fShiftZLoc;
171 fDxActive = src.fDxActive;
172 fDzActive = src.fDzActive;
174 fGuardBot = src.fGuardBot;
175 fGuardTop = src.fGuardTop;
176 fGuardRgt = src.fGuardRgt;
177 fGuardLft = src.fGuardLft;
179 fDiodShiftMatNCol = src.fDiodShiftMatNCol;
180 fDiodShiftMatNRow = src.fDiodShiftMatNRow;
181 fDiodShiftMatDim = src.fDiodShiftMatDim;
182 delete fDiodShidtMatX; fDiodShidtMatX = 0;
183 delete fDiodShidtMatZ; fDiodShidtMatZ = 0;
184 if (fDiodShiftMatDim) {
185 fDiodShidtMatX = new Float_t[fDiodShiftMatDim];
186 fDiodShidtMatZ = new Float_t[fDiodShiftMatDim];
187 for (int i=fDiodShiftMatDim;i--;) {
188 fDiodShidtMatX[i] = src.fDiodShidtMatX[i];
189 fDiodShidtMatZ[i] = src.fDiodShidtMatZ[i];
196 //____________________________________________________________________________RS
197 AliITSUSegmentationPix::AliITSUSegmentationPix(const AliITSUSegmentationPix &src) :
198 AliITSsegmentation(src)
199 ,fGuardLft(src.fGuardLft)
200 ,fGuardRgt(src.fGuardRgt)
201 ,fGuardTop(src.fGuardTop)
202 ,fGuardBot(src.fGuardBot)
203 ,fShiftXLoc(src.fShiftXLoc)
204 ,fShiftZLoc(src.fShiftZLoc)
205 ,fDxActive(src.fDxActive)
206 ,fDzActive(src.fDzActive)
207 ,fPitchX(src.fPitchX)
208 ,fPitchZ(src.fPitchZ)
209 ,fPitchZLftCol(src.fPitchZLftCol)
210 ,fPitchZRgtCol(src.fPitchZRgtCol)
211 ,fChipDZ(src.fChipDZ)
212 ,fNChips(src.fNChips)
213 ,fNColPerChip(src.fNColPerChip)
216 ,fDiodShiftMatNCol(src.fDiodShiftMatNCol)
217 ,fDiodShiftMatNRow(src.fDiodShiftMatNRow)
218 ,fDiodShiftMatDim(src.fDiodShiftMatDim)
223 if (fDiodShiftMatDim) {
224 fDiodShidtMatX = new Float_t[fDiodShiftMatDim];
225 fDiodShidtMatZ = new Float_t[fDiodShiftMatDim];
226 for (int i=fDiodShiftMatDim;i--;) {
227 fDiodShidtMatX[i] = src.fDiodShidtMatX[i];
228 fDiodShidtMatZ[i] = src.fDiodShidtMatZ[i];
233 //____________________________________________________________________________RS
234 Float_t AliITSUSegmentationPix::Dpx(Int_t ) const
236 //returs x pixel pitch for a give pixel
240 //____________________________________________________________________________RS
241 Float_t AliITSUSegmentationPix::Dpz(Int_t col) const
243 // returns z pixel pitch for a given pixel (cols starts from 0)
245 if (!col) return fPitchZLftCol;
246 if (col==fNColPerChip-1) return fPitchZRgtCol;
251 //------------------------------
252 void AliITSUSegmentationPix::Neighbours(Int_t iX, Int_t iZ, Int_t* nlist, Int_t xlist[8], Int_t zlist[8]) const
254 // returns the neighbouring pixels for use in Cluster Finders and the like.
257 xlist[0]=xlist[1]=iX;
262 zlist[2]=zlist[3]=iZ;
278 //______________________________________________________________________
279 Bool_t AliITSUSegmentationPix::LocalToDet(Float_t x,Float_t z,Int_t &ix,Int_t &iz) const
281 // Transformation from Geant detector centered local coordinates (cm) to
282 // Pixel cell numbers ix and iz.
284 // Float_t x detector local coordinate x in cm with respect to
285 // the center of the sensitive volume.
286 // Float_t z detector local coordinate z in cm with respect to
287 // the center of the sensitive volulme.
289 // Int_t ix detector x cell coordinate. Has the range
291 // Int_t iz detector z cell coordinate. Has the range
294 // kTRUE if point x,z is inside sensitive volume, kFALSE otherwise.
295 // A value of -1 for ix or iz indecates that this point is outside of the
296 // detector segmentation as defined.
297 x += 0.5*DxActive() + fShiftXLoc; // get X,Z wrt bottom/left corner
298 z += 0.5*DzActive() + fShiftZLoc;
300 if(x<0 || x>DxActive()) return kFALSE; // outside x range.
301 if(z<0 || z>DzActive()) return kFALSE; // outside z range.
304 return kTRUE; // Found ix and iz, return.
307 //______________________________________________________________________
308 void AliITSUSegmentationPix::DetToLocal(Int_t ix,Int_t iz,Float_t &x,Float_t &z) const
310 // Transformation from Detector cell coordiantes to Geant detector centered
311 // local coordinates (cm).
313 // Int_t ix detector x cell coordinate. Has the range 0<=ix<fNRow.
314 // Int_t iz detector z cell coordinate. Has the range 0<=iz<fNCol.
316 // Float_t x detector local coordinate x in cm with respect to the
317 // center of the sensitive volume.
318 // Float_t z detector local coordinate z in cm with respect to the
319 // center of the sensitive volulme.
320 // If ix and or iz is outside of the segmentation range a value of -0.5*Dx()
321 // or -0.5*Dz() is returned.
323 x = -0.5*DxActive(); // default value.
324 z = -0.5*DzActive(); // default value.
325 if(ix<0 || ix>=fNRow) {AliWarning(Form("Obtained row %d is not in range [%d:%d)",ix,0,fNRow)); return;} // outside of detector
326 if(iz<0 || iz>=fNCol) {AliWarning(Form("Obtained col %d is not in range [%d:%d)",ix,0,fNCol)); return;} // outside of detector
327 x += (ix+0.5)*fPitchX - fShiftXLoc; // RS: we go to the center of the pad, i.e. + pitch/2, not to the boundary as in SPD
328 z += Col2Z(iz) - fShiftZLoc;
329 return; // Found x and z, return.
332 //______________________________________________________________________
333 void AliITSUSegmentationPix::CellBoundries(Int_t ix,Int_t iz,Double_t &xl,Double_t &xu,Double_t &zl,Double_t &zu) const
335 // Transformation from Detector cell coordiantes to Geant detector centerd
336 // local coordinates (cm).
338 // Int_t ix detector x cell coordinate. Has the range 0<=ix<fNRow.
339 // Int_t iz detector z cell coordinate. Has the range 0<=iz<fNCol.
341 // Double_t xl detector local coordinate cell lower bounds x in cm
342 // with respect to the center of the sensitive volume.
343 // Double_t xu detector local coordinate cell upper bounds x in cm
344 // with respect to the center of the sensitive volume.
345 // Double_t zl detector local coordinate lower bounds z in cm with
346 // respect to the center of the sensitive volulme.
347 // Double_t zu detector local coordinate upper bounds z in cm with
348 // respect to the center of the sensitive volulme.
349 // If ix and or iz is outside of the segmentation range a value of -0.5*DxActive()
350 // and -0.5*DxActive() or -0.5*DzActive() and -0.5*DzActive() are returned.
352 DetToLocal(ix,iz,x,z);
354 if( ix<0 || ix>=fNRow || iz<0 || iz>=fNCol) {
355 xl = xu = -0.5*Dx(); // default value.
356 zl = zu = -0.5*Dz(); // default value.
357 return; // outside of detctor
359 float zpitchH = Dpz(iz)*0.5;
360 float xpitchH = fPitchX*0.5;
365 return; // Found x and z, return.
368 //______________________________________________________________________
369 Int_t AliITSUSegmentationPix::GetChipFromChannel(Int_t, Int_t iz) const
371 // returns chip number (in range 0-4) starting from channel number
372 if(iz>=fNCol || iz<0 ){
373 AliWarning("Bad cell number");
376 return iz/fNColPerChip;
379 //______________________________________________________________________
380 Int_t AliITSUSegmentationPix::GetChipFromLocal(Float_t, Float_t zloc) const
382 // returns chip number (in range 0-4) starting from local Geant coordinates
384 if (!LocalToDet(0,zloc,ix0,iz)) {
385 AliWarning("Bad local coordinate");
388 return GetChipFromChannel(ix0,iz);
391 //______________________________________________________________________
392 Int_t AliITSUSegmentationPix::GetChipsInLocalWindow(Int_t* array, Float_t zmin, Float_t zmax, Float_t, Float_t) const
394 // returns the number of chips containing a road defined by given local Geant coordinate limits
397 AliWarning("Bad coordinate limits: zmin>zmax!");
403 Float_t zminDet = -0.5*DzActive()-fShiftZLoc;
404 Float_t zmaxDet = 0.5*DzActive()-fShiftZLoc;
405 if(zmin<zminDet) zmin=zminDet;
406 if(zmax>zmaxDet) zmax=zmaxDet;
408 Int_t n1 = GetChipFromLocal(0,zmin);
409 array[nChipInW] = n1;
412 Int_t n2 = GetChipFromLocal(0,zmax);
415 Int_t imin=Min(n1,n2);
416 Int_t imax=Max(n1,n2);
417 for(Int_t ichip=imin; ichip<=imax; ichip++){
418 if(ichip==n1) continue;
419 array[nChipInW]=ichip;
427 //______________________________________________________________________
428 void AliITSUSegmentationPix::Init()
433 //______________________________________________________________________
434 Bool_t AliITSUSegmentationPix::Store(const char* outf)
436 // store in the special list under given ID
438 gSystem->ExpandPathName(fns);
439 if (fns.IsNull()) {AliFatal("No file name provided"); return kFALSE;}
440 TFile* fout = TFile::Open(fns.Data(),"update");
441 if (!fout) {AliFatal(Form("Failed to open output file %s",outf)); return kFALSE;}
442 TObjArray* arr = (TObjArray*)fout->Get(fgkSegmListName);
443 int id = GetUniqueID();
444 if (!arr) arr = new TObjArray();
445 else if (arr->At(id)) {AliFatal(Form("Segmenation %d already exists in file %s",id,outf));return kFALSE;}
447 arr->AddAtAndExpand(this,id);
448 arr->SetOwner(kTRUE);
449 fout->WriteObject(arr,fgkSegmListName,"kSingleKey");
454 AliInfo(Form("Stored segmentation %d in %s",id,outf));
459 //______________________________________________________________________
460 AliITSUSegmentationPix* AliITSUSegmentationPix::LoadWithID(UInt_t id, const char* inpf)
462 // store in the special list under given ID
464 gSystem->ExpandPathName(fns);
465 if (fns.IsNull()) {AliFatalGeneral("LoadWithID","No file name provided"); return 0;}
466 TFile* finp = TFile::Open(fns.Data());
467 if (!finp) {AliFatalGeneral("LoadWithID",Form("Failed to open file %s",inpf)); return 0;}
468 TObjArray* arr = (TObjArray*)finp->Get(fgkSegmListName);
470 AliFatalGeneral("LoadWithID",Form("Failed to find segmenation array %s in %s",fgkSegmListName,inpf));
473 AliITSUSegmentationPix* segm = dynamic_cast<AliITSUSegmentationPix*>(arr->At(id));
474 if (!segm || segm->GetUniqueID()!=id) {AliFatalGeneral("LoadWithID",Form("Failed to find segmenation %d in %s",id,inpf)); return 0;}
477 arr->SetOwner(kTRUE); // to not leave in memory other segmenations
485 //______________________________________________________________________
486 void AliITSUSegmentationPix::LoadSegmentations(TObjArray* dest, const char* inpf)
488 // store in the special list under given ID
491 gSystem->ExpandPathName(fns);
492 if (fns.IsNull()) AliFatalGeneral("LoadWithID","No file name provided");
493 TFile* finp = TFile::Open(fns.Data());
494 if (!finp) AliFatalGeneral("LoadWithID",Form("Failed to open file %s",inpf));
495 TObjArray* arr = (TObjArray*)finp->Get(fgkSegmListName);
496 if (!arr) AliFatalGeneral("LoadWithID",Form("Failed to find segmenation array %s in %s",fgkSegmListName,inpf));
497 int nent = arr->GetEntriesFast();
499 for (int i=nent;i--;) if ((segm=arr->At(i))) dest->AddAtAndExpand(segm,segm->GetUniqueID());
500 AliInfoGeneral("LoadSegmentations",Form("Loaded %d segmantions from %s",arr->GetEntries(),inpf));
501 arr->SetOwner(kFALSE);
509 //______________________________________________________________________
510 void AliITSUSegmentationPix::SetDiodShiftMatrix(Int_t nrow,Int_t ncol, const Float_t *shiftX, const Float_t *shiftZ)
512 // set matrix of periodic shifts of diod center. provided arrays must be in the format shift[nrow][ncol]
513 if (fDiodShiftMatDim) {
514 delete fDiodShidtMatX;
515 delete fDiodShidtMatZ;
516 fDiodShidtMatX = fDiodShidtMatZ = 0;
519 fDiodShiftMatNCol = ncol;
520 fDiodShiftMatNRow = nrow;
521 fDiodShiftMatDim = fDiodShiftMatNCol*fDiodShiftMatNRow;
522 if (fDiodShiftMatDim) {
523 fDiodShidtMatX = new Float_t[fDiodShiftMatDim];
524 fDiodShidtMatZ = new Float_t[fDiodShiftMatDim];
525 for (int ir=0;ir<fDiodShiftMatNRow;ir++) {
526 for (int ic=0;ic<fDiodShiftMatNCol;ic++) {
527 int cnt = ic+ir*fDiodShiftMatNCol;
528 fDiodShidtMatX[cnt] = shiftX ? shiftX[cnt] : 0.;
529 fDiodShidtMatZ[cnt] = shiftZ ? shiftZ[cnt] : 0.;
535 //______________________________________________________________________
536 void AliITSUSegmentationPix::SetDiodShiftMatrix(Int_t nrow,Int_t ncol, const Double_t *shiftX, const Double_t *shiftZ)
538 // set matrix of periodic shifts of diod center. provided arrays must be in the format shift[nrow][ncol]
539 if (fDiodShiftMatDim) {
540 delete fDiodShidtMatX;
541 delete fDiodShidtMatZ;
542 fDiodShidtMatX = fDiodShidtMatZ = 0;
545 fDiodShiftMatNCol = ncol;
546 fDiodShiftMatNRow = nrow;
547 fDiodShiftMatDim = fDiodShiftMatNCol*fDiodShiftMatNRow;
548 if (fDiodShiftMatDim) {
549 fDiodShidtMatX = new Float_t[fDiodShiftMatDim];
550 fDiodShidtMatZ = new Float_t[fDiodShiftMatDim];
551 for (int ir=0;ir<fDiodShiftMatNRow;ir++) {
552 for (int ic=0;ic<fDiodShiftMatNCol;ic++) {
553 int cnt = ic+ir*fDiodShiftMatNCol;
554 fDiodShidtMatX[cnt] = shiftX ? shiftX[cnt] : 0.;
555 fDiodShidtMatZ[cnt] = shiftZ ? shiftZ[cnt] : 0.;
561 //______________________________________________________________________
562 void AliITSUSegmentationPix::Print(Option_t* /*option*/) const
565 const double kmc=1e4;
566 printf("Segmentation %d: Active Size: DX: %.1f DY: %.1f DZ: %.1f | Pitch: X:%.1f Z:%.1f\n",
567 GetUniqueID(),kmc*DxActive(),kmc*Dy(),kmc*DzActive(),kmc*Dpx(1),kmc*Dpz(1));
568 printf("Passive Edges: Bottom: %.1f Right: %.1f Top: %.1f Left: %.1f -> DX: %.1f DZ: %.1f Shift: x:%.1f z:%.1f\n",
569 kmc*fGuardBot,kmc*fGuardRgt,kmc*fGuardTop,kmc*fGuardLft,kmc*Dx(),kmc*Dz(),kmc*fShiftXLoc,kmc*fShiftZLoc);
570 printf("%d chips along Z: chip Ncol=%d Nrow=%d\n",fNChips, fNColPerChip,fNRow);
571 if (Abs(fPitchZLftCol-fPitchZ)>1e-5) printf("Special left column pitch: %.1f\n",fPitchZLftCol*kmc);
572 if (Abs(fPitchZRgtCol-fPitchZ)>1e-5) printf("Special right column pitch: %.1f\n",fPitchZRgtCol*kmc);
574 if (fDiodShiftMatDim) {
576 printf("Diod shift (fraction of pitch) periodicity pattern (X,Z[row][col])\n");
577 for (int irow=0;irow<fDiodShiftMatNRow;irow++) {
578 for (int icol=0;icol<fDiodShiftMatNCol;icol++) {
579 GetDiodShift(irow,icol,dx,dz);
580 printf("%.1f/%.1f |",dx,dz);
587 //______________________________________________________________________
588 void AliITSUSegmentationPix::GetDiodShift(Int_t row,Int_t col, Float_t &dx,Float_t &dz) const
590 // obtain optional diod shift
591 if (!fDiodShiftMatDim) {dx=dz=0; return;}
592 int cnt = (col%fDiodShiftMatNCol) + (row%fDiodShiftMatNRow)*fDiodShiftMatNCol;
593 dx = fDiodShidtMatX[cnt];
594 dz = fDiodShidtMatZ[cnt];