#include <ClusterSequence.hh>
Inheritance diagram for fastjet::ClusterSequence:


Public Types | |
| enum | JetType { Invalid = -3, InexistentParent = -2, BeamJet = -1 } |
Public Member Functions | |
| ClusterSequence () | |
| default constructor | |
| template<class L> | |
| ClusterSequence (const std::vector< L > &pseudojets, const double &R=1.0, const Strategy &strategy=Best, const bool &writeout_combinations=false) | |
| create a clustersequence starting from the supplied set of pseudojets and clustering them with the long-invariant kt algorithm (E-scheme recombination) with the supplied value for R. | |
| template<class L> | |
| ClusterSequence (const std::vector< L > &pseudojets, const JetDefinition &jet_def, const bool &writeout_combinations=false) | |
| constructor of a jet-clustering sequence from a vector of four-momenta, with the jet definition specified by jet_def | |
| 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. | |
| int | n_exclusive_jets (const double &dcut) const |
| return the number of jets (in the sense of the exclusive algorithm) that would be obtained when running the algorithm with the given dcut. | |
| std::vector< PseudoJet > | exclusive_jets (const double &dcut) const |
| return a vector of all jets (in the sense of the exclusive algorithm) that would be obtained when running the algorithm with the given dcut. | |
| std::vector< PseudoJet > | exclusive_jets (const int &njets) const |
| return a vector of all jets when the event is clustered (in the exclusive sense) to exactly njets. | |
| double | exclusive_dmerge (const int &njets) const |
| return the dmin corresponding to the recombination that went from n+1 to n jets | |
| double | exclusive_dmerge_max (const int &njets) const |
| return the maximum of the dmin encountered during all recombinations up to the one that led to an n-jet final state; identical to exclusive_dmerge, except in cases where the dmin do not increase monotonically. | |
| bool | object_in_jet (const PseudoJet &object, const PseudoJet &jet) const |
| returns true iff the object is included in the jet. | |
| bool | has_parents (const PseudoJet &jet, PseudoJet &parent1, PseudoJet &parent2) const |
| if the jet has parents in the clustering, it returns true and sets parent1 and parent2 equal to them. | |
| bool | has_child (const PseudoJet &jet, PseudoJet &child) const |
| if the jet has a child then return true and give the child jet otherwise return false and set the child to zero | |
| bool | has_child (const PseudoJet &jet, const PseudoJet *&childp) const |
| Version of has_child that sets a pointer to the child if the child exists;. | |
| bool | has_partner (const PseudoJet &jet, PseudoJet &partner) const |
| if this jet has a child (and so a partner) return true and give the partner, otherwise return false and set the partner to zero | |
| std::vector< PseudoJet > | constituents (const PseudoJet &jet) const |
| return a vector of the particles that make up jet | |
| void | print_jets_for_root (const std::vector< PseudoJet > &jets, std::ostream &ostr=std::cout) const |
| output the supplied vector of jets in a format that can be read by an appropriate root script; the format is: jet-n jet-px jet-py jet-pz jet-E particle-n particle-rap particle-phi particle-pt particle-n particle-rap particle-phi particle-pt | |
| void | add_constituents (const PseudoJet &jet, std::vector< PseudoJet > &subjet_vector) const |
| add on to subjet_vector the subjets of jet (for internal use mainly) | |
| Strategy | strategy_used () const |
| return the enum value of the strategy used to cluster the event | |
| std::string | strategy_string () const |
| const JetDefinition & | jet_def () const |
| return a reference to the jet definition | |
| 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-algorithm, 1 for the Cambridge algorithm). | |
| 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 | |
| void | plugin_record_ij_recombination (int jet_i, int jet_j, double dij, const PseudoJet &newjet, int &newjet_k) |
| as for the simpler variant of plugin_record_ij_recombination, except that the new jet is attributed the momentum and user_index of newjet | |
| 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, with the specified diB; when looking for inclusive jets, any iB recombination will returned to the user as a jet. | |
| void | plugin_associate_extras (std::auto_ptr< Extras > extras_in) |
| the plugin can associated some extra information with the ClusterSequence object by calling this function | |
| bool | plugin_activated () const |
| returns true when the plugin is allowed to run the show. | |
| const Extras * | extras () const |
| returns a pointer to the extras object (may be null) | |
| const std::vector< PseudoJet > & | jets () const |
| allow the user to access the jets in this raw manner (needed because we don't seem to be able to access protected elements of the class for an object that is not "this" (at least in case where "this" is of a slightly different kind from the object, both derived from ClusterSequence). | |
| const std::vector< history_element > & | history () const |
| allow the user to access the history in this raw manner (see above for motivation). | |
| unsigned int | n_particles () const |
| returns the number of particles that were provided to the clustering algorithm (helps the user find their way around the history and jets objects if they weren't paying attention beforehand). | |
| std::vector< int > | particle_jet_indices (const std::vector< PseudoJet > &) const |
| returns a vector of size n_particles() which indicates, for each of the initial particles (in the order in which they were supplied), which of the supplied jets it belongs to; if it does not belong to any of the supplied jets, the index is set to -1; | |
| std::vector< int > | unique_history_order () const |
| routine that returns an order in which to read the history such that clusterings that lead to identical jet compositions but different histories (because of degeneracies in the clustering order) will have matching constituents for each matching entry in the unique_history_order. | |
| std::vector< PseudoJet > | unclustered_particles () const |
| return the set of particles that have not been clustered. | |
| void | transfer_from_sequence (ClusterSequence &from_seq) |
| transfer the sequence contained in other_seq into our own; any plugin "extras" contained in the from_seq will be lost from there. | |
Static Public Member Functions | |
| static void | set_jet_algorithm (JetAlgorithm jet_algorithm) |
| set the default (static) jet finder across all current and future ClusterSequence objects -- deprecated and obsolescent (i.e. | |
| static void | set_jet_finder (JetAlgorithm jet_algorithm) |
| same as above for backward compatibility | |
Protected Member Functions | |
| bool | _potentially_valid (const PseudoJet &jet) const |
| returns true if the jet has a history index contained within the range of this CS | |
| template<class L> | |
| void | _transfer_input_jets (const std::vector< L > &pseudojets) |
| transfer the vector<L> of input jets into our own vector<PseudoJet> _jets (with some reserved space for future growth). | |
| void | _initialise_and_run (const JetDefinition &jet_def, const bool &writeout_combinations) |
| This is the routine that will do all the initialisation and then run the clustering (may be called by various constructors). | |
| void | _initialise_and_run (const double &R, const Strategy &strategy, const bool &writeout_combinations) |
| This is an alternative routine for initialising and running the clustering, provided for legacy purposes. | |
| void | _decant_options (const JetDefinition &jet_def, const bool &writeout_combinations) |
| fills in the various member variables with "decanted" options from the jet_definition and writeout_combinations variables | |
| void | _fill_initial_history () |
| fill out the history (and jet cross refs) related to the initial set of jets (assumed already to have been "transferred"), without any clustering | |
| void | _do_ij_recombination_step (const int &jet_i, const int &jet_j, const double &dij, int &newjet_k) |
| carries out the bookkeeping associated with the step of recombining jet_i and jet_j (assuming a distance dij) and returns the index of the recombined jet, newjet_k. | |
| void | _do_iB_recombination_step (const int &jet_i, const double &diB) |
| carries out the bookkeeping associated with the step of recombining jet_i with the beam | |
Protected Attributes | |
| JetDefinition | _jet_def |
| std::vector< PseudoJet > | _jets |
| This contains the physical PseudoJets; for each PseudoJet one can find the corresponding position in the _history by looking at _jets[i].cluster_hist_index(). | |
| std::vector< history_element > | _history |
| this vector will contain the branching history; for each stage, _history[i].jetp_index indicates where to look in the _jets vector to get the physical PseudoJet. | |
| bool | _writeout_combinations |
| int | _initial_n |
| double | _Rparam |
| double | _R2 |
| double | _invR2 |
| Strategy | _strategy |
| JetAlgorithm | _jet_algorithm |
Static Protected Attributes | |
| static JetAlgorithm | _default_jet_algorithm = kt_algorithm |
Private Types | |
| typedef std::pair< int, int > | TwoVertices |
| typedef std::pair< double, TwoVertices > | DijEntry |
| typedef std::multimap< double, TwoVertices > | DistMap |
Private Member Functions | |
| void | _really_dumb_cluster () |
| Run the clustering in a very slow variant of the N^3 algorithm. | |
| void | _delaunay_cluster () |
| Run the clustering using a Hierarchical Delaunay triangulation and STL maps to achieve O(N*ln N) behaviour. | |
| void | _simple_N2_cluster () |
| Order(N^2) clustering. | |
| void | _tiled_N2_cluster () |
| run a tiled clustering | |
| void | _faster_tiled_N2_cluster () |
| run a tiled clustering | |
| void | _minheap_faster_tiled_N2_cluster () |
| run a tiled clustering, with our minheap for keeping track of the smallest dij | |
| void | _CP2DChan_cluster () |
| a 4pi variant of the closest pair clustering | |
| void | _CP2DChan_cluster_2pi2R () |
| a variant of the closest pair clustering which uses a region of size 2pi+2R in phi. | |
| void | _CP2DChan_cluster_2piMultD () |
| a variant of the closest pair clustering which uses a region of size 2pi + 2*0.3 and then carries on with 2pi+2*R | |
| void | _CP2DChan_limited_cluster (double D) |
| clusters only up to a distance Dlim -- does not deal with "inclusive" jets -- these are left to some other part of the program | |
| void | _do_Cambridge_inclusive_jets () |
| void | _add_step_to_history (const int &step_number, const int &parent1, const int &parent2, const int &jetp_index, const double &dij) |
| void | _extract_tree_children (int pos, std::valarray< bool > &, const std::valarray< int > &, std::vector< int > &) const |
| internal routine associated with the construction of the unique history order (following children in the tree) | |
| void | _extract_tree_parents (int pos, std::valarray< bool > &, const std::valarray< int > &, std::vector< int > &) const |
| internal routine associated with the construction of the unique history order (following parents in the tree) | |
| void | _add_ktdistance_to_map (const int &ii, DistMap &DijMap, const DynamicNearestNeighbours *DNN) |
| Add the current kt distance for particle ii to the map (DijMap) using information from the DNN object. | |
| void | _print_banner () |
| for making sure the user knows what it is they're running... | |
| template<class J> | |
| void | _bj_set_jetinfo (J *const jet, const int _jets_index) const |
| set the kinematic and labelling info for jeta so that it corresponds to _jets[_jets_index] | |
| void | _bj_remove_from_tiles (TiledJet *const jet) const |
| "remove" this jet, which implies updating links of neighbours and perhaps modifying the tile structure | |
| template<class J> | |
| double | _bj_dist (const J *const jeta, const J *const jetb) const |
| return the distance between two BriefJet objects | |
| template<class J> | |
| double | _bj_diJ (const J *const jeta) const |
| template<class J> | |
| J * | _bj_of_hindex (const int hist_index, J *const head, J *const tail) const |
| for testing purposes only: if in the range head--tail-1 there is a a jet which corresponds to hist_index in the history, then return a pointer to that jet; otherwise return tail. | |
| template<class J> | |
| void | _bj_set_NN_nocross (J *const jeta, J *const head, const J *const tail) const |
| updates (only towards smaller distances) the NN for jeta without checking whether in the process jeta itself might be a new NN of one of the jets being scanned -- span the range head to tail-1 with assumption that jeta is not contained in that range | |
| template<class J> | |
| void | _bj_set_NN_crosscheck (J *const jeta, J *const head, const J *const tail) const |
| reset the NN for jeta and DO check whether in the process jeta itself might be a new NN of one of the jets being scanned -- span the range head to tail-1 with assumption that jeta is not contained in that range | |
| int | _tile_index (int ieta, int iphi) const |
| int | _tile_index (const double &eta, const double &phi) const |
| return the tile index corresponding to the given eta,phi point | |
| void | _tj_set_jetinfo (TiledJet *const jet, const int _jets_index) |
| void | _bj_remove_from_tiles (TiledJet *const jet) |
| void | _initialise_tiles () |
Set up the tiles:
| |
| void | _print_tiles (TiledJet *briefjets) const |
| output the contents of the tiles | |
| void | _add_neighbours_to_tile_union (const int tile_index, std::vector< int > &tile_union, int &n_near_tiles) const |
| Add to the vector tile_union the tiles that are in the neighbourhood of the specified tile_index, including itself -- start adding from position n_near_tiles-1, and increase n_near_tiles as you go along (could have done it more C++ like with vector with reserved space, but fear is that it would have been slower, e.g. | |
| void | _add_untagged_neighbours_to_tile_union (const int tile_index, std::vector< int > &tile_union, int &n_near_tiles) |
| Like _add_neighbours_to_tile_union, but only adds neighbours if their "tagged" status is false; when a neighbour is added its tagged status is set to true. | |
Private Attributes | |
| bool | _plugin_activated |
| std::auto_ptr< Extras > | _extras |
| std::vector< Tile > | _tiles |
| double | _tiles_eta_min |
| double | _tiles_eta_max |
| double | _tile_size_eta |
| double | _tile_size_phi |
| int | _n_tiles_phi |
| int | _tiles_ieta_min |
| int | _tiles_ieta_max |
Static Private Attributes | |
| static bool | _first_time = true |
| will be set by default to be true for the first run | |
| static int | _n_exclusive_warnings = 0 |
| record the number of warnings provided about the exclusive algorithm -- so that we don't print it out more than a few times. | |
| static const int | n_tile_neighbours = 9 |
| number of neighbours that a tile will have (rectangular geometry gives 9 neighbours). | |
Classes | |
| struct | BriefJet |
| the fundamental structure which contains the minimal info about a jet, as needed for our plain N^2 algorithm -- the idea is to put all info that will be accessed N^2 times into an array of BriefJets. More... | |
| class | Extras |
| a class intended to serve as a base in case a plugin needs to associate extra information with a ClusterSequence (see SISConePlugin. More... | |
| struct | history_element |
| a single element in the clustering history (see vector _history below). More... | |
| struct | Tile |
| The fundamental structures to be used for the tiled N^2 algorithm (see CCN27-44 for some discussion of pattern of tiling). More... | |
| class | TiledJet |
| structure analogous to BriefJet, but with the extra information needed for dealing with tiles More... | |
Definition at line 65 of file ClusterSequence.hh.
|
|
Definition at line 448 of file ClusterSequence.hh. |
|
|
Definition at line 449 of file ClusterSequence.hh. |
|
|
Definition at line 447 of file ClusterSequence.hh. |
|
|
Definition at line 290 of file ClusterSequence.hh. 00290 {Invalid=-3, InexistentParent = -2, BeamJet = -1};
|
|
|
default constructor
Definition at line 71 of file ClusterSequence.hh. 00071 {}
|
|
||||||||||||||||||||||||
|
create a clustersequence starting from the supplied set of pseudojets and clustering them with the long-invariant kt algorithm (E-scheme recombination) with the supplied value for R. If strategy=DumbN3 a very stupid N^3 algorithm is used for the clustering; otherwise strategy = NlnN* uses cylinders algorithms with some number of pi coverage. If writeout_combinations=true a summary of the recombination sequence is written out Definition at line 623 of file ClusterSequence.hh. References _initialise_and_run(), and _transfer_input_jets(). 00627 {
00628
00629 // transfer the initial jets (type L) into our own array
00630 _transfer_input_jets(pseudojets);
00631
00632 // run the clustering
00633 _initialise_and_run(R,strategy,writeout_combinations);
00634 }
|
|
||||||||||||||||||||
|
constructor of a jet-clustering sequence from a vector of four-momenta, with the jet definition specified by jet_def
Definition at line 640 of file ClusterSequence.hh. References _initialise_and_run(), and _transfer_input_jets(). 00643 {
00644
00645 // transfer the initial jets (type L) into our own array
00646 _transfer_input_jets(pseudojets);
00647
00648 // run the clustering
00649 _initialise_and_run(jet_def,writeout_combinations);
00650 }
|
|
||||||||||||||||
|
Add the current kt distance for particle ii to the map (DijMap) using information from the DNN object. Work as follows: . if the kt is zero then it's nearest neighbour is taken to be the the beam jet and the distance is zero. . if cylinder distance to nearest neighbour > _Rparam then it is yiB that is smallest and this is added to map. . otherwise if the nearest neighbour jj has a larger kt then add dij to the map. . otherwise do nothing Definition at line 220 of file ClusterSequence_Delaunay.cc. References _invR2, _jets, jet_scale_for_algorithm(), fastjet::DynamicNearestNeighbours::NearestNeighbourDistance(), and fastjet::DynamicNearestNeighbours::NearestNeighbourIndex(). Referenced by _delaunay_cluster(). 00223 {
00224
00225 double yiB = jet_scale_for_algorithm(_jets[ii]);
00226 if (yiB == 0.0) {
00227 // in this case convention is that we do not worry about distances
00228 // but directly state that nearest neighbour is beam
00229 DijMap.insert(DijEntry(yiB, TwoVertices(ii,-1)));
00230 } else {
00231 double DeltaR2 = DNN->NearestNeighbourDistance(ii) * _invR2;
00232 // Logic of following bit is: only add point to map if it has
00233 // smaller kt2 than nearest neighbour j (if it has larger kt,
00234 // then: either it is j's nearest neighbour and then we will
00235 // include dij when we come to j; or it is not j's nearest
00236 // neighbour and j will recombine with someone else).
00237
00238 // If DeltaR2 > 1.0 then in any case it will recombine with beam rather
00239 // than with any neighbours.
00240 // (put general normalisation here at some point)
00241 if (DeltaR2 > 1.0) {
00242 DijMap.insert(DijEntry(yiB, TwoVertices(ii,-1)));
00243 } else {
00244 double kt2i = jet_scale_for_algorithm(_jets[ii]);
00245 int jj = DNN->NearestNeighbourIndex(ii);
00246 if (kt2i <= jet_scale_for_algorithm(_jets[jj])) {
00247 double dij = DeltaR2 * kt2i;
00248 DijMap.insert(DijEntry(dij, TwoVertices(ii,jj)));
00249 }
00250 }
00251 }
00252 }
|
|
||||||||||||||||
|
Add to the vector tile_union the tiles that are in the neighbourhood of the specified tile_index, including itself -- start adding from position n_near_tiles-1, and increase n_near_tiles as you go along (could have done it more C++ like with vector with reserved space, but fear is that it would have been slower, e.g. checking for end of vector at each stage to decide whether to resize it) Definition at line 233 of file ClusterSequence_TiledN2.cc. References _tiles. Referenced by _tiled_N2_cluster(). 00234 {
00235 for (Tile * const * near_tile = _tiles[tile_index].begin_tiles;
00236 near_tile != _tiles[tile_index].end_tiles; near_tile++){
00237 // get the tile number
00238 tile_union[n_near_tiles] = *near_tile - & _tiles[0];
00239 n_near_tiles++;
00240 }
00241 }
|
|
||||||||||||||||||||||||
|
Definition at line 715 of file ClusterSequence.cc. References _history, _jets, _writeout_combinations, fastjet::ClusterSequence::history_element::child, fastjet::ClusterSequence::history_element::dij, Invalid, fastjet::ClusterSequence::history_element::jetp_index, fastjet::ClusterSequence::history_element::max_dij_so_far, fastjet::ClusterSequence::history_element::parent1, and fastjet::ClusterSequence::history_element::parent2. Referenced by _do_iB_recombination_step(), and _do_ij_recombination_step(). 00718 {
00719
00720 history_element element;
00721 element.parent1 = parent1;
00722 element.parent2 = parent2;
00723 element.jetp_index = jetp_index;
00724 element.child = Invalid;
00725 element.dij = dij;
00726 element.max_dij_so_far = max(dij,_history[_history.size()-1].max_dij_so_far);
00727 _history.push_back(element);
00728
00729 int local_step = _history.size()-1;
00730 assert(local_step == step_number);
00731
00732 assert(parent1 >= 0);
00733 _history[parent1].child = local_step;
00734 if (parent2 >= 0) {_history[parent2].child = local_step;}
00735
00736 // get cross-referencing right from PseudoJets
00737 if (jetp_index != Invalid) {
00738 assert(jetp_index >= 0);
00739 //cout << _jets.size() <<" "<<jetp_index<<"\n";
00740 _jets[jetp_index].set_cluster_hist_index(local_step);
00741 }
00742
00743 if (_writeout_combinations) {
00744 cout << local_step << ": "
00745 << parent1 << " with " << parent2
00746 << "; y = "<< dij<<endl;
00747 }
00748
00749 }
|
|
||||||||||||||||
|
Like _add_neighbours_to_tile_union, but only adds neighbours if their "tagged" status is false; when a neighbour is added its tagged status is set to true.
Definition at line 248 of file ClusterSequence_TiledN2.cc. References _tiles. Referenced by _faster_tiled_N2_cluster(), and _minheap_faster_tiled_N2_cluster(). 00250 {
00251 for (Tile ** near_tile = _tiles[tile_index].begin_tiles;
00252 near_tile != _tiles[tile_index].end_tiles; near_tile++){
00253 if (! (*near_tile)->tagged) {
00254 (*near_tile)->tagged = true;
00255 // get the tile number
00256 tile_union[n_near_tiles] = *near_tile - & _tiles[0];
00257 n_near_tiles++;
00258 }
00259 }
00260 }
|
|
||||||||||
|
Definition at line 690 of file ClusterSequence.hh. Referenced by _faster_tiled_N2_cluster(), _minheap_faster_tiled_N2_cluster(), _simple_N2_cluster(), and _tiled_N2_cluster(). 00690 {
00691 double kt2 = jet->kt2;
00692 if (jet->NN != NULL) {if (jet->NN->kt2 < kt2) {kt2 = jet->NN->kt2;}}
00693 return jet->NN_dist * kt2;
00694 }
|
|
||||||||||||||||
|
return the distance between two BriefJet objects
Definition at line 681 of file ClusterSequence.hh. References fastjet::pi, and fastjet::twopi. Referenced by _bj_set_NN_crosscheck(), _bj_set_NN_nocross(), _faster_tiled_N2_cluster(), _minheap_faster_tiled_N2_cluster(), _simple_N2_cluster(), and _tiled_N2_cluster(). 00682 {
00683 double dphi = std::abs(jetA->phi - jetB->phi);
00684 double deta = (jetA->eta - jetB->eta);
00685 if (dphi > pi) {dphi = twopi - dphi;}
00686 return dphi*dphi + deta*deta;
00687 }
|
|
||||||||||||||||||||
|
for testing purposes only: if in the range head--tail-1 there is a a jet which corresponds to hist_index in the history, then return a pointer to that jet; otherwise return tail.
Definition at line 515 of file ClusterSequence.hh. 00518 {
00519 J * res;
00520 for(res = head; res<tail; res++) {
00521 if (_jets[res->_jets_index].cluster_hist_index() == hist_index) {break;}
00522 }
00523 return res;
00524 }
|
|
|
Definition at line 50 of file ClusterSequence_TiledN2.cc. References _tiles, fastjet::ClusterSequence::Tile::head, fastjet::ClusterSequence::TiledJet::next, fastjet::ClusterSequence::TiledJet::previous, and fastjet::ClusterSequence::TiledJet::tile_index. 00050 {
00051 Tile * tile = & _tiles[jet->tile_index];
00052
00053 if (jet->previous == NULL) {
00054 // we are at head of the tile, so reset it.
00055 // If this was the only jet on the tile then tile->head will now be NULL
00056 tile->head = jet->next;
00057 } else {
00058 // adjust link from previous jet in this tile
00059 jet->previous->next = jet->next;
00060 }
00061 if (jet->next != NULL) {
00062 // adjust backwards-link from next jet in this tile
00063 jet->next->previous = jet->previous;
00064 }
00065 }
|
|
|
"remove" this jet, which implies updating links of neighbours and perhaps modifying the tile structure
Referenced by _faster_tiled_N2_cluster(), _minheap_faster_tiled_N2_cluster(), and _tiled_N2_cluster(). |
|
||||||||||||||||
|
set the kinematic and labelling info for jeta so that it corresponds to _jets[_jets_index]
Definition at line 666 of file ClusterSequence.hh. References _jets, _R2, and jet_scale_for_algorithm(). Referenced by _simple_N2_cluster(). 00667 {
00668 jetA->eta = _jets[_jets_index].rap();
00669 jetA->phi = _jets[_jets_index].phi_02pi();
00670 jetA->kt2 = jet_scale_for_algorithm(_jets[_jets_index]);
00671 jetA->_jets_index = _jets_index;
00672 // initialise NN info as well
00673 jetA->NN_dist = _R2;
00674 jetA->NN = NULL;
00675 }
|
|
||||||||||||||||||||
|
reset the NN for jeta and DO check whether in the process jeta itself might be a new NN of one of the jets being scanned -- span the range head to tail-1 with assumption that jeta is not contained in that range
Definition at line 728 of file ClusterSequence.hh. References _bj_dist(), and _R2. Referenced by _simple_N2_cluster(). 00729 {
00730 double NN_dist = _R2;
00731 J * NN = NULL;
00732 for (J * jetB = head; jetB != tail; jetB++) {
00733 double dist = _bj_dist(jet,jetB);
00734 if (dist < NN_dist) {
00735 NN_dist = dist;
00736 NN = jetB;
00737 }
00738 if (dist < jetB->NN_dist) {
00739 jetB->NN_dist = dist;
00740 jetB->NN = jet;
00741 }
00742 }
00743 jet->NN = NN;
00744 jet->NN_dist = NN_dist;
00745 }
|
|
||||||||||||||||||||
|
updates (only towards smaller distances) the NN for jeta without checking whether in the process jeta itself might be a new NN of one of the jets being scanned -- span the range head to tail-1 with assumption that jeta is not contained in that range
Definition at line 700 of file ClusterSequence.hh. References _bj_dist(), and _R2. Referenced by _simple_N2_cluster(). 00701 {
00702 double NN_dist = _R2;
00703 J * NN = NULL;
00704 if (head < jet) {
00705 for (J * jetB = head; jetB != jet; jetB++) {
00706 double dist = _bj_dist(jet,jetB);
00707 if (dist < NN_dist) {
00708 NN_dist = dist;
00709 NN = jetB;
00710 }
00711 }
00712 }
00713 if (tail > jet) {
00714 for (J * jetB = jet+1; jetB != tail; jetB++) {
00715 double dist = _bj_dist(jet,jetB);
00716 if (dist < NN_dist) {
00717 NN_dist = dist;
00718 NN = jetB;
00719 }
00720 }
00721 }
00722 jet->NN = NN;
00723 jet->NN_dist = NN_dist;
00724 }
|
|
|
a 4pi variant of the closest pair clustering
Definition at line 223 of file ClusterSequence_CP2DChan.cc. References _do_Cambridge_inclusive_jets(), _do_ij_recombination_step(), _invR2, _jet_algorithm, _jets, BeamJet, fastjet::cambridge_algorithm, fastjet::ClosestPair2D::closest_pair(), Invalid, fastjet::ClosestPair2D::replace(), and fastjet::twopi. Referenced by _initialise_and_run(). 00223 {
00224
00225 if (_jet_algorithm != cambridge_algorithm) throw Error("_CP2DChan_cluster called for a jet-finder that is not the cambridge algorithm");
00226
00227 unsigned int n = _jets.size();
00228
00229 vector<MirrorInfo> coordIDs(2*n); // link from original to mirror indices
00230 vector<int> jetIDs(2*n); // link from mirror to original indices
00231 vector<Coord2D> coords(2*n); // our coordinates (and copies)
00232
00233 // start things off...
00234 double minrap = numeric_limits<double>::max();
00235 double maxrap = -minrap;
00236 int coord_index = 0;
00237 for (unsigned i = 0; i < n; i++) {
00238 // separate out points with infinite rapidity
00239 if (_jets[i].E() == abs(_jets[i].pz()) && _jets[i].perp2() == 0.0) {
00240 coordIDs[i] = MirrorInfo(BeamJet,BeamJet);
00241 } else {
00242 coordIDs[i].orig = coord_index;
00243 coordIDs[i].mirror = coord_index+1;
00244 coords[coord_index] = Coord2D(_jets[i].rap(), _jets[i].phi_02pi());
00245 coords[coord_index+1] = Coord2D(_jets[i].rap(), _jets[i].phi_02pi()+twopi);
00246 jetIDs[coord_index] = i;
00247 jetIDs[coord_index+1] = i;
00248 minrap = min(coords[coord_index].x,minrap);
00249 maxrap = max(coords[coord_index].x,maxrap);
00250 coord_index += 2;
00251 }
00252 }
00253 // label remaining "mirror info" as saying that there are no jets
00254 for (unsigned i = n; i < 2*n; i++) {coordIDs[i].orig = Invalid;}
00255
00256 // set them to their actual size...
00257 coords.resize(coord_index);
00258
00259 // establish limits (with some leeway on rapidity)
00260 Coord2D left_edge(minrap-1.0, 0.0);
00261 Coord2D right_edge(maxrap+1.0, 2*twopi);
00262
00263 // now create the closest pair search object
00264 ClosestPair2D cp(coords, left_edge, right_edge);
00265
00266 // and start iterating...
00267 vector<Coord2D> new_points(2);
00268 vector<unsigned int> cIDs_to_remove(4);
00269 vector<unsigned int> new_cIDs(2);
00270 do {
00271 // find out which pair we recombine
00272 unsigned int cID1, cID2;
00273 double distance2;
00274 cp.closest_pair(cID1,cID2,distance2);
00275 distance2 *= _invR2;
00276
00277 // if the closest distance > 1, we exit and go to "inclusive" stage
00278 if (distance2 > 1.0) {break;}
00279
00280 // do the recombination...
00281 int jet_i = jetIDs[cID1];
00282 int jet_j = jetIDs[cID2];
00283 int newjet_k;
00284 _do_ij_recombination_step(jet_i, jet_j, distance2, newjet_k);
00285
00286 // now prepare operations on CP structure
00287 cIDs_to_remove[0] = coordIDs[jet_i].orig;
00288 cIDs_to_remove[1] = coordIDs[jet_i].mirror;
00289 cIDs_to_remove[2] = coordIDs[jet_j].orig;
00290 cIDs_to_remove[3] = coordIDs[jet_j].mirror;
00291 new_points[0] = Coord2D(_jets[newjet_k].rap(),_jets[newjet_k].phi_02pi());
00292 new_points[1] = Coord2D(_jets[newjet_k].rap(),_jets[newjet_k].phi_02pi()+twopi);
00293 // carry out the CP operation
00294 //cp.replace_many(cIDs_to_remove, new_points, new_cIDs);
00295 // remarkable the following is faster...
00296 new_cIDs[0] = cp.replace(cIDs_to_remove[0], cIDs_to_remove[2], new_points[0]);
00297 new_cIDs[1] = cp.replace(cIDs_to_remove[1], cIDs_to_remove[3], new_points[1]);
00298 // signal that the following jets no longer exist
00299 coordIDs[jet_i].orig = Invalid;
00300 coordIDs[jet_j].orig = Invalid;
00301 // and do bookkeeping for new jet
00302 coordIDs[newjet_k] = MirrorInfo(new_cIDs[0], new_cIDs[1]);
00303 jetIDs[new_cIDs[0]] = newjet_k;
00304 jetIDs[new_cIDs[1]] = newjet_k;
00305
00306 // if we've reached one jet we should exit...
00307 n--;
00308 if (n == 1) {break;}
00309
00310 } while(true);
00311
00312
00313 // now do "beam" recombinations
00314 //for (unsigned int jet_i = 0; jet_i < coordIDs.size(); jet_i++) {
00315 // // if we have a predeclared beam jet or a valid set of mirror
00316 // // coordinates, recombine then recombine this jet with the beam
00317 // if (coordIDs[jet_i].orig == BeamJet || coordIDs[jet_i].orig > 0) {
00318 // // diB = 1 _always_ (for the cambridge alg.)
00319 // _do_iB_recombination_step(jet_i, 1.0);
00320 // }
00321 //}
00322
00323 _do_Cambridge_inclusive_jets();
00324
00325 //n = _history.size();
00326 //for (unsigned int hist_i = 0; hist_i < n; hist_i++) {
00327 // if (_history[hist_i].child == Invalid) {
00328 // _do_iB_recombination_step(_history[hist_i].jetp_index, 1.0);
00329 // }
00330 //}
00331
00332 }
|
|
|
a variant of the closest pair clustering which uses a region of size 2pi+2R in phi.
Definition at line 193 of file ClusterSequence_CP2DChan.cc. References _CP2DChan_limited_cluster(), _do_Cambridge_inclusive_jets(), _jet_algorithm, _Rparam, and fastjet::cambridge_algorithm. Referenced by _CP2DChan_cluster_2piMultD(), and _initialise_and_run(). 00193 {
00194
00195 if (_jet_algorithm != cambridge_algorithm) throw Error("CP2DChan clustering method called for a jet-finder that is not the cambridge algorithm");
00196
00197 // run the clustering with mirror copies kept such that only things
00198 // within _Rparam of a border are mirrored
00199 _CP2DChan_limited_cluster(_Rparam);
00200
00201 //
00202 _do_Cambridge_inclusive_jets();
00203 }
|
|
|
a variant of the closest pair clustering which uses a region of size 2pi + 2*0.3 and then carries on with 2pi+2*R
Definition at line 209 of file ClusterSequence_CP2DChan.cc. References _CP2DChan_cluster_2pi2R(), _CP2DChan_limited_cluster(), and _Rparam. Referenced by _initialise_and_run(). 00209 {
00210
00211 // do a first run of clustering up to a small distance parameter,
00212 if (_Rparam >= 0.39) {
00213 _CP2DChan_limited_cluster(min(_Rparam/2,0.3));
00214 }
00215
00216 // and then the final round of clustering
00217 _CP2DChan_cluster_2pi2R ();
00218 }
|
|
|
clusters only up to a distance Dlim -- does not deal with "inclusive" jets -- these are left to some other part of the program
Definition at line 69 of file ClusterSequence_CP2DChan.cc. References _do_ij_recombination_step(), _history, _initial_n, _invR2, _jets, fastjet::ClosestPair2D::closest_pair(), Invalid, fastjet::Private::make_mirror(), fastjet::pi, and fastjet::ClosestPair2D::replace_many(). Referenced by _CP2DChan_cluster_2pi2R(), and _CP2DChan_cluster_2piMultD(). 00069 {
00070
00071 unsigned int n = _initial_n;
00072
00073 vector<MirrorInfo> coordIDs(2*n); // coord IDs of a given jetID
00074 vector<int> jetIDs(2*n); // jet ID for a given coord ID
00075 vector<Coord2D> coords(2*n); // our coordinates (and copies)
00076
00077 // start things off...
00078 double minrap = numeric_limits<double>::max();
00079 double maxrap = -minrap;
00080 int coord_index = -1;
00081 int n_active = 0;
00082 for (unsigned jet_i = 0; jet_i < _jets.size(); jet_i++) {
00083
00084 // skip jets that already have children or that have infinite
00085 // rapidity
00086 if (_history[_jets[jet_i].cluster_hist_index()].child != Invalid ||
00087 (_jets[jet_i].E() == abs(_jets[jet_i].pz()) &&
00088 _jets[jet_i].perp2() == 0.0)
00089 ) {continue;}
00090
00091 n_active++;
00092
00093 coordIDs[jet_i].orig = ++coord_index;
00094 coords[coord_index] = Coord2D(_jets[jet_i].rap(), _jets[jet_i].phi_02pi());
00095 jetIDs[coord_index] = jet_i;
00096 minrap = min(coords[coord_index].x,minrap);
00097 maxrap = max(coords[coord_index].x,maxrap);
00098
00099 Coord2D mirror_point(coords[coord_index]);
00100 if (make_mirror(mirror_point, Dlim)) {
00101 coordIDs[jet_i].mirror = ++coord_index;
00102 coords[coord_index] = mirror_point;
00103 jetIDs[coord_index] = jet_i;
00104 } else {
00105 coordIDs[jet_i].mirror = Invalid;
00106 }
00107 }
00108
00109 // set them to their actual size...
00110 coords.resize(coord_index+1);
00111
00112 // establish limits (with some leeway on rapidity)
00113 Coord2D left_edge(minrap-1.0, -pi);
00114 Coord2D right_edge(maxrap+1.0, 3*pi);
00115
00116 //cerr << "minrap, maxrap = " << minrap << " " << maxrap << endl;
00117
00118 // now create the closest pair search object
00119 ClosestPair2D cp(coords, left_edge, right_edge);
00120
00121 // cross check to see what's going on...
00122 //cerr << "Tree depths before: ";
00123 //cp.print_tree_depths(cerr);
00124
00125 // and start iterating...
00126 vector<Coord2D> new_points(2);
00127 vector<unsigned int> cIDs_to_remove(4);
00128 vector<unsigned int> new_cIDs(2);
00129
00130 do {
00131 // find out which pair we recombine
00132 unsigned int cID1, cID2;
00133 double distance2;
00134 cp.closest_pair(cID1,cID2,distance2);
00135
00136 // if the closest distance > Dlim, we exit and go to "inclusive" stage
00137 if (distance2 > Dlim*Dlim) {break;}
00138
00139 // normalise distance as we like it
00140 distance2 *= _invR2;
00141
00142 // do the recombination...
00143 int jet_i = jetIDs[cID1];
00144 int jet_j = jetIDs[cID2];
00145 int newjet_k;
00146 _do_ij_recombination_step(jet_i, jet_j, distance2, newjet_k);
00147
00148 // don't bother with any further action if only one active particle
00149 // is left (also avoid closest-pair error [cannot remove last particle]).
00150 if (--n_active == 1) {break;}
00151
00152 // now prepare operations on CP structure
00153 cIDs_to_remove.resize(0);
00154 cIDs_to_remove.push_back(coordIDs[jet_i].orig);
00155 cIDs_to_remove.push_back(coordIDs[jet_j].orig);
00156 if (coordIDs[jet_i].mirror != Invalid)
00157 cIDs_to_remove.push_back(coordIDs[jet_i].mirror);
00158 if (coordIDs[jet_j].mirror != Invalid)
00159 cIDs_to_remove.push_back(coordIDs[jet_j].mirror);
00160
00161 Coord2D new_point(_jets[newjet_k].rap(),_jets[newjet_k].phi_02pi());
00162 new_points.resize(0);
00163 new_points.push_back(new_point);
00164 if (make_mirror(new_point, Dlim)) new_points.push_back(new_point);
00165
00166 // carry out actions on search tree
00167 cp.replace_many(cIDs_to_remove, new_points, new_cIDs);
00168
00169 // now fill in info for new points...
00170 coordIDs[newjet_k].orig = new_cIDs[0];
00171 jetIDs[new_cIDs[0]] = newjet_k;
00172 if (new_cIDs.size() == 2) {
00173 coordIDs[newjet_k].mirror = new_cIDs[1];
00174 jetIDs[new_cIDs[1]] = newjet_k;
00175 } else {coordIDs[newjet_k].mirror = Invalid;}
00176
00178 //n_active--;
00179 //if (n_active == 1) {break;}
00180
00181 } while(true);
00182
00183 // cross check to see what's going on...
00184 //cerr << "Max tree depths after: ";
00185 //cp.print_tree_depths(cerr);
00186
00187 }
|
|
||||||||||||
|
fills in the various member variables with "decanted" options from the jet_definition and writeout_combinations variables
Definition at line 182 of file ClusterSequence.cc. References _invR2, _jet_algorithm, _jet_def, _plugin_activated, _print_banner(), _R2, _Rparam, _strategy, and _writeout_combinations. Referenced by fastjet::ClusterSequenceActiveArea::_initialise_AA(), and _initialise_and_run(). 00183 {
00184
00185 // let the user know what's going on
00186 _print_banner();
00187
00188 // make a local copy of the jet definition (for future use?)
00189 _jet_def = jet_def;
00190
00191 _writeout_combinations = writeout_combinations;
00192 _jet_algorithm = jet_def.jet_algorithm();
00193 _Rparam = jet_def.R(); _R2 = _Rparam*_Rparam; _invR2 = 1.0/_R2;
00194 _strategy = jet_def.strategy();
00195
00196 // disallow interference from the plugin
00197 _plugin_activated = false;
00198
00199 }
|
|
|
Run the clustering using a Hierarchical Delaunay triangulation and STL maps to achieve O(N*ln N) behaviour. There may be internally asserted assumptions about absence of points with coincident eta-phi coordinates. Definition at line 58 of file ClusterSequence_Delaunay.cc. References _add_ktdistance_to_map(), _do_iB_recombination_step(), _do_ij_recombination_step(), _jets, _Rparam, _strategy, BeamJet, fastjet::NlnN, fastjet::NlnN3pi, fastjet::NlnN4pi, fastjet::DynamicNearestNeighbours::RemoveCombinedAddCombination(), fastjet::DynamicNearestNeighbours::RemovePoint(), fastjet::EtaPhi::sanitize(), strategy_string(), fastjet::twopi, and fastjet::DynamicNearestNeighbours::Valid(). Referenced by _initialise_and_run(). 00058 {
00059
00060 int n = _jets.size();
00061
00062 vector<EtaPhi> points(n); // recall EtaPhi is just a typedef'd pair<double>
00063 for (int i = 0; i < n; i++) {
00064 points[i] = EtaPhi(_jets[i].rap(),_jets[i].phi_02pi());
00065 points[i].sanitize(); // make sure things are in the right range
00066 }
00067
00068 // initialise our DNN structure with the set of points
00069 DynamicNearestNeighbours * DNN;
00070 #ifndef DROP_CGAL // strategy = NlnN* are not supported if we drop CGAL...
00071 bool verbose = false;
00072 bool ignore_nearest_is_mirror = (_Rparam < twopi);
00073 if (_strategy == NlnN4pi) {
00074 DNN = new Dnn4piCylinder(points,verbose);
00075 } else if (_strategy == NlnN3pi) {
00076 DNN = new Dnn3piCylinder(points,ignore_nearest_is_mirror,verbose);
00077 } else if (_strategy == NlnN) {
00078 DNN = new Dnn2piCylinder(points,ignore_nearest_is_mirror,verbose);
00079 } else
00080 #else
00081 if (_strategy == NlnN4pi || _strategy == NlnN3pi || _strategy == NlnN) {
00082 ostringstream err;
00083 err << "ERROR: Requested strategy "<<strategy_string()<<" but it is not"<<endl;
00084 err << " supported because FastJet was compiled without CGAL"<<endl;
00085 throw Error(err.str());
00086 //assert(false);
00087 }
00088 #endif // DROP_CGAL
00089 {
00090 ostringstream err;
00091 err << "ERROR: Unrecognized value for strategy: "<<_strategy<<endl;
00092 assert(false);
00093 throw Error(err.str());
00094 }
00095
00096 // We will find nearest neighbour for each vertex, and include
00097 // distance in map (NB DistMap is a typedef given in the .h file)
00098 DistMap DijMap;
00099
00100 // fill the map with the minimal (as far as we know) subset of Dij
00101 // distances (i.e. nearest neighbour ones).
00102 for (int ii = 0; ii < n; ii++) {
00103 _add_ktdistance_to_map(ii, DijMap, DNN);
00104 }
00105
00106 // run the clustering (go up to i=n-1, but then will stop half-way down,
00107 // when we reach that point -- it will be the final beam jet and there
00108 // will be no nearest neighbours to find).
00109 for (int i=0;i<n;i++) {
00110 // find nearest vertices
00111 // NB: skip cases where the point is not there anymore!
00112 TwoVertices SmallestDijPair;
00113 int jet_i, jet_j;
00114 double SmallestDij;
00115 bool Valid2;
00116 bool recombine_with_beam;
00117 do {
00118 SmallestDij = DijMap.begin()->first;
00119 SmallestDijPair = DijMap.begin()->second;
00120 jet_i = SmallestDijPair.first;
00121 jet_j = SmallestDijPair.second;
00122 // distance is immediately removed regardless of whether or not
00123 // it is used.
00124 // Some temporary testing code relating to problems with the gcc-3.2 compiler
00125 //cout << "got here and size is "<< DijMap.size()<< " and it is "<<SmallestDij <<"\n";
00126 //cout << jet_i << " "<< jet_j<<"\n";
00127 DijMap.erase(DijMap.begin());
00128 //cout << "got beyond here\n";
00129
00130 // need to "prime" the validity of jet_j in such a way that
00131 // if it corresponds to the beam then it is automatically valid.
00132 recombine_with_beam = (jet_j == BeamJet);
00133 if (!recombine_with_beam) {Valid2 = DNN->Valid(jet_j);}
00134 else {Valid2 = true;}
00135
00136 } while ( !DNN->Valid(jet_i) || !Valid2);
00137
00138
00139 // The following part acts just on jet momenta and on the history.
00140 // The action on the nearest-neighbour structures takes place
00141 // later (only if at least 2 jets are around).
00142 if (! recombine_with_beam) {
00143 int nn; // will be index of new jet
00144 _do_ij_recombination_step(jet_i, jet_j, SmallestDij, nn);
00145 //OBS // merge the two jets, add new jet, remove old ones
00146 //OBS _jets.push_back(_jets[jet_i] + _jets[jet_j]);
00147 //OBS
00148 //OBS int nn = _jets.size()-1;
00149 //OBS _jets[nn].set_cluster_hist_index(n+i);
00150 //OBS
00151 //OBS // get corresponding indices in history structure
00152 //OBS int hist_i = _jets[jet_i].cluster_hist_index();
00153 //OBS int hist_j = _jets[jet_j].cluster_hist_index();
00154 //OBS
00155 //OBS
00156 //OBS _add_step_to_history(n+i,min(hist_i,hist_j), max(hist_i,hist_j),
00157 //OBS _jets.size()-1, SmallestDij);
00158
00159 // add new point to points vector
00160 EtaPhi newpoint(_jets[nn].rap(), _jets[nn].phi_02pi());
00161 newpoint.sanitize(); // make sure it is in correct range
00162 points.push_back(newpoint);
00163 } else {
00164 // recombine the jet with the beam
00165 _do_iB_recombination_step(jet_i, SmallestDij);
00166 //OBS _add_step_to_history(n+i,_jets[jet_i].cluster_hist_index(),BeamJet,
00167 //OBS Invalid, SmallestDij);
00168 }
00169
00170 // exit the loop because we do not want to look for nearest neighbours
00171 // etc. of zero partons
00172 if (i == n-1) {break;}
00173
00174 vector<int> updated_neighbours;
00175 if (! recombine_with_beam) {
00176 // update DNN
00177 int point3;
00178 DNN->RemoveCombinedAddCombination(jet_i, jet_j,
00179 points[points.size()-1], point3,
00180 updated_neighbours);
00181 // C++ beginners' comment: static_cast to unsigned int is necessary
00182 // to do away with warnings about type mismatch between point3 (int)
00183 // and points.size (unsigned int)
00184 if (static_cast<unsigned int> (point3) != points.size()-1) {
00185 throw Error("INTERNAL ERROR: point3 != points.size()-1");}
00186 } else {
00187 // update DNN
00188 DNN->RemovePoint(jet_i, updated_neighbours);
00189 }
00190
00191 // update map
00192 vector<int>::iterator it = updated_neighbours.begin();
00193 for (; it != updated_neighbours.end(); ++it) {
00194 int ii = *it;
00195 _add_ktdistance_to_map(ii, DijMap, DNN);
00196 }
00197
00198 } // end clustering loop
00199
00200 // remember to clean up!
00201 delete DNN;
00202 }
|
|
|
Definition at line 336 of file ClusterSequence_CP2DChan.cc. References _do_iB_recombination_step(), _history, and Invalid. Referenced by _CP2DChan_cluster(), and _CP2DChan_cluster_2pi2R(). 00336 {
00337 unsigned int n = _history.size();
00338 for (unsigned int hist_i = 0; hist_i < n; hist_i++) {
00339 if (_history[hist_i].child == Invalid) {
00340 _do_iB_recombination_step(_history[hist_i].jetp_index, 1.0);
00341 }
00342 }
00343 }
|
|
||||||||||||
|
carries out the bookkeeping associated with the step of recombining jet_i with the beam
Definition at line 892 of file ClusterSequence.cc. References _add_step_to_history(), _history, _jets, BeamJet, and Invalid. Referenced by _delaunay_cluster(), _do_Cambridge_inclusive_jets(), _faster_tiled_N2_cluster(), _minheap_faster_tiled_N2_cluster(), _really_dumb_cluster(), _simple_N2_cluster(), _tiled_N2_cluster(), and fastjet::ClusterSequenceActiveArea::_transfer_ghost_free_history(). 00893 {
00894 // get history index
00895 int newstep_k = _history.size();
00896
00897 // recombine the jet with the beam
00898 _add_step_to_history(newstep_k,_jets[jet_i].cluster_hist_index(),BeamJet,
00899 Invalid, diB);
00900
00901 }
|
|
||||||||||||||||||||
|
carries out the bookkeeping associated with the step of recombining jet_i and jet_j (assuming a distance dij) and returns the index of the recombined jet, newjet_k.
Definition at line 859 of file ClusterSequence.cc. References _add_step_to_history(), _history, _jet_def, _jets, and fastjet::JetDefinition::recombiner(). Referenced by _CP2DChan_cluster(), _CP2DChan_limited_cluster(), _delaunay_cluster(), _faster_tiled_N2_cluster(), _minheap_faster_tiled_N2_cluster(), _really_dumb_cluster(), _simple_N2_cluster(), _tiled_N2_cluster(), and fastjet::ClusterSequenceActiveArea::_transfer_ghost_free_history(). 00862 {
00863
00864 // create the new jet by recombining the first two
00865 PseudoJet newjet;
00866 _jet_def.recombiner()->recombine(_jets[jet_i], _jets[jet_j], newjet);
00867 _jets.push_back(newjet);
00868 // original version...
00869 //_jets.push_back(_jets[jet_i] + _jets[jet_j]);
00870
00871 // get its index
00872 newjet_k = _jets.size()-1;
00873
00874 // get history index
00875 int newstep_k = _history.size();
00876 // and provide jet with the info
00877 _jets[newjet_k].set_cluster_hist_index(newstep_k);
00878
00879 // finally sort out the history
00880 int hist_i = _jets[jet_i].cluster_hist_index();
00881 int hist_j = _jets[jet_j].cluster_hist_index();
00882
00883 _add_step_to_history(newstep_k, min(hist_i, hist_j), max(hist_i,hist_j),
00884 newjet_k, dij);
00885
00886 }
|
|
||||||||||||||||||||
|
internal routine associated with the construction of the unique history order (following children in the tree)
Reimplemented in fastjet::ClusterSequenceActiveArea. Definition at line 795 of file ClusterSequence.cc. References _extract_tree_parents(), and _history. Referenced by unique_history_order(). 00799 {
00800 if (!extracted[position]) {
00801 // that means we may have unidentified parents around, so go and
00802 // collect them (extracted[position]) will then be made true)
00803 _extract_tree_parents(position,extracted,lowest_constituent,unique_tree);
00804 }
00805
00806 // now look after the children...
00807 int child = _history[position].child;
00808 if (child >= 0) _extract_tree_children(child,extracted,lowest_constituent,unique_tree);
00809 }
|
|
||||||||||||||||||||
|
internal routine associated with the construction of the unique history order (following parents in the tree)
Reimplemented in fastjet::ClusterSequenceActiveArea. Definition at line 827 of file ClusterSequence.cc. References _history. Referenced by _extract_tree_children(). 00831 {
00832
00833 if (!extracted[position]) {
00834 int parent1 = _history[position].parent1;
00835 int parent2 = _history[position].parent2;
00836 // where relevant order parents so that we will first treat the
00837 // one containing the smaller "lowest_constituent"
00838 if (parent1 >= 0 && parent2 >= 0) {
00839 if (lowest_constituent[parent1] > lowest_constituent[parent2])
00840 swap(parent1, parent2);
00841 }
00842 // then actually run through the parents to extract the constituents...
00843 if (parent1 >= 0 && !extracted[parent1])
00844 _extract_tree_parents(parent1,extracted,lowest_constituent,unique_tree);
00845 if (parent2 >= 0 && !extracted[parent2])
00846 _extract_tree_parents(parent2,extracted,lowest_constituent,unique_tree);
00847 // finally declare this position to be accounted for and push it
00848 // onto our list.
00849 unique_tree.push_back(position);
00850 extracted[position] = true;
00851 }
00852 }
|
|
|
run a tiled clustering
Definition at line 508 of file ClusterSequence_TiledN2.cc. References _add_untagged_neighbours_to_tile_union(), _bj_diJ(), _bj_dist(), _bj_remove_from_tiles(), _do_iB_recombination_step(), _do_ij_recombination_step(), _initialise_tiles(), _invR2, _jets, fastjet::ClusterSequence::TiledJet::_jets_index, _R2, _tiles, _tj_set_jetinfo(), fastjet::ClusterSequence::Tile::begin_tiles, fastjet::ClusterSequence::TiledJet::diJ_posn, fastjet::ClusterSequence::Tile::end_tiles, fastjet::ClusterSequence::Tile::head, n_tile_neighbours, fastjet::ClusterSequence::TiledJet::next, fastjet::ClusterSequence::TiledJet::NN, fastjet::ClusterSequence::TiledJet::NN_dist, fastjet::ClusterSequence::Tile::tagged, and fastjet::ClusterSequence::TiledJet::tile_index. Referenced by _initialise_and_run(). 00508 {
00509
00510 _initialise_tiles();
00511
00512 int n = _jets.size();
00513 TiledJet * briefjets = new TiledJet[n];
00514 TiledJet * jetA = briefjets, * jetB;
00515 TiledJet oldB;
00516
00517
00518 // will be used quite deep inside loops, but declare it here so that
00519 // memory (de)allocation gets done only once
00520 vector<int> tile_union(3*n_tile_neighbours);
00521
00522 // initialise the basic jet info
00523 for (int i = 0; i< n; i++) {
00524 _tj_set_jetinfo(jetA, i);
00525 //cout << i<<": "<<jetA->tile_index<<"\n";
00526 jetA++; // move on to next entry of briefjets
00527 }
00528 TiledJet * head = briefjets; // a nicer way of naming start
00529
00530 // set up the initial nearest neighbour information
00531 vector<Tile>::const_iterator tile;
00532 for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
00533 // first do it on this tile
00534 for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
00535 for (jetB = tile->head; jetB != jetA; jetB = jetB->next) {
00536 double dist = _bj_dist(jetA,jetB);
00537 if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
00538 if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
00539 }
00540 }
00541 // then do it for RH tiles
00542 for (Tile ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
00543 for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
00544 for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
00545 double dist = _bj_dist(jetA,jetB);
00546 if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
00547 if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
00548 }
00549 }
00550 }
00551 // no need to do it for LH tiles, since they are implicitly done
00552 // when we set NN for both jetA and jetB on the RH tiles.
00553 }
00554
00555
00556 // now create the diJ (where J is i's NN) table -- remember that
00557 // we differ from standard normalisation here by a factor of R2
00558 // (corrected for at the end).
00559 struct diJ_plus_link {
00560 double diJ; // the distance
00561 TiledJet * jet; // the jet (i) for which we've found this distance
00562 // (whose NN will the J).
00563 };
00564 diJ_plus_link * diJ = new diJ_plus_link[n];
00565 jetA = head;
00566 for (int i = 0; i < n; i++) {
00567 diJ[i].diJ = _bj_diJ(jetA); // kt distance * R^2
00568 diJ[i].jet = jetA; // our compact diJ table will not be in
00569 jetA->diJ_posn = i; // one-to-one corresp. with non-compact jets,
00570 // so set up bi-directional correspondence here.
00571 jetA++; // have jetA follow i
00572 }
00573
00574 // now run the recombination loop
00575 int history_location = n-1;
00576 while (n > 0) {
00577
00578 // find the minimum of the diJ on this round
00579 diJ_plus_link * best, *stop; // pointers a bit faster than indices
00580 // could use best to keep track of diJ min, but it turns out to be
00581 // marginally faster to have a separate variable (avoids n
00582 // dereferences at the expense of n/2 assignments).
00583 double diJ_min = diJ[0].diJ; // initialise the best one here.
00584 best = diJ; // and here
00585 stop = diJ+n;
00586 for (diJ_plus_link * here = diJ+1; here != stop; here++) {
00587 if (here->diJ < diJ_min) {best = here; diJ_min = here->diJ;}
00588 }
00589
00590 // do the recombination between A and B
00591 history_location++;
00592 jetA = best->jet;
00593 jetB = jetA->NN;
00594 // put the normalisation back in
00595 diJ_min *= _invR2;
00596
00597 if (jetB != NULL) {
00598 // jet-jet recombination
00599 // If necessary relabel A & B to ensure jetB < jetA, that way if
00600 // the larger of them == newtail then that ends up being jetA and
00601 // the new jet that is added as jetB is inserted in a position that
00602 // has a future!
00603 if (jetA < jetB) {swap(jetA,jetB);}
00604
00605 int nn; // new jet index
00606 _do_ij_recombination_step(jetA->_jets_index, jetB->_jets_index, diJ_min, nn);
00607
00608 //OBS// get the two history indices
00609 //OBSint ihstry_a = _jets[jetA->_jets_index].cluster_hist_index();
00610 //OBSint ihstry_b = _jets[jetB->_jets_index].cluster_hist_index();
00611 //OBS// create the recombined jet
00612 //OBS_jets.push_back(_jets[jetA->_jets_index] + _jets[jetB->_jets_index]);
00613 //OBSint nn = _jets.size() - 1;
00614 //OBS_jets[nn].set_cluster_hist_index(history_location);
00615 //OBS// update history
00616 //OBS//cout <<n-1<<" "<<jetA-head<<" "<<jetB-head<<"; ";
00617 //OBS_add_step_to_history(history_location,
00618 //OBS min(ihstry_a,ihstry_b),max(ihstry_a,ihstry_b),
00619 //OBS nn, diJ_min);
00620 // what was jetB will now become the new jet
00621 _bj_remove_from_tiles(jetA);
00622 oldB = * jetB; // take a copy because we will need it...
00623 _bj_remove_from_tiles(jetB);
00624 _tj_set_jetinfo(jetB, nn); // cause jetB to become _jets[nn]
00625 // (also registers the jet in the tiling)
00626 } else {
00627 // jet-beam recombination
00628 // get the hist_index
00629 _do_iB_recombination_step(jetA->_jets_index, diJ_min);
00630 //OBSint ihstry_a = _jets[jetA->_jets_index].cluster_hist_index();
00631 //OBS//cout <<n-1<<" "<<jetA-head<<" "<<-1<<"; ";
00632 //OBS_add_step_to_history(history_location,ihstry_a,BeamJet,Invalid,diJ_min);
00633 _bj_remove_from_tiles(jetA);
00634 }
00635
00636 // first establish the set of tiles over which we are going to
00637 // have to run searches for updated and new nearest-neighbours --
00638 // basically a combination of vicinity of the tiles of the two old
00639 // and one new jet.
00640 int n_near_tiles = 0;
00641 _add_untagged_neighbours_to_tile_union(jetA->tile_index,
00642 tile_union, n_near_tiles);
00643 if (jetB != NULL) {
00644 if (jetB->tile_index != jetA->tile_index) {
00645 _add_untagged_neighbours_to_tile_union(jetB->tile_index,
00646 tile_union,n_near_tiles);
00647 }
00648 if (oldB.tile_index != jetA->tile_index &&
00649 oldB.tile_index != jetB->tile_index) {
00650 _add_untagged_neighbours_to_tile_union(oldB.tile_index,
00651 tile_union,n_near_tiles);
00652 }
00653 }
00654
00655 // now update our nearest neighbour info and diJ table
00656 // first reduce size of table
00657 n--;
00658 // then compactify the diJ by taking the last of the diJ and copying
00659 // it to the position occupied by the diJ for jetA
00660 diJ[n].jet->diJ_posn = jetA->diJ_posn;
00661 diJ[jetA->diJ_posn] = diJ[n];
00662
00663 // Initialise jetB's NN distance as well as updating it for
00664 // other particles.
00665 // Run over all tiles in our union
00666 for (int itile = 0; itile < n_near_tiles; itile++) {
00667 Tile * tile = &_tiles[tile_union[itile]];
00668 tile->tagged = false; // reset tag, since we're done with unions
00669 // run over all jets in the current tile
00670 for (TiledJet * jetI = tile->head; jetI != NULL; jetI = jetI->next) {
00671 // see if jetI had jetA or jetB as a NN -- if so recalculate the NN
00672 if (jetI->NN == jetA || (jetI->NN == jetB && jetB != NULL)) {
00673 jetI->NN_dist = _R2;
00674 jetI->NN = NULL;
00675 // now go over tiles that are neighbours of I (include own tile)
00676 for (Tile ** near_tile = tile->begin_tiles;
00677 near_tile != tile->end_tiles; near_tile++) {
00678 // and then over the contents of that tile
00679 for (TiledJet * jetJ = (*near_tile)->head;
00680 jetJ != NULL; jetJ = jetJ->next) {
00681 double dist = _bj_dist(jetI,jetJ);
00682 if (dist < jetI->NN_dist && jetJ != jetI) {
00683 jetI->NN_dist = dist; jetI->NN = jetJ;
00684 }
00685 }
00686 }
00687 diJ[jetI->diJ_posn].diJ = _bj_diJ(jetI); // update diJ kt-dist
00688 }
00689 // check whether new jetB is closer than jetI's current NN and
00690 // if jetI is closer than jetB's current (evolving) nearest
00691 // neighbour. Where relevant update things
00692 if (jetB != NULL) {
00693 double dist = _bj_dist(jetI,jetB);
00694 if (dist < jetI->NN_dist) {
00695 if (jetI != jetB) {
00696 jetI->NN_dist = dist;
00697 jetI->NN = jetB;
00698 diJ[jetI->diJ_posn].diJ = _bj_diJ(jetI); // update diJ...
00699 }
00700 }
00701 if (dist < jetB->NN_dist) {
00702 if (jetI != jetB) {
00703 jetB->NN_dist = dist;
00704 jetB->NN = jetI;}
00705 }
00706 }
00707 }
00708 }
00709
00710 // finally, register the updated kt distance for B
00711 if (jetB != NULL) {diJ[jetB->diJ_posn].diJ = _bj_diJ(jetB);}
00712
00713 }
00714
00715 // final cleaning up;
00716 delete[] diJ;
00717 delete[] briefjets;
00718 }
|
|
|
fill out the history (and jet cross refs) related to the initial set of jets (assumed already to have been "transferred"), without any clustering
Definition at line 204 of file ClusterSequence.cc. References _history, _initial_n, _jet_def, _jets, fastjet::ClusterSequence::history_element::child, fastjet::ClusterSequence::history_element::dij, InexistentParent, Invalid, fastjet::ClusterSequence::history_element::jetp_index, fastjet::ClusterSequence::history_element::max_dij_so_far, fastjet::ClusterSequence::history_element::parent1, fastjet::ClusterSequence::history_element::parent2, and fastjet::JetDefinition::recombiner(). Referenced by fastjet::ClusterSequenceActiveArea::_initialise_AA(), and _initialise_and_run(). 00204 {
00205
00206 if (_jets.size() == 0) {throw Error("Cannot run jet-finder on empty event");}
00207
00208 // reserve sufficient space for everything
00209 _jets.reserve(_jets.size()*2);
00210 _history.reserve(_jets.size()*2);
00211
00212 for (int i = 0; i < static_cast<int>(_jets.size()) ; i++) {
00213 history_element element;
00214 element.parent1 = InexistentParent;
00215 element.parent2 = InexistentParent;
00216 element.child = Invalid;
00217 element.jetp_index = i;
00218 element.dij = 0.0;
00219 element.max_dij_so_far = 0.0;
00220
00221 _history.push_back(element);
00222
00223 // do any momentum preprocessing needed by the recombination scheme
00224 _jet_def.recombiner()->preprocess(_jets[i]);
00225
00226 // get cross-referencing right from PseudoJets
00227 _jets[i].set_cluster_hist_index(i);
00228 }
00229 _initial_n = _jets.size();
00230 }
|
|
||||||||||||||||
|
This is an alternative routine for initialising and running the clustering, provided for legacy purposes. The jet finder is that specified in the static member _default_jet_algorithm. Definition at line 52 of file ClusterSequence.cc. References _default_jet_algorithm, _initialise_and_run(), and jet_def(). 00055 {
00056
00057 JetDefinition jet_def(_default_jet_algorithm, R, strategy);
00058 _initialise_and_run(jet_def, writeout_combinations);
00059 }
|
|
||||||||||||
|
This is the routine that will do all the initialisation and then run the clustering (may be called by various constructors). It assumes _jets contains the momenta to be clustered. Definition at line 63 of file ClusterSequence.cc. References _CP2DChan_cluster(), _CP2DChan_cluster_2pi2R(), _CP2DChan_cluster_2piMultD(), _decant_options(), _delaunay_cluster(), _faster_tiled_N2_cluster(), _fill_initial_history(), _jet_algorithm, _jet_def, _jets, _minheap_faster_tiled_N2_cluster(), _plugin_activated, _really_dumb_cluster(), _Rparam, _simple_N2_cluster(), _strategy, _tiled_N2_cluster(), fastjet::Best, fastjet::cambridge_algorithm, fastjet::JetDefinition::jet_algorithm(), fastjet::N2MinHeapTiled, fastjet::N2Plain, fastjet::N2PoorTiled, fastjet::N2Tiled, fastjet::N3Dumb, fastjet::NlnN, fastjet::NlnN3pi, fastjet::NlnN4pi, fastjet::NlnNCam, fastjet::NlnNCam2pi2R, fastjet::NlnNCam4pi, fastjet::JetDefinition::plugin(), and fastjet::plugin_algorithm. Referenced by fastjet::ClusterSequenceActiveArea::_initialise_AA(), _initialise_and_run(), and ClusterSequence(). 00065 {
00066
00067 // transfer all relevant info into internal variables
00068 _decant_options(jet_def, writeout_combinations);
00069
00070 // set up the history entries for the initial particles (those
00071 // currently in _jets)
00072 _fill_initial_history();
00073
00074 // run the plugin if that's what's decreed
00075 if (_jet_algorithm == plugin_algorithm) {
00076 _plugin_activated = true;
00077 _jet_def.plugin()->run_clustering( (*this) );
00078 _plugin_activated = false;
00079 return;
00080 }
00081
00082
00083 // automatically redefine the strategy according to N if that is
00084 // what the user requested -- transition points (and especially
00085 // their R-dependence) are based on empirical observations for a
00086 // R=0.4, 0.7 and 1.0, running on toth (3.4GHz, Pentium IV D [dual
00087 // core] with 2MB of cache).
00088 if (_strategy == Best) {
00089 int N = _jets.size();
00090 if (N > 6200/pow(_Rparam,2.0)
00091 && jet_def.jet_algorithm() == cambridge_algorithm) {
00092 _strategy = NlnNCam;}
00093 else
00094 #ifndef DROP_CGAL
00095 if (N > 16000/pow(_Rparam,1.15)) {
00096 _strategy = NlnN; }
00097 else
00098 #endif // DROP_CGAL
00099 if (N > 450) {
00100 _strategy = N2MinHeapTiled;
00101 }
00102 else if (N > 55*max(0.5,min(1.0,_Rparam))) {// empirical scaling with R
00103 _strategy = N2Tiled;
00104 } else {
00105 _strategy = N2Plain;
00106 }
00107 }
00108
00109
00110 // run the code containing the selected strategy
00111 if (_strategy == NlnN || _strategy == NlnN3pi
00112 || _strategy == NlnN4pi ) {
00113 this->_delaunay_cluster();
00114 } else if (_strategy == N3Dumb ) {
00115 this->_really_dumb_cluster();
00116 } else if (_strategy == N2Tiled) {
00117 this->_faster_tiled_N2_cluster();
00118 } else if (_strategy == N2PoorTiled) {
00119 this->_tiled_N2_cluster();
00120 } else if (_strategy == N2Plain) {
00121 this->_simple_N2_cluster();
00122 } else if (_strategy == N2MinHeapTiled) {
00123 this->_minheap_faster_tiled_N2_cluster();
00124 } else if (_strategy == NlnNCam4pi) {
00125 this->_CP2DChan_cluster();
00126 } else if (_strategy == NlnNCam2pi2R) {
00127 this->_CP2DChan_cluster_2pi2R();
00128 } else if (_strategy == NlnNCam) {
00129 this->_CP2DChan_cluster_2piMultD();
00130 } else {
00131 ostringstream err;
00132 err << "Unrecognised value for strategy: "<<_strategy;
00133 throw Error(err.str());
00134 //assert(false);
00135 }
00136 }
|
|
|
Set up the tiles:
The neighbourhood of a tile is set up as follows LRR LXR LLR such that tiles is an array containing XLLLLRRRR with pointers | \ RH_tiles \ surrounding_tiles with appropriate precautions when close to the edge of the tiled region. Definition at line 86 of file ClusterSequence_TiledN2.cc. References _jets, _n_tiles_phi, _Rparam, _tile_index(), _tile_size_eta, _tile_size_phi, _tiles, _tiles_eta_max, _tiles_eta_min, _tiles_ieta_max, _tiles_ieta_min, fastjet::ClusterSequence::Tile::begin_tiles, fastjet::ClusterSequence::Tile::end_tiles, fastjet::ClusterSequence::Tile::head, fastjet::ClusterSequence::Tile::RH_tiles, fastjet::ClusterSequence::Tile::surrounding_tiles, fastjet::ClusterSequence::Tile::tagged, and fastjet::twopi. Referenced by _faster_tiled_N2_cluster(), _minheap_faster_tiled_N2_cluster(), and _tiled_N2_cluster(). 00086 {
00087
00088 // first decide tile sizes
00089 _tile_size_eta = _Rparam;
00090 _n_tiles_phi = int(floor(twopi/_Rparam));
00091 _tile_size_phi = twopi / _n_tiles_phi; // >= _Rparam and fits in 2pi
00092
00093 // always include zero rapidity in the tiling region
00094 _tiles_eta_min = 0.0;
00095 _tiles_eta_max = 0.0;
00096 // but go no further than following
00097 const double maxrap = 7.0;
00098
00099 // and find out how much further one should go
00100 for(unsigned int i = 0; i < _jets.size(); i++) {
00101 double eta = _jets[i].rap();
00102 // first check if eta is in range -- to avoid taking into account
00103 // very spurious rapidities due to particles with near-zero kt.
00104 if (abs(eta) < maxrap) {
00105 if (eta < _tiles_eta_min) {_tiles_eta_min = eta;}
00106 if (eta > _tiles_eta_max) {_tiles_eta_max = eta;}
00107 }
00108 }
00109
00110 // now adjust the values
00111 _tiles_ieta_min = int(floor(_tiles_eta_min/_tile_size_eta));
00112 _tiles_ieta_max = int(floor( _tiles_eta_max/_tile_size_eta));
00113 _tiles_eta_min = _tiles_ieta_min * _tile_size_eta;
00114 _tiles_eta_max = _tiles_ieta_max * _tile_size_eta;
00115
00116 // allocate the tiles
00117 _tiles.resize((_tiles_ieta_max-_tiles_ieta_min+1)*_n_tiles_phi);
00118
00119 // now set up the cross-referencing between tiles
00120 for (int ieta = _tiles_ieta_min; ieta <= _tiles_ieta_max; ieta++) {
00121 for (int iphi = 0; iphi < _n_tiles_phi; iphi++) {
00122 Tile * tile = & _tiles[_tile_index(ieta,iphi)];
00123 // no jets in this tile yet
00124 tile->head = NULL; // first element of tiles points to itself
00125 tile->begin_tiles[0] = tile;
00126 Tile ** pptile = & (tile->begin_tiles[0]);
00127 pptile++;
00128 //
00129 // set up L's in column to the left of X
00130 tile->surrounding_tiles = pptile;
00131 if (ieta > _tiles_ieta_min) {
00132 // with the itile subroutine, we can safely run tiles from
00133 // idphi=-1 to idphi=+1, because it takes care of
00134 // negative and positive boundaries
00135 for (int idphi = -1; idphi <=+1; idphi++) {
00136 *pptile = & _tiles[_tile_index(ieta-1,iphi+idphi)];
00137 pptile++;
00138 }
00139 }
00140 // now set up last L (below X)
00141 *pptile = & _tiles[_tile_index(ieta,iphi-1)];
00142 pptile++;
00143 // set up first R (above X)
00144 tile->RH_tiles = pptile;
00145 *pptile = & _tiles[_tile_index(ieta,iphi+1)];
00146 pptile++;
00147 // set up remaining R's, to the right of X
00148 if (ieta < _tiles_ieta_max) {
00149 for (int idphi = -1; idphi <= +1; idphi++) {
00150 *pptile = & _tiles[_tile_index(ieta+1,iphi+idphi)];
00151 pptile++;
00152 }
00153 }
00154 // now put semaphore for end tile
00155 tile->end_tiles = pptile;
00156 // finally make sure tiles are untagged
00157 tile->tagged = false;
00158 }
00159 }
00160
00161 }
|
|
|
run a tiled clustering, with our minheap for keeping track of the smallest dij
Definition at line 725 of file ClusterSequence_TiledN2.cc. References _add_untagged_neighbours_to_tile_union(), _bj_diJ(), _bj_dist(), _bj_remove_from_tiles(), _do_iB_recombination_step(), _do_ij_recombination_step(), _initialise_tiles(), _invR2, _jets, fastjet::ClusterSequence::TiledJet::_jets_index, _R2, _tiles, _tj_set_jetinfo(), fastjet::ClusterSequence::Tile::begin_tiles, fastjet::ClusterSequence::Tile::end_tiles, fastjet::ClusterSequence::Tile::head, fastjet::ClusterSequence::TiledJet::label_minheap_update_done(), fastjet::MinHeap::minloc(), fastjet::MinHeap::minval(), n_tile_neighbours, fastjet::ClusterSequence::TiledJet::next, fastjet::ClusterSequence::TiledJet::NN, fastjet::ClusterSequence::TiledJet::NN_dist, fastjet::MinHeap::remove(), fastjet::ClusterSequence::Tile::tagged, fastjet::ClusterSequence::TiledJet::tile_index, and fastjet::MinHeap::update(). Referenced by _initialise_and_run(). 00725 {
00726
00727 _initialise_tiles();
00728
00729 int n = _jets.size();
00730 TiledJet * briefjets = new TiledJet[n];
00731 TiledJet * jetA = briefjets, * jetB;
00732 TiledJet oldB;
00733
00734
00735 // will be used quite deep inside loops, but declare it here so that
00736 // memory (de)allocation gets done only once
00737 vector<int> tile_union(3*n_tile_neighbours);
00738
00739 // initialise the basic jet info
00740 for (int i = 0; i< n; i++) {
00741 _tj_set_jetinfo(jetA, i);
00742 //cout << i<<": "<<jetA->tile_index<<"\n";
00743 jetA++; // move on to next entry of briefjets
00744 }
00745 TiledJet * head = briefjets; // a nicer way of naming start
00746
00747 // set up the initial nearest neighbour information
00748 vector<Tile>::const_iterator tile;
00749 for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
00750 // first do it on this tile
00751 for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
00752 for (jetB = tile->head; jetB != jetA; jetB = jetB->next) {
00753 double dist = _bj_dist(jetA,jetB);
00754 if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
00755 if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
00756 }
00757 }
00758 // then do it for RH tiles
00759 for (Tile ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
00760 for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
00761 for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
00762 double dist = _bj_dist(jetA,jetB);
00763 if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
00764 if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
00765 }
00766 }
00767 }
00768 // no need to do it for LH tiles, since they are implicitly done
00769 // when we set NN for both jetA and jetB on the RH tiles.
00770 }
00771
00772
00776 //struct diJ_plus_link {
00777 // double diJ; // the distance
00778 // TiledJet * jet; // the jet (i) for which we've found this distance
00779 // // (whose NN will the J).
00780 //};
00781 //diJ_plus_link * diJ = new diJ_plus_link[n];
00782 //jetA = head;
00783 //for (int i = 0; i < n; i++) {
00784 // diJ[i].diJ = _bj_diJ(jetA); // kt distance * R^2
00785 // diJ[i].jet = jetA; // our compact diJ table will not be in
00786 // jetA->diJ_posn = i; // one-to-one corresp. with non-compact jets,
00787 // // so set up bi-directional correspondence here.
00788 // jetA++; // have jetA follow i
00789 //}
00790
00791 vector<double> diJs(n);
00792 for (int i = 0; i < n; i++) {
00793 diJs[i] = _bj_diJ(&briefjets[i]);
00794 briefjets[i].label_minheap_update_done();
00795 }
00796 MinHeap minheap(diJs);
00797 // have a stack telling us which jets we'll have to update on the heap
00798 vector<TiledJet *> jets_for_minheap;
00799 jets_for_minheap.reserve(n);
00800
00801 // now run the recombination loop
00802 int history_location = n-1;
00803 while (n > 0) {
00804
00805 double diJ_min = minheap.minval() *_invR2;
00806 jetA = head + minheap.minloc();
00807
00808 // do the recombination between A and B
00809 history_location++;
00810 jetB = jetA->NN;
00811
00812 if (jetB != NULL) {
00813 // jet-jet recombination
00814 // If necessary relabel A & B to ensure jetB < jetA, that way if
00815 // the larger of them == newtail then that ends up being jetA and
00816 // the new jet that is added as jetB is inserted in a position that
00817 // has a future!
00818 if (jetA < jetB) {swap(jetA,jetB);}
00819
00820 int nn; // new jet index
00821 _do_ij_recombination_step(jetA->_jets_index, jetB->_jets_index, diJ_min, nn);
00822
00823 // what was jetB will now become the new jet
00824 _bj_remove_from_tiles(jetA);
00825 oldB = * jetB; // take a copy because we will need it...
00826 _bj_remove_from_tiles(jetB);
00827 _tj_set_jetinfo(jetB, nn); // cause jetB to become _jets[nn]
00828 // (also registers the jet in the tiling)
00829 } else {
00830 // jet-beam recombination
00831 // get the hist_index
00832 _do_iB_recombination_step(jetA->_jets_index, diJ_min);
00833 _bj_remove_from_tiles(jetA);
00834 }
00835
00836 // remove the minheap entry for jetA
00837 minheap.remove(jetA-head);
00838
00839 // first establish the set of tiles over which we are going to
00840 // have to run searches for updated and new nearest-neighbours --
00841 // basically a combination of vicinity of the tiles of the two old
00842 // and one new jet.
00843 int n_near_tiles = 0;
00844 _add_untagged_neighbours_to_tile_union(jetA->tile_index,
00845 tile_union, n_near_tiles);
00846 if (jetB != NULL) {
00847 if (jetB->tile_index != jetA->tile_index) {
00848 _add_untagged_neighbours_to_tile_union(jetB->tile_index,
00849 tile_union,n_near_tiles);
00850 }
00851 if (oldB.tile_index != jetA->tile_index &&
00852 oldB.tile_index != jetB->tile_index) {
00853 _add_untagged_neighbours_to_tile_union(oldB.tile_index,
00854 tile_union,n_near_tiles);
00855 }
00856 // indicate that we'll have to update jetB in the minheap
00857 jetB->label_minheap_update_needed();
00858 jets_for_minheap.push_back(jetB);
00859 }
00860
00861
00862 // Initialise jetB's NN distance as well as updating it for
00863 // other particles.
00864 // Run over all tiles in our union
00865 for (int itile = 0; itile < n_near_tiles; itile++) {
00866 Tile * tile = &_tiles[tile_union[itile]];
00867 tile->tagged = false; // reset tag, since we're done with unions
00868 // run over all jets in the current tile
00869 for (TiledJet * jetI = tile->head; jetI != NULL; jetI = jetI->next) {
00870 // see if jetI had jetA or jetB as a NN -- if so recalculate the NN
00871 if (jetI->NN == jetA || (jetI->NN == jetB && jetB != NULL)) {
00872 jetI->NN_dist = _R2;
00873 jetI->NN = NULL;
00874 // label jetI as needing heap action...
00875 if (!jetI->minheap_update_needed()) {
00876 jetI->label_minheap_update_needed();
00877 jets_for_minheap.push_back(jetI);}
00878 // now go over tiles that are neighbours of I (include own tile)
00879 for (Tile ** near_tile = tile->begin_tiles;
00880 near_tile != tile->end_tiles; near_tile++) {
00881 // and then over the contents of that tile
00882 for (TiledJet * jetJ = (*near_tile)->head;
00883 jetJ != NULL; jetJ = jetJ->next) {
00884 double dist = _bj_dist(jetI,jetJ);
00885 if (dist < jetI->NN_dist && jetJ != jetI) {
00886 jetI->NN_dist = dist; jetI->NN = jetJ;
00887 }
00888 }
00889 }
00890 }
00891 // check whether new jetB is closer than jetI's current NN and
00892 // if jetI is closer than jetB's current (evolving) nearest
00893 // neighbour. Where relevant update things
00894 if (jetB != NULL) {
00895 double dist = _bj_dist(jetI,jetB);
00896 if (dist < jetI->NN_dist) {
00897 if (jetI != jetB) {
00898 jetI->NN_dist = dist;
00899 jetI->NN = jetB;
00900 // label jetI as needing heap action...
00901 if (!jetI->minheap_update_needed()) {
00902 jetI->label_minheap_update_needed();
00903 jets_for_minheap.push_back(jetI);}
00904 }
00905 }
00906 if (dist < jetB->NN_dist) {
00907 if (jetI != jetB) {
00908 jetB->NN_dist = dist;
00909 jetB->NN = jetI;}
00910 }
00911 }
00912 }
00913 }
00914
00915 // deal with jets whose minheap entry needs updating
00916 while (jets_for_minheap.size() > 0) {
00917 TiledJet * jetI = jets_for_minheap.back();
00918 jets_for_minheap.pop_back();
00919 minheap.update(jetI-head, _bj_diJ(jetI));
00920 jetI->label_minheap_update_done();
00921 }
00922 n--;
00923 }
00924
00925 // final cleaning up;
00926 delete[] briefjets;
00927 }
|
|
|
returns true if the jet has a history index contained within the range of this CS
Definition at line 348 of file ClusterSequence.hh. References fastjet::PseudoJet::cluster_hist_index(). Referenced by object_in_jet(). 00348 {
00349 return jet.cluster_hist_index() >= 0
00350 && jet.cluster_hist_index() < int(_history.size());
00351 }
|
|
|
for making sure the user knows what it is they're running...
Definition at line 153 of file ClusterSequence.cc. References _first_time, and fastjet_version. Referenced by _decant_options(). 00153 {
00154
00155 if (!_first_time) {return;}
00156 _first_time = false;
00157
00158
00159 //Symp. Discr. Alg, p.472 (2002) and CGAL (http://www.cgal.org);
00160
00161 cout << "#--------------------------------------------------------------------------\n";
00162 cout << "# FastJet release " << fastjet_version << endl;
00163 cout << "# Written by M. Cacciari, G.P. Salam and G. Soyez \n";
00164 cout << "# http://www.lpthe.jussieu.fr/~salam/fastjet \n";
00165 cout << "# \n";
00166 cout << "# Longitudinally invariant Kt, anti-Kt, and inclusive Cambridge/Aachen \n";
00167 cout << "# clustering using fast geometric algorithms, with area measures and optional\n";
00168 cout << "# external jet-finder plugins. \n";
00169 cout << "# Please cite Phys. Lett. B641 (2006) [hep-ph/0512210] if you use this code.\n";
00170 cout << "# \n";
00171 cout << "# This package uses T.Chan's closest pair algorithm, Proc.13th ACM-SIAM \n";
00172 cout << "# Symp. Discr. Alg, p.472 (2002), S.Fortune's Voronoi algorithm and code " ;
00173 #ifndef DROP_CGAL
00174 cout << endl << "# and CGAL: http://www.cgal.org/";
00175 #endif // DROP_CGAL
00176 cout << ".\n";
00177 cout << "#-------------------------------------------------------------------------\n";
00178 }
|
|
|
output the contents of the tiles
Definition at line 210 of file ClusterSequence_TiledN2.cc. References _tiles. 00210 {
00211 for (vector<Tile>::const_iterator tile = _tiles.begin();
00212 tile < _tiles.end(); tile++) {
00213 cout << "Tile " << tile - _tiles.begin()<<" = ";
00214 vector<int> list;
00215 for (TiledJet * jetI = tile->head; jetI != NULL; jetI = jetI->next) {
00216 list.push_back(jetI-briefjets);
00217 //cout <<" "<<jetI-briefjets;
00218 }
00219 sort(list.begin(),list.end());
00220 for (unsigned int i = 0; i < list.size(); i++) {cout <<" "<<list[i];}
00221 cout <<"\n";
00222 }
00223 }
|
|
|
Run the clustering in a very slow variant of the N^3 algorithm. The only thing this routine has going for it is that memory usage is O(N)! Definition at line 50 of file ClusterSequence_DumbN3.cc. References _do_iB_recombination_step(), _do_ij_recombination_step(), _invR2, _jets, BeamJet, and jet_scale_for_algorithm(). Referenced by _initialise_and_run(). 00050 {
00051
00052 // the array that will be overwritten here will be one
00053 // of pointers to jets.
00054 vector<PseudoJet *> jetsp(_jets.size());
00055 vector<int> indices(_jets.size());
00056
00057 for (size_t i = 0; i<_jets.size(); i++) {
00058 jetsp[i] = & _jets[i];
00059 indices[i] = i;
00060 }
00061
00062 for (int n = jetsp.size(); n > 0; n--) {
00063 int ii, jj;
00064 // find smallest beam distance [remember jet_scale_for_algorithm
00065 // will return kt^2 for the kt-algorithm and 1 for the Cambridge/Aachen]
00066 double ymin = jet_scale_for_algorithm(*(jetsp[0]));
00067 ii = 0; jj = -2;
00068 for (int i = 0; i < n; i++) {
00069 double yiB = jet_scale_for_algorithm(*(jetsp[i]));
00070 if (yiB < ymin) {
00071 ymin = yiB; ii = i; jj = -2;}
00072 }
00073
00074 // find smallest distance between pair of jetsp
00075 for (int i = 0; i < n-1; i++) {
00076 for (int j = i+1; j < n; j++) {
00077 //double y = jetsp[i]->kt_distance(*jetsp[j])*_invR2;
00078 double y = min(jet_scale_for_algorithm(*(jetsp[i])),
00079 jet_scale_for_algorithm(*(jetsp[j])))
00080 * jetsp[i]->plain_distance(*jetsp[j])*_invR2;
00081 if (y < ymin) {ymin = y; ii = i; jj = j;}
00082 }
00083 }
00084
00085 // output recombination sequence
00086 // old "ktclus" way of labelling
00087 //cout <<n<< " "<< ii+1 << " with " << jj+1 << "; y = "<< ymin<<endl;
00088 // new delaunay way of labelling
00089 int jjindex_or_beam, iiindex;
00090 if (jj < 0) {jjindex_or_beam = BeamJet; iiindex = indices[ii];}
00091 else {
00092 jjindex_or_beam = max(indices[ii],indices[jj]);
00093 iiindex = min(indices[ii],indices[jj]);
00094 }
00095
00096 // now recombine
00097 int newn = 2*jetsp.size() - n;
00098 if (jj >= 0) {
00099 // combine pair
00100 int nn; // new jet index
00101 _do_ij_recombination_step(jetsp[ii]-&_jets[0],
00102 jetsp[jj]-&_jets[0], ymin, nn);
00103
00104 // sort out internal bookkeeping
00105 jetsp[ii] = &_jets[nn];
00106 // have jj point to jet that was pointed at by n-1
00107 // (since original jj is no longer current, so put n-1 into jj)
00108 jetsp[jj] = jetsp[n-1];
00109 indices[ii] = newn;
00110 indices[jj] = indices[n-1];
00111
00112 //OBS_jets.push_back(*jetsp[ii] + *jetsp[jj]);
00113 //OBSjetsp[ii] = &_jets[_jets.size()-1];
00114 //OBS// have jj point to jet that was pointed at by n-1
00115 //OBS// (since original jj is no longer current, so put n-1 into jj)
00116 //OBSjetsp[jj] = jetsp[n-1];
00117 //OBS
00118 //OBSindices[ii] = newn;
00119 //OBSindices[jj] = indices[n-1];
00120 //OBS_add_step_to_history(newn,iiindex,
00121 //OBS jjindex_or_beam,_jets.size()-1,ymin);
00122 } else {
00123 // combine ii with beam
00124 _do_iB_recombination_step(jetsp[ii]-&_jets[0], ymin);
00125 // put last jet (pointer) in place of ii (which has disappeared)
00126 jetsp[ii] = jetsp[n-1];
00127 indices[ii] = indices[n-1];
00128 //OBS_add_step_to_history(newn,iiindex,jjindex_or_beam,Invalid, ymin);
00129 }
00130 }
00131
00132 }
|
|
|
Order(N^2) clustering.
Definition at line 48 of file ClusterSequence_N2.cc. References _bj_diJ(), _bj_dist(), _bj_set_jetinfo(), _bj_set_NN_crosscheck(), _bj_set_NN_nocross(), _do_iB_recombination_step(), _do_ij_recombination_step(), _invR2, _jets, fastjet::ClusterSequence::BriefJet::_jets_index, and fastjet::ClusterSequence::BriefJet::NN. Referenced by _initialise_and_run(). 00048 {
00049 int n = _jets.size();
00050 BriefJet * briefjets = new BriefJet[n];
00051 BriefJet * jetA = briefjets, * jetB;
00052
00053 // initialise the basic jet info
00054 for (int i = 0; i< n; i++) {
00055 _bj_set_jetinfo(jetA, i);
00056 jetA++; // move on to next entry of briefjets
00057 }
00058 BriefJet * tail = jetA; // a semaphore for the end of briefjets
00059 BriefJet * head = briefjets; // a nicer way of naming start
00060
00061 // now initialise the NN distances: jetA will run from 1..n-1; and
00062 // jetB from 0..jetA-1
00063 for (jetA = head + 1; jetA != tail; jetA++) {
00064 // set NN info for jetA based on jets running from head..jetA-1,
00065 // checking in the process whether jetA itself is an undiscovered
00066 // NN of one of those jets.
00067 _bj_set_NN_crosscheck(jetA, head, jetA);
00068 }
00069
00070
00071 // now create the diJ (where J is i's NN) table -- remember that
00072 // we differ from standard normalisation here by a factor of R2
00073 double * diJ = new double[n];
00074 jetA = head;
00075 for (int i = 0; i < n; i++) {
00076 diJ[i] = _bj_diJ(jetA);
00077 jetA++; // have jetA follow i
00078 }
00079
00080 // now run the recombination loop
00081 int history_location = n-1;
00082 while (tail != head) {
00083
00084 // find the minimum of the diJ on this round
00085 double diJ_min = diJ[0];
00086 int diJ_min_jet = 0;
00087 for (int i = 1; i < n; i++) {
00088 if (diJ[i] < diJ_min) {diJ_min_jet = i; diJ_min = diJ[i];}
00089 }
00090
00091 // do the recombination between A and B
00092 history_location++;
00093 jetA = & briefjets[diJ_min_jet];
00094 jetB = jetA->NN;
00095 // put the normalisation back in
00096 diJ_min *= _invR2;
00097 if (jetB != NULL) {
00098 // jet-jet recombination
00099 // If necessary relabel A & B to ensure jetB < jetA, that way if
00100 // the larger of them == newtail then that ends up being jetA and
00101 // the new jet that is added as jetB is inserted in a position that
00102 // has a future!
00103 if (jetA < jetB) {swap(jetA,jetB);}
00104
00105 int nn; // new jet index
00106 _do_ij_recombination_step(jetA->_jets_index, jetB->_jets_index, diJ_min, nn);
00107
00108 //OBS // get the two history indices
00109 //OBS int hist_a = _jets[jetA->_jets_index].cluster_hist_index();
00110 //OBS int hist_b = _jets[jetB->_jets_index].cluster_hist_index();
00111 //OBS // create the recombined jet
00112 //OBS _jets.push_back(_jets[jetA->_jets_index] + _jets[jetB->_jets_index]);
00113 //OBS int nn = _jets.size() - 1;
00114 //OBS _jets[nn].set_cluster_hist_index(history_location);
00115 //OBS // update history
00116 //OBS _add_step_to_history(history_location,
00117 //OBS min(hist_a,hist_b),max(hist_a,hist_b),
00118 //OBS nn, diJ_min);
00119 // what was jetB will now become the new jet
00120 _bj_set_jetinfo(jetB, nn);
00121 } else {
00122 // jet-beam recombination
00123 _do_iB_recombination_step(jetA->_jets_index, diJ_min);
00124 //OBS // get the hist_index
00125 //OBS int hist_a = _jets[jetA->_jets_index].cluster_hist_index();
00126 //OBS _add_step_to_history(history_location,hist_a,BeamJet,Invalid,diJ_min);
00127 }
00128
00129 // now update our nearest neighbour info and diJ table
00130 // first reduce size of table
00131 tail--; n--;
00132 // Copy last jet contents and diJ info into position of jetA
00133 *jetA = *tail;
00134 diJ[jetA - head] = diJ[tail-head];
00135
00136 // Initialise jetB's NN distance as well as updating it for
00137 // other particles.
00138 // NB: by having different loops for jetB == or != NULL we could
00139 // perhaps save a few percent (usually avoid one if inside loop),
00140 // but will not do it for now because on laptop fluctuations are
00141 // too large to reliably measure a few percent difference...
00142 for (BriefJet * jetI = head; jetI != tail; jetI++) {
00143 // see if jetI had jetA or jetB as a NN -- if so recalculate the NN
00144 if (jetI->NN == jetA || jetI->NN == jetB) {
00145 _bj_set_NN_nocross(jetI, head, tail);
00146 diJ[jetI-head] = _bj_diJ(jetI); // update diJ
00147 }
00148 // check whether new jetB is closer than jetI's current NN and
00149 // if need be update things
00150 if (jetB != NULL) {
00151 double dist = _bj_dist(jetI,jetB);
00152 if (dist < jetI->NN_dist) {
00153 if (jetI != jetB) {
00154 jetI->NN_dist = dist;
00155 jetI->NN = jetB;
00156 diJ[jetI-head] = _bj_diJ(jetI); // update diJ...
00157 }
00158 }
00159 if (dist < jetB->NN_dist) {
00160 if (jetI != jetB) {
00161 jetB->NN_dist = dist;
00162 jetB->NN = jetI;}
00163 }
00164 }
00165 // if jetI's NN is the new tail then relabel it so that it becomes jetA
00166 if (jetI->NN == tail) {jetI->NN = jetA;}
00167 }
00168
00169
00170 if (jetB != NULL) {diJ[jetB-head] = _bj_diJ(jetB);}
00171
00172
00173 }
00174
00175
00176 // final cleaning up;
00177 delete[] diJ;
00178 delete[] briefjets;
00179 }
|
|
||||||||||||
|
return the tile index corresponding to the given eta,phi point
Definition at line 166 of file ClusterSequence_TiledN2.cc. References _n_tiles_phi, _tile_size_eta, _tile_size_phi, _tiles_eta_max, _tiles_eta_min, _tiles_ieta_max, _tiles_ieta_min, and fastjet::twopi. 00166 {
00167 int ieta, iphi;
00168 if (eta <= _tiles_eta_min) {ieta = 0;}
00169 else if (eta >= _tiles_eta_max) {ieta = _tiles_ieta_max-_tiles_ieta_min;}
00170 else {
00171 //ieta = int(floor((eta - _tiles_eta_min) / _tile_size_eta));
00172 ieta = int(((eta - _tiles_eta_min) / _tile_size_eta));
00173 // following needed in case of rare but nasty rounding errors
00174 if (ieta > _tiles_ieta_max-_tiles_ieta_min) {
00175 ieta = _tiles_ieta_max-_tiles_ieta_min;}
00176 }
00177 // allow for some extent of being beyond range in calculation of phi
00178 // as well
00179 //iphi = (int(floor(phi/_tile_size_phi)) + _n_tiles_phi) % _n_tiles_phi;
00180 // with just int and no floor, things run faster but beware
00181 iphi = int((phi+twopi)/_tile_size_phi) % _n_tiles_phi;
00182 return (iphi + ieta * _n_tiles_phi);
00183 }
|
|
||||||||||||
|
Definition at line 573 of file ClusterSequence.hh. Referenced by _initialise_tiles(), and _tj_set_jetinfo(). 00573 {
00574 // note that (-1)%n = -1 so that we have to add _n_tiles_phi
00575 // before performing modulo operation
00576 return (ieta-_tiles_ieta_min)*_n_tiles_phi
00577 + (iphi+_n_tiles_phi) % _n_tiles_phi;
00578 }
|
|
|
run a tiled clustering
Definition at line 265 of file ClusterSequence_TiledN2.cc. References _add_neighbours_to_tile_union(), _bj_diJ(), _bj_dist(), _bj_remove_from_tiles(), _do_iB_recombination_step(), _do_ij_recombination_step(), _initialise_tiles(), _invR2, _jets, fastjet::ClusterSequence::TiledJet::_jets_index, _R2, _tiles, _tj_set_jetinfo(), fastjet::ClusterSequence::Tile::begin_tiles, fastjet::ClusterSequence::Tile::end_tiles, fastjet::ClusterSequence::Tile::head, n_tile_neighbours, fastjet::ClusterSequence::TiledJet::next, fastjet::ClusterSequence::TiledJet::NN, fastjet::ClusterSequence::TiledJet::NN_dist, fastjet::ClusterSequence::TiledJet::previous, and fastjet::ClusterSequence::TiledJet::tile_index. Referenced by _initialise_and_run(). 00265 {
00266
00267 _initialise_tiles();
00268
00269 int n = _jets.size();
00270 TiledJet * briefjets = new TiledJet[n];
00271 TiledJet * jetA = briefjets, * jetB;
00272 TiledJet oldB;
00273
00274
00275 // will be used quite deep inside loops, but declare it here so that
00276 // memory (de)allocation gets done only once
00277 vector<int> tile_union(3*n_tile_neighbours);
00278
00279 // initialise the basic jet info
00280 for (int i = 0; i< n; i++) {
00281 _tj_set_jetinfo(jetA, i);
00282 //cout << i<<": "<<jetA->tile_index<<"\n";
00283 jetA++; // move on to next entry of briefjets
00284 }
00285 TiledJet * tail = jetA; // a semaphore for the end of briefjets
00286 TiledJet * head = briefjets; // a nicer way of naming start
00287
00288 // set up the initial nearest neighbour information
00289 vector<Tile>::const_iterator tile;
00290 for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
00291 // first do it on this tile
00292 for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
00293 for (jetB = tile->head; jetB != jetA; jetB = jetB->next) {
00294 double dist = _bj_dist(jetA,jetB);
00295 if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
00296 if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
00297 }
00298 }
00299 // then do it for RH tiles
00300 for (Tile ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
00301 for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
00302 for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
00303 double dist = _bj_dist(jetA,jetB);
00304 if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
00305 if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
00306 }
00307 }
00308 }
00309 }
00310
00311 // now create the diJ (where J is i's NN) table -- remember that
00312 // we differ from standard normalisation here by a factor of R2
00313 double * diJ = new double[n];
00314 jetA = head;
00315 for (int i = 0; i < n; i++) {
00316 diJ[i] = _bj_diJ(jetA);
00317 jetA++; // have jetA follow i
00318 }
00319
00320 // now run the recombination loop
00321 int history_location = n-1;
00322 while (tail != head) {
00323
00324 // find the minimum of the diJ on this round
00325 double diJ_min = diJ[0];
00326 int diJ_min_jet = 0;
00327 for (int i = 1; i < n; i++) {
00328 if (diJ[i] < diJ_min) {diJ_min_jet = i; diJ_min = diJ[i];}
00329 }
00330
00331 // do the recombination between A and B
00332 history_location++;
00333 jetA = & briefjets[diJ_min_jet];
00334 jetB = jetA->NN;
00335 // put the normalisation back in
00336 diJ_min *= _invR2;
00337
00338 //if (n == 19) {cout << "Hello "<<jetA-head<<" "<<jetB-head<<"\n";}
00339
00340 //cout <<" WILL RECOMBINE "<< jetA-briefjets<<" "<<jetB-briefjets<<"\n";
00341
00342 if (jetB != NULL) {
00343 // jet-jet recombination
00344 // If necessary relabel A & B to ensure jetB < jetA, that way if
00345 // the larger of them == newtail then that ends up being jetA and
00346 // the new jet that is added as jetB is inserted in a position that
00347 // has a future!
00348 if (jetA < jetB) {swap(jetA,jetB);}
00349
00350 int nn; // new jet index
00351 _do_ij_recombination_step(jetA->_jets_index, jetB->_jets_index, diJ_min, nn);
00352
00353 //OBS// get the two history indices
00354 //OBSint hist_a = _jets[jetA->_jets_index].cluster_hist_index();
00355 //OBSint hist_b = _jets[jetB->_jets_index].cluster_hist_index();
00356 //OBS// create the recombined jet
00357 //OBS_jets.push_back(_jets[jetA->_jets_index] + _jets[jetB->_jets_index]);
00358 //OBSint nn = _jets.size() - 1;
00359 //OBS_jets[nn].set_cluster_hist_index(history_location);
00360 //OBS// update history
00361 //OBS//cout <<n-1<<" "<<jetA-head<<" "<<jetB-head<<"; ";
00362 //OBS_add_step_to_history(history_location,
00363 //OBS min(hist_a,hist_b),max(hist_a,hist_b),
00364 //OBS nn, diJ_min);
00365
00366 // what was jetB will now become the new jet
00367 _bj_remove_from_tiles(jetA);
00368 oldB = * jetB; // take a copy because we will need it...
00369 _bj_remove_from_tiles(jetB);
00370 _tj_set_jetinfo(jetB, nn); // also registers the jet in the tiling
00371 } else {
00372 // jet-beam recombination
00373 _do_iB_recombination_step(jetA->_jets_index, diJ_min);
00374
00375 //OBS// get the hist_index
00376 //OBSint hist_a = _jets[jetA->_jets_index].cluster_hist_index();
00377 //OBS//cout <<n-1<<" "<<jetA-head<<" "<<-1<<"; ";
00378 //OBS_add_step_to_history(history_location,hist_a,BeamJet,Invalid,diJ_min);
00379 _bj_remove_from_tiles(jetA);
00380 }
00381
00382 // first establish the set of tiles over which we are going to
00383 // have to run searches for updated and new nearest-neighbours
00384 int n_near_tiles = 0;
00385 _add_neighbours_to_tile_union(jetA->tile_index, tile_union, n_near_tiles);
00386 if (jetB != NULL) {
00387 bool sort_it = false;
00388 if (jetB->tile_index != jetA->tile_index) {
00389 sort_it = true;
00390 _add_neighbours_to_tile_union(jetB->tile_index,tile_union,n_near_tiles);
00391 }
00392 if (oldB.tile_index != jetA->tile_index &&
00393 oldB.tile_index != jetB->tile_index) {
00394 sort_it = true;
00395 _add_neighbours_to_tile_union(oldB.tile_index,tile_union,n_near_tiles);
00396 }
00397
00398 if (sort_it) {
00399 // sort the tiles before then compressing the list
00400 sort(tile_union.begin(), tile_union.begin()+n_near_tiles);
00401 // and now condense the list
00402 int nnn = 1;
00403 for (int i = 1; i < n_near_tiles; i++) {
00404 if (tile_union[i] != tile_union[nnn-1]) {
00405 tile_union[nnn] = tile_union[i];
00406 nnn++;
00407 }
00408 }
00409 n_near_tiles = nnn;
00410 }
00411 }
00412
00413 // now update our nearest neighbour info and diJ table
00414 // first reduce size of table
00415 tail--; n--;
00416 if (jetA == tail) {
00417 // there is nothing to be done
00418 } else {
00419 // Copy last jet contents and diJ info into position of jetA
00420 *jetA = *tail;
00421 diJ[jetA - head] = diJ[tail-head];
00422 // IN the tiling fix pointers to tail and turn them into
00423 // pointers to jetA (from predecessors, successors and the tile
00424 // head if need be)
00425 if (jetA->previous == NULL) {
00426 _tiles[jetA->tile_index].head = jetA;
00427 } else {
00428 jetA->previous->next = jetA;
00429 }
00430 if (jetA->next != NULL) {jetA->next->previous = jetA;}
00431 }
00432
00433 // Initialise jetB's NN distance as well as updating it for
00434 // other particles.
00435 for (int itile = 0; itile < n_near_tiles; itile++) {
00436 Tile * tile = &_tiles[tile_union[itile]];
00437 for (TiledJet * jetI = tile->head; jetI != NULL; jetI = jetI->next) {
00438 // see if jetI had jetA or jetB as a NN -- if so recalculate the NN
00439 if (jetI->NN == jetA || (jetI->NN == jetB && jetB != NULL)) {
00440 jetI->NN_dist = _R2;
00441 jetI->NN = NULL;
00442 // now go over tiles that are neighbours of I (include own tile)
00443 for (Tile ** near_tile = tile->begin_tiles;
00444 near_tile != tile->end_tiles; near_tile++) {
00445 // and then over the contents of that tile
00446 for (TiledJet * jetJ = (*near_tile)->head;
00447 jetJ != NULL; jetJ = jetJ->next) {
00448 double dist = _bj_dist(jetI,jetJ);
00449 if (dist < jetI->NN_dist && jetJ != jetI) {
00450 jetI->NN_dist = dist; jetI->NN = jetJ;
00451 }
00452 }
00453 }
00454 diJ[jetI-head] = _bj_diJ(jetI); // update diJ
00455 }
00456 // check whether new jetB is closer than jetI's current NN and
00457 // if need to update things
00458 if (jetB != NULL) {
00459 double dist = _bj_dist(jetI,jetB);
00460 if (dist < jetI->NN_dist) {
00461 if (jetI != jetB) {
00462 jetI->NN_dist = dist;
00463 jetI->NN = jetB;
00464 diJ[jetI-head] = _bj_diJ(jetI); // update diJ...
00465 }
00466 }
00467 if (dist < jetB->NN_dist) {
00468 if (jetI != jetB) {
00469 jetB->NN_dist = dist;
00470 jetB->NN = jetI;}
00471 }
00472 }
00473 }
00474 }
00475
00476
00477 if (jetB != NULL) {diJ[jetB-head] = _bj_diJ(jetB);}
00478 //cout << n<<" "<<briefjets[95].NN-briefjets<<" "<<briefjets[95].NN_dist <<"\n";
00479
00480 // remember to update pointers to tail
00481 for (Tile ** near_tile = _tiles[tail->tile_index].begin_tiles;
00482 near_tile!= _tiles[tail->tile_index].end_tiles; near_tile++){
00483 // and then the contents of that tile
00484 for (TiledJet * jetJ = (*near_tile)->head;
00485 jetJ != NULL; jetJ = jetJ->next) {
00486 if (jetJ->NN == tail) {jetJ->NN = jetA;}
00487 }
00488 }
00489
00490 //for (int i = 0; i < n; i++) {
00491 // if (briefjets[i].NN-briefjets >= n && briefjets[i].NN != NULL) {cout <<"YOU MUST BE CRAZY for n ="<<n<<", i = "<<i<<", NN = "<<briefjets[i].NN-briefjets<<"\n";}
00492 //}
00493
00494
00495 if (jetB != NULL) {diJ[jetB-head] = _bj_diJ(jetB);}
00496 //cout << briefjets[95].NN-briefjets<<" "<<briefjets[95].NN_dist <<"\n";
00497
00498 }
00499
00500 // final cleaning up;
00501 delete[] diJ;
00502 delete[] briefjets;
00503 }
|
|
||||||||||||
|
Definition at line 189 of file ClusterSequence_TiledN2.cc. References _tile_index(), _tiles, and fastjet::ClusterSequence::Tile::head. Referenced by _faster_tiled_N2_cluster(), _minheap_faster_tiled_N2_cluster(), and _tiled_N2_cluster(). 00190 {
00191 // first call the generic setup
00192 _bj_set_jetinfo<>(jet, _jets_index);
00193
00194 // Then do the setup specific to the tiled case.
00195
00196 // Find out which tile it belonds to
00197 jet->tile_index = _tile_index(jet->eta, jet->phi);
00198
00199 // Insert it into the tile's linked list of jets
00200 Tile * tile = &_tiles[jet->tile_index];
00201 jet->previous = NULL;
00202 jet->next = tile->head;
00203 if (jet->next != NULL) {jet->next->previous = jet;}
00204 tile->head = jet;
00205 }
|
|
||||||||||
|
transfer the vector<L> of input jets into our own vector<PseudoJet> _jets (with some reserved space for future growth).
Definition at line 604 of file ClusterSequence.hh. References _jets. Referenced by ClusterSequence(). 00605 {
00606
00607 // this will ensure that we can point to jets without difficulties
00608 // arising.
00609 _jets.reserve(pseudojets.size()*2);
00610
00611 // insert initial jets this way so that any type L that can be
00612 // converted to a pseudojet will work fine (basically PseudoJet
00613 // and any type that has [] subscript access to the momentum
00614 // components, such as CLHEP HepLorentzVector).
00615 for (unsigned int i = 0; i < pseudojets.size(); i++) {
00616 _jets.push_back(pseudojets[i]);}
00617
00618 }
|
|
||||||||||||
|
add on to subjet_vector the subjets of jet (for internal use mainly)
Definition at line 688 of file ClusterSequence.cc. References _history, _jets, BeamJet, fastjet::PseudoJet::cluster_hist_index(), and InexistentParent. Referenced by constituents(). 00689 {
00690 // find out position in cluster history
00691 int i = jet.cluster_hist_index();
00692 int parent1 = _history[i].parent1;
00693 int parent2 = _history[i].parent2;
00694
00695 if (parent1 == InexistentParent) {
00696 // It is an original particle (labelled by its parent having value
00697 // InexistentParent), therefore add it on to the subjet vector
00698 subjet_vector.push_back(jet);
00699 return;
00700 }
00701
00702 // add parent 1
00703 add_constituents(_jets[_history[parent1].jetp_index], subjet_vector);
00704
00705 // see if parent2 is a real jet; if it is then add its constituents
00706 if (parent2 != BeamJet) {
00707 add_constituents(_jets[_history[parent2].jetp_index], subjet_vector);
00708 }
00709 }
|
|
|
return a vector of the particles that make up jet
Definition at line 606 of file ClusterSequence.cc. References add_constituents(). Referenced by main(), particle_jet_indices(), print_jets(), and print_jets_for_root(). 00606 {
00607 vector<PseudoJet> subjets;
00608 add_constituents(jet, subjets);
00609 return subjets;
00610 }
|
|
|
return the dmin corresponding to the recombination that went from n+1 to n jets
Definition at line 466 of file ClusterSequence.cc. References _history, and _initial_n. 00466 {
00467 assert(njets >= 0);
00468 if (njets >= _initial_n) {return 0.0;}
00469 return _history[2*_initial_n-njets-1].dij;
00470 }
|
|
|
return the maximum of the dmin encountered during all recombinations up to the one that led to an n-jet final state; identical to exclusive_dmerge, except in cases where the dmin do not increase monotonically.
Definition at line 478 of file ClusterSequence.cc. References _history, and _initial_n. 00478 {
00479 assert(njets >= 0);
00480 if (njets >= _initial_n) {return 0.0;}
00481 return _history[2*_initial_n-njets-1].max_dij_so_far;
00482 }
|
|
|
return a vector of all jets when the event is clustered (in the exclusive sense) to exactly njets.
Definition at line 406 of file ClusterSequence.cc. References _history, _initial_n, _jet_def, _jets, _n_exclusive_warnings, fastjet::JetDefinition::jet_algorithm(), jets(), and fastjet::kt_algorithm. 00406 {
00407
00408 // make sure the user does not ask for more than jets than there
00409 // were particles in the first place.
00410 assert (njets <= _initial_n);
00411
00412 // provide a warning when extracting exclusive jets
00413 if (_jet_def.jet_algorithm() != kt_algorithm && _n_exclusive_warnings < 5) {
00414 _n_exclusive_warnings++;
00415 cerr << "FastJet WARNING: dcut and exclusive jets for jet-finders other than kt should be interpreted with care." << endl;
00416 }
00417
00418
00419 // calculate the point where we have to stop the clustering.
00420 // relation between stop_point, njets assumes one extra jet disappears
00421 // at each clustering.
00422 int stop_point = 2*_initial_n - njets;
00423
00424 // some sanity checking to make sure that e+e- does not give us
00425 // surprises (should we ever implement e+e-)...
00426 if (2*_initial_n != static_cast<int>(_history.size())) {
00427 ostringstream err;
00428 err << "2*_initial_n != _history.size() -- this endangers internal assumptions!\n";
00429 throw Error(err.str());
00430 //assert(false);
00431 }
00432
00433 // now go forwards and reconstitute the jets that we have --
00434 // basically for any history element, see if the parent jets to
00435 // which it refers were created before the stopping point -- if they
00436 // were then add them to the list, otherwise they are subsequent
00437 // recombinations of the jets that we are looking for.
00438 vector<PseudoJet> jets;
00439 for (unsigned int i = stop_point; i < _history.size(); i++) {
00440 int parent1 = _history[i].parent1;
00441 if (parent1 < stop_point) {
00442 jets.push_back(_jets[_history[parent1].jetp_index]);
00443 }
00444 int parent2 = _history[i].parent2;
00445 if (parent2 < stop_point && parent2 > 0) {
00446 jets.push_back(_jets[_history[parent2].jetp_index]);
00447 }
00448
00449 }
00450
00451 // sanity check...
00452 if (static_cast<int>(jets.size()) != njets) {
00453 ostringstream err;
00454 err << "ClusterSequence::exclusive_jets: size of returned vector ("
00455 <<jets.size()<<") does not coincide with requested number of jets ("
00456 <<njets<<")";
00457 throw Error(err.str());
00458 }
00459
00460 return jets;
00461 }
|
|
|
return a vector of all jets (in the sense of the exclusive algorithm) that would be obtained when running the algorithm with the given dcut.
Definition at line 398 of file ClusterSequence.cc. References n_exclusive_jets(). Referenced by main(). 00398 {
00399 int njets = n_exclusive_jets(dcut);
00400 return exclusive_jets(njets);
00401 }
|
|
|
returns a pointer to the extras object (may be null)
Definition at line 247 of file ClusterSequence.hh. Referenced by main(). 00247 {return _extras.get();}
|
|
||||||||||||
|
Version of has_child that sets a pointer to the child if the child exists;.
Definition at line 558 of file ClusterSequence.cc. References _history, _jets, fastjet::ClusterSequence::history_element::child, and fastjet::PseudoJet::cluster_hist_index(). 00558 {
00559
00560 const history_element & hist = _history[jet.cluster_hist_index()];
00561
00562 // check that this jet has a child and that the child corresponds to
00563 // a true jet [RETHINK-IF-CHANGE-NUMBERING: what is the right
00564 // behaviour if the child is the same jet but made inclusive...?]
00565 if (hist.child >= 0 && _history[hist.child].jetp_index >= 0) {
00566 childp = &(_jets[_history[hist.child].jetp_index]);
00567 return true;
00568 } else {
00569 childp = NULL;
00570 return false;
00571 }
00572 }
|
|
||||||||||||
|
if the jet has a child then return true and give the child jet otherwise return false and set the child to zero
Definition at line 536 of file ClusterSequence.cc. Referenced by object_in_jet(). 00536 {
00537
00538 //const history_element & hist = _history[jet.cluster_hist_index()];
00539 //
00540 //if (hist.child >= 0) {
00541 // child = _jets[_history[hist.child].jetp_index];
00542 // return true;
00543 //} else {
00544 // child = PseudoJet(0.0,0.0,0.0,0.0);
00545 // return false;
00546 //}
00547 const PseudoJet * childp;
00548 bool res = has_child(jet, childp);
00549 if (res) {
00550 child = *childp;
00551 return true;
00552 } else {
00553 child = PseudoJet(0.0,0.0,0.0,0.0);
00554 return false;
00555 }
00556 }
|
|
||||||||||||||||
|
if the jet has parents in the clustering, it returns true and sets parent1 and parent2 equal to them. if it has no parents it returns false and sets parent1 and parent2 to zero Definition at line 510 of file ClusterSequence.cc. References _history, _jets, fastjet::ClusterSequence::history_element::parent1, fastjet::ClusterSequence::history_element::parent2, and fastjet::PseudoJet::perp2(). 00511 {
00512
00513 const history_element & hist = _history[jet.cluster_hist_index()];
00514
00515 // make sure we do not run into any unexpected situations --
00516 // i.e. both parents valid, or neither
00517 assert ((hist.parent1 >= 0 && hist.parent2 >= 0) ||
00518 (hist.parent1 < 0 && hist.parent2 < 0));
00519
00520 if (hist.parent1 < 0) {
00521 parent1 = PseudoJet(0.0,0.0,0.0,0.0);
00522 parent2 = parent1;
00523 return false;
00524 } else {
00525 parent1 = _jets[_history[hist.parent1].jetp_index];
00526 parent2 = _jets[_history[hist.parent2].jetp_index];
00527 // order the parents in decreasing pt
00528 if (parent1.perp2() < parent2.perp2()) swap(parent1,parent2);
00529 return true;
00530 }
00531 }
|
|
||||||||||||
|
if this jet has a child (and so a partner) return true and give the partner, otherwise return false and set the partner to zero
Definition at line 579 of file ClusterSequence.cc. References _history, _jets, fastjet::ClusterSequence::history_element::child, fastjet::PseudoJet::cluster_hist_index(), fastjet::ClusterSequence::history_element::parent1, and fastjet::ClusterSequence::history_element::parent2. 00580 {
00581
00582 const history_element & hist = _history[jet.cluster_hist_index()];
00583
00584 // make sure we have a child and that the child does not correspond
00585 // to a clustering with the beam (or some other invalid quantity)
00586 if (hist.child >= 0 && _history[hist.child].parent2 >= 0) {
00587 const history_element & child_hist = _history[hist.child];
00588 if (child_hist.parent1 == jet.cluster_hist_index()) {
00589 // partner will be child's parent2 -- for iB clustering
00590 // parent2 will not be valid
00591 partner = _jets[_history[child_hist.parent2].jetp_index];
00592 } else {
00593 // partner will be child's parent1
00594 partner = _jets[_history[child_hist.parent1].jetp_index];
00595 }
00596 return true;
00597 } else {
00598 partner = PseudoJet(0.0,0.0,0.0,0.0);
00599 return false;
00600 }
00601 }
|
|
|
allow the user to access the history in this raw manner (see above for motivation).
Definition at line 657 of file ClusterSequence.hh. References _history. Referenced by fastjet::ClusterSequenceActiveArea::_transfer_areas(), main(), and particle_jet_indices(). 00657 {
00658 return _history;
00659 }
|
|
|
return a vector of all jets (in the sense of the inclusive algorithm) with pt >= ptmin. Time taken should be of the order of the number of jets returned. Definition at line 330 of file ClusterSequence.cc. References _history, _jet_algorithm, _jets, fastjet::antikt_algorithm, BeamJet, fastjet::cambridge_algorithm, fastjet::cambridge_for_passive_algorithm, jets(), fastjet::kt_algorithm, fastjet::PseudoJet::perp2(), and fastjet::plugin_algorithm. Referenced by fastjet::ClusterSequenceAreaBase::empty_area(), fastjet::ClusterSequenceAreaBase::get_median_rho_and_sigma(), main(), fastjet::ClusterSequenceAreaBase::parabolic_pt_per_unit_area(), fastjet::ClusterSequenceActiveArea::pt_per_unit_area(), run_jet_finder(), and fastjet::ClusterSequenceAreaBase::subtracted_jets(). 00330 {
00331 double dcut = ptmin*ptmin;
00332 int i = _history.size() - 1; // last jet
00333 vector<PseudoJet> jets;
00334 if (_jet_algorithm == kt_algorithm) {
00335 while (i >= 0) {
00336 // with our specific definition of dij and diB (i.e. R appears only in
00337 // dij), then dij==diB is the same as the jet.perp2() and we can exploit
00338 // this in selecting the jets...
00339 if (_history[i].max_dij_so_far < dcut) {break;}
00340 if (_history[i].parent2 == BeamJet && _history[i].dij >= dcut) {
00341 // for beam jets
00342 int parent1 = _history[i].parent1;
00343 jets.push_back(_jets[_history[parent1].jetp_index]);}
00344 i--;
00345 }
00346 } else if (_jet_algorithm == cambridge_algorithm) {
00347 while (i >= 0) {
00348 // inclusive jets are all at end of clustering sequence in the
00349 // Cambridge algorithm -- so if we find a non-exclusive jet, then
00350 // we can exit
00351 if (_history[i].parent2 != BeamJet) {break;}
00352 int parent1 = _history[i].parent1;
00353 const PseudoJet & jet = _jets[_history[parent1].jetp_index];
00354 if (jet.perp2() >= dcut) {jets.push_back(jet);}
00355 i--;
00356 }
00357 } else if (_jet_algorithm == plugin_algorithm
00358 || _jet_algorithm == antikt_algorithm
00359 || _jet_algorithm == cambridge_for_passive_algorithm) {
00360 // for inclusive jets with a plugin algorithm, we make no
00361 // assumptions about anything (relation of dij to momenta,
00362 // ordering of the dij, etc.)
00363 while (i >= 0) {
00364 if (_history[i].parent2 == BeamJet) {
00365 int parent1 = _history[i].parent1;
00366 const PseudoJet & jet = _jets[_history[parent1].jetp_index];
00367 if (jet.perp2() >= dcut) {jets.push_back(jet);}
00368 }
00369 i--;
00370 }
00371 } else {throw Error("Unrecognized jet algorithm");}
00372 return jets;
00373 }
|
|
|
return a reference to the jet definition
Definition at line 191 of file ClusterSequence.hh. Referenced by fastjet::ClusterSequenceAreaBase::_check_jet_alg_good_for_median(), _initialise_and_run(), fastjet::ClusterSequence1GhostPassiveArea::_run_1GPA(), fastjet::ClusterSequenceActiveArea::_run_AA(), fastjet::ClusterSequenceArea::_warn_if_range_unsuitable(), and fastjet::ClusterSequencePassiveArea::empty_area(). 00191 {return _jet_def;}
|
|
|
returns the scale associated with a jet as required for this clustering algorithm (kt^2 for the kt-algorithm, 1 for the Cambridge algorithm). [May become virtual at some point] Definition at line 270 of file ClusterSequence.cc. References _jet_algorithm, _jet_def, fastjet::antikt_algorithm, fastjet::cambridge_algorithm, fastjet::cambridge_for_passive_algorithm, fastjet::JetDefinition::extra_param(), fastjet::PseudoJet::kt2(), and fastjet::kt_algorithm. Referenced by _add_ktdistance_to_map(), _bj_set_jetinfo(), and _really_dumb_cluster(). 00271 {
00272 if (_jet_algorithm == kt_algorithm) {return jet.kt2();}
00273 else if (_jet_algorithm == cambridge_algorithm) {return 1.0;}
00274 else if (_jet_algorithm == antikt_algorithm) {
00275 double kt2=jet.kt2();
00276 return kt2 > 1e-300 ? 1.0/kt2 : 1e300;
00277 } else if (_jet_algorithm == cambridge_for_passive_algorithm) {
00278 double kt2 = jet.kt2();
00279 double lim = _jet_def.extra_param();
00280 if (kt2 < lim*lim && kt2 != 0.0) {
00281 return 1.0/kt2;
00282 } else {return 1.0;}
00283 } else {throw Error("Unrecognised jet finder");}
00284 }
|
|
|
allow the user to access the jets in this raw manner (needed because we don't seem to be able to access protected elements of the class for an object that is not "this" (at least in case where "this" is of a slightly different kind from the object, both derived from ClusterSequence).
Definition at line 653 of file ClusterSequence.hh. References _jets. Referenced by fastjet::ClusterSequenceActiveArea::_transfer_areas(), exclusive_jets(), inclusive_jets(), fastjet::SISConePlugin::run_clustering(), fastjet::PxConePlugin::run_clustering(), fastjet::CDFMidPointPlugin::run_clustering(), fastjet::CDFJetCluPlugin::run_clustering(), and fastjet::ClusterSequenceAreaBase::subtracted_jets(). 00653 {
00654 return _jets;
00655 }
|
|
|
return the number of jets (in the sense of the exclusive algorithm) that would be obtained when running the algorithm with the given dcut.
Definition at line 379 of file ClusterSequence.cc. References _history, and _initial_n. Referenced by exclusive_jets(). 00379 {
00380
00381 // first locate the point where clustering would have stopped (i.e. the
00382 // first time max_dij_so_far > dcut)
00383 int i = _history.size() - 1; // last jet
00384 while (i >= 0) {
00385 if (_history[i].max_dij_so_far <= dcut) {break;}
00386 i--;
00387 }
00388 int stop_point = i + 1;
00389 // relation between stop_point, njets assumes one extra jet disappears
00390 // at each clustering.
00391 int njets = 2*_initial_n - stop_point;
00392 return njets;
00393 }
|
|
|
returns the number of particles that were provided to the clustering algorithm (helps the user find their way around the history and jets objects if they weren't paying attention beforehand).
Definition at line 661 of file ClusterSequence.hh. References _initial_n. Referenced by fastjet::ClusterSequenceVoronoiArea::_initializeVA(), fastjet::ClusterSequenceActiveArea::_transfer_areas(), particle_jet_indices(), unclustered_particles(), and unique_history_order(). 00661 {return _initial_n;}
|
|
||||||||||||
|
returns true iff the object is included in the jet. NB: this is only sensible if the object is already registered within the cluster sequence, so you cannot use it with an input particle to the CS (since the particle won't have the history index set properly). For nice clustering structures it should run in O(ln(N)) time but in worst cases (certain cone plugins) it can take O(n) time, where n is the number of particles in the jet. Definition at line 487 of file ClusterSequence.cc. References _potentially_valid(), fastjet::PseudoJet::cluster_hist_index(), and has_child(). 00488 {
00489
00490 // make sure the object conceivably belongs to this clustering
00491 // sequence
00492 assert(_potentially_valid(object) && _potentially_valid(jet));
00493
00494 const PseudoJet * this_object = &object;
00495 const PseudoJet * childp;
00496 while(true) {
00497 if (this_object->cluster_hist_index() == jet.cluster_hist_index()) {
00498 return true;
00499 } else if (has_child(*this_object, childp)) {this_object = childp;}
00500 else {return false;}
00501 }
00502 }
|
|
|
returns a vector of size n_particles() which indicates, for each of the initial particles (in the order in which they were supplied), which of the supplied jets it belongs to; if it does not belong to any of the supplied jets, the index is set to -1;
Definition at line 657 of file ClusterSequence.cc. References constituents(), history(), and n_particles(). 00658 {
00659
00660 vector<int> indices(n_particles());
00661
00662 // first label all particles as not belonging to any jets
00663 for (unsigned ipart = 0; ipart < n_particles(); ipart++)
00664 indices[ipart] = -1;
00665
00666 // then for each of the jets relabel its consituents as belonging to
00667 // that jet
00668 for (unsigned ijet = 0; ijet < jets.size(); ijet++) {
00669
00670 vector<PseudoJet> jet_constituents(constituents(jets[ijet]));
00671
00672 for (unsigned ip = 0; ip < jet_constituents.size(); ip++) {
00673 // a safe (if slightly redundant) way of getting the particle
00674 // index (for initial particles it is actually safe to assume
00675 // ipart=iclust).
00676 unsigned iclust = jet_constituents[ip].cluster_hist_index();
00677 unsigned ipart = history()[iclust].jetp_index;
00678 indices[ipart] = ijet;
00679 }
00680 }
00681
00682 return indices;
00683 }
|
|
|
returns true when the plugin is allowed to run the show.
Definition at line 244 of file ClusterSequence.hh. 00244 {return _plugin_activated;}
|
|
|
the plugin can associated some extra information with the ClusterSequence object by calling this function
Definition at line 239 of file ClusterSequence.hh. Referenced by fastjet::SISConePlugin::run_clustering(). 00239 {
00240 _extras = extras_in;
00241 }
|
|
||||||||||||
|
record the fact that there has been a recombination between jets()[jet_i] and the beam, with the specified diB; when looking for inclusive jets, any iB recombination will returned to the user as a jet.
Definition at line 223 of file ClusterSequence.hh. Referenced by fastjet::SISConePlugin::run_clustering(), fastjet::PxConePlugin::run_clustering(), fastjet::CDFMidPointPlugin::run_clustering(), and fastjet::CDFJetCluPlugin::run_clustering(). 00223 {
00224 assert(plugin_activated());
00225 _do_iB_recombination_step(jet_i, diB);
00226 }
|
|
||||||||||||||||||||||||
|
as for the simpler variant of plugin_record_ij_recombination, except that the new jet is attributed the momentum and user_index of newjet
Definition at line 315 of file ClusterSequence.cc. References _jets, and plugin_record_ij_recombination(). 00317 {
00318
00319 plugin_record_ij_recombination(jet_i, jet_j, dij, newjet_k);
00320
00321 // now transfer newjet into place
00322 int tmp_index = _jets[newjet_k].cluster_hist_index();
00323 _jets[newjet_k] = newjet;
00324 _jets[newjet_k].set_cluster_hist_index(tmp_index);
00325 }
|
|
||||||||||||||||||||
|
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
Definition at line 206 of file ClusterSequence.hh. Referenced by plugin_record_ij_recombination(), fastjet::SISConePlugin::run_clustering(), fastjet::PxConePlugin::run_clustering(), fastjet::CDFMidPointPlugin::run_clustering(), and fastjet::CDFJetCluPlugin::run_clustering(). 00207 {
00208 assert(plugin_activated());
00209 _do_ij_recombination_step(jet_i, jet_j, dij, newjet_k);
00210 }
|
|
||||||||||||
|
output the supplied vector of jets in a format that can be read by an appropriate root script; the format is: jet-n jet-px jet-py jet-pz jet-E particle-n particle-rap particle-phi particle-pt particle-n particle-rap particle-phi particle-pt .. #END ... [i.e. above repeated] Definition at line 621 of file ClusterSequence.cc. References constituents(). Referenced by main(). 00622 {
00623 for (unsigned i = 0; i < jets.size(); i++) {
00624 ostr << i << " "
00625 << jets[i].px() << " "
00626 << jets[i].py() << " "
00627 << jets[i].pz() << " "
00628 << jets[i].E() << endl;
00629 vector<PseudoJet> cst = constituents(jets[i]);
00630 for (unsigned j = 0; j < cst.size() ; j++) {
00631 ostr << " " << j << " "
00632 << cst[j].rap() << " "
00633 << cst[j].phi() << " "
00634 << cst[j].perp() << endl;
00635 }
00636 ostr << "#END" << endl;
00637 }
00638 }
|
|
|
set the default (static) jet finder across all current and future ClusterSequence objects -- deprecated and obsolescent (i.e. may be suppressed in a future release). Definition at line 253 of file ClusterSequence.hh. 00253 {_default_jet_algorithm = jet_algorithm;}
|
|
|
same as above for backward compatibility
Definition at line 255 of file ClusterSequence.hh. 00255 {_default_jet_algorithm = jet_algorithm;}
|
|
|
Definition at line 236 of file ClusterSequence.cc. References _strategy, fastjet::N2MinHeapTiled, fastjet::N2Plain, fastjet::N2PoorTiled, fastjet::N2Tiled, fastjet::N3Dumb, fastjet::NlnN, fastjet::NlnN3pi, fastjet::NlnN4pi, fastjet::NlnNCam, fastjet::NlnNCam2pi2R, fastjet::NlnNCam4pi, and fastjet::plugin_strategy. Referenced by _delaunay_cluster(), and main(). 00236 {
00237 string strategy;
00238 switch(_strategy) {
00239 case NlnN:
00240 strategy = "NlnN"; break;
00241 case NlnN3pi:
00242 strategy = "NlnN3pi"; break;
00243 case NlnN4pi:
00244 strategy = "NlnN4pi"; break;
00245 case N2Plain:
00246 strategy = "N2Plain"; break;
00247 case N2Tiled:
00248 strategy = "N2Tiled"; break;
00249 case N2MinHeapTiled:
00250 strategy = "N2MinHeapTiled"; break;
00251 case N2PoorTiled:
00252 strategy = "N2PoorTiled"; break;
00253 case N3Dumb:
00254 strategy = "N3Dumb"; break;
00255 case NlnNCam4pi:
00256 strategy = "NlnNCam4pi"; break;
00257 case NlnNCam2pi2R:
00258 strategy = "NlnNCam2pi2R"; break;
00259 case NlnNCam:
00260 strategy = "NlnNCam"; break; // 2piMultD
00261 case plugin_strategy:
00262 strategy = "plugin strategy"; break;
00263 default:
00264 strategy = "Unrecognized";
00265 }
00266 return strategy;
00267 }
|
|
|
return the enum value of the strategy used to cluster the event
Definition at line 187 of file ClusterSequence.hh. 00187 {return _strategy;}
|
|
|
transfer the sequence contained in other_seq into our own; any plugin "extras" contained in the from_seq will be lost from there.
Definition at line 291 of file ClusterSequence.cc. References _extras, _history, _initial_n, _invR2, _jet_algorithm, _jet_def, _jets, _plugin_activated, _R2, _Rparam, _strategy, and _writeout_combinations. Referenced by fastjet::ClusterSequencePassiveArea::_initialise_and_run_PA(), and fastjet::ClusterSequenceArea::initialize_and_run_cswa(). 00291 {
00292
00293 // the metadata
00294 _jet_def = from_seq._jet_def ;
00295 _writeout_combinations = from_seq._writeout_combinations ;
00296 _initial_n = from_seq._initial_n ;
00297 _Rparam = from_seq._Rparam ;
00298 _R2 = from_seq._R2 ;
00299 _invR2 = from_seq._invR2 ;
00300 _strategy = from_seq._strategy ;
00301 _jet_algorithm = from_seq._jet_algorithm ;
00302 _plugin_activated = from_seq._plugin_activated ;
00303
00304 // the data
00305 _jets = from_seq._jets;
00306 _history = from_seq._history;
00307 // the following transferse ownership of the extras from the from_seq
00308 _extras = from_seq._extras;
00309
00310 }
|
|
|
return the set of particles that have not been clustered. For kt and cam/aachen algorithms this should always be null, but for cone type algorithms it can be non-null; Definition at line 814 of file ClusterSequence.cc. References _history, _jets, Invalid, and n_particles(). Referenced by fastjet::ClusterSequenceActiveArea::_transfer_areas(), and fastjet::ClusterSequenceActiveAreaExplicitGhosts::empty_area(). 00814 {
00815 vector<PseudoJet> unclustered;
00816 for (unsigned i = 0; i < n_particles() ; i++) {
00817 if (_history[i].child == Invalid)
00818 unclustered.push_back(_jets[_history[i].jetp_index]);
00819 }
00820 return unclustered;
00821 }
|
|
|
routine that returns an order in which to read the history such that clusterings that lead to identical jet compositions but different histories (because of degeneracies in the clustering order) will have matching constituents for each matching entry in the unique_history_order. The order has the property that an entry's parents will always appear prior to that entry itself. Roughly speaking the order is such that we first provide all steps that lead to the final jet containing particle 1; then we have the steps that lead to reconstruction of the jet containing the next-lowest-numbered unclustered particle, etc... [see GPS CCN28-12 for more info -- of course a full explanation here would be better...] Definition at line 759 of file ClusterSequence.cc. References _extract_tree_children(), _history, and n_particles(). Referenced by fastjet::ClusterSequence1GhostPassiveArea::_run_1GPA(), fastjet::ClusterSequenceActiveArea::_run_AA(), fastjet::ClusterSequenceActiveArea::_transfer_areas(), and main(). 00759 {
00760
00761 // first construct an array that will tell us the lowest constituent
00762 // of a given jet -- this will always be one of the original
00763 // particles, whose order is well defined and so will help us to
00764 // follow the tree in a unique manner.
00765 valarray<int> lowest_constituent(_history.size());
00766 int hist_n = _history.size();
00767 lowest_constituent = hist_n; // give it a large number
00768 for (int i = 0; i < hist_n; i++) {
00769 // sets things up for the initial partons
00770 lowest_constituent[i] = min(lowest_constituent[i],i);
00771 // propagates them through to the children of this parton
00772 if (_history[i].child > 0) lowest_constituent[_history[i].child]
00773 = min(lowest_constituent[_history[i].child],lowest_constituent[i]);
00774 }
00775
00776 // establish an array for what we have and have not extracted so far
00777 valarray<bool> extracted(_history.size()); extracted = false;
00778 vector<int> unique_tree;
00779 unique_tree.reserve(_history.size());
00780
00781 // now work our way through the tree
00782 for (unsigned i = 0; i < n_particles(); i++) {
00783 if (!extracted[i]) {
00784 unique_tree.push_back(i);
00785 extracted[i] = true;
00786 _extract_tree_children(i, extracted, lowest_constituent, unique_tree);
00787 }
00788 }
00789
00790 return unique_tree;
00791 }
|
|
|
Definition at line 47 of file ClusterSequence.cc. Referenced by _initialise_and_run(). |
|
|
Definition at line 412 of file ClusterSequence.hh. Referenced by transfer_from_sequence(). |
|
|
will be set by default to be true for the first run
Definition at line 140 of file ClusterSequence.cc. Referenced by _print_banner(). |
|
|
|
|
Definition at line 405 of file ClusterSequence.hh. Referenced by _add_ktdistance_to_map(), _CP2DChan_cluster(), _CP2DChan_limited_cluster(), _decant_options(), _faster_tiled_N2_cluster(), _minheap_faster_tiled_N2_cluster(), _really_dumb_cluster(), _simple_N2_cluster(), _tiled_N2_cluster(), and transfer_from_sequence(). |
|
|
Definition at line 407 of file ClusterSequence.hh. Referenced by _CP2DChan_cluster(), _CP2DChan_cluster_2pi2R(), _decant_options(), _initialise_and_run(), inclusive_jets(), jet_scale_for_algorithm(), and transfer_from_sequence(). |
|
|
|
|
record the number of warnings provided about the exclusive algorithm -- so that we don't print it out more than a few times.
Definition at line 141 of file ClusterSequence.cc. Referenced by exclusive_jets(). |
|
|
Definition at line 569 of file ClusterSequence.hh. Referenced by _initialise_tiles(), and _tile_index(). |
|
|
Definition at line 411 of file ClusterSequence.hh. Referenced by _decant_options(), _initialise_and_run(), and transfer_from_sequence(). |
|
|
Definition at line 405 of file ClusterSequence.hh. Referenced by _bj_set_jetinfo(), _bj_set_NN_crosscheck(), _bj_set_NN_nocross(), _decant_options(), _faster_tiled_N2_cluster(), _minheap_faster_tiled_N2_cluster(), _tiled_N2_cluster(), and transfer_from_sequence(). |
|
|
Definition at line 405 of file ClusterSequence.hh. Referenced by _CP2DChan_cluster_2pi2R(), _CP2DChan_cluster_2piMultD(), _decant_options(), _delaunay_cluster(), _initialise_and_run(), _initialise_tiles(), and transfer_from_sequence(). |
|
|
Definition at line 406 of file ClusterSequence.hh. Referenced by _decant_options(), _delaunay_cluster(), _initialise_and_run(), fastjet::ClusterSequenceActiveArea::_transfer_ghost_free_history(), strategy_string(), and transfer_from_sequence(). |
|
|
Definition at line 568 of file ClusterSequence.hh. Referenced by _initialise_tiles(), and _tile_index(). |
|
|
Definition at line 568 of file ClusterSequence.hh. Referenced by _initialise_tiles(), and _tile_index(). |
|
|
Definition at line 566 of file ClusterSequence.hh. Referenced by _add_neighbours_to_tile_union(), _add_untagged_neighbours_to_tile_union(), _bj_remove_from_tiles(), _faster_tiled_N2_cluster(), _initialise_tiles(), _minheap_faster_tiled_N2_cluster(), _print_tiles(), _tiled_N2_cluster(), and _tj_set_jetinfo(). |
|
|
Definition at line 567 of file ClusterSequence.hh. Referenced by _initialise_tiles(), and _tile_index(). |
|
|
Definition at line 567 of file ClusterSequence.hh. Referenced by _initialise_tiles(), and _tile_index(). |
|
|
Definition at line 569 of file ClusterSequence.hh. Referenced by _initialise_tiles(), and _tile_index(). |
|
|
Definition at line 569 of file ClusterSequence.hh. Referenced by _initialise_tiles(), and _tile_index(). |
|
|
Definition at line 403 of file ClusterSequence.hh. Referenced by _add_step_to_history(), _decant_options(), and transfer_from_sequence(). |
|
|
number of neighbours that a tile will have (rectangular geometry gives 9 neighbours).
Definition at line 548 of file ClusterSequence.hh. Referenced by _faster_tiled_N2_cluster(), _minheap_faster_tiled_N2_cluster(), and _tiled_N2_cluster(). |
1.4.2