10#include <mdst/calibration/BeamParametersFitter.h>
13#include <framework/database/Database.h>
14#include <framework/database/DBImportObjPtr.h>
15#include <framework/database/DBStore.h>
16#include <framework/gearbox/Const.h>
17#include <framework/logging/Logger.h>
22#include <Math/Vector3D.h>
23#include <Math/Vector4D.h>
24#include <Math/VectorUtil.h>
25#include <Math/RotationY.h>
30static double s_InvariantMass;
33static double s_InvariantMassError;
36static TVector3 s_BoostVector;
39static TMatrixDSym s_BoostVectorInverseCovariance(3);
42static TVector3 s_DirectionHER;
45static TVector3 s_DirectionLER;
48static double s_AngleError;
53static ROOT::Math::PxPyPzEVector getMomentum(
double energy,
double thetaX,
double thetaY,
56 const double pz = std::sqrt(energy * energy -
58 const double sx = sin(thetaX);
59 const double cx = cos(thetaX);
60 const double sy = sin(thetaY);
61 const double cy = cos(thetaY);
62 const double px = sy * cx * pz;
63 const double py = -sx * pz;
64 ROOT::Math::PxPyPzEVector result(px, py, cx * cy * pz, energy);
66 ROOT::Math::RotationY rotationY(M_PI);
67 result = rotationY(result);
72static void fcn(
int& npar,
double* grad,
double& fval,
double* par,
int iflag)
77 ROOT::Math::PxPyPzEVector pHER, pLER;
78 pHER = getMomentum(par[0], par[1], par[2],
false);
79 pLER = getMomentum(par[3], par[4], par[5],
true);
80 ROOT::Math::PxPyPzEVector pBeam = pHER + pLER;
81 ROOT::Math::XYZVector beamBoost = pBeam.BoostToCM();
82 TVectorD boostDifference(3);
83 boostDifference[0] = beamBoost.X() - s_BoostVector.X();
84 boostDifference[1] = beamBoost.Y() - s_BoostVector.Y();
85 boostDifference[2] = beamBoost.Z() - s_BoostVector.Z();
86 double boostChi2 = s_BoostVectorInverseCovariance.Similarity(boostDifference);
87 double invariantMass = pBeam.M();
88 double massChi2 = pow((invariantMass - s_InvariantMass) /
89 s_InvariantMassError, 2);
90 double angleHER = ROOT::Math::VectorUtil::Angle(pHER.Vect(), s_DirectionHER);
91 double angleLER = ROOT::Math::VectorUtil::Angle(pLER.Vect(), s_DirectionLER);
92 double angleChi2 = pow(angleHER / s_AngleError, 2) +
93 pow(angleLER / s_AngleError, 2);
94 fval = boostChi2 + massChi2 + angleChi2;
195 double herMomentum, herThetaX, herThetaY;
196 double lerMomentum, lerThetaX, lerThetaY;
199 if (s_BoostVectorInverseCovariance.Determinant() == 0) {
200 B2WARNING(
"Determinant of boost covariance matrix is 0, "
201 "using generic inverse covariance matrix for fit.");
203 s_BoostVectorInverseCovariance[0][1] = 0;
204 s_BoostVectorInverseCovariance[0][2] = 0;
205 s_BoostVectorInverseCovariance[1][0] = 0;
207 s_BoostVectorInverseCovariance[1][2] = 0;
208 s_BoostVectorInverseCovariance[2][0] = 0;
209 s_BoostVectorInverseCovariance[2][1] = 0;
212 s_BoostVectorInverseCovariance.Invert();
216 if (s_InvariantMassError == 0) {
217 B2WARNING(
"Invariant-mass errror is 0, using generic error for fit.");
220 s_DirectionHER.SetX(0);
221 s_DirectionHER.SetY(0);
222 s_DirectionHER.SetZ(1);
224 s_DirectionLER.SetX(0);
225 s_DirectionLER.SetY(0);
226 s_DirectionLER.SetZ(1);
231 minuit.SetPrintLevel(-1);
233 minuit.mnparm(0,
"PHER_E", 7, 0.01, 0, 0, minuitResult);
234 minuit.mnparm(1,
"PHER_TX", 0, 0.01, 0, 0, minuitResult);
235 minuit.mnparm(2,
"PHER_TY", 0, 0.01, 0, 0, minuitResult);
236 minuit.mnparm(3,
"PLER_E", 4, 0.01, 0, 0, minuitResult);
237 minuit.mnparm(4,
"PLER_TX", 0, 0.01, 0, 0, minuitResult);
238 minuit.mnparm(5,
"PLER_TY", 0, 0.01, 0, 0, minuitResult);
239 minuit.mncomd(
"FIX 2 3 5 6", minuitResult);
240 minuit.mncomd(
"MIGRAD 10000", minuitResult);
241 minuit.mncomd(
"RELEASE 2 3 5 6", minuitResult);
242 minuit.mncomd(
"MIGRAD 10000", minuitResult);
244 minuit.GetParameter(0, herMomentum, error);
245 minuit.GetParameter(1, herThetaX, error);
246 minuit.GetParameter(2, herThetaY, error);
247 minuit.GetParameter(3, lerMomentum, error);
248 minuit.GetParameter(4, lerThetaX, error);
249 minuit.GetParameter(5, lerThetaY, error);
251 ROOT::Math::PxPyPzEVector pHER = getMomentum(herMomentum, herThetaX, herThetaY,
false);
252 ROOT::Math::PxPyPzEVector pLER = getMomentum(lerMomentum, lerThetaX, lerThetaY,
true);
253 ROOT::Math::PxPyPzEVector pBeam = pHER + pLER;
254 double fittedInvariantMass = pBeam.M();
255 B2RESULT(
"Initial invariant mass: " << s_InvariantMass <<
256 "; fitted invariant mass: " << fittedInvariantMass);
257 double cosThetaX = cos(herThetaX);
258 double sinThetaX = sin(herThetaX);
259 double cosThetaY = cos(herThetaY);
260 double sinThetaY = sin(herThetaY);
262 (pBeam.E() - pHER.E() / pHER.P() *
263 (pBeam.Px() * cosThetaX * sinThetaY - pBeam.Py() * sinThetaX +
264 pBeam.Pz() * cosThetaX * cosThetaY)) / fittedInvariantMass;
265 cosThetaX = cos(lerThetaX);
266 sinThetaX = sin(lerThetaX);
267 cosThetaY = cos(lerThetaY + M_PI);
268 sinThetaY = sin(lerThetaY + M_PI);
270 (pBeam.E() - pLER.E() / pLER.P() *
271 (pBeam.Px() * cosThetaX * sinThetaY - pBeam.Py() * sinThetaX +
272 pBeam.Pz() * cosThetaX * cosThetaY)) / fittedInvariantMass;
274 double k =
sqrt(sigmaInvariantMass * sigmaInvariantMass /
275 (pow(herPartial * pHER.E(), 2) +
276 pow(lerPartial * pLER.E(), 2)));
277 double herSpread = k * pHER.E();
278 double lerSpread = k * pLER.E();
279 B2INFO(
"Invariant mass spread: " << sigmaInvariantMass);
280 B2RESULT(
"HER energy spread: " << herSpread <<
281 "; LER energy spread: " << lerSpread);
285 TMatrixDSym covariance(3);
286 for (
int i = 0; i < 3; ++i) {
287 for (
int j = 0; j < 3; ++j)
288 covariance[i][j] = 0;
290 covariance[0][0] = herSpread * herSpread;
292 covariance[0][0] = lerSpread * lerSpread;
297 double covarianceXX,
double covarianceYY)
301 TMatrixDSym beamSize =
m_BeamSpot->getSizeCovMatrix();
302 double xScale, yScale;
303 if (covarianceXX < 0)
306 xScale =
sqrt(covarianceXX / beamSize[0][0]);
307 if (covarianceYY < 0)
310 yScale =
sqrt(covarianceYY / beamSize[1][1]);
311 for (
int i = 0; i < 3; ++i) {
312 beamSize[0][i] *= xScale;
313 beamSize[i][0] *= xScale;
314 beamSize[1][i] *= yScale;
315 beamSize[i][1] *= yScale;
void fit()
Perform the fit.
double m_AngleLER
LER angle.
BeamParameters m_BeamParameters
Beam parameters.
void setupDatabase()
Setup database.
double m_InvariantMassError
Invariant-mass error (use only if error is 0).
DBObjPtr< CollisionBoostVector > m_CollisionBoostVector
Collision boost vector.
double m_AngleHER
HER angle.
bool m_Verbose
Whether to be verbose (print Minuit output).
void importBeamParameters()
Import beam parameters.
DBObjPtr< CollisionInvariantMass > m_CollisionInvariantMass
Collision invariant mass.
IntervalOfValidity m_IntervalOfValidity
Interval of validity.
DBObjPtr< BeamSpot > m_BeamSpot
Beam spot.
double m_BoostError
Boost error (use only if inverse error matrix is not available).
double m_AngleError
Angle error.
void fillVertexData(double covarianceXX, double covarianceYY)
Fill beam spot (vertex) data.
void setHER(double energy, double angleX, double angleY, const std::vector< double > &cov)
Set the HER FourVector and error matrix from beam energy, angle and covariance entries.
void setLER(double energy, double angleX, double angleY, const std::vector< double > &cov)
Set the LER FourVector and error matrix from beam energy, angle and covariance entries.
void setCovLER(const TMatrixDSym &cov)
Set the covariance matrix for LER (E, theta_x, theta_y) where E is the energy, theta_x is the horizon...
void setCovHER(const TMatrixDSym &cov)
Set the covariance matrix for HER (E, theta_x, theta_y) where E is the energy, theta_x is the horizon...
void setVertex(const ROOT::Math::XYZVector &vertex, const std::vector< double > &cov)
Set the vertex position and error matrix.
void setCovVertex(const TMatrixDSym &cov)
Set the covariance matrix of the vertex position.
static const double electronMass
electron mass
bool import(const IntervalOfValidity &iov)
Import the object to database.
Class for importing a single object to the database.
void construct(Args &&... params)
Construct an object of type T in this DBImportObjPtr using the provided constructor arguments.
Singleton class to cache database objects.
static DataStore & Instance()
Instance of singleton Store.
void setInitializeActive(bool active)
Setter for m_initializeActive.
int getRunLow() const
Getter for lowest run number.
int getExperimentLow() const
Getter for lowest experiment number.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
Type-safe access to single objects in the data store.
bool isValid() const
Check whether the object was created.
bool construct(Args &&... params)
Construct an object of type T in this StoreObjPtr, using the provided constructor arguments.
static DBStore & Instance()
Instance of a singleton DBStore.
void updateEvent()
Updates all intra-run dependent objects.
void update()
Updates all objects that are outside their interval of validity.
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.