1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
17 Revision 1.18 2001/01/26 21:37:53 morsch
18 Use access functions to AliMUONDigit member data.
20 Revision 1.17 2001/01/23 18:58:19 hristov
21 Initialisation of some pointers
23 Revision 1.16 2000/12/21 23:27:30 morsch
24 Error in argument list of AddRawCluster corrected.
26 Revision 1.15 2000/12/21 22:14:38 morsch
27 Clean-up of coding rule violations.
29 Revision 1.14 2000/10/23 16:03:45 morsch
30 Correct z-position of all clusters created "on the flight".
32 Revision 1.13 2000/10/23 13:38:23 morsch
33 Set correct z-coordinate when cluster is split.
35 Revision 1.12 2000/10/18 11:42:06 morsch
36 - AliMUONRawCluster contains z-position.
37 - Some clean-up of useless print statements during initialisations.
39 Revision 1.11 2000/10/06 09:04:05 morsch
40 - Dummy z-arguments in GetPadI, SetHit, FirstPad replaced by real z-coordinate
41 to make code work with slat chambers (AM)
42 - Replace GetPadI calls with unchecked x,y coordinates by pad iterator calls wherever possible.
44 Revision 1.10 2000/10/03 13:51:57 egangler
45 Removal of useless dependencies via forward declarations
47 Revision 1.9 2000/10/02 16:58:29 egangler
48 Cleaning of the code :
51 -> some useless includes removed or replaced by "class" statement
53 Revision 1.8 2000/07/03 11:54:57 morsch
54 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
55 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
57 Revision 1.7 2000/06/28 15:16:35 morsch
58 (1) Client code adapted to new method signatures in AliMUONSegmentation (see comments there)
59 to allow development of slat-muon chamber simulation and reconstruction code in the MUON
60 framework. The changes should have no side effects (mostly dummy arguments).
61 (2) Hit disintegration uses 3-dim hit coordinates to allow simulation
62 of chambers with overlapping modules (MakePadHits, Disintegration).
64 Revision 1.6 2000/06/28 12:19:18 morsch
65 More consequent seperation of global input data services (AliMUONClusterInput singleton) and the
66 cluster and hit reconstruction algorithms in AliMUONClusterFinderVS.
67 AliMUONClusterFinderVS becomes the base class for clustering and hit reconstruction.
68 It requires two cathode planes. Small modifications in the code will make it usable for
69 one cathode plane and, hence, more general (for test beam data).
70 AliMUONClusterFinder is now obsolete.
72 Revision 1.5 2000/06/28 08:06:10 morsch
73 Avoid global variables in AliMUONClusterFinderVS by seperating the input data for the fit from the
74 algorithmic part of the class. Input data resides inside the AliMUONClusterInput singleton.
75 It also naturally takes care of the TMinuit instance.
77 Revision 1.4 2000/06/27 16:18:47 gosset
78 Finally correct implementation of xm, ym, ixm, iym sizes
79 when at least three local maxima on cathode 1 or on cathode 2
81 Revision 1.3 2000/06/22 14:02:45 morsch
82 Parameterised size of xm[], ym[], ixm[], iym[] correctly implemented (PH)
83 Some HP scope problems corrected (PH)
85 Revision 1.2 2000/06/15 07:58:48 morsch
86 Code from MUON-dev joined
88 Revision 1.1.2.3 2000/06/09 21:58:33 morsch
89 Most coding rule violations corrected.
91 Revision 1.1.2.2 2000/02/15 08:33:52 morsch
92 Error in calculation of contribution map for double clusters (Split method) corrected (A.M.)
93 Error in determination of track list for double cluster (FillCluster method) corrected (A.M.)
94 Revised and extended SplitByLocalMaxima method (Isabelle Chevrot):
95 - For clusters with more than 2 maxima on one of the cathode planes all valid
96 combinations of maxima on the two cathodes are preserved. The position of the maxima is
97 taken as the hit position.
98 - New FillCluster method with 2 arguments to find tracks associated to the clusters
99 defined above added. (Method destinction by argument list not very elegant in this case,
100 should be revides (A.M.)
101 - Bug in if-statement to handle maximum 1 maximum per plane corrected
102 - Two cluster per cathode but only 1 combination valid is handled.
103 - More rigerous treatment of 1-2 and 2-1 combinations of maxima.
107 #include "AliMUONClusterFinderVS.h"
108 #include "AliMUONDigit.h"
109 #include "AliMUONRawCluster.h"
110 #include "AliSegmentation.h"
111 #include "AliMUONResponse.h"
112 #include "AliMUONClusterInput.h"
113 #include "AliMUONHitMapA1.h"
122 #include <TPostScript.h>
127 #include <iostream.h>
129 //_____________________________________________________________________
130 // This function is minimized in the double-Mathieson fit
131 void fcnS2(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag);
132 void fcnS1(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag);
133 void fcnCombiS1(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag);
134 void fcnCombiS2(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag);
136 ClassImp(AliMUONClusterFinderVS)
138 AliMUONClusterFinderVS::AliMUONClusterFinderVS()
140 // Default constructor
141 fInput=AliMUONClusterInput::Instance();
144 fTrack[0]=fTrack[1]=-1;
145 fDebugLevel = 0; // make silent default
146 fGhostChi2Cut = 1e6; // nothing done by default
149 for(Int_t i=0; i<100; i++) {
150 for (Int_t j=0; j<2; j++) {
156 AliMUONClusterFinderVS::AliMUONClusterFinderVS(
157 const AliMUONClusterFinderVS & clusterFinder)
159 // Dummy copy Constructor
163 void AliMUONClusterFinderVS::Decluster(AliMUONRawCluster *cluster)
165 // Decluster by local maxima
166 SplitByLocalMaxima(cluster);
169 void AliMUONClusterFinderVS::SplitByLocalMaxima(AliMUONRawCluster *c)
171 // Split complex cluster by local maxima
174 fInput->SetCluster(c);
176 fMul[0]=c->fMultiplicity[0];
177 fMul[1]=c->fMultiplicity[1];
180 // dump digit information into arrays
185 for (cath=0; cath<2; cath++) {
187 for (i=0; i<fMul[cath]; i++)
190 fDig[i][cath]=fInput->Digit(cath, c->fIndexMap[i][cath]);
192 fIx[i][cath]= fDig[i][cath]->PadX();
193 fIy[i][cath]= fDig[i][cath]->PadY();
195 fQ[i][cath] = fDig[i][cath]->Signal();
196 // pad centre coordinates
198 GetPadC(fIx[i][cath], fIy[i][cath], fX[i][cath], fY[i][cath], fZ[i][cath]);
199 } // loop over cluster digits
200 } // loop over cathodes
206 // Initialise and perform mathieson fits
207 Float_t chi2, oldchi2;
208 // ++++++++++++++++++*************+++++++++++++++++++++
209 // (1) No more than one local maximum per cathode plane
210 // +++++++++++++++++++++++++++++++*************++++++++
211 if ((fNLocal[0]==1 && (fNLocal[1]==0 || fNLocal[1]==1)) ||
212 (fNLocal[0]==0 && fNLocal[1]==1)) {
213 // Perform combined single Mathieson fit
214 // Initial values for coordinates (x,y)
216 // One local maximum on cathodes 1 and 2 (X->cathode 2, Y->cathode 1)
217 if (fNLocal[0]==1 && fNLocal[1]==1) {
220 // One local maximum on cathode 1 (X,Y->cathode 1)
221 } else if (fNLocal[0]==1) {
224 // One local maximum on cathode 2 (X,Y->cathode 2)
230 fprintf(stderr,"\n cas (1) CombiSingleMathiesonFit(c)\n");
231 chi2=CombiSingleMathiesonFit(c);
232 // Int_t ndf = fgNbins[0]+fgNbins[1]-2;
233 // Float_t prob = TMath::Prob(Double_t(chi2),ndf);
234 // prob1->Fill(prob);
235 // chi2_1->Fill(chi2);
238 fprintf(stderr," chi2 %f ",chi2);
248 c->fX[0]=fSeg[0]->GetAnod(c->fX[0]);
249 c->fX[1]=fSeg[1]->GetAnod(c->fX[1]);
251 // If reasonable chi^2 add result to the list of rawclusters
254 // If not try combined double Mathieson Fit
256 fprintf(stderr," MAUVAIS CHI2 !!!\n");
257 if (fNLocal[0]==1 && fNLocal[1]==1) {
258 fXInit[0]=fX[fIndLocal[0][1]][1];
259 fYInit[0]=fY[fIndLocal[0][0]][0];
260 fXInit[1]=fX[fIndLocal[0][1]][1];
261 fYInit[1]=fY[fIndLocal[0][0]][0];
262 } else if (fNLocal[0]==1) {
263 fXInit[0]=fX[fIndLocal[0][0]][0];
264 fYInit[0]=fY[fIndLocal[0][0]][0];
265 fXInit[1]=fX[fIndLocal[0][0]][0];
266 fYInit[1]=fY[fIndLocal[0][0]][0];
268 fXInit[0]=fX[fIndLocal[0][1]][1];
269 fYInit[0]=fY[fIndLocal[0][1]][1];
270 fXInit[1]=fX[fIndLocal[0][1]][1];
271 fYInit[1]=fY[fIndLocal[0][1]][1];
274 // Initial value for charge ratios
278 fprintf(stderr,"\n cas (1) CombiDoubleMathiesonFit(c)\n");
279 chi2=CombiDoubleMathiesonFit(c);
280 // Int_t ndf = fgNbins[0]+fgNbins[1]-6;
281 // Float_t prob = TMath::Prob(chi2,ndf);
282 // prob2->Fill(prob);
283 // chi2_2->Fill(chi2);
285 // Was this any better ??
286 fprintf(stderr," Old and new chi2 %f %f ", oldchi2, chi2);
287 if (fFitStat!=0 && chi2>0 && (2.*chi2 < oldchi2)) {
288 fprintf(stderr," Split\n");
289 // Split cluster into two according to fit result
292 fprintf(stderr," Don't Split\n");
298 // +++++++++++++++++++++++++++++++++++++++
299 // (2) Two local maxima per cathode plane
300 // +++++++++++++++++++++++++++++++++++++++
301 } else if (fNLocal[0]==2 && fNLocal[1]==2) {
303 // Let's look for ghosts first
305 Float_t xm[4][2], ym[4][2];
306 Float_t dpx, dpy, dx, dy;
307 Int_t ixm[4][2], iym[4][2];
308 Int_t isec, im1, im2, ico;
310 // Form the 2x2 combinations
311 // 0-0, 0-1, 1-0, 1-1
313 for (im1=0; im1<2; im1++) {
314 for (im2=0; im2<2; im2++) {
315 xm[ico][0]=fX[fIndLocal[im1][0]][0];
316 ym[ico][0]=fY[fIndLocal[im1][0]][0];
317 xm[ico][1]=fX[fIndLocal[im2][1]][1];
318 ym[ico][1]=fY[fIndLocal[im2][1]][1];
320 ixm[ico][0]=fIx[fIndLocal[im1][0]][0];
321 iym[ico][0]=fIy[fIndLocal[im1][0]][0];
322 ixm[ico][1]=fIx[fIndLocal[im2][1]][1];
323 iym[ico][1]=fIy[fIndLocal[im2][1]][1];
327 // ico = 0 : first local maximum on cathodes 1 and 2
328 // ico = 1 : fisrt local maximum on cathode 1 and second on cathode 2
329 // ico = 2 : second local maximum on cathode 1 and first on cathode 1
330 // ico = 3 : second local maximum on cathodes 1 and 2
332 // Analyse the combinations and keep those that are possible !
333 // For each combination check consistency in x and y
338 for (ico=0; ico<4; ico++) {
339 accepted[ico]=kFALSE;
340 // cathode one: x-coordinate
341 isec=fSeg[0]->Sector(ixm[ico][0], iym[ico][0]);
342 dpx=fSeg[0]->Dpx(isec)/2.;
343 dx=TMath::Abs(xm[ico][0]-xm[ico][1]);
344 // cathode two: y-coordinate
345 isec=fSeg[1]->Sector(ixm[ico][1], iym[ico][1]);
346 dpy=fSeg[1]->Dpy(isec)/2.;
347 dy=TMath::Abs(ym[ico][0]-ym[ico][1]);
349 printf("\n %i %f %f %f %f \n", ico, ym[ico][0], ym[ico][1], dy, dpy );
350 if ((dx <= dpx) && (dy <= dpy)) {
356 accepted[ico]=kFALSE;
362 fprintf(stderr,"\n iacc=2: No problem ! \n");
363 } else if (iacc==4) {
364 fprintf(stderr,"\n iacc=4: Ok, but ghost problem !!! \n");
365 } else if (iacc==0) {
366 fprintf(stderr,"\n iacc=0: I don't know what to do with this !!!!!!!!! \n");
370 // Initial value for charge ratios
371 fQrInit[0]=Float_t(fQ[fIndLocal[0][0]][0])/
372 Float_t(fQ[fIndLocal[0][0]][0]+fQ[fIndLocal[1][0]][0]);
373 fQrInit[1]=Float_t(fQ[fIndLocal[0][1]][1])/
374 Float_t(fQ[fIndLocal[0][1]][1]+fQ[fIndLocal[1][1]][1]);
376 // ******* iacc = 0 *******
377 // No combinations found between the 2 cathodes
378 // We keep the center of gravity of the cluster
383 // ******* iacc = 1 *******
384 // Only one combination found between the 2 cathodes
386 // Initial values for the 2 maxima (x,y)
388 // 1 maximum is initialised with the maximum of the combination found (X->cathode 2, Y->cathode 1)
389 // 1 maximum is initialised with the other maximum of the first cathode
391 fprintf(stderr,"ico=0\n");
396 } else if (accepted[1]){
397 fprintf(stderr,"ico=1\n");
402 } else if (accepted[2]){
403 fprintf(stderr,"ico=2\n");
408 } else if (accepted[3]){
409 fprintf(stderr,"ico=3\n");
416 fprintf(stderr,"\n cas (2) CombiDoubleMathiesonFit(c)\n");
417 chi2=CombiDoubleMathiesonFit(c);
418 // Int_t ndf = fgNbins[0]+fgNbins[1]-6;
419 // Float_t prob = TMath::Prob(chi2,ndf);
420 // prob2->Fill(prob);
421 // chi2_2->Fill(chi2);
423 fprintf(stderr," chi2 %f\n",chi2);
425 // If reasonable chi^2 add result to the list of rawclusters
430 // 1 maximum is initialised with the maximum of the combination found (X->cathode 2, Y->cathode 1)
431 // 1 maximum is initialised with the other maximum of the second cathode
433 fprintf(stderr,"ico=0\n");
438 } else if (accepted[1]){
439 fprintf(stderr,"ico=1\n");
444 } else if (accepted[2]){
445 fprintf(stderr,"ico=2\n");
450 } else if (accepted[3]){
451 fprintf(stderr,"ico=3\n");
458 fprintf(stderr,"\n cas (2) CombiDoubleMathiesonFit(c)\n");
459 chi2=CombiDoubleMathiesonFit(c);
460 // Int_t ndf = fgNbins[0]+fgNbins[1]-6;
461 // Float_t prob = TMath::Prob(chi2,ndf);
462 // prob2->Fill(prob);
463 // chi2_2->Fill(chi2);
465 fprintf(stderr," chi2 %f\n",chi2);
467 // If reasonable chi^2 add result to the list of rawclusters
471 //We keep only the combination found (X->cathode 2, Y->cathode 1)
472 for (Int_t ico=0; ico<2; ico++) {
474 AliMUONRawCluster cnew;
476 for (cath=0; cath<2; cath++) {
477 cnew.fX[cath]=Float_t(xm[ico][1]);
478 cnew.fY[cath]=Float_t(ym[ico][0]);
479 cnew.fZ[cath]=fZPlane;
481 cnew.fMultiplicity[cath]=c->fMultiplicity[cath];
482 for (i=0; i<fMul[cath]; i++) {
483 cnew.fIndexMap[i][cath]=c->fIndexMap[i][cath];
484 fSeg[cath]->SetPad(fIx[i][cath], fIy[i][cath]);
486 fprintf(stderr,"\nRawCluster %d cath %d\n",ico,cath);
487 fprintf(stderr,"mult_av %d\n",c->fMultiplicity[cath]);
488 FillCluster(&cnew,cath);
490 cnew.fClusterType=cnew.PhysicsContribution();
499 // ******* iacc = 2 *******
500 // Two combinations found between the 2 cathodes
502 // Was the same maximum taken twice
503 if ((accepted[0]&&accepted[1]) || (accepted[2]&&accepted[3])) {
504 fprintf(stderr,"\n Maximum taken twice !!!\n");
506 // Have a try !! with that
507 if (accepted[0]&&accepted[3]) {
519 fprintf(stderr,"\n cas (2) CombiDoubleMathiesonFit(c)\n");
520 chi2=CombiDoubleMathiesonFit(c);
521 // Int_t ndf = fgNbins[0]+fgNbins[1]-6;
522 // Float_t prob = TMath::Prob(chi2,ndf);
523 // prob2->Fill(prob);
524 // chi2_2->Fill(chi2);
528 // No ghosts ! No Problems ! - Perform one fit only !
529 if (accepted[0]&&accepted[3]) {
541 fprintf(stderr,"\n cas (2) CombiDoubleMathiesonFit(c)\n");
542 chi2=CombiDoubleMathiesonFit(c);
543 // Int_t ndf = fgNbins[0]+fgNbins[1]-6;
544 // Float_t prob = TMath::Prob(chi2,ndf);
545 // prob2->Fill(prob);
546 // chi2_2->Fill(chi2);
548 fprintf(stderr," chi2 %f\n",chi2);
552 // ******* iacc = 4 *******
553 // Four combinations found between the 2 cathodes
555 } else if (iacc==4) {
556 // Perform fits for the two possibilities !!
557 // Accept if charges are compatible on both cathodes
558 // If none are compatible, keep everything
564 fprintf(stderr,"\n cas (2) CombiDoubleMathiesonFit(c)\n");
565 chi2=CombiDoubleMathiesonFit(c);
566 // Int_t ndf = fgNbins[0]+fgNbins[1]-6;
567 // Float_t prob = TMath::Prob(chi2,ndf);
568 // prob2->Fill(prob);
569 // chi2_2->Fill(chi2);
571 fprintf(stderr," chi2 %f\n",chi2);
572 // store results of fit and postpone decision
573 Double_t sXFit[2],sYFit[2],sQrFit[2];
575 for (Int_t i=0;i<2;i++) {
586 fprintf(stderr,"\n cas (2) CombiDoubleMathiesonFit(c)\n");
587 chi2=CombiDoubleMathiesonFit(c);
588 // ndf = fgNbins[0]+fgNbins[1]-6;
589 // prob = TMath::Prob(chi2,ndf);
590 // prob2->Fill(prob);
591 // chi2_2->Fill(chi2);
593 fprintf(stderr," chi2 %f\n",chi2);
594 // We have all informations to perform the decision
595 // Compute the chi2 for the 2 possibilities
596 Float_t chi2fi,chi2si,chi2f,chi2s;
598 chi2f = (TMath::Log(fInput->TotalCharge(0)*fQrFit[0]
599 / (fInput->TotalCharge(1)*fQrFit[1]) )
600 / fInput->Response()->ChargeCorrel() );
602 chi2fi = (TMath::Log(fInput->TotalCharge(0)*(1-fQrFit[0])
603 / (fInput->TotalCharge(1)*(1-fQrFit[1])) )
604 / fInput->Response()->ChargeCorrel() );
605 chi2f += chi2fi*chi2fi;
607 chi2s = (TMath::Log(fInput->TotalCharge(0)*sQrFit[0]
608 / (fInput->TotalCharge(1)*sQrFit[1]) )
609 / fInput->Response()->ChargeCorrel() );
611 chi2si = (TMath::Log(fInput->TotalCharge(0)*(1-sQrFit[0])
612 / (fInput->TotalCharge(1)*(1-sQrFit[1])) )
613 / fInput->Response()->ChargeCorrel() );
614 chi2s += chi2si*chi2si;
616 // usefull to store the charge matching chi2 in the cluster
617 // fChi2[0]=sChi2[1]=chi2f;
618 // fChi2[1]=sChi2[0]=chi2s;
620 if (chi2f<=fGhostChi2Cut && chi2s<=fGhostChi2Cut)
622 if (chi2f>fGhostChi2Cut && chi2s>fGhostChi2Cut) {
628 if (chi2f<=fGhostChi2Cut)
630 if (chi2s<=fGhostChi2Cut) {
631 // retreive saved values
632 for (Int_t i=0;i<2;i++) {
643 } else if (fNLocal[0]==2 && fNLocal[1]==1) {
644 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
645 // (3) Two local maxima on cathode 1 and one maximum on cathode 2
646 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
648 Float_t xm[4][2], ym[4][2];
649 Float_t dpx, dpy, dx, dy;
650 Int_t ixm[4][2], iym[4][2];
651 Int_t isec, im1, ico;
653 // Form the 2x2 combinations
654 // 0-0, 0-1, 1-0, 1-1
656 for (im1=0; im1<2; im1++) {
657 xm[ico][0]=fX[fIndLocal[im1][0]][0];
658 ym[ico][0]=fY[fIndLocal[im1][0]][0];
659 xm[ico][1]=fX[fIndLocal[0][1]][1];
660 ym[ico][1]=fY[fIndLocal[0][1]][1];
662 ixm[ico][0]=fIx[fIndLocal[im1][0]][0];
663 iym[ico][0]=fIy[fIndLocal[im1][0]][0];
664 ixm[ico][1]=fIx[fIndLocal[0][1]][1];
665 iym[ico][1]=fIy[fIndLocal[0][1]][1];
668 // ico = 0 : first local maximum on cathodes 1 and 2
669 // ico = 1 : second local maximum on cathode 1 and first on cathode 2
671 // Analyse the combinations and keep those that are possible !
672 // For each combination check consistency in x and y
677 for (ico=0; ico<2; ico++) {
678 accepted[ico]=kFALSE;
679 isec=fSeg[0]->Sector(ixm[ico][0], iym[ico][0]);
680 dpx=fSeg[0]->Dpx(isec)/2.;
681 dx=TMath::Abs(xm[ico][0]-xm[ico][1]);
682 isec=fSeg[1]->Sector(ixm[ico][1], iym[ico][1]);
683 dpy=fSeg[1]->Dpy(isec)/2.;
684 dy=TMath::Abs(ym[ico][0]-ym[ico][1]);
686 printf("\n %i %f %f %f %f \n", ico, ym[ico][0], ym[ico][1], dy, dpy );
687 if ((dx <= dpx) && (dy <= dpy)) {
693 accepted[ico]=kFALSE;
705 chi21=CombiDoubleMathiesonFit(c);
706 // Int_t ndf = fgNbins[0]+fgNbins[1]-6;
707 // Float_t prob = TMath::Prob(chi2,ndf);
708 // prob2->Fill(prob);
709 // chi2_2->Fill(chi21);
711 fprintf(stderr," chi2 %f\n",chi21);
712 if (chi21<10) Split(c);
713 } else if (accepted[1]) {
718 chi22=CombiDoubleMathiesonFit(c);
719 // Int_t ndf = fgNbins[0]+fgNbins[1]-6;
720 // Float_t prob = TMath::Prob(chi2,ndf);
721 // prob2->Fill(prob);
722 // chi2_2->Fill(chi22);
724 fprintf(stderr," chi2 %f\n",chi22);
725 if (chi22<10) Split(c);
728 if (chi21 > 10 && chi22 > 10) {
729 // We keep only the combination found (X->cathode 2, Y->cathode 1)
730 for (Int_t ico=0; ico<2; ico++) {
732 AliMUONRawCluster cnew;
734 for (cath=0; cath<2; cath++) {
735 cnew.fX[cath]=Float_t(xm[ico][1]);
736 cnew.fY[cath]=Float_t(ym[ico][0]);
737 cnew.fZ[cath]=fZPlane;
738 cnew.fMultiplicity[cath]=c->fMultiplicity[cath];
739 for (i=0; i<fMul[cath]; i++) {
740 cnew.fIndexMap[i][cath]=c->fIndexMap[i][cath];
741 fSeg[cath]->SetPad(fIx[i][cath], fIy[i][cath]);
743 fprintf(stderr,"\nRawCluster %d cath %d\n",ico,cath);
744 fprintf(stderr,"mult_av %d\n",c->fMultiplicity[cath]);
745 FillCluster(&cnew,cath);
747 cnew.fClusterType=cnew.PhysicsContribution();
754 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
755 // (3') One local maximum on cathode 1 and two maxima on cathode 2
756 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
757 } else if (fNLocal[0]==1 && fNLocal[1]==2) {
758 Float_t xm[4][2], ym[4][2];
759 Float_t dpx, dpy, dx, dy;
760 Int_t ixm[4][2], iym[4][2];
761 Int_t isec, im1, ico;
763 // Form the 2x2 combinations
764 // 0-0, 0-1, 1-0, 1-1
766 for (im1=0; im1<2; im1++) {
767 xm[ico][0]=fX[fIndLocal[0][0]][0];
768 ym[ico][0]=fY[fIndLocal[0][0]][0];
769 xm[ico][1]=fX[fIndLocal[im1][1]][1];
770 ym[ico][1]=fY[fIndLocal[im1][1]][1];
772 ixm[ico][0]=fIx[fIndLocal[0][0]][0];
773 iym[ico][0]=fIy[fIndLocal[0][0]][0];
774 ixm[ico][1]=fIx[fIndLocal[im1][1]][1];
775 iym[ico][1]=fIy[fIndLocal[im1][1]][1];
778 // ico = 0 : first local maximum on cathodes 1 and 2
779 // ico = 1 : first local maximum on cathode 1 and second on cathode 2
781 // Analyse the combinations and keep those that are possible !
782 // For each combination check consistency in x and y
787 for (ico=0; ico<2; ico++) {
788 accepted[ico]=kFALSE;
789 isec=fSeg[0]->Sector(ixm[ico][0], iym[ico][0]);
790 dpx=fSeg[0]->Dpx(isec)/2.;
791 dx=TMath::Abs(xm[ico][0]-xm[ico][1]);
792 isec=fSeg[1]->Sector(ixm[ico][1], iym[ico][1]);
793 dpy=fSeg[1]->Dpy(isec)/2.;
794 dy=TMath::Abs(ym[ico][0]-ym[ico][1]);
796 printf("\n %i %f %f %f %f \n", ico, ym[ico][0], ym[ico][1], dy, dpy );
797 if ((dx <= dpx) && (dy <= dpy)) {
800 fprintf(stderr,"ico %d\n",ico);
804 accepted[ico]=kFALSE;
816 chi21=CombiDoubleMathiesonFit(c);
817 // Int_t ndf = fgNbins[0]+fgNbins[1]-6;
818 // Float_t prob = TMath::Prob(chi2,ndf);
819 // prob2->Fill(prob);
820 // chi2_2->Fill(chi21);
822 fprintf(stderr," chi2 %f\n",chi21);
823 if (chi21<10) Split(c);
824 } else if (accepted[1]) {
829 chi22=CombiDoubleMathiesonFit(c);
830 // Int_t ndf = fgNbins[0]+fgNbins[1]-6;
831 // Float_t prob = TMath::Prob(chi2,ndf);
832 // prob2->Fill(prob);
833 // chi2_2->Fill(chi22);
835 fprintf(stderr," chi2 %f\n",chi22);
836 if (chi22<10) Split(c);
839 if (chi21 > 10 && chi22 > 10) {
840 //We keep only the combination found (X->cathode 2, Y->cathode 1)
841 for (Int_t ico=0; ico<2; ico++) {
843 AliMUONRawCluster cnew;
845 for (cath=0; cath<2; cath++) {
846 cnew.fX[cath]=Float_t(xm[ico][1]);
847 cnew.fY[cath]=Float_t(ym[ico][0]);
848 cnew.fZ[cath]=fZPlane;
849 cnew.fMultiplicity[cath]=c->fMultiplicity[cath];
850 for (i=0; i<fMul[cath]; i++) {
851 cnew.fIndexMap[i][cath]=c->fIndexMap[i][cath];
852 fSeg[cath]->SetPad(fIx[i][cath], fIy[i][cath]);
854 fprintf(stderr,"\nRawCluster %d cath %d\n",ico,cath);
855 fprintf(stderr,"mult_av %d\n",c->fMultiplicity[cath]);
856 FillCluster(&cnew,cath);
858 cnew.fClusterType=cnew.PhysicsContribution();
865 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
866 // (4) At least three local maxima on cathode 1 or on cathode 2
867 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
868 } else if (fNLocal[0]>2 || fNLocal[1]>2) {
869 Int_t param = fNLocal[0]*fNLocal[1];
872 Float_t ** xm = new Float_t * [param];
873 for (ii=0; ii<param; ii++) xm[ii]=new Float_t [2];
874 Float_t ** ym = new Float_t * [param];
875 for (ii=0; ii<param; ii++) ym[ii]=new Float_t [2];
876 Int_t ** ixm = new Int_t * [param];
877 for (ii=0; ii<param; ii++) ixm[ii]=new Int_t [2];
878 Int_t ** iym = new Int_t * [param];
879 for (ii=0; ii<param; ii++) iym[ii]=new Int_t [2];
882 Float_t dpx, dpy, dx, dy;
885 for (Int_t im1=0; im1<fNLocal[0]; im1++) {
886 for (Int_t im2=0; im2<fNLocal[1]; im2++) {
887 xm[ico][0]=fX[fIndLocal[im1][0]][0];
888 ym[ico][0]=fY[fIndLocal[im1][0]][0];
889 xm[ico][1]=fX[fIndLocal[im2][1]][1];
890 ym[ico][1]=fY[fIndLocal[im2][1]][1];
892 ixm[ico][0]=fIx[fIndLocal[im1][0]][0];
893 iym[ico][0]=fIy[fIndLocal[im1][0]][0];
894 ixm[ico][1]=fIx[fIndLocal[im2][1]][1];
895 iym[ico][1]=fIy[fIndLocal[im2][1]][1];
902 fprintf(stderr,"nIco %d\n",nIco);
903 for (ico=0; ico<nIco; ico++) {
905 fprintf(stderr,"ico = %d\n",ico);
906 isec=fSeg[0]->Sector(ixm[ico][0], iym[ico][0]);
907 dpx=fSeg[0]->Dpx(isec)/2.;
908 dx=TMath::Abs(xm[ico][0]-xm[ico][1]);
909 isec=fSeg[1]->Sector(ixm[ico][1], iym[ico][1]);
910 dpy=fSeg[1]->Dpy(isec)/2.;
911 dy=TMath::Abs(ym[ico][0]-ym[ico][1]);
913 fprintf(stderr,"dx %f dpx %f dy %f dpy %f\n",dx,dpx,dy,dpy);
914 fprintf(stderr," X %f Y %f\n",xm[ico][1],ym[ico][0]);
916 if ((dx <= dpx) && (dy <= dpy)) {
918 fprintf(stderr,"ok\n");
920 AliMUONRawCluster cnew;
921 for (cath=0; cath<2; cath++) {
922 cnew.fX[cath]=Float_t(xm[ico][1]);
923 cnew.fY[cath]=Float_t(ym[ico][0]);
924 cnew.fZ[cath]=fZPlane;
925 cnew.fMultiplicity[cath]=c->fMultiplicity[cath];
926 for (i=0; i<fMul[cath]; i++) {
927 cnew.fIndexMap[i][cath]=c->fIndexMap[i][cath];
928 fSeg[cath]->SetPad(fIx[i][cath], fIy[i][cath]);
930 FillCluster(&cnew,cath);
932 cnew.fClusterType=cnew.PhysicsContribution();
944 void AliMUONClusterFinderVS::FindLocalMaxima(AliMUONRawCluster* c)
946 // Find all local maxima of a cluster
948 printf("\n Find Local maxima !");
952 Int_t cath, cath1; // loops over cathodes
953 Int_t i; // loops over digits
954 Int_t j; // loops over cathodes
958 // counters for number of local maxima
959 fNLocal[0]=fNLocal[1]=0;
960 // flags digits as local maximum
961 Bool_t isLocal[100][2];
962 for (i=0; i<100;i++) {
963 isLocal[i][0]=isLocal[i][1]=kFALSE;
965 // number of next neighbours and arrays to store them
968 // loop over cathodes
969 for (cath=0; cath<2; cath++) {
970 // loop over cluster digits
971 for (i=0; i<fMul[cath]; i++) {
972 // get neighbours for that digit and assume that it is local maximum
973 fSeg[cath]->Neighbours(fIx[i][cath], fIy[i][cath], &nn, x, y);
974 isLocal[i][cath]=kTRUE;
975 Int_t isec= fSeg[cath]->Sector(fIx[i][cath], fIy[i][cath]);
976 Float_t a0 = fSeg[cath]->Dpx(isec)*fSeg[cath]->Dpy(isec);
977 // loop over next neighbours, if at least one neighbour has higher charger assumption
978 // digit is not local maximum
979 for (j=0; j<nn; j++) {
980 if (fHitMap[cath]->TestHit(x[j], y[j])==kEmpty) continue;
981 digt=(AliMUONDigit*) fHitMap[cath]->GetHit(x[j], y[j]);
982 isec=fSeg[cath]->Sector(x[j], y[j]);
983 Float_t a1 = fSeg[cath]->Dpx(isec)*fSeg[cath]->Dpy(isec);
984 if (digt->Signal()/a1 > fQ[i][cath]/a0) {
985 isLocal[i][cath]=kFALSE;
988 // handle special case of neighbouring pads with equal signal
989 } else if (digt->Signal() == fQ[i][cath]) {
990 if (fNLocal[cath]>0) {
991 for (Int_t k=0; k<fNLocal[cath]; k++) {
992 if (x[j]==fIx[fIndLocal[k][cath]][cath]
993 && y[j]==fIy[fIndLocal[k][cath]][cath])
995 isLocal[i][cath]=kFALSE;
997 } // loop over local maxima
998 } // are there already local maxima
1000 } // loop over next neighbours
1001 if (isLocal[i][cath]) {
1002 fIndLocal[fNLocal[cath]][cath]=i;
1005 } // loop over all digits
1006 } // loop over cathodes
1009 printf("\n Found %d %d %d %d local Maxima\n",
1010 fNLocal[0], fNLocal[1], fMul[0], fMul[1]);
1011 fprintf(stderr,"\n Cathode 1 local Maxima %d Multiplicite %d\n",fNLocal[0], fMul[0]);
1012 fprintf(stderr," Cathode 2 local Maxima %d Multiplicite %d\n",fNLocal[1], fMul[1]);
1018 if (fNLocal[1]==2 && (fNLocal[0]==1 || fNLocal[0]==0)) {
1019 Int_t iback=fNLocal[0];
1021 // Two local maxima on cathode 2 and one maximum on cathode 1
1022 // Look for local maxima considering up and down neighbours on the 1st cathode only
1024 // Loop over cluster digits
1028 for (i=0; i<fMul[cath]; i++) {
1029 isec=fSeg[cath]->Sector(fIx[i][cath],fIy[i][cath]);
1030 dpy=fSeg[cath]->Dpy(isec);
1031 dpx=fSeg[cath]->Dpx(isec);
1032 if (isLocal[i][cath]) continue;
1033 // Pad position should be consistent with position of local maxima on the opposite cathode
1034 if ((TMath::Abs(fX[i][cath]-fX[fIndLocal[0][cath1]][cath1]) > dpx/2.) &&
1035 (TMath::Abs(fX[i][cath]-fX[fIndLocal[1][cath1]][cath1]) > dpx/2.))
1038 // get neighbours for that digit and assume that it is local maximum
1039 isLocal[i][cath]=kTRUE;
1040 // compare signal to that on the two neighbours on the left and on the right
1041 // iNN counts the number of neighbours with signal, it should be 1 or 2
1045 ->FirstPad(fX[i][cath], fY[i][cath], fZPlane, 0., dpy);
1051 ix = fSeg[cath]->Ix();
1052 iy = fSeg[cath]->Iy();
1053 // skip the current pad
1054 if (iy == fIy[i][cath]) continue;
1056 if (fHitMap[cath]->TestHit(ix, iy)!=kEmpty) {
1058 digt=(AliMUONDigit*) fHitMap[cath]->GetHit(ix,iy);
1059 if (digt->Signal() > fQ[i][cath]) isLocal[i][cath]=kFALSE;
1061 } // Loop over pad neighbours in y
1062 if (isLocal[i][cath] && iNN>0) {
1063 fIndLocal[fNLocal[cath]][cath]=i;
1066 } // loop over all digits
1067 // if one additional maximum has been found we are happy
1068 // if more maxima have been found restore the previous situation
1071 "\n New search gives %d local maxima for cathode 1 \n",
1074 " %d local maxima for cathode 2 \n",
1077 if (fNLocal[cath]>2) {
1078 fNLocal[cath]=iback;
1081 } // 1,2 local maxima
1083 if (fNLocal[0]==2 && (fNLocal[1]==1 || fNLocal[1]==0)) {
1084 Int_t iback=fNLocal[1];
1086 // Two local maxima on cathode 1 and one maximum on cathode 2
1087 // Look for local maxima considering left and right neighbours on the 2nd cathode only
1091 // Loop over cluster digits
1092 for (i=0; i<fMul[cath]; i++) {
1093 isec=fSeg[cath]->Sector(fIx[i][cath],fIy[i][cath]);
1094 dpx=fSeg[cath]->Dpx(isec);
1095 dpy=fSeg[cath]->Dpy(isec);
1096 if (isLocal[i][cath]) continue;
1097 // Pad position should be consistent with position of local maxima on the opposite cathode
1098 if ((TMath::Abs(fY[i][cath]-fY[fIndLocal[0][cath1]][cath1]) > dpy/2.) &&
1099 (TMath::Abs(fY[i][cath]-fY[fIndLocal[1][cath1]][cath1]) > dpy/2.))
1102 // get neighbours for that digit and assume that it is local maximum
1103 isLocal[i][cath]=kTRUE;
1104 // compare signal to that on the two neighbours on the left and on the right
1106 // iNN counts the number of neighbours with signal, it should be 1 or 2
1109 ->FirstPad(fX[i][cath], fY[i][cath], fZPlane, 0., dpx);
1115 ix = fSeg[cath]->Ix();
1116 iy = fSeg[cath]->Iy();
1118 // skip the current pad
1119 if (ix == fIx[i][cath]) continue;
1121 if (fHitMap[cath]->TestHit(ix, iy)!=kEmpty) {
1123 digt=(AliMUONDigit*) fHitMap[cath]->GetHit(ix,iy);
1124 if (digt->Signal() > fQ[i][cath]) isLocal[i][cath]=kFALSE;
1126 } // Loop over pad neighbours in x
1127 if (isLocal[i][cath] && iNN>0) {
1128 fIndLocal[fNLocal[cath]][cath]=i;
1131 } // loop over all digits
1132 // if one additional maximum has been found we are happy
1133 // if more maxima have been found restore the previous situation
1135 fprintf(stderr,"\n New search gives %d local maxima for cathode 1 \n",fNLocal[0]);
1136 fprintf(stderr,"\n %d local maxima for cathode 2 \n",fNLocal[1]);
1137 printf("\n New search gives %d %d \n",fNLocal[0],fNLocal[1]);
1139 if (fNLocal[cath]>2) {
1140 fNLocal[cath]=iback;
1142 } // 2,1 local maxima
1146 void AliMUONClusterFinderVS::FillCluster(AliMUONRawCluster* c, Int_t flag, Int_t cath)
1149 // Completes cluster information starting from list of digits
1156 c->fPeakSignal[cath]=c->fPeakSignal[0];
1158 c->fPeakSignal[cath]=0;
1169 fprintf(stderr,"\n fPeakSignal %d\n",c->fPeakSignal[cath]);
1170 for (Int_t i=0; i<c->fMultiplicity[cath]; i++)
1172 dig= fInput->Digit(cath,c->fIndexMap[i][cath]);
1173 ix=dig->PadX()+c->fOffsetMap[i][cath];
1175 Int_t q=dig->Signal();
1176 if (!flag) q=Int_t(q*c->fContMap[i][cath]);
1177 // fprintf(stderr,"q %d c->fPeakSignal[ %d ] %d\n",q,cath,c->fPeakSignal[cath]);
1178 if (dig->Physics() >= dig->Signal()) {
1179 c->fPhysicsMap[i]=2;
1180 } else if (dig->Physics() == 0) {
1181 c->fPhysicsMap[i]=0;
1182 } else c->fPhysicsMap[i]=1;
1186 fprintf(stderr,"q %d c->fPeakSignal[cath] %d\n",q,c->fPeakSignal[cath]);
1187 // peak signal and track list
1188 if (q>c->fPeakSignal[cath]) {
1189 c->fPeakSignal[cath]=q;
1190 c->fTracks[0]=dig->Hit();
1191 c->fTracks[1]=dig->Track(0);
1192 c->fTracks[2]=dig->Track(1);
1193 // fprintf(stderr," c->fTracks[0] %d c->fTracks[1] %d\n",dig->fHit,dig->fTracks[0]);
1197 fSeg[cath]->GetPadC(ix, iy, x, y, z);
1202 } // loop over digits
1204 fprintf(stderr," fin du cluster c\n");
1208 c->fX[cath]/=c->fQ[cath];
1210 c->fX[cath]=fSeg[cath]->GetAnod(c->fX[cath]);
1211 c->fY[cath]/=c->fQ[cath];
1213 // apply correction to the coordinate along the anode wire
1217 fSeg[cath]->GetPadI(x, y, fZPlane, ix, iy);
1218 fSeg[cath]->GetPadC(ix, iy, x, y, z);
1219 Int_t isec=fSeg[cath]->Sector(ix,iy);
1220 TF1* cogCorr = fSeg[cath]->CorrFunc(isec-1);
1223 Float_t yOnPad=(c->fY[cath]-y)/fSeg[cath]->Dpy(isec);
1224 c->fY[cath]=c->fY[cath]-cogCorr->Eval(yOnPad, 0, 0);
1229 void AliMUONClusterFinderVS::FillCluster(AliMUONRawCluster* c, Int_t cath)
1232 // Completes cluster information starting from list of digits
1242 Float_t xpad, ypad, zpad;
1245 for (Int_t i=0; i<c->fMultiplicity[cath]; i++)
1247 dig = fInput->Digit(cath,c->fIndexMap[i][cath]);
1249 GetPadC(dig->PadX(),dig->PadY(),xpad,ypad, zpad);
1251 fprintf(stderr,"x %f y %f cx %f cy %f\n",xpad,ypad,c->fX[0],c->fY[0]);
1252 dx = xpad - c->fX[0];
1253 dy = ypad - c->fY[0];
1254 dr = TMath::Sqrt(dx*dx+dy*dy);
1259 fprintf(stderr," dr %f\n",dr);
1260 Int_t q=dig->Signal();
1261 if (dig->Physics() >= dig->Signal()) {
1262 c->fPhysicsMap[i]=2;
1263 } else if (dig->Physics() == 0) {
1264 c->fPhysicsMap[i]=0;
1265 } else c->fPhysicsMap[i]=1;
1266 c->fPeakSignal[cath]=q;
1267 c->fTracks[0]=dig->Hit();
1268 c->fTracks[1]=dig->Track(0);
1269 c->fTracks[2]=dig->Track(1);
1271 fprintf(stderr," c->fTracks[0] %d c->fTracks[1] %d\n",dig->Hit(),
1275 } // loop over digits
1277 // apply correction to the coordinate along the anode wire
1279 c->fX[cath]=fSeg[cath]->GetAnod(c->fX[cath]);
1282 void AliMUONClusterFinderVS::FindCluster(Int_t i, Int_t j, Int_t cath, AliMUONRawCluster &c){
1286 // Find a super cluster on both cathodes
1289 // Add i,j as element of the cluster
1292 Int_t idx = fHitMap[cath]->GetHitIndex(i,j);
1293 AliMUONDigit* dig = (AliMUONDigit*) fHitMap[cath]->GetHit(i,j);
1294 Int_t q=dig->Signal();
1295 Int_t theX=dig->PadX();
1296 Int_t theY=dig->PadY();
1298 if (q > TMath::Abs(c.fPeakSignal[0]) && q > TMath::Abs(c.fPeakSignal[1])) {
1299 c.fPeakSignal[cath]=q;
1300 c.fTracks[0]=dig->Hit();
1301 c.fTracks[1]=dig->Track(0);
1302 c.fTracks[2]=dig->Track(1);
1306 // Make sure that list of digits is ordered
1308 Int_t mu=c.fMultiplicity[cath];
1309 c.fIndexMap[mu][cath]=idx;
1311 if (dig->Physics() >= dig->Signal()) {
1312 c.fPhysicsMap[mu]=2;
1313 } else if (dig->Physics() == 0) {
1314 c.fPhysicsMap[mu]=0;
1315 } else c.fPhysicsMap[mu]=1;
1319 for (Int_t ind = mu-1; ind >= 0; ind--) {
1320 Int_t ist=(c.fIndexMap)[ind][cath];
1321 Int_t ql=fInput->Digit(cath, ist)->Signal();
1322 Int_t ix=fInput->Digit(cath, ist)->PadX();
1323 Int_t iy=fInput->Digit(cath, ist)->PadY();
1325 if (q>ql || (q==ql && theX > ix && theY < iy)) {
1326 c.fIndexMap[ind][cath]=idx;
1327 c.fIndexMap[ind+1][cath]=ist;
1335 c.fMultiplicity[cath]++;
1336 if (c.fMultiplicity[cath] >= 50 ) {
1337 printf("FindCluster - multiplicity >50 %d \n",c.fMultiplicity[0]);
1338 c.fMultiplicity[cath]=49;
1341 // Prepare center of gravity calculation
1343 fSeg[cath]->GetPadC(i, j, x, y, z);
1349 // Flag hit as "taken"
1350 fHitMap[cath]->FlagHit(i,j);
1352 // Now look recursively for all neighbours and pad hit on opposite cathode
1354 // Loop over neighbours
1358 Int_t xList[10], yList[10];
1359 fSeg[cath]->Neighbours(i,j,&nn,xList,yList);
1360 for (Int_t in=0; in<nn; in++) {
1364 if (fHitMap[cath]->TestHit(ix,iy)==kUnused) {
1366 printf("\n Neighbours %d %d %d", cath, ix, iy);
1367 FindCluster(ix, iy, cath, c);
1372 Int_t iXopp[50], iYopp[50];
1374 // Neighbours on opposite cathode
1375 // Take into account that several pads can overlap with the present pad
1376 Int_t isec=fSeg[cath]->Sector(i,j);
1382 dx = (fSeg[cath]->Dpx(isec))/2.;
1387 dy = (fSeg[cath]->Dpy(isec))/2;
1389 // loop over pad neighbours on opposite cathode
1390 for (fSeg[iop]->FirstPad(x, y, fZPlane, dx, dy);
1391 fSeg[iop]->MorePads();
1392 fSeg[iop]->NextPad())
1395 ix = fSeg[iop]->Ix(); iy = fSeg[iop]->Iy();
1397 printf("\n ix, iy: %f %f %f %d %d %d", x,y,z,ix, iy, fSector);
1398 if (fHitMap[iop]->TestHit(ix,iy)==kUnused){
1402 printf("\n Opposite %d %d %d", iop, ix, iy);
1405 } // Loop over pad neighbours
1406 // This had to go outside the loop since recursive calls inside the iterator are not possible
1409 for (jopp=0; jopp<nOpp; jopp++) {
1410 if (fHitMap[iop]->TestHit(iXopp[jopp],iYopp[jopp]) == kUnused)
1411 FindCluster(iXopp[jopp], iYopp[jopp], iop, c);
1415 //_____________________________________________________________________________
1417 void AliMUONClusterFinderVS::FindRawClusters()
1420 // MUON cluster finder from digits -- finds neighbours on both cathodes and
1421 // fills the tree with raw clusters
1424 // Return if no input datad available
1425 if (!fInput->NDigits(0) && !fInput->NDigits(1)) return;
1427 fSeg[0] = fInput->Segmentation(0);
1428 fSeg[1] = fInput->Segmentation(1);
1430 fHitMap[0] = new AliMUONHitMapA1(fSeg[0], fInput->Digits(0));
1431 fHitMap[1] = new AliMUONHitMapA1(fSeg[1], fInput->Digits(1));
1439 fHitMap[0]->FillHits();
1440 fHitMap[1]->FillHits();
1442 // Outer Loop over Cathodes
1443 for (cath=0; cath<2; cath++) {
1444 for (ndig=0; ndig<fInput->NDigits(cath); ndig++) {
1445 dig = fInput->Digit(cath, ndig);
1446 Int_t i=dig->PadX();
1447 Int_t j=dig->PadY();
1448 if (fHitMap[cath]->TestHit(i,j)==kUsed ||fHitMap[0]->TestHit(i,j)==kEmpty) {
1453 fprintf(stderr,"\n CATHODE %d CLUSTER %d\n",cath,ncls);
1454 AliMUONRawCluster c;
1455 c.fMultiplicity[0]=0;
1456 c.fMultiplicity[1]=0;
1457 c.fPeakSignal[cath]=dig->Signal();
1458 c.fTracks[0]=dig->Hit();
1459 c.fTracks[1]=dig->Track(0);
1460 c.fTracks[2]=dig->Track(1);
1461 // tag the beginning of cluster list in a raw cluster
1464 fSeg[cath]->GetPadC(i,j,xcu, ycu, fZPlane);
1465 fSector= fSeg[cath]->Sector(i,j)/100;
1467 printf("\n New Seed %d %d ", i,j);
1469 FindCluster(i,j,cath,c);
1470 // ^^^^^^^^^^^^^^^^^^^^^^^^
1471 // center of gravity
1474 c.fX[0]=fSeg[0]->GetAnod(c.fX[0]);
1478 c.fX[1]=fSeg[0]->GetAnod(c.fX[1]);
1485 fprintf(stderr,"\n Cathode 1 multiplicite %d X(CG) %f Y(CG) %f\n",
1486 c.fMultiplicity[0],c.fX[0],c.fY[0]);
1487 fprintf(stderr," Cathode 2 multiplicite %d X(CG) %f Y(CG) %f\n",
1488 c.fMultiplicity[1],c.fX[1],c.fY[1]);
1490 // Analyse cluster and decluster if necessary
1493 c.fNcluster[1]=fNRawClusters;
1494 c.fClusterType=c.PhysicsContribution();
1501 // reset Cluster object
1502 { // begin local scope
1503 for (int k=0;k<c.fMultiplicity[0];k++) c.fIndexMap[k][0]=0;
1504 } // end local scope
1506 { // begin local scope
1507 for (int k=0;k<c.fMultiplicity[1];k++) c.fIndexMap[k][1]=0;
1508 } // end local scope
1510 c.fMultiplicity[0]=c.fMultiplicity[0]=0;
1514 } // end loop cathodes
1519 Float_t AliMUONClusterFinderVS::SingleMathiesonFit(AliMUONRawCluster *c, Int_t cath)
1521 // Performs a single Mathieson fit on one cathode
1523 AliMUONClusterInput& clusterInput = *(AliMUONClusterInput::Instance());
1525 clusterInput.Fitter()->SetFCN(fcnS1);
1526 clusterInput.Fitter()->mninit(2,10,7);
1527 Double_t arglist[20];
1530 // Set starting values
1531 static Double_t vstart[2];
1536 // lower and upper limits
1537 static Double_t lower[2], upper[2];
1539 fSeg[cath]->GetPadI(c->fX[cath], c->fY[cath], fZPlane, ix, iy);
1540 Int_t isec=fSeg[cath]->Sector(ix, iy);
1541 lower[0]=vstart[0]-fSeg[cath]->Dpx(isec)/2;
1542 lower[1]=vstart[1]-fSeg[cath]->Dpy(isec)/2;
1544 upper[0]=lower[0]+fSeg[cath]->Dpx(isec);
1545 upper[1]=lower[1]+fSeg[cath]->Dpy(isec);
1548 static Double_t step[2]={0.0005, 0.0005};
1550 clusterInput.Fitter()->mnparm(0,"x1",vstart[0],step[0],lower[0],upper[0],ierflag);
1551 clusterInput.Fitter()->mnparm(1,"y1",vstart[1],step[1],lower[1],upper[1],ierflag);
1552 // ready for minimisation
1553 clusterInput.Fitter()->SetPrintLevel(-1+fDebugLevel);
1555 clusterInput.Fitter()->mnexcm("SET NOW", arglist, 0, ierflag);
1556 clusterInput.Fitter()->mnexcm("SET OUT", arglist, 0, ierflag);
1560 clusterInput.Fitter()->mnexcm("SET NOGR", arglist, 0, ierflag);
1561 clusterInput.Fitter()->mnexcm("MIGRAD", arglist, 0, ierflag);
1562 clusterInput.Fitter()->mnexcm("EXIT" , arglist, 0, ierflag);
1563 Double_t fmin, fedm, errdef;
1564 Int_t npari, nparx, istat;
1566 clusterInput.Fitter()->mnstat(fmin, fedm, errdef, npari, nparx, istat);
1570 // Get fitted parameters
1571 Double_t xrec, yrec;
1573 Double_t epxz, b1, b2;
1575 clusterInput.Fitter()->mnpout(0, chname, xrec, epxz, b1, b2, ierflg);
1576 clusterInput.Fitter()->mnpout(1, chname, yrec, epxz, b1, b2, ierflg);
1582 Float_t AliMUONClusterFinderVS::CombiSingleMathiesonFit(AliMUONRawCluster *c)
1584 // Perform combined Mathieson fit on both cathode planes
1586 AliMUONClusterInput& clusterInput = *(AliMUONClusterInput::Instance());
1587 clusterInput.Fitter()->SetFCN(fcnCombiS1);
1588 clusterInput.Fitter()->mninit(2,10,7);
1589 Double_t arglist[20];
1592 static Double_t vstart[2];
1593 vstart[0]=fXInit[0];
1594 vstart[1]=fYInit[0];
1597 // lower and upper limits
1598 static Float_t lower[2], upper[2];
1600 fSeg[0]->GetPadI(fXInit[0], fYInit[0], fZPlane, ix, iy);
1601 isec=fSeg[0]->Sector(ix, iy);
1602 Float_t dpy=fSeg[0]->Dpy(isec);
1603 fSeg[1]->GetPadI(fXInit[0], fYInit[0], fZPlane, ix, iy);
1604 isec=fSeg[1]->Sector(ix, iy);
1605 Float_t dpx=fSeg[1]->Dpx(isec);
1608 Float_t xdum, ydum, zdum;
1610 // Find save upper and lower limits
1614 for (fSeg[1]->FirstPad(fXInit[0], fYInit[0], fZPlane, dpx, 0.);
1615 fSeg[1]->MorePads(); fSeg[1]->NextPad())
1617 ix=fSeg[1]->Ix(); iy=fSeg[1]->Iy();
1618 fSeg[1]->GetPadC(ix,iy, upper[0], ydum, zdum);
1619 if (icount ==0) lower[0]=upper[0];
1623 if (lower[0]>upper[0]) {xdum=lower[0]; lower[0]=upper[0]; upper[0]=xdum;}
1627 printf("\n single y %f %f", fXInit[0], fYInit[0]);
1629 for (fSeg[0]->FirstPad(fXInit[0], fYInit[0], fZPlane, 0., dpy);
1630 fSeg[0]->MorePads(); fSeg[0]->NextPad())
1632 ix=fSeg[0]->Ix(); iy=fSeg[0]->Iy();
1633 fSeg[0]->GetPadC(ix,iy,xdum,upper[1],zdum);
1634 if (icount ==0) lower[1]=upper[1];
1637 printf("\n upper lower %d %f %f", icount, upper[1], lower[1]);
1640 if (lower[1]>upper[1]) {xdum=lower[1]; lower[1]=upper[1]; upper[1]=xdum;}
1643 static Double_t step[2]={0.00001, 0.0001};
1645 clusterInput.Fitter()->mnparm(0,"x1",vstart[0],step[0],lower[0],upper[0],ierflag);
1646 clusterInput.Fitter()->mnparm(1,"y1",vstart[1],step[1],lower[1],upper[1],ierflag);
1647 // ready for minimisation
1648 clusterInput.Fitter()->SetPrintLevel(-1+fDebugLevel);
1650 clusterInput.Fitter()->mnexcm("SET NOW", arglist, 0, ierflag);
1651 clusterInput.Fitter()->mnexcm("SET OUT", arglist, 0, ierflag);
1655 clusterInput.Fitter()->mnexcm("SET NOGR", arglist, 0, ierflag);
1656 clusterInput.Fitter()->mnexcm("MIGRAD", arglist, 0, ierflag);
1657 clusterInput.Fitter()->mnexcm("EXIT" , arglist, 0, ierflag);
1658 Double_t fmin, fedm, errdef;
1659 Int_t npari, nparx, istat;
1661 clusterInput.Fitter()->mnstat(fmin, fedm, errdef, npari, nparx, istat);
1665 // Get fitted parameters
1666 Double_t xrec, yrec;
1668 Double_t epxz, b1, b2;
1670 clusterInput.Fitter()->mnpout(0, chname, xrec, epxz, b1, b2, ierflg);
1671 clusterInput.Fitter()->mnpout(1, chname, yrec, epxz, b1, b2, ierflg);
1677 Bool_t AliMUONClusterFinderVS::DoubleMathiesonFit(AliMUONRawCluster *c, Int_t cath)
1679 // Performs a double Mathieson fit on one cathode
1683 // Initialise global variables for fit
1684 AliMUONClusterInput& clusterInput = *(AliMUONClusterInput::Instance());
1685 clusterInput.Fitter()->SetFCN(fcnS2);
1686 clusterInput.Fitter()->mninit(5,10,7);
1687 Double_t arglist[20];
1690 // Set starting values
1691 static Double_t vstart[5];
1692 vstart[0]=fX[fIndLocal[0][cath]][cath];
1693 vstart[1]=fY[fIndLocal[0][cath]][cath];
1694 vstart[2]=fX[fIndLocal[1][cath]][cath];
1695 vstart[3]=fY[fIndLocal[1][cath]][cath];
1696 vstart[4]=Float_t(fQ[fIndLocal[0][cath]][cath])/
1697 Float_t(fQ[fIndLocal[0][cath]][cath]+fQ[fIndLocal[1][cath]][cath]);
1698 // lower and upper limits
1699 static Float_t lower[5], upper[5];
1700 Int_t isec=fSeg[cath]->Sector(fIx[fIndLocal[0][cath]][cath], fIy[fIndLocal[0][cath]][cath]);
1701 lower[0]=vstart[0]-fSeg[cath]->Dpx(isec);
1702 lower[1]=vstart[1]-fSeg[cath]->Dpy(isec);
1704 upper[0]=lower[0]+2.*fSeg[cath]->Dpx(isec);
1705 upper[1]=lower[1]+2.*fSeg[cath]->Dpy(isec);
1707 isec=fSeg[cath]->Sector(fIx[fIndLocal[1][cath]][cath], fIy[fIndLocal[1][cath]][cath]);
1708 lower[2]=vstart[2]-fSeg[cath]->Dpx(isec)/2;
1709 lower[3]=vstart[3]-fSeg[cath]->Dpy(isec)/2;
1711 upper[2]=lower[2]+fSeg[cath]->Dpx(isec);
1712 upper[3]=lower[3]+fSeg[cath]->Dpy(isec);
1717 static Double_t step[5]={0.0005, 0.0005, 0.0005, 0.0005, 0.0001};
1719 clusterInput.Fitter()->mnparm(0,"x1",vstart[0],step[0],lower[0],upper[0],ierflag);
1720 clusterInput.Fitter()->mnparm(1,"y1",vstart[1],step[1],lower[1],upper[1],ierflag);
1721 clusterInput.Fitter()->mnparm(2,"x2",vstart[2],step[2],lower[2],upper[2],ierflag);
1722 clusterInput.Fitter()->mnparm(3,"y2",vstart[3],step[3],lower[3],upper[3],ierflag);
1723 clusterInput.Fitter()->mnparm(4,"a0",vstart[4],step[4],lower[4],upper[4],ierflag);
1724 // ready for minimisation
1725 clusterInput.Fitter()->SetPrintLevel(-1+fDebugLevel);
1727 clusterInput.Fitter()->mnexcm("SET NOW", arglist, 0, ierflag);
1728 clusterInput.Fitter()->mnexcm("SET OUT", arglist, 0, ierflag);
1732 clusterInput.Fitter()->mnexcm("SET NOGR", arglist, 0, ierflag);
1733 clusterInput.Fitter()->mnexcm("MIGRAD", arglist, 0, ierflag);
1734 clusterInput.Fitter()->mnexcm("EXIT" , arglist, 0, ierflag);
1735 // Get fitted parameters
1736 Double_t xrec[2], yrec[2], qfrac;
1738 Double_t epxz, b1, b2;
1740 clusterInput.Fitter()->mnpout(0, chname, xrec[0], epxz, b1, b2, ierflg);
1741 clusterInput.Fitter()->mnpout(1, chname, yrec[0], epxz, b1, b2, ierflg);
1742 clusterInput.Fitter()->mnpout(2, chname, xrec[1], epxz, b1, b2, ierflg);
1743 clusterInput.Fitter()->mnpout(3, chname, yrec[1], epxz, b1, b2, ierflg);
1744 clusterInput.Fitter()->mnpout(4, chname, qfrac, epxz, b1, b2, ierflg);
1746 Double_t fmin, fedm, errdef;
1747 Int_t npari, nparx, istat;
1749 clusterInput.Fitter()->mnstat(fmin, fedm, errdef, npari, nparx, istat);
1754 Float_t AliMUONClusterFinderVS::CombiDoubleMathiesonFit(AliMUONRawCluster *c)
1757 // Perform combined double Mathieson fit on both cathode planes
1759 AliMUONClusterInput& clusterInput = *(AliMUONClusterInput::Instance());
1760 clusterInput.Fitter()->SetFCN(fcnCombiS2);
1761 clusterInput.Fitter()->mninit(6,10,7);
1762 Double_t arglist[20];
1765 // Set starting values
1766 static Double_t vstart[6];
1767 vstart[0]=fXInit[0];
1768 vstart[1]=fYInit[0];
1769 vstart[2]=fXInit[1];
1770 vstart[3]=fYInit[1];
1771 vstart[4]=fQrInit[0];
1772 vstart[5]=fQrInit[1];
1773 // lower and upper limits
1774 static Float_t lower[6], upper[6];
1778 fSeg[1]->GetPadI(fXInit[0], fYInit[0], fZPlane, ix, iy);
1779 isec=fSeg[1]->Sector(ix, iy);
1780 dpx=fSeg[1]->Dpx(isec);
1782 fSeg[0]->GetPadI(fXInit[0], fYInit[0], fZPlane, ix, iy);
1783 isec=fSeg[0]->Sector(ix, iy);
1784 dpy=fSeg[0]->Dpy(isec);
1788 Float_t xdum, ydum, zdum;
1790 printf("\n Cluster Finder: %f %f %f %f ", fXInit[0], fXInit[1],fYInit[0], fYInit[1] );
1792 // Find save upper and lower limits
1795 for (fSeg[1]->FirstPad(fXInit[0], fYInit[0], fZPlane, dpx, 0.);
1796 fSeg[1]->MorePads(); fSeg[1]->NextPad())
1798 ix=fSeg[1]->Ix(); iy=fSeg[1]->Iy();
1799 fSeg[1]->GetPadC(ix,iy,upper[0],ydum,zdum);
1800 if (icount ==0) lower[0]=upper[0];
1803 if (lower[0]>upper[0]) {xdum=lower[0]; lower[0]=upper[0]; upper[0]=xdum;}
1806 for (fSeg[0]->FirstPad(fXInit[0], fYInit[0], fZPlane, 0., dpy);
1807 fSeg[0]->MorePads(); fSeg[0]->NextPad())
1809 ix=fSeg[0]->Ix(); iy=fSeg[0]->Iy();
1810 fSeg[0]->GetPadC(ix,iy,xdum,upper[1],zdum);
1811 if (icount ==0) lower[1]=upper[1];
1814 if (lower[1]>upper[1]) {xdum=lower[1]; lower[1]=upper[1]; upper[1]=xdum;}
1816 fSeg[1]->GetPadI(fXInit[1], fYInit[1], fZPlane, ix, iy);
1817 isec=fSeg[1]->Sector(ix, iy);
1818 dpx=fSeg[1]->Dpx(isec);
1819 fSeg[0]->GetPadI(fXInit[1], fYInit[1], fZPlane, ix, iy);
1820 isec=fSeg[0]->Sector(ix, iy);
1821 dpy=fSeg[0]->Dpy(isec);
1824 // Find save upper and lower limits
1828 for (fSeg[1]->FirstPad(fXInit[1], fYInit[1], fZPlane, dpx, 0);
1829 fSeg[1]->MorePads(); fSeg[1]->NextPad())
1831 ix=fSeg[1]->Ix(); iy=fSeg[1]->Iy();
1832 fSeg[1]->GetPadC(ix,iy,upper[2],ydum,zdum);
1833 if (icount ==0) lower[2]=upper[2];
1836 if (lower[2]>upper[2]) {xdum=lower[2]; lower[2]=upper[2]; upper[2]=xdum;}
1840 for (fSeg[0]->FirstPad(fXInit[1], fYInit[1], fZPlane, 0, dpy);
1841 fSeg[0]-> MorePads(); fSeg[0]->NextPad())
1843 ix=fSeg[0]->Ix(); iy=fSeg[0]->Iy();
1844 fSeg[0]->GetPadC(ix,iy,xdum,upper[3],zdum);
1845 if (icount ==0) lower[3]=upper[3];
1848 if (lower[3]>upper[3]) {xdum=lower[3]; lower[3]=upper[3]; upper[3]=xdum;}
1856 static Double_t step[6]={0.0005, 0.0005, 0.0005, 0.0005, 0.001, 0.001};
1857 clusterInput.Fitter()->mnparm(0,"x1",vstart[0],step[0],lower[0],upper[0],ierflag);
1858 clusterInput.Fitter()->mnparm(1,"y1",vstart[1],step[1],lower[1],upper[1],ierflag);
1859 clusterInput.Fitter()->mnparm(2,"x2",vstart[2],step[2],lower[2],upper[2],ierflag);
1860 clusterInput.Fitter()->mnparm(3,"y2",vstart[3],step[3],lower[3],upper[3],ierflag);
1861 clusterInput.Fitter()->mnparm(4,"a0",vstart[4],step[4],lower[4],upper[4],ierflag);
1862 clusterInput.Fitter()->mnparm(5,"a1",vstart[5],step[5],lower[5],upper[5],ierflag);
1863 // ready for minimisation
1864 clusterInput.Fitter()->SetPrintLevel(-1+fDebugLevel);
1866 clusterInput.Fitter()->mnexcm("SET NOW", arglist, 0, ierflag);
1867 clusterInput.Fitter()->mnexcm("SET OUT", arglist, 0, ierflag);
1871 clusterInput.Fitter()->mnexcm("SET NOGR", arglist, 0, ierflag);
1872 clusterInput.Fitter()->mnexcm("MIGRAD", arglist, 0, ierflag);
1873 clusterInput.Fitter()->mnexcm("EXIT" , arglist, 0, ierflag);
1874 // Get fitted parameters
1876 Double_t epxz, b1, b2;
1878 clusterInput.Fitter()->mnpout(0, chname, fXFit[0], epxz, b1, b2, ierflg);
1879 clusterInput.Fitter()->mnpout(1, chname, fYFit[0], epxz, b1, b2, ierflg);
1880 clusterInput.Fitter()->mnpout(2, chname, fXFit[1], epxz, b1, b2, ierflg);
1881 clusterInput.Fitter()->mnpout(3, chname, fYFit[1], epxz, b1, b2, ierflg);
1882 clusterInput.Fitter()->mnpout(4, chname, fQrFit[0], epxz, b1, b2, ierflg);
1883 clusterInput.Fitter()->mnpout(5, chname, fQrFit[1], epxz, b1, b2, ierflg);
1885 Double_t fmin, fedm, errdef;
1886 Int_t npari, nparx, istat;
1888 clusterInput.Fitter()->mnstat(fmin, fedm, errdef, npari, nparx, istat);
1896 void AliMUONClusterFinderVS::Split(AliMUONRawCluster* c)
1899 // One cluster for each maximum
1902 AliMUONClusterInput& clusterInput = *(AliMUONClusterInput::Instance());
1903 for (j=0; j<2; j++) {
1904 AliMUONRawCluster cnew;
1905 cnew.fGhost=c->fGhost;
1906 for (cath=0; cath<2; cath++) {
1907 cnew.fChi2[cath]=fChi2[0];
1908 // ?? why not cnew.fChi2[cath]=fChi2[cath];
1911 cnew.fNcluster[0]=-1;
1912 cnew.fNcluster[1]=fNRawClusters;
1914 cnew.fNcluster[0]=fNPeaks;
1915 cnew.fNcluster[1]=0;
1917 cnew.fMultiplicity[cath]=0;
1918 cnew.fX[cath]=Float_t(fXFit[j]);
1919 cnew.fY[cath]=Float_t(fYFit[j]);
1920 cnew.fZ[cath]=fZPlane;
1922 cnew.fQ[cath]=Int_t(clusterInput.TotalCharge(cath)*fQrFit[cath]);
1924 cnew.fQ[cath]=Int_t(clusterInput.TotalCharge(cath)*(1-fQrFit[cath]));
1926 fSeg[cath]->SetHit(fXFit[j],fYFit[j],fZPlane);
1927 for (i=0; i<fMul[cath]; i++) {
1928 cnew.fIndexMap[cnew.fMultiplicity[cath]][cath]=
1929 c->fIndexMap[i][cath];
1930 fSeg[cath]->SetPad(fIx[i][cath], fIy[i][cath]);
1931 Float_t q1=fInput->Response()->IntXY(fSeg[cath]);
1932 cnew.fContMap[i][cath]
1933 =(q1*Float_t(cnew.fQ[cath]))/Float_t(fQ[i][cath]);
1934 cnew.fMultiplicity[cath]++;
1936 FillCluster(&cnew,0,cath);
1939 cnew.fClusterType=cnew.PhysicsContribution();
1940 if (cnew.fQ[0]>0 && cnew.fQ[1]>0) AddRawCluster(cnew);
1947 // Minimisation functions
1949 void fcnS1(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag)
1951 AliMUONClusterInput& clusterInput = *(AliMUONClusterInput::Instance());
1958 for (i=0; i<clusterInput.Nmul(0); i++) {
1959 Float_t q0=clusterInput.Charge(i,0);
1960 Float_t q1=clusterInput.DiscrChargeS1(i,par);
1969 void fcnCombiS1(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag)
1971 AliMUONClusterInput& clusterInput = *(AliMUONClusterInput::Instance());
1978 for (cath=0; cath<2; cath++) {
1979 for (i=0; i<clusterInput.Nmul(cath); i++) {
1980 Float_t q0=clusterInput.Charge(i,cath);
1981 Float_t q1=clusterInput.DiscrChargeCombiS1(i,par,cath);
1992 void fcnS2(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag)
1994 AliMUONClusterInput& clusterInput = *(AliMUONClusterInput::Instance());
2001 for (i=0; i<clusterInput.Nmul(0); i++) {
2003 Float_t q0=clusterInput.Charge(i,0);
2004 Float_t q1=clusterInput.DiscrChargeS2(i,par);
2014 void fcnCombiS2(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag)
2016 AliMUONClusterInput& clusterInput = *(AliMUONClusterInput::Instance());
2022 for (cath=0; cath<2; cath++) {
2023 for (i=0; i<clusterInput.Nmul(cath); i++) {
2024 Float_t q0=clusterInput.Charge(i,cath);
2025 Float_t q1=clusterInput.DiscrChargeCombiS2(i,par,cath);
2035 void AliMUONClusterFinderVS::AddRawCluster(const AliMUONRawCluster c)
2038 // Add a raw cluster copy to the list
2040 AliMUON *pMUON=(AliMUON*)gAlice->GetModule("MUON");
2041 pMUON->AddRawCluster(fInput->Chamber(),c);
2044 fprintf(stderr,"\nfNRawClusters %d\n",fNRawClusters);
2047 Bool_t AliMUONClusterFinderVS::TestTrack(Int_t t) {
2048 // Test if track was user selected
2049 if (fTrack[0]==-1 || fTrack[1]==-1) {
2051 } else if (t==fTrack[0] || t==fTrack[1]) {
2058 AliMUONClusterFinderVS& AliMUONClusterFinderVS
2059 ::operator = (const AliMUONClusterFinderVS& rhs)
2061 // Dummy assignment operator