1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
17 #include "AliITSClusterFinderSDD.h"
18 #include "AliITSMapA2.h"
19 #include "AliITSMapA1.h"
25 ClassImp(AliITSClusterFinderSDD)
27 //----------------------------------------------------------
28 AliITSClusterFinderSDD::AliITSClusterFinderSDD
29 (AliITSsegmentation *seg, AliITSresponse *response, TClonesArray *digits, TClonesArray *recp)
36 fNclusters= fClusters->GetEntriesFast();
45 //_____________________________________________________________________________
46 AliITSClusterFinderSDD::AliITSClusterFinderSDD()
64 //_____________________________________________________________________________
65 AliITSClusterFinderSDD::~AliITSClusterFinderSDD()
70 if(fMapA2) delete fMapA2;
73 //__________________________________________________________________________
74 AliITSClusterFinderSDD::AliITSClusterFinderSDD(const AliITSClusterFinderSDD &source){
76 if(&source == this) return;
77 this->fClusters = source.fClusters ;
78 this->fNclusters = source.fNclusters ;
79 this->fMap = source.fMap ;
80 this->fMapA2 = source.fMapA2 ;
81 this->fCutAmplitude = source.fCutAmplitude ;
82 this->fDAnode = source.fDAnode ;
83 this->fDTime = source.fDTime ;
84 this->fMinPeak = source.fMinPeak ;
85 this->fMinNCells = source.fMinNCells ;
89 //_________________________________________________________________________
90 AliITSClusterFinderSDD&
91 AliITSClusterFinderSDD::operator=(const AliITSClusterFinderSDD &source) {
92 // Assignment operator
93 if(&source == this) return *this;
94 this->fClusters = source.fClusters ;
95 this->fNclusters = source.fNclusters ;
96 this->fMap = source.fMap ;
97 this->fMapA2 = source.fMapA2 ;
98 this->fCutAmplitude = source.fCutAmplitude ;
99 this->fDAnode = source.fDAnode ;
100 this->fDTime = source.fDTime ;
101 this->fMinPeak = source.fMinPeak ;
102 this->fMinNCells = source.fMinNCells ;
106 //_____________________________________________________________________________
107 void AliITSClusterFinderSDD::SetMap()
110 if(!fMapA2) fMapA2=new AliITSMapA2(fSegmentation,fDigits,(double)fCutAmplitude);
111 if(!fMap) fMap=new AliITSMapA1(fSegmentation,fDigits);
114 //_____________________________________________________________________________
116 void AliITSClusterFinderSDD::Find1DClusters()
120 AliITS *iTS=(AliITS*)gAlice->GetModule("ITS");
122 // retrieve the parameters
123 Int_t fNofMaps = fSegmentation->Npz();
124 Int_t fMaxNofSamples = fSegmentation->Npx();
125 Int_t fNofAnodes = fNofMaps/2;
127 Float_t fTimeStep = fSegmentation->Dpx(dummy);
128 Float_t fSddLength = fSegmentation->Dx();
129 Float_t fDriftSpeed = fResponse->DriftSpeed();
131 Float_t anodePitch = fSegmentation->Dpz(dummy);
135 // Piergiorgio's code - do not subtract baseline since we start
136 // from digits and do not duplicate arrays, i.e. use fMap instead
137 // of Float_t fadc[2*fNofAnodes][fMaxNofSamples];
140 Int_t nofFoundClusters = 0;
142 Float_t **dfadc = new Float_t*[fNofMaps];
143 for(i=0;i<fNofMaps;i++) dfadc[i] = new Float_t[fMaxNofSamples];
144 Float_t fadc, fadc1, fadc2;
147 for(k=0;k<fNofAnodes;k++) {
148 idx = j*fNofAnodes+k;
149 // signal (fadc) & derivative (dfadc)
150 for(l=0; l<fMaxNofSamples; l++) {
151 fadc2=(Float_t)fMapA2->GetSignal(idx,l);
152 fadc1=(Float_t)fMapA2->GetSignal(idx,l-1);
153 if(l>0) dfadc[k][l-1] = fadc2-fadc1;
157 for(k=0;k<fNofAnodes;k++) {
158 idx = j*fNofAnodes+k;
163 while(it <= fMaxNofSamples-3) {
164 // cout << "sample: " << it << endl;
170 Float_t fadcmax = 0.;
171 Float_t dfadcmax = 0.;
173 // if(it >= 60) lthrmina = 2;
174 // if(it >= 100) lthrmina = 3;
176 //if(it >= 60) lthrmint = 3;
177 //if(it >= 100) lthrmint = 4;
183 if(id>=fMaxNofSamples) break;
184 fadc=fMapA2->GetSignal(idx,id);
187 if(fadc > 0) { lthra++; lthrt++; }
190 if(dfadc[k][id] > dfadcmax) {
191 dfadcmax = dfadc[k][id];
196 // skip if no signal over threshold
197 if(fMapA2->TestHit(idx,imax) == kEmpty) {it++; continue;}
200 if(fMapA2->TestHit(idx-1,imax) != kEmpty) lthra++;
203 if(fMapA2->TestHit(idx+1,imax) != kEmpty) lthra++;
206 if(fMapA2->TestHit(idx,imax-1) != kEmpty) lthrt++;
208 if(imax<fMaxNofSamples)
209 if(fMapA2->TestHit(idx,imax+1) != kEmpty) lthrt++;
215 if(lthrt >= lthrmint && lthra >= lthrmina) ilcl = 1;
219 Int_t tstop = tstart;
220 Float_t dfadcmin = 10000.;
222 for(ij=0; ij<10; ij++) {
223 if(dfadc[k][it+ij] < dfadcmin) {
225 dfadcmin = dfadc[k][it+ij];
229 Float_t clusterCharge = 0.;
230 Float_t clusterAnode = k+0.5;
231 Float_t clusterTime = 0.;
232 Float_t clusterMult = 0.;
233 Float_t clusterPeakAmplitude = 0.;
236 fResponse->GetNoiseParam(n,baseline);
237 for(its=tstart; its<=tstop; its++) {
238 fadc=fMapA2->GetSignal(idx,its)-baseline;
239 clusterCharge += fadc;
240 if(fadc > clusterPeakAmplitude) clusterPeakAmplitude = fadc;
241 clusterTime += fadc*its;
244 clusterTime /= (clusterCharge/fTimeStep); // ns
245 clusterCharge *= (fTimeStep/160.); // keV
246 if(clusterTime > 58.2) clusterTime -= 58.2; // ns
249 cout << "Warning: cluster with negative time " << clusterTime << ", peak ampl.: " << clusterPeakAmplitude << ", mult: " << clusterMult << ", charge: " << clusterCharge << endl;
250 cout << "Anode: " << k << ", tstart: " << tstart << ", tstop: " << tstop << ", Charge: " << clusterCharge << endl;
255 // cout << "Anode: " << k << ", tstart: " << tstart << ", tstop: " << tstop << ", Charge: " << clusterCharge << endl;
257 Float_t clusteranodePath = (0.06 + clusterAnode - fNofAnodes/2)*anodePitch;
258 Float_t clusterDriftPath = clusterTime*fDriftSpeed;
259 clusterDriftPath = fSddLength-clusterDriftPath;
261 if(clusterCharge < 0.) break;
263 //printf("wing clusterMult clusterAnode clusterTime %d %f %f %f \n",j+1,clusterMult, clusterAnode, clusterTime);
265 AliITSRawClusterSDD *clust = new AliITSRawClusterSDD(j+1,clusterAnode,clusterTime,clusterCharge,clusterPeakAmplitude,0.,0.,clusterDriftPath,clusteranodePath,clusterMult);
266 //fClusters->Add(point);
267 iTS->AddCluster(1,clust);
280 for(i=0;i<fNofMaps;i++) delete[] dfadc[i];
287 //_____________________________________________________________________________
288 void AliITSClusterFinderSDD::GroupClusters()
292 Float_t fTimeStep = fSegmentation->Dpx(dummy);
295 // get number of clusters for this module
296 Int_t nofClusters = fClusters->GetEntriesFast();
297 nofClusters -= fNclusters;
299 AliITSRawClusterSDD *clusterI;
300 AliITSRawClusterSDD *clusterJ;
302 Int_t *label = new Int_t [nofClusters];
304 for(i=0; i<nofClusters; i++) label[i] = 0;
305 for(i=0; i<nofClusters; i++) {
306 if(label[i] != 0) continue;
307 for(j=i+1; j<nofClusters; j++) {
308 if(label[j] != 0) continue;
309 clusterI = (AliITSRawClusterSDD*) fClusters->At(i);
310 clusterJ = (AliITSRawClusterSDD*) fClusters->At(j);
312 if(clusterI->T() < fTimeStep*60) fDAnode = 3.2;
313 if(clusterI->T() < fTimeStep*10) fDAnode = 1.2;
314 Bool_t pair = clusterI->Brother(clusterJ,fDAnode,fDTime);
316 // clusterI->PrintInfo();
317 // clusterJ->PrintInfo();
318 clusterI->Add(clusterJ);
320 fClusters->RemoveAt(j);
324 fClusters->Compress();
331 //_____________________________________________________________________________
333 void AliITSClusterFinderSDD::SelectClusters()
335 // get number of clusters for this module
336 Int_t nofClusters = fClusters->GetEntriesFast();
337 nofClusters -= fNclusters;
340 for(i=0; i<nofClusters; i++) {
341 AliITSRawClusterSDD *clusterI = (AliITSRawClusterSDD*) fClusters->At(i);
344 if(clusterI->Anodes() != 0.) {
345 wy = ((Float_t) clusterI->Samples())/clusterI->Anodes();
347 Float_t amp = clusterI->PeakAmpl();
348 if(amp < fMinPeak) rmflg = 1;
349 if(wy < fMinNCells) rmflg = 1;
350 if(rmflg) fClusters->RemoveAt(i);
352 fClusters->Compress();
357 //_____________________________________________________________________________
359 void AliITSClusterFinderSDD::GetRecPoints()
363 AliITS *iTS=(AliITS*)gAlice->GetModule("ITS");
365 // get number of clusters for this module
366 Int_t nofClusters = fClusters->GetEntriesFast();
367 nofClusters -= fNclusters;
369 const Float_t kconvGeV = 1.e-6; // GeV -> KeV
370 const Float_t kconv = 1.0e-4;
371 const Float_t kRMSx = 38.0*kconv; // microns->cm ITS TDR Table 1.3
372 const Float_t kRMSz = 28.0*kconv; // microns->cm ITS TDR Table 1.3
377 for(i=0; i<nofClusters; i++) {
378 AliITSRawClusterSDD *clusterI = (AliITSRawClusterSDD*) fClusters->At(i);
379 fSegmentation->GetPadIxz(clusterI->X(),clusterI->Z(),ix,iz);
380 AliITSdigitSDD *dig = (AliITSdigitSDD*)fMap->GetHit(iz-1,ix-1);
382 rnew.SetX(clusterI->X());
383 rnew.SetZ(clusterI->Z());
384 rnew.SetQ(clusterI->Q()); // in KeV - should be ADC
385 rnew.SetdEdX(kconvGeV*clusterI->Q());
386 rnew.SetSigmaX2(kRMSx*kRMSx);
387 rnew.SetSigmaZ2(kRMSz*kRMSz);
388 rnew.fTracks[0]=dig->fTracks[0];
389 rnew.fTracks[1]=dig->fTracks[1];
390 rnew.fTracks[2]=dig->fTracks[2];
391 iTS->AddRecPoint(rnew);
397 //_____________________________________________________________________________
399 void AliITSClusterFinderSDD::FindRawClusters()