19 #include <momemta/ParameterSet.h> 20 #include <momemta/Module.h> 21 #include <momemta/Solution.h> 23 #include <momemta/InputTag.h> 24 #include <momemta/Types.h> 26 #include <Math/GenVector/VectorUtil.h> 74 sqrt_s = parameters.globalParameters().get<
double>(
"energy");
76 s12 = get<double>(parameters.get<
InputTag>(
"s12"));
78 p1 = get<LorentzVector>(parameters.get<
InputTag>(
"p1"));
79 p2 = get<LorentzVector>(parameters.get<
InputTag>(
"p2"));
82 virtual Status
work()
override {
86 const double m1 = p1->M();
87 const double sq_m1 =
SQ(m1);
88 const double m2 = p2->M();
89 const double sq_m2 =
SQ(m2);
92 if (*s12 >=
SQ(sqrt_s) || sq_m1 + sq_m2 >= *s12)
95 std::vector<double> E1_solutions;
96 const double theta1 = p1->Theta();
97 const double phi1 = p1->Phi();
99 const double E2 = p2->E();
100 const double norm2 = p2->P();
102 const double cos_theta12 = ROOT::Math::VectorUtil::CosTheta(*p1, *p2);
105 const double quadraticTerm = 4 *
SQ(E2) - 4 *
SQ(norm2) *
SQ(cos_theta12);
106 const double linearTerm = 4 * E2 * (sq_m1 + sq_m2 - *s12);
107 const double indepTerm =
SQ(sq_m1 + sq_m2 - *s12) + 4 * sq_m1 *
SQ(norm2) *
SQ(cos_theta12);
109 bool foundSolution =
solveQuadratic(quadraticTerm, linearTerm, indepTerm, E1_solutions);
111 if (!foundSolution) {
115 for (
const double& E1: E1_solutions) {
117 if (E1 <= 0 || E1 <= m1)
121 if ((sq_m1 + sq_m2 + 2 * E1 * E2 - *s12) * cos_theta12 < 0)
124 LorentzVector gen_p1_sol;
125 double norm1 = std::sqrt(
SQ(E1) - sq_m1);
126 double gen_pt1_sol = norm1 * std::sin(theta1);
127 gen_p1_sol.SetPxPyPzE(
128 gen_pt1_sol * std::cos(phi1),
129 gen_pt1_sol * std::sin(phi1),
130 norm1 * std::cos(theta1),
133 if (!
ApproxComparison(gen_p1_sol.M() / gen_p1_sol.E(), m1 / gen_p1_sol.E())) {
135 LOG(trace) <<
"[SecondaryBlockCD] Throwing solution because of invalid mass. " <<
136 "Expected " << m1 <<
", got " << gen_p1_sol.M();
144 LOG(trace) <<
"[SecondaryBlockCD] Throwing solution because of invalid invariant mass. " <<
145 "Expected " << *s12 <<
", got " << (gen_p1_sol + *p2).M2();
151 double jacobian = std::abs( std::sin(theta1) *
SQ(norm1) / (32 *
CB(M_PI) * (norm1 * E2 - E1 * norm2 * cos_theta12)) );
153 Solution s { {gen_p1_sol}, jacobian,
true };
154 solutions->push_back(s);
157 return (solutions->size() > 0) ? Status::OK : Status::NEXT;
169 std::shared_ptr<SolutionCollection> solutions = produce<SolutionCollection>(
"solutions");
177 .GlobalAttr(
"energy: double");
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 .
Parent class for all the modules.
A class encapsulating a lua table.
virtual Status work() override
Main function.
Module(PoolPtr pool, const std::string &name)
Constructor.
Secondary Block C/D, describing .