12 #include <mdst/calibration/BeamParametersFitter.h>
15 #include <framework/database/Database.h>
16 #include <framework/database/DBImportObjPtr.h>
17 #include <framework/database/DBStore.h>
18 #include <framework/gearbox/Const.h>
19 #include <framework/logging/Logger.h>
22 #include <TLorentzVector.h>
29 static bool s_UseMomentum;
32 static double s_InvariantMass;
35 static double s_InvariantMassError;
38 static TVector3 s_BoostVector;
41 static TMatrixDSym s_BoostVectorInverseCovariance(3);
44 static TVector3 s_DirectionHER;
47 static TVector3 s_DirectionLER;
50 static double s_AngleError;
55 static TLorentzVector getMomentum(
double energy,
double thetaX,
double thetaY,
58 const double pz = std::sqrt(energy * energy -
60 const double sx = sin(thetaX);
61 const double cx = cos(thetaX);
62 const double sy = sin(thetaY);
63 const double cy = cos(thetaY);
64 const double px = sy * cx * pz;
65 const double py = -sx * pz;
66 TLorentzVector result(px, py, cx * cy * pz, energy);
73 static void fcn(
int& npar,
double* grad,
double& fval,
double* par,
int iflag)
78 TLorentzVector pHER, pLER;
83 pHER = getMomentum(par[0], par[1], par[2],
false);
84 pLER = getMomentum(par[3], par[4], par[5],
true);
86 TLorentzVector pBeam = pHER + pLER;
87 TVector3 beamBoost = pBeam.BoostVector();
88 TVectorD boostDifference(3);
89 boostDifference[0] = beamBoost.X() - s_BoostVector.X();
90 boostDifference[1] = beamBoost.Y() - s_BoostVector.Y();
91 boostDifference[2] = beamBoost.Z() - s_BoostVector.Z();
92 double boostChi2 = s_BoostVectorInverseCovariance.Similarity(boostDifference);
93 double invariantMass = pBeam.M();
94 double massChi2 = pow((invariantMass - s_InvariantMass) /
95 s_InvariantMassError, 2);
96 double angleHER = pHER.Vect().Angle(s_DirectionHER);
97 double angleLER = pLER.Vect().Angle(s_DirectionLER);
98 double angleChi2 = pow(angleHER / s_AngleError, 2) +
99 pow(angleLER / s_AngleError, 2);
100 fval = boostChi2 + massChi2 + angleChi2;
108 eventMetaData.registerInDataStore();
201 double herMomentum, herThetaX, herThetaY;
202 double lerMomentum, lerThetaX, lerThetaY;
205 if (s_BoostVectorInverseCovariance.Determinant() == 0) {
206 B2WARNING(
"Determinant of boost covariance matrix is 0, "
207 "using generic inverse covariance matrix for fit.");
209 s_BoostVectorInverseCovariance[0][1] = 0;
210 s_BoostVectorInverseCovariance[0][2] = 0;
211 s_BoostVectorInverseCovariance[1][0] = 0;
213 s_BoostVectorInverseCovariance[1][2] = 0;
214 s_BoostVectorInverseCovariance[2][0] = 0;
215 s_BoostVectorInverseCovariance[2][1] = 0;
218 s_BoostVectorInverseCovariance.Invert();
222 if (s_InvariantMassError == 0) {
223 B2WARNING(
"Invariant-mass errror is 0, using generic error for fit.");
226 s_DirectionHER.SetX(0);
227 s_DirectionHER.SetY(0);
228 s_DirectionHER.SetZ(1);
230 s_DirectionLER.SetX(0);
231 s_DirectionLER.SetY(0);
232 s_DirectionLER.SetZ(1);
238 minuit.SetPrintLevel(-1);
241 minuit.mnparm(0,
"PHER_X", 0, 0.01, 0, 0, minuitResult);
242 minuit.mnparm(1,
"PHER_Y", 0, 0.01, 0, 0, minuitResult);
243 minuit.mnparm(2,
"PHER_Z", 7, 0.01, 0, 0, minuitResult);
244 minuit.mnparm(3,
"PLER_X", 0, 0.01, 0, 0, minuitResult);
245 minuit.mnparm(4,
"PLER_Y", 0, 0.01, 0, 0, minuitResult);
246 minuit.mnparm(5,
"PLER_Z", -4, 0.01, 0, 0, minuitResult);
247 minuit.mncomd(
"FIX 1 2 4 5", minuitResult);
248 minuit.mncomd(
"MIGRAD 10000", minuitResult);
249 minuit.mncomd(
"RELEASE 1 2 4 5", minuitResult);
250 minuit.mncomd(
"MIGRAD 10000", minuitResult);
252 minuit.mnparm(0,
"PHER_E", 7, 0.01, 0, 0, minuitResult);
253 minuit.mnparm(1,
"PHER_TX", 0, 0.01, 0, 0, minuitResult);
254 minuit.mnparm(2,
"PHER_TY", 0, 0.01, 0, 0, minuitResult);
255 minuit.mnparm(3,
"PLER_E", 4, 0.01, 0, 0, minuitResult);
256 minuit.mnparm(4,
"PLER_TX", 0, 0.01, 0, 0, minuitResult);
257 minuit.mnparm(5,
"PLER_TY", 0, 0.01, 0, 0, minuitResult);
258 minuit.mncomd(
"FIX 2 3 5 6", minuitResult);
259 minuit.mncomd(
"MIGRAD 10000", minuitResult);
260 minuit.mncomd(
"RELEASE 2 3 5 6", minuitResult);
261 minuit.mncomd(
"MIGRAD 10000", minuitResult);
263 minuit.GetParameter(0, herMomentum, error);
264 minuit.GetParameter(1, herThetaX, error);
265 minuit.GetParameter(2, herThetaY, error);
266 minuit.GetParameter(3, lerMomentum, error);
267 minuit.GetParameter(4, lerThetaX, error);
268 minuit.GetParameter(5, lerThetaY, error);
271 TLorentzVector pHER = getMomentum(herMomentum, herThetaX, herThetaY,
false);
272 TLorentzVector pLER = getMomentum(lerMomentum, lerThetaX, lerThetaY,
true);
273 TLorentzVector pBeam = pHER + pLER;
274 double fittedInvariantMass = pBeam.M();
275 B2RESULT(
"Initial invariant mass: " << s_InvariantMass <<
276 "; fitted invariant mass: " << fittedInvariantMass);
277 double cosThetaX = cos(herThetaX);
278 double sinThetaX = sin(herThetaX);
279 double cosThetaY = cos(herThetaY);
280 double sinThetaY = sin(herThetaY);
282 (pBeam.E() - pHER.E() / pHER.Vect().Mag() *
283 (pBeam.Px() * cosThetaX * sinThetaY - pBeam.Py() * sinThetaX +
284 pBeam.Pz() * cosThetaX * cosThetaY)) / fittedInvariantMass;
285 cosThetaX = cos(lerThetaX);
286 sinThetaX = sin(lerThetaX);
287 cosThetaY = cos(lerThetaY + M_PI);
288 sinThetaY = sin(lerThetaY + M_PI);
290 (pBeam.E() - pLER.E() / pLER.Vect().Mag() *
291 (pBeam.Px() * cosThetaX * sinThetaY - pBeam.Py() * sinThetaX +
292 pBeam.Pz() * cosThetaX * cosThetaY)) / fittedInvariantMass;
294 double k = sqrt(sigmaInvariantMass * sigmaInvariantMass /
295 (pow(herPartial * pHER.E(), 2) +
296 pow(lerPartial * pLER.E(), 2)));
297 double herSpread = k * pHER.E();
298 double lerSpread = k * pLER.E();
299 B2INFO(
"Invariant mass spread: " << sigmaInvariantMass);
300 B2RESULT(
"HER energy spread: " << herSpread <<
301 "; LER energy spread: " << lerSpread);
305 TMatrixDSym covariance(3);
306 for (
int i = 0; i < 3; ++i) {
307 for (
int j = 0; j < 3; ++j)
308 covariance[i][j] = 0;
310 covariance[0][0] = herSpread * herSpread;
312 covariance[0][0] = lerSpread * lerSpread;
317 double covarianceXX,
double covarianceYY)
321 TMatrixDSym beamSize =
m_BeamSpot->getSizeCovMatrix();
322 double xScale, yScale;
323 if (covarianceXX < 0)
326 xScale = sqrt(covarianceXX / beamSize[0][0]);
327 if (covarianceYY < 0)
330 yScale = sqrt(covarianceYY / beamSize[1][1]);
331 for (
int i = 0; i < 3; ++i) {
332 beamSize[0][i] *= xScale;
333 beamSize[i][0] *= xScale;
334 beamSize[1][i] *= yScale;
335 beamSize[i][1] *= yScale;