]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONClusterFinderVS.cxx
0c5f92825628fb0f69e09da260413b8dce934e50
[u/mrichter/AliRoot.git] / MUON / AliMUONClusterFinderVS.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, 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 #include "AliMUONClusterFinderVS.h"
19 #include "AliMUONDigit.h"
20 #include "AliMUONRawCluster.h"
21 #include "AliSegmentation.h"
22 #include "AliMUONResponse.h"
23 #include "AliMUONClusterInput.h"
24 #include "AliMUONHitMapA1.h"
25 #include "AliRun.h"
26 #include "AliMUON.h"
27
28 #include <TTree.h>
29 #include <TCanvas.h>
30 #include <TH1.h>
31 #include <TPad.h>
32 #include <TGraph.h> 
33 #include <TPostScript.h> 
34 #include <TMinuit.h> 
35 #include <TF1.h>
36
37 #include <stdio.h>
38 #include <Riostream.h>
39
40 //_____________________________________________________________________
41 // This function is minimized in the double-Mathieson fit
42 void fcnS2(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag);
43 void fcnS1(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag);
44 void fcnCombiS1(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag);
45 void fcnCombiS2(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag);
46
47 ClassImp(AliMUONClusterFinderVS)
48
49     AliMUONClusterFinderVS::AliMUONClusterFinderVS()
50 {
51 // Default constructor
52     fInput=AliMUONClusterInput::Instance();
53     fHitMap[0] = 0;
54     fHitMap[1] = 0;
55     fTrack[0]=fTrack[1]=-1;
56     fDebugLevel = 0; // make silent default
57     fGhostChi2Cut = 1e6; // nothing done by default
58     fSeg[0]    = 0;
59     fSeg[1]    = 0;
60     for(Int_t i=0; i<100; i++) {
61       for (Int_t j=0; j<2; j++) {
62         fDig[i][j] = 0;
63       }
64     }
65 }
66
67 AliMUONClusterFinderVS::AliMUONClusterFinderVS(const AliMUONClusterFinderVS & clusterFinder):TObject(clusterFinder)
68 {
69 // Dummy copy Constructor
70     ;
71 }
72
73 void AliMUONClusterFinderVS::Decluster(AliMUONRawCluster *cluster)
74 {
75 // Decluster by local maxima
76     SplitByLocalMaxima(cluster);
77 }
78
79 void AliMUONClusterFinderVS::SplitByLocalMaxima(AliMUONRawCluster *c)
80 {
81 // Split complex cluster by local maxima 
82     Int_t cath, i;
83
84     fInput->SetCluster(c);
85
86     fMul[0]=c->fMultiplicity[0];
87     fMul[1]=c->fMultiplicity[1];
88
89 //
90 //  dump digit information into arrays
91 //
92
93     Float_t qtot;
94     
95     for (cath=0; cath<2; cath++) {
96         qtot=0;
97         for (i=0; i<fMul[cath]; i++)
98         {
99             // pointer to digit
100             fDig[i][cath]=fInput->Digit(cath, c->fIndexMap[i][cath]);
101             // pad coordinates
102             fIx[i][cath]= fDig[i][cath]->PadX();
103             fIy[i][cath]= fDig[i][cath]->PadY();
104             // pad charge
105             fQ[i][cath] = fDig[i][cath]->Signal();
106             // pad centre coordinates
107             fSeg[cath]->
108                 GetPadC(fIx[i][cath], fIy[i][cath], fX[i][cath], fY[i][cath], fZ[i][cath]);
109         } // loop over cluster digits
110     }  // loop over cathodes
111
112
113     FindLocalMaxima(c);
114
115 //
116 //  Initialise and perform mathieson fits
117     Float_t chi2, oldchi2;
118 //  ++++++++++++++++++*************+++++++++++++++++++++
119 //  (1) No more than one local maximum per cathode plane 
120 //  +++++++++++++++++++++++++++++++*************++++++++
121     if ((fNLocal[0]==1 && (fNLocal[1]==0 ||  fNLocal[1]==1)) || 
122         (fNLocal[0]==0 && fNLocal[1]==1)) {
123 // Perform combined single Mathieson fit
124 // Initial values for coordinates (x,y) 
125
126         // One local maximum on cathodes 1 and 2 (X->cathode 2, Y->cathode 1)
127         if (fNLocal[0]==1 &&  fNLocal[1]==1) {
128             fXInit[0]=c->fX[1];
129             fYInit[0]=c->fY[0];
130             // One local maximum on cathode 1 (X,Y->cathode 1)
131         } else if (fNLocal[0]==1) {
132             fXInit[0]=c->fX[0];
133             fYInit[0]=c->fY[0];
134             // One local maximum on cathode 2  (X,Y->cathode 2)
135         } else {
136             fXInit[0]=c->fX[1];
137             fYInit[0]=c->fY[1];
138         }
139         if (fDebugLevel)
140             fprintf(stderr,"\n cas (1) CombiSingleMathiesonFit(c)\n");
141         chi2=CombiSingleMathiesonFit(c);
142 //      Int_t ndf = fgNbins[0]+fgNbins[1]-2;
143 //      Float_t prob = TMath::Prob(Double_t(chi2),ndf);
144 //      prob1->Fill(prob);
145 //      chi2_1->Fill(chi2);
146         oldchi2=chi2;
147         if (fDebugLevel)
148             fprintf(stderr," chi2 %f ",chi2);
149
150         c->fX[0]=fXFit[0];
151         c->fY[0]=fYFit[0];
152
153         c->fX[1]=fXFit[0];
154         c->fY[1]=fYFit[0];
155         c->fChi2[0]=chi2;
156         c->fChi2[1]=chi2;
157         // Force on anod
158         c->fX[0]=fSeg[0]->GetAnod(c->fX[0]);
159         c->fX[1]=fSeg[1]->GetAnod(c->fX[1]);
160         
161 // If reasonable chi^2 add result to the list of rawclusters
162         if (chi2 < 0.3) {
163             AddRawCluster(*c);
164 // If not try combined double Mathieson Fit
165         } else {
166             fprintf(stderr," MAUVAIS CHI2 !!!\n");
167             if (fNLocal[0]==1 &&  fNLocal[1]==1) {
168                 fXInit[0]=fX[fIndLocal[0][1]][1];
169                 fYInit[0]=fY[fIndLocal[0][0]][0];
170                 fXInit[1]=fX[fIndLocal[0][1]][1];
171                 fYInit[1]=fY[fIndLocal[0][0]][0];
172             } else if (fNLocal[0]==1) {
173                 fXInit[0]=fX[fIndLocal[0][0]][0];
174                 fYInit[0]=fY[fIndLocal[0][0]][0];
175                 fXInit[1]=fX[fIndLocal[0][0]][0];
176                 fYInit[1]=fY[fIndLocal[0][0]][0];
177             } else {
178                 fXInit[0]=fX[fIndLocal[0][1]][1];
179                 fYInit[0]=fY[fIndLocal[0][1]][1];
180                 fXInit[1]=fX[fIndLocal[0][1]][1];
181                 fYInit[1]=fY[fIndLocal[0][1]][1];
182             }
183             
184 //  Initial value for charge ratios
185             fQrInit[0]=0.5;
186             fQrInit[1]=0.5;
187             if (fDebugLevel)
188             fprintf(stderr,"\n cas (1) CombiDoubleMathiesonFit(c)\n");
189             chi2=CombiDoubleMathiesonFit(c);
190 //          Int_t ndf = fgNbins[0]+fgNbins[1]-6;
191 //          Float_t prob = TMath::Prob(chi2,ndf);
192 //          prob2->Fill(prob);
193 //          chi2_2->Fill(chi2);
194             
195 // Was this any better ??
196             fprintf(stderr," Old and new chi2 %f %f ", oldchi2, chi2);
197             if (fFitStat!=0 && chi2>0 && (2.*chi2 < oldchi2)) {
198                 fprintf(stderr," Split\n");
199                 // Split cluster into two according to fit result
200                 Split(c);
201             } else {
202                 fprintf(stderr," Don't Split\n");
203                 // Don't split
204                 AddRawCluster(*c);
205             }
206         }
207
208 //  +++++++++++++++++++++++++++++++++++++++
209 //  (2) Two local maxima per cathode plane 
210 //  +++++++++++++++++++++++++++++++++++++++
211     } else if (fNLocal[0]==2 &&  fNLocal[1]==2) {
212 //
213 //  Let's look for ghosts first 
214
215         Float_t xm[4][2], ym[4][2];
216         Float_t dpx, dpy, dx, dy;
217         Int_t ixm[4][2], iym[4][2];
218         Int_t isec, im1, im2, ico;
219 //
220 //  Form the 2x2 combinations
221 //  0-0, 0-1, 1-0, 1-1  
222         ico=0;
223         for (im1=0; im1<2; im1++) {
224             for (im2=0; im2<2; im2++) {     
225                 xm[ico][0]=fX[fIndLocal[im1][0]][0];
226                 ym[ico][0]=fY[fIndLocal[im1][0]][0];
227                 xm[ico][1]=fX[fIndLocal[im2][1]][1];
228                 ym[ico][1]=fY[fIndLocal[im2][1]][1];
229
230                 ixm[ico][0]=fIx[fIndLocal[im1][0]][0];
231                 iym[ico][0]=fIy[fIndLocal[im1][0]][0];
232                 ixm[ico][1]=fIx[fIndLocal[im2][1]][1];
233                 iym[ico][1]=fIy[fIndLocal[im2][1]][1];
234                 ico++;
235             }
236         }
237 // ico = 0 : first local maximum on cathodes 1 and 2
238 // ico = 1 : fisrt local maximum on cathode 1 and second on cathode 2
239 // ico = 2 : second local maximum on cathode 1 and first on cathode 1
240 // ico = 3 : second local maximum on cathodes 1 and 2
241
242 // Analyse the combinations and keep those that are possible !
243 // For each combination check consistency in x and y    
244         Int_t   iacc;
245         Bool_t  accepted[4];
246         Float_t dr[4] = {1.e4, 1.e4, 1.e4, 1.e4};
247         iacc=0;
248
249 // In case of staggering maxima are displaced by exactly half the pad-size in y. 
250 // We have to take into account the numerical precision in the consistency check;       
251         Float_t eps = 1.e-5;
252 //
253         for (ico=0; ico<4; ico++) {
254             accepted[ico]=kFALSE;
255 // cathode one: x-coordinate
256             isec=fSeg[0]->Sector(ixm[ico][0], iym[ico][0]);
257             dpx=fSeg[0]->Dpx(isec)/2.;
258             dx=TMath::Abs(xm[ico][0]-xm[ico][1]);
259 // cathode two: y-coordinate
260             isec=fSeg[1]->Sector(ixm[ico][1], iym[ico][1]);
261             dpy=fSeg[1]->Dpy(isec)/2.;
262             dy=TMath::Abs(ym[ico][0]-ym[ico][1]);
263             if (fDebugLevel>1) 
264                 printf("\n %i %f %f %f %f %f %f \n", ico, ym[ico][0], ym[ico][1], dy, dpy, dx, dpx );
265             if ((dx <= dpx) && (dy <= dpy+eps)) {
266                 // consistent
267                 accepted[ico]=kTRUE;
268                 dr[ico] = TMath::Sqrt(dx*dx+dy*dy);
269                 iacc++;
270             } else {
271                 // reject
272                 accepted[ico]=kFALSE;
273             }
274         }
275         printf("\n iacc= %d:\n", iacc);
276         if (iacc == 3) {
277             if (accepted[0] && accepted[1]) {
278                 if (dr[0] >= dr[1]) {
279                     accepted[0]=kFALSE;
280                 } else {
281                     accepted[1]=kFALSE;
282                 }
283             }
284
285             if (accepted[2] && accepted[3]) {
286                 if (dr[2] >= dr[3]) {
287                     accepted[2]=kFALSE;
288                 } else {
289                     accepted[3]=kFALSE;
290                 }
291             }
292 /*          
293 // eliminate one candidate
294             Float_t drmax = 0;
295             Int_t icobad = -1;
296
297             for (ico=0; ico<4; ico++) {
298                 if (accepted[ico] && dr[ico] > drmax) {
299                     icobad = ico;
300                     drmax  = dr[ico];
301                 }
302             }
303             
304             accepted[icobad] = kFALSE;
305 */
306             iacc = 2;
307         }
308         
309         
310         printf("\n iacc= %d:\n", iacc);
311         if (fDebugLevel) {
312             if (iacc==2) {
313                 fprintf(stderr,"\n iacc=2: No problem ! \n");
314             } else if (iacc==4) {
315                 fprintf(stderr,"\n iacc=4: Ok, but ghost problem !!! \n");
316             } else if (iacc==0) {
317                 fprintf(stderr,"\n iacc=0: I don't know what to do with this !!!!!!!!! \n");
318             }
319         }
320
321 //  Initial value for charge ratios
322         fQrInit[0]=Float_t(fQ[fIndLocal[0][0]][0])/
323             Float_t(fQ[fIndLocal[0][0]][0]+fQ[fIndLocal[1][0]][0]);
324         fQrInit[1]=Float_t(fQ[fIndLocal[0][1]][1])/
325             Float_t(fQ[fIndLocal[0][1]][1]+fQ[fIndLocal[1][1]][1]);
326         
327 // ******* iacc = 0 *******
328 // No combinations found between the 2 cathodes
329 // We keep the center of gravity of the cluster
330         if (iacc==0) {
331             AddRawCluster(*c);
332         }
333
334 // ******* iacc = 1 *******
335 // Only one combination found between the 2 cathodes
336         if (iacc==1) {
337 // Initial values for the 2 maxima (x,y)
338
339 // 1 maximum is initialised with the maximum of the combination found (X->cathode 2, Y->cathode 1)
340 // 1 maximum is initialised with the other maximum of the first cathode  
341             if (accepted[0]){
342                 fprintf(stderr,"ico=0\n");
343                 fXInit[0]=xm[0][1];
344                 fYInit[0]=ym[0][0];
345                 fXInit[1]=xm[3][0];
346                 fYInit[1]=ym[3][0];
347             } else if (accepted[1]){
348                 fprintf(stderr,"ico=1\n");
349                 fXInit[0]=xm[1][1];
350                 fYInit[0]=ym[1][0];
351                 fXInit[1]=xm[2][0];
352                 fYInit[1]=ym[2][0];
353             } else if (accepted[2]){
354                 fprintf(stderr,"ico=2\n");
355                 fXInit[0]=xm[2][1];
356                 fYInit[0]=ym[2][0];
357                 fXInit[1]=xm[1][0];
358                 fYInit[1]=ym[1][0];
359             } else if (accepted[3]){
360                 fprintf(stderr,"ico=3\n");
361                 fXInit[0]=xm[3][1];
362                 fYInit[0]=ym[3][0];
363                 fXInit[1]=xm[0][0];
364                 fYInit[1]=ym[0][0];
365             }
366             if (fDebugLevel)
367                 fprintf(stderr,"\n cas (2) CombiDoubleMathiesonFit(c)\n");
368             chi2=CombiDoubleMathiesonFit(c);
369 //          Int_t ndf = fgNbins[0]+fgNbins[1]-6;
370 //          Float_t prob = TMath::Prob(chi2,ndf);
371 //          prob2->Fill(prob);
372 //          chi2_2->Fill(chi2);
373             if (fDebugLevel)
374                 fprintf(stderr," chi2 %f\n",chi2);
375
376 // If reasonable chi^2 add result to the list of rawclusters
377             if (chi2<10) {
378                 Split(c);
379
380             } else {
381 // 1 maximum is initialised with the maximum of the combination found (X->cathode 2, Y->cathode 1)
382 // 1 maximum is initialised with the other maximum of the second cathode  
383                 if (accepted[0]){
384                     fprintf(stderr,"ico=0\n");
385                     fXInit[0]=xm[0][1];
386                     fYInit[0]=ym[0][0];
387                     fXInit[1]=xm[3][1];
388                     fYInit[1]=ym[3][1];
389                 } else if (accepted[1]){
390                     fprintf(stderr,"ico=1\n");
391                     fXInit[0]=xm[1][1];
392                     fYInit[0]=ym[1][0];
393                     fXInit[1]=xm[2][1];
394                     fYInit[1]=ym[2][1];
395                 } else if (accepted[2]){
396                     fprintf(stderr,"ico=2\n");
397                     fXInit[0]=xm[2][1];
398                     fYInit[0]=ym[2][0];
399                     fXInit[1]=xm[1][1];
400                     fYInit[1]=ym[1][1];
401                 } else if (accepted[3]){
402                     fprintf(stderr,"ico=3\n");
403                     fXInit[0]=xm[3][1];
404                     fYInit[0]=ym[3][0];
405                     fXInit[1]=xm[0][1];
406                     fYInit[1]=ym[0][1];
407                 }
408                 if (fDebugLevel)
409                     fprintf(stderr,"\n cas (2) CombiDoubleMathiesonFit(c)\n");
410                 chi2=CombiDoubleMathiesonFit(c);
411 //              Int_t ndf = fgNbins[0]+fgNbins[1]-6;
412 //              Float_t prob = TMath::Prob(chi2,ndf);
413 //              prob2->Fill(prob);
414 //              chi2_2->Fill(chi2);
415                 if (fDebugLevel)
416                     fprintf(stderr," chi2 %f\n",chi2);
417
418 // If reasonable chi^2 add result to the list of rawclusters
419                 if (chi2<10) {
420                     Split(c);
421                 } else {
422 //We keep only the combination found (X->cathode 2, Y->cathode 1)
423                     for (Int_t ico=0; ico<2; ico++) {
424                         if (accepted[ico]) {
425                             AliMUONRawCluster cnew;
426                             Int_t cath;    
427                             for (cath=0; cath<2; cath++) {
428                                 cnew.fX[cath]=Float_t(xm[ico][1]);
429                                 cnew.fY[cath]=Float_t(ym[ico][0]);
430                                 cnew.fZ[cath]=fZPlane;
431                                 
432                                 cnew.fMultiplicity[cath]=c->fMultiplicity[cath];
433                                 for (i=0; i<fMul[cath]; i++) {
434                                     cnew.fIndexMap[i][cath]=c->fIndexMap[i][cath];
435                                     fSeg[cath]->SetPad(fIx[i][cath], fIy[i][cath]);
436                                 }
437                                 fprintf(stderr,"\nRawCluster %d cath %d\n",ico,cath);
438                                 fprintf(stderr,"mult_av %d\n",c->fMultiplicity[cath]);
439                                 FillCluster(&cnew,cath);
440                             } 
441                             cnew.fClusterType=cnew.PhysicsContribution();
442                             AddRawCluster(cnew);
443                             fNPeaks++;
444                         }
445                     }
446                 }
447             }
448         }
449         
450 // ******* iacc = 2 *******
451 // Two combinations found between the 2 cathodes
452         if (iacc==2) {
453 // Was the same maximum taken twice
454             if ((accepted[0]&&accepted[1]) || (accepted[2]&&accepted[3])) {
455                 fprintf(stderr,"\n Maximum taken twice !!!\n");
456
457 // Have a try !! with that
458                 if (accepted[0]&&accepted[3]) {
459                     fXInit[0]=xm[0][1];
460                     fYInit[0]=ym[0][0];
461                     fXInit[1]=xm[1][1];
462                     fYInit[1]=ym[1][0];
463                 } else {
464                     fXInit[0]=xm[2][1];
465                     fYInit[0]=ym[2][0];
466                     fXInit[1]=xm[3][1];
467                     fYInit[1]=ym[3][0];
468                 }
469                 if (fDebugLevel)
470                     fprintf(stderr,"\n cas (2) CombiDoubleMathiesonFit(c)\n");
471                 chi2=CombiDoubleMathiesonFit(c);
472 //                  Int_t ndf = fgNbins[0]+fgNbins[1]-6;
473 //                  Float_t prob = TMath::Prob(chi2,ndf);
474 //                  prob2->Fill(prob);
475 //                  chi2_2->Fill(chi2);
476                 Split(c);
477                 
478             } else {
479 // No ghosts ! No Problems ! -  Perform one fit only !
480                 if (accepted[0]&&accepted[3]) {
481                     fXInit[0]=xm[0][1];
482                     fYInit[0]=ym[0][0];
483                     fXInit[1]=xm[3][1];
484                     fYInit[1]=ym[3][0];
485                 } else {
486                     fXInit[0]=xm[1][1];
487                     fYInit[0]=ym[1][0];
488                     fXInit[1]=xm[2][1];
489                     fYInit[1]=ym[2][0];
490                 }
491                 if (fDebugLevel)
492                     fprintf(stderr,"\n cas (2) CombiDoubleMathiesonFit(c)\n");
493                 chi2=CombiDoubleMathiesonFit(c);
494 //                  Int_t ndf = fgNbins[0]+fgNbins[1]-6;
495 //                  Float_t prob = TMath::Prob(chi2,ndf);
496 //                  prob2->Fill(prob);
497 //                  chi2_2->Fill(chi2);
498                 if (fDebugLevel)
499                     fprintf(stderr," chi2 %f\n",chi2);
500                 Split(c);
501             }
502             
503 // ******* iacc = 4 *******
504 // Four combinations found between the 2 cathodes
505 // Ghost !!
506         } else if (iacc==4) {
507 // Perform fits for the two possibilities !!    
508 // Accept if charges are compatible on both cathodes
509 // If none are compatible, keep everything
510             fXInit[0]=xm[0][1];
511             fYInit[0]=ym[0][0];
512             fXInit[1]=xm[3][1];
513             fYInit[1]=ym[3][0];
514             if (fDebugLevel)
515                 fprintf(stderr,"\n cas (2) CombiDoubleMathiesonFit(c)\n");
516             chi2=CombiDoubleMathiesonFit(c);
517 //              Int_t ndf = fgNbins[0]+fgNbins[1]-6;
518 //              Float_t prob = TMath::Prob(chi2,ndf);
519 //              prob2->Fill(prob);
520 //              chi2_2->Fill(chi2);
521             if (fDebugLevel)
522                 fprintf(stderr," chi2 %f\n",chi2);
523             // store results of fit and postpone decision
524             Double_t sXFit[2],sYFit[2],sQrFit[2];
525             Float_t sChi2[2];
526             for (Int_t i=0;i<2;i++) {
527                 sXFit[i]=fXFit[i];
528                 sYFit[i]=fYFit[i];
529                 sQrFit[i]=fQrFit[i];
530                 sChi2[i]=fChi2[i];
531             }
532             fXInit[0]=xm[1][1];
533             fYInit[0]=ym[1][0];
534             fXInit[1]=xm[2][1];
535             fYInit[1]=ym[2][0];
536             if (fDebugLevel)
537                 fprintf(stderr,"\n cas (2) CombiDoubleMathiesonFit(c)\n");
538             chi2=CombiDoubleMathiesonFit(c);
539 //              ndf = fgNbins[0]+fgNbins[1]-6;
540 //              prob = TMath::Prob(chi2,ndf);
541 //              prob2->Fill(prob);
542 //              chi2_2->Fill(chi2);
543             if (fDebugLevel)
544                 fprintf(stderr," chi2 %f\n",chi2);
545             // We have all informations to perform the decision
546             // Compute the chi2 for the 2 possibilities
547             Float_t chi2fi,chi2si,chi2f,chi2s;
548
549             chi2f = (TMath::Log(fInput->TotalCharge(0)*fQrFit[0]
550                   /  (fInput->TotalCharge(1)*fQrFit[1]) )
551                   / fInput->Response()->ChargeCorrel() );
552             chi2f *=chi2f;
553             chi2fi = (TMath::Log(fInput->TotalCharge(0)*(1-fQrFit[0])
554                   /  (fInput->TotalCharge(1)*(1-fQrFit[1])) )
555                   / fInput->Response()->ChargeCorrel() );
556             chi2f += chi2fi*chi2fi;
557
558             chi2s = (TMath::Log(fInput->TotalCharge(0)*sQrFit[0]
559                   /  (fInput->TotalCharge(1)*sQrFit[1]) )
560                   / fInput->Response()->ChargeCorrel() );
561             chi2s *=chi2s;
562             chi2si = (TMath::Log(fInput->TotalCharge(0)*(1-sQrFit[0])
563                   /  (fInput->TotalCharge(1)*(1-sQrFit[1])) )
564                   / fInput->Response()->ChargeCorrel() );
565             chi2s += chi2si*chi2si;
566
567             // usefull to store the charge matching chi2 in the cluster
568             // fChi2[0]=sChi2[1]=chi2f;
569             // fChi2[1]=sChi2[0]=chi2s;
570
571             if (chi2f<=fGhostChi2Cut && chi2s<=fGhostChi2Cut)
572                 c->fGhost=1;
573             if   (chi2f>fGhostChi2Cut && chi2s>fGhostChi2Cut) {
574                 // we keep the ghost
575                 c->fGhost=2;
576                 chi2s=-1;
577                 chi2f=-1;
578             }
579             if (chi2f<=fGhostChi2Cut)
580                 Split(c);
581             if (chi2s<=fGhostChi2Cut) {
582                 // retreive saved values
583                 for (Int_t i=0;i<2;i++) {
584                     fXFit[i]=sXFit[i];
585                     fYFit[i]=sYFit[i];
586                     fQrFit[i]=sQrFit[i];
587                     fChi2[i]=sChi2[i];
588                 }
589                 Split(c);
590             }
591             c->fGhost=0;
592         }
593
594     } else if (fNLocal[0]==2 &&  fNLocal[1]==1) {
595 //  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
596 //  (3) Two local maxima on cathode 1 and one maximum on cathode 2 
597 //  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
598 //
599         Float_t xm[4][2], ym[4][2];
600         Float_t dpx, dpy, dx, dy;
601         Int_t ixm[4][2], iym[4][2];
602         Int_t isec, im1, ico;
603 //
604 //  Form the 2x2 combinations
605 //  0-0, 0-1, 1-0, 1-1  
606         ico=0;
607         for (im1=0; im1<2; im1++) {
608             xm[ico][0]=fX[fIndLocal[im1][0]][0];
609             ym[ico][0]=fY[fIndLocal[im1][0]][0];
610             xm[ico][1]=fX[fIndLocal[0][1]][1];
611             ym[ico][1]=fY[fIndLocal[0][1]][1];
612             
613             ixm[ico][0]=fIx[fIndLocal[im1][0]][0];
614             iym[ico][0]=fIy[fIndLocal[im1][0]][0];
615             ixm[ico][1]=fIx[fIndLocal[0][1]][1];
616             iym[ico][1]=fIy[fIndLocal[0][1]][1];
617             ico++;
618         }
619 // ico = 0 : first local maximum on cathodes 1 and 2
620 // ico = 1 : second local maximum on cathode 1 and first on cathode 2
621
622 // Analyse the combinations and keep those that are possible !
623 // For each combination check consistency in x and y    
624         Int_t iacc;
625         Bool_t accepted[4];
626         iacc=0;
627         // In case of staggering maxima are displaced by exactly half the pad-size in y. 
628         // We have to take into account the numerical precision in the consistency check;
629         
630         Float_t eps = 1.e-5;
631
632         for (ico=0; ico<2; ico++) {
633             accepted[ico]=kFALSE;
634             isec=fSeg[0]->Sector(ixm[ico][0], iym[ico][0]);
635             dpx=fSeg[0]->Dpx(isec)/2.;
636             dx=TMath::Abs(xm[ico][0]-xm[ico][1]);
637             isec=fSeg[1]->Sector(ixm[ico][1], iym[ico][1]);
638             dpy=fSeg[1]->Dpy(isec)/2.;
639             dy=TMath::Abs(ym[ico][0]-ym[ico][1]);
640             if (fDebugLevel>1)
641                 printf("\n %i %f %f %f %f \n", ico, ym[ico][0], ym[ico][1], dy, dpy );
642             if ((dx <= dpx) && (dy <= dpy+eps)) {
643                 // consistent
644                 accepted[ico]=kTRUE;
645                 iacc++;
646             } else {
647                 // reject
648                 accepted[ico]=kFALSE;
649             }
650         }
651         
652         Float_t chi21 = 100;
653         Float_t chi22 = 100;
654         Float_t chi23 = 100;
655
656         //  Initial value for charge ratios
657         fQrInit[0]=Float_t(fQ[fIndLocal[0][0]][0])/
658             Float_t(fQ[fIndLocal[0][0]][0]+fQ[fIndLocal[1][0]][0]);
659         fQrInit[1]=fQrInit[0];
660         
661         if (accepted[0] && accepted[1]) {
662             
663             fXInit[0]=0.5*(xm[0][1]+xm[0][0]);
664             fYInit[0]=ym[0][0];
665             fXInit[1]=0.5*(xm[0][1]+xm[1][0]);
666             fYInit[1]=ym[1][0];
667             fQrInit[0]=0.5;
668             fQrInit[1]=0.5;
669             chi23=CombiDoubleMathiesonFit(c);
670             if (chi23<10) {
671                 Split(c);
672                 Float_t yst;
673                 yst = fYFit[0];
674                 fYFit[0] = fYFit[1];
675                 fYFit[1] = yst;
676                 Split(c);
677             }
678         } else if (accepted[0]) {
679             fXInit[0]=xm[0][1];
680             fYInit[0]=ym[0][0];
681             fXInit[1]=xm[1][0];
682             fYInit[1]=ym[1][0];
683             chi21=CombiDoubleMathiesonFit(c);
684 //          Int_t ndf = fgNbins[0]+fgNbins[1]-6;
685 //          Float_t prob = TMath::Prob(chi2,ndf);
686 //          prob2->Fill(prob);
687 //          chi2_2->Fill(chi21);
688             if (fDebugLevel)
689                 fprintf(stderr," chi2 %f\n",chi21);
690             if (chi21<10) Split(c);
691         } else if (accepted[1]) {
692             fXInit[0]=xm[1][1];
693             fYInit[0]=ym[1][0];
694             fXInit[1]=xm[0][0];
695             fYInit[1]=ym[0][0];
696             chi22=CombiDoubleMathiesonFit(c);
697 //          Int_t ndf = fgNbins[0]+fgNbins[1]-6;
698 //          Float_t prob = TMath::Prob(chi2,ndf);
699 //          prob2->Fill(prob);
700 //          chi2_2->Fill(chi22);
701             if (fDebugLevel)
702                 fprintf(stderr," chi2 %f\n",chi22);
703             if (chi22<10) Split(c);
704         }
705
706         if (chi21 > 10 && chi22 > 10 && chi23 > 10) {
707 // We keep only the combination found (X->cathode 2, Y->cathode 1)
708             for (Int_t ico=0; ico<2; ico++) {
709                 if (accepted[ico]) {
710                     AliMUONRawCluster cnew;
711                     Int_t cath;    
712                     for (cath=0; cath<2; cath++) {
713                         cnew.fX[cath]=Float_t(xm[ico][1]);
714                         cnew.fY[cath]=Float_t(ym[ico][0]);
715                         cnew.fZ[cath]=fZPlane;
716                         cnew.fMultiplicity[cath]=c->fMultiplicity[cath];
717                         for (i=0; i<fMul[cath]; i++) {
718                             cnew.fIndexMap[i][cath]=c->fIndexMap[i][cath];
719                             fSeg[cath]->SetPad(fIx[i][cath], fIy[i][cath]);
720                         }
721                         fprintf(stderr,"\nRawCluster %d cath %d\n",ico,cath);
722                         fprintf(stderr,"mult_av %d\n",c->fMultiplicity[cath]);
723                         FillCluster(&cnew,cath);
724                     } 
725                     cnew.fClusterType=cnew.PhysicsContribution();
726                     AddRawCluster(cnew);
727                     fNPeaks++;
728                 }
729             }
730         }
731         
732 //  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
733 //  (3') One local maximum on cathode 1 and two maxima on cathode 2 
734 //  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
735     } else if (fNLocal[0]==1 && fNLocal[1]==2) {
736         Float_t xm[4][2], ym[4][2];
737         Float_t dpx, dpy, dx, dy;
738         Int_t ixm[4][2], iym[4][2];
739         Int_t isec, im1, ico;
740 //
741 //  Form the 2x2 combinations
742 //  0-0, 0-1, 1-0, 1-1  
743         ico=0;
744         for (im1=0; im1<2; im1++) {
745             xm[ico][0]=fX[fIndLocal[0][0]][0];
746             ym[ico][0]=fY[fIndLocal[0][0]][0];
747             xm[ico][1]=fX[fIndLocal[im1][1]][1];
748             ym[ico][1]=fY[fIndLocal[im1][1]][1];
749             
750             ixm[ico][0]=fIx[fIndLocal[0][0]][0];
751             iym[ico][0]=fIy[fIndLocal[0][0]][0];
752             ixm[ico][1]=fIx[fIndLocal[im1][1]][1];
753             iym[ico][1]=fIy[fIndLocal[im1][1]][1];
754             ico++;
755         }
756 // ico = 0 : first local maximum on cathodes 1 and 2
757 // ico = 1 : first local maximum on cathode 1 and second on cathode 2
758
759 // Analyse the combinations and keep those that are possible !
760 // For each combination check consistency in x and y    
761         Int_t iacc;
762         Bool_t accepted[4];
763         iacc=0;
764         // In case of staggering maxima are displaced by exactly half the pad-size in y. 
765         // We have to take into account the numerical precision in the consistency check;       
766         Float_t eps = 1.e-5;
767
768         
769         for (ico=0; ico<2; ico++) {
770             accepted[ico]=kFALSE;
771             isec=fSeg[0]->Sector(ixm[ico][0], iym[ico][0]);
772             dpx=fSeg[0]->Dpx(isec)/2.;
773             dx=TMath::Abs(xm[ico][0]-xm[ico][1]);
774             isec=fSeg[1]->Sector(ixm[ico][1], iym[ico][1]);
775             dpy=fSeg[1]->Dpy(isec)/2.;
776             dy=TMath::Abs(ym[ico][0]-ym[ico][1]);
777             if (fDebugLevel>0)
778                 printf("\n %i %f %f %f %f \n", ico, ym[ico][0], ym[ico][1], dy, dpy );
779             if ((dx <= dpx) && (dy <= dpy+eps)) {
780                 // consistent
781                 accepted[ico]=kTRUE;
782                 fprintf(stderr,"ico %d\n",ico);
783                 iacc++;
784             } else {
785                 // reject
786                 accepted[ico]=kFALSE;
787             }
788         }
789
790         Float_t chi21 = 100;
791         Float_t chi22 = 100;
792         Float_t chi23 = 100;
793
794         fQrInit[1]=Float_t(fQ[fIndLocal[0][1]][1])/
795             Float_t(fQ[fIndLocal[0][1]][1]+fQ[fIndLocal[1][1]][1]);
796         
797         fQrInit[0]=fQrInit[1];
798
799         
800         if (accepted[0] && accepted[1]) {
801             fXInit[0]=xm[0][1];
802             fYInit[0]=0.5*(ym[0][0]+ym[0][1]);
803             fXInit[1]=xm[1][1];
804             fYInit[1]=0.5*(ym[0][0]+ym[1][1]);
805             fQrInit[0]=0.5;
806             fQrInit[1]=0.5;
807             chi23=CombiDoubleMathiesonFit(c);
808             if (chi23<10) {
809                 Split(c);
810                 Float_t yst;
811                 yst = fYFit[0];
812                 fYFit[0] = fYFit[1];
813                 fYFit[1] = yst;
814                 Split(c);
815             }
816         } else if (accepted[0]) {
817             fXInit[0]=xm[0][0];
818             fYInit[0]=ym[0][1];
819             fXInit[1]=xm[1][1];
820             fYInit[1]=ym[1][1];
821             chi21=CombiDoubleMathiesonFit(c);
822 //          Int_t ndf = fgNbins[0]+fgNbins[1]-6;
823 //          Float_t prob = TMath::Prob(chi2,ndf);
824 //          prob2->Fill(prob);
825 //          chi2_2->Fill(chi21);
826             if (fDebugLevel)
827                 fprintf(stderr," chi2 %f\n",chi21);
828             if (chi21<10) Split(c);
829         } else if (accepted[1]) {
830             fXInit[0]=xm[1][0];
831             fYInit[0]=ym[1][1];
832             fXInit[1]=xm[0][1];
833             fYInit[1]=ym[0][1];
834             chi22=CombiDoubleMathiesonFit(c);
835 //          Int_t ndf = fgNbins[0]+fgNbins[1]-6;
836 //          Float_t prob = TMath::Prob(chi2,ndf);
837 //          prob2->Fill(prob);
838 //          chi2_2->Fill(chi22);
839             if (fDebugLevel)
840                 fprintf(stderr," chi2 %f\n",chi22);
841             if (chi22<10) Split(c);
842         }
843
844         if (chi21 > 10 && chi22 > 10 && chi23 > 10) {
845 //We keep only the combination found (X->cathode 2, Y->cathode 1)
846             for (Int_t ico=0; ico<2; ico++) {
847                 if (accepted[ico]) {
848                     AliMUONRawCluster cnew;
849                     Int_t cath;    
850                     for (cath=0; cath<2; cath++) {
851                         cnew.fX[cath]=Float_t(xm[ico][1]);
852                         cnew.fY[cath]=Float_t(ym[ico][0]);
853                         cnew.fZ[cath]=fZPlane;
854                         cnew.fMultiplicity[cath]=c->fMultiplicity[cath];
855                         for (i=0; i<fMul[cath]; i++) {
856                             cnew.fIndexMap[i][cath]=c->fIndexMap[i][cath];
857                             fSeg[cath]->SetPad(fIx[i][cath], fIy[i][cath]);
858                         }
859                         fprintf(stderr,"\nRawCluster %d cath %d\n",ico,cath);
860                         fprintf(stderr,"mult_av %d\n",c->fMultiplicity[cath]);
861                         FillCluster(&cnew,cath);
862                     } 
863                     cnew.fClusterType=cnew.PhysicsContribution();
864                     AddRawCluster(cnew);
865                     fNPeaks++;
866                 }
867             }
868         }
869
870 //  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
871 //  (4) At least three local maxima on cathode 1 or on cathode 2 
872 //  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
873     } else if (fNLocal[0]>2 || fNLocal[1]>2) {
874         Int_t param = fNLocal[0]*fNLocal[1];
875         Int_t ii;
876
877         Float_t ** xm = new Float_t * [param];
878         for (ii=0; ii<param; ii++) xm[ii]=new Float_t [2];
879         Float_t ** ym = new Float_t * [param];
880         for (ii=0; ii<param; ii++) ym[ii]=new Float_t [2];
881         Int_t ** ixm = new Int_t * [param];
882         for (ii=0; ii<param; ii++) ixm[ii]=new Int_t [2];
883         Int_t ** iym = new Int_t * [param];
884         for (ii=0; ii<param; ii++) iym[ii]=new Int_t [2];
885         
886         Int_t isec, ico;
887         Float_t dpx, dpy, dx, dy;
888
889         ico=0;
890         for (Int_t im1=0; im1<fNLocal[0]; im1++) {
891             for (Int_t im2=0; im2<fNLocal[1]; im2++) {
892                 xm[ico][0]=fX[fIndLocal[im1][0]][0];
893                 ym[ico][0]=fY[fIndLocal[im1][0]][0];
894                 xm[ico][1]=fX[fIndLocal[im2][1]][1];
895                 ym[ico][1]=fY[fIndLocal[im2][1]][1];
896
897                 ixm[ico][0]=fIx[fIndLocal[im1][0]][0];
898                 iym[ico][0]=fIy[fIndLocal[im1][0]][0];
899                 ixm[ico][1]=fIx[fIndLocal[im2][1]][1];
900                 iym[ico][1]=fIy[fIndLocal[im2][1]][1];
901                 ico++;
902             }
903         }
904         
905         Int_t nIco = ico;
906         if (fDebugLevel)
907             fprintf(stderr,"nIco %d\n",nIco);
908         for (ico=0; ico<nIco; ico++) {
909             if (fDebugLevel)
910                 fprintf(stderr,"ico = %d\n",ico);
911             isec=fSeg[0]->Sector(ixm[ico][0], iym[ico][0]);
912             dpx=fSeg[0]->Dpx(isec)/2.;
913             dx=TMath::Abs(xm[ico][0]-xm[ico][1]);
914             isec=fSeg[1]->Sector(ixm[ico][1], iym[ico][1]);
915             dpy=fSeg[1]->Dpy(isec)/2.;
916             dy=TMath::Abs(ym[ico][0]-ym[ico][1]);
917             if (fDebugLevel) {
918                 fprintf(stderr,"dx %f dpx %f dy %f dpy %f\n",dx,dpx,dy,dpy);
919                 fprintf(stderr,"  X %f Y %f\n",xm[ico][1],ym[ico][0]);
920             }
921             if ((dx <= dpx) && (dy <= dpy)) {
922                 if (fDebugLevel)
923                     fprintf(stderr,"ok\n");
924                 Int_t cath;    
925                 AliMUONRawCluster cnew;
926                 for (cath=0; cath<2; cath++) {
927                     cnew.fX[cath]=Float_t(xm[ico][1]);
928                     cnew.fY[cath]=Float_t(ym[ico][0]);
929                     cnew.fZ[cath]=fZPlane;
930                     cnew.fMultiplicity[cath]=c->fMultiplicity[cath];
931                     for (i=0; i<fMul[cath]; i++) {
932                         cnew.fIndexMap[i][cath]=c->fIndexMap[i][cath];
933                         fSeg[cath]->SetPad(fIx[i][cath], fIy[i][cath]);
934                     }
935                     FillCluster(&cnew,cath);
936                 } 
937                 cnew.fClusterType=cnew.PhysicsContribution();
938                 AddRawCluster(cnew);
939                 fNPeaks++;
940             }
941         }
942         delete [] xm;
943         delete [] ym;
944         delete [] ixm;
945         delete [] iym;
946     }
947 }
948
949 void AliMUONClusterFinderVS::FindLocalMaxima(AliMUONRawCluster* /*c*/)
950 {
951 // Find all local maxima of a cluster
952     if (fDebugLevel)
953         printf("\n Find Local maxima  !");
954     
955     AliMUONDigit* digt;
956     
957     Int_t cath, cath1; // loops over cathodes
958     Int_t i;           // loops over digits
959     Int_t j;           // loops over cathodes
960 //
961 //  Find local maxima
962 //
963 //  counters for number of local maxima
964     fNLocal[0]=fNLocal[1]=0;
965 //  flags digits as local maximum
966     Bool_t isLocal[100][2];
967     for (i=0; i<100;i++) {
968         isLocal[i][0]=isLocal[i][1]=kFALSE;
969     }
970 //  number of next neighbours and arrays to store them 
971     Int_t nn;
972     Int_t x[10], y[10];
973 // loop over cathodes
974     for (cath=0; cath<2; cath++) {
975 // loop over cluster digits
976         for (i=0; i<fMul[cath]; i++) {
977 // get neighbours for that digit and assume that it is local maximum        
978             fSeg[cath]->Neighbours(fIx[i][cath], fIy[i][cath], &nn, x, y);
979             isLocal[i][cath]=kTRUE;
980             Int_t isec= fSeg[cath]->Sector(fIx[i][cath], fIy[i][cath]);
981             Float_t a0 = fSeg[cath]->Dpx(isec)*fSeg[cath]->Dpy(isec);
982 // loop over next neighbours, if at least one neighbour has higher charger assumption
983 // digit is not local maximum 
984             for (j=0; j<nn; j++) {
985                 if (fHitMap[cath]->TestHit(x[j], y[j])==kEmpty) continue;
986                 digt=(AliMUONDigit*) fHitMap[cath]->GetHit(x[j], y[j]);
987                 isec=fSeg[cath]->Sector(x[j], y[j]);
988                 Float_t a1 = fSeg[cath]->Dpx(isec)*fSeg[cath]->Dpy(isec);
989                 if (digt->Signal()/a1 > fQ[i][cath]/a0) {
990                     isLocal[i][cath]=kFALSE;
991                     break;
992 //
993 // handle special case of neighbouring pads with equal signal
994                 } else if (digt->Signal() == fQ[i][cath]) {
995                     if (fNLocal[cath]>0) {
996                         for (Int_t k=0; k<fNLocal[cath]; k++) {
997                             if (x[j]==fIx[fIndLocal[k][cath]][cath] 
998                                 && y[j]==fIy[fIndLocal[k][cath]][cath])
999                             {
1000                                 isLocal[i][cath]=kFALSE;
1001                             } 
1002                         } // loop over local maxima
1003                     } // are there already local maxima
1004                 } // same charge ? 
1005             } // loop over next neighbours
1006             if (isLocal[i][cath]) {
1007                 fIndLocal[fNLocal[cath]][cath]=i;
1008                 fNLocal[cath]++;
1009             } 
1010         } // loop over all digits
1011     } // loop over cathodes
1012
1013     if (fDebugLevel) {
1014         printf("\n Found %d %d %d %d local Maxima\n",
1015                fNLocal[0], fNLocal[1], fMul[0], fMul[1]);
1016         fprintf(stderr,"\n Cathode 1 local Maxima %d Multiplicite %d\n",fNLocal[0], fMul[0]);
1017         fprintf(stderr," Cathode 2 local Maxima %d Multiplicite %d\n",fNLocal[1], fMul[1]);
1018     }
1019     Int_t ix, iy, isec;
1020     Float_t dpx, dpy;
1021     
1022     
1023     if (fNLocal[1]==2 &&  (fNLocal[0]==1 || fNLocal[0]==0)) {
1024         Int_t iback=fNLocal[0];
1025         
1026 //  Two local maxima on cathode 2 and one maximum on cathode 1 
1027 //  Look for local maxima considering up and down neighbours on the 1st cathode only
1028 //
1029 //  Loop over cluster digits
1030         cath=0;
1031         cath1=1;
1032         
1033         for (i=0; i<fMul[cath]; i++) {
1034             isec=fSeg[cath]->Sector(fIx[i][cath],fIy[i][cath]);
1035             dpy=fSeg[cath]->Dpy(isec);
1036             dpx=fSeg[cath]->Dpx(isec);
1037             if (isLocal[i][cath]) continue;
1038 // Pad position should be consistent with position of local maxima on the opposite cathode
1039             if ((TMath::Abs(fX[i][cath]-fX[fIndLocal[0][cath1]][cath1]) > dpx/2.) && 
1040                 (TMath::Abs(fX[i][cath]-fX[fIndLocal[1][cath1]][cath1]) > dpx/2.))
1041                 continue;
1042
1043 // get neighbours for that digit and assume that it is local maximum        
1044             isLocal[i][cath]=kTRUE;
1045 // compare signal to that on the two neighbours on the left and on the right
1046 // iNN counts the number of neighbours with signal, it should be 1 or 2
1047             Int_t iNN=0;
1048
1049             for (fSeg[cath]
1050                      ->FirstPad(fX[i][cath], fY[i][cath], fZPlane, 0., dpy);
1051                  fSeg[cath]
1052                      ->MorePads();
1053                  fSeg[cath]
1054                      ->NextPad())
1055             {
1056                 ix = fSeg[cath]->Ix();
1057                 iy = fSeg[cath]->Iy();
1058                 // skip the current pad
1059                 if (iy == fIy[i][cath]) continue;
1060                 
1061                 if (fHitMap[cath]->TestHit(ix, iy)!=kEmpty) {
1062                     iNN++;
1063                     digt=(AliMUONDigit*) fHitMap[cath]->GetHit(ix,iy);
1064                     if (digt->Signal() > fQ[i][cath]) isLocal[i][cath]=kFALSE;
1065                 }
1066             } // Loop over pad neighbours in y
1067             if (isLocal[i][cath] && iNN>0) {
1068                 fIndLocal[fNLocal[cath]][cath]=i;
1069                 fNLocal[cath]++;
1070             } 
1071         } // loop over all digits
1072 // if one additional maximum has been found we are happy 
1073 // if more maxima have been found restore the previous situation
1074         if (fDebugLevel) {
1075             fprintf(stderr,
1076                     "\n New search gives %d local maxima for cathode 1 \n",
1077                     fNLocal[0]);
1078             fprintf(stderr,
1079                     "                  %d local maxima for cathode 2 \n",
1080                     fNLocal[1]);
1081         }
1082         if (fNLocal[cath]>2) {
1083             fNLocal[cath]=iback;
1084         }
1085         
1086     } // 1,2 local maxima
1087     
1088     if (fNLocal[0]==2 &&  (fNLocal[1]==1 || fNLocal[1]==0)) {
1089         Int_t iback=fNLocal[1];
1090         
1091 //  Two local maxima on cathode 1 and one maximum on cathode 2 
1092 //  Look for local maxima considering left and right neighbours on the 2nd cathode only
1093         cath=1;
1094         Int_t cath1 = 0;
1095         Float_t eps = 1.e-5;
1096         
1097 //
1098 //  Loop over cluster digits
1099         for (i=0; i<fMul[cath]; i++) {
1100             isec=fSeg[cath]->Sector(fIx[i][cath],fIy[i][cath]);
1101             dpx=fSeg[cath]->Dpx(isec);
1102             dpy=fSeg[cath]->Dpy(isec);
1103             if (isLocal[i][cath]) continue;
1104 // Pad position should be consistent with position of local maxima on the opposite cathode
1105             if ((TMath::Abs(fY[i][cath]-fY[fIndLocal[0][cath1]][cath1]) > dpy/2.+eps) && 
1106                 (TMath::Abs(fY[i][cath]-fY[fIndLocal[1][cath1]][cath1]) > dpy/2.+eps))
1107                 continue;
1108             
1109 //
1110 // get neighbours for that digit and assume that it is local maximum        
1111             isLocal[i][cath]=kTRUE;
1112 // compare signal to that on the two neighbours on the left and on the right
1113
1114 // iNN counts the number of neighbours with signal, it should be 1 or 2
1115             Int_t iNN=0;
1116             for (fSeg[cath]
1117                      ->FirstPad(fX[i][cath], fY[i][cath], fZPlane, dpx, 0.);
1118                  fSeg[cath]
1119                      ->MorePads();
1120                  fSeg[cath]
1121                      ->NextPad())
1122             {
1123
1124                 ix = fSeg[cath]->Ix();
1125                 iy = fSeg[cath]->Iy();
1126
1127                 // skip the current pad
1128                 if (ix == fIx[i][cath]) continue;
1129                 
1130                 if (fHitMap[cath]->TestHit(ix, iy)!=kEmpty) {
1131                     iNN++;
1132                     digt=(AliMUONDigit*) fHitMap[cath]->GetHit(ix,iy);
1133                     if (digt->Signal() > fQ[i][cath]) isLocal[i][cath]=kFALSE;
1134                 }
1135             } // Loop over pad neighbours in x
1136             if (isLocal[i][cath] && iNN>0) {
1137                 fIndLocal[fNLocal[cath]][cath]=i;
1138                 fNLocal[cath]++;
1139             } 
1140         } // loop over all digits
1141 // if one additional maximum has been found we are happy 
1142 // if more maxima have been found restore the previous situation
1143         if (fDebugLevel) {
1144             fprintf(stderr,"\n New search gives %d local maxima for cathode 1 \n",fNLocal[0]);
1145             fprintf(stderr,"\n                  %d local maxima for cathode 2 \n",fNLocal[1]);
1146             printf("\n New search gives %d %d \n",fNLocal[0],fNLocal[1]);
1147         }
1148         if (fNLocal[cath]>2) {
1149             fNLocal[cath]=iback;
1150         }
1151     } // 2,1 local maxima
1152 }
1153
1154
1155 void  AliMUONClusterFinderVS::FillCluster(AliMUONRawCluster* c, Int_t flag, Int_t cath) 
1156 {
1157 //
1158 //  Completes cluster information starting from list of digits
1159 //
1160     AliMUONDigit* dig;
1161     Float_t x, y, z;
1162     Int_t  ix, iy;
1163     
1164     if (cath==1) {
1165         c->fPeakSignal[cath]=c->fPeakSignal[0]; 
1166     } else {
1167         c->fPeakSignal[cath]=0;
1168     }
1169     
1170     
1171     if (flag) {
1172         c->fX[cath]=0;
1173         c->fY[cath]=0;
1174         c->fQ[cath]=0;
1175     }
1176
1177     if (fDebugLevel)
1178         fprintf(stderr,"\n fPeakSignal %d\n",c->fPeakSignal[cath]);
1179     for (Int_t i=0; i<c->fMultiplicity[cath]; i++)
1180     {
1181         dig= fInput->Digit(cath,c->fIndexMap[i][cath]);
1182         ix=dig->PadX()+c->fOffsetMap[i][cath];
1183         iy=dig->PadY();
1184         Int_t q=dig->Signal();
1185         if (!flag) q=Int_t(q*c->fContMap[i][cath]);
1186 //      fprintf(stderr,"q %d c->fPeakSignal[ %d ] %d\n",q,cath,c->fPeakSignal[cath]);
1187         if (dig->Physics() >= dig->Signal()) {
1188             c->fPhysicsMap[i]=2;
1189         } else if (dig->Physics() == 0) {
1190             c->fPhysicsMap[i]=0;
1191         } else  c->fPhysicsMap[i]=1;
1192 //
1193 // 
1194         if (fDebugLevel>1)
1195             fprintf(stderr,"q %d c->fPeakSignal[cath] %d\n",q,c->fPeakSignal[cath]);
1196 // peak signal and track list
1197         if (q>c->fPeakSignal[cath]) {
1198             c->fPeakSignal[cath]=q;
1199             c->fTracks[0]=dig->Hit();
1200             c->fTracks[1]=dig->Track(0);
1201             c->fTracks[2]=dig->Track(1);
1202 //          fprintf(stderr," c->fTracks[0] %d c->fTracks[1] %d\n",dig->fHit,dig->fTracks[0]);
1203         }
1204 //
1205         if (flag) {
1206             fSeg[cath]->GetPadC(ix, iy, x, y, z);
1207             c->fX[cath] += q*x;
1208             c->fY[cath] += q*y;
1209             c->fQ[cath] += q;
1210         }
1211     } // loop over digits
1212     if (fDebugLevel)
1213         fprintf(stderr," fin du cluster c\n");
1214
1215
1216     if (flag) {
1217         c->fX[cath]/=c->fQ[cath];
1218 // Force on anod
1219         c->fX[cath]=fSeg[cath]->GetAnod(c->fX[cath]);
1220         c->fY[cath]/=c->fQ[cath]; 
1221 //
1222 //  apply correction to the coordinate along the anode wire
1223 //
1224         x=c->fX[cath];   
1225         y=c->fY[cath];
1226         fSeg[cath]->GetPadI(x, y, fZPlane, ix, iy);
1227         fSeg[cath]->GetPadC(ix, iy, x, y, z);
1228         Int_t isec=fSeg[cath]->Sector(ix,iy);
1229         TF1* cogCorr = fSeg[cath]->CorrFunc(isec-1);
1230         
1231         if (cogCorr) {
1232             Float_t yOnPad=(c->fY[cath]-y)/fSeg[cath]->Dpy(isec);
1233             c->fY[cath]=c->fY[cath]-cogCorr->Eval(yOnPad, 0, 0);
1234         }
1235     }
1236 }
1237
1238 void  AliMUONClusterFinderVS::FillCluster(AliMUONRawCluster* c, Int_t cath) 
1239 {
1240 //
1241 //  Completes cluster information starting from list of digits
1242 //
1243     static Float_t dr0;
1244
1245     AliMUONDigit* dig;
1246
1247     if (cath==0) {
1248         dr0 = 10000;
1249     }
1250     
1251     Float_t xpad, ypad, zpad;
1252     Float_t dx, dy, dr;
1253
1254     for (Int_t i=0; i<c->fMultiplicity[cath]; i++)
1255     {
1256         dig = fInput->Digit(cath,c->fIndexMap[i][cath]);
1257         fSeg[cath]->
1258         GetPadC(dig->PadX(),dig->PadY(),xpad,ypad, zpad);
1259         if (fDebugLevel)
1260             fprintf(stderr,"x %f y %f cx %f cy %f\n",xpad,ypad,c->fX[0],c->fY[0]);
1261         dx = xpad - c->fX[0];
1262         dy = ypad - c->fY[0];
1263         dr = TMath::Sqrt(dx*dx+dy*dy);
1264
1265         if (dr < dr0) {
1266             dr0 = dr;
1267             if (fDebugLevel)
1268                 fprintf(stderr," dr %f\n",dr);
1269             Int_t q=dig->Signal();
1270             if (dig->Physics() >= dig->Signal()) {
1271                 c->fPhysicsMap[i]=2;
1272             } else if (dig->Physics() == 0) {
1273                 c->fPhysicsMap[i]=0;
1274             } else  c->fPhysicsMap[i]=1;
1275             c->fPeakSignal[cath]=q;
1276             c->fTracks[0]=dig->Hit();
1277             c->fTracks[1]=dig->Track(0);
1278             c->fTracks[2]=dig->Track(1);
1279             if (fDebugLevel)
1280                 fprintf(stderr," c->fTracks[0] %d c->fTracks[1] %d\n",dig->Hit(),
1281                     dig->Track(0));
1282         }
1283 //
1284     } // loop over digits
1285
1286 //  apply correction to the coordinate along the anode wire
1287 // Force on anod
1288     c->fX[cath]=fSeg[cath]->GetAnod(c->fX[cath]);
1289 }
1290
1291 void  AliMUONClusterFinderVS::FindCluster(Int_t i, Int_t j, Int_t cath, AliMUONRawCluster &c){
1292
1293
1294 //
1295 //  Find a super cluster on both cathodes
1296 //
1297 //
1298 //  Add i,j as element of the cluster
1299 //
1300     
1301     Int_t idx = fHitMap[cath]->GetHitIndex(i,j);
1302     AliMUONDigit* dig = (AliMUONDigit*) fHitMap[cath]->GetHit(i,j);
1303     Int_t q=dig->Signal();
1304     Int_t theX=dig->PadX();
1305     Int_t theY=dig->PadY(); 
1306    
1307     if (q > TMath::Abs(c.fPeakSignal[0]) && q > TMath::Abs(c.fPeakSignal[1])) {
1308         c.fPeakSignal[cath]=q;
1309         c.fTracks[0]=dig->Hit();
1310         c.fTracks[1]=dig->Track(0);
1311         c.fTracks[2]=dig->Track(1);
1312     }
1313
1314 //
1315 //  Make sure that list of digits is ordered 
1316 // 
1317     Int_t mu=c.fMultiplicity[cath];
1318     c.fIndexMap[mu][cath]=idx;
1319     
1320     if (dig->Physics() >= dig->Signal()) {
1321         c.fPhysicsMap[mu]=2;
1322     } else if (dig->Physics() == 0) {
1323         c.fPhysicsMap[mu]=0;
1324     } else  c.fPhysicsMap[mu]=1;
1325
1326     
1327     if (mu > 0) {
1328         for (Int_t ind = mu-1; ind >= 0; ind--) {
1329             Int_t ist=(c.fIndexMap)[ind][cath];
1330             Int_t ql=fInput->Digit(cath, ist)->Signal();
1331             Int_t ix=fInput->Digit(cath, ist)->PadX();
1332             Int_t iy=fInput->Digit(cath, ist)->PadY();
1333             
1334             if (q>ql || (q==ql && theX > ix && theY < iy)) {
1335                 c.fIndexMap[ind][cath]=idx;
1336                 c.fIndexMap[ind+1][cath]=ist;
1337             } else {
1338                 
1339                 break;
1340             }
1341         }
1342     }
1343
1344     c.fMultiplicity[cath]++;
1345     if (c.fMultiplicity[cath] >= 50 ) {
1346         printf("FindCluster - multiplicity >50  %d \n",c.fMultiplicity[0]);
1347         c.fMultiplicity[cath]=49;
1348     }
1349
1350 // Prepare center of gravity calculation
1351     Float_t x, y, z;
1352     fSeg[cath]->GetPadC(i, j, x, y, z);
1353     
1354     c.fX[cath] += q*x;
1355     c.fY[cath] += q*y;
1356     c.fQ[cath] += q;
1357 //
1358 // Flag hit as "taken"  
1359     fHitMap[cath]->FlagHit(i,j);
1360 //
1361 //  Now look recursively for all neighbours and pad hit on opposite cathode
1362 //
1363 //  Loop over neighbours
1364     Int_t ix,iy;
1365     ix=iy=0;
1366     Int_t nn;
1367     Int_t xList[10], yList[10];
1368     fSeg[cath]->Neighbours(i,j,&nn,xList,yList);
1369     for (Int_t in=0; in<nn; in++) {
1370         ix=xList[in];
1371         iy=yList[in];
1372         
1373         if (fHitMap[cath]->TestHit(ix,iy)==kUnused) {
1374             if (fDebugLevel>1)
1375                 printf("\n Neighbours %d %d %d", cath, ix, iy);
1376             FindCluster(ix, iy, cath, c);
1377         }
1378         
1379    }
1380     Int_t nOpp=0;
1381     Int_t iXopp[50], iYopp[50];
1382     
1383 //  Neighbours on opposite cathode 
1384 //  Take into account that several pads can overlap with the present pad
1385     Int_t isec=fSeg[cath]->Sector(i,j);    
1386     Int_t iop;
1387     Float_t dx, dy;
1388
1389     if (cath==0) {
1390         iop = 1;
1391         dx  = (fSeg[cath]->Dpx(isec))/2.;
1392         dy  = 0.;
1393     } else {
1394         iop = 0;
1395         dx  = 0.;
1396         dy  = (fSeg[cath]->Dpy(isec))/2;
1397     }
1398 // loop over pad neighbours on opposite cathode
1399     for (fSeg[iop]->FirstPad(x, y, fZPlane, dx, dy);
1400          fSeg[iop]->MorePads();
1401          fSeg[iop]->NextPad())
1402     {
1403         
1404         ix = fSeg[iop]->Ix(); iy = fSeg[iop]->Iy();
1405         if (fDebugLevel > 1)
1406             printf("\n ix, iy: %f %f %f %d %d %d", x,y,z,ix, iy, fSector);
1407         if (fHitMap[iop]->TestHit(ix,iy)==kUnused){
1408             iXopp[nOpp]=ix;
1409             iYopp[nOpp++]=iy;
1410             if (fDebugLevel > 1)
1411                 printf("\n Opposite %d %d %d", iop, ix, iy);
1412         }
1413         
1414     } // Loop over pad neighbours
1415 //  This had to go outside the loop since recursive calls inside the iterator are not possible
1416 //
1417     Int_t jopp;
1418     for (jopp=0; jopp<nOpp; jopp++) {
1419         if (fHitMap[iop]->TestHit(iXopp[jopp],iYopp[jopp]) == kUnused) 
1420             FindCluster(iXopp[jopp], iYopp[jopp], iop, c);
1421     }
1422 }
1423
1424 //_____________________________________________________________________________
1425
1426 void AliMUONClusterFinderVS::FindRawClusters()
1427 {
1428   //
1429   // MUON cluster finder from digits -- finds neighbours on both cathodes and 
1430   // fills the tree with raw clusters
1431   //
1432
1433 //  Return if no input datad available
1434     if (!fInput->NDigits(0) && !fInput->NDigits(1)) return;
1435
1436     fSeg[0] = fInput->Segmentation(0);
1437     fSeg[1] = fInput->Segmentation(1);
1438
1439     fHitMap[0]  = new AliMUONHitMapA1(fSeg[0], fInput->Digits(0));
1440     fHitMap[1]  = new AliMUONHitMapA1(fSeg[1], fInput->Digits(1));
1441
1442  
1443     AliMUONDigit *dig;
1444
1445     Int_t ndig, cath;
1446     Int_t nskip=0;
1447     Int_t ncls=0;
1448     fHitMap[0]->FillHits();
1449     fHitMap[1]->FillHits();
1450 //
1451 //  Outer Loop over Cathodes
1452     for (cath=0; cath<2; cath++) {
1453         for (ndig=0; ndig<fInput->NDigits(cath); ndig++) {
1454             dig = fInput->Digit(cath, ndig);
1455             Int_t i=dig->PadX();
1456             Int_t j=dig->PadY();
1457             if (fHitMap[cath]->TestHit(i,j)==kUsed ||fHitMap[0]->TestHit(i,j)==kEmpty) {
1458                 nskip++;
1459                 continue;
1460             }
1461             if (fDebugLevel)
1462                 fprintf(stderr,"\n CATHODE %d CLUSTER %d\n",cath,ncls);
1463             AliMUONRawCluster c;
1464             c.fMultiplicity[0]=0;
1465             c.fMultiplicity[1]=0;
1466             c.fPeakSignal[cath]=dig->Signal();
1467             c.fTracks[0]=dig->Hit();
1468             c.fTracks[1]=dig->Track(0);
1469             c.fTracks[2]=dig->Track(1);
1470             // tag the beginning of cluster list in a raw cluster
1471             c.fNcluster[0]=-1;
1472             Float_t xcu, ycu;
1473             fSeg[cath]->GetPadC(i,j,xcu, ycu, fZPlane);
1474             fSector= fSeg[cath]->Sector(i,j)/100;
1475             if (fDebugLevel)
1476                 printf("\n New Seed %d %d ", i,j);
1477             
1478             FindCluster(i,j,cath,c);
1479 //          ^^^^^^^^^^^^^^^^^^^^^^^^
1480             // center of gravity
1481             c.fX[0] /= c.fQ[0];
1482 // Force on anod
1483             c.fX[0]=fSeg[0]->GetAnod(c.fX[0]);
1484             c.fY[0] /= c.fQ[0];
1485             c.fX[1] /= c.fQ[1];
1486 // Force on anod
1487             c.fX[1]=fSeg[0]->GetAnod(c.fX[1]);
1488             c.fY[1] /= c.fQ[1];
1489             
1490             c.fZ[0] = fZPlane;
1491             c.fZ[1] = fZPlane;      
1492
1493             if (fDebugLevel) {
1494                 fprintf(stderr,"\n Cathode 1 multiplicite %d X(CG) %f Y(CG) %f\n",
1495                         c.fMultiplicity[0],c.fX[0],c.fY[0]);
1496                 fprintf(stderr," Cathode 2 multiplicite %d X(CG) %f Y(CG) %f\n",
1497                         c.fMultiplicity[1],c.fX[1],c.fY[1]);
1498             }
1499 //      Analyse cluster and decluster if necessary
1500 //      
1501         ncls++;
1502         c.fNcluster[1]=fNRawClusters;
1503         c.fClusterType=c.PhysicsContribution();
1504
1505         fNPeaks=0;
1506 //
1507 //
1508         Decluster(&c);
1509 //
1510 //      reset Cluster object
1511         { // begin local scope
1512             for (int k=0;k<c.fMultiplicity[0];k++) c.fIndexMap[k][0]=0;
1513         } // end local scope
1514
1515         { // begin local scope
1516             for (int k=0;k<c.fMultiplicity[1];k++) c.fIndexMap[k][1]=0;
1517         } // end local scope
1518         
1519         c.fMultiplicity[0]=c.fMultiplicity[0]=0;
1520
1521         
1522         } // end loop ndig
1523     } // end loop cathodes
1524     delete fHitMap[0];
1525     delete fHitMap[1];
1526 }
1527
1528 Float_t AliMUONClusterFinderVS::SingleMathiesonFit(AliMUONRawCluster *c, Int_t cath)
1529 {
1530 // Performs a single Mathieson fit on one cathode
1531 // 
1532     AliMUONClusterInput& clusterInput = *(AliMUONClusterInput::Instance());
1533     
1534     clusterInput.Fitter()->SetFCN(fcnS1);
1535     clusterInput.Fitter()->mninit(2,10,7);
1536     Double_t arglist[20];
1537     Int_t ierflag=0;
1538     arglist[0]=1;
1539 // Set starting values 
1540     static Double_t vstart[2];
1541     vstart[0]=c->fX[1];
1542     vstart[1]=c->fY[0];
1543     
1544     
1545 // lower and upper limits
1546     static Double_t lower[2], upper[2];
1547     Int_t ix,iy;
1548     fSeg[cath]->GetPadI(c->fX[cath], c->fY[cath], fZPlane, ix, iy);
1549     Int_t isec=fSeg[cath]->Sector(ix, iy);
1550     lower[0]=vstart[0]-fSeg[cath]->Dpx(isec)/2;
1551     lower[1]=vstart[1]-fSeg[cath]->Dpy(isec)/2;
1552     
1553     upper[0]=lower[0]+fSeg[cath]->Dpx(isec);
1554     upper[1]=lower[1]+fSeg[cath]->Dpy(isec);
1555     
1556 // step sizes
1557     static Double_t step[2]={0.0005, 0.0005};
1558     
1559     clusterInput.Fitter()->mnparm(0,"x1",vstart[0],step[0],lower[0],upper[0],ierflag);
1560     clusterInput.Fitter()->mnparm(1,"y1",vstart[1],step[1],lower[1],upper[1],ierflag);
1561 // ready for minimisation       
1562     clusterInput.Fitter()->SetPrintLevel(-1+fDebugLevel);
1563     if (fDebugLevel==0)
1564         clusterInput.Fitter()->mnexcm("SET NOW", arglist, 0, ierflag);
1565     clusterInput.Fitter()->mnexcm("SET OUT", arglist, 0, ierflag);
1566     arglist[0]= -1;
1567     arglist[1]= 0;
1568     
1569     clusterInput.Fitter()->mnexcm("SET NOGR", arglist, 0, ierflag);
1570     clusterInput.Fitter()->mnexcm("MIGRAD", arglist, 0, ierflag);
1571     clusterInput.Fitter()->mnexcm("EXIT" , arglist, 0, ierflag);
1572     Double_t fmin, fedm, errdef;
1573     Int_t   npari, nparx, istat;
1574       
1575     clusterInput.Fitter()->mnstat(fmin, fedm, errdef, npari, nparx, istat);  
1576     fFitStat=istat;
1577     
1578 // Print results
1579 // Get fitted parameters
1580     Double_t xrec, yrec;
1581     TString chname;
1582     Double_t epxz, b1, b2;
1583     Int_t ierflg;
1584     clusterInput.Fitter()->mnpout(0, chname, xrec, epxz, b1, b2, ierflg);       
1585     clusterInput.Fitter()->mnpout(1, chname, yrec, epxz, b1, b2, ierflg);       
1586     fXFit[cath]=xrec;
1587     fYFit[cath]=yrec;
1588     return fmin;
1589 }
1590
1591 Float_t AliMUONClusterFinderVS::CombiSingleMathiesonFit(AliMUONRawCluster * /*c*/)
1592 {
1593 // Perform combined Mathieson fit on both cathode planes
1594 //
1595     AliMUONClusterInput& clusterInput = *(AliMUONClusterInput::Instance());
1596     clusterInput.Fitter()->SetFCN(fcnCombiS1);
1597     clusterInput.Fitter()->mninit(2,10,7);
1598     Double_t arglist[20];
1599     Int_t ierflag=0;
1600     arglist[0]=1;
1601     static Double_t vstart[2];
1602     vstart[0]=fXInit[0];
1603     vstart[1]=fYInit[0];
1604     
1605     
1606 // lower and upper limits
1607     static Float_t lower[2], upper[2];
1608     Int_t ix,iy,isec;
1609     fSeg[0]->GetPadI(fXInit[0], fYInit[0], fZPlane, ix, iy);
1610     isec=fSeg[0]->Sector(ix, iy);
1611     Float_t dpy=fSeg[0]->Dpy(isec);
1612     fSeg[1]->GetPadI(fXInit[0], fYInit[0], fZPlane, ix, iy);
1613     isec=fSeg[1]->Sector(ix, iy);
1614     Float_t dpx=fSeg[1]->Dpx(isec);
1615
1616     Int_t icount;
1617     Float_t xdum, ydum, zdum;
1618
1619 //  Find save upper and lower limits    
1620     
1621     icount = 0;
1622     
1623     for (fSeg[1]->FirstPad(fXInit[0], fYInit[0], fZPlane, dpx, 0.); 
1624          fSeg[1]->MorePads(); fSeg[1]->NextPad())
1625     {
1626         ix=fSeg[1]->Ix(); iy=fSeg[1]->Iy();
1627         fSeg[1]->GetPadC(ix,iy, upper[0], ydum, zdum);  
1628         if (icount ==0) lower[0]=upper[0];
1629         icount++;
1630     }
1631
1632     if (lower[0]>upper[0]) {xdum=lower[0]; lower[0]=upper[0]; upper[0]=xdum;}
1633         
1634     icount=0;
1635     if (fDebugLevel)
1636         printf("\n single y %f %f", fXInit[0], fYInit[0]);
1637     
1638     for (fSeg[0]->FirstPad(fXInit[0], fYInit[0], fZPlane, 0., dpy); 
1639          fSeg[0]->MorePads(); fSeg[0]->NextPad())
1640     {
1641         ix=fSeg[0]->Ix(); iy=fSeg[0]->Iy();
1642         fSeg[0]->GetPadC(ix,iy,xdum,upper[1],zdum);     
1643         if (icount ==0) lower[1]=upper[1];
1644         icount++;
1645         if (fDebugLevel)
1646             printf("\n upper lower %d %f %f", icount, upper[1], lower[1]);
1647     }
1648     
1649     if (lower[1]>upper[1]) {xdum=lower[1]; lower[1]=upper[1]; upper[1]=xdum;}
1650
1651 // step sizes
1652     static Double_t step[2]={0.00001, 0.0001};
1653     
1654     clusterInput.Fitter()->mnparm(0,"x1",vstart[0],step[0],lower[0],upper[0],ierflag);
1655     clusterInput.Fitter()->mnparm(1,"y1",vstart[1],step[1],lower[1],upper[1],ierflag);
1656 // ready for minimisation       
1657     clusterInput.Fitter()->SetPrintLevel(-1+fDebugLevel);
1658     if (fDebugLevel==0)
1659         clusterInput.Fitter()->mnexcm("SET NOW", arglist, 0, ierflag);
1660     clusterInput.Fitter()->mnexcm("SET OUT", arglist, 0, ierflag);
1661     arglist[0]= -1;
1662     arglist[1]= 0;
1663     
1664     clusterInput.Fitter()->mnexcm("SET NOGR", arglist, 0, ierflag);
1665     clusterInput.Fitter()->mnexcm("MIGRAD", arglist, 0, ierflag);
1666     clusterInput.Fitter()->mnexcm("EXIT" , arglist, 0, ierflag);
1667     Double_t fmin, fedm, errdef;
1668     Int_t   npari, nparx, istat;
1669       
1670     clusterInput.Fitter()->mnstat(fmin, fedm, errdef, npari, nparx, istat);  
1671     fFitStat=istat;
1672     
1673 // Print results
1674 // Get fitted parameters
1675     Double_t xrec, yrec;
1676     TString chname;
1677     Double_t epxz, b1, b2;
1678     Int_t ierflg;
1679     clusterInput.Fitter()->mnpout(0, chname, xrec, epxz, b1, b2, ierflg);       
1680     clusterInput.Fitter()->mnpout(1, chname, yrec, epxz, b1, b2, ierflg);       
1681     fXFit[0]=xrec;
1682     fYFit[0]=yrec;
1683     return fmin;
1684 }
1685
1686 Bool_t AliMUONClusterFinderVS::DoubleMathiesonFit(AliMUONRawCluster * /*c*/, Int_t cath)
1687 {
1688 // Performs a double Mathieson fit on one cathode
1689 // 
1690
1691 //
1692 //  Initialise global variables for fit
1693     AliMUONClusterInput& clusterInput = *(AliMUONClusterInput::Instance());
1694     clusterInput.Fitter()->SetFCN(fcnS2);
1695     clusterInput.Fitter()->mninit(5,10,7);
1696     Double_t arglist[20];
1697     Int_t ierflag=0;
1698     arglist[0]=1;
1699 // Set starting values 
1700     static Double_t vstart[5];
1701     vstart[0]=fX[fIndLocal[0][cath]][cath];
1702     vstart[1]=fY[fIndLocal[0][cath]][cath];     
1703     vstart[2]=fX[fIndLocal[1][cath]][cath];
1704     vstart[3]=fY[fIndLocal[1][cath]][cath];     
1705     vstart[4]=Float_t(fQ[fIndLocal[0][cath]][cath])/
1706         Float_t(fQ[fIndLocal[0][cath]][cath]+fQ[fIndLocal[1][cath]][cath]);
1707 // lower and upper limits
1708     static Float_t lower[5], upper[5];
1709     Int_t isec=fSeg[cath]->Sector(fIx[fIndLocal[0][cath]][cath], fIy[fIndLocal[0][cath]][cath]);
1710     lower[0]=vstart[0]-fSeg[cath]->Dpx(isec);
1711     lower[1]=vstart[1]-fSeg[cath]->Dpy(isec);
1712     
1713     upper[0]=lower[0]+2.*fSeg[cath]->Dpx(isec);
1714     upper[1]=lower[1]+2.*fSeg[cath]->Dpy(isec);
1715     
1716     isec=fSeg[cath]->Sector(fIx[fIndLocal[1][cath]][cath], fIy[fIndLocal[1][cath]][cath]);
1717     lower[2]=vstart[2]-fSeg[cath]->Dpx(isec)/2;
1718     lower[3]=vstart[3]-fSeg[cath]->Dpy(isec)/2;
1719     
1720     upper[2]=lower[2]+fSeg[cath]->Dpx(isec);
1721     upper[3]=lower[3]+fSeg[cath]->Dpy(isec);
1722     
1723     lower[4]=0.;
1724     upper[4]=1.;
1725 // step sizes
1726     static Double_t step[5]={0.0005, 0.0005, 0.0005, 0.0005, 0.0001};
1727     
1728     clusterInput.Fitter()->mnparm(0,"x1",vstart[0],step[0],lower[0],upper[0],ierflag);
1729     clusterInput.Fitter()->mnparm(1,"y1",vstart[1],step[1],lower[1],upper[1],ierflag);
1730     clusterInput.Fitter()->mnparm(2,"x2",vstart[2],step[2],lower[2],upper[2],ierflag);
1731     clusterInput.Fitter()->mnparm(3,"y2",vstart[3],step[3],lower[3],upper[3],ierflag);
1732     clusterInput.Fitter()->mnparm(4,"a0",vstart[4],step[4],lower[4],upper[4],ierflag);
1733 // ready for minimisation       
1734     clusterInput.Fitter()->SetPrintLevel(-1+fDebugLevel);
1735     if (fDebugLevel==0)
1736         clusterInput.Fitter()->mnexcm("SET NOW", arglist, 0, ierflag);
1737     clusterInput.Fitter()->mnexcm("SET OUT", arglist, 0, ierflag);
1738     arglist[0]= -1;
1739     arglist[1]= 0;
1740     
1741     clusterInput.Fitter()->mnexcm("SET NOGR", arglist, 0, ierflag);
1742     clusterInput.Fitter()->mnexcm("MIGRAD", arglist, 0, ierflag);
1743     clusterInput.Fitter()->mnexcm("EXIT" , arglist, 0, ierflag);
1744 // Get fitted parameters
1745     Double_t xrec[2], yrec[2], qfrac;
1746     TString chname;
1747     Double_t epxz, b1, b2;
1748     Int_t ierflg;
1749     clusterInput.Fitter()->mnpout(0, chname, xrec[0], epxz, b1, b2, ierflg);    
1750     clusterInput.Fitter()->mnpout(1, chname, yrec[0], epxz, b1, b2, ierflg);    
1751     clusterInput.Fitter()->mnpout(2, chname, xrec[1], epxz, b1, b2, ierflg);    
1752     clusterInput.Fitter()->mnpout(3, chname, yrec[1], epxz, b1, b2, ierflg);    
1753     clusterInput.Fitter()->mnpout(4, chname, qfrac,   epxz, b1, b2, ierflg);    
1754
1755     Double_t fmin, fedm, errdef;
1756     Int_t   npari, nparx, istat;
1757       
1758     clusterInput.Fitter()->mnstat(fmin, fedm, errdef, npari, nparx, istat);  
1759     fFitStat=istat;
1760     return kTRUE;
1761 }
1762
1763 Float_t AliMUONClusterFinderVS::CombiDoubleMathiesonFit(AliMUONRawCluster * /*c*/)
1764 {
1765 //
1766 // Perform combined double Mathieson fit on both cathode planes
1767 //
1768     AliMUONClusterInput& clusterInput = *(AliMUONClusterInput::Instance());
1769     clusterInput.Fitter()->SetFCN(fcnCombiS2);
1770     clusterInput.Fitter()->mninit(6,10,7);
1771     Double_t arglist[20];
1772     Int_t ierflag=0;
1773     arglist[0]=1;
1774 // Set starting values 
1775     static Double_t vstart[6];
1776     vstart[0]=fXInit[0];
1777     vstart[1]=fYInit[0];
1778     vstart[2]=fXInit[1];
1779     vstart[3]=fYInit[1];
1780     vstart[4]=fQrInit[0];
1781     vstart[5]=fQrInit[1];
1782 // lower and upper limits
1783     static Float_t lower[6], upper[6];
1784     Int_t ix,iy,isec;
1785     Float_t dpx, dpy;
1786     
1787     fSeg[1]->GetPadI(fXInit[0], fYInit[0], fZPlane, ix, iy);
1788     isec=fSeg[1]->Sector(ix, iy);
1789     dpx=fSeg[1]->Dpx(isec);
1790
1791     fSeg[0]->GetPadI(fXInit[0], fYInit[0], fZPlane, ix, iy);
1792     isec=fSeg[0]->Sector(ix, iy);
1793     dpy=fSeg[0]->Dpy(isec);
1794
1795
1796     Int_t icount;
1797     Float_t xdum, ydum, zdum;
1798     if (fDebugLevel)
1799         printf("\n Cluster Finder: %f %f %f %f  ", fXInit[0], fXInit[1],fYInit[0], fYInit[1] );
1800     
1801 //  Find save upper and lower limits    
1802     icount = 0;
1803     
1804     for (fSeg[1]->FirstPad(fXInit[0], fYInit[0], fZPlane, dpx, 0.); 
1805          fSeg[1]->MorePads(); fSeg[1]->NextPad())
1806     {
1807         ix=fSeg[1]->Ix(); iy=fSeg[1]->Iy();
1808 //      if (fHitMap[1]->TestHit(ix, iy) == kEmpty) continue;
1809         fSeg[1]->GetPadC(ix,iy,upper[0],ydum,zdum);     
1810         if (icount ==0) lower[0]=upper[0];
1811         icount++;
1812     }
1813     if (lower[0]>upper[0]) {xdum=lower[0]; lower[0]=upper[0]; upper[0]=xdum;}    
1814 //    vstart[0] = 0.5*(lower[0]+upper[0]);
1815
1816     
1817     icount=0;
1818     
1819     for (fSeg[0]->FirstPad(fXInit[0], fYInit[0], fZPlane, 0., dpy); 
1820          fSeg[0]->MorePads(); fSeg[0]->NextPad())
1821     {
1822         ix=fSeg[0]->Ix(); iy=fSeg[0]->Iy();
1823 //      if (fHitMap[0]->TestHit(ix, iy) == kEmpty) continue;
1824         fSeg[0]->GetPadC(ix,iy,xdum,upper[1],zdum);     
1825         if (icount ==0) lower[1]=upper[1];
1826         icount++;
1827     }
1828     
1829     if (lower[1]>upper[1]) {xdum=lower[1]; lower[1]=upper[1]; upper[1]=xdum;}    
1830 //     vstart[1] = 0.5*(lower[1]+upper[1]);
1831
1832
1833     fSeg[1]->GetPadI(fXInit[1], fYInit[1], fZPlane, ix, iy);
1834     isec=fSeg[1]->Sector(ix, iy);
1835     dpx=fSeg[1]->Dpx(isec);
1836     fSeg[0]->GetPadI(fXInit[1], fYInit[1], fZPlane, ix, iy);
1837     isec=fSeg[0]->Sector(ix, iy);
1838     dpy=fSeg[0]->Dpy(isec);
1839
1840
1841 //  Find save upper and lower limits    
1842
1843     icount=0;
1844     
1845     for (fSeg[1]->FirstPad(fXInit[1], fYInit[1], fZPlane, dpx, 0); 
1846          fSeg[1]->MorePads(); fSeg[1]->NextPad())
1847     {
1848         ix=fSeg[1]->Ix(); iy=fSeg[1]->Iy();
1849 //      if (fHitMap[1]->TestHit(ix, iy) == kEmpty) continue;
1850         fSeg[1]->GetPadC(ix,iy,upper[2],ydum,zdum);     
1851         if (icount ==0) lower[2]=upper[2];
1852         icount++;
1853     }
1854     if (lower[2]>upper[2]) {xdum=lower[2]; lower[2]=upper[2]; upper[2]=xdum;}    
1855     //    vstart[2] = 0.5*(lower[2]+upper[2]);
1856
1857     icount=0;
1858     
1859     for (fSeg[0]->FirstPad(fXInit[1], fYInit[1], fZPlane, 0, dpy); 
1860          fSeg[0]-> MorePads(); fSeg[0]->NextPad())
1861     {
1862         ix=fSeg[0]->Ix(); iy=fSeg[0]->Iy();
1863 //      if (fHitMap[0]->TestHit(ix, iy) != kEmpty) continue;
1864         
1865         fSeg[0]->GetPadC(ix,iy,xdum,upper[3],zdum);     
1866         if (icount ==0) lower[3]=upper[3];
1867         icount++;
1868
1869     }
1870     if (lower[3]>upper[3]) {xdum=lower[3]; lower[3]=upper[3]; upper[3]=xdum;}    
1871     
1872 //     vstart[3] = 0.5*(lower[3]+upper[3]);
1873     
1874     lower[4]=0.;
1875     upper[4]=1.;
1876     lower[5]=0.;
1877     upper[5]=1.;
1878
1879 // step sizes
1880     static Double_t step[6]={0.0005, 0.0005, 0.0005, 0.0005, 0.001, 0.001};
1881     clusterInput.Fitter()->mnparm(0,"x1",vstart[0],step[0],lower[0],upper[0],ierflag);
1882     clusterInput.Fitter()->mnparm(1,"y1",vstart[1],step[1],lower[1],upper[1],ierflag);
1883     clusterInput.Fitter()->mnparm(2,"x2",vstart[2],step[2],lower[2],upper[2],ierflag);
1884     clusterInput.Fitter()->mnparm(3,"y2",vstart[3],step[3],lower[3],upper[3],ierflag);
1885     clusterInput.Fitter()->mnparm(4,"a0",vstart[4],step[4],lower[4],upper[4],ierflag);
1886     clusterInput.Fitter()->mnparm(5,"a1",vstart[5],step[5],lower[5],upper[5],ierflag);
1887 // ready for minimisation       
1888     clusterInput.Fitter()->SetPrintLevel(-1+fDebugLevel);
1889     if (fDebugLevel)
1890         clusterInput.Fitter()->mnexcm("SET NOW", arglist, 0, ierflag);
1891     clusterInput.Fitter()->mnexcm("SET OUT", arglist, 0, ierflag);
1892     arglist[0]= -1;
1893     arglist[1]= 0;
1894     
1895     clusterInput.Fitter()->mnexcm("SET NOGR", arglist, 0, ierflag);
1896     clusterInput.Fitter()->mnexcm("MIGRAD", arglist, 0, ierflag);
1897     clusterInput.Fitter()->mnexcm("EXIT" , arglist, 0, ierflag);
1898 // Get fitted parameters
1899     TString chname;
1900     Double_t epxz, b1, b2;
1901     Int_t ierflg;
1902     clusterInput.Fitter()->mnpout(0, chname, fXFit[0],  epxz, b1, b2, ierflg);  
1903     clusterInput.Fitter()->mnpout(1, chname, fYFit[0],  epxz, b1, b2, ierflg);  
1904     clusterInput.Fitter()->mnpout(2, chname, fXFit[1],  epxz, b1, b2, ierflg);  
1905     clusterInput.Fitter()->mnpout(3, chname, fYFit[1],  epxz, b1, b2, ierflg);  
1906     clusterInput.Fitter()->mnpout(4, chname, fQrFit[0], epxz, b1, b2, ierflg);  
1907     clusterInput.Fitter()->mnpout(5, chname, fQrFit[1], epxz, b1, b2, ierflg);  
1908
1909     Double_t fmin, fedm, errdef;
1910     Int_t   npari, nparx, istat;
1911       
1912     clusterInput.Fitter()->mnstat(fmin, fedm, errdef, npari, nparx, istat);  
1913     fFitStat=istat;
1914     
1915     fChi2[0]=fmin;
1916     fChi2[1]=fmin;
1917     return fmin;
1918 }
1919
1920 void AliMUONClusterFinderVS::Split(AliMUONRawCluster* c)
1921 {
1922 //
1923 // One cluster for each maximum
1924 //
1925     Int_t i, j, cath;
1926     AliMUONClusterInput& clusterInput = *(AliMUONClusterInput::Instance());
1927     for (j=0; j<2; j++) {
1928         AliMUONRawCluster cnew;
1929         cnew.fGhost=c->fGhost;
1930         for (cath=0; cath<2; cath++) {
1931             cnew.fChi2[cath]=fChi2[0];
1932             // ?? why not cnew.fChi2[cath]=fChi2[cath];
1933             
1934             if (fNPeaks == 0) {
1935                 cnew.fNcluster[0]=-1;
1936                 cnew.fNcluster[1]=fNRawClusters;
1937             } else {
1938                 cnew.fNcluster[0]=fNPeaks;
1939                 cnew.fNcluster[1]=0;
1940             }
1941             cnew.fMultiplicity[cath]=0;
1942             cnew.fX[cath]=Float_t(fXFit[j]);
1943             cnew.fY[cath]=Float_t(fYFit[j]);
1944             cnew.fZ[cath]=fZPlane;
1945             if (j==0) {
1946                 cnew.fQ[cath]=Int_t(clusterInput.TotalCharge(cath)*fQrFit[cath]);
1947             } else {
1948                 cnew.fQ[cath]=Int_t(clusterInput.TotalCharge(cath)*(1-fQrFit[cath]));
1949             }
1950             fSeg[cath]->SetHit(fXFit[j],fYFit[j],fZPlane);
1951             for (i=0; i<fMul[cath]; i++) {
1952                 cnew.fIndexMap[cnew.fMultiplicity[cath]][cath]=
1953                     c->fIndexMap[i][cath];
1954                 fSeg[cath]->SetPad(fIx[i][cath], fIy[i][cath]);
1955                 Float_t q1=fInput->Response()->IntXY(fSeg[cath]);
1956                 cnew.fContMap[i][cath]
1957                     =(q1*Float_t(cnew.fQ[cath]))/Float_t(fQ[i][cath]);
1958                 cnew.fMultiplicity[cath]++;
1959             }
1960             FillCluster(&cnew,0,cath);
1961         } // cathode loop
1962         
1963         cnew.fClusterType=cnew.PhysicsContribution();
1964         if (cnew.fQ[0]>0 && cnew.fQ[1]>0) AddRawCluster(cnew);
1965         fNPeaks++;
1966     }
1967 }
1968
1969
1970 //
1971 // Minimisation functions
1972 // Single Mathieson
1973 void fcnS1(Int_t & /*npar*/, Double_t * /*gin*/, Double_t &f, Double_t *par, Int_t /*iflag*/)
1974 {
1975     AliMUONClusterInput& clusterInput = *(AliMUONClusterInput::Instance());    
1976     Int_t i;
1977     Float_t delta;
1978     Float_t chisq=0;
1979     Float_t qcont=0;
1980     Float_t qtot=0;
1981
1982     for (i=0; i<clusterInput.Nmul(0); i++) {
1983         Float_t q0=clusterInput.Charge(i,0);
1984         Float_t q1=clusterInput.DiscrChargeS1(i,par);
1985         delta=(q0-q1)/q0;
1986         chisq+=delta*delta;
1987         qcont+=q1;
1988         qtot+=q0;
1989     }
1990     f=chisq;
1991 }
1992
1993 void fcnCombiS1(Int_t & /*npar*/, Double_t * /*gin*/, Double_t &f, Double_t *par, Int_t /*iflag*/)
1994 {
1995     AliMUONClusterInput& clusterInput = *(AliMUONClusterInput::Instance());    
1996     Int_t i, cath;
1997     Float_t delta;
1998     Float_t chisq=0;
1999     Float_t qcont=0;
2000     Float_t qtot=0;
2001
2002     for (cath=0; cath<2; cath++) {
2003         for (i=0; i<clusterInput.Nmul(cath); i++) {
2004             Float_t q0=clusterInput.Charge(i,cath);
2005             Float_t q1=clusterInput.DiscrChargeCombiS1(i,par,cath);
2006             delta=(q0-q1)/q0;
2007             chisq+=delta*delta;
2008             qcont+=q1;
2009             qtot+=q0;
2010         }
2011     }
2012     f=chisq;
2013 }
2014
2015 // Double Mathieson
2016 void fcnS2(Int_t & /*npar*/, Double_t * /*gin*/, Double_t &f, Double_t *par, Int_t /*iflag*/)
2017 {
2018     AliMUONClusterInput& clusterInput = *(AliMUONClusterInput::Instance());    
2019     Int_t i;
2020     Float_t delta;
2021     Float_t chisq=0;
2022     Float_t qcont=0;
2023     Float_t qtot=0;
2024     
2025     for (i=0; i<clusterInput.Nmul(0); i++) {
2026
2027         Float_t q0=clusterInput.Charge(i,0);
2028         Float_t q1=clusterInput.DiscrChargeS2(i,par);
2029         delta=(q0-q1)/q0;
2030         chisq+=delta*delta;
2031         qcont+=q1;
2032         qtot+=q0;
2033     }
2034     f=chisq;
2035 }
2036
2037 // Double Mathieson
2038 void fcnCombiS2(Int_t & /*npar*/, Double_t * /*gin*/, Double_t &f, Double_t *par, Int_t /*iflag*/)
2039 {
2040     AliMUONClusterInput& clusterInput = *(AliMUONClusterInput::Instance());    
2041     Int_t i, cath;
2042     Float_t delta;
2043     Float_t chisq=0;
2044     Float_t qcont=0;
2045     Float_t qtot=0;
2046     for (cath=0; cath<2; cath++) {
2047         for (i=0; i<clusterInput.Nmul(cath); i++) {
2048             Float_t q0=clusterInput.Charge(i,cath);
2049             Float_t q1=clusterInput.DiscrChargeCombiS2(i,par,cath);
2050             delta=(q0-q1)/q0;
2051             chisq+=delta*delta;
2052             qcont+=q1;
2053             qtot+=q0;
2054         }
2055     }
2056     f=chisq;
2057 }
2058
2059 void AliMUONClusterFinderVS::AddRawCluster(const AliMUONRawCluster c)
2060 {
2061   //
2062   // Add a raw cluster copy to the list
2063   //
2064     AliMUON *pMUON=(AliMUON*)gAlice->GetModule("MUON");
2065     pMUON->GetMUONData()->AddRawCluster(fInput->Chamber(),c); 
2066     fNRawClusters++;
2067 //    if (fDebugLevel)
2068         fprintf(stderr,"\nfNRawClusters %d\n",fNRawClusters);
2069 }
2070
2071 Bool_t AliMUONClusterFinderVS::TestTrack(Int_t t) {
2072 // Test if track was user selected
2073     if (fTrack[0]==-1 || fTrack[1]==-1) {
2074         return kTRUE;
2075     } else if (t==fTrack[0] || t==fTrack[1]) {
2076         return kTRUE;
2077     } else {
2078         return kFALSE;
2079     }
2080 }
2081
2082 AliMUONClusterFinderVS& AliMUONClusterFinderVS
2083 ::operator = (const AliMUONClusterFinderVS& /*rhs*/)
2084 {
2085 // Dummy assignment operator
2086     return *this;
2087 }
2088
2089
2090
2091
2092
2093
2094
2095
2096