11#include " FCCAnalyses/Algorithms.h"
2+ #include " FCCAnalyses/Utils.h"
23#include " Math/Minimizer.h"
34#include " Math/IFunction.h"
45#include " Math/Factory.h"
@@ -163,6 +164,150 @@ ROOT::VecOps::RVec<float> minimize_thrust::operator()(const ROOT::VecOps::RVec<f
163164}
164165
165166
167+ ROOT::VecOps::RVec<float > Algorithms::calculate_thrust::operator ()(
168+ const ROOT::VecOps::RVec<float >& px,
169+ const ROOT::VecOps::RVec<float >& py,
170+ const ROOT::VecOps::RVec<float >& pz) {
171+
172+ if (px.size () != py.size ()) {
173+ throw std::domain_error (" calculate_thrust: Input vector sizes are not equal." );
174+ }
175+ if (px.size () != pz.size ()) {
176+ throw std::domain_error (" calculate_thrust: Input vector sizes are not equal." );
177+ }
178+
179+ ROOT::VecOps::RVec<float > result;
180+
181+ size_t nParticles = px.size ();
182+ if (nParticles < 2 ) {
183+ // std::cout << "calculate_thrust: Number of input particles too small."
184+ // << std::endl;
185+
186+ result.push_back (-1 );
187+ result.push_back (-1 );
188+ result.push_back (-1 );
189+ result.push_back (-1 );
190+
191+ return result;
192+ }
193+
194+ // std::cout << "calculate_thrust: Calculating sum of all particles in event"
195+ // << std::endl;
196+
197+ // Array to store x, y, z and magnitude squared of the particles.
198+ // 0 -- magnitude squared, 1 -- x, 2 -- y, 3 -- z
199+ float pArr[nParticles][4 ];
200+ float pSum = 0 .;
201+ for (size_t i = 0 ; i < nParticles; ++i) {
202+ pArr[i][1 ] = px[i];
203+ pArr[i][2 ] = py[i];
204+ pArr[i][3 ] = pz[i];
205+ mag2 (pArr[i]);
206+ pSum += std::sqrt (pArr[i][0 ]);
207+ }
208+
209+ // Trying all combinations of reference vector orthogonal to two selected
210+ // particles.
211+ // std::cout << "Trying all combinations..." << std::endl;
212+ float pMax[4 ] = {0 ., 0 ., 0 ., 0 .};
213+ for (size_t i = 0 ; i < nParticles - 1 ; ++i) {
214+ for (size_t j = i + 1 ; j < nParticles; ++j) {
215+ float nRef[4 ];
216+ cross (nRef, pArr[i], pArr[j]);
217+ mag2 (nRef);
218+ unit (nRef);
219+
220+ float pPart[4 ] = {0 ., 0 ., 0 ., 0 .};
221+ for (size_t k = 0 ; k < nParticles; ++k) {
222+ if (k == i || k == j) {
223+ continue ;
224+ }
225+
226+ if (dot (nRef, pArr[k]) > 0 .) {
227+ plus (pPart, pPart, pArr[k]);
228+ } else {
229+ minus (pPart, pPart, pArr[k]);
230+ }
231+ }
232+
233+ float pFullArr[4 ][4 ];
234+ // pPart + pArr[i] + pArr[j]
235+ plus (pFullArr[0 ], pPart, pArr[i]);
236+ plus (pFullArr[0 ], pFullArr[0 ], pArr[j]);
237+
238+ // pPart + pArr[i] - pArr[j]
239+ plus (pFullArr[1 ], pPart, pArr[i]);
240+ minus (pFullArr[1 ], pFullArr[1 ], pArr[j]);
241+
242+ // pPart - pArr[i] + pArr[j]
243+ minus (pFullArr[2 ], pPart, pArr[i]);
244+ plus (pFullArr[2 ], pFullArr[2 ], pArr[j]);
245+
246+ // pPart - pArr[i] - pArr[j]
247+ minus (pFullArr[3 ], pPart, pArr[i]);
248+ minus (pFullArr[3 ], pFullArr[3 ], pArr[j]);
249+
250+ for (size_t k = 0 ; k < 4 ; ++k) {
251+ mag2 (pFullArr[k]);
252+ if (pFullArr[k][0 ] > pMax[0 ]) {
253+ copy (pMax, pFullArr[k]);
254+ }
255+ }
256+ }
257+ }
258+
259+ float pMaxMag = std::sqrt (pMax[0 ]);
260+ // std::cout << "Thrust value arr: " << pMaxMag / pSum << std::endl;
261+ result.push_back (pMaxMag / pSum);
262+ // Normalizing the thrust vector
263+ result.push_back (pMax[1 ]/pMaxMag);
264+ result.push_back (pMax[2 ]/pMaxMag);
265+ result.push_back (pMax[3 ]/pMaxMag);
266+
267+ return result;
268+ }
269+
270+ inline void Algorithms::calculate_thrust::mag2 (float (&vec)[4]) {
271+ vec[0 ] = vec[1 ]*vec[1 ] + vec[2 ]*vec[2 ] + vec[3 ]*vec[3 ];
272+ }
273+
274+ inline float Algorithms::calculate_thrust::dot (float vec1[4 ], float vec2[4 ]) {
275+ return vec1[1 ]*vec2[1 ] + vec1[2 ]*vec2[2 ] + vec1[3 ]*vec2[3 ];
276+ }
277+
278+ inline void Algorithms::calculate_thrust::cross (float (&vec)[4], float vec1[4], float vec2[4]) {
279+ vec[1 ] = vec1[2 ]*vec2[3 ] - vec1[3 ]*vec2[2 ];
280+ vec[2 ] = vec1[3 ]*vec2[1 ] - vec1[1 ]*vec2[3 ];
281+ vec[3 ] = vec1[1 ]*vec2[2 ] - vec1[2 ]*vec2[1 ];
282+ }
283+
284+ inline void Algorithms::calculate_thrust::unit (float (&vec)[4]) {
285+ float mag = std::sqrt (vec[0 ]);
286+ vec[1 ] = vec[1 ]/mag;
287+ vec[2 ] = vec[2 ]/mag;
288+ vec[3 ] = vec[3 ]/mag;
289+ }
290+
291+ inline void Algorithms::calculate_thrust::plus (float (&vec)[4], float vecIn1[4], float vecIn2[4]) {
292+ vec[1 ] = vecIn1[1 ] + vecIn2[1 ];
293+ vec[2 ] = vecIn1[2 ] + vecIn2[2 ];
294+ vec[3 ] = vecIn1[3 ] + vecIn2[3 ];
295+ }
296+
297+ inline void Algorithms::calculate_thrust::minus (float (&vecOut)[4], float vecIn1[4], float vecIn2[4]) {
298+ vecOut[1 ] = vecIn1[1 ] - vecIn2[1 ];
299+ vecOut[2 ] = vecIn1[2 ] - vecIn2[2 ];
300+ vecOut[3 ] = vecIn1[3 ] - vecIn2[3 ];
301+ }
302+
303+ inline void Algorithms::calculate_thrust::copy (float (&vecOut)[4], float vecIn[4]) {
304+ vecOut[0 ] = vecIn[0 ];
305+ vecOut[1 ] = vecIn[1 ];
306+ vecOut[2 ] = vecIn[2 ];
307+ vecOut[3 ] = vecIn[3 ];
308+ }
309+
310+
166311getAxisCharge::getAxisCharge (bool arg_pos,
167312 float arg_power){
168313 _pos = arg_pos;
@@ -185,7 +330,6 @@ float getAxisCharge::operator() (const ROOT::VecOps::RVec<float> & angle,
185330}
186331
187332
188-
189333getAxisMass::getAxisMass (bool arg_pos){
190334 _pos=arg_pos;
191335}
0 commit comments