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();
648 _Parabola(
double a,
double b,
double c) : _a(a), _b(b), _c(c) {}
649 inline double operator()(
const double R)
const {
return _c*(_a*R*R + _b*R + 1);}
657 _Line(
double a,
double b) : _a(a), _b(b) {}
658 inline double operator()(
const double R)
const {
return _a*R + _b;}
682 void get_subhist_set(std::set<const history_element*> & subhist,
683 const PseudoJet & jet,
double dcut,
int maxjet)
const;
685 bool _writeout_combinations;
687 double _Rparam, _R2, _invR2;
693 int _structure_use_count_after_construction;
702 bool _plugin_activated;
705 void _really_dumb_cluster ();
706 void _delaunay_cluster ();
708 template<
class BJ>
void _simple_N2_cluster ();
709 void _tiled_N2_cluster ();
710 void _faster_tiled_N2_cluster ();
713 void _minheap_faster_tiled_N2_cluster();
717 void _CP2DChan_cluster();
718 void _CP2DChan_cluster_2pi2R ();
719 void _CP2DChan_cluster_2piMultD ();
720 void _CP2DChan_limited_cluster(
double D);
721 void _do_Cambridge_inclusive_jets();
724 void _fast_NsqrtN_cluster();
726 void _add_step_to_history(
const int step_number,
const int parent1,
727 const int parent2,
const int jetp_index,
732 void _extract_tree_children(
int pos, std::valarray<bool> &,
733 const std::valarray<int> &, std::vector<int> &)
const;
737 void _extract_tree_parents (
int pos, std::valarray<bool> &,
738 const std::valarray<int> &, std::vector<int> &)
const;
742 typedef std::pair<int,int> TwoVertices;
743 typedef std::pair<double,TwoVertices> DijEntry;
744 typedef std::multimap<double,TwoVertices> DistMap;
747 void _add_ktdistance_to_map(
const int ii,
749 const DynamicNearestNeighbours * DNN);
753 static bool _first_time;
769 double eta, phi, kt2, NN_dist;
778 double eta, phi, kt2, NN_dist;
780 int _jets_index, tile_index, diJ_posn;
785 inline void label_minheap_update_needed() {diJ_posn = 1;}
786 inline void label_minheap_update_done() {diJ_posn = 0;}
787 inline bool minheap_update_needed()
const {
return diJ_posn==1;}
795 template <
class J>
void _bj_set_jetinfo( J *
const jet,
796 const int _jets_index)
const;
800 void _bj_remove_from_tiles( TiledJet *
const jet)
const;
803 template <
class J>
double _bj_dist(
const J *
const jeta,
804 const J *
const jetb)
const;
808 template <
class J>
double _bj_diJ(
const J *
const jeta)
const;
813 template <
class J>
inline J * _bj_of_hindex(
814 const int hist_index,
815 J *
const head, J *
const tail)
818 for(res = head; res<tail; res++) {
819 if (_jets[res->_jets_index].cluster_hist_index() == hist_index) {
break;}
832 template <
class J>
void _bj_set_NN_nocross(J *
const jeta,
833 J *
const head,
const J *
const tail)
const;
839 template <
class J>
void _bj_set_NN_crosscheck(J *
const jeta,
840 J *
const head,
const J *
const tail)
const;
846 static const int n_tile_neighbours = 9;
852 Tile * begin_tiles[n_tile_neighbours];
854 Tile ** surrounding_tiles;
864 std::vector<Tile> _tiles;
865 double _tiles_eta_min, _tiles_eta_max;
866 double _tile_size_eta, _tile_size_phi;
867 int _n_tiles_phi,_tiles_ieta_min,_tiles_ieta_max;
871 inline int _tile_index (
int ieta,
int iphi)
const {
874 return (ieta-_tiles_ieta_min)*_n_tiles_phi
875 + (iphi+_n_tiles_phi) % _n_tiles_phi;
880 int _tile_index(
const double eta,
const double phi)
const;
881 void _tj_set_jetinfo ( TiledJet *
const jet,
const int _jets_index);
882 void _bj_remove_from_tiles(TiledJet *
const jet);
883 void _initialise_tiles();
884 void _print_tiles(TiledJet * briefjets )
const;
885 void _add_neighbours_to_tile_union(
const int tile_index,
886 std::vector<int> & tile_union,
int & n_near_tiles)
const;
887 void _add_untagged_neighbours_to_tile_union(
const int tile_index,
888 std::vector<int> & tile_union,
int & n_near_tiles);
906 void _simple_N2_cluster_BriefJet();
908 void _simple_N2_cluster_EEBriefJet();
919 template<
class L>
void ClusterSequence::_transfer_input_jets(
920 const std::vector<L> & pseudojets) {
924 _jets.reserve(pseudojets.size()*2);
930 for (
unsigned int i = 0; i < pseudojets.size(); i++) {
931 _jets.push_back(pseudojets[i]);}
955 template<
class L> ClusterSequence::ClusterSequence (
956 const std::vector<L> & pseudojets,
958 const bool & writeout_combinations) :
959 _jet_def(jet_def_in), _writeout_combinations(writeout_combinations),
970 _initialise_and_run_no_decant();
994 std::vector<PseudoJet> jets;
1003 if (jets.size() != 0) {
1015 template <
class J>
inline void ClusterSequence::_bj_set_jetinfo(
1016 J *
const jetA,
const int _jets_index)
const {
1017 jetA->eta =
_jets[_jets_index].rap();
1018 jetA->phi =
_jets[_jets_index].phi_02pi();
1020 jetA->_jets_index = _jets_index;
1022 jetA->NN_dist = _R2;
1030 template <
class J>
inline double ClusterSequence::_bj_dist(
1031 const J *
const jetA,
const J *
const jetB)
const {
1032 double dphi = std::abs(jetA->phi - jetB->phi);
1033 double deta = (jetA->eta - jetB->eta);
1034 if (dphi > pi) {dphi = twopi - dphi;}
1035 return dphi*dphi + deta*deta;
1039 template <
class J>
inline double ClusterSequence::_bj_diJ(
const J *
const jet)
const {
1040 double kt2 = jet->kt2;
1041 if (jet->NN != NULL) {
if (jet->NN->kt2 < kt2) {kt2 = jet->NN->kt2;}}
1042 return jet->NN_dist * kt2;
1049 template <
class J>
inline void ClusterSequence::_bj_set_NN_nocross(
1050 J *
const jet, J *
const head,
const J *
const tail)
const {
1051 double NN_dist = _R2;
1054 for (J * jetB = head; jetB != jet; jetB++) {
1055 double dist = _bj_dist(jet,jetB);
1056 if (dist < NN_dist) {
1063 for (J * jetB = jet+1; jetB != tail; jetB++) {
1064 double dist = _bj_dist(jet,jetB);
1065 if (dist < NN_dist) {
1072 jet->NN_dist = NN_dist;
1077 template <
class J>
inline void ClusterSequence::_bj_set_NN_crosscheck(J *
const jet,
1078 J *
const head,
const J *
const tail)
const {
1079 double NN_dist = _R2;
1081 for (J * jetB = head; jetB != tail; jetB++) {
1082 double dist = _bj_dist(jet,jetB);
1083 if (dist < NN_dist) {
1087 if (dist < jetB->NN_dist) {
1088 jetB->NN_dist = dist;
1093 jet->NN_dist = NN_dist;
1096 FASTJET_END_NAMESPACE
1098 #endif // __FASTJET_CLUSTERSEQUENCE_HH__