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