22 #include "fastjet/tools/Recluster.hh" 23 #include "fastjet/CompositeJetStructure.hh" 24 #include <fastjet/ClusterSequenceActiveAreaExplicitGhosts.hh> 46 FASTJET_BEGIN_NAMESPACE
48 LimitedWarning 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())){
217 void 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));
248 void 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);
296 cs->delete_self_when_unused();
313 bool 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;
332 void 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);
362 bool 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;
383 bool 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;
417 FASTJET_END_NAMESPACE
const JetDefinition & jet_def() const
return a reference to the jet definition
vector< PseudoJet > sorted_by_pt(const vector< PseudoJet > &jets)
return a vector of jets sorted into decreasing kt2
virtual bool has_area() const
check if it has a defined area
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...
std::string description_no_recombiner() const
returns a description not including the recombiner information
PseudoJetStructureBase * structure_non_const_ptr()
return a non-const pointer to the structure (of type PseudoJetStructureBase*) associated with this Ps...
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.
static std::string algorithm_description(const JetAlgorithm jet_alg)
a short textual description of the algorithm jet_alg
The structure for a jet made of pieces.
void warn(const char *warning)
outputs a warning to standard error (or the user's default warning stream if set) ...
keep only the hardest inclusive jet and return a "standard" jet with an associated ClusterSequence [t...
Keep
the various options for the output of Recluster
base class corresponding to errors that can be thrown by FastJet
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; ...
static const double max_allowable_R
R values larger than max_allowable_R are not allowed.
virtual bool has_constituents() const
returns true if the PseudoJet has constituents
void discard_area()
disable the area of the composite jet
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 ...
static unsigned int n_parameters_for_algorithm(const JetAlgorithm jet_alg)
the number of parameters associated to a given jet algorithm
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.
the longitudinally invariant variant of the cambridge algorithm (aka Aachen algoithm).
Selector SelectorIsPureGhost()
select objects that are (or are only made of) ghosts.
std::string description() const
return a textual description of the current jet definition
JetAlgorithm
the various families of jet-clustering algorithm
Class to contain pseudojets, including minimal information of use to jet-clustering routines...
Recluster()
default constructor (uses an undefined JetDefinition, and so cannot be used directly).
class that is intended to hold a full definition of the jet clusterer
virtual std::string description() const
class description