#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(). |