]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ITS/AliITSClusterFinderSSD.cxx
Modifications associated with remerging the Ba/Sa and Dubna pixel simulations,
[u/mrichter/AliRoot.git] / ITS / AliITSClusterFinderSSD.cxx
CommitLineData
b0f5e3fc 1/**************************************************************************
2 * Copyright(c) 1998-1999, 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
bf3f2830 16// **************************************************************************
17// * The package was revised and changed by Boris Batiounia in the time *
18// * period of March - June 2001 *
19// **************************************************************************/
20//
4ae5bbc4 21#include <Riostream.h>
eb08b98f 22#include <TArrayI.h>
b0f5e3fc 23#include "AliRun.h"
e8189707 24#include "AliITS.h"
e869281d 25#include "AliITSdigitSSD.h"
41b19549 26#include "AliITSRawClusterSSD.h"
3c9a27a7 27#include "AliITSRecPoint.h"
e8189707 28#include "AliITSMapA1.h"
b0f5e3fc 29#include "AliITSClusterFinderSSD.h"
e8189707 30#include "AliITSclusterSSD.h"
31#include "AliITSpackageSSD.h"
aacedc3e 32#include "AliITSresponseSSD.h"
33#include "AliITSsegmentationSSD.h"
0315d466 34#include "AliITSgeom.h"
b669392e 35
114da3a4 36const Bool_t AliITSClusterFinderSSD::fgkSIDEP=kTRUE;
37const Bool_t AliITSClusterFinderSSD::fgkSIDEN=kFALSE;
b0f5e3fc 38
39ClassImp(AliITSClusterFinderSSD)
40
f239b2fe 41//____________________________________________________________________
b0f5e3fc 42//
43// Constructor
fe15e140 44//______________________________________________________________________
aacedc3e 45AliITSClusterFinderSSD::AliITSClusterFinderSSD():
46AliITSClusterFinder(),
47fITS(0),
48fClusterP(0),
49fNClusterP(0),
50fClusterN(0),
51fNClusterN(0),
52fPackages(0),
53fNPackages(0),
54fDigitsIndexP(0),
55fNDigitsP(0),
56fDigitsIndexN(0),
57fNDigitsN(0),
58fPitch(0.0),
59fTanP(0.0),
60fTanN(0.0),
61fPNsignalRatio(0.0),
62fSFF(0),
63fSFB(0){
fe15e140 64 //Default constructor
aacedc3e 65}
66//______________________________________________________________________
67AliITSClusterFinderSSD::AliITSClusterFinderSSD(AliITSsegmentation *seg,
68 TClonesArray *digits):
69AliITSClusterFinder(seg,0),
70fITS(0),
71fClusterP(0),
72fNClusterP(0),
73fClusterN(0),
74fNClusterN(0),
75fPackages(0),
76fNPackages(0),
77fDigitsIndexP(0),
78fNDigitsP(0),
79fDigitsIndexN(0),
80fNDigitsN(0),
81fPitch(0.0),
82fTanP(0.0),
83fTanN(0.0),
84fPNsignalRatio(0.0),
85fSFF(0),
86fSFB(0){
87 //Standard constructor
fe15e140 88
aacedc3e 89 SetDigits(digits);
90 SetMap(new AliITSMapA1(GetSeg(),Digits()));
91 fITS = (AliITS*)gAlice->GetModule("ITS");
92 fClusterP = new TClonesArray ("AliITSclusterSSD",200);
93 fNClusterP = 0;
94 fClusterN = new TClonesArray ("AliITSclusterSSD",200);
fe15e140 95 fNClusterN = 0;
aacedc3e 96 fPackages = new TClonesArray ("AliITSpackageSSD",200); //packages
fe15e140 97 fNPackages = 0;
aacedc3e 98 fDigitsIndexP = new TArrayI(300);
fe15e140 99 fNDigitsP = 0;
aacedc3e 100 fDigitsIndexN = new TArrayI(300);
fe15e140 101 fNDigitsN = 0;
aacedc3e 102 fPitch = GetSeg()->Dpx(0);
103 fPNsignalRatio= 7./8.; // warning: hard-wired number
b0f5e3fc 104}
fe15e140 105//______________________________________________________________________}
106AliITSClusterFinderSSD::AliITSClusterFinderSSD(AliITSsegmentation *seg,
aacedc3e 107 AliITSresponse *res):
108AliITSClusterFinder(seg,res),
109fITS(0),
110fClusterP(0),
111fNClusterP(0),
112fClusterN(0),
113fNClusterN(0),
114fPackages(0),
115fNPackages(0),
116fDigitsIndexP(0),
117fNDigitsP(0),
118fDigitsIndexN(0),
119fNDigitsN(0),
120fPitch(0.0),
121fTanP(0.0),
122fTanN(0.0),
123fPNsignalRatio(0.0),
124fSFF(0),
125fSFB(0){
fe15e140 126 //Standard constructor
127
fe15e140 128 fITS = (AliITS*)gAlice->GetModule("ITS");
129 fClusterP = new TClonesArray ("AliITSclusterSSD",200);
130 fNClusterP = 0;
131 fClusterN = new TClonesArray ("AliITSclusterSSD",200);
132 fNClusterN = 0;
133 fPackages = new TClonesArray ("AliITSpackageSSD",200); //packages
134 fNPackages = 0;
135 fDigitsIndexP = new TArrayI(300);
136 fNDigitsP = 0;
137 fDigitsIndexN = new TArrayI(300);
138 fNDigitsN = 0;
aacedc3e 139 fPitch = GetSeg()->Dpx(0);
fe15e140 140 fPNsignalRatio= 7./8.; // warning: hard-wired number
141}
142//______________________________________________________________________
143AliITSClusterFinderSSD::~AliITSClusterFinderSSD(){
144 // Default destructor
3c9a27a7 145
aacedc3e 146 fITS = 0;
b0f5e3fc 147 delete fClusterP;
148 delete fClusterN;
149 delete fPackages;
150 delete fDigitsIndexP;
151 delete fDigitsIndexN;
152}
fe15e140 153//______________________________________________________________________
154void AliITSClusterFinderSSD::InitReconstruction(){
155 // initialization of the cluster finder
f239b2fe 156
fe15e140 157 register Int_t i; //iterator
b0f5e3fc 158
fe15e140 159 for (i=0;i<fNClusterP;i++) fClusterP->RemoveAt(i);
160 fNClusterP =0;
161 for (i=0;i<fNClusterN;i++) fClusterN->RemoveAt(i);
162 fNClusterN=0;
163 for (i=0;i<fNPackages;i++) fPackages->RemoveAt(i);
164 fNPackages = 0;
165 fNDigitsP = 0;
166 fNDigitsN = 0;
bf3f2830 167 Float_t stereoP,stereoN;
aacedc3e 168 GetSeg()->Angles(stereoP,stereoN);
bf3f2830 169 CalcStepFactor(stereoP,stereoN);
aacedc3e 170 if(GetDebug(1)) cout<<"fSFF = "<<fSFF<<" fSFB = "<<fSFB<<"\n";
b0f5e3fc 171}
fe15e140 172//______________________________________________________________________
173void AliITSClusterFinderSSD::FindRawClusters(Int_t module){
174 // This function findes out all clusters belonging to one module
175 // 1. Zeroes all space after previous module reconstruction
176 // 2. Finds all neighbouring digits, create clusters
177 // 3. If necesery, resolves for each group of neighbouring digits
178 // how many clusters creates it.
179 // 4. Colculate the x and z coordinate
180 Int_t lay, lad, detect;
181 AliITSgeom *geom = fITS->GetITSgeom();
182
aacedc3e 183 SetModule(module);
184 geom->GetModuleId(GetModule(),lay, lad, detect);
185 if ( lay == 6 ) ((AliITSsegmentationSSD*)GetSeg())->SetLayer(6);
186 if ( lay == 5 ) ((AliITSsegmentationSSD*)GetSeg())->SetLayer(5);
fe15e140 187
188 InitReconstruction(); //ad. 1
aacedc3e 189 Map()->FillMap();
fe15e140 190 FillDigitsIndex();
191 SortDigits();
192 FindNeighbouringDigits(); //ad. 2
193 //SeparateOverlappedClusters(); //ad. 3
194 ClustersToPackages(); //ad. 4
aacedc3e 195 Map()->ClearMap();
b0f5e3fc 196}
fe15e140 197//______________________________________________________________________
198void AliITSClusterFinderSSD::FindNeighbouringDigits(){
199 //If there are any digits on this side, create 1st Cluster,
200 // add to it this digit, and increment number of clusters
201 register Int_t i;
202
203 if ((fNDigitsP>0 ) && (fNDigitsN > 0 )) {
204 Int_t currentstripNo;
205 Int_t *dbuffer = new Int_t [300]; //buffer for strip numbers
206 Int_t dnumber; //curent number of digits in buffer
207 TArrayI &lDigitsIndexP = *fDigitsIndexP;
208 TArrayI &lDigitsIndexN = *fDigitsIndexN;
209 TObjArray &lDigits = *(Digits());
210 TClonesArray &lClusterP = *fClusterP;
211 TClonesArray &lClusterN = *fClusterN;
212 //process P side
213 dnumber = 1;
214 dbuffer[0]=lDigitsIndexP[0];
215 //If next digit is a neigh. of previous, adds to last clust. this digit
216 for (i=1; i<fNDigitsP; i++) {
217 //reads new digit
218 currentstripNo = ((AliITSdigitSSD*)lDigits[lDigitsIndexP[i]])->
219 GetStripNumber();
220 //check if it is a neighbour of a previous one
221 if((((AliITSdigitSSD*)lDigits[lDigitsIndexP[i-1]])->
222 GetStripNumber())
223 == (currentstripNo-1) ) dbuffer[dnumber++]=lDigitsIndexP[i];
224 else{
225 //create a new one side cluster
226 new(lClusterP[fNClusterP++]) AliITSclusterSSD(dnumber,dbuffer,
227 Digits(),
228 fgkSIDEP);
229 dbuffer[0]=lDigitsIndexP[i];
230 dnumber = 1;
231 } // end if else
232 } // end loop over fNDigitsP
233 new(lClusterP[fNClusterP++]) AliITSclusterSSD(dnumber,dbuffer,
234 Digits(),fgkSIDEP);
235 //process N side
236 //for comments, see above
237 dnumber = 1;
238 dbuffer[0]=lDigitsIndexN[0];
239 //If next digit is a neigh. of previous, adds to last clust. this digit
240 for (i=1; i<fNDigitsN; i++) {
241 currentstripNo = ((AliITSdigitSSD*)(lDigits[lDigitsIndexN[i]]))->
b0f5e3fc 242 GetStripNumber();
fe15e140 243 if ( (((AliITSdigitSSD*)lDigits[lDigitsIndexN[i-1]])->
aacedc3e 244 GetStripNumber())
fe15e140 245 == (currentstripNo-1) ) dbuffer[dnumber++]=lDigitsIndexN[i];
246 else {
247 new(lClusterN[fNClusterN++]) AliITSclusterSSD(dnumber,dbuffer,
aacedc3e 248 Digits(),
249 fgkSIDEN);
fe15e140 250 dbuffer[0]=lDigitsIndexN[i];
251 dnumber = 1;
252 } // end if else
253 } // end loop over fNDigitsN
254 new(lClusterN[fNClusterN++]) AliITSclusterSSD(dnumber,dbuffer,
aacedc3e 255 Digits(),fgkSIDEN);
fe15e140 256 delete [] dbuffer;
257
258 } // end condition on NDigits
259
aacedc3e 260 if (GetDebug(1)) cout<<"\n Found clusters: fNClusterP = "<<fNClusterP
fe15e140 261 <<" fNClusterN ="<<fNClusterN<<"\n";
262}
263//______________________________________________________________________
264void AliITSClusterFinderSSD::SeparateOverlappedClusters(){
265 // overlapped clusters separation
266 register Int_t i; //iterator
aacedc3e 267 Double_t factor=0.75; // How many percent must be lower signal
fe15e140 268 // on the middle one digit
269 // from its neighbours
270 Int_t signal0; //signal on the strip before the current one
271 Int_t signal1; //signal on the current one signal
272 Int_t signal2; //signal on the strip after the current one
273 TArrayI *splitlist; // List of splits
274 Int_t numerofsplits=0; // number of splits
275 Int_t initPsize = fNClusterP; //initial size of the arrays
276 Int_t initNsize = fNClusterN; //we have to keep it because it will grow
277 // in this function and it doasn't make
278 // sense to pass through it again
279 splitlist = new TArrayI(300);
280
281 for (i=0;i<initPsize;i++){
282 if (( ((AliITSclusterSSD*)(*fClusterP)[i])->
283 GetNumOfDigits())==1) continue;
284 if (( ((AliITSclusterSSD*)(*fClusterP)[i])->
285 GetNumOfDigits())==2) continue;
b0f5e3fc 286 Int_t nj=(((AliITSclusterSSD*)(*fClusterP)[i])->GetNumOfDigits()-1);
fe15e140 287 for (Int_t j=1; j<nj; j++){
b0f5e3fc 288 signal1=((AliITSclusterSSD*)(*fClusterP)[i])->GetDigitSignal(j);
289 signal0=((AliITSclusterSSD*)(*fClusterP)[i])->GetDigitSignal(j-1);
290 signal2=((AliITSclusterSSD*)(*fClusterP)[i])->GetDigitSignal(j+1);
291 //if signal is less then factor*signal of its neighbours
fe15e140 292 if ( (signal1<(factor*signal0)) && (signal1<(factor*signal2)) ){
293 (*splitlist)[numerofsplits++]=j;
294 } // end if
295 } // end loop over number of digits
296 //split this cluster if necessary
297 if(numerofsplits>0) SplitCluster(splitlist,numerofsplits,i,fgkSIDEP);
298 numerofsplits=0;
299 //in signed places (splitlist)
300 } // end loop over clusters on Pside
301
302 for (i=0;i<initNsize;i++) {
303 if (( ((AliITSclusterSSD*)(*fClusterN)[i])->
304 GetNumOfDigits())==1) continue;
305 if (( ((AliITSclusterSSD*)(*fClusterN)[i])->
306 GetNumOfDigits())==2) continue;
307 Int_t nj=(((AliITSclusterSSD*)(*fClusterN)[i])->GetNumOfDigits()-1);
308 for (Int_t j=1; j<nj; j++){
b0f5e3fc 309 signal1=((AliITSclusterSSD*)(*fClusterN)[i])->GetDigitSignal(j);
310 signal0=((AliITSclusterSSD*)(*fClusterN)[i])->GetDigitSignal(j-1);
311 signal2=((AliITSclusterSSD*)(*fClusterN)[i])->GetDigitSignal(j+1);
312 //if signal is less then factor*signal of its neighbours
313 if ( (signal1<(factor*signal0)) && (signal1<(factor*signal2)) )
fe15e140 314 (*splitlist)[numerofsplits++]=j;
315 } // end loop over number of digits
316 //split this cluster into more clusters
317 if(numerofsplits>0) SplitCluster(splitlist,numerofsplits,i,fgkSIDEN);
318 numerofsplits=0;
319 //in signed places (splitlist)
320 } // end loop over clusters on Nside
321
322 delete splitlist;
b0f5e3fc 323}
fe15e140 324//______________________________________________________________________
325void AliITSClusterFinderSSD::SplitCluster(TArrayI *list, Int_t nsplits,
326 Int_t index, Bool_t side){
327 //This function splits one side cluster into more clusters
328 //number of splits is defined by "nsplits"
329 //Place of splits are defined in the TArray "list"
330 // For further optimisation: Replace this function by two
331 // specialised ones (each for one side)
332 // save one "if"
333 //For comlete comments see AliITSclusterSSD::SplitCluster
334 register Int_t i; //iterator
335 AliITSclusterSSD* curentcluster;
336 Int_t *tmpdigits = new Int_t[100];
bf3f2830 337 Int_t nn;
fe15e140 338
339 // side true means P side
340 if (side) {
341 curentcluster =((AliITSclusterSSD*)((*fClusterP)[index])) ;
342 for (i = nsplits; i>0 ;i--) {
bf3f2830 343 nn=curentcluster->SplitCluster((*list)[(i-1)],tmpdigits);
344 new ((*fClusterP)[fNClusterP]) AliITSclusterSSD(nn,tmpdigits,
fe15e140 345 Digits(),side);
346 ( (AliITSclusterSSD*)((*fClusterP)[fNClusterP]) )->
f239b2fe 347 SetLeftNeighbour(kTRUE);
fe15e140 348 //if left cluster had neighbour on the right before split
349 //new should have it too
350 if ( curentcluster->GetRightNeighbour() )
351 ( (AliITSclusterSSD*)((*fClusterP)[fNClusterP]) )->
f239b2fe 352 SetRightNeighbour(kTRUE);
fe15e140 353 else curentcluster->SetRightNeighbour(kTRUE);
354 fNClusterP++;
355 } // end loop over nplits
356 } else {
357 curentcluster =((AliITSclusterSSD*)((*fClusterN)[index]));
358 for (i = nsplits; i>0 ;i--) {
bf3f2830 359 nn=curentcluster->SplitCluster((*list)[(i-1)],tmpdigits);
360 new ((*fClusterN)[fNClusterN]) AliITSclusterSSD(nn,tmpdigits,
fe15e140 361 Digits(),side);
362 ((AliITSclusterSSD*)((*fClusterN)[fNClusterN]))->
f239b2fe 363 SetRightNeighbour(kTRUE);
fe15e140 364 if (curentcluster->GetRightNeighbour())
365 ( (AliITSclusterSSD*)( (*fClusterN)[fNClusterN]) )->
f239b2fe 366 SetRightNeighbour(kTRUE);
fe15e140 367 else curentcluster->SetRightNeighbour(kTRUE);
368 fNClusterN++;
369 } // end loop over nplits
370 } // end if side
371 delete []tmpdigits;
b0f5e3fc 372}
fe15e140 373//______________________________________________________________________
374Int_t AliITSClusterFinderSSD::SortDigitsP(Int_t start, Int_t end){
375 // sort digits on the P side
376 Int_t right;
377 Int_t left;
378
379 if (start != (end - 1) ){
380 left=this->SortDigitsP(start,(start+end)/2);
381 right=this->SortDigitsP((start+end)/2,end);
382 return (left || right);
383 }else{
384 left = ((AliITSdigitSSD*)((*(Digits()))[(*fDigitsIndexP)[start]]))->
385 GetStripNumber();
386 right= ((AliITSdigitSSD*)((*(Digits()))[(*fDigitsIndexP)[end]]))->
387 GetStripNumber();
388 if( left > right ){
389 Int_t tmp = (*fDigitsIndexP)[start];
390 (*fDigitsIndexP)[start]=(*fDigitsIndexP)[end];
391 (*fDigitsIndexP)[end]=tmp;
392 return 1;
393 }else return 0;
394 } // end if
b0f5e3fc 395}
fe15e140 396//______________________________________________________________________
397Int_t AliITSClusterFinderSSD::SortDigitsN(Int_t start, Int_t end){
398 // sort digits on the N side
399 Int_t right;
400 Int_t left;
401
402 if (start != (end - 1)){
aacedc3e 403 left=this->SortDigitsN(start,(start+end)/2);
404 right=this->SortDigitsN((start+end)/2,end);
405 return (left || right);
fe15e140 406 }else{
aacedc3e 407 left =((AliITSdigitSSD*)((*(Digits()))[(*fDigitsIndexN)[start]]))->
408 GetStripNumber();
409 right=((AliITSdigitSSD*)((*(Digits()))[(*fDigitsIndexN)[end]]))->
410 GetStripNumber();
411 if ( left > right ){
412 Int_t tmp = (*fDigitsIndexN)[start];
413 (*fDigitsIndexN)[start]=(*fDigitsIndexN)[end];
414 (*fDigitsIndexN)[end]=tmp;
415 return 1;
416 }else return 0;
fe15e140 417 } // end if
b0f5e3fc 418}
fe15e140 419//______________________________________________________________________
420void AliITSClusterFinderSSD::FillDigitsIndex(){
421 //Fill the indexes of the clusters belonging to a given ITS module
bf3f2830 422 Int_t pns=0, nns=0;
fe15e140 423 Int_t tmp,bit,k;
bf3f2830 424 Int_t noentries;
fe15e140 425 Int_t i;
426
aacedc3e 427 noentries = NDigits();
fe15e140 428
bf3f2830 429 Int_t* psidx = new Int_t [noentries*sizeof(Int_t)];
430 Int_t* nsidx = new Int_t [noentries*sizeof(Int_t)];
431 if (fDigitsIndexP==NULL) fDigitsIndexP = new TArrayI(noentries);
432 if (fDigitsIndexN==NULL) fDigitsIndexN = new TArrayI(noentries);
fe15e140 433
434 AliITSdigitSSD *dig;
435
bf3f2830 436 for ( i = 0 ; i< noentries; i++ ) {
aacedc3e 437 dig = (AliITSdigitSSD*)GetDigit(i);
438 if(dig->IsSideP()) {
439 bit=1;
440 tmp=dig->GetStripNumber();
441 // I find this totally unnecessary - it's just a
442 // CPU consuming double check
443 for( k=0;k<pns;k++){
444 if (tmp==psidx[k]){
445 if (GetDebug(1)) cout<<"Such a digit exists \n";
446 bit=0;
447 } // end if
448 } // end for k
449 // end comment
450 if(bit) {
451 fDigitsIndexP->AddAt(i,fNDigitsP++);
452 psidx[pns++]=tmp;
453 } // end if bit
454 } else {
455 bit=1;
456 tmp=dig->GetStripNumber();
457 // same as above
458 for( k=0;k<nns;k++){
459 if (tmp==nsidx[k]){
460 if (GetDebug(1)) cout<<"Such a digit exists \n";
461 bit=0;
462 } // end if
463 } // for k
464 // end comment
465 if (bit) {
466 fDigitsIndexN->AddAt(i,fNDigitsN++);
467 nsidx[nns++] =tmp;
468 } // end if bit
469 } // end if
fe15e140 470 } // end for i
471
bf3f2830 472 delete [] psidx;
473 delete [] nsidx;
fe15e140 474
aacedc3e 475 if(GetDebug(1)) cout<<"Digits: P = "<<fNDigitsP<<" N = "<<fNDigitsN<<endl;
b0f5e3fc 476}
fe15e140 477//______________________________________________________________________
478void AliITSClusterFinderSSD::SortDigits(){
479 // sort digits
480 Int_t i;
481
482 if(fNDigitsP>1) for (i=0;i<fNDigitsP-1;i++)
aacedc3e 483 if (SortDigitsP(0,(fNDigitsP-1-i))==0) break;
fe15e140 484 if(fNDigitsN>1) for (i=0;i<fNDigitsN-1;i++)
aacedc3e 485 if(SortDigitsN(0,(fNDigitsN-1-i))==0) break;
b0f5e3fc 486}
fe15e140 487//______________________________________________________________________
aacedc3e 488void AliITSClusterFinderSSD::FillClIndexArrays(Int_t* arrayP,Int_t *arrayN)
489 const{
fe15e140 490 // fill cluster index array
491 register Int_t i;
f239b2fe 492
fe15e140 493 for (i=0; i<fNClusterP;i++) arrayP[i]=i;
494 for (i=0; i<fNClusterN;i++) arrayN[i]=i;
b0f5e3fc 495}
fe15e140 496//______________________________________________________________________
497void AliITSClusterFinderSSD::SortClusters(Int_t* arrayP, Int_t *arrayN){
498 // sort clusters
499 Int_t i;
500
501 if(fNClusterP>1) for (i=0;i<fNClusterP-1;i++)
aacedc3e 502 if (SortClustersP(0,(fNClusterP-1),arrayP)==0) break;
503 if(fNClusterN>1) for (i=0;i<fNClusterN-1;i++)
504 if (SortClustersN(0,(fNClusterN-1),arrayN)==0) break;
b0f5e3fc 505}
fe15e140 506//______________________________________________________________________
507Int_t AliITSClusterFinderSSD::SortClustersP(Int_t start, Int_t end,
508 Int_t *array){
509 //Sort P side clusters
510 Int_t right;
511 Int_t left;
512
513 if (start != (end - 1) ) {
aacedc3e 514 left=this->SortClustersP(start,(start+end)/2,array);
515 right=this->SortClustersP((start+end)/2,end,array);
516 return (left || right);
fe15e140 517 } else {
aacedc3e 518 left =((AliITSclusterSSD*)((*fClusterP)[array[start]]))->
519 GetDigitStripNo(0);
520 right=((AliITSclusterSSD*)((*fClusterP)[array[ end ]]))->
521 GetDigitStripNo(0);
522 if(left>right) {
523 Int_t tmp = array[start];
524 array[start]=array[end];
525 array[end]=tmp;
526 return 1;
527 } else return 0;
fe15e140 528 } // end if
b0f5e3fc 529}
fe15e140 530//______________________________________________________________________
531Int_t AliITSClusterFinderSSD::SortClustersN(Int_t start, Int_t end,
aacedc3e 532 Int_t *array){
fe15e140 533 //Sort N side clusters
534 Int_t right;
535 Int_t left;
536
537 if (start != (end - 1) ) {
aacedc3e 538 left=this->SortClustersN(start,(start+end)/2,array);
539 right=this->SortClustersN((start+end)/2,end,array);
540 return (left || right);
fe15e140 541 } else {
aacedc3e 542 left =((AliITSclusterSSD*)((*fClusterN)[array[start]]))->
543 GetDigitStripNo(0);
544 right=((AliITSclusterSSD*)((*fClusterN)[array[ end ]]))->
545 GetDigitStripNo(0);
546 if( left > right) {
547 Int_t tmp = array[start];
548 array[start]=array[end];
549 array[end]=tmp;
550 return 1;
551 } else return 0;
fe15e140 552 } // end if
b0f5e3fc 553}
fe15e140 554//______________________________________________________________________
555void AliITSClusterFinderSSD::ClustersToPackages(){
556 // fill packages
f239b2fe 557
fe15e140 558 Int_t *oneSclP = new Int_t[fNClusterP];//I want to have sorted 1 S clusters
559 Int_t *oneSclN = new Int_t[fNClusterN];//I can not sort it in TClonesArray
560 //so, I create table of indexes and
561 //sort it
562 //I do not use TArrayI on purpose
563 //MB: well, that's not true that one
564 //cannot sort objs in TClonesArray
565 AliITSclusterSSD *currentP;
566 AliITSclusterSSD *currentN;
567 Int_t j1, j2;
568
569 //Fills in One Side Clusters Index Array
570 FillClIndexArrays(oneSclP,oneSclN);
571 //Sorts filled Arrays
572 //SortClusters(oneSclP,oneSclN);
573
574 fNPackages=1;
575 new ((*fPackages)[0]) AliITSpackageSSD(fClusterP,fClusterN);
576
577 //This part was includede by Boris Batiounia in March 2001.
578 // Take all recpoint pairs (x coordinates) in both P and N sides
579 // to calculate z coordinates of the recpoints
580
581 for (j1=0;j1<fNClusterP;j1++) {
582 currentP = GetPSideCluster(oneSclP[j1]);
583 Double_t xP = currentP->GetPosition();
aacedc3e 584 Double_t signalP = currentP->GetTotalSignal();
fe15e140 585 for (j2=0;j2<fNClusterN;j2++) {
586 currentN = GetNSideCluster(oneSclN[j2]);
587 Double_t xN = currentN->GetPosition();
aacedc3e 588 Double_t signalN = currentN->GetTotalSignal();
fe15e140 589 CreateNewRecPoint(xP,1,xN,1,signalP,signalN,currentP,currentN,
aacedc3e 590 0.75);
fe15e140 591 } // end for j2
592 } // end for j1
593
594 delete [] oneSclP;
595 delete [] oneSclN;
b0f5e3fc 596}
fe15e140 597//______________________________________________________________________
aacedc3e 598Bool_t AliITSClusterFinderSSD::CreateNewRecPoint(Double_t P,Double_t dP,
599 Double_t N, Double_t dN,
600 Double_t SigP,Double_t SigN,
fe15e140 601 AliITSclusterSSD *clusterP,
602 AliITSclusterSSD *clusterN,
603 Stat_t prob){
604 // create the recpoints
aacedc3e 605 const Double_t kADCtoKeV = 2.16;
fe15e140 606 // 50 ADC units -> 30000 e-h pairs; 1e-h pair -> 3.6e-3 KeV;
607 // 1 ADC unit -> (30000/50)*3.6e-3 = 2.16 KeV
aacedc3e 608 const Double_t kconv = 1.0e-4;
609 const Double_t kRMSx = 20.0*kconv;
610 const Double_t kRMSz = 800.0*kconv;
fe15e140 611 Int_t n=0;
612 Int_t *tr;
bf3f2830 613 Int_t ntracks;
fe15e140 614
615 if (GetCrossing(P,N)) {
aacedc3e 616 //GetCrossingError(dP,dN);
617 dP = dN = prob = 0.0; // to remove unused variable warning.
618 AliITSRawClusterSSD cnew;
619 Int_t nstripsP=clusterP->GetNumOfDigits();
620 Int_t nstripsN=clusterN->GetNumOfDigits();
621 Double_t signal = 0;
622 Double_t dedx = 0;
623 if(SigP>SigN) {
624 signal = SigP;
625 dedx = SigP*kADCtoKeV;
626 }else{
627 signal = SigN;
628 dedx = SigN*kADCtoKeV;
629 } // end if SigP>SigN
630 tr = (Int_t*) clusterP->GetTracks(n);
631 ntracks = clusterP->GetNTracks();
632 cnew.SetSignalP(SigP);
633 cnew.SetSignalN(SigN);
634 cnew.SetMultiplicity(nstripsP);
635 cnew.SetMultN(nstripsN);
636 cnew.SetQErr(TMath::Abs(SigP-SigN));
637 cnew.SetNTrack(ntracks);
638 fITS->AddCluster(2,&cnew);
639 AliITSRecPoint rnew;
640 rnew.SetX(P*kconv);
641 rnew.SetZ(N*kconv);
642 rnew.SetQ(signal);
643 rnew.SetdEdX(dedx);
644 rnew.SetSigmaX2( kRMSx* kRMSx);
645 rnew.SetSigmaZ2( kRMSz* kRMSz);
646 rnew.fTracks[0]=tr[0];
647 rnew.fTracks[1]=tr[1];
648 rnew.fTracks[2]=tr[2];
649 fITS->AddRecPoint(rnew);
650 return kTRUE;
fe15e140 651 } // end if
652 return kFALSE;
b0f5e3fc 653}
fe15e140 654//______________________________________________________________________
aacedc3e 655void AliITSClusterFinderSSD::CalcStepFactor(Double_t Psteo, Double_t Nsteo){
fe15e140 656 // calculate the step factor for matching clusters
657 // 95 is the pitch, 4000 - dimension along z ?
aacedc3e 658 Double_t dz=GetSeg()->Dz();
fe15e140 659
660 fSFF = ( (Int_t) (Psteo*dz/fPitch ) );// +1;
661 fSFB = ( (Int_t) (Nsteo*dz/fPitch ) );// +1;
b0f5e3fc 662}
fe15e140 663//______________________________________________________________________
664AliITSclusterSSD* AliITSClusterFinderSSD::GetPSideCluster(Int_t idx){
665 // get P side clusters
666
667 if((idx<0)||(idx>=fNClusterP)){
aacedc3e 668 Info("GetPSideCluster","0<index=%d<=%d out of range",idx,fNClusterP);
669 return 0;
fe15e140 670 }else{
aacedc3e 671 return (AliITSclusterSSD*)((*fClusterP)[idx]);
fe15e140 672 } // end if
b0f5e3fc 673}
fe15e140 674//______________________________________________________________________
675AliITSclusterSSD* AliITSClusterFinderSSD::GetNSideCluster(Int_t idx){
676 // get N side clusters
677
678 if((idx<0)||(idx>=fNClusterN)){
aacedc3e 679 Info("GetNSideCluster","0<index=%d >= %d out of range",idx,fNClusterN);
680 return 0;
fe15e140 681 }else{
aacedc3e 682 return (AliITSclusterSSD*)((*fClusterN)[idx]);
fe15e140 683 } // end if
b0f5e3fc 684}
fe15e140 685//______________________________________________________________________
aacedc3e 686Bool_t AliITSClusterFinderSSD::GetCrossing (Double_t &P, Double_t &N){
fe15e140 687 // get crossing
688 // This function was rivised and changed by Boris Batiounia in March 2001
aacedc3e 689 Double_t dx = GetSeg()->Dx(); // detector size in x direction, microns
690 Double_t dz = GetSeg()->Dz(); // detector size in z direction, microns
691 Double_t xL; // x local coordinate
692 Double_t zL; // z local coordinate
693 Double_t x; // x = xL + dx/2
694 Double_t z; // z = zL + dz/2
695 Double_t xP; // x coordinate in the P side from the first P strip
696 Double_t xN; // x coordinate in the N side from the first N strip
bf3f2830 697 Float_t stereoP,stereoN;
fe15e140 698
aacedc3e 699 GetSeg()->Angles(stereoP,stereoN);
bf3f2830 700 fTanP=TMath::Tan(stereoP);
701 fTanN=TMath::Tan(stereoN);
aacedc3e 702 Double_t kP = fTanP; // Tangent of 0.0075 mrad
703 Double_t kN = fTanN; // Tangent of 0.0275 mrad
b0f5e3fc 704 P *= fPitch;
705 N *= fPitch;
6298ec22 706
fd61217e 707 xP = N; // change the mistake for the P/N
708 xN = P; // coordinates correspondence in this function
6298ec22 709
bf3f2830 710 x = xP + kP*(dz*kN-xP+xN)/(kP+kN);
711 z = (dz*kN-xP+xN)/(kP+kN);
712 xL = x - dx/2;
713 zL = z - dz/2;
fd61217e 714 P = xL;
715 N = zL;
716
bf3f2830 717 if(TMath::Abs(xL) > dx/2 || TMath::Abs(zL) > dz/2) return kFALSE;
6298ec22 718
fd61217e 719 // Check that xL and zL are inside the detector for the
720 // correspondent xP and xN coordinates
b0f5e3fc 721
722 return kTRUE;
723}
fe15e140 724//______________________________________________________________________
aacedc3e 725void AliITSClusterFinderSSD::GetCrossingError(Double_t& dP, Double_t& dN){
fe15e140 726 // get crossing error
aacedc3e 727 Double_t dz, dx;
fe15e140 728
729 dz = TMath::Abs(( dP + dN )*fPitch/(fTanP + fTanN) );
730 dx = fPitch*(TMath::Abs(dP*(1 - fTanP/(fTanP + fTanN))) +
aacedc3e 731 TMath::Abs(dN *fTanP/(fTanP + fTanN) ));
fe15e140 732 dN = dz;
733 dP = dx;
b0f5e3fc 734}