19 #include <momemta/Logging.h> 20 #include <momemta/Module.h> 21 #include <momemta/ParameterSet.h> 22 #include <momemta/Solution.h> 23 #include <momemta/Types.h> 97 sqrt_s = parameters.globalParameters().get<
double>(
"energy");
99 s13 = get<double>(parameters.get<
InputTag>(
"s13"));
100 s24 = get<double>(parameters.get<
InputTag>(
"s24"));
101 s_hat = get<double>(parameters.get<
InputTag>(
"s_hat"));
102 y_tot = get<double>(parameters.get<
InputTag>(
"y_tot"));
104 m1 = parameters.get<
double>(
"m1", 0.);
105 m2 = parameters.get<
double>(
"m2", 0.);
107 p3 = get<LorentzVector>(parameters.get<
InputTag>(
"p3"));
108 p4 = get<LorentzVector>(parameters.get<
InputTag>(
"p4"));
110 if (parameters.exists(
"branches")) {
111 auto branches_tags = parameters.get<std::vector<InputTag>>(
"branches");
112 for (
auto& t: branches_tags)
113 m_branches.push_back(get<LorentzVector>(t));
117 virtual Status
work()
override {
121 const double s =
SQ(sqrt_s);
123 const double sq_m1 =
SQ(m1);
124 const double sq_m2 =
SQ(m2);
125 const double sq_m3 = p3->M2();
126 const double sq_m4 = p4->M2();
129 if (sq_m1 + sq_m3 >= *s13 || sq_m2 + sq_m4 >= *s24 || *s13 + *s24 >= *s_hat || *s_hat >= s)
132 const double sqrt_shat = std::sqrt(*s_hat);
134 const double p3x = p3->Px();
135 const double p3y = p3->Py();
136 const double p3z = p3->Pz();
137 const double E3 = p3->E();
139 const double p4x = p4->Px();
140 const double p4y = p4->Py();
141 const double p4z = p4->pz();
142 const double E4 = p4->E();
145 LorentzVector pb = *p3 + *p4;
146 for (
size_t i = 0; i < m_branches.size(); i++) {
147 pb += *m_branches[i];
150 const double Eb = pb.E();
151 const double pbx = pb.Px();
152 const double pby = pb.Py();
153 const double pbz = pb.Pz();
155 const double Etot = sqrt_shat * std::cosh(*y_tot) - Eb;
156 const double ptotz = sqrt_shat * std::sinh(*y_tot) - pbz;
158 const double X = 0.5 * (- sq_m1 - sq_m3 + *s13);
159 const double Y = 0.5 * (- sq_m2 - sq_m4 + *s24);
179 const double den = p3z * p4x - p3x * p4z;
181 const double A1x = - (E4 * p3z - E3 * p4z) / den;
182 const double B1x = (p3z * p4y - p3y * p4z) / den;
183 const double C1x = - (p4z * (E3 * Etot - p3z * ptotz + p3y * pby - X) - p3z * (Y - p4x * pbx)) / den;
185 const double A1z = (E4 * p3x - E3 * p4x) / den;
186 const double B1z = (p3y * p4x - p3x * p4y) / den;
187 const double C1z = (p4x * (E3 * Etot + p3y * pby + p3x * pbx - X) - p3x * (Y + p4z * ptotz)) / den;
201 const double fac = 2 * (A1x * pbx - A1z * ptotz - Etot);
202 const double a = - 2 * (B1x * pbx - B1z * ptotz - pby) / fac;
203 const double b = - (
SQ(Etot) + pow(C1x + pbx, 2) + pow(C1z - ptotz, 2) + sq_m2 -
SQ(C1x) -
SQ(pby) -
SQ(C1z) - sq_m1) / fac;
205 const double a20 = 1 -
SQ(A1x) -
SQ(A1z);
206 const double a02 = - (
SQ(B1x) +
SQ(B1z) + 1);
207 const double a11 = - 2 * (A1x * B1x + A1z * B1z);
208 const double a10 = - 2 * (A1x * C1x + A1z * C1z + Etot);
209 const double a01 = - 2 * (B1x * C1x + B1z * C1z + pby);
210 const double a00 =
SQ(Etot) - (
SQ(C1x) +
SQ(C1z) +
SQ(pby) + sq_m1);
212 std::vector<double> p2y_sol;
214 2 * a * b * a20 + b * a11 + a01 + a * a10,
215 SQ(b) * a20 + b * a10 + a00,
221 for (
const double p2y: p2y_sol) {
222 const double E2 = a * p2y + b;
227 const double E1 = Etot - E2;
232 const double p1x = A1x * E2 + B1x * p2y + C1x;
233 const double p1y = - p2y - pby;
234 const double p1z = A1z * E2 + B1z * p2y + C1z;
235 const LorentzVector p1(p1x, p1y, p1z, E1);
237 const double p2x = - p1x - pbx;
238 const double p2z = - p1z + ptotz;
239 const LorentzVector p2(p2x, p2y, p2z, E2);
242 const LorentzVector tot = p1 + p2 + pb;
243 const double q1Pz = std::abs(tot.Pz() + tot.E()) / 2.;
244 const double q2Pz = std::abs(tot.Pz() - tot.E()) / 2.;
246 if (q1Pz > sqrt_s/2 || q2Pz > sqrt_s/2)
251 LOG(trace) <<
"[BlockE] Throwing solution because total Pt is incorrect. " 252 <<
"Expected " << 0. <<
", got " << tot.Pt();
259 LOG(trace) <<
"[BlockE] Throwing solution because p1 has an invalid mass. " <<
260 "Expected " << m1 <<
", got " << p1.M();
267 LOG(trace) <<
"[BlockE] Throwing solution because p2 has an invalid mass. " <<
268 "Expected " << m2 <<
", got " << p2.M();
275 LOG(trace) <<
"[BlockE] Throwing solution because of invalid invariant mass. " <<
276 "Expected " << *s13 <<
", got " << (p1 + *p3).M2();
283 LOG(trace) <<
"[BlockE] Throwing solution because of invalid invariant mass. " <<
284 "Expected " << *s24 <<
", got " << (p2 + *p4).M2();
289 const double jacobian = 1. / (64 *
SQ(M_PI) * s * std::abs(E4*(p1z*p2y*p3x - p1y*p2z*p3x - p1z*p2x*p3y + p1x*p2z*p3y + p1y*p2x*p3z - p1x*p2y*p3z) + E2*p1z*p3y*p4x - E1*p2z*p3y*p4x - E2*p1y*p3z*p4x + E1*p2y*p3z*p4x - E2*p1z*p3x*p4y + E1*p2z*p3x*p4y + E2*p1x*p3z*p4y - E1*p2x*p3z*p4y + (E2*p1y*p3x - E1*p2y*p3x - E2*p1x*p3y + E1*p2x*p3y)*p4z + E3*(-(p1z*p2y*p4x) + p1y*p2z*p4x + p1z*p2x*p4y - p1x*p2z*p4y - p1y*p2x*p4z + p1x*p2y*p4z)));
291 Solution s { {p1, p2}, jacobian,
true };
292 solutions->push_back(s);
295 return solutions->size() > 0 ? Status::OK : Status::NEXT;
309 std::vector<Value<LorentzVector>> m_branches;
312 std::shared_ptr<SolutionCollection> solutions = produce<SolutionCollection>(
"solutions");
322 .OptionalInputs(
"branches")
324 .GlobalAttr(
"energy:double")
326 .Attr(
"m2:double=0");
Final (main) Block E, describing
bool ApproxComparison(double value, double expected)
Compare two doubles and return true if they are approximatively equal.
Generic solution structure representing a set of particles, along with its jacobian.
bool solveQuadratic(const double a, const double b, const double c, std::vector< double > &roots, bool verbose=false)
Finds the real solutions to .
virtual Status work() override
Main function.
Parent class for all the modules.
A class encapsulating a lua table.
Module(PoolPtr pool, const std::string &name)
Constructor.