fixed the tainted variables
[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 "AliITSCalibrationSSD.h"
33 #include "AliITSsegmentationSPD.h"
34 #include "AliITSsegmentationSDD.h"
35 #include "AliITSsegmentationSSD.h"
36 #include "AliCDBEntry.h"
37 #include "TMath.h"
38 #include "AliLog.h"
39
40 ClassImp(AliITSChannelStatus)
41
42
43 //______________________________________________________________________
44 AliITSChannelStatus::AliITSChannelStatus():
45 TObject(),
46 fSPDChannelStatus(0),
47 fSDDChannelStatus(0),
48 fSSDChannelStatus(0)
49 {
50   // default constructor 
51   UInt_t nSPDchan=kSPDModules*kSPDNpxPerModule*kSPDNpzPerModule;
52   fSPDChannelStatus=new TBits(nSPDchan);
53   UInt_t nSDDchan=kSDDModules*kSDDAnodesPerModule;
54   fSDDChannelStatus=new TBits(nSDDchan);
55   UInt_t nSSDchan=kSSDModules*kSSDStripsPerModule;
56   fSSDChannelStatus=new TBits(nSSDchan);
57   InitDefaults();
58 }
59 //______________________________________________________________________
60 AliITSChannelStatus::AliITSChannelStatus(AliCDBManager *cdb):
61 TObject(),
62 fSPDChannelStatus(0),
63 fSDDChannelStatus(0),
64 fSSDChannelStatus(0)
65 {
66   AliCDBEntry* spdEntryD = cdb->Get("ITS/Calib/SPDDead");
67   if (!spdEntryD) AliFatal("Cannot get CDB entry for SPDDead");
68   TObjArray* deadArrSPD = (TObjArray*)spdEntryD->GetObject();
69   if (!deadArrSPD) AliFatal("No object found in SPDDead file");
70
71   AliCDBEntry* spdEntryN = cdb->Get("ITS/Calib/SPDNoisy");
72   if (!spdEntryN) AliFatal("Cannot get CDB entry for SPDNoisy");
73   TObjArray* noisArrSPD = (TObjArray*)spdEntryN->GetObject();
74   if (!noisArrSPD) AliFatal("No object found in SPDNoisy file");
75
76   AliCDBEntry* sddEntry = cdb->Get("ITS/Calib/CalibSDD");
77   if (!sddEntry) AliFatal("Cannot get CDB entry for CalibSDD");
78   TObjArray* calArrSDD = (TObjArray*)sddEntry->GetObject();
79   if (!calArrSDD) AliFatal("No object found in CalibSDD file");
80
81   AliCDBEntry* ssdEntry = cdb->Get("ITS/Calib/CalibSSD");
82   if (!ssdEntry) AliFatal("Cannot get CDB entry for CalibSSD");
83   TObjArray* calArrSSD = (TObjArray*)ssdEntry->GetObject();
84   if (!calArrSSD) AliFatal("No object found in CalibSSD file");
85
86   UInt_t nSPDchan=kSPDModules*kSPDNpxPerModule*kSPDNpzPerModule;
87   fSPDChannelStatus=new TBits(nSPDchan);
88   UInt_t nSDDchan=kSDDModules*kSDDAnodesPerModule;
89   fSDDChannelStatus=new TBits(nSDDchan);
90   UInt_t nSSDchan=kSSDModules*kSSDStripsPerModule;
91   fSSDChannelStatus=new TBits(nSSDchan);
92   InitFromOCDB(deadArrSPD,noisArrSPD,calArrSDD,calArrSSD);
93 }
94 //______________________________________________________________________
95 AliITSChannelStatus::AliITSChannelStatus(const AliITSDetTypeRec *dtrec):
96 TObject(),
97 fSPDChannelStatus(0),
98 fSDDChannelStatus(0),
99 fSSDChannelStatus(0)
100 {
101   UInt_t nSPDchan=kSPDModules*kSPDNpxPerModule*kSPDNpzPerModule;
102   fSPDChannelStatus=new TBits(nSPDchan);
103   
104   UInt_t nSDDchan=kSDDModules*kSDDAnodesPerModule;
105   fSDDChannelStatus=new TBits(nSDDchan);
106
107   UInt_t nSSDchan=kSSDModules*kSSDStripsPerModule;
108   fSSDChannelStatus=new TBits(nSSDchan);
109   
110   // SPD modules
111   for(Int_t imod=0; imod<kSPDModules; imod++){
112     for(Int_t ix=0; ix<kSPDNpxPerModule; ix++){
113       for(Int_t iz=0; iz<kSPDNpzPerModule; iz++){
114         Int_t index=imod*kSPDNpxPerModule*kSPDNpzPerModule+ix*kSPDNpzPerModule+iz;
115         fSPDChannelStatus->SetBitNumber(index,kTRUE);
116       }
117     }
118     Int_t ix,iz;
119
120     // Mask SPD dead pixels
121     AliITSCalibrationSPD* deadspd=(AliITSCalibrationSPD*)dtrec->GetSPDDeadModel(imod);
122     for(Int_t ipix=0; ipix<deadspd->GetNrBad();ipix++){
123       deadspd->GetBadPixel(ipix,ix,iz);
124       Int_t index=imod*kSPDNpxPerModule*kSPDNpzPerModule+ix*kSPDNpzPerModule+iz;
125       fSPDChannelStatus->SetBitNumber(index,kFALSE);      
126     }
127     // Mask SPD noisy pixels
128     AliITSCalibrationSPD* noisspd=(AliITSCalibrationSPD*)dtrec->GetCalibrationModel(imod);
129     for(Int_t ipix=0; ipix<noisspd->GetNrBad();ipix++){
130       noisspd->GetBadPixel(ipix,ix,iz);
131       Int_t index=imod*kSPDNpxPerModule*kSPDNpzPerModule+ix*kSPDNpzPerModule+iz;
132       fSPDChannelStatus->SetBitNumber(index,kFALSE);
133     }
134   }
135
136   // SDD modules
137   for(Int_t imod=0; imod<kSDDModules; imod++){
138     AliITSCalibrationSDD* calsdd=(AliITSCalibrationSDD*)dtrec->GetCalibrationModel(imod+kSPDModules);
139     for(Int_t ian=0; ian<kSDDAnodesPerModule; ian++){
140       Bool_t cstatus=kTRUE;
141       if(calsdd->IsBadChannel(ian)) cstatus=kFALSE;
142       Int_t index=imod*kSDDAnodesPerModule+ian;
143       fSDDChannelStatus->SetBitNumber(index,cstatus);
144     }
145   }
146
147   // SSD modules
148   for (Int_t imod = 0; imod < kSSDModules; imod++) {
149     AliITSCalibrationSSD* calssd=(AliITSCalibrationSSD*)dtrec->GetCalibrationModel(kSSDFirstModule+imod);
150     for(Int_t ip=0; ip<kSSDStripsPerModule; ip++) {
151       Int_t index=imod*kSSDStripsPerModule+ip;
152       Bool_t cstatus = kTRUE;
153       if (ip < 768 && calssd->IsPChannelBad(ip))
154         cstatus = kFALSE;
155       if (ip >= 768 && calssd->IsNChannelBad(ip-768))
156         cstatus = kFALSE;
157
158       fSSDChannelStatus->SetBitNumber(index,cstatus);
159     }
160   }
161 }
162 //______________________________________________________________________
163 void  AliITSChannelStatus::InitDefaults(){
164   // fill bitmaps setting all channels as good
165   for(Int_t imod=0; imod<kSPDModules; imod++){
166     for(Int_t ix=0; ix<kSPDNpxPerModule; ix++){
167       for(Int_t iz=0; iz<kSPDNpzPerModule; iz++){
168         Int_t index=imod*kSPDNpxPerModule*kSPDNpzPerModule+ix*kSPDNpzPerModule+iz;
169         fSPDChannelStatus->SetBitNumber(index,kTRUE);
170       }
171     }
172   }
173   for(Int_t imod=0; imod<kSDDModules; imod++){
174     for(Int_t ian=0; ian<kSDDAnodesPerModule; ian++){
175       Int_t index=imod*kSDDAnodesPerModule+ian;
176       fSDDChannelStatus->SetBitNumber(index,kTRUE);
177     }
178   }
179   for(Int_t imod=0; imod<kSSDModules; imod++){
180     for(Int_t is=0; is<kSSDStripsPerModule; is++){
181       Int_t index=imod*kSSDStripsPerModule+is;
182       fSSDChannelStatus->SetBitNumber(index,kTRUE);
183     }
184   }
185 }
186 //______________________________________________________________________
187 void AliITSChannelStatus::InitFromOCDB(TObjArray* deadArrSPD, TObjArray* noisArrSPD, TObjArray* calArrSDD, TObjArray *calArrSSD){
188 // fills bitmaps from arrays of AliITSCalibrationSXD objects
189
190   // SPD modules
191   for(Int_t imod=0; imod<kSPDModules; imod++){
192     for(Int_t ix=0; ix<kSPDNpxPerModule; ix++){
193       for(Int_t iz=0; iz<kSPDNpzPerModule; iz++){
194         Int_t index=imod*kSPDNpxPerModule*kSPDNpzPerModule+ix*kSPDNpzPerModule+iz;
195         fSPDChannelStatus->SetBitNumber(index,kTRUE);
196       }
197     }
198     Int_t ix,iz;
199
200     // Mask SPD dead pixels
201     AliITSCalibrationSPD* deadspd=(AliITSCalibrationSPD*)deadArrSPD->At(imod);
202     for(Int_t ipix=0; ipix<deadspd->GetNrBad();ipix++){
203       deadspd->GetBadPixel(ipix,ix,iz);
204       Int_t index=imod*kSPDNpxPerModule*kSPDNpzPerModule+ix*kSPDNpzPerModule+iz;
205       fSPDChannelStatus->SetBitNumber(index,kFALSE);      
206     }
207
208     // Mask SPD noisy pixels
209     AliITSCalibrationSPD* noisspd=(AliITSCalibrationSPD*)noisArrSPD->At(imod);
210     for(Int_t ipix=0; ipix<noisspd->GetNrBad();ipix++){
211       noisspd->GetBadPixel(ipix,ix,iz);
212       Int_t index=imod*kSPDNpxPerModule*kSPDNpzPerModule+ix*kSPDNpzPerModule+iz;
213       fSPDChannelStatus->SetBitNumber(index,kFALSE);
214     }
215   }
216
217   // SDD modules
218   for(Int_t imod=0; imod<kSDDModules; imod++){
219     AliITSCalibrationSDD* calsdd=(AliITSCalibrationSDD*)calArrSDD->At(imod);
220     for(Int_t ian=0; ian<kSDDAnodesPerModule; ian++){
221       Bool_t cstatus=kTRUE;
222       if(calsdd->IsBadChannel(ian)) cstatus=kFALSE;
223       Int_t index=imod*kSDDAnodesPerModule+ian;
224       fSDDChannelStatus->SetBitNumber(index,cstatus);
225     }
226   }
227
228   // SSD modules
229   for (Int_t imod = 0; imod < kSSDModules; imod++) {
230     AliITSCalibrationSSD* calssd=(AliITSCalibrationSSD*)calArrSSD->At(imod);
231     for(Int_t ip=0; ip<kSSDStripsPerModule; ip++) {
232       Int_t index=imod*kSSDStripsPerModule+ip;
233       Bool_t cstatus = kTRUE;
234       if (ip < 768 && calssd->IsPChannelBad(ip))
235         cstatus = kFALSE;
236       if (ip >= 768 && calssd->IsNChannelBad(ip-768))
237         cstatus = kFALSE;
238
239       fSSDChannelStatus->SetBitNumber(index,cstatus);
240     }
241   }
242 }
243 //______________________________________________________________________
244 AliITSChannelStatus::AliITSChannelStatus(const AliITSChannelStatus& cstatus):
245 TObject(),
246 fSPDChannelStatus(cstatus.fSPDChannelStatus),
247 fSDDChannelStatus(cstatus.fSDDChannelStatus),
248 fSSDChannelStatus(cstatus.fSSDChannelStatus)
249 {
250   // copy constructor 
251 }
252 //______________________________________________________________________
253 AliITSChannelStatus& AliITSChannelStatus::operator=(const AliITSChannelStatus& cstatus)
254 {
255   // assignment operator
256   this->~AliITSChannelStatus();
257   new(this) AliITSChannelStatus(cstatus);
258   return *this;
259 }
260
261 //______________________________________________________________________
262 AliITSChannelStatus::~AliITSChannelStatus(){
263   // destructor
264   if(fSPDChannelStatus) delete fSPDChannelStatus;
265   if(fSDDChannelStatus) delete fSDDChannelStatus;
266   if(fSSDChannelStatus) delete fSSDChannelStatus;
267 }
268
269 //______________________________________________________________________
270 Bool_t AliITSChannelStatus::CheckBounds(Int_t imod, Int_t iz, Int_t ix) const {
271   // check for out of bounds
272   if(imod<0 || imod>=kSPDModules+kSDDModules+kSSDModules){
273     AliError(Form("Module number out of range 0-%d",kSPDModules+kSDDModules));
274     return kFALSE;
275   }
276   if(imod<kSPDModules){
277     if(ix<0 || ix>=kSPDNpxPerModule || iz<0 || iz>=kSPDNpzPerModule){
278       AliError("SPD: Pixel number out of range");
279       return kFALSE;
280     }
281   }else if (imod<kSSDFirstModule){
282     if(iz<0 || iz>=kSDDAnodesPerModule){
283       AliError("SDD: anode number out of range");
284       return kFALSE;
285     }
286   }
287   else {
288     if(iz<0 || iz>=kSSDStripsPerModule){
289       AliError("SSD: strip number out of range");
290       return kFALSE;
291     }
292   }
293   return kTRUE;
294 }
295 //______________________________________________________________________
296 Bool_t AliITSChannelStatus::GetChannelStatus(Int_t imod, Int_t iz, Int_t ix) const {
297   // return status of inquired channel
298   if(CheckBounds(imod,iz,ix)==kFALSE) return kFALSE;
299   if(imod<kSPDModules){
300     Int_t index=imod*kSPDNpxPerModule*kSPDNpzPerModule+ix*kSPDNpzPerModule+iz;
301     return fSPDChannelStatus->TestBitNumber(index);
302   } else if (imod < kSSDFirstModule) {
303     imod-=kSPDModules;
304     Int_t index=imod*kSDDAnodesPerModule+iz;
305     return fSDDChannelStatus->TestBitNumber(index);    
306   }
307   else { // SSD: iz is strip number 0-767 P-side, 768 - 1535 N-side
308     imod-=kSSDFirstModule;
309     Int_t index=imod*kSSDStripsPerModule+iz;
310     return fSSDChannelStatus->TestBitNumber(index);    
311   }
312 }
313 //______________________________________________________________________
314 void AliITSChannelStatus::SetChannelStatus(Bool_t cstatus, Int_t imod, Int_t iz, Int_t ix){
315   // set status for given channel
316   if(CheckBounds(imod,iz,ix)==kFALSE) return;
317   if(imod<kSPDModules){
318     Int_t index=imod*kSPDNpxPerModule*kSPDNpzPerModule+ix*kSPDNpzPerModule+iz;
319     fSPDChannelStatus->SetBitNumber(index,cstatus);
320   }else if (imod < kSSDFirstModule) {
321     imod-=kSPDModules;
322     Int_t index=imod*kSDDAnodesPerModule+iz;
323     fSDDChannelStatus->SetBitNumber(index,cstatus);
324   }
325   else { // SSD: iz is strip number 0-767 P-side, 768 - 1535 N-side
326     imod-=kSSDFirstModule;
327     Int_t index=imod*kSSDStripsPerModule+iz;
328     return fSSDChannelStatus->SetBitNumber(index,cstatus);    
329   }
330 }
331 //______________________________________________________________________
332 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 {
333   // Returns min. and max. anode numbers from local coordindate
334   AliITSsegmentationSDD *seg=new AliITSsegmentationSDD();
335   Float_t dummySpeed=6.5; // to avoid warnings in SDD segmentation
336   Float_t tolerance=0.9999;
337   seg->SetDriftSpeed(dummySpeed);
338   Float_t zHalfSize=0.5*seg->Dz()/10000.;
339   zHalfSize*=tolerance;
340   if(zlocmin<-zHalfSize) zlocmin=-zHalfSize;
341   if(zlocmax>zHalfSize) zlocmax=zHalfSize;
342   if(zlocmax<-zHalfSize || zlocmin>zHalfSize){
343     AliWarning("Search region completely outside module");
344     return kFALSE;
345   }
346   Float_t xHalfSize=seg->Dx()/10000.;
347   xHalfSize*=tolerance;
348   if(xlocmin<-xHalfSize) xlocmin=-xHalfSize;
349   if(xlocmax>xHalfSize) xlocmax=xHalfSize;
350   if(xlocmax<-xHalfSize || xlocmin>xHalfSize){
351     AliWarning("Search region completely outside module");
352     return kFALSE;
353   }
354   
355   Int_t iSid1=seg->GetSideFromLocalX(xlocmin);
356   Int_t iSid2=seg->GetSideFromLocalX(xlocmax);
357   Int_t iz1,iz2,ixdummy;
358   seg->LocalToDet(xlocmin,zlocmin,ixdummy,iz1);
359   seg->LocalToDet(xlocmin,zlocmax,ixdummy,iz2);
360   izmin=TMath::Min(iz1,iz2);
361   izmax=TMath::Max(iz1,iz2);    
362   if(iSid1==iSid2){
363     izmax2=izmin2=-1;
364   }else{
365     seg->LocalToDet(xlocmax,zlocmin,ixdummy,iz1);
366     seg->LocalToDet(xlocmax,zlocmax,ixdummy,iz2);
367     izmin2=TMath::Min(iz1,iz2);
368     izmax2=TMath::Max(iz1,iz2);    
369   }
370   delete seg;
371   return kTRUE;
372 }
373 //______________________________________________________________________
374 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 {
375   // Returns min. and max. pixel numbers from local coordindate
376   Float_t tolerance=0.9999;
377   AliITSsegmentationSPD *seg=new AliITSsegmentationSPD();
378   Float_t zHalfSize=0.5*seg->Dz()/10000.;
379   zHalfSize*=tolerance;
380   if(zlocmin<-zHalfSize) zlocmin=-zHalfSize;
381   if(zlocmax>zHalfSize) zlocmax=zHalfSize;
382   if(zlocmax<-zHalfSize || zlocmin>zHalfSize){
383     AliWarning("Search region completely outside module");
384     return kFALSE;
385   }
386   Float_t xHalfSize=0.5*seg->Dx()/10000.;
387   xHalfSize*=tolerance;
388   if(xlocmin<-xHalfSize) xlocmin=-xHalfSize;
389   if(xlocmax>xHalfSize) xlocmax=xHalfSize;
390   if(xlocmax<-xHalfSize || xlocmin>xHalfSize){
391     AliWarning("Search region completely outside module");
392     return kFALSE;
393   }
394
395   Int_t iz1,ix1,iz2,ix2;
396   seg->LocalToDet(xlocmin,zlocmin,ix1,iz1);
397   seg->LocalToDet(xlocmax,zlocmax,ix2,iz2);
398   izmin=TMath::Min(iz1,iz2);
399   izmax=TMath::Max(iz1,iz2);
400   ixmin=TMath::Min(ix1,ix2);
401   ixmax=TMath::Max(ix1,ix2);
402   delete seg;
403   return kTRUE;
404 }
405 //______________________________________________________________________
406 Bool_t AliITSChannelStatus::GetSSDLimits(Int_t layer, Float_t zlocmin, Float_t zlocmax, Float_t xlocmin, Float_t xlocmax, Int_t& iPmin, Int_t& iPmax, Int_t& iNmin, Int_t& iNmax) const {
407   // Returns min, max strip for SSD, given a search window
408   static AliITSsegmentationSSD seg;
409
410   AliDebug(2,Form("xmin %f zmin %f xmax %f zmax %f\n",xlocmin,zlocmin,xlocmax,zlocmax));
411
412   Int_t p,n;
413   seg.SetLayer(layer);
414   seg.GetPadIxz(xlocmin,zlocmin,p,n);
415   iPmin = iPmax = p;
416   iNmin = iNmax = n;
417   AliDebug(5,Form("lay %d xmin, zmin p %d n %d\n",layer,p,n));
418   seg.GetPadIxz(xlocmax,zlocmin,p,n);
419   iPmin = TMath::Min(iPmin,p);
420   iPmax = TMath::Max(iPmax,p);
421   iNmin = TMath::Min(iNmin,n);
422   iNmax = TMath::Max(iNmax,n);
423   AliDebug(5,Form("lay %d xmax, zmin p %d n %d\n",layer,p,n));
424   seg.GetPadIxz(xlocmax,zlocmax,p,n);
425   iPmin = TMath::Min(iPmin,p);
426   iPmax = TMath::Max(iPmax,p);
427   iNmin = TMath::Min(iNmin,n);
428   iNmax = TMath::Max(iNmax,n);
429   AliDebug(5,Form("lay %d xmax, zmax p %d n %d\n",layer,p,n));
430   seg.GetPadIxz(xlocmin,zlocmax,p,n);
431   iPmin = TMath::Min(iPmin,p);
432   iPmax = TMath::Max(iPmax,p);
433   iNmin = TMath::Min(iNmin,n);
434   iNmax = TMath::Max(iNmax,n);
435   AliDebug(5,Form("lay %d xmin, zmax p %d n %d\n",layer,p,n));
436
437   if (iPmin < 0)
438     iPmin = 0;
439   if (iNmin < 0)
440     iNmin = 0;
441   if (iPmax >= kSSDStripsPerSide)
442     iPmax = kSSDStripsPerSide-1;
443   if (iNmax >= kSSDStripsPerSide)
444     iNmax = kSSDStripsPerSide-1;
445   AliDebug(2,Form("lay %d p %d %d n %d %d\n",layer,iPmin,iPmax,iNmin,iNmax));
446   return kTRUE;
447 }
448 //______________________________________________________________________
449 Bool_t AliITSChannelStatus::AnyBadInRoad(Int_t imod, Float_t zlocmin, Float_t zlocmax, Float_t xlocmin, Float_t xlocmax) const{
450   // Checks if there is at least one bad channel in the search road
451   // For SSD: return kTRUE if there is at least one bad strip on both sides
452   //          if only bad strips on one side 1D clusters can be used
453   AliDebug(2,Form("checking for module %d",imod));
454   if(imod<kSPDModules){
455     Int_t izmin,izmax,ixmin,ixmax;
456     Bool_t retcode=GetSPDLimits(zlocmin,zlocmax,xlocmin,xlocmax,izmin,izmax,ixmin,ixmax);
457     if(!retcode) return kFALSE;
458     for(Int_t iz=izmin; iz<=izmax;iz++){
459       for(Int_t ix=ixmin; ix<=ixmax;ix++){
460         if(GetChannelStatus(imod,iz,ix)==kFALSE) return kTRUE;
461       }
462     }
463   }else if (imod < kSSDFirstModule) {
464     Int_t izmin,izmax,izmin2,izmax2;
465     Bool_t retcode=GetSDDLimits(zlocmin,zlocmax,xlocmin,xlocmax,izmin,izmax,izmin2,izmax2);
466     if(!retcode) return kFALSE;
467     for(Int_t iz=izmin; iz<=izmax;iz++){
468       if(GetChannelStatus(imod,iz,0)==kFALSE) { return kTRUE;}
469     }
470     if(izmin2!=-1 && izmax2!=-1){
471       for(Int_t iz=izmin2; iz<=izmax2;iz++){
472         if(GetChannelStatus(imod,iz,0)==kFALSE) { return kTRUE;}
473       }
474     }
475   }
476   else {
477     Int_t layer = 5;
478     if (imod > kSSDMaxModLay5) 
479       layer = 6;
480     Int_t iPmin,iPmax,iNmin,iNmax;
481     Bool_t retcode=GetSSDLimits(layer,zlocmin,zlocmax,xlocmin,xlocmax,iPmin,iPmax,iNmin,iNmax);
482     if(!retcode) return kFALSE;
483     Int_t nPbad = 0;
484     for(Int_t iP=iPmin; iP<=iPmax;iP++){
485       if(GetChannelStatus(imod,iP,0)==kFALSE) nPbad++;
486     }
487     if (nPbad == 0)
488       return kFALSE;
489     for(Int_t iN=iNmin; iN<=iNmax;iN++){
490       if(GetChannelStatus(imod,iN+768,0)==kFALSE) { return kTRUE; }
491     }
492   }
493   return kFALSE;
494 }
495 //______________________________________________________________________
496 Float_t AliITSChannelStatus::FractionOfBadInRoad(Int_t imod, Float_t zlocmin, Float_t zlocmax, Float_t xlocmin, Float_t xlocmax) const{
497   // Calculate the fraction of bad channels in the road  
498   // Note: SSD returns fraction of dead strips on 'best' side. This 
499   //       is not proportional to dead surface area. 
500   Float_t totChan=0.;
501   Float_t badChan=0.;
502   if(imod<kSPDModules){
503     Int_t izmin,izmax,ixmin,ixmax;
504     Bool_t retcode=GetSPDLimits(zlocmin,zlocmax,xlocmin,xlocmax,izmin,izmax,ixmin,ixmax);
505     if(!retcode) return 0.;
506     for(Int_t iz=izmin; iz<=izmax;iz++){
507       for(Int_t ix=ixmin; ix<=ixmax;ix++){
508         totChan+=1;
509         if(GetChannelStatus(imod,iz,ix)==kFALSE) badChan+=1.;
510       }
511     }
512   }else if (imod < kSSDFirstModule) {
513     Int_t izmin,izmax,izmin2,izmax2;
514     Bool_t retcode=GetSDDLimits(zlocmin,zlocmax,xlocmin,xlocmax,izmin,izmax,izmin2,izmax2);
515     if(!retcode) return 0.;
516     for(Int_t iz=izmin; iz<=izmax;iz++){
517       totChan+=1;
518       if(GetChannelStatus(imod,iz,0)==kFALSE) badChan+=1.;
519     }
520     if(izmin2!=-1 && izmax2!=-1){
521       for(Int_t iz=izmin2; iz<=izmax2;iz++){
522         totChan+=1;
523         if(GetChannelStatus(imod,iz,0)==kFALSE) badChan+=1.;
524       }
525     }
526   }
527   else {
528     Int_t layer = 5;
529     if (imod > kSSDMaxModLay5) 
530       layer = 6;
531     Int_t iPmin,iPmax,iNmin,iNmax;
532     Bool_t retcode=GetSSDLimits(layer,zlocmin,zlocmax,xlocmin,xlocmax,iPmin,iPmax,iNmin,iNmax);
533     if(!retcode) return kFALSE;
534     Int_t nPbad = 0;
535     for(Int_t iP=iPmin; iP<=iPmax;iP++){
536       if(GetChannelStatus(imod,iP,0)==kFALSE) nPbad++;
537     }
538     Float_t fracP = (Float_t) nPbad / (iPmax-iPmin+1);
539     if (nPbad == 0)
540       return 0;
541     Int_t nNbad = 0;
542     for(Int_t iN=iNmin; iN<=iNmax;iN++){
543       if(GetChannelStatus(imod,iN+768,0)==kFALSE) nNbad++;
544     }
545     Float_t fracN = (Float_t) nNbad / (iPmax-iPmin+1);
546     return TMath::Min(fracP,fracN);
547   }
548   if(totChan==0.) return 0.;
549   else return badChan/totChan;
550 }
551