Fix for ITS dictionaries
[u/mrichter/AliRoot.git] / ITS / UPGRADE / AliITSUSegmentationPix.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
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  **************************************************************************/
15
16 /* $Id: AliITSUSegmentationPix.cxx 47180 2011-02-08 09:42:29Z masera $ */
17 #include <TGeoManager.h>
18 #include <TGeoVolume.h>
19 #include <TGeoBBox.h>
20 #include <TObjArray.h>
21 #include <TString.h>
22 #include <TSystem.h>
23 #include <TFile.h>
24 #include "AliITSUGeomTGeo.h"
25 #include "AliITSUSegmentationPix.h"
26 using namespace TMath;
27
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                                                     //
35 //                                                                                                        //
36 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
37
38 ClassImp(AliITSUSegmentationPix)
39
40 const char* AliITSUSegmentationPix::fgkSegmListName = "ITSUSegmentations";
41
42 //_____________________________________________________________________________RS
43 AliITSUSegmentationPix::AliITSUSegmentationPix(UInt_t id, int nchips,int ncol,int nrow,
44                                                    float pitchX,float pitchZ,
45                                                    float thickness,
46                                                    float pitchLftC,float pitchRgtC,
47                                                    float edgL,float edgR,float edgT,float edgB)
48 : AliITSsegmentation()
49   ,fGuardLft(edgL)
50   ,fGuardRgt(edgR)
51   ,fGuardTop(edgT)
52   ,fGuardBot(edgB)
53   ,fShiftXLoc(0.5*(edgT-edgB))
54   ,fShiftZLoc(0.5*(edgR-edgL))
55   ,fDxActive(0)
56   ,fDzActive(0)
57   ,fPitchX(pitchX)
58   ,fPitchZ(pitchZ)
59   ,fPitchZLftCol(pitchLftC<0 ? pitchZ:pitchLftC)
60   ,fPitchZRgtCol(pitchRgtC<0 ? pitchZ:pitchRgtC)
61   ,fChipDZ(0)
62   ,fNChips(nchips)
63   ,fNColPerChip(nchips>0 ? ncol/nchips:0)
64   ,fNRow(nrow)
65   ,fNCol(ncol)
66   ,fDiodShiftMatNCol(0)
67   ,fDiodShiftMatNRow(0)
68   ,fDiodShiftMatDim(0)
69   ,fDiodShidtMatX(0)
70   ,fDiodShidtMatZ(0)
71 {
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,
79               thickness);
80   //
81 }
82
83 //_____________________________________________________________________________RS
84 AliITSUSegmentationPix::~AliITSUSegmentationPix()
85 {
86   // d-tor
87   delete[] fDiodShidtMatX;
88   delete[] fDiodShidtMatZ;
89 }
90
91
92 //_____________________________________________________________________________RS
93 void AliITSUSegmentationPix::GetPadIxz(Float_t x,Float_t z,Int_t &ix,Int_t &iz) const 
94 {
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.
97   ix = int(x/fPitchX);     
98   iz = int(Z2Col(z));
99   //  
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;}
104   //
105 }
106
107 //_____________________________________________________________________________RS
108 void AliITSUSegmentationPix::GetPadTxz(Float_t &x,Float_t &z) const
109 {
110   //  local transformation of real local coordinates (x,z)
111   //  expects x, z in cm (wrt corner of col/row 0:0
112   x /= fPitchX;
113   z = Z2Col(z);
114   //
115 }
116
117 //_____________________________________________________________________________RS
118 void AliITSUSegmentationPix::GetPadCxz(Int_t ix,Int_t iz,Float_t &x,Float_t&z) const
119 {
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);
123   z = Col2Z(iz);
124   //
125 }
126
127 //_____________________________________________________________________________RS
128 Float_t AliITSUSegmentationPix::Z2Col(Float_t z) const 
129 {
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;
133   z -= chip*fChipDZ;
134   if (z>fPitchZLftCol) col += 1+(z-fPitchZLftCol)/fPitchZ;
135   return col;
136 }
137
138 //_____________________________________________________________________________RS
139 Float_t AliITSUSegmentationPix::Col2Z(Int_t col) const 
140 {
141   // convert column number (from 0) to Z coordinate wrt bottom left corner of the active matrix
142   int nchip = col/fNColPerChip;
143   col %= fNColPerChip;
144   float z = nchip*fChipDZ;
145   if (col>0) {
146     if (col<fNColPerChip-1) z += fPitchZLftCol + (col-0.5)*fPitchZ;
147     else                    z += fChipDZ - fPitchZRgtCol/2;
148   }
149   else z += fPitchZLftCol/2;
150   return z;
151   //
152 }
153
154 //______________________________________________________________________RS
155 AliITSUSegmentationPix& AliITSUSegmentationPix::operator=(const AliITSUSegmentationPix &src)
156 {
157   // = operator
158   if(this==&src) return *this;
159   AliITSsegmentation::operator=(src);
160   fNCol  = src.fNCol;
161   fNRow  = src.fNRow;
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;
173   //
174   fGuardBot = src.fGuardBot;
175   fGuardTop = src.fGuardTop;
176   fGuardRgt = src.fGuardRgt;
177   fGuardLft = src.fGuardLft;
178   //
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];
190     }
191   }
192   //
193   return *this;
194 }
195
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)
214   ,fNRow(src.fNRow)
215   ,fNCol(src.fNCol)  
216   ,fDiodShiftMatNCol(src.fDiodShiftMatNCol)
217   ,fDiodShiftMatNRow(src.fDiodShiftMatNRow)
218   ,fDiodShiftMatDim(src.fDiodShiftMatDim)
219   ,fDiodShidtMatX(0)
220   ,fDiodShidtMatZ(0)
221 {
222   // copy constructor
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];
229     }
230   }
231 }
232
233 //____________________________________________________________________________RS
234 Float_t AliITSUSegmentationPix::Dpx(Int_t ) const 
235 {
236   //returs x pixel pitch for a give pixel
237   return fPitchX;
238 }
239
240 //____________________________________________________________________________RS
241 Float_t AliITSUSegmentationPix::Dpz(Int_t col) const 
242 {
243   // returns z pixel pitch for a given pixel (cols starts from 0)
244   col %= fNColPerChip;
245   if (!col) return fPitchZLftCol;
246   if (col==fNColPerChip-1) return fPitchZRgtCol;
247   return fPitchZ;
248   //
249 }
250
251 //------------------------------
252 void AliITSUSegmentationPix::Neighbours(Int_t iX, Int_t iZ, Int_t* nlist, Int_t xlist[8], Int_t zlist[8]) const 
253 {
254   // returns the neighbouring pixels for use in Cluster Finders and the like.
255   //
256   *nlist=8;
257   xlist[0]=xlist[1]=iX;
258   xlist[2]=iX-1;
259   xlist[3]=iX+1;
260   zlist[0]=iZ-1;
261   zlist[1]=iZ+1;
262   zlist[2]=zlist[3]=iZ;
263   // Diagonal elements
264   xlist[4]=iX+1;
265   zlist[4]=iZ+1;
266   //  
267   xlist[5]=iX-1;
268   zlist[5]=iZ-1;
269   //
270   xlist[6]=iX-1;
271   zlist[6]=iZ+1;
272   //
273   xlist[7]=iX+1;
274   zlist[7]=iZ-1;
275   //
276 }
277
278 //______________________________________________________________________
279 Bool_t AliITSUSegmentationPix::LocalToDet(Float_t x,Float_t z,Int_t &ix,Int_t &iz) const 
280 {
281   // Transformation from Geant detector centered local coordinates (cm) to
282   // Pixel cell numbers ix and iz.
283   // Input:
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.
288   // Output:
289   //    Int_t    ix        detector x cell coordinate. Has the range 
290   //                       0<=ix<fNRow.
291   //    Int_t    iz        detector z cell coordinate. Has the range 
292   //                       0<=iz<fNCol.
293   // Return:
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;
299   ix = iz = -1;
300   if(x<0 || x>DxActive()) return kFALSE; // outside x range.
301   if(z<0 || z>DzActive()) return kFALSE; // outside z range.
302   ix = int(x/fPitchX);
303   iz = Z2Col(z);
304   return kTRUE; // Found ix and iz, return.
305 }
306
307 //______________________________________________________________________
308 void AliITSUSegmentationPix::DetToLocal(Int_t ix,Int_t iz,Float_t &x,Float_t &z) const
309 {
310 // Transformation from Detector cell coordiantes to Geant detector centered 
311 // local coordinates (cm).
312 // Input:
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.
315 // Output:
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.
322   //
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.
330 }
331
332 //______________________________________________________________________
333 void AliITSUSegmentationPix::CellBoundries(Int_t ix,Int_t iz,Double_t &xl,Double_t &xu,Double_t &zl,Double_t &zu) const
334 {
335   // Transformation from Detector cell coordiantes to Geant detector centerd 
336   // local coordinates (cm).
337   // Input:
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.
340   // Output:
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.
351   Float_t x,z;
352   DetToLocal(ix,iz,x,z);
353   //
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
358   }
359   float zpitchH = Dpz(iz)*0.5;
360   float xpitchH = fPitchX*0.5;
361   xl -= xpitchH;
362   xu += xpitchH;
363   zl -= zpitchH;
364   zu += zpitchH;
365   return; // Found x and z, return.
366 }
367
368 //______________________________________________________________________
369 Int_t AliITSUSegmentationPix::GetChipFromChannel(Int_t, Int_t iz) const 
370 {
371   // returns chip number (in range 0-4) starting from channel number
372   if(iz>=fNCol  || iz<0 ){
373     AliWarning("Bad cell number");
374     return -1;
375   }
376   return iz/fNColPerChip;
377 }
378
379 //______________________________________________________________________
380 Int_t AliITSUSegmentationPix::GetChipFromLocal(Float_t, Float_t zloc) const 
381 {
382   // returns chip number (in range 0-4) starting from local Geant coordinates
383   Int_t ix0,iz;
384   if (!LocalToDet(0,zloc,ix0,iz)) {
385     AliWarning("Bad local coordinate");
386     return -1;
387   } 
388   return GetChipFromChannel(ix0,iz);
389 }
390
391 //______________________________________________________________________
392 Int_t AliITSUSegmentationPix::GetChipsInLocalWindow(Int_t* array, Float_t zmin, Float_t zmax, Float_t, Float_t) const 
393 {
394   // returns the number of chips containing a road defined by given local Geant coordinate limits
395   //
396   if (zmin>zmax) {
397     AliWarning("Bad coordinate limits: zmin>zmax!");
398     return -1;
399   } 
400   //
401   Int_t nChipInW = 0;
402   //
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;
407
408   Int_t n1 = GetChipFromLocal(0,zmin);
409   array[nChipInW] = n1;
410   nChipInW++;
411
412   Int_t n2 = GetChipFromLocal(0,zmax);
413
414   if(n2!=n1){
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;
420       nChipInW++;
421     }
422   }
423   //
424   return nChipInW;
425 }
426
427 //______________________________________________________________________
428 void AliITSUSegmentationPix::Init()
429 {
430   // init settings
431 }
432
433 //______________________________________________________________________
434 Bool_t AliITSUSegmentationPix::Store(const char* outf)
435 {
436   // store in the special list under given ID
437   TString fns = outf;
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;}
446   //
447   arr->AddAtAndExpand(this,id);
448   arr->SetOwner(kTRUE);
449   fout->WriteObject(arr,fgkSegmListName,"kSingleKey");
450   fout->Close();
451   delete fout;
452   arr->RemoveAt(id);
453   delete arr;
454   AliInfo(Form("Stored segmentation %d in %s",id,outf));
455   return kTRUE;
456   //
457 }
458
459 //______________________________________________________________________
460 AliITSUSegmentationPix* AliITSUSegmentationPix::LoadWithID(UInt_t id, const char* inpf)
461 {
462   // store in the special list under given ID
463   TString fns = inpf;
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);
469   if (!arr) {
470     AliFatalGeneral("LoadWithID",Form("Failed to find segmenation array %s in %s",fgkSegmListName,inpf)); 
471     return 0;
472   }
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;}
475   //
476   arr->RemoveAt(id);
477   arr->SetOwner(kTRUE); // to not leave in memory other segmenations
478   finp->Close();
479   delete finp;
480   delete arr;
481   //
482   return segm;
483 }
484
485 //______________________________________________________________________
486 void AliITSUSegmentationPix::LoadSegmentations(TObjArray* dest, const char* inpf)
487 {
488   // store in the special list under given ID
489   if (!dest) return;
490   TString fns = inpf;
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();
498   TObject *segm = 0;
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);
502   arr->Clear();
503   finp->Close();
504   delete finp;
505   delete arr;
506   //
507 }
508
509 //______________________________________________________________________
510 void AliITSUSegmentationPix::SetDiodShiftMatrix(Int_t nrow,Int_t ncol, const Float_t *shiftX, const Float_t *shiftZ)
511 {
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;
517   }
518   //
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.;
530       }
531     }
532   }
533   
534 }
535 //______________________________________________________________________
536 void AliITSUSegmentationPix::SetDiodShiftMatrix(Int_t nrow,Int_t ncol, const Double_t *shiftX, const Double_t *shiftZ)
537 {
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;
543   }
544   //
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.;
556       }
557     }
558   }
559 }
560
561 //______________________________________________________________________
562 void AliITSUSegmentationPix::Print(Option_t* /*option*/) const
563 {
564   // print itself
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);
573   //
574   if (fDiodShiftMatDim) {
575     double dx,dz=0;
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);
581       }
582       printf("\n");
583     }
584   }
585 }
586
587 //______________________________________________________________________
588 void AliITSUSegmentationPix::GetDiodShift(Int_t row,Int_t col, Float_t &dx,Float_t &dz) const
589 {
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];  
595   //
596 }