]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ITS/AliITSClusterFinderV2SDD.cxx
SSD services on the cones (E. Cattaruzza). Removed SSD relate overlaps (M. Sitta)
[u/mrichter/AliRoot.git] / ITS / AliITSClusterFinderV2SDD.cxx
CommitLineData
04366a57 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 **************************************************************************/
d76cb3ad 15
16/* $Id$*/
17
04366a57 18////////////////////////////////////////////////////////////////////////////
19// Implementation of the ITS clusterer V2 class //
20// //
21// Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch //
22// //
23///////////////////////////////////////////////////////////////////////////
24
25
04366a57 26
ae485645 27#include <TClonesArray.h>
04366a57 28#include "AliITSClusterFinderV2SDD.h"
00a7cc50 29#include "AliITSRecPoint.h"
7d62fb64 30#include "AliITSDetTypeRec.h"
04366a57 31#include "AliRawReader.h"
0599a018 32#include "AliITSRawStreamSDD.h"
5bfe44ce 33#include "AliITSCalibrationSDD.h"
34#include "AliITSDetTypeRec.h"
debf7b78 35#include "AliITSReconstructor.h"
5bfe44ce 36#include "AliITSsegmentationSDD.h"
04366a57 37#include "AliITSdigitSDD.h"
b4704be3 38#include "AliITSgeomTGeo.h"
debf7b78 39
04366a57 40ClassImp(AliITSClusterFinderV2SDD)
41
4952f440 42AliITSClusterFinderV2SDD::AliITSClusterFinderV2SDD(AliITSDetTypeRec* dettyp):AliITSClusterFinderV2(dettyp)
a66a0eb6 43{
04366a57 44
45 //Default constructor
46
04366a57 47}
48
49
50void AliITSClusterFinderV2SDD::FindRawClusters(Int_t mod){
51
52 //Find clusters V2
53 SetModule(mod);
54 FindClustersSDD(fDigits);
55
56}
57
58void AliITSClusterFinderV2SDD::FindClustersSDD(TClonesArray *digits) {
59 //------------------------------------------------------------
60 // Actual SDD cluster finder
61 //------------------------------------------------------------
4952f440 62 Int_t nAnodes = GetSeg()->NpzHalf();
63 Int_t nzBins = nAnodes+2;
64 Int_t nTimeBins = GetSeg()->Npx();
65 Int_t nxBins = nTimeBins+2;
f6b6d58e 66 const Int_t kMaxBin=nzBins*nxBins;
04366a57 67
68 AliBin *bins[2];
4952f440 69 bins[0]=new AliBin[kMaxBin];
70 bins[1]=new AliBin[kMaxBin];
404c1c29 71 AliITSCalibrationSDD* cal = (AliITSCalibrationSDD*)GetResp(fModule);
9c7f5947 72 if(cal==0){
73 AliError(Form("Calibration object not present for SDD module %d\n",fModule));
74 return;
75 }
83ec5e27 76
04366a57 77 AliITSdigitSDD *d=0;
78 Int_t i, ndigits=digits->GetEntriesFast();
79 for (i=0; i<ndigits; i++) {
80 d=(AliITSdigitSDD*)digits->UncheckedAt(i);
20f3f947 81 Int_t ian=d->GetCoord1();
82 Int_t itb=d->GetCoord2();
83 Int_t iSide=0;
84 if (ian >= nAnodes) iSide=1;
85 Float_t gain=cal->GetChannelGain(ian);
83ec5e27 86 Float_t charge=d->GetSignal(); // returns expanded signal
87 // (10 bit, low threshold already added)
20f3f947 88 Float_t baseline = cal->GetBaseline(ian);
89 if(charge>baseline) charge-=baseline;
90 else charge=0;
5683bd96 91
9c7f5947 92 if(gain>0.){ // Bad channels have gain=0.
93 charge/=gain;
20f3f947 94 if(charge<cal->GetThresholdAnode(ian)) continue;
9c7f5947 95 Int_t q=(Int_t)(charge+0.5);
20f3f947 96 Int_t y=itb+1;
97 Int_t z=ian+1;
9c7f5947 98 if (z <= nAnodes){
99 bins[0][y*nzBins+z].SetQ(q);
100 bins[0][y*nzBins+z].SetMask(1);
101 bins[0][y*nzBins+z].SetIndex(i);
102 } else {
103 z-=nAnodes;
104 bins[1][y*nzBins+z].SetQ(q);
105 bins[1][y*nzBins+z].SetMask(1);
106 bins[1][y*nzBins+z].SetIndex(i);
107 }
04366a57 108 }
109 }
110
4952f440 111 FindClustersSDD(bins, kMaxBin, nzBins, digits);
04366a57 112
113 delete[] bins[0];
114 delete[] bins[1];
115
116}
117
118void AliITSClusterFinderV2SDD::
119FindClustersSDD(AliBin* bins[2], Int_t nMaxBin, Int_t nzBins,
120 TClonesArray *digits, TClonesArray *clusters) {
121 //------------------------------------------------------------
122 // Actual SDD cluster finder
123 //------------------------------------------------------------
b4704be3 124
debf7b78 125 static AliITSRecoParam *repa = NULL;
126 if(!repa){
127 repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
128 if(!repa){
ed446fa3 129 repa = AliITSRecoParam::GetHighFluxParam();
debf7b78 130 AliWarning("Using default AliITSRecoParam class");
131 }
132 }
b4704be3 133 const TGeoHMatrix *mT2L=AliITSgeomTGeo::GetTracking2LocalMatrix(fModule);
404c1c29 134 AliITSCalibrationSDD* cal = (AliITSCalibrationSDD*)GetResp(fModule);
9c7f5947 135 if(cal==0){
136 AliError(Form("Calibration object not present for SDD module %d\n",fModule));
137 return;
138 }
04366a57 139 Int_t ncl=0;
140 TClonesArray &cl=*clusters;
141 for (Int_t s=0; s<2; s++)
142 for (Int_t i=0; i<nMaxBin; i++) {
e3ee4984 143 NoiseSuppress(i,s,nzBins,bins[s],cal);
04366a57 144 if (bins[s][i].IsUsed()) continue;
145 Int_t idx[32]; UInt_t msk[32]; Int_t npeaks=0;
146 FindPeaks(i, nzBins, bins[s], idx, msk, npeaks);
147
148 if (npeaks>30) continue;
149 if (npeaks==0) continue;
150
151 Int_t k,l;
152 for (k=0; k<npeaks-1; k++){//mark adjacent peaks
153 if (idx[k] < 0) continue; //this peak is already removed
154 for (l=k+1; l<npeaks; l++) {
f6b6d58e 155 if (idx[l] < 0) continue; //this peak is already removed
156 Int_t ki=idx[k]/nzBins, kj=idx[k] - ki*nzBins;
157 Int_t li=idx[l]/nzBins, lj=idx[l] - li*nzBins;
158 Int_t di=TMath::Abs(ki - li);
159 Int_t dj=TMath::Abs(kj - lj);
160 if (di>1 || dj>1) continue;
161 if (bins[s][idx[k]].GetQ() > bins[s][idx[l]].GetQ()) {
162 msk[l]=msk[k];
163 idx[l]*=-1;
164 } else {
165 msk[k]=msk[l];
166 idx[k]*=-1;
167 break;
168 }
04366a57 169 }
170 }
171
172 for (k=0; k<npeaks; k++) {
debf7b78 173 if(repa->GetUseUnfoldingInClusterFinderSDD()==kFALSE) msk[k]=msk[0];
04366a57 174 MarkPeak(TMath::Abs(idx[k]), nzBins, bins[s], msk[k]);
175 }
176
177 for (k=0; k<npeaks; k++) {
f6b6d58e 178 if (idx[k] < 0) continue; //removed peak
179 AliITSRecPoint c;
180 MakeCluster(idx[k], nzBins, bins[s], msk[k], c);
181 //mi change
182 Int_t milab[10];
183 for (Int_t ilab=0;ilab<10;ilab++){
184 milab[ilab]=-2;
185 }
186 Int_t maxi=0,mini=0,maxj=0,minj=0;
187 //AliBin *bmax=&bins[s][idx[k]];
188 //Float_t max = TMath::Max(TMath::Abs(bmax->GetQ())/5.,3.);
189
190 for (Int_t di=-2; di<=2;di++){
191 for (Int_t dj=-3;dj<=3;dj++){
192 Int_t index = idx[k]+di+dj*nzBins;
193 if (index<0) continue;
194 if (index>=nMaxBin) continue;
195 AliBin *b=&bins[s][index];
196 Int_t nAnode=index%nzBins-1;
197 Int_t adcSignal=b->GetQ();
198 if(adcSignal>cal->GetThresholdAnode(nAnode)){
199 if (di>maxi) maxi=di;
200 if (di<mini) mini=di;
201 if (dj>maxj) maxj=dj;
202 if (dj<minj) minj=dj;
203 }
204 //
205 if(digits) {
206 if (TMath::Abs(di)<2&&TMath::Abs(dj)<2){
207 AliITSdigitSDD* d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
208 for (Int_t itrack=0;itrack<10;itrack++){
209 Int_t track = (d->GetTracks())[itrack];
210 if (track>=0) {
211 AddLabel(milab, track);
212 }
213 }
214 }
215 }
216 }
217 }
218
219
220 Float_t y=c.GetY(),z=c.GetZ(), q=c.GetQ();
221 y/=q; z/=q;
222 Float_t zAnode=z-0.5; // to have anode in range 0.-255. and centered on the mid of the pitch
223 Float_t timebin=y-0.5; // to have time bin in range 0.-255. amd centered on the mid of the bin
224 if(s==1) zAnode += GetSeg()->NpzHalf(); // right side has anodes from 256. to 511.
225 Float_t zdet = GetSeg()->GetLocalZFromAnode(zAnode);
226 Float_t driftTime = GetSeg()->GetDriftTimeFromTb(timebin) - cal->GetTimeOffset();
227 Float_t driftPathMicron = cal->GetDriftPath(driftTime,zAnode);
228 const Double_t kMicronTocm = 1.0e-4;
229 Float_t xdet=(driftPathMicron-GetSeg()->Dx())*kMicronTocm; // xdet is negative
230 if (s==0) xdet=-xdet; // left side has positive local x
c9a38d3d 231
232 Float_t corrx=0, corrz=0;
233 cal->GetCorrections(zdet,xdet,corrz,corrx,GetSeg());
234 zdet+=corrz;
235 xdet+=corrx;
f6b6d58e 236
237 Double_t loc[3]={xdet,0.,zdet},trk[3]={0.,0.,0.};
238 mT2L->MasterToLocal(loc,trk);
239 y=trk[1];
240 z=trk[2];
241
242 q/=cal->GetADC2keV(); //to have MPV 1 MIP = 86.4 KeV
243 Float_t hit[5] = {y, z, 0.0030*0.0030, 0.0020*0.0020, q};
244 Int_t info[3] = {maxj-minj+1, maxi-mini+1, fNlayer[fModule]};
245 if (digits) {
246 // AliBin *b=&bins[s][idx[k]];
247 // AliITSdigitSDD* d=(AliITSdigitSDD*)digits->UncheckedAt(b->GetIndex());
248 {
249 //Int_t lab[3];
250 //lab[0]=(d->GetTracks())[0];
251 //lab[1]=(d->GetTracks())[1];
252 //lab[2]=(d->GetTracks())[2];
253 //CheckLabels(lab);
254 CheckLabels2(milab);
255 }
256 }
257 milab[3]=fNdet[fModule];
258
259 AliITSRecPoint cc(milab,hit,info);
260 cc.SetType(npeaks);
261 if(clusters) new (cl[ncl]) AliITSRecPoint(cc);
262 else {
263 fDetTypeRec->AddRecPoint(cc);
264 }
265 ncl++;
04366a57 266 }
267 }
24c98369 268
04366a57 269}
f6b6d58e 270//______________________________________________________________________
04366a57 271void AliITSClusterFinderV2SDD::RawdataToClusters(AliRawReader* rawReader,TClonesArray** clusters){
272 //------------------------------------------------------------
273 // This function creates ITS clusters from raw data
274 //------------------------------------------------------------
275 rawReader->Reset();
0599a018 276 AliITSRawStreamSDD inputSDD(rawReader);
979b5a5f 277 AliITSDDLModuleMapSDD *ddlmap=(AliITSDDLModuleMapSDD*)fDetTypeRec->GetDDLModuleMapSDD();
278 inputSDD.SetDDLModuleMap(ddlmap);
83ec5e27 279 for(Int_t iddl=0; iddl<AliITSDDLModuleMapSDD::GetNDDLs(); iddl++){
280 for(Int_t icar=0; icar<AliITSDDLModuleMapSDD::GetNModPerDDL();icar++){
281 Int_t iMod=ddlmap->GetModuleNumber(iddl,icar);
282 if(iMod==-1) continue;
283 AliITSCalibrationSDD* cal = (AliITSCalibrationSDD*)GetResp(iMod);
284 if(cal==0){
285 AliError(Form("Calibration object not present for SDD module %d\n",iMod));
286 continue;
287 }
288 AliITSresponseSDD* res = (AliITSresponseSDD*)cal->GetResponse();
289 const char *option=res->ZeroSuppOption();
290 if(strstr(option,"ZS")){
291 for(Int_t iSid=0; iSid<2; iSid++) inputSDD.SetZeroSuppLowThreshold(iMod-240,iSid,cal->GetZSLowThreshold(iSid));
292 }else{
293 for(Int_t iSid=0; iSid<2; iSid++) inputSDD.SetZeroSuppLowThreshold(iMod-240,iSid,0);
294 }
295 }
296 }
04366a57 297 FindClustersSDD(&inputSDD,clusters);
298
299}
300
301void AliITSClusterFinderV2SDD::FindClustersSDD(AliITSRawStream* input,
302 TClonesArray** clusters)
303{
304 //------------------------------------------------------------
305 // Actual SDD cluster finder for raw data
306 //------------------------------------------------------------
307 Int_t nClustersSDD = 0;
4952f440 308 Int_t nAnodes = GetSeg()->NpzHalf();
309 Int_t nzBins = nAnodes+2;
310 Int_t nTimeBins = GetSeg()->Npx();
311 Int_t nxBins = nTimeBins+2;
f6b6d58e 312 const Int_t kMaxBin=nzBins*nxBins;
ae485645 313 AliBin *bins[2];
93a93288 314 AliBin *ddlbins[kHybridsPerDDL]; // 12 modules (=24 hybrids) of 1 DDL read "in parallel"
315 for(Int_t iHyb=0;iHyb<kHybridsPerDDL;iHyb++) ddlbins[iHyb]=new AliBin[kMaxBin];
04366a57 316 // read raw data input stream
14dceddf 317 while (input->Next()) {
e4da2288 318 Int_t iModule = input->GetModuleID();
93a93288 319 if(iModule<0){
320 AliWarning(Form("Invalid SDD module number %d\n", iModule));
321 continue;
322 }
44c5b268 323
14dceddf 324 Int_t iCarlos =((AliITSRawStreamSDD*)input)->GetCarlosId();
325 Int_t iSide = ((AliITSRawStreamSDD*)input)->GetChannel();
326 Int_t iHybrid=iCarlos*2+iSide;
327 if (input->IsCompletedModule()) {
04366a57 328 // when all data from a module was read, search for clusters
44c5b268 329 if(iCarlos<0){
330 AliWarning(Form("Invalid SDD carlos number %d on module %d\n", iCarlos,iModule));
331 continue;
332 }
333 clusters[iModule] = new TClonesArray("AliITSRecPoint");
334 fModule = iModule;
335 bins[0]=ddlbins[iCarlos*2]; // first hybrid of the completed module
336 bins[1]=ddlbins[iCarlos*2+1]; // second hybrid of the completed module
337 FindClustersSDD(bins, kMaxBin, nzBins, NULL, clusters[iModule]);
338 Int_t nClusters = clusters[iModule]->GetEntriesFast();
339 nClustersSDD += nClusters;
340 for(Int_t iBin=0;iBin<kMaxBin; iBin++){
341 ddlbins[iCarlos*2][iBin].Reset();
342 ddlbins[iCarlos*2+1][iBin].Reset();
343 }
5dfa68c5 344 }else{
04366a57 345 // fill the current digit into the bins array
44c5b268 346 if(iHybrid<0 || iHybrid>=kHybridsPerDDL){
347 AliWarning(Form("Invalid SDD hybrid number %d on module %d\n", iHybrid,iModule));
348 continue;
349 }
e4da2288 350 AliITSCalibrationSDD* cal = (AliITSCalibrationSDD*)GetResp(iModule);
9c7f5947 351 if(cal==0){
352 AliError(Form("Calibration object not present for SDD module %d\n",iModule));
353 continue;
354 }
5683bd96 355 Float_t charge=input->GetSignal();
14dceddf 356 Int_t chan=input->GetCoord1()+nAnodes*iSide;
357 Float_t gain=cal->GetChannelGain(chan);
20f3f947 358 Float_t baseline = cal->GetBaseline(chan);
359 if(charge>baseline) charge-=baseline;
360 else charge=0;
9c7f5947 361 if(gain>0.){ // Bad channels have gain=0
362 charge/=gain;
363 if(charge>=cal->GetThresholdAnode(chan)) {
364 Int_t q=(Int_t)(charge+0.5);
365 Int_t iz = input->GetCoord1();
366 Int_t itb = input->GetCoord2();
367 Int_t index = (itb+1) * nzBins + (iz+1);
368 if(index<kMaxBin){
369 ddlbins[iHybrid][index].SetQ(q);
370 ddlbins[iHybrid][index].SetMask(1);
371 ddlbins[iHybrid][index].SetIndex(index);
372 }else{
373 AliWarning(Form("Invalid SDD cell: Anode=%d TimeBin=%d",iz,itb));
374 }
93a93288 375 }
5dfa68c5 376 }
04366a57 377 }
378 }
93a93288 379 for(Int_t iHyb=0;iHyb<kHybridsPerDDL;iHyb++) delete [] ddlbins[iHyb];
04366a57 380 Info("FindClustersSDD", "found clusters in ITS SDD: %d", nClustersSDD);
04366a57 381}
382
e3ee4984 383//______________________________________________________________________
384void AliITSClusterFinderV2SDD::NoiseSuppress(Int_t k, Int_t sid,Int_t nzBins, AliBin* bins, AliITSCalibrationSDD* cal) const {
385 // applies zero suppression using the measured noise of each anode
386 // threshold values from ALICE-INT-1999-28 V10
83ec5e27 387 Float_t xfactL=2.2;
388 Float_t xfactH=4.0;
e3ee4984 389 //
390
391 Int_t iAn=(k%nzBins)-1;
392 if(iAn<0 || iAn>255) return;
393 if(sid==1) iAn+=256;
394 Int_t nLow=0, nHigh=0;
395 Float_t noise=cal->GetNoiseAfterElectronics(iAn);
396 Float_t noisem1=noise;
397 if(iAn>1) noisem1=cal->GetNoiseAfterElectronics(iAn-1);
398 Float_t noisep1=noise;
399 if(iAn<511) noisep1=cal->GetNoiseAfterElectronics(iAn+1);
83ec5e27 400 Float_t tL=noise*xfactL;
401 Float_t tH=noise*xfactH;
402 Float_t tLp1=noisep1*xfactL;
403 Float_t tHp1=noisep1*xfactH;
404 Float_t tLm1=noisem1*xfactL;
405 Float_t tHm1=noisem1*xfactH;
e3ee4984 406 Float_t cC=bins[k].GetQ();
407 if(cC<=tL){
408 bins[k].SetQ(0);
409 bins[k].SetMask(0xFFFFFFFE);
410 return;
411 }
412 nLow++; // cC is greater than tL
413 if(cC>tH) nHigh++;
414 Int_t sS=bins[k-1].GetQ();
415 if(sS>tLm1) nLow++;
416 if(sS>tHm1) nHigh++;
417 Int_t nN=bins[k+1].GetQ();
418 if(nN>tLp1) nLow++;
419 if(nN>tHp1) nHigh++;
420 Int_t eE=bins[k-nzBins].GetQ();
421 if(eE>tL) nLow++;
422 if(eE>tH) nHigh++;
423 Int_t wW=bins[k+nzBins].GetQ();
424 if(wW>tL) nLow++;
425 if(wW>tH) nHigh++;
426 if(nLow<3 || nHigh<1){
427 bins[k].SetQ(0);
428 bins[k].SetMask(0xFFFFFFFE);
429 }
430}
431
04366a57 432
d97eb3fe 433