]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSClusterFinderV2SSD.cxx
filter out additional compile defines to fit into rootcints 1024 char limit
[u/mrichter/AliRoot.git] / ITS / AliITSClusterFinderV2SSD.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-2003, 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 //          Revised: Enrico Fragiacomo, enrico.fragiacomo@ts.infn.it      //
23 //                                                                        //
24 ///////////////////////////////////////////////////////////////////////////
25
26 #include <Riostream.h>
27
28
29 #include "AliITSClusterFinderV2SSD.h"
30 #include "AliITSRecPoint.h"
31 #include "AliITSgeomTGeo.h"
32 #include "AliITSDetTypeRec.h"
33 #include "AliRawReader.h"
34 #include "AliITSRawStreamSSD.h"
35 #include <TClonesArray.h>
36 #include "AliITSdigitSSD.h"
37 #include "AliITSCalibrationSSD.h"
38
39 Short_t *AliITSClusterFinderV2SSD::fgPairs = 0x0;
40 Int_t    AliITSClusterFinderV2SSD::fgPairsSize = 0;
41
42 ClassImp(AliITSClusterFinderV2SSD)
43
44
45 AliITSClusterFinderV2SSD::AliITSClusterFinderV2SSD(AliITSDetTypeRec* dettyp):AliITSClusterFinderV2(dettyp),
46 fLastSSD1(AliITSgeomTGeo::GetModuleIndex(6,1,1)-1),
47 fYpitchSSD(0.0095),
48 fHwSSD(3.65),
49 fHlSSD(2.00),
50 fTanP(0.0275),
51 fTanN(0.0075){
52
53   //Default constructor
54
55 }
56  
57 //______________________________________________________________________
58 AliITSClusterFinderV2SSD::AliITSClusterFinderV2SSD(const AliITSClusterFinderV2SSD &cf) : AliITSClusterFinderV2(cf),                                             fLastSSD1(cf.fLastSSD1),
59 fYpitchSSD(cf.fYpitchSSD),
60 fHwSSD(cf.fHwSSD),
61 fHlSSD(cf.fHlSSD),
62 fTanP(cf.fTanP),
63 fTanN(cf.fTanN)
64 {
65   // Copy constructor
66
67 }
68
69 //______________________________________________________________________
70 AliITSClusterFinderV2SSD& AliITSClusterFinderV2SSD::operator=(const AliITSClusterFinderV2SSD&  cf ){
71   // Assignment operator
72
73   this->~AliITSClusterFinderV2SSD();
74   new(this) AliITSClusterFinderV2SSD(cf);
75   return *this;
76 }
77
78
79 void AliITSClusterFinderV2SSD::FindRawClusters(Int_t mod){
80
81   //Find clusters V2
82   SetModule(mod);
83   FindClustersSSD(fDigits);
84
85 }
86
87 void AliITSClusterFinderV2SSD::FindClustersSSD(TClonesArray *alldigits) {
88   //------------------------------------------------------------
89   // Actual SSD cluster finder
90   //------------------------------------------------------------
91   AliITSCalibrationSSD* cal = (AliITSCalibrationSSD*)GetResp(fModule);
92   Float_t gain=0;
93
94   Int_t smaxall=alldigits->GetEntriesFast();
95   if (smaxall==0) return;
96   //  TObjArray *digits = new TObjArray;
97   TObjArray digits;
98   for (Int_t i=0;i<smaxall; i++){
99     AliITSdigitSSD *d=(AliITSdigitSSD*)alldigits->UncheckedAt(i);
100
101     if(d->IsSideP()) gain = cal->GetGainP(d->GetStripNumber());  
102     else gain = cal->GetGainN(d->GetStripNumber());
103
104     Float_t q=gain*d->GetSignal(); // calibration brings mip peaks around 120 (in ADC units)
105     q=cal->ADCToKeV(q); // converts the charge in KeV from ADC units
106     //Float_t q=d->GetSignal()/4.29;// temp. fix (for PID purposed - normalis. to be checked)
107     d->SetSignal(Int_t(q));
108
109     if (d->GetSignal()<3) continue;
110     digits.AddLast(d);
111   }
112   Int_t smax = digits.GetEntriesFast();
113   if (smax==0) return;
114   
115   const Int_t kMax=1000;
116   Int_t np=0, nn=0; 
117   Ali1Dcluster pos[kMax], neg[kMax];
118   Float_t y=0., q=0., qmax=0.; 
119   Int_t lab[4]={-2,-2,-2,-2};
120   
121   AliITSdigitSSD *d=(AliITSdigitSSD*)digits.UncheckedAt(0);
122   q += d->GetSignal();
123   y += d->GetCoord2()*d->GetSignal();
124   qmax=d->GetSignal();
125   lab[0]=d->GetTrack(0); lab[1]=d->GetTrack(1); lab[2]=d->GetTrack(2);
126   Int_t curr=d->GetCoord2();
127   Int_t flag=d->GetCoord1();
128   Int_t *n=&nn;
129   Ali1Dcluster *c=neg;
130   Int_t nd=1;
131   Int_t milab[10];
132   for (Int_t ilab=0;ilab<10;ilab++){
133     milab[ilab]=-2;
134   }
135   milab[0]=d->GetTrack(0); milab[1]=d->GetTrack(1); milab[2]=d->GetTrack(2);
136
137   for (Int_t s=1; s<smax; s++) {
138       d=(AliITSdigitSSD*)digits.UncheckedAt(s);      
139       Int_t strip=d->GetCoord2();
140       if ((strip-curr) > 1 || flag!=d->GetCoord1()) {
141          c[*n].SetY(y/q);
142          c[*n].SetQ(q);
143          c[*n].SetNd(nd);
144          CheckLabels2(milab);
145          c[*n].SetLabels(milab);
146          //Split suspiciously big cluster
147          if (nd>4&&nd<25) {
148            c[*n].SetY(y/q-0.25*nd);
149            c[*n].SetQ(0.5*q);
150            (*n)++;
151            if (*n==kMax) {
152              Error("FindClustersSSD","Too many 1D clusters !");
153              return;
154            }
155            c[*n].SetY(y/q+0.25*nd);
156            c[*n].SetQ(0.5*q);
157            c[*n].SetNd(nd);
158            c[*n].SetLabels(milab);
159          }       
160          (*n)++;
161          if (*n==kMax) {
162           Error("FindClustersSSD","Too many 1D clusters !");
163           return;
164          }
165          y=q=qmax=0.;
166          nd=0;
167          lab[0]=lab[1]=lab[2]=-2;
168          //
169          for (Int_t ilab=0;ilab<10;ilab++){
170            milab[ilab]=-2;
171          }
172          //
173          if (flag!=d->GetCoord1()) { n=&np; c=pos; }
174       }
175       flag=d->GetCoord1();
176       q += d->GetSignal();
177       y += d->GetCoord2()*d->GetSignal();
178       nd++;
179       if (d->GetSignal()>qmax) {
180          qmax=d->GetSignal();
181          lab[0]=d->GetTrack(0); lab[1]=d->GetTrack(1); lab[2]=d->GetTrack(2);
182       }
183       for (Int_t ilab=0;ilab<10;ilab++) {
184         if (d->GetTrack(ilab)>=0) AddLabel(milab, (d->GetTrack(ilab))); 
185       }
186       curr=strip;
187   }
188   c[*n].SetY(y/q);
189   c[*n].SetQ(q);
190   c[*n].SetNd(nd);
191   c[*n].SetLabels(lab);
192   //Split suspiciously big cluster
193   if (nd>4 && nd<25) {
194      c[*n].SetY(y/q-0.25*nd);
195      c[*n].SetQ(0.5*q);
196      (*n)++;
197      if (*n==kMax) {
198         Error("FindClustersSSD","Too many 1D clusters !");
199         return;
200      }
201      c[*n].SetY(y/q+0.25*nd);
202      c[*n].SetQ(0.5*q);
203      c[*n].SetNd(nd);
204      c[*n].SetLabels(lab);
205   }
206   (*n)++;
207   if (*n==kMax) {
208      Error("FindClustersSSD","Too many 1D clusters !");
209      return;
210   }
211
212   FindClustersSSD(neg, nn, pos, np);
213 }
214
215
216 void AliITSClusterFinderV2SSD::RawdataToClusters(AliRawReader* rawReader,TClonesArray** clusters){
217
218     //------------------------------------------------------------
219   // This function creates ITS clusters from raw data
220   //------------------------------------------------------------
221   rawReader->Reset();
222   AliITSRawStreamSSD inputSSD(rawReader);
223   //  rawReader->SelectEquipment(-1,0,15);
224   FindClustersSSD(&inputSSD,clusters);
225   
226 }
227
228 void AliITSClusterFinderV2SSD::FindClustersSSD(AliITSRawStreamSSD* input, 
229                                         TClonesArray** clusters) 
230 {
231   //------------------------------------------------------------
232   // Actual SSD cluster finder for raw data
233   //------------------------------------------------------------
234   Int_t nClustersSSD = 0;
235   const Int_t kMax = 1000;
236   Ali1Dcluster clusters1D[2][kMax];
237   Int_t nClusters[2] = {0, 0};
238   Int_t lab[3]={-2,-2,-2};
239   Float_t q = 0.;
240   Float_t y = 0.;
241   Int_t nDigits = 0;
242   Float_t gain=0;
243   Float_t noise=0.;
244   Float_t oldnoise=0.;
245   AliITSCalibrationSSD* cal=NULL;
246
247   Int_t signal=0;
248   Int_t iModule;
249   Int_t matrix[12][1536];
250   Int_t iddl=511;
251   Int_t iad=1;
252   Int_t ddl, ad, adc;
253   Int_t oddl = 0;
254   Int_t oad = 0;
255   Int_t oadc = 0;
256   Int_t ostrip = 0;
257   Int_t osignal = 65535;
258   Int_t strip;
259   Int_t n=0;
260   Bool_t next=0;
261
262   // read raw data input stream
263   while (kTRUE) {
264     
265     // reset signal matrix
266     for(Int_t i=0; i<12; i++) { for(Int_t j=0; j<1536; j++) { matrix[i][j] = 65535;} }
267
268     if(osignal!=65535) { 
269       n++;
270       matrix[oadc][ostrip] = osignal; // recover data from previous occurence of input->Next() 
271     }
272
273     // buffer data for ddl=iddl and ad=iad
274     while(kTRUE) {
275
276       next = input->Next();
277       ddl=input->GetDDL(); 
278       ad=input->GetAD();
279            if((!next)&&(input->flag)) continue;
280       adc = input->GetADC(); adc = (adc<6)? adc : adc - 2;
281       strip = input->GetStrip();
282       if(input->GetSideFlag()) strip=1535-strip;
283       signal = input->GetSignal();
284       //cout<<ddl<<" "<<ad<<" "<<adc<<" "<<strip<<" "<<signal<<endl;
285
286       if((ddl==iddl)&&(ad==iad)) {n++; matrix[adc][strip] = signal;}
287       else {oddl=iddl; oad=iad; oadc = adc; ostrip = strip; osignal=signal; iddl=ddl; iad=ad; break;}
288       
289       if(!next) break;
290     }
291     
292     if(n==0) continue; // first occurence
293     n=0; osignal=0;
294
295     // fill 1Dclusters
296     for(Int_t iadc=0; iadc<12; iadc++) {  // loop over ADC index for ddl=oddl and ad=oad
297
298       Int_t iimod = (oad - 1)  * 12 + iadc;
299       iModule = AliITSRawStreamSSD::GetModuleNumber(oddl,iimod);
300       if(iModule==-1) continue;
301       //cout<<"ddl="<<oddl<<" ad"<<oad<<" module="<<iModule<<endl;
302       cal = (AliITSCalibrationSSD*)GetResp(iModule);
303
304       Bool_t first = 0;
305
306       for(Int_t istrip=0; istrip<768; istrip++) { // P-side
307
308         signal = matrix[iadc][istrip];
309         oldnoise = noise;
310         noise = cal->GetNoiseP(istrip);
311         if(signal<3*noise) signal = 65535; // in case ZS was not done in hw do it now
312
313         if (signal!=65535) {
314           gain = cal->GetGainP(istrip);
315           signal = (Int_t) ( signal * gain ); // signal is corrected for gain
316           //cout<<"ddl="<<oddl<<" ad"<<oad<<" module="<<iModule<<" strip= "<<istrip<<
317           //        " sig="<<signal<<endl;
318           signal = (Int_t) cal->ADCToKeV( signal ); // signal is  converted in KeV 
319          
320           q += signal;    // add digit to current cluster
321           y += istrip * signal;   
322           nDigits++;
323           first=1;
324         }
325
326         else if(first) {
327
328           if ( ((nDigits==1)&&(q>5*oldnoise)) || (nDigits>1) ) {
329
330             Ali1Dcluster& cluster = clusters1D[0][nClusters[0]++];
331             cluster.SetY(y/q);
332             cluster.SetQ(q);
333             cluster.SetNd(nDigits);
334             cluster.SetLabels(lab);
335             
336             //Split suspiciously big cluster
337             if (nDigits > 4&&nDigits < 25) {
338               cluster.SetY(y/q - 0.25*nDigits);
339               cluster.SetQ(0.5*q);
340               if (nClusters[0] == kMax) {
341                 Error("FindClustersSSD", "Too many 1D clusters !");
342                 return;
343               }
344               Ali1Dcluster& cluster2 = clusters1D[0][nClusters[0]++];
345               cluster2.SetY(y/q + 0.25*nDigits);
346               cluster2.SetQ(0.5*q);
347               cluster2.SetNd(nDigits);
348               cluster2.SetLabels(lab);
349             }
350             
351           }
352           
353           y = q = 0.;
354           nDigits = 0;
355           first=0;
356         }
357
358       } // loop over strip on P-side
359
360       // if last strip does have signal
361       if(first) {
362         
363           if ( ((nDigits==1)&&(q>5*oldnoise)) || (nDigits>1) ) {
364
365             Ali1Dcluster& cluster = clusters1D[0][nClusters[0]++];
366             cluster.SetY(y/q);
367             cluster.SetQ(q);
368             cluster.SetNd(nDigits);
369             cluster.SetLabels(lab);
370             
371             //Split suspiciously big cluster
372             if (nDigits > 4&&nDigits < 25) {
373               cluster.SetY(y/q - 0.25*nDigits);
374               cluster.SetQ(0.5*q);
375               if (nClusters[0] == kMax) {
376                 Error("FindClustersSSD", "Too many 1D clusters !");
377                 return;
378               }
379               Ali1Dcluster& cluster2 = clusters1D[0][nClusters[0]++];
380               cluster2.SetY(y/q + 0.25*nDigits);
381               cluster2.SetQ(0.5*q);
382               cluster2.SetNd(nDigits);
383               cluster2.SetLabels(lab);
384             }
385             
386           }
387           y = q = 0.;
388           nDigits = 0;
389           first=0;
390       }
391       
392       oldnoise = 0.;
393       noise = 0.;
394       for(Int_t istrip=768; istrip<1536; istrip++) { // N-side
395         
396         signal = matrix[iadc][istrip];
397         strip = 1535-istrip;
398         oldnoise = noise;
399         noise = cal->GetNoiseN(strip);
400         if(signal<3*noise) signal = 65535; // in case ZS was not done in hw do it now
401
402         if (signal!=65535) {
403           gain = cal->GetGainN(strip);
404           signal = (Int_t) ( signal * gain); // signal is corrected for gain
405           signal = (Int_t) cal->ADCToKeV( signal ); // signal is  converted in KeV 
406           
407           // add digit to current cluster
408           q += signal;
409           y += strip * signal;
410           nDigits++;
411           first=1;
412         }
413
414         else if(first) {
415
416           if ( ((nDigits==1)&&(q>5*oldnoise)) || (nDigits>1) ) {
417             
418             Ali1Dcluster& cluster = clusters1D[1][nClusters[1]++];
419             cluster.SetY(y/q);
420             cluster.SetQ(q);
421             cluster.SetNd(nDigits);
422             cluster.SetLabels(lab);
423             
424             //Split suspiciously big cluster
425             if (nDigits > 4&&nDigits < 25) {
426               cluster.SetY(y/q - 0.25*nDigits);
427               cluster.SetQ(0.5*q);
428               if (nClusters[1] == kMax) {
429                 Error("FindClustersSSD", "Too many 1D clusters !");
430                 return;
431               }
432               Ali1Dcluster& cluster2 = clusters1D[1][nClusters[1]++];
433               cluster2.SetY(y/q + 0.25*nDigits);
434               cluster2.SetQ(0.5*q);
435               cluster2.SetNd(nDigits);
436               cluster2.SetLabels(lab);
437             }
438             
439           }
440           y = q = 0.;
441           nDigits = 0;
442           first=0;        
443         }
444         
445       } // loop over strips on N-side
446
447       if(first) {
448         
449           if ( ((nDigits==1)&&(q>5*oldnoise)) || (nDigits>1) ) {
450
451             Ali1Dcluster& cluster = clusters1D[1][nClusters[1]++];
452             cluster.SetY(y/q);
453             cluster.SetQ(q);
454             cluster.SetNd(nDigits);
455             cluster.SetLabels(lab);
456             
457             //Split suspiciously big cluster
458             if (nDigits > 4&&nDigits < 25) {
459               cluster.SetY(y/q - 0.25*nDigits);
460               cluster.SetQ(0.5*q);
461               if (nClusters[1] == kMax) {
462                 Error("FindClustersSSD", "Too many 1D clusters !");
463                 return;
464               }
465               Ali1Dcluster& cluster2 = clusters1D[1][nClusters[1]++];
466               cluster2.SetY(y/q + 0.25*nDigits);
467               cluster2.SetQ(0.5*q);
468               cluster2.SetNd(nDigits);
469               cluster2.SetLabels(lab);
470             }
471             
472           }
473           y = q = 0.;
474           nDigits = 0;
475           first=0;        
476       }
477       
478       // create recpoints
479       if((nClusters[0])&&(nClusters[1])) {
480  
481         //cout<<"creating recpoint for module="<<iModule<<" "<<nClusters[0]<<" "<<nClusters[1]<<endl;
482         clusters[iModule] = new TClonesArray("AliITSRecPoint");
483         fModule = iModule;
484         //      fModule = 500;
485         FindClustersSSD(&clusters1D[0][0], nClusters[0], 
486                         &clusters1D[1][0], nClusters[1], clusters[iModule]);
487         Int_t nClusters = clusters[iModule]->GetEntriesFast();
488         nClustersSSD += nClusters;
489       }
490
491       nClusters[0] = nClusters[1] = 0;
492       y = q = 0.;
493       nDigits = 0;
494
495     } // loop over adc
496
497     if((!next)||(iddl==528)) break;
498   }
499   
500   Info("FindClustersSSD", "found clusters in ITS SSD: %d", nClustersSSD);
501 }
502
503 void AliITSClusterFinderV2SSD::
504 FindClustersSSD(Ali1Dcluster* neg, Int_t nn, 
505                 Ali1Dcluster* pos, Int_t np,
506                 TClonesArray *clusters) {
507   //------------------------------------------------------------
508   // Actual SSD cluster finder
509   //------------------------------------------------------------
510
511   //  Float_t xyz[3];
512
513   const TGeoHMatrix *mT2L=AliITSgeomTGeo::GetTracking2LocalMatrix(fModule);
514
515   TClonesArray &cl=*clusters;
516   //
517   Float_t tanp=fTanP, tann=fTanN;
518   if (fModule>fLastSSD1) {tann=fTanP; tanp=fTanN;}
519   Int_t idet=fNdet[fModule];
520   Int_t ncl=0;
521   //
522   Int_t negativepair[30000];
523   Int_t cnegative[3000];  
524   Int_t cused1[3000];
525   Int_t positivepair[30000];
526   Int_t cpositive[3000];
527   Int_t cused2[3000];
528   for (Int_t i=0;i<3000;i++) {cnegative[i]=0; cused1[i]=0;}
529   for (Int_t i=0;i<3000;i++) {cpositive[i]=0; cused2[i]=0;}
530   for (Int_t i=0;i<30000;i++) {negativepair[i]=0; positivepair[i]=0;}
531
532   if ((np*nn) > fgPairsSize) {
533     if (fgPairs) delete [] fgPairs;
534     fgPairsSize = 4*np*nn;
535     fgPairs = new Short_t[fgPairsSize];
536   }
537   memset(fgPairs,0,sizeof(Short_t)*np*nn);
538
539   //
540   // find available pairs
541   //
542   for (Int_t i=0; i<np; i++) {
543     Float_t yp=pos[i].GetY()*fYpitchSSD; 
544     if (pos[i].GetQ()<3) continue;
545     for (Int_t j=0; j<nn; j++) {
546       if (neg[j].GetQ()<3) continue;
547       Float_t yn=neg[j].GetY()*fYpitchSSD;
548       Float_t zt=(2*fHlSSD*tanp + yp - yn)/(tann+tanp);
549       Float_t yt=yn + tann*zt;
550       zt-=fHlSSD; yt-=fHwSSD;
551       if (TMath::Abs(yt)<fHwSSD+0.01)
552       if (TMath::Abs(zt)<fHlSSD+0.01*(neg[j].GetNd()+pos[i].GetNd())) {
553         negativepair[i*10+cnegative[i]] =j;  //index
554         positivepair[j*10+cpositive[j]] =i;
555         cnegative[i]++;  //counters
556         cpositive[j]++; 
557         fgPairs[i*nn+j]=100;
558       }
559     }
560   }
561
562   //
563   // try to recover points out of but close to the module boundaries 
564   //
565   for (Int_t i=0; i<np; i++) {
566     Float_t yp=pos[i].GetY()*fYpitchSSD; 
567     if (pos[i].GetQ()<3) continue;
568     for (Int_t j=0; j<nn; j++) {
569       if (neg[j].GetQ()<3) continue;
570       // if both 1Dclusters have an other cross continue
571       if (cpositive[j]&&cnegative[i]) continue;
572       Float_t yn=neg[j].GetY()*fYpitchSSD;
573       Float_t zt=(2*fHlSSD*tanp + yp - yn)/(tann+tanp);
574       Float_t yt=yn + tann*zt;
575       zt-=fHlSSD; yt-=fHwSSD;
576       if (TMath::Abs(yt)<fHwSSD+0.1)
577       if (TMath::Abs(zt)<fHlSSD+0.15) {
578         // tag 1Dcluster (eventually will produce low quality recpoint)
579         if (cnegative[i]==0) pos[i].SetNd(100);  // not available pair
580         if (cpositive[j]==0) neg[j].SetNd(100);  // not available pair
581         negativepair[i*10+cnegative[i]] =j;  //index
582         positivepair[j*10+cpositive[j]] =i;
583         cnegative[i]++;  //counters
584         cpositive[j]++; 
585         fgPairs[i*nn+j]=100;
586       }
587     }
588   }
589
590   //
591   Float_t lp[5];
592   Int_t milab[10];
593   Double_t ratio;
594   
595   //
596   // sign gold tracks
597   //
598   for (Int_t ip=0;ip<np;ip++){
599     Float_t ybest=1000,zbest=1000,qbest=0;
600     //
601     // select gold clusters
602     if ( (cnegative[ip]==1) && cpositive[negativepair[10*ip]]==1){ 
603       Float_t yp=pos[ip].GetY()*fYpitchSSD; 
604       Int_t j = negativepair[10*ip];      
605       ratio = (pos[ip].GetQ()-neg[j].GetQ())/(pos[ip].GetQ()+neg[j].GetQ());
606       //
607       Float_t yn=neg[j].GetY()*fYpitchSSD;
608       Float_t zt=(2*fHlSSD*tanp + yp - yn)/(tann+tanp);
609       Float_t yt=yn + tann*zt;
610       zt-=fHlSSD; yt-=fHwSSD;
611       ybest=yt; zbest=zt; 
612       qbest=0.5*(pos[ip].GetQ()+neg[j].GetQ());
613       {
614       Double_t loc[3]={ybest,0.,zbest},trk[3]={0.,0.,0.};
615       mT2L->MasterToLocal(loc,trk);
616       lp[0]=trk[1];
617       lp[1]=trk[2];
618       }
619       lp[2]=0.0025*0.0025;  //SigmaY2
620       lp[3]=0.110*0.110;  //SigmaZ2
621       
622       lp[4]=qbest;        //Q
623       for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
624       for (Int_t ilab=0;ilab<3;ilab++){
625         milab[ilab] = pos[ip].GetLabel(ilab);
626         milab[ilab+3] = neg[j].GetLabel(ilab);
627       }
628       //
629       CheckLabels2(milab);
630       milab[3]=(((ip<<10) + j)<<10) + idet; // pos|neg|det
631       Int_t info[3] = {pos[ip].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
632       AliITSRecPoint * cl2;
633     
634       if(clusters){  // Note clusters != 0 when method is called for rawdata
635
636
637         cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);
638
639         //      cl2-> GetGlobalXYZ(xyz); cout<<"rec "<<xyz[0]<<" "<<xyz[1]<<" "<<xyz[2]<<endl;
640
641         cl2->SetChargeRatio(ratio);     
642         cl2->SetType(1);
643         fgPairs[ip*nn+j]=1;
644         if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
645           cl2->SetType(2);
646           fgPairs[ip*nn+j]=2;
647         }
648         cused1[ip]++;
649         cused2[j]++;
650         
651       }
652       else{ // Note clusters == 0 when method is called for digits
653
654         cl2 = new AliITSRecPoint(milab,lp,info);        
655
656         //      cl2-> GetGlobalXYZ(xyz); cout<<"rec "<<xyz[0]<<" "<<xyz[1]<<" "<<xyz[2]<<endl;
657
658         cl2->SetChargeRatio(ratio);     
659         cl2->SetType(1);
660         fgPairs[ip*nn+j]=1;
661         if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
662           cl2->SetType(2);
663           fgPairs[ip*nn+j]=2;
664         }
665         cused1[ip]++;
666         cused2[j]++;
667         //cout<<"AliITSClusterFinderV2SSD "<<fModule<<" gold"<<endl;
668         fDetTypeRec->AddRecPoint(*cl2);
669       }
670       ncl++;
671     }
672   }
673     
674   for (Int_t ip=0;ip<np;ip++){
675     Float_t ybest=1000,zbest=1000,qbest=0;
676     //
677     //
678     // select "silber" cluster
679     if ( cnegative[ip]==1 && cpositive[negativepair[10*ip]]==2){
680       Int_t in  = negativepair[10*ip];
681       Int_t ip2 = positivepair[10*in];
682       if (ip2==ip) ip2 =  positivepair[10*in+1];
683       Float_t pcharge = pos[ip].GetQ()+pos[ip2].GetQ();
684       if (TMath::Abs(pcharge-neg[in].GetQ())<10){
685         //
686         // add first pair
687         if (fgPairs[ip*nn+in]==100){  //
688           Float_t yp=pos[ip].GetY()*fYpitchSSD; 
689           Float_t yn=neg[in].GetY()*fYpitchSSD;
690           Float_t zt=(2*fHlSSD*tanp + yp - yn)/(tann+tanp);
691           Float_t yt=yn + tann*zt;
692           zt-=fHlSSD; yt-=fHwSSD;
693           ybest =yt;  zbest=zt; 
694           qbest =pos[ip].GetQ();
695           {
696           Double_t loc[3]={ybest,0.,zbest},trk[3]={0.,0.,0.};
697           mT2L->MasterToLocal(loc,trk);
698           lp[0]=trk[1];
699           lp[1]=trk[2];
700           }
701           lp[2]=0.0025*0.0025;  //SigmaY2
702           lp[3]=0.110*0.110;  //SigmaZ2
703           
704           lp[4]=qbest;        //Q
705           for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
706           for (Int_t ilab=0;ilab<3;ilab++){
707             milab[ilab] = pos[ip].GetLabel(ilab);
708             milab[ilab+3] = neg[in].GetLabel(ilab);
709           }
710           //
711           CheckLabels2(milab);
712           ratio = (pos[ip].GetQ()-neg[in].GetQ())/(pos[ip].GetQ()+neg[in].GetQ());
713           milab[3]=(((ip<<10) + in)<<10) + idet; // pos|neg|det
714           Int_t info[3] = {pos[ip].GetNd(),neg[in].GetNd(),fNlayer[fModule]};
715
716           AliITSRecPoint * cl2;
717           if(clusters){
718
719             cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);
720
721             //  cl2-> GetGlobalXYZ(xyz); cout<<"rec "<<xyz[0]<<" "<<xyz[1]<<" "<<xyz[2]<<endl;
722
723             cl2->SetChargeRatio(ratio);         
724             cl2->SetType(5);
725             fgPairs[ip*nn+in] = 5;
726             if ((pos[ip].GetNd()+neg[in].GetNd())>6){ //multi cluster
727               cl2->SetType(6);
728               fgPairs[ip*nn+in] = 6;
729             }       
730           }
731           else{
732             cl2 = new AliITSRecPoint(milab,lp,info);
733             cl2->SetChargeRatio(ratio);         
734             cl2->SetType(5);
735             fgPairs[ip*nn+in] = 5;
736             if ((pos[ip].GetNd()+neg[in].GetNd())>6){ //multi cluster
737               cl2->SetType(6);
738               fgPairs[ip*nn+in] = 6;
739             }
740             //cout<<"AliITSClusterFinderV2SSD "<<fModule<<" silver1"<<endl;
741
742             fDetTypeRec->AddRecPoint(*cl2);
743           }
744           ncl++;
745         }
746         
747         //
748         // add second pair
749         
750       //        if (!(cused1[ip2] || cused2[in])){  //
751         if (fgPairs[ip2*nn+in]==100){
752           Float_t yp=pos[ip2].GetY()*fYpitchSSD;
753           Float_t yn=neg[in].GetY()*fYpitchSSD;
754           Float_t zt=(2*fHlSSD*tanp + yp - yn)/(tann+tanp);
755           Float_t yt=yn + tann*zt;
756           zt-=fHlSSD; yt-=fHwSSD;
757           ybest =yt;  zbest=zt; 
758           qbest =pos[ip2].GetQ();
759           {
760           Double_t loc[3]={ybest,0.,zbest},trk[3]={0.,0.,0.};
761           mT2L->MasterToLocal(loc,trk);
762           lp[0]=trk[1];
763           lp[1]=trk[2];
764           }
765           lp[2]=0.0025*0.0025;  //SigmaY2
766           lp[3]=0.110*0.110;  //SigmaZ2
767           
768           lp[4]=qbest;        //Q
769           for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
770           for (Int_t ilab=0;ilab<3;ilab++){
771             milab[ilab] = pos[ip2].GetLabel(ilab);
772             milab[ilab+3] = neg[in].GetLabel(ilab);
773           }
774           //
775           CheckLabels2(milab);
776           ratio = (pos[ip2].GetQ()-neg[in].GetQ())/(pos[ip2].GetQ()+neg[in].GetQ());
777           milab[3]=(((ip2<<10) + in)<<10) + idet; // pos|neg|det
778           Int_t info[3] = {pos[ip2].GetNd(),neg[in].GetNd(),fNlayer[fModule]};
779           
780           AliITSRecPoint * cl2;
781           if(clusters){
782             cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);
783
784             //  cl2-> GetGlobalXYZ(xyz); cout<<"rec "<<xyz[0]<<" "<<xyz[1]<<" "<<xyz[2]<<endl;
785
786             cl2->SetChargeRatio(ratio);         
787             cl2->SetType(5);
788             fgPairs[ip2*nn+in] =5;
789             if ((pos[ip2].GetNd()+neg[in].GetNd())>6){ //multi cluster
790               cl2->SetType(6);
791               fgPairs[ip2*nn+in] =6;
792             }
793           }
794           else{
795             cl2 = new AliITSRecPoint(milab,lp,info);
796             cl2->SetChargeRatio(ratio);         
797             cl2->SetType(5);
798             fgPairs[ip2*nn+in] =5;
799             if ((pos[ip2].GetNd()+neg[in].GetNd())>6){ //multi cluster
800               cl2->SetType(6);
801               fgPairs[ip2*nn+in] =6;
802             }
803             
804             //   cout<<"AliITSClusterFinderV2SSD "<<fModule<<" silver2"<<endl;
805             fDetTypeRec->AddRecPoint(*cl2);
806           }
807           ncl++;
808         }       
809         cused1[ip]++;
810         cused1[ip2]++;
811         cused2[in]++;
812       }
813     }    
814   }
815
816   //  
817   for (Int_t jn=0;jn<nn;jn++){
818     if (cused2[jn]) continue;
819     Float_t ybest=1000,zbest=1000,qbest=0;
820     // select "silber" cluster
821     if ( cpositive[jn]==1 && cnegative[positivepair[10*jn]]==2){
822       Int_t ip  = positivepair[10*jn];
823       Int_t jn2 = negativepair[10*ip];
824       if (jn2==jn) jn2 =  negativepair[10*ip+1];
825       Float_t pcharge = neg[jn].GetQ()+neg[jn2].GetQ();
826       //
827       if (TMath::Abs(pcharge-pos[ip].GetQ())<10){
828         //
829         // add first pair
830         //      if (!(cused1[ip]||cused2[jn])){
831         if (fgPairs[ip*nn+jn]==100){
832           Float_t yn=neg[jn].GetY()*fYpitchSSD; 
833           Float_t yp=pos[ip].GetY()*fYpitchSSD;
834           Float_t zt=(2*fHlSSD*tanp + yp - yn)/(tann+tanp);
835           Float_t yt=yn + tann*zt;
836           zt-=fHlSSD; yt-=fHwSSD;
837           ybest =yt;  zbest=zt; 
838           qbest =neg[jn].GetQ();
839           {
840           Double_t loc[3]={ybest,0.,zbest},trk[3]={0.,0.,0.};
841           mT2L->MasterToLocal(loc,trk);
842           lp[0]=trk[1];
843           lp[1]=trk[2];
844           }
845           lp[2]=0.0025*0.0025;  //SigmaY2
846           lp[3]=0.110*0.110;  //SigmaZ2
847           
848           lp[4]=qbest;        //Q
849           for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
850           for (Int_t ilab=0;ilab<3;ilab++){
851             milab[ilab] = pos[ip].GetLabel(ilab);
852             milab[ilab+3] = neg[jn].GetLabel(ilab);
853           }
854           //
855           CheckLabels2(milab);
856           ratio = (pos[ip].GetQ()-neg[jn].GetQ())/(pos[ip].GetQ()+neg[jn].GetQ());
857           milab[3]=(((ip<<10) + jn)<<10) + idet; // pos|neg|det
858           Int_t info[3] = {pos[ip].GetNd(),neg[jn].GetNd(),fNlayer[fModule]};
859
860           AliITSRecPoint * cl2;
861           if(clusters){
862             cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);
863
864             //  cl2-> GetGlobalXYZ(xyz); cout<<"rec "<<xyz[0]<<" "<<xyz[1]<<" "<<xyz[2]<<endl;
865
866             cl2->SetChargeRatio(ratio);         
867             cl2->SetType(7);
868             fgPairs[ip*nn+jn] =7;
869             if ((pos[ip].GetNd()+neg[jn].GetNd())>6){ //multi cluster
870               cl2->SetType(8);
871               fgPairs[ip*nn+jn]=8;
872             }
873
874           }
875           else{
876             cl2 = new AliITSRecPoint(milab,lp,info);
877             cl2->SetChargeRatio(ratio);         
878             cl2->SetType(7);
879             fgPairs[ip*nn+jn] =7;
880             if ((pos[ip].GetNd()+neg[jn].GetNd())>6){ //multi cluster
881               cl2->SetType(8);
882               fgPairs[ip*nn+jn]=8;
883             }
884             //cout<<"AliITSClusterFinderV2SSD "<<fModule<<" silverN1"<<endl;
885
886             fDetTypeRec->AddRecPoint(*cl2);
887           }
888           ncl++;
889         }
890         //
891         // add second pair
892         //      if (!(cused1[ip]||cused2[jn2])){
893         if (fgPairs[ip*nn+jn2]==100){
894           Float_t yn=neg[jn2].GetY()*fYpitchSSD; 
895           Double_t yp=pos[ip].GetY()*fYpitchSSD; 
896           Double_t zt=(2*fHlSSD*tanp + yp - yn)/(tann+tanp);
897           Double_t yt=yn + tann*zt;
898           zt-=fHlSSD; yt-=fHwSSD;
899           ybest =yt;  zbest=zt; 
900           qbest =neg[jn2].GetQ();
901           {
902           Double_t loc[3]={ybest,0.,zbest},trk[3]={0.,0.,0.};
903           mT2L->MasterToLocal(loc,trk);
904           lp[0]=trk[1];
905           lp[1]=trk[2];
906           }
907           lp[2]=0.0025*0.0025;  //SigmaY2
908           lp[3]=0.110*0.110;  //SigmaZ2
909           
910           lp[4]=qbest;        //Q
911           for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
912           for (Int_t ilab=0;ilab<3;ilab++){
913             milab[ilab] = pos[ip].GetLabel(ilab);
914             milab[ilab+3] = neg[jn2].GetLabel(ilab);
915           }
916           //
917           CheckLabels2(milab);
918           ratio = (pos[ip].GetQ()-neg[jn2].GetQ())/(pos[ip].GetQ()+neg[jn2].GetQ());
919           milab[3]=(((ip<<10) + jn2)<<10) + idet; // pos|neg|det
920           Int_t info[3] = {pos[ip].GetNd(),neg[jn2].GetNd(),fNlayer[fModule]};
921           AliITSRecPoint * cl2;
922           if(clusters){
923             cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);
924
925             //  cl2-> GetGlobalXYZ(xyz); cout<<"rec "<<xyz[0]<<" "<<xyz[1]<<" "<<xyz[2]<<endl;
926
927             cl2->SetChargeRatio(ratio);         
928             fgPairs[ip*nn+jn2]=7;
929             cl2->SetType(7);
930             if ((pos[ip].GetNd()+neg[jn2].GetNd())>6){ //multi cluster
931               cl2->SetType(8);
932               fgPairs[ip*nn+jn2]=8;
933             }
934             
935           }
936           else{
937             cl2 = new AliITSRecPoint(milab,lp,info);
938             cl2->SetChargeRatio(ratio);         
939             fgPairs[ip*nn+jn2]=7;
940             cl2->SetType(7);
941             if ((pos[ip].GetNd()+neg[jn2].GetNd())>6){ //multi cluster
942               cl2->SetType(8);
943               fgPairs[ip*nn+jn2]=8;
944             }
945             //cout<<"AliITSClusterFinderV2SSD "<<fModule<<" silverN2"<<endl;
946
947             fDetTypeRec->AddRecPoint(*cl2);
948           }
949
950           ncl++;
951         }
952         cused1[ip]++;
953         cused2[jn]++;
954         cused2[jn2]++;
955       }
956     }    
957   }
958   
959   for (Int_t ip=0;ip<np;ip++){
960     Float_t ybest=1000,zbest=1000,qbest=0;
961     //
962     // 2x2 clusters
963     //
964     if ( (cnegative[ip]<5) && cpositive[negativepair[10*ip]]<5){ 
965       Float_t minchargediff =4.;
966       Int_t j=-1;
967       for (Int_t di=0;di<cnegative[ip];di++){
968         Int_t   jc = negativepair[ip*10+di];
969         Float_t chargedif = pos[ip].GetQ()-neg[jc].GetQ();
970         if (TMath::Abs(chargedif)<minchargediff){
971           j =jc;
972           minchargediff = TMath::Abs(chargedif);
973         }
974       }
975       if (j<0) continue;  // not proper cluster      
976
977       Int_t count =0;
978       for (Int_t di=0;di<cnegative[ip];di++){
979         Int_t   jc = negativepair[ip*10+di];
980         Float_t chargedif = pos[ip].GetQ()-neg[jc].GetQ();
981         if (TMath::Abs(chargedif)<minchargediff+3.) count++;
982       }
983       if (count>1) continue;  // more than one "proper" cluster for positive
984       //
985       count =0;
986       for (Int_t dj=0;dj<cpositive[j];dj++){
987         Int_t   ic  = positivepair[j*10+dj];
988         Float_t chargedif = pos[ic].GetQ()-neg[j].GetQ();
989         if (TMath::Abs(chargedif)<minchargediff+3.) count++;
990       }
991       if (count>1) continue;  // more than one "proper" cluster for negative
992       
993       Int_t jp = 0;
994       
995       count =0;
996       for (Int_t dj=0;dj<cnegative[jp];dj++){
997         Int_t   ic = positivepair[jp*10+dj];
998         Float_t chargedif = pos[ic].GetQ()-neg[jp].GetQ();
999         if (TMath::Abs(chargedif)<minchargediff+4.) count++;
1000       }
1001       if (count>1) continue;   
1002       if (fgPairs[ip*nn+j]<100) continue;
1003       //
1004       //almost gold clusters
1005       Float_t yp=pos[ip].GetY()*fYpitchSSD; 
1006       Float_t yn=neg[j].GetY()*fYpitchSSD;
1007       Float_t zt=(2*fHlSSD*tanp + yp - yn)/(tann+tanp);
1008       Float_t yt=yn + tann*zt;
1009       zt-=fHlSSD; yt-=fHwSSD;
1010       ybest=yt; zbest=zt; 
1011       qbest=0.5*(pos[ip].GetQ()+neg[j].GetQ());
1012       {
1013       Double_t loc[3]={ybest,0.,zbest},trk[3]={0.,0.,0.};
1014       mT2L->MasterToLocal(loc,trk);
1015       lp[0]=trk[1];
1016       lp[1]=trk[2];
1017       }
1018       lp[2]=0.0025*0.0025;  //SigmaY2
1019       lp[3]=0.110*0.110;  //SigmaZ2     
1020       lp[4]=qbest;        //Q
1021       for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1022       for (Int_t ilab=0;ilab<3;ilab++){
1023         milab[ilab] = pos[ip].GetLabel(ilab);
1024         milab[ilab+3] = neg[j].GetLabel(ilab);
1025       }
1026       //
1027       CheckLabels2(milab);
1028       ratio = (pos[ip].GetQ()-neg[j].GetQ())/(pos[ip].GetQ()+neg[j].GetQ());
1029       milab[3]=(((ip<<10) + j)<<10) + idet; // pos|neg|det
1030       Int_t info[3] = {pos[ip].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
1031       AliITSRecPoint * cl2;
1032       if(clusters){
1033         cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);
1034
1035         //      cl2-> GetGlobalXYZ(xyz); cout<<"rec "<<xyz[0]<<" "<<xyz[1]<<" "<<xyz[2]<<endl;
1036
1037         cl2->SetChargeRatio(ratio);     
1038         cl2->SetType(10);
1039         fgPairs[ip*nn+j]=10;
1040         if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
1041           cl2->SetType(11);
1042           fgPairs[ip*nn+j]=11;
1043         }
1044         cused1[ip]++;
1045         cused2[j]++;      
1046       }
1047       else{
1048         cl2 = new AliITSRecPoint(milab,lp,info);
1049         cl2->SetChargeRatio(ratio);     
1050         cl2->SetType(10);
1051         fgPairs[ip*nn+j]=10;
1052         if ((pos[ip].GetNd()+neg[j].GetNd())>6){ //multi cluster
1053           cl2->SetType(11);
1054           fgPairs[ip*nn+j]=11;
1055         }
1056         cused1[ip]++;
1057         cused2[j]++;      
1058         
1059         //cout<<"AliITSClusterFinderV2SSD "<<fModule<<" 2x2"<<endl;
1060
1061         fDetTypeRec->AddRecPoint(*cl2);
1062       }      
1063       ncl++;
1064     }
1065
1066   }
1067   
1068   //  
1069   for (Int_t i=0; i<np; i++) {
1070     Float_t ybest=1000,zbest=1000,qbest=0;
1071     Float_t yp=pos[i].GetY()*fYpitchSSD; 
1072     if (pos[i].GetQ()<3) continue;
1073     for (Int_t j=0; j<nn; j++) {
1074     //    for (Int_t di = 0;di<cpositive[i];di++){
1075     //  Int_t j = negativepair[10*i+di];
1076       if (neg[j].GetQ()<3) continue;
1077       if (cused2[j]||cused1[i]) continue;      
1078       if (fgPairs[i*nn+j]>0 &&fgPairs[i*nn+j]<100) continue;
1079       ratio = (pos[i].GetQ()-neg[j].GetQ())/(pos[i].GetQ()+neg[j].GetQ());      
1080       Float_t yn=neg[j].GetY()*fYpitchSSD;
1081       Float_t zt=(2*fHlSSD*tanp + yp - yn)/(tann+tanp);
1082       Float_t yt=yn + tann*zt;
1083       zt-=fHlSSD; yt-=fHwSSD;
1084       if (TMath::Abs(yt)<fHwSSD+0.01)
1085       if (TMath::Abs(zt)<fHlSSD+0.01*(neg[j].GetNd()+pos[i].GetNd())) {
1086         ybest=yt; zbest=zt; 
1087         qbest=0.5*(pos[i].GetQ()+neg[j].GetQ());
1088         {
1089         Double_t loc[3]={ybest,0.,zbest},trk[3]={0.,0.,0.};
1090         mT2L->MasterToLocal(loc,trk);
1091         lp[0]=trk[1];
1092         lp[1]=trk[2];
1093         }
1094         lp[2]=0.0025*0.0025;  //SigmaY2
1095         lp[3]=0.110*0.110;  //SigmaZ2
1096
1097         lp[4]=qbest;        //Q
1098         for (Int_t ilab=0;ilab<10;ilab++) milab[ilab]=-2;
1099         for (Int_t ilab=0;ilab<3;ilab++){
1100           milab[ilab] = pos[i].GetLabel(ilab);
1101           milab[ilab+3] = neg[j].GetLabel(ilab);
1102         }
1103         //
1104         CheckLabels2(milab);
1105         milab[3]=(((i<<10) + j)<<10) + idet; // pos|neg|det
1106         Int_t info[3] = {pos[i].GetNd(),neg[j].GetNd(),fNlayer[fModule]};
1107         AliITSRecPoint * cl2;
1108         if(clusters){
1109           cl2 = new (cl[ncl]) AliITSRecPoint(milab,lp,info);
1110
1111           //    cl2-> GetGlobalXYZ(xyz); cout<<"rec "<<xyz[0]<<" "<<xyz[1]<<" "<<xyz[2]<<endl;
1112
1113           cl2->SetChargeRatio(ratio);
1114           cl2->SetType(100+cpositive[j]+cnegative[i]);    
1115         }
1116         else{
1117           cl2 = new AliITSRecPoint(milab,lp,info);
1118           cl2->SetChargeRatio(ratio);
1119           cl2->SetType(100+cpositive[j]+cnegative[i]);
1120           
1121           //cout<<"AliITSClusterFinderV2SSD "<<fModule<<" other"<<endl;
1122
1123           fDetTypeRec->AddRecPoint(*cl2);
1124         }
1125         ncl++;
1126         //cl2->SetType(0);
1127         /*
1128           if (fgPairs[i*nn+j]<100){
1129           printf("problem:- %d\n", fgPairs[i*nn+j]);
1130           }
1131           if (cnegative[i]<2&&cpositive[j]<2){
1132           printf("problem:- %d\n", fgPairs[i*nn+j]);
1133           }
1134         */
1135       }
1136     }
1137   }
1138
1139 }
1140
1141