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 module 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 double pitchX,double pitchZ,
46 double pitchLftC,double pitchRgtC,
47 double edgL,double edgR,double edgT,double edgB)
48 : AliITSsegmentation()
55 ,fPitchZLftCol(pitchLftC<0 ? pitchZ:pitchLftC)
56 ,fPitchZRgtCol(pitchRgtC<0 ? pitchZ:pitchRgtC)
59 ,fNColPerChip(nchips>0 ? ncol/nchips:0)
68 // Default constructor, sizes in cm
69 if (nchips) SetUniqueID( AliITSUGeomTGeo::ComposeDetTypeID(id) );
70 fChipDZ = (fNColPerChip-2)*fPitchZ + fPitchZLftCol + fPitchZRgtCol;
71 SetDetSize( fNRow*fPitchX /*+fGuardTop+fGuardBot*/,
72 fNChips*fChipDZ /*+fGuardLft+fGuardRgt*/,
77 //_____________________________________________________________________________RS
78 void AliITSUSegmentationPix::GetPadIxz(Float_t x,Float_t z,Int_t &ix,Int_t &iz) const
80 // Returns pixel coordinates (ix,iz) for given coordinates (x,z counted from col/row 0:0)
81 // expects x, z in cm.
85 if (iz<0) { AliWarning(Form("Z=%f gives col=%d ouside [%d:%d)",z,iz,0,fNCol)); iz=0; }
86 else if (iz >= fNCol) { AliWarning(Form("Z=%f gives col=%d ouside [%d:%d)",z,iz,0,fNCol)); iz= fNCol-1;}
87 if (ix<0) { AliWarning(Form("X=%f gives row=%d ouside [%d:%d)",x,ix,0,fNRow)); ix=0; }
88 else if (ix >= fNRow) { AliWarning(Form("X=%f gives row=%d ouside [%d:%d)",x,ix,0,fNRow)); ix= fNRow-1;}
92 //_____________________________________________________________________________RS
93 void AliITSUSegmentationPix::GetPadTxz(Float_t &x,Float_t &z) const
95 // local transformation of real local coordinates (x,z)
102 //_____________________________________________________________________________RS
103 void AliITSUSegmentationPix::GetPadCxz(Int_t ix,Int_t iz,Float_t &x,Float_t&z) const
105 // Transform from pixel to real local coordinates
106 // returns x, z in cm.
107 x = Float_t((ix+0.5)*fPitchX);
112 //_____________________________________________________________________________RS
113 Float_t AliITSUSegmentationPix::Z2Col(Float_t z) const
115 // get column number (from 0) from local Z (wrt bottom left corner of the active matrix)
116 int chip = int(z/fChipDZ);
117 float col = chip*fNColPerChip;
119 if (z>fPitchZLftCol) col += 1+(z-fPitchZLftCol)/fPitchZ;
123 //_____________________________________________________________________________RS
124 Float_t AliITSUSegmentationPix::Col2Z(Int_t col) const
126 // convert column number (from 0) to Z coordinate
127 int nchip = col/fNColPerChip;
129 float z = nchip*fChipDZ;
131 if (col<fNColPerChip-1) z += fPitchZLftCol + (col-0.5)*fPitchZ;
132 else z += fChipDZ - fPitchZRgtCol/2;
134 else z += fPitchZLftCol/2;
139 //______________________________________________________________________RS
140 AliITSUSegmentationPix& AliITSUSegmentationPix::operator=(const AliITSUSegmentationPix &src)
143 if(this==&src) return *this;
144 AliITSsegmentation::operator=(src);
147 fNColPerChip = src.fNColPerChip;
148 fNChips = src.fNChips;
149 fChipDZ = src.fChipDZ;
150 fPitchZRgtCol = src.fPitchZRgtCol;
151 fPitchZLftCol = src.fPitchZLftCol;
152 fPitchZ = src.fPitchZ;
153 fPitchX = src.fPitchX;
155 fGuardBot = src.fGuardBot;
156 fGuardTop = src.fGuardTop;
157 fGuardRgt = src.fGuardRgt;
158 fGuardLft = src.fGuardLft;
160 fDiodShiftMatNCol = src.fDiodShiftMatNCol;
161 fDiodShiftMatNRow = src.fDiodShiftMatNRow;
162 fDiodShiftMatDim = src.fDiodShiftMatDim;
163 delete fDiodShidtMatX; fDiodShidtMatX = 0;
164 delete fDiodShidtMatZ; fDiodShidtMatZ = 0;
165 if (fDiodShiftMatDim) {
166 fDiodShidtMatX = new Double32_t[fDiodShiftMatDim];
167 fDiodShidtMatZ = new Double32_t[fDiodShiftMatDim];
168 for (int i=fDiodShiftMatDim;i--;) {
169 fDiodShidtMatX[i] = src.fDiodShidtMatX[i];
170 fDiodShidtMatZ[i] = src.fDiodShidtMatZ[i];
177 //____________________________________________________________________________RS
178 AliITSUSegmentationPix::AliITSUSegmentationPix(const AliITSUSegmentationPix &src) :
179 AliITSsegmentation(src)
180 ,fGuardLft(src.fGuardLft)
181 ,fGuardRgt(src.fGuardRgt)
182 ,fGuardTop(src.fGuardTop)
183 ,fGuardBot(src.fGuardBot)
184 ,fPitchX(src.fPitchX)
185 ,fPitchZ(src.fPitchZ)
186 ,fPitchZLftCol(src.fPitchZLftCol)
187 ,fPitchZRgtCol(src.fPitchZRgtCol)
188 ,fChipDZ(src.fChipDZ)
189 ,fNChips(src.fNChips)
190 ,fNColPerChip(src.fNColPerChip)
193 ,fDiodShiftMatNCol(src.fDiodShiftMatNCol)
194 ,fDiodShiftMatNRow(src.fDiodShiftMatNRow)
195 ,fDiodShiftMatDim(src.fDiodShiftMatDim)
200 if (fDiodShiftMatDim) {
201 fDiodShidtMatX = new Double32_t[fDiodShiftMatDim];
202 fDiodShidtMatZ = new Double32_t[fDiodShiftMatDim];
203 for (int i=fDiodShiftMatDim;i--;) {
204 fDiodShidtMatX[i] = src.fDiodShidtMatX[i];
205 fDiodShidtMatZ[i] = src.fDiodShidtMatZ[i];
210 //____________________________________________________________________________RS
211 Float_t AliITSUSegmentationPix::Dpx(Int_t ) const
213 //returs x pixel pitch for a give pixel
217 //____________________________________________________________________________RS
218 Float_t AliITSUSegmentationPix::Dpz(Int_t col) const
220 // returns z pixel pitch for a given pixel (cols starts from 0)
222 if (!col) return fPitchZLftCol;
223 if (col==fNColPerChip-1) return fPitchZRgtCol;
228 //------------------------------
229 void AliITSUSegmentationPix::Neighbours(Int_t iX, Int_t iZ, Int_t* nlist, Int_t xlist[8], Int_t zlist[8]) const
231 // returns the neighbouring pixels for use in Cluster Finders and the like.
234 xlist[0]=xlist[1]=iX;
239 zlist[2]=zlist[3]=iZ;
255 //______________________________________________________________________
256 Bool_t AliITSUSegmentationPix::LocalToDet(Float_t x,Float_t z,Int_t &ix,Int_t &iz) const
258 // Transformation from Geant detector centered local coordinates (cm) to
259 // Pixel cell numbers ix and iz.
261 // Float_t x detector local coordinate x in cm with respect to
262 // the center of the sensitive volume.
263 // Float_t z detector local coordinate z in cm with respect to
264 // the center of the sensitive volulme.
266 // Int_t ix detector x cell coordinate. Has the range
268 // Int_t iz detector z cell coordinate. Has the range
271 // kTRUE if point x,z is inside sensitive volume, kFALSE otherwise.
272 // A value of -1 for ix or iz indecates that this point is outside of the
273 // detector segmentation as defined.
277 if(x<0 || x>Dx()) return kFALSE; // outside x range.
278 if(z<0 || z>Dz()) return kFALSE; // outside z range.
281 return kTRUE; // Found ix and iz, return.
284 //______________________________________________________________________
285 void AliITSUSegmentationPix::DetToLocal(Int_t ix,Int_t iz,Float_t &x,Float_t &z) const
287 // Transformation from Detector cell coordiantes to Geant detector centerd
288 // local coordinates (cm).
290 // Int_t ix detector x cell coordinate. Has the range 0<=ix<fNRow.
291 // Int_t iz detector z cell coordinate. Has the range 0<=iz<fNCol.
293 // Float_t x detector local coordinate x in cm with respect to the
294 // center of the sensitive volume.
295 // Float_t z detector local coordinate z in cm with respect to the
296 // center of the sensitive volulme.
297 // If ix and or iz is outside of the segmentation range a value of -0.5*Dx()
298 // or -0.5*Dz() is returned.
300 x = -0.5*Dx(); // default value.
301 z = -0.5*Dz(); // default value.
302 // RS: to check: why we don't do strict check for [0:n)
303 if(ix<0 || ix>=fNRow) {AliWarning(Form("Obtained row %d is not in range [%d:%d)",ix,0,fNRow)); return;} // outside of detector
304 if(iz<0 || iz>=fNCol) {AliWarning(Form("Obtained col %d is not in range [%d:%d)",ix,0,fNCol)); return;} // outside of detector
305 x += (ix+0.5)*fPitchX; // RS: we go to the center of the pad, i.e. + pitch/2, not to the boundary as in SPD
307 return; // Found x and z, return.
310 //______________________________________________________________________
311 void AliITSUSegmentationPix::CellBoundries(Int_t ix,Int_t iz,Double_t &xl,Double_t &xu,Double_t &zl,Double_t &zu) const
313 // Transformation from Detector cell coordiantes to Geant detector centerd
314 // local coordinates (cm).
316 // Int_t ix detector x cell coordinate. Has the range 0<=ix<fNRow.
317 // Int_t iz detector z cell coordinate. Has the range 0<=iz<fNCol.
319 // Double_t xl detector local coordinate cell lower bounds x in cm
320 // with respect to the center of the sensitive volume.
321 // Double_t xu detector local coordinate cell upper bounds x in cm
322 // with respect to the center of the sensitive volume.
323 // Double_t zl detector local coordinate lower bounds z in cm with
324 // respect to the center of the sensitive volulme.
325 // Double_t zu detector local coordinate upper bounds z in cm with
326 // respect to the center of the sensitive volulme.
327 // If ix and or iz is outside of the segmentation range a value of -0.5*Dx()
328 // and -0.5*Dx() or -0.5*Dz() and -0.5*Dz() are returned.
330 DetToLocal(ix,iz,x,z);
332 if( ix<0 || ix>=fNRow || iz<0 || iz>=fNCol) {
333 xl = xu = -0.5*Dx(); // default value.
334 zl = zu = -0.5*Dz(); // default value.
335 return; // outside of detctor
337 float zpitchH = Dpz(iz)*0.5;
338 float xpitchH = fPitchX*0.5;
343 return; // Found x and z, return.
346 //______________________________________________________________________
347 Int_t AliITSUSegmentationPix::GetChipFromChannel(Int_t, Int_t iz) const
349 // returns chip number (in range 0-4) starting from channel number
350 if(iz>=fNCol || iz<0 ){
351 AliWarning("Bad cell number");
354 return iz/fNColPerChip;
357 //______________________________________________________________________
358 Int_t AliITSUSegmentationPix::GetChipFromLocal(Float_t, Float_t zloc) const
360 // returns chip number (in range 0-4) starting from local coordinates
362 if (!LocalToDet(0,zloc,ix0,iz)) {
363 AliWarning("Bad local coordinate");
366 return GetChipFromChannel(ix0,iz);
369 //______________________________________________________________________
370 Int_t AliITSUSegmentationPix::GetChipsInLocalWindow(Int_t* array, Float_t zmin, Float_t zmax, Float_t, Float_t) const
372 // returns the number of chips containing a road defined by given local coordinate limits
375 AliWarning("Bad coordinate limits: zmin>zmax!");
381 Float_t zminDet = -0.5*Dz();
382 Float_t zmaxDet = 0.5*Dz();
383 if(zmin<zminDet) zmin=zminDet;
384 if(zmax>zmaxDet) zmax=zmaxDet;
386 Int_t n1 = GetChipFromLocal(0,zmin);
387 array[nChipInW] = n1;
390 Int_t n2 = GetChipFromLocal(0,zmax);
393 Int_t imin=Min(n1,n2);
394 Int_t imax=Max(n1,n2);
395 for(Int_t ichip=imin; ichip<=imax; ichip++){
396 if(ichip==n1) continue;
397 array[nChipInW]=ichip;
405 //______________________________________________________________________
406 void AliITSUSegmentationPix::Init()
411 //______________________________________________________________________
412 Bool_t AliITSUSegmentationPix::Store(const char* outf)
414 // store in the special list under given ID
416 gSystem->ExpandPathName(fns);
417 if (fns.IsNull()) {AliFatal("No file name provided"); return kFALSE;}
418 TFile* fout = TFile::Open(fns.Data(),"update");
419 if (!fout) {AliFatal(Form("Failed to open output file %s",outf)); return kFALSE;}
420 TObjArray* arr = (TObjArray*)fout->Get(fgkSegmListName);
421 int id = GetUniqueID();
422 if (!arr) arr = new TObjArray();
423 else if (arr->At(id)) {AliFatal(Form("Segmenation %d already exists in file %s",id,outf));return kFALSE;}
425 arr->AddAtAndExpand(this,id);
426 arr->SetOwner(kTRUE);
427 fout->WriteObject(arr,fgkSegmListName,"kSingleKey");
432 AliInfo(Form("Stored segmentation %d in %s",id,outf));
437 //______________________________________________________________________
438 AliITSUSegmentationPix* AliITSUSegmentationPix::LoadWithID(UInt_t id, const char* inpf)
440 // store in the special list under given ID
442 gSystem->ExpandPathName(fns);
443 if (fns.IsNull()) {AliFatalGeneral("LoadWithID","No file name provided"); return 0;}
444 TFile* finp = TFile::Open(fns.Data());
445 if (!finp) {AliFatalGeneral("LoadWithID",Form("Failed to open file %s",inpf)); return 0;}
446 TObjArray* arr = (TObjArray*)finp->Get(fgkSegmListName);
448 AliFatalGeneral("LoadWithID",Form("Failed to find segmenation array %s in %s",fgkSegmListName,inpf));
451 AliITSUSegmentationPix* segm = dynamic_cast<AliITSUSegmentationPix*>(arr->At(id));
452 if (!segm || segm->GetUniqueID()!=id) {AliFatalGeneral("LoadWithID",Form("Failed to find segmenation %d in %s",id,inpf)); return 0;}
455 arr->SetOwner(kTRUE); // to not leave in memory other segmenations
463 //______________________________________________________________________
464 void AliITSUSegmentationPix::LoadSegmentations(TObjArray* dest, const char* inpf)
466 // store in the special list under given ID
469 gSystem->ExpandPathName(fns);
470 if (fns.IsNull()) AliFatalGeneral("LoadWithID","No file name provided");
471 TFile* finp = TFile::Open(fns.Data());
472 if (!finp) AliFatalGeneral("LoadWithID",Form("Failed to open file %s",inpf));
473 TObjArray* arr = (TObjArray*)finp->Get(fgkSegmListName);
474 if (!arr) AliFatalGeneral("LoadWithID",Form("Failed to find segmenation array %s in %s",fgkSegmListName,inpf));
475 int nent = arr->GetEntriesFast();
477 for (int i=nent;i--;) if ((segm=arr->At(i))) dest->AddAtAndExpand(segm,segm->GetUniqueID());
478 AliInfoGeneral("LoadSegmentations",Form("Loaded %d segmantions from %s",arr->GetEntries(),inpf));
479 arr->SetOwner(kFALSE);
487 //______________________________________________________________________
488 void AliITSUSegmentationPix::SetDiodShiftMatrix(Int_t nrow,Int_t ncol, const Double_t *shiftX, const Double_t *shiftZ)
490 // set matrix of periodic shifts of diod center. provided arrays must be in the format shift[nrow][ncol]
491 if (fDiodShiftMatDim) {
492 delete fDiodShidtMatX;
493 delete fDiodShidtMatZ;
494 fDiodShidtMatX = fDiodShidtMatZ = 0;
497 fDiodShiftMatNCol = ncol;
498 fDiodShiftMatNRow = nrow;
499 fDiodShiftMatDim = fDiodShiftMatNCol*fDiodShiftMatNRow;
500 if (fDiodShiftMatDim) {
501 fDiodShidtMatX = new Double32_t[fDiodShiftMatDim];
502 fDiodShidtMatZ = new Double32_t[fDiodShiftMatDim];
503 for (int ir=0;ir<fDiodShiftMatNRow;ir++) {
504 for (int ic=0;ic<fDiodShiftMatNCol;ic++) {
505 int cnt = ic+ir*fDiodShiftMatNCol;
506 fDiodShidtMatX[cnt] = shiftX ? shiftX[cnt] : 0.;
507 fDiodShidtMatZ[cnt] = shiftZ ? shiftZ[cnt] : 0.;
514 //______________________________________________________________________
515 void AliITSUSegmentationPix::Print(Option_t* option) const
518 const double kmc=1e4;
519 printf("Segmentation %d: Size: DX: %.1f DZ: %.1f DY: %.1f | Pitch: X:%.1f Z:%.1f\n",
520 GetUniqueID(),kmc*Dx(),kmc*Dy(),kmc*Dz(),kmc*Dpx(1),kmc*Dpz(1));
521 printf("%d chips along Z: chip Ncol=%d Nrow=%d\n",fNChips, fNColPerChip,fNRow);
522 if (Abs(fPitchZLftCol-fPitchZ)>1e-5) printf("Special left column pitch: %.1f\n",fPitchZLftCol*kmc);
523 if (Abs(fPitchZRgtCol-fPitchZ)>1e-5) printf("Special right column pitch: %.1f\n",fPitchZRgtCol*kmc);
524 printf("Guard-rings: Left: %.1f Right: %.1f Top: %.1f Bottom: %.1f\n",kmc*fGuardLft,kmc*fGuardRgt,kmc*fGuardTop,kmc*fGuardBot);
526 if (fDiodShiftMatDim) {
528 printf("Diod shift periodicity pattern (X,Z[row][col])\n");
529 for (int irow=0;irow<fDiodShiftMatNRow;irow++) {
530 for (int icol=0;icol<fDiodShiftMatNCol;icol++) {
531 GetDiodShift(irow,icol,dx,dz);
532 printf("%.1f/%.1f |",kmc*dx,kmc*dz);
539 //______________________________________________________________________
540 void AliITSUSegmentationPix::GetDiodShift(Int_t row,Int_t col, Float_t &dx,Float_t &dz) const
542 // obtain optional diod shift
543 if (!fDiodShiftMatDim) {dx=dz=0; return;}
544 int cnt = (col%fDiodShiftMatNCol) + (row%fDiodShiftMatNRow)*fDiodShiftMatNCol;
545 dx = fDiodShidtMatX[cnt];
546 dz = fDiodShidtMatZ[cnt];