20 #include <momemta/ParameterSet.h> 21 #include <momemta/Module.h> 22 #include <momemta/Solution.h> 23 #include <momemta/Types.h> 91 sqrt_s = parameters.globalParameters().get<
double>(
"energy");
92 pT_is_met = parameters.get<
bool>(
"pT_is_met",
false);
94 m1 = parameters.get<
double>(
"m1", 0.);
95 m2 = parameters.get<
double>(
"m2", 0.);
97 s13 = get<double>(parameters.get<
InputTag>(
"s13"));
98 s134 = get<double>(parameters.get<
InputTag>(
"s134"));
99 s25 = get<double>(parameters.get<
InputTag>(
"s25"));
100 s256 = get<double>(parameters.get<
InputTag>(
"s256"));
102 m_particles.push_back(get<LorentzVector>(parameters.get<
InputTag>(
"p3")));
103 m_particles.push_back(get<LorentzVector>(parameters.get<
InputTag>(
"p4")));
104 m_particles.push_back(get<LorentzVector>(parameters.get<
InputTag>(
"p5")));
105 m_particles.push_back(get<LorentzVector>(parameters.get<
InputTag>(
"p6")));
107 if (parameters.exists(
"branches")) {
108 auto branches_tags = parameters.get<std::vector<InputTag>>(
"branches");
109 for (
auto& t: branches_tags)
110 m_branches.push_back(get<LorentzVector>(t));
116 if (parameters.exists(
"met")) {
117 met_tag = parameters.get<
InputTag>(
"met");
122 m_met = get<LorentzVector>(met_tag);
125 virtual Status
work()
override {
129 const LorentzVector& p3 = *m_particles[0];
130 const LorentzVector& p4 = *m_particles[1];
131 const LorentzVector& p5 = *m_particles[2];
132 const LorentzVector& p6 = *m_particles[3];
134 const double p11 =
SQ(m1);
135 const double p22 =
SQ(m2);
136 const double p33 = p3.M2();
137 const double p44 = p4.M2();
138 const double p55 = p5.M2();
139 const double p66 = p6.M2();
142 if (*s13 + p44 >= *s134 || *s25 + p66 >= *s256 || *s134 + *s256 >=
SQ(sqrt_s) || *s13 <= p11 + p33 || *s25 <= p22 + p55)
157 pT = p3 + p4 + p5 + p6;
158 for (
size_t i = 0; i < m_branches.size(); i++) {
159 pT += *m_branches[i];
163 const double p34 = p3.Dot(p4);
164 const double p56 = p5.Dot(p6);
170 const double A1 = 2.*( -p3.Px() + p3.Pz()*p4.Px()/p4.Pz() );
171 const double A2 = 2.*( p5.Px() - p5.Pz()*p6.Px()/p6.Pz() );
173 const double B1 = 2.*( -p3.Py() + p3.Pz()*p4.Py()/p4.Pz() );
174 const double B2 = 2.*( p5.Py() - p5.Pz()*p6.Py()/p6.Pz() );
176 const double Dx = B2*A1 - B1*A2;
177 const double Dy = A2*B1 - A1*B2;
179 const double X = 2*( pT.Px()*p5.Px() + pT.Py()*p5.Py() - p5.Pz()/p6.Pz()*( 0.5*(*s25 - *s256 + p66) + p56 + pT.Px()*p6.Px() + pT.Py()*p6.Py() ) ) + p55 + p22 - *s25;
180 const double Y = p3.Pz()/p4.Pz()*( *s13 - *s134 + 2*p34 + p44 ) - p33 - p11 + *s13;
189 const double alpha1 = -2*B2*(p3.E() - p4.E()*p3.Pz()/p4.Pz())/Dx;
190 const double beta1 = 2*B1*(p5.E() - p6.E()*p5.Pz()/p6.Pz())/Dx;
191 const double gamma1 = B1*X/Dx + B2*Y/Dx;
193 const double alpha2 = -2*A2*(p3.E() - p4.E()*p3.Pz()/p4.Pz())/Dy;
194 const double beta2 = 2*A1*(p5.E() - p6.E()*p5.Pz()/p6.Pz())/Dy;
195 const double gamma2 = A1*X/Dy + A2*Y/Dy;
197 const double alpha3 = (p4.E() - alpha1*p4.Px() - alpha2*p4.Py())/p4.Pz();
198 const double beta3 = -(beta1*p4.Px() + beta2*p4.Py())/p4.Pz();
199 const double gamma3 = ( 0.5*(*s13 - *s134 + p44) + p34 - gamma1*p4.Px() - gamma2*p4.Py() )/p4.Pz();
201 const double alpha4 = (alpha1*p6.Px() + alpha2*p6.Py())/p6.Pz();
202 const double beta4 = (p6.E() + beta1*p6.Px() + beta2*p6.Py())/p6.Pz();
203 const double gamma4 = ( 0.5*(*s25 - *s256 + p66) + p56 + (gamma1 + pT.Px())*p6.Px() + (gamma2 + pT.Py())*p6.Py() )/p6.Pz();
205 const double alpha5 = -alpha1;
206 const double beta5 = -beta1;
207 const double gamma5 = -pT.Px() - gamma1;
209 const double alpha6 = -alpha2;
210 const double beta6 = -beta2;
211 const double gamma6 = -pT.Py() - gamma2;
216 const double a11 = -1 + (
SQ(alpha1) +
SQ(alpha2) +
SQ(alpha3) );
217 const double a22 =
SQ(beta1) +
SQ(beta2) +
SQ(beta3);
218 const double a12 = 2.*( alpha1*beta1 + alpha2*beta2 + alpha3*beta3 );
219 const double a10 = 2.*( alpha1*gamma1 + alpha2*gamma2 + alpha3*gamma3 );
220 const double a01 = 2.*( beta1*gamma1 + beta2*gamma2 + beta3*gamma3 );
221 const double a00 =
SQ(gamma1) +
SQ(gamma2) +
SQ(gamma3) + p11;
223 const double b11 =
SQ(alpha5) +
SQ(alpha6) +
SQ(alpha4);
224 const double b22 = -1 + (
SQ(beta5) +
SQ(beta6) +
SQ(beta4) );
225 const double b12 = 2.*( alpha5*beta5 + alpha6*beta6 + alpha4*beta4 );
226 const double b10 = 2.*( alpha5*gamma5 + alpha6*gamma6 + alpha4*gamma4 );
227 const double b01 = 2.*( beta5*gamma5 + beta6*gamma6 + beta4*gamma4 );
228 const double b00 =
SQ(gamma5) +
SQ(gamma6) +
SQ(gamma4) + p22;
231 std::vector<double> E1, E2;
232 solve2Quads(a11, a22, a12, a10, a01, a00, b11, b22, b12, b10, b01, b00, E1, E2,
false);
239 for(
unsigned int i = 0; i < E1.size(); i++){
240 const double e1 = E1.at(i);
241 const double e2 = E2.at(i);
243 if (e1 <= 0 || e2 <= 0)
247 alpha1*e1 + beta1*e2 + gamma1,
248 alpha2*e1 + beta2*e2 + gamma2,
249 alpha3*e1 + beta3*e2 + gamma3,
253 alpha5*e1 + beta5*e2 + gamma5,
254 alpha6*e1 + beta6*e2 + gamma6,
255 alpha4*e1 + beta4*e2 + gamma4,
259 LorentzVector tot = p1 + p2 + p3 + p4 + p5 + p6;
260 for (
size_t i = 0; i < m_branches.size(); i++) {
261 tot += *m_branches[i];
263 double q1Pz = std::abs(tot.Pz() + tot.E()) / 2.;
264 double q2Pz = std::abs(tot.Pz() - tot.E()) / 2.;
265 if (q1Pz > sqrt_s / 2 || q2Pz > sqrt_s / 2)
270 LOG(trace) <<
"[BlockD] Throwing solution because neutrino balance is incorrect. " 271 <<
"Expected " << pT.Pt() <<
", got " <<(p1 + p2).Pt();
278 LOG(trace) <<
"[BlockD] Throwing solution because p1 has an invalid mass. " <<
279 "Expected " << m1 <<
", got " << p1.M();
286 LOG(trace) <<
"[BlockD] Throwing solution because p2 has an invalid mass. " <<
287 "Expected " << m2 <<
", got " << p2.M();
294 LOG(trace) <<
"[BlockD] Throwing solution because of invalid invariant mass. " <<
295 "Expected " << *s13 <<
", got " << (p1 + p3).M2();
302 LOG(trace) <<
"[BlockD] Throwing solution because of invalid invariant mass. " <<
303 "Expected " << *s134 <<
", got " << (p1 + p3 + p4).M2();
310 LOG(trace) <<
"[BlockD] Throwing solution because of invalid invariant mass. " <<
311 "Expected " << *s25 <<
", got " << (p2 + p5).M2();
318 LOG(trace) <<
"[BlockD] Throwing solution because of invalid invariant mass. " <<
319 "Expected " << *s256 <<
", got " << (p2 + p5 + p6).M2();
325 double jacobian = computeJacobian(p1, p2, p3, p4, p5, p6);
326 Solution s { {p1, p2}, jacobian,
true };
327 solutions->push_back(s);
330 return solutions->size() > 0 ? Status::OK : Status::NEXT;
333 double computeJacobian(
const LorentzVector& p1,
const LorentzVector& p2,
const LorentzVector& p3,
const LorentzVector& p4,
const LorentzVector& p5,
const LorentzVector& p6) {
335 const double E1 = p1.E();
336 const double p1x = p1.Px();
337 const double p1y = p1.Py();
338 const double p1z = p1.Pz();
340 const double E2 = p2.E();
341 const double p2x = p2.Px();
342 const double p2y = p2.Py();
343 const double p2z = p2.Pz();
345 const double E3 = p3.E();
346 const double p3x = p3.Px();
347 const double p3y = p3.Py();
348 const double p3z = p3.Pz();
350 const double E4 = p4.E();
351 const double p4x = p4.Px();
352 const double p4y = p4.Py();
353 const double p4z = p4.Pz();
355 const double E5 = p5.E();
356 const double p5x = p5.Px();
357 const double p5y = p5.Py();
358 const double p5z = p5.Pz();
360 const double E6 = p6.E();
361 const double p6x = p6.Px();
362 const double p6y = p6.Py();
363 const double p6z = p6.Pz();
365 const double E34 = E3 + E4;
366 const double p34x = p3x + p4x;
367 const double p34y = p3y + p4y;
368 const double p34z = p3z + p4z;
370 const double E56 = E5 + E6;
371 const double p56x = p5x + p6x;
372 const double p56y = p5y + p6y;
373 const double p56z = p5z + p6z;
377 double inv_jac = E3*(E5*
378 (p34z*(p1y*p2z*p56x - p1x*p2z*p56y - p1y*p2x*p56z +
380 p1z*(-(p2z*p34y*p56x) + p2z*p34x*p56y -
381 p2y*p34x*p56z + p2x*p34y*p56z)) +
383 (p1z*p34y*p5x - p1y*p34z*p5x - p1z*p34x*p5y +
385 (E56*(p1z*p2y*p34x - p1z*p2x*p34y + p1y*p2x*p34z -
387 E2*(p1z*p34y*p56x - p1y*p34z*p56x - p1z*p34x*p56y +
388 p1x*p34z*p56y))*p5z) +
389 E34*(E5*p2z*(p1z*p3y*p56x - p1y*p3z*p56x - p1z*p3x*p56y +
391 E5*(p1z*p2y*p3x - p1z*p2x*p3y + p1y*p2x*p3z -
394 (p1z*p3y*p5x - p1y*p3z*p5x - p1z*p3x*p5y + p1x*p3z*p5y)
395 - (E56*(p1z*p2y*p3x - p1z*p2x*p3y + p1y*p2x*p3z -
397 E2*(p1z*p3y*p56x - p1y*p3z*p56x - p1z*p3x*p56y +
398 p1x*p3z*p56y))*p5z) +
399 E1*(E5*(p2z*(-(p34z*p3y*p56x) + p34y*p3z*p56x +
400 p34z*p3x*p56y - p34x*p3z*p56y) +
401 (-(p2y*p34z*p3x) + p2x*p34z*p3y + p2y*p34x*p3z -
402 p2x*p34y*p3z)*p56z) +
404 (p34z*p3y*p5x - p34y*p3z*p5x - p34z*p3x*p5y +
406 (E56*(p2y*p34z*p3x - p2x*p34z*p3y - p2y*p34x*p3z +
408 E2*(p34z*p3y*p56x - p34y*p3z*p56x - p34z*p3x*p56y +
409 p34x*p3z*p56y))*p5z);
411 inv_jac *= 8.*16.*
SQ(M_PI*sqrt_s);
413 return 1. / std::abs(inv_jac);
428 std::vector<Value<LorentzVector>> m_particles;
429 std::vector<Value<LorentzVector>> m_branches;
433 std::shared_ptr<SolutionCollection> solutions = produce<SolutionCollection>(
"solutions");
445 .OptionalInputs(
"branches")
446 .Input(
"met=met::p4")
448 .GlobalAttr(
"energy:double")
449 .Attr(
"pT_is_met:bool=false")
450 .Attr(
"m1:double=0.")
451 .Attr(
"m2:double=0.");
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.
Parent class for all the modules.
A class encapsulating a lua table.
Module(PoolPtr pool, const std::string &name)
Constructor.
virtual Status work() override
Main function.
Final (main) Block D, describing
bool solve2Quads(const double a20, const double a02, const double a11, const double a10, const double a01, const double a00, const double b20, const double b02, const double b11, const double b10, const double b01, const double b00, std::vector< double > &E1, std::vector< double > &E2, bool verbose=false)
Solve a system of two quadratic equations.