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/Vector4D.h>
23 #include <Math/RotationY.h>
28 static double s_InvariantMass;
31 static double s_InvariantMassError;
34 static TVector3 s_BoostVector;
37 static TMatrixDSym s_BoostVectorInverseCovariance(3);
40 static TVector3 s_DirectionHER;
43 static TVector3 s_DirectionLER;
46 static double s_AngleError;
51 static ROOT::Math::PxPyPzEVector getMomentum(
double energy,
double thetaX,
double thetaY,
54 const double pz = std::sqrt(energy * energy -
56 const double sx = sin(thetaX);
57 const double cx = cos(thetaX);
58 const double sy = sin(thetaY);
59 const double cy = cos(thetaY);
60 const double px = sy * cx * pz;
61 const double py = -sx * pz;
62 ROOT::Math::PxPyPzEVector result(px, py, cx * cy * pz, energy);
64 ROOT::Math::RotationY rotationY(M_PI);
65 result = rotationY(result);
70 static void fcn(
int& npar,
double* grad,
double& fval,
double* par,
int iflag)
75 ROOT::Math::PxPyPzEVector pHER, pLER;
76 pHER = getMomentum(par[0], par[1], par[2],
false);
77 pLER = getMomentum(par[3], par[4], par[5],
true);
78 ROOT::Math::PxPyPzEVector pBeam = pHER + pLER;
80 TVectorD boostDifference(3);
81 boostDifference[0] = beamBoost.
X() - s_BoostVector.X();
82 boostDifference[1] = beamBoost.
Y() - s_BoostVector.Y();
83 boostDifference[2] = beamBoost.
Z() - s_BoostVector.Z();
84 double boostChi2 = s_BoostVectorInverseCovariance.Similarity(boostDifference);
85 double invariantMass = pBeam.M();
86 double massChi2 = pow((invariantMass - s_InvariantMass) /
87 s_InvariantMassError, 2);
90 double angleChi2 = pow(angleHER / s_AngleError, 2) +
91 pow(angleLER / s_AngleError, 2);
92 fval = boostChi2 + massChi2 + angleChi2;
193 double herMomentum, herThetaX, herThetaY;
194 double lerMomentum, lerThetaX, lerThetaY;
197 if (s_BoostVectorInverseCovariance.Determinant() == 0) {
198 B2WARNING(
"Determinant of boost covariance matrix is 0, "
199 "using generic inverse covariance matrix for fit.");
201 s_BoostVectorInverseCovariance[0][1] = 0;
202 s_BoostVectorInverseCovariance[0][2] = 0;
203 s_BoostVectorInverseCovariance[1][0] = 0;
205 s_BoostVectorInverseCovariance[1][2] = 0;
206 s_BoostVectorInverseCovariance[2][0] = 0;
207 s_BoostVectorInverseCovariance[2][1] = 0;
210 s_BoostVectorInverseCovariance.Invert();
214 if (s_InvariantMassError == 0) {
215 B2WARNING(
"Invariant-mass errror is 0, using generic error for fit.");
218 s_DirectionHER.SetX(0);
219 s_DirectionHER.SetY(0);
220 s_DirectionHER.SetZ(1);
222 s_DirectionLER.SetX(0);
223 s_DirectionLER.SetY(0);
224 s_DirectionLER.SetZ(1);
229 minuit.SetPrintLevel(-1);
231 minuit.mnparm(0,
"PHER_E", 7, 0.01, 0, 0, minuitResult);
232 minuit.mnparm(1,
"PHER_TX", 0, 0.01, 0, 0, minuitResult);
233 minuit.mnparm(2,
"PHER_TY", 0, 0.01, 0, 0, minuitResult);
234 minuit.mnparm(3,
"PLER_E", 4, 0.01, 0, 0, minuitResult);
235 minuit.mnparm(4,
"PLER_TX", 0, 0.01, 0, 0, minuitResult);
236 minuit.mnparm(5,
"PLER_TY", 0, 0.01, 0, 0, minuitResult);
237 minuit.mncomd(
"FIX 2 3 5 6", minuitResult);
238 minuit.mncomd(
"MIGRAD 10000", minuitResult);
239 minuit.mncomd(
"RELEASE 2 3 5 6", minuitResult);
240 minuit.mncomd(
"MIGRAD 10000", minuitResult);
242 minuit.GetParameter(0, herMomentum, error);
243 minuit.GetParameter(1, herThetaX, error);
244 minuit.GetParameter(2, herThetaY, error);
245 minuit.GetParameter(3, lerMomentum, error);
246 minuit.GetParameter(4, lerThetaX, error);
247 minuit.GetParameter(5, lerThetaY, error);
249 ROOT::Math::PxPyPzEVector pHER = getMomentum(herMomentum, herThetaX, herThetaY,
false);
250 ROOT::Math::PxPyPzEVector pLER = getMomentum(lerMomentum, lerThetaX, lerThetaY,
true);
251 ROOT::Math::PxPyPzEVector pBeam = pHER + pLER;
252 double fittedInvariantMass = pBeam.M();
253 B2RESULT(
"Initial invariant mass: " << s_InvariantMass <<
254 "; fitted invariant mass: " << fittedInvariantMass);
255 double cosThetaX = cos(herThetaX);
256 double sinThetaX = sin(herThetaX);
257 double cosThetaY = cos(herThetaY);
258 double sinThetaY = sin(herThetaY);
260 (pBeam.E() - pHER.E() / pHER.P() *
261 (pBeam.Px() * cosThetaX * sinThetaY - pBeam.Py() * sinThetaX +
262 pBeam.Pz() * cosThetaX * cosThetaY)) / fittedInvariantMass;
263 cosThetaX = cos(lerThetaX);
264 sinThetaX = sin(lerThetaX);
265 cosThetaY = cos(lerThetaY + M_PI);
266 sinThetaY = sin(lerThetaY + M_PI);
268 (pBeam.E() - pLER.E() / pLER.P() *
269 (pBeam.Px() * cosThetaX * sinThetaY - pBeam.Py() * sinThetaX +
270 pBeam.Pz() * cosThetaX * cosThetaY)) / fittedInvariantMass;
272 double k = sqrt(sigmaInvariantMass * sigmaInvariantMass /
273 (pow(herPartial * pHER.E(), 2) +
274 pow(lerPartial * pLER.E(), 2)));
275 double herSpread = k * pHER.E();
276 double lerSpread = k * pLER.E();
277 B2INFO(
"Invariant mass spread: " << sigmaInvariantMass);
278 B2RESULT(
"HER energy spread: " << herSpread <<
279 "; LER energy spread: " << lerSpread);
283 TMatrixDSym covariance(3);
284 for (
int i = 0; i < 3; ++i) {
285 for (
int j = 0; j < 3; ++j)
286 covariance[i][j] = 0;
288 covariance[0][0] = herSpread * herSpread;
290 covariance[0][0] = lerSpread * lerSpread;
295 double covarianceXX,
double covarianceYY)
299 TMatrixDSym beamSize =
m_BeamSpot->getSizeCovMatrix();
300 double xScale, yScale;
301 if (covarianceXX < 0)
304 xScale = sqrt(covarianceXX / beamSize[0][0]);
305 if (covarianceYY < 0)
308 yScale = sqrt(covarianceYY / beamSize[1][1]);
309 for (
int i = 0; i < 3; ++i) {
310 beamSize[0][i] *= xScale;
311 beamSize[i][0] *= xScale;
312 beamSize[1][i] *= yScale;
313 beamSize[i][1] *= yScale;
DataType Z() const
access variable Z (= .at(2) without boundary check)
DataType X() const
access variable X (= .at(0) without boundary check)
DataType Y() const
access variable Y (= .at(1) without boundary check)
DataType Angle(const B2Vector3< DataType > &q) const
The angle w.r.t.
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 setVertex(const TVector3 &vertex, const std::vector< double > &cov)
Set the vertex position and error matrix.
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 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.
B2Vector3< double > B2Vector3D
typedef for common usage with double
Abstract base class for different kinds of events.