22#include "fastjet/tools/Recluster.hh"
23#include "fastjet/CompositeJetStructure.hh"
24#include "fastjet/ClusterSequenceActiveAreaExplicitGhosts.hh"
46FASTJET_BEGIN_NAMESPACE
48LimitedWarning Recluster::_explicit_ghost_warning;
53 _acquire_recombiner(true), _keep(keep_in), _cambridge_optimisation_enabled(true){}
56 : _acquire_recombiner(true), _keep(keep_in), _cambridge_optimisation_enabled(true){
69 ostr <<
"Recluster with new_jet_def = ";
70 if (_acquire_recombiner){
72 ostr <<
", using a recombiner obtained from the jet being reclustered";
78 ostr <<
" and keeping the hardest inclusive jet";
80 ostr <<
" and joining all inclusive jets into a composite jet";
90 vector<PseudoJet> incljets;
109 vector<PseudoJet> & output_jets)
const{
114 throw Error(
"Recluster can only be applied on jets having constituents");
125 vector<PseudoJet> all_pieces;
126 if ((!_get_all_pieces(input_jet, all_pieces)) || (all_pieces.size()==0)){
127 throw Error(
"Recluster: failed to retrieve all the pieces composing the jet.");
133 if (_acquire_recombiner){
134 _acquire_recombiner_from_pieces(all_pieces, new_jet_def);
152 if (_check_ca(all_pieces, new_jet_def)){
153 _recluster_ca(all_pieces, output_jets, new_jet_def.R());
160 bool include_area_support = input_jet.
has_area();
161 if ((include_area_support) && (!_check_explicit_ghosts(all_pieces))){
162 _explicit_ghost_warning.
warn(
"Recluster: the original cluster sequence is lacking explicit ghosts; area support will no longer be available after re-clustering");
163 include_area_support =
false;
168 _recluster_generic(input_jet, output_jets, new_jet_def, include_area_support);
177 bool ca_optimisation_used)
const{
180 if (incljets.size() > 0) {
190 if (incljets.size()==0)
return join(incljets);
193 *(incljets[0].associated_cluster_sequence()->jet_def().recombiner()));
199 if (ca_optimisation_used){
201 (incljets.size() > 0) &&
202 (! incljets[0].validated_csab()->has_explicit_ghosts())){
217void Recluster::_recluster_ca(
const vector<PseudoJet> & all_pieces,
218 vector<PseudoJet> & subjets,
224 for (vector<PseudoJet>::const_iterator piece_it = all_pieces.begin();
225 piece_it!=all_pieces.end(); piece_it++){
228 vector<PseudoJet> local_subjets;
230 double dcut = Rfilt / cs->
jet_def().R();
236 local_subjets.push_back(*piece_it);
238 local_subjets = piece_it->exclusive_subjets(dcut*dcut);
241 copy(local_subjets.begin(), local_subjets.end(), back_inserter(subjets));
248void Recluster::_recluster_generic(
const PseudoJet & jet,
249 vector<PseudoJet> & incljets,
250 const JetDefinition & new_jet_def,
251 bool do_areas)
const{
265 vector<PseudoJet> regular_constituents, ghosts;
271 double ghost_area = (ghosts.size()) ? ghosts[0].area() : 0.01;
272 ClusterSequenceActiveAreaExplicitGhosts * csa
273 =
new ClusterSequenceActiveAreaExplicitGhosts(regular_constituents,
277 incljets = csa->inclusive_jets();
287 csa->delete_self_when_unused();
291 ClusterSequence * cs =
new ClusterSequence(jet.constituents(), new_jet_def);
292 incljets = cs->inclusive_jets();
296 cs->delete_self_when_unused();
313bool Recluster::_get_all_pieces(
const PseudoJet &jet, vector<PseudoJet> &all_pieces)
const{
314 if (jet.has_associated_cluster_sequence()){
315 all_pieces.push_back(jet);
319 if (jet.has_pieces()){
320 const vector<PseudoJet> pieces = jet.pieces();
321 for (vector<PseudoJet>::const_iterator it=pieces.begin(); it!=pieces.end(); it++)
322 if (!_get_all_pieces(*it, all_pieces))
return false;
332void Recluster::_acquire_recombiner_from_pieces(
const vector<PseudoJet> &all_pieces,
333 JetDefinition &new_jet_def)
const{
335 assert(_acquire_recombiner);
342 const JetDefinition & jd_ref = all_pieces[0].validated_cs()->jet_def();
343 for (
unsigned int i=1; i<all_pieces.size(); i++){
344 if (!all_pieces[i].validated_cs()->jet_def().has_same_recombiner(jd_ref)){
345 throw Error(
"Recluster instance is configured to determine the recombination scheme (or recombiner) from the original jet, but different pieces of the jet were found to have non-equivalent recombiners.");
350 new_jet_def.set_recombiner(jd_ref);
362bool Recluster::_check_explicit_ghosts(
const vector<PseudoJet> &all_pieces)
const{
363 for (vector<PseudoJet>::const_iterator it=all_pieces.begin(); it!=all_pieces.end(); it++)
364 if (! it->validated_csab()->has_explicit_ghosts())
return false;
383bool Recluster::_check_ca(
const vector<PseudoJet> &all_pieces,
384 const JetDefinition &new_jet_def)
const{
386 if (!_cambridge_optimisation_enabled)
return false;
394 const ClusterSequence * cs_ref = all_pieces[0].validated_cs();
396 for (
unsigned int i=1; i<all_pieces.size(); i++)
397 if (all_pieces[i].validated_cs() != cs_ref)
return false;
402 if (!cs_ref->jet_def().has_same_recombiner(new_jet_def))
return false;
406 double Rnew2 = new_jet_def.R();
408 for (
unsigned int i=0; i<all_pieces.size()-1; i++){
409 for (
unsigned int j=i+1; j<all_pieces.size(); j++){
410 if (all_pieces[i].squared_distance(all_pieces[j]) < Rnew2)
return false;
const JetDefinition & jet_def() const
return a reference to the jet definition
The structure for a jet made of pieces.
void discard_area()
disable the area of the composite jet
base class corresponding to errors that can be thrown by FastJet
class that is intended to hold a full definition of the jet clusterer
std::string description() const
return a textual description of the current jet definition
static std::string algorithm_description(const JetAlgorithm jet_alg)
a short textual description of the algorithm jet_alg
static unsigned int n_parameters_for_algorithm(const JetAlgorithm jet_alg)
the number of parameters associated to a given jet algorithm
std::string description_no_recombiner() const
returns a description not including the recombiner information
static const double max_allowable_R
R values larger than max_allowable_R are not allowed.
void warn(const char *warning)
outputs a warning to standard error (or the user's default warning stream if set)
Class to contain pseudojets, including minimal information of use to jet-clustering routines.
PseudoJetStructureBase * structure_non_const_ptr()
return a non-const pointer to the structure (of type PseudoJetStructureBase*) associated with this Ps...
virtual bool has_area() const
check if it has a defined area
virtual bool has_constituents() const
returns true if the PseudoJet has constituents
PseudoJet generate_output_jet(std::vector< PseudoJet > &incljets, bool ca_optimisation_used) const
given a set of inclusive jets and a jet definition used, create the resulting PseudoJet;
bool get_new_jets_and_def(const PseudoJet &input_jet, std::vector< PseudoJet > &output_jets) const
A lower-level method that does the actual work of reclustering the input jet.
Keep
the various options for the output of Recluster
@ keep_only_hardest
keep only the hardest inclusive jet and return a "standard" jet with an associated ClusterSequence [t...
virtual std::string description() const
class description
Recluster()
default constructor (uses an undefined JetDefinition, and so cannot be used directly).
virtual PseudoJet result(const PseudoJet &jet) const
runs the reclustering and sets kept and rejected to be the jets of interest (with non-zero rho,...
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 SelectorIsPureGhost()
select objects that are (or are only made of) ghosts.
JetAlgorithm
the various families of jet-clustering algorithm
@ cambridge_algorithm
the longitudinally invariant variant of the cambridge algorithm (aka Aachen algoithm).
vector< PseudoJet > sorted_by_pt(const vector< PseudoJet > &jets)
return a vector of jets sorted into decreasing kt2