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() <<
") ";
241 s <<
"Mass constraint:\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);
332 double xx = e * e - obj.mass * obj.mass;
347 e = (obj.mass == 0 ? p :
sqrt(obj.mass * obj.mass + p * p));
353 if (fabs(eta) > 50) {
355 eta = eta > 0 ? 50 : -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)
398 c(ndx +
p_offs) = obj.p.vect().mag();
403 c(ndx +
eta_offs) = obj.p.pseudoRapidity();
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);
505 xm(kt_ndx +
x_offs) = ev.kt().x();
506 xm(kt_ndx +
y_offs) = ev.kt().y();
509 G_i(kt_ndx +
x_offs, kt_ndx +
x_offs) = ev.kt_x_error() * ev.kt_x_error();
510 G_i(kt_ndx +
y_offs, kt_ndx +
y_offs) = ev.kt_y_error() * ev.kt_y_error();
511 G_i(kt_ndx +
x_offs, kt_ndx +
y_offs) = ev.kt_xy_covar();
512 G_i(kt_ndx +
y_offs, kt_ndx +
x_offs) = ev.kt_xy_covar();
516 if (ev.has_neutrino()) {
517 ym(
nu_z) = ev.nu().z();
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) {
655 v1_x[
p_offs] = (dot - v1.m2() * e2 / e1) / p1;
656 v2_x[
p_offs] = (dot - v2.m2() * e1 / e2) / p2;
663 v1_x[
phi_offs] = v1(1) * v2(0) - v1(0) * v2(1);
666 double fac = v1(0) * v2(0) + v1(1) * v2(1);
667 v1_x[
eta_offs] = pt1 * v2(2) - v1(2) / pt1 * fac;
668 v2_x[
eta_offs] = pt2 * v1(2) - v2(2) / pt2 * fac;
694 void addin_obj_gradient(
int constraint_no,
int sign,
int base_index,
const double grad[],
Matrix& Bx)
713 Bx(base_index +
p_offs, constraint_no) += sign * grad[
p_offs];
745 void addin_nu_gradient(
int constraint_no,
int sign,
int kt_ndx,
const double grad[],
Matrix& Bx,
Matrix& By)
765 Bx(kt_ndx +
x_offs, constraint_no) += sign * grad[
p_offs];
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()) {
819 assert(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)
915 F(
i + 1) += constraints[
i].sum_mass_terms(ev);
951 bool calculate_mass_constraints(
const Fourvec_Event& ev,
952 const Pair_Table&
pt,
953 const vector<Constraint>& constraints,
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);
998 add_mass_terms(ev, constraints, F);
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;
1053 Bx(ndx +
phi_offs, j) += py * dxnu - px * dynu;
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);
1129 By(
nu_z, j) = fac[0][2] * Bx(kt_ndx +
x_offs, j) + fac[2][2] * 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++) {
1180 const Fourvec& obj = ev.obj(j).p;
1183 int ndx = obj_index(j);
1184 double p = obj.vect().mag();
1185 double cot_theta = obj.z() / obj.vect().perp();
1189 Bx(ndx +
eta_offs, base + 1) =
obj(0) * cot_theta;
1193 Bx(ndx +
eta_offs, base + 2) =
obj(1) * cot_theta;
1196 Bx(ndx +
p_offs, base + 1) *= obj.e() /
p;
1197 Bx(ndx +
p_offs, base + 2) *= obj.e() /
p;
1201 int kt_ndx = obj_index(nobjs);
1202 Bx(kt_ndx +
x_offs, base + 1) = -1;
1203 Bx(kt_ndx +
y_offs, base + 2) = -1;
1205 F(base + 1) =
tmp(0) - ev.kt().x();
1206 F(base + 2) =
tmp(1) - ev.kt().y();
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;
1276 const vector<Constraint>& constraints,
1317 const vector<Constraint>& constraints,
1330 _constraints(constraints),
1332 _pt(constraints, ev)
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 = 1e-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++) {
1397 const FE_Obj& obj = _ev.obj(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 = 1e-10;
1460 const double eta_max = 10;
1463 for (
int j = 0; j < nobjs; j++)
1464 if (x(obj_index(j) +
p_offs) < p_eps || fabs(x(obj_index(j) +
eta_offs)) > eta_max) {
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;
1646 n_unmeasured_vars = 1;
1651 Matrix G_i(n_measured_vars, n_measured_vars);
1655 pack_event(ev,
_args.
use_e(), use_kt, x, y, G_i,
Y);
1668 double chisq = fitter.fit(cc, xm, x, ym, y, G_i, Y, pullx, pully, Q, R, S);
1670 unpack_event(ev, x, y,
_args.
use_e(), use_kt);
const edm::EventSetup & c
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
Exp< T >::type exp(const T &t)
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.
int nobjs() const
Return the number of objects in the event not including any neutrinos.
Abstract base class for evaluating constraints. Users derive from this class and implement the eval()...
Fourvec_Constrainer_Args(const Defaults &defs)
Constructor, initialize from a Defaults object.
bool calculate_constraints(Row_Vector &F, Matrix &Bx, Matrix &By) const
Calculate the constraint functions and gradients.
if(conf_.getParameter< bool >("UseStripCablingDB"))
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
const Chisq_Constrainer_Args & chisq_constrainer_args() const
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.
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...
double S(const TLorentzVector &, const TLorentzVector &)
Chisq_Constrainer_Args _chisq_constrainer_args
std::vector< Constraint > _constraints
T dot(const Basic3DVector &v) const
Scalar product, or "dot" product, with a vector of same type.
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.
tuple size
Write out results.
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.
bool has_neutrino() const
Return TRUE is this event contains a neutrino, otherwise returns FALSE.