fastjet::ClusterSequenceActiveArea Class Reference

Class that behaves essentially like ClusterSequence except that it also provides access to the area of a jet (which will be a random quantity. More...

#include <ClusterSequenceActiveArea.hh>

Inheritance diagram for fastjet::ClusterSequenceActiveArea:

Inheritance graph
fastjet::ClusterSequence1GhostPassiveAreafastjet::ClusterSequenceAreaBasefastjet::ClusterSequencefastjet::ClusterSequencePassiveArea
[legend]
Collaboration diagram for fastjet::ClusterSequenceActiveArea:

Collaboration graph
fastjet::ClusterSequenceAreaBasefastjet::ClusterSequencefastjet::JetDefinitionfastjet::JetDefinition::DefaultRecombinerfastjet::JetDefinition::Recombinerfastjet::JetDefinition::PluginLimitedWarning
[legend]
List of all members.

Public Types

enum  mean_pt_strategies {
  median = 0, non_ghost_median, pttot_over_areatot, pttot_over_areatot_cut,
  mean_ratio_cut, play, median_4vector
}
 enum providing a variety of tentative strategies for estimating the background (e.g. More...

Public Member Functions

 ClusterSequenceActiveArea ()
 default constructor
template<class L>
 ClusterSequenceActiveArea (const std::vector< L > &pseudojets, const JetDefinition &jet_def, const GhostedAreaSpec &area_spec, const bool &writeout_combinations=false)
 constructor based on JetDefinition and GhostedAreaSpec
virtual double area (const PseudoJet &jet) const
 return the area associated with the given jet; this base class returns 0.
virtual double area_error (const PseudoJet &jet) const
 return the error (uncertainty) associated with the determination of the area of this jet; this base class returns 0.
virtual PseudoJet area_4vector (const PseudoJet &jet) const
 return a PseudoJet whose 4-vector is defined by the following integral
double pt_per_unit_area (mean_pt_strategies strat=median, double range=2.0) const
 return the transverse momentum per unit area according to one of the above strategies; for some strategies (those with "cut" in their name) the parameter "range" allows one to exclude a subset of the jets for the background estimation, those that have pt/area > median(pt/area)*range.
void parabolic_pt_per_unit_area (double &a, double &b, double raprange=-1.0, double exclude_above=-1.0, bool use_area_4vector=false) const
 fits a form pt_per_unit_area(y) = a + b*y^2 in the range abs(y)<raprange (for negative raprange, it defaults to _safe_rap_for_area).
virtual double empty_area (const RangeDefinition &range) const
 rewrite the empty area from the parent class, so as to use all info at our disposal return the total area, in the given y-phi range, that consists of ghost jets or unclustered ghosts
virtual double n_empty_jets (const RangeDefinition &range) const
 return the true number of empty jets (replaces ClusterSequenceAreaBase::n_empty_jets(.

Protected Member Functions

void _resize_and_zero_AA ()
void _initialise_AA (const JetDefinition &jet_def, const GhostedAreaSpec &area_spec, const bool &writeout_combinations, bool &continue_running)
void _run_AA (const GhostedAreaSpec &area_spec)
void _postprocess_AA (const GhostedAreaSpec &area_spec)
 run the postprocessing for the active area (and derived classes)
void _initialise_and_run_AA (const JetDefinition &jet_def, const GhostedAreaSpec &area_spec, const bool &writeout_combinations=false)
 global routine for running active area
void _transfer_ghost_free_history (const ClusterSequenceActiveAreaExplicitGhosts &clust_seq)
 transfer the history (and jet-momenta) from clust_seq to our own internal structure while removing ghosts
void _transfer_areas (const vector< int > &unique_hist_order, const ClusterSequenceActiveAreaExplicitGhosts &)
 transfer areas from the ClusterSequenceActiveAreaExplicitGhosts object into our internal area bookkeeping.
bool has_dangerous_particles () const
 returns true if there are any particles whose transverse momentum if so low that there's a risk of the ghosts having modified the clustering sequence

Protected Attributes

valarray< double > _average_area
 child classes benefit from having these at their disposal
valarray< double > _average_area2
valarray< PseudoJet_average_area_4vector

Private Member Functions

void _extract_tree (vector< int > &) const
 routine for extracting the tree in an order that will be independent of any degeneracies in the recombination sequence that don't affect the composition of the final jets
void _extract_tree_children (int pos, valarray< bool > &, const valarray< int > &, vector< int > &) const
 do the part of the extraction associated with pos, working through its children and their parents
void _extract_tree_parents (int pos, valarray< bool > &, const valarray< int > &, vector< int > &) const
 do the part of the extraction associated with the parents of pos.
void _throw_unless_jets_have_same_perp_or_E (const PseudoJet &jet, const PseudoJet &refjet, double tolerance, const ClusterSequenceActiveAreaExplicitGhosts &jets_ghosted_seq) const
 check if two jets have the same momentum to within the tolerance (and if pt's are not the same we're forgiving and look to see if the energy is the same)

Private Attributes

double _non_jet_area
double _non_jet_area2
double _non_jet_number
double _maxrap_for_area
double _safe_rap_for_area
bool _has_dangerous_particles
int _area_spec_repeat
 since we are playing nasty games with seeds, we should warn the user a few times
std::vector< GhostJet_ghost_jets
std::vector< GhostJet_unclustered_ghosts

Classes

class  GhostJet
 a class for our internal storage of ghost jets More...

Detailed Description

Class that behaves essentially like ClusterSequence except that it also provides access to the area of a jet (which will be a random quantity.

.. Figure out what to do about seeds later...)

Definition at line 56 of file ClusterSequenceActiveArea.hh.


Member Enumeration Documentation

enum fastjet::ClusterSequenceActiveArea::mean_pt_strategies

enum providing a variety of tentative strategies for estimating the background (e.g.

non-jet) activity in a highly populated event; the one that has been most extensively tested is median.

Enumerator:
median 
non_ghost_median 
pttot_over_areatot 
pttot_over_areatot_cut 
mean_ratio_cut 
play 
median_4vector 

Definition at line 80 of file ClusterSequenceActiveArea.hh.


Constructor & Destructor Documentation

fastjet::ClusterSequenceActiveArea::ClusterSequenceActiveArea (  )  [inline]

default constructor

Definition at line 60 of file ClusterSequenceActiveArea.hh.

00060 {}

template<class L>
fastjet::ClusterSequenceActiveArea::ClusterSequenceActiveArea ( const std::vector< L > &  pseudojets,
const JetDefinition jet_def,
const GhostedAreaSpec area_spec,
const bool &  writeout_combinations = false 
) [inline]

constructor based on JetDefinition and GhostedAreaSpec

Definition at line 199 of file ClusterSequenceActiveArea.hh.

00202                                      {
00203 
00204   // transfer the initial jets (type L) into our own array
00205   _transfer_input_jets(pseudojets);
00206 
00207   // run the clustering for active areas
00208   _initialise_and_run_AA(jet_def, area_spec, writeout_combinations);
00209 
00210 }


Member Function Documentation

virtual double fastjet::ClusterSequenceActiveArea::area ( const PseudoJet jet  )  const [inline, virtual]

return the area associated with the given jet; this base class returns 0.

Reimplemented from fastjet::ClusterSequenceAreaBase.

Definition at line 69 of file ClusterSequenceActiveArea.hh.

References fastjet::PseudoJet::cluster_hist_index().

Referenced by _transfer_areas(), empty_area(), parabolic_pt_per_unit_area(), and pt_per_unit_area().

00069                                                     {
00070                              return _average_area[jet.cluster_hist_index()];};

virtual double fastjet::ClusterSequenceActiveArea::area_error ( const PseudoJet jet  )  const [inline, virtual]

return the error (uncertainty) associated with the determination of the area of this jet; this base class returns 0.

Reimplemented from fastjet::ClusterSequenceAreaBase.

Definition at line 71 of file ClusterSequenceActiveArea.hh.

References fastjet::PseudoJet::cluster_hist_index().

00071                                                           {
00072                              return _average_area2[jet.cluster_hist_index()];};

virtual PseudoJet fastjet::ClusterSequenceActiveArea::area_4vector ( const PseudoJet jet  )  const [inline, virtual]

return a PseudoJet whose 4-vector is defined by the following integral

drap d PseudoJet("rap,phi,pt=one") * Theta("rap,phi inside jet boundary")

where PseudoJet("rap,phi,pt=one") is a 4-vector with the given rapidity (rap), azimuth (phi) and pt=1, while Theta("rap,phi inside jet boundary") is a function that is 1 when rap,phi define a direction inside the jet boundary and 0 otherwise.

This base class returns a null 4-vector.

Reimplemented from fastjet::ClusterSequenceAreaBase.

Definition at line 74 of file ClusterSequenceActiveArea.hh.

References fastjet::PseudoJet::cluster_hist_index().

Referenced by parabolic_pt_per_unit_area(), and pt_per_unit_area().

00074                                                                {
00075                     return _average_area_4vector[jet.cluster_hist_index()];};

double fastjet::ClusterSequenceActiveArea::pt_per_unit_area ( mean_pt_strategies  strat = median,
double  range = 2.0 
) const

return the transverse momentum per unit area according to one of the above strategies; for some strategies (those with "cut" in their name) the parameter "range" allows one to exclude a subset of the jets for the background estimation, those that have pt/area > median(pt/area)*range.

Definition at line 271 of file ClusterSequenceActiveArea.cc.

References _non_jet_area, _non_jet_number, _safe_rap_for_area, area(), area_4vector(), fastjet::ClusterSequence::inclusive_jets(), mean_ratio_cut, median, median_4vector, non_ghost_median, fastjet::PseudoJet::perp(), play, pttot_over_areatot, and pttot_over_areatot_cut.

00272                                                                      {
00273   
00274   vector<PseudoJet> incl_jets = inclusive_jets();
00275   vector<double> pt_over_areas;
00276 
00277   for (unsigned i = 0; i < incl_jets.size(); i++) {
00278     if (abs(incl_jets[i].rap()) < _safe_rap_for_area) {
00279       double this_area;
00280       if ( strat == median_4vector ) {
00281           this_area = area_4vector(incl_jets[i]).perp();
00282       } else {
00283           this_area = area(incl_jets[i]);
00284       }
00285       pt_over_areas.push_back(incl_jets[i].perp()/this_area);
00286     }
00287   }
00288   
00289   // there is nothing inside our region, so answer will always be zero
00290   if (pt_over_areas.size() == 0) {return 0.0;}
00291   
00292   // get median (pt/area) [this is the "old" median definition. It considers
00293   // only the "real" jets in calculating the median, i.e. excluding the
00294   // only-ghost ones]
00295   sort(pt_over_areas.begin(), pt_over_areas.end());
00296   double non_ghost_median_ratio = pt_over_areas[pt_over_areas.size()/2];
00297 
00298   // new median definition that takes into account non-jet area (i.e.
00299   // jets composed only of ghosts), and for fractional median position 
00300   // interpolates between the corresponding entries in the pt_over_areas array
00301   double nj_median_pos = (pt_over_areas.size()-1 - _non_jet_number)/2.0;
00302   double nj_median_ratio;
00303   if (nj_median_pos >= 0 && pt_over_areas.size() > 1) {
00304     int int_nj_median = int(nj_median_pos);
00305     nj_median_ratio = 
00306       pt_over_areas[int_nj_median] * (int_nj_median+1-nj_median_pos)
00307       + pt_over_areas[int_nj_median+1] * (nj_median_pos - int_nj_median);
00308   } else {
00309     nj_median_ratio = 0.0;
00310   }
00311 
00312 
00313   // get various forms of mean (pt/area)
00314   double pt_sum = 0.0, pt_sum_with_cut = 0.0;
00315   double area_sum = _non_jet_area, area_sum_with_cut = _non_jet_area;
00316   double ratio_sum = 0.0; 
00317   double ratio_n = _non_jet_number;
00318   for (unsigned i = 0; i < incl_jets.size(); i++) {
00319     if (abs(incl_jets[i].rap()) < _safe_rap_for_area) {
00320       double this_area;
00321       if ( strat == median_4vector ) {
00322           this_area = area_4vector(incl_jets[i]).perp();
00323       } else {
00324           this_area = area(incl_jets[i]);
00325       }
00326       pt_sum   += incl_jets[i].perp();
00327       area_sum += this_area;
00328       double ratio = incl_jets[i].perp()/this_area;
00329       if (ratio < range*nj_median_ratio) {
00330         pt_sum_with_cut   += incl_jets[i].perp();
00331         area_sum_with_cut += this_area;
00332         ratio_sum += ratio; ratio_n++;
00333       }
00334     }
00335   }
00336   
00337   if (strat == play) {
00338     double trunc_sum = 0, trunc_sumsqr = 0;
00339     vector<double> means(pt_over_areas.size()), sd(pt_over_areas.size());
00340     for (unsigned i = 0; i < pt_over_areas.size() ; i++ ) {
00341       double ratio = pt_over_areas[i];
00342       trunc_sum += ratio;
00343       trunc_sumsqr += ratio*ratio;
00344       means[i] = trunc_sum / (i+1);
00345       sd[i]    = sqrt(abs(means[i]*means[i]  - trunc_sumsqr/(i+1)));
00346       cerr << "i, means, sd: " <<i<<", "<< means[i] <<", "<<sd[i]<<", "<<
00347         sd[i]/sqrt(i+1.0)<<endl;
00348     }
00349     cout << "-----------------------------------"<<endl;
00350     for (unsigned i = 0; i <= pt_over_areas.size()/2 ; i++ ) {
00351       cout << "Median "<< i <<" = " << pt_over_areas[i]<<endl;
00352     }
00353     cout << "Number of non-jets: "<<_non_jet_number<<endl;
00354     cout << "Area of non-jets: "<<_non_jet_area<<endl;
00355     cout << "Default median position: " << (pt_over_areas.size()-1)/2.0<<endl;
00356     cout << "NJ median position: " << nj_median_pos <<endl;
00357     cout << "NJ median value: " << nj_median_ratio <<endl;
00358     return 0.0;
00359   }
00360 
00361   switch(strat) {
00362   case median:
00363   case median_4vector:
00364     return nj_median_ratio;
00365   case non_ghost_median:
00366     return non_ghost_median_ratio; 
00367   case pttot_over_areatot:
00368     return pt_sum / area_sum;
00369   case pttot_over_areatot_cut:
00370     return pt_sum_with_cut / area_sum_with_cut;
00371   case mean_ratio_cut:
00372     return ratio_sum/ratio_n;
00373   default:
00374     return nj_median_ratio;
00375   }
00376 
00377 }

void fastjet::ClusterSequenceActiveArea::parabolic_pt_per_unit_area ( double &  a,
double &  b,
double  raprange = -1.0,
double  exclude_above = -1.0,
bool  use_area_4vector = false 
) const

fits a form pt_per_unit_area(y) = a + b*y^2 in the range abs(y)<raprange (for negative raprange, it defaults to _safe_rap_for_area).

Definition at line 383 of file ClusterSequenceActiveArea.cc.

References _safe_rap_for_area, area(), area_4vector(), fastjet::ClusterSequence::inclusive_jets(), and fastjet::PseudoJet::perp().

00385                                     {
00386   
00387   double this_raprange;
00388   if (raprange <= 0) {this_raprange = _safe_rap_for_area;}
00389   else {this_raprange = raprange;}
00390 
00391   int n=0;
00392   int n_excluded = 0;
00393   double mean_f=0, mean_x2=0, mean_x4=0, mean_fx2=0; 
00394 
00395   vector<PseudoJet> incl_jets = inclusive_jets();
00396 
00397   for (unsigned i = 0; i < incl_jets.size(); i++) {
00398     if (abs(incl_jets[i].rap()) < this_raprange) {
00399       double this_area;
00400       if ( use_area_4vector ) {
00401           this_area = area_4vector(incl_jets[i]).perp();     
00402       } else {
00403           this_area = area(incl_jets[i]);
00404       }
00405       double f = incl_jets[i].perp()/this_area;
00406       if (exclude_above <= 0.0 || f < exclude_above) {
00407         double x = incl_jets[i].rap(); double x2 = x*x;
00408         mean_f   += f;
00409         mean_x2  += x2;
00410         mean_x4  += x2*x2;
00411         mean_fx2 += f*x2;
00412         n++;
00413       } else {
00414         n_excluded++;
00415       }
00416     }
00417   }
00418 
00419   if (n <= 1) {
00420     // meaningful results require at least two jets inside the
00421     // area -- mind you if there are empty jets we should be in 
00422     // any case doing something special...
00423     a = 0.0;
00424     b = 0.0;
00425   } else {
00426     mean_f   /= n;
00427     mean_x2  /= n;
00428     mean_x4  /= n;
00429     mean_fx2 /= n;
00430     
00431     b = (mean_f*mean_x2 - mean_fx2)/(mean_x2*mean_x2 - mean_x4);
00432     a = mean_f - b*mean_x2;
00433   }
00434   //cerr << "n_excluded = "<< n_excluded << endl;
00435 }

double fastjet::ClusterSequenceActiveArea::empty_area ( const RangeDefinition range  )  const [virtual]

rewrite the empty area from the parent class, so as to use all info at our disposal return the total area, in the given y-phi range, that consists of ghost jets or unclustered ghosts

Reimplemented from fastjet::ClusterSequenceAreaBase.

Reimplemented in fastjet::ClusterSequencePassiveArea.

Definition at line 439 of file ClusterSequenceActiveArea.cc.

References _area_spec_repeat, _ghost_jets, _unclustered_ghosts, area(), and fastjet::RangeDefinition::is_in_range().

Referenced by fastjet::ClusterSequencePassiveArea::empty_area().

00439                                                                                 {
00440   double empty = 0.0;
00441   // first deal with ghost jets
00442   for (unsigned  i = 0; i < _ghost_jets.size(); i++) {
00443     if (range.is_in_range(_ghost_jets[i])) {
00444       empty += _ghost_jets[i].area;
00445     }
00446   }
00447   // then deal with unclustered ghosts
00448   for (unsigned  i = 0; i < _unclustered_ghosts.size(); i++) {
00449     if (range.is_in_range(_unclustered_ghosts[i])) {
00450       empty += _unclustered_ghosts[i].area;
00451     }
00452   }
00453   empty /= _area_spec_repeat;
00454   return empty;
00455 }

double fastjet::ClusterSequenceActiveArea::n_empty_jets ( const RangeDefinition range  )  const [virtual]

return the true number of empty jets (replaces ClusterSequenceAreaBase::n_empty_jets(.

..))

Reimplemented from fastjet::ClusterSequenceAreaBase.

Reimplemented in fastjet::ClusterSequence1GhostPassiveArea.

Definition at line 458 of file ClusterSequenceActiveArea.cc.

References _area_spec_repeat, _ghost_jets, and fastjet::RangeDefinition::is_in_range().

00458                                                                                   {
00459   double inrange = 0;
00460   for (unsigned  i = 0; i < _ghost_jets.size(); i++) {
00461     if (range.is_in_range(_ghost_jets[i])) inrange++;
00462   }
00463   inrange /= _area_spec_repeat;
00464   return inrange;
00465 }

void fastjet::ClusterSequenceActiveArea::_resize_and_zero_AA (  )  [protected]

Definition at line 64 of file ClusterSequenceActiveArea.cc.

References _average_area, _average_area2, _average_area_4vector, fastjet::ClusterSequence::_jets, _non_jet_area, _non_jet_area2, and _non_jet_number.

Referenced by _initialise_AA(), and fastjet::ClusterSequencePassiveArea::_initialise_and_run_PA().

00064                                                      {
00065   // initialize our local area information
00066   _average_area.resize(2*_jets.size());  _average_area  = 0.0;
00067   _average_area2.resize(2*_jets.size()); _average_area2 = 0.0;
00068   _average_area_4vector.resize(2*_jets.size()); 
00069   _average_area_4vector = PseudoJet(0.0,0.0,0.0,0.0);
00070   _non_jet_area = 0.0; _non_jet_area2 = 0.0; _non_jet_number=0.0;
00071 }

void fastjet::ClusterSequenceActiveArea::_initialise_AA ( const JetDefinition jet_def,
const GhostedAreaSpec area_spec,
const bool &  writeout_combinations,
bool &  continue_running 
) [protected]

Definition at line 74 of file ClusterSequenceActiveArea.cc.

References _area_spec_repeat, fastjet::ClusterSequence::_decant_options(), fastjet::ClusterSequence::_fill_initial_history(), _has_dangerous_particles, fastjet::ClusterSequence::_initialise_and_run(), _maxrap_for_area, _resize_and_zero_AA(), _safe_rap_for_area, fastjet::GhostedAreaSpec::ghost_maxrap(), fastjet::ClusterSequence::jet_def(), fastjet::JetDefinition::R(), and fastjet::GhostedAreaSpec::repeat().

Referenced by fastjet::ClusterSequence1GhostPassiveArea::_initialise_and_run_1GPA(), and _initialise_and_run_AA().

00079 {
00080 
00081   // store this for future use
00082   _area_spec_repeat = area_spec.repeat();
00083 
00084   // make sure placeholders are there & zeroed
00085   _resize_and_zero_AA();
00086      
00087   // for future reference...
00088   _maxrap_for_area = area_spec.ghost_maxrap();
00089   _safe_rap_for_area = _maxrap_for_area - jet_def.R();
00090 
00091   // Make sure we'll have at least one repetition -- then we can
00092   // deduce the unghosted clustering sequence from one of the ghosted
00093   // sequences. If we do not have any repetitions, then get the
00094   // unghosted sequence from the plain unghosted clustering.
00095   //
00096   // NB: all decanting and filling of initial history will then
00097   // be carried out by base-class routine
00098   if (area_spec.repeat() <= 0) {
00099     _initialise_and_run(jet_def, writeout_combinations);
00100     continue_running = false;
00101     return;
00102   }
00103 
00104   // transfer all relevant info into internal variables
00105   _decant_options(jet_def, writeout_combinations);
00106 
00107   // set up the history entries for the initial particles (those
00108   // currently in _jets)
00109   _fill_initial_history();
00110 
00111   // by default it does not...
00112   _has_dangerous_particles = false;
00113   
00114   continue_running = true;
00115 }

void fastjet::ClusterSequenceActiveArea::_run_AA ( const GhostedAreaSpec area_spec  )  [protected]

Definition at line 119 of file ClusterSequenceActiveArea.cc.

References _has_dangerous_particles, fastjet::ClusterSequence::_jets, _transfer_areas(), _transfer_ghost_free_history(), fastjet::ClusterSequence::jet_def(), fastjet::GhostedAreaSpec::repeat(), and fastjet::ClusterSequence::unique_history_order().

Referenced by _initialise_and_run_AA().

00119                                                                           {
00120   // record the input jets as they are currently
00121   vector<PseudoJet> input_jets(_jets);
00122 
00123   // code for testing the unique tree
00124   vector<int> unique_tree;
00125 
00126   // run the clustering multiple times so as to get areas of all the jets
00127   for (int irepeat = 0; irepeat < area_spec.repeat(); irepeat++) {
00128 
00129     ClusterSequenceActiveAreaExplicitGhosts clust_seq(input_jets, 
00130                                                       jet_def(), area_spec);
00131 
00132     _has_dangerous_particles |= clust_seq.has_dangerous_particles();
00133     if (irepeat == 0) {
00134       // take the non-ghost part of the history and put into our own
00135       // history.
00136       _transfer_ghost_free_history(clust_seq);
00137       // get the "unique" order that will be used for transferring all areas. 
00138       unique_tree = unique_history_order();
00139     }
00140 
00141     // transfer areas from clust_seq into our object
00142     _transfer_areas(unique_tree, clust_seq);
00143   }
00144 }

void fastjet::ClusterSequenceActiveArea::_postprocess_AA ( const GhostedAreaSpec area_spec  )  [protected]

run the postprocessing for the active area (and derived classes)

Definition at line 149 of file ClusterSequenceActiveArea.cc.

References _average_area, _average_area2, _average_area_4vector, _non_jet_area, _non_jet_area2, _non_jet_number, and fastjet::GhostedAreaSpec::repeat().

Referenced by fastjet::ClusterSequence1GhostPassiveArea::_initialise_and_run_1GPA(), and _initialise_and_run_AA().

00149                                                                                   {
00150   _average_area  /= area_spec.repeat();
00151   _average_area2 /= area_spec.repeat();
00152   if (area_spec.repeat() > 1) {
00153     _average_area2 = sqrt(abs(_average_area2 - _average_area*_average_area)/
00154                           (area_spec.repeat()-1));
00155   } else {
00156     _average_area2 = 0.0;
00157   }
00158 
00159   _non_jet_area  /= area_spec.repeat();
00160   _non_jet_area2 /= area_spec.repeat();
00161   _non_jet_area2  = sqrt(abs(_non_jet_area2 - _non_jet_area*_non_jet_area)/
00162                          area_spec.repeat());
00163   _non_jet_number /= area_spec.repeat();
00164 
00165   // following bizarre way of writing things is related to 
00166   // poverty of operations on PseudoJet objects (as well as some confusion
00167   // in one or two places)
00168   for (unsigned i = 0; i < _average_area_4vector.size(); i++) {
00169     _average_area_4vector[i] = (1.0/area_spec.repeat()) * _average_area_4vector[i];
00170   }
00171   //cerr << "Non-jet area = " << _non_jet_area << " +- " << _non_jet_area2<<endl;
00172 }

void fastjet::ClusterSequenceActiveArea::_initialise_and_run_AA ( const JetDefinition jet_def,
const GhostedAreaSpec area_spec,
const bool &  writeout_combinations = false 
) [protected]

global routine for running active area

Definition at line 50 of file ClusterSequenceActiveArea.cc.

References _initialise_AA(), _postprocess_AA(), _run_AA(), and fastjet::ClusterSequence::jet_def().

Referenced by fastjet::ClusterSequencePassiveArea::_initialise_and_run_PA().

00053                                                     {
00054 
00055   bool continue_running;
00056   _initialise_AA(jet_def,  area_spec, writeout_combinations, continue_running);
00057   if (continue_running) {
00058     _run_AA(area_spec);
00059     _postprocess_AA(area_spec);
00060   }
00061 }

void fastjet::ClusterSequenceActiveArea::_transfer_ghost_free_history ( const ClusterSequenceActiveAreaExplicitGhosts clust_seq  )  [protected]

transfer the history (and jet-momenta) from clust_seq to our own internal structure while removing ghosts

Definition at line 470 of file ClusterSequenceActiveArea.cc.

References fastjet::ClusterSequence::_do_iB_recombination_step(), fastjet::ClusterSequence::_do_ij_recombination_step(), fastjet::ClusterSequence::_history, fastjet::ClusterSequence::_strategy, fastjet::ClusterSequence::BeamJet, fastjet::ClusterSequence::history(), fastjet::ClusterSequence::InexistentParent, fastjet::ClusterSequence::Invalid, fastjet::ClusterSequenceActiveAreaExplicitGhosts::is_pure_ghost(), and fastjet::ClusterSequence::strategy_used().

Referenced by fastjet::ClusterSequence1GhostPassiveArea::_run_1GPA(), and _run_AA().

00471                                                                           {
00472   
00473   const vector<history_element> & gs_history  = ghosted_seq.history();
00474   vector<int> gs2self_hist_map(gs_history.size());
00475 
00476   // work our way through to first non-trivial combination
00477   unsigned igs = 0;
00478   unsigned iself = 0;
00479   while (gs_history[igs].parent1 == InexistentParent) {
00480     // record correspondence 
00481     if (!ghosted_seq.is_pure_ghost(igs)) {
00482       gs2self_hist_map[igs] = iself++; 
00483     } else {
00484       gs2self_hist_map[igs] = Invalid; 
00485     }
00486     igs++;
00487   };
00488 
00489   // make sure the count of non-ghost initial jets is equal to
00490   // what we already have in terms of initial jets
00491   assert(iself == _history.size());
00492 
00493   // now actually transfer things
00494   do  {
00495     // if we are a pure ghost, then go on to next round
00496     if (ghosted_seq.is_pure_ghost(igs)) {
00497       gs2self_hist_map[igs] = Invalid;
00498       continue;
00499     }
00500 
00501     const history_element & gs_hist_el = gs_history[igs];
00502 
00503     bool parent1_is_ghost = ghosted_seq.is_pure_ghost(gs_hist_el.parent1);
00504     bool parent2_is_ghost = ghosted_seq.is_pure_ghost(gs_hist_el.parent2);
00505 
00506     // if exactly one parent is a ghost then maintain info about the
00507     // non-ghost correspondence for this jet, and then go on to next
00508     // recombination in the ghosted sequence
00509     if (parent1_is_ghost && !parent2_is_ghost && gs_hist_el.parent2 >= 0) {
00510       gs2self_hist_map[igs] = gs2self_hist_map[gs_hist_el.parent2];
00511       continue;
00512     }
00513     if (!parent1_is_ghost && parent2_is_ghost) {
00514       gs2self_hist_map[igs] = gs2self_hist_map[gs_hist_el.parent1];
00515       continue;
00516     }
00517 
00518     // no parents are ghosts...
00519     if (gs_hist_el.parent2 >= 0) {
00520       // recombination of two non-ghosts
00521       gs2self_hist_map[igs] = _history.size();
00522       // record the recombination in our own sequence
00523       int newjet_k; // dummy var -- not used
00524       int jet_i = _history[gs2self_hist_map[gs_hist_el.parent1]].jetp_index;
00525       int jet_j = _history[gs2self_hist_map[gs_hist_el.parent2]].jetp_index;
00526       //cerr << "recombining "<< jet_i << " and "<< jet_j << endl;
00527       _do_ij_recombination_step(jet_i, jet_j, gs_hist_el.dij, newjet_k);
00528     } else {
00529       // we have a non-ghost that has become a beam-jet
00530       assert(gs_history[igs].parent2 == BeamJet);
00531       // record position
00532       gs2self_hist_map[igs] = _history.size();
00533       // record the recombination in our own sequence
00534       _do_iB_recombination_step(
00535              _history[gs2self_hist_map[gs_hist_el.parent1]].jetp_index,
00536              gs_hist_el.dij);
00537     }
00538   } while (++igs < gs_history.size());
00539 
00540   // finally transfer info about strategy used (which isn't necessarily
00541   // always the one that got asked for...)
00542   _strategy = ghosted_seq.strategy_used();
00543 }

void fastjet::ClusterSequenceActiveArea::_transfer_areas ( const vector< int > &  unique_hist_order,
const ClusterSequenceActiveAreaExplicitGhosts  
) [protected]

transfer areas from the ClusterSequenceActiveAreaExplicitGhosts object into our internal area bookkeeping.

..

Definition at line 546 of file ClusterSequenceActiveArea.cc.

References _average_area, _average_area2, _average_area_4vector, _ghost_jets, fastjet::ClusterSequence::_history, fastjet::ClusterSequence::_initial_n, fastjet::ClusterSequence::_jet_def, fastjet::ClusterSequence::_jets, _non_jet_area, _non_jet_area2, _non_jet_number, _safe_rap_for_area, _throw_unless_jets_have_same_perp_or_E(), _unclustered_ghosts, fastjet::ClusterSequenceActiveAreaExplicitGhosts::area(), area(), fastjet::ClusterSequenceActiveAreaExplicitGhosts::area_4vector(), fastjet::ClusterSequence::BeamJet, fastjet::ClusterSequence::history(), fastjet::ClusterSequenceActiveAreaExplicitGhosts::is_pure_ghost(), fastjet::ClusterSequence::jets(), fastjet::ClusterSequence::n_particles(), fastjet::JetDefinition::recombiner(), fastjet::ClusterSequence::unclustered_particles(), and fastjet::ClusterSequence::unique_history_order().

Referenced by fastjet::ClusterSequence1GhostPassiveArea::_run_1GPA(), and _run_AA().

00548                                                                            {
00549 
00550   const vector<history_element> & gs_history  = ghosted_seq.history();
00551   const vector<PseudoJet>       & gs_jets     = ghosted_seq.jets();
00552   vector<int>    gs_unique_hist_order = ghosted_seq.unique_history_order();
00553 
00554   const double tolerance = 1e-11; // to decide when two jets are the same
00555 
00556   int j = -1;
00557   int hist_index = -1;
00558   
00559   valarray<double> our_areas(_history.size());
00560   our_areas = 0.0;
00561 
00562   valarray<PseudoJet> our_area_4vectors(_history.size());
00563   our_area_4vectors = PseudoJet(0.0,0.0,0.0,0.0);
00564 
00565   for (unsigned i = 0; i < gs_history.size(); i++) {
00566     // only consider composite particles
00567     unsigned gs_hist_index = gs_unique_hist_order[i];
00568     if (gs_hist_index < ghosted_seq.n_particles()) continue;
00569     const history_element & gs_hist = gs_history[gs_unique_hist_order[i]];
00570     int parent1 = gs_hist.parent1;
00571     int parent2 = gs_hist.parent2;
00572 
00573     if (parent2 == BeamJet) {
00574       // need to look at parent to get the actual jet
00575       const PseudoJet & jet = 
00576           gs_jets[gs_history[parent1].jetp_index];
00577       double area = ghosted_seq.area(jet);
00578       PseudoJet ext_area = ghosted_seq.area_4vector(jet);
00579 
00580       if (ghosted_seq.is_pure_ghost(parent1)) {
00581         // record the existence of the pure ghost jet for future use
00582         _ghost_jets.push_back(GhostJet(jet,area));
00583         if (abs(jet.rap()) < _safe_rap_for_area) {
00584           _non_jet_area  += area;
00585           _non_jet_area2 += area*area;
00586           _non_jet_number += 1;
00587         }
00588       } else {
00589 
00590         // get next "combined-particle" index in our own history
00591         // making sure we don't go beyond its bounds (if we do
00592         // then we're in big trouble anyway...)
00593         while (++j < int(_history.size())) {
00594           hist_index = unique_hist_order[j];
00595           if (hist_index >= _initial_n) break;}
00596 
00597         // sanity checking -- do not overrun
00598         if (j >= int(_history.size())) throw Error("ClusterSequenceActiveArea: overran reference array in diB matching");
00599 
00600         // sanity check -- make sure we are taking about the same 
00601         // jet in reference and new sequences
00602         int refjet_index = _history[_history[hist_index].parent1].jetp_index;
00603         assert(refjet_index >= 0 && refjet_index < int(_jets.size()));
00604         const PseudoJet & refjet = _jets[refjet_index];
00605 
00606       //cerr << "Inclusive" << endl;
00607       //cerr << gs_history[parent1].jetp_index << " " << gs_jets.size() << endl;
00608       //cerr << _history[_history[hist_index].parent1].jetp_index << " " << _jets.size() << endl;
00609 
00610         // If pt disagrees check E; if they both disagree there's a
00611         // problem here... NB: a massive particle with zero pt may
00612         // have its pt changed when a ghost is added -- this is why we
00613         // also require the energy to be wrong before complaining
00614         _throw_unless_jets_have_same_perp_or_E(jet, refjet, tolerance,
00615                                                ghosted_seq);
00616 
00617         // set the area at this clustering stage
00618         our_areas[hist_index]  = area; 
00619         our_area_4vectors[hist_index]  = ext_area; 
00620 
00621         // update the parent as well -- that way its area is the area
00622         // immediately before clustering (i.e. resolve an ambiguity in
00623         // the Cambridge case and ensure in the kt case that the original
00624         // particles get a correct area)
00625         our_areas[_history[hist_index].parent1] = area;
00626         our_area_4vectors[_history[hist_index].parent1] = ext_area;
00627         
00628       }
00629     }
00630     else if (!ghosted_seq.is_pure_ghost(parent1) && 
00631              !ghosted_seq.is_pure_ghost(parent2)) {
00632 
00633       // get next "combined-particle" index in our own history
00634       while (++j < int(_history.size())) {
00635         hist_index = unique_hist_order[j];
00636         if (hist_index >= _initial_n) break;}
00637       
00638       // sanity checking -- do not overrun
00639       if (j >= int(_history.size())) throw Error("ClusterSequenceActiveArea: overran reference array in dij matching");
00640 
00641       // make sure that our reference history entry is also for
00642       // an exclusive (dij) clustering (otherwise the comparison jet
00643       // will not exist)
00644       if (_history[hist_index].parent2 == BeamJet) throw Error("ClusterSequenceActiveArea: could not match clustering sequences (encountered dij matched with diB)");
00645 
00646       //cerr << "Exclusive: hist_index,hist_size: " << hist_index << " " << _history.size()<< endl;
00647       //cerr << gs_hist.jetp_index << " " << gs_jets.size() << endl;
00648       //cerr << _history[hist_index].jetp_index << " " << _jets.size() << endl;
00649 
00650       const PseudoJet & jet = gs_jets[gs_hist.jetp_index];
00651       const PseudoJet & refjet = _jets[_history[hist_index].jetp_index];
00652 
00653       // run sanity check 
00654       _throw_unless_jets_have_same_perp_or_E(jet, refjet, tolerance,
00655                                              ghosted_seq);
00656 
00657       // update area and our local index (maybe redundant since later
00658       // the descendants will reupdate it?)
00659       double area  = ghosted_seq.area(jet);
00660       our_areas[hist_index]  += area; 
00661 
00662       PseudoJet ext_area = ghosted_seq.area_4vector(jet);
00663 
00664       // GPS TMP debugging (jetclu) -----------------------
00665       //ext_area = PseudoJet(1e-100,1e-100,1e-100,4e-100);
00666       //our_area_4vectors[hist_index] = ext_area;
00667       //cout << "aa " 
00668       //     << our_area_4vectors[hist_index].px() << " "
00669       //     << our_area_4vectors[hist_index].py() << " "
00670       //     << our_area_4vectors[hist_index].pz() << " "
00671       //     << our_area_4vectors[hist_index].E() << endl;
00672       //cout << "bb " 
00673       //     << ext_area.px() << " "
00674       //     << ext_area.py() << " "
00675       //     << ext_area.pz() << " "
00676       //     << ext_area.E() << endl;
00677       //---------------------------------------------------
00678 
00679       _jet_def.recombiner()->plus_equal(our_area_4vectors[hist_index], ext_area);
00680 
00681       // now update areas of parents (so that they becomes areas
00682       // immediately before clustering occurred). This is of use
00683       // because it allows us to set the areas of the original hard
00684       // particles in the kt algorithm; for the Cambridge case it
00685       // means a jet's area will be the area just before it clusters
00686       // with another hard jet.
00687       const PseudoJet & jet1 = gs_jets[gs_history[parent1].jetp_index];
00688       int our_parent1 = _history[hist_index].parent1;
00689       our_areas[our_parent1] = ghosted_seq.area(jet1);
00690       our_area_4vectors[our_parent1] = ghosted_seq.area_4vector(jet1);
00691 
00692       const PseudoJet & jet2 = gs_jets[gs_history[parent2].jetp_index];
00693       int our_parent2 = _history[hist_index].parent2;
00694       our_areas[our_parent2] = ghosted_seq.area(jet2);
00695       our_area_4vectors[our_parent2] = ghosted_seq.area_4vector(jet2);
00696     }
00697 
00698   }
00699 
00700   // now add unclustered ghosts to the relevant list so that we can
00701   // calculate empty area later.
00702   vector<PseudoJet> unclust = ghosted_seq.unclustered_particles();
00703   for (unsigned iu = 0; iu < unclust.size();  iu++) {
00704     if (ghosted_seq.is_pure_ghost(unclust[iu])) {
00705       double area = ghosted_seq.area(unclust[iu]);
00706       _unclustered_ghosts.push_back(GhostJet(unclust[iu],area));
00707     }
00708   }
00709 
00710   _average_area  += our_areas; 
00711   _average_area2 += our_areas*our_areas; 
00712 
00713   //_average_area_4vector += our_area_4vectors;
00714   // Use the proper recombination scheme when averaging the area_4vectors
00715   // over multiple ghost runs (i.e. the repeat stage);
00716   for (unsigned i = 0; i < _average_area_4vector.size(); i++) {
00717     _jet_def.recombiner()->plus_equal(_average_area_4vector[i],
00718                                        our_area_4vectors[i]);
00719   }
00720 }

bool fastjet::ClusterSequenceActiveArea::has_dangerous_particles (  )  const [inline, protected]

returns true if there are any particles whose transverse momentum if so low that there's a risk of the ghosts having modified the clustering sequence

Definition at line 144 of file ClusterSequenceActiveArea.hh.

00144 {return _has_dangerous_particles;}

void fastjet::ClusterSequenceActiveArea::_extract_tree ( vector< int > &   )  const [private]

routine for extracting the tree in an order that will be independent of any degeneracies in the recombination sequence that don't affect the composition of the final jets

void fastjet::ClusterSequenceActiveArea::_extract_tree_children ( int  pos,
valarray< bool > &  ,
const valarray< int > &  ,
vector< int > &   
) const [private]

do the part of the extraction associated with pos, working through its children and their parents

void fastjet::ClusterSequenceActiveArea::_extract_tree_parents ( int  pos,
valarray< bool > &  ,
const valarray< int > &  ,
vector< int > &   
) const [private]

do the part of the extraction associated with the parents of pos.

void fastjet::ClusterSequenceActiveArea::_throw_unless_jets_have_same_perp_or_E ( const PseudoJet jet,
const PseudoJet refjet,
double  tolerance,
const ClusterSequenceActiveAreaExplicitGhosts jets_ghosted_seq 
) const [private]

check if two jets have the same momentum to within the tolerance (and if pt's are not the same we're forgiving and look to see if the energy is the same)

Definition at line 726 of file ClusterSequenceActiveArea.cc.

References fastjet::PseudoJet::E(), fastjet::ClusterSequenceActiveAreaExplicitGhosts::has_dangerous_particles(), fastjet::PseudoJet::perp2(), fastjet::PseudoJet::px(), fastjet::PseudoJet::py(), and fastjet::PseudoJet::pz().

Referenced by _transfer_areas().

00731         {
00732 
00733   if (abs(jet.perp2()-refjet.perp2()) > 
00734       tolerance*max(jet.perp2(),refjet.perp2())
00735       && abs(jet.E()-refjet.E()) > tolerance*max(jet.E(),refjet.E())) {
00736     ostringstream ostr;
00737     ostr << "Could not match clustering sequence for an inclusive/exclusive jet when reconstructing areas" << endl;
00738     ostr << "  Ref-Jet: "
00739          << refjet.px() << " " 
00740          << refjet.py() << " " 
00741          << refjet.pz() << " " 
00742          << refjet.E() << endl;
00743     ostr << "  New-Jet: "
00744          << jet.px() << " " 
00745          << jet.py() << " " 
00746          << jet.pz() << " " 
00747          << jet.E() << endl;
00748     if (jets_ghosted_seq.has_dangerous_particles()) {
00749       ostr << "  NB: some particles have pt too low wrt ghosts -- this may be the cause" << endl;}
00750     //ostr << jet.perp() << " " << refjet.perp() << " "
00751     //     << jet.perp() - refjet.perp() << endl;
00752     throw Error(ostr.str());
00753   }
00754 }


Member Data Documentation

valarray<double> fastjet::ClusterSequenceActiveArea::_average_area [protected]

child classes benefit from having these at their disposal

Definition at line 138 of file ClusterSequenceActiveArea.hh.

Referenced by fastjet::ClusterSequencePassiveArea::_initialise_and_run_PA(), _postprocess_AA(), _resize_and_zero_AA(), fastjet::ClusterSequence1GhostPassiveArea::_run_1GPA(), and _transfer_areas().

valarray<double> fastjet::ClusterSequenceActiveArea::_average_area2 [protected]

Definition at line 138 of file ClusterSequenceActiveArea.hh.

Referenced by _postprocess_AA(), _resize_and_zero_AA(), fastjet::ClusterSequence1GhostPassiveArea::_run_1GPA(), and _transfer_areas().

valarray<PseudoJet> fastjet::ClusterSequenceActiveArea::_average_area_4vector [protected]

Definition at line 139 of file ClusterSequenceActiveArea.hh.

Referenced by fastjet::ClusterSequencePassiveArea::_initialise_and_run_PA(), _postprocess_AA(), _resize_and_zero_AA(), and _transfer_areas().

double fastjet::ClusterSequenceActiveArea::_non_jet_area [private]

Definition at line 149 of file ClusterSequenceActiveArea.hh.

Referenced by _postprocess_AA(), _resize_and_zero_AA(), _transfer_areas(), and pt_per_unit_area().

double fastjet::ClusterSequenceActiveArea::_non_jet_area2 [private]

Definition at line 149 of file ClusterSequenceActiveArea.hh.

Referenced by _postprocess_AA(), _resize_and_zero_AA(), and _transfer_areas().

double fastjet::ClusterSequenceActiveArea::_non_jet_number [private]

Definition at line 149 of file ClusterSequenceActiveArea.hh.

Referenced by _postprocess_AA(), _resize_and_zero_AA(), _transfer_areas(), and pt_per_unit_area().

double fastjet::ClusterSequenceActiveArea::_maxrap_for_area [private]

Definition at line 151 of file ClusterSequenceActiveArea.hh.

Referenced by _initialise_AA().

double fastjet::ClusterSequenceActiveArea::_safe_rap_for_area [private]

Definition at line 152 of file ClusterSequenceActiveArea.hh.

Referenced by _initialise_AA(), _transfer_areas(), parabolic_pt_per_unit_area(), and pt_per_unit_area().

bool fastjet::ClusterSequenceActiveArea::_has_dangerous_particles [private]

Definition at line 154 of file ClusterSequenceActiveArea.hh.

Referenced by _initialise_AA(), and _run_AA().

int fastjet::ClusterSequenceActiveArea::_area_spec_repeat [private]

since we are playing nasty games with seeds, we should warn the user a few times

Definition at line 182 of file ClusterSequenceActiveArea.hh.

Referenced by _initialise_AA(), empty_area(), and n_empty_jets().

std::vector<GhostJet> fastjet::ClusterSequenceActiveArea::_ghost_jets [private]

Definition at line 191 of file ClusterSequenceActiveArea.hh.

Referenced by _transfer_areas(), empty_area(), and n_empty_jets().

std::vector<GhostJet> fastjet::ClusterSequenceActiveArea::_unclustered_ghosts [private]

Definition at line 192 of file ClusterSequenceActiveArea.hh.

Referenced by _transfer_areas(), and empty_area().


The documentation for this class was generated from the following files:
Generated on Tue Dec 18 17:05:50 2007 for fastjet by  doxygen 1.5.2