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 **************************************************************************/
18 #include "AliMUONClusterFinderSimpleFit.h"
21 #include "AliMpDEManager.h"
22 #include "AliMUONCluster.h"
23 #include "AliMUONConstants.h"
24 #include "AliMUONVDigit.h"
25 #include "AliMUONMathieson.h"
26 #include "AliMUONPad.h"
27 #include "AliMpArea.h"
28 #include "TClonesArray.h"
29 #include "TObjArray.h"
31 #include "TVirtualFitter.h"
33 #include "AliMUONVDigitStore.h"
34 #include <Riostream.h>
36 //-----------------------------------------------------------------------------
37 /// \class AliMUONClusterFinderSimpleFit
39 /// Basic cluster finder
41 /// We simply use AliMUONPreClusterFinder to get basic cluster,
42 /// and then we try to fit the charge repartition using a Mathieson
43 /// distribution, varying the position.
45 /// FIXME: this one is still at the developping stage...
47 /// \author Laurent Aphecetche
48 //-----------------------------------------------------------------------------
51 ClassImp(AliMUONClusterFinderSimpleFit)
56 //___________________________________________________________________________
58 FitFunction(Int_t& /*notused*/, Double_t* /*notused*/,
59 Double_t& f, Double_t* par,
62 /// Chi2 Function to minimize: Mathieson charge distribution in 2 dimensions
64 TObjArray* userObjects = static_cast<TObjArray*>(TVirtualFitter::GetFitter()->GetObjectFit());
66 AliMUONCluster* cluster = static_cast<AliMUONCluster*>(userObjects->At(0));
67 AliMUONMathieson* mathieson = static_cast<AliMUONMathieson*>(userObjects->At(1));
70 Float_t qTot = cluster->Charge();
71 // Float_t chargeCorrel[] = { cluster->Charge(0)/qTot, cluster->Charge(1)/qTot };
72 // Float_t qRatio[] = { 1.0/par[2], par[2] };
74 for ( Int_t i = 0 ; i < cluster->Multiplicity(); ++i )
76 AliMUONPad* pad = cluster->Pad(i);
77 // skip pads w/ saturation or other problem(s)
78 if ( pad->Status() ) continue;
79 TVector2 lowerLeft = TVector2(par[0],par[1]) - pad->Position() - pad->Dimensions();
80 TVector2 upperRight(lowerLeft + pad->Dimensions()*2.0);
81 Float_t estimatedCharge = mathieson->IntXY(lowerLeft.X(),lowerLeft.Y(),
82 upperRight.X(),upperRight.Y());
83 // estimatedCharge *= 2/(1+qRatio[pad->Cathode()]);
84 Float_t actualCharge = pad->Charge()/qTot;
86 Float_t delta = (estimatedCharge - actualCharge);
93 //_____________________________________________________________________________
94 AliMUONClusterFinderSimpleFit::AliMUONClusterFinderSimpleFit(AliMUONVClusterFinder* clusterFinder)
95 : AliMUONVClusterFinder(),
96 fClusterFinder(clusterFinder),
102 //_____________________________________________________________________________
103 AliMUONClusterFinderSimpleFit::~AliMUONClusterFinderSimpleFit()
106 delete fClusterFinder;
110 //_____________________________________________________________________________
112 AliMUONClusterFinderSimpleFit::Prepare(Int_t detElemId,
113 TClonesArray* pads[2],
114 const AliMpArea& area)
116 /// Prepare for clustering
118 // FIXME: should we get the Mathieson from elsewhere ?
120 // Find out the DetElemId
121 AliMq::Station12Type stationType = AliMpDEManager::GetStation12Type(detElemId);
123 Float_t kx3 = AliMUONConstants::SqrtKx3();
124 Float_t ky3 = AliMUONConstants::SqrtKy3();
125 Float_t pitch = AliMUONConstants::Pitch();
127 if ( stationType == AliMq::kStation1 )
129 kx3 = AliMUONConstants::SqrtKx3St1();
130 ky3 = AliMUONConstants::SqrtKy3St1();
131 pitch = AliMUONConstants::PitchSt1();
135 fMathieson = new AliMUONMathieson;
137 fMathieson->SetPitch(pitch);
138 fMathieson->SetSqrtKx3AndDeriveKx2Kx4(kx3);
139 fMathieson->SetSqrtKy3AndDeriveKy2Ky4(ky3);
141 return fClusterFinder->Prepare(detElemId,pads,area);
144 //_____________________________________________________________________________
146 AliMUONClusterFinderSimpleFit::NextCluster()
148 /// Returns next cluster
150 if ( !fClusterFinder ) return 0x0;
151 AliMUONCluster* cluster = fClusterFinder->NextCluster();
154 ComputePosition(*cluster);
156 if ( cluster->Charge() < 7 )
159 return NextCluster();
165 //_____________________________________________________________________________
167 AliMUONClusterFinderSimpleFit::ComputePosition(AliMUONCluster& cluster)
169 /// Compute the position of the given cluster, by fitting a Mathieson
170 /// charge distribution to it
172 TVirtualFitter* fitter = TVirtualFitter::Fitter(0,2);
173 fitter->SetFCN(FitFunction);
175 if ( cluster.Multiplicity() < 3 ) return;
177 // We try a Mathieson fit, starting
178 // with the center-of-gravity estimate as a first guess
179 // for the cluster center.
181 Double_t xCOG = cluster.Position().X();
182 Double_t yCOG = cluster.Position().Y();
184 Float_t stepX = 0.01; // cm
185 Float_t stepY = 0.01; // cm
187 Double_t arg(-1); // disable printout
189 fitter->ExecuteCommand("SET PRINT",&arg,1);
191 fitter->SetParameter(0,"cluster X position",xCOG,stepX,0,0);
192 fitter->SetParameter(1,"cluster Y position",yCOG,stepY,0,0);
194 TObjArray userObjects;
196 userObjects.Add(&cluster);
197 userObjects.Add(fMathieson);
199 fitter->SetObjectFit(&userObjects);
201 Int_t val = fitter->ExecuteCommand("MIGRAD",0,0);
202 AliDebug(1,Form("ExecuteCommand returned value=%d",val));
205 // fit failed. Using COG results, with big errors
206 AliWarning("Fit failed. Using COG results for cluster=");
207 StdoutToAliWarning(cluster.Print());
208 cluster.SetPosition(TVector2(xCOG,yCOG),TVector2(TMath::Abs(xCOG),TMath::Abs(yCOG)));
209 cluster.SetChi2(1E3);
212 Double_t results[] = { fitter->GetParameter(0),
213 fitter->GetParameter(1) };
215 Double_t errors[] = { fitter->GetParError(0),
216 fitter->GetParError(1) };
218 cluster.SetPosition(TVector2(results[0],results[1]),
219 TVector2(errors[0],errors[1]));
221 Double_t amin, edm, errdef;
224 fitter->GetStats(amin, edm, errdef, nvpar, nparx);
226 Double_t chi2 = amin;
228 AliDebug(1,Form("Cluster fitted to (x,y)=(%e,%e) (xerr,yerr)=(%e,%e) \n chi2=%e ndf=%d",
229 results[0],results[1],
230 errors[0],errors[1],chi2,fitter->GetNumberFreeParameters()));
231 cluster.SetChi2(chi2);