]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSClusterFinderV2SSD.cxx
New class for dE/dx analysis (comparison with Bethe-Bloch, check of response function...
[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   TClonesArray &cl=*clusters;
748   
749   AliITSsegmentationSSD *seg = dynamic_cast<AliITSsegmentationSSD*>(fDetTypeRec->GetSegmentationModel(2));
750   if (fModule>fLastSSD1) 
751     seg->SetLayer(6);
752   else 
753     seg->SetLayer(5);
754
755   Float_t hwSSD = seg->Dx()*1e-4/2;
756   Float_t hlSSD = seg->Dz()*1e-4/2;
757
758   Int_t idet=fNdet[fModule];
759   Int_t ncl=0;
760
761   //
762   Int_t *cnegative = new Int_t[np];  
763   Int_t *cused1 = new Int_t[np];
764   Int_t *negativepair = new Int_t[10*np];
765   Int_t *cpositive = new Int_t[nn];  
766   Int_t *cused2 = new Int_t[nn];  
767   Int_t *positivepair = new Int_t[10*nn];  
768   for (Int_t i=0;i<np;i++) {cnegative[i]=0; cused1[i]=0;}
769   for (Int_t i=0;i<nn;i++) {cpositive[i]=0; cused2[i]=0;}
770   for (Int_t i=0;i<10*np;i++) {negativepair[i]=0;}
771   for (Int_t i=0;i<10*nn;i++) {positivepair[i]=0;}
772
773   if ((np*nn) > fgPairsSize) {
774
775     if (fgPairs) delete [] fgPairs;
776     fgPairsSize = 4*np*nn;
777     fgPairs = new Short_t[fgPairsSize];
778   }
779   memset(fgPairs,0,sizeof(Short_t)*np*nn);
780
781   //
782   // find available pairs
783   //
784   for (Int_t i=0; i<np; i++) {
785     Float_t yp=pos[i].GetY(); 
786     if ( (pos[i].GetQ()>0) && (pos[i].GetQ()<3) ) continue;
787     for (Int_t j=0; j<nn; j++) {
788       if ( (neg[j].GetQ()>0) && (neg[j].GetQ()<3) ) continue;
789       Float_t yn=neg[j].GetY();
790
791       Float_t xt, zt;
792       seg->GetPadCxz(yn, yp, xt, zt);
793       //cout<<yn<<" "<<yp<<" "<<xt<<" "<<zt<<endl;
794       
795       if (TMath::Abs(xt)<hwSSD+0.01)
796       if (TMath::Abs(zt)<hlSSD+0.01*(neg[j].GetNd()+pos[i].GetNd())) {
797         negativepair[i*10+cnegative[i]] =j;  //index
798         positivepair[j*10+cpositive[j]] =i;
799         cnegative[i]++;  //counters
800         cpositive[j]++; 
801         fgPairs[i*nn+j]=100;
802       }
803     }
804   }
805
806   //
807   // try to recover points out of but close to the module boundaries 
808   //
809   for (Int_t i=0; i<np; i++) {
810     Float_t yp=pos[i].GetY(); 
811     if ( (pos[i].GetQ()>0) && (pos[i].GetQ()<3) ) continue;
812     for (Int_t j=0; j<nn; j++) {
813       if ( (neg[j].GetQ()>0) && (neg[j].GetQ()<3) ) continue;
814       // if both 1Dclusters have an other cross continue
815       if (cpositive[j]&&cnegative[i]) continue;
816       Float_t yn=neg[j].GetY();
817       
818       Float_t xt, zt;
819       seg->GetPadCxz(yn, yp, xt, zt);
820       
821       if (TMath::Abs(xt)<hwSSD+0.1)
822       if (TMath::Abs(zt)<hlSSD+0.15) {
823         // tag 1Dcluster (eventually will produce low quality recpoint)
824         if (cnegative[i]==0) pos[i].SetNd(100);  // not available pair
825         if (cpositive[j]==0) neg[j].SetNd(100);  // not available pair
826         negativepair[i*10+cnegative[i]] =j;  //index
827         positivepair[j*10+cpositive[j]] =i;
828         cnegative[i]++;  //counters
829         cpositive[j]++; 
830         fgPairs[i*nn+j]=100;
831       }
832     }
833   }
834
835   //
836   Float_t lp[6];
837   Int_t milab[10];
838   Double_t ratio;
839   
840
841   static AliITSRecoParam *repa = NULL;
842   if(!repa){
843     repa = (AliITSRecoParam*) AliITSReconstructor::GetRecoParam();
844     if(!repa){
845       repa = AliITSRecoParam::GetHighFluxParam();
846       AliWarning("Using default AliITSRecoParam class");
847     }
848   }
849
850   if(repa->GetUseChargeMatchingInClusterFinderSSD()==kTRUE) {
851
852
853     //
854     // sign gold tracks
855     //
856     for (Int_t ip=0;ip<np;ip++){
857       Float_t xbest=1000,zbest=1000,qbest=0;
858       //
859       // select gold clusters
860       if ( (cnegative[ip]==1) && cpositive[negativepair[10*ip]]==1){ 
861         Float_t yp=pos[ip].GetY(); 
862         Int_t j = negativepair[10*ip];      
863
864         if( (pos[ip].GetQ()==0) && (neg[j].GetQ() ==0) ) { 
865           // both bad, hence continue;    
866           // mark both as used (to avoid recover at the end)
867           cused1[ip]++; 
868           cused2[j]++;
869           continue;
870         }
871
872         ratio = (pos[ip].GetQ()-neg[j].GetQ())/(pos[ip].GetQ()+neg[j].GetQ());
873         //cout<<"ratio="<<ratio<<endl;
874
875         // charge matching (note that if posQ or negQ is 0 -> ratio=1 and the following condition is met
876         if (TMath::Abs(ratio)>0.2) continue; // note: 0.2=3xsigma_ratio calculated in cosmics tests
877
878         //
879         Float_t yn=neg[j].GetY();
880         
881         Float_t xt, zt;
882         seg->GetPadCxz(yn, yp, xt, zt);
883         
884         xbest=xt; zbest=zt; 
885
886         
887         qbest=0.5*(pos[ip].GetQ()+neg[j].GetQ());
888         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
889         
890         {
891           Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
892           mT2L->MasterToLocal(loc,trk);
893           lp[0]=trk[1];
894           lp[1]=trk[2];
895         }
896         lp[4]=qbest;        //Q
897         for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
898         for (Int_t ilab=0;ilab<3;ilab++){
899           milab[ilab] = pos[ip].GetLabel(ilab);
900           milab[ilab+3] = neg[j].GetLabel(ilab);
901         }
902         //
903         CheckLabels2(milab);
904         milab[3]=(((ip<<10) + j)<<10) + idet; // pos|neg|det
905         Int_t info[3] = {pos[ip].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
906
907         lp[2]=0.0022*0.0022;  //SigmaY2
908         lp[3]=0.110*0.110;  //SigmaZ2
909         // out-of-diagonal element of covariance matrix
910         if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
911         else if ( (info[0]>1) && (info[1]>1) ) { 
912           lp[2]=0.0016*0.0016;  //SigmaY2
913           lp[3]=0.08*0.08;  //SigmaZ2
914           lp[5]=-0.00006;
915         }
916         else {
917           lp[3]=0.0093*0.0093;
918           if (info[0]==1) { lp[5]=-0.00014;}
919           else { lp[2]=0.0017*0.0017; lp[5]=-0.00004;}
920         }
921
922         AliITSRecPoint * cl2;
923         
924         if(clusters){  // Note clusters != 0 when method is called for rawdata
925           
926           
927           cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);
928           
929           cl2->SetChargeRatio(ratio);           
930           cl2->SetType(1);
931           fgPairs[ip*nn+j]=1;
932
933           if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
934             cl2->SetType(2);
935             fgPairs[ip*nn+j]=2;
936           }
937
938           if(pos[ip].GetQ()==0) cl2->SetType(3);
939           if(neg[j].GetQ()==0) cl2->SetType(4);
940
941           cused1[ip]++;
942           cused2[j]++;
943           
944         }
945         else{ // Note clusters == 0 when method is called for digits
946           
947           cl2 = new AliITSRecPoint(milab,lp,info);      
948           
949           cl2->SetChargeRatio(ratio);           
950           cl2->SetType(1);
951           fgPairs[ip*nn+j]=1;
952
953           if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
954             cl2->SetType(2);
955             fgPairs[ip*nn+j]=2;
956           }
957
958           if(pos[ip].GetQ()==0) cl2->SetType(3);
959           if(neg[j].GetQ()==0) cl2->SetType(4);
960
961           cused1[ip]++;
962           cused2[j]++;
963
964           fDetTypeRec->AddRecPoint(*cl2);
965         }
966         ncl++;
967       }
968     }
969     
970     for (Int_t ip=0;ip<np;ip++){
971       Float_t xbest=1000,zbest=1000,qbest=0;
972       //
973       //
974       // select "silber" cluster
975       if ( cnegative[ip]==1 && cpositive[negativepair[10*ip]]==2){
976         Int_t in  = negativepair[10*ip];
977         Int_t ip2 = positivepair[10*in];
978         if (ip2==ip) ip2 =  positivepair[10*in+1];
979         Float_t pcharge = pos[ip].GetQ()+pos[ip2].GetQ();
980         
981
982
983         ratio = (pcharge-neg[in].GetQ())/(pcharge+neg[in].GetQ());
984         if ( (TMath::Abs(ratio)<0.2) && (pcharge!=0) ) {
985           //if ( (TMath::Abs(pcharge-neg[in].GetQ())<30) && (pcharge!=0) ) { // 
986           
987           //
988           // add first pair
989           if ( (fgPairs[ip*nn+in]==100)&&(pos[ip].GetQ() ) ) {  //
990             
991             Float_t yp=pos[ip].GetY(); 
992             Float_t yn=neg[in].GetY();
993             
994             Float_t xt, zt;
995             seg->GetPadCxz(yn, yp, xt, zt);
996             
997             xbest=xt; zbest=zt; 
998
999             qbest =pos[ip].GetQ();
1000             Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
1001             mT2L->MasterToLocal(loc,trk);
1002             lp[0]=trk[1];
1003             lp[1]=trk[2];
1004             
1005             lp[4]=qbest;        //Q
1006             for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1007             for (Int_t ilab=0;ilab<3;ilab++){
1008               milab[ilab] = pos[ip].GetLabel(ilab);
1009               milab[ilab+3] = neg[in].GetLabel(ilab);
1010             }
1011             //
1012             CheckLabels2(milab);
1013             ratio = (pos[ip].GetQ()-neg[in].GetQ())/(pos[ip].GetQ()+neg[in].GetQ());
1014             milab[3]=(((ip<<10) + in)<<10) + idet; // pos|neg|det
1015             Int_t info[3] = {pos[ip].GetNd(),neg[in].GetNd(),fNlayer[fModule]};
1016             
1017         lp[2]=0.0022*0.0022;  //SigmaY2
1018         lp[3]=0.110*0.110;  //SigmaZ2
1019         // out-of-diagonal element of covariance matrix
1020         if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
1021         else if ( (info[0]>1) && (info[1]>1) ) { 
1022           lp[2]=0.0016*0.0016;  //SigmaY2
1023           lp[3]=0.08*0.08;  //SigmaZ2
1024           lp[5]=-0.00006;
1025         }
1026         else {
1027           lp[3]=0.0093*0.0093;
1028           if (info[0]==1) { lp[5]=-0.00014;}
1029           else { lp[2]=0.0017*0.0017; lp[5]=-0.00004;}
1030         }
1031
1032             AliITSRecPoint * cl2;
1033             if(clusters){
1034               
1035               cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);
1036               cl2->SetChargeRatio(ratio);       
1037               cl2->SetType(5);
1038               fgPairs[ip*nn+in] = 5;
1039               if ((pos[ip].GetNd()+neg[in].GetNd())>6){ //multi cluster
1040                 cl2->SetType(6);
1041                 fgPairs[ip*nn+in] = 6;
1042               }     
1043             }
1044             else{
1045               cl2 = new AliITSRecPoint(milab,lp,info);
1046               cl2->SetChargeRatio(ratio);       
1047               cl2->SetType(5);
1048               fgPairs[ip*nn+in] = 5;
1049               if ((pos[ip].GetNd()+neg[in].GetNd())>6){ //multi cluster
1050                 cl2->SetType(6);
1051                 fgPairs[ip*nn+in] = 6;
1052               }
1053               
1054               fDetTypeRec->AddRecPoint(*cl2);
1055             }
1056             ncl++;
1057           }
1058           
1059           
1060           //
1061           // add second pair
1062           
1063           //    if (!(cused1[ip2] || cused2[in])){  //
1064           if ( (fgPairs[ip2*nn+in]==100) && (pos[ip2].GetQ()) ) {
1065             
1066             Float_t yp=pos[ip2].GetY();
1067             Float_t yn=neg[in].GetY();
1068             
1069             Float_t xt, zt;
1070             seg->GetPadCxz(yn, yp, xt, zt);
1071             
1072             xbest=xt; zbest=zt; 
1073
1074             qbest =pos[ip2].GetQ();
1075             
1076             Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
1077             mT2L->MasterToLocal(loc,trk);
1078             lp[0]=trk[1];
1079             lp[1]=trk[2];
1080             
1081             lp[4]=qbest;        //Q
1082             for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1083             for (Int_t ilab=0;ilab<3;ilab++){
1084               milab[ilab] = pos[ip2].GetLabel(ilab);
1085               milab[ilab+3] = neg[in].GetLabel(ilab);
1086             }
1087             //
1088             CheckLabels2(milab);
1089             ratio = (pos[ip2].GetQ()-neg[in].GetQ())/(pos[ip2].GetQ()+neg[in].GetQ());
1090             milab[3]=(((ip2<<10) + in)<<10) + idet; // pos|neg|det
1091             Int_t info[3] = {pos[ip2].GetNd(),neg[in].GetNd(),fNlayer[fModule]};
1092             
1093         lp[2]=0.0022*0.0022;  //SigmaY2
1094         lp[3]=0.110*0.110;  //SigmaZ2
1095         // out-of-diagonal element of covariance matrix
1096         if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
1097         else if ( (info[0]>1) && (info[1]>1) ) { 
1098           lp[2]=0.0016*0.0016;  //SigmaY2
1099           lp[3]=0.08*0.08;  //SigmaZ2
1100           lp[5]=-0.00006;
1101         }
1102         else {
1103           lp[3]=0.0093*0.0093;
1104           if (info[0]==1) { lp[5]=-0.00014;}
1105           else { lp[2]=0.0017*0.0017; lp[5]=-0.00004;}
1106         }
1107
1108             AliITSRecPoint * cl2;
1109             if(clusters){
1110               cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);
1111               
1112               cl2->SetChargeRatio(ratio);       
1113               cl2->SetType(5);
1114               fgPairs[ip2*nn+in] =5;
1115               if ((pos[ip2].GetNd()+neg[in].GetNd())>6){ //multi cluster
1116                 cl2->SetType(6);
1117                 fgPairs[ip2*nn+in] =6;
1118               }
1119             }
1120             else{
1121               cl2 = new AliITSRecPoint(milab,lp,info);
1122               cl2->SetChargeRatio(ratio);       
1123               cl2->SetType(5);
1124               fgPairs[ip2*nn+in] =5;
1125               if ((pos[ip2].GetNd()+neg[in].GetNd())>6){ //multi cluster
1126                 cl2->SetType(6);
1127                 fgPairs[ip2*nn+in] =6;
1128               }
1129               
1130               fDetTypeRec->AddRecPoint(*cl2);
1131             }
1132             ncl++;
1133           }
1134           
1135           cused1[ip]++;
1136           cused1[ip2]++;
1137           cused2[in]++;
1138
1139         } // charge matching condition
1140
1141       } // 2 Pside cross 1 Nside
1142     } // loop over Pside clusters
1143     
1144     
1145       
1146       //  
1147     for (Int_t jn=0;jn<nn;jn++){
1148       if (cused2[jn]) continue;
1149       Float_t xbest=1000,zbest=1000,qbest=0;
1150       // select "silber" cluster
1151       if ( cpositive[jn]==1 && cnegative[positivepair[10*jn]]==2){
1152         Int_t ip  = positivepair[10*jn];
1153         Int_t jn2 = negativepair[10*ip];
1154         if (jn2==jn) jn2 =  negativepair[10*ip+1];
1155         Float_t pcharge = neg[jn].GetQ()+neg[jn2].GetQ();
1156         //
1157         
1158
1159         ratio = (pcharge-pos[ip].GetQ())/(pcharge+pos[ip].GetQ());
1160         if ( (TMath::Abs(ratio)<0.2) && (pcharge!=0) ) {
1161
1162           /*
1163         if ( (TMath::Abs(pcharge-pos[ip].GetQ())<30) &&  // charge matching 
1164              (pcharge!=0) ) { // reject combinations of bad strips
1165           */
1166
1167
1168           //
1169           // add first pair
1170           //    if (!(cused1[ip]||cused2[jn])){
1171           if ( (fgPairs[ip*nn+jn]==100) && (neg[jn].GetQ()) ) {  //
1172             
1173             Float_t yn=neg[jn].GetY(); 
1174             Float_t yp=pos[ip].GetY();
1175
1176             Float_t xt, zt;
1177             seg->GetPadCxz(yn, yp, xt, zt);
1178             
1179             xbest=xt; zbest=zt; 
1180
1181             qbest =neg[jn].GetQ();
1182
1183             {
1184               Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
1185               mT2L->MasterToLocal(loc,trk);
1186               lp[0]=trk[1];
1187               lp[1]=trk[2];
1188           }
1189           
1190           lp[4]=qbest;        //Q
1191           for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1192           for (Int_t ilab=0;ilab<3;ilab++){
1193             milab[ilab] = pos[ip].GetLabel(ilab);
1194             milab[ilab+3] = neg[jn].GetLabel(ilab);
1195           }
1196           //
1197           CheckLabels2(milab);
1198           ratio = (pos[ip].GetQ()-neg[jn].GetQ())/(pos[ip].GetQ()+neg[jn].GetQ());
1199           milab[3]=(((ip<<10) + jn)<<10) + idet; // pos|neg|det
1200           Int_t info[3] = {pos[ip].GetNd(),neg[jn].GetNd(),fNlayer[fModule]};
1201
1202         lp[2]=0.0022*0.0022;  //SigmaY2
1203         lp[3]=0.110*0.110;  //SigmaZ2
1204         // out-of-diagonal element of covariance matrix
1205         if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
1206         else if ( (info[0]>1) && (info[1]>1) ) { 
1207           lp[2]=0.0016*0.0016;  //SigmaY2
1208           lp[3]=0.08*0.08;  //SigmaZ2
1209           lp[5]=-0.00006;
1210         }
1211         else {
1212           lp[3]=0.0093*0.0093;
1213           if (info[0]==1) { lp[5]=-0.00014;}
1214           else { lp[2]=0.0017*0.0017; lp[5]=-0.00004;}
1215         }
1216
1217           AliITSRecPoint * cl2;
1218           if(clusters){
1219             cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);
1220
1221             cl2->SetChargeRatio(ratio);         
1222             cl2->SetType(7);
1223             fgPairs[ip*nn+jn] =7;
1224             if ((pos[ip].GetNd()+neg[jn].GetNd())>6){ //multi cluster
1225               cl2->SetType(8);
1226               fgPairs[ip*nn+jn]=8;
1227             }
1228
1229           }
1230           else{
1231             cl2 = new AliITSRecPoint(milab,lp,info);
1232             cl2->SetChargeRatio(ratio);         
1233             cl2->SetType(7);
1234             fgPairs[ip*nn+jn] =7;
1235             if ((pos[ip].GetNd()+neg[jn].GetNd())>6){ //multi cluster
1236               cl2->SetType(8);
1237               fgPairs[ip*nn+jn]=8;
1238             }
1239
1240             fDetTypeRec->AddRecPoint(*cl2);
1241           }
1242           ncl++;
1243         }
1244         //
1245         // add second pair
1246         //      if (!(cused1[ip]||cused2[jn2])){
1247         if ( (fgPairs[ip*nn+jn2]==100)&&(neg[jn2].GetQ() ) ) {  //
1248
1249           Float_t yn=neg[jn2].GetY(); 
1250           Double_t yp=pos[ip].GetY(); 
1251
1252           Float_t xt, zt;
1253           seg->GetPadCxz(yn, yp, xt, zt);
1254           
1255           xbest=xt; zbest=zt; 
1256
1257           qbest =neg[jn2].GetQ();
1258
1259           {
1260           Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
1261           mT2L->MasterToLocal(loc,trk);
1262           lp[0]=trk[1];
1263           lp[1]=trk[2];
1264           }
1265
1266           lp[4]=qbest;        //Q
1267           for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1268           for (Int_t ilab=0;ilab<3;ilab++){
1269             milab[ilab] = pos[ip].GetLabel(ilab);
1270             milab[ilab+3] = neg[jn2].GetLabel(ilab);
1271           }
1272           //
1273           CheckLabels2(milab);
1274           ratio = (pos[ip].GetQ()-neg[jn2].GetQ())/(pos[ip].GetQ()+neg[jn2].GetQ());
1275           milab[3]=(((ip<<10) + jn2)<<10) + idet; // pos|neg|det
1276           Int_t info[3] = {pos[ip].GetNd(),neg[jn2].GetNd(),fNlayer[fModule]};
1277
1278         lp[2]=0.0022*0.0022;  //SigmaY2
1279         lp[3]=0.110*0.110;  //SigmaZ2
1280         // out-of-diagonal element of covariance matrix
1281         if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
1282         else if ( (info[0]>1) && (info[1]>1) ) { 
1283           lp[2]=0.0016*0.0016;  //SigmaY2
1284           lp[3]=0.08*0.08;  //SigmaZ2
1285           lp[5]=-0.00006;
1286         }
1287         else {
1288           lp[3]=0.0093*0.0093;
1289           if (info[0]==1) { lp[5]=-0.00014;}
1290           else { lp[2]=0.0017*0.0017; lp[5]=-0.00004;}
1291         }
1292
1293           AliITSRecPoint * cl2;
1294           if(clusters){
1295             cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);
1296
1297
1298             cl2->SetChargeRatio(ratio);         
1299             fgPairs[ip*nn+jn2]=7;
1300             cl2->SetType(7);
1301             if ((pos[ip].GetNd()+neg[jn2].GetNd())>6){ //multi cluster
1302               cl2->SetType(8);
1303               fgPairs[ip*nn+jn2]=8;
1304             }
1305             
1306           }
1307           else{
1308             cl2 = new AliITSRecPoint(milab,lp,info);
1309             cl2->SetChargeRatio(ratio);         
1310             fgPairs[ip*nn+jn2]=7;
1311             cl2->SetType(7);
1312             if ((pos[ip].GetNd()+neg[jn2].GetNd())>6){ //multi cluster
1313               cl2->SetType(8);
1314               fgPairs[ip*nn+jn2]=8;
1315             }
1316
1317             fDetTypeRec->AddRecPoint(*cl2);
1318           }
1319
1320           ncl++;
1321         }
1322         cused1[ip]++;
1323         cused2[jn]++;
1324         cused2[jn2]++;
1325
1326         } // charge matching condition
1327
1328       } // 2 Nside cross 1 Pside
1329     } // loop over Pside clusters
1330
1331   
1332     
1333     for (Int_t ip=0;ip<np;ip++){
1334
1335       if(cused1[ip]) continue;
1336
1337
1338       Float_t xbest=1000,zbest=1000,qbest=0;
1339       //
1340       // 2x2 clusters
1341       //
1342       if ( (cnegative[ip]==2) && cpositive[negativepair[10*ip]]==2){ 
1343         Float_t minchargediff =4.;
1344         Float_t minchargeratio =0.2;
1345
1346         Int_t j=-1;
1347         for (Int_t di=0;di<cnegative[ip];di++){
1348           Int_t   jc = negativepair[ip*10+di];
1349           Float_t chargedif = pos[ip].GetQ()-neg[jc].GetQ();
1350           ratio = (pos[ip].GetQ()-neg[jc].GetQ())/(pos[ip].GetQ()+neg[jc].GetQ()); 
1351           //if (TMath::Abs(chargedif)<minchargediff){
1352           if (TMath::Abs(ratio)<0.2){
1353             j =jc;
1354             minchargediff = TMath::Abs(chargedif);
1355             minchargeratio = TMath::Abs(ratio);
1356           }
1357         }
1358         if (j<0) continue;  // not proper cluster      
1359         
1360
1361         Int_t count =0;
1362         for (Int_t di=0;di<cnegative[ip];di++){
1363           Int_t   jc = negativepair[ip*10+di];
1364           Float_t chargedif = pos[ip].GetQ()-neg[jc].GetQ();
1365           if (TMath::Abs(chargedif)<minchargediff+3.) count++;
1366         }
1367         if (count>1) continue;  // more than one "proper" cluster for positive
1368         //
1369         
1370         count =0;
1371         for (Int_t dj=0;dj<cpositive[j];dj++){
1372           Int_t   ic  = positivepair[j*10+dj];
1373           Float_t chargedif = pos[ic].GetQ()-neg[j].GetQ();
1374           if (TMath::Abs(chargedif)<minchargediff+3.) count++;
1375         }
1376         if (count>1) continue;  // more than one "proper" cluster for negative
1377         
1378         Int_t jp = 0;
1379         
1380         count =0;
1381         for (Int_t dj=0;dj<cnegative[jp];dj++){
1382           Int_t   ic = positivepair[jp*10+dj];
1383           Float_t chargedif = pos[ic].GetQ()-neg[jp].GetQ();
1384           if (TMath::Abs(chargedif)<minchargediff+4.) count++;
1385         }
1386         if (count>1) continue;   
1387         if (fgPairs[ip*nn+j]<100) continue;
1388         //
1389         
1390
1391
1392         //almost gold clusters
1393         Float_t yp=pos[ip].GetY(); 
1394         Float_t yn=neg[j].GetY();      
1395         Float_t xt, zt;
1396         seg->GetPadCxz(yn, yp, xt, zt); 
1397         xbest=xt; zbest=zt; 
1398         qbest=0.5*(pos[ip].GetQ()+neg[j].GetQ());
1399         {
1400           Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
1401           mT2L->MasterToLocal(loc,trk);
1402           lp[0]=trk[1];
1403           lp[1]=trk[2];
1404         }
1405         lp[4]=qbest;        //Q
1406         for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1407         for (Int_t ilab=0;ilab<3;ilab++){
1408           milab[ilab] = pos[ip].GetLabel(ilab);
1409           milab[ilab+3] = neg[j].GetLabel(ilab);
1410         }
1411         //
1412         CheckLabels2(milab);
1413         if ((neg[j].GetQ()==0)&&(pos[ip].GetQ()==0)) continue; // reject crosses of bad strips!!
1414         ratio = (pos[ip].GetQ()-neg[j].GetQ())/(pos[ip].GetQ()+neg[j].GetQ());
1415         milab[3]=(((ip<<10) + j)<<10) + idet; // pos|neg|det
1416         Int_t info[3] = {pos[ip].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
1417
1418         lp[2]=0.0022*0.0022;  //SigmaY2
1419         lp[3]=0.110*0.110;  //SigmaZ2
1420         // out-of-diagonal element of covariance matrix
1421         if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
1422         else if ( (info[0]>1) && (info[1]>1) ) { 
1423           lp[2]=0.0016*0.0016;  //SigmaY2
1424           lp[3]=0.08*0.08;  //SigmaZ2
1425           lp[5]=-0.00006;
1426         }
1427         else {
1428           lp[3]=0.0093*0.0093;
1429           if (info[0]==1) { lp[5]=-0.00014;}
1430           else { lp[2]=0.0017*0.0017; lp[5]=-0.00004;}
1431         }
1432
1433         AliITSRecPoint * cl2;
1434         if(clusters){
1435           cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);
1436                   
1437           cl2->SetChargeRatio(ratio);           
1438           cl2->SetType(10);
1439           fgPairs[ip*nn+j]=10;
1440           if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
1441             cl2->SetType(11);
1442             fgPairs[ip*nn+j]=11;
1443           }
1444           cused1[ip]++;
1445           cused2[j]++;      
1446         }
1447         else{
1448           cl2 = new AliITSRecPoint(milab,lp,info);
1449           cl2->SetChargeRatio(ratio);           
1450           cl2->SetType(10);
1451           fgPairs[ip*nn+j]=10;
1452           if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
1453             cl2->SetType(11);
1454             fgPairs[ip*nn+j]=11;
1455           }
1456           cused1[ip]++;
1457           cused2[j]++;      
1458           
1459           fDetTypeRec->AddRecPoint(*cl2);
1460         }      
1461         ncl++;
1462         
1463       } // 2X2
1464     } // loop over Pside 1Dclusters
1465
1466
1467
1468     for (Int_t ip=0;ip<np;ip++){
1469
1470       if(cused1[ip]) continue;
1471
1472
1473       Float_t xbest=1000,zbest=1000,qbest=0;
1474       //
1475       // manyxmany clusters
1476       //
1477       if ( (cnegative[ip]<5) && cpositive[negativepair[10*ip]]<5){ 
1478         Float_t minchargediff =4.;
1479         Int_t j=-1;
1480         for (Int_t di=0;di<cnegative[ip];di++){
1481           Int_t   jc = negativepair[ip*10+di];
1482           Float_t chargedif = pos[ip].GetQ()-neg[jc].GetQ();
1483           if (TMath::Abs(chargedif)<minchargediff){
1484             j =jc;
1485             minchargediff = TMath::Abs(chargedif);
1486           }
1487         }
1488         if (j<0) continue;  // not proper cluster      
1489         
1490         Int_t count =0;
1491         for (Int_t di=0;di<cnegative[ip];di++){
1492           Int_t   jc = negativepair[ip*10+di];
1493           Float_t chargedif = pos[ip].GetQ()-neg[jc].GetQ();
1494           if (TMath::Abs(chargedif)<minchargediff+3.) count++;
1495         }
1496         if (count>1) continue;  // more than one "proper" cluster for positive
1497         //
1498         
1499         count =0;
1500         for (Int_t dj=0;dj<cpositive[j];dj++){
1501           Int_t   ic  = positivepair[j*10+dj];
1502           Float_t chargedif = pos[ic].GetQ()-neg[j].GetQ();
1503           if (TMath::Abs(chargedif)<minchargediff+3.) count++;
1504         }
1505         if (count>1) continue;  // more than one "proper" cluster for negative
1506         
1507         Int_t jp = 0;
1508         
1509         count =0;
1510         for (Int_t dj=0;dj<cnegative[jp];dj++){
1511           Int_t   ic = positivepair[jp*10+dj];
1512           Float_t chargedif = pos[ic].GetQ()-neg[jp].GetQ();
1513           if (TMath::Abs(chargedif)<minchargediff+4.) count++;
1514         }
1515         if (count>1) continue;   
1516         if (fgPairs[ip*nn+j]<100) continue;
1517         //
1518         
1519         //almost gold clusters
1520         Float_t yp=pos[ip].GetY(); 
1521         Float_t yn=neg[j].GetY();
1522       
1523
1524         Float_t xt, zt;
1525         seg->GetPadCxz(yn, yp, xt, zt);
1526         
1527         xbest=xt; zbest=zt; 
1528
1529         qbest=0.5*(pos[ip].GetQ()+neg[j].GetQ());
1530
1531         {
1532           Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
1533           mT2L->MasterToLocal(loc,trk);
1534           lp[0]=trk[1];
1535           lp[1]=trk[2];
1536         }
1537         lp[4]=qbest;        //Q
1538         for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1539         for (Int_t ilab=0;ilab<3;ilab++){
1540           milab[ilab] = pos[ip].GetLabel(ilab);
1541           milab[ilab+3] = neg[j].GetLabel(ilab);
1542         }
1543         //
1544         CheckLabels2(milab);
1545         if ((neg[j].GetQ()==0)&&(pos[ip].GetQ()==0)) continue; // reject crosses of bad strips!!
1546         ratio = (pos[ip].GetQ()-neg[j].GetQ())/(pos[ip].GetQ()+neg[j].GetQ());
1547         milab[3]=(((ip<<10) + j)<<10) + idet; // pos|neg|det
1548         Int_t info[3] = {pos[ip].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
1549
1550         lp[2]=0.0022*0.0022;  //SigmaY2
1551         lp[3]=0.110*0.110;  //SigmaZ2
1552         // out-of-diagonal element of covariance matrix
1553         if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
1554         else if ( (info[0]>1) && (info[1]>1) ) { 
1555           lp[2]=0.0016*0.0016;  //SigmaY2
1556           lp[3]=0.08*0.08;  //SigmaZ2
1557           lp[5]=-0.00006;
1558         }
1559         else {
1560           lp[3]=0.0093*0.0093;
1561           if (info[0]==1) { lp[5]=-0.00014;}
1562           else { lp[2]=0.0017*0.0017; lp[5]=-0.00004;}
1563         }
1564
1565         AliITSRecPoint * cl2;
1566         if(clusters){
1567           cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);
1568                   
1569           cl2->SetChargeRatio(ratio);           
1570           cl2->SetType(12);
1571           fgPairs[ip*nn+j]=12;
1572           if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
1573             cl2->SetType(13);
1574             fgPairs[ip*nn+j]=13;
1575           }
1576           cused1[ip]++;
1577           cused2[j]++;      
1578         }
1579         else{
1580           cl2 = new AliITSRecPoint(milab,lp,info);
1581           cl2->SetChargeRatio(ratio);           
1582           cl2->SetType(12);
1583           fgPairs[ip*nn+j]=12;
1584           if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
1585             cl2->SetType(13);
1586             fgPairs[ip*nn+j]=13;
1587           }
1588           cused1[ip]++;
1589           cused2[j]++;      
1590           
1591           fDetTypeRec->AddRecPoint(*cl2);
1592         }      
1593         ncl++;
1594         
1595       } // manyXmany
1596     } // loop over Pside 1Dclusters
1597     
1598   } // use charge matching
1599   
1600   
1601   // recover all the other crosses
1602   //  
1603   for (Int_t i=0; i<np; i++) {
1604     Float_t xbest=1000,zbest=1000,qbest=0;
1605     Float_t yp=pos[i].GetY(); 
1606     if ((pos[i].GetQ()>0)&&(pos[i].GetQ()<3)) continue;
1607     for (Int_t j=0; j<nn; j++) {
1608     //    for (Int_t di = 0;di<cpositive[i];di++){
1609     //  Int_t j = negativepair[10*i+di];
1610       if ((neg[j].GetQ()>0)&&(neg[j].GetQ()<3)) continue;
1611
1612       if ((neg[j].GetQ()==0)&&(pos[i].GetQ()==0)) continue; // reject crosses of bad strips!!
1613
1614       if (cused2[j]||cused1[i]) continue;      
1615       if (fgPairs[i*nn+j]>0 &&fgPairs[i*nn+j]<100) continue;
1616       ratio = (pos[i].GetQ()-neg[j].GetQ())/(pos[i].GetQ()+neg[j].GetQ());      
1617       Float_t yn=neg[j].GetY();
1618       
1619       Float_t xt, zt;
1620       seg->GetPadCxz(yn, yp, xt, zt);
1621       
1622       if (TMath::Abs(xt)<hwSSD+0.01)
1623       if (TMath::Abs(zt)<hlSSD+0.01*(neg[j].GetNd()+pos[i].GetNd())) {
1624         xbest=xt; zbest=zt; 
1625
1626         qbest=0.5*(pos[i].GetQ()+neg[j].GetQ());
1627
1628         {
1629         Double_t loc[3]={xbest,0.,zbest},trk[3]={0.,0.,0.};
1630         mT2L->MasterToLocal(loc,trk);
1631         lp[0]=trk[1];
1632         lp[1]=trk[2];
1633         }
1634         lp[4]=qbest;        //Q
1635         for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1636         for (Int_t ilab=0;ilab<3;ilab++){
1637           milab[ilab] = pos[i].GetLabel(ilab);
1638           milab[ilab+3] = neg[j].GetLabel(ilab);
1639         }
1640         //
1641         CheckLabels2(milab);
1642         milab[3]=(((i<<10) + j)<<10) + idet; // pos|neg|det
1643         Int_t info[3] = {pos[i].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
1644
1645         lp[2]=0.0022*0.0022;  //SigmaY2
1646         lp[3]=0.110*0.110;  //SigmaZ2
1647         // out-of-diagonal element of covariance matrix
1648         if( (info[0]==1) && (info[1]==1) ) lp[5]=-0.00012;
1649         else if ( (info[0]>1) && (info[1]>1) ) { 
1650           lp[2]=0.0016*0.0016;  //SigmaY2
1651           lp[3]=0.08*0.08;  //SigmaZ2
1652           lp[5]=-0.00006;
1653         }
1654         else {
1655           lp[3]=0.0093*0.0093;
1656           if (info[0]==1) { lp[5]=-0.00014;}
1657           else { lp[2]=0.0017*0.0017; lp[5]=-0.00004;}
1658         }
1659
1660         AliITSRecPoint * cl2;
1661         if(clusters){
1662           cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);
1663
1664           cl2->SetChargeRatio(ratio);
1665           cl2->SetType(100+cpositive[j]+cnegative[i]);    
1666
1667           if(pos[i].GetQ()==0) cl2->SetType(200+cpositive[j]+cnegative[i]);
1668           if(neg[j].GetQ()==0) cl2->SetType(300+cpositive[j]+cnegative[i]);
1669
1670         }
1671         else{
1672           cl2 = new AliITSRecPoint(milab,lp,info);
1673           cl2->SetChargeRatio(ratio);
1674           cl2->SetType(100+cpositive[j]+cnegative[i]);
1675           
1676           if(pos[i].GetQ()==0) cl2->SetType(200+cpositive[j]+cnegative[i]);
1677           if(neg[j].GetQ()==0) cl2->SetType(300+cpositive[j]+cnegative[i]);
1678
1679           fDetTypeRec->AddRecPoint(*cl2);
1680         }
1681         ncl++;
1682       }
1683     }
1684   }
1685
1686
1687   //---------------------------------------------------------
1688   // recover crosses of good 1D clusters with bad strips on the other side
1689   // Note1: at first iteration skip modules with a bad side (or almost), (would produce too many fake!) 
1690   // Note2: for modules with a bad side see below 
1691   
1692   AliITSCalibrationSSD* cal = (AliITSCalibrationSSD*)GetResp(fModule);
1693   Int_t countPbad=0, countNbad=0;
1694   for(Int_t ib=0; ib<768; ib++) {
1695     if(cal->IsPChannelBad(ib)) countPbad++;
1696     if(cal->IsNChannelBad(ib)) countNbad++;
1697   }
1698   //  AliInfo(Form("module %d has %d P- and %d N-bad strips",fModule,countPbad,countNbad));
1699
1700   if( (countPbad<100) && (countNbad<100) ) { // no bad side!!
1701     
1702     for (Int_t i=0; i<np; i++) { // loop over Nside 1Dclusters with no crosses
1703       if(cnegative[i]) continue; // if intersecting Pside clusters continue;
1704       
1705       //      for(Int_t ib=0; ib<768; ib++) { // loop over all Pstrips
1706       for(Int_t ib=15; ib<753; ib++) { // loop over all Pstrips
1707         
1708         if(cal->IsPChannelBad(ib)) { // check if strips is bad
1709           Float_t yN=pos[i].GetY();     
1710           Float_t xt, zt;
1711           seg->GetPadCxz(1.*ib, yN, xt, zt);    
1712           
1713           //----------
1714           // bad Pstrip is crossing the Nside 1Dcluster -> create recpoint
1715           // 
1716           if ( (TMath::Abs(xt)<hwSSD+0.01) && (TMath::Abs(zt)<hlSSD+0.01) ) {
1717             Double_t loc[3]={xt,0.,zt},trk[3]={0.,0.,0.};
1718             mT2L->MasterToLocal(loc,trk);
1719             lp[0]=trk[1];
1720             lp[1]=trk[2];        
1721             lp[4]=pos[i].GetQ(); //Q
1722             for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1723             for (Int_t ilab=0;ilab<3;ilab++) milab[ilab] = pos[i].GetLabel(ilab);         
1724             CheckLabels2(milab);
1725             milab[3]=( (i<<10) << 10 ) + idet; // pos|neg|det
1726             Int_t info[3] = {pos[i].GetNd(),0,fNlayer[fModule]};
1727             
1728             // out-of-diagonal element of covariance matrix
1729             if (info[0]==1) lp[5]=0.0065;
1730             else lp[5]=0.0093;
1731
1732         lp[2]=0.0022*0.0022;  //SigmaY2
1733         lp[3]=0.110*0.110;  //SigmaZ2
1734         lp[5]=-0.00012; // out-of-diagonal element of covariance matrix
1735         
1736             AliITSRecPoint * cl2;
1737             if(clusters){
1738               cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);            
1739               cl2->SetChargeRatio(1.);
1740               cl2->SetType(50);   
1741             }
1742             else{
1743               cl2 = new AliITSRecPoint(milab,lp,info);
1744               cl2->SetChargeRatio(1.);
1745               cl2->SetType(50);
1746               fDetTypeRec->AddRecPoint(*cl2);
1747             }
1748             ncl++;
1749           } // cross is within the detector
1750           //
1751           //--------------
1752           
1753         } // bad Pstrip
1754         
1755       } // end loop over Pstrips
1756       
1757     } // end loop over Nside 1D clusters
1758     
1759     for (Int_t j=0; j<nn; j++) { // loop over Pside 1D clusters with no crosses
1760       if(cpositive[j]) continue;
1761       
1762       //      for(Int_t ib=0; ib<768; ib++) { // loop over all Nside strips
1763       for(Int_t ib=15; ib<753; ib++) { // loop over all Nside strips
1764         
1765         if(cal->IsNChannelBad(ib)) { // check if strip is bad
1766           Float_t yP=neg[j].GetY();     
1767           Float_t xt, zt;
1768           seg->GetPadCxz(yP, 1.*ib, xt, zt);    
1769           
1770           //----------
1771           // bad Nstrip is crossing the Pside 1Dcluster -> create recpoint
1772           // 
1773           if ( (TMath::Abs(xt)<hwSSD+0.01) && (TMath::Abs(zt)<hlSSD+0.01) ) {
1774             Double_t loc[3]={xt,0.,zt},trk[3]={0.,0.,0.};
1775             mT2L->MasterToLocal(loc,trk);
1776             lp[0]=trk[1];
1777             lp[1]=trk[2];        
1778             lp[4]=neg[j].GetQ(); //Q
1779             for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1780             for (Int_t ilab=0;ilab<3;ilab++) milab[ilab] = neg[j].GetLabel(ilab);         
1781             CheckLabels2(milab);
1782             milab[3]=( j << 10 ) + idet; // pos|neg|det
1783             Int_t info[3] = {0.,neg[j].GetNd(),fNlayer[fModule]};
1784
1785         lp[2]=0.0022*0.0022;  //SigmaY2
1786         lp[3]=0.110*0.110;  //SigmaZ2
1787         lp[5]=-0.00012; // out-of-diagonal element of covariance matrix
1788         
1789             AliITSRecPoint * cl2;
1790             if(clusters){
1791               cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);            
1792               cl2->SetChargeRatio(1.);
1793               cl2->SetType(60);   
1794             }
1795             else{
1796               cl2 = new AliITSRecPoint(milab,lp,info);
1797               cl2->SetChargeRatio(1.);
1798               cl2->SetType(60);
1799               fDetTypeRec->AddRecPoint(*cl2);
1800             }
1801             ncl++;
1802           } // cross is within the detector
1803           //
1804           //--------------
1805           
1806         } // bad Nstrip
1807       } // end loop over Nstrips
1808     } // end loop over Pside 1D clusters
1809     
1810   } // no bad sides 
1811
1812   //---------------------------------------------------------
1813
1814   else if( (countPbad>700) && (countNbad<100) ) { // bad Pside!!
1815
1816     for (Int_t i=0; i<np; i++) { // loop over Nside 1Dclusters with no crosses
1817       if(cnegative[i]) continue; // if intersecting Pside clusters continue;
1818       
1819       Float_t xt, zt;
1820       Float_t yN=pos[i].GetY(); 
1821       Float_t yP=0.;
1822       if (seg->GetLayer()==5) yP = yN + (7.6/1.9);
1823       else yP = yN - (7.6/1.9);
1824       seg->GetPadCxz(yP, yN, xt, zt);   
1825           
1826       if ( (TMath::Abs(xt)<hwSSD+0.01) && (TMath::Abs(zt)<hlSSD+0.01) ) {
1827         Double_t loc[3]={xt,0.,zt},trk[3]={0.,0.,0.};
1828         mT2L->MasterToLocal(loc,trk);
1829         lp[0]=trk[1];
1830         lp[1]=trk[2];        
1831         lp[4]=pos[i].GetQ(); //Q
1832         for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1833         for (Int_t ilab=0;ilab<3;ilab++) milab[ilab] = pos[i].GetLabel(ilab);     
1834         CheckLabels2(milab);
1835         milab[3]=( (i<<10) << 10 ) + idet; // pos|neg|det
1836         Int_t info[3] = {pos[i].GetNd(),0.,fNlayer[fModule]};
1837
1838         lp[2]=0.031*0.031;  //SigmaY2
1839         lp[3]=1.15*1.15;  //SigmaZ2
1840         lp[5]=-0.036;
1841
1842         AliITSRecPoint * cl2;
1843         if(clusters){
1844           cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);        
1845           cl2->SetChargeRatio(1.);
1846           cl2->SetType(70);       
1847         }
1848         else{
1849           cl2 = new AliITSRecPoint(milab,lp,info);
1850           cl2->SetChargeRatio(1.);
1851           cl2->SetType(70);
1852           fDetTypeRec->AddRecPoint(*cl2);
1853         }
1854         ncl++;
1855       } // cross is within the detector
1856       //
1857       //--------------
1858       
1859     } // end loop over Nside 1D clusters
1860     
1861   } // bad Pside module
1862   
1863   else if( (countNbad>700) && (countPbad<100) ) { // bad Nside!!
1864     
1865     for (Int_t j=0; j<nn; j++) { // loop over Pside 1D clusters with no crosses
1866       if(cpositive[j]) continue;
1867       
1868       Float_t xt, zt;
1869       Float_t yP=neg[j].GetY(); 
1870       Float_t yN=0.;
1871       if (seg->GetLayer()==5) yN = yP - (7.6/1.9);
1872       else yN = yP + (7.6/1.9);
1873       seg->GetPadCxz(yP, yN, xt, zt);   
1874       
1875       if ( (TMath::Abs(xt)<hwSSD+0.01) && (TMath::Abs(zt)<hlSSD+0.01) ) {
1876         Double_t loc[3]={xt,0.,zt},trk[3]={0.,0.,0.};
1877         mT2L->MasterToLocal(loc,trk);
1878         lp[0]=trk[1];
1879         lp[1]=trk[2];        
1880         lp[4]=neg[j].GetQ(); //Q
1881         for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1882         for (Int_t ilab=0;ilab<3;ilab++) milab[ilab] = neg[j].GetLabel(ilab);     
1883         CheckLabels2(milab);
1884         milab[3]=( j << 10 ) + idet; // pos|neg|det
1885         Int_t info[3] = {0.,neg[j].GetNd(),fNlayer[fModule]};
1886
1887         lp[2]=0.0085*0.0085;  //SigmaY2
1888         lp[3]=1.15*1.15;  //SigmaZ2
1889         lp[5]=0.0093;
1890
1891         AliITSRecPoint * cl2;
1892         if(clusters){
1893           cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);        
1894           cl2->SetChargeRatio(1.);
1895           cl2->SetType(80);       
1896         }
1897         else{
1898           cl2 = new AliITSRecPoint(milab,lp,info);
1899           cl2->SetChargeRatio(1.);
1900           cl2->SetType(80);
1901           fDetTypeRec->AddRecPoint(*cl2);
1902         }
1903         ncl++;
1904       } // cross is within the detector
1905       //
1906       //--------------
1907       
1908     } // end loop over Pside 1D clusters
1909     
1910   } // bad Nside module
1911   
1912   //---------------------------------------------------------
1913   
1914   //cout<<ncl<<" clusters for this module"<<endl;
1915
1916   delete [] cnegative;
1917   delete [] cused1;
1918   delete [] negativepair;
1919   delete [] cpositive;
1920   delete [] cused2;
1921   delete [] positivepair;
1922
1923 }