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";
274 int nobjs = ev.
nobjs();
275 for (
int i = 0;
i < nobjs;
i++) {
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);
398 c(ndx +
p_offs) = obj.
p.vect().mag();
415 Matrix error_matrix(
double p_sig,
double phi_sig,
double eta_sig)
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++) {
497 int this_index = obj_index(
i);
498 set_p_eta_phi_vec(obj, xm, this_index, use_e_flag);
504 int kt_ndx = obj_index(nobjs);
558 for (
int j = 0;
j < ev.
nobjs();
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());
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];
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);
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);
915 F(i + 1) += constraints[
i].sum_mass_terms(ev);
953 const vector<Constraint>& constraints,
981 for (
int p = 0;
p < npairs;
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);
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;
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);
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();
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;
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 = 1
e-10;
1374 for (
int j = 0;
j < nobjs;
j++) {
1391 for (
int j = 0;
j < nobjs;
j++) {
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++)
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);
1543 const vector<Constraint>& mass_constraint,
1569 if (mass_constraint.empty()) {
1576 int n_measured_vars = ev.
nobjs() * 3 + 2;
1577 int n_unmeasured_vars = 0;
1579 n_unmeasured_vars = 1;
1582 Matrix Bx(n_measured_vars, 1);
1583 Matrix By(n_unmeasured_vars, 1);
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);
1672 calculate_mass(ev, _mass_constraint,
_args, chisq, Q, R, S, m, sigm);
const Objpair & get_pair(std::vector< Objpair >::size_type pairno) const
Get one of the pairs from the table, index starts from 0.
friend std::ostream & operator<<(std::ostream &s, const Fourvec_Constrainer &c)
Output stream operator, print the content of this Fourvec_Constrainer to an output stream...
int for_constraint(std::vector< signed char >::size_type k) const
Retrieve the value set for a constraint.
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
int npairs() const
Return the number of pairs in the table.
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.
const FE_Obj & obj(std::vector< FE_Obj >::size_type i) const
Access object at index i, with the convention that the index starts at 0.
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.
double kt_y_error() const
Return the y uncertainty in .
double kt_xy_covar() const
Return the xy covariance in .
int j() const
Return the index of the second 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
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.
void set_nu_p(const Fourvec &p)
Set the neutrino four-momentum to . This method adds a neutrino if there wasn't already one...
void set_obj_p(std::vector< FE_Obj >::size_type i, const Fourvec &p)
Set the four-momentum of object at index i to .
CLHEP::HepDiagMatrix Diagonal_Matrix
void set_x_p(const Fourvec &p)
Set the four-momentum of the object.
const Fourvec & kt() const
Access the four-momentum.
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.
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...
double kt_x_error() const
Return the x uncertainty in .
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...
const Fourvec & nu() const
Access the neutrino four-momentum.
Do a kinematic fit for a set of four-momenta, given a set of mass constraints.
A lookup table to speed up constraint evaluation.
Represent a pair of objects in Pair_Table.
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.
int i() const
Return the index of the first object.
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.