1 #ifndef __FASTJET_CLUSTERSEQUENCE_HH__
2 #define __FASTJET_CLUSTERSEQUENCE_HH__
37 #include "fastjet/PseudoJet.hh"
44 #include "fastjet/Error.hh"
45 #include "fastjet/JetDefinition.hh"
46 #include "fastjet/SharedPtr.hh"
47 #include "fastjet/LimitedWarning.hh"
48 #include "fastjet/FunctionOfPseudoJet.hh"
49 #include "fastjet/ClusterSequenceStructure.hh"
51 FASTJET_BEGIN_NAMESPACE
55 class ClusterSequenceStructure;
56 class DynamicNearestNeighbours;
73 const std::vector<L> & pseudojets,
75 const bool & writeout_combinations =
false);
79 transfer_from_sequence(cs);
93 std::vector<PseudoJet> inclusive_jets (
const double ptmin = 0.0)
const;
98 int n_exclusive_jets (
const double dcut)
const;
103 std::vector<PseudoJet> exclusive_jets (
const double dcut)
const;
110 std::vector<PseudoJet> exclusive_jets (
const int njets)
const;
117 std::vector<PseudoJet> exclusive_jets_up_to (
const int njets)
const;
122 double exclusive_dmerge (
const int njets)
const;
128 double exclusive_dmerge_max (
const int njets)
const;
142 int njets = n_exclusive_jets_ycut(ycut);
143 return exclusive_jets(njets);
157 std::vector<PseudoJet> exclusive_subjets (
const PseudoJet & jet,
158 const double dcut)
const;
163 int n_exclusive_subjets(
const PseudoJet & jet,
164 const double dcut)
const;
171 std::vector<PseudoJet> exclusive_subjets (
const PseudoJet & jet,
179 std::vector<PseudoJet> exclusive_subjets_up_to (
const PseudoJet & jet,
186 double exclusive_subdmerge(
const PseudoJet & jet,
int nsub)
const;
193 double exclusive_subdmerge_max(
const PseudoJet & jet,
int nsub)
const;
200 double Q()
const {
return _Qtot;}
202 double Q2()
const {
return _Qtot*_Qtot;}
239 std::vector<PseudoJet> constituents (
const PseudoJet & jet)
const;
250 void print_jets_for_root(
const std::vector<PseudoJet> & jets,
251 std::ostream & ostr = std::cout)
const;
255 void print_jets_for_root(
const std::vector<PseudoJet> & jets,
256 const std::string & filename,
257 const std::string & comment =
"")
const;
264 void add_constituents (
const PseudoJet & jet,
265 std::vector<PseudoJet> & subjet_vector)
const;
274 std::string strategy_string (
Strategy strategy_in)
const;
291 void delete_self_when_unused();
298 void signal_imminent_self_deletion()
const;
304 double jet_scale_for_algorithm(
const PseudoJet & jet)
const;
318 assert(plugin_activated());
319 _do_ij_recombination_step(jet_i, jet_j, dij, newjet_k);
325 void plugin_record_ij_recombination(
int jet_i,
int jet_j,
double dij,
334 assert(plugin_activated());
335 _do_iB_recombination_step(jet_i, diB);
348 virtual std::string description()
const {
return "This is a dummy extras class that contains no extra information! Derive from it if you want to use it to provide extra information from a plugin jet finder";}
356 _extras.reset(extras_in);
365 _extras.reset(extras_in.release());
382 assert(plugin_activated());
383 _simple_N2_cluster<GBJ>();
431 enum JetType {Invalid=-3, InexistentParent = -2, BeamJet = -1};
449 const std::vector<PseudoJet> & jets()
const;
462 const std::vector<history_element> & history()
const;
468 unsigned int n_particles()
const;
474 std::vector<int> particle_jet_indices(
const std::vector<PseudoJet> &)
const;
491 std::vector<int> unique_history_order()
const;
496 std::vector<PseudoJet> unclustered_particles()
const;
502 std::vector<PseudoJet> childless_pseudojets()
const;
509 bool contains(
const PseudoJet &
object)
const;
528 return _structure_shared_ptr;
541 static void print_banner();
556 static void set_fastjet_banner_stream(std::ostream * ostr) {_fastjet_banner_ostr = ostr;}
570 static std::ostream * _fastjet_banner_ostr;
580 template<
class L>
void _transfer_input_jets(
581 const std::vector<L> & pseudojets);
587 const bool & writeout_combinations);
593 void _initialise_and_run_no_decant();
605 const bool & writeout_combinations);
611 void _decant_options_partial();
616 void _fill_initial_history();
621 void _do_ij_recombination_step(
const int jet_i,
const int jet_j,
622 const double dij,
int & newjet_k);
626 void _do_iB_recombination_step(
const int jet_i,
const double diB);
633 void _set_structure_shared_ptr(
PseudoJet & j);
637 void _update_structure_use_count();
651 _Parabola(
double a,
double b,
double c) : _a(a), _b(b), _c(c) {}
652 inline double operator()(
const double R)
const {
return _c*(_a*R*R + _b*R + 1);}
663 _Line(
double a,
double b) : _a(a), _b(b) {}
664 inline double operator()(
const double R)
const {
return _a*R + _b;}
688 void get_subhist_set(std::set<const history_element*> & subhist,
689 const PseudoJet & jet,
double dcut,
int maxjet)
const;
691 bool _writeout_combinations;
693 double _Rparam, _R2, _invR2;
699 int _structure_use_count_after_construction;
708 bool _plugin_activated;
711 void _really_dumb_cluster ();
712 void _delaunay_cluster ();
714 template<
class BJ>
void _simple_N2_cluster ();
715 void _tiled_N2_cluster ();
716 void _faster_tiled_N2_cluster ();
719 void _minheap_faster_tiled_N2_cluster();
723 void _CP2DChan_cluster();
724 void _CP2DChan_cluster_2pi2R ();
725 void _CP2DChan_cluster_2piMultD ();
726 void _CP2DChan_limited_cluster(
double D);
727 void _do_Cambridge_inclusive_jets();
730 void _fast_NsqrtN_cluster();
732 void _add_step_to_history(
const int step_number,
const int parent1,
733 const int parent2,
const int jetp_index,
738 void _extract_tree_children(
int pos, std::valarray<bool> &,
739 const std::valarray<int> &, std::vector<int> &)
const;
743 void _extract_tree_parents (
int pos, std::valarray<bool> &,
744 const std::valarray<int> &, std::vector<int> &)
const;
748 typedef std::pair<int,int> TwoVertices;
749 typedef std::pair<double,TwoVertices> DijEntry;
750 typedef std::multimap<double,TwoVertices> DistMap;
753 void _add_ktdistance_to_map(
const int ii,
755 const DynamicNearestNeighbours * DNN);
759 static bool _first_time;
775 double eta, phi, kt2, NN_dist;
784 double eta, phi, kt2, NN_dist;
786 int _jets_index, tile_index, diJ_posn;
791 inline void label_minheap_update_needed() {diJ_posn = 1;}
792 inline void label_minheap_update_done() {diJ_posn = 0;}
793 inline bool minheap_update_needed()
const {
return diJ_posn==1;}
801 template <
class J>
void _bj_set_jetinfo( J *
const jet,
802 const int _jets_index)
const;
806 void _bj_remove_from_tiles( TiledJet *
const jet)
const;
809 template <
class J>
double _bj_dist(
const J *
const jeta,
810 const J *
const jetb)
const;
814 template <
class J>
double _bj_diJ(
const J *
const jeta)
const;
819 template <
class J>
inline J * _bj_of_hindex(
820 const int hist_index,
821 J *
const head, J *
const tail)
824 for(res = head; res<tail; res++) {
825 if (_jets[res->_jets_index].cluster_hist_index() == hist_index) {
break;}
838 template <
class J>
void _bj_set_NN_nocross(J *
const jeta,
839 J *
const head,
const J *
const tail)
const;
845 template <
class J>
void _bj_set_NN_crosscheck(J *
const jeta,
846 J *
const head,
const J *
const tail)
const;
852 static const int n_tile_neighbours = 9;
858 Tile * begin_tiles[n_tile_neighbours];
860 Tile ** surrounding_tiles;
870 std::vector<Tile> _tiles;
871 double _tiles_eta_min, _tiles_eta_max;
872 double _tile_size_eta, _tile_size_phi;
873 int _n_tiles_phi,_tiles_ieta_min,_tiles_ieta_max;
877 inline int _tile_index (
int ieta,
int iphi)
const {
880 return (ieta-_tiles_ieta_min)*_n_tiles_phi
881 + (iphi+_n_tiles_phi) % _n_tiles_phi;
886 int _tile_index(
const double eta,
const double phi)
const;
887 void _tj_set_jetinfo ( TiledJet *
const jet,
const int _jets_index);
888 void _bj_remove_from_tiles(TiledJet *
const jet);
889 void _initialise_tiles();
890 void _print_tiles(TiledJet * briefjets )
const;
891 void _add_neighbours_to_tile_union(
const int tile_index,
892 std::vector<int> & tile_union,
int & n_near_tiles)
const;
893 void _add_untagged_neighbours_to_tile_union(
const int tile_index,
894 std::vector<int> & tile_union,
int & n_near_tiles);
912 void _simple_N2_cluster_BriefJet();
914 void _simple_N2_cluster_EEBriefJet();
925 template<
class L>
void ClusterSequence::_transfer_input_jets(
926 const std::vector<L> & pseudojets) {
930 _jets.reserve(pseudojets.size()*2);
936 for (
unsigned int i = 0; i < pseudojets.size(); i++) {
937 _jets.push_back(pseudojets[i]);}
961 template<
class L> ClusterSequence::ClusterSequence (
962 const std::vector<L> & pseudojets,
964 const bool & writeout_combinations) :
965 _jet_def(jet_def_in), _writeout_combinations(writeout_combinations),
976 _initialise_and_run_no_decant();
1001 std::vector<PseudoJet> jets;
1010 if (jets.size() != 0) {
1022 template <
class J>
inline void ClusterSequence::_bj_set_jetinfo(
1023 J *
const jetA,
const int _jets_index)
const {
1024 jetA->eta = _jets[_jets_index].rap();
1025 jetA->phi = _jets[_jets_index].phi_02pi();
1027 jetA->_jets_index = _jets_index;
1029 jetA->NN_dist = _R2;
1037 template <
class J>
inline double ClusterSequence::_bj_dist(
1038 const J *
const jetA,
const J *
const jetB)
const {
1039 double dphi = std::abs(jetA->phi - jetB->phi);
1040 double deta = (jetA->eta - jetB->eta);
1041 if (dphi > pi) {dphi = twopi - dphi;}
1042 return dphi*dphi + deta*deta;
1046 template <
class J>
inline double ClusterSequence::_bj_diJ(
const J *
const jet)
const {
1047 double kt2 = jet->kt2;
1048 if (jet->NN != NULL) {
if (jet->NN->kt2 < kt2) {kt2 = jet->NN->kt2;}}
1049 return jet->NN_dist * kt2;
1056 template <
class J>
inline void ClusterSequence::_bj_set_NN_nocross(
1057 J *
const jet, J *
const head,
const J *
const tail)
const {
1058 double NN_dist = _R2;
1061 for (J * jetB = head; jetB != jet; jetB++) {
1062 double dist = _bj_dist(jet,jetB);
1063 if (dist < NN_dist) {
1070 for (J * jetB = jet+1; jetB != tail; jetB++) {
1071 double dist = _bj_dist(jet,jetB);
1072 if (dist < NN_dist) {
1079 jet->NN_dist = NN_dist;
1084 template <
class J>
inline void ClusterSequence::_bj_set_NN_crosscheck(J *
const jet,
1085 J *
const head,
const J *
const tail)
const {
1086 double NN_dist = _R2;
1088 for (J * jetB = head; jetB != tail; jetB++) {
1089 double dist = _bj_dist(jet,jetB);
1090 if (dist < NN_dist) {
1094 if (dist < jetB->NN_dist) {
1095 jetB->NN_dist = dist;
1100 jet->NN_dist = NN_dist;
1103 FASTJET_END_NAMESPACE
1105 #endif // __FASTJET_CLUSTERSEQUENCE_HH__
bool will_delete_self_when_unused() const
return true if the object has been told to delete itself when unused
ClusterSequenceStructure StructureType
the structure type associated with a jet belonging to a ClusterSequence
const std::vector< PseudoJet > & jets() const
allow the user to access the internally stored _jets() array, which contains both the initial particl...
void plugin_associate_extras(Extras *extras_in)
the plugin can associate some extra information with the ClusterSequence object by calling this funct...
void _transfer_input_jets(const std::vector< L > &pseudojets)
transfer the vector
of input jets into our own vector _jets (with some reserved space f...
const Extras * extras() const
returns a pointer to the extras object (may be null)
vector< PseudoJet > sorted_by_pt(const vector< PseudoJet > &jets)
return a vector of jets sorted into decreasing kt2
double Q() const
returns the sum of all energies in the event (relevant mainly for e+e-)
void plugin_simple_N2_cluster()
allows a plugin to run a templated clustering (nearest-neighbour heuristic)
std::vector< PseudoJet > operator()(const std::vector< L > &particles) const
cluster the supplied particles and returns a vector of resulting jets, sorted by pt (or energy in the...
ClusterSequence()
default constructor
ClusterSequence(const ClusterSequence &cs)
copy constructor for a ClusterSequence
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.
double Q2() const
return Q()^2
int jetp_index
index in _history where the current jet is recombined with another jet to form its child...
const SharedPtr< PseudoJetStructureBase > & structure_shared_ptr() const
retrieve a shared pointer to the wrapper to this ClusterSequence
Contains any information related to the clustering that should be directly accessible to PseudoJet...
void plugin_record_ij_recombination(int jet_i, int jet_j, double dij, int &newjet_k)
record the fact that there has been a recombination between jets()[jet_i] and jets()[jet_k], with the specified dij, and return the index (newjet_k) allocated to the new jet, whose momentum is assumed to be the 4-vector sum of that of jet_i and jet_j
std::vector< PseudoJet > _jets
This contains the physical PseudoJets; for each PseudoJet one can find the corresponding position in ...
const JetDefinition & jet_def() const
return a reference to the jet definition
std::vector< history_element > _history
this vector will contain the branching history; for each stage, _history[i].jetp_index indicates wher...
class to provide facilities for giving warnings up to some maximum number of times and to provide glo...
int parent2
index in _history where first parent of this jet was created (InexistentParent if this jet is an orig...
double dij
index in the _jets vector where we will find the
void plugin_record_iB_recombination(int jet_i, double diB)
record the fact that there has been a recombination between jets()[jet_i] and the beam...
unsigned int n_particles() const
returns the number of particles that were provided to the clustering algorithm (helps the user find t...
const std::vector< history_element > & history() const
allow the user to access the raw internal history.
vector< PseudoJet > sorted_by_E(const vector< PseudoJet > &jets)
return a vector of jets sorted into decreasing energy
int child
index in _history where second parent of this jet was created (InexistentParent if this jet is an ori...
an implementation of C++0x shared pointers (or boost's)
void plugin_associate_extras(std::auto_ptr< Extras > extras_in)
the plugin can associate some extra information with the ClusterSequence object by calling this funct...
a single element in the clustering history
structure analogous to BriefJet, but with the extra information needed for dealing with tiles ...
Strategy strategy_used() const
return the enum value of the strategy used to cluster the event
bool plugin_activated() const
returns true when the plugin is allowed to run the show.
double exclusive_ymerge(int njets) const
return the ymin corresponding to the recombination that went from n+1 to n jets (sometimes known as y...
bool is_spherical() const
returns true if the jet definition involves an algorithm intended for use on a spherical geometry (e...
static std::ostream * fastjet_banner_stream()
returns a pointer to the stream to be used to print banners (cout by default).
void _decant_options_partial()
assuming that the jet definition, writeout_combinations and _structure_shared_ptr have been set (e...
JetAlgorithm
the various families of jet-clustering algorithm
std::vector< PseudoJet > exclusive_jets_ycut(double ycut) const
the exclusive jets obtained at the given ycut
void delete_self_when_unused()
by calling this routine you tell the ClusterSequence to delete itself when all the Pseudojets associa...
Strategy
the various options for the algorithmic strategy to adopt in clustering events with kt and cambridge ...
bool _deletes_self_when_unused
if true then the CS will delete itself when the last external object referring to it disappears...
Class to contain pseudojets, including minimal information of use to jet-clustering routines...
double max_dij_so_far
the distance corresponding to the recombination at this stage of the clustering.
int n_exclusive_jets_ycut(double ycut) const
the number of exclusive jets at the given ycut
double exclusive_ymerge_max(int njets) const
same as exclusive_dmerge_max, but normalised to squared total energy
class that is intended to hold a full definition of the jet clusterer
double jet_scale_for_algorithm(const PseudoJet &jet) const
returns the scale associated with a jet as required for this clustering algorithm (kt^2 for the kt-al...
std::string strategy_string() const
return the name of the strategy used to cluster the event