909b16e7 |
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 | |
451f5018 |
16 | /* $Id: AliITSUSegmentationPix.cxx 47180 2011-02-08 09:42:29Z masera $ */ |
909b16e7 |
17 | #include <TGeoManager.h> |
18 | #include <TGeoVolume.h> |
19 | #include <TGeoBBox.h> |
e5373622 |
20 | #include <TObjArray.h> |
21 | #include <TString.h> |
22 | #include <TSystem.h> |
23 | #include <TFile.h> |
451f5018 |
24 | #include "AliITSUGeomTGeo.h" |
25 | #include "AliITSUSegmentationPix.h" |
a11ef2e4 |
26 | using namespace TMath; |
909b16e7 |
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 | |
451f5018 |
38 | ClassImp(AliITSUSegmentationPix) |
909b16e7 |
39 | |
02d6eccc |
40 | const char* AliITSUSegmentationPix::fgkSegmListName = "ITSUSegmentations"; |
e5373622 |
41 | |
909b16e7 |
42 | //_____________________________________________________________________________RS |
451f5018 |
43 | AliITSUSegmentationPix::AliITSUSegmentationPix(UInt_t id, int nchips,int ncol,int nrow, |
909b16e7 |
44 | double pitchX,double pitchZ, |
909b16e7 |
45 | double thickness, |
e5373622 |
46 | double pitchLftC,double pitchRgtC, |
909b16e7 |
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 | { |
29f5e263 |
63 | // Default constructor, sizes in cm |
451f5018 |
64 | if (nchips) SetUniqueID( AliITSUGeomTGeo::ComposeDetTypeID(id) ); |
909b16e7 |
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 |
451f5018 |
73 | void AliITSUSegmentationPix::GetPadIxz(Float_t x,Float_t z,Int_t &ix,Int_t &iz) const |
909b16e7 |
74 | { |
75 | // Returns pixel coordinates (ix,iz) for given real local coordinates (x,z) |
29f5e263 |
76 | // expects x, z in cm. RS: TO CHECK: why from 1 |
909b16e7 |
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 |
451f5018 |
86 | void AliITSUSegmentationPix::GetPadTxz(Float_t &x,Float_t &z) const |
909b16e7 |
87 | { |
88 | // local transformation of real local coordinates (x,z) |
29f5e263 |
89 | // expects x, z in cm |
909b16e7 |
90 | x /= fPitchX; |
91 | z = Z2Col(z); |
92 | // |
93 | } |
94 | |
95 | //_____________________________________________________________________________RS |
451f5018 |
96 | void AliITSUSegmentationPix::GetPadCxz(Int_t ix,Int_t iz,Float_t &x,Float_t&z) const |
909b16e7 |
97 | { |
98 | // Transform from pixel to real local coordinates |
29f5e263 |
99 | // returns x, z in cm. RS: TO CHECK if indexing starts from 1 or 0 |
909b16e7 |
100 | x = (ix>0) ? Float_t((ix-0.5)*fPitchX) : Float_t((ix+0.5)*fPitchX); |
101 | z = Col2Z(iz); |
102 | // |
103 | } |
104 | |
105 | //_____________________________________________________________________________RS |
451f5018 |
106 | Float_t AliITSUSegmentationPix::Z2Col(Float_t z) const |
909b16e7 |
107 | { |
108 | // get column number (from 0) from local Z |
4fa9d550 |
109 | int chip = int(z/fChipDZ); |
909b16e7 |
110 | float col = chip*fNColPerChip; |
111 | z -= chip*fChipDZ; |
4fa9d550 |
112 | if (z>fPitchZLftCol) col += 1+(z-fPitchZLftCol)/fPitchZ; |
909b16e7 |
113 | return col; |
114 | } |
115 | |
116 | //_____________________________________________________________________________RS |
451f5018 |
117 | Float_t AliITSUSegmentationPix::Col2Z(Int_t col) const |
909b16e7 |
118 | { |
119 | // convert column number (from 0) to Z coordinate |
120 | int nchip = col/fNColPerChip; |
121 | col %= fNColPerChip; |
122 | float z = nchip*fChipDZ; |
4fa9d550 |
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; |
909b16e7 |
128 | return z; |
129 | // |
130 | } |
131 | |
132 | //______________________________________________________________________RS |
451f5018 |
133 | AliITSUSegmentationPix& AliITSUSegmentationPix::operator=(const AliITSUSegmentationPix &src) |
909b16e7 |
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 |
451f5018 |
157 | AliITSUSegmentationPix::AliITSUSegmentationPix(const AliITSUSegmentationPix &src) : |
909b16e7 |
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 |
451f5018 |
176 | Float_t AliITSUSegmentationPix::Dpx(Int_t ) const |
909b16e7 |
177 | { |
178 | //returs x pixel pitch for a give pixel |
179 | return fPitchX; |
180 | } |
181 | |
182 | //____________________________________________________________________________RS |
451f5018 |
183 | Float_t AliITSUSegmentationPix::Dpz(Int_t col) const |
909b16e7 |
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 | //------------------------------ |
451f5018 |
194 | void AliITSUSegmentationPix::Neighbours(Int_t iX, Int_t iZ, Int_t* nlist, Int_t xlist[8], Int_t zlist[8]) const |
909b16e7 |
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 | //______________________________________________________________________ |
451f5018 |
221 | Bool_t AliITSUSegmentationPix::LocalToDet(Float_t x,Float_t z,Int_t &ix,Int_t &iz) const |
909b16e7 |
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. |
29f5e263 |
239 | x += 0.5*Dx(); |
240 | z += 0.5*Dz(); |
909b16e7 |
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 | //______________________________________________________________________ |
451f5018 |
250 | void AliITSUSegmentationPix::DetToLocal(Int_t ix,Int_t iz,Float_t &x,Float_t &z) const |
909b16e7 |
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 | // |
29f5e263 |
265 | x = -0.5*Dx(); // default value. |
266 | z = -0.5*Dz(); // default value. |
909b16e7 |
267 | // RS: to check: why we don't do strict check for [0:n) |
4fa9d550 |
268 | if(ix<0 || ix>fNRow) return; // outside of detector |
269 | if(iz<0 || iz>fNCol) return; // outside of detctor |
29f5e263 |
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); |
909b16e7 |
272 | return; // Found x and z, return. |
273 | } |
274 | |
275 | //______________________________________________________________________ |
451f5018 |
276 | void AliITSUSegmentationPix::CellBoundries(Int_t ix,Int_t iz,Double_t &xl,Double_t &xu,Double_t &zl,Double_t &zu) const |
909b16e7 |
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) { |
29f5e263 |
298 | xl = xu = -0.5*Dx(); // default value. |
299 | zl = zu = -0.5*Dz(); // default value. |
909b16e7 |
300 | return; // outside of detctor |
301 | } |
29f5e263 |
302 | float zpitchH = Dpz(iz)*0.5; |
303 | float xpitchH = fPitchX*0.5; |
909b16e7 |
304 | xl -= xpitchH; |
305 | xu += xpitchH; |
306 | zl -= zpitchH; |
307 | zu += zpitchH; |
308 | return; // Found x and z, return. |
309 | } |
310 | |
311 | //______________________________________________________________________ |
451f5018 |
312 | Int_t AliITSUSegmentationPix::GetChipFromChannel(Int_t, Int_t iz) const |
909b16e7 |
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 | //______________________________________________________________________ |
451f5018 |
323 | Int_t AliITSUSegmentationPix::GetChipFromLocal(Float_t, Float_t zloc) const |
909b16e7 |
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 | //______________________________________________________________________ |
451f5018 |
335 | Int_t AliITSUSegmentationPix::GetChipsInLocalWindow(Int_t* array, Float_t zmin, Float_t zmax, Float_t, Float_t) const |
909b16e7 |
336 | { |
337 | // returns the number of chips containing a road defined by given local coordinate limits |
338 | // |
909b16e7 |
339 | if (zmin>zmax) { |
340 | AliWarning("Bad coordinate limits: zmin>zmax!"); |
341 | return -1; |
342 | } |
343 | // |
344 | Int_t nChipInW = 0; |
345 | // |
29f5e263 |
346 | Float_t zminDet = -0.5*Dz(); |
347 | Float_t zmaxDet = 0.5*Dz(); |
909b16e7 |
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){ |
a11ef2e4 |
358 | Int_t imin=Min(n1,n2); |
359 | Int_t imax=Max(n1,n2); |
909b16e7 |
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 | } |
a84c4b15 |
369 | |
370 | //______________________________________________________________________ |
451f5018 |
371 | void AliITSUSegmentationPix::Init() |
a84c4b15 |
372 | { |
373 | // init settings |
374 | } |
e5373622 |
375 | |
376 | //______________________________________________________________________ |
451f5018 |
377 | Bool_t AliITSUSegmentationPix::Store(const char* outf) |
e5373622 |
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); |
451f5018 |
386 | int id = GetUniqueID(); |
e5373622 |
387 | if (!arr) arr = new TObjArray(); |
451f5018 |
388 | else if (arr->At(id)) {AliFatal(Form("Segmenation %d already exists in file %s",id,outf));return kFALSE;} |
e5373622 |
389 | // |
451f5018 |
390 | arr->AddAtAndExpand(this,id); |
e5373622 |
391 | arr->SetOwner(kTRUE); |
392 | fout->WriteObject(arr,fgkSegmListName,"kSingleKey"); |
393 | fout->Close(); |
394 | delete fout; |
451f5018 |
395 | arr->RemoveAt(id); |
e5373622 |
396 | delete arr; |
397 | AliInfo(Form("Stored segmentation %d in %s",id,outf)); |
398 | return kTRUE; |
399 | // |
400 | } |
401 | |
402 | //______________________________________________________________________ |
451f5018 |
403 | AliITSUSegmentationPix* AliITSUSegmentationPix::LoadWithID(UInt_t id, const char* inpf) |
e5373622 |
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 | } |
451f5018 |
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;} |
e5373622 |
418 | // |
451f5018 |
419 | arr->RemoveAt(id); |
e5373622 |
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 | } |
451f5018 |
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); |
02d6eccc |
445 | arr->Clear(); |
451f5018 |
446 | finp->Close(); |
447 | delete finp; |
448 | delete arr; |
449 | // |
450 | } |