]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ITS/AliITSClusterFinderV2SSD.cxx
### files: AliTPCTempMap.h (.cxx)
[u/mrichter/AliRoot.git] / ITS / AliITSClusterFinderV2SSD.cxx
CommitLineData
04366a57 1/**************************************************************************
b42cfa25 2 * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
04366a57 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 **************************************************************************/
308b5ea4 15
16/* $Id$ */
17
04366a57 18////////////////////////////////////////////////////////////////////////////
19// Implementation of the ITS clusterer V2 class //
20// //
21// Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch //
308b5ea4 22// Revised: Enrico Fragiacomo, enrico.fragiacomo@ts.infn.it //
d036ccd3 23// Revised 23/06/08: Marco Bregant
04366a57 24// //
25///////////////////////////////////////////////////////////////////////////
26
308b5ea4 27#include <Riostream.h>
28
04366a57 29
30#include "AliITSClusterFinderV2SSD.h"
00a7cc50 31#include "AliITSRecPoint.h"
1f3e997f 32#include "AliITSgeomTGeo.h"
7d62fb64 33#include "AliITSDetTypeRec.h"
04366a57 34#include "AliRawReader.h"
35#include "AliITSRawStreamSSD.h"
04366a57 36#include <TClonesArray.h>
04366a57 37#include "AliITSdigitSSD.h"
a86176e3 38#include "AliITSReconstructor.h"
3a4139a2 39#include "AliITSCalibrationSSD.h"
8be4e1b1 40#include "AliITSsegmentationSSD.h"
04366a57 41
308b5ea4 42Short_t *AliITSClusterFinderV2SSD::fgPairs = 0x0;
43Int_t AliITSClusterFinderV2SSD::fgPairsSize = 0;
c157c94e 44
04366a57 45ClassImp(AliITSClusterFinderV2SSD)
46
47
e56160b8 48AliITSClusterFinderV2SSD::AliITSClusterFinderV2SSD(AliITSDetTypeRec* dettyp):AliITSClusterFinderV2(dettyp),
8be4e1b1 49fLastSSD1(AliITSgeomTGeo::GetModuleIndex(6,1,1)-1)
d036ccd3 50{
8be4e1b1 51//Default constructor
04366a57 52
04366a57 53}
54
308b5ea4 55//______________________________________________________________________
8be4e1b1 56AliITSClusterFinderV2SSD::AliITSClusterFinderV2SSD(const AliITSClusterFinderV2SSD &cf) : AliITSClusterFinderV2(cf), fLastSSD1(cf.fLastSSD1)
308b5ea4 57{
58 // Copy constructor
308b5ea4 59}
60
61//______________________________________________________________________
62AliITSClusterFinderV2SSD& AliITSClusterFinderV2SSD::operator=(const AliITSClusterFinderV2SSD& cf ){
63 // Assignment operator
64
65 this->~AliITSClusterFinderV2SSD();
66 new(this) AliITSClusterFinderV2SSD(cf);
67 return *this;
68}
69
04366a57 70
71void AliITSClusterFinderV2SSD::FindRawClusters(Int_t mod){
72
73 //Find clusters V2
74 SetModule(mod);
75 FindClustersSSD(fDigits);
76
77}
78
79void AliITSClusterFinderV2SSD::FindClustersSSD(TClonesArray *alldigits) {
80 //------------------------------------------------------------
81 // Actual SSD cluster finder
82 //------------------------------------------------------------
a86176e3 83
84 static AliITSRecoParam *repa = NULL;
d036ccd3 85
86
a86176e3 87 if(!repa){
88 repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
89 if(!repa){
ed446fa3 90 repa = AliITSRecoParam::GetHighFluxParam();
a86176e3 91 AliWarning("Using default AliITSRecoParam class");
92 }
93 }
94
3a4139a2 95 AliITSCalibrationSSD* cal = (AliITSCalibrationSSD*)GetResp(fModule);
96 Float_t gain=0;
97
04366a57 98 Int_t smaxall=alldigits->GetEntriesFast();
99 if (smaxall==0) return;
f7b30404 100 // TObjArray *digits = new TObjArray;
101 TObjArray digits;
04366a57 102 for (Int_t i=0;i<smaxall; i++){
103 AliITSdigitSSD *d=(AliITSdigitSSD*)alldigits->UncheckedAt(i);
3a4139a2 104
105 if(d->IsSideP()) gain = cal->GetGainP(d->GetStripNumber());
106 else gain = cal->GetGainN(d->GetStripNumber());
107
108 Float_t q=gain*d->GetSignal(); // calibration brings mip peaks around 120 (in ADC units)
109 q=cal->ADCToKeV(q); // converts the charge in KeV from ADC units
6490e1c5 110 d->SetSignal(Int_t(q));
3a4139a2 111
04366a57 112 if (d->GetSignal()<3) continue;
f7b30404 113 digits.AddLast(d);
04366a57 114 }
f7b30404 115 Int_t smax = digits.GetEntriesFast();
04366a57 116 if (smax==0) return;
117
118 const Int_t kMax=1000;
119 Int_t np=0, nn=0;
120 Ali1Dcluster pos[kMax], neg[kMax];
121 Float_t y=0., q=0., qmax=0.;
122 Int_t lab[4]={-2,-2,-2,-2};
123
f7b30404 124 AliITSdigitSSD *d=(AliITSdigitSSD*)digits.UncheckedAt(0);
04366a57 125 q += d->GetSignal();
126 y += d->GetCoord2()*d->GetSignal();
127 qmax=d->GetSignal();
128 lab[0]=d->GetTrack(0); lab[1]=d->GetTrack(1); lab[2]=d->GetTrack(2);
129 Int_t curr=d->GetCoord2();
130 Int_t flag=d->GetCoord1();
131 Int_t *n=&nn;
132 Ali1Dcluster *c=neg;
133 Int_t nd=1;
134 Int_t milab[10];
135 for (Int_t ilab=0;ilab<10;ilab++){
136 milab[ilab]=-2;
137 }
138 milab[0]=d->GetTrack(0); milab[1]=d->GetTrack(1); milab[2]=d->GetTrack(2);
139
140 for (Int_t s=1; s<smax; s++) {
f7b30404 141 d=(AliITSdigitSSD*)digits.UncheckedAt(s);
04366a57 142 Int_t strip=d->GetCoord2();
143 if ((strip-curr) > 1 || flag!=d->GetCoord1()) {
144 c[*n].SetY(y/q);
145 c[*n].SetQ(q);
146 c[*n].SetNd(nd);
147 CheckLabels2(milab);
148 c[*n].SetLabels(milab);
a86176e3 149
150 if(repa->GetUseUnfoldingInClusterFinderSSD()==kTRUE) {
151
152 //Split suspiciously big cluster
153 if (nd>4&&nd<25) {
154 c[*n].SetY(y/q-0.25*nd);
155 c[*n].SetQ(0.5*q);
156 (*n)++;
157 if (*n==kMax) {
158 Error("FindClustersSSD","Too many 1D clusters !");
159 return;
160 }
161 c[*n].SetY(y/q+0.25*nd);
162 c[*n].SetQ(0.5*q);
163 c[*n].SetNd(nd);
164 c[*n].SetLabels(milab);
165 }
166
167 } // unfolding is on
168
04366a57 169 (*n)++;
170 if (*n==kMax) {
171 Error("FindClustersSSD","Too many 1D clusters !");
172 return;
173 }
174 y=q=qmax=0.;
175 nd=0;
176 lab[0]=lab[1]=lab[2]=-2;
177 //
178 for (Int_t ilab=0;ilab<10;ilab++){
179 milab[ilab]=-2;
180 }
181 //
182 if (flag!=d->GetCoord1()) { n=&np; c=pos; }
183 }
184 flag=d->GetCoord1();
185 q += d->GetSignal();
186 y += d->GetCoord2()*d->GetSignal();
187 nd++;
188 if (d->GetSignal()>qmax) {
189 qmax=d->GetSignal();
190 lab[0]=d->GetTrack(0); lab[1]=d->GetTrack(1); lab[2]=d->GetTrack(2);
191 }
192 for (Int_t ilab=0;ilab<10;ilab++) {
193 if (d->GetTrack(ilab)>=0) AddLabel(milab, (d->GetTrack(ilab)));
194 }
195 curr=strip;
196 }
197 c[*n].SetY(y/q);
198 c[*n].SetQ(q);
199 c[*n].SetNd(nd);
200 c[*n].SetLabels(lab);
a86176e3 201
202 if(repa->GetUseUnfoldingInClusterFinderSSD()==kTRUE) {
203
204 //Split suspiciously big cluster
205 if (nd>4 && nd<25) {
206 c[*n].SetY(y/q-0.25*nd);
207 c[*n].SetQ(0.5*q);
208 (*n)++;
209 if (*n==kMax) {
04366a57 210 Error("FindClustersSSD","Too many 1D clusters !");
211 return;
a86176e3 212 }
213 c[*n].SetY(y/q+0.25*nd);
214 c[*n].SetQ(0.5*q);
215 c[*n].SetNd(nd);
216 c[*n].SetLabels(lab);
217 }
218 } // unfolding is on
219
04366a57 220 (*n)++;
221 if (*n==kMax) {
222 Error("FindClustersSSD","Too many 1D clusters !");
223 return;
224 }
225
226 FindClustersSSD(neg, nn, pos, np);
227}
228
229
230void AliITSClusterFinderV2SSD::RawdataToClusters(AliRawReader* rawReader,TClonesArray** clusters){
231
232 //------------------------------------------------------------
233 // This function creates ITS clusters from raw data
234 //------------------------------------------------------------
235 rawReader->Reset();
236 AliITSRawStreamSSD inputSSD(rawReader);
237 FindClustersSSD(&inputSSD,clusters);
238
239}
240
3a4139a2 241void AliITSClusterFinderV2SSD::FindClustersSSD(AliITSRawStreamSSD* input,
04366a57 242 TClonesArray** clusters)
243{
244 //------------------------------------------------------------
245 // Actual SSD cluster finder for raw data
246 //------------------------------------------------------------
a86176e3 247
248 static AliITSRecoParam *repa = NULL;
249 if(!repa){
250 repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
251 if(!repa){
ed446fa3 252 repa = AliITSRecoParam::GetHighFluxParam();
a86176e3 253 AliWarning("Using default AliITSRecoParam class");
254 }
255 }
256
04366a57 257 Int_t nClustersSSD = 0;
258 const Int_t kMax = 1000;
259 Ali1Dcluster clusters1D[2][kMax];
260 Int_t nClusters[2] = {0, 0};
261 Int_t lab[3]={-2,-2,-2};
262 Float_t q = 0.;
263 Float_t y = 0.;
264 Int_t nDigits = 0;
3a4139a2 265 Float_t gain=0;
308b5ea4 266 Float_t noise=0.;
5ffe058f 267 // Float_t pedestal=0.;
308b5ea4 268 Float_t oldnoise=0.;
b4704be3 269 AliITSCalibrationSSD* cal=NULL;
308b5ea4 270
308b5ea4 271 Int_t matrix[12][1536];
d5ad0697 272 Int_t iddl=-1;
273 Int_t iad=-1;
274 Int_t oddl = -1;
275 Int_t oad = -1;
276 Int_t oadc = -1;
277 Int_t ostrip = -1;
308b5ea4 278 Int_t osignal = 65535;
308b5ea4 279 Int_t n=0;
280 Bool_t next=0;
04366a57 281
282 // read raw data input stream
283 while (kTRUE) {
308b5ea4 284
285 // reset signal matrix
286 for(Int_t i=0; i<12; i++) { for(Int_t j=0; j<1536; j++) { matrix[i][j] = 65535;} }
b42cfa25 287
cbf26d57 288 if((osignal!=65535)&&(ostrip>0)&&(ostrip<1536)) {
308b5ea4 289 n++;
290 matrix[oadc][ostrip] = osignal; // recover data from previous occurence of input->Next()
291 }
b42cfa25 292
308b5ea4 293 // buffer data for ddl=iddl and ad=iad
294 while(kTRUE) {
bc4dd89a 295
308b5ea4 296 next = input->Next();
d5ad0697 297 if((!next)&&(input->flag)) continue;
298 Int_t ddl=input->GetDDL();
299 Int_t ad=input->GetAD();
300 Int_t adc = input->GetADC(); adc = (adc<6)? adc : adc - 2;
301 Int_t strip = input->GetStrip();
308b5ea4 302 if(input->GetSideFlag()) strip=1535-strip;
d5ad0697 303 Int_t signal = input->GetSignal();
d036ccd3 304
cbf26d57 305 if((ddl==iddl)&&(ad==iad)&&(strip>0)&&(strip<1536)) {n++; matrix[adc][strip] = signal;}
4ae225e9 306 else {if ((strip<1536) && (strip>0)) {oddl=iddl; oad=iad; oadc = adc; ostrip = strip; osignal=signal; iddl=ddl; iad=ad; break;}}
308b5ea4 307
b42cfa25 308 if(!next) {oddl=iddl; oad=iad; oadc = adc; ostrip = strip; osignal=signal; iddl=ddl; iad=ad; break;}
309 //break;
308b5ea4 310 }
b42cfa25 311
312 // No SSD data
d5ad0697 313 if(!next && oddl<0) break;
b42cfa25 314
308b5ea4 315 if(n==0) continue; // first occurence
d036ccd3 316 n=0; //osignal=0;
b42cfa25 317
308b5ea4 318 // fill 1Dclusters
319 for(Int_t iadc=0; iadc<12; iadc++) { // loop over ADC index for ddl=oddl and ad=oad
b42cfa25 320
308b5ea4 321 Int_t iimod = (oad - 1) * 12 + iadc;
d5ad0697 322 Int_t iModule = AliITSRawStreamSSD::GetModuleNumber(oddl,iimod);
308b5ea4 323 if(iModule==-1) continue;
308b5ea4 324 cal = (AliITSCalibrationSSD*)GetResp(iModule);
b42cfa25 325
308b5ea4 326 Bool_t first = 0;
b42cfa25 327
bc4dd89a 328 /*
308b5ea4 329 for(Int_t istrip=0; istrip<768; istrip++) { // P-side
d5ad0697 330 Int_t signal = matrix[iadc][istrip];
b42cfa25 331 pedestal = cal->GetPedestalP(istrip);
e7f0e76b 332 matrix[iadc][istrip]=signal-(Int_t)pedestal;
bc4dd89a 333 }
334 */
335
336 /*
b42cfa25 337 Float_t cmode=0;
338 for(Int_t l=0; l<6; l++) {
339 cmode=0;
340 for(Int_t n=20; n<108; n++) cmode+=matrix[iadc][l*128+n];
341 cmode/=88.;
e7f0e76b 342 for(Int_t n=0; n<128; n++) matrix[iadc][l*128+n]-=(Int_t)cmode;
b42cfa25 343
344 }
bc4dd89a 345 */
346
a64f9843 347 Int_t istrip=0;
348 for(istrip=0; istrip<768; istrip++) { // P-side
b42cfa25 349
350 Int_t signal = TMath::Abs(matrix[iadc][istrip]);
351
308b5ea4 352 oldnoise = noise;
b42cfa25 353 noise = cal->GetNoiseP(istrip); if(noise<1.) signal = 65535;
a64f9843 354 if(signal<3*noise) signal = 65535; // in case ZS was not done in hw do it now
355
ced4d9bc 356 // if(cal->IsPChannelBad(istrip)) signal=0;
308b5ea4 357
358 if (signal!=65535) {
359 gain = cal->GetGainP(istrip);
360 signal = (Int_t) ( signal * gain ); // signal is corrected for gain
308b5ea4 361 signal = (Int_t) cal->ADCToKeV( signal ); // signal is converted in KeV
b42cfa25 362
308b5ea4 363 q += signal; // add digit to current cluster
364 y += istrip * signal;
365 nDigits++;
366 first=1;
367 }
b42cfa25 368
308b5ea4 369 else if(first) {
b42cfa25 370
a64f9843 371 if ( ( (nDigits==1) && ( (q==0) || (q>5*oldnoise)) ) || (nDigits>1) ) {
b42cfa25 372
308b5ea4 373 Ali1Dcluster& cluster = clusters1D[0][nClusters[0]++];
a64f9843 374
375 if(q!=0) cluster.SetY(y/q);
376 else cluster.SetY(istrip-1);
377
308b5ea4 378 cluster.SetQ(q);
379 cluster.SetNd(nDigits);
380 cluster.SetLabels(lab);
381
a86176e3 382 if(repa->GetUseUnfoldingInClusterFinderSSD()==kTRUE) {
383
384 //Split suspiciously big cluster
385 if (nDigits > 4&&nDigits < 25) {
982ce430 386 if(q!=0) cluster.SetY(y/q - 0.25*nDigits);
387 else cluster.SetY(istrip-1 - 0.25*nDigits);
a86176e3 388 cluster.SetQ(0.5*q);
389 if (nClusters[0] == kMax) {
390 Error("FindClustersSSD", "Too many 1D clusters !");
391 return;
392 }
393 Ali1Dcluster& cluster2 = clusters1D[0][nClusters[0]++];
982ce430 394 if(q!=0) cluster2.SetY(y/q + 0.25*nDigits);
395 else cluster2.SetY(istrip-1 + 0.25*nDigits);
a86176e3 396 cluster2.SetQ(0.5*q);
397 cluster2.SetNd(nDigits);
398 cluster2.SetLabels(lab);
308b5ea4 399 }
a86176e3 400 } // unfolding is on
308b5ea4 401 }
402
403 y = q = 0.;
404 nDigits = 0;
405 first=0;
04366a57 406 }
a86176e3 407
308b5ea4 408 } // loop over strip on P-side
a86176e3 409
308b5ea4 410 // if last strip does have signal
411 if(first) {
412
a64f9843 413 if ( ( (nDigits==1) && ( (q==0) || (q>5*oldnoise)) ) || (nDigits>1) ) {
a86176e3 414
415 Ali1Dcluster& cluster = clusters1D[0][nClusters[0]++];
a64f9843 416
417 if(q!=0) cluster.SetY(y/q);
418 else cluster.SetY(istrip-1);
419
a86176e3 420 cluster.SetQ(q);
421 cluster.SetNd(nDigits);
422 cluster.SetLabels(lab);
423
424 if(repa->GetUseUnfoldingInClusterFinderSSD()==kTRUE) {
308b5ea4 425
426 //Split suspiciously big cluster
427 if (nDigits > 4&&nDigits < 25) {
982ce430 428 if(q!=0) cluster.SetY(y/q - 0.25*nDigits);
429 else cluster.SetY(istrip-1 - 0.25*nDigits);
308b5ea4 430 cluster.SetQ(0.5*q);
431 if (nClusters[0] == kMax) {
432 Error("FindClustersSSD", "Too many 1D clusters !");
433 return;
434 }
435 Ali1Dcluster& cluster2 = clusters1D[0][nClusters[0]++];
982ce430 436 if(q!=0) cluster2.SetY(y/q + 0.25*nDigits);
437 else cluster2.SetY(istrip-1 + 0.25*nDigits);
308b5ea4 438 cluster2.SetQ(0.5*q);
439 cluster2.SetNd(nDigits);
440 cluster2.SetLabels(lab);
441 }
a86176e3 442 } // unfolding is on
443
444 }
445 y = q = 0.;
446 nDigits = 0;
447 first=0;
04366a57 448 }
308b5ea4 449
bc4dd89a 450 /*
b42cfa25 451 for(Int_t istrip=768; istrip<1536; istrip++) { // P-side
452 Int_t signal = matrix[iadc][istrip];
453 pedestal = cal->GetPedestalN(1535-istrip);
e7f0e76b 454 matrix[iadc][istrip]=signal-(Int_t)pedestal;
b42cfa25 455 }
bc4dd89a 456 */
b42cfa25 457
bc4dd89a 458 /*
b42cfa25 459 for(Int_t l=6; l<12; l++) {
460 Float_t cmode=0;
461 for(Int_t n=20; n<108; n++) cmode+=matrix[iadc][l*128+n];
462 cmode/=88.;
e7f0e76b 463 for(Int_t n=0; n<128; n++) matrix[iadc][l*128+n]-=(Int_t)cmode;
b42cfa25 464 }
bc4dd89a 465 */
b42cfa25 466
308b5ea4 467 oldnoise = 0.;
468 noise = 0.;
a64f9843 469 Int_t strip=0;
4adcf390 470 for(Int_t iistrip=768; iistrip<1536; iistrip++) { // N-side
308b5ea4 471
4adcf390 472 Int_t signal = TMath::Abs(matrix[iadc][iistrip]);
4adcf390 473 strip = 1535-iistrip;
b42cfa25 474
308b5ea4 475 oldnoise = noise;
b42cfa25 476 noise = cal->GetNoiseN(strip); if(noise<1.) signal=65535;
a64f9843 477
d036ccd3 478 // if(cal->IsNChannelBad(strip)) signal=0;
a64f9843 479
480 if(signal<3*noise) signal = 65535; // in case ZS was not done in hw do it now
308b5ea4 481
482 if (signal!=65535) {
483 gain = cal->GetGainN(strip);
484 signal = (Int_t) ( signal * gain); // signal is corrected for gain
485 signal = (Int_t) cal->ADCToKeV( signal ); // signal is converted in KeV
486
487 // add digit to current cluster
488 q += signal;
489 y += strip * signal;
490 nDigits++;
491 first=1;
492 }
493
494 else if(first) {
a86176e3 495
a64f9843 496 if ( ( (nDigits==1) && ( (q==0) || (q>5*oldnoise)) ) || (nDigits>1) ) {
308b5ea4 497
498 Ali1Dcluster& cluster = clusters1D[1][nClusters[1]++];
a64f9843 499
500 if(q!=0) cluster.SetY(y/q);
501 else cluster.SetY(strip+1);
502
308b5ea4 503 cluster.SetQ(q);
504 cluster.SetNd(nDigits);
505 cluster.SetLabels(lab);
506
a86176e3 507 if(repa->GetUseUnfoldingInClusterFinderSSD()==kTRUE) {
508
509 //Split suspiciously big cluster
510 if (nDigits > 4&&nDigits < 25) {
511 cluster.SetY(y/q - 0.25*nDigits);
512 cluster.SetQ(0.5*q);
513 if (nClusters[1] == kMax) {
514 Error("FindClustersSSD", "Too many 1D clusters !");
515 return;
516 }
517 Ali1Dcluster& cluster2 = clusters1D[1][nClusters[1]++];
518 cluster2.SetY(y/q + 0.25*nDigits);
519 cluster2.SetQ(0.5*q);
520 cluster2.SetNd(nDigits);
521 cluster2.SetLabels(lab);
522 }
523 } // unfolding is on
524 }
525
308b5ea4 526 y = q = 0.;
527 nDigits = 0;
528 first=0;
529 }
530
531 } // loop over strips on N-side
04366a57 532
308b5ea4 533 if(first) {
534
a64f9843 535 if ( ( (nDigits==1) && ( (q==0) || (q>5*oldnoise)) ) || (nDigits>1) ) {
a86176e3 536
537 Ali1Dcluster& cluster = clusters1D[1][nClusters[1]++];
a64f9843 538
539 if(q!=0) cluster.SetY(y/q);
540 else cluster.SetY(strip+1);
541
a86176e3 542 cluster.SetQ(q);
543 cluster.SetNd(nDigits);
544 cluster.SetLabels(lab);
545
546 if(repa->GetUseUnfoldingInClusterFinderSSD()==kTRUE) {
308b5ea4 547
548 //Split suspiciously big cluster
549 if (nDigits > 4&&nDigits < 25) {
982ce430 550 if(q!=0) cluster.SetY(y/q - 0.25*nDigits);
551 else cluster.SetY(strip+1 - 0.25*nDigits);
308b5ea4 552 cluster.SetQ(0.5*q);
553 if (nClusters[1] == kMax) {
554 Error("FindClustersSSD", "Too many 1D clusters !");
555 return;
556 }
557 Ali1Dcluster& cluster2 = clusters1D[1][nClusters[1]++];
982ce430 558 if(q!=0) cluster2.SetY(y/q + 0.25*nDigits);
559 else cluster2.SetY(strip+1 + 0.25*nDigits);
308b5ea4 560 cluster2.SetQ(0.5*q);
561 cluster2.SetNd(nDigits);
562 cluster2.SetLabels(lab);
563 }
a86176e3 564 } // unfolding is on
565 }
566
567 y = q = 0.;
568 nDigits = 0;
569 first=0;
308b5ea4 570 }
571
572 // create recpoints
573 if((nClusters[0])&&(nClusters[1])) {
a86176e3 574
00a7cc50 575 clusters[iModule] = new TClonesArray("AliITSRecPoint");
04366a57 576 fModule = iModule;
577 FindClustersSSD(&clusters1D[0][0], nClusters[0],
578 &clusters1D[1][0], nClusters[1], clusters[iModule]);
4adcf390 579 Int_t nClustersn = clusters[iModule]->GetEntriesFast();
580 nClustersSSD += nClustersn;
04366a57 581 }
582
04366a57 583 nClusters[0] = nClusters[1] = 0;
584 y = q = 0.;
585 nDigits = 0;
3a4139a2 586
308b5ea4 587 } // loop over adc
04366a57 588
d5ad0697 589 if(!next) break;
04366a57 590 }
308b5ea4 591
04366a57 592 Info("FindClustersSSD", "found clusters in ITS SSD: %d", nClustersSSD);
593}
594
595void AliITSClusterFinderV2SSD::
596FindClustersSSD(Ali1Dcluster* neg, Int_t nn,
597 Ali1Dcluster* pos, Int_t np,
598 TClonesArray *clusters) {
599 //------------------------------------------------------------
600 // Actual SSD cluster finder
601 //------------------------------------------------------------
b4704be3 602
603 const TGeoHMatrix *mT2L=AliITSgeomTGeo::GetTracking2LocalMatrix(fModule);
604
04366a57 605 TClonesArray &cl=*clusters;
d036ccd3 606
8be4e1b1 607 AliITSsegmentationSSD *seg = dynamic_cast<AliITSsegmentationSSD*>(fDetTypeRec->GetSegmentationModel(2));
608 if (fModule>fLastSSD1)
609 seg->SetLayer(6);
610 else
611 seg->SetLayer(5);
612
613 Float_t hwSSD = seg->Dx()*1e-4/2;
614 Float_t hlSSD = seg->Dz()*1e-4/2;
615
04366a57 616 Int_t idet=fNdet[fModule];
617 Int_t ncl=0;
d036ccd3 618
04366a57 619 //
8be4e1b1 620 Int_t *cnegative = new Int_t[np];
621 Int_t *cused1 = new Int_t[np];
622 Int_t *negativepair = new Int_t[10*np];
623 Int_t *cpositive = new Int_t[nn];
624 Int_t *cused2 = new Int_t[nn];
625 Int_t *positivepair = new Int_t[10*nn];
626 for (Int_t i=0;i<np;i++) {cnegative[i]=0; cused1[i]=0;}
627 for (Int_t i=0;i<nn;i++) {cpositive[i]=0; cused2[i]=0;}
628 for (Int_t i=0;i<10*np;i++) {negativepair[i]=0;}
629 for (Int_t i=0;i<10*nn;i++) {positivepair[i]=0;}
c157c94e 630
308b5ea4 631 if ((np*nn) > fgPairsSize) {
d036ccd3 632
308b5ea4 633 if (fgPairs) delete [] fgPairs;
634 fgPairsSize = 4*np*nn;
635 fgPairs = new Short_t[fgPairsSize];
c157c94e 636 }
308b5ea4 637 memset(fgPairs,0,sizeof(Short_t)*np*nn);
638
04366a57 639 //
640 // find available pairs
641 //
642 for (Int_t i=0; i<np; i++) {
d036ccd3 643 Float_t yp=pos[i].GetY();
a64f9843 644 if ( (pos[i].GetQ()>0) && (pos[i].GetQ()<3) ) continue;
04366a57 645 for (Int_t j=0; j<nn; j++) {
a64f9843 646 if ( (neg[j].GetQ()>0) && (neg[j].GetQ()<3) ) continue;
d036ccd3 647 Float_t yn=neg[j].GetY();
648
8be4e1b1 649 Float_t xt, zt;
650 seg->GetPadCxz(yn, yp, xt, zt);
d036ccd3 651
8be4e1b1 652 if (TMath::Abs(xt)<hwSSD+0.01)
653 if (TMath::Abs(zt)<hlSSD+0.01*(neg[j].GetNd()+pos[i].GetNd())) {
04366a57 654 negativepair[i*10+cnegative[i]] =j; //index
655 positivepair[j*10+cpositive[j]] =i;
656 cnegative[i]++; //counters
657 cpositive[j]++;
308b5ea4 658 fgPairs[i*nn+j]=100;
04366a57 659 }
660 }
661 }
308b5ea4 662
663 //
664 // try to recover points out of but close to the module boundaries
04366a57 665 //
666 for (Int_t i=0; i<np; i++) {
d036ccd3 667 Float_t yp=pos[i].GetY();
a64f9843 668 if ( (pos[i].GetQ()>0) && (pos[i].GetQ()<3) ) continue;
04366a57 669 for (Int_t j=0; j<nn; j++) {
a64f9843 670 if ( (neg[j].GetQ()>0) && (neg[j].GetQ()<3) ) continue;
308b5ea4 671 // if both 1Dclusters have an other cross continue
04366a57 672 if (cpositive[j]&&cnegative[i]) continue;
8be4e1b1 673 Float_t yn=neg[j].GetY();
d036ccd3 674
8be4e1b1 675 Float_t xt, zt;
676 seg->GetPadCxz(yn, yp, xt, zt);
d036ccd3 677
8be4e1b1 678 if (TMath::Abs(xt)<hwSSD+0.1)
679 if (TMath::Abs(zt)<hlSSD+0.15) {
308b5ea4 680 // tag 1Dcluster (eventually will produce low quality recpoint)
04366a57 681 if (cnegative[i]==0) pos[i].SetNd(100); // not available pair
682 if (cpositive[j]==0) neg[j].SetNd(100); // not available pair
683 negativepair[i*10+cnegative[i]] =j; //index
684 positivepair[j*10+cpositive[j]] =i;
685 cnegative[i]++; //counters
686 cpositive[j]++;
308b5ea4 687 fgPairs[i*nn+j]=100;
04366a57 688 }
689 }
690 }
308b5ea4 691
04366a57 692 //
693 Float_t lp[5];
694 Int_t milab[10];
695 Double_t ratio;
696
b42cfa25 697
a86176e3 698 static AliITSRecoParam *repa = NULL;
699 if(!repa){
700 repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
701 if(!repa){
ed446fa3 702 repa = AliITSRecoParam::GetHighFluxParam();
a86176e3 703 AliWarning("Using default AliITSRecoParam class");
704 }
705 }
b42cfa25 706
a86176e3 707 if(repa->GetUseChargeMatchingInClusterFinderSSD()==kTRUE) {
308b5ea4 708
709
a86176e3 710 //
711 // sign gold tracks
712 //
713 for (Int_t ip=0;ip<np;ip++){
8be4e1b1 714 Float_t xbest=1000,zbest=1000,qbest=0;
a86176e3 715 //
716 // select gold clusters
717 if ( (cnegative[ip]==1) && cpositive[negativepair[10*ip]]==1){
d036ccd3 718 Float_t yp=pos[ip].GetY();
a86176e3 719 Int_t j = negativepair[10*ip];
a64f9843 720
721 if( (pos[ip].GetQ()==0) && (neg[j].GetQ() ==0) ) {
722 // both bad, hence continue;
723 // mark both as used (to avoid recover at the end)
724 cused1[ip]++;
725 cused2[j]++;
726 continue;
727 }
728
a86176e3 729 ratio = (pos[ip].GetQ()-neg[j].GetQ())/(pos[ip].GetQ()+neg[j].GetQ());
a64f9843 730
731 // charge matching (note that if posQ or negQ is 0 -> ratio=1 and the following condition is met
2069484c 732 if (TMath::Abs(ratio)>0.2) continue; // note: 0.2=3xsigma_ratio calculated in cosmics tests
a64f9843 733
a86176e3 734 //
8be4e1b1 735 Float_t yn=neg[j].GetY();
736
737 Float_t xt, zt;
738 seg->GetPadCxz(yn, yp, xt, zt);
739
740 xbest=xt; zbest=zt;
2069484c 741
2069484c 742
a86176e3 743 qbest=0.5*(pos[ip].GetQ()+neg[j].GetQ());
a64f9843 744 if( (pos[ip].GetQ()==0)||(neg[ip].GetQ()==0)) qbest*=2; // in case of bad strips on one side keep all charge from the other one
a86176e3 745
a86176e3 746 {
8be4e1b1 747 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
a86176e3 748 mT2L->MasterToLocal(loc,trk);
749 lp[0]=trk[1];
750 lp[1]=trk[2];
00a7cc50 751 }
a86176e3 752 lp[2]=0.0025*0.0025; //SigmaY2
753 lp[3]=0.110*0.110; //SigmaZ2
00a7cc50 754
a86176e3 755 lp[4]=qbest; //Q
756 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
757 for (Int_t ilab=0;ilab<3;ilab++){
758 milab[ilab] = pos[ip].GetLabel(ilab);
759 milab[ilab+3] = neg[j].GetLabel(ilab);
00a7cc50 760 }
04366a57 761 //
a86176e3 762 CheckLabels2(milab);
763 milab[3]=(((ip<<10) + j)<<10) + idet; // pos|neg|det
764 Int_t info[3] = {pos[ip].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
765 AliITSRecPoint * cl2;
766
767 if(clusters){ // Note clusters != 0 when method is called for rawdata
04366a57 768
a86176e3 769
770 cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);
771
a86176e3 772 cl2->SetChargeRatio(ratio);
773 cl2->SetType(1);
774 fgPairs[ip*nn+j]=1;
a64f9843 775
a86176e3 776 if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
777 cl2->SetType(2);
778 fgPairs[ip*nn+j]=2;
04366a57 779 }
a64f9843 780
781 if(pos[ip].GetQ()==0) cl2->SetType(3);
782 if(neg[ip].GetQ()==0) cl2->SetType(4);
783
a86176e3 784 cused1[ip]++;
785 cused2[j]++;
786
787 }
788 else{ // Note clusters == 0 when method is called for digits
789
790 cl2 = new AliITSRecPoint(milab,lp,info);
791
a86176e3 792 cl2->SetChargeRatio(ratio);
793 cl2->SetType(1);
794 fgPairs[ip*nn+j]=1;
a64f9843 795
a86176e3 796 if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
797 cl2->SetType(2);
798 fgPairs[ip*nn+j]=2;
00a7cc50 799 }
a64f9843 800
801 if(pos[ip].GetQ()==0) cl2->SetType(3);
802 if(neg[ip].GetQ()==0) cl2->SetType(4);
803
a86176e3 804 cused1[ip]++;
805 cused2[j]++;
a64f9843 806
a86176e3 807 fDetTypeRec->AddRecPoint(*cl2);
808 }
809 ncl++;
810 }
811 }
812
813 for (Int_t ip=0;ip<np;ip++){
8be4e1b1 814 Float_t xbest=1000,zbest=1000,qbest=0;
a86176e3 815 //
816 //
817 // select "silber" cluster
818 if ( cnegative[ip]==1 && cpositive[negativepair[10*ip]]==2){
819 Int_t in = negativepair[10*ip];
820 Int_t ip2 = positivepair[10*in];
821 if (ip2==ip) ip2 = positivepair[10*in+1];
822 Float_t pcharge = pos[ip].GetQ()+pos[ip2].GetQ();
a64f9843 823
2069484c 824 if ( (TMath::Abs(pcharge-neg[in].GetQ())<30) && (pcharge!=0) ) { //
a64f9843 825
a86176e3 826 //
827 // add first pair
a64f9843 828 if ( (fgPairs[ip*nn+in]==100)&&(pos[ip].GetQ() ) ) { //
829
d036ccd3 830 Float_t yp=pos[ip].GetY();
8be4e1b1 831 Float_t yn=neg[in].GetY();
832
833 Float_t xt, zt;
834 seg->GetPadCxz(yn, yp, xt, zt);
835
836 xbest=xt; zbest=zt;
2069484c 837
a86176e3 838 qbest =pos[ip].GetQ();
8be4e1b1 839 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
a64f9843 840 mT2L->MasterToLocal(loc,trk);
841 lp[0]=trk[1];
842 lp[1]=trk[2];
843
a86176e3 844 lp[2]=0.0025*0.0025; //SigmaY2
845 lp[3]=0.110*0.110; //SigmaZ2
846
847 lp[4]=qbest; //Q
848 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
849 for (Int_t ilab=0;ilab<3;ilab++){
850 milab[ilab] = pos[ip].GetLabel(ilab);
851 milab[ilab+3] = neg[in].GetLabel(ilab);
852 }
853 //
854 CheckLabels2(milab);
855 ratio = (pos[ip].GetQ()-neg[in].GetQ())/(pos[ip].GetQ()+neg[in].GetQ());
856 milab[3]=(((ip<<10) + in)<<10) + idet; // pos|neg|det
857 Int_t info[3] = {pos[ip].GetNd(),neg[in].GetNd(),fNlayer[fModule]};
858
859 AliITSRecPoint * cl2;
860 if(clusters){
861
862 cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);
a86176e3 863 cl2->SetChargeRatio(ratio);
864 cl2->SetType(5);
865 fgPairs[ip*nn+in] = 5;
866 if ((pos[ip].GetNd()+neg[in].GetNd())>6){ //multi cluster
867 cl2->SetType(6);
868 fgPairs[ip*nn+in] = 6;
869 }
870 }
871 else{
872 cl2 = new AliITSRecPoint(milab,lp,info);
873 cl2->SetChargeRatio(ratio);
874 cl2->SetType(5);
875 fgPairs[ip*nn+in] = 5;
876 if ((pos[ip].GetNd()+neg[in].GetNd())>6){ //multi cluster
877 cl2->SetType(6);
878 fgPairs[ip*nn+in] = 6;
879 }
a86176e3 880
881 fDetTypeRec->AddRecPoint(*cl2);
882 }
883 ncl++;
04366a57 884 }
04366a57 885
a64f9843 886
04366a57 887 //
a86176e3 888 // add second pair
00a7cc50 889
a86176e3 890 // if (!(cused1[ip2] || cused2[in])){ //
a64f9843 891 if ( (fgPairs[ip2*nn+in]==100) && (pos[ip2].GetQ()) ) {
892
d036ccd3 893 Float_t yp=pos[ip2].GetY();
8be4e1b1 894 Float_t yn=neg[in].GetY();
895
896 Float_t xt, zt;
897 seg->GetPadCxz(yn, yp, xt, zt);
898
899 xbest=xt; zbest=zt;
2069484c 900
a86176e3 901 qbest =pos[ip2].GetQ();
a64f9843 902
8be4e1b1 903 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
a64f9843 904 mT2L->MasterToLocal(loc,trk);
905 lp[0]=trk[1];
906 lp[1]=trk[2];
907
a86176e3 908 lp[2]=0.0025*0.0025; //SigmaY2
909 lp[3]=0.110*0.110; //SigmaZ2
910
911 lp[4]=qbest; //Q
912 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
913 for (Int_t ilab=0;ilab<3;ilab++){
914 milab[ilab] = pos[ip2].GetLabel(ilab);
915 milab[ilab+3] = neg[in].GetLabel(ilab);
00a7cc50 916 }
a86176e3 917 //
918 CheckLabels2(milab);
919 ratio = (pos[ip2].GetQ()-neg[in].GetQ())/(pos[ip2].GetQ()+neg[in].GetQ());
920 milab[3]=(((ip2<<10) + in)<<10) + idet; // pos|neg|det
921 Int_t info[3] = {pos[ip2].GetNd(),neg[in].GetNd(),fNlayer[fModule]};
308b5ea4 922
a86176e3 923 AliITSRecPoint * cl2;
924 if(clusters){
925 cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);
926
a86176e3 927 cl2->SetChargeRatio(ratio);
928 cl2->SetType(5);
929 fgPairs[ip2*nn+in] =5;
930 if ((pos[ip2].GetNd()+neg[in].GetNd())>6){ //multi cluster
931 cl2->SetType(6);
932 fgPairs[ip2*nn+in] =6;
933 }
934 }
935 else{
936 cl2 = new AliITSRecPoint(milab,lp,info);
937 cl2->SetChargeRatio(ratio);
938 cl2->SetType(5);
939 fgPairs[ip2*nn+in] =5;
940 if ((pos[ip2].GetNd()+neg[in].GetNd())>6){ //multi cluster
941 cl2->SetType(6);
942 fgPairs[ip2*nn+in] =6;
943 }
944
a86176e3 945 fDetTypeRec->AddRecPoint(*cl2);
946 }
947 ncl++;
a64f9843 948 }
949
a86176e3 950 cused1[ip]++;
951 cused1[ip2]++;
952 cused2[in]++;
a64f9843 953
954 } // charge matching condition
955
956 } // 2 Pside cross 1 Nside
957 } // loop over Pside clusters
a86176e3 958
a64f9843 959
960
961 //
962 for (Int_t jn=0;jn<nn;jn++){
963 if (cused2[jn]) continue;
8be4e1b1 964 Float_t xbest=1000,zbest=1000,qbest=0;
a64f9843 965 // select "silber" cluster
966 if ( cpositive[jn]==1 && cnegative[positivepair[10*jn]]==2){
967 Int_t ip = positivepair[10*jn];
968 Int_t jn2 = negativepair[10*ip];
969 if (jn2==jn) jn2 = negativepair[10*ip+1];
970 Float_t pcharge = neg[jn].GetQ()+neg[jn2].GetQ();
04366a57 971 //
a64f9843 972
2069484c 973 if ( (TMath::Abs(pcharge-pos[ip].GetQ())<30) && // charge matching
a64f9843 974 (pcharge!=0) ) { // reject combinations of bad strips
975
976 //
977 // add first pair
978 // if (!(cused1[ip]||cused2[jn])){
979 if ( (fgPairs[ip*nn+jn]==100) && (neg[jn].GetQ()) ) { //
980
d036ccd3 981 Float_t yn=neg[jn].GetY();
8be4e1b1 982 Float_t yp=pos[ip].GetY();
2069484c 983
8be4e1b1 984 Float_t xt, zt;
985 seg->GetPadCxz(yn, yp, xt, zt);
986
987 xbest=xt; zbest=zt;
2069484c 988
a64f9843 989 qbest =neg[jn].GetQ();
d036ccd3 990
a64f9843 991 {
8be4e1b1 992 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
a64f9843 993 mT2L->MasterToLocal(loc,trk);
994 lp[0]=trk[1];
995 lp[1]=trk[2];
b4704be3 996 }
04366a57 997 lp[2]=0.0025*0.0025; //SigmaY2
998 lp[3]=0.110*0.110; //SigmaZ2
999
1000 lp[4]=qbest; //Q
1001 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1002 for (Int_t ilab=0;ilab<3;ilab++){
1003 milab[ilab] = pos[ip].GetLabel(ilab);
1004 milab[ilab+3] = neg[jn].GetLabel(ilab);
1005 }
1006 //
1007 CheckLabels2(milab);
1008 ratio = (pos[ip].GetQ()-neg[jn].GetQ())/(pos[ip].GetQ()+neg[jn].GetQ());
1009 milab[3]=(((ip<<10) + jn)<<10) + idet; // pos|neg|det
1010 Int_t info[3] = {pos[ip].GetNd(),neg[jn].GetNd(),fNlayer[fModule]};
1011
00a7cc50 1012 AliITSRecPoint * cl2;
1013 if(clusters){
75fb37cc 1014 cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);
308b5ea4 1015
00a7cc50 1016 cl2->SetChargeRatio(ratio);
1017 cl2->SetType(7);
308b5ea4 1018 fgPairs[ip*nn+jn] =7;
00a7cc50 1019 if ((pos[ip].GetNd()+neg[jn].GetNd())>6){ //multi cluster
1020 cl2->SetType(8);
308b5ea4 1021 fgPairs[ip*nn+jn]=8;
00a7cc50 1022 }
1023
1024 }
04366a57 1025 else{
75fb37cc 1026 cl2 = new AliITSRecPoint(milab,lp,info);
00a7cc50 1027 cl2->SetChargeRatio(ratio);
1028 cl2->SetType(7);
308b5ea4 1029 fgPairs[ip*nn+jn] =7;
00a7cc50 1030 if ((pos[ip].GetNd()+neg[jn].GetNd())>6){ //multi cluster
1031 cl2->SetType(8);
308b5ea4 1032 fgPairs[ip*nn+jn]=8;
00a7cc50 1033 }
1034
1035 fDetTypeRec->AddRecPoint(*cl2);
04366a57 1036 }
1037 ncl++;
04366a57 1038 }
1039 //
1040 // add second pair
1041 // if (!(cused1[ip]||cused2[jn2])){
a64f9843 1042 if ( (fgPairs[ip*nn+jn2]==100)&&(neg[jn2].GetQ() ) ) { //
1043
d036ccd3 1044 Float_t yn=neg[jn2].GetY();
1045 Double_t yp=pos[ip].GetY();
2069484c 1046
8be4e1b1 1047 Float_t xt, zt;
1048 seg->GetPadCxz(yn, yp, xt, zt);
1049
1050 xbest=xt; zbest=zt;
2069484c 1051
04366a57 1052 qbest =neg[jn2].GetQ();
d036ccd3 1053
b4704be3 1054 {
8be4e1b1 1055 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
b4704be3 1056 mT2L->MasterToLocal(loc,trk);
1057 lp[0]=trk[1];
1058 lp[1]=trk[2];
1059 }
04366a57 1060 lp[2]=0.0025*0.0025; //SigmaY2
1061 lp[3]=0.110*0.110; //SigmaZ2
1062
1063 lp[4]=qbest; //Q
1064 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1065 for (Int_t ilab=0;ilab<3;ilab++){
1066 milab[ilab] = pos[ip].GetLabel(ilab);
1067 milab[ilab+3] = neg[jn2].GetLabel(ilab);
1068 }
1069 //
1070 CheckLabels2(milab);
1071 ratio = (pos[ip].GetQ()-neg[jn2].GetQ())/(pos[ip].GetQ()+neg[jn2].GetQ());
1072 milab[3]=(((ip<<10) + jn2)<<10) + idet; // pos|neg|det
1073 Int_t info[3] = {pos[ip].GetNd(),neg[jn2].GetNd(),fNlayer[fModule]};
00a7cc50 1074 AliITSRecPoint * cl2;
1075 if(clusters){
75fb37cc 1076 cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);
308b5ea4 1077
308b5ea4 1078
00a7cc50 1079 cl2->SetChargeRatio(ratio);
308b5ea4 1080 fgPairs[ip*nn+jn2]=7;
00a7cc50 1081 cl2->SetType(7);
1082 if ((pos[ip].GetNd()+neg[jn2].GetNd())>6){ //multi cluster
1083 cl2->SetType(8);
308b5ea4 1084 fgPairs[ip*nn+jn2]=8;
00a7cc50 1085 }
1086
1087 }
04366a57 1088 else{
75fb37cc 1089 cl2 = new AliITSRecPoint(milab,lp,info);
00a7cc50 1090 cl2->SetChargeRatio(ratio);
308b5ea4 1091 fgPairs[ip*nn+jn2]=7;
00a7cc50 1092 cl2->SetType(7);
1093 if ((pos[ip].GetNd()+neg[jn2].GetNd())>6){ //multi cluster
1094 cl2->SetType(8);
308b5ea4 1095 fgPairs[ip*nn+jn2]=8;
00a7cc50 1096 }
308b5ea4 1097
00a7cc50 1098 fDetTypeRec->AddRecPoint(*cl2);
04366a57 1099 }
1100
1101 ncl++;
04366a57 1102 }
1103 cused1[ip]++;
1104 cused2[jn]++;
1105 cused2[jn2]++;
308b5ea4 1106
a64f9843 1107 } // charge matching condition
1108
1109 } // 2 Nside cross 1 Pside
1110 } // loop over Pside clusters
1111
1112
1113
1114 for (Int_t ip=0;ip<np;ip++){
8be4e1b1 1115 Float_t xbest=1000,zbest=1000,qbest=0;
04366a57 1116 //
a64f9843 1117 // 2x2 clusters
04366a57 1118 //
a64f9843 1119 if ( (cnegative[ip]<5) && cpositive[negativepair[10*ip]]<5){
1120 Float_t minchargediff =4.;
1121 Int_t j=-1;
1122 for (Int_t di=0;di<cnegative[ip];di++){
1123 Int_t jc = negativepair[ip*10+di];
1124 Float_t chargedif = pos[ip].GetQ()-neg[jc].GetQ();
1125 if (TMath::Abs(chargedif)<minchargediff){
1126 j =jc;
1127 minchargediff = TMath::Abs(chargedif);
1128 }
00a7cc50 1129 }
a64f9843 1130 if (j<0) continue; // not proper cluster
1131
1132 Int_t count =0;
1133 for (Int_t di=0;di<cnegative[ip];di++){
1134 Int_t jc = negativepair[ip*10+di];
1135 Float_t chargedif = pos[ip].GetQ()-neg[jc].GetQ();
1136 if (TMath::Abs(chargedif)<minchargediff+3.) count++;
00a7cc50 1137 }
a64f9843 1138 if (count>1) continue; // more than one "proper" cluster for positive
1139 //
00a7cc50 1140
a64f9843 1141 count =0;
1142 for (Int_t dj=0;dj<cpositive[j];dj++){
1143 Int_t ic = positivepair[j*10+dj];
1144 Float_t chargedif = pos[ic].GetQ()-neg[j].GetQ();
1145 if (TMath::Abs(chargedif)<minchargediff+3.) count++;
1146 }
1147 if (count>1) continue; // more than one "proper" cluster for negative
1148
1149 Int_t jp = 0;
1150
1151 count =0;
1152 for (Int_t dj=0;dj<cnegative[jp];dj++){
1153 Int_t ic = positivepair[jp*10+dj];
1154 Float_t chargedif = pos[ic].GetQ()-neg[jp].GetQ();
1155 if (TMath::Abs(chargedif)<minchargediff+4.) count++;
1156 }
1157 if (count>1) continue;
1158 if (fgPairs[ip*nn+j]<100) continue;
1159 //
1160
1161 //almost gold clusters
d036ccd3 1162 Float_t yp=pos[ip].GetY();
1163 Float_t yn=neg[j].GetY();
1164
8be4e1b1 1165
1166 Float_t xt, zt;
1167 seg->GetPadCxz(yn, yp, xt, zt);
1168
1169 xbest=xt; zbest=zt;
1170
a64f9843 1171 qbest=0.5*(pos[ip].GetQ()+neg[j].GetQ());
d036ccd3 1172
a64f9843 1173 {
8be4e1b1 1174 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
a64f9843 1175 mT2L->MasterToLocal(loc,trk);
1176 lp[0]=trk[1];
1177 lp[1]=trk[2];
1178 }
1179 lp[2]=0.0025*0.0025; //SigmaY2
1180 lp[3]=0.110*0.110; //SigmaZ2
1181 lp[4]=qbest; //Q
1182 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1183 for (Int_t ilab=0;ilab<3;ilab++){
1184 milab[ilab] = pos[ip].GetLabel(ilab);
1185 milab[ilab+3] = neg[j].GetLabel(ilab);
1186 }
1187 //
1188 CheckLabels2(milab);
db6e54cd 1189 if ((neg[j].GetQ()==0)&&(pos[ip].GetQ()==0)) continue; // reject crosses of bad strips!!
a64f9843 1190 ratio = (pos[ip].GetQ()-neg[j].GetQ())/(pos[ip].GetQ()+neg[j].GetQ());
1191 milab[3]=(((ip<<10) + j)<<10) + idet; // pos|neg|det
1192 Int_t info[3] = {pos[ip].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
1193 AliITSRecPoint * cl2;
1194 if(clusters){
1195 cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);
d036ccd3 1196
a64f9843 1197 cl2->SetChargeRatio(ratio);
1198 cl2->SetType(10);
1199 fgPairs[ip*nn+j]=10;
1200 if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
1201 cl2->SetType(11);
1202 fgPairs[ip*nn+j]=11;
1203 }
1204 cused1[ip]++;
1205 cused2[j]++;
1206 }
1207 else{
1208 cl2 = new AliITSRecPoint(milab,lp,info);
1209 cl2->SetChargeRatio(ratio);
1210 cl2->SetType(10);
1211 fgPairs[ip*nn+j]=10;
1212 if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
1213 cl2->SetType(11);
1214 fgPairs[ip*nn+j]=11;
1215 }
1216 cused1[ip]++;
1217 cused2[j]++;
1218
a64f9843 1219 fDetTypeRec->AddRecPoint(*cl2);
1220 }
1221 ncl++;
1222
1223 } // manyXmany
1224 } // loop over Pside 1Dclusters
1225
1226
1227 } // use charge matching
1228
04366a57 1229
a64f9843 1230 // recover all the other crosses
04366a57 1231 //
1232 for (Int_t i=0; i<np; i++) {
8be4e1b1 1233 Float_t xbest=1000,zbest=1000,qbest=0;
d036ccd3 1234 Float_t yp=pos[i].GetY();
a64f9843 1235 if ((pos[i].GetQ()>0)&&(pos[i].GetQ()<3)) continue;
04366a57 1236 for (Int_t j=0; j<nn; j++) {
1237 // for (Int_t di = 0;di<cpositive[i];di++){
1238 // Int_t j = negativepair[10*i+di];
a64f9843 1239 if ((neg[j].GetQ()>0)&&(neg[j].GetQ()<3)) continue;
1240
1241 if ((neg[j].GetQ()==0)&&(pos[i].GetQ()==0)) continue; // reject crosses of bad strips!!
1242
04366a57 1243 if (cused2[j]||cused1[i]) continue;
308b5ea4 1244 if (fgPairs[i*nn+j]>0 &&fgPairs[i*nn+j]<100) continue;
04366a57 1245 ratio = (pos[i].GetQ()-neg[j].GetQ())/(pos[i].GetQ()+neg[j].GetQ());
d036ccd3 1246 Float_t yn=neg[j].GetY();
1247
8be4e1b1 1248 Float_t xt, zt;
1249 seg->GetPadCxz(yn, yp, xt, zt);
d036ccd3 1250
8be4e1b1 1251 if (TMath::Abs(xt)<hwSSD+0.01)
1252 if (TMath::Abs(zt)<hlSSD+0.01*(neg[j].GetNd()+pos[i].GetNd())) {
1253 xbest=xt; zbest=zt;
1254
04366a57 1255 qbest=0.5*(pos[i].GetQ()+neg[j].GetQ());
d036ccd3 1256
b4704be3 1257 {
8be4e1b1 1258 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
b4704be3 1259 mT2L->MasterToLocal(loc,trk);
1260 lp[0]=trk[1];
1261 lp[1]=trk[2];
1262 }
04366a57 1263 lp[2]=0.0025*0.0025; //SigmaY2
1264 lp[3]=0.110*0.110; //SigmaZ2
1265
1266 lp[4]=qbest; //Q
1267 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1268 for (Int_t ilab=0;ilab<3;ilab++){
1269 milab[ilab] = pos[i].GetLabel(ilab);
1270 milab[ilab+3] = neg[j].GetLabel(ilab);
1271 }
1272 //
1273 CheckLabels2(milab);
1274 milab[3]=(((i<<10) + j)<<10) + idet; // pos|neg|det
1275 Int_t info[3] = {pos[i].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
00a7cc50 1276 AliITSRecPoint * cl2;
1277 if(clusters){
75fb37cc 1278 cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);
308b5ea4 1279
00a7cc50 1280 cl2->SetChargeRatio(ratio);
1281 cl2->SetType(100+cpositive[j]+cnegative[i]);
a64f9843 1282
1283 if(pos[i].GetQ()==0) cl2->SetType(200+cpositive[j]+cnegative[i]);
1284 if(neg[j].GetQ()==0) cl2->SetType(300+cpositive[j]+cnegative[i]);
1285
00a7cc50 1286 }
04366a57 1287 else{
75fb37cc 1288 cl2 = new AliITSRecPoint(milab,lp,info);
00a7cc50 1289 cl2->SetChargeRatio(ratio);
1290 cl2->SetType(100+cpositive[j]+cnegative[i]);
308b5ea4 1291
a64f9843 1292 if(pos[i].GetQ()==0) cl2->SetType(200+cpositive[j]+cnegative[i]);
1293 if(neg[j].GetQ()==0) cl2->SetType(300+cpositive[j]+cnegative[i]);
308b5ea4 1294
00a7cc50 1295 fDetTypeRec->AddRecPoint(*cl2);
04366a57 1296 }
1297 ncl++;
04366a57 1298 }
1299 }
1300 }
8be4e1b1 1301 delete [] cnegative;
1302 delete [] cused1;
1303 delete [] negativepair;
1304 delete [] cpositive;
1305 delete [] cused2;
1306 delete [] positivepair;
04366a57 1307
04366a57 1308}