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