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