20 #include <momemta/Logging.h> 21 #include <momemta/ParameterSet.h> 22 #include <momemta/Module.h> 23 #include <momemta/Solution.h> 24 #include <momemta/Types.h> 25 #include <momemta/Utils.h> 83 sqrt_s = parameters.globalParameters().get<
double>(
"energy");
85 p1 = get<LorentzVector>(parameters.get<
InputTag>(
"p1"));
86 p2 = get<LorentzVector>(parameters.get<
InputTag>(
"p2"));
88 auto branches_tags = parameters.get<std::vector<InputTag>>(
"branches");
89 for (
auto& t: branches_tags)
90 m_branches.push_back(get<LorentzVector>(t));
91 if (m_branches.empty()) {
92 auto exception = std::invalid_argument(
"BlockA is not valid without at least a third particle in the event.");
93 LOG(fatal) << exception.what();
98 virtual Status
work()
override {
103 for (
size_t i = 0; i < m_branches.size(); i++) {
104 pb += *m_branches[i];
107 double pbx = pb.Px();
108 double pby = pb.Py();
109 const double theta1 = p1->Theta();
110 const double phi1 = p1->Phi();
111 const double theta2 = p2->Theta();
112 const double phi2 = p2->Phi();
113 const double m1 = p1->M();
114 const double m2 = p2->M();
123 std::vector<double> modp1;
124 std::vector<double> modp2;
126 const double sin_theta1 = std::sin(theta1);
127 const double cos_phi1 = std::cos(phi1);
128 const double sin_theta2 = std::sin(theta2);
129 const double cos_phi2 = std::cos(phi2);
130 const double sin_phi1 = std::sin(phi1);
131 const double sin_phi2 = std::sin(phi2);
132 const double cos_theta1 = std::cos(theta1);
133 const double cos_theta2 = std::cos(theta2);
135 const double a10 = sin_theta1 * cos_phi1;
136 const double a01 = sin_theta2 * cos_phi2;
137 const double a00 = pbx;
138 const double b10 = sin_theta1 * sin_phi1;
139 const double b01 = sin_theta2 * sin_phi2;
140 const double b00 = pby;
142 bool foundSolution =
solve2Linear(a10, a01, a00, b10, b01, b00, modp1, modp2,
false);
147 double mod_p1 = modp1[0];
148 double mod_p2 = modp2[0];
149 if (mod_p1 < 0 || mod_p2 < 0)
152 double E1 = sqrt(
SQ(mod_p1) +
SQ(m1));
153 double E2 = sqrt(
SQ(mod_p2) +
SQ(m2));
155 LorentzVector gen_p1(mod_p1 * sin_theta1 * cos_phi1, mod_p1 * sin_theta1 * sin_phi1, mod_p1 * cos_theta1, E1);
156 LorentzVector gen_p2(mod_p2 * sin_theta2 * cos_phi2, mod_p2 * sin_theta2 * sin_phi2, mod_p2 * cos_theta2, E2);
159 LorentzVector tot = gen_p1 + gen_p2 + pb;
160 double q1Pz = std::abs(tot.Pz() + tot.E()) / 2.;
161 double q2Pz = std::abs(tot.Pz() - tot.E()) / 2.;
162 if (q1Pz > sqrt_s / 2 || q2Pz > sqrt_s / 2)
168 LOG(trace) <<
"[BlockA] Throwing solution because total Pt is not null: " << tot.Pt();
173 double jacobian = (
SQ(mod_p1) *
SQ(mod_p2)) / (8 *
SQ(M_PI * sqrt_s) * E1 * E2);
174 jacobian *= 1. / std::abs(cos_phi1 * sin_phi2 - sin_phi1 * cos_phi2);
176 Solution s = { {gen_p1, gen_p2}, jacobian,
true };
177 solutions->push_back(s);
188 std::vector<Value<LorentzVector>> m_branches;
190 std::shared_ptr<SolutionCollection> solutions = produce<SolutionCollection>(
"solutions");
196 .OptionalInputs(
"branches")
198 .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.
Parent class for all the modules.
bool solve2Linear(const double a10, const double a01, const double a00, 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 linear equations.
A class encapsulating a lua table.
Final (main) Block A, describing .
Module(PoolPtr pool, const std::string &name)
Constructor.
virtual Status work() override
Main function.