]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSPlaneEffSPD.cxx
Creation of AliAlignObjParam with equivalent transformation for sensitive volumes
[u/mrichter/AliRoot.git] / ITS / AliITSPlaneEffSPD.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 of the SPD,        
18 //  evaluated by tracks
19 //  (Inherits from AliITSPlaneEff)
20 //  Author: G.E. Bruno 
21 //          giuseppe.bruno@ba.infn.it
22 //
23 ///////////////////////////////////////////////////////////////////////////
24
25 /* $Id$ */
26
27 #include <TMath.h>
28 #include "AliITSPlaneEffSPD.h"
29 #include "AliLog.h"
30 #include "AliCDBStorage.h"
31 #include "AliCDBEntry.h"
32 #include "AliCDBManager.h"
33 //#include "AliCDBRunRange.h"
34 //#include "AliITSsegmentationSPD.h"
35 #include "AliITSCalibrationSPD.h"
36
37 ClassImp(AliITSPlaneEffSPD)     
38 //______________________________________________________________________
39 AliITSPlaneEffSPD::AliITSPlaneEffSPD():
40   AliITSPlaneEff(){
41 //  for (UInt_t im=0; im<kNModule; im++){
42 //  for (UInt_t ic=0; ic<kNChip; ic++){
43 //    fFound[im][ic]=0;
44 //    fTried[im][ic]=0;
45 //  }}
46   for (UInt_t i=0; i<kNModule*kNChip; i++){
47     fFound[i]=0;
48     fTried[i]=0;
49   }
50   // default constructor
51   AliDebug(1,Form("Calling default constructor"));
52 }
53 //______________________________________________________________________
54 AliITSPlaneEffSPD::~AliITSPlaneEffSPD(){
55     // destructor
56     // Inputs:
57     //    none.
58     // Outputs:
59     //    none.
60     // Return:
61     //     none.
62 }
63 //______________________________________________________________________
64 AliITSPlaneEffSPD::AliITSPlaneEffSPD(const AliITSPlaneEffSPD &s) : AliITSPlaneEff(s) //,
65 //fHis(s.fHis),
66 {
67     //     Copy Constructor
68     // Inputs:
69     //    AliITSPlaneEffSPD &s The original class for which
70     //                                this class is a copy of
71     // Outputs:
72     //    none.
73     // Return:
74
75 }
76 //_________________________________________________________________________
77 AliITSPlaneEffSPD& AliITSPlaneEffSPD::operator+=(const AliITSPlaneEffSPD &add){
78     //    Add-to-me operator
79     // Inputs:
80     //    const AliITSPlaneEffSPD &add  simulation class to be added
81     // Outputs:
82     //    none.
83     // Return:
84     //    none
85     for (UInt_t i=0; i<kNModule*kNChip; i++){
86       fFound[i] += add.fFound[i];
87       fTried[i] += add.fTried[i];
88     }
89     return *this;
90 }
91 //______________________________________________________________________
92 AliITSPlaneEffSPD&  AliITSPlaneEffSPD::operator=(const
93                                            AliITSPlaneEffSPD &s){
94     //    Assignment operator
95     // Inputs:
96     //    AliITSPlaneEffSPD &s The original class for which
97     //                                this class is a copy of
98     // Outputs:
99     //    none.
100     // Return:
101  
102     if(this==&s) return *this;
103     s.Copy(*this);
104 //    if(&s == this) return *this;
105 //    for (UInt_t i=0; i<kNModule*kNChip; i++){
106 //      this->fFound[i] = s.fFound[i];
107 //      this->fTried[i] = s.fTried[i];
108 //    }
109     return *this;
110 }
111 //______________________________________________________________________
112 void AliITSPlaneEffSPD::Copy(TObject &obj) const {
113   // protected method. copy this to obj
114   AliITSPlaneEff::Copy(obj);
115   //((AliITSPlaneEffSPD& ) obj).fNpx  = fNpx;
116   for(Int_t i=0;i<kNModule*kNChip;i++) {
117       ((AliITSPlaneEffSPD& ) obj).fFound[i] = fFound[i];
118       ((AliITSPlaneEffSPD& ) obj).fTried[i] = fTried[i];
119   }
120 }
121 //______________________________________________________________________
122 AliITSPlaneEff&  AliITSPlaneEffSPD::operator=(const
123                                            AliITSPlaneEff &s){
124     //    Assignment operator
125     // Inputs:
126     //    AliITSPlaneEffSPD &s The original class for which
127     //                                this class is a copy of
128     // Outputs:
129     //    none.
130     // Return:
131
132     if(&s == this) return *this;
133     AliError("operator=: Not allowed to make a =, use default creater instead");
134     return *this;
135 }
136 //_______________________________________________________________________
137 Int_t AliITSPlaneEffSPD::GetMissingTracksForGivenEff(Double_t eff, Double_t RelErr,
138           UInt_t im, UInt_t ic) const {
139    
140   //   Estimate the number of tracks still to be collected to attain a 
141   //   given efficiency eff, with relative error RelErr
142   //   Inputs:
143   //         eff    -> Expected efficiency (e.g. those from actual estimate)
144   //         RelErr -> tollerance [0,1] 
145   //         im     -> module number [0,249]
146   //         ic     -> chip number [0,4]
147   //   Outputs: none
148   //   Return: the estimated n. of tracks 
149   //
150 if (im>=kNModule || ic>=kNChip) 
151  {AliError("GetMissingTracksForGivenEff: you asked for a non existing chip");
152  return -1;}
153 else return GetNTracksForGivenEff(eff,RelErr)-fTried[GetKey(im,ic)];
154 }
155 //_________________________________________________________________________
156 Double_t  AliITSPlaneEffSPD::PlaneEff(const UInt_t im,const UInt_t ic) const {
157 // Compute the efficiency for a basic block, 
158 // Inputs:
159 //        im     -> module number [0,249]
160 //        ic     -> chip number [0,4] 
161 if (im>=kNModule || ic>=kNChip) 
162  {AliError("PlaneEff(Uint_t,Uint_t): you asked for a non existing chip"); return -1.;}
163  Int_t nf=fFound[GetKey(im,ic)];
164  Int_t nt=fTried[GetKey(im,ic)];
165 return AliITSPlaneEff::PlaneEff(nf,nt);
166 }
167 //_________________________________________________________________________
168 Double_t  AliITSPlaneEffSPD::ErrPlaneEff(const UInt_t im,const UInt_t ic) const {
169     // Compute the statistical error on efficiency for a basic block,
170     // using binomial statistics 
171     // Inputs:
172     //        im     -> module number [0,249]
173     //        ic     -> chip number [0,4] 
174 if (im>=kNModule || ic>=kNChip) 
175  {AliError("ErrPlaneEff(Uint_t,Uint_t): you asked for a non existing chip"); return -1.;}
176 Int_t nf=fFound[GetKey(im,ic)];
177 Int_t nt=fTried[GetKey(im,ic)];
178 return AliITSPlaneEff::ErrPlaneEff(nf,nt);
179
180 //_________________________________________________________________________
181 Bool_t AliITSPlaneEffSPD::UpDatePlaneEff(const Bool_t Kfound,
182                                          const UInt_t im, const UInt_t ic) {
183   // Update efficiency for a basic block
184 if (im>=kNModule || ic>=kNChip) 
185  {AliError("UpDatePlaneEff: you asked for a non existing chip"); return kFALSE;}
186  fTried[GetKey(im,ic)]++;
187  if(Kfound) fFound[GetKey(im,ic)]++;
188  return kTRUE;
189 }
190 //_________________________________________________________________________
191 UInt_t AliITSPlaneEffSPD::GetChipFromCol(const UInt_t col) const {
192   // get chip given the column
193 if(col>=kNCol*kNChip) 
194  {AliDebug(1,Form("GetChipFromCol: you asked for a non existing column %d",col)); return 10;}
195 return col/kNCol;
196 }
197 //__________________________________________________________________________
198 UInt_t AliITSPlaneEffSPD::GetKey(const UInt_t mod, const UInt_t chip) const {
199   // get key given a basic block
200 if(mod>=kNModule || chip>=kNChip)
201   {AliWarning("GetKey: you asked for a non existing block"); return 99999;}
202 return mod*kNChip+chip;
203 }
204 //__________________________________________________________________________
205 UInt_t AliITSPlaneEffSPD::GetModFromKey(const UInt_t key) const {
206   // get mod. from key
207 if(key>=kNModule*kNChip)
208   {AliError("GetModFromKey: you asked for a non existing key"); return 9999;}
209 return key/kNChip;
210 }
211 //__________________________________________________________________________
212 UInt_t AliITSPlaneEffSPD::GetChipFromKey(const UInt_t key) const {
213   // retrieves chip from key
214 if(key>=kNModule*kNChip)
215   {AliError("GetChipFromKey: you asked for a non existing key"); return 999;}
216 return (key%(kNModule*kNChip))%kNChip;
217 }
218 //__________________________________________________________________________
219 void AliITSPlaneEffSPD::GetModAndChipFromKey(const UInt_t key,UInt_t& mod,UInt_t& chip) const {
220   // get module and chip from a key
221 if(key>=kNModule*kNChip)
222   {AliError("GetModAndChipFromKey: you asked for a non existing key"); 
223   mod=9999;
224   chip=999;
225   return;}
226 mod=key/kNChip;
227 chip=(key%(kNModule*kNChip))%kNChip;
228 return;
229 }
230 //____________________________________________________________________________
231 Double_t AliITSPlaneEffSPD::LivePlaneEff(UInt_t key) const {
232   // returns plane efficieny after adding the fraction of sensor which is bad
233 if(key>=kNModule*kNChip)
234   {AliError("LivePlaneEff: you asked for a non existing key");
235    return -1.;}
236 Double_t leff=AliITSPlaneEff::LivePlaneEff(0); // this just for the Warning
237 leff=PlaneEff(key)+GetFracBad(key);
238 return leff>1?1:leff;
239 }
240 //____________________________________________________________________________
241 Double_t AliITSPlaneEffSPD::ErrLivePlaneEff(UInt_t key) const {
242   // returns error on live plane efficiency
243 if(key>=kNModule*kNChip)
244   {AliError("ErrLivePlaneEff: you asked for a non existing key");
245    return -1.;}
246 Int_t nf=fFound[key];
247 Double_t triedInLive=GetFracLive(key)*fTried[key];
248 Int_t nt=TMath::Max(nf,TMath::Nint(triedInLive));
249 return AliITSPlaneEff::ErrPlaneEff(nf,nt); // for the time being: to be checked
250 }
251 //_____________________________________________________________________________
252 Double_t AliITSPlaneEffSPD::GetFracLive(const UInt_t key) const {
253   // returns the fraction of the sensor which is OK
254 if(key>=kNModule*kNChip)
255   {AliError("GetFracLive: you asked for a non existing key");
256    return -1.;}
257     // Compute the fraction of bad (dead+noisy) detector 
258 UInt_t dead=0,noisy=0;
259 GetDeadAndNoisyInChip(key,dead,noisy);
260 Double_t live=dead+noisy;
261 live/=(kNRow*kNCol);
262 return 1.-live;
263 }
264 //_____________________________________________________________________________
265 void AliITSPlaneEffSPD::GetDeadAndNoisyInChip(const UInt_t key,
266       UInt_t& nrDeadInChip, UInt_t& nrNoisyInChip) const {
267   // returns the number of dead and noisy pixels
268 nrDeadInChip=0;
269 nrNoisyInChip=0;
270 if(key>=kNModule*kNChip)
271   {AliError("GetDeadAndNoisyInChip: you asked for a non existing key");
272    return;}
273     // Compute the number of bad (dead+noisy) pixel in a chip
274 //
275 if(!fInitCDBCalled) 
276   {AliError("GetDeadAndNoisyInChip: CDB not inizialized: call InitCDB first");
277    return;};
278 AliCDBManager* man = AliCDBManager::Instance();
279 // retrieve map of dead Pixel 
280 AliCDBEntry *cdbSPDDead = man->Get("ITS/Calib/SPDDead", fRunNumber);
281 TObjArray* spdDead;
282 if(cdbSPDDead) {
283   spdDead = (TObjArray*)cdbSPDDead->GetObject();
284   if(!spdDead) 
285   {AliError("GetDeadAndNoisyInChip: SPDDead not found in CDB");
286    return;}
287 } else {
288   AliError("GetDeadAndNoisyInChip: did not find Calib/SPDDead.");
289   return;
290 }
291 // retrieve map of noisy Pixel 
292 AliCDBEntry *cdbSPDNoisy = man->Get("ITS/Calib/SPDNoisy", fRunNumber);
293 TObjArray* spdNoisy;
294 if(cdbSPDNoisy) {
295   spdNoisy = (TObjArray*)cdbSPDNoisy->GetObject();
296   if(!spdNoisy) 
297   {AliError("GetDeadAndNoisyInChip: SPDNoisy not found in CDB");
298    return;}
299 } else {
300   AliError("GetDeadAndNoisyInChip: did not find Calib/SPDNoisy.");
301   return;
302 }
303 //
304 UInt_t mod=GetModFromKey(key);
305 UInt_t chip=GetChipFromKey(key);
306 // count number of dead
307 AliITSCalibrationSPD* calibSPD=(AliITSCalibrationSPD*) spdDead->At(mod);
308 UInt_t nrDead = calibSPD->GetNrBad();
309 for (UInt_t index=0; index<nrDead; index++) {
310   if(GetChipFromCol(calibSPD->GetBadColAt(index))==chip) nrDeadInChip++;
311 }
312 calibSPD=(AliITSCalibrationSPD*) spdNoisy->At(mod);
313 UInt_t nrNoisy = calibSPD->GetNrBad();
314 for (UInt_t index=0; index<nrNoisy; index++) {
315   if(GetChipFromCol(calibSPD->GetBadColAt(index))==chip) nrNoisyInChip++;
316 }
317 return;
318 }
319 //_____________________________________________________________________________
320 Double_t AliITSPlaneEffSPD::GetFracBad(const UInt_t key) const {
321   // returns 1-fractional live
322 if(key>=kNModule*kNChip)
323   {AliError("GetFracBad: you asked for a non existing key");
324    return -1.;}
325 return 1.-GetFracLive(key);
326 }
327 //_____________________________________________________________________________
328 Bool_t AliITSPlaneEffSPD::WriteIntoCDB() const {
329 // write onto CDB
330 if(!fInitCDBCalled)
331   {AliError("WriteIntoCDB: CDB not inizialized. Call InitCDB first");
332    return kFALSE;}
333 // to be written properly: now only for debugging 
334   AliCDBMetaData *md= new AliCDBMetaData(); // metaData describing the object
335   md->SetObjectClassName("AliITSPlaneEff");
336   md->SetResponsible("Giuseppe Eugenio Bruno");
337   md->SetBeamPeriod(0);
338   md->SetAliRootVersion("head 19/11/07"); //root version
339   AliCDBId id("ITS/PlaneEff/PlaneEffSPD",0,AliCDBRunRange::Infinity()); 
340   AliITSPlaneEffSPD eff; 
341   eff=*this;
342   Bool_t r=AliCDBManager::Instance()->GetDefaultStorage()->Put(&eff,id,md);
343   delete md;
344   return r;
345 }
346 //_____________________________________________________________________________
347 Bool_t AliITSPlaneEffSPD::ReadFromCDB() {
348 // read from CDB
349 if(!fInitCDBCalled)
350   {AliError("ReadFromCDB: CDB not inizialized. Call InitCDB first");
351    return kFALSE;}
352 //if(!AliCDBManager::Instance()->IsDefaultStorageSet()) {
353 //    AliCDBManager::Instance()->SetDefaultStorage("local://$ALICE_ROOT");
354 //  }
355 AliCDBEntry *cdbEntry = AliCDBManager::Instance()->Get("ITS/PlaneEff/PlaneEffSPD",fRunNumber);
356 AliITSPlaneEffSPD* eff= (AliITSPlaneEffSPD*)cdbEntry->GetObject();
357 if(this==eff) return kFALSE;
358 eff->Copy(*this);
359 return kTRUE;
360 }
361 //_____________________________________________________________________________
362 UInt_t AliITSPlaneEffSPD::GetKeyFromDetLocCoord(Int_t ilay, Int_t idet, 
363                                                 Float_t, Float_t locz) const {
364 // method to locate a basic block from Detector Local coordinate (to be used in tracking)
365 UInt_t key=999999;
366 if(ilay<0 || ilay>1) 
367   {AliError("GetKeyFromDetLocCoord: you asked for a non existing layer");
368    return key;}
369 if(ilay==0 && (idet<0 || idet>79))
370  {AliError("GetKeyFromDetLocCoord: you asked for a non existing detector");
371    return key;}
372 if(ilay==1 && (idet<0 || idet>159))
373  {AliError("GetKeyFromDetLocCoord: you asked for a non existing detector");
374    return key;}
375
376 UInt_t mod=idet;
377 if(ilay==1) mod+=80;
378 key=GetKey(mod,GetChipFromCol(GetColFromLocZ(locz)));
379 return key;
380 }
381 //_____________________________________________________________________________
382 UInt_t AliITSPlaneEffSPD::GetColFromLocZ(Float_t zloc) const {
383 UInt_t col=0;
384 /* note: as it is now, the AliITSsegmentationSPD::Init() does not properly initialize (6 chips !!!)
385 AliITSsegmentationSPD spd;
386 spd.Init();
387 Int_t ix,iz;
388 if(spd.LocalToDet(0,zloc,ix,iz)) col+=iz;
389 else {
390   AliError("GetColFromLocZ: cannot compute column number from local z");
391   col=99999;}
392 return col;
393 */
394 const Float_t kconv = 1.0E-04; // converts microns to cm.
395 Float_t bz[160];
396 for(Int_t i=000;i<160;i++) bz[i] = 425.0; // most are 425 microns except below
397 bz[ 31] = bz[ 32] = 625.0; // first chip boundry
398 bz[ 63] = bz[ 64] = 625.0; // first chip boundry
399 bz[ 95] = bz[ 96] = 625.0; // first chip boundry
400 bz[127] = bz[128] = 625.0; // first chip boundry
401 //
402 Int_t j=-1;
403 Float_t dz=0;
404 for(Int_t i=000;i<160;i++) dz+=bz[i];
405 dz = -0.5*kconv*dz;
406 if(zloc<dz || zloc>-1*dz) { // outside z range
407   AliDebug(1,Form("GetColFromLocZ: cannot compute column number from local z=%f",zloc));
408   return 99999;}
409 for(j=0;j<160;j++){
410   dz += kconv*bz[j];
411   if(zloc<dz) break;
412 } // end for j
413 col+=j;
414 //
415 return col;
416 }
417 //________________________________________________________
418 Bool_t AliITSPlaneEffSPD::GetBlockBoundaries(const UInt_t key, Float_t& xmn,Float_t& xmx,
419                                              Float_t& zmn,Float_t& zmx) const {
420 //
421 //  This method return the geometrical boundaries of the active volume of a given 
422 //  basic block, in the detector reference system.
423 //  Input: unique key to locate a basic block.
424 //  
425 //  Output: Ymin, Ymax, Zmin, Zmax of a basic block (chip for SPD)
426 //  Return: kTRUE if computation was succesfully, kFALSE otherwise
427 //
428 if(key>=kNModule*kNChip)
429   {AliWarning("GetBlockBoundaries: you asked for a non existing key"); return kFALSE;}
430 UInt_t chip=GetChipFromKey(key);
431 zmn=GetLocZFromCol(chip*kNCol);
432 zmx=GetLocZFromCol((chip+1)*kNCol);
433 xmn=GetLocXFromRow(0);
434 xmx=GetLocXFromRow(kNRow);
435 Float_t tmp=zmn;
436 if(zmx<zmn) {zmn=zmx; zmx=tmp;}
437 tmp=xmn;
438 if(xmx<xmn) {xmn=xmx; xmx=tmp;}
439 return kTRUE;
440 }
441 //________________________________________________________
442 Float_t AliITSPlaneEffSPD::GetLocXFromRow(const UInt_t row) const {
443 // 
444 //  This method return the local (i.e. detector reference system) lower x coordinate 
445 //  of the row. To get the central value of a given row, you can do 
446 //  1/2*[LocXFromRow(row)+LocXFromRow(row+1)].
447 //
448 //  Input: row number in the range [0,kNRow] 
449 //  Output: lower local X coordinate of this row.
450 //
451 if(row>kNRow)  // not >= ! allow also computation of upper limit of the last row. 
452   {AliError("LocYFromRow: you asked for a non existing row"); return 9999999.;}
453 const Float_t kconv = 1.0E-04; // converts microns to cm.
454 Float_t bx[256];
455 for(Int_t i=000;i<256;i++) bx[i] = 50.0; // in x all are 50 microns.
456 //
457 Float_t dx=0;
458 for(Int_t i=000;i<256;i++) dx+=bx[i];
459 dx = -0.5*kconv*dx;
460 for(UInt_t j=0;j<row;j++){
461   dx += kconv*bx[j];
462 } // end for j
463 return dx;
464 }
465 //________________________________________________________
466 Float_t AliITSPlaneEffSPD::GetLocZFromCol(const UInt_t col) const {
467 //
468 //  This method return the local (i.e. detector reference system) lower Z coordinate
469 //  of the column. To get the central value of a given column, you can do
470 //  1/2*[LocZFromCol(col)+LocZFromCol(col+1)].
471 //
472 //  Input: col number in the range [0,kNChip*kNCol]
473 //  Output: lower local Y coordinate of this row.
474 //
475 if(col>kNChip*kNCol) // not >= ! allow also computation of upper limit of the last column
476   {AliError("LocZFromCol: you asked for a non existing column"); return 9999999.;}
477 const Float_t kconv = 1.0E-04; // converts microns to cm.
478 Float_t bz[160];
479 for(Int_t i=000;i<160;i++) bz[i] = 425.0; // most are 425 microns except below
480 bz[ 31] = bz[ 32] = 625.0; // first chip boundry
481 bz[ 63] = bz[ 64] = 625.0; // first chip boundry
482 bz[ 95] = bz[ 96] = 625.0; // first chip boundry
483 bz[127] = bz[128] = 625.0; // first chip boundry
484 //
485 Float_t dz=0;
486 for(Int_t i=000;i<160;i++) dz+=bz[i];
487 dz = -0.5*kconv*dz;
488 for(UInt_t j=0;j<col;j++){
489   dz += kconv*bz[j];
490 } // end for j
491 return dz;
492 }