29 #include "fastjet/tools/Pruner.hh"
30 #include "fastjet/ClusterSequenceActiveAreaExplicitGhosts.hh"
31 #include "fastjet/Selector.hh"
40 FASTJET_BEGIN_NAMESPACE
55 : _jet_def(jet_def), _zcut(0), _Rcut_factor(0),
56 _zcut_dyn(zcut_dyn), _Rcut_dyn(Rcut_dyn), _get_recombiner_from_jet(false) {
57 assert(_zcut_dyn != 0 && _Rcut_dyn != 0);
65 throw Error(
"Pruner: trying to apply the Pruner transformer to a jet that has no constituents");
70 bool do_areas = jet.
has_area() && _check_explicit_ghosts(jet);
73 double Rcut = (_Rcut_dyn) ? (*_Rcut_dyn)(jet) : _Rcut_factor * 2.0*jet.
m()/jet.
perp();
74 double zcut = (_zcut_dyn) ? (*_zcut_dyn)(jet) : _zcut;
75 PruningPlugin * pruning_plugin;
79 if (_get_recombiner_from_jet) {
81 _get_common_recombiner(jet);
82 if (common_recombiner) {
91 pruning_plugin =
new PruningPlugin(jet_def, zcut, Rcut);
95 pruning_plugin =
new PruningPlugin(_jet_def, zcut, Rcut);
98 pruning_plugin =
new PruningPlugin(_jet_def, zcut, Rcut);
110 vector<PseudoJet> particles, ghosts;
115 double ghost_area = (ghosts.size()) ? ghosts[0].area() : 0.01;
138 bool Pruner::_check_explicit_ghosts(
const PseudoJet &jet)
const{
146 vector<PseudoJet> pieces = jet.
pieces();
147 for (
unsigned int i=0;i<pieces.size(); i++)
148 if (!_check_explicit_ghosts(pieces[i]))
return false;
167 const JetDefinition::Recombiner * Pruner::_get_common_recombiner(
const PseudoJet &jet)
const{
168 if (jet.has_associated_cluster_sequence())
169 return jet.validated_cs()->jet_def().recombiner();
172 if (jet.has_pieces()){
173 vector<PseudoJet> pieces = jet.pieces();
174 if (pieces.size() == 0)
return 0;
175 const JetDefinition::Recombiner * reco = _get_common_recombiner(pieces[0]);
176 for (
unsigned int i=1;i<pieces.size(); i++)
177 if (_get_common_recombiner(pieces[i]) != reco)
return 0;
190 oss <<
"Pruner with jet_definition = (" << _jet_def.
description() <<
")";
192 oss <<
", dynamic zcut (" << _zcut_dyn->
description() <<
")"
193 <<
", dynamic Rcut (" << _Rcut_dyn->
description() <<
")";
195 oss <<
", zcut = " << _zcut
196 <<
", Rcut_factor = " << _Rcut_factor;
220 void PruningRecombiner::recombine(
const PseudoJet &pa,
224 _recombiner->recombine(pa, pb, p);
231 double pt2a = pa.
perp2();
232 double pt2b = pb.
perp2();
236 if (pt2a<_zcut2*p.
perp2()){
242 if (pt2b<_zcut2*p.
perp2()) {
251 string PruningRecombiner::description()
const{
253 oss <<
"Pruning recombiner with zcut = " << sqrt(_zcut2)
254 <<
", Rcut = " << sqrt(_Rcut2)
255 <<
", and underlying recombiner = " << _recombiner->
description();
266 void PruningPlugin::run_clustering(ClusterSequence &input_cs)
const{
268 PruningRecombiner pruning_recombiner(_zcut, _Rcut, _jet_def.recombiner());
269 JetDefinition jet_def = _jet_def;
270 jet_def.set_recombiner(&pruning_recombiner);
273 ClusterSequence internal_cs(input_cs.jets(), jet_def);
274 const vector<ClusterSequence::history_element> & internal_hist = internal_cs.history();
277 vector<bool> kept(internal_hist.size(),
true);
278 const vector<unsigned int> &pr_rej = pruning_recombiner.rejected();
279 for (
unsigned int i=0;i<pr_rej.size(); i++) kept[pr_rej[i]]=
false;
285 vector<unsigned int> internal2input(internal_hist.size());
286 for (
unsigned int i=0; i<input_cs.jets().size(); i++)
287 internal2input[i] = i;
289 for (
unsigned int i=input_cs.jets().size(); i<internal_hist.size(); i++){
290 const ClusterSequence::history_element &he = internal_hist[i];
293 if (he.parent2 == ClusterSequence::BeamJet){
294 int internal_jetp_index = internal_hist[he.parent1].jetp_index;
295 int internal_hist_index = internal_cs.jets()[internal_jetp_index].cluster_hist_index();
297 int input_jetp_index = input_cs.history()[internal2input[internal_hist_index]].jetp_index;
302 input_cs.plugin_record_iB_recombination(input_jetp_index, he.dij);
307 if (!kept[he.parent1]){
308 internal2input[i]=internal2input[he.parent2];
313 }
else if (!kept[he.parent2]){
314 internal2input[i]=internal2input[he.parent1];
321 input_cs.plugin_record_ij_recombination(input_cs.history()[internal2input[he.parent1]].jetp_index,
322 input_cs.history()[internal2input[he.parent2]].jetp_index,
323 he.dij, internal_cs.jets()[he.jetp_index], new_index);
324 internal2input[i]=input_cs.jets()[new_index].cluster_hist_index();
333 string PruningPlugin::description()
const{
335 oss <<
"Pruning plugin with jet_definition = (" << _jet_def.description()
336 <<
"), zcut = " << _zcut
337 <<
", Rcut = " << _Rcut;
342 FASTJET_END_NAMESPACE