ATLAS Offline Software
Loading...
Searching...
No Matches
JetSubStructureUtils::Thrust Class Reference

#include <Thrust.h>

Inheritance diagram for JetSubStructureUtils::Thrust:
Collaboration diagram for JetSubStructureUtils::Thrust:

Public Member Functions

virtual std::map< std::string, double > result (const fastjet::PseudoJet &jet) const
virtual TOut result (const xAOD::Jet &jet) const

Detailed Description

Member Function Documentation

◆ result() [1/2]

map< string, double > Thrust::result ( const fastjet::PseudoJet & jet) const
virtual

Definition at line 12 of file Reconstruction/Jet/JetSubStructureUtils/Root/Thrust.cxx.

13{
14 map<string, double> Variables;
15 Variables["ThrustMin"] = -999. * 1000.;
16 Variables["ThrustMaj"] = -999. * 1000.;
17
18 vector<fastjet::PseudoJet> clusters = boostToCenterOfMass(jet, jet.constituents());
19 if(clusters.size() < 2) return Variables;
20
21 const bool useThreeD = true;
22
23 /*
24 This code is recopied from Atlas Code (Rolf Seuster)
25
26 Finding the thrust axis in an event is not trivial.
27
28 Here, we follow the procedure described in the PYTHIA manual JHEP 05 (2006) 026,
29 also hep-ph/0603175. The approach is to use an iterative method, which usually
30 converges quickly. As the minimization can find just a local minimum, different
31 starting points for the thrust axis are tried. By default, first the direction
32 of the four most energetic particles are tried, if their result disagrees, all
33 16 permutations of the sum of all 4 particles are tried (with coefficients +- 1)
34
35 Note, that the thrust is calculated for _ALL_ particles. If you want only a subset
36 of particles, you have to apply a cut beforehand.
37 See e.g. Reconstruction/EventShapes/EventShapeTools for examples.
38 */
39
40 double thrust_major = -1;
41 double thrust_minor = -1;
42
43 if(clusters.size() < 4) return Variables;
44
45 std::vector<fastjet::PseudoJet>::const_iterator iBeg = clusters.begin();
46 std::vector<fastjet::PseudoJet>::const_iterator iEnd = clusters.end();
47
48 TVector3 thrust(0,0,0);
49
50 int agree = 0;
51 int disagree = 0;
52
53 TVector3 n_0[20];
54 short add0[20] = { 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1,-1 };
55 short add1[20] = { 0, 1, 0, 0, 1, 1, 1, 1,-1,-1,-1,-1, 1, 1, 1, 1,-1,-1,-1,-1 };
56 short add2[20] = { 0, 0, 1, 0, 1, 1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1 };
57 short add3[20] = { 0, 0, 0, 1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1 };
58
59 std::vector<fastjet::PseudoJet> clusters_Esorted = fastjet::sorted_by_E(clusters);
60 std::vector<fastjet::PseudoJet> v_copy(4);
61 for(int i=0; i<4; i++) {
62 v_copy[i] = clusters_Esorted[i];
63 }
64
65 int n_tests = 0;
66 int max_tests = min<int>(20, distance(iBeg, iEnd));
67 do {
68 n_0[n_tests]=TVector3(0,0,0);
69
70 // assign direction of four most energetic particles
71 n_0[n_tests] +=
72 add0[n_tests] * TVector3(v_copy.at(0).px(), v_copy.at(0).py(), v_copy.at(0).pz()) +
73 add1[n_tests] * TVector3(v_copy.at(1).px(), v_copy.at(1).py(), v_copy.at(1).pz()) +
74 add2[n_tests] * TVector3(v_copy.at(2).px(), v_copy.at(2).py(), v_copy.at(2).pz()) +
75 add3[n_tests] * TVector3(v_copy.at(3).px(), v_copy.at(3).py(), v_copy.at(3).pz());
76
77 if (!useThreeD)
78 n_0[n_tests].SetZ(0);
79
80 // protect against small number of input particles (smaller than 4!)
81 if (n_0[n_tests].Mag() > 0)
82 n_0[n_tests] *= 1/n_0[n_tests].Mag();
83
84 int loop = 0;
85 bool run = false;
86 do {
87 TVector3 n_1(0,0,0);
88 for (std::vector<fastjet::PseudoJet>::const_iterator i = iBeg; i != iEnd; ++i) {
89 const fastjet::PseudoJet &itr = *i;
90 if ((itr).px() * n_0[n_tests].x() +
91 (itr).py() * n_0[n_tests].y() +
92 (itr).pz() * n_0[n_tests].z() > 0)
93 n_1 += TVector3((itr).px(), (itr).py(), (itr).pz());
94 else
95 n_1 -= TVector3((itr).px(), (itr).py(), (itr).pz());
96 }
97
98 if (!useThreeD)
99 n_1.SetZ(0);
100
101 // protect against few number of input particles (smaller than 4!)
102 if (n_1.Mag() > 0)
103 n_1 *= 1/n_1.Mag();
104
105 // has axis changed ? if so, try at most ten times (thrust axis has two fold ambiguity)
106 run = (n_0[n_tests] != n_1) && (-n_0[n_tests] != n_1) && loop++ < 10;
107 n_0[n_tests] = n_1;
108 } while (run);
109
110 // agrees or disagrees with first result ?
111 // thrust has a sign ambiguity
112 if (n_tests > 0 && (n_0[0] == n_0[n_tests] || n_0[0] == -n_0[n_tests])) agree++;
113 if (n_tests > 0 && n_0[0] != n_0[n_tests] && n_0[0] != -n_0[n_tests]) disagree++;
114
115 // stop if four first tries give same result (no test for first try! )
116 // if not, try at most max_tests combinations
117 } while ((disagree > 0 || agree < 4) && ++n_tests < max_tests);
118
119 // now that we have the thrust axis, we determine the thrust value
120 // if the various calculations of the thrust axes disagree, try all
121 // and take the maximum, calculate minor and mayor axis
122 n_tests = 0;
123
124
125 do {
126 double denominator = 0;
127 double numerator_t = 0;
128 double numerator_m = 0;
129 for(std::vector<fastjet::PseudoJet>::const_iterator i = iBeg; i != iEnd; ++i) {
130 const fastjet::PseudoJet & itr = *i;
131
132 TLorentzVector v((itr).px(), (itr).py(), (itr).pz(), (itr).e());
133 TVector3 c(v.Vect());
134 numerator_t += fabs(c.Dot(n_0[n_tests]));
135 numerator_m += (c.Cross(n_0[n_tests])).Mag();
136 denominator += c.Mag();
137 }
138
139 if(denominator < 1e-20) { //FPE
140 return Variables;
141 }
142
143 if (numerator_t / denominator > thrust_major) {
144 thrust_major = numerator_t / denominator;
145 thrust_minor = numerator_m / denominator;
146 thrust=n_0[n_tests];
147 }
148 } while (disagree > 0 && ++n_tests < max_tests);
149
150 Variables["ThrustMin"] = thrust_minor;
151 Variables["ThrustMaj"] = thrust_major;
152
153 return Variables;
154}
#define y
#define x
#define z
#define min(a, b)
Definition cfImp.cxx:40
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
CLHEP::Hep3Vector thrust(const I4MomIter_t &iBeg, const I4MomIter_t &iEnd, double &thrust_major, double &thrust_minor, bool useThreeD=false)
std::vector< fastjet::PseudoJet > boostToCenterOfMass(const fastjet::PseudoJet &jet, std::vector< fastjet::PseudoJet > constituents)

◆ result() [2/2]

virtual TOut JetSubStructureUtils::SubstructureCalculator< TOut >::result ( const xAOD::Jet & jet) const
inlinevirtual

Reimplemented from JetSubStructureUtils::SubstructureCalculator< std::map< std::string, double > >.

Definition at line 25 of file SubstructureCalculator.h.

25 {
26 // PS 4/18 master developent
27 // std::vector<fastjet::PseudoJet> constit_pseudojets =
28 // jet::JetConstituentFiller::constituentPseudoJets(jet);
29
30 std::vector<fastjet::PseudoJet> constit_pseudojets;
31 std::transform(jet.getConstituents().begin(),
32 jet.getConstituents().end(),
33 std::back_inserter(constit_pseudojets),
34 [](const auto& c){
35 const xAOD::IParticle* ip = c->rawConstituent();
36 return
37 // fastjet::PseudoJet((c->rawConstituent())->p4());
38 fastjet::PseudoJet(ip->p4());
39 });
40
41 fastjet::PseudoJet pjet = fastjet::join(constit_pseudojets);
42
43 return result(pjet);
44 }
virtual std::map< std::string, double > result(const fastjet::PseudoJet &jet) const
iterator begin() const
iterator on the first constituent
iterator end() const
iterator after the last constituent
JetConstituentVector getConstituents() const
Return a vector of consituents. The object behaves like vector<const IParticle*>. See JetConstituentV...
Definition Jet_v1.cxx:147

The documentation for this class was generated from the following files: