00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef __FASTJET_PSEUDOJET_HH__
00033 #define __FASTJET_PSEUDOJET_HH__
00034
00035 #include<valarray>
00036 #include<vector>
00037 #include<cassert>
00038 #include<cmath>
00039 #include<iostream>
00040 #include "fastjet/internal/numconsts.hh"
00041 #include "fastjet/internal/IsBase.hh"
00042 #include "fastjet/internal/DerivedPseudoJetHelper.hh"
00043 #include "fastjet/SharedPtr.hh"
00044 #include "fastjet/Error.hh"
00045 #include "fastjet/ClusterSequenceWrapper.hh"
00046
00047 FASTJET_BEGIN_NAMESPACE
00048
00049
00050
00053 const double MaxRap = 1e5;
00054
00056 const double pseudojet_invalid_phi = -100.0;
00057
00058
00059 class ClusterSequenceAreaBase;
00060
00065 class PseudoJet {
00066
00067 public:
00068
00070
00072 PseudoJet() {};
00074 PseudoJet(const double px, const double py, const double pz, const double E);
00076 template <class L> PseudoJet(const L & some_four_vector) ;
00077
00079 virtual ~PseudoJet(){};
00080
00081
00082
00084
00085
00086 inline double E() const {return _E;}
00087 inline double e() const {return _E;}
00088 inline double px() const {return _px;}
00089 inline double py() const {return _py;}
00090 inline double pz() const {return _pz;}
00091
00093 inline double phi() const {return phi_02pi();}
00094
00096 inline double phi_std() const {
00097 _ensure_valid_rap_phi();
00098 return _phi > pi ? _phi-twopi : _phi;}
00099
00101 inline double phi_02pi() const {
00102 _ensure_valid_rap_phi();
00103 return _phi;
00104 }
00105
00108 inline double rap() const {
00109 _ensure_valid_rap_phi();
00110 return _rap;
00111 }
00112
00114 inline double rapidity() const {return rap();}
00115
00118 double pseudorapidity() const;
00119 double eta() const {return pseudorapidity();}
00120
00122 inline double kt2() const {return _kt2;}
00124 inline double perp2() const {return _kt2;}
00126 inline double perp() const {return sqrt(_kt2);}
00128 inline double m2() const {return (_E+_pz)*(_E-_pz)-_kt2;}
00130 inline double mperp2() const {return (_E+_pz)*(_E-_pz);}
00132 inline double mperp() const {return sqrt(std::abs(mperp2()));}
00135 inline double m() const;
00137 inline double modp2() const {return _kt2+_pz*_pz;}
00139 inline double Et() const {return (_kt2==0) ? 0.0 : _E/sqrt(1.0+_pz*_pz/_kt2);}
00141 inline double Et2() const {return (_kt2==0) ? 0.0 : _E*_E/(1.0+_pz*_pz/_kt2);}
00142
00144 double operator () (int i) const ;
00146 inline double operator [] (int i) const { return (*this)(i); };
00147
00148
00149
00151 double kt_distance(const PseudoJet & other) const;
00152
00154 double plain_distance(const PseudoJet & other) const;
00157 inline double squared_distance(const PseudoJet & other) const {
00158 return plain_distance(other);}
00159
00162 double delta_phi_to(const PseudoJet & other) const;
00163
00165
00166
00167
00168
00170 inline double beam_distance() const {return _kt2;}
00171
00174 std::valarray<double> four_mom() const;
00175
00176
00177
00178
00179 enum { X=0, Y=1, Z=2, T=3, NUM_COORDINATES=4, SIZE=NUM_COORDINATES };
00180
00181
00182
00184
00185
00188 PseudoJet & boost(const PseudoJet & prest);
00191 PseudoJet & unboost(const PseudoJet & prest);
00192
00193 void operator*=(double);
00194 void operator/=(double);
00195 void operator+=(const PseudoJet &);
00196 void operator-=(const PseudoJet &);
00197
00200 inline void reset(double px, double py, double pz, double E);
00201
00206 inline void reset(const PseudoJet & psjet) {
00207 (*this) = psjet;
00208 }
00209
00213 template <class L> inline void reset(const L & some_four_vector) {
00214 reset(some_four_vector[0], some_four_vector[1],
00215 some_four_vector[2], some_four_vector[3]);
00216 }
00217
00218
00219
00220
00227
00228
00229
00231 inline int user_index() const {return _user_index;}
00234 inline void set_user_index(const int index) {_user_index = index;}
00235
00236
00237
00238
00245
00246
00257 class ExtraInfo{
00258 public:
00259
00260 ExtraInfo(){};
00261
00262
00263
00264 virtual ~ExtraInfo(){};
00265 };
00266
00269 class InexistentExtraInfo : public Error {
00270 public:
00271 InexistentExtraInfo();
00272 };
00273
00275 const ExtraInfo* extra_info() const{
00276 if (!_extra_info()) return NULL;
00277 return _extra_info.get();
00278 }
00279
00287 void set_extra_info(ExtraInfo * extra_info_in) {
00288 _extra_info.reset(extra_info_in);
00289 }
00290
00296 template<class L>
00297 const L & extra_info_cast() const{
00298 if (_extra_info.get() == 0) throw InexistentExtraInfo();
00299 return dynamic_cast<const L &>(* _extra_info.get());
00300 }
00301
00303 SharedPtr<ExtraInfo> & extra_info_shared(){
00304 return _extra_info;
00305 }
00306
00308 const SharedPtr<ExtraInfo> & extra_info_shared() const{
00309 return _extra_info;
00310 }
00311
00312
00313
00314
00321
00322
00325 bool has_associated_cluster_sequence() const;
00326
00329 const ClusterSequence* associated_cluster_sequence() const;
00330
00331
00332
00338
00339
00340
00347 virtual bool has_partner(PseudoJet &partner) const;
00348
00355 virtual bool has_child(PseudoJet &child) const;
00356
00363 virtual bool has_parents(PseudoJet &parent1, PseudoJet &parent2) const;
00364
00370 virtual bool contains(const PseudoJet &constituent) const;
00371
00377 virtual bool is_inside(const PseudoJet &jet) const;
00378
00383 virtual std::vector<PseudoJet> constituents() const;
00384
00396 std::vector<PseudoJet> exclusive_subjets (const double & dcut) const;
00397
00404 int n_exclusive_subjets(const double & dcut) const;
00405
00414 std::vector<PseudoJet> exclusive_subjets (int nsub) const;
00415
00421 double exclusive_subdmerge(int nsub) const;
00422
00429 double exclusive_subdmerge_max(int nsub) const;
00430
00431
00432
00433
00434
00435
00437 virtual bool has_area() const;
00438
00441 virtual double area() const;
00442
00446 virtual double area_error() const;
00447
00450 virtual PseudoJet area_4vector() const;
00451
00454 virtual bool is_pure_ghost() const;
00455
00456
00457
00458
00459
00460
00462
00463
00466 inline int cluster_hist_index() const {return _cluster_hist_index;}
00468 inline void set_cluster_hist_index(const int index) {_cluster_hist_index = index;}
00469
00471 inline int cluster_sequence_history_index() const {
00472 return cluster_hist_index();}
00475 inline void set_cluster_sequence_history_index(const int index) {
00476 set_cluster_hist_index(index);}
00477
00479 void set_associated_csw(const SharedPtr<ClusterSequenceWrapper> &csw){
00480 _associated_csw = csw;
00481 }
00482
00484 const SharedPtr<ClusterSequenceWrapper> & associated_csw() const {
00485 return _associated_csw;
00486 }
00487
00490 const ClusterSequence * validated_cs() const;
00491
00494 const ClusterSequenceAreaBase * validated_csab() const;
00495
00496
00497
00498 private:
00499
00500 double _px,_py,_pz,_E;
00501 mutable double _phi, _rap;
00502 double _kt2;
00503 int _cluster_hist_index, _user_index;
00504
00505 SharedPtr<ClusterSequenceWrapper> _associated_csw;
00506 SharedPtr<ExtraInfo> _extra_info;
00507
00509 void _finish_init();
00511 void _reset_indices();
00512
00515 inline void _ensure_valid_rap_phi() const {
00516 if (_phi == pseudojet_invalid_phi) _set_rap_phi();
00517 }
00518
00520 void _set_rap_phi() const;
00521 };
00522
00523
00524
00525
00526
00527 PseudoJet operator+(const PseudoJet &, const PseudoJet &);
00528 PseudoJet operator-(const PseudoJet &, const PseudoJet &);
00529 PseudoJet operator*(double, const PseudoJet &);
00530 PseudoJet operator*(const PseudoJet &, double);
00531 PseudoJet operator/(const PseudoJet &, double);
00532
00533 inline double dot_product(const PseudoJet & a, const PseudoJet & b) {
00534 return a.E()*b.E() - a.px()*b.px() - a.py()*b.py() - a.pz()*b.pz();
00535 }
00536
00538 bool have_same_momentum(const PseudoJet &, const PseudoJet &);
00539
00541 PseudoJet PtYPhiM(double pt, double y, double phi, double m = 0.0);
00542
00543
00544
00545
00547 std::vector<PseudoJet> sorted_by_pt(const std::vector<PseudoJet> & jets);
00548
00550 std::vector<PseudoJet> sorted_by_rapidity(const std::vector<PseudoJet> & jets);
00551
00553 std::vector<PseudoJet> sorted_by_E(const std::vector<PseudoJet> & jets);
00554
00556 std::vector<PseudoJet> sorted_by_pz(const std::vector<PseudoJet> & jets);
00557
00558
00559
00560
00563 void sort_indices(std::vector<int> & indices,
00564 const std::vector<double> & values);
00565
00570 template<class T> std::vector<T> objects_sorted_by_values(const std::vector<T> & objects,
00571 const std::vector<double> & values);
00572
00578 class IndexedSortHelper {
00579 public:
00580 inline IndexedSortHelper (const std::vector<double> * reference_values) {
00581 _ref_values = reference_values;
00582 };
00583 inline int operator() (const int & i1, const int & i2) const {
00584 return (*_ref_values)[i1] < (*_ref_values)[i2];
00585 };
00586 private:
00587 const std::vector<double> * _ref_values;
00588 };
00589
00590
00591
00593
00594
00595 template <class L> inline PseudoJet::PseudoJet(const L & some_four_vector) {
00596
00597
00598
00599 DerivedPseudoJetHelper<L, IsBaseAndDerived<PseudoJet,L>::value> dpj_helper(some_four_vector);
00600
00601 if (dpj_helper() != NULL){
00602 const PseudoJet *pj = dpj_helper();
00603 reset(*pj);
00604 } else {
00605 reset(some_four_vector);
00606 }
00607 }
00608
00609
00610
00611 inline void PseudoJet::_reset_indices() {
00612 set_cluster_hist_index(-1);
00613 set_user_index(-1);
00614 _associated_csw.reset();
00615 }
00616
00617
00621
00622
00623
00624
00632
00633
00634 inline double PseudoJet::m() const {
00635 double mm = m2();
00636 return mm < 0.0 ? -std::sqrt(-mm) : std::sqrt(mm);
00637 }
00638
00639
00640 inline void PseudoJet::reset(double px, double py, double pz, double E) {
00641 _px = px;
00642 _py = py;
00643 _pz = pz;
00644 _E = E;
00645 _finish_init();
00646 _reset_indices();
00647 }
00648
00649
00650 FASTJET_END_NAMESPACE
00651
00652 #endif // __FASTJET_PSEUDOJET_HH__