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