3d9bda953d9ddbd2eef3282369b391cdcf4125ef
[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 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                                                     //
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                                                    double pitchX,double pitchZ,
45                                                    double thickness,
46                                                    double pitchLftC,double pitchRgtC,
47                                                    double edgL,double edgR,double edgT,double edgB)
48 : AliITSsegmentation()
49   ,fGuardLft(edgL)
50   ,fGuardRgt(edgR)
51   ,fGuardTop(edgT)
52   ,fGuardBot(edgB)
53   ,fPitchX(pitchX)
54   ,fPitchZ(pitchZ)
55   ,fPitchZLftCol(pitchLftC<0 ? pitchZ:pitchLftC)
56   ,fPitchZRgtCol(pitchRgtC<0 ? pitchZ:pitchRgtC)
57   ,fChipDZ(0)
58   ,fNChips(nchips)
59   ,fNColPerChip(nchips>0 ? ncol/nchips:0)
60   ,fNRow(nrow)
61   ,fNCol(ncol)
62 {
63   // Default constructor, sizes in cm
64   if (nchips) SetUniqueID( AliITSUGeomTGeo::ComposeDetTypeID(id) );
65   fChipDZ = (fNColPerChip-2)*fPitchZ + fPitchZLftCol + fPitchZRgtCol;
66   SetDetSize( fNRow*fPitchX /*+fGuardTop+fGuardBot*/,
67               fNChips*fChipDZ /*+fGuardLft+fGuardRgt*/,
68               thickness);
69   //
70 }
71
72 //_____________________________________________________________________________RS
73 void AliITSUSegmentationPix::GetPadIxz(Float_t x,Float_t z,Int_t &ix,Int_t &iz) const 
74 {
75   //  Returns pixel coordinates (ix,iz) for given real local coordinates (x,z)
76   //  expects x, z in cm. RS: TO CHECK: why from 1
77   ix = int(x/fPitchX) + 1;     
78   iz = int(Z2Col(z)) + 1;
79   //  
80   if (iz >  fNCol) iz= fNCol;
81   if (ix >  fNRow) ix= fNRow;
82   //
83 }
84
85 //_____________________________________________________________________________RS
86 void AliITSUSegmentationPix::GetPadTxz(Float_t &x,Float_t &z) const
87 {
88   //  local transformation of real local coordinates (x,z)
89   //  expects x, z in cm
90   x /= fPitchX;
91   z = Z2Col(z);
92   //
93 }
94
95 //_____________________________________________________________________________RS
96 void AliITSUSegmentationPix::GetPadCxz(Int_t ix,Int_t iz,Float_t &x,Float_t&z) const
97 {
98   // Transform from pixel to real local coordinates
99   // returns x, z in cm. 
100   x = Float_t((ix+0.5)*fPitchX);
101   z = Col2Z(iz);
102   //
103 }
104
105 //_____________________________________________________________________________RS
106 Float_t AliITSUSegmentationPix::Z2Col(Float_t z) const 
107 {
108   // get column number (from 0) from local Z
109   int chip = int(z/fChipDZ);
110   float col = chip*fNColPerChip;
111   z -= chip*fChipDZ;
112   if (z>fPitchZLftCol) col += 1+(z-fPitchZLftCol)/fPitchZ;
113   return col;
114 }
115
116 //_____________________________________________________________________________RS
117 Float_t AliITSUSegmentationPix::Col2Z(Int_t col) const 
118 {
119   // convert column number (from 0) to Z coordinate
120   int nchip = col/fNColPerChip;
121   col %= fNColPerChip;
122   float z = nchip*fChipDZ;
123   if (col>0) {
124     if (col<fNColPerChip-1) z += fPitchZLftCol + (col-0.5)*fPitchZ;
125     else                    z += fChipDZ - fPitchZRgtCol/2;
126   }
127   else z += fPitchZLftCol/2;
128   return z;
129   //
130 }
131
132 //______________________________________________________________________RS
133 AliITSUSegmentationPix& AliITSUSegmentationPix::operator=(const AliITSUSegmentationPix &src)
134 {
135   // = operator
136   if(this==&src) return *this;
137   AliITSsegmentation::operator=(src);
138   fNCol  = src.fNCol;
139   fNRow  = src.fNRow;
140   fNColPerChip  = src.fNColPerChip;
141   fNChips = src.fNChips;
142   fChipDZ = src.fChipDZ;
143   fPitchZRgtCol = src.fPitchZRgtCol;
144   fPitchZLftCol = src.fPitchZLftCol;
145   fPitchZ = src.fPitchZ;
146   fPitchX = src.fPitchX;
147   //
148   fGuardBot = src.fGuardBot;
149   fGuardTop = src.fGuardTop;
150   fGuardRgt = src.fGuardRgt;
151   fGuardLft = src.fGuardLft;
152   //
153   return *this;
154 }
155
156 //____________________________________________________________________________RS
157 AliITSUSegmentationPix::AliITSUSegmentationPix(const AliITSUSegmentationPix &src) :
158   AliITSsegmentation(src)
159   ,fGuardLft(src.fGuardLft)
160   ,fGuardRgt(src.fGuardRgt)
161   ,fGuardTop(src.fGuardTop)
162   ,fGuardBot(src.fGuardBot)
163   ,fPitchX(src.fPitchX)
164   ,fPitchZ(src.fPitchZ)
165   ,fPitchZLftCol(src.fPitchZLftCol)
166   ,fPitchZRgtCol(src.fPitchZRgtCol)
167   ,fChipDZ(src.fChipDZ)
168   ,fNChips(src.fNChips)
169   ,fNColPerChip(src.fNColPerChip)
170   ,fNRow(src.fNRow)
171   ,fNCol(src.fNCol)  
172 {
173 }
174
175 //____________________________________________________________________________RS
176 Float_t AliITSUSegmentationPix::Dpx(Int_t ) const 
177 {
178   //returs x pixel pitch for a give pixel
179   return fPitchX;
180 }
181
182 //____________________________________________________________________________RS
183 Float_t AliITSUSegmentationPix::Dpz(Int_t col) const 
184 {
185   // returns z pixel pitch for a given pixel (cols starts from 0)
186   col %= fNColPerChip;
187   if (!col) return fPitchZLftCol;
188   if (col==fNColPerChip-1) return fPitchZRgtCol;
189   return fPitchZ;
190   //
191 }
192
193 //------------------------------
194 void AliITSUSegmentationPix::Neighbours(Int_t iX, Int_t iZ, Int_t* nlist, Int_t xlist[8], Int_t zlist[8]) const 
195 {
196   // returns the neighbouring pixels for use in Cluster Finders and the like.
197   //
198   *nlist=8;
199   xlist[0]=xlist[1]=iX;
200   xlist[2]=iX-1;
201   xlist[3]=iX+1;
202   zlist[0]=iZ-1;
203   zlist[1]=iZ+1;
204   zlist[2]=zlist[3]=iZ;
205   // Diagonal elements
206   xlist[4]=iX+1;
207   zlist[4]=iZ+1;
208   //  
209   xlist[5]=iX-1;
210   zlist[5]=iZ-1;
211   //
212   xlist[6]=iX-1;
213   zlist[6]=iZ+1;
214   //
215   xlist[7]=iX+1;
216   zlist[7]=iZ-1;
217   //
218 }
219
220 //______________________________________________________________________
221 Bool_t AliITSUSegmentationPix::LocalToDet(Float_t x,Float_t z,Int_t &ix,Int_t &iz) const 
222 {
223   // Transformation from Geant detector centered local coordinates (cm) to
224   // Pixel cell numbers ix and iz.
225   // Input:
226   //    Float_t   x        detector local coordinate x in cm with respect to
227   //                       the center of the sensitive volume.
228   //    Float_t   z        detector local coordinate z in cm with respect to
229   //                       the center of the sensitive volulme.
230   // Output:
231   //    Int_t    ix        detector x cell coordinate. Has the range 
232   //                       0<=ix<fNRow.
233   //    Int_t    iz        detector z cell coordinate. Has the range 
234   //                       0<=iz<fNCol.
235   // Return:
236   //   kTRUE if point x,z is inside sensitive volume, kFALSE otherwise.
237   //   A value of -1 for ix or iz indecates that this point is outside of the
238   //   detector segmentation as defined.
239   x += 0.5*Dx();
240   z += 0.5*Dz();
241   ix = iz = -1;
242   if(x<0 || x>Dx()) return kFALSE; // outside x range.
243   if(z<0 || z>Dz()) return kFALSE; // outside z range.
244   ix = int(x/fPitchX);
245   iz = Z2Col(z);
246   return kTRUE; // Found ix and iz, return.
247 }
248
249 //______________________________________________________________________
250 void AliITSUSegmentationPix::DetToLocal(Int_t ix,Int_t iz,Float_t &x,Float_t &z) const
251 {
252 // Transformation from Detector cell coordiantes to Geant detector centerd 
253 // local coordinates (cm).
254 // Input:
255 // Int_t    ix        detector x cell coordinate. Has the range 0<=ix<fNRow.
256 // Int_t    iz        detector z cell coordinate. Has the range 0<=iz<fNCol.
257 // Output:
258 // Float_t   x        detector local coordinate x in cm with respect to the
259 //                    center of the sensitive volume.
260 // Float_t   z        detector local coordinate z in cm with respect to the
261 //                    center of the sensitive volulme.
262 // If ix and or iz is outside of the segmentation range a value of -0.5*Dx()
263 // or -0.5*Dz() is returned.
264   //
265   x = -0.5*Dx(); // default value.
266   z = -0.5*Dz(); // default value.
267   // RS: to check: why we don't do strict check for [0:n)
268   if(ix<0 || ix>fNRow) return; // outside of detector 
269   if(iz<0 || iz>fNCol) return; // outside of detctor
270   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
271   z += Col2Z(iz); 
272   return; // Found x and z, return.
273 }
274
275 //______________________________________________________________________
276 void AliITSUSegmentationPix::CellBoundries(Int_t ix,Int_t iz,Double_t &xl,Double_t &xu,Double_t &zl,Double_t &zu) const
277 {
278   // Transformation from Detector cell coordiantes to Geant detector centerd 
279   // local coordinates (cm).
280   // Input:
281   // Int_t    ix        detector x cell coordinate. Has the range 0<=ix<fNRow.
282   // Int_t    iz        detector z cell coordinate. Has the range 0<=iz<fNCol.
283   // Output:
284   // Double_t   xl       detector local coordinate cell lower bounds x in cm
285   //                    with respect to the center of the sensitive volume.
286   // Double_t   xu       detector local coordinate cell upper bounds x in cm 
287   //                    with respect to the center of the sensitive volume.
288   // Double_t   zl       detector local coordinate lower bounds z in cm with
289   //                    respect to the center of the sensitive volulme.
290   // Double_t   zu       detector local coordinate upper bounds z in cm with 
291   //                    respect to the center of the sensitive volulme.
292   // If ix and or iz is outside of the segmentation range a value of -0.5*Dx()
293   // and -0.5*Dx() or -0.5*Dz() and -0.5*Dz() are returned.
294   Float_t x,z;
295   DetToLocal(ix,iz,x,z);
296   //
297   if( ix<0 || ix>=fNRow || iz<0 || iz>=fNCol) {
298     xl = xu = -0.5*Dx(); // default value.
299     zl = zu = -0.5*Dz(); // default value.
300     return; // outside of detctor
301   }
302   float zpitchH = Dpz(iz)*0.5;
303   float xpitchH = fPitchX*0.5;
304   xl -= xpitchH;
305   xu += xpitchH;
306   zl -= zpitchH;
307   zu += zpitchH;
308   return; // Found x and z, return.
309 }
310
311 //______________________________________________________________________
312 Int_t AliITSUSegmentationPix::GetChipFromChannel(Int_t, Int_t iz) const 
313 {
314   // returns chip number (in range 0-4) starting from channel number
315   if(iz>=fNCol  || iz<0 ){
316     AliWarning("Bad cell number");
317     return -1;
318   }
319   return iz/fNColPerChip;
320 }
321
322 //______________________________________________________________________
323 Int_t AliITSUSegmentationPix::GetChipFromLocal(Float_t, Float_t zloc) const 
324 {
325   // returns chip number (in range 0-4) starting from local coordinates
326   Int_t ix0,iz;
327   if (!LocalToDet(0,zloc,ix0,iz)) {
328     AliWarning("Bad local coordinate");
329     return -1;
330   } 
331   return GetChipFromChannel(ix0,iz);
332 }
333
334 //______________________________________________________________________
335 Int_t AliITSUSegmentationPix::GetChipsInLocalWindow(Int_t* array, Float_t zmin, Float_t zmax, Float_t, Float_t) const 
336 {
337   // returns the number of chips containing a road defined by given local coordinate limits
338   //
339   if (zmin>zmax) {
340     AliWarning("Bad coordinate limits: zmin>zmax!");
341     return -1;
342   } 
343   //
344   Int_t nChipInW = 0;
345   //
346   Float_t zminDet = -0.5*Dz();
347   Float_t zmaxDet =  0.5*Dz();
348   if(zmin<zminDet) zmin=zminDet;
349   if(zmax>zmaxDet) zmax=zmaxDet;
350
351   Int_t n1 = GetChipFromLocal(0,zmin);
352   array[nChipInW] = n1;
353   nChipInW++;
354
355   Int_t n2 = GetChipFromLocal(0,zmax);
356
357   if(n2!=n1){
358     Int_t imin=Min(n1,n2);
359     Int_t imax=Max(n1,n2);
360     for(Int_t ichip=imin; ichip<=imax; ichip++){
361       if(ichip==n1) continue;
362       array[nChipInW]=ichip;
363       nChipInW++;
364     }
365   }
366   //
367   return nChipInW;
368 }
369
370 //______________________________________________________________________
371 void AliITSUSegmentationPix::Init()
372 {
373   // init settings
374 }
375
376 //______________________________________________________________________
377 Bool_t AliITSUSegmentationPix::Store(const char* outf)
378 {
379   // store in the special list under given ID
380   TString fns = outf;
381   gSystem->ExpandPathName(fns);
382   if (fns.IsNull()) {AliFatal("No file name provided"); return kFALSE;}
383   TFile* fout = TFile::Open(fns.Data(),"update");
384   if (!fout) {AliFatal(Form("Failed to open output file %s",outf)); return kFALSE;}
385   TObjArray* arr = (TObjArray*)fout->Get(fgkSegmListName);
386   int id = GetUniqueID();
387   if (!arr) arr = new TObjArray();
388   else if (arr->At(id)) {AliFatal(Form("Segmenation %d already exists in file %s",id,outf));return kFALSE;}
389   //
390   arr->AddAtAndExpand(this,id);
391   arr->SetOwner(kTRUE);
392   fout->WriteObject(arr,fgkSegmListName,"kSingleKey");
393   fout->Close();
394   delete fout;
395   arr->RemoveAt(id);
396   delete arr;
397   AliInfo(Form("Stored segmentation %d in %s",id,outf));
398   return kTRUE;
399   //
400 }
401
402 //______________________________________________________________________
403 AliITSUSegmentationPix* AliITSUSegmentationPix::LoadWithID(UInt_t id, const char* inpf)
404 {
405   // store in the special list under given ID
406   TString fns = inpf;
407   gSystem->ExpandPathName(fns);
408   if (fns.IsNull()) {AliFatalGeneral("LoadWithID","No file name provided"); return 0;}
409   TFile* finp = TFile::Open(fns.Data());
410   if (!finp) {AliFatalGeneral("LoadWithID",Form("Failed to open file %s",inpf)); return 0;}
411   TObjArray* arr = (TObjArray*)finp->Get(fgkSegmListName);
412   if (!arr) {
413     AliFatalGeneral("LoadWithID",Form("Failed to find segmenation array %s in %s",fgkSegmListName,inpf)); 
414     return 0;
415   }
416   AliITSUSegmentationPix* segm = dynamic_cast<AliITSUSegmentationPix*>(arr->At(id));
417   if (!segm || segm->GetUniqueID()!=id) {AliFatalGeneral("LoadWithID",Form("Failed to find segmenation %d in %s",id,inpf)); return 0;}
418   //
419   arr->RemoveAt(id);
420   arr->SetOwner(kTRUE); // to not leave in memory other segmenations
421   finp->Close();
422   delete finp;
423   delete arr;
424   //
425   return segm;
426 }
427
428 //______________________________________________________________________
429 void AliITSUSegmentationPix::LoadSegmentations(TObjArray* dest, const char* inpf)
430 {
431   // store in the special list under given ID
432   if (!dest) return;
433   TString fns = inpf;
434   gSystem->ExpandPathName(fns);
435   if (fns.IsNull()) AliFatalGeneral("LoadWithID","No file name provided");
436   TFile* finp = TFile::Open(fns.Data());
437   if (!finp) AliFatalGeneral("LoadWithID",Form("Failed to open file %s",inpf));
438   TObjArray* arr = (TObjArray*)finp->Get(fgkSegmListName);
439   if (!arr) AliFatalGeneral("LoadWithID",Form("Failed to find segmenation array %s in %s",fgkSegmListName,inpf)); 
440   int nent = arr->GetEntriesFast();
441   TObject *segm = 0;
442   for (int i=nent;i--;) if ((segm=arr->At(i))) dest->AddAtAndExpand(segm,segm->GetUniqueID());
443   AliInfoGeneral("LoadSegmentations",Form("Loaded %d segmantions from %s",arr->GetEntries(),inpf));
444   arr->SetOwner(kFALSE);
445   arr->Clear();
446   finp->Close();
447   delete finp;
448   delete arr;
449   //
450 }