72{
73
74
75 XYZVector thrust_axis, trial_axis, base_axis;
76 auto end = momenta.end();
77 auto begin = momenta.begin();
78 decltype(begin) itr;
79
80 double sum_magnitude_mom = 0.;
81 double thrust = 0.;
82
83
84
85
86
87 for (auto const& momentum : momenta)
88 sum_magnitude_mom += momentum.R();
89
90
91
92
93
94
95 for (auto const& mom : momenta) {
96
97 trial_axis = (mom.Z() >= 0.) ? XYZVector(mom) : XYZVector(-mom);
98
99
100 trial_axis = trial_axis.Unit();
101
102
103
104
105
106
107 itr = begin;
108 while (itr != end) {
109 base_axis = trial_axis;
110 trial_axis = XYZVector();
111
112
113 for (auto const& momentum : momenta)
114 trial_axis += (momentum.Dot(base_axis) >= 0.) ? \
115 XYZVector(momentum) : XYZVector(-momentum);
116
117
118
119
120
121 for (itr = begin; itr != end; itr++)
122 if ((*itr).Dot(trial_axis) * (*itr).Dot(base_axis) < 0.) break;
123
124
125
126
127
128
129
130
131 }
132
133 double trial_mag(trial_axis.R());
134
135
136
137
138
139
140
141
142 double trial_thrust(0.);
143 for (auto const& momentum : momenta)
144 trial_thrust += std::fabs(momentum.Dot(trial_axis));
145
146 trial_thrust /= (sum_magnitude_mom * trial_mag);
147
148
149
150
151
152 if (trial_thrust > thrust) {
153 thrust = trial_thrust;
154 thrust_axis = trial_axis / trial_mag;
155
156 }
157
158
159
160
161
162 }
163
164
165
166
167 thrust_axis *= thrust;
168 return thrust_axis;
169}