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}