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