Adding some further mother volumes to speed-up the overlap checking and particle...
[u/mrichter/AliRoot.git] / ITS / AliITSChannelStatus.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 /* $Id:$ */
17
18 //////////////////////////////////////////////////////////////////////////
19 //                                                                      //
20 // Implementation of the class for bad channel treatment in the tracker //
21 // Stores 1 status bit for each SPD pixel and SDD anode:                //
22 //  0 = bad channel                                                     //
23 //  1 = good channel                                                    //
24 // Dead and noisy channels are read from AliITSCalibration objects      //
25 // Origin: F.Prino, Torino, prino@to.infn.it                            //
26 //                                                                      //
27 //////////////////////////////////////////////////////////////////////////
28
29 #include "AliITSChannelStatus.h"
30 #include "AliITSCalibrationSPD.h"
31 #include "AliITSCalibrationSDD.h"
32 #include "AliITSsegmentationSPD.h"
33 #include "AliITSsegmentationSDD.h"
34 #include "AliCDBEntry.h"
35 #include "TMath.h"
36 #include "AliLog.h"
37
38 ClassImp(AliITSChannelStatus)
39
40
41 //______________________________________________________________________
42 AliITSChannelStatus::AliITSChannelStatus():
43 TObject(),
44 fSPDChannelStatus(0),
45 fSDDChannelStatus(0)
46 {
47   // default constructor 
48   UInt_t nSPDchan=kSPDModules*kSPDNpxPerModule*kSPDNpzPerModule;
49   fSPDChannelStatus=new TBits(nSPDchan);
50   UInt_t nSDDchan=kSDDModules*kSDDAnodesPerModule;
51   fSDDChannelStatus=new TBits(nSDDchan);
52   InitDefaults();
53 }
54 //______________________________________________________________________
55 AliITSChannelStatus::AliITSChannelStatus(AliCDBManager *cdb):
56 TObject(),
57 fSPDChannelStatus(0),
58 fSDDChannelStatus(0)
59 {
60   AliCDBEntry* spdEntryD = cdb->Get("ITS/Calib/SPDDead");
61   if (!spdEntryD) AliFatal("Cannot get CDB entry for SPDDead");
62   TObjArray* deadArrSPD = (TObjArray*)spdEntryD->GetObject();
63   if (!deadArrSPD) AliFatal("No object found in SPDDead file");
64
65   AliCDBEntry* spdEntryN = cdb->Get("ITS/Calib/SPDNoisy");
66   if (!spdEntryN) AliFatal("Cannot get CDB entry for SPDNoisy");
67   TObjArray* noisArrSPD = (TObjArray*)spdEntryN->GetObject();
68   if (!noisArrSPD) AliFatal("No object found in SPDNoisy file");
69
70   AliCDBEntry* sddEntry = cdb->Get("ITS/Calib/CalibSDD");
71   if (!sddEntry) AliFatal("Cannot get CDB entry for CalibSDD");
72   TObjArray* calArrSDD = (TObjArray*)sddEntry->GetObject();
73   if (!calArrSDD) AliFatal("No object found in CalibSDD file");
74
75   UInt_t nSPDchan=kSPDModules*kSPDNpxPerModule*kSPDNpzPerModule;
76   fSPDChannelStatus=new TBits(nSPDchan);
77   UInt_t nSDDchan=kSDDModules*kSDDAnodesPerModule;
78   fSDDChannelStatus=new TBits(nSDDchan);
79   InitFromOCDB(deadArrSPD,noisArrSPD,calArrSDD);
80 }
81 //______________________________________________________________________
82 AliITSChannelStatus::AliITSChannelStatus(const AliITSDetTypeRec *dtrec):
83 TObject(),
84 fSPDChannelStatus(0),
85 fSDDChannelStatus(0)
86 {
87   UInt_t nSPDchan=kSPDModules*kSPDNpxPerModule*kSPDNpzPerModule;
88   fSPDChannelStatus=new TBits(nSPDchan);
89   
90   UInt_t nSDDchan=kSDDModules*kSDDAnodesPerModule;
91   fSDDChannelStatus=new TBits(nSDDchan);
92   
93   // SPD modules
94   for(Int_t imod=0; imod<kSPDModules; imod++){
95     for(Int_t ix=0; ix<kSPDNpxPerModule; ix++){
96       for(Int_t iz=0; iz<kSPDNpzPerModule; iz++){
97         Int_t index=imod*kSPDNpxPerModule*kSPDNpzPerModule+ix*kSPDNpzPerModule+iz;
98         fSPDChannelStatus->SetBitNumber(index,kTRUE);
99       }
100     }
101     Int_t ix,iz;
102
103     // Mask SPD dead pixels
104     AliITSCalibrationSPD* deadspd=(AliITSCalibrationSPD*)dtrec->GetSPDDeadModel(imod);
105     for(Int_t ipix=0; ipix<deadspd->GetNrBad();ipix++){
106       deadspd->GetBadPixel(ipix,ix,iz);
107       Int_t index=imod*kSPDNpxPerModule*kSPDNpzPerModule+ix*kSPDNpzPerModule+iz;
108       fSPDChannelStatus->SetBitNumber(index,kFALSE);      
109     }
110     // Mask SPD noisy pixels
111     AliITSCalibrationSPD* noisspd=(AliITSCalibrationSPD*)dtrec->GetCalibrationModel(imod);
112     for(Int_t ipix=0; ipix<noisspd->GetNrBad();ipix++){
113       noisspd->GetBadPixel(ipix,ix,iz);
114       Int_t index=imod*kSPDNpxPerModule*kSPDNpzPerModule+ix*kSPDNpzPerModule+iz;
115       fSPDChannelStatus->SetBitNumber(index,kFALSE);
116     }
117   }
118
119   // SDD modules
120   for(Int_t imod=0; imod<kSDDModules; imod++){
121     AliITSCalibrationSDD* calsdd=(AliITSCalibrationSDD*)dtrec->GetCalibrationModel(imod+kSPDModules);
122     for(Int_t ian=0; ian<kSDDAnodesPerModule; ian++){
123       Bool_t cstatus=kTRUE;
124       if(calsdd->IsBadChannel(ian)) cstatus=kFALSE;
125       Int_t index=imod*kSDDAnodesPerModule+ian;
126       fSDDChannelStatus->SetBitNumber(index,cstatus);
127     }
128   }
129 }
130 //______________________________________________________________________
131 void  AliITSChannelStatus::InitDefaults(){
132   // fill bitmaps setting all channels as good
133   for(Int_t imod=0; imod<kSPDModules; imod++){
134     for(Int_t ix=0; ix<kSPDNpxPerModule; ix++){
135       for(Int_t iz=0; iz<kSPDNpzPerModule; iz++){
136         Int_t index=imod*kSPDNpxPerModule*kSPDNpzPerModule+ix*kSPDNpzPerModule+iz;
137         fSPDChannelStatus->SetBitNumber(index,kTRUE);
138       }
139     }
140   }
141   for(Int_t imod=0; imod<kSDDModules; imod++){
142     for(Int_t ian=0; ian<kSDDAnodesPerModule; ian++){
143       Int_t index=imod*kSDDAnodesPerModule+ian;
144       fSDDChannelStatus->SetBitNumber(index,kTRUE);
145     }
146   }
147 }
148 //______________________________________________________________________
149 void AliITSChannelStatus::InitFromOCDB(TObjArray* deadArrSPD, TObjArray* noisArrSPD, TObjArray* calArrSDD){
150 // fills bitmaps from arrays of AliITSCalibrationSXD objects
151
152   // SPD modules
153   for(Int_t imod=0; imod<kSPDModules; imod++){
154     for(Int_t ix=0; ix<kSPDNpxPerModule; ix++){
155       for(Int_t iz=0; iz<kSPDNpzPerModule; iz++){
156         Int_t index=imod*kSPDNpxPerModule*kSPDNpzPerModule+ix*kSPDNpzPerModule+iz;
157         fSPDChannelStatus->SetBitNumber(index,kTRUE);
158       }
159     }
160     Int_t ix,iz;
161
162     // Mask SPD dead pixels
163     AliITSCalibrationSPD* deadspd=(AliITSCalibrationSPD*)deadArrSPD->At(imod);
164     for(Int_t ipix=0; ipix<deadspd->GetNrBad();ipix++){
165       deadspd->GetBadPixel(ipix,ix,iz);
166       Int_t index=imod*kSPDNpxPerModule*kSPDNpzPerModule+ix*kSPDNpzPerModule+iz;
167       fSPDChannelStatus->SetBitNumber(index,kFALSE);      
168     }
169
170     // Mask SPD noisy pixels
171     AliITSCalibrationSPD* noisspd=(AliITSCalibrationSPD*)noisArrSPD->At(imod);
172     for(Int_t ipix=0; ipix<noisspd->GetNrBad();ipix++){
173       noisspd->GetBadPixel(ipix,ix,iz);
174       Int_t index=imod*kSPDNpxPerModule*kSPDNpzPerModule+ix*kSPDNpzPerModule+iz;
175       fSPDChannelStatus->SetBitNumber(index,kFALSE);
176     }
177   }
178
179   // SDD modules
180   for(Int_t imod=0; imod<kSDDModules; imod++){
181     AliITSCalibrationSDD* calsdd=(AliITSCalibrationSDD*)calArrSDD->At(imod);
182     for(Int_t ian=0; ian<kSDDAnodesPerModule; ian++){
183       Bool_t cstatus=kTRUE;
184       if(calsdd->IsBadChannel(ian)) cstatus=kFALSE;
185       Int_t index=imod*kSDDAnodesPerModule+ian;
186       fSDDChannelStatus->SetBitNumber(index,cstatus);
187     }
188   }
189 }
190 //______________________________________________________________________
191 AliITSChannelStatus::AliITSChannelStatus(const AliITSChannelStatus& cstatus):
192 TObject(),
193 fSPDChannelStatus(cstatus.fSPDChannelStatus),
194 fSDDChannelStatus(cstatus.fSDDChannelStatus)
195 {
196   // copy constructor 
197 }
198 //______________________________________________________________________
199 AliITSChannelStatus& AliITSChannelStatus::operator=(const AliITSChannelStatus& cstatus)
200 {
201   // assignment operator
202   this->~AliITSChannelStatus();
203   new(this) AliITSChannelStatus(cstatus);
204   return *this;
205 }
206
207 //______________________________________________________________________
208 AliITSChannelStatus::~AliITSChannelStatus(){
209   // destructor
210   if(fSPDChannelStatus) delete fSPDChannelStatus;
211   if(fSDDChannelStatus) delete fSDDChannelStatus;
212 }
213
214 //______________________________________________________________________
215 Bool_t AliITSChannelStatus::CheckBounds(Int_t imod, Int_t iz, Int_t ix) const {
216   // check for out of bounds
217   if(imod<0 || imod>=kSPDModules+kSDDModules){
218     AliError(Form("Module number out of range 0-%d",kSPDModules+kSDDModules));
219     return kFALSE;
220   }
221   if(imod<kSPDModules){
222     if(ix<0 || ix>=kSPDNpxPerModule || iz<0 || iz>=kSPDNpzPerModule){
223       AliError("SPD: Pixel number out of range");
224       return kFALSE;
225     }
226   }else{
227     if(iz<0 || iz>=kSDDAnodesPerModule){
228       AliError("SDD: anode number out of range");
229       return kFALSE;
230     }
231   }
232   return kTRUE;
233 }
234 //______________________________________________________________________
235 Bool_t AliITSChannelStatus::GetChannelStatus(Int_t imod, Int_t iz, Int_t ix) const {
236   // return status of inquired channel
237   if(CheckBounds(imod,iz,ix)==kFALSE) return kFALSE;
238   if(imod<kSPDModules){
239     Int_t index=imod*kSPDNpxPerModule*kSPDNpzPerModule+ix*kSPDNpzPerModule+iz;
240     return fSPDChannelStatus->TestBitNumber(index);
241   }else{
242     imod-=kSPDModules;
243     Int_t index=imod*kSDDAnodesPerModule+iz;
244     return fSDDChannelStatus->TestBitNumber(index);    
245   }
246 }
247 //______________________________________________________________________
248 void AliITSChannelStatus::SetChannelStatus(Bool_t cstatus, Int_t imod, Int_t iz, Int_t ix){
249   // set status for given channel
250   if(CheckBounds(imod,iz,ix)==kFALSE) return;
251   if(imod<kSPDModules){
252     Int_t index=imod*kSPDNpxPerModule*kSPDNpzPerModule+ix*kSPDNpzPerModule+iz;
253     fSPDChannelStatus->SetBitNumber(index,cstatus);
254   }else{
255     imod-=kSPDModules;
256     Int_t index=imod*kSDDAnodesPerModule+iz;
257     fSDDChannelStatus->SetBitNumber(index,cstatus);
258   }
259 }
260 //______________________________________________________________________
261 Bool_t AliITSChannelStatus::GetSDDLimits(Float_t zlocmin, Float_t zlocmax, Float_t xlocmin, Float_t xlocmax, Int_t& izmin, Int_t& izmax, Int_t& izmin2, Int_t& izmax2) const {
262   // Returns min. and max. anode numbers from local coordindate
263   AliITSsegmentationSDD *seg=new AliITSsegmentationSDD();
264   Float_t dummySpeed=6.5; // to avoid warnings in SDD segmentation
265   Float_t tolerance=0.9999;
266   seg->SetDriftSpeed(dummySpeed);
267   Float_t zHalfSize=0.5*seg->Dz()/10000.;
268   zHalfSize*=tolerance;
269   if(zlocmin<-zHalfSize) zlocmin=-zHalfSize;
270   if(zlocmax>zHalfSize) zlocmax=zHalfSize;
271   if(zlocmax<-zHalfSize || zlocmin>zHalfSize){
272     AliWarning("Search region completely outside module");
273     return kFALSE;
274   }
275   Float_t xHalfSize=seg->Dx()/10000.;
276   xHalfSize*=tolerance;
277   if(xlocmin<-xHalfSize) xlocmin=-xHalfSize;
278   if(xlocmax>xHalfSize) xlocmax=xHalfSize;
279   if(xlocmax<-xHalfSize || xlocmin>xHalfSize){
280     AliWarning("Search region completely outside module");
281     return kFALSE;
282   }
283   
284   Int_t iSid1=seg->GetSideFromLocalX(xlocmin);
285   Int_t iSid2=seg->GetSideFromLocalX(xlocmax);
286   Int_t iz1,iz2,ixdummy;
287   seg->LocalToDet(xlocmin,zlocmin,ixdummy,iz1);
288   seg->LocalToDet(xlocmin,zlocmax,ixdummy,iz2);
289   izmin=TMath::Min(iz1,iz2);
290   izmax=TMath::Max(iz1,iz2);    
291   if(iSid1==iSid2){
292     izmax2=izmin2=-1;
293   }else{
294     seg->LocalToDet(xlocmax,zlocmin,ixdummy,iz1);
295     seg->LocalToDet(xlocmax,zlocmax,ixdummy,iz2);
296     izmin2=TMath::Min(iz1,iz2);
297     izmax2=TMath::Max(iz1,iz2);    
298   }
299   delete seg;
300   return kTRUE;
301 }
302 //______________________________________________________________________
303 Bool_t AliITSChannelStatus::GetSPDLimits(Float_t zlocmin, Float_t zlocmax, Float_t xlocmin, Float_t xlocmax, Int_t& izmin, Int_t& izmax, Int_t& ixmin, Int_t& ixmax) const {
304   // Returns min. and max. pixel numbers from local coordindate
305   Float_t tolerance=0.9999;
306   AliITSsegmentationSPD *seg=new AliITSsegmentationSPD();
307   Float_t zHalfSize=0.5*seg->Dz()/10000.;
308   zHalfSize*=tolerance;
309   if(zlocmin<-zHalfSize) zlocmin=-zHalfSize;
310   if(zlocmax>zHalfSize) zlocmax=zHalfSize;
311   if(zlocmax<-zHalfSize || zlocmin>zHalfSize){
312     AliWarning("Search region completely outside module");
313     return kFALSE;
314   }
315   Float_t xHalfSize=0.5*seg->Dx()/10000.;
316   xHalfSize*=tolerance;
317   if(xlocmin<-xHalfSize) xlocmin=-xHalfSize;
318   if(xlocmax>xHalfSize) xlocmax=xHalfSize;
319   if(xlocmax<-xHalfSize || xlocmin>xHalfSize){
320     AliWarning("Search region completely outside module");
321     return kFALSE;
322   }
323
324   Int_t iz1,ix1,iz2,ix2;
325   seg->LocalToDet(xlocmin,zlocmin,ix1,iz1);
326   seg->LocalToDet(xlocmax,zlocmax,ix2,iz2);
327   izmin=TMath::Min(iz1,iz2);
328   izmax=TMath::Max(iz1,iz2);
329   ixmin=TMath::Min(ix1,ix2);
330   ixmax=TMath::Max(ix1,ix2);
331   delete seg;
332   return kTRUE;
333 }
334 //______________________________________________________________________
335 Bool_t AliITSChannelStatus::AnyBadInRoad(Int_t imod, Float_t zlocmin, Float_t zlocmax, Float_t xlocmin, Float_t xlocmax) const{
336   // Checks if there is at least one bad channel in the search road
337   if(imod<kSPDModules){
338     Int_t izmin,izmax,ixmin,ixmax;
339     Bool_t retcode=GetSPDLimits(zlocmin,zlocmax,xlocmin,xlocmax,izmin,izmax,ixmin,ixmax);
340     if(!retcode) return kFALSE;
341     for(Int_t iz=izmin; iz<=izmax;iz++){
342       for(Int_t ix=ixmin; ix<=ixmax;ix++){
343         if(GetChannelStatus(imod,iz,ix)==kFALSE) return kTRUE;
344       }
345     }
346   }else{
347     Int_t izmin,izmax,izmin2,izmax2;
348     Bool_t retcode=GetSDDLimits(zlocmin,zlocmax,xlocmin,xlocmax,izmin,izmax,izmin2,izmax2);
349     if(!retcode) return kFALSE;
350     for(Int_t iz=izmin; iz<=izmax;iz++){
351       if(GetChannelStatus(imod,iz,0)==kFALSE) return kTRUE;
352     }
353     if(izmin2!=-1 && izmax2!=-1){
354       for(Int_t iz=izmin2; iz<=izmax2;iz++){
355         if(GetChannelStatus(imod,iz,0)==kFALSE) return kTRUE;
356       }
357     }
358   }
359   return kFALSE;
360 }
361 //______________________________________________________________________
362 Float_t AliITSChannelStatus::FractionOfBadInRoad(Int_t imod, Float_t zlocmin, Float_t zlocmax, Float_t xlocmin, Float_t xlocmax) const{
363   // Calculate the fraction of bad channels in the road  
364   Float_t totChan=0.;
365   Float_t badChan=0.;
366   if(imod<kSPDModules){
367     Int_t izmin,izmax,ixmin,ixmax;
368     Bool_t retcode=GetSPDLimits(zlocmin,zlocmax,xlocmin,xlocmax,izmin,izmax,ixmin,ixmax);
369     if(!retcode) return 0.;
370     for(Int_t iz=izmin; iz<=izmax;iz++){
371       for(Int_t ix=ixmin; ix<=ixmax;ix++){
372         totChan+=1;
373         if(GetChannelStatus(imod,iz,ix)==kFALSE) badChan+=1.;
374       }
375     }
376   }else{
377     Int_t izmin,izmax,izmin2,izmax2;
378     Bool_t retcode=GetSDDLimits(zlocmin,zlocmax,xlocmin,xlocmax,izmin,izmax,izmin2,izmax2);
379     if(!retcode) return 0.;
380     for(Int_t iz=izmin; iz<=izmax;iz++){
381       totChan+=1;
382       if(GetChannelStatus(imod,iz,0)==kFALSE) badChan+=1.;
383     }
384     if(izmin2!=-1 && izmax2!=-1){
385       for(Int_t iz=izmin2; iz<=izmax2;iz++){
386         totChan+=1;
387         if(GetChannelStatus(imod,iz,0)==kFALSE) badChan+=1.;
388       }
389     }
390   }
391   if(totChan==0.) return 0.;
392   else return badChan/totChan;
393 }