1 /**************************************************************************
2 * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 ////////////////////////////////////////////////////////////////////////////
19 // Implementation of the ITS clusterer V2 class //
21 // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch //
22 // Last revision: 13-05-09 Enrico Fragiacomo //
23 // enrico.fragiacomo@ts.infn.it //
25 ///////////////////////////////////////////////////////////////////////////
27 #include <Riostream.h>
30 #include "AliITSClusterFinderV2SSD.h"
31 #include "AliITSRecPoint.h"
32 #include "AliITSRecPointContainer.h"
33 #include "AliITSgeomTGeo.h"
34 #include "AliITSDetTypeRec.h"
35 #include "AliRawReader.h"
36 #include "AliITSRawStreamSSD.h"
37 #include <TClonesArray.h>
38 #include <TCollection.h>
39 #include "AliITSdigitSSD.h"
40 #include "AliITSReconstructor.h"
41 #include "AliITSCalibrationSSD.h"
42 #include "AliITSsegmentationSSD.h"
44 Short_t *AliITSClusterFinderV2SSD::fgPairs = 0x0;
45 Int_t AliITSClusterFinderV2SSD::fgPairsSize = 0;
46 const Float_t AliITSClusterFinderV2SSD::fgkThreshold = 5.;
48 const Float_t AliITSClusterFinderV2SSD::fgkCosmic2008StripShifts[16][9] =
49 {{-0.35,-0.35,-0.35,-0.35,-0.35,-0.35,-0.35,-0.35,-0.35}, // DDL 512
50 {-0.35,-0.35,-0.35,-0.35,-0.35,-0.35,-0.35,-0.35,-0.35}, // DDL 513
51 {-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15}, // DDL 514
52 {-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15}, // DDL 515
53 { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}, // DDL 516
54 { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}, // DDL 517
55 {-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15}, // DDL 518
56 {-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15}, // DDL 519
57 {-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.25,-0.15}, // DDL 520
58 {-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15,-0.15}, // DDL 521
59 {-0.10,-0.10,-0.10,-0.40,-0.40,-0.40,-0.10,-0.10,-0.45}, // DDL 522
60 {-0.10,-0.10,-0.10,-0.35,-0.35,-0.35,-0.10,-0.35,-0.50}, // DDL 523
61 { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}, // DDL 524
62 { 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00}, // DDL 525
63 { 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35, 0.35}, // DDL 526
64 { 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45, 0.45}}; // DDL 527
66 ClassImp(AliITSClusterFinderV2SSD)
69 AliITSClusterFinderV2SSD::AliITSClusterFinderV2SSD(AliITSDetTypeRec* dettyp):AliITSClusterFinder(dettyp),
70 fLastSSD1(AliITSgeomTGeo::GetModuleIndex(6,1,1)-1)
76 //______________________________________________________________________
77 AliITSClusterFinderV2SSD::AliITSClusterFinderV2SSD(const AliITSClusterFinderV2SSD &cf) : AliITSClusterFinder(cf), fLastSSD1(cf.fLastSSD1)
82 //______________________________________________________________________
83 AliITSClusterFinderV2SSD& AliITSClusterFinderV2SSD::operator=(const AliITSClusterFinderV2SSD& cf ){
84 // Assignment operator
86 this->~AliITSClusterFinderV2SSD();
87 new(this) AliITSClusterFinderV2SSD(cf);
92 void AliITSClusterFinderV2SSD::FindRawClusters(Int_t mod){
96 FindClustersSSD(fDigits);
100 void AliITSClusterFinderV2SSD::FindClustersSSD(TClonesArray *alldigits) {
101 //------------------------------------------------------------
102 // Actual SSD cluster finder
103 //------------------------------------------------------------
104 Int_t smaxall=alldigits->GetEntriesFast();
105 if (smaxall==0) return;
108 //---------------------------------------
109 // load recoparam and calibration
111 static AliITSRecoParam *repa = NULL;
113 repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
115 repa = AliITSRecoParam::GetHighFluxParam();
116 AliWarning("Using default AliITSRecoParam class");
120 AliITSCalibrationSSD* cal = (AliITSCalibrationSSD*)GetResp(fModule);
123 //---------------------------------------
126 //------------------------------------
127 // fill the digits array with zero-suppression condition
128 // Signal is converted in KeV
131 for (Int_t i=0;i<smaxall; i++){
132 AliITSdigitSSD *d=(AliITSdigitSSD*)alldigits->UncheckedAt(i);
134 if(d->IsSideP()) noise = cal->GetNoiseP(d->GetStripNumber());
135 else noise = cal->GetNoiseN(d->GetStripNumber());
136 if (d->GetSignal()<3.*noise) continue;
138 if(d->IsSideP()) gain = cal->GetGainP(d->GetStripNumber());
139 else gain = cal->GetGainN(d->GetStripNumber());
141 Float_t q=gain*d->GetSignal(); //
142 q=cal->ADCToKeV(q); // converts the charge in KeV from ADC units
143 d->SetSignal(Int_t(q));
147 Int_t smax = digits.GetEntriesFast();
149 //------------------------------------
152 const Int_t kMax=1000;
154 Ali1Dcluster pos[kMax], neg[kMax];
155 Float_t y=0., q=0., qmax=0.;
156 Int_t lab[4]={-2,-2,-2,-2};
160 cout<<"-----------------------------"<<endl;
161 cout<<"this is module "<<fModule;
166 //--------------------------------------------------------
167 // start 1D-clustering from the first digit in the digits array
169 AliITSdigitSSD *d=(AliITSdigitSSD*)digits.UncheckedAt(0);
171 y += d->GetCoord2()*d->GetSignal();
173 lab[0]=d->GetTrack(0); lab[1]=d->GetTrack(1); lab[2]=d->GetTrack(2);
176 noise = cal->GetNoiseP(d->GetStripNumber());
177 gain = cal->GetGainP(d->GetStripNumber());
180 noise = cal->GetNoiseN(d->GetStripNumber());
181 gain = cal->GetGainN(d->GetStripNumber());
184 noise=cal->ADCToKeV(noise); // converts noise in KeV from ADC units
186 if(qmax>fgkThreshold*noise) flag5=1; // seed for the cluster
189 cout<<d->GetSignal()<<" "<<noise<<" "<<flag5<<" "<<
190 d->GetCoord1()<<" "<<d->GetCoord2()<<endl;
193 Int_t curr=d->GetCoord2();
194 Int_t flag=d->GetCoord1();
196 // Note: the first side which will be processed is supposed to be the
197 // P-side which is neg
200 if(flag) {n=&np; c=pos;} // in case we have only Nstrips (P was bad!)
204 for (Int_t ilab=0;ilab<10;ilab++){
207 milab[0]=d->GetTrack(0); milab[1]=d->GetTrack(1); milab[2]=d->GetTrack(2);
210 //----------------------------------------------------------
211 // search for neighboring digits
213 for (Int_t s=1; s<smax; s++) {
214 d=(AliITSdigitSSD*)digits.UncheckedAt(s);
215 Int_t strip=d->GetCoord2();
217 // if digits is not a neighbour or side did not change
218 // and at least one of the previous digits met the seed condition
219 // then creates a new 1D cluster
220 if ( ( ((strip-curr) > 1) || (flag!=d->GetCoord1()) ) ) {
223 //cout<<"here1"<<endl;
228 c[*n].SetLabels(milab);
230 if(repa->GetUseUnfoldingInClusterFinderSSD()==kTRUE) {
231 // Note: fUseUnfoldingInClusterFinderSSD=kFALSE by default in RecoParam
233 //Split suspiciously big cluster
235 c[*n].SetY(y/q-0.25*nd);
239 Error("FindClustersSSD","Too many 1D clusters !");
242 c[*n].SetY(y/q+0.25*nd);
245 c[*n].SetLabels(milab);
252 Error("FindClustersSSD","Too many 1D clusters !");
262 lab[0]=lab[1]=lab[2]=-2;
263 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
265 // if side changed from P to N, switch to pos 1D clusters
266 // (if for some reason the side changed from N to P then do the opposite)
267 if (flag!=d->GetCoord1())
268 { if(!flag) {n=&np; c=pos;} else {n=&nn; c=neg;} }
270 } // end create new 1D cluster from previous neighboring digits
272 // continues adding digits to the previous cluster
273 // or start a new one
276 y += d->GetCoord2()*d->GetSignal();
280 noise = cal->GetNoiseP(d->GetStripNumber());
281 gain = cal->GetGainP(d->GetStripNumber());
284 noise = cal->GetNoiseN(d->GetStripNumber());
285 gain = cal->GetGainN(d->GetStripNumber());
288 noise=cal->ADCToKeV(noise); // converts the charge in KeV from ADC units
290 if(d->GetSignal()>fgkThreshold*noise) flag5=1;
293 cout<<d->GetSignal()<<" "<<noise<<" "<<flag5<<" "<<
294 d->GetCoord1()<<" "<<d->GetCoord2()<<endl;
297 if (d->GetSignal()>qmax) {
299 lab[0]=d->GetTrack(0); lab[1]=d->GetTrack(1); lab[2]=d->GetTrack(2);
301 for (Int_t ilab=0;ilab<10;ilab++) {
302 if (d->GetTrack(ilab)>=0) AddLabel(milab, (d->GetTrack(ilab)));
307 } // loop over digits, no more digits in the digits array
310 // add the last 1D cluster
313 // cout<<"here2"<<endl;
318 c[*n].SetLabels(lab);
320 if(repa->GetUseUnfoldingInClusterFinderSSD()==kTRUE) {
322 //Split suspiciously big cluster
324 c[*n].SetY(y/q-0.25*nd);
328 Error("FindClustersSSD","Too many 1D clusters !");
331 c[*n].SetY(y/q+0.25*nd);
334 c[*n].SetLabels(lab);
340 Error("FindClustersSSD","Too many 1D clusters !");
344 } // if flag5 last 1D cluster added
347 //------------------------------------------------------
348 // call FindClustersSSD to pair neg and pos 1D clusters
349 // and create recpoints from the crosses
350 // Note1: neg are Pside and pos are Nside!!
351 // Note2: if there are no Pside digits nn=0 (bad strips!!) (same for Nside)
353 // cout<<nn<<" Pside and "<<np<<" Nside clusters"<<endl;
355 AliITSRecPointContainer* rpc = AliITSRecPointContainer::Instance();
357 TClonesArray* clusters = rpc->UncheckedGetClusters(fModule);
359 FindClustersSSD(neg, nn, pos, np, clusters);
362 while ((irp = (AliITSRecPoint*)itr.Next())) fDetTypeRec->AddRecPoint(*irp);
364 //-----------------------------------------------------
368 void AliITSClusterFinderV2SSD::RawdataToClusters(AliRawReader* rawReader){
370 //------------------------------------------------------------
371 // This function creates ITS clusters from raw data
372 //------------------------------------------------------------
374 AliITSRawStreamSSD inputSSD(rawReader);
375 FindClustersSSD(&inputSSD);
380 void AliITSClusterFinderV2SSD::FindClustersSSD(AliITSRawStreamSSD* input)
382 //------------------------------------------------------------
383 // Actual SSD cluster finder for raw data
384 //------------------------------------------------------------
386 AliITSRecPointContainer* rpc = AliITSRecPointContainer::Instance();
387 static AliITSRecoParam *repa = NULL;
389 repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
391 repa = AliITSRecoParam::GetHighFluxParam();
392 AliWarning("Using default AliITSRecoParam class");
395 Int_t nClustersSSD = 0;
396 const Int_t kNADC = 12;
397 const Int_t kMaxADCClusters = 1000;
399 Int_t strips[kNADC][2][kMaxADCClusters][2]; // [ADC],[side],[istrip], [0]=istrip [1]=signal
400 Int_t nStrips[kNADC][2];
402 for( int i=0; i<kNADC; i++ ){
411 //* Loop over modules DDL+AD
416 bool next = input->Next();
419 //* Continue if corrupted input
422 if( (!next)&&(input->flag) ){
423 AliWarning(Form("ITSClustersFinderSSD: Corrupted data: warning from RawReader"));
427 Int_t newDDL = input->GetDDL();
428 Int_t newAD = input->GetAD();
431 if( newDDL<0 || newDDL>15 ){
432 AliWarning(Form("ITSClustersFinderSSD: Corrupted data: wrong DDL number (%d)",newDDL));
436 if( newAD<1 || newAD>9 ){
437 AliWarning(Form("ITSClustersFinderSSD: Corrupted data: wrong AD number (%d)",newAD));
442 bool newModule = ( !next || ddl!= newDDL || ad!=newAD );
444 if( newModule && ddl>=0 && ad>=0 ){
447 //* Reconstruct the previous block of 12 modules --- actual clusterfinder
450 for( int adc = 0; adc<kNADC; adc++ ){
454 Ali1Dcluster clusters1D[2][kMaxADCClusters]; // per ADC, per side
455 Int_t nClusters1D[2] = {0,0};
456 //int nstat[2] = {0,0};
457 fModule = AliITSRawStreamSSD::GetModuleNumber(ddl, (ad - 1) * 12 + adc );
460 // AliWarning(Form("ITSClustersFinderSSD: Corrupted data: module (ddl %d ad %d adc %d) not found in the map",ddl,ad,adc));
461 //CM channels are always present even everything is suppressed
465 AliITSCalibrationSSD* cal = (AliITSCalibrationSSD*)fDetTypeRec->GetCalibrationModel(fModule);
467 AliWarning(Form("ITSClustersFinderSSD: No calibration found for module (ddl %d ad %d adc %d)",ddl,ad,adc));
473 if( repa->GetUseCosmicRunShiftsSSD()) { // Special condition for 2007/2008 cosmic data
474 dStrip = fgkCosmic2008StripShifts[ddl][ad-1];
475 if (TMath::Abs(dStrip) > 1.5){
476 AliWarning(Form("Indexing error in Cosmic calibration: ddl = %d, dStrip %f\n",ddl,dStrip));
481 for( int side=0; side<=1; side++ ){
483 Int_t lab[3]={-2,-2,-2};
490 Int_t n = nStrips[adc][side];
491 for( int istr = 0; istr<n+1; istr++ ){
495 Float_t signal=0.0, noise=0.0, gain=0.0;
498 strip = strips[adc][side][istr][0];
499 signal = strips[adc][side][istr][1];
501 //cout<<"strip "<<adc<<" / "<<side<<": "<<strip<<endl;
504 noise = side ?cal->GetNoiseN(strip) :cal->GetNoiseP(strip);
505 gain = side ?cal->GetGainN(strip) :cal->GetGainP(strip);
506 stripOK = ( noise>=1. && signal>=3.0*noise
507 //&& !cal->IsPChannelBad(strip)
510 } else stripOK = 0; // end of data
512 bool newCluster = ( (abs(strip-ostrip)!=1) || !stripOK );
516 //* Store the previous cluster
518 if( nDigits>0 && q>0 && snFlag ){
520 if (nClusters1D[side] >= kMaxADCClusters-1 ) {
521 AliWarning("HLT ClustersFinderSSD: Too many 1D clusters !");
524 Ali1Dcluster &cluster = clusters1D[side][nClusters1D[side]++];
525 cluster.SetY( y / q + dStrip);
527 cluster.SetNd(nDigits);
528 cluster.SetLabels(lab);
529 //cout<<"cluster 1D side "<<side<<": y= "<<y<<" q= "<<q<<" d="<<dStrip<<" Y="<<cluster.GetY()<<endl;
530 //Split suspiciously big cluster
532 if( repa->GetUseUnfoldingInClusterFinderSSD()
533 && nDigits > 4 && nDigits < 25
535 cluster.SetY(y/q + dStrip - 0.25*nDigits);
537 Ali1Dcluster& cluster2 = clusters1D[side][nClusters1D[side]++];
538 cluster2.SetY(y/q + dStrip + 0.25*nDigits);
539 cluster2.SetQ(0.5*q);
540 cluster2.SetNd(nDigits);
541 cluster2.SetLabels(lab);
549 } //* End store the previous cluster
551 if( stripOK ){ // add new signal to the cluster
552 // signal = (Int_t) (signal * gain); // signal is corrected for gain
553 if( signal>fgkThreshold*noise) snFlag = 1;
554 signal = signal * gain; // signal is corrected for gain
555 // if( cal ) signal = (Int_t) cal->ADCToKeV( signal ); // signal is converted in KeV
556 if( cal ) signal = cal->ADCToKeV( signal ); // signal is converted in KeV
557 q += signal; // add digit to current cluster
564 } //* end loop over strips
566 } //* end loop over ADC sides
570 if( nClusters1D[0] && nClusters1D[1] && fModule>=0 ){
571 TClonesArray* clusters = rpc->UncheckedGetClusters(fModule);
572 FindClustersSSD( clusters1D[0], nClusters1D[0], clusters1D[1], nClusters1D[1], clusters);
573 Int_t nClustersn = clusters->GetEntriesFast();
574 nClustersSSD += nClustersn;
577 //cout<<"SG: "<<ddl<<" "<<ad<<" "<<adc<<": strips "<<nstat[0]<<"+"<<nstat[1]<<", clusters 1D= "<<nClusters1D[0]<<" + "<<nClusters1D[1]<<", 2D= "<<clusters.size()<<endl;
579 }//* end loop over adc
581 }//* end of reconstruction of previous block of 12 modules
586 //* Clean up arrays and set new module
589 for( int i=0; i<kNADC; i++ ){
599 //* Exit main loop when there is no more input
605 //* Fill the current strip information
608 Int_t adc = input->GetADC();
609 if( adc<0 || adc>=kNADC+2 || (adc>5&&adc<8) ){
610 AliWarning(Form("HLT ClustersFinderSSD: Corrupted data: wrong adc number (%d)", adc));
614 if( adc>7 ) adc-= 2; // shift ADC numbers 8-13 to 6-11
616 Bool_t side = input->GetSideFlag();
617 Int_t strip = input->GetStrip();
618 Int_t signal = input->GetSignal();
621 //cout<<"SSD: "<<ddl<<" "<<ad<<" "<<adc<<" "<<side<<" "<<strip<<" : "<<signal<<endl;
624 AliWarning(Form("HLT ClustersFinderSSD: Corrupted data: wrong strip number (ddl %d ad %d adc %d side %d, strip %d",
625 ddl, ad, adc, side,strip) );
628 if (strip < 0) continue;
630 int &n = nStrips[adc][side];
632 Int_t oldStrip = strips[adc][side][n-1][0];
634 if( strip==oldStrip ){
635 AliWarning(Form("HLT ClustersFinderSSD: Corrupted data: duplicated signal: ddl %d ad %d adc %d, side %d, strip %d",
636 ddl, ad, adc, side, strip ));
640 strips[adc][side][n][0] = strip;
641 strips[adc][side][n][1] = signal;
644 //cout<<"SSD: "<<input->GetDDL()<<" "<<input->GetAD()<<" "
645 //<<input->GetADC()<<" "<<input->GetSideFlag()<<" "<<((int)input->GetStrip())<<" "<<strip<<" : "<<input->GetSignal()<<endl;
647 } //* End main loop over the input
649 AliDebug(1,Form("found clusters in ITS SSD: %d", nClustersSSD));
653 void AliITSClusterFinderV2SSD::
654 FindClustersSSD(Ali1Dcluster* neg, Int_t nn,
655 Ali1Dcluster* pos, Int_t np,
656 TClonesArray *clusters) {
657 //------------------------------------------------------------
658 // Actual SSD cluster finder
659 //------------------------------------------------------------
661 const TGeoHMatrix *mT2L=AliITSgeomTGeo::GetTracking2LocalMatrix(fModule);
663 //---------------------------------------
666 static AliITSRecoParam *repa = NULL;
668 repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
670 repa = AliITSRecoParam::GetHighFluxParam();
671 AliWarning("Using default AliITSRecoParam class");
675 // TClonesArray &cl=*clusters;
677 AliITSsegmentationSSD *seg = dynamic_cast<AliITSsegmentationSSD*>(fDetTypeRec->GetSegmentationModel(2));
678 if (fModule>fLastSSD1)
683 Float_t hwSSD = seg->Dx()*1e-4/2;
684 Float_t hlSSD = seg->Dz()*1e-4/2;
686 Int_t idet=fNdet[fModule];
690 Int_t *cnegative = new Int_t[np];
691 Int_t *cused1 = new Int_t[np];
692 Int_t *negativepair = new Int_t[10*np];
693 Int_t *cpositive = new Int_t[nn];
694 Int_t *cused2 = new Int_t[nn];
695 Int_t *positivepair = new Int_t[10*nn];
696 for (Int_t i=0;i<np;i++) {cnegative[i]=0; cused1[i]=0;}
697 for (Int_t i=0;i<nn;i++) {cpositive[i]=0; cused2[i]=0;}
698 for (Int_t i=0;i<10*np;i++) {negativepair[i]=0;}
699 for (Int_t i=0;i<10*nn;i++) {positivepair[i]=0;}
701 if ((np*nn) > fgPairsSize) {
703 if (fgPairs) delete [] fgPairs;
704 fgPairsSize = 4*np*nn;
705 fgPairs = new Short_t[fgPairsSize];
707 memset(fgPairs,0,sizeof(Short_t)*np*nn);
710 // find available pairs
713 for (Int_t i=0; i<np; i++) {
714 Float_t yp=pos[i].GetY();
715 if ( (pos[i].GetQ()>0) && (pos[i].GetQ()<3) ) continue;
716 for (Int_t j=0; j<nn; j++) {
717 if ( (neg[j].GetQ()>0) && (neg[j].GetQ()<3) ) continue;
718 Float_t yn=neg[j].GetY();
721 seg->GetPadCxz(yn, yp, xt, zt);
722 //cout<<yn<<" "<<yp<<" "<<xt<<" "<<zt<<endl;
724 if (TMath::Abs(xt)<hwSSD)
725 if (TMath::Abs(zt)<hlSSD) {
726 Int_t in = i*10+cnegative[i];
727 Int_t ip = j*10+cpositive[j];
728 if ((in < 10*np) && (ip < 10*nn)) {
729 negativepair[in] =j; //index
731 cnegative[i]++; //counters
737 AliError(Form("Index out of range: ip=%d, in=%d",ip,in));
745 delete [] negativepair;
748 delete [] positivepair;
751 //why not to allocate memorey here? if(!clusters) clusters = new TClonesArray("AliITSRecPoint", ncross);
754 // try to recover points out of but close to the module boundaries
756 for (Int_t i=0; i<np; i++) {
757 Float_t yp=pos[i].GetY();
758 if ( (pos[i].GetQ()>0) && (pos[i].GetQ()<3) ) continue;
759 for (Int_t j=0; j<nn; j++) {
760 if ( (neg[j].GetQ()>0) && (neg[j].GetQ()<3) ) continue;
761 // if both 1Dclusters have an other cross continue
762 if (cpositive[j]&&cnegative[i]) continue;
763 Float_t yn=neg[j].GetY();
766 seg->GetPadCxz(yn, yp, xt, zt);
768 if (TMath::Abs(xt)<hwSSD+0.1)
769 if (TMath::Abs(zt)<hlSSD+0.15) {
770 // tag 1Dcluster (eventually will produce low quality recpoint)
771 if (cnegative[i]==0) pos[i].SetNd(100); // not available pair
772 if (cpositive[j]==0) neg[j].SetNd(100); // not available pair
773 Int_t in = i*10+cnegative[i];
774 Int_t ip = j*10+cpositive[j];
775 if ((in < 10*np) && (ip < 10*nn)) {
776 negativepair[in] =j; //index
778 cnegative[i]++; //counters
783 AliError(Form("Index out of range: ip=%d, in=%d",ip,in));
795 if(repa->GetUseChargeMatchingInClusterFinderSSD()==kTRUE) {
801 for (Int_t ip=0;ip<np;ip++){
802 Float_t xbest=1000,zbest=1000,qbest=0;
804 // select gold clusters
805 if ( (cnegative[ip]==1) && cpositive[negativepair[10*ip]]==1){
806 Float_t yp=pos[ip].GetY();
807 Int_t j = negativepair[10*ip];
809 if( (pos[ip].GetQ()==0) && (neg[j].GetQ() ==0) ) {
810 // both bad, hence continue;
811 // mark both as used (to avoid recover at the end)
817 ratio = (pos[ip].GetQ()-neg[j].GetQ())/(pos[ip].GetQ()+neg[j].GetQ());
818 //cout<<"ratio="<<ratio<<endl;
820 // charge matching (note that if posQ or negQ is 0 -> ratio=1 and the following condition is met
821 if (TMath::Abs(ratio)>0.2) continue; // note: 0.2=3xsigma_ratio calculated in cosmics tests
824 Float_t yn=neg[j].GetY();
827 seg->GetPadCxz(yn, yp, xt, zt);
832 qbest=0.5*(pos[ip].GetQ()+neg[j].GetQ());
833 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
836 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
837 mT2L->MasterToLocal(loc,trk);
842 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
843 for (Int_t ilab=0;ilab<3;ilab++){
844 milab[ilab] = pos[ip].GetLabel(ilab);
845 milab[ilab+3] = neg[j].GetLabel(ilab);
849 milab[3]=(((ip<<10) + j)<<10) + idet; // pos|neg|det
850 Int_t info[3] = {pos[ip].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
852 lp[2]=4.968e-06; // 0.00223*0.00223; //SigmaY2
853 lp[3]=0.012; // 0.110*0.110; //SigmaZ2
854 // out-of-diagonal element of covariance matrix
855 if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
856 else if ( (info[0]>1) && (info[1]>1) ) {
857 lp[2]=2.63e-06; // 0.0016*0.0016; //SigmaY2
858 lp[3]=0.0065; // 0.08*0.08; //SigmaZ2
862 lp[2]=4.80e-06; // 0.00219*0.00219
863 lp[3]=0.0093; // 0.0964*0.0964;
868 lp[2]=2.79e-06; // 0.0017*0.0017;
869 lp[3]=0.00935; // 0.967*0.967;
874 AliITSRecPoint * cl2;
875 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
877 cl2->SetChargeRatio(ratio);
881 if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
886 if(pos[ip].GetQ()==0) cl2->SetType(3);
887 if(neg[j].GetQ()==0) cl2->SetType(4);
896 for (Int_t ip=0;ip<np;ip++){
897 Float_t xbest=1000,zbest=1000,qbest=0;
900 // select "silber" cluster
901 if ( cnegative[ip]==1 && cpositive[negativepair[10*ip]]==2){
902 Int_t in = negativepair[10*ip];
903 Int_t ip2 = positivepair[10*in];
904 if (ip2==ip) ip2 = positivepair[10*in+1];
905 Float_t pcharge = pos[ip].GetQ()+pos[ip2].GetQ();
909 ratio = (pcharge-neg[in].GetQ())/(pcharge+neg[in].GetQ());
910 if ( (TMath::Abs(ratio)<0.2) && (pcharge!=0) ) {
911 //if ( (TMath::Abs(pcharge-neg[in].GetQ())<30) && (pcharge!=0) ) { //
915 if ( (fgPairs[ip*nn+in]==100)&&(pos[ip].GetQ() ) ) { //
917 Float_t yp=pos[ip].GetY();
918 Float_t yn=neg[in].GetY();
921 seg->GetPadCxz(yn, yp, xt, zt);
925 qbest =pos[ip].GetQ();
926 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
927 mT2L->MasterToLocal(loc,trk);
932 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
933 for (Int_t ilab=0;ilab<3;ilab++){
934 milab[ilab] = pos[ip].GetLabel(ilab);
935 milab[ilab+3] = neg[in].GetLabel(ilab);
939 ratio = (pos[ip].GetQ()-neg[in].GetQ())/(pos[ip].GetQ()+neg[in].GetQ());
940 milab[3]=(((ip<<10) + in)<<10) + idet; // pos|neg|det
941 Int_t info[3] = {pos[ip].GetNd(),neg[in].GetNd(),fNlayer[fModule]};
943 lp[2]=4.968e-06; // 0.00223*0.00223; //SigmaY2
944 lp[3]=0.012; // 0.110*0.110; //SigmaZ2
945 // out-of-diagonal element of covariance matrix
946 if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
947 else if ( (info[0]>1) && (info[1]>1) ) {
948 lp[2]=2.63e-06; // 0.0016*0.0016; //SigmaY2
949 lp[3]=0.0065; // 0.08*0.08; //SigmaZ2
953 lp[2]=4.80e-06; // 0.00219*0.00219
954 lp[3]=0.0093; // 0.0964*0.0964;
959 lp[2]=2.79e-06; // 0.0017*0.0017;
960 lp[3]=0.00935; // 0.967*0.967;
965 AliITSRecPoint * cl2;
966 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
967 cl2->SetChargeRatio(ratio);
969 fgPairs[ip*nn+in] = 5;
970 if ((pos[ip].GetNd()+neg[in].GetNd())>6){ //multi cluster
972 fgPairs[ip*nn+in] = 6;
981 // if (!(cused1[ip2] || cused2[in])){ //
982 if ( (fgPairs[ip2*nn+in]==100) && (pos[ip2].GetQ()) ) {
984 Float_t yp=pos[ip2].GetY();
985 Float_t yn=neg[in].GetY();
988 seg->GetPadCxz(yn, yp, xt, zt);
992 qbest =pos[ip2].GetQ();
994 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
995 mT2L->MasterToLocal(loc,trk);
1000 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1001 for (Int_t ilab=0;ilab<3;ilab++){
1002 milab[ilab] = pos[ip2].GetLabel(ilab);
1003 milab[ilab+3] = neg[in].GetLabel(ilab);
1006 CheckLabels2(milab);
1007 ratio = (pos[ip2].GetQ()-neg[in].GetQ())/(pos[ip2].GetQ()+neg[in].GetQ());
1008 milab[3]=(((ip2<<10) + in)<<10) + idet; // pos|neg|det
1009 Int_t info[3] = {pos[ip2].GetNd(),neg[in].GetNd(),fNlayer[fModule]};
1011 lp[2]=4.968e-06; // 0.00223*0.00223; //SigmaY2
1012 lp[3]=0.012; // 0.110*0.110; //SigmaZ2
1013 // out-of-diagonal element of covariance matrix
1014 if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
1015 else if ( (info[0]>1) && (info[1]>1) ) {
1016 lp[2]=2.63e-06; // 0.0016*0.0016; //SigmaY2
1017 lp[3]=0.0065; // 0.08*0.08; //SigmaZ2
1021 lp[2]=4.80e-06; // 0.00219*0.00219
1022 lp[3]=0.0093; // 0.0964*0.0964;
1027 lp[2]=2.79e-06; // 0.0017*0.0017;
1028 lp[3]=0.00935; // 0.967*0.967;
1033 AliITSRecPoint * cl2;
1034 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
1036 cl2->SetChargeRatio(ratio);
1038 fgPairs[ip2*nn+in] =5;
1039 if ((pos[ip2].GetNd()+neg[in].GetNd())>6){ //multi cluster
1041 fgPairs[ip2*nn+in] =6;
1050 } // charge matching condition
1052 } // 2 Pside cross 1 Nside
1053 } // loop over Pside clusters
1058 for (Int_t jn=0;jn<nn;jn++){
1059 if (cused2[jn]) continue;
1060 Float_t xbest=1000,zbest=1000,qbest=0;
1061 // select "silber" cluster
1062 if ( cpositive[jn]==1 && cnegative[positivepair[10*jn]]==2){
1063 Int_t ip = positivepair[10*jn];
1064 Int_t jn2 = negativepair[10*ip];
1065 if (jn2==jn) jn2 = negativepair[10*ip+1];
1066 Float_t pcharge = neg[jn].GetQ()+neg[jn2].GetQ();
1070 ratio = (pcharge-pos[ip].GetQ())/(pcharge+pos[ip].GetQ());
1071 if ( (TMath::Abs(ratio)<0.2) && (pcharge!=0) ) {
1074 if ( (TMath::Abs(pcharge-pos[ip].GetQ())<30) && // charge matching
1075 (pcharge!=0) ) { // reject combinations of bad strips
1081 // if (!(cused1[ip]||cused2[jn])){
1082 if ( (fgPairs[ip*nn+jn]==100) && (neg[jn].GetQ()) ) { //
1084 Float_t yn=neg[jn].GetY();
1085 Float_t yp=pos[ip].GetY();
1088 seg->GetPadCxz(yn, yp, xt, zt);
1092 qbest =neg[jn].GetQ();
1095 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
1096 mT2L->MasterToLocal(loc,trk);
1102 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1103 for (Int_t ilab=0;ilab<3;ilab++){
1104 milab[ilab] = pos[ip].GetLabel(ilab);
1105 milab[ilab+3] = neg[jn].GetLabel(ilab);
1108 CheckLabels2(milab);
1109 ratio = (pos[ip].GetQ()-neg[jn].GetQ())/(pos[ip].GetQ()+neg[jn].GetQ());
1110 milab[3]=(((ip<<10) + jn)<<10) + idet; // pos|neg|det
1111 Int_t info[3] = {pos[ip].GetNd(),neg[jn].GetNd(),fNlayer[fModule]};
1113 lp[2]=4.968e-06; // 0.00223*0.00223; //SigmaY2
1114 lp[3]=0.012; // 0.110*0.110; //SigmaZ2
1115 // out-of-diagonal element of covariance matrix
1116 if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
1117 else if ( (info[0]>1) && (info[1]>1) ) {
1118 lp[2]=2.63e-06; // 0.0016*0.0016; //SigmaY2
1119 lp[3]=0.0065; // 0.08*0.08; //SigmaZ2
1123 lp[2]=4.80e-06; // 0.00219*0.00219
1124 lp[3]=0.0093; // 0.0964*0.0964;
1129 lp[2]=2.79e-06; // 0.0017*0.0017;
1130 lp[3]=0.00935; // 0.967*0.967;
1135 AliITSRecPoint * cl2;
1136 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
1138 cl2->SetChargeRatio(ratio);
1140 fgPairs[ip*nn+jn] =7;
1141 if ((pos[ip].GetNd()+neg[jn].GetNd())>6){ //multi cluster
1143 fgPairs[ip*nn+jn]=8;
1149 // if (!(cused1[ip]||cused2[jn2])){
1150 if ( (fgPairs[ip*nn+jn2]==100)&&(neg[jn2].GetQ() ) ) { //
1152 Float_t yn=neg[jn2].GetY();
1153 Double_t yp=pos[ip].GetY();
1156 seg->GetPadCxz(yn, yp, xt, zt);
1160 qbest =neg[jn2].GetQ();
1163 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
1164 mT2L->MasterToLocal(loc,trk);
1170 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1171 for (Int_t ilab=0;ilab<3;ilab++){
1172 milab[ilab] = pos[ip].GetLabel(ilab);
1173 milab[ilab+3] = neg[jn2].GetLabel(ilab);
1176 CheckLabels2(milab);
1177 ratio = (pos[ip].GetQ()-neg[jn2].GetQ())/(pos[ip].GetQ()+neg[jn2].GetQ());
1178 milab[3]=(((ip<<10) + jn2)<<10) + idet; // pos|neg|det
1179 Int_t info[3] = {pos[ip].GetNd(),neg[jn2].GetNd(),fNlayer[fModule]};
1181 lp[2]=4.968e-06; // 0.00223*0.00223; //SigmaY2
1182 lp[3]=0.012; // 0.110*0.110; //SigmaZ2
1183 // out-of-diagonal element of covariance matrix
1184 if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
1185 else if ( (info[0]>1) && (info[1]>1) ) {
1186 lp[2]=2.63e-06; // 0.0016*0.0016; //SigmaY2
1187 lp[3]=0.0065; // 0.08*0.08; //SigmaZ2
1191 lp[2]=4.80e-06; // 0.00219*0.00219
1192 lp[3]=0.0093; // 0.0964*0.0964;
1197 lp[2]=2.79e-06; // 0.0017*0.0017;
1198 lp[3]=0.00935; // 0.967*0.967;
1203 AliITSRecPoint * cl2;
1204 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
1207 cl2->SetChargeRatio(ratio);
1208 fgPairs[ip*nn+jn2]=7;
1210 if ((pos[ip].GetNd()+neg[jn2].GetNd())>6){ //multi cluster
1212 fgPairs[ip*nn+jn2]=8;
1220 } // charge matching condition
1222 } // 2 Nside cross 1 Pside
1223 } // loop over Pside clusters
1227 for (Int_t ip=0;ip<np;ip++){
1229 if(cused1[ip]) continue;
1232 Float_t xbest=1000,zbest=1000,qbest=0;
1236 if ( (cnegative[ip]==2) && cpositive[negativepair[10*ip]]==2){
1237 Float_t minchargediff =4.;
1238 Float_t minchargeratio =0.2;
1241 for (Int_t di=0;di<cnegative[ip];di++){
1242 Int_t jc = negativepair[ip*10+di];
1243 Float_t chargedif = pos[ip].GetQ()-neg[jc].GetQ();
1244 ratio = (pos[ip].GetQ()-neg[jc].GetQ())/(pos[ip].GetQ()+neg[jc].GetQ());
1245 //if (TMath::Abs(chargedif)<minchargediff){
1246 if (TMath::Abs(ratio)<0.2){
1248 minchargediff = TMath::Abs(chargedif);
1249 minchargeratio = TMath::Abs(ratio);
1252 if (j<0) continue; // not proper cluster
1256 for (Int_t di=0;di<cnegative[ip];di++){
1257 Int_t jc = negativepair[ip*10+di];
1258 Float_t chargedif = pos[ip].GetQ()-neg[jc].GetQ();
1259 if (TMath::Abs(chargedif)<minchargediff+3.) count++;
1261 if (count>1) continue; // more than one "proper" cluster for positive
1265 for (Int_t dj=0;dj<cpositive[j];dj++){
1266 Int_t ic = positivepair[j*10+dj];
1267 Float_t chargedif = pos[ic].GetQ()-neg[j].GetQ();
1268 if (TMath::Abs(chargedif)<minchargediff+3.) count++;
1270 if (count>1) continue; // more than one "proper" cluster for negative
1275 for (Int_t dj=0;dj<cnegative[jp];dj++){
1276 Int_t ic = positivepair[jp*10+dj];
1277 Float_t chargedif = pos[ic].GetQ()-neg[jp].GetQ();
1278 if (TMath::Abs(chargedif)<minchargediff+4.) count++;
1280 if (count>1) continue;
1281 if (fgPairs[ip*nn+j]<100) continue;
1286 //almost gold clusters
1287 Float_t yp=pos[ip].GetY();
1288 Float_t yn=neg[j].GetY();
1290 seg->GetPadCxz(yn, yp, xt, zt);
1292 qbest=0.5*(pos[ip].GetQ()+neg[j].GetQ());
1294 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
1295 mT2L->MasterToLocal(loc,trk);
1300 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1301 for (Int_t ilab=0;ilab<3;ilab++){
1302 milab[ilab] = pos[ip].GetLabel(ilab);
1303 milab[ilab+3] = neg[j].GetLabel(ilab);
1306 CheckLabels2(milab);
1307 if ((neg[j].GetQ()==0)&&(pos[ip].GetQ()==0)) continue; // reject crosses of bad strips!!
1308 ratio = (pos[ip].GetQ()-neg[j].GetQ())/(pos[ip].GetQ()+neg[j].GetQ());
1309 milab[3]=(((ip<<10) + j)<<10) + idet; // pos|neg|det
1310 Int_t info[3] = {pos[ip].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
1312 lp[2]=4.968e-06; // 0.00223*0.00223; //SigmaY2
1313 lp[3]=0.012; // 0.110*0.110; //SigmaZ2
1314 // out-of-diagonal element of covariance matrix
1315 if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
1316 else if ( (info[0]>1) && (info[1]>1) ) {
1317 lp[2]=2.63e-06; // 0.0016*0.0016; //SigmaY2
1318 lp[3]=0.0065; // 0.08*0.08; //SigmaZ2
1322 lp[2]=4.80e-06; // 0.00219*0.00219
1323 lp[3]=0.0093; // 0.0964*0.0964;
1328 lp[2]=2.79e-06; // 0.0017*0.0017;
1329 lp[3]=0.00935; // 0.967*0.967;
1334 AliITSRecPoint * cl2;
1335 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
1337 cl2->SetChargeRatio(ratio);
1339 fgPairs[ip*nn+j]=10;
1340 if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
1342 fgPairs[ip*nn+j]=11;
1349 } // loop over Pside 1Dclusters
1353 for (Int_t ip=0;ip<np;ip++){
1355 if(cused1[ip]) continue;
1358 Float_t xbest=1000,zbest=1000,qbest=0;
1360 // manyxmany clusters
1362 if ( (cnegative[ip]<5) && cpositive[negativepair[10*ip]]<5){
1363 Float_t minchargediff =4.;
1365 for (Int_t di=0;di<cnegative[ip];di++){
1366 Int_t jc = negativepair[ip*10+di];
1367 Float_t chargedif = pos[ip].GetQ()-neg[jc].GetQ();
1368 if (TMath::Abs(chargedif)<minchargediff){
1370 minchargediff = TMath::Abs(chargedif);
1373 if (j<0) continue; // not proper cluster
1376 for (Int_t di=0;di<cnegative[ip];di++){
1377 Int_t jc = negativepair[ip*10+di];
1378 Float_t chargedif = pos[ip].GetQ()-neg[jc].GetQ();
1379 if (TMath::Abs(chargedif)<minchargediff+3.) count++;
1381 if (count>1) continue; // more than one "proper" cluster for positive
1385 for (Int_t dj=0;dj<cpositive[j];dj++){
1386 Int_t ic = positivepair[j*10+dj];
1387 Float_t chargedif = pos[ic].GetQ()-neg[j].GetQ();
1388 if (TMath::Abs(chargedif)<minchargediff+3.) count++;
1390 if (count>1) continue; // more than one "proper" cluster for negative
1395 for (Int_t dj=0;dj<cnegative[jp];dj++){
1396 Int_t ic = positivepair[jp*10+dj];
1397 Float_t chargedif = pos[ic].GetQ()-neg[jp].GetQ();
1398 if (TMath::Abs(chargedif)<minchargediff+4.) count++;
1400 if (count>1) continue;
1401 if (fgPairs[ip*nn+j]<100) continue;
1404 //almost gold clusters
1405 Float_t yp=pos[ip].GetY();
1406 Float_t yn=neg[j].GetY();
1410 seg->GetPadCxz(yn, yp, xt, zt);
1414 qbest=0.5*(pos[ip].GetQ()+neg[j].GetQ());
1417 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
1418 mT2L->MasterToLocal(loc,trk);
1423 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1424 for (Int_t ilab=0;ilab<3;ilab++){
1425 milab[ilab] = pos[ip].GetLabel(ilab);
1426 milab[ilab+3] = neg[j].GetLabel(ilab);
1429 CheckLabels2(milab);
1430 if ((neg[j].GetQ()==0)&&(pos[ip].GetQ()==0)) continue; // reject crosses of bad strips!!
1431 ratio = (pos[ip].GetQ()-neg[j].GetQ())/(pos[ip].GetQ()+neg[j].GetQ());
1432 milab[3]=(((ip<<10) + j)<<10) + idet; // pos|neg|det
1433 Int_t info[3] = {pos[ip].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
1435 lp[2]=4.968e-06; // 0.00223*0.00223; //SigmaY2
1436 lp[3]=0.012; // 0.110*0.110; //SigmaZ2
1437 // out-of-diagonal element of covariance matrix
1438 if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
1439 else if ( (info[0]>1) && (info[1]>1) ) {
1440 lp[2]=2.63e-06; // 0.0016*0.0016; //SigmaY2
1441 lp[3]=0.0065; // 0.08*0.08; //SigmaZ2
1445 lp[2]=4.80e-06; // 0.00219*0.00219
1446 lp[3]=0.0093; // 0.0964*0.0964;
1451 lp[2]=2.79e-06; // 0.0017*0.0017;
1452 lp[3]=0.00935; // 0.967*0.967;
1457 AliITSRecPoint * cl2;
1458 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
1460 cl2->SetChargeRatio(ratio);
1462 fgPairs[ip*nn+j]=12;
1463 if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
1465 fgPairs[ip*nn+j]=13;
1472 } // loop over Pside 1Dclusters
1474 } // use charge matching
1477 // recover all the other crosses
1479 for (Int_t i=0; i<np; i++) {
1480 Float_t xbest=1000,zbest=1000,qbest=0;
1481 Float_t yp=pos[i].GetY();
1482 if ((pos[i].GetQ()>0)&&(pos[i].GetQ()<3)) continue;
1483 for (Int_t j=0; j<nn; j++) {
1484 // for (Int_t di = 0;di<cpositive[i];di++){
1485 // Int_t j = negativepair[10*i+di];
1486 if ((neg[j].GetQ()>0)&&(neg[j].GetQ()<3)) continue;
1488 if ((neg[j].GetQ()==0)&&(pos[i].GetQ()==0)) continue; // reject crosses of bad strips!!
1490 if (cused2[j]||cused1[i]) continue;
1491 if (fgPairs[i*nn+j]>0 &&fgPairs[i*nn+j]<100) continue;
1492 ratio = (pos[i].GetQ()-neg[j].GetQ())/(pos[i].GetQ()+neg[j].GetQ());
1493 Float_t yn=neg[j].GetY();
1496 seg->GetPadCxz(yn, yp, xt, zt);
1498 if (TMath::Abs(xt)<hwSSD)
1499 if (TMath::Abs(zt)<hlSSD) {
1502 qbest=0.5*(pos[i].GetQ()+neg[j].GetQ());
1505 Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
1506 mT2L->MasterToLocal(loc,trk);
1511 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1512 for (Int_t ilab=0;ilab<3;ilab++){
1513 milab[ilab] = pos[i].GetLabel(ilab);
1514 milab[ilab+3] = neg[j].GetLabel(ilab);
1517 CheckLabels2(milab);
1518 milab[3]=(((i<<10) + j)<<10) + idet; // pos|neg|det
1519 Int_t info[3] = {pos[i].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
1521 lp[2]=4.968e-06; // 0.00223*0.00223; //SigmaY2
1522 lp[3]=0.012; // 0.110*0.110; //SigmaZ2
1523 // out-of-diagonal element of covariance matrix
1524 if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
1525 else if ( (info[0]>1) && (info[1]>1) ) {
1526 lp[2]=2.63e-06; // 0.0016*0.0016; //SigmaY2
1527 lp[3]=0.0065; // 0.08*0.08; //SigmaZ2
1531 lp[2]=4.80e-06; // 0.00219*0.00219
1532 lp[3]=0.0093; // 0.0964*0.0964;
1537 lp[2]=2.79e-06; // 0.0017*0.0017;
1538 lp[3]=0.00935; // 0.967*0.967;
1543 AliITSRecPoint * cl2;
1544 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
1546 cl2->SetChargeRatio(ratio);
1547 cl2->SetType(100+cpositive[j]+cnegative[i]);
1549 if(pos[i].GetQ()==0) cl2->SetType(200+cpositive[j]+cnegative[i]);
1550 if(neg[j].GetQ()==0) cl2->SetType(300+cpositive[j]+cnegative[i]);
1558 if(repa->GetUseBadChannelsInClusterFinderSSD()==kTRUE) {
1560 //---------------------------------------------------------
1561 // recover crosses of good 1D clusters with bad strips on the other side
1562 // Note1: at first iteration skip modules with a bad side (or almost), (would produce too many fake!)
1563 // Note2: for modules with a bad side see below
1565 AliITSCalibrationSSD* cal = (AliITSCalibrationSSD*)GetResp(fModule);
1566 Int_t countPbad=0, countNbad=0;
1567 for(Int_t ib=0; ib<768; ib++) {
1568 if(cal->IsPChannelBad(ib)) countPbad++;
1569 if(cal->IsNChannelBad(ib)) countNbad++;
1571 // AliInfo(Form("module %d has %d P- and %d N-bad strips",fModule,countPbad,countNbad));
1573 if( (countPbad<100) && (countNbad<100) ) { // no bad side!!
1575 for (Int_t i=0; i<np; i++) { // loop over Nside 1Dclusters with no crosses
1576 if(cnegative[i]) continue; // if intersecting Pside clusters continue;
1578 // for(Int_t ib=0; ib<768; ib++) { // loop over all Pstrips
1579 for(Int_t ib=15; ib<753; ib++) { // loop over all Pstrips
1581 if(cal->IsPChannelBad(ib)) { // check if strips is bad
1582 Float_t yN=pos[i].GetY();
1584 seg->GetPadCxz(1.*ib, yN, xt, zt);
1587 // bad Pstrip is crossing the Nside 1Dcluster -> create recpoint
1589 if ( (TMath::Abs(xt)<hwSSD) && (TMath::Abs(zt)<hlSSD) ) {
1590 Double_t loc[3]={xt,0.,zt},trk[3]={0.,0.,0.};
1591 mT2L->MasterToLocal(loc,trk);
1594 lp[4]=pos[i].GetQ(); //Q
1595 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1596 for (Int_t ilab=0;ilab<3;ilab++) milab[ilab] = pos[i].GetLabel(ilab);
1597 CheckLabels2(milab);
1598 milab[3]=( (i<<10) << 10 ) + idet; // pos|neg|det
1599 Int_t info[3] = {pos[i].GetNd(),0,fNlayer[fModule]};
1601 lp[2]=4.968e-06; // 0.00223*0.00223; //SigmaY2
1602 lp[3]=0.012; // 0.110*0.110; //SigmaZ2
1603 lp[5]=-0.00012; // out-of-diagonal element of covariance matrix
1610 AliITSRecPoint * cl2;
1611 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
1612 cl2->SetChargeRatio(1.);
1615 } // cross is within the detector
1621 } // end loop over Pstrips
1623 } // end loop over Nside 1D clusters
1625 for (Int_t j=0; j<nn; j++) { // loop over Pside 1D clusters with no crosses
1626 if(cpositive[j]) continue;
1628 // for(Int_t ib=0; ib<768; ib++) { // loop over all Nside strips
1629 for(Int_t ib=15; ib<753; ib++) { // loop over all Nside strips
1631 if(cal->IsNChannelBad(ib)) { // check if strip is bad
1632 Float_t yP=neg[j].GetY();
1634 seg->GetPadCxz(yP, 1.*ib, xt, zt);
1637 // bad Nstrip is crossing the Pside 1Dcluster -> create recpoint
1639 if ( (TMath::Abs(xt)<hwSSD) && (TMath::Abs(zt)<hlSSD) ) {
1640 Double_t loc[3]={xt,0.,zt},trk[3]={0.,0.,0.};
1641 mT2L->MasterToLocal(loc,trk);
1644 lp[4]=neg[j].GetQ(); //Q
1645 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1646 for (Int_t ilab=0;ilab<3;ilab++) milab[ilab] = neg[j].GetLabel(ilab);
1647 CheckLabels2(milab);
1648 milab[3]=( j << 10 ) + idet; // pos|neg|det
1649 Int_t info[3]={0,(Int_t)neg[j].GetNd(),fNlayer[fModule]};
1651 lp[2]=4.968e-06; // 0.00223*0.00223; //SigmaY2
1652 lp[3]=0.012; // 0.110*0.110; //SigmaZ2
1653 lp[5]=-0.00012; // out-of-diagonal element of covariance matrix
1660 AliITSRecPoint * cl2;
1661 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
1662 cl2->SetChargeRatio(1.);
1665 } // cross is within the detector
1670 } // end loop over Nstrips
1671 } // end loop over Pside 1D clusters
1675 //---------------------------------------------------------
1677 else if( (countPbad>700) && (countNbad<100) ) { // bad Pside!!
1679 for (Int_t i=0; i<np; i++) { // loop over Nside 1Dclusters with no crosses
1680 if(cnegative[i]) continue; // if intersecting Pside clusters continue;
1683 Float_t yN=pos[i].GetY();
1685 if (seg->GetLayer()==5) yP = yN + (7.6/1.9);
1686 else yP = yN - (7.6/1.9);
1687 seg->GetPadCxz(yP, yN, xt, zt);
1689 if ( (TMath::Abs(xt)<hwSSD) && (TMath::Abs(zt)<hlSSD) ) {
1690 Double_t loc[3]={xt,0.,zt},trk[3]={0.,0.,0.};
1691 mT2L->MasterToLocal(loc,trk);
1694 lp[4]=pos[i].GetQ(); //Q
1695 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1696 for (Int_t ilab=0;ilab<3;ilab++) milab[ilab] = pos[i].GetLabel(ilab);
1697 CheckLabels2(milab);
1698 milab[3]=( (i<<10) << 10 ) + idet; // pos|neg|det
1699 Int_t info[3] = {(Int_t)pos[i].GetNd(),0,fNlayer[fModule]};
1701 lp[2]=0.00098; // 0.031*0.031; //SigmaY2
1702 lp[3]=1.329; // 1.15*1.15; //SigmaZ2
1704 if(info[0]>1) lp[2]=0.00097;
1706 AliITSRecPoint * cl2;
1707 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
1708 cl2->SetChargeRatio(1.);
1711 } // cross is within the detector
1715 } // end loop over Nside 1D clusters
1717 } // bad Pside module
1719 else if( (countNbad>700) && (countPbad<100) ) { // bad Nside!!
1721 for (Int_t j=0; j<nn; j++) { // loop over Pside 1D clusters with no crosses
1722 if(cpositive[j]) continue;
1725 Float_t yP=neg[j].GetY();
1727 if (seg->GetLayer()==5) yN = yP - (7.6/1.9);
1728 else yN = yP + (7.6/1.9);
1729 seg->GetPadCxz(yP, yN, xt, zt);
1731 if ( (TMath::Abs(xt)<hwSSD) && (TMath::Abs(zt)<hlSSD) ) {
1732 Double_t loc[3]={xt,0.,zt},trk[3]={0.,0.,0.};
1733 mT2L->MasterToLocal(loc,trk);
1736 lp[4]=neg[j].GetQ(); //Q
1737 for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1738 for (Int_t ilab=0;ilab<3;ilab++) milab[ilab] = neg[j].GetLabel(ilab);
1739 CheckLabels2(milab);
1740 milab[3]=( j << 10 ) + idet; // pos|neg|det
1741 Int_t info[3] = {0,(Int_t)neg[j].GetNd(),fNlayer[fModule]};
1743 lp[2]=7.27e-05; // 0.0085*0.0085; //SigmaY2
1744 lp[3]=1.33; // 1.15*1.15; //SigmaZ2
1746 if(info[1]>1) lp[2]=6.91e-05;
1748 AliITSRecPoint * cl2;
1749 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
1750 cl2->SetChargeRatio(1.);
1753 } // cross is within the detector
1757 } // end loop over Pside 1D clusters
1759 } // bad Nside module
1761 //---------------------------------------------------------
1763 } // use bad channels
1765 //cout<<ncl<<" clusters for this module"<<endl;
1767 delete [] cnegative;
1769 delete [] negativepair;
1770 delete [] cpositive;
1772 delete [] positivepair;