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