1 /**************************************************************************
2 * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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)
22 // giuseppe.bruno@ba.infn.it
24 ///////////////////////////////////////////////////////////////////////////
29 #include "AliITSPlaneEffSDD.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"
39 ClassImp(AliITSPlaneEffSDD)
40 //______________________________________________________________________
41 AliITSPlaneEffSDD::AliITSPlaneEffSDD():
43 for (UInt_t i=0; i<kNModule*kNChip*kNWing*kNSubWing; i++){
47 // default constructor
48 AliDebug(1,Form("Calling default constructor"));
50 //______________________________________________________________________
51 AliITSPlaneEffSDD::~AliITSPlaneEffSDD(){
60 //______________________________________________________________________
61 AliITSPlaneEffSDD::AliITSPlaneEffSDD(const AliITSPlaneEffSDD &s) : AliITSPlaneEff(s) //,
66 // AliITSPlaneEffSDD &s The original class for which
67 // this class is a copy of
73 //_________________________________________________________________________
74 AliITSPlaneEffSDD& AliITSPlaneEffSDD::operator+=(const AliITSPlaneEffSDD &add){
77 // const AliITSPlaneEffSDD &add simulation class to be added
82 for (UInt_t i=0; i<kNModule*kNChip*kNWing*kNSubWing; i++){
83 fFound[i] += add.fFound[i];
84 fTried[i] += add.fTried[i];
88 //______________________________________________________________________
89 AliITSPlaneEffSDD& AliITSPlaneEffSDD::operator=(const
90 AliITSPlaneEffSDD &s){
91 // Assignment operator
93 // AliITSPlaneEffSDD &s The original class for which
94 // this class is a copy of
99 if(this==&s) return *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];
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];
117 //______________________________________________________________________
118 AliITSPlaneEff& AliITSPlaneEffSDD::operator=(const
120 // Assignment operator
122 // AliITSPlaneEffSDD &s The original class for which
123 // this class is a copy of
128 if(&s == this) return *this;
129 AliError("operator=: Not allowed to make a =, use default creater instead");
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 {
136 // Estimate the number of tracks still to be collected to attain a
137 // given efficiency eff, with relative error RelErr
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]
146 // Return: the estimated n. of tracks
148 if (im>=kNModule || ic>=kNChip || iw>=kNWing || is>=kNSubWing)
149 {AliError("GetMissingTracksForGivenEff: you asked for a non existing block");
151 else return GetNTracksForGivenEff(eff,RelErr)-fTried[GetKey(im,ic,iw,is)];
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,
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);
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
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);
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)]++;
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");
207 if(anode>=kNChip*kNAnode) wing=1;
208 if(wing==1) chip-=kNChip;
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;}
218 Int_t chip=anode/kNAnode;
219 if(anode>=kNChip*kNAnode) wing=1;
220 if(wing==1)chip-=kNChip;
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;}
230 if(anode>=kNChip*kNAnode) wing=1;
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;
241 //__________________________________________________________________________
242 UInt_t AliITSPlaneEffSDD::GetModFromKey(const UInt_t key) const {
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);
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);
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);
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);
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");
280 mod=GetModFromKey(key);
281 chip=GetChipFromKey(key);
282 wing=GetWingFromKey(key);
283 subw=GetSubWingFromKey(key);
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");
292 Double_t leff=AliITSPlaneEff::LivePlaneEff(0); // this just for the Warning
293 leff=PlaneEff(key)+GetFracBad(key);
294 return leff>1?1:leff;
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");
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
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");
313 // Compute the fraction of bad (dead+noisy) detector
315 GetBadInBlock(key,bad);
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)
325 if(key>=kNModule*kNChip*kNWing*kNSubWing)
326 {AliError("GetBadInBlock: you asked for a non existing key");
330 {AliError("GetBadInBlock: CDB not inizialized: call InitCDB first");
332 AliCDBManager* man = AliCDBManager::Instance();
333 // retrieve map of dead Pixel
334 AliCDBEntry *cdbSDD = man->Get("ITS/Calib/CalibSDD", fRunNumber);
337 sddEntry = (TObjArray*)cdbSDD->GetObject();
339 {AliError("GetBadInBlock: SDDEntry not found in CDB");
342 AliError("GetBadInBlock: Did not find Calib/CalibSDD");
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++;
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");
364 return 1.-GetFracLive(key);
366 //_____________________________________________________________________________
367 Bool_t AliITSPlaneEffSDD::WriteIntoCDB() const {
370 {AliError("WriteIntoCDB: CDB not inizialized: call InitCDB first");
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;
381 Bool_t r=AliCDBManager::Instance()->GetDefaultStorage()->Put(&eff,id,md);
385 //_____________________________________________________________________________
386 Bool_t AliITSPlaneEffSDD::ReadFromCDB() {
389 {AliError("ReadFromCDB: CDB not inizialized: call InitCDB first");
391 //if(!AliCDBManager::Instance()->IsDefaultStorageSet()) {
392 // AliCDBManager::Instance()->SetDefaultStorage("local://$ALICE_ROOT");
394 AliCDBEntry *cdbEntry = AliCDBManager::Instance()->Get("ITS/PlaneEff/PlaneEffSDD",fRunNumber);
395 AliITSPlaneEffSDD* eff= (AliITSPlaneEffSDD*)cdbEntry->GetObject();
396 if(this==eff) return kFALSE;
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)
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)
410 // _________________________|__________________________ 3.5085
414 // | key=1 | key=3 | key=5 | key=7 |
416 // |____________|____________|____________|____________|_0_____\ local z (cm)
419 // | key=0 | key=2 | key=4 | key=6 |
422 // |____________|____________|____________|____________| -3.5085
423 //-3.7632 -1.8816 0 1.1186 3.7632
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.
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).
432 // bottom wing (from below): 0,1,..,kNSubWing-1,
433 // upper wing (from up): kNSubWing, ... , 2*kNSubWing-1
435 // bottom wing (from below): 2*kNSubWing, .. , 3*kNSubWing-1
436 // upper wing (from up): 3*kNSubWing, ... ,4*kNSubWing-1
438 // 4nd (last) column :
439 // bottom wing (from below): 6*kNSubWing, .. , 7*kNSubWing-1
440 // upper wing (from up): 7*kNSubWing, ... ,8*kNSubWing-1
446 // _________________________|__________________________ 3.5085
448 // | key=2 | key=6 | key=10 | key=14 |
449 // |____________|____________|____________|____________|
451 // | key=3 | key=7 | key=11 | key=15 |
452 // |____________|____________|____________|____________|_0_____\ local z (cm)
454 // | key=1 | key=5 | key=9 | key=13 |
455 // |____________|____________|____________|____________|
457 // | key=0 | key=4 | key=8 | key=12 |
458 // |____________|____________|____________|____________| -3.5085
459 //-3.7632 -1.8816 0 1.1186 3.7632
461 //___________________________________________________________________________
465 {AliError("GetKeyFromDetLocCoord: you asked for a non existing layer");
467 if(ilay==2 && (idet<0 || idet>83))
468 {AliError("GetKeyFromDetLocCoord: you asked for a non existing detector");
470 if(ilay==3 && (idet<0 || idet>175))
471 {AliError("GetKeyFromDetLocCoord: you asked for a non existing detector");
475 UInt_t chip=0,wing=0,subw=0;
476 ChipAndWingAndSubWingFromLocCoor(locx,locz,chip,wing,subw);
477 key=GetKey(mod,chip,wing,subw);
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 !!!
490 if(sdd.LocalToDet(xloc,zloc,ix,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.");
500 AliError("ChipAndWingAndSubWingFromLocCoor: cannot calculate anode number and time bin.");
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));
513 //AliDebug(Form("tb = %d, ntb= %d , NSubWing = %d",tb,ntb,kNSubWing));
517 return TMath::Nint(h);
519 //________________________________________________________
520 Bool_t AliITSPlaneEffSDD::GetBlockBoundaries(const UInt_t key, Float_t& xmn,Float_t& xmx,
521 Float_t& zmn,Float_t& zmx) const {
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.
527 // Output: Ymin, Ymax, Zmin, Zmax of a basic block (chip for SPD)
528 // Return: kTRUE if computation was succesfully, kFALSE otherwise
530 // the following scheemes will help in following the method implementation
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
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
563 if(key>=kNModule*kNChip*kNWing*kNSubWing)
564 {AliWarning("GetBlockBoundaries: you asked for a non existing key"); return kFALSE;}
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);
578 else if(wing==1) { // count from top
579 xmx=kconv*(kDxDefault-kDxDefault/kNSubWing*subw);
580 xmn=kconv*(kDxDefault-kDxDefault/kNSubWing*(subw+1));
582 else {AliError("GetBlockBoundaries: you got wrong n. of wing"); return kFALSE;}
585 //________________________________________________________