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
std::string description() const
return a string describing what kind of PseudoJet we are dealing with
const ClusterSequenceAreaBase * validated_csab() const
shorthand for validated_cluster_sequence_area_base()
vector< PseudoJet > sorted_by_pt(const vector< PseudoJet > &jets)
return a vector of jets sorted into decreasing kt2
void sift(const std::vector< PseudoJet > &jets, std::vector< PseudoJet > &jets_that_pass, std::vector< PseudoJet > &jets_that_fail) const
sift the input jets into two vectors – those that pass the selector and those that do not ...
Selector SelectorNHardest(unsigned int n)
select the n hardest objects
int cluster_hist_index() const
return the cluster_hist_index, intended to be used by clustering routines.
virtual const ClusterSequence * validated_cs() const
if the jet has a valid associated cluster sequence then return a pointer to it; otherwise throw an er...
void delete_plugin_when_unused()
calling this causes the JetDefinition to handle the deletion of the plugin when it is no longer used ...
std::vector< PseudoJet > inclusive_jets(const double ptmin=0.0) const
return a vector of all jets (in the sense of the inclusive algorithm) with pt >= ptmin.
virtual bool has_explicit_ghosts() const
returns true if ghosts are explicitly included within jets for this ClusterSequence; ...
virtual bool has_constituents() const
returns true if the PseudoJet has constituents
virtual std::vector< PseudoJet > pieces() const
retrieve the pieces that make up the jet.
virtual bool has_pieces() const
returns true if a jet has pieces
The structure associated with a PseudoJet thas has gone through a Pruner transformer.
std::string description() const
return a textual description of the current jet definition
base class corresponding to errors that can be thrown by FastJet
Like ClusterSequence with computation of the active jet area with the addition of explicit ghosts...
double squared_distance(const PseudoJet &other) const
returns squared cylinder (rap-phi) distance between this jet and another
virtual std::string description() const
returns a description of the function (an empty string by default)
virtual std::string description() const
description
std::vector< PseudoJet > extra_jets() const
return the other jets that may have been found along with the result of the pruning The resulting vec...
an implementation of C++0x shared pointers (or boost's)
void set_recombiner(const Recombiner *recomb)
set the recombiner class to the one provided
void set_structure_shared_ptr(const SharedPtr< PseudoJetStructureBase > &structure)
set the associated structure
double perp() const
returns the scalar transverse momentum
bool has_associated_cluster_sequence() const
returns true if this PseudoJet has an associated ClusterSequence.
virtual bool has_area() const
check if it has a defined area
Selector SelectorIsPureGhost()
select objects that are (or are only made of) ghosts.
double m() const
returns the invariant mass (If m2() is negative then -sqrt(-m2()) is returned, as in CLHEP) ...
void delete_self_when_unused()
by calling this routine you tell the ClusterSequence to delete itself when all the Pseudojets associa...
virtual std::vector< PseudoJet > constituents() const
retrieve the constituents.
Class to contain pseudojets, including minimal information of use to jet-clustering routines...
double perp2() const
returns the squared transverse momentum
class that is intended to hold a full definition of the jet clusterer
virtual PseudoJet result(const PseudoJet &jet) const
action on a single jet