AliITSv11GeometrySPD has added missing parts, set up to help with
[u/mrichter/AliRoot.git] / ITS / AliITSPlaneEffSDD.cxx
CommitLineData
6344adcc 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
7167ae53 17// It is used for chip by chip efficiency (eventually with sui-bwing division
18// along the drift direction) of the SDD,
6344adcc 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"
7167ae53 35#include "AliITSgeom.h"
6344adcc 36#include "AliITSCalibrationSDD.h"
7167ae53 37#include "AliITSsegmentationSDD.h"
6344adcc 38
39ClassImp(AliITSPlaneEffSDD)
40//______________________________________________________________________
41AliITSPlaneEffSDD::AliITSPlaneEffSDD():
42 AliITSPlaneEff(){
6344adcc 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//______________________________________________________________________
51AliITSPlaneEffSDD::~AliITSPlaneEffSDD(){
52 // destructor
53 // Inputs:
54 // none.
55 // Outputs:
56 // none.
57 // Return:
58 // none.
59}
60//______________________________________________________________________
61AliITSPlaneEffSDD::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//_________________________________________________________________________
74AliITSPlaneEffSDD& 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//______________________________________________________________________
89AliITSPlaneEffSDD& 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//______________________________________________________________________
109void 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//______________________________________________________________________
118AliITSPlaneEff& 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;
7167ae53 129 AliError("operator=: Not allowed to make a =, use default creater instead");
6344adcc 130 return *this;
131}
132//_______________________________________________________________________
133Int_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 //
148if (im>=kNModule || ic>=kNChip || iw>=kNWing || is>=kNSubWing)
7167ae53 149 {AliError("GetMissingTracksForGivenEff: you asked for a non existing block");
6344adcc 150 return -1;}
151else return GetNTracksForGivenEff(eff,RelErr)-fTried[GetKey(im,ic,iw,is)];
152}
153//_________________________________________________________________________
154Double_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]
162if (im>=kNModule || ic>=kNChip || iw>=kNWing || is>=kNSubWing)
7167ae53 163 {AliError("PlaneEff(UInt_t,UInt_t,UInt_t,UInt_t): you asked for a non existing block"); return -1.;}
6344adcc 164 Int_t nf=fFound[GetKey(im,ic,iw,is)];
165 Int_t nt=fTried[GetKey(im,ic,iw,is)];
166return AliITSPlaneEff::PlaneEff(nf,nt);
167}
168//_________________________________________________________________________
169Double_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]
178if (im>=kNModule || ic>=kNChip || iw>=kNWing || is>=kNSubWing)
7167ae53 179 {AliError("ErrPlaneEff(UInt_t,UInt_t,UInt_t,UInt_t): you asked for a non existing block"); return -1.;}
6344adcc 180Int_t nf=fFound[GetKey(im,ic,iw,is)];
181Int_t nt=fTried[GetKey(im,ic,iw,is)];
182return AliITSPlaneEff::ErrPlaneEff(nf,nt);
183}
184//_________________________________________________________________________
185Bool_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
189if (im>=kNModule || ic>=kNChip || iw>=kNWing || is>=kNSubWing)
7167ae53 190 {AliError("UpDatePlaneEff: you asked for a non existing block"); return kFALSE;}
6344adcc 191 fTried[GetKey(im,ic,iw,is)]++;
192 if(Kfound) fFound[GetKey(im,ic,iw,is)]++;
193 return kTRUE;
194}
195//_________________________________________________________________________
196void 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]
200if(anode>=kNAnode*kNChip*kNWing)
7167ae53 201 {AliError("ChipAndWingFromAnode: you asked for a non existing anode");
6344adcc 202 chip=999;
203 wing=99;
204 return;}
205wing=0;
206chip=anode/kNAnode;
207if(anode>=kNChip*kNAnode) wing=1;
208if(wing==1) chip-=kNChip;
209return;
210}
211//_________________________________________________________________________
212UInt_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]
215if(anode>=kNAnode*kNChip*kNWing)
7167ae53 216 {AliError("ChipFromAnode: you asked for a non existing anode"); return 999;}
6344adcc 217Int_t wing=0;
218Int_t chip=anode/kNAnode;
219if(anode>=kNChip*kNAnode) wing=1;
220if(wing==1)chip-=kNChip;
221return chip;
222}
223//_________________________________________________________________________
224UInt_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]
227if(anode>=kNAnode*kNChip*kNWing)
7167ae53 228 {AliError("WingFromAnode: you asked for a non existing anode"); return 99;}
6344adcc 229Int_t wing=0;
230if(anode>=kNChip*kNAnode) wing=1;
231return wing;
232}
233//__________________________________________________________________________
234UInt_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
237if(mod>=kNModule || chip>=kNChip || wing>= kNWing || subw>=kNSubWing)
7167ae53 238 {AliError("GetKey: you asked for a non existing block"); return 99999;}
6344adcc 239return mod*kNChip*kNWing*kNSubWing+chip*kNWing*kNSubWing+wing*kNSubWing+subw;
240}
241//__________________________________________________________________________
242UInt_t AliITSPlaneEffSDD::GetModFromKey(const UInt_t key) const {
243 // get mod. from key
244if(key>=kNModule*kNChip*kNWing*kNSubWing)
7167ae53 245 {AliError("GetModFromKey: you asked for a non existing key"); return 9999;}
6344adcc 246return key/(kNChip*kNWing*kNSubWing);
247}
248//__________________________________________________________________________
249UInt_t AliITSPlaneEffSDD::GetChipFromKey(const UInt_t key) const {
250 // retrieves chip from key
251if(key>=kNModule*kNChip*kNWing*kNSubWing)
7167ae53 252 {AliError("GetChipFromKey: you asked for a non existing key"); return 999;}
6344adcc 253return (key%(kNChip*kNWing*kNSubWing))/(kNWing*kNSubWing);
254}
255//__________________________________________________________________________
256UInt_t AliITSPlaneEffSDD::GetWingFromKey(const UInt_t key) const {
257 // retrieves wing from key
258if(key>=kNModule*kNChip*kNWing*kNSubWing)
7167ae53 259 {AliError("GetWingFromKey: you asked for a non existing key"); return 99;}
6344adcc 260return ((key%(kNChip*kNWing*kNSubWing))%(kNWing*kNSubWing))/(kNSubWing);
261}
262//__________________________________________________________________________
263UInt_t AliITSPlaneEffSDD::GetSubWingFromKey(const UInt_t key) const {
264 // retrieves sub-wing from key
265if(key>=kNModule*kNChip*kNWing*kNSubWing)
7167ae53 266 {AliError("GetSubWingFromKey: you asked for a non existing key"); return 9;}
6344adcc 267return ((key%(kNChip*kNWing*kNSubWing))%(kNWing*kNSubWing))%(kNSubWing);
268}
269//__________________________________________________________________________
270void 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
273if(key>=kNModule*kNChip*kNWing*kNSubWing)
7167ae53 274 {AliError("GetAllFromKey: you asked for a non existing key");
6344adcc 275 mod=9999;
276 chip=999;
277 wing=99;
278 subw=9;
279 return;}
280mod=GetModFromKey(key);
281chip=GetChipFromKey(key);
282wing=GetWingFromKey(key);
283subw=GetSubWingFromKey(key);
284return;
285}
286//____________________________________________________________________________
287Double_t AliITSPlaneEffSDD::LivePlaneEff(UInt_t key) const {
288 // returns plane efficieny after adding the fraction of sensor which is bad
289if(key>=kNModule*kNChip*kNWing*kNSubWing)
7167ae53 290 {AliError("LivePlaneEff: you asked for a non existing key");
6344adcc 291 return -1.;}
292Double_t leff=AliITSPlaneEff::LivePlaneEff(0); // this just for the Warning
293leff=PlaneEff(key)+GetFracBad(key);
294return leff>1?1:leff;
295}
296//____________________________________________________________________________
297Double_t AliITSPlaneEffSDD::ErrLivePlaneEff(UInt_t key) const {
298 // returns error on live plane efficiency
299if(key>=kNModule*kNChip*kNWing*kNSubWing)
7167ae53 300 {AliError("ErrLivePlaneEff: you asked for a non existing key");
6344adcc 301 return -1.;}
302Int_t nf=fFound[key];
303Double_t triedInLive=GetFracLive(key)*fTried[key];
304Int_t nt=TMath::Max(nf,TMath::Nint(triedInLive));
305return AliITSPlaneEff::ErrPlaneEff(nf,nt); // for the time being: to be checked
306}
307//_____________________________________________________________________________
308Double_t AliITSPlaneEffSDD::GetFracLive(const UInt_t key) const {
309 // returns the fraction of the sensor which is OK
310if(key>=kNModule*kNChip*kNWing*kNSubWing)
7167ae53 311 {AliError("GetFracLive: you asked for a non existing key");
6344adcc 312 return -1.;}
313 // Compute the fraction of bad (dead+noisy) detector
314UInt_t bad=0;
315GetBadInBlock(key,bad);
316Double_t live=bad;
317live/=(kNAnode);
318return 1.-live;
319}
320//_____________________________________________________________________________
321void 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)
324nrBadInBlock=0;
325if(key>=kNModule*kNChip*kNWing*kNSubWing)
7167ae53 326 {AliError("GetBadInBlock: you asked for a non existing key");
6344adcc 327 return;}
328//
329if(!fInitCDBCalled)
7167ae53 330 {AliError("GetBadInBlock: CDB not inizialized: call InitCDB first");
6344adcc 331 return;};
332AliCDBManager* man = AliCDBManager::Instance();
333// retrieve map of dead Pixel
334AliCDBEntry *cdbSDD = man->Get("ITS/Calib/CalibSDD", fRunNumber);
335TObjArray* sddEntry;
336if(cdbSDD) {
337 sddEntry = (TObjArray*)cdbSDD->GetObject();
338 if(!sddEntry)
7167ae53 339 {AliError("GetBadInBlock: SDDEntry not found in CDB");
6344adcc 340 return;}
341} else {
7167ae53 342 AliError("GetBadInBlock: Did not find Calib/CalibSDD");
6344adcc 343 return;
344}
345//
346UInt_t mod=GetModFromKey(key);
347UInt_t chip=GetChipFromKey(key);
348UInt_t wing=GetWingFromKey(key);
349// count number of dead
350AliITSCalibrationSDD* calibSDD=(AliITSCalibrationSDD*) sddEntry->At(mod);
351UInt_t nrBad = calibSDD-> GetDeadChannels();
352for (UInt_t index=0; index<nrBad; index++) {
353 if(ChipFromAnode(calibSDD->GetBadChannel(index))==chip &&
354 WingFromAnode(calibSDD->GetBadChannel(index))==wing ) nrBadInBlock++;
355}
356return;
357}
358//_____________________________________________________________________________
359Double_t AliITSPlaneEffSDD::GetFracBad(const UInt_t key) const {
360 // returns 1-fractional live
361if(key>=kNModule*kNChip*kNWing*kNSubWing)
7167ae53 362 {AliError("GetFracBad: you asked for a non existing key");
6344adcc 363 return -1.;}
364return 1.-GetFracLive(key);
365}
366//_____________________________________________________________________________
367Bool_t AliITSPlaneEffSDD::WriteIntoCDB() const {
368// write onto CDB
369if(!fInitCDBCalled)
7167ae53 370 {AliError("WriteIntoCDB: CDB not inizialized: call InitCDB first");
6344adcc 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//_____________________________________________________________________________
386Bool_t AliITSPlaneEffSDD::ReadFromCDB() {
387// read from CDB
388if(!fInitCDBCalled)
7167ae53 389 {AliError("ReadFromCDB: CDB not inizialized: call InitCDB first");
6344adcc 390 return kFALSE;}
391//if(!AliCDBManager::Instance()->IsDefaultStorageSet()) {
392// AliCDBManager::Instance()->SetDefaultStorage("local://$ALICE_ROOT");
393// }
394AliCDBEntry *cdbEntry = AliCDBManager::Instance()->Get("ITS/PlaneEff/PlaneEffSDD",fRunNumber);
395AliITSPlaneEffSDD* eff= (AliITSPlaneEffSDD*)cdbEntry->GetObject();
396if(this==eff) return kFALSE;
397eff->Copy(*this);
398return kTRUE;
399}
7167ae53 400//_____________________________________________________________________________
401UInt_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//
463UInt_t key=999999;
464if(ilay<2 || ilay>3)
465 {AliError("GetKeyFromDetLocCoord: you asked for a non existing layer");
466 return key;}
467if(ilay==2 && (idet<0 || idet>83))
468 {AliError("GetKeyFromDetLocCoord: you asked for a non existing detector");
469 return key;}
470if(ilay==3 && (idet<0 || idet>175))
471 {AliError("GetKeyFromDetLocCoord: you asked for a non existing detector");
472 return key;}
473UInt_t mod=idet;
474if(ilay==3) mod+=84;
475UInt_t chip=0,wing=0,subw=0;
476ChipAndWingAndSubWingFromLocCoor(locx,locz,chip,wing,subw);
477key=GetKey(mod,chip,wing,subw);
478return key;
479}
480//_____________________________________________________________________________
481void AliITSPlaneEffSDD::ChipAndWingAndSubWingFromLocCoor(Float_t xloc, Float_t zloc,
482 UInt_t& chip, UInt_t& wing, UInt_t& subw) const {
483AliITSgeom* geom=NULL;
484//AliITSsegmentationSDD* sdd=new AliITSsegmentationSDD(geom);
485AliITSsegmentationSDD sdd=AliITSsegmentationSDD(geom);
486sdd.SetDriftSpeed(sdd.GetDriftSpeed()); // this only for setting fSetDriftSpeed=kTRUE !!!
487Int_t ix,iz;
488Int_t ntb;
489UInt_t anode=0;
490if(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}
505delete geom;
506}
507//__________________________________________________________________________________
508UInt_t AliITSPlaneEffSDD::SubWingFromTimeBin(const Int_t tb, const Int_t ntb) const {
509if(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));
514Float_t h=tb;
515 h/=ntb;
516 h*=(kNSubWing-1);
517return TMath::Nint(h);
518}