]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSPlaneEffSDD.cxx
Possibility to getthe data from zip file
[u/mrichter/AliRoot.git] / ITS / AliITSPlaneEffSDD.cxx
1 /**************************************************************************
2  * Copyright(c) 2007-2009, 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 //  Plane Efficiency class for ITS                      
17 //  It is used for chip by chip efficiency (eventually with sui-bwing division 
18 //  along the drift direction) of the SDD,        
19 //  evaluated by tracks
20 //  (Inherits from AliITSPlaneEff)
21 //  Author: G.E. Bruno 
22 //          giuseppe.bruno@ba.infn.it
23 //
24 ///////////////////////////////////////////////////////////////////////////
25
26 /* $Id$ */
27
28 #include <TMath.h>
29 #include "AliITSPlaneEffSDD.h"
30 #include "AliLog.h"
31 #include "AliCDBStorage.h"
32 #include "AliCDBEntry.h"
33 #include "AliCDBManager.h"
34 //#include "AliCDBRunRange.h"
35 #include "AliITSgeom.h"
36 #include "AliITSCalibrationSDD.h"
37 #include "AliITSsegmentationSDD.h"
38
39 ClassImp(AliITSPlaneEffSDD)     
40 //______________________________________________________________________
41 AliITSPlaneEffSDD::AliITSPlaneEffSDD():
42   AliITSPlaneEff(){
43   for (UInt_t i=0; i<kNModule*kNChip*kNWing*kNSubWing; i++){
44     fFound[i]=0;
45     fTried[i]=0;
46   }
47   // default constructor
48   AliDebug(1,Form("Calling default constructor"));
49 }
50 //______________________________________________________________________
51 AliITSPlaneEffSDD::~AliITSPlaneEffSDD(){
52     // destructor
53     // Inputs:
54     //    none.
55     // Outputs:
56     //    none.
57     // Return:
58     //     none.
59 }
60 //______________________________________________________________________
61 AliITSPlaneEffSDD::AliITSPlaneEffSDD(const AliITSPlaneEffSDD &s) : AliITSPlaneEff(s) //,
62 //fHis(s.fHis),
63 {
64     //     Copy Constructor
65     // Inputs:
66     //    AliITSPlaneEffSDD &s The original class for which
67     //                                this class is a copy of
68     // Outputs:
69     //    none.
70     // Return:
71
72 }
73 //_________________________________________________________________________
74 AliITSPlaneEffSDD& AliITSPlaneEffSDD::operator+=(const AliITSPlaneEffSDD &add){
75     //    Add-to-me operator
76     // Inputs:
77     //    const AliITSPlaneEffSDD &add  simulation class to be added
78     // Outputs:
79     //    none.
80     // Return:
81     //    none
82     for (UInt_t i=0; i<kNModule*kNChip*kNWing*kNSubWing; i++){
83       fFound[i] += add.fFound[i];
84       fTried[i] += add.fTried[i];
85     }
86     return *this;
87 }
88 //______________________________________________________________________
89 AliITSPlaneEffSDD&  AliITSPlaneEffSDD::operator=(const
90                                            AliITSPlaneEffSDD &s){
91     //    Assignment operator
92     // Inputs:
93     //    AliITSPlaneEffSDD &s The original class for which
94     //                                this class is a copy of
95     // Outputs:
96     //    none.
97     // Return:
98  
99     if(this==&s) return *this;
100     s.Copy(*this);
101 //    if(&s == this) return *this;
102 //    for (UInt_t i=0; i<kNModule*kNChip*kNWing*kNSubWing; i++){
103 //      this->fFound[i] = s.fFound[i];
104 //      this->fTried[i] = s.fTried[i];
105 //    }
106     return *this;
107 }
108 //______________________________________________________________________
109 void AliITSPlaneEffSDD::Copy(TObject &obj) const {
110   // protected method. copy this to obj
111   AliITSPlaneEff::Copy(obj);
112   for(Int_t i=0;i<kNModule*kNChip*kNWing*kNSubWing;i++) {
113       ((AliITSPlaneEffSDD& ) obj).fFound[i] = fFound[i];
114       ((AliITSPlaneEffSDD& ) obj).fTried[i] = fTried[i];
115   }
116 }
117 //______________________________________________________________________
118 AliITSPlaneEff&  AliITSPlaneEffSDD::operator=(const
119                                            AliITSPlaneEff &s){
120     //    Assignment operator
121     // Inputs:
122     //    AliITSPlaneEffSDD &s The original class for which
123     //                                this class is a copy of
124     // Outputs:
125     //    none.
126     // Return:
127
128     if(&s == this) return *this;
129     AliError("operator=: Not allowed to make a =, use default creater instead");
130     return *this;
131 }
132 //_______________________________________________________________________
133 Int_t AliITSPlaneEffSDD::GetMissingTracksForGivenEff(Double_t eff, Double_t RelErr,
134           UInt_t im, UInt_t ic, UInt_t iw, UInt_t is) const {
135    
136   //   Estimate the number of tracks still to be collected to attain a 
137   //   given efficiency eff, with relative error RelErr
138   //   Inputs:
139   //         eff    -> Expected efficiency (e.g. those from actual estimate)
140   //         RelErr -> tollerance [0,1] 
141   //         im     -> module number [0,259]
142   //         ic     -> chip number [0,3]
143   //         iw     -> wing number [0,1]
144   //         is     -> chip number [0,kNSubWing-1]
145   //   Outputs: none
146   //   Return: the estimated n. of tracks 
147   //
148 if (im>=kNModule || ic>=kNChip || iw>=kNWing || is>=kNSubWing) 
149  {AliError("GetMissingTracksForGivenEff: you asked for a non existing block");
150  return -1;}
151 else return GetNTracksForGivenEff(eff,RelErr)-fTried[GetKey(im,ic,iw,is)];
152 }
153 //_________________________________________________________________________
154 Double_t  AliITSPlaneEffSDD::PlaneEff(const UInt_t im,const UInt_t ic,
155                                       const UInt_t iw,const UInt_t is) const {
156 // Compute the efficiency for a basic block, 
157 // Inputs:
158 //        im     -> module number [0,259]
159 //        ic     -> chip number [0,3]
160 //        iw     -> wing number [0,1]
161 //        is     -> chip number [0,kNSubWing-1]
162 if (im>=kNModule || ic>=kNChip || iw>=kNWing || is>=kNSubWing) 
163  {AliError("PlaneEff(UInt_t,UInt_t,UInt_t,UInt_t): you asked for a non existing block"); return -1.;}
164  Int_t nf=fFound[GetKey(im,ic,iw,is)];
165  Int_t nt=fTried[GetKey(im,ic,iw,is)];
166 return AliITSPlaneEff::PlaneEff(nf,nt);
167 }
168 //_________________________________________________________________________
169 Double_t  AliITSPlaneEffSDD::ErrPlaneEff(const UInt_t im,const UInt_t ic,
170                                          const UInt_t iw,const UInt_t is) const {
171     // Compute the statistical error on efficiency for a basic block,
172     // using binomial statistics 
173     // Inputs:
174     //        im     -> module number [0,259]
175     //        ic     -> chip number [0,3]
176     //        iw     -> wing number [0,1]
177     //        is     -> chip number [0,kNSubWing-1]
178 if (im>=kNModule || ic>=kNChip || iw>=kNWing || is>=kNSubWing) 
179  {AliError("ErrPlaneEff(UInt_t,UInt_t,UInt_t,UInt_t): you asked for a non existing block"); return -1.;}
180 Int_t nf=fFound[GetKey(im,ic,iw,is)];
181 Int_t nt=fTried[GetKey(im,ic,iw,is)];
182 return AliITSPlaneEff::ErrPlaneEff(nf,nt);
183
184 //_________________________________________________________________________
185 Bool_t AliITSPlaneEffSDD::UpDatePlaneEff(const Bool_t Kfound,
186                                          const UInt_t im, const UInt_t ic,
187                                          const UInt_t iw, const UInt_t is) {
188   // Update efficiency for a basic block
189 if (im>=kNModule || ic>=kNChip || iw>=kNWing || is>=kNSubWing) 
190  {AliError("UpDatePlaneEff: you asked for a non existing block"); return kFALSE;}
191  fTried[GetKey(im,ic,iw,is)]++;
192  if(Kfound) fFound[GetKey(im,ic,iw,is)]++;
193  return kTRUE;
194 }
195 //_________________________________________________________________________
196 void AliITSPlaneEffSDD::ChipAndWingFromAnode(const UInt_t anode, UInt_t& chip,
197                                       UInt_t& wing) const {
198   // Retun the chip number [0,3] and the wing number [0,1] given the anode number
199   // input: anode number [0,511]
200 if(anode>=kNAnode*kNChip*kNWing)
201  {AliError("ChipAndWingFromAnode: you asked for a non existing anode"); 
202   chip=999;
203   wing=99;
204   return;}
205 wing=0;
206 chip=anode/kNAnode;
207 if(anode>=kNChip*kNAnode) wing=1;
208 if(wing==1) chip-=kNChip;
209 return;
210 }
211 //_________________________________________________________________________
212 UInt_t AliITSPlaneEffSDD::ChipFromAnode(const UInt_t anode) const {
213   // Retun the chip number [0,3] given the anode number 
214   // input: anode number [0,511]
215 if(anode>=kNAnode*kNChip*kNWing) 
216  {AliError("ChipFromAnode: you asked for a non existing anode"); return 999;}
217 Int_t wing=0;
218 Int_t chip=anode/kNAnode;
219 if(anode>=kNChip*kNAnode) wing=1;
220 if(wing==1)chip-=kNChip;
221 return chip;
222 }
223 //_________________________________________________________________________
224 UInt_t AliITSPlaneEffSDD::WingFromAnode(const UInt_t anode) const {
225   // return the wing number [0,1] given the anode number 
226   // input: anode number [0,511]
227 if(anode>=kNAnode*kNChip*kNWing) 
228  {AliError("WingFromAnode: you asked for a non existing anode"); return 99;}
229 Int_t wing=0;
230 if(anode>=kNChip*kNAnode) wing=1;
231 return wing;
232 }
233 //__________________________________________________________________________
234 UInt_t AliITSPlaneEffSDD::GetKey(const UInt_t mod, const UInt_t chip,
235                                  const UInt_t wing, const UInt_t subw) const {
236   // get key given a basic block
237 if(mod>=kNModule || chip>=kNChip || wing>= kNWing || subw>=kNSubWing)
238   {AliError("GetKey: you asked for a non existing block"); return 99999;}
239 return mod*kNChip*kNWing*kNSubWing+chip*kNWing*kNSubWing+wing*kNSubWing+subw;
240 }
241 //__________________________________________________________________________
242 UInt_t AliITSPlaneEffSDD::GetModFromKey(const UInt_t key) const {
243   // get mod. from key
244 if(key>=kNModule*kNChip*kNWing*kNSubWing)
245   {AliError("GetModFromKey: you asked for a non existing key"); return 9999;}
246 return key/(kNChip*kNWing*kNSubWing);
247 }
248 //__________________________________________________________________________
249 UInt_t AliITSPlaneEffSDD::GetChipFromKey(const UInt_t key) const {
250   // retrieves chip from key
251 if(key>=kNModule*kNChip*kNWing*kNSubWing)
252   {AliError("GetChipFromKey: you asked for a non existing key"); return 999;}
253 return (key%(kNChip*kNWing*kNSubWing))/(kNWing*kNSubWing);
254 }
255 //__________________________________________________________________________
256 UInt_t AliITSPlaneEffSDD::GetWingFromKey(const UInt_t key) const {
257   // retrieves wing from key
258 if(key>=kNModule*kNChip*kNWing*kNSubWing)
259   {AliError("GetWingFromKey: you asked for a non existing key"); return 99;}
260 return ((key%(kNChip*kNWing*kNSubWing))%(kNWing*kNSubWing))/(kNSubWing);
261 }
262 //__________________________________________________________________________
263 UInt_t AliITSPlaneEffSDD::GetSubWingFromKey(const UInt_t key) const {
264   // retrieves sub-wing from key
265 if(key>=kNModule*kNChip*kNWing*kNSubWing)
266   {AliError("GetSubWingFromKey: you asked for a non existing key"); return 9;}
267 return ((key%(kNChip*kNWing*kNSubWing))%(kNWing*kNSubWing))%(kNSubWing);
268 }
269 //__________________________________________________________________________
270 void AliITSPlaneEffSDD::GetAllFromKey(const UInt_t key,UInt_t& mod,UInt_t& chip,
271                                       UInt_t& wing,UInt_t& subw) const {
272   // get module, chip, wing and subwing from a key
273 if(key>=kNModule*kNChip*kNWing*kNSubWing)
274   {AliError("GetAllFromKey: you asked for a non existing key"); 
275   mod=9999;
276   chip=999;
277   wing=99;
278   subw=9;
279   return;}
280 mod=GetModFromKey(key);
281 chip=GetChipFromKey(key);
282 wing=GetWingFromKey(key);
283 subw=GetSubWingFromKey(key);
284 return;
285 }
286 //____________________________________________________________________________
287 Double_t AliITSPlaneEffSDD::LivePlaneEff(UInt_t key) const {
288   // returns plane efficieny after adding the fraction of sensor which is bad
289 if(key>=kNModule*kNChip*kNWing*kNSubWing)
290   {AliError("LivePlaneEff: you asked for a non existing key");
291    return -1.;}
292 Double_t leff=AliITSPlaneEff::LivePlaneEff(0); // this just for the Warning
293 leff=PlaneEff(key)+GetFracBad(key);
294 return leff>1?1:leff;
295 }
296 //____________________________________________________________________________
297 Double_t AliITSPlaneEffSDD::ErrLivePlaneEff(UInt_t key) const {
298   // returns error on live plane efficiency
299 if(key>=kNModule*kNChip*kNWing*kNSubWing)
300   {AliError("ErrLivePlaneEff: you asked for a non existing key");
301    return -1.;}
302 Int_t nf=fFound[key];
303 Double_t triedInLive=GetFracLive(key)*fTried[key];
304 Int_t nt=TMath::Max(nf,TMath::Nint(triedInLive));
305 return AliITSPlaneEff::ErrPlaneEff(nf,nt); // for the time being: to be checked
306 }
307 //_____________________________________________________________________________
308 Double_t AliITSPlaneEffSDD::GetFracLive(const UInt_t key) const {
309   // returns the fraction of the sensor which is OK
310 if(key>=kNModule*kNChip*kNWing*kNSubWing)
311   {AliError("GetFracLive: you asked for a non existing key");
312    return -1.;}
313     // Compute the fraction of bad (dead+noisy) detector 
314 UInt_t bad=0;
315 GetBadInBlock(key,bad);
316 Double_t live=bad;
317 live/=(kNAnode);
318 return 1.-live;
319 }
320 //_____________________________________________________________________________
321 void AliITSPlaneEffSDD::GetBadInBlock(const UInt_t key, UInt_t& nrBadInBlock) const {
322   // Compute the number of bad (dead+noisy) anodes inside a block
323   // (it depends on the chip, not on the sub-wing)
324 nrBadInBlock=0;
325 if(key>=kNModule*kNChip*kNWing*kNSubWing)
326   {AliError("GetBadInBlock: you asked for a non existing key");
327    return;}
328 //
329 if(!fInitCDBCalled) 
330   {AliError("GetBadInBlock: CDB not inizialized: call InitCDB first");
331    return;};
332 AliCDBManager* man = AliCDBManager::Instance();
333 // retrieve map of dead Pixel 
334 AliCDBEntry *cdbSDD = man->Get("ITS/Calib/CalibSDD", fRunNumber);
335 TObjArray* sddEntry;
336 if(cdbSDD) {
337   sddEntry = (TObjArray*)cdbSDD->GetObject();
338   if(!sddEntry) 
339   {AliError("GetBadInBlock: SDDEntry not found in CDB");
340    return;}
341 } else {
342   AliError("GetBadInBlock: Did not find Calib/CalibSDD");
343   return;
344 }
345 //
346 UInt_t mod=GetModFromKey(key);
347 UInt_t chip=GetChipFromKey(key);
348 UInt_t wing=GetWingFromKey(key);
349 // count number of dead
350 AliITSCalibrationSDD* calibSDD=(AliITSCalibrationSDD*) sddEntry->At(mod);
351 UInt_t nrBad = calibSDD-> GetDeadChannels();
352 for (UInt_t index=0; index<nrBad; index++) {
353   if(ChipFromAnode(calibSDD->GetBadChannel(index))==chip &&
354      WingFromAnode(calibSDD->GetBadChannel(index))==wing    ) nrBadInBlock++;
355 }
356 return;
357 }
358 //_____________________________________________________________________________
359 Double_t AliITSPlaneEffSDD::GetFracBad(const UInt_t key) const {
360   // returns 1-fractional live
361 if(key>=kNModule*kNChip*kNWing*kNSubWing)
362   {AliError("GetFracBad: you asked for a non existing key");
363    return -1.;}
364 return 1.-GetFracLive(key);
365 }
366 //_____________________________________________________________________________
367 Bool_t AliITSPlaneEffSDD::WriteIntoCDB() const {
368 // write onto CDB
369 if(!fInitCDBCalled)
370   {AliError("WriteIntoCDB: CDB not inizialized: call InitCDB first");
371    return kFALSE;}
372 // to be written properly: now only for debugging 
373   AliCDBMetaData *md= new AliCDBMetaData(); // metaData describing the object
374   md->SetObjectClassName("AliITSPlaneEff");
375   md->SetResponsible("Giuseppe Eugenio Bruno");
376   md->SetBeamPeriod(0);
377   md->SetAliRootVersion("head 02/01/08"); //root version
378   AliCDBId id("ITS/PlaneEff/PlaneEffSDD",0,AliCDBRunRange::Infinity()); 
379   AliITSPlaneEffSDD eff; 
380   eff=*this;
381   Bool_t r=AliCDBManager::Instance()->GetDefaultStorage()->Put(&eff,id,md);
382   delete md;
383   return r;
384 }
385 //_____________________________________________________________________________
386 Bool_t AliITSPlaneEffSDD::ReadFromCDB() {
387 // read from CDB
388 if(!fInitCDBCalled)
389   {AliError("ReadFromCDB: CDB not inizialized: call InitCDB first");
390    return kFALSE;}
391 //if(!AliCDBManager::Instance()->IsDefaultStorageSet()) {
392 //    AliCDBManager::Instance()->SetDefaultStorage("local://$ALICE_ROOT");
393 //  }
394 AliCDBEntry *cdbEntry = AliCDBManager::Instance()->Get("ITS/PlaneEff/PlaneEffSDD",fRunNumber);
395 AliITSPlaneEffSDD* eff= (AliITSPlaneEffSDD*)cdbEntry->GetObject();
396 if(this==eff) return kFALSE;
397 eff->Copy(*this);
398 return kTRUE;
399 }
400 //_____________________________________________________________________________
401 UInt_t AliITSPlaneEffSDD::GetKeyFromDetLocCoord(Int_t ilay, Int_t idet,
402                                                 Float_t locx, Float_t locz) const {
403 // method to locate a basic block from Detector Local coordinate (to be used in tracking)
404 //
405 // If kNSubWing = 1, i.e. no sub-wing subdivision, then the numbering scheme of the 
406 // unique key is the following, e.g. for the first detector (idet=0,  ilayer=2)
407 //
408 //                            ^x_loc (cm)
409 //                            |
410 //   _________________________|__________________________ 3.5085
411 //  |            |            |            |            |
412 //  |            |            |            |            |
413 //  |            |            |            |            |
414 //  |   key=1    |   key=3    |   key=5    |   key=7    |
415 //  |            |            |            |            |
416 //  |____________|____________|____________|____________|_0_____\  local z (cm)
417 //  |            |            |            |            |       /
418 //  |            |            |            |            |
419 //  |   key=0    |   key=2    |   key=4    |   key=6    |
420 //  |            |            |            |            |
421 //  |            |            |            |            |
422 //  |____________|____________|____________|____________| -3.5085
423 //-3.7632     -1.8816         0          1.1186      3.7632 
424 //
425 // for the second detector (idet=2, ilay=2), first key is 8 (bottom-left), 
426 // last one is 15 (upper-right), and so on. 
427 //
428 // If subwing division has been applied, then you count in each wing, starting from 
429 // the one with negative local ,  from the anode side (outer part) towards the 
430 // cathod strip (center). 
431 //                    first column: 
432 //                      bottom wing   (from below): 0,1,..,kNSubWing-1, 
433 //                      upper wing    (from up):    kNSubWing, ... , 2*kNSubWing-1
434 //                    2nd column  
435 //                      bottom wing   (from below): 2*kNSubWing, .. , 3*kNSubWing-1
436 //                      upper wing    (from up):    3*kNSubWing, ... ,4*kNSubWing-1
437 //                      ... 
438 //                    4nd (last) column :   
439 //                      bottom wing   (from below): 6*kNSubWing, .. , 7*kNSubWing-1
440 //                      upper wing    (from up):    7*kNSubWing, ... ,8*kNSubWing-1
441 //
442 // E.g. kNSubWing=2.
443 //
444 //                            ^x_loc (cm)
445 //                            |   
446 //   _________________________|__________________________ 3.5085
447 //  |            |            |            |            |
448 //  |   key=2    |   key=6    |   key=10   |   key=14   |
449 //  |____________|____________|____________|____________|
450 //  |            |            |            |            |
451 //  |   key=3    |   key=7    |   key=11   |   key=15   |
452 //  |____________|____________|____________|____________|_0_____\  local z (cm)
453 //  |            |            |            |            |       /
454 //  |   key=1    |   key=5    |   key=9    |   key=13   |
455 //  |____________|____________|____________|____________|
456 //  |            |            |            |            |
457 //  |   key=0    |   key=4    |   key=8    |   key=12   |
458 //  |____________|____________|____________|____________| -3.5085
459 //-3.7632     -1.8816         0          1.1186      3.7632 
460 //
461 //___________________________________________________________________________
462 //
463 UInt_t key=999999;
464 if(ilay<2 || ilay>3)
465   {AliError("GetKeyFromDetLocCoord: you asked for a non existing layer");
466    return key;}
467 if(ilay==2 && (idet<0 || idet>83))
468  {AliError("GetKeyFromDetLocCoord: you asked for a non existing detector");
469    return key;}
470 if(ilay==3 && (idet<0 || idet>175))
471  {AliError("GetKeyFromDetLocCoord: you asked for a non existing detector");
472    return key;}
473 UInt_t mod=idet;
474 if(ilay==3) mod+=84;
475 UInt_t chip=0,wing=0,subw=0;
476 ChipAndWingAndSubWingFromLocCoor(locx,locz,chip,wing,subw);
477 key=GetKey(mod,chip,wing,subw);
478 return key;
479 }
480 //_____________________________________________________________________________
481 void AliITSPlaneEffSDD::ChipAndWingAndSubWingFromLocCoor(Float_t xloc, Float_t zloc, 
482                                 UInt_t& chip, UInt_t& wing, UInt_t& subw) const {
483 AliITSgeom* geom=NULL;
484 //AliITSsegmentationSDD* sdd=new AliITSsegmentationSDD(geom);
485 AliITSsegmentationSDD sdd=AliITSsegmentationSDD(geom);
486 sdd.SetDriftSpeed(sdd.GetDriftSpeed()); // this only for setting fSetDriftSpeed=kTRUE !!!
487 Int_t ix,iz;
488 Int_t ntb;
489 UInt_t anode=0;
490 if(sdd.LocalToDet(xloc,zloc,ix,iz)) {  
491   anode+=iz; 
492   ChipAndWingFromAnode(anode,chip,wing);
493   if(sdd.LocalToDet(0.,0.,ntb,iz)) {  // in this way the sub-division along time coordinate
494     subw=SubWingFromTimeBin(ix,ntb); }  // is purely geometrical one and it does not 
495   else {                                // depen on the drift-velocity. 
496     AliError("ChipAndWingAndSubWingFromLocCoor: cannot calculate n. of time bins for SubWing.");
497     subw=9;
498   }
499 } else {
500   AliError("ChipAndWingAndSubWingFromLocCoor: cannot calculate anode number and time bin."); 
501   chip=999; 
502   wing=99; 
503   subw=9;
504 }
505 delete geom;
506 }
507 //__________________________________________________________________________________
508 UInt_t AliITSPlaneEffSDD::SubWingFromTimeBin(const Int_t tb, const Int_t ntb) const {
509 if(tb<0 || tb>ntb || ntb<0) {
510  AliError(Form("SubWingFromTimeBin: you asked time bin = %d with %d n. of bins",tb,ntb));
511  return 9;
512 }
513 //AliDebug(Form("tb = %d, ntb= %d , NSubWing = %d",tb,ntb,kNSubWing));
514 Float_t h=tb;
515  h/=ntb;
516  h*=(kNSubWing-1);
517 return TMath::Nint(h);
518 }
519 //________________________________________________________
520 Bool_t AliITSPlaneEffSDD::GetBlockBoundaries(const UInt_t key, Float_t& xmn,Float_t& xmx,
521                                              Float_t& zmn,Float_t& zmx) const {
522 //
523 //  This method return the geometrical boundaries of the active volume of a given
524 //  basic block, in the detector reference system.
525 //  Input: unique key to locate a basic block.
526 //
527 //  Output: Ymin, Ymax, Zmin, Zmax of a basic block (chip for SPD)
528 //  Return: kTRUE if computation was succesfully, kFALSE otherwise
529 //
530 // the following scheemes will help in following the method implementation
531 // E.g. kNSubWing=1
532 //                            ^x_loc (cm)
533 //     for all: subw=0        |
534 //   _________________________|__________________________ 3.5085
535 //  |   wing=1   |   wing=1   |   wing=1   |   wing=1   |
536 //  |   chip=0   |   chip=1   |   chip=2   |   chip=3   |
537 //  |   key=1    |   key=3    |   key=5    |   key=7    |
538 //  |____________|____________|____________|____________|_0_____\  local z (cm)
539 //  |   wing=0   |   wing=0   |   wing=0   |   wing=0   |       /
540 //  |   chip=0   |   chip=1   |   chip=2   |   chip=3   |
541 //  |   key=0    |   key=2    |   key=4    |   key=6    |
542 //  |____________|____________|____________|____________| -3.5085
543 //-3.7632     -1.8816         0          1.1186      3.7632
544 //
545 // E.g. kNSubWing=2
546 //                            ^x_loc (cm)
547 //                            |
548 //   _________________________|__________________________ 3.5085
549 //  |   chip=0   |   chip=1   |   chip=2   |   chip=3   |
550 //  |   key=2    |   key=6    |   key=10   |   key=14   | subw=0
551 //  |____________|____________|____________|____________|        wing=1
552 //  |   chip=0   |   chip=1   |   chip=2   |   chip=3   | subw=1
553 //  |   key=3    |   key=7    |   key=11   |   key=15   |
554 //  |____________|____________|____________|____________|_0________\  local z (cm)
555 //  |   chip=0   |   chip=1   |   chip=2   |   chip=3   |          /
556 //  |   key=1    |   key=5    |   key=9    |   key=13   | subw=1
557 //  |____________|____________|____________|____________|        wing=0
558 //  |   chip=0   |   chip=1   |   chip=2   |   chip=3   | subw=0  
559 //  |   key=0    |   key=4    |   key=8    |   key=12   | 
560 //  |____________|____________|____________|____________| -3.5085
561 //-3.7632     -1.8816         0          1.1186      3.7632
562 //
563 if(key>=kNModule*kNChip*kNWing*kNSubWing)
564   {AliWarning("GetBlockBoundaries: you asked for a non existing key"); return kFALSE;}
565 //
566 const Float_t kDxDefault = 35085.; // For Plane Eff. purpouses, default values
567 const Float_t kDzDefault = 75264.; // are precise enough !!!
568 const Float_t kconv = 1.0E-04;  //converts microns to cm.
569 UInt_t chip=GetChipFromKey(key);
570 UInt_t wing=GetWingFromKey(key);
571 UInt_t subw=GetSubWingFromKey(key);
572 zmn=kconv*(kDzDefault/kNChip*chip-0.5*kDzDefault);
573 zmx=kconv*(kDzDefault/kNChip*(chip+1)-0.5*kDzDefault);
574 if(wing==0) { // count from below
575 xmn=kconv*(kDxDefault/kNSubWing*subw-kDxDefault);
576 xmx=kconv*(kDxDefault/kNSubWing*(subw+1)-kDxDefault);
577 }
578 else if(wing==1) { // count from top
579 xmx=kconv*(kDxDefault-kDxDefault/kNSubWing*subw);
580 xmn=kconv*(kDxDefault-kDxDefault/kNSubWing*(subw+1));
581 }
582 else {AliError("GetBlockBoundaries: you got wrong n. of wing"); return kFALSE;}
583 return kTRUE;
584 }
585 //________________________________________________________