#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. | |
| std::vector< PseudoJet > | constituents (const PseudoJet &jet) const |
| return a vector of the particles that make up jet | |
| void | add_constituents (const PseudoJet &jet, std::vector< PseudoJet > &subjet_vector) const |
| add on to subjet_vector the subjets of jet. | |
| Strategy | strategy_used () const |
| return the enum value of the strategy used to cluster the event | |
| std::string | strategy_string () const |
| 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. | |
Static Public Member Functions | |
| static void | set_jet_finder (JetFinder jet_finder) |
| set the default (static) jet finder across all current and future ClusterSequence objects -- deprecated and obsolescent (i.e. | |
Protected Member Functions | |
| 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 |
| JetFinder | _jet_finder |
Static Protected Attributes | |
| static JetFinder | _default_jet_finder = 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 383 of file ClusterSequence.hh. |
|
|
Definition at line 384 of file ClusterSequence.hh. |
|
|
Definition at line 382 of file ClusterSequence.hh. |
|
|
Definition at line 236 of file ClusterSequence.hh. 00236 {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 558 of file ClusterSequence.hh. References _initialise_and_run(), and _transfer_input_jets(). 00562 {
00563
00564 // transfer the initial jets (type L) into our own array
00565 _transfer_input_jets(pseudojets);
00566
00567 // run the clustering
00568 _initialise_and_run(R,strategy,writeout_combinations);
00569 }
|
|
||||||||||||||||||||
|
constructor of a jet-clustering sequence from a vector of four-momenta, with the jet definition specified by jet_def
Definition at line 575 of file ClusterSequence.hh. References _initialise_and_run(), and _transfer_input_jets(). 00578 {
00579
00580 // transfer the initial jets (type L) into our own array
00581 _transfer_input_jets(pseudojets);
00582
00583 // run the clustering
00584 _initialise_and_run(jet_def,writeout_combinations);
00585 }
|
|
||||||||||||||||
|
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 232 of file ClusterSequence_TiledN2.cc. References _tiles. Referenced by _tiled_N2_cluster(). 00233 {
00234 for (Tile * const * near_tile = _tiles[tile_index].begin_tiles;
00235 near_tile != _tiles[tile_index].end_tiles; near_tile++){
00236 // get the tile number
00237 tile_union[n_near_tiles] = *near_tile - & _tiles[0];
00238 n_near_tiles++;
00239 }
00240 }
|
|
||||||||||||||||||||||||
|
Definition at line 504 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(). 00507 {
00508
00509 history_element element;
00510 element.parent1 = parent1;
00511 element.parent2 = parent2;
00512 element.jetp_index = jetp_index;
00513 element.child = Invalid;
00514 element.dij = dij;
00515 element.max_dij_so_far = max(dij,_history[_history.size()-1].max_dij_so_far);
00516 _history.push_back(element);
00517
00518 int local_step = _history.size()-1;
00519 assert(local_step == step_number);
00520
00521 assert(parent1 >= 0);
00522 _history[parent1].child = local_step;
00523 if (parent2 >= 0) {_history[parent2].child = local_step;}
00524
00525 // get cross-referencing right from PseudoJets
00526 if (jetp_index != Invalid) {
00527 assert(jetp_index >= 0);
00528 //cout << _jets.size() <<" "<<jetp_index<<"\n";
00529 _jets[jetp_index].set_cluster_hist_index(local_step);
00530 }
00531
00532 if (_writeout_combinations) {
00533 cout << local_step << ": "
00534 << parent1 << " with " << parent2
00535 << "; y = "<< dij<<endl;
00536 }
00537
00538 }
|
|
||||||||||||||||
|
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 247 of file ClusterSequence_TiledN2.cc. References _tiles. Referenced by _faster_tiled_N2_cluster(), and _minheap_faster_tiled_N2_cluster(). 00249 {
00250 for (Tile ** near_tile = _tiles[tile_index].begin_tiles;
00251 near_tile != _tiles[tile_index].end_tiles; near_tile++){
00252 if (! (*near_tile)->tagged) {
00253 (*near_tile)->tagged = true;
00254 // get the tile number
00255 tile_union[n_near_tiles] = *near_tile - & _tiles[0];
00256 n_near_tiles++;
00257 }
00258 }
00259 }
|
|
||||||||||
|
Definition at line 633 of file ClusterSequence.hh. Referenced by _faster_tiled_N2_cluster(), _minheap_faster_tiled_N2_cluster(), _simple_N2_cluster(), and _tiled_N2_cluster(). 00633 {
00634 double kt2 = jet->kt2;
00635 if (jet->NN != NULL) {if (jet->NN->kt2 < kt2) {kt2 = jet->NN->kt2;}}
00636 return jet->NN_dist * kt2;
00637 }
|
|
||||||||||||||||
|
return the distance between two BriefJet objects
Definition at line 624 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(). 00625 {
00626 double dphi = std::abs(jetA->phi - jetB->phi);
00627 double deta = (jetA->eta - jetB->eta);
00628 if (dphi > pi) {dphi = twopi - dphi;}
00629 return dphi*dphi + deta*deta;
00630 }
|
|
||||||||||||||||||||
|
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 450 of file ClusterSequence.hh. 00453 {
00454 J * res;
00455 for(res = head; res<tail; res++) {
00456 if (_jets[res->_jets_index].cluster_hist_index() == hist_index) {break;}
00457 }
00458 return res;
00459 }
|
|
|
Definition at line 49 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. 00049 {
00050 Tile * tile = & _tiles[jet->tile_index];
00051
00052 if (jet->previous == NULL) {
00053 // we are at head of the tile, so reset it.
00054 // If this was the only jet on the tile then tile->head will now be NULL
00055 tile->head = jet->next;
00056 } else {
00057 // adjust link from previous jet in this tile
00058 jet->previous->next = jet->next;
00059 }
00060 if (jet->next != NULL) {
00061 // adjust backwards-link from next jet in this tile
00062 jet->next->previous = jet->previous;
00063 }
00064 }
|
|
|
"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 609 of file ClusterSequence.hh. References _jets, _R2, and jet_scale_for_algorithm(). Referenced by _simple_N2_cluster(). 00610 {
00611 jetA->eta = _jets[_jets_index].rap();
00612 jetA->phi = _jets[_jets_index].phi_02pi();
00613 jetA->kt2 = jet_scale_for_algorithm(_jets[_jets_index]);
00614 jetA->_jets_index = _jets_index;
00615 // initialise NN info as well
00616 jetA->NN_dist = _R2;
00617 jetA->NN = NULL;
00618 }
|
|
||||||||||||||||||||
|
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 671 of file ClusterSequence.hh. References _bj_dist(), and _R2. Referenced by _simple_N2_cluster(). 00672 {
00673 double NN_dist = _R2;
00674 J * NN = NULL;
00675 for (J * jetB = head; jetB != tail; jetB++) {
00676 double dist = _bj_dist(jet,jetB);
00677 if (dist < NN_dist) {
00678 NN_dist = dist;
00679 NN = jetB;
00680 }
00681 if (dist < jetB->NN_dist) {
00682 jetB->NN_dist = dist;
00683 jetB->NN = jet;
00684 }
00685 }
00686 jet->NN = NN;
00687 jet->NN_dist = NN_dist;
00688 }
|
|
||||||||||||||||||||
|
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 643 of file ClusterSequence.hh. References _bj_dist(), and _R2. Referenced by _simple_N2_cluster(). 00644 {
00645 double NN_dist = _R2;
00646 J * NN = NULL;
00647 if (head < jet) {
00648 for (J * jetB = head; jetB != jet; jetB++) {
00649 double dist = _bj_dist(jet,jetB);
00650 if (dist < NN_dist) {
00651 NN_dist = dist;
00652 NN = jetB;
00653 }
00654 }
00655 }
00656 if (tail > jet) {
00657 for (J * jetB = jet+1; jetB != tail; jetB++) {
00658 double dist = _bj_dist(jet,jetB);
00659 if (dist < NN_dist) {
00660 NN_dist = dist;
00661 NN = jetB;
00662 }
00663 }
00664 }
00665 jet->NN = NN;
00666 jet->NN_dist = NN_dist;
00667 }
|
|
|
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_finder, _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_finder != 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_finder, _Rparam, and fastjet::cambridge_algorithm. Referenced by _CP2DChan_cluster_2piMultD(), and _initialise_and_run(). 00193 {
00194
00195 if (_jet_finder != 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 173 of file ClusterSequence.cc. References _invR2, _jet_def, _jet_finder, _plugin_activated, _print_banner(), _R2, _Rparam, _strategy, and _writeout_combinations. Referenced by _initialise_and_run(), and fastjet::ClusterSequenceActiveArea::_initialise_and_run_AA(). 00174 {
00175
00176 // let the user know what's going on
00177 _print_banner();
00178
00179 // make a local copy of the jet definition (for future use?)
00180 _jet_def = jet_def;
00181
00182 _writeout_combinations = writeout_combinations;
00183 _jet_finder = jet_def.jet_finder();
00184 _Rparam = jet_def.R(); _R2 = _Rparam*_Rparam; _invR2 = 1.0/_R2;
00185 _strategy = jet_def.strategy();
00186
00187 // disallow interference from the plugin
00188 _plugin_activated = false;
00189
00190 }
|
|
|
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 681 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(). 00682 {
00683 // get history index
00684 int newstep_k = _history.size();
00685
00686 // recombine the jet with the beam
00687 _add_step_to_history(newstep_k,_jets[jet_i].cluster_hist_index(),BeamJet,
00688 Invalid, diB);
00689
00690 }
|
|
||||||||||||||||||||
|
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 648 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(). 00651 {
00652
00653 // create the new jet by recombining the first two
00654 PseudoJet newjet;
00655 _jet_def.recombiner()->recombine(_jets[jet_i], _jets[jet_j], newjet);
00656 _jets.push_back(newjet);
00657 // original version...
00658 //_jets.push_back(_jets[jet_i] + _jets[jet_j]);
00659
00660 // get its index
00661 newjet_k = _jets.size()-1;
00662
00663 // get history index
00664 int newstep_k = _history.size();
00665 // and provide jet with the info
00666 _jets[newjet_k].set_cluster_hist_index(newstep_k);
00667
00668 // finally sort out the history
00669 int hist_i = _jets[jet_i].cluster_hist_index();
00670 int hist_j = _jets[jet_j].cluster_hist_index();
00671
00672 _add_step_to_history(newstep_k, min(hist_i, hist_j), max(hist_i,hist_j),
00673 newjet_k, dij);
00674
00675 }
|
|
||||||||||||||||||||
|
internal routine associated with the construction of the unique history order (following children in the tree)
Definition at line 584 of file ClusterSequence.cc. References _extract_tree_parents(), and _history. Referenced by unique_history_order(). 00588 {
00589 if (!extracted[position]) {
00590 // that means we may have unidentified parents around, so go and
00591 // collect them (extracted[position]) will then be made true)
00592 _extract_tree_parents(position,extracted,lowest_constituent,unique_tree);
00593 }
00594
00595 // now look after the children...
00596 int child = _history[position].child;
00597 if (child >= 0) _extract_tree_children(child,extracted,lowest_constituent,unique_tree);
00598 }
|
|
||||||||||||||||||||
|
internal routine associated with the construction of the unique history order (following parents in the tree)
Definition at line 616 of file ClusterSequence.cc. References _history. Referenced by _extract_tree_children(). 00620 {
00621
00622 if (!extracted[position]) {
00623 int parent1 = _history[position].parent1;
00624 int parent2 = _history[position].parent2;
00625 // where relevant order parents so that we will first treat the
00626 // one containing the smaller "lowest_constituent"
00627 if (parent1 >= 0 && parent2 >= 0) {
00628 if (lowest_constituent[parent1] > lowest_constituent[parent2])
00629 swap(parent1, parent2);
00630 }
00631 // then actually run through the parents to extract the constituents...
00632 if (parent1 >= 0 && !extracted[parent1])
00633 _extract_tree_parents(parent1,extracted,lowest_constituent,unique_tree);
00634 if (parent2 >= 0 && !extracted[parent2])
00635 _extract_tree_parents(parent2,extracted,lowest_constituent,unique_tree);
00636 // finally declare this position to be accounted for and push it
00637 // onto our list.
00638 unique_tree.push_back(position);
00639 extracted[position] = true;
00640 }
00641 }
|
|
|
run a tiled clustering
Definition at line 507 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(). 00507 {
00508
00509 _initialise_tiles();
00510
00511 int n = _jets.size();
00512 TiledJet * briefjets = new TiledJet[n];
00513 TiledJet * jetA = briefjets, * jetB;
00514 TiledJet oldB;
00515
00516
00517 // will be used quite deep inside loops, but declare it here so that
00518 // memory (de)allocation gets done only once
00519 vector<int> tile_union(3*n_tile_neighbours);
00520
00521 // initialise the basic jet info
00522 for (int i = 0; i< n; i++) {
00523 _tj_set_jetinfo(jetA, i);
00524 //cout << i<<": "<<jetA->tile_index<<"\n";
00525 jetA++; // move on to next entry of briefjets
00526 }
00527 TiledJet * head = briefjets; // a nicer way of naming start
00528
00529 // set up the initial nearest neighbour information
00530 vector<Tile>::const_iterator tile;
00531 for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
00532 // first do it on this tile
00533 for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
00534 for (jetB = tile->head; jetB != jetA; jetB = jetB->next) {
00535 double dist = _bj_dist(jetA,jetB);
00536 if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
00537 if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
00538 }
00539 }
00540 // then do it for RH tiles
00541 for (Tile ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
00542 for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
00543 for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
00544 double dist = _bj_dist(jetA,jetB);
00545 if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
00546 if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
00547 }
00548 }
00549 }
00550 // no need to do it for LH tiles, since they are implicitly done
00551 // when we set NN for both jetA and jetB on the RH tiles.
00552 }
00553
00554
00555 // now create the diJ (where J is i's NN) table -- remember that
00556 // we differ from standard normalisation here by a factor of R2
00557 // (corrected for at the end).
00558 struct diJ_plus_link {
00559 double diJ; // the distance
00560 TiledJet * jet; // the jet (i) for which we've found this distance
00561 // (whose NN will the J).
00562 };
00563 diJ_plus_link * diJ = new diJ_plus_link[n];
00564 jetA = head;
00565 for (int i = 0; i < n; i++) {
00566 diJ[i].diJ = _bj_diJ(jetA); // kt distance * R^2
00567 diJ[i].jet = jetA; // our compact diJ table will not be in
00568 jetA->diJ_posn = i; // one-to-one corresp. with non-compact jets,
00569 // so set up bi-directional correspondence here.
00570 jetA++; // have jetA follow i
00571 }
00572
00573 // now run the recombination loop
00574 int history_location = n-1;
00575 while (n > 0) {
00576
00577 // find the minimum of the diJ on this round
00578 diJ_plus_link * best, *stop; // pointers a bit faster than indices
00579 // could use best to keep track of diJ min, but it turns out to be
00580 // marginally faster to have a separate variable (avoids n
00581 // dereferences at the expense of n/2 assignments).
00582 double diJ_min = diJ[0].diJ; // initialise the best one here.
00583 best = diJ; // and here
00584 stop = diJ+n;
00585 for (diJ_plus_link * here = diJ+1; here != stop; here++) {
00586 if (here->diJ < diJ_min) {best = here; diJ_min = here->diJ;}
00587 }
00588
00589 // do the recombination between A and B
00590 history_location++;
00591 jetA = best->jet;
00592 jetB = jetA->NN;
00593 // put the normalisation back in
00594 diJ_min *= _invR2;
00595
00596 if (jetB != NULL) {
00597 // jet-jet recombination
00598 // If necessary relabel A & B to ensure jetB < jetA, that way if
00599 // the larger of them == newtail then that ends up being jetA and
00600 // the new jet that is added as jetB is inserted in a position that
00601 // has a future!
00602 if (jetA < jetB) {swap(jetA,jetB);}
00603
00604 int nn; // new jet index
00605 _do_ij_recombination_step(jetA->_jets_index, jetB->_jets_index, diJ_min, nn);
00606
00607 //OBS// get the two history indices
00608 //OBSint ihstry_a = _jets[jetA->_jets_index].cluster_hist_index();
00609 //OBSint ihstry_b = _jets[jetB->_jets_index].cluster_hist_index();
00610 //OBS// create the recombined jet
00611 //OBS_jets.push_back(_jets[jetA->_jets_index] + _jets[jetB->_jets_index]);
00612 //OBSint nn = _jets.size() - 1;
00613 //OBS_jets[nn].set_cluster_hist_index(history_location);
00614 //OBS// update history
00615 //OBS//cout <<n-1<<" "<<jetA-head<<" "<<jetB-head<<"; ";
00616 //OBS_add_step_to_history(history_location,
00617 //OBS min(ihstry_a,ihstry_b),max(ihstry_a,ihstry_b),
00618 //OBS nn, diJ_min);
00619 // what was jetB will now become the new jet
00620 _bj_remove_from_tiles(jetA);
00621 oldB = * jetB; // take a copy because we will need it...
00622 _bj_remove_from_tiles(jetB);
00623 _tj_set_jetinfo(jetB, nn); // cause jetB to become _jets[nn]
00624 // (also registers the jet in the tiling)
00625 } else {
00626 // jet-beam recombination
00627 // get the hist_index
00628 _do_iB_recombination_step(jetA->_jets_index, diJ_min);
00629 //OBSint ihstry_a = _jets[jetA->_jets_index].cluster_hist_index();
00630 //OBS//cout <<n-1<<" "<<jetA-head<<" "<<-1<<"; ";
00631 //OBS_add_step_to_history(history_location,ihstry_a,BeamJet,Invalid,diJ_min);
00632 _bj_remove_from_tiles(jetA);
00633 }
00634
00635 // first establish the set of tiles over which we are going to
00636 // have to run searches for updated and new nearest-neighbours --
00637 // basically a combination of vicinity of the tiles of the two old
00638 // and one new jet.
00639 int n_near_tiles = 0;
00640 _add_untagged_neighbours_to_tile_union(jetA->tile_index,
00641 tile_union, n_near_tiles);
00642 if (jetB != NULL) {
00643 if (jetB->tile_index != jetA->tile_index) {
00644 _add_untagged_neighbours_to_tile_union(jetB->tile_index,
00645 tile_union,n_near_tiles);
00646 }
00647 if (oldB.tile_index != jetA->tile_index &&
00648 oldB.tile_index != jetB->tile_index) {
00649 _add_untagged_neighbours_to_tile_union(oldB.tile_index,
00650 tile_union,n_near_tiles);
00651 }
00652 }
00653
00654 // now update our nearest neighbour info and diJ table
00655 // first reduce size of table
00656 n--;
00657 // then compactify the diJ by taking the last of the diJ and copying
00658 // it to the position occupied by the diJ for jetA
00659 diJ[n].jet->diJ_posn = jetA->diJ_posn;
00660 diJ[jetA->diJ_posn] = diJ[n];
00661
00662 // Initialise jetB's NN distance as well as updating it for
00663 // other particles.
00664 // Run over all tiles in our union
00665 for (int itile = 0; itile < n_near_tiles; itile++) {
00666 Tile * tile = &_tiles[tile_union[itile]];
00667 tile->tagged = false; // reset tag, since we're done with unions
00668 // run over all jets in the current tile
00669 for (TiledJet * jetI = tile->head; jetI != NULL; jetI = jetI->next) {
00670 // see if jetI had jetA or jetB as a NN -- if so recalculate the NN
00671 if (jetI->NN == jetA || (jetI->NN == jetB && jetB != NULL)) {
00672 jetI->NN_dist = _R2;
00673 jetI->NN = NULL;
00674 // now go over tiles that are neighbours of I (include own tile)
00675 for (Tile ** near_tile = tile->begin_tiles;
00676 near_tile != tile->end_tiles; near_tile++) {
00677 // and then over the contents of that tile
00678 for (TiledJet * jetJ = (*near_tile)->head;
00679 jetJ != NULL; jetJ = jetJ->next) {
00680 double dist = _bj_dist(jetI,jetJ);
00681 if (dist < jetI->NN_dist && jetJ != jetI) {
00682 jetI->NN_dist = dist; jetI->NN = jetJ;
00683 }
00684 }
00685 }
00686 diJ[jetI->diJ_posn].diJ = _bj_diJ(jetI); // update diJ kt-dist
00687 }
00688 // check whether new jetB is closer than jetI's current NN and
00689 // if jetI is closer than jetB's current (evolving) nearest
00690 // neighbour. Where relevant update things
00691 if (jetB != NULL) {
00692 double dist = _bj_dist(jetI,jetB);
00693 if (dist < jetI->NN_dist) {
00694 if (jetI != jetB) {
00695 jetI->NN_dist = dist;
00696 jetI->NN = jetB;
00697 diJ[jetI->diJ_posn].diJ = _bj_diJ(jetI); // update diJ...
00698 }
00699 }
00700 if (dist < jetB->NN_dist) {
00701 if (jetI != jetB) {
00702 jetB->NN_dist = dist;
00703 jetB->NN = jetI;}
00704 }
00705 }
00706 }
00707 }
00708
00709 // finally, register the updated kt distance for B
00710 if (jetB != NULL) {diJ[jetB->diJ_posn].diJ = _bj_diJ(jetB);}
00711
00712 }
00713
00714 // final cleaning up;
00715 delete[] diJ;
00716 delete[] briefjets;
00717 }
|
|
|
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 195 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 _initialise_and_run(), and fastjet::ClusterSequenceActiveArea::_initialise_and_run_AA(). 00195 {
00196
00197 if (_jets.size() == 0) {throw Error("Cannot run jet-finder on empty event");}
00198
00199 // reserve sufficient space for everything
00200 _jets.reserve(_jets.size()*2);
00201 _history.reserve(_jets.size()*2);
00202
00203 for (int i = 0; i < static_cast<int>(_jets.size()) ; i++) {
00204 history_element element;
00205 element.parent1 = InexistentParent;
00206 element.parent2 = InexistentParent;
00207 element.child = Invalid;
00208 element.jetp_index = i;
00209 element.dij = 0.0;
00210 element.max_dij_so_far = 0.0;
00211
00212 _history.push_back(element);
00213
00214 // do any momentum preprocessing needed by the recombination scheme
00215 _jet_def.recombiner()->preprocess(_jets[i]);
00216
00217 // get cross-referencing right from PseudoJets
00218 _jets[i].set_cluster_hist_index(i);
00219 }
00220 _initial_n = _jets.size();
00221 }
|
|
||||||||||||||||
|
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_finder. Definition at line 52 of file ClusterSequence.cc. References _default_jet_finder, and _initialise_and_run(). 00055 {
00056
00057 JetDefinition jet_def(_default_jet_finder, 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_def, _jet_finder, _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_finder(), 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 _initialise_and_run(), fastjet::ClusterSequenceActiveArea::_initialise_and_run_AA(), 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_finder == 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_finder() == 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 85 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(). 00085 {
00086
00087 // first decide tile sizes
00088 _tile_size_eta = _Rparam;
00089 _n_tiles_phi = int(floor(twopi/_Rparam));
00090 _tile_size_phi = twopi / _n_tiles_phi; // >= _Rparam and fits in 2pi
00091
00092 // always include zero rapidity in the tiling region
00093 _tiles_eta_min = 0.0;
00094 _tiles_eta_max = 0.0;
00095 // but go no further than following
00096 const double maxrap = 7.0;
00097
00098 // and find out how much further one should go
00099 for(unsigned int i = 0; i < _jets.size(); i++) {
00100 double eta = _jets[i].rap();
00101 // first check if eta is in range -- to avoid taking into account
00102 // very spurious rapidities due to particles with near-zero kt.
00103 if (abs(eta) < maxrap) {
00104 if (eta < _tiles_eta_min) {_tiles_eta_min = eta;}
00105 if (eta > _tiles_eta_max) {_tiles_eta_max = eta;}
00106 }
00107 }
00108
00109 // now adjust the values
00110 _tiles_ieta_min = int(floor(_tiles_eta_min/_tile_size_eta));
00111 _tiles_ieta_max = int(floor( _tiles_eta_max/_tile_size_eta));
00112 _tiles_eta_min = _tiles_ieta_min * _tile_size_eta;
00113 _tiles_eta_max = _tiles_ieta_max * _tile_size_eta;
00114
00115 // allocate the tiles
00116 _tiles.resize((_tiles_ieta_max-_tiles_ieta_min+1)*_n_tiles_phi);
00117
00118 // now set up the cross-referencing between tiles
00119 for (int ieta = _tiles_ieta_min; ieta <= _tiles_ieta_max; ieta++) {
00120 for (int iphi = 0; iphi < _n_tiles_phi; iphi++) {
00121 Tile * tile = & _tiles[_tile_index(ieta,iphi)];
00122 // no jets in this tile yet
00123 tile->head = NULL; // first element of tiles points to itself
00124 tile->begin_tiles[0] = tile;
00125 Tile ** pptile = & (tile->begin_tiles[0]);
00126 pptile++;
00127 //
00128 // set up L's in column to the left of X
00129 tile->surrounding_tiles = pptile;
00130 if (ieta > _tiles_ieta_min) {
00131 // with the itile subroutine, we can safely run tiles from
00132 // idphi=-1 to idphi=+1, because it takes care of
00133 // negative and positive boundaries
00134 for (int idphi = -1; idphi <=+1; idphi++) {
00135 *pptile = & _tiles[_tile_index(ieta-1,iphi+idphi)];
00136 pptile++;
00137 }
00138 }
00139 // now set up last L (below X)
00140 *pptile = & _tiles[_tile_index(ieta,iphi-1)];
00141 pptile++;
00142 // set up first R (above X)
00143 tile->RH_tiles = pptile;
00144 *pptile = & _tiles[_tile_index(ieta,iphi+1)];
00145 pptile++;
00146 // set up remaining R's, to the right of X
00147 if (ieta < _tiles_ieta_max) {
00148 for (int idphi = -1; idphi <= +1; idphi++) {
00149 *pptile = & _tiles[_tile_index(ieta+1,iphi+idphi)];
00150 pptile++;
00151 }
00152 }
00153 // now put semaphore for end tile
00154 tile->end_tiles = pptile;
00155 // finally make sure tiles are untagged
00156 tile->tagged = false;
00157 }
00158 }
00159
00160 }
|
|
|
run a tiled clustering, with our minheap for keeping track of the smallest dij
Definition at line 724 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(). 00724 {
00725
00726 _initialise_tiles();
00727
00728 int n = _jets.size();
00729 TiledJet * briefjets = new TiledJet[n];
00730 TiledJet * jetA = briefjets, * jetB;
00731 TiledJet oldB;
00732
00733
00734 // will be used quite deep inside loops, but declare it here so that
00735 // memory (de)allocation gets done only once
00736 vector<int> tile_union(3*n_tile_neighbours);
00737
00738 // initialise the basic jet info
00739 for (int i = 0; i< n; i++) {
00740 _tj_set_jetinfo(jetA, i);
00741 //cout << i<<": "<<jetA->tile_index<<"\n";
00742 jetA++; // move on to next entry of briefjets
00743 }
00744 TiledJet * head = briefjets; // a nicer way of naming start
00745
00746 // set up the initial nearest neighbour information
00747 vector<Tile>::const_iterator tile;
00748 for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
00749 // first do it on this tile
00750 for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
00751 for (jetB = tile->head; jetB != jetA; jetB = jetB->next) {
00752 double dist = _bj_dist(jetA,jetB);
00753 if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
00754 if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
00755 }
00756 }
00757 // then do it for RH tiles
00758 for (Tile ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
00759 for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
00760 for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
00761 double dist = _bj_dist(jetA,jetB);
00762 if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
00763 if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
00764 }
00765 }
00766 }
00767 // no need to do it for LH tiles, since they are implicitly done
00768 // when we set NN for both jetA and jetB on the RH tiles.
00769 }
00770
00771
00775 //struct diJ_plus_link {
00776 // double diJ; // the distance
00777 // TiledJet * jet; // the jet (i) for which we've found this distance
00778 // // (whose NN will the J).
00779 //};
00780 //diJ_plus_link * diJ = new diJ_plus_link[n];
00781 //jetA = head;
00782 //for (int i = 0; i < n; i++) {
00783 // diJ[i].diJ = _bj_diJ(jetA); // kt distance * R^2
00784 // diJ[i].jet = jetA; // our compact diJ table will not be in
00785 // jetA->diJ_posn = i; // one-to-one corresp. with non-compact jets,
00786 // // so set up bi-directional correspondence here.
00787 // jetA++; // have jetA follow i
00788 //}
00789
00790 vector<double> diJs(n);
00791 for (int i = 0; i < n; i++) {
00792 diJs[i] = _bj_diJ(&briefjets[i]);
00793 briefjets[i].label_minheap_update_done();
00794 }
00795 MinHeap minheap(diJs);
00796 // have a stack telling us which jets we'll have to update on the heap
00797 vector<TiledJet *> jets_for_minheap;
00798 jets_for_minheap.reserve(n);
00799
00800 // now run the recombination loop
00801 int history_location = n-1;
00802 while (n > 0) {
00803
00804 double diJ_min = minheap.minval() *_invR2;
00805 jetA = head + minheap.minloc();
00806
00807 // do the recombination between A and B
00808 history_location++;
00809 jetB = jetA->NN;
00810
00811 if (jetB != NULL) {
00812 // jet-jet recombination
00813 // If necessary relabel A & B to ensure jetB < jetA, that way if
00814 // the larger of them == newtail then that ends up being jetA and
00815 // the new jet that is added as jetB is inserted in a position that
00816 // has a future!
00817 if (jetA < jetB) {swap(jetA,jetB);}
00818
00819 int nn; // new jet index
00820 _do_ij_recombination_step(jetA->_jets_index, jetB->_jets_index, diJ_min, nn);
00821
00822 // what was jetB will now become the new jet
00823 _bj_remove_from_tiles(jetA);
00824 oldB = * jetB; // take a copy because we will need it...
00825 _bj_remove_from_tiles(jetB);
00826 _tj_set_jetinfo(jetB, nn); // cause jetB to become _jets[nn]
00827 // (also registers the jet in the tiling)
00828 } else {
00829 // jet-beam recombination
00830 // get the hist_index
00831 _do_iB_recombination_step(jetA->_jets_index, diJ_min);
00832 _bj_remove_from_tiles(jetA);
00833 }
00834
00835 // remove the minheap entry for jetA
00836 minheap.remove(jetA-head);
00837
00838 // first establish the set of tiles over which we are going to
00839 // have to run searches for updated and new nearest-neighbours --
00840 // basically a combination of vicinity of the tiles of the two old
00841 // and one new jet.
00842 int n_near_tiles = 0;
00843 _add_untagged_neighbours_to_tile_union(jetA->tile_index,
00844 tile_union, n_near_tiles);
00845 if (jetB != NULL) {
00846 if (jetB->tile_index != jetA->tile_index) {
00847 _add_untagged_neighbours_to_tile_union(jetB->tile_index,
00848 tile_union,n_near_tiles);
00849 }
00850 if (oldB.tile_index != jetA->tile_index &&
00851 oldB.tile_index != jetB->tile_index) {
00852 _add_untagged_neighbours_to_tile_union(oldB.tile_index,
00853 tile_union,n_near_tiles);
00854 }
00855 // indicate that we'll have to update jetB in the minheap
00856 jetB->label_minheap_update_needed();
00857 jets_for_minheap.push_back(jetB);
00858 }
00859
00860
00861 // Initialise jetB's NN distance as well as updating it for
00862 // other particles.
00863 // Run over all tiles in our union
00864 for (int itile = 0; itile < n_near_tiles; itile++) {
00865 Tile * tile = &_tiles[tile_union[itile]];
00866 tile->tagged = false; // reset tag, since we're done with unions
00867 // run over all jets in the current tile
00868 for (TiledJet * jetI = tile->head; jetI != NULL; jetI = jetI->next) {
00869 // see if jetI had jetA or jetB as a NN -- if so recalculate the NN
00870 if (jetI->NN == jetA || (jetI->NN == jetB && jetB != NULL)) {
00871 jetI->NN_dist = _R2;
00872 jetI->NN = NULL;
00873 // label jetI as needing heap action...
00874 if (!jetI->minheap_update_needed()) {
00875 jetI->label_minheap_update_needed();
00876 jets_for_minheap.push_back(jetI);}
00877 // now go over tiles that are neighbours of I (include own tile)
00878 for (Tile ** near_tile = tile->begin_tiles;
00879 near_tile != tile->end_tiles; near_tile++) {
00880 // and then over the contents of that tile
00881 for (TiledJet * jetJ = (*near_tile)->head;
00882 jetJ != NULL; jetJ = jetJ->next) {
00883 double dist = _bj_dist(jetI,jetJ);
00884 if (dist < jetI->NN_dist && jetJ != jetI) {
00885 jetI->NN_dist = dist; jetI->NN = jetJ;
00886 }
00887 }
00888 }
00889 }
00890 // check whether new jetB is closer than jetI's current NN and
00891 // if jetI is closer than jetB's current (evolving) nearest
00892 // neighbour. Where relevant update things
00893 if (jetB != NULL) {
00894 double dist = _bj_dist(jetI,jetB);
00895 if (dist < jetI->NN_dist) {
00896 if (jetI != jetB) {
00897 jetI->NN_dist = dist;
00898 jetI->NN = jetB;
00899 // label jetI as needing heap action...
00900 if (!jetI->minheap_update_needed()) {
00901 jetI->label_minheap_update_needed();
00902 jets_for_minheap.push_back(jetI);}
00903 }
00904 }
00905 if (dist < jetB->NN_dist) {
00906 if (jetI != jetB) {
00907 jetB->NN_dist = dist;
00908 jetB->NN = jetI;}
00909 }
00910 }
00911 }
00912 }
00913
00914 // deal with jets whose minheap entry needs updating
00915 while (jets_for_minheap.size() > 0) {
00916 TiledJet * jetI = jets_for_minheap.back();
00917 jets_for_minheap.pop_back();
00918 minheap.update(jetI-head, _bj_diJ(jetI));
00919 jetI->label_minheap_update_done();
00920 }
00921 n--;
00922 }
00923
00924 // final cleaning up;
00925 delete[] briefjets;
00926 }
|
|
|
for making sure the user knows what it is they're running...
Definition at line 145 of file ClusterSequence.cc. References _first_time, and fastjet_version. Referenced by _decant_options(). 00145 {
00146
00147 if (!_first_time) {return;}
00148 _first_time = false;
00149
00150
00151 //Symp. Discr. Alg, p.472 (2002) and CGAL (http://www.cgal.org);
00152
00153 cout << "#------------------------------------------------------------------------\n";
00154 cout << "# FastJet release " << fastjet_version << endl;
00155 cout << "# Written by Matteo Cacciari and Gavin Salam \n";
00156 cout << "# http://www.lpthe.jussieu.fr/~salam/fastjet \n";
00157 cout << "# \n";
00158 cout << "# Longitudinally invariant Kt, and inclusive Cambridge/Aachen clustering\n";
00159 cout << "# using fast geometric algorithms, with optional external jet-finder \n";
00160 cout << "# plugins. Please cite hep-ph/0512210 if you use this code. \n";
00161 cout << "# \n";
00162 cout << "# This package uses T.Chan's closest pair algorithm, Proc.13th ACM-SIAM \n";
00163 cout << "# Symp. Discr. Alg, p.472 (2002)";
00164 #ifndef DROP_CGAL
00165 cout << " as well as CGAL: http://www.cgal.org/";
00166 #endif // DROP_CGAL
00167 cout << ".\n";
00168 cout << "#-----------------------------------------------------------------------\n";
00169 }
|
|
|
output the contents of the tiles
Definition at line 209 of file ClusterSequence_TiledN2.cc. References _tiles. 00209 {
00210 for (vector<Tile>::const_iterator tile = _tiles.begin();
00211 tile < _tiles.end(); tile++) {
00212 cout << "Tile " << tile - _tiles.begin()<<" = ";
00213 vector<int> list;
00214 for (TiledJet * jetI = tile->head; jetI != NULL; jetI = jetI->next) {
00215 list.push_back(jetI-briefjets);
00216 //cout <<" "<<jetI-briefjets;
00217 }
00218 sort(list.begin(),list.end());
00219 for (unsigned int i = 0; i < list.size(); i++) {cout <<" "<<list[i];}
00220 cout <<"\n";
00221 }
00222 }
|
|
|
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 165 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. 00165 {
00166 int ieta, iphi;
00167 if (eta <= _tiles_eta_min) {ieta = 0;}
00168 else if (eta >= _tiles_eta_max) {ieta = _tiles_ieta_max-_tiles_ieta_min;}
00169 else {
00170 //ieta = int(floor((eta - _tiles_eta_min) / _tile_size_eta));
00171 ieta = int(((eta - _tiles_eta_min) / _tile_size_eta));
00172 // following needed in case of rare but nasty rounding errors
00173 if (ieta > _tiles_ieta_max-_tiles_ieta_min) {
00174 ieta = _tiles_ieta_max-_tiles_ieta_min;}
00175 }
00176 // allow for some extent of being beyond range in calculation of phi
00177 // as well
00178 //iphi = (int(floor(phi/_tile_size_phi)) + _n_tiles_phi) % _n_tiles_phi;
00179 // with just int and no floor, things run faster but beware
00180 iphi = int((phi+twopi)/_tile_size_phi) % _n_tiles_phi;
00181 return (iphi + ieta * _n_tiles_phi);
00182 }
|
|
||||||||||||
|
Definition at line 508 of file ClusterSequence.hh. Referenced by _initialise_tiles(), and _tj_set_jetinfo(). 00508 {
00509 // note that (-1)%n = -1 so that we have to add _n_tiles_phi
00510 // before performing modulo operation
00511 return (ieta-_tiles_ieta_min)*_n_tiles_phi
00512 + (iphi+_n_tiles_phi) % _n_tiles_phi;
00513 }
|
|
|
run a tiled clustering
Definition at line 264 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(). 00264 {
00265
00266 _initialise_tiles();
00267
00268 int n = _jets.size();
00269 TiledJet * briefjets = new TiledJet[n];
00270 TiledJet * jetA = briefjets, * jetB;
00271 TiledJet oldB;
00272
00273
00274 // will be used quite deep inside loops, but declare it here so that
00275 // memory (de)allocation gets done only once
00276 vector<int> tile_union(3*n_tile_neighbours);
00277
00278 // initialise the basic jet info
00279 for (int i = 0; i< n; i++) {
00280 _tj_set_jetinfo(jetA, i);
00281 //cout << i<<": "<<jetA->tile_index<<"\n";
00282 jetA++; // move on to next entry of briefjets
00283 }
00284 TiledJet * tail = jetA; // a semaphore for the end of briefjets
00285 TiledJet * head = briefjets; // a nicer way of naming start
00286
00287 // set up the initial nearest neighbour information
00288 vector<Tile>::const_iterator tile;
00289 for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
00290 // first do it on this tile
00291 for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
00292 for (jetB = tile->head; jetB != jetA; jetB = jetB->next) {
00293 double dist = _bj_dist(jetA,jetB);
00294 if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
00295 if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
00296 }
00297 }
00298 // then do it for RH tiles
00299 for (Tile ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
00300 for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
00301 for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
00302 double dist = _bj_dist(jetA,jetB);
00303 if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
00304 if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
00305 }
00306 }
00307 }
00308 }
00309
00310 // now create the diJ (where J is i's NN) table -- remember that
00311 // we differ from standard normalisation here by a factor of R2
00312 double * diJ = new double[n];
00313 jetA = head;
00314 for (int i = 0; i < n; i++) {
00315 diJ[i] = _bj_diJ(jetA);
00316 jetA++; // have jetA follow i
00317 }
00318
00319 // now run the recombination loop
00320 int history_location = n-1;
00321 while (tail != head) {
00322
00323 // find the minimum of the diJ on this round
00324 double diJ_min = diJ[0];
00325 int diJ_min_jet = 0;
00326 for (int i = 1; i < n; i++) {
00327 if (diJ[i] < diJ_min) {diJ_min_jet = i; diJ_min = diJ[i];}
00328 }
00329
00330 // do the recombination between A and B
00331 history_location++;
00332 jetA = & briefjets[diJ_min_jet];
00333 jetB = jetA->NN;
00334 // put the normalisation back in
00335 diJ_min *= _invR2;
00336
00337 //if (n == 19) {cout << "Hello "<<jetA-head<<" "<<jetB-head<<"\n";}
00338
00339 //cout <<" WILL RECOMBINE "<< jetA-briefjets<<" "<<jetB-briefjets<<"\n";
00340
00341 if (jetB != NULL) {
00342 // jet-jet recombination
00343 // If necessary relabel A & B to ensure jetB < jetA, that way if
00344 // the larger of them == newtail then that ends up being jetA and
00345 // the new jet that is added as jetB is inserted in a position that
00346 // has a future!
00347 if (jetA < jetB) {swap(jetA,jetB);}
00348
00349 int nn; // new jet index
00350 _do_ij_recombination_step(jetA->_jets_index, jetB->_jets_index, diJ_min, nn);
00351
00352 //OBS// get the two history indices
00353 //OBSint hist_a = _jets[jetA->_jets_index].cluster_hist_index();
00354 //OBSint hist_b = _jets[jetB->_jets_index].cluster_hist_index();
00355 //OBS// create the recombined jet
00356 //OBS_jets.push_back(_jets[jetA->_jets_index] + _jets[jetB->_jets_index]);
00357 //OBSint nn = _jets.size() - 1;
00358 //OBS_jets[nn].set_cluster_hist_index(history_location);
00359 //OBS// update history
00360 //OBS//cout <<n-1<<" "<<jetA-head<<" "<<jetB-head<<"; ";
00361 //OBS_add_step_to_history(history_location,
00362 //OBS min(hist_a,hist_b),max(hist_a,hist_b),
00363 //OBS nn, diJ_min);
00364
00365 // what was jetB will now become the new jet
00366 _bj_remove_from_tiles(jetA);
00367 oldB = * jetB; // take a copy because we will need it...
00368 _bj_remove_from_tiles(jetB);
00369 _tj_set_jetinfo(jetB, nn); // also registers the jet in the tiling
00370 } else {
00371 // jet-beam recombination
00372 _do_iB_recombination_step(jetA->_jets_index, diJ_min);
00373
00374 //OBS// get the hist_index
00375 //OBSint hist_a = _jets[jetA->_jets_index].cluster_hist_index();
00376 //OBS//cout <<n-1<<" "<<jetA-head<<" "<<-1<<"; ";
00377 //OBS_add_step_to_history(history_location,hist_a,BeamJet,Invalid,diJ_min);
00378 _bj_remove_from_tiles(jetA);
00379 }
00380
00381 // first establish the set of tiles over which we are going to
00382 // have to run searches for updated and new nearest-neighbours
00383 int n_near_tiles = 0;
00384 _add_neighbours_to_tile_union(jetA->tile_index, tile_union, n_near_tiles);
00385 if (jetB != NULL) {
00386 bool sort_it = false;
00387 if (jetB->tile_index != jetA->tile_index) {
00388 sort_it = true;
00389 _add_neighbours_to_tile_union(jetB->tile_index,tile_union,n_near_tiles);
00390 }
00391 if (oldB.tile_index != jetA->tile_index &&
00392 oldB.tile_index != jetB->tile_index) {
00393 sort_it = true;
00394 _add_neighbours_to_tile_union(oldB.tile_index,tile_union,n_near_tiles);
00395 }
00396
00397 if (sort_it) {
00398 // sort the tiles before then compressing the list
00399 sort(tile_union.begin(), tile_union.begin()+n_near_tiles);
00400 // and now condense the list
00401 int nnn = 1;
00402 for (int i = 1; i < n_near_tiles; i++) {
00403 if (tile_union[i] != tile_union[nnn-1]) {
00404 tile_union[nnn] = tile_union[i];
00405 nnn++;
00406 }
00407 }
00408 n_near_tiles = nnn;
00409 }
00410 }
00411
00412 // now update our nearest neighbour info and diJ table
00413 // first reduce size of table
00414 tail--; n--;
00415 if (jetA == tail) {
00416 // there is nothing to be done
00417 } else {
00418 // Copy last jet contents and diJ info into position of jetA
00419 *jetA = *tail;
00420 diJ[jetA - head] = diJ[tail-head];
00421 // IN the tiling fix pointers to tail and turn them into
00422 // pointers to jetA (from predecessors, successors and the tile
00423 // head if need be)
00424 if (jetA->previous == NULL) {
00425 _tiles[jetA->tile_index].head = jetA;
00426 } else {
00427 jetA->previous->next = jetA;
00428 }
00429 if (jetA->next != NULL) {jetA->next->previous = jetA;}
00430 }
00431
00432 // Initialise jetB's NN distance as well as updating it for
00433 // other particles.
00434 for (int itile = 0; itile < n_near_tiles; itile++) {
00435 Tile * tile = &_tiles[tile_union[itile]];
00436 for (TiledJet * jetI = tile->head; jetI != NULL; jetI = jetI->next) {
00437 // see if jetI had jetA or jetB as a NN -- if so recalculate the NN
00438 if (jetI->NN == jetA || (jetI->NN == jetB && jetB != NULL)) {
00439 jetI->NN_dist = _R2;
00440 jetI->NN = NULL;
00441 // now go over tiles that are neighbours of I (include own tile)
00442 for (Tile ** near_tile = tile->begin_tiles;
00443 near_tile != tile->end_tiles; near_tile++) {
00444 // and then over the contents of that tile
00445 for (TiledJet * jetJ = (*near_tile)->head;
00446 jetJ != NULL; jetJ = jetJ->next) {
00447 double dist = _bj_dist(jetI,jetJ);
00448 if (dist < jetI->NN_dist && jetJ != jetI) {
00449 jetI->NN_dist = dist; jetI->NN = jetJ;
00450 }
00451 }
00452 }
00453 diJ[jetI-head] = _bj_diJ(jetI); // update diJ
00454 }
00455 // check whether new jetB is closer than jetI's current NN and
00456 // if need to update things
00457 if (jetB != NULL) {
00458 double dist = _bj_dist(jetI,jetB);
00459 if (dist < jetI->NN_dist) {
00460 if (jetI != jetB) {
00461 jetI->NN_dist = dist;
00462 jetI->NN = jetB;
00463 diJ[jetI-head] = _bj_diJ(jetI); // update diJ...
00464 }
00465 }
00466 if (dist < jetB->NN_dist) {
00467 if (jetI != jetB) {
00468 jetB->NN_dist = dist;
00469 jetB->NN = jetI;}
00470 }
00471 }
00472 }
00473 }
00474
00475
00476 if (jetB != NULL) {diJ[jetB-head] = _bj_diJ(jetB);}
00477 //cout << n<<" "<<briefjets[95].NN-briefjets<<" "<<briefjets[95].NN_dist <<"\n";
00478
00479 // remember to update pointers to tail
00480 for (Tile ** near_tile = _tiles[tail->tile_index].begin_tiles;
00481 near_tile!= _tiles[tail->tile_index].end_tiles; near_tile++){
00482 // and then the contents of that tile
00483 for (TiledJet * jetJ = (*near_tile)->head;
00484 jetJ != NULL; jetJ = jetJ->next) {
00485 if (jetJ->NN == tail) {jetJ->NN = jetA;}
00486 }
00487 }
00488
00489 //for (int i = 0; i < n; i++) {
00490 // 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";}
00491 //}
00492
00493
00494 if (jetB != NULL) {diJ[jetB-head] = _bj_diJ(jetB);}
00495 //cout << briefjets[95].NN-briefjets<<" "<<briefjets[95].NN_dist <<"\n";
00496
00497 }
00498
00499 // final cleaning up;
00500 delete[] diJ;
00501 delete[] briefjets;
00502 }
|
|
||||||||||||
|
Definition at line 188 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(). 00189 {
00190 // first call the generic setup
00191 _bj_set_jetinfo<>(jet, _jets_index);
00192
00193 // Then do the setup specific to the tiled case.
00194
00195 // Find out which tile it belonds to
00196 jet->tile_index = _tile_index(jet->eta, jet->phi);
00197
00198 // Insert it into the tile's linked list of jets
00199 Tile * tile = &_tiles[jet->tile_index];
00200 jet->previous = NULL;
00201 jet->next = tile->head;
00202 if (jet->next != NULL) {jet->next->previous = jet;}
00203 tile->head = jet;
00204 }
|
|
||||||||||
|
transfer the vector<L> of input jets into our own vector<PseudoJet> _jets (with some reserved space for future growth).
Definition at line 539 of file ClusterSequence.hh. References _jets. Referenced by ClusterSequence(). 00540 {
00541
00542 // this will ensure that we can point to jets without difficulties
00543 // arising.
00544 _jets.reserve(pseudojets.size()*2);
00545
00546 // insert initial jets this way so that any type L that can be
00547 // converted to a pseudojet will work fine (basically PseudoJet
00548 // and any type that has [] subscript access to the momentum
00549 // components, such as CLHEP HepLorentzVector).
00550 for (unsigned int i = 0; i < pseudojets.size(); i++) {
00551 _jets.push_back(pseudojets[i]);}
00552
00553 }
|
|
||||||||||||
|
add on to subjet_vector the subjets of jet.
Definition at line 477 of file ClusterSequence.cc. References _history, _jets, BeamJet, fastjet::PseudoJet::cluster_hist_index(), and InexistentParent. Referenced by constituents(). 00478 {
00479 // find out position in cluster history
00480 int i = jet.cluster_hist_index();
00481 int parent1 = _history[i].parent1;
00482 int parent2 = _history[i].parent2;
00483
00484 if (parent1 == InexistentParent) {
00485 // It is an original particle (labelled by its parent having value
00486 // InexistentParent), therefore add it on to the subjet vector
00487 subjet_vector.push_back(jet);
00488 return;
00489 }
00490
00491 // add parent 1
00492 add_constituents(_jets[_history[parent1].jetp_index], subjet_vector);
00493
00494 // see if parent2 is a real jet; if it is then add its constituents
00495 if (parent2 != BeamJet) {
00496 add_constituents(_jets[_history[parent2].jetp_index], subjet_vector);
00497 }
00498 }
|
|
|
return a vector of the particles that make up jet
Definition at line 434 of file ClusterSequence.cc. References add_constituents(). Referenced by main(), particle_jet_indices(), and print_jets(). 00434 {
00435 vector<PseudoJet> subjets;
00436 add_constituents(jet, subjets);
00437 return subjets;
00438 }
|
|
|
return the dmin corresponding to the recombination that went from n+1 to n jets
Definition at line 413 of file ClusterSequence.cc. References _history, and _initial_n. 00413 {
00414 assert(njets > 0);
00415 if (njets >= _initial_n) {return 0.0;}
00416 return _history[2*_initial_n-njets-1].dij;
00417 }
|
|
|
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 425 of file ClusterSequence.cc. References _history, and _initial_n. 00425 {
00426 assert(njets > 0);
00427 if (njets >= _initial_n) {return 0.0;}
00428 return _history[2*_initial_n-njets-1].max_dij_so_far;
00429 }
|
|
|
return a vector of all jets when the event is clustered (in the exclusive sense) to exactly njets.
Definition at line 353 of file ClusterSequence.cc. References _history, _initial_n, _jet_def, _jets, _n_exclusive_warnings, fastjet::JetDefinition::jet_finder(), jets(), and fastjet::kt_algorithm. 00353 {
00354
00355 // make sure the user does not ask for more than jets than there
00356 // were particles in the first place.
00357 assert (njets <= _initial_n);
00358
00359 // provide a warning when extracting exclusive jets
00360 if (_jet_def.jet_finder() != kt_algorithm && _n_exclusive_warnings < 5) {
00361 _n_exclusive_warnings++;
00362 cerr << "FastJet WARNING: dcut and exclusive jets for jet-finders other than kt should be interpreted with care." << endl;
00363 }
00364
00365
00366 // calculate the point where we have to stop the clustering.
00367 // relation between stop_point, njets assumes one extra jet disappears
00368 // at each clustering.
00369 int stop_point = 2*_initial_n - njets;
00370
00371 // some sanity checking to make sure that e+e- does not give us
00372 // surprises (should we ever implement e+e-)...
00373 if (2*_initial_n != static_cast<int>(_history.size())) {
00374 ostringstream err;
00375 err << "2*_initial_n != _history.size() -- this endangers internal assumptions!\n";
00376 throw Error(err.str());
00377 //assert(false);
00378 }
00379
00380 // now go forwards and reconstitute the jets that we have --
00381 // basically for any history element, see if the parent jets to
00382 // which it refers were created before the stopping point -- if they
00383 // were then add them to the list, otherwise they are subsequent
00384 // recombinations of the jets that we are looking for.
00385 vector<PseudoJet> jets;
00386 for (unsigned int i = stop_point; i < _history.size(); i++) {
00387 int parent1 = _history[i].parent1;
00388 if (parent1 < stop_point) {
00389 jets.push_back(_jets[_history[parent1].jetp_index]);
00390 }
00391 int parent2 = _history[i].parent2;
00392 if (parent2 < stop_point && parent2 > 0) {
00393 jets.push_back(_jets[_history[parent2].jetp_index]);
00394 }
00395
00396 }
00397
00398 // sanity check...
00399 if (static_cast<int>(jets.size()) != njets) {
00400 ostringstream err;
00401 err << "ClusterSequence::exclusive_jets: size of returned vector ("
00402 <<jets.size()<<") does not coincide with requested number of jets ("
00403 <<njets<<")";
00404 throw Error(err.str());
00405 }
00406
00407 return jets;
00408 }
|
|
|
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 345 of file ClusterSequence.cc. References n_exclusive_jets(). Referenced by main(). 00345 {
00346 int njets = n_exclusive_jets(dcut);
00347 return exclusive_jets(njets);
00348 }
|
|
|
returns a pointer to the extras object (may be null)
Definition at line 195 of file ClusterSequence.hh. Referenced by main(). 00195 {return _extras.get();}
|
|
|
allow the user to access the history in this raw manner (see above for motivation).
Definition at line 592 of file ClusterSequence.hh. References _history. Referenced by fastjet::ClusterSequenceActiveArea::_transfer_areas(), fastjet::ClusterSequenceActiveArea::_transfer_ghost_free_history(), main(), and particle_jet_indices(). 00592 {
00593 return _history;
00594 }
|
|
|
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 279 of file ClusterSequence.cc. References _history, _jet_finder, _jets, BeamJet, fastjet::cambridge_algorithm, jets(), fastjet::kt_algorithm, fastjet::PseudoJet::perp2(), and fastjet::plugin_algorithm. Referenced by main(), fastjet::ClusterSequenceActiveArea::parabolic_pt_per_unit_area(), fastjet::ClusterSequenceActiveArea::pt_per_unit_area(), and run_jet_finder(). 00279 {
00280 double dcut = ptmin*ptmin;
00281 int i = _history.size() - 1; // last jet
00282 vector<PseudoJet> jets;
00283 if (_jet_finder == kt_algorithm) {
00284 while (i >= 0) {
00285 // with our specific definition of dij and diB (i.e. R appears only in
00286 // dij), then dij==diB is the same as the jet.perp2() and we can exploit
00287 // this in selecting the jets...
00288 if (_history[i].max_dij_so_far < dcut) {break;}
00289 if (_history[i].parent2 == BeamJet && _history[i].dij >= dcut) {
00290 // for beam jets
00291 int parent1 = _history[i].parent1;
00292 jets.push_back(_jets[_history[parent1].jetp_index]);}
00293 i--;
00294 }
00295 } else if (_jet_finder == cambridge_algorithm) {
00296 while (i >= 0) {
00297 // inclusive jets are all at end of clustering sequence in the
00298 // Cambridge algorithm -- so if we find a non-exclusive jet, then
00299 // we can exit
00300 if (_history[i].parent2 != BeamJet) {break;}
00301 int parent1 = _history[i].parent1;
00302 const PseudoJet & jet = _jets[_history[parent1].jetp_index];
00303 if (jet.perp2() >= dcut) {jets.push_back(jet);}
00304 i--;
00305 }
00306 } else if (_jet_finder == plugin_algorithm) {
00307 // for inclusive jets with a plugin algorith, we make no
00308 // assumptions about anything (relation of dij to momenta,
00309 // ordering of the dij, etc.)
00310 while (i >= 0) {
00311 if (_history[i].parent2 == BeamJet) {
00312 int parent1 = _history[i].parent1;
00313 const PseudoJet & jet = _jets[_history[parent1].jetp_index];
00314 if (jet.perp2() >= dcut) {jets.push_back(jet);}
00315 }
00316 i--;
00317 }
00318 } else {throw Error("Unrecognized jet algorithm");}
00319 return jets;
00320 }
|
|
|
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 600 of file ClusterSequence.hh. References _jet_finder, fastjet::cambridge_algorithm, fastjet::PseudoJet::kt2(), and fastjet::kt_algorithm. Referenced by _add_ktdistance_to_map(), _bj_set_jetinfo(), and _really_dumb_cluster(). 00601 {
00602 if (_jet_finder == kt_algorithm) {return jet.kt2();}
00603 else if (_jet_finder == cambridge_algorithm) {return 1.0;}
00604 else {throw Error("Unrecognised jet finder");}
00605 }
|
|
|
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 588 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(), and fastjet::CDFJetCluPlugin::run_clustering(). 00588 {
00589 return _jets;
00590 }
|
|
|
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 326 of file ClusterSequence.cc. References _history, and _initial_n. Referenced by exclusive_jets(). 00326 {
00327
00328 // first locate the point where clustering would have stopped (i.e. the
00329 // first time max_dij_so_far > dcut)
00330 int i = _history.size() - 1; // last jet
00331 while (i >= 0) {
00332 if (_history[i].max_dij_so_far <= dcut) {break;}
00333 i--;
00334 }
00335 int stop_point = i + 1;
00336 // relation between stop_point, njets assumes one extra jet disappears
00337 // at each clustering.
00338 int njets = 2*_initial_n - stop_point;
00339 return njets;
00340 }
|
|
|
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 596 of file ClusterSequence.hh. References _initial_n. Referenced by fastjet::ClusterSequenceActiveArea::_transfer_areas(), particle_jet_indices(), unclustered_particles(), and unique_history_order(). 00596 {return _initial_n;}
|
|
|
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 446 of file ClusterSequence.cc. References constituents(), history(), and n_particles(). 00447 {
00448
00449 vector<int> indices(n_particles());
00450
00451 // first label all particles as not belonging to any jets
00452 for (unsigned ipart = 0; ipart < n_particles(); ipart++)
00453 indices[ipart] = -1;
00454
00455 // then for each of the jets relabel its consituents as belonging to
00456 // that jet
00457 for (unsigned ijet = 0; ijet < jets.size(); ijet++) {
00458
00459 vector<PseudoJet> jet_constituents(constituents(jets[ijet]));
00460
00461 for (unsigned ip = 0; ip < jet_constituents.size(); ip++) {
00462 // a safe (if slightly redundant) way of getting the particle
00463 // index (for initial particles it is actually safe to assume
00464 // ipart=iclust).
00465 unsigned iclust = jet_constituents[ip].cluster_hist_index();
00466 unsigned ipart = history()[iclust].jetp_index;
00467 indices[ipart] = ijet;
00468 }
00469 }
00470
00471 return indices;
00472 }
|
|
|
returns true when the plugin is allowed to run the show.
Definition at line 192 of file ClusterSequence.hh. 00192 {return _plugin_activated;}
|
|
|
the plugin can associated some extra information with the ClusterSequence object by calling this function
Definition at line 187 of file ClusterSequence.hh. Referenced by fastjet::SISConePlugin::run_clustering(). 00187 {
00188 _extras = extras_in;
00189 }
|
|
||||||||||||
|
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 171 of file ClusterSequence.hh. Referenced by fastjet::SISConePlugin::run_clustering(), fastjet::PxConePlugin::run_clustering(), fastjet::CDFMidPointPlugin::run_clustering(), and fastjet::CDFJetCluPlugin::run_clustering(). 00171 {
00172 assert(plugin_activated());
00173 _do_iB_recombination_step(jet_i, diB);
00174 }
|
|
||||||||||||||||||||||||
|
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 264 of file ClusterSequence.cc. References _jets, and plugin_record_ij_recombination(). 00266 {
00267
00268 plugin_record_ij_recombination(jet_i, jet_j, dij, newjet_k);
00269
00270 // now transfer newjet into place
00271 int tmp_index = _jets[newjet_k].cluster_hist_index();
00272 _jets[newjet_k] = newjet;
00273 _jets[newjet_k].set_cluster_hist_index(tmp_index);
00274 }
|
|
||||||||||||||||||||
|
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 154 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(). 00155 {
00156 assert(plugin_activated());
00157 _do_ij_recombination_step(jet_i, jet_j, dij, newjet_k);
00158 }
|
|
|
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 201 of file ClusterSequence.hh. 00201 {_default_jet_finder = jet_finder;}
|
|
|
Definition at line 227 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(). 00227 {
00228 string strategy;
00229 switch(_strategy) {
00230 case NlnN:
00231 strategy = "NlnN"; break;
00232 case NlnN3pi:
00233 strategy = "NlnN3pi"; break;
00234 case NlnN4pi:
00235 strategy = "NlnN4pi"; break;
00236 case N2Plain:
00237 strategy = "N2Plain"; break;
00238 case N2Tiled:
00239 strategy = "N2Tiled"; break;
00240 case N2MinHeapTiled:
00241 strategy = "N2MinHeapTiled"; break;
00242 case N2PoorTiled:
00243 strategy = "N2PoorTiled"; break;
00244 case N3Dumb:
00245 strategy = "N3Dumb"; break;
00246 case NlnNCam4pi:
00247 strategy = "NlnNCam4pi"; break;
00248 case NlnNCam2pi2R:
00249 strategy = "NlnNCam2pi2R"; break;
00250 case NlnNCam:
00251 strategy = "NlnNCam"; break; // 2piMultD
00252 case plugin_strategy:
00253 strategy = "plugin strategy"; break;
00254 default:
00255 strategy = "Unrecognized";
00256 }
00257 return strategy;
00258 }
|
|
|
return the enum value of the strategy used to cluster the event
Definition at line 137 of file ClusterSequence.hh. Referenced by fastjet::ClusterSequenceActiveArea::_transfer_ghost_free_history(). 00137 {return _strategy;}
|
|
|
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 603 of file ClusterSequence.cc. References _history, _jets, Invalid, and n_particles(). 00603 {
00604 vector<PseudoJet> unclustered;
00605 for (unsigned i = 0; i < n_particles() ; i++) {
00606 if (_history[i].child == Invalid)
00607 unclustered.push_back(_jets[_history[i].jetp_index]);
00608 }
00609 return unclustered;
00610 }
|
|
|
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 548 of file ClusterSequence.cc. References _extract_tree_children(), _history, and n_particles(). Referenced by fastjet::ClusterSequenceActiveArea::_initialise_and_run_AA(), fastjet::ClusterSequenceActiveArea::_transfer_areas(), and main(). 00548 {
00549
00550 // first construct an array that will tell us the lowest constituent
00551 // of a given jet -- this will always be one of the original
00552 // particles, whose order is well defined and so will help us to
00553 // follow the tree in a unique manner.
00554 valarray<int> lowest_constituent(_history.size());
00555 int hist_n = _history.size();
00556 lowest_constituent = hist_n; // give it a large number
00557 for (int i = 0; i < hist_n; i++) {
00558 // sets things up for the initial partons
00559 lowest_constituent[i] = min(lowest_constituent[i],i);
00560 // propagates them through to the children of this parton
00561 if (_history[i].child > 0) lowest_constituent[_history[i].child]
00562 = min(lowest_constituent[_history[i].child],lowest_constituent[i]);
00563 }
00564
00565 // establish an array for what we have and have not extracted so far
00566 valarray<bool> extracted(_history.size()); extracted = false;
00567 vector<int> unique_tree;
00568 unique_tree.reserve(_history.size());
00569
00570 // now work our way through the tree
00571 for (unsigned i = 0; i < n_particles(); i++) {
00572 if (!extracted[i]) {
00573 unique_tree.push_back(i);
00574 extracted[i] = true;
00575 _extract_tree_children(i, extracted, lowest_constituent, unique_tree);
00576 }
00577 }
00578
00579 return unique_tree;
00580 }
|
|
|
Definition at line 47 of file ClusterSequence.cc. Referenced by _initialise_and_run(). |
|
|
Definition at line 347 of file ClusterSequence.hh. |
|
|
will be set by default to be true for the first run
Definition at line 140 of file ClusterSequence.cc. Referenced by _print_banner(). |
|
|
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.
Definition at line 336 of file ClusterSequence.hh. Referenced by _add_step_to_history(), _CP2DChan_limited_cluster(), _do_Cambridge_inclusive_jets(), _do_iB_recombination_step(), _do_ij_recombination_step(), _extract_tree_children(), _extract_tree_parents(), _fill_initial_history(), fastjet::ClusterSequenceActiveAreaExplicitGhosts::_post_process(), fastjet::ClusterSequenceActiveArea::_transfer_areas(), fastjet::ClusterSequenceActiveArea::_transfer_ghost_free_history(), add_constituents(), exclusive_dmerge(), exclusive_dmerge_max(), exclusive_jets(), history(), inclusive_jets(), n_exclusive_jets(), unclustered_particles(), and unique_history_order(). |
|
|
|
Definition at line 340 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(), and _tiled_N2_cluster(). |
|
|
Definition at line 286 of file ClusterSequence.hh. Referenced by _decant_options(), _do_ij_recombination_step(), _fill_initial_history(), _initialise_and_run(), fastjet::ClusterSequenceActiveAreaExplicitGhosts::_post_process(), fastjet::ClusterSequenceActiveArea::_transfer_areas(), and exclusive_jets(). |
|
|
Definition at line 342 of file ClusterSequence.hh. Referenced by _CP2DChan_cluster(), _CP2DChan_cluster_2pi2R(), _decant_options(), _initialise_and_run(), inclusive_jets(), and jet_scale_for_algorithm(). |
|
|
|
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 504 of file ClusterSequence.hh. Referenced by _initialise_tiles(), and _tile_index(). |
|
|
Definition at line 346 of file ClusterSequence.hh. Referenced by _decant_options(), and _initialise_and_run(). |
|
|
Definition at line 340 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(), and _tiled_N2_cluster(). |
|
|
Definition at line 340 of file ClusterSequence.hh. Referenced by _CP2DChan_cluster_2pi2R(), _CP2DChan_cluster_2piMultD(), _decant_options(), _delaunay_cluster(), _initialise_and_run(), and _initialise_tiles(). |
|
|
Definition at line 341 of file ClusterSequence.hh. Referenced by _decant_options(), _delaunay_cluster(), _initialise_and_run(), fastjet::ClusterSequenceActiveArea::_transfer_ghost_free_history(), and strategy_string(). |
|
|
Definition at line 503 of file ClusterSequence.hh. Referenced by _initialise_tiles(), and _tile_index(). |
|
|
Definition at line 503 of file ClusterSequence.hh. Referenced by _initialise_tiles(), and _tile_index(). |
|
|
Definition at line 501 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 502 of file ClusterSequence.hh. Referenced by _initialise_tiles(), and _tile_index(). |
|
|
Definition at line 502 of file ClusterSequence.hh. Referenced by _initialise_tiles(), and _tile_index(). |
|
|
Definition at line 504 of file ClusterSequence.hh. Referenced by _initialise_tiles(), and _tile_index(). |
|
|
Definition at line 504 of file ClusterSequence.hh. Referenced by _initialise_tiles(), and _tile_index(). |
|
|
Definition at line 338 of file ClusterSequence.hh. Referenced by _add_step_to_history(), and _decant_options(). |
|
|
number of neighbours that a tile will have (rectangular geometry gives 9 neighbours).
Definition at line 483 of file ClusterSequence.hh. Referenced by _faster_tiled_N2_cluster(), _minheap_faster_tiled_N2_cluster(), and _tiled_N2_cluster(). |
1.4.2