20 #include "StRoot/St_base/StMessMgr.h"
21 #include "StEvent/StFmsHit.h"
27 const Int_t kNFitParameters = 10;
28 TF2 showerShapeFitFunction(
"showerShapeFitFunction",
30 -25.0, 25.0, -25.0, 25.0, kNFitParameters);
33 namespace FMSCluster {
40 : mMinuit(3 * kMaxNPhotons + 1) {
43 0.0, 0.1, 0.1, 0.2, 0.1, 0.1, 0.2, 0.1, 0.1, 0.2, 0.1,
44 0.1, 0.2, 0.1, 0.1, 0.2, 0.1, 0.1, 0.2, 0.1, 0.1, 0.2
49 std::vector<Float_t> towerWidth = geometry->
towerWidths(detectorId);
53 Double_t para[kNFitParameters];
64 showerShapeFitFunction.SetParameters(para);
72 return &showerShapeFitFunction;
76 const Double_t* low,
const Double_t* up,
84 LOG_ERROR <<
"no tower data available! return -1!" << endm;
88 Int_t nPh = (Int_t)para[0];
90 LOG_ERROR <<
"nPh = " << nPh <<
"! Number of photons must be between 1 and "
91 << kMaxNPhotons <<
"! Set it to be 1!" << endm;
98 Double_t nPhotons(nPh);
99 mMinuit.mnparm(0,
"nph", nPhotons, 0, 0.5, 4.5, ierflg);
101 for (Int_t i = 0; i < nPh; i++) {
103 mMinuit.mnparm(j, Form(
"x%d", i + 1),
104 para[j], step[j], low[j], up[j], ierflg);
106 mMinuit.mnparm(j, Form(
"y%d", i + 1),
107 para[j], step[j], low[j], up[j], ierflg);
109 mMinuit.mnparm(j, Form(
"E%d", i + 1),
110 para[j], step[j], low[j], up[j], ierflg);
112 Double_t arglist[10];
116 mMinuit.mnexcm(
"MIGRAD", arglist, 2, ierflg);
118 if (0 ==
mMinuit.GetStatus() && photons) {
122 mMinuit.GetParameter(0, param[0], error[0]);
124 nPh = (Int_t)param[0];
125 const Int_t nPar = 3 * nPh + 1;
126 for (Int_t i(1); i < nPar; ++i) {
127 mMinuit.GetParameter(i, param[i], error[i]);
129 for (Int_t par(1); par < nPar; par += 3) {
132 error[par], error[par + 1], error[par + 2]));
136 mMinuit.Eval(photons->size(), NULL, chiSq, param, iflag);
173 const Double_t* step,
183 LOG_ERROR <<
"no tower data available! return -1!" << endm;
187 Int_t nPh = (Int_t)para[0];
189 LOG_ERROR <<
"number of photons must be 2 for special 2-photon cluster "
190 <<
"fitter \"Int_t StFmsClusterFitter::fit2PhotonCluster(...)\"!"
191 <<
" Set it to be 2!" << endm;
198 Double_t nPhotons(nPh);
199 mMinuit.mnparm(0,
"nph", nPhotons, 0, 1.5, 2.5, ierflg);
200 mMinuit.mnparm(1,
"xPi" , para[1], step[1], low[1], up[1], ierflg);
201 mMinuit.mnparm(2,
"yPi" , para[2], step[2], low[2], up[2], ierflg);
202 mMinuit.mnparm(3,
"d_gg" , para[3], step[3], low[3], up[3], ierflg);
203 mMinuit.mnparm(4,
"theta", para[4], step[4], low[4], up[4], ierflg);
204 mMinuit.mnparm(5,
"z_gg" , para[5], step[5], low[5], up[5], ierflg);
205 mMinuit.mnparm(6,
"E_gg" , para[6], step[6], low[6], up[6], ierflg);
209 Double_t arglist[10];
213 mMinuit.mnexcm(
"MIGRAD", arglist, 2, ierflg);
215 if (0 ==
mMinuit.GetStatus() && photons) {
219 mMinuit.GetParameter(0, param[0], error[0]);
220 Int_t nPar = 3 * (Int_t)param[0] + 1;
221 for (Int_t ipar = 1; ipar < nPar; ipar++) {
222 mMinuit.GetParameter(ipar, param[ipar], error[ipar]);
227 double x = param[1] + cos(param[4]) * param[3] * (1 - param[5]) / 2.0;
228 double xErr = error[1] +
229 (cos(param[4]) * error[3] - error[4] * sin(param[4]) * param[3]) *
230 (1 - param[5]) / 2 - cos(param[4]) * param[3] * error[5] / 2.0;
231 double y = param[2] + sin(param[4]) * param[3] * (1 - param[5]) / 2.0;
232 double yErr = error[2] +
233 (sin(param[4]) * error[3] + error[4] * cos(param[4]) * param[3]) *
234 (1 - param[5]) / 2 - sin(param[4]) * param[3] * error[5] / 2.0;
235 double E = param[6] * (1 + param[5]) / 2.0;
236 double EErr = error[6] * (1 + param[5]) / 2.0 + param[6] * error[5] / 2.0;
239 x = param[1] - cos(param[4]) * param[3] * (1 + param[5]) / 2.0;
241 (-cos(param[4]) * error[3] + error[4] * sin(param[4]) * param[3]) *
242 (1 + param[5]) / 2 - cos(param[4]) * param[3] * error[5] / 2.0;
243 y = param[2] - sin(param[4]) * param[3] * (1 + param[5]) / 2.0;
245 (sin(param[4]) * error[3] - error[4] * cos(param[4]) * param[3]) *
246 (1 + param[5]) / 2 - sin(param[4]) * param[3] * error[5] / 2.0;
247 E = param[6] * (1 - param[5]) / 2.0;
248 EErr = error[6] * (1 - param[5]) / 2.0 - param[6] * error[5] / 2.0;
252 mMinuit.Eval(7, NULL, chiSq, param, iflag);
265 for (Int_t ix = 0; ix < 2; ix++) {
266 for (Int_t iy = 0; iy < 2; iy++) {
267 Double_t signX = pow(-1.0, ix);
268 Double_t signY = pow(-1.0, iy);
272 s[0] = xy[0] - para[7] + signX * para[0] / 2.0;
273 s[1] = xy[1] - para[8] + signY * para[0] / 2.0;
284 Double_t* parameters) {
288 for (Int_t i = 1; i <= 3; i++) {
292 Double_t a = parameters[i];
293 Double_t b = parameters[i + 3];
294 f += a * atan(x * y / (b * sqrt(b * b + x * x + y * y)));
296 return f / TMath::TwoPi();
307 Int_t numbPh = (Int_t)para[0];
310 typedef StFmsTowerCluster::Towers::const_iterator TowerIter;
312 sumCl += (*i)->hit()->energy();
322 const Double_t x = (tower->
column() - 0.5) *
324 const Double_t y = (tower->
row() - 0.5) *
327 const Double_t eMeas = tower->
hit()->energy();
330 for (Int_t iph = 0; iph < numbPh; iph++) {
332 Double_t Eshape = para[j + 3] *
333 showerShapeFitFunction.Eval(x - para[j + 1],
337 const Double_t dev = eMeas - eSS;
338 const Double_t errFactor = 0.03;
339 const Double_t errQ = 0.01;
341 const Double_t err = (errFactor * pow(eMeas / sumCl, 1. - 0.001 * sumCl) *
342 pow(1 - eMeas / sumCl, 1. - 0.007 * sumCl)) * sumCl
344 const Double_t dchi2 = dev * dev / err;
361 Double_t oldParam[7];
363 oldParam[0] = param[0];
364 oldParam[1] = param[1] + cos(param[4]) * dd * (1 - param[5]) / 2.0;
365 oldParam[2] = param[2] + sin(param[4]) * dd * (1 - param[5]) / 2.0;
366 oldParam[3] = param[6] * (1 + param[5]) / 2.0;
367 oldParam[4] = param[1] - cos(param[4]) * dd * (1 + param[5]) / 2.0;
368 oldParam[5] = param[2] - sin(param[4]) * dd * (1 + param[5]) / 2.0;
369 oldParam[6] = param[6] * (1 - param[5]) / 2.0;
static const Int_t kMaxNPhotons
Maximum number that can be fitted.
static Double_t energyDepositionDistribution(Double_t *x, Double_t *par)
Declaration of StFmsGeometry, an FMS database geometry interface.
Double_t fit(const Double_t *par, const Double_t *step, const Double_t *low, const Double_t *up, PhotonList *photons)
static Double_t energyDepositionInTower(Double_t *x, Double_t *par)
TMinuit mMinuit
Minuit fitting interface.
Declaration of StFmsTower, a simple FMS tower wrapper.
Declaration of StFmsClusterFitter, shower-shape fitting routine.
std::list< StFmsTower * > Towers
Shorthand for tower collection.
Double_t mSteps[3 *kMaxNPhotons+1]
Step size in each fit variable.
static Float_t mTowerWidthXY[2]
glass width X, Y in cm
static void minimizationFunction2Photon(Int_t &nparam, Double_t *grad, Double_t &fval, Double_t *param, Int_t iflag)
TF2 * showerShapeFunction()
const StFmsHit * hit() const
Int_t fit2PhotonCluster(const Double_t *para, const Double_t *step, const Double_t *low, const Double_t *up, PhotonList *photons)
std::vector< Float_t > towerWidths(Int_t detectorId) const
std::list< StFmsFittedPhoton > PhotonList
Double_t mTowerWidth
width of one lead glass module
static void minimizationFunctionNPhoton(Int_t &npar, Double_t *grad, Double_t &fval, Double_t *par, Int_t iflag)
static StFmsTowerCluster::Towers * mTowers
List of towers to fit.