31 #include "fastjet/tools/Pruner.hh" 
   32 #include "fastjet/ClusterSequenceActiveAreaExplicitGhosts.hh" 
   33 #include "fastjet/Selector.hh" 
   42 FASTJET_BEGIN_NAMESPACE      
 
   57   : _jet_def(jet_def), _zcut(0), _Rcut_factor(0),
 
   58     _zcut_dyn(zcut_dyn), _Rcut_dyn(Rcut_dyn), _get_recombiner_from_jet(false)  {
 
   59   assert(_zcut_dyn != 0 && _Rcut_dyn != 0);
 
   67     throw Error(
"Pruner: trying to apply the Pruner transformer to a jet that has no constituents");
 
   72   bool do_areas = jet.
has_area() && _check_explicit_ghosts(jet);
 
   75   double Rcut = (_Rcut_dyn) ? (*_Rcut_dyn)(jet) : _Rcut_factor * 2.0*jet.
m()/jet.
perp();
 
   76   double zcut = (_zcut_dyn) ? (*_zcut_dyn)(jet) : _zcut;
 
   77   PruningPlugin * pruning_plugin;
 
   81   if (_get_recombiner_from_jet) {
 
   87     if (_check_common_recombiner(jet, jet_def_for_recombiner)){
 
   90     pruning_plugin = 
new PruningPlugin(jet_def, zcut, Rcut);
 
   92     pruning_plugin = 
new PruningPlugin(_jet_def, zcut, Rcut);
 
  104     vector<PseudoJet> particles, ghosts;
 
  109     double ghost_area = (ghosts.size()) ? ghosts[0].area() : 0.01;
 
  134 bool Pruner::_check_explicit_ghosts(
const PseudoJet &jet)
 const{
 
  142     vector<PseudoJet> pieces = jet.
pieces();
 
  143     for (
unsigned int i=0;i<pieces.size(); i++)
 
  144       if (!_check_explicit_ghosts(pieces[i])) 
return false;
 
  159 bool Pruner::_check_common_recombiner(
const PseudoJet &jet, 
 
  160                                       JetDefinition &jet_def_for_recombiner,
 
  161                                       bool assigned)
 const{
 
  162   if (jet.has_associated_cluster_sequence()){
 
  165       return jet.validated_cs()->jet_def().has_same_recombiner(jet_def_for_recombiner);
 
  168     jet_def_for_recombiner = jet.validated_cs()->jet_def();
 
  174   if (jet.has_pieces()){
 
  175     vector<PseudoJet> pieces = jet.pieces();
 
  176     if (pieces.size() == 0) 
return false;
 
  177     for (
unsigned int i=0;i<pieces.size(); i++)
 
  178       if (!_check_common_recombiner(pieces[i], jet_def_for_recombiner, assigned)) 
return false;
 
  191   oss << 
"Pruner with jet_definition = (" << _jet_def.
description() << 
")";
 
  193     oss << 
", dynamic zcut (" << _zcut_dyn->
description() << 
")" 
  194         << 
", dynamic Rcut (" << _Rcut_dyn->
description() << 
")";
 
  196     oss << 
", zcut = " << _zcut
 
  197         << 
", Rcut_factor = " << _Rcut_factor;
 
  221 void PruningRecombiner::recombine(
const PseudoJet &pa, 
 
  225   _recombiner->recombine(pa, pb, p);
 
  232   double pt2a = pa.
perp2();
 
  233   double pt2b = pb.
perp2();
 
  237     if (pt2a<_zcut2*p.
perp2()){
 
  243     if (pt2b<_zcut2*p.
perp2()) {
 
  252 string PruningRecombiner::description()
 const{
 
  254   oss << 
"Pruning recombiner with zcut = " << sqrt(_zcut2)
 
  255       << 
", Rcut = " << sqrt(_Rcut2)
 
  256       << 
", and underlying recombiner = " << _recombiner->
description();
 
  267 void PruningPlugin::run_clustering(ClusterSequence &input_cs)
 const{
 
  269   PruningRecombiner pruning_recombiner(_zcut, _Rcut, _jet_def.recombiner());
 
  270   JetDefinition jet_def = _jet_def;
 
  271   jet_def.set_recombiner(&pruning_recombiner);
 
  274   ClusterSequence internal_cs(input_cs.jets(), jet_def);
 
  275   const vector<ClusterSequence::history_element> & internal_hist = internal_cs.history();
 
  278   vector<bool> kept(internal_hist.size(), 
true);
 
  279   const vector<unsigned int> &pr_rej = pruning_recombiner.rejected();
 
  280   for (
unsigned int i=0;i<pr_rej.size(); i++) kept[pr_rej[i]]=
false;
 
  286   vector<unsigned int> internal2input(internal_hist.size());
 
  287   for (
unsigned int i=0; i<input_cs.jets().size(); i++)
 
  288     internal2input[i] = i;
 
  290   for (
unsigned int i=input_cs.jets().size(); i<internal_hist.size(); i++){
 
  291     const ClusterSequence::history_element &he = internal_hist[i];
 
  294     if (he.parent2 == ClusterSequence::BeamJet){
 
  295       int internal_jetp_index = internal_hist[he.parent1].jetp_index;
 
  296       int internal_hist_index = internal_cs.jets()[internal_jetp_index].cluster_hist_index();
 
  298       int input_jetp_index = input_cs.history()[internal2input[internal_hist_index]].jetp_index;
 
  303       input_cs.plugin_record_iB_recombination(input_jetp_index, he.dij);
 
  308     if (!kept[he.parent1]){ 
 
  309       internal2input[i]=internal2input[he.parent2];
 
  314     } 
else if (!kept[he.parent2]){ 
 
  315       internal2input[i]=internal2input[he.parent1];
 
  322       input_cs.plugin_record_ij_recombination(input_cs.history()[internal2input[he.parent1]].jetp_index,
 
  323                                               input_cs.history()[internal2input[he.parent2]].jetp_index,
 
  324                                               he.dij, internal_cs.jets()[he.jetp_index], new_index);
 
  325       internal2input[i]=input_cs.jets()[new_index].cluster_hist_index();
 
  334 string PruningPlugin::description()
 const{
 
  336   oss << 
"Pruning plugin with jet_definition = (" << _jet_def.description()
 
  337       <<
"), zcut = " << _zcut
 
  338       << 
", Rcut = " << _Rcut;
 
  343 FASTJET_END_NAMESPACE