extra AOD cuts
[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 //
d695268b 22// Last revision: 13-05-09 Enrico Fragiacomo //
23// enrico.fragiacomo@ts.infn.it //
04366a57 24// //
25///////////////////////////////////////////////////////////////////////////
26
66b89079 27#include "AliITSClusterFinderV2SSD.h"
28
308b5ea4 29#include <Riostream.h>
66b89079 30#include <TGeoGlobalMagField.h>
04366a57 31
66b89079 32#include "AliLog.h"
33#include "AliMagF.h"
00a7cc50 34#include "AliITSRecPoint.h"
01ef1bd4 35#include "AliITSRecPointContainer.h"
1f3e997f 36#include "AliITSgeomTGeo.h"
7d62fb64 37#include "AliITSDetTypeRec.h"
04366a57 38#include "AliRawReader.h"
39#include "AliITSRawStreamSSD.h"
04366a57 40#include <TClonesArray.h>
138df073 41#include <TCollection.h>
04366a57 42#include "AliITSdigitSSD.h"
a86176e3 43#include "AliITSReconstructor.h"
3a4139a2 44#include "AliITSCalibrationSSD.h"
8be4e1b1 45#include "AliITSsegmentationSSD.h"
04366a57 46
308b5ea4 47Short_t *AliITSClusterFinderV2SSD::fgPairs = 0x0;
48Int_t AliITSClusterFinderV2SSD::fgPairsSize = 0;
d695268b 49const Float_t AliITSClusterFinderV2SSD::fgkThreshold = 5.;
50
42ed6062 51const Float_t AliITSClusterFinderV2SSD::fgkCosmic2008StripShifts[16][9] =
52 {{-0.35,-0.35,-0.35,-0.35,-0.35,-0.35,-0.35,-0.35,-0.35}, // DDL 512
53 {-0.35,-0.35,-0.35,-0.35,-0.35,-0.35,-0.35,-0.35,-0.35}, // DDL 513
54 {-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15}, // DDL 514
55 {-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15}, // DDL 515
56 { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}, // DDL 516
57 { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}, // DDL 517
58 {-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15}, // DDL 518
59 {-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15}, // DDL 519
60 {-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.25,-0.15}, // DDL 520
61 {-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15}, // DDL 521
62 {-0.10,-0.10,-0.10,-0.40,-0.40,-0.40,-0.10,-0.10,-0.45}, // DDL 522
63 {-0.10,-0.10,-0.10,-0.35,-0.35,-0.35,-0.10,-0.35,-0.50}, // DDL 523
64 { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}, // DDL 524
65 { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}, // DDL 525
66 { 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35}, // DDL 526
67 { 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45}}; // DDL 527
c157c94e 68
04366a57 69ClassImp(AliITSClusterFinderV2SSD)
70
71
66b89079 72 AliITSClusterFinderV2SSD::AliITSClusterFinderV2SSD(AliITSDetTypeRec* dettyp):AliITSClusterFinder(dettyp),fLastSSD1(AliITSgeomTGeo::GetModuleIndex(6,1,1)-1), fLorentzShiftP(0), fLorentzShiftN(0)
d036ccd3 73{
8be4e1b1 74//Default constructor
66b89079 75 static AliITSRecoParam *repa = NULL;
76 if(!repa){
77 repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
78 if(!repa){
79 repa = AliITSRecoParam::GetHighFluxParam();
80 AliWarning("Using default AliITSRecoParam class");
81 }
82 }
04366a57 83
66b89079 84 if (repa->GetCorrectLorentzAngleSSD()) {
85 AliMagF* field = dynamic_cast<AliMagF*>(TGeoGlobalMagField::Instance()->GetField());
86 if (field == 0)
87 AliError("Cannot get magnetic field from TGeoGlobalMagField");
88 Float_t Bfield = field->SolenoidField();
89 // NB: spatial shift has opposite sign for lay 5 and 6, but strip numbering also changes direction, so no sign-change
90 // Shift due to ExB on drift N-side, units: strip width
91 fLorentzShiftP = -repa->GetTanLorentzAngleElectronsSSD() * 150.e-4/95.e-4 * Bfield / 5.0;
92 // Shift due to ExB on drift P-side, units: strip width
93 fLorentzShiftN = -repa->GetTanLorentzAngleHolesSSD() * 150.e-4/95.e-4 * Bfield / 5.0;
94 AliDebug(1,Form("Bfield %f Lorentz Shift P-side %f N-side %f",Bfield,fLorentzShiftN,fLorentzShiftP));
95 }
04366a57 96}
97
308b5ea4 98//______________________________________________________________________
66b89079 99AliITSClusterFinderV2SSD::AliITSClusterFinderV2SSD(const AliITSClusterFinderV2SSD &cf) : AliITSClusterFinder(cf), fLastSSD1(cf.fLastSSD1), fLorentzShiftP(cf.fLorentzShiftP), fLorentzShiftN(cf.fLorentzShiftN)
308b5ea4 100{
101 // Copy constructor
308b5ea4 102}
103
104//______________________________________________________________________
105AliITSClusterFinderV2SSD& AliITSClusterFinderV2SSD::operator=(const AliITSClusterFinderV2SSD& cf ){
106 // Assignment operator
107
108 this->~AliITSClusterFinderV2SSD();
109 new(this) AliITSClusterFinderV2SSD(cf);
110 return *this;
111}
112
04366a57 113
114void AliITSClusterFinderV2SSD::FindRawClusters(Int_t mod){
115
116 //Find clusters V2
117 SetModule(mod);
118 FindClustersSSD(fDigits);
119
120}
121
122void AliITSClusterFinderV2SSD::FindClustersSSD(TClonesArray *alldigits) {
123 //------------------------------------------------------------
124 // Actual SSD cluster finder
125 //------------------------------------------------------------
d695268b 126 Int_t smaxall=alldigits->GetEntriesFast();
127 if (smaxall==0) return;
a86176e3 128
d695268b 129
130 //---------------------------------------
131 // load recoparam and calibration
132 //
133 static AliITSRecoParam *repa = NULL;
a86176e3 134 if(!repa){
135 repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
136 if(!repa){
ed446fa3 137 repa = AliITSRecoParam::GetHighFluxParam();
a86176e3 138 AliWarning("Using default AliITSRecoParam class");
139 }
140 }
141
3a4139a2 142 AliITSCalibrationSSD* cal = (AliITSCalibrationSSD*)GetResp(fModule);
143 Float_t gain=0;
d695268b 144 Float_t noise=0;
145 //---------------------------------------
3a4139a2 146
d695268b 147
148 //------------------------------------
149 // fill the digits array with zero-suppression condition
150 // Signal is converted in KeV
151 //
f7b30404 152 TObjArray digits;
04366a57 153 for (Int_t i=0;i<smaxall; i++){
154 AliITSdigitSSD *d=(AliITSdigitSSD*)alldigits->UncheckedAt(i);
3a4139a2 155
d695268b 156 if(d->IsSideP()) noise = cal->GetNoiseP(d->GetStripNumber());
157 else noise = cal->GetNoiseN(d->GetStripNumber());
158 if (d->GetSignal()<3.*noise) continue;
159
3a4139a2 160 if(d->IsSideP()) gain = cal->GetGainP(d->GetStripNumber());
161 else gain = cal->GetGainN(d->GetStripNumber());
162
d695268b 163 Float_t q=gain*d->GetSignal(); //
3a4139a2 164 q=cal->ADCToKeV(q); // converts the charge in KeV from ADC units
6490e1c5 165 d->SetSignal(Int_t(q));
3a4139a2 166
f7b30404 167 digits.AddLast(d);
04366a57 168 }
f7b30404 169 Int_t smax = digits.GetEntriesFast();
04366a57 170 if (smax==0) return;
d695268b 171 //------------------------------------
172
04366a57 173
174 const Int_t kMax=1000;
175 Int_t np=0, nn=0;
176 Ali1Dcluster pos[kMax], neg[kMax];
177 Float_t y=0., q=0., qmax=0.;
d695268b 178 Int_t lab[4]={-2,-2,-2,-2};
179 Bool_t flag5 = 0;
04366a57 180
d695268b 181 /*
182 cout<<"-----------------------------"<<endl;
183 cout<<"this is module "<<fModule;
184 cout<<endl;
185 cout<<endl;
186 */
66b89079 187 Int_t layer = 4;
188 if (fModule>fLastSSD1)
189 layer = 5;
d695268b 190
191 //--------------------------------------------------------
192 // start 1D-clustering from the first digit in the digits array
193 //
f7b30404 194 AliITSdigitSSD *d=(AliITSdigitSSD*)digits.UncheckedAt(0);
04366a57 195 q += d->GetSignal();
196 y += d->GetCoord2()*d->GetSignal();
197 qmax=d->GetSignal();
198 lab[0]=d->GetTrack(0); lab[1]=d->GetTrack(1); lab[2]=d->GetTrack(2);
d695268b 199
200 if(d->IsSideP()) {
201 noise = cal->GetNoiseP(d->GetStripNumber());
202 gain = cal->GetGainP(d->GetStripNumber());
203 }
204 else {
205 noise = cal->GetNoiseN(d->GetStripNumber());
206 gain = cal->GetGainN(d->GetStripNumber());
207 }
208 noise*=gain;
209 noise=cal->ADCToKeV(noise); // converts noise in KeV from ADC units
210
211 if(qmax>fgkThreshold*noise) flag5=1; // seed for the cluster
212
213 /*
214 cout<<d->GetSignal()<<" "<<noise<<" "<<flag5<<" "<<
215 d->GetCoord1()<<" "<<d->GetCoord2()<<endl;
216 */
217
04366a57 218 Int_t curr=d->GetCoord2();
219 Int_t flag=d->GetCoord1();
d695268b 220
221 // Note: the first side which will be processed is supposed to be the
222 // P-side which is neg
04366a57 223 Int_t *n=&nn;
224 Ali1Dcluster *c=neg;
d695268b 225 if(flag) {n=&np; c=pos;} // in case we have only Nstrips (P was bad!)
226
04366a57 227 Int_t nd=1;
228 Int_t milab[10];
229 for (Int_t ilab=0;ilab<10;ilab++){
230 milab[ilab]=-2;
231 }
232 milab[0]=d->GetTrack(0); milab[1]=d->GetTrack(1); milab[2]=d->GetTrack(2);
233
d695268b 234
235 //----------------------------------------------------------
236 // search for neighboring digits
237 //
04366a57 238 for (Int_t s=1; s<smax; s++) {
f7b30404 239 d=(AliITSdigitSSD*)digits.UncheckedAt(s);
04366a57 240 Int_t strip=d->GetCoord2();
d695268b 241
242 // if digits is not a neighbour or side did not change
243 // and at least one of the previous digits met the seed condition
244 // then creates a new 1D cluster
245 if ( ( ((strip-curr) > 1) || (flag!=d->GetCoord1()) ) ) {
246
247 if(flag5) {
248 //cout<<"here1"<<endl;
66b89079 249 Float_t dLorentz = 0;
250 if (!flag) { // P-side is neg clust
251 dLorentz = fLorentzShiftN;
252 }
253 else { // N-side is p clust
254 dLorentz = fLorentzShiftP;
255 }
256 c[*n].SetY(y/q+dLorentz);
04366a57 257 c[*n].SetQ(q);
258 c[*n].SetNd(nd);
259 CheckLabels2(milab);
260 c[*n].SetLabels(milab);
a86176e3 261
262 if(repa->GetUseUnfoldingInClusterFinderSSD()==kTRUE) {
d695268b 263 // Note: fUseUnfoldingInClusterFinderSSD=kFALSE by default in RecoParam
264
a86176e3 265 //Split suspiciously big cluster
266 if (nd>4&&nd<25) {
66b89079 267 c[*n].SetY(y/q-0.25*nd+dLorentz);
a86176e3 268 c[*n].SetQ(0.5*q);
269 (*n)++;
270 if (*n==kMax) {
271 Error("FindClustersSSD","Too many 1D clusters !");
272 return;
273 }
66b89079 274 c[*n].SetY(y/q+0.25*nd+dLorentz);
a86176e3 275 c[*n].SetQ(0.5*q);
276 c[*n].SetNd(nd);
277 c[*n].SetLabels(milab);
278 }
279
280 } // unfolding is on
281
04366a57 282 (*n)++;
283 if (*n==kMax) {
284 Error("FindClustersSSD","Too many 1D clusters !");
285 return;
286 }
d695268b 287
288 } // flag5 set
289
290 // reset everything
04366a57 291 y=q=qmax=0.;
292 nd=0;
d695268b 293 flag5=0;
04366a57 294 lab[0]=lab[1]=lab[2]=-2;
d695268b 295 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
296
297 // if side changed from P to N, switch to pos 1D clusters
298 // (if for some reason the side changed from N to P then do the opposite)
299 if (flag!=d->GetCoord1())
300 { if(!flag) {n=&np; c=pos;} else {n=&nn; c=neg;} }
301
302 } // end create new 1D cluster from previous neighboring digits
303
304 // continues adding digits to the previous cluster
305 // or start a new one
04366a57 306 flag=d->GetCoord1();
307 q += d->GetSignal();
308 y += d->GetCoord2()*d->GetSignal();
309 nd++;
d695268b 310
311 if(d->IsSideP()) {
312 noise = cal->GetNoiseP(d->GetStripNumber());
313 gain = cal->GetGainP(d->GetStripNumber());
314 }
315 else {
316 noise = cal->GetNoiseN(d->GetStripNumber());
317 gain = cal->GetGainN(d->GetStripNumber());
318 }
319 noise*=gain;
320 noise=cal->ADCToKeV(noise); // converts the charge in KeV from ADC units
321
322 if(d->GetSignal()>fgkThreshold*noise) flag5=1;
323
324 /*
325 cout<<d->GetSignal()<<" "<<noise<<" "<<flag5<<" "<<
326 d->GetCoord1()<<" "<<d->GetCoord2()<<endl;
327 */
328
04366a57 329 if (d->GetSignal()>qmax) {
330 qmax=d->GetSignal();
331 lab[0]=d->GetTrack(0); lab[1]=d->GetTrack(1); lab[2]=d->GetTrack(2);
332 }
333 for (Int_t ilab=0;ilab<10;ilab++) {
334 if (d->GetTrack(ilab)>=0) AddLabel(milab, (d->GetTrack(ilab)));
335 }
336 curr=strip;
a86176e3 337
d695268b 338
339 } // loop over digits, no more digits in the digits array
340
341
342 // add the last 1D cluster
343 if(flag5) {
344
345 // cout<<"here2"<<endl;
66b89079 346 Float_t dLorentz = 0;
347 if (!flag) { // P-side is neg clust
348 dLorentz = fLorentzShiftN;
349 }
350 else { // N-side is p clust
351 dLorentz = fLorentzShiftP;
352 }
353
354 c[*n].SetY(y/q + dLorentz);
d695268b 355 c[*n].SetQ(q);
356 c[*n].SetNd(nd);
357 c[*n].SetLabels(lab);
a86176e3 358
d695268b 359 if(repa->GetUseUnfoldingInClusterFinderSSD()==kTRUE) {
360
361 //Split suspiciously big cluster
362 if (nd>4 && nd<25) {
66b89079 363 c[*n].SetY(y/q-0.25*nd + dLorentz);
d695268b 364 c[*n].SetQ(0.5*q);
365 (*n)++;
366 if (*n==kMax) {
367 Error("FindClustersSSD","Too many 1D clusters !");
368 return;
369 }
66b89079 370 c[*n].SetY(y/q+0.25*nd + dLorentz);
d695268b 371 c[*n].SetQ(0.5*q);
372 c[*n].SetNd(nd);
373 c[*n].SetLabels(lab);
a86176e3 374 }
d695268b 375 } // unfolding is on
376
377 (*n)++;
378 if (*n==kMax) {
379 Error("FindClustersSSD","Too many 1D clusters !");
380 return;
a86176e3 381 }
04366a57 382
d695268b 383 } // if flag5 last 1D cluster added
384
385
386 //------------------------------------------------------
387 // call FindClustersSSD to pair neg and pos 1D clusters
388 // and create recpoints from the crosses
389 // Note1: neg are Pside and pos are Nside!!
390 // Note2: if there are no Pside digits nn=0 (bad strips!!) (same for Nside)
391 //
392 // cout<<nn<<" Pside and "<<np<<" Nside clusters"<<endl;
138df073 393
394 AliITSRecPointContainer* rpc = AliITSRecPointContainer::Instance();
395 if (nn*np > 0) {
396 TClonesArray* clusters = rpc->UncheckedGetClusters(fModule);
397 clusters->Clear();
398 FindClustersSSD(neg, nn, pos, np, clusters);
399 TIter itr(clusters);
400 AliITSRecPoint *irp;
401 while ((irp = (AliITSRecPoint*)itr.Next())) fDetTypeRec->AddRecPoint(*irp);
402 }
d695268b 403 //-----------------------------------------------------
04366a57 404}
405
406
01ef1bd4 407void AliITSClusterFinderV2SSD::RawdataToClusters(AliRawReader* rawReader){
04366a57 408
66b89079 409 //------------------------------------------------------------
04366a57 410 // This function creates ITS clusters from raw data
411 //------------------------------------------------------------
412 rawReader->Reset();
413 AliITSRawStreamSSD inputSSD(rawReader);
01ef1bd4 414 FindClustersSSD(&inputSSD);
04366a57 415
416}
417
138df073 418
01ef1bd4 419void AliITSClusterFinderV2SSD::FindClustersSSD(AliITSRawStreamSSD* input)
04366a57 420{
421 //------------------------------------------------------------
422 // Actual SSD cluster finder for raw data
423 //------------------------------------------------------------
a86176e3 424
01ef1bd4 425 AliITSRecPointContainer* rpc = AliITSRecPointContainer::Instance();
a86176e3 426 static AliITSRecoParam *repa = NULL;
427 if(!repa){
428 repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
429 if(!repa){
ed446fa3 430 repa = AliITSRecoParam::GetHighFluxParam();
a86176e3 431 AliWarning("Using default AliITSRecoParam class");
432 }
433 }
04366a57 434 Int_t nClustersSSD = 0;
138df073 435 const Int_t kNADC = 12;
436 const Int_t kMaxADCClusters = 1000;
437
438 Int_t strips[kNADC][2][kMaxADCClusters][2]; // [ADC],[side],[istrip], [0]=istrip [1]=signal
439 Int_t nStrips[kNADC][2];
440
441 for( int i=0; i<kNADC; i++ ){
442 nStrips[i][0] = 0;
443 nStrips[i][1] = 0;
444 }
445
446 Int_t ddl = -1;
447 Int_t ad = -1;
448
449 //*
450 //* Loop over modules DDL+AD
451 //*
452
04366a57 453 while (kTRUE) {
138df073 454
455 bool next = input->Next();
308b5ea4 456
138df073 457 //*
458 //* Continue if corrupted input
459 //*
460
461 if( (!next)&&(input->flag) ){
462 AliWarning(Form("ITSClustersFinderSSD: Corrupted data: warning from RawReader"));
463 continue;
308b5ea4 464 }
138df073 465
466 Int_t newDDL = input->GetDDL();
467 Int_t newAD = input->GetAD();
468
469 if( next ){
470 if( newDDL<0 || newDDL>15 ){
471 AliWarning(Form("ITSClustersFinderSSD: Corrupted data: wrong DDL number (%d)",newDDL));
472 continue;
473 }
308b5ea4 474
138df073 475 if( newAD<1 || newAD>9 ){
476 AliWarning(Form("ITSClustersFinderSSD: Corrupted data: wrong AD number (%d)",newAD));
477 continue;
478 }
308b5ea4 479 }
42ed6062 480
138df073 481 bool newModule = ( !next || ddl!= newDDL || ad!=newAD );
42ed6062 482
138df073 483 if( newModule && ddl>=0 && ad>=0 ){
bc4dd89a 484
138df073 485 //*
486 //* Reconstruct the previous block of 12 modules --- actual clusterfinder
487 //*
488 //cout<<endl;
489 for( int adc = 0; adc<kNADC; adc++ ){
b42cfa25 490
138df073 491 //* 1D clusterfinder
bc4dd89a 492
138df073 493 Ali1Dcluster clusters1D[2][kMaxADCClusters]; // per ADC, per side
494 Int_t nClusters1D[2] = {0,0};
495 //int nstat[2] = {0,0};
496 fModule = AliITSRawStreamSSD::GetModuleNumber(ddl, (ad - 1) * 12 + adc );
b42cfa25 497
138df073 498 if( fModule<0 ){
499// AliWarning(Form("ITSClustersFinderSSD: Corrupted data: module (ddl %d ad %d adc %d) not found in the map",ddl,ad,adc));
500//CM channels are always present even everything is suppressed
501 continue;
502 }
66b89079 503
504 Int_t layer = 4;
505 if (fModule>fLastSSD1)
506 layer = 5;
a64f9843 507
138df073 508 AliITSCalibrationSSD* cal = (AliITSCalibrationSSD*)fDetTypeRec->GetCalibrationModel(fModule);
509 if( !cal ){
510 AliWarning(Form("ITSClustersFinderSSD: No calibration found for module (ddl %d ad %d adc %d)",ddl,ad,adc));
511 continue;
512 }
308b5ea4 513
138df073 514 Float_t dStrip = 0;
515
516 if( repa->GetUseCosmicRunShiftsSSD()) { // Special condition for 2007/2008 cosmic data
517 dStrip = fgkCosmic2008StripShifts[ddl][ad-1];
518 if (TMath::Abs(dStrip) > 1.5){
519 AliWarning(Form("Indexing error in Cosmic calibration: ddl = %d, dStrip %f\n",ddl,dStrip));
520 dStrip = 0;
521 }
308b5ea4 522 }
b42cfa25 523
138df073 524 for( int side=0; side<=1; side++ ){
525
526 Int_t lab[3]={-2,-2,-2};
527 Float_t q = 0.;
528 Float_t y = 0.;
529 Int_t nDigits = 0;
530 Int_t ostrip = -2;
531 Bool_t snFlag = 0;
66b89079 532
533 Float_t dLorentz = 0;
534 if (side==0) { // P-side is neg clust
535 dLorentz = fLorentzShiftN;
536 }
537 else { // N-side is pos clust
538 dLorentz = fLorentzShiftP;
539 }
b42cfa25 540
138df073 541 Int_t n = nStrips[adc][side];
542 for( int istr = 0; istr<n+1; istr++ ){
b42cfa25 543
138df073 544 bool stripOK = 1;
545 Int_t strip=0;
546 Float_t signal=0.0, noise=0.0, gain=0.0;
308b5ea4 547
138df073 548 if( istr<n ){
549 strip = strips[adc][side][istr][0];
550 signal = strips[adc][side][istr][1];
a86176e3 551
138df073 552 //cout<<"strip "<<adc<<" / "<<side<<": "<<strip<<endl;
553
554 if( cal ){
555 noise = side ?cal->GetNoiseN(strip) :cal->GetNoiseP(strip);
556 gain = side ?cal->GetGainN(strip) :cal->GetGainP(strip);
557 stripOK = ( noise>=1. && signal>=3.0*noise
558 //&& !cal->IsPChannelBad(strip)
559 );
560 }
561 } else stripOK = 0; // end of data
562
563 bool newCluster = ( (abs(strip-ostrip)!=1) || !stripOK );
564
565 if( newCluster ){
566
567 //* Store the previous cluster
568
569 if( nDigits>0 && q>0 && snFlag ){
570
571 if (nClusters1D[side] >= kMaxADCClusters-1 ) {
572 AliWarning("HLT ClustersFinderSSD: Too many 1D clusters !");
573 }else {
574
575 Ali1Dcluster &cluster = clusters1D[side][nClusters1D[side]++];
66b89079 576 cluster.SetY( y / q + dStrip + dLorentz);
138df073 577 cluster.SetQ(q);
578 cluster.SetNd(nDigits);
579 cluster.SetLabels(lab);
580 //cout<<"cluster 1D side "<<side<<": y= "<<y<<" q= "<<q<<" d="<<dStrip<<" Y="<<cluster.GetY()<<endl;
581 //Split suspiciously big cluster
582
583 if( repa->GetUseUnfoldingInClusterFinderSSD()
584 && nDigits > 4 && nDigits < 25
585 ){
66b89079 586 cluster.SetY(y/q + dStrip - 0.25*nDigits + dLorentz);
138df073 587 cluster.SetQ(0.5*q);
588 Ali1Dcluster& cluster2 = clusters1D[side][nClusters1D[side]++];
66b89079 589 cluster2.SetY(y/q + dStrip + 0.25*nDigits + dLorentz);
138df073 590 cluster2.SetQ(0.5*q);
591 cluster2.SetNd(nDigits);
592 cluster2.SetLabels(lab);
593 } // unfolding is on
a86176e3 594 }
308b5ea4 595 }
138df073 596 y = q = 0.;
597 nDigits = 0;
598 snFlag = 0;
599
600 } //* End store the previous cluster
601
602 if( stripOK ){ // add new signal to the cluster
603// signal = (Int_t) (signal * gain); // signal is corrected for gain
604 if( signal>fgkThreshold*noise) snFlag = 1;
605 signal = signal * gain; // signal is corrected for gain
606// if( cal ) signal = (Int_t) cal->ADCToKeV( signal ); // signal is converted in KeV
607 if( cal ) signal = cal->ADCToKeV( signal ); // signal is converted in KeV
608 q += signal; // add digit to current cluster
609 y += strip * signal;
610 nDigits++;
611 //nstat[side]++;
612 ostrip = strip;
a64f9843 613
308b5ea4 614 }
138df073 615 } //* end loop over strips
b42cfa25 616
138df073 617 } //* end loop over ADC sides
308b5ea4 618
a64f9843 619
138df073 620 //* 2D clusterfinder
621 if( nClusters1D[0] && nClusters1D[1] && fModule>=0 ){
622 TClonesArray* clusters = rpc->UncheckedGetClusters(fModule);
623 FindClustersSSD( clusters1D[0], nClusters1D[0], clusters1D[1], nClusters1D[1], clusters);
624 Int_t nClustersn = clusters->GetEntriesFast();
625 nClustersSSD += nClustersn;
308b5ea4 626 }
627
138df073 628 //cout<<"SG: "<<ddl<<" "<<ad<<" "<<adc<<": strips "<<nstat[0]<<"+"<<nstat[1]<<", clusters 1D= "<<nClusters1D[0]<<" + "<<nClusters1D[1]<<", 2D= "<<clusters.size()<<endl;
a64f9843 629
138df073 630 }//* end loop over adc
631
632 }//* end of reconstruction of previous block of 12 modules
633
634 if( newModule ){
635
636 //*
637 //* Clean up arrays and set new module
638 //*
639
640 for( int i=0; i<kNADC; i++ ){
641 nStrips[i][0] = 0;
642 nStrips[i][1] = 0;
643 }
644 ddl = newDDL;
645 ad = newAD;
646 }
647
a64f9843 648
138df073 649 //*
650 //* Exit main loop when there is no more input
651 //*
04366a57 652
138df073 653 if( !next ) break;
654
655 //*
656 //* Fill the current strip information
657 //*
658
659 Int_t adc = input->GetADC();
660 if( adc<0 || adc>=kNADC+2 || (adc>5&&adc<8) ){
661 AliWarning(Form("HLT ClustersFinderSSD: Corrupted data: wrong adc number (%d)", adc));
662 continue;
663 }
a64f9843 664
138df073 665 if( adc>7 ) adc-= 2; // shift ADC numbers 8-13 to 6-11
666
667 Bool_t side = input->GetSideFlag();
668 Int_t strip = input->GetStrip();
669 Int_t signal = input->GetSignal();
670
a86176e3 671
138df073 672 //cout<<"SSD: "<<ddl<<" "<<ad<<" "<<adc<<" "<<side<<" "<<strip<<" : "<<signal<<endl;
04366a57 673
138df073 674 if( strip>767 ){
675 AliWarning(Form("HLT ClustersFinderSSD: Corrupted data: wrong strip number (ddl %d ad %d adc %d side %d, strip %d",
676 ddl, ad, adc, side,strip) );
677 continue;
678 }
679 if (strip < 0) continue;
680
681 int &n = nStrips[adc][side];
682 if( n >0 ){
683 Int_t oldStrip = strips[adc][side][n-1][0];
684
685 if( strip==oldStrip ){
686 AliWarning(Form("HLT ClustersFinderSSD: Corrupted data: duplicated signal: ddl %d ad %d adc %d, side %d, strip %d",
687 ddl, ad, adc, side, strip ));
688 continue;
689 }
690 }
691 strips[adc][side][n][0] = strip;
692 strips[adc][side][n][1] = signal;
693 n++;
3a4139a2 694
138df073 695 //cout<<"SSD: "<<input->GetDDL()<<" "<<input->GetAD()<<" "
696 //<<input->GetADC()<<" "<<input->GetSideFlag()<<" "<<((int)input->GetStrip())<<" "<<strip<<" : "<<input->GetSignal()<<endl;
04366a57 697
138df073 698 } //* End main loop over the input
308b5ea4 699
3b1d8321 700 AliDebug(1,Form("found clusters in ITS SSD: %d", nClustersSSD));
04366a57 701}
702
138df073 703
04366a57 704void AliITSClusterFinderV2SSD::
705FindClustersSSD(Ali1Dcluster* neg, Int_t nn,
706 Ali1Dcluster* pos, Int_t np,
707 TClonesArray *clusters) {
708 //------------------------------------------------------------
709 // Actual SSD cluster finder
710 //------------------------------------------------------------
b4704be3 711
712 const TGeoHMatrix *mT2L=AliITSgeomTGeo::GetTracking2LocalMatrix(fModule);
713
7101948c 714 //---------------------------------------
715 // load recoparam
716 //
717 static AliITSRecoParam *repa = NULL;
718 if(!repa){
719 repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
720 if(!repa){
721 repa = AliITSRecoParam::GetHighFluxParam();
722 AliWarning("Using default AliITSRecoParam class");
723 }
724 }
725
138df073 726// TClonesArray &cl=*clusters;
d036ccd3 727
8be4e1b1 728 AliITSsegmentationSSD *seg = dynamic_cast<AliITSsegmentationSSD*>(fDetTypeRec->GetSegmentationModel(2));
729 if (fModule>fLastSSD1)
730 seg->SetLayer(6);
731 else
732 seg->SetLayer(5);
733
734 Float_t hwSSD = seg->Dx()*1e-4/2;
735 Float_t hlSSD = seg->Dz()*1e-4/2;
736
04366a57 737 Int_t idet=fNdet[fModule];
738 Int_t ncl=0;
d036ccd3 739
04366a57 740 //
8be4e1b1 741 Int_t *cnegative = new Int_t[np];
742 Int_t *cused1 = new Int_t[np];
743 Int_t *negativepair = new Int_t[10*np];
744 Int_t *cpositive = new Int_t[nn];
745 Int_t *cused2 = new Int_t[nn];
746 Int_t *positivepair = new Int_t[10*nn];
747 for (Int_t i=0;i<np;i++) {cnegative[i]=0; cused1[i]=0;}
748 for (Int_t i=0;i<nn;i++) {cpositive[i]=0; cused2[i]=0;}
749 for (Int_t i=0;i<10*np;i++) {negativepair[i]=0;}
750 for (Int_t i=0;i<10*nn;i++) {positivepair[i]=0;}
c157c94e 751
308b5ea4 752 if ((np*nn) > fgPairsSize) {
d036ccd3 753
308b5ea4 754 if (fgPairs) delete [] fgPairs;
755 fgPairsSize = 4*np*nn;
756 fgPairs = new Short_t[fgPairsSize];
c157c94e 757 }
308b5ea4 758 memset(fgPairs,0,sizeof(Short_t)*np*nn);
759
04366a57 760 //
761 // find available pairs
762 //
138df073 763 Int_t ncross = 0;
04366a57 764 for (Int_t i=0; i<np; i++) {
d036ccd3 765 Float_t yp=pos[i].GetY();
a64f9843 766 if ( (pos[i].GetQ()>0) && (pos[i].GetQ()<3) ) continue;
04366a57 767 for (Int_t j=0; j<nn; j++) {
a64f9843 768 if ( (neg[j].GetQ()>0) && (neg[j].GetQ()<3) ) continue;
d036ccd3 769 Float_t yn=neg[j].GetY();
770
8be4e1b1 771 Float_t xt, zt;
772 seg->GetPadCxz(yn, yp, xt, zt);
d695268b 773 //cout<<yn<<" "<<yp<<" "<<xt<<" "<<zt<<endl;
d036ccd3 774
5846520e 775 if (TMath::Abs(xt)<hwSSD)
776 if (TMath::Abs(zt)<hlSSD) {
710f576f 777 Int_t in = i*10+cnegative[i];
778 Int_t ip = j*10+cpositive[j];
779 if ((in < 10*np) && (ip < 10*nn)) {
780 negativepair[in] =j; //index
781 positivepair[ip] =i;
782 cnegative[i]++; //counters
138df073 783 cpositive[j]++;
784 ncross++;
710f576f 785 fgPairs[i*nn+j]=100;
786 }
787 else
788 AliError(Form("Index out of range: ip=%d, in=%d",ip,in));
04366a57 789 }
790 }
791 }
308b5ea4 792
eb595a70 793 if (!ncross) {
794 delete [] cnegative;
795 delete [] cused1;
796 delete [] negativepair;
797 delete [] cpositive;
798 delete [] cused2;
799 delete [] positivepair;
800 return;
801 }
138df073 802//why not to allocate memorey here? if(!clusters) clusters = new TClonesArray("AliITSRecPoint", ncross);
803
5846520e 804 /* //
308b5ea4 805 // try to recover points out of but close to the module boundaries
04366a57 806 //
807 for (Int_t i=0; i<np; i++) {
d036ccd3 808 Float_t yp=pos[i].GetY();
a64f9843 809 if ( (pos[i].GetQ()>0) && (pos[i].GetQ()<3) ) continue;
04366a57 810 for (Int_t j=0; j<nn; j++) {
a64f9843 811 if ( (neg[j].GetQ()>0) && (neg[j].GetQ()<3) ) continue;
308b5ea4 812 // if both 1Dclusters have an other cross continue
04366a57 813 if (cpositive[j]&&cnegative[i]) continue;
8be4e1b1 814 Float_t yn=neg[j].GetY();
d036ccd3 815
8be4e1b1 816 Float_t xt, zt;
817 seg->GetPadCxz(yn, yp, xt, zt);
d036ccd3 818
8be4e1b1 819 if (TMath::Abs(xt)<hwSSD+0.1)
820 if (TMath::Abs(zt)<hlSSD+0.15) {
308b5ea4 821 // tag 1Dcluster (eventually will produce low quality recpoint)
04366a57 822 if (cnegative[i]==0) pos[i].SetNd(100); // not available pair
823 if (cpositive[j]==0) neg[j].SetNd(100); // not available pair
710f576f 824 Int_t in = i*10+cnegative[i];
825 Int_t ip = j*10+cpositive[j];
826 if ((in < 10*np) && (ip < 10*nn)) {
827 negativepair[in] =j; //index
828 positivepair[ip] =i;
829 cnegative[i]++; //counters
830 cpositive[j]++;
831 fgPairs[i*nn+j]=100;
832 }
833 else
834 AliError(Form("Index out of range: ip=%d, in=%d",ip,in));
04366a57 835 }
836 }
837 }
5846520e 838 */
308b5ea4 839
04366a57 840 //
d695268b 841 Float_t lp[6];
04366a57 842 Int_t milab[10];
843 Double_t ratio;
844
b42cfa25 845
a86176e3 846 if(repa->GetUseChargeMatchingInClusterFinderSSD()==kTRUE) {
308b5ea4 847
848
a86176e3 849 //
850 // sign gold tracks
851 //
852 for (Int_t ip=0;ip<np;ip++){
8be4e1b1 853 Float_t xbest=1000,zbest=1000,qbest=0;
a86176e3 854 //
855 // select gold clusters
856 if ( (cnegative[ip]==1) && cpositive[negativepair[10*ip]]==1){
d036ccd3 857 Float_t yp=pos[ip].GetY();
a86176e3 858 Int_t j = negativepair[10*ip];
a64f9843 859
860 if( (pos[ip].GetQ()==0) && (neg[j].GetQ() ==0) ) {
861 // both bad, hence continue;
862 // mark both as used (to avoid recover at the end)
863 cused1[ip]++;
864 cused2[j]++;
865 continue;
866 }
867
a86176e3 868 ratio = (pos[ip].GetQ()-neg[j].GetQ())/(pos[ip].GetQ()+neg[j].GetQ());
d695268b 869 //cout<<"ratio="<<ratio<<endl;
a64f9843 870
871 // charge matching (note that if posQ or negQ is 0 -> ratio=1 and the following condition is met
2069484c 872 if (TMath::Abs(ratio)>0.2) continue; // note: 0.2=3xsigma_ratio calculated in cosmics tests
a64f9843 873
a86176e3 874 //
8be4e1b1 875 Float_t yn=neg[j].GetY();
876
877 Float_t xt, zt;
878 seg->GetPadCxz(yn, yp, xt, zt);
879
880 xbest=xt; zbest=zt;
2069484c 881
2069484c 882
a86176e3 883 qbest=0.5*(pos[ip].GetQ()+neg[j].GetQ());
d695268b 884 if( (pos[ip].GetQ()==0)||(neg[j].GetQ()==0)) qbest*=2; // in case of bad strips on one side keep all charge from the other one
a86176e3 885
a86176e3 886 {
8be4e1b1 887 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
a86176e3 888 mT2L->MasterToLocal(loc,trk);
889 lp[0]=trk[1];
890 lp[1]=trk[2];
00a7cc50 891 }
a86176e3 892 lp[4]=qbest; //Q
893 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
894 for (Int_t ilab=0;ilab<3;ilab++){
895 milab[ilab] = pos[ip].GetLabel(ilab);
896 milab[ilab+3] = neg[j].GetLabel(ilab);
00a7cc50 897 }
04366a57 898 //
a86176e3 899 CheckLabels2(milab);
900 milab[3]=(((ip<<10) + j)<<10) + idet; // pos|neg|det
901 Int_t info[3] = {pos[ip].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
d695268b 902
7eb157d7 903 lp[2]=4.968e-06; // 0.00223*0.00223; //SigmaY2
904 lp[3]=0.012; // 0.110*0.110; //SigmaZ2
d695268b 905 // out-of-diagonal element of covariance matrix
906 if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
907 else if ( (info[0]>1) && (info[1]>1) ) {
7eb157d7 908 lp[2]=2.63e-06; // 0.0016*0.0016; //SigmaY2
909 lp[3]=0.0065; // 0.08*0.08; //SigmaZ2
910 lp[5]=-6.48e-05;
d695268b 911 }
912 else {
7eb157d7 913 lp[2]=4.80e-06; // 0.00219*0.00219
914 lp[3]=0.0093; // 0.0964*0.0964;
915 if (info[0]==1) {
916 lp[5]=-0.00014;
917 }
918 else {
919 lp[2]=2.79e-06; // 0.0017*0.0017;
920 lp[3]=0.00935; // 0.967*0.967;
921 lp[5]=-4.32e-05;
922 }
d695268b 923 }
924
a86176e3 925 AliITSRecPoint * cl2;
138df073 926 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
a86176e3 927
138df073 928 cl2->SetChargeRatio(ratio);
929 cl2->SetType(1);
930 fgPairs[ip*nn+j]=1;
a64f9843 931
138df073 932 if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
933 cl2->SetType(2);
934 fgPairs[ip*nn+j]=2;
935 }
a64f9843 936
138df073 937 if(pos[ip].GetQ()==0) cl2->SetType(3);
938 if(neg[j].GetQ()==0) cl2->SetType(4);
a64f9843 939
138df073 940 cused1[ip]++;
941 cused2[j]++;
a64f9843 942
138df073 943 ncl++;
a86176e3 944 }
945 }
946
947 for (Int_t ip=0;ip<np;ip++){
8be4e1b1 948 Float_t xbest=1000,zbest=1000,qbest=0;
a86176e3 949 //
950 //
951 // select "silber" cluster
952 if ( cnegative[ip]==1 && cpositive[negativepair[10*ip]]==2){
953 Int_t in = negativepair[10*ip];
954 Int_t ip2 = positivepair[10*in];
955 if (ip2==ip) ip2 = positivepair[10*in+1];
956 Float_t pcharge = pos[ip].GetQ()+pos[ip2].GetQ();
a64f9843 957
d695268b 958
959
960 ratio = (pcharge-neg[in].GetQ())/(pcharge+neg[in].GetQ());
961 if ( (TMath::Abs(ratio)<0.2) && (pcharge!=0) ) {
962 //if ( (TMath::Abs(pcharge-neg[in].GetQ())<30) && (pcharge!=0) ) { //
a64f9843 963
a86176e3 964 //
965 // add first pair
a64f9843 966 if ( (fgPairs[ip*nn+in]==100)&&(pos[ip].GetQ() ) ) { //
967
d036ccd3 968 Float_t yp=pos[ip].GetY();
8be4e1b1 969 Float_t yn=neg[in].GetY();
970
971 Float_t xt, zt;
972 seg->GetPadCxz(yn, yp, xt, zt);
973
974 xbest=xt; zbest=zt;
2069484c 975
a86176e3 976 qbest =pos[ip].GetQ();
8be4e1b1 977 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
a64f9843 978 mT2L->MasterToLocal(loc,trk);
979 lp[0]=trk[1];
980 lp[1]=trk[2];
981
a86176e3 982 lp[4]=qbest; //Q
983 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
984 for (Int_t ilab=0;ilab<3;ilab++){
985 milab[ilab] = pos[ip].GetLabel(ilab);
986 milab[ilab+3] = neg[in].GetLabel(ilab);
987 }
988 //
989 CheckLabels2(milab);
990 ratio = (pos[ip].GetQ()-neg[in].GetQ())/(pos[ip].GetQ()+neg[in].GetQ());
991 milab[3]=(((ip<<10) + in)<<10) + idet; // pos|neg|det
992 Int_t info[3] = {pos[ip].GetNd(),neg[in].GetNd(),fNlayer[fModule]};
993
7eb157d7 994 lp[2]=4.968e-06; // 0.00223*0.00223; //SigmaY2
995 lp[3]=0.012; // 0.110*0.110; //SigmaZ2
d695268b 996 // out-of-diagonal element of covariance matrix
997 if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
998 else if ( (info[0]>1) && (info[1]>1) ) {
7eb157d7 999 lp[2]=2.63e-06; // 0.0016*0.0016; //SigmaY2
1000 lp[3]=0.0065; // 0.08*0.08; //SigmaZ2
1001 lp[5]=-6.48e-05;
d695268b 1002 }
1003 else {
7eb157d7 1004 lp[2]=4.80e-06; // 0.00219*0.00219
1005 lp[3]=0.0093; // 0.0964*0.0964;
1006 if (info[0]==1) {
1007 lp[5]=-0.00014;
1008 }
1009 else {
1010 lp[2]=2.79e-06; // 0.0017*0.0017;
1011 lp[3]=0.00935; // 0.967*0.967;
1012 lp[5]=-4.32e-05;
1013 }
d695268b 1014 }
1015
7eb157d7 1016 AliITSRecPoint * cl2;
138df073 1017 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
a86176e3 1018 cl2->SetChargeRatio(ratio);
1019 cl2->SetType(5);
1020 fgPairs[ip*nn+in] = 5;
1021 if ((pos[ip].GetNd()+neg[in].GetNd())>6){ //multi cluster
1022 cl2->SetType(6);
1023 fgPairs[ip*nn+in] = 6;
1024 }
a86176e3 1025 ncl++;
04366a57 1026 }
04366a57 1027
a64f9843 1028
04366a57 1029 //
a86176e3 1030 // add second pair
00a7cc50 1031
a86176e3 1032 // if (!(cused1[ip2] || cused2[in])){ //
a64f9843 1033 if ( (fgPairs[ip2*nn+in]==100) && (pos[ip2].GetQ()) ) {
1034
d036ccd3 1035 Float_t yp=pos[ip2].GetY();
8be4e1b1 1036 Float_t yn=neg[in].GetY();
1037
1038 Float_t xt, zt;
1039 seg->GetPadCxz(yn, yp, xt, zt);
1040
1041 xbest=xt; zbest=zt;
2069484c 1042
a86176e3 1043 qbest =pos[ip2].GetQ();
a64f9843 1044
8be4e1b1 1045 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
a64f9843 1046 mT2L->MasterToLocal(loc,trk);
1047 lp[0]=trk[1];
1048 lp[1]=trk[2];
1049
a86176e3 1050 lp[4]=qbest; //Q
1051 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1052 for (Int_t ilab=0;ilab<3;ilab++){
1053 milab[ilab] = pos[ip2].GetLabel(ilab);
1054 milab[ilab+3] = neg[in].GetLabel(ilab);
00a7cc50 1055 }
a86176e3 1056 //
1057 CheckLabels2(milab);
1058 ratio = (pos[ip2].GetQ()-neg[in].GetQ())/(pos[ip2].GetQ()+neg[in].GetQ());
1059 milab[3]=(((ip2<<10) + in)<<10) + idet; // pos|neg|det
1060 Int_t info[3] = {pos[ip2].GetNd(),neg[in].GetNd(),fNlayer[fModule]};
308b5ea4 1061
7eb157d7 1062 lp[2]=4.968e-06; // 0.00223*0.00223; //SigmaY2
1063 lp[3]=0.012; // 0.110*0.110; //SigmaZ2
d695268b 1064 // out-of-diagonal element of covariance matrix
1065 if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
1066 else if ( (info[0]>1) && (info[1]>1) ) {
7eb157d7 1067 lp[2]=2.63e-06; // 0.0016*0.0016; //SigmaY2
1068 lp[3]=0.0065; // 0.08*0.08; //SigmaZ2
1069 lp[5]=-6.48e-05;
d695268b 1070 }
1071 else {
7eb157d7 1072 lp[2]=4.80e-06; // 0.00219*0.00219
1073 lp[3]=0.0093; // 0.0964*0.0964;
1074 if (info[0]==1) {
1075 lp[5]=-0.00014;
1076 }
1077 else {
1078 lp[2]=2.79e-06; // 0.0017*0.0017;
1079 lp[3]=0.00935; // 0.967*0.967;
1080 lp[5]=-4.32e-05;
1081 }
d695268b 1082 }
1083
a86176e3 1084 AliITSRecPoint * cl2;
138df073 1085 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
a86176e3 1086
a86176e3 1087 cl2->SetChargeRatio(ratio);
1088 cl2->SetType(5);
1089 fgPairs[ip2*nn+in] =5;
1090 if ((pos[ip2].GetNd()+neg[in].GetNd())>6){ //multi cluster
1091 cl2->SetType(6);
1092 fgPairs[ip2*nn+in] =6;
1093 }
a86176e3 1094 ncl++;
a64f9843 1095 }
1096
a86176e3 1097 cused1[ip]++;
1098 cused1[ip2]++;
1099 cused2[in]++;
a64f9843 1100
1101 } // charge matching condition
1102
1103 } // 2 Pside cross 1 Nside
1104 } // loop over Pside clusters
a86176e3 1105
a64f9843 1106
1107
1108 //
1109 for (Int_t jn=0;jn<nn;jn++){
1110 if (cused2[jn]) continue;
8be4e1b1 1111 Float_t xbest=1000,zbest=1000,qbest=0;
a64f9843 1112 // select "silber" cluster
1113 if ( cpositive[jn]==1 && cnegative[positivepair[10*jn]]==2){
1114 Int_t ip = positivepair[10*jn];
1115 Int_t jn2 = negativepair[10*ip];
1116 if (jn2==jn) jn2 = negativepair[10*ip+1];
1117 Float_t pcharge = neg[jn].GetQ()+neg[jn2].GetQ();
04366a57 1118 //
a64f9843 1119
d695268b 1120
1121 ratio = (pcharge-pos[ip].GetQ())/(pcharge+pos[ip].GetQ());
1122 if ( (TMath::Abs(ratio)<0.2) && (pcharge!=0) ) {
1123
1124 /*
2069484c 1125 if ( (TMath::Abs(pcharge-pos[ip].GetQ())<30) && // charge matching
a64f9843 1126 (pcharge!=0) ) { // reject combinations of bad strips
d695268b 1127 */
1128
1129
a64f9843 1130 //
1131 // add first pair
1132 // if (!(cused1[ip]||cused2[jn])){
1133 if ( (fgPairs[ip*nn+jn]==100) && (neg[jn].GetQ()) ) { //
1134
d036ccd3 1135 Float_t yn=neg[jn].GetY();
8be4e1b1 1136 Float_t yp=pos[ip].GetY();
2069484c 1137
8be4e1b1 1138 Float_t xt, zt;
1139 seg->GetPadCxz(yn, yp, xt, zt);
1140
1141 xbest=xt; zbest=zt;
2069484c 1142
a64f9843 1143 qbest =neg[jn].GetQ();
d036ccd3 1144
a64f9843 1145 {
8be4e1b1 1146 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
a64f9843 1147 mT2L->MasterToLocal(loc,trk);
1148 lp[0]=trk[1];
1149 lp[1]=trk[2];
b4704be3 1150 }
04366a57 1151
1152 lp[4]=qbest; //Q
1153 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1154 for (Int_t ilab=0;ilab<3;ilab++){
1155 milab[ilab] = pos[ip].GetLabel(ilab);
1156 milab[ilab+3] = neg[jn].GetLabel(ilab);
1157 }
1158 //
1159 CheckLabels2(milab);
1160 ratio = (pos[ip].GetQ()-neg[jn].GetQ())/(pos[ip].GetQ()+neg[jn].GetQ());
1161 milab[3]=(((ip<<10) + jn)<<10) + idet; // pos|neg|det
1162 Int_t info[3] = {pos[ip].GetNd(),neg[jn].GetNd(),fNlayer[fModule]};
1163
7eb157d7 1164 lp[2]=4.968e-06; // 0.00223*0.00223; //SigmaY2
1165 lp[3]=0.012; // 0.110*0.110; //SigmaZ2
d695268b 1166 // out-of-diagonal element of covariance matrix
1167 if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
1168 else if ( (info[0]>1) && (info[1]>1) ) {
7eb157d7 1169 lp[2]=2.63e-06; // 0.0016*0.0016; //SigmaY2
1170 lp[3]=0.0065; // 0.08*0.08; //SigmaZ2
1171 lp[5]=-6.48e-05;
d695268b 1172 }
1173 else {
7eb157d7 1174 lp[2]=4.80e-06; // 0.00219*0.00219
1175 lp[3]=0.0093; // 0.0964*0.0964;
1176 if (info[0]==1) {
1177 lp[5]=-0.00014;
1178 }
1179 else {
1180 lp[2]=2.79e-06; // 0.0017*0.0017;
1181 lp[3]=0.00935; // 0.967*0.967;
1182 lp[5]=-4.32e-05;
1183 }
d695268b 1184 }
1185
00a7cc50 1186 AliITSRecPoint * cl2;
138df073 1187 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
308b5ea4 1188
00a7cc50 1189 cl2->SetChargeRatio(ratio);
1190 cl2->SetType(7);
308b5ea4 1191 fgPairs[ip*nn+jn] =7;
00a7cc50 1192 if ((pos[ip].GetNd()+neg[jn].GetNd())>6){ //multi cluster
1193 cl2->SetType(8);
308b5ea4 1194 fgPairs[ip*nn+jn]=8;
00a7cc50 1195 }
04366a57 1196 ncl++;
04366a57 1197 }
1198 //
1199 // add second pair
1200 // if (!(cused1[ip]||cused2[jn2])){
a64f9843 1201 if ( (fgPairs[ip*nn+jn2]==100)&&(neg[jn2].GetQ() ) ) { //
1202
d036ccd3 1203 Float_t yn=neg[jn2].GetY();
1204 Double_t yp=pos[ip].GetY();
2069484c 1205
8be4e1b1 1206 Float_t xt, zt;
1207 seg->GetPadCxz(yn, yp, xt, zt);
1208
1209 xbest=xt; zbest=zt;
2069484c 1210
04366a57 1211 qbest =neg[jn2].GetQ();
d036ccd3 1212
b4704be3 1213 {
8be4e1b1 1214 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
b4704be3 1215 mT2L->MasterToLocal(loc,trk);
1216 lp[0]=trk[1];
1217 lp[1]=trk[2];
1218 }
d695268b 1219
04366a57 1220 lp[4]=qbest; //Q
1221 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1222 for (Int_t ilab=0;ilab<3;ilab++){
1223 milab[ilab] = pos[ip].GetLabel(ilab);
1224 milab[ilab+3] = neg[jn2].GetLabel(ilab);
1225 }
1226 //
1227 CheckLabels2(milab);
1228 ratio = (pos[ip].GetQ()-neg[jn2].GetQ())/(pos[ip].GetQ()+neg[jn2].GetQ());
1229 milab[3]=(((ip<<10) + jn2)<<10) + idet; // pos|neg|det
1230 Int_t info[3] = {pos[ip].GetNd(),neg[jn2].GetNd(),fNlayer[fModule]};
d695268b 1231
7eb157d7 1232 lp[2]=4.968e-06; // 0.00223*0.00223; //SigmaY2
1233 lp[3]=0.012; // 0.110*0.110; //SigmaZ2
d695268b 1234 // out-of-diagonal element of covariance matrix
1235 if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
1236 else if ( (info[0]>1) && (info[1]>1) ) {
7eb157d7 1237 lp[2]=2.63e-06; // 0.0016*0.0016; //SigmaY2
1238 lp[3]=0.0065; // 0.08*0.08; //SigmaZ2
1239 lp[5]=-6.48e-05;
d695268b 1240 }
1241 else {
7eb157d7 1242 lp[2]=4.80e-06; // 0.00219*0.00219
1243 lp[3]=0.0093; // 0.0964*0.0964;
1244 if (info[0]==1) {
1245 lp[5]=-0.00014;
1246 }
1247 else {
1248 lp[2]=2.79e-06; // 0.0017*0.0017;
1249 lp[3]=0.00935; // 0.967*0.967;
1250 lp[5]=-4.32e-05;
1251 }
d695268b 1252 }
1253
00a7cc50 1254 AliITSRecPoint * cl2;
138df073 1255 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
308b5ea4 1256
308b5ea4 1257
00a7cc50 1258 cl2->SetChargeRatio(ratio);
308b5ea4 1259 fgPairs[ip*nn+jn2]=7;
00a7cc50 1260 cl2->SetType(7);
1261 if ((pos[ip].GetNd()+neg[jn2].GetNd())>6){ //multi cluster
1262 cl2->SetType(8);
308b5ea4 1263 fgPairs[ip*nn+jn2]=8;
00a7cc50 1264 }
04366a57 1265 ncl++;
04366a57 1266 }
1267 cused1[ip]++;
1268 cused2[jn]++;
1269 cused2[jn2]++;
308b5ea4 1270
a64f9843 1271 } // charge matching condition
1272
1273 } // 2 Nside cross 1 Pside
1274 } // loop over Pside clusters
1275
1276
1277
1278 for (Int_t ip=0;ip<np;ip++){
d695268b 1279
1280 if(cused1[ip]) continue;
1281
1282
8be4e1b1 1283 Float_t xbest=1000,zbest=1000,qbest=0;
04366a57 1284 //
a64f9843 1285 // 2x2 clusters
04366a57 1286 //
d695268b 1287 if ( (cnegative[ip]==2) && cpositive[negativepair[10*ip]]==2){
1288 Float_t minchargediff =4.;
1289 Float_t minchargeratio =0.2;
1290
1291 Int_t j=-1;
1292 for (Int_t di=0;di<cnegative[ip];di++){
1293 Int_t jc = negativepair[ip*10+di];
1294 Float_t chargedif = pos[ip].GetQ()-neg[jc].GetQ();
1295 ratio = (pos[ip].GetQ()-neg[jc].GetQ())/(pos[ip].GetQ()+neg[jc].GetQ());
1296 //if (TMath::Abs(chargedif)<minchargediff){
1297 if (TMath::Abs(ratio)<0.2){
1298 j =jc;
1299 minchargediff = TMath::Abs(chargedif);
1300 minchargeratio = TMath::Abs(ratio);
1301 }
1302 }
1303 if (j<0) continue; // not proper cluster
1304
1305
1306 Int_t count =0;
1307 for (Int_t di=0;di<cnegative[ip];di++){
1308 Int_t jc = negativepair[ip*10+di];
1309 Float_t chargedif = pos[ip].GetQ()-neg[jc].GetQ();
1310 if (TMath::Abs(chargedif)<minchargediff+3.) count++;
1311 }
1312 if (count>1) continue; // more than one "proper" cluster for positive
1313 //
1314
1315 count =0;
1316 for (Int_t dj=0;dj<cpositive[j];dj++){
1317 Int_t ic = positivepair[j*10+dj];
1318 Float_t chargedif = pos[ic].GetQ()-neg[j].GetQ();
1319 if (TMath::Abs(chargedif)<minchargediff+3.) count++;
1320 }
1321 if (count>1) continue; // more than one "proper" cluster for negative
1322
1323 Int_t jp = 0;
1324
1325 count =0;
1326 for (Int_t dj=0;dj<cnegative[jp];dj++){
1327 Int_t ic = positivepair[jp*10+dj];
1328 Float_t chargedif = pos[ic].GetQ()-neg[jp].GetQ();
1329 if (TMath::Abs(chargedif)<minchargediff+4.) count++;
1330 }
1331 if (count>1) continue;
1332 if (fgPairs[ip*nn+j]<100) continue;
1333 //
1334
1335
1336
1337 //almost gold clusters
1338 Float_t yp=pos[ip].GetY();
1339 Float_t yn=neg[j].GetY();
1340 Float_t xt, zt;
1341 seg->GetPadCxz(yn, yp, xt, zt);
1342 xbest=xt; zbest=zt;
1343 qbest=0.5*(pos[ip].GetQ()+neg[j].GetQ());
1344 {
1345 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
1346 mT2L->MasterToLocal(loc,trk);
1347 lp[0]=trk[1];
1348 lp[1]=trk[2];
1349 }
1350 lp[4]=qbest; //Q
1351 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1352 for (Int_t ilab=0;ilab<3;ilab++){
1353 milab[ilab] = pos[ip].GetLabel(ilab);
1354 milab[ilab+3] = neg[j].GetLabel(ilab);
1355 }
1356 //
1357 CheckLabels2(milab);
1358 if ((neg[j].GetQ()==0)&&(pos[ip].GetQ()==0)) continue; // reject crosses of bad strips!!
1359 ratio = (pos[ip].GetQ()-neg[j].GetQ())/(pos[ip].GetQ()+neg[j].GetQ());
1360 milab[3]=(((ip<<10) + j)<<10) + idet; // pos|neg|det
1361 Int_t info[3] = {pos[ip].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
1362
7eb157d7 1363 lp[2]=4.968e-06; // 0.00223*0.00223; //SigmaY2
1364 lp[3]=0.012; // 0.110*0.110; //SigmaZ2
d695268b 1365 // out-of-diagonal element of covariance matrix
1366 if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
1367 else if ( (info[0]>1) && (info[1]>1) ) {
7eb157d7 1368 lp[2]=2.63e-06; // 0.0016*0.0016; //SigmaY2
1369 lp[3]=0.0065; // 0.08*0.08; //SigmaZ2
1370 lp[5]=-6.48e-05;
d695268b 1371 }
1372 else {
7eb157d7 1373 lp[2]=4.80e-06; // 0.00219*0.00219
1374 lp[3]=0.0093; // 0.0964*0.0964;
1375 if (info[0]==1) {
1376 lp[5]=-0.00014;
1377 }
1378 else {
1379 lp[2]=2.79e-06; // 0.0017*0.0017;
1380 lp[3]=0.00935; // 0.967*0.967;
1381 lp[5]=-4.32e-05;
1382 }
d695268b 1383 }
1384
1385 AliITSRecPoint * cl2;
138df073 1386 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
d695268b 1387
1388 cl2->SetChargeRatio(ratio);
1389 cl2->SetType(10);
1390 fgPairs[ip*nn+j]=10;
1391 if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
1392 cl2->SetType(11);
1393 fgPairs[ip*nn+j]=11;
1394 }
1395 cused1[ip]++;
1396 cused2[j]++;
d695268b 1397 ncl++;
1398
1399 } // 2X2
1400 } // loop over Pside 1Dclusters
1401
1402
1403
1404 for (Int_t ip=0;ip<np;ip++){
1405
1406 if(cused1[ip]) continue;
1407
1408
1409 Float_t xbest=1000,zbest=1000,qbest=0;
1410 //
1411 // manyxmany clusters
1412 //
a64f9843 1413 if ( (cnegative[ip]<5) && cpositive[negativepair[10*ip]]<5){
1414 Float_t minchargediff =4.;
1415 Int_t j=-1;
1416 for (Int_t di=0;di<cnegative[ip];di++){
1417 Int_t jc = negativepair[ip*10+di];
1418 Float_t chargedif = pos[ip].GetQ()-neg[jc].GetQ();
1419 if (TMath::Abs(chargedif)<minchargediff){
1420 j =jc;
1421 minchargediff = TMath::Abs(chargedif);
1422 }
00a7cc50 1423 }
a64f9843 1424 if (j<0) continue; // not proper cluster
1425
1426 Int_t count =0;
1427 for (Int_t di=0;di<cnegative[ip];di++){
1428 Int_t jc = negativepair[ip*10+di];
1429 Float_t chargedif = pos[ip].GetQ()-neg[jc].GetQ();
1430 if (TMath::Abs(chargedif)<minchargediff+3.) count++;
00a7cc50 1431 }
a64f9843 1432 if (count>1) continue; // more than one "proper" cluster for positive
1433 //
00a7cc50 1434
a64f9843 1435 count =0;
1436 for (Int_t dj=0;dj<cpositive[j];dj++){
1437 Int_t ic = positivepair[j*10+dj];
1438 Float_t chargedif = pos[ic].GetQ()-neg[j].GetQ();
1439 if (TMath::Abs(chargedif)<minchargediff+3.) count++;
1440 }
1441 if (count>1) continue; // more than one "proper" cluster for negative
1442
1443 Int_t jp = 0;
1444
1445 count =0;
1446 for (Int_t dj=0;dj<cnegative[jp];dj++){
1447 Int_t ic = positivepair[jp*10+dj];
1448 Float_t chargedif = pos[ic].GetQ()-neg[jp].GetQ();
1449 if (TMath::Abs(chargedif)<minchargediff+4.) count++;
1450 }
1451 if (count>1) continue;
1452 if (fgPairs[ip*nn+j]<100) continue;
1453 //
1454
1455 //almost gold clusters
d036ccd3 1456 Float_t yp=pos[ip].GetY();
1457 Float_t yn=neg[j].GetY();
1458
8be4e1b1 1459
1460 Float_t xt, zt;
1461 seg->GetPadCxz(yn, yp, xt, zt);
1462
1463 xbest=xt; zbest=zt;
1464
a64f9843 1465 qbest=0.5*(pos[ip].GetQ()+neg[j].GetQ());
d036ccd3 1466
a64f9843 1467 {
8be4e1b1 1468 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
a64f9843 1469 mT2L->MasterToLocal(loc,trk);
1470 lp[0]=trk[1];
1471 lp[1]=trk[2];
1472 }
a64f9843 1473 lp[4]=qbest; //Q
1474 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1475 for (Int_t ilab=0;ilab<3;ilab++){
1476 milab[ilab] = pos[ip].GetLabel(ilab);
1477 milab[ilab+3] = neg[j].GetLabel(ilab);
1478 }
1479 //
1480 CheckLabels2(milab);
db6e54cd 1481 if ((neg[j].GetQ()==0)&&(pos[ip].GetQ()==0)) continue; // reject crosses of bad strips!!
a64f9843 1482 ratio = (pos[ip].GetQ()-neg[j].GetQ())/(pos[ip].GetQ()+neg[j].GetQ());
1483 milab[3]=(((ip<<10) + j)<<10) + idet; // pos|neg|det
1484 Int_t info[3] = {pos[ip].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
d695268b 1485
7eb157d7 1486 lp[2]=4.968e-06; // 0.00223*0.00223; //SigmaY2
1487 lp[3]=0.012; // 0.110*0.110; //SigmaZ2
d695268b 1488 // out-of-diagonal element of covariance matrix
1489 if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
1490 else if ( (info[0]>1) && (info[1]>1) ) {
7eb157d7 1491 lp[2]=2.63e-06; // 0.0016*0.0016; //SigmaY2
1492 lp[3]=0.0065; // 0.08*0.08; //SigmaZ2
1493 lp[5]=-6.48e-05;
d695268b 1494 }
1495 else {
7eb157d7 1496 lp[2]=4.80e-06; // 0.00219*0.00219
1497 lp[3]=0.0093; // 0.0964*0.0964;
1498 if (info[0]==1) {
1499 lp[5]=-0.00014;
1500 }
1501 else {
1502 lp[2]=2.79e-06; // 0.0017*0.0017;
1503 lp[3]=0.00935; // 0.967*0.967;
1504 lp[5]=-4.32e-05;
1505 }
d695268b 1506 }
1507
a64f9843 1508 AliITSRecPoint * cl2;
138df073 1509 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
d036ccd3 1510
a64f9843 1511 cl2->SetChargeRatio(ratio);
d695268b 1512 cl2->SetType(12);
1513 fgPairs[ip*nn+j]=12;
a64f9843 1514 if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
d695268b 1515 cl2->SetType(13);
1516 fgPairs[ip*nn+j]=13;
a64f9843 1517 }
1518 cused1[ip]++;
1519 cused2[j]++;
a64f9843 1520 ncl++;
1521
1522 } // manyXmany
1523 } // loop over Pside 1Dclusters
1524
a64f9843 1525 } // use charge matching
1526
04366a57 1527
a64f9843 1528 // recover all the other crosses
04366a57 1529 //
1530 for (Int_t i=0; i<np; i++) {
8be4e1b1 1531 Float_t xbest=1000,zbest=1000,qbest=0;
d036ccd3 1532 Float_t yp=pos[i].GetY();
a64f9843 1533 if ((pos[i].GetQ()>0)&&(pos[i].GetQ()<3)) continue;
04366a57 1534 for (Int_t j=0; j<nn; j++) {
1535 // for (Int_t di = 0;di<cpositive[i];di++){
1536 // Int_t j = negativepair[10*i+di];
a64f9843 1537 if ((neg[j].GetQ()>0)&&(neg[j].GetQ()<3)) continue;
1538
1539 if ((neg[j].GetQ()==0)&&(pos[i].GetQ()==0)) continue; // reject crosses of bad strips!!
1540
04366a57 1541 if (cused2[j]||cused1[i]) continue;
308b5ea4 1542 if (fgPairs[i*nn+j]>0 &&fgPairs[i*nn+j]<100) continue;
04366a57 1543 ratio = (pos[i].GetQ()-neg[j].GetQ())/(pos[i].GetQ()+neg[j].GetQ());
d036ccd3 1544 Float_t yn=neg[j].GetY();
1545
8be4e1b1 1546 Float_t xt, zt;
1547 seg->GetPadCxz(yn, yp, xt, zt);
d036ccd3 1548
5846520e 1549 if (TMath::Abs(xt)<hwSSD)
1550 if (TMath::Abs(zt)<hlSSD) {
8be4e1b1 1551 xbest=xt; zbest=zt;
1552
04366a57 1553 qbest=0.5*(pos[i].GetQ()+neg[j].GetQ());
d036ccd3 1554
b4704be3 1555 {
8be4e1b1 1556 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
b4704be3 1557 mT2L->MasterToLocal(loc,trk);
1558 lp[0]=trk[1];
1559 lp[1]=trk[2];
1560 }
04366a57 1561 lp[4]=qbest; //Q
1562 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1563 for (Int_t ilab=0;ilab<3;ilab++){
1564 milab[ilab] = pos[i].GetLabel(ilab);
1565 milab[ilab+3] = neg[j].GetLabel(ilab);
1566 }
1567 //
1568 CheckLabels2(milab);
1569 milab[3]=(((i<<10) + j)<<10) + idet; // pos|neg|det
1570 Int_t info[3] = {pos[i].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
d695268b 1571
7eb157d7 1572 lp[2]=4.968e-06; // 0.00223*0.00223; //SigmaY2
1573 lp[3]=0.012; // 0.110*0.110; //SigmaZ2
d695268b 1574 // out-of-diagonal element of covariance matrix
1575 if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
1576 else if ( (info[0]>1) && (info[1]>1) ) {
7eb157d7 1577 lp[2]=2.63e-06; // 0.0016*0.0016; //SigmaY2
1578 lp[3]=0.0065; // 0.08*0.08; //SigmaZ2
1579 lp[5]=-6.48e-05;
d695268b 1580 }
1581 else {
7eb157d7 1582 lp[2]=4.80e-06; // 0.00219*0.00219
1583 lp[3]=0.0093; // 0.0964*0.0964;
1584 if (info[0]==1) {
1585 lp[5]=-0.00014;
1586 }
1587 else {
1588 lp[2]=2.79e-06; // 0.0017*0.0017;
1589 lp[3]=0.00935; // 0.967*0.967;
1590 lp[5]=-4.32e-05;
1591 }
d695268b 1592 }
1593
00a7cc50 1594 AliITSRecPoint * cl2;
138df073 1595 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
308b5ea4 1596
00a7cc50 1597 cl2->SetChargeRatio(ratio);
1598 cl2->SetType(100+cpositive[j]+cnegative[i]);
a64f9843 1599
1600 if(pos[i].GetQ()==0) cl2->SetType(200+cpositive[j]+cnegative[i]);
1601 if(neg[j].GetQ()==0) cl2->SetType(300+cpositive[j]+cnegative[i]);
04366a57 1602 ncl++;
04366a57 1603 }
1604 }
1605 }
d695268b 1606
1607
d695268b 1608
7101948c 1609 if(repa->GetUseBadChannelsInClusterFinderSSD()==kTRUE) {
1610
1611 //---------------------------------------------------------
1612 // recover crosses of good 1D clusters with bad strips on the other side
1613 // Note1: at first iteration skip modules with a bad side (or almost), (would produce too many fake!)
1614 // Note2: for modules with a bad side see below
1615
1616 AliITSCalibrationSSD* cal = (AliITSCalibrationSSD*)GetResp(fModule);
1617 Int_t countPbad=0, countNbad=0;
1618 for(Int_t ib=0; ib<768; ib++) {
1619 if(cal->IsPChannelBad(ib)) countPbad++;
1620 if(cal->IsNChannelBad(ib)) countNbad++;
1621 }
1622 // AliInfo(Form("module %d has %d P- and %d N-bad strips",fModule,countPbad,countNbad));
d695268b 1623
7101948c 1624 if( (countPbad<100) && (countNbad<100) ) { // no bad side!!
d695268b 1625
7101948c 1626 for (Int_t i=0; i<np; i++) { // loop over Nside 1Dclusters with no crosses
1627 if(cnegative[i]) continue; // if intersecting Pside clusters continue;
d695268b 1628
7101948c 1629 // for(Int_t ib=0; ib<768; ib++) { // loop over all Pstrips
1630 for(Int_t ib=15; ib<753; ib++) { // loop over all Pstrips
d695268b 1631
7101948c 1632 if(cal->IsPChannelBad(ib)) { // check if strips is bad
1633 Float_t yN=pos[i].GetY();
1634 Float_t xt, zt;
1635 seg->GetPadCxz(1.*ib, yN, xt, zt);
d695268b 1636
7101948c 1637 //----------
1638 // bad Pstrip is crossing the Nside 1Dcluster -> create recpoint
1639 //
5846520e 1640 if ( (TMath::Abs(xt)<hwSSD) && (TMath::Abs(zt)<hlSSD) ) {
7101948c 1641 Double_t loc[3]={xt,0.,zt},trk[3]={0.,0.,0.};
1642 mT2L->MasterToLocal(loc,trk);
1643 lp[0]=trk[1];
1644 lp[1]=trk[2];
1645 lp[4]=pos[i].GetQ(); //Q
1646 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1647 for (Int_t ilab=0;ilab<3;ilab++) milab[ilab] = pos[i].GetLabel(ilab);
1648 CheckLabels2(milab);
1649 milab[3]=( (i<<10) << 10 ) + idet; // pos|neg|det
1650 Int_t info[3] = {pos[i].GetNd(),0,fNlayer[fModule]};
1651
7eb157d7 1652 lp[2]=4.968e-06; // 0.00223*0.00223; //SigmaY2
1653 lp[3]=0.012; // 0.110*0.110; //SigmaZ2
7101948c 1654 lp[5]=-0.00012; // out-of-diagonal element of covariance matrix
7eb157d7 1655 if (info[0]>1) {
1656 lp[2]=4.80e-06;
1657 lp[3]=0.0093;
1658 lp[5]=0.00014;
1659 }
1660
7101948c 1661 AliITSRecPoint * cl2;
138df073 1662 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
7101948c 1663 cl2->SetChargeRatio(1.);
d695268b 1664 cl2->SetType(50);
7101948c 1665 ncl++;
1666 } // cross is within the detector
1667 //
1668 //--------------
1669
1670 } // bad Pstrip
d695268b 1671
7101948c 1672 } // end loop over Pstrips
d695268b 1673
7101948c 1674 } // end loop over Nside 1D clusters
d695268b 1675
7101948c 1676 for (Int_t j=0; j<nn; j++) { // loop over Pside 1D clusters with no crosses
1677 if(cpositive[j]) continue;
1678
1679 // for(Int_t ib=0; ib<768; ib++) { // loop over all Nside strips
1680 for(Int_t ib=15; ib<753; ib++) { // loop over all Nside strips
1681
1682 if(cal->IsNChannelBad(ib)) { // check if strip is bad
1683 Float_t yP=neg[j].GetY();
1684 Float_t xt, zt;
1685 seg->GetPadCxz(yP, 1.*ib, xt, zt);
1686
1687 //----------
1688 // bad Nstrip is crossing the Pside 1Dcluster -> create recpoint
1689 //
5846520e 1690 if ( (TMath::Abs(xt)<hwSSD) && (TMath::Abs(zt)<hlSSD) ) {
7101948c 1691 Double_t loc[3]={xt,0.,zt},trk[3]={0.,0.,0.};
1692 mT2L->MasterToLocal(loc,trk);
1693 lp[0]=trk[1];
1694 lp[1]=trk[2];
1695 lp[4]=neg[j].GetQ(); //Q
1696 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1697 for (Int_t ilab=0;ilab<3;ilab++) milab[ilab] = neg[j].GetLabel(ilab);
1698 CheckLabels2(milab);
1699 milab[3]=( j << 10 ) + idet; // pos|neg|det
1700 Int_t info[3]={0,(Int_t)neg[j].GetNd(),fNlayer[fModule]};
1701
7eb157d7 1702 lp[2]=4.968e-06; // 0.00223*0.00223; //SigmaY2
1703 lp[3]=0.012; // 0.110*0.110; //SigmaZ2
7101948c 1704 lp[5]=-0.00012; // out-of-diagonal element of covariance matrix
7eb157d7 1705 if (info[0]>1) {
1706 lp[2]=2.79e-06;
1707 lp[3]=0.00935;
1708 lp[5]=-4.32e-05;
1709 }
7101948c 1710
1711 AliITSRecPoint * cl2;
138df073 1712 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
7101948c 1713 cl2->SetChargeRatio(1.);
1714 cl2->SetType(60);
7101948c 1715 ncl++;
1716 } // cross is within the detector
1717 //
1718 //--------------
1719
1720 } // bad Nstrip
1721 } // end loop over Nstrips
1722 } // end loop over Pside 1D clusters
1723
1724 } // no bad sides
1725
1726 //---------------------------------------------------------
d695268b 1727
7101948c 1728 else if( (countPbad>700) && (countNbad<100) ) { // bad Pside!!
d695268b 1729
7101948c 1730 for (Int_t i=0; i<np; i++) { // loop over Nside 1Dclusters with no crosses
1731 if(cnegative[i]) continue; // if intersecting Pside clusters continue;
d695268b 1732
7101948c 1733 Float_t xt, zt;
1734 Float_t yN=pos[i].GetY();
1735 Float_t yP=0.;
1736 if (seg->GetLayer()==5) yP = yN + (7.6/1.9);
1737 else yP = yN - (7.6/1.9);
1738 seg->GetPadCxz(yP, yN, xt, zt);
1739
5846520e 1740 if ( (TMath::Abs(xt)<hwSSD) && (TMath::Abs(zt)<hlSSD) ) {
7101948c 1741 Double_t loc[3]={xt,0.,zt},trk[3]={0.,0.,0.};
1742 mT2L->MasterToLocal(loc,trk);
1743 lp[0]=trk[1];
1744 lp[1]=trk[2];
1745 lp[4]=pos[i].GetQ(); //Q
1746 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1747 for (Int_t ilab=0;ilab<3;ilab++) milab[ilab] = pos[i].GetLabel(ilab);
1748 CheckLabels2(milab);
1749 milab[3]=( (i<<10) << 10 ) + idet; // pos|neg|det
1750 Int_t info[3] = {(Int_t)pos[i].GetNd(),0,fNlayer[fModule]};
d695268b 1751
7eb157d7 1752 lp[2]=0.00098; // 0.031*0.031; //SigmaY2
1753 lp[3]=1.329; // 1.15*1.15; //SigmaZ2
1754 lp[5]=-0.0359;
1755 if(info[0]>1) lp[2]=0.00097;
1756
7101948c 1757 AliITSRecPoint * cl2;
138df073 1758 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
7101948c 1759 cl2->SetChargeRatio(1.);
1760 cl2->SetType(70);
7101948c 1761 ncl++;
1762 } // cross is within the detector
1763 //
1764 //--------------
1765
1766 } // end loop over Nside 1D clusters
1767
1768 } // bad Pside module
d695268b 1769
7101948c 1770 else if( (countNbad>700) && (countPbad<100) ) { // bad Nside!!
d695268b 1771
7101948c 1772 for (Int_t j=0; j<nn; j++) { // loop over Pside 1D clusters with no crosses
1773 if(cpositive[j]) continue;
1774
1775 Float_t xt, zt;
1776 Float_t yP=neg[j].GetY();
1777 Float_t yN=0.;
1778 if (seg->GetLayer()==5) yN = yP - (7.6/1.9);
1779 else yN = yP + (7.6/1.9);
1780 seg->GetPadCxz(yP, yN, xt, zt);
1781
5846520e 1782 if ( (TMath::Abs(xt)<hwSSD) && (TMath::Abs(zt)<hlSSD) ) {
7101948c 1783 Double_t loc[3]={xt,0.,zt},trk[3]={0.,0.,0.};
1784 mT2L->MasterToLocal(loc,trk);
1785 lp[0]=trk[1];
1786 lp[1]=trk[2];
1787 lp[4]=neg[j].GetQ(); //Q
1788 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1789 for (Int_t ilab=0;ilab<3;ilab++) milab[ilab] = neg[j].GetLabel(ilab);
1790 CheckLabels2(milab);
1791 milab[3]=( j << 10 ) + idet; // pos|neg|det
1792 Int_t info[3] = {0,(Int_t)neg[j].GetNd(),fNlayer[fModule]};
d695268b 1793
7eb157d7 1794 lp[2]=7.27e-05; // 0.0085*0.0085; //SigmaY2
1795 lp[3]=1.33; // 1.15*1.15; //SigmaZ2
1796 lp[5]=0.00931;
1797 if(info[1]>1) lp[2]=6.91e-05;
7101948c 1798
1799 AliITSRecPoint * cl2;
138df073 1800 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
7101948c 1801 cl2->SetChargeRatio(1.);
1802 cl2->SetType(80);
7101948c 1803 ncl++;
1804 } // cross is within the detector
1805 //
1806 //--------------
1807
1808 } // end loop over Pside 1D clusters
d695268b 1809
7101948c 1810 } // bad Nside module
d695268b 1811
7101948c 1812 //---------------------------------------------------------
d695268b 1813
7101948c 1814 } // use bad channels
d695268b 1815
d695268b 1816 //cout<<ncl<<" clusters for this module"<<endl;
1817
8be4e1b1 1818 delete [] cnegative;
1819 delete [] cused1;
1820 delete [] negativepair;
1821 delete [] cpositive;
1822 delete [] cused2;
1823 delete [] positivepair;
04366a57 1824
0a56760a 1825}