68 : _use_e(defs.get_bool(
"use_e")),
69 _e_com(defs.get_float(
"e_com")),
70 _ignore_met(defs.get_bool(
"ignore_met")),
71 _chisq_constrainer_args(defs) {}
232 s <<
"Constraints: (e_com = " <<
c._args.e_com() <<
") ";
238 s <<
" " <<
c._constraints[
i] <<
"\n";
240 if (!
c._mass_constraint.empty()) {
241 s <<
"Mass constraint:\n";
242 s <<
c._mass_constraint[0] <<
"\n";
263 void adjust_fourvecs(Fourvec_Event&
ev,
bool use_e_flag)
274 int nobjs =
ev.nobjs();
275 for (
int i = 0;
i < nobjs;
i++) {
276 const FE_Obj&
obj =
ev.obj(
i);
353 if (fabs(
eta) > 50) {
357 double exp_eta =
exp(
eta);
358 double iexp_eta = 1 / exp_eta;
359 double sin_theta = 2 / (exp_eta + iexp_eta);
360 double cos_theta = (exp_eta - iexp_eta) / (exp_eta + iexp_eta);
363 return Fourvec(
p * sin_theta *
cos(phi),
p * sin_theta *
sin(phi),
p * cos_theta,
e);
382 void set_p_eta_phi_vec(
const FE_Obj&
obj,
Column_Vector&
c,
int ndx,
bool use_e_flag)
415 Matrix error_matrix(
double p_sig,
double phi_sig,
double eta_sig)
460 void pack_event(
const Fourvec_Event&
ev,
485 int nobjs =
ev.nobjs();
487 int n_measured_vars = nobjs * 3;
489 n_measured_vars += 2;
492 G_i =
Matrix(n_measured_vars, n_measured_vars, 0);
495 for (
int i = 0;
i < nobjs;
i++) {
496 const FE_Obj&
obj =
ev.obj(
i);
497 int this_index = obj_index(
i);
498 set_p_eta_phi_vec(
obj, xm, this_index, use_e_flag);
499 G_i.sub(this_index, this_index, error_matrix(
obj.p_error,
obj.phi_error,
obj.eta_error));
504 int kt_ndx = obj_index(nobjs);
516 if (
ev.has_neutrino()) {
558 for (
int j = 0;
j <
ev.nobjs();
j++) {
559 const FE_Obj&
obj =
ev.obj(
j);
560 ev.set_obj_p(
j, get_p_eta_phi_vec(x, obj_index(
j),
obj, use_e_flag));
565 int kt_ndx = obj_index(
ev.nobjs());
568 if (
ev.has_neutrino()) {
615 double dot_and_gradient(
616 const Fourvec& v1,
const Fourvec& v2,
bool use_e_flag,
double v1_x[3],
double v2_x[3],
bool& badflag)
636 double dot = v1 * v2;
638 double p1 = v1.vect().mag();
639 double p2 = v2.vect().mag();
642 double pt1 = v1.vect().perp();
643 double pt2 = v2.vect().perp();
647 if (
p1 == 0 ||
p2 == 0 ||
e1 == 0 || e2 == 0 ||
pt1 == 0 ||
pt2 == 0) {
663 v1_x[
phi_offs] = v1(1) * v2(0) - v1(0) * v2(1);
666 double fac = v1(0) * v2(0) + v1(1) * v2(1);
694 void addin_obj_gradient(
int constraint_no,
int sign,
int base_index,
const double grad[],
Matrix& Bx)
745 void addin_nu_gradient(
int constraint_no,
int sign,
int kt_ndx,
const double grad[],
Matrix& Bx,
Matrix& By)
797 const Fourvec_Event&
ev,
int constraint_no,
int sign,
int obj_no,
const double grad[],
Matrix& Bx,
Matrix& By)
818 if (obj_no >=
ev.nobjs()) {
820 addin_nu_gradient(constraint_no,
sign, obj_index(obj_no), grad, Bx, By);
822 addin_obj_gradient(constraint_no,
sign, obj_index(obj_no), grad, Bx);
855 void addin_gradients(
const Fourvec_Event&
ev,
859 const double igrad[],
861 const double jgrad[],
885 addin_gradient(
ev, constraint_no,
sign,
i, igrad, Bx, By);
886 addin_gradient(
ev, constraint_no,
sign,
j, jgrad, Bx, By);
901 void add_mass_terms(
const Fourvec_Event&
ev,
const vector<Constraint>&
constraints, Row_Vector&
F)
951 bool calculate_mass_constraints(
const Fourvec_Event&
ev,
952 const Pair_Table&
pt,
980 int npairs =
pt.npairs();
981 for (
int p = 0;
p < npairs;
p++) {
982 const Objpair& objpair =
pt.get_pair(
p);
985 double igrad[3], jgrad[3];
986 bool badflag =
false;
987 double dot = dot_and_gradient(
ev.obj(
i).p,
ev.obj(
j).p, use_e_flag, igrad, jgrad, badflag);
992 if (objpair.for_constraint(
k)) {
993 F(
k + 1) += objpair.for_constraint(
k) *
dot;
994 addin_gradients(
ev,
k + 1, objpair.for_constraint(
k),
i, igrad,
j, jgrad, Bx, By);
1024 void add_nuterm(
unsigned ndx,
const Fourvec&
v,
Matrix& Bx,
bool use_e_flag,
int kt_ndx)
1042 double cot_theta =
v.pz() /
v.vect().perp();
1044 for (
int j = 1;
j <= Bx.num_col();
j++) {
1045 double dxnu = Bx(kt_ndx +
x_offs,
j);
1046 double dynu = Bx(kt_ndx +
y_offs,
j);
1048 if (dxnu != 0 || dynu != 0) {
1049 double fac = 1 /
v.vect().mag();
1051 fac =
v.e() * fac * fac;
1052 Bx(ndx +
p_offs,
j) -= (
px * dxnu +
py * dynu) * fac;
1054 Bx(ndx +
eta_offs,
j) -= (
px * dxnu +
py * dynu) * cot_theta;
1082 void convert_neutrino(
const Fourvec_Event&
ev,
bool use_e_flag,
Matrix& Bx,
Matrix& By)
1100 int nconstraints = Bx.num_col();
1105 double pnu2 = nu.vect().mag2();
1106 double pnu =
sqrt(pnu2);
1107 double ptnu2 = nu.vect().perp2();
1108 double ptnu =
sqrt(ptnu2);
1112 double thfac = nu.z() / pnu2 / ptnu;
1114 fac[0][0] = nu(0) / pnu;
1115 fac[0][1] = nu(1) / pnu;
1116 fac[0][2] = nu(2) / pnu;
1117 fac[1][0] = -nu(1) / ptnu2;
1118 fac[1][1] = nu(0) / ptnu2;
1120 fac[2][0] = nu(0) * thfac;
1121 fac[2][1] = nu(1) * thfac;
1122 fac[2][2] = -ptnu / pnu2;
1124 int kt_ndx = obj_index(
ev.nobjs());
1125 for (
int j = 1;
j <= nconstraints;
j++) {
1126 double tmp1 = fac[0][0] * Bx(kt_ndx +
x_offs,
j) + fac[1][0] * Bx(kt_ndx +
y_offs,
j) + fac[2][0] * By(
nu_z,
j);
1128 fac[0][1] * Bx(kt_ndx +
x_offs,
j) + fac[1][1] * Bx(kt_ndx +
y_offs,
j) + fac[2][1] * By(
nu_z,
j);
1131 Bx(kt_ndx +
x_offs,
j) = tmp1;
1135 for (
int j = 0;
j <
ev.nobjs();
j++) {
1136 add_nuterm(obj_index(
j),
ev.obj(
j).p, Bx, use_e_flag, kt_ndx);
1160 void calculate_kt_constraints(
const Fourvec_Event&
ev,
bool use_e_flag, Row_Vector&
F,
Matrix& Bx)
1177 int base =
F.num_col() - 2;
1178 int nobjs =
ev.nobjs();
1179 for (
int j = 0;
j < nobjs;
j++) {
1183 int ndx = obj_index(
j);
1184 double p =
obj.vect().mag();
1185 double cot_theta =
obj.z() /
obj.vect().perp();
1201 int kt_ndx = obj_index(nobjs);
1222 void ddtheta_to_ddeta(
int i,
double cos_theta,
Matrix& Bx)
1236 double sin_theta =
sqrt(1 - cos_theta * cos_theta);
1237 for (
int j = 1;
j <= Bx.num_col();
j++)
1238 Bx(
i,
j) *= -sin_theta;
1361 Bx =
Matrix(Bx.num_row(), Bx.num_col(), 0);
1362 By =
Matrix(By.num_row(), By.num_col(), 0);
1365 const double p_eps = 1
e-10;
1367 if (_ev.has_neutrino() && _ev.nu().z() > _args.e_com()) {
1371 int nobjs = _ev.nobjs();
1374 for (
int j = 0;
j < nobjs;
j++) {
1375 if (_ev.obj(
j).p.perp() <= p_eps || _ev.obj(
j).p.e() <= p_eps) {
1380 if (!calculate_mass_constraints(_ev, _pt, _constraints, _args.use_e(),
F, Bx, By))
1383 if (_ev.has_neutrino())
1384 convert_neutrino(_ev, _args.use_e(), Bx, By);
1385 else if (!_args.ignore_met()) {
1387 calculate_kt_constraints(_ev, _args.use_e(),
F, Bx);
1391 for (
int j = 0;
j < nobjs;
j++) {
1392 ddtheta_to_ddeta(obj_index(
j) +
eta_offs, _ev.obj(
j).p.cosTheta(), Bx);
1396 for (
int j = 0;
j < nobjs;
j++) {
1400 double pmu2 =
obj.p.vect().mag2();
1401 int ndx = obj_index(
j) +
p_offs;
1402 for (
int k = 1;
k <= Bx.num_col();
k++)
1403 Bx(ndx,
k) = -Bx(ndx,
k) * pmu2;
1459 const double p_eps = 1
e-10;
1463 for (
int j = 0;
j < nobjs;
j++)
1496 double calculate_sigm(
1509 double sig2 =
scalar(Bx.T() * Q * Bx);
1511 if (By.num_row() > 0) {
1512 sig2 +=
scalar(By.T() *
R * By);
1513 sig2 += 2 *
scalar(Bx.T() *
S * By);
1542 void calculate_mass(Fourvec_Event&
ev,
1543 const vector<Constraint>& mass_constraint,
1544 const Fourvec_Constrainer_Args&
args,
1569 if (mass_constraint.empty()) {
1576 int n_measured_vars =
ev.nobjs() * 3 + 2;
1577 int n_unmeasured_vars = 0;
1578 if (
ev.has_neutrino())
1579 n_unmeasured_vars = 1;
1582 Matrix Bx(n_measured_vars, 1);
1583 Matrix By(n_unmeasured_vars, 1);
1585 Fourvec_Constraint_Calculator cc(
ev, mass_constraint,
args);
1586 cc.calculate_constraints(
F, Bx, By);
1606 sigm = calculate_sigm(Q,
R,
S, Bx, By);
1637 int nobjs =
ev.nobjs();
1638 int n_measured_vars = nobjs * 3;
1639 int n_unmeasured_vars = 0;
1643 n_measured_vars += 2;
1645 if (
ev.has_neutrino())
1646 n_unmeasured_vars = 1;
1651 Matrix G_i(n_measured_vars, n_measured_vars);
1668 double chisq = fitter.fit(cc, xm,
x, ym, y, G_i,
Y, pullx, pully, Q,
R,
S);
Define an abstract interface for getting parameter settings.
Represent a mass constraint equation. Mass constraints come in two varieties, either saying that the ...
void adjust_e_for_mass(Fourvec &v, double mass)
Adjust the energy component of four-vector v (leaving the three-vector part unchanged) so that the fo...
Represent an event for kinematic fitting as a collection of four-momenta. Each object is represented ...
Sin< T >::type sin(const T &t)
Fourvec_Constrainer(const Fourvec_Constrainer_Args &args)
Constructor.
CLHEP::HepVector Column_Vector
Concrete realization of the Constraint_Calculator class. Evaluate constraints at the point described ...
Define matrix types for the HitFit package, and supply a few additional operations.
Abstract base class for evaluating constraints. Users derive from this class and implement the eval()...
T dot(const Basic3DVector &v) const
Scalar product, or "dot" product, with a vector of same type.
Fourvec_Constrainer_Args(const Defaults &defs)
Constructor, initialize from a Defaults object.
Cos< T >::type cos(const T &t)
Minimize a subject to a set of constraints. Based on the SQUAW algorithm.
Minimize a subject to a set of constraints, based on the SQUAW algorithm.
CLHEP::HepLorentzVector Fourvec
Typedef for a HepLorentzVector.
~Fourvec_Constraint_Calculator() override
Hold on to parameters for the Chisq_Constrainer class.
const Fourvec_Constrainer_Args _args
void adjust_p_for_mass(Fourvec &v, double mass)
Adjust the three-vector part of v, leaving the energy unchanged,.
std::vector< Constraint > _mass_constraint
Fourvec_Constraint_Calculator(Fourvec_Event &ev, const vector< Constraint > &constraints, const Fourvec_Constrainer_Args &args)
Constructor.
bool calculate_constraints(Row_Vector &F, Matrix &Bx, Matrix &By) const
Calculate the constraint functions and gradients.
int nobjs() const
Return the number of objects in the event not including any neutrinos.
CLHEP::HepDiagMatrix Diagonal_Matrix
A lookup table to speed up constraint evaluation using Fourvec_Constrainer.
bool eval(const Column_Vector &x, const Column_Vector &y, Row_Vector &F, Matrix &Bx, Matrix &By) override
Evaluate constraints at the point described by x and y (well-measured and poorly-measured variables...
bool has_neutrino() const
Return TRUE is this event contains a neutrino, otherwise returns FALSE.
Chisq_Constrainer_Args _chisq_constrainer_args
std::vector< Constraint > _constraints
double constrain(Fourvec_Event &ev, double &m, double &sigm, Column_Vector &pullx, Column_Vector &pully)
Do a constrained fit for event ev. Returns the requested mass and its uncertainty in m and sigm...
Define an interface for getting parameter settings.
std::ostream & operator<<(std::ostream &s, const Constraint_Intermed &ci)
Output stream operator, print the content of this Constraint_Intermed to an output stream...
const Fourvec_Constrainer_Args & _args
Do a kinematic fit for a set of four-vectors, given a set of mass constraints.
void mass_constraint(std::string s)
Specify a combination of objects that will be returned by the constrain() method as mass...
Represent a single object in a Fourvec_Event, this is just a dumb data container. Each object in a Fo...
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
const vector< Constraint > & _constraints
void add_constraint(std::string s)
Specify an additional constraint s for the problem. The format for s is described in the class descri...
Do a kinematic fit for a set of four-momenta, given a set of mass constraints.
const Chisq_Constrainer_Args & chisq_constrainer_args() const
A lookup table to speed up constraint evaluation.
Row-vector class. CLHEP doesn't have a row-vector class, so HitFit uses its own. This is only a simpl...
Hold on to parameters for the Fourvec_Constrainer class.
double scalar(const CLHEP::HepGenMatrix &m)
Return the matrix as a scalar. Raise an assertion if the matris is not .
Represent an event for kinematic fitting as a collection of four-momenta.