Line data Source code
1 : /**************************************************************************
2 : * Copyright(c) 1998-2003, 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 : // Implementation of the ITS clusterer V2 class //
20 : // //
21 : // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch //
22 : // //
23 : ///////////////////////////////////////////////////////////////////////////
24 :
25 :
26 :
27 : #include <TClonesArray.h>
28 : #include <TBits.h>
29 : #include "AliITSClusterFinderV2SDD.h"
30 : #include "AliITSRecPoint.h"
31 : #include "AliITSRecPointContainer.h"
32 : #include "AliITSDetTypeRec.h"
33 : #include "AliRawReader.h"
34 : #include "AliITSRawStreamSDD.h"
35 : #include "AliITSRawStreamSDDCompressed.h"
36 : #include "AliITSCalibrationSDD.h"
37 : #include "AliITSresponseSDD.h"
38 : #include "AliITSDetTypeRec.h"
39 : #include "AliITSReconstructor.h"
40 : #include "AliITSsegmentationSDD.h"
41 : #include "AliITSdigitSDD.h"
42 : #include "AliITSgeomTGeo.h"
43 :
44 118 : ClassImp(AliITSClusterFinderV2SDD)
45 :
46 0 : AliITSClusterFinderV2SDD::AliITSClusterFinderV2SDD(AliITSDetTypeRec* dettyp):AliITSClusterFinder(dettyp),
47 0 : fNAnodes(0),
48 0 : fNTimeBins(0),
49 0 : fNZbins(0),
50 0 : fNXbins(0),
51 0 : fCutOnPeakLoose(0.),
52 0 : fCutOnPeakTight(0.),
53 0 : fMaxDrTimeForTightCut(0.)
54 0 : {
55 : //Default constructor
56 :
57 0 : fNAnodes = GetSeg()->NpzHalf();
58 0 : fNZbins = fNAnodes+2;
59 0 : fNTimeBins = GetSeg()->Npx();
60 0 : fNXbins = fNTimeBins+2;
61 0 : AliDebug(2,Form("Cells in SDD cluster finder: Andoes=%d TimeBins=%d",fNAnodes,fNTimeBins));
62 0 : const Int_t kMaxBin=fNZbins*fNXbins;
63 0 : for(Int_t iHyb=0;iHyb<kHybridsPerDDL;iHyb++){
64 0 : fDDLBins[iHyb]=new AliBin[kMaxBin];
65 : }
66 0 : SetPeakSelection(15.,30.,2000.);
67 0 : }
68 :
69 :
70 : //______________________________________________________________________
71 : AliITSClusterFinderV2SDD::~AliITSClusterFinderV2SDD()
72 0 : {
73 : //Destructor
74 0 : for(Int_t iHyb=0;iHyb<kHybridsPerDDL;iHyb++){
75 0 : delete [] fDDLBins[iHyb];
76 : }
77 0 : }
78 :
79 : //______________________________________________________________________
80 : void AliITSClusterFinderV2SDD::FindRawClusters(Int_t mod){
81 :
82 : //Find clusters V2
83 0 : SetModule(mod);
84 0 : FindClustersSDD(fDigits);
85 :
86 0 : }
87 :
88 : //______________________________________________________________________
89 : void AliITSClusterFinderV2SDD::FindClustersSDD(TClonesArray *digits) {
90 : //------------------------------------------------------------
91 : // Actual SDD cluster finder
92 : //------------------------------------------------------------
93 :
94 0 : const Int_t kMaxBin=fNZbins*fNXbins;
95 0 : AliBin *bins[2];
96 0 : bins[0]=new AliBin[kMaxBin];
97 0 : bins[1]=new AliBin[kMaxBin];
98 0 : TBits *anodeFired[2];
99 0 : anodeFired[0]=new TBits(fNAnodes);
100 0 : anodeFired[1]=new TBits(fNAnodes);
101 0 : anodeFired[0]->ResetAllBits();
102 0 : anodeFired[1]->ResetAllBits();
103 0 : AliITSCalibrationSDD* cal = (AliITSCalibrationSDD*)GetResp(fModule);
104 0 : if(cal==0){
105 0 : AliError(Form("Calibration object not present for SDD module %d\n",fModule));
106 0 : return;
107 : }
108 :
109 : AliITSdigitSDD *d=0;
110 0 : Int_t i, ndigits=digits->GetEntriesFast();
111 0 : for (i=0; i<ndigits; i++) {
112 0 : d=(AliITSdigitSDD*)digits->UncheckedAt(i);
113 0 : Int_t ian=d->GetCoord1();
114 0 : Int_t itb=d->GetCoord2();
115 : //Int_t iSide=0;
116 : //if (ian >= fNAnodes) iSide=1;
117 0 : Float_t gain=cal->GetChannelGain(ian)/fDetTypeRec->GetAverageGainSDD();
118 0 : Float_t charge=d->GetSignal(); // returns expanded signal
119 : // (10 bit, low threshold already added)
120 0 : Float_t baseline = cal->GetBaseline(ian);
121 0 : if(charge>baseline) charge-=baseline;
122 : else charge=0;
123 :
124 0 : if(gain>0.){ // Bad channels have gain=0.
125 0 : charge/=gain;
126 0 : if(charge<cal->GetThresholdAnode(ian)) continue;
127 0 : Int_t q=(Int_t)(charge+0.5);
128 0 : Int_t y=itb+1;
129 0 : Int_t z=ian+1;
130 0 : if (z <= fNAnodes){
131 0 : bins[0][y*fNZbins+z].SetQ(q);
132 0 : bins[0][y*fNZbins+z].SetMask(1);
133 0 : bins[0][y*fNZbins+z].SetIndex(i);
134 0 : anodeFired[0]->SetBitNumber(ian);
135 0 : } else {
136 0 : z-=fNAnodes;
137 0 : bins[1][y*fNZbins+z].SetQ(q);
138 0 : bins[1][y*fNZbins+z].SetMask(1);
139 0 : bins[1][y*fNZbins+z].SetIndex(i);
140 0 : anodeFired[1]->SetBitNumber(ian-fNAnodes);
141 : }
142 0 : }
143 0 : }
144 :
145 0 : FindClustersSDD(bins, anodeFired, digits);
146 :
147 0 : delete[] bins[0];
148 0 : delete[] bins[1];
149 0 : delete anodeFired[0];
150 0 : delete anodeFired[1];
151 :
152 0 : }
153 :
154 : //______________________________________________________________________
155 : void AliITSClusterFinderV2SDD::
156 : FindClustersSDD(AliBin* bins[2], TBits* anodeFired[2],
157 : TClonesArray *digits, TClonesArray *clusters, Int_t jitter) {
158 : //------------------------------------------------------------
159 : // Actual SDD cluster finder
160 : //------------------------------------------------------------
161 :
162 : static AliITSRecoParam *repa = NULL;
163 0 : if(!repa){
164 0 : repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
165 0 : if(!repa){
166 0 : repa = AliITSRecoParam::GetHighFluxParam();
167 0 : AliWarning("Using default AliITSRecoParam class");
168 0 : }
169 : }
170 0 : const TGeoHMatrix *mT2L=AliITSgeomTGeo::GetTracking2LocalMatrix(fModule);
171 0 : AliITSCalibrationSDD* cal = (AliITSCalibrationSDD*)GetResp(fModule);
172 0 : if(cal==0){
173 0 : AliError(Form("Calibration object not present for SDD module %d\n",fModule));
174 0 : return;
175 : }
176 0 : const Int_t kMaxBin=fNZbins*fNXbins;
177 : Int_t ncl=0;
178 : TClonesArray &cl=*clusters;
179 0 : for (Int_t s=0; s<2; s++){
180 0 : for(Int_t iAnode=0; iAnode<GetSeg()->NpzHalf(); iAnode++){
181 0 : if(anodeFired[s]->TestBitNumber(iAnode)==kFALSE) continue;
182 0 : for(Int_t iTimeBin=0; iTimeBin<GetSeg()->Npx(); iTimeBin++){
183 0 : Int_t index=(iTimeBin+1)*fNZbins+(iAnode+1);
184 0 : if (bins[s][index].IsUsed()) continue;
185 0 : if(NoiseSuppress(index,s,bins[s],cal)) continue;
186 0 : Int_t idx[32]; UInt_t msk[32]; Int_t npeaks=0;
187 0 : FindPeaks(index, fNZbins, bins[s], idx, msk, npeaks);
188 :
189 0 : if (npeaks>30) continue;
190 0 : if (npeaks==0) continue;
191 :
192 : Int_t k,l;
193 : Int_t nClust;
194 0 : if(repa->GetUseUnfoldingInClusterFinderSDD()){
195 0 : for (k=0; k<npeaks-1; k++){//mark adjacent peaks
196 0 : if (idx[k] < 0) continue; //this peak is already removed
197 0 : for (l=k+1; l<npeaks; l++) {
198 0 : if (idx[l] < 0) continue; //this peak is already removed
199 0 : Int_t ki=idx[k]/fNZbins, kj=idx[k] - ki*fNZbins;
200 0 : Int_t li=idx[l]/fNZbins, lj=idx[l] - li*fNZbins;
201 0 : Int_t di=TMath::Abs(ki - li);
202 0 : Int_t dj=TMath::Abs(kj - lj);
203 0 : if (di>1 || dj>1) continue;
204 0 : if (bins[s][idx[k]].GetQ() > bins[s][idx[l]].GetQ()) {
205 0 : msk[l]=msk[k];
206 0 : idx[l]*=-1;
207 : } else {
208 0 : msk[k]=msk[l];
209 0 : idx[k]*=-1;
210 0 : break;
211 : }
212 0 : }
213 : }
214 : nClust=npeaks;
215 0 : }else{
216 0 : for (k=1; k<npeaks; k++) msk[k]=msk[0];
217 : nClust=1;
218 : }
219 : Float_t maxADC=0;
220 0 : for (k=0; k<npeaks; k++) {
221 0 : if(idx[k]>0. && bins[s][idx[k]].GetQ() > maxADC) maxADC=bins[s][idx[k]].GetQ();
222 0 : MarkPeak(TMath::Abs(idx[k]), fNZbins, bins[s], msk[k]);
223 : }
224 0 : if(maxADC<fCutOnPeakLoose) continue;
225 :
226 0 : for (k=0; k<nClust; k++) {
227 0 : if (idx[k] < 0) continue; //removed peak
228 0 : AliITSRecPoint c;
229 0 : MakeCluster(idx[k], fNZbins, bins[s], msk[k], c);
230 : //mi change
231 0 : Int_t milab[10];
232 0 : for (Int_t ilab=0;ilab<10;ilab++){
233 0 : milab[ilab]=-2;
234 : }
235 :
236 0 : if(digits) {
237 0 : for (Int_t di=-2; di<=2;di++){
238 0 : for (Int_t dj=-2;dj<=2;dj++){
239 0 : index = idx[k]+di+dj*fNZbins;
240 0 : if (index<0) continue;
241 0 : if (index>=kMaxBin) continue;
242 0 : AliBin *b=&bins[s][index];
243 0 : if(b->GetQ()<0.1) continue;
244 0 : AliITSdigitSDD* d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
245 0 : for (Int_t itrack=0;itrack<10;itrack++){
246 0 : Int_t track = (d->GetTracks())[itrack];
247 0 : if (track>=0) {
248 0 : AddLabel(milab, track);
249 : }
250 : }
251 0 : }
252 : }
253 0 : }
254 : else { // raw data
255 0 : if (fRawID2ClusID) milab[0] = fNClusters+1; // RS: store clID+1 as a reference to the cluster
256 : }
257 :
258 :
259 0 : Int_t clSizAnode=fZmax-fZmin+1;
260 0 : Int_t clSizTb=fXmax-fXmin+1;
261 0 : if(repa->GetUseSDDClusterSizeSelection()){
262 0 : if(clSizTb==1) continue; // cut common mode noise spikes
263 0 : if(clSizAnode>5) continue; // cut common mode noise spikes
264 0 : if(clSizTb>10) continue; // cut clusters on noisy anodes
265 0 : if(cal-> IsAMAt20MHz() && clSizTb>8) continue; // cut clusters on noisy anodes
266 : }
267 :
268 0 : AliITSresponseSDD* rsdd = fDetTypeRec->GetResponseSDD();
269 0 : Float_t y=c.GetY(),z=c.GetZ(), q=c.GetQ();
270 0 : y/=q; z/=q;
271 0 : Float_t zAnode=z-0.5; // to have anode in range 0.-255. and centered on the mid of the pitch
272 0 : Float_t timebin=y-0.5; // to have time bin in range 0.-255. amd centered on the mid of the bin
273 0 : if(s==1) zAnode += GetSeg()->NpzHalf(); // right side has anodes from 256. to 511.
274 0 : Float_t zdet = GetSeg()->GetLocalZFromAnode(zAnode);
275 0 : Float_t driftTimeUncorr = GetSeg()->GetDriftTimeFromTb(timebin)+jitter*rsdd->GetCarlosRXClockPeriod();
276 0 : Float_t driftTime=driftTimeUncorr-rsdd->GetTimeZero(fModule);
277 0 : if(driftTime<fMaxDrTimeForTightCut && maxADC<fCutOnPeakTight) continue;
278 :
279 0 : Float_t driftSpeed = cal->GetDriftSpeedAtAnode(zAnode) + rsdd->GetDeltaVDrift(fModule,zAnode>255);
280 0 : Float_t driftPathMicron = driftTime*driftSpeed;
281 : const Double_t kMicronTocm = 1.0e-4;
282 0 : Float_t xdet=(driftPathMicron-GetSeg()->Dx())*kMicronTocm; // xdet is negative
283 0 : if (s==0) xdet=-xdet; // left side has positive local x
284 :
285 0 : if(repa->GetUseSDDCorrectionMaps()){
286 0 : Float_t corrx=0, corrz=0;
287 0 : cal->GetCorrections(zdet,xdet,corrz,corrx,GetSeg());
288 0 : zdet+=corrz;
289 0 : xdet+=corrx;
290 0 : }
291 :
292 0 : Double_t loc[3]={xdet,0.,zdet},trk[3]={0.,0.,0.};
293 0 : mT2L->MasterToLocal(loc,trk);
294 0 : y=trk[1];
295 0 : z=trk[2];
296 :
297 : Double_t dEdxslope;
298 0 : if(digits) dEdxslope=rsdd->GetADCvsDriftTime(fModule,kTRUE);
299 0 : else dEdxslope=rsdd->GetADCvsDriftTime(fModule);
300 0 : q+=(driftTime*dEdxslope); // correction for zero supp.
301 0 : q/=rsdd->GetADCtokeV(fModule);
302 0 : if(cal-> IsAMAt20MHz()) q*=2.; // account for 1/2 sampling freq.
303 0 : if(q<repa->GetMinClusterChargeSDD()) continue; // remove noise clusters
304 :
305 0 : Float_t hit[6] = {y, z, 0.0030*0.0030, 0.0020*0.0020, q, 0.};
306 0 : Int_t info[3] = {clSizTb, clSizAnode, fNlayer[fModule]};
307 0 : if (digits) CheckLabels2(milab);
308 0 : milab[3]=fNdet[fModule];
309 0 : AliITSRecPoint cc(milab,hit,info);
310 0 : cc.SetType(nClust*100+npeaks);
311 0 : cc.SetDriftTime(driftTimeUncorr);
312 0 : cc.SetDriftSide(s);
313 0 : cc.SetChargeRatio(maxADC);
314 0 : if(clusters) new (cl[ncl]) AliITSRecPoint(cc);
315 : else {
316 0 : fDetTypeRec->AddRecPoint(cc);
317 : }
318 0 : fNClusters++; // RS
319 0 : ncl++;
320 0 : }
321 0 : }
322 0 : }
323 : }
324 0 : AliDebug(2,Form("Clusters found on SDD module %d (unfolding %d) = %d\n",fModule,repa->GetUseUnfoldingInClusterFinderSDD(),ncl));
325 :
326 0 : }
327 : //______________________________________________________________________
328 : void AliITSClusterFinderV2SDD::RawdataToClusters(AliRawReader* rawReader){
329 : //------------------------------------------------------------
330 : // This function creates ITS clusters from raw data
331 : //------------------------------------------------------------
332 0 : fNClusters = 0; //RS
333 0 : AliITSRawStream* inputSDD=AliITSRawStreamSDD::CreateRawStreamSDD(rawReader);
334 0 : AliDebug(1,Form("%s is used",inputSDD->ClassName()));
335 :
336 0 : AliITSDDLModuleMapSDD *ddlmap=(AliITSDDLModuleMapSDD*)fDetTypeRec->GetDDLModuleMapSDD();
337 0 : inputSDD->SetDDLModuleMap(ddlmap);
338 0 : for(Int_t iddl=0; iddl<AliITSDDLModuleMapSDD::GetNDDLs(); iddl++){
339 0 : for(Int_t icar=0; icar<AliITSDDLModuleMapSDD::GetNModPerDDL();icar++){
340 0 : Int_t iMod=ddlmap->GetModuleNumber(iddl,icar);
341 0 : if(iMod==-1) continue;
342 0 : AliITSCalibrationSDD* cal = (AliITSCalibrationSDD*)GetResp(iMod);
343 0 : if(cal==0){
344 0 : AliError(Form("Calibration object not present for SDD module %d\n",iMod));
345 0 : continue;
346 : }
347 0 : Bool_t isZeroSupp=cal->GetZeroSupp();
348 0 : if(isZeroSupp){
349 0 : for(Int_t iSid=0; iSid<2; iSid++) inputSDD->SetZeroSuppLowThreshold(iMod-240,iSid,cal->GetZSLowThreshold(iSid));
350 0 : }else{
351 0 : for(Int_t iSid=0; iSid<2; iSid++) inputSDD->SetZeroSuppLowThreshold(iMod-240,iSid,0);
352 : }
353 0 : }
354 : }
355 0 : FindClustersSDD(inputSDD);
356 0 : delete inputSDD;
357 0 : }
358 :
359 : void AliITSClusterFinderV2SDD::FindClustersSDD(AliITSRawStream* input)
360 : {
361 : //------------------------------------------------------------
362 : // Actual SDD cluster finder for raw data
363 : //------------------------------------------------------------
364 0 : AliITSRecPointContainer* rpc = AliITSRecPointContainer::Instance();
365 : Int_t nClustersSDD = 0;
366 0 : AliBin *bins[2];
367 0 : TBits* anodeFired[2];
368 0 : TBits* ddlAnodeFired[kHybridsPerDDL];
369 0 : for(Int_t iHyb=0;iHyb<kHybridsPerDDL;iHyb++){
370 0 : ddlAnodeFired[iHyb]=new TBits(fNAnodes);
371 0 : ddlAnodeFired[iHyb]->ResetAllBits();
372 : }
373 0 : Int_t vectModId[kModulesPerDDL];
374 0 : for(Int_t iMod=0; iMod<kModulesPerDDL; iMod++) vectModId[iMod]=-1;
375 :
376 : // read raw data input stream
377 : int countRW = 0; //RS
378 0 : if (fRawID2ClusID) fRawID2ClusID->Reset(); //RS if array was provided, we shall store the rawID -> ClusterID
379 : //
380 0 : while (input->Next()) {
381 0 : Int_t iModule = input->GetModuleID();
382 0 : if(iModule<0){
383 0 : AliWarning(Form("Invalid SDD module number %d\n", iModule));
384 0 : continue;
385 : }
386 0 : Int_t iCarlos =input->GetCarlosId();
387 0 : Int_t iSide = input->GetChannel();
388 0 : Int_t iHybrid=iCarlos*2+iSide;
389 :
390 0 : if (input->IsCompletedModule()) {
391 : // store the module number
392 0 : vectModId[iCarlos]=iModule;
393 0 : }
394 0 : else if (input->IsCompletedDDL()) {
395 : // when all data from a DDL was read, search for clusters
396 0 : Int_t jitter=input->GetJitter();
397 0 : for(Int_t iMod=0; iMod<kModulesPerDDL; iMod++){
398 0 : if(vectModId[iMod]>=0){
399 0 : fModule = vectModId[iMod];
400 0 : TClonesArray* clusters = rpc->UncheckedGetClusters(fModule);
401 0 : bins[0]=fDDLBins[iMod*2]; // first hybrid of the module
402 0 : bins[1]=fDDLBins[iMod*2+1]; // second hybrid of the module
403 0 : anodeFired[0]=ddlAnodeFired[iMod*2];
404 0 : anodeFired[1]=ddlAnodeFired[iMod*2+1];
405 0 : FindClustersSDD(bins, anodeFired, NULL, clusters,jitter);
406 0 : Int_t nClusters = clusters->GetEntriesFast();
407 0 : nClustersSDD += nClusters;
408 0 : vectModId[iMod]=-1;
409 0 : }
410 0 : for (Int_t s=0; s<2; s++){
411 0 : Int_t indexHyb=iMod*2+s;
412 0 : for(Int_t iAnode=0; iAnode<GetSeg()->NpzHalf(); iAnode++){
413 0 : if(ddlAnodeFired[indexHyb]->TestBitNumber(iAnode)==kFALSE) continue;
414 0 : for(Int_t iTimeBin=0; iTimeBin<GetSeg()->Npx(); iTimeBin++){
415 0 : Int_t index=(iTimeBin+1)*fNZbins+(iAnode+1);
416 0 : fDDLBins[indexHyb][index].Reset();
417 : }
418 0 : }
419 : }
420 0 : ddlAnodeFired[iMod*2]->ResetAllBits();
421 0 : ddlAnodeFired[iMod*2+1]->ResetAllBits();
422 : }
423 0 : }else{
424 : // fill the current digit into the bins array
425 0 : if(iHybrid<0 || iHybrid>=kHybridsPerDDL){
426 0 : AliWarning(Form("Invalid SDD hybrid number %d on module %d\n", iHybrid,iModule));
427 0 : continue;
428 : }
429 0 : AliITSCalibrationSDD* cal = (AliITSCalibrationSDD*)GetResp(iModule);
430 0 : if(cal==0){
431 0 : AliError(Form("Calibration object not present for SDD module %d\n",iModule));
432 0 : continue;
433 : }
434 0 : Float_t charge=input->GetSignal();
435 0 : Int_t chan=input->GetCoord1()+fNAnodes*iSide;
436 0 : Float_t gain=cal->GetChannelGain(chan)/fDetTypeRec->GetAverageGainSDD();;
437 0 : Float_t baseline = cal->GetBaseline(chan);
438 0 : if(charge>baseline) charge-=baseline;
439 : else charge=0;
440 0 : if(gain>0.){ // Bad channels have gain=0
441 0 : charge/=gain;
442 0 : if(charge>=cal->GetThresholdAnode(chan)) {
443 0 : Int_t q=(Int_t)(charge+0.5);
444 0 : Int_t iz = input->GetCoord1();
445 0 : Int_t itb = input->GetCoord2();
446 0 : Int_t index = (itb+1) * fNZbins + (iz+1);
447 0 : if((itb < fNTimeBins) && (iz < fNAnodes)) {
448 0 : fDDLBins[iHybrid][index].SetQ(q);
449 0 : fDDLBins[iHybrid][index].SetMask(1);
450 0 : fDDLBins[iHybrid][index].SetIndex(index);
451 0 : fDDLBins[iHybrid][index].SetRawID(countRW); //RS register raw id
452 0 : ddlAnodeFired[iHybrid]->SetBitNumber(iz);
453 0 : }else{
454 0 : AliWarning(Form("Invalid SDD cell: Anode=%d TimeBin=%d",iz,itb));
455 : }
456 0 : }
457 : }
458 0 : }
459 0 : countRW++; //RS
460 0 : }
461 0 : for(Int_t iHyb=0;iHyb<kHybridsPerDDL;iHyb++){
462 0 : delete ddlAnodeFired[iHyb];
463 : }
464 0 : AliDebug(1,Form("found clusters in ITS SDD: %d", nClustersSDD));
465 0 : }
466 :
467 : //______________________________________________________________________
468 : Bool_t AliITSClusterFinderV2SDD::NoiseSuppress(Int_t k, Int_t sid, AliBin* bins, const AliITSCalibrationSDD* cal) const {
469 : // applies zero suppression using the measured noise of each anode
470 : // threshold values from ALICE-INT-1999-28 V10
471 : // returns kTRUE if the digit should eb noise suppressed, kFALSE if it should be kept
472 : Float_t xfactL=2.2;
473 : Float_t xfactH=4.0;
474 : //
475 :
476 0 : Int_t iAn=(k%fNZbins)-1;
477 0 : if(iAn<0 || iAn>255) return kTRUE;
478 0 : if(sid==1) iAn+=256;
479 : Int_t nLow=0, nHigh=0;
480 0 : Float_t noise=cal->GetNoiseAfterElectronics(iAn);
481 : Float_t noisem1=noise;
482 0 : if(iAn>1) noisem1=cal->GetNoiseAfterElectronics(iAn-1);
483 : Float_t noisep1=noise;
484 0 : if(iAn<511) noisep1=cal->GetNoiseAfterElectronics(iAn+1);
485 0 : Float_t tL=noise*xfactL;
486 0 : Float_t tH=noise*xfactH;
487 0 : Float_t tLp1=noisep1*xfactL;
488 0 : Float_t tHp1=noisep1*xfactH;
489 0 : Float_t tLm1=noisem1*xfactL;
490 0 : Float_t tHm1=noisem1*xfactH;
491 0 : Int_t cC=bins[k].GetQ();
492 0 : if(cC<=tL){
493 0 : bins[k].SetQ(0);
494 0 : bins[k].SetMask(0xFFFFFFFE);
495 0 : return kTRUE;;
496 : }
497 : nLow++; // cC is greater than tL
498 0 : if(cC>tH) nHigh++;
499 0 : Int_t sS=bins[k-1].GetQ();
500 0 : if(sS>tLm1) nLow++;
501 0 : if(sS>tHm1) nHigh++;
502 0 : Int_t nN=bins[k+1].GetQ();
503 0 : if(nN>tLp1) nLow++;
504 0 : if(nN>tHp1) nHigh++;
505 0 : Int_t eE=bins[k-fNZbins].GetQ();
506 0 : if(eE>tL) nLow++;
507 0 : if(eE>tH) nHigh++;
508 0 : Int_t wW=bins[k+fNZbins].GetQ();
509 0 : if(wW>tL) nLow++;
510 0 : if(wW>tH) nHigh++;
511 0 : if(nLow<2 || nHigh<1) return kTRUE;
512 0 : else return kFALSE;
513 0 : }
514 :
515 :
516 :
|