]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSClusterFinderV2SSD.cxx
Fix a Coverity warning: missing array deletion under certain circumstances (M. van...
[u/mrichter/AliRoot.git] / ITS / AliITSClusterFinderV2SSD.cxx
1 /**************************************************************************
2  * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /* $Id$ */
17
18 ////////////////////////////////////////////////////////////////////////////
19 //            Implementation of the ITS clusterer V2 class                //
20 //                                                                        //
21 //          Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch            //
22 //          Last revision: 13-05-09 Enrico Fragiacomo                     //
23 //                                  enrico.fragiacomo@ts.infn.it          //
24 //                                                                        //
25 ///////////////////////////////////////////////////////////////////////////
26
27 #include <Riostream.h>
28 #include "AliLog.h"
29
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"
43
44 Short_t *AliITSClusterFinderV2SSD::fgPairs = 0x0;
45 Int_t    AliITSClusterFinderV2SSD::fgPairsSize = 0;
46 const Float_t  AliITSClusterFinderV2SSD::fgkThreshold = 5.;
47
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
65
66 ClassImp(AliITSClusterFinderV2SSD)
67
68
69 AliITSClusterFinderV2SSD::AliITSClusterFinderV2SSD(AliITSDetTypeRec* dettyp):AliITSClusterFinder(dettyp),
70                                                                              fLastSSD1(AliITSgeomTGeo::GetModuleIndex(6,1,1)-1)
71 {
72 //Default constructor
73
74 }
75  
76 //______________________________________________________________________
77 AliITSClusterFinderV2SSD::AliITSClusterFinderV2SSD(const AliITSClusterFinderV2SSD &cf) : AliITSClusterFinder(cf),                                               fLastSSD1(cf.fLastSSD1)
78 {
79   // Copy constructor
80 }
81
82 //______________________________________________________________________
83 AliITSClusterFinderV2SSD& AliITSClusterFinderV2SSD::operator=(const AliITSClusterFinderV2SSD&  cf ){
84   // Assignment operator
85
86   this->~AliITSClusterFinderV2SSD();
87   new(this) AliITSClusterFinderV2SSD(cf);
88   return *this;
89 }
90
91
92 void AliITSClusterFinderV2SSD::FindRawClusters(Int_t mod){
93
94   //Find clusters V2
95   SetModule(mod);
96   FindClustersSSD(fDigits);
97
98 }
99
100 void AliITSClusterFinderV2SSD::FindClustersSSD(TClonesArray *alldigits) {
101   //------------------------------------------------------------
102   // Actual SSD cluster finder
103   //------------------------------------------------------------
104   Int_t smaxall=alldigits->GetEntriesFast();
105   if (smaxall==0) return;
106
107
108   //---------------------------------------
109   // load recoparam and calibration
110   // 
111   static AliITSRecoParam *repa = NULL;  
112   if(!repa){
113     repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
114     if(!repa){
115       repa = AliITSRecoParam::GetHighFluxParam();
116       AliWarning("Using default AliITSRecoParam class");
117     }
118   }
119
120   AliITSCalibrationSSD* cal = (AliITSCalibrationSSD*)GetResp(fModule);
121   Float_t gain=0;
122   Float_t noise=0;
123   //---------------------------------------
124
125
126   //------------------------------------
127   // fill the digits array with zero-suppression condition
128   // Signal is converted in KeV
129   //
130   TObjArray digits;
131   for (Int_t i=0;i<smaxall; i++){
132     AliITSdigitSSD *d=(AliITSdigitSSD*)alldigits->UncheckedAt(i);
133
134     if(d->IsSideP()) noise = cal->GetNoiseP(d->GetStripNumber());  
135     else noise = cal->GetNoiseN(d->GetStripNumber());
136     if (d->GetSignal()<3.*noise) continue;
137
138     if(d->IsSideP()) gain = cal->GetGainP(d->GetStripNumber());  
139     else gain = cal->GetGainN(d->GetStripNumber());
140
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));
144
145     digits.AddLast(d);
146   }
147   Int_t smax = digits.GetEntriesFast();
148   if (smax==0) return;
149   //------------------------------------
150
151   
152   const Int_t kMax=1000;
153   Int_t np=0, nn=0; 
154   Ali1Dcluster pos[kMax], neg[kMax];
155   Float_t y=0., q=0., qmax=0.; 
156   Int_t lab[4]={-2,-2,-2,-2};  
157   Bool_t flag5 = 0;
158   
159   /*
160   cout<<"-----------------------------"<<endl;
161   cout<<"this is module "<<fModule;
162   cout<<endl;
163   cout<<endl;
164   */
165
166   //--------------------------------------------------------
167   // start 1D-clustering from the first digit in the digits array
168   //
169   AliITSdigitSSD *d=(AliITSdigitSSD*)digits.UncheckedAt(0);
170   q += d->GetSignal();
171   y += d->GetCoord2()*d->GetSignal();
172   qmax=d->GetSignal();
173   lab[0]=d->GetTrack(0); lab[1]=d->GetTrack(1); lab[2]=d->GetTrack(2);
174   
175   if(d->IsSideP()) {
176     noise = cal->GetNoiseP(d->GetStripNumber());  
177     gain = cal->GetGainP(d->GetStripNumber());
178   }
179   else {
180     noise = cal->GetNoiseN(d->GetStripNumber());
181     gain = cal->GetGainN(d->GetStripNumber());
182   }  
183   noise*=gain;
184   noise=cal->ADCToKeV(noise); // converts noise in KeV from ADC units
185
186   if(qmax>fgkThreshold*noise) flag5=1; // seed for the cluster
187
188   /*
189   cout<<d->GetSignal()<<" "<<noise<<" "<<flag5<<" "<<
190     d->GetCoord1()<<" "<<d->GetCoord2()<<endl;
191   */
192
193   Int_t curr=d->GetCoord2();
194   Int_t flag=d->GetCoord1();
195
196   // Note: the first side which will be processed is supposed to be the 
197   // P-side which is neg
198   Int_t *n=&nn;
199   Ali1Dcluster *c=neg;
200   if(flag) {n=&np; c=pos;} // in case we have only Nstrips (P was bad!)
201
202   Int_t nd=1;
203   Int_t milab[10];
204   for (Int_t ilab=0;ilab<10;ilab++){
205     milab[ilab]=-2;
206   }
207   milab[0]=d->GetTrack(0); milab[1]=d->GetTrack(1); milab[2]=d->GetTrack(2);
208
209
210   //----------------------------------------------------------
211   // search for neighboring digits
212   //
213   for (Int_t s=1; s<smax; s++) {
214       d=(AliITSdigitSSD*)digits.UncheckedAt(s);      
215       Int_t strip=d->GetCoord2();
216
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()) ) ) {
221
222         if(flag5) {
223           //cout<<"here1"<<endl;
224          c[*n].SetY(y/q);
225          c[*n].SetQ(q);
226          c[*n].SetNd(nd);
227          CheckLabels2(milab);
228          c[*n].SetLabels(milab);
229
230          if(repa->GetUseUnfoldingInClusterFinderSSD()==kTRUE) {
231            // Note: fUseUnfoldingInClusterFinderSSD=kFALSE by default in RecoParam
232
233            //Split suspiciously big cluster
234            if (nd>4&&nd<25) {
235              c[*n].SetY(y/q-0.25*nd);
236              c[*n].SetQ(0.5*q);
237              (*n)++;
238              if (*n==kMax) {
239                Error("FindClustersSSD","Too many 1D clusters !");
240                return;
241              }
242              c[*n].SetY(y/q+0.25*nd);
243              c[*n].SetQ(0.5*q);
244              c[*n].SetNd(nd);
245              c[*n].SetLabels(milab);
246            }     
247            
248          } // unfolding is on
249
250          (*n)++;
251          if (*n==kMax) {
252           Error("FindClustersSSD","Too many 1D clusters !");
253           return;
254          }
255
256         } // flag5 set
257
258          // reset everything
259          y=q=qmax=0.;
260          nd=0;
261          flag5=0;
262          lab[0]=lab[1]=lab[2]=-2;
263          for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
264
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;} }
269
270       } // end create new 1D cluster from previous neighboring digits
271
272       // continues adding digits to the previous cluster 
273       // or start a new one 
274       flag=d->GetCoord1();
275       q += d->GetSignal();
276       y += d->GetCoord2()*d->GetSignal();
277       nd++;
278
279       if(d->IsSideP()) {
280         noise = cal->GetNoiseP(d->GetStripNumber());  
281         gain = cal->GetGainP(d->GetStripNumber());
282       }
283       else {
284         noise = cal->GetNoiseN(d->GetStripNumber());
285         gain = cal->GetGainN(d->GetStripNumber());
286       }
287       noise*=gain;
288       noise=cal->ADCToKeV(noise); // converts the charge in KeV from ADC units
289
290       if(d->GetSignal()>fgkThreshold*noise) flag5=1;
291
292       /*
293   cout<<d->GetSignal()<<" "<<noise<<" "<<flag5<<" "<<
294     d->GetCoord1()<<" "<<d->GetCoord2()<<endl;
295       */
296
297       if (d->GetSignal()>qmax) {
298          qmax=d->GetSignal();
299          lab[0]=d->GetTrack(0); lab[1]=d->GetTrack(1); lab[2]=d->GetTrack(2);
300       }
301       for (Int_t ilab=0;ilab<10;ilab++) {
302         if (d->GetTrack(ilab)>=0) AddLabel(milab, (d->GetTrack(ilab))); 
303       }
304       curr=strip;
305
306
307   } // loop over digits, no more digits in the digits array
308
309
310   // add the last 1D cluster 
311   if(flag5) {
312
313     //  cout<<"here2"<<endl;
314
315     c[*n].SetY(y/q);
316     c[*n].SetQ(q);
317     c[*n].SetNd(nd);
318     c[*n].SetLabels(lab);
319     
320     if(repa->GetUseUnfoldingInClusterFinderSSD()==kTRUE) {
321       
322       //Split suspiciously big cluster
323       if (nd>4 && nd<25) {
324         c[*n].SetY(y/q-0.25*nd);
325         c[*n].SetQ(0.5*q);
326         (*n)++;
327         if (*n==kMax) {
328           Error("FindClustersSSD","Too many 1D clusters !");
329           return;
330         }
331         c[*n].SetY(y/q+0.25*nd);
332         c[*n].SetQ(0.5*q);
333         c[*n].SetNd(nd);
334         c[*n].SetLabels(lab);
335       }
336     } // unfolding is on
337     
338     (*n)++;
339     if (*n==kMax) {
340       Error("FindClustersSSD","Too many 1D clusters !");
341       return;
342     }
343
344   } // if flag5 last 1D cluster added
345
346
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)
352   //
353   //  cout<<nn<<" Pside and "<<np<<" Nside clusters"<<endl;
354   
355   AliITSRecPointContainer* rpc = AliITSRecPointContainer::Instance();   
356   if (nn*np > 0) { 
357     TClonesArray* clusters = rpc->UncheckedGetClusters(fModule);
358     clusters->Clear();
359     FindClustersSSD(neg, nn, pos, np, clusters);
360     TIter itr(clusters);
361     AliITSRecPoint *irp;
362     while ((irp = (AliITSRecPoint*)itr.Next()))  fDetTypeRec->AddRecPoint(*irp);
363   }
364   //-----------------------------------------------------
365 }
366
367
368 void AliITSClusterFinderV2SSD::RawdataToClusters(AliRawReader* rawReader){
369
370     //------------------------------------------------------------
371   // This function creates ITS clusters from raw data
372   //------------------------------------------------------------
373   rawReader->Reset();
374   AliITSRawStreamSSD inputSSD(rawReader);
375   FindClustersSSD(&inputSSD);
376   
377 }
378
379
380 void AliITSClusterFinderV2SSD::FindClustersSSD(AliITSRawStreamSSD* input) 
381 {
382   //------------------------------------------------------------
383   // Actual SSD cluster finder for raw data
384   //------------------------------------------------------------
385
386   AliITSRecPointContainer* rpc = AliITSRecPointContainer::Instance();
387   static AliITSRecoParam *repa = NULL;
388   if(!repa){
389     repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
390     if(!repa){
391       repa = AliITSRecoParam::GetHighFluxParam();
392       AliWarning("Using default AliITSRecoParam class");
393     }
394   }
395   Int_t nClustersSSD = 0;
396   const Int_t kNADC = 12;
397   const Int_t kMaxADCClusters = 1000;
398
399   Int_t strips[kNADC][2][kMaxADCClusters][2]; // [ADC],[side],[istrip], [0]=istrip [1]=signal
400   Int_t nStrips[kNADC][2];
401
402   for( int i=0; i<kNADC; i++ ){
403     nStrips[i][0] = 0;
404     nStrips[i][1] = 0;
405   }
406
407   Int_t ddl = -1;
408   Int_t ad = -1;
409   
410   //*
411   //* Loop over modules DDL+AD
412   //*
413   
414   while (kTRUE) {
415
416     bool next = input->Next();
417     
418     //* 
419     //* Continue if corrupted input
420     //*
421
422     if( (!next)&&(input->flag) ){
423      AliWarning(Form("ITSClustersFinderSSD: Corrupted data: warning from RawReader"));
424       continue; 
425     }
426
427     Int_t newDDL = input->GetDDL(); 
428     Int_t newAD = input->GetAD();
429
430     if( next ){
431       if( newDDL<0 || newDDL>15 ){
432         AliWarning(Form("ITSClustersFinderSSD: Corrupted data: wrong DDL number (%d)",newDDL));
433         continue;
434       }
435       
436       if( newAD<1 || newAD>9 ){
437         AliWarning(Form("ITSClustersFinderSSD: Corrupted data: wrong AD number (%d)",newAD));
438         continue;
439       }
440     }
441
442     bool newModule = ( !next || ddl!= newDDL || ad!=newAD );
443
444     if( newModule && ddl>=0 && ad>=0 ){ 
445
446       //*
447       //* Reconstruct the previous block of 12 modules --- actual clusterfinder
448       //* 
449       //cout<<endl;
450       for( int adc = 0; adc<kNADC; adc++ ){
451         
452         //* 1D clusterfinder
453
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 );
458         
459         if( fModule<0 ){
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 
462           continue;
463         }
464
465         AliITSCalibrationSSD* cal = (AliITSCalibrationSSD*)fDetTypeRec->GetCalibrationModel(fModule);
466         if( !cal ){
467           AliWarning(Form("ITSClustersFinderSSD: No calibration found for module (ddl %d ad %d adc %d)",ddl,ad,adc));       
468           continue;
469         }
470
471         Float_t dStrip = 0;
472
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));
477             dStrip = 0;
478           }     
479         }
480         
481         for( int side=0; side<=1; side++ ){
482
483           Int_t lab[3]={-2,-2,-2};
484           Float_t q = 0.;
485           Float_t y = 0.;
486           Int_t nDigits = 0;
487           Int_t ostrip = -2;
488           Bool_t snFlag = 0;
489           
490           Int_t n = nStrips[adc][side];
491           for( int istr = 0; istr<n+1; istr++ ){
492             
493             bool stripOK = 1;
494             Int_t strip=0;
495             Float_t signal=0.0, noise=0.0, gain=0.0;
496             
497             if( istr<n ){
498               strip = strips[adc][side][istr][0];
499               signal = strips[adc][side][istr][1];
500               
501               //cout<<"strip "<<adc<<" / "<<side<<": "<<strip<<endl;
502
503               if( cal ){
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) 
508                             );
509               }
510             } else stripOK = 0; // end of data
511
512             bool newCluster = ( (abs(strip-ostrip)!=1) || !stripOK );     
513                 
514             if( newCluster ){
515
516               //* Store the previous cluster
517
518               if( nDigits>0 && q>0 && snFlag ){
519
520                 if (nClusters1D[side] >= kMaxADCClusters-1 ) {
521                   AliWarning("HLT ClustersFinderSSD: Too many 1D clusters !");
522                 }else {
523                   
524                   Ali1Dcluster &cluster = clusters1D[side][nClusters1D[side]++];
525                   cluster.SetY( y / q + dStrip);
526                   cluster.SetQ(q);
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
531
532                   if( repa->GetUseUnfoldingInClusterFinderSSD()
533                       && nDigits > 4 && nDigits < 25 
534                       ){
535                     cluster.SetY(y/q + dStrip - 0.25*nDigits);      
536                     cluster.SetQ(0.5*q);          
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);      
542                   } // unfolding is on          
543                 }
544               }
545               y = q = 0.;
546               nDigits = 0;
547               snFlag = 0;
548
549             } //* End store the previous cluster
550
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
558               y += strip * signal;        
559               nDigits++;
560               //nstat[side]++;
561               ostrip = strip;
562
563             }
564           } //* end loop over strips
565
566         } //* end loop over ADC sides
567         
568
569         //* 2D clusterfinder
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;
575         }
576
577         //cout<<"SG: "<<ddl<<" "<<ad<<" "<<adc<<": strips "<<nstat[0]<<"+"<<nstat[1]<<", clusters 1D= "<<nClusters1D[0]<<" + "<<nClusters1D[1]<<", 2D= "<<clusters.size()<<endl;
578
579       }//* end loop over adc
580       
581     }//* end of reconstruction of previous block of 12 modules
582     
583     if( newModule ){
584       
585       //*
586       //* Clean up arrays and set new module
587       //* 
588       
589       for( int i=0; i<kNADC; i++ ){
590         nStrips[i][0] = 0;
591         nStrips[i][1] = 0;
592       }     
593       ddl = newDDL;
594       ad = newAD;
595     } 
596     
597
598     //*
599     //* Exit main loop when there is no more input
600     //* 
601
602     if( !next ) break;
603     
604     //* 
605     //* Fill the current strip information
606     //* 
607
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));
611       continue;
612     }
613
614     if( adc>7 ) adc-= 2; // shift ADC numbers 8-13 to 6-11
615     
616     Bool_t side = input->GetSideFlag();
617     Int_t strip = input->GetStrip();
618     Int_t signal = input->GetSignal();
619     
620
621     //cout<<"SSD: "<<ddl<<" "<<ad<<" "<<adc<<" "<<side<<" "<<strip<<" : "<<signal<<endl;
622
623     if( strip>767 ){    
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) );
626       continue;
627     }
628     if (strip < 0) continue;
629     
630     int &n = nStrips[adc][side];
631     if( n >0 ){
632       Int_t oldStrip = strips[adc][side][n-1][0];
633
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 ));
637         continue;
638       }
639     }
640     strips[adc][side][n][0] = strip;
641     strips[adc][side][n][1] = signal;    
642     n++;
643
644     //cout<<"SSD: "<<input->GetDDL()<<" "<<input->GetAD()<<" "
645     //<<input->GetADC()<<" "<<input->GetSideFlag()<<" "<<((int)input->GetStrip())<<" "<<strip<<" : "<<input->GetSignal()<<endl;
646
647   } //* End main loop over the input
648   
649   AliDebug(1,Form("found clusters in ITS SSD: %d", nClustersSSD));
650 }
651
652
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   //------------------------------------------------------------
660
661   const TGeoHMatrix *mT2L=AliITSgeomTGeo::GetTracking2LocalMatrix(fModule);
662
663   //---------------------------------------
664   // load recoparam
665   // 
666   static AliITSRecoParam *repa = NULL;  
667   if(!repa){
668     repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
669     if(!repa){
670       repa = AliITSRecoParam::GetHighFluxParam();
671       AliWarning("Using default AliITSRecoParam class");
672     }
673   }
674
675 //  TClonesArray &cl=*clusters;
676   
677   AliITSsegmentationSSD *seg = dynamic_cast<AliITSsegmentationSSD*>(fDetTypeRec->GetSegmentationModel(2));
678   if (fModule>fLastSSD1) 
679     seg->SetLayer(6);
680   else 
681     seg->SetLayer(5);
682
683   Float_t hwSSD = seg->Dx()*1e-4/2;
684   Float_t hlSSD = seg->Dz()*1e-4/2;
685
686   Int_t idet=fNdet[fModule];
687   Int_t ncl=0;
688
689   //
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;}
700
701   if ((np*nn) > fgPairsSize) {
702
703     if (fgPairs) delete [] fgPairs;
704     fgPairsSize = 4*np*nn;
705     fgPairs = new Short_t[fgPairsSize];
706   }
707   memset(fgPairs,0,sizeof(Short_t)*np*nn);
708
709   //
710   // find available pairs
711   //
712   Int_t ncross = 0;
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();
719
720       Float_t xt, zt;
721       seg->GetPadCxz(yn, yp, xt, zt);
722       //cout<<yn<<" "<<yp<<" "<<xt<<" "<<zt<<endl;
723       
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
730           positivepair[ip] =i;
731           cnegative[i]++;  //counters
732           cpositive[j]++;
733           ncross++;     
734           fgPairs[i*nn+j]=100;
735         }
736         else
737           AliError(Form("Index out of range: ip=%d, in=%d",ip,in));
738       }
739     }
740   }
741
742   if (!ncross) {
743     delete [] cnegative;
744     delete [] cused1;
745     delete [] negativepair;
746     delete [] cpositive;
747     delete [] cused2;
748     delete [] positivepair;
749     return;
750   }
751 //why not to allocate memorey here?  if(!clusters) clusters = new TClonesArray("AliITSRecPoint", ncross);
752   
753   /* //
754   // try to recover points out of but close to the module boundaries 
755   //
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();
764       
765       Float_t xt, zt;
766       seg->GetPadCxz(yn, yp, xt, zt);
767       
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
777           positivepair[ip] =i;
778           cnegative[i]++;  //counters
779           cpositive[j]++;       
780           fgPairs[i*nn+j]=100;
781         }
782         else
783           AliError(Form("Index out of range: ip=%d, in=%d",ip,in));
784       }
785     }
786   }
787   */
788
789   //
790   Float_t lp[6];
791   Int_t milab[10];
792   Double_t ratio;
793   
794
795   if(repa->GetUseChargeMatchingInClusterFinderSSD()==kTRUE) {
796
797
798     //
799     // sign gold tracks
800     //
801     for (Int_t ip=0;ip<np;ip++){
802       Float_t xbest=1000,zbest=1000,qbest=0;
803       //
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];      
808
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)
812           cused1[ip]++; 
813           cused2[j]++;
814           continue;
815         }
816
817         ratio = (pos[ip].GetQ()-neg[j].GetQ())/(pos[ip].GetQ()+neg[j].GetQ());
818         //cout<<"ratio="<<ratio<<endl;
819
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
822
823         //
824         Float_t yn=neg[j].GetY();
825         
826         Float_t xt, zt;
827         seg->GetPadCxz(yn, yp, xt, zt);
828         
829         xbest=xt; zbest=zt; 
830
831         
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
834         
835         {
836           Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
837           mT2L->MasterToLocal(loc,trk);
838           lp[0]=trk[1];
839           lp[1]=trk[2];
840         }
841         lp[4]=qbest;        //Q
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);
846         }
847         //
848         CheckLabels2(milab);
849         milab[3]=(((ip<<10) + j)<<10) + idet; // pos|neg|det
850         Int_t info[3] = {pos[ip].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
851
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
859           lp[5]=-6.48e-05;
860         }
861         else {
862           lp[2]=4.80e-06;      // 0.00219*0.00219
863           lp[3]=0.0093;        // 0.0964*0.0964;
864           if (info[0]==1) {
865             lp[5]=-0.00014;
866           }
867           else { 
868             lp[2]=2.79e-06;    // 0.0017*0.0017; 
869             lp[3]=0.00935;     // 0.967*0.967;
870             lp[5]=-4.32e-05;
871           }
872         }
873
874         AliITSRecPoint * cl2;
875     cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
876           
877     cl2->SetChargeRatio(ratio);         
878     cl2->SetType(1);
879     fgPairs[ip*nn+j]=1;
880
881     if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
882       cl2->SetType(2);
883       fgPairs[ip*nn+j]=2;
884     }
885
886     if(pos[ip].GetQ()==0) cl2->SetType(3);
887     if(neg[j].GetQ()==0) cl2->SetType(4);
888
889     cused1[ip]++;
890     cused2[j]++;
891
892         ncl++;
893       }
894     }
895     
896     for (Int_t ip=0;ip<np;ip++){
897       Float_t xbest=1000,zbest=1000,qbest=0;
898       //
899       //
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();
906         
907
908
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) ) { // 
912           
913           //
914           // add first pair
915           if ( (fgPairs[ip*nn+in]==100)&&(pos[ip].GetQ() ) ) {  //
916             
917             Float_t yp=pos[ip].GetY(); 
918             Float_t yn=neg[in].GetY();
919             
920             Float_t xt, zt;
921             seg->GetPadCxz(yn, yp, xt, zt);
922             
923             xbest=xt; zbest=zt; 
924
925             qbest =pos[ip].GetQ();
926             Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
927             mT2L->MasterToLocal(loc,trk);
928             lp[0]=trk[1];
929             lp[1]=trk[2];
930             
931             lp[4]=qbest;        //Q
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);
936             }
937             //
938             CheckLabels2(milab);
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]};
942             
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
950           lp[5]=-6.48e-05;
951         }
952         else {
953           lp[2]=4.80e-06;      // 0.00219*0.00219
954           lp[3]=0.0093;        // 0.0964*0.0964;
955           if (info[0]==1) {
956             lp[5]=-0.00014;
957           }
958           else { 
959             lp[2]=2.79e-06;    // 0.0017*0.0017; 
960             lp[3]=0.00935;     // 0.967*0.967;
961             lp[5]=-4.32e-05;
962           }
963         }
964
965         AliITSRecPoint * cl2;
966               cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
967               cl2->SetChargeRatio(ratio);       
968               cl2->SetType(5);
969               fgPairs[ip*nn+in] = 5;
970               if ((pos[ip].GetNd()+neg[in].GetNd())>6){ //multi cluster
971                 cl2->SetType(6);
972                 fgPairs[ip*nn+in] = 6;
973               }     
974             ncl++;
975           }
976           
977           
978           //
979           // add second pair
980           
981           //    if (!(cused1[ip2] || cused2[in])){  //
982           if ( (fgPairs[ip2*nn+in]==100) && (pos[ip2].GetQ()) ) {
983             
984             Float_t yp=pos[ip2].GetY();
985             Float_t yn=neg[in].GetY();
986             
987             Float_t xt, zt;
988             seg->GetPadCxz(yn, yp, xt, zt);
989             
990             xbest=xt; zbest=zt; 
991
992             qbest =pos[ip2].GetQ();
993             
994             Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
995             mT2L->MasterToLocal(loc,trk);
996             lp[0]=trk[1];
997             lp[1]=trk[2];
998             
999             lp[4]=qbest;        //Q
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);
1004             }
1005             //
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]};
1010             
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
1018           lp[5]=-6.48e-05;
1019         }
1020         else {
1021           lp[2]=4.80e-06;      // 0.00219*0.00219
1022           lp[3]=0.0093;        // 0.0964*0.0964;
1023           if (info[0]==1) {
1024             lp[5]=-0.00014;
1025           }
1026           else { 
1027             lp[2]=2.79e-06;    // 0.0017*0.0017; 
1028             lp[3]=0.00935;     // 0.967*0.967;
1029             lp[5]=-4.32e-05;
1030           }
1031         }
1032
1033             AliITSRecPoint * cl2;
1034               cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
1035               
1036               cl2->SetChargeRatio(ratio);       
1037               cl2->SetType(5);
1038               fgPairs[ip2*nn+in] =5;
1039               if ((pos[ip2].GetNd()+neg[in].GetNd())>6){ //multi cluster
1040                 cl2->SetType(6);
1041                 fgPairs[ip2*nn+in] =6;
1042               }
1043             ncl++;
1044           }
1045           
1046           cused1[ip]++;
1047           cused1[ip2]++;
1048           cused2[in]++;
1049
1050         } // charge matching condition
1051
1052       } // 2 Pside cross 1 Nside
1053     } // loop over Pside clusters
1054     
1055     
1056       
1057       //  
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();
1067         //
1068         
1069
1070         ratio = (pcharge-pos[ip].GetQ())/(pcharge+pos[ip].GetQ());
1071         if ( (TMath::Abs(ratio)<0.2) && (pcharge!=0) ) {
1072
1073           /*
1074         if ( (TMath::Abs(pcharge-pos[ip].GetQ())<30) &&  // charge matching 
1075              (pcharge!=0) ) { // reject combinations of bad strips
1076           */
1077
1078
1079           //
1080           // add first pair
1081           //    if (!(cused1[ip]||cused2[jn])){
1082           if ( (fgPairs[ip*nn+jn]==100) && (neg[jn].GetQ()) ) {  //
1083             
1084             Float_t yn=neg[jn].GetY(); 
1085             Float_t yp=pos[ip].GetY();
1086
1087             Float_t xt, zt;
1088             seg->GetPadCxz(yn, yp, xt, zt);
1089             
1090             xbest=xt; zbest=zt; 
1091
1092             qbest =neg[jn].GetQ();
1093
1094             {
1095               Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
1096               mT2L->MasterToLocal(loc,trk);
1097               lp[0]=trk[1];
1098               lp[1]=trk[2];
1099           }
1100           
1101           lp[4]=qbest;        //Q
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);
1106           }
1107           //
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]};
1112
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
1120           lp[5]=-6.48e-05;
1121         }
1122         else {
1123           lp[2]=4.80e-06;      // 0.00219*0.00219
1124           lp[3]=0.0093;        // 0.0964*0.0964;
1125           if (info[0]==1) {
1126             lp[5]=-0.00014;
1127           }
1128           else { 
1129             lp[2]=2.79e-06;    // 0.0017*0.0017; 
1130             lp[3]=0.00935;     // 0.967*0.967;
1131             lp[5]=-4.32e-05;
1132           }
1133         }
1134
1135           AliITSRecPoint * cl2;
1136             cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
1137
1138             cl2->SetChargeRatio(ratio);         
1139             cl2->SetType(7);
1140             fgPairs[ip*nn+jn] =7;
1141             if ((pos[ip].GetNd()+neg[jn].GetNd())>6){ //multi cluster
1142               cl2->SetType(8);
1143               fgPairs[ip*nn+jn]=8;
1144             }
1145           ncl++;
1146         }
1147         //
1148         // add second pair
1149         //      if (!(cused1[ip]||cused2[jn2])){
1150         if ( (fgPairs[ip*nn+jn2]==100)&&(neg[jn2].GetQ() ) ) {  //
1151
1152           Float_t yn=neg[jn2].GetY(); 
1153           Double_t yp=pos[ip].GetY(); 
1154
1155           Float_t xt, zt;
1156           seg->GetPadCxz(yn, yp, xt, zt);
1157           
1158           xbest=xt; zbest=zt; 
1159
1160           qbest =neg[jn2].GetQ();
1161
1162           {
1163           Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
1164           mT2L->MasterToLocal(loc,trk);
1165           lp[0]=trk[1];
1166           lp[1]=trk[2];
1167           }
1168
1169           lp[4]=qbest;        //Q
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);
1174           }
1175           //
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]};
1180
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
1188           lp[5]=-6.48e-05;
1189         }
1190         else {
1191           lp[2]=4.80e-06;      // 0.00219*0.00219
1192           lp[3]=0.0093;        // 0.0964*0.0964;
1193           if (info[0]==1) {
1194             lp[5]=-0.00014;
1195           }
1196           else { 
1197             lp[2]=2.79e-06;    // 0.0017*0.0017; 
1198             lp[3]=0.00935;     // 0.967*0.967;
1199             lp[5]=-4.32e-05;
1200           }
1201         }
1202
1203           AliITSRecPoint * cl2;
1204             cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
1205
1206
1207             cl2->SetChargeRatio(ratio);         
1208             fgPairs[ip*nn+jn2]=7;
1209             cl2->SetType(7);
1210             if ((pos[ip].GetNd()+neg[jn2].GetNd())>6){ //multi cluster
1211               cl2->SetType(8);
1212               fgPairs[ip*nn+jn2]=8;
1213             }
1214           ncl++;
1215         }
1216         cused1[ip]++;
1217         cused2[jn]++;
1218         cused2[jn2]++;
1219
1220         } // charge matching condition
1221
1222       } // 2 Nside cross 1 Pside
1223     } // loop over Pside clusters
1224
1225   
1226     
1227     for (Int_t ip=0;ip<np;ip++){
1228
1229       if(cused1[ip]) continue;
1230
1231
1232       Float_t xbest=1000,zbest=1000,qbest=0;
1233       //
1234       // 2x2 clusters
1235       //
1236       if ( (cnegative[ip]==2) && cpositive[negativepair[10*ip]]==2){ 
1237         Float_t minchargediff =4.;
1238         Float_t minchargeratio =0.2;
1239
1240         Int_t j=-1;
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){
1247             j =jc;
1248             minchargediff = TMath::Abs(chargedif);
1249             minchargeratio = TMath::Abs(ratio);
1250           }
1251         }
1252         if (j<0) continue;  // not proper cluster      
1253         
1254
1255         Int_t count =0;
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++;
1260         }
1261         if (count>1) continue;  // more than one "proper" cluster for positive
1262         //
1263         
1264         count =0;
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++;
1269         }
1270         if (count>1) continue;  // more than one "proper" cluster for negative
1271         
1272         Int_t jp = 0;
1273         
1274         count =0;
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++;
1279         }
1280         if (count>1) continue;   
1281         if (fgPairs[ip*nn+j]<100) continue;
1282         //
1283         
1284
1285
1286         //almost gold clusters
1287         Float_t yp=pos[ip].GetY(); 
1288         Float_t yn=neg[j].GetY();      
1289         Float_t xt, zt;
1290         seg->GetPadCxz(yn, yp, xt, zt); 
1291         xbest=xt; zbest=zt; 
1292         qbest=0.5*(pos[ip].GetQ()+neg[j].GetQ());
1293         {
1294           Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
1295           mT2L->MasterToLocal(loc,trk);
1296           lp[0]=trk[1];
1297           lp[1]=trk[2];
1298         }
1299         lp[4]=qbest;        //Q
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);
1304         }
1305         //
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]};
1311
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
1319           lp[5]=-6.48e-05;
1320         }
1321         else {
1322           lp[2]=4.80e-06;      // 0.00219*0.00219
1323           lp[3]=0.0093;        // 0.0964*0.0964;
1324           if (info[0]==1) {
1325             lp[5]=-0.00014;
1326           }
1327           else { 
1328             lp[2]=2.79e-06;    // 0.0017*0.0017; 
1329             lp[3]=0.00935;     // 0.967*0.967;
1330             lp[5]=-4.32e-05;
1331           }
1332         }
1333
1334         AliITSRecPoint * cl2;
1335           cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
1336                   
1337           cl2->SetChargeRatio(ratio);           
1338           cl2->SetType(10);
1339           fgPairs[ip*nn+j]=10;
1340           if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
1341             cl2->SetType(11);
1342             fgPairs[ip*nn+j]=11;
1343           }
1344           cused1[ip]++;
1345           cused2[j]++;      
1346         ncl++;
1347         
1348       } // 2X2
1349     } // loop over Pside 1Dclusters
1350
1351
1352
1353     for (Int_t ip=0;ip<np;ip++){
1354
1355       if(cused1[ip]) continue;
1356
1357
1358       Float_t xbest=1000,zbest=1000,qbest=0;
1359       //
1360       // manyxmany clusters
1361       //
1362       if ( (cnegative[ip]<5) && cpositive[negativepair[10*ip]]<5){ 
1363         Float_t minchargediff =4.;
1364         Int_t j=-1;
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){
1369             j =jc;
1370             minchargediff = TMath::Abs(chargedif);
1371           }
1372         }
1373         if (j<0) continue;  // not proper cluster      
1374         
1375         Int_t count =0;
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++;
1380         }
1381         if (count>1) continue;  // more than one "proper" cluster for positive
1382         //
1383         
1384         count =0;
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++;
1389         }
1390         if (count>1) continue;  // more than one "proper" cluster for negative
1391         
1392         Int_t jp = 0;
1393         
1394         count =0;
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++;
1399         }
1400         if (count>1) continue;   
1401         if (fgPairs[ip*nn+j]<100) continue;
1402         //
1403         
1404         //almost gold clusters
1405         Float_t yp=pos[ip].GetY(); 
1406         Float_t yn=neg[j].GetY();
1407       
1408
1409         Float_t xt, zt;
1410         seg->GetPadCxz(yn, yp, xt, zt);
1411         
1412         xbest=xt; zbest=zt; 
1413
1414         qbest=0.5*(pos[ip].GetQ()+neg[j].GetQ());
1415
1416         {
1417           Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
1418           mT2L->MasterToLocal(loc,trk);
1419           lp[0]=trk[1];
1420           lp[1]=trk[2];
1421         }
1422         lp[4]=qbest;        //Q
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);
1427         }
1428         //
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]};
1434
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
1442           lp[5]=-6.48e-05;
1443         }
1444         else {
1445           lp[2]=4.80e-06;      // 0.00219*0.00219
1446           lp[3]=0.0093;        // 0.0964*0.0964;
1447           if (info[0]==1) {
1448             lp[5]=-0.00014;
1449           }
1450           else { 
1451             lp[2]=2.79e-06;    // 0.0017*0.0017; 
1452             lp[3]=0.00935;     // 0.967*0.967;
1453             lp[5]=-4.32e-05;
1454           }
1455         }
1456
1457         AliITSRecPoint * cl2;
1458           cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
1459                   
1460           cl2->SetChargeRatio(ratio);           
1461           cl2->SetType(12);
1462           fgPairs[ip*nn+j]=12;
1463           if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
1464             cl2->SetType(13);
1465             fgPairs[ip*nn+j]=13;
1466           }
1467           cused1[ip]++;
1468           cused2[j]++;      
1469         ncl++;
1470         
1471       } // manyXmany
1472     } // loop over Pside 1Dclusters
1473     
1474   } // use charge matching
1475   
1476   
1477   // recover all the other crosses
1478   //  
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;
1487
1488       if ((neg[j].GetQ()==0)&&(pos[i].GetQ()==0)) continue; // reject crosses of bad strips!!
1489
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();
1494       
1495       Float_t xt, zt;
1496       seg->GetPadCxz(yn, yp, xt, zt);
1497       
1498       if (TMath::Abs(xt)<hwSSD)
1499       if (TMath::Abs(zt)<hlSSD) {
1500         xbest=xt; zbest=zt; 
1501
1502         qbest=0.5*(pos[i].GetQ()+neg[j].GetQ());
1503
1504         {
1505         Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
1506         mT2L->MasterToLocal(loc,trk);
1507         lp[0]=trk[1];
1508         lp[1]=trk[2];
1509         }
1510         lp[4]=qbest;        //Q
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);
1515         }
1516         //
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]};
1520
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
1528           lp[5]=-6.48e-05;
1529         }
1530         else {
1531           lp[2]=4.80e-06;      // 0.00219*0.00219
1532           lp[3]=0.0093;        // 0.0964*0.0964;
1533           if (info[0]==1) {
1534             lp[5]=-0.00014;
1535           }
1536           else { 
1537             lp[2]=2.79e-06;    // 0.0017*0.0017; 
1538             lp[3]=0.00935;     // 0.967*0.967;
1539             lp[5]=-4.32e-05;
1540           }
1541         }
1542
1543         AliITSRecPoint * cl2;
1544           cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);
1545
1546           cl2->SetChargeRatio(ratio);
1547           cl2->SetType(100+cpositive[j]+cnegative[i]);    
1548
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]);
1551         ncl++;
1552       }
1553     }
1554   }
1555
1556
1557
1558   if(repa->GetUseBadChannelsInClusterFinderSSD()==kTRUE) {
1559     
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 
1564     
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++;
1570     }
1571     //  AliInfo(Form("module %d has %d P- and %d N-bad strips",fModule,countPbad,countNbad));
1572     
1573     if( (countPbad<100) && (countNbad<100) ) { // no bad side!!
1574       
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;
1577         
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
1580           
1581           if(cal->IsPChannelBad(ib)) { // check if strips is bad
1582             Float_t yN=pos[i].GetY();   
1583             Float_t xt, zt;
1584             seg->GetPadCxz(1.*ib, yN, xt, zt);  
1585             
1586             //----------
1587             // bad Pstrip is crossing the Nside 1Dcluster -> create recpoint
1588             // 
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);
1592               lp[0]=trk[1];
1593               lp[1]=trk[2];        
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]};
1600               
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
1604               if (info[0]>1) {
1605                 lp[2]=4.80e-06;
1606                 lp[3]=0.0093;
1607                 lp[5]=0.00014;
1608               }
1609                       
1610               AliITSRecPoint * cl2;
1611                 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);         
1612                 cl2->SetChargeRatio(1.);
1613               cl2->SetType(50);   
1614               ncl++;
1615             } // cross is within the detector
1616             //
1617             //--------------
1618             
1619           } // bad Pstrip
1620           
1621         } // end loop over Pstrips
1622         
1623       } // end loop over Nside 1D clusters
1624       
1625       for (Int_t j=0; j<nn; j++) { // loop over Pside 1D clusters with no crosses
1626         if(cpositive[j]) continue;
1627         
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
1630           
1631           if(cal->IsNChannelBad(ib)) { // check if strip is bad
1632             Float_t yP=neg[j].GetY();   
1633             Float_t xt, zt;
1634             seg->GetPadCxz(yP, 1.*ib, xt, zt);  
1635             
1636             //----------
1637             // bad Nstrip is crossing the Pside 1Dcluster -> create recpoint
1638             // 
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);
1642               lp[0]=trk[1];
1643               lp[1]=trk[2];        
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]};
1650               
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
1654               if (info[0]>1) {
1655                 lp[2]=2.79e-06;
1656                 lp[3]=0.00935;
1657                 lp[5]=-4.32e-05;
1658               }
1659               
1660               AliITSRecPoint * cl2;
1661                 cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);         
1662                 cl2->SetChargeRatio(1.);
1663                 cl2->SetType(60);         
1664               ncl++;
1665             } // cross is within the detector
1666             //
1667             //--------------
1668             
1669           } // bad Nstrip
1670         } // end loop over Nstrips
1671       } // end loop over Pside 1D clusters
1672       
1673     } // no bad sides 
1674     
1675     //---------------------------------------------------------
1676     
1677     else if( (countPbad>700) && (countNbad<100) ) { // bad Pside!!
1678       
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;
1681         
1682         Float_t xt, zt;
1683         Float_t yN=pos[i].GetY();       
1684         Float_t yP=0.;
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); 
1688         
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);
1692           lp[0]=trk[1];
1693           lp[1]=trk[2];        
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]};
1700           
1701           lp[2]=0.00098;    // 0.031*0.031;  //SigmaY2
1702           lp[3]=1.329;      // 1.15*1.15;  //SigmaZ2
1703           lp[5]=-0.0359;
1704           if(info[0]>1) lp[2]=0.00097;
1705
1706           AliITSRecPoint * cl2;
1707             cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);     
1708             cl2->SetChargeRatio(1.);
1709             cl2->SetType(70);     
1710           ncl++;
1711         } // cross is within the detector
1712         //
1713         //--------------
1714         
1715       } // end loop over Nside 1D clusters
1716       
1717     } // bad Pside module
1718     
1719     else if( (countNbad>700) && (countPbad<100) ) { // bad Nside!!
1720       
1721       for (Int_t j=0; j<nn; j++) { // loop over Pside 1D clusters with no crosses
1722         if(cpositive[j]) continue;
1723         
1724         Float_t xt, zt;
1725         Float_t yP=neg[j].GetY();       
1726         Float_t yN=0.;
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); 
1730         
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);
1734           lp[0]=trk[1];
1735           lp[1]=trk[2];        
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]};
1742           
1743           lp[2]=7.27e-05;   // 0.0085*0.0085;  //SigmaY2
1744           lp[3]=1.33;       // 1.15*1.15;  //SigmaZ2
1745           lp[5]=0.00931;
1746           if(info[1]>1) lp[2]=6.91e-05;
1747           
1748           AliITSRecPoint * cl2;
1749             cl2 = new ((*clusters)[ncl]) AliITSRecPoint(milab,lp,info);     
1750             cl2->SetChargeRatio(1.);
1751             cl2->SetType(80);     
1752           ncl++;
1753         } // cross is within the detector
1754         //
1755         //--------------
1756         
1757       } // end loop over Pside 1D clusters
1758       
1759     } // bad Nside module
1760     
1761     //---------------------------------------------------------
1762     
1763   } // use bad channels
1764     
1765   //cout<<ncl<<" clusters for this module"<<endl;
1766
1767   delete [] cnegative;
1768   delete [] cused1;
1769   delete [] negativepair;
1770   delete [] cpositive;
1771   delete [] cused2;
1772   delete [] positivepair;
1773
1774 }