LCOV - code coverage report
Current view: top level - PYTHIA8/pythia8210dev/include/Pythia8 - FJcore.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 291 0.3 %
Date: 2016-06-14 17:26:59 Functions: 2 317 0.6 %

          Line data    Source code
       1             : // fjcore -- extracted from FastJet v3.0.5 (http://fastjet.fr)
       2             : //
       3             : // fjcore constitutes a digest of the main FastJet functionality.
       4             : // The files fjcore.hh and fjcore.cc are meant to provide easy access to these
       5             : // core functions, in the form of single files and without the need of a full
       6             : // FastJet installation:
       7             : //
       8             : //     g++ main.cc fjcore.cc
       9             : //
      10             : // with main.cc including fjcore.hh.
      11             : //
      12             : // The results are expected to be identical to those obtained by linking to
      13             : // the full FastJet distribution.
      14             : //
      15             : // NOTE THAT, IN ORDER TO MAKE IT POSSIBLE FOR FJCORE AND THE FULL FASTJET
      16             : // TO COEXIST, THE FORMER USES THE "fjcore" NAMESPACE INSTEAD OF "fastjet".
      17             : //
      18             : // In particular, fjcore provides:
      19             : //
      20             : //   - access to all native pp and ee algorithms, kt, anti-kt, C/A.
      21             : //     For C/A, the NlnN method is available, while anti-kt and kt
      22             : //     are limited to the N^2 one (still the fastest for N < 20k particles)
      23             : //   - access to selectors, for implementing cuts and selections
      24             : //   - access to all functionalities related to pseudojets (e.g. a jet's
      25             : //     structure or user-defined information)
      26             : //
      27             : // Instead, it does NOT provide:
      28             : //
      29             : //   - jet areas functionality
      30             : //   - background estimation
      31             : //   - access to other algorithms via plugins
      32             : //   - interface to CGAL
      33             : //   - fastjet tools, e.g. filters, taggers
      34             : //
      35             : // If these functionalities are needed, the full FastJet installation must be
      36             : // used. The code will be fully compatible, with the sole replacement of the
      37             : // header files and of the fjcore namespace with the fastjet one.
      38             : //
      39             : // fjcore.hh and fjcore.cc are not meant to be human-readable.
      40             : // For documentation, see the full FastJet manual and doxygen at http://fastjet.fr
      41             : //
      42             : // Like FastJet, fjcore is released under the terms of the GNU General Public
      43             : // License version 2 (GPLv2). If you use this code as part of work towards a
      44             : // scientific publication, whether directly or contained within another program
      45             : // (e.g. Delphes, SpartyJet, Rivet, LHC collaboration software frameworks,
      46             : // etc.), you should include a citation to
      47             : //
      48             : //   EPJC72(2012)1896 [arXiv:1111.6097] (FastJet User Manual)
      49             : //   and, optionally, Phys.Lett.B641 (2006) 57 [arXiv:hep-ph/0512210]
      50             : //
      51             : // Copyright (c) 2005-2013, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
      52             : //
      53             : //----------------------------------------------------------------------
      54             : // This file is part of FastJet.
      55             : //
      56             : //  FastJet is free software; you can redistribute it and/or modify
      57             : //  it under the terms of the GNU General Public License as published by
      58             : //  the Free Software Foundation; either version 2 of the License, or
      59             : //  (at your option) any later version.
      60             : //
      61             : //  The algorithms that underlie FastJet have required considerable
      62             : //  development and are described in hep-ph/0512210. If you use
      63             : //  FastJet as part of work towards a scientific publication, please
      64             : //  include a citation to the FastJet paper.
      65             : //
      66             : //  FastJet is distributed in the hope that it will be useful,
      67             : //  but WITHOUT ANY WARRANTY; without even the implied warranty of
      68             : //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      69             : //  GNU General Public License for more details.
      70             : //
      71             : //  You should have received a copy of the GNU General Public License
      72             : //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
      73             : //----------------------------------------------------------------------
      74             : //
      75             : #ifndef __FJCORE_HH__
      76             : #define __FJCORE_HH__
      77             : #define __FJCORE__   // remove all the non-core code (a safekeeper)
      78             : #define __FJCORE_DROP_CGAL    // disable CGAL support
      79             : #ifndef __FJCORE_FASTJET_BASE_HH__
      80             : #define __FJCORE_FASTJET_BASE_HH__
      81             : #define FJCORE_BEGIN_NAMESPACE namespace fjcore {
      82             : #define FJCORE_END_NAMESPACE   }
      83             : #endif // __FJCORE_FASTJET_BASE_HH__
      84             : #ifndef __FJCORE_NUMCONSTS__
      85             : #define __FJCORE_NUMCONSTS__
      86             : FJCORE_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
      87             : const double pi = 3.141592653589793238462643383279502884197;
      88             : const double twopi = 6.283185307179586476925286766559005768394;
      89             : const double pisq  = 9.869604401089358618834490999876151135314;
      90             : const double zeta2 = 1.644934066848226436472415166646025189219;
      91             : const double zeta3 = 1.202056903159594285399738161511449990765;
      92             : const double eulergamma = 0.577215664901532860606512090082402431042;
      93             : const double ln2   = 0.693147180559945309417232121458176568076;
      94             : FJCORE_END_NAMESPACE
      95             : #endif // __FJCORE_NUMCONSTS__
      96             : #ifndef __FJCORE_INTERNAL_IS_BASE_HH__
      97             : #define __FJCORE_INTERNAL_IS_BASE_HH__
      98             : FJCORE_BEGIN_NAMESPACE
      99             : template<typename T, T _t>
     100             : struct integral_type{
     101             :   static const T value = _t;         ///< the value (only member carrying info)
     102             :   typedef T value_type;              ///< a typedef for the type T
     103             :   typedef integral_type<T,_t> type;  ///< a typedef for the whole structure
     104             : };
     105             : template<typename T, T _t>
     106             : const T integral_type<T, _t>::value;
     107             : typedef integral_type<bool, true>  true_type;  ///< the bool 'true'  value promoted to a type
     108             : typedef integral_type<bool, false> false_type; ///< the bool 'false' value promoted to a type
     109             : typedef char (&__yes_type)[1]; //< the yes type
     110             : typedef char (&__no_type) [2]; //< the no type
     111             : template<typename B, typename D>
     112             : struct __inheritance_helper{
     113             : #if !((_MSC_VER !=0 ) && (_MSC_VER == 1310))   // MSVC 7.1
     114             :   template <typename T>
     115             :   static __yes_type check_sig(D const volatile *, T);
     116             : #else
     117             :   static __yes_type check_sig(D const volatile *, long);
     118             : #endif
     119             :   static __no_type  check_sig(B const volatile *, int);
     120             : };
     121             : template<typename B, typename D>
     122             : struct IsBaseAndDerived{
     123             : #if ((_MSC_FULL_VER != 0) && (_MSC_FULL_VER >= 140050000))
     124             : #pragma warning(push)
     125             : #pragma warning(disable:6334)
     126             : #endif
     127             :   struct Host{
     128             : #if !((_MSC_VER !=0 ) && (_MSC_VER == 1310))
     129             :     operator B const volatile *() const;
     130             : #else
     131             :     operator B const volatile * const&() const;
     132             : #endif
     133             :     operator D const volatile *();
     134             :   };
     135             :   static const bool value = ((sizeof(B)!=0) &&
     136             :                              (sizeof(D)!=0) &&
     137             :                              (sizeof(__inheritance_helper<B,D>::check_sig(Host(), 0)) == sizeof(__yes_type)));
     138             : #if ((_MSC_FULL_VER != 0) && (_MSC_FULL_VER >= 140050000))
     139             : #pragma warning(pop)
     140             : #endif
     141             : };
     142             : template<class B, class D>
     143             : B* cast_if_derived(D* d){
     144             :   return IsBaseAndDerived<B,D>::value ? (B*)(d) : 0;
     145             : }
     146             : FJCORE_END_NAMESPACE
     147             : #endif  // __IS_BASE_OF_HH__
     148             : #ifndef _INCLUDE_FJCORE_CONFIG_AUTO_H
     149             : #define _INCLUDE_FJCORE_CONFIG_AUTO_H 1
     150             : #ifndef FJCORE_HAVE_DLFCN_H
     151             : #define FJCORE_HAVE_DLFCN_H  1
     152             : #endif
     153             : #ifndef FJCORE_HAVE_EXECINFO_H
     154             : #define FJCORE_HAVE_EXECINFO_H  1
     155             : #endif
     156             : #ifndef FJCORE_HAVE_INTTYPES_H
     157             : #define FJCORE_HAVE_INTTYPES_H  1
     158             : #endif
     159             : #ifndef FJCORE_HAVE_LIBM
     160             : #define FJCORE_HAVE_LIBM  1
     161             : #endif
     162             : #ifndef FJCORE_HAVE_MEMORY_H
     163             : #define FJCORE_HAVE_MEMORY_H  1
     164             : #endif
     165             : #ifndef FJCORE_HAVE_STDINT_H
     166             : #define FJCORE_HAVE_STDINT_H  1
     167             : #endif
     168             : #ifndef FJCORE_HAVE_STDLIB_H
     169             : #define FJCORE_HAVE_STDLIB_H  1
     170             : #endif
     171             : #ifndef FJCORE_HAVE_STRINGS_H
     172             : #define FJCORE_HAVE_STRINGS_H  1
     173             : #endif
     174             : #ifndef FJCORE_HAVE_STRING_H
     175             : #define FJCORE_HAVE_STRING_H  1
     176             : #endif
     177             : #ifndef FJCORE_HAVE_SYS_STAT_H
     178             : #define FJCORE_HAVE_SYS_STAT_H  1
     179             : #endif
     180             : #ifndef FJCORE_HAVE_SYS_TYPES_H
     181             : #define FJCORE_HAVE_SYS_TYPES_H  1
     182             : #endif
     183             : #ifndef FJCORE_HAVE_UNISTD_H
     184             : #define FJCORE_HAVE_UNISTD_H  1
     185             : #endif
     186             : #ifndef FJCORE_LT_OBJDIR
     187             : #define FJCORE_LT_OBJDIR  ".libs/"
     188             : #endif
     189             : #ifndef FJCORE_PACKAGE
     190             : #define FJCORE_PACKAGE  "fastjet"
     191             : #endif
     192             : #ifndef FJCORE_PACKAGE_BUGREPORT
     193             : #define FJCORE_PACKAGE_BUGREPORT  ""
     194             : #endif
     195             : #ifndef FJCORE_PACKAGE_NAME
     196             : #define FJCORE_PACKAGE_NAME  "FastJet"
     197             : #endif
     198             : #ifndef FJCORE_PACKAGE_STRING
     199             : #define FJCORE_PACKAGE_STRING  "FastJet 3.0.5"
     200             : #endif
     201             : #ifndef FJCORE_PACKAGE_TARNAME
     202             : #define FJCORE_PACKAGE_TARNAME  "fastjet"
     203             : #endif
     204             : #ifndef FJCORE_PACKAGE_VERSION
     205             : #define FJCORE_PACKAGE_VERSION  "3.0.5"
     206             : #endif
     207             : #ifndef FJCORE_STDC_HEADERS
     208             : #define FJCORE_STDC_HEADERS  1
     209             : #endif
     210             : #ifndef FJCORE_VERSION
     211             : #define FJCORE_VERSION  "3.0.5"
     212             : #endif
     213             : #endif
     214             : #ifndef __FJCORE_CONFIG_H__
     215             : #define __FJCORE_CONFIG_H__
     216             : #endif // __FJCORE_CONFIG_H__
     217             : #ifndef __FJCORE_SHARED_PTR_HH__
     218             : #define __FJCORE_SHARED_PTR_HH__
     219             : #include <cstdlib>  // for NULL!!!
     220             : #ifdef __FJCORE_USETR1SHAREDPTR
     221             : #include <tr1/memory>
     222             : #endif // __FJCORE_USETR1SHAREDPTR
     223             : FJCORE_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
     224             : #ifdef __FJCORE_USETR1SHAREDPTR
     225             : template<class T>
     226             : class SharedPtr : public std::tr1::shared_ptr<T> {
     227             : public:
     228             :   SharedPtr() : std::tr1::shared_ptr<T>() {}
     229             :   SharedPtr(T * t) : std::tr1::shared_ptr<T>(t) {}
     230             :   SharedPtr(const SharedPtr<T> & t) : std::tr1::shared_ptr<T>(t) {}
     231             :   inline operator bool() const {return (this->get()!=NULL);}
     232             :   T* operator ()() const{
     233             :     return this->get(); // automatically returns NULL when out-of-scope
     234             :   }
     235             : };
     236             : #else // __FJCORE_USETR1SHAREDPTR
     237             : template<class T>
     238             : class SharedPtr{
     239             : public:
     240             :   class __SharedCountingPtr;
     241           0 :   SharedPtr() : _ptr(NULL){}
     242           0 :   template<class Y> explicit SharedPtr(Y* ptr){
     243           0 :     _ptr = new __SharedCountingPtr(ptr);
     244           0 :   }
     245           0 :   SharedPtr(SharedPtr const & share) : _ptr(share._get_container()){
     246           0 :     if (_ptr!=NULL) ++(*_ptr);
     247           0 :   }
     248           0 :   ~SharedPtr(){
     249           0 :     if (_ptr==NULL) return;
     250           0 :     _decrease_count();
     251           0 :   }
     252             :   void reset(){
     253           0 :     SharedPtr().swap(*this);
     254           0 :   }
     255             :   template<class Y> void reset(Y * ptr){
     256           0 :     SharedPtr(ptr).swap(*this);
     257           0 :   }
     258             :   template<class Y> void reset(SharedPtr<Y> const & share){
     259           0 :     if (_ptr!=NULL){
     260           0 :       if (_ptr == share._get_container()) return;
     261           0 :       _decrease_count();
     262           0 :     }
     263           0 :     _ptr = share._get_container();  // Note: automatically set it to NULL if share is empty
     264           0 :     if (_ptr!=NULL) ++(*_ptr);
     265           0 :   }
     266             :   SharedPtr& operator=(SharedPtr const & share){
     267           0 :     reset(share);
     268           0 :     return *this;
     269             :   }
     270             :   template<class Y> SharedPtr& operator=(SharedPtr<Y> const & share){
     271             :     reset(share);
     272             :     return *this;
     273             :   }
     274             :   T* operator ()() const{
     275           0 :     if (_ptr==NULL) return NULL;
     276           0 :     return _ptr->get(); // automatically returns NULL when out-of-scope
     277           0 :   }
     278             :   inline T& operator*() const{
     279             :     return *(_ptr->get());
     280             :   }
     281             :   inline T* operator->() const{
     282           0 :     if (_ptr==NULL) return NULL;
     283           0 :     return _ptr->get();
     284           0 :   }
     285             :   inline T* get() const{
     286           0 :     if (_ptr==NULL) return NULL;
     287           0 :     return _ptr->get();
     288           0 :   }
     289             :   inline bool unique() const{
     290           0 :     return (use_count()==1);
     291             :   }
     292             :   inline long use_count() const{
     293           0 :     if (_ptr==NULL) return 0;
     294           0 :     return _ptr->use_count(); // automatically returns NULL when out-of-scope
     295           0 :   }
     296             :   inline operator bool() const{
     297             :     return (get()!=NULL);
     298             :   }
     299             :   inline void swap(SharedPtr & share){
     300           0 :     __SharedCountingPtr* share_container = share._ptr;
     301           0 :     share._ptr = _ptr;
     302           0 :     _ptr = share_container;
     303           0 :   }
     304             :   void set_count(const long & count){
     305           0 :     if (_ptr==NULL) return;
     306           0 :     _ptr->set_count(count);
     307           0 :   }
     308             :   class __SharedCountingPtr{
     309             :   public:
     310             :     __SharedCountingPtr() : _ptr(NULL), _count(0){}
     311           0 :     template<class Y> explicit __SharedCountingPtr(Y* ptr) : _ptr(ptr), _count(1){}
     312           0 :     ~__SharedCountingPtr(){
     313           0 :       if (_ptr!=NULL){ delete _ptr;}
     314           0 :     }
     315           0 :     inline T* get() const {return _ptr;}
     316           0 :     inline long use_count() const {return _count;}
     317           0 :     inline long operator++(){return ++_count;}
     318             :     inline long operator--(){return --_count;}
     319             :     inline long operator++(int){return _count++;}
     320           0 :     inline long operator--(int){return _count--;}
     321             :     void set_count(const long & count){
     322           0 :       _count = count;
     323           0 :     }
     324             :   private:
     325             :     T *_ptr;              ///< the pointer we're counting the references to
     326             :     long _count;  ///< the number of references
     327             :   };
     328             : private:
     329             :   inline __SharedCountingPtr* _get_container() const{
     330           0 :     return _ptr;
     331             :   }
     332             :   void _decrease_count(){
     333           0 :     (*_ptr)--;
     334           0 :     if (_ptr->use_count()==0)
     335           0 :       delete _ptr; // that automatically deletes the object itself
     336           0 :   }
     337             :   __SharedCountingPtr *_ptr;
     338             : };
     339             : template<class T,class U>
     340             : inline bool operator==(SharedPtr<T> const & t, SharedPtr<U> const & u){
     341             :   return t.get() == u.get();
     342             : }
     343             : template<class T,class U>
     344             : inline bool operator!=(SharedPtr<T> const & t, SharedPtr<U> const & u){
     345             :   return t.get() != u.get();
     346             : }
     347             : template<class T,class U>
     348             : inline bool operator<(SharedPtr<T> const & t, SharedPtr<U> const & u){
     349             :   return t.get() < u.get();
     350             : }
     351             : template<class T>
     352             : inline void swap(SharedPtr<T> & a, SharedPtr<T> & b){
     353             :   return a.swap(b);
     354             : }
     355             : template<class T>
     356             : inline T* get_pointer(SharedPtr<T> const & t){
     357             :   return t.get();
     358             : }
     359             : #endif // __FJCORE_USETR1SHAREDPTR
     360             : FJCORE_END_NAMESPACE      // defined in fastjet/internal/base.hh
     361             : #endif   // __FJCORE_SHARED_PTR_HH__
     362             : #ifndef __FJCORE_ERROR_HH__
     363             : #define __FJCORE_ERROR_HH__
     364             : #include<iostream>
     365             : #include<string>
     366             : FJCORE_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
     367             : class Error {
     368             : public:
     369             :   Error() {}
     370             :   Error(const std::string & message);
     371           0 :   virtual ~Error() {}
     372             :   std::string message() const {return _message;}
     373             :   static void set_print_errors(bool print_errors) {_print_errors = print_errors;}
     374             :   static void set_print_backtrace(bool enabled) {_print_backtrace = enabled;}
     375             :   static void set_default_stream(std::ostream * ostr) {
     376             :     _default_ostr = ostr;
     377             :   }
     378             : private:
     379             :   std::string _message;                ///< error message
     380             :   static bool _print_errors;           ///< do we print anything?
     381             :   static bool _print_backtrace;        ///< do we print the backtrace?
     382             :   static std::ostream * _default_ostr; ///< the output stream (cerr if not set)
     383             : };
     384             : FJCORE_END_NAMESPACE
     385             : #endif // __FJCORE_ERROR_HH__
     386             : #ifndef __FJCORE_LIMITEDWARNING_HH__
     387             : #define __FJCORE_LIMITEDWARNING_HH__
     388             : #include <iostream>
     389             : #include <string>
     390             : #include <list>
     391             : FJCORE_BEGIN_NAMESPACE
     392             : class LimitedWarning {
     393             : public:
     394          12 :   LimitedWarning() : _max_warn(_max_warn_default), _n_warn_so_far(0), _this_warning_summary(0) {}
     395             :   LimitedWarning(int max_warn) : _max_warn(max_warn), _n_warn_so_far(0), _this_warning_summary(0) {}
     396             :   void warn(const std::string & warning);
     397             :   void warn(const std::string & warning, std::ostream * ostr);
     398             :   static void set_default_stream(std::ostream * ostr) {
     399             :     _default_ostr = ostr;
     400             :   }
     401             :   static void set_default_max_warn(int max_warn) {
     402             :     _max_warn_default = max_warn;
     403             :   }
     404             :   static std::string summary();
     405             : private:
     406             :   int _max_warn, _n_warn_so_far;
     407             :   static int _max_warn_default;
     408             :   static std::ostream * _default_ostr;
     409             :   typedef std::pair<std::string, unsigned int> Summary;
     410             :   static std::list< Summary > _global_warnings_summary;
     411             :   Summary * _this_warning_summary;
     412             : };
     413             : FJCORE_END_NAMESPACE
     414             : #endif // __FJCORE_LIMITEDWARNING_HH__
     415             : #ifndef __FJCORE_PSEUDOJET_STRUCTURE_BASE_HH__
     416             : #define __FJCORE_PSEUDOJET_STRUCTURE_BASE_HH__
     417             : #include <vector>
     418             : #include <string>
     419             : FJCORE_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
     420             : class PseudoJet;
     421             : class ClusterSequence;
     422             : class PseudoJetStructureBase{
     423             : public:
     424           0 :   PseudoJetStructureBase(){};
     425           0 :   virtual ~PseudoJetStructureBase(){};
     426           0 :   virtual std::string description() const{ return "PseudoJet with an unknown structure"; }
     427           0 :   virtual bool has_associated_cluster_sequence() const { return false;}
     428             :   virtual const ClusterSequence* associated_cluster_sequence() const;
     429           0 :   virtual bool has_valid_cluster_sequence() const {return false;}
     430             :   virtual const ClusterSequence * validated_cs() const;
     431             :   virtual bool has_partner(const PseudoJet &reference, PseudoJet &partner) const;
     432             :   virtual bool has_child(const PseudoJet &reference, PseudoJet &child) const;
     433             :   virtual bool has_parents(const PseudoJet &reference, PseudoJet &parent1, PseudoJet &parent2) const;
     434             :   virtual bool object_in_jet(const PseudoJet &reference, const PseudoJet &jet) const;
     435           0 :   virtual bool has_constituents() const {return false;}
     436             :   virtual std::vector<PseudoJet> constituents(const PseudoJet &reference) const;
     437           0 :   virtual bool has_exclusive_subjets() const {return false;}
     438             :   virtual std::vector<PseudoJet> exclusive_subjets(const PseudoJet &reference, const double & dcut) const;
     439             :   virtual int n_exclusive_subjets(const PseudoJet &reference, const double & dcut) const;
     440             :   virtual std::vector<PseudoJet> exclusive_subjets_up_to (const PseudoJet &reference, int nsub) const;
     441             :   virtual double exclusive_subdmerge(const PseudoJet &reference, int nsub) const;
     442             :   virtual double exclusive_subdmerge_max(const PseudoJet &reference, int nsub) const;
     443             :   virtual bool has_pieces(const PseudoJet & /* reference */) const {
     444           0 :     return false;}
     445             :   virtual std::vector<PseudoJet> pieces(const PseudoJet & /* reference */
     446             :                                         ) const;
     447             : };
     448             : FJCORE_END_NAMESPACE
     449             : #endif  //  __FJCORE_PSEUDOJET_STRUCTURE_BASE_HH__
     450             : #ifndef __FJCORE_PSEUDOJET_HH__
     451             : #define __FJCORE_PSEUDOJET_HH__
     452             : #include<valarray>
     453             : #include<vector>
     454             : #include<cassert>
     455             : #include<cmath>
     456             : #include<iostream>
     457             : FJCORE_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
     458             : const double MaxRap = 1e5;
     459             : const double pseudojet_invalid_phi = -100.0;
     460             : const double pseudojet_invalid_rap = -1e200;
     461           0 : class PseudoJet {
     462             :  public:
     463           0 :   PseudoJet() : _px(0), _py(0), _pz(0), _E(0) {_finish_init(); _reset_indices();}
     464             :   PseudoJet(const double px, const double py, const double pz, const double E);
     465             :   template <class L> PseudoJet(const L & some_four_vector);
     466           0 :   PseudoJet(bool /* dummy */) {}
     467           0 :   virtual ~PseudoJet(){};
     468           0 :   inline double E()   const {return _E;}
     469           0 :   inline double e()   const {return _E;} // like CLHEP
     470           0 :   inline double px()  const {return _px;}
     471           0 :   inline double py()  const {return _py;}
     472           0 :   inline double pz()  const {return _pz;}
     473           0 :   inline double phi() const {return phi_02pi();}
     474             :   inline double phi_std()  const {
     475           0 :     _ensure_valid_rap_phi();
     476           0 :     return _phi > pi ? _phi-twopi : _phi;}
     477             :   inline double phi_02pi() const {
     478           0 :     _ensure_valid_rap_phi();
     479           0 :     return _phi;
     480             :   }
     481             :   inline double rap() const {
     482           0 :     _ensure_valid_rap_phi();
     483           0 :     return _rap;
     484             :   }
     485             :   inline double rapidity() const {return rap();} // like CLHEP
     486             :   double pseudorapidity() const;
     487           0 :   double eta() const {return pseudorapidity();}
     488           0 :   inline double pt2() const {return _kt2;}
     489             :   inline double  pt() const {return sqrt(_kt2);}
     490           0 :   inline double perp2() const {return _kt2;}  // like CLHEP
     491           0 :   inline double  perp() const {return sqrt(_kt2);}    // like CLHEP
     492           0 :   inline double kt2() const {return _kt2;} // for bkwds compatibility
     493           0 :   inline double  m2() const {return (_E+_pz)*(_E-_pz)-_kt2;}
     494             :   inline double  m() const;
     495             :   inline double mperp2() const {return (_E+_pz)*(_E-_pz);}
     496             :   inline double mperp() const {return sqrt(std::abs(mperp2()));}
     497             :   inline double mt2() const {return (_E+_pz)*(_E-_pz);}
     498             :   inline double mt() const {return sqrt(std::abs(mperp2()));}
     499           0 :   inline double modp2() const {return _kt2+_pz*_pz;}
     500             :   inline double modp() const {return sqrt(_kt2+_pz*_pz);}
     501             :   inline double Et() const {return (_kt2==0) ? 0.0 : _E/sqrt(1.0+_pz*_pz/_kt2);}
     502           0 :   inline double Et2() const {return (_kt2==0) ? 0.0 : _E*_E/(1.0+_pz*_pz/_kt2);}
     503             :   double operator () (int i) const ;
     504             :   inline double operator [] (int i) const { return (*this)(i); }; // this too
     505             :   double kt_distance(const PseudoJet & other) const;
     506             :   double plain_distance(const PseudoJet & other) const;
     507             :   inline double squared_distance(const PseudoJet & other) const {
     508           0 :     return plain_distance(other);}
     509             :   inline double delta_R(const PseudoJet & other) const {
     510             :     return sqrt(squared_distance(other));
     511             :   }
     512             :   double delta_phi_to(const PseudoJet & other) const;
     513             :   inline double beam_distance() const {return _kt2;}
     514             :   std::valarray<double> four_mom() const;
     515             :   enum { X=0, Y=1, Z=2, T=3, NUM_COORDINATES=4, SIZE=NUM_COORDINATES };
     516             :   PseudoJet & boost(const PseudoJet & prest);
     517             :   PseudoJet & unboost(const PseudoJet & prest);
     518             :   void operator*=(double);
     519             :   void operator/=(double);
     520             :   void operator+=(const PseudoJet &);
     521             :   void operator-=(const PseudoJet &);
     522             :   inline void reset(double px, double py, double pz, double E);
     523             :   inline void reset(const PseudoJet & psjet) {
     524             :     (*this) = psjet;
     525             :   }
     526             :   template <class L> inline void reset(const L & some_four_vector) {
     527             :     const PseudoJet * pj = fjcore::cast_if_derived<const PseudoJet>(&some_four_vector);
     528             :     if (pj){
     529             :       (*this) = *pj;
     530             :     } else {
     531             :       reset(some_four_vector[0], some_four_vector[1],
     532             :             some_four_vector[2], some_four_vector[3]);
     533             :     }
     534             :   }
     535             :   inline void reset_PtYPhiM(double pt_in, double y_in, double phi_in, double m_in=0.0) {
     536           0 :     reset_momentum_PtYPhiM(pt_in, y_in, phi_in, m_in);
     537           0 :     _reset_indices();
     538           0 :   }
     539             :   inline void reset_momentum(double px, double py, double pz, double E);
     540             :   inline void reset_momentum(const PseudoJet & pj);
     541             :   void reset_momentum_PtYPhiM(double pt, double y, double phi, double m=0.0);
     542             :   template <class L> inline void reset_momentum(const L & some_four_vector) {
     543             :     reset_momentum(some_four_vector[0], some_four_vector[1],
     544             :                    some_four_vector[2], some_four_vector[3]);
     545             :   }
     546             :   void set_cached_rap_phi(double rap, double phi);
     547           0 :   inline int user_index() const {return _user_index;}
     548           0 :   inline void set_user_index(const int index) {_user_index = index;}
     549             :   class UserInfoBase{
     550             :   public:
     551             :     UserInfoBase(){};
     552             :     virtual ~UserInfoBase(){};
     553             :   };
     554           0 :   class InexistentUserInfo : public Error {
     555             :   public:
     556             :     InexistentUserInfo();
     557             :   };
     558             :   void set_user_info(UserInfoBase * user_info_in) {
     559             :     _user_info.reset(user_info_in);
     560             :   }
     561             :   template<class L>
     562             :   const L & user_info() const{
     563             :     if (_user_info.get() == 0) throw InexistentUserInfo();
     564             :     return dynamic_cast<const L &>(* _user_info.get());
     565             :   }
     566             :   bool has_user_info() const{
     567             :     return _user_info.get();
     568             :   }
     569             :   template<class L>
     570             :   bool has_user_info() const{
     571             :     return _user_info.get() && dynamic_cast<const L *>(_user_info.get());
     572             :   }
     573             :   const UserInfoBase * user_info_ptr() const{
     574           0 :     if (!_user_info()) return NULL;
     575           0 :     return _user_info.get();
     576           0 :   }
     577             :   const SharedPtr<UserInfoBase> & user_info_shared_ptr() const{
     578             :     return _user_info;
     579             :   }
     580             :   SharedPtr<UserInfoBase> & user_info_shared_ptr(){
     581             :     return _user_info;
     582             :   }
     583             :   std::string description() const;
     584             :   bool has_associated_cluster_sequence() const;
     585             :   bool has_associated_cs() const {return has_associated_cluster_sequence();}
     586             :   bool has_valid_cluster_sequence() const;
     587             :   bool has_valid_cs() const {return has_valid_cluster_sequence();}
     588             :   const ClusterSequence* associated_cluster_sequence() const;
     589             :   const ClusterSequence* associated_cs() const {return associated_cluster_sequence();}
     590             :   inline const ClusterSequence * validated_cluster_sequence() const {
     591             :     return validated_cs();
     592             :   }
     593             :   const ClusterSequence * validated_cs() const;
     594             :   void set_structure_shared_ptr(const SharedPtr<PseudoJetStructureBase> &structure);
     595             :   bool has_structure() const;
     596             :   const PseudoJetStructureBase* structure_ptr() const;
     597             :   PseudoJetStructureBase* structure_non_const_ptr();
     598             :   const PseudoJetStructureBase* validated_structure_ptr() const;
     599             :   const SharedPtr<PseudoJetStructureBase> & structure_shared_ptr() const;
     600             :   template<typename StructureType>
     601             :   const StructureType & structure() const;
     602             :   template<typename TransformerType>
     603             :   bool has_structure_of() const;
     604             :   template<typename TransformerType>
     605             :   const typename TransformerType::StructureType & structure_of() const;
     606             :   virtual bool has_partner(PseudoJet &partner) const;
     607             :   virtual bool has_child(PseudoJet &child) const;
     608             :   virtual bool has_parents(PseudoJet &parent1, PseudoJet &parent2) const;
     609             :   virtual bool contains(const PseudoJet &constituent) const;
     610             :   virtual bool is_inside(const PseudoJet &jet) const;
     611             :   virtual bool has_constituents() const;
     612             :   virtual std::vector<PseudoJet> constituents() const;
     613             :   virtual bool has_exclusive_subjets() const;
     614             :   std::vector<PseudoJet> exclusive_subjets (const double & dcut) const;
     615             :   int n_exclusive_subjets(const double & dcut) const;
     616             :   std::vector<PseudoJet> exclusive_subjets (int nsub) const;
     617             :   std::vector<PseudoJet> exclusive_subjets_up_to (int nsub) const;
     618             :   double exclusive_subdmerge(int nsub) const;
     619             :   double exclusive_subdmerge_max(int nsub) const;
     620             :   virtual bool has_pieces() const;
     621             :   virtual std::vector<PseudoJet> pieces() const;
     622           0 :   inline int cluster_hist_index() const {return _cluster_hist_index;}
     623           0 :   inline void set_cluster_hist_index(const int index) {_cluster_hist_index = index;}
     624             :   inline int cluster_sequence_history_index() const {
     625             :     return cluster_hist_index();}
     626             :   inline void set_cluster_sequence_history_index(const int index) {
     627             :     set_cluster_hist_index(index);}
     628             :  protected:
     629             :   SharedPtr<PseudoJetStructureBase> _structure;
     630             :   SharedPtr<UserInfoBase> _user_info;
     631             :  private:
     632             :   double _px,_py,_pz,_E;
     633             :   mutable double _phi, _rap;
     634             :   double _kt2;
     635             :   int    _cluster_hist_index, _user_index;
     636             :   void _finish_init();
     637             :   void _reset_indices();
     638             :   inline void _ensure_valid_rap_phi() const {
     639           0 :     if (_phi == pseudojet_invalid_phi) _set_rap_phi();
     640           0 :   }
     641             :   void _set_rap_phi() const;
     642             : };
     643             : PseudoJet operator+(const PseudoJet &, const PseudoJet &);
     644             : PseudoJet operator-(const PseudoJet &, const PseudoJet &);
     645             : PseudoJet operator*(double, const PseudoJet &);
     646             : PseudoJet operator*(const PseudoJet &, double);
     647             : PseudoJet operator/(const PseudoJet &, double);
     648             : bool operator==(const PseudoJet &, const PseudoJet &);
     649             : inline bool operator!=(const PseudoJet & a, const PseudoJet & b) {return !(a==b);}
     650             : bool operator==(const PseudoJet & jet, const double val);
     651             : inline bool operator!=(const PseudoJet & a, const double & val) {return !(a==val);}
     652             : inline double dot_product(const PseudoJet & a, const PseudoJet & b) {
     653             :   return a.E()*b.E() - a.px()*b.px() - a.py()*b.py() - a.pz()*b.pz();
     654             : }
     655             : bool have_same_momentum(const PseudoJet &, const PseudoJet &);
     656             : PseudoJet PtYPhiM(double pt, double y, double phi, double m = 0.0);
     657             : std::vector<PseudoJet> sorted_by_pt(const std::vector<PseudoJet> & jets);
     658             : std::vector<PseudoJet> sorted_by_rapidity(const std::vector<PseudoJet> & jets);
     659             : std::vector<PseudoJet> sorted_by_E(const std::vector<PseudoJet> & jets);
     660             : std::vector<PseudoJet> sorted_by_pz(const std::vector<PseudoJet> & jets);
     661             : void sort_indices(std::vector<int> & indices,
     662             :                   const std::vector<double> & values);
     663             : template<class T> std::vector<T> objects_sorted_by_values(const std::vector<T> & objects,
     664             :                                               const std::vector<double> & values);
     665             : class IndexedSortHelper {
     666             : public:
     667           0 :   inline IndexedSortHelper (const std::vector<double> * reference_values) {
     668           0 :     _ref_values = reference_values;
     669           0 :   };
     670             :   inline int operator() (const int & i1, const int & i2) const {
     671           0 :     return  (*_ref_values)[i1] < (*_ref_values)[i2];
     672             :   };
     673             : private:
     674             :   const std::vector<double> * _ref_values;
     675             : };
     676             : template <class L> inline  PseudoJet::PseudoJet(const L & some_four_vector) {
     677             :   reset(some_four_vector);
     678             : }
     679             : inline void PseudoJet::_reset_indices() {
     680           0 :   set_cluster_hist_index(-1);
     681           0 :   set_user_index(-1);
     682           0 :   _structure.reset();
     683           0 :   _user_info.reset();
     684           0 : }
     685             : inline double PseudoJet::m() const {
     686           0 :   double mm = m2();
     687           0 :   return mm < 0.0 ? -std::sqrt(-mm) : std::sqrt(mm);
     688             : }
     689             : inline void PseudoJet::reset(double px_in, double py_in, double pz_in, double E_in) {
     690           0 :   _px = px_in;
     691           0 :   _py = py_in;
     692           0 :   _pz = pz_in;
     693           0 :   _E  = E_in;
     694           0 :   _finish_init();
     695           0 :   _reset_indices();
     696           0 : }
     697             : inline void PseudoJet::reset_momentum(double px_in, double py_in, double pz_in, double E_in) {
     698           0 :   _px = px_in;
     699           0 :   _py = py_in;
     700           0 :   _pz = pz_in;
     701           0 :   _E  = E_in;
     702           0 :   _finish_init();
     703           0 : }
     704             : inline void PseudoJet::reset_momentum(const PseudoJet & pj) {
     705             :   _px  = pj._px ;
     706             :   _py  = pj._py ;
     707             :   _pz  = pj._pz ;
     708             :   _E   = pj._E  ;
     709             :   _phi = pj._phi;
     710             :   _rap = pj._rap;
     711             :   _kt2 = pj._kt2;
     712             : }
     713             : template<typename StructureType>
     714             : const StructureType & PseudoJet::structure() const{
     715             :   return dynamic_cast<const StructureType &>(* validated_structure_ptr());
     716             : }
     717             : template<typename TransformerType>
     718             : bool PseudoJet::has_structure_of() const{
     719             :   if (!_structure()) return false;
     720             :   return dynamic_cast<const typename TransformerType::StructureType *>(_structure.get()) != 0;
     721             : }
     722             : template<typename TransformerType>
     723             : const typename TransformerType::StructureType & PseudoJet::structure_of() const{
     724             :   if (!_structure())
     725             :     throw Error("Trying to access the structure of a PseudoJet without an associated structure");
     726             :   return dynamic_cast<const typename TransformerType::StructureType &>(*_structure);
     727             : }
     728             : PseudoJet join(const std::vector<PseudoJet> & pieces);
     729             : PseudoJet join(const PseudoJet & j1);
     730             : PseudoJet join(const PseudoJet & j1, const PseudoJet & j2);
     731             : PseudoJet join(const PseudoJet & j1, const PseudoJet & j2, const PseudoJet & j3);
     732             : PseudoJet join(const PseudoJet & j1, const PseudoJet & j2, const PseudoJet & j3, const PseudoJet & j4);
     733             : FJCORE_END_NAMESPACE
     734             : #endif // __FJCORE_PSEUDOJET_HH__
     735             : #ifndef __FJCORE_FUNCTION_OF_PSEUDOJET_HH__
     736             : #define __FJCORE_FUNCTION_OF_PSEUDOJET_HH__
     737             : FJCORE_BEGIN_NAMESPACE
     738             : template<typename TOut>
     739             : class FunctionOfPseudoJet{
     740             : public:
     741             :   FunctionOfPseudoJet(){}
     742             :   FunctionOfPseudoJet(const TOut &constant_value);
     743             :   virtual ~FunctionOfPseudoJet(){}
     744             :   virtual std::string description() const{ return "";}
     745             :   virtual TOut result(const PseudoJet &pj) const = 0;
     746             :   TOut operator()(const PseudoJet &pj) const { return result(pj);}
     747             :   std::vector<TOut> operator()(const std::vector<PseudoJet> &pjs) const {
     748           0 :     std::vector<TOut> res(pjs.size());
     749           0 :     for (unsigned int i=0; i<pjs.size(); i++)
     750           0 :       res[i] = result(pjs[i]);
     751             :     return res;
     752           0 :   }
     753             : };
     754             : FJCORE_END_NAMESPACE
     755             : #endif  // __FJCORE_FUNCTION_OF_PSEUDOJET_HH__
     756             : #ifndef __FJCORE_SELECTOR_HH__
     757             : #define __FJCORE_SELECTOR_HH__
     758             : #include <limits>
     759             : #include <cmath>
     760             : FJCORE_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
     761             : class Selector;
     762           0 : class SelectorWorker {
     763             : public:
     764           0 :   virtual ~SelectorWorker() {}
     765             :   virtual bool pass(const PseudoJet & jet) const = 0;
     766             :   virtual void terminator(std::vector<const PseudoJet *> & jets) const {
     767           0 :     for (unsigned i = 0; i < jets.size(); i++) {
     768           0 :       if (jets[i] && !pass(*jets[i])) jets[i] = NULL;
     769             :     }
     770           0 :   }
     771           0 :   virtual bool applies_jet_by_jet() const {return true;}
     772           0 :   virtual std::string description() const {return "missing description";}
     773           0 :   virtual bool takes_reference() const { return false;}
     774             :   virtual void set_reference(const PseudoJet & /*reference*/){
     775           0 :     throw Error("set_reference(...) cannot be used for a selector worker that does not take a reference");
     776           0 :   }
     777             :   virtual SelectorWorker* copy(){
     778           0 :     throw Error("this SelectorWorker has nothing to copy");
     779           0 :   }
     780             :   virtual void get_rapidity_extent(double & rapmin, double & rapmax) const {
     781           0 :     rapmax = std::numeric_limits<double>::infinity();
     782           0 :     rapmin = -rapmax;
     783           0 :   }
     784           0 :   virtual bool is_geometric() const { return false;}
     785             :   virtual bool has_finite_area() const;
     786           0 :   virtual bool has_known_area() const { return false;}
     787             :   virtual double known_area() const{
     788           0 :     throw Error("this selector has no computable area");
     789           0 :   }
     790             : };
     791           0 : class Selector{
     792             : public:
     793             :   Selector() {}
     794           0 :   Selector(SelectorWorker * worker_in) {_worker.reset(worker_in);}
     795           0 :   virtual ~Selector(){}
     796             :   bool pass(const PseudoJet & jet) const {
     797           0 :     if (!validated_worker()->applies_jet_by_jet()) {
     798           0 :       throw Error("Cannot apply this selector to an individual jet");
     799             :     }
     800           0 :     return _worker->pass(jet);
     801           0 :   }
     802             :   bool operator()(const PseudoJet & jet) const {
     803             :     return pass(jet);
     804             :   }
     805             :   unsigned int count(const std::vector<PseudoJet> & jets) const;
     806             :   void sift(const std::vector<PseudoJet> & jets,
     807             :                   std::vector<PseudoJet> & jets_that_pass,
     808             :                   std::vector<PseudoJet> & jets_that_fail) const;
     809             :   bool applies_jet_by_jet() const {
     810           0 :     return validated_worker()->applies_jet_by_jet();
     811             :   }
     812             :   std::vector<PseudoJet> operator()(const std::vector<PseudoJet> & jets) const;
     813             :   virtual void nullify_non_selected(std::vector<const PseudoJet *> & jets) const {
     814           0 :     validated_worker()->terminator(jets);
     815           0 :   }
     816             :   void get_rapidity_extent(double &rapmin, double &rapmax) const {
     817           0 :     return validated_worker()->get_rapidity_extent(rapmin, rapmax);
     818             :   }
     819             :   std::string description() const {
     820           0 :     return validated_worker()->description();
     821             :   }
     822             :   bool is_geometric() const{
     823           0 :     return validated_worker()->is_geometric();
     824             :   }
     825             :   bool has_finite_area() const{
     826             :     return validated_worker()->has_finite_area();
     827             :   }
     828           0 :   const SharedPtr<SelectorWorker> & worker() const {return _worker;}
     829             :   const SelectorWorker* validated_worker() const {
     830           0 :     const SelectorWorker* worker_ptr = _worker.get();
     831           0 :     if (worker_ptr == 0) throw InvalidWorker();
     832           0 :     return worker_ptr;
     833           0 :   }
     834             :   bool takes_reference() const {
     835           0 :     return validated_worker()->takes_reference();
     836             :   }
     837             :   const Selector & set_reference(const PseudoJet &reference){
     838           0 :     if (! validated_worker()->takes_reference()){
     839           0 :       return *this;
     840             :     }
     841           0 :     _copy_worker_if_needed();
     842           0 :     _worker->set_reference(reference);
     843           0 :     return *this;
     844           0 :   }
     845           0 :   class InvalidWorker : public Error {
     846             :   public:
     847           0 :     InvalidWorker() : Error("Attempt to use Selector with no valid underlying worker") {}
     848             :   };
     849             :   class InvalidArea : public Error {
     850             :   public:
     851             :     InvalidArea() : Error("Attempt to obtain area from Selector for which this is not meaningful") {}
     852             :   };
     853             :   Selector & operator &=(const Selector & b);
     854             :   Selector & operator |=(const Selector & b);
     855             : protected:
     856             :   void _copy_worker_if_needed(){
     857           0 :     if (_worker.unique()) return;
     858           0 :     _worker.reset(_worker->copy());
     859           0 :   }
     860             : private:
     861             :   SharedPtr<SelectorWorker> _worker; ///< the underlying worker
     862             : };
     863             : Selector SelectorIdentity();
     864             : Selector operator!(const Selector & s);
     865             : Selector operator ||(const Selector & s1, const Selector & s2);
     866             : Selector operator&&(const Selector & s1, const Selector & s2);
     867             : Selector operator*(const Selector & s1, const Selector & s2);
     868             : Selector SelectorPtMin(double ptmin);                    ///< select objects with pt >= ptmin
     869             : Selector SelectorPtMax(double ptmax);                    ///< select objects with pt <= ptmax
     870             : Selector SelectorPtRange(double ptmin, double ptmax);    ///< select objects with ptmin <= pt <= ptmax
     871             : Selector SelectorEtMin(double Etmin);                    ///< select objects with Et >= Etmin
     872             : Selector SelectorEtMax(double Etmax);                    ///< select objects with Et <= Etmax
     873             : Selector SelectorEtRange(double Etmin, double Etmax);    ///< select objects with Etmin <= Et <= Etmax
     874             : Selector SelectorEMin(double Emin);                      ///< select objects with E >= Emin
     875             : Selector SelectorEMax(double Emax);                      ///< select objects with E <= Emax
     876             : Selector SelectorERange(double Emin, double Emax);       ///< select objects with Emin <= E <= Emax
     877             : Selector SelectorMassMin(double Mmin);                      ///< select objects with Mass >= Mmin
     878             : Selector SelectorMassMax(double Mmax);                      ///< select objects with Mass <= Mmax
     879             : Selector SelectorMassRange(double Mmin, double Mmax);       ///< select objects with Mmin <= Mass <= Mmax
     880             : Selector SelectorRapMin(double rapmin);                  ///< select objects with rap >= rapmin
     881             : Selector SelectorRapMax(double rapmax);                  ///< select objects with rap <= rapmax
     882             : Selector SelectorRapRange(double rapmin, double rapmax); ///< select objects with rapmin <= rap <= rapmax
     883             : Selector SelectorAbsRapMin(double absrapmin);                     ///< select objects with |rap| >= absrapmin
     884             : Selector SelectorAbsRapMax(double absrapmax);                     ///< select objects with |rap| <= absrapmax
     885             : Selector SelectorAbsRapRange(double absrapmin, double absrapmax); ///< select objects with absrapmin <= |rap| <= absrapmax
     886             : Selector SelectorEtaMin(double etamin);                  ///< select objects with eta >= etamin
     887             : Selector SelectorEtaMax(double etamax);                  ///< select objects with eta <= etamax
     888             : Selector SelectorEtaRange(double etamin, double etamax); ///< select objects with etamin <= eta <= etamax
     889             : Selector SelectorAbsEtaMin(double absetamin);                     ///< select objects with |eta| >= absetamin
     890             : Selector SelectorAbsEtaMax(double absetamax);                     ///< select objects with |eta| <= absetamax
     891             : Selector SelectorAbsEtaRange(double absetamin, double absetamax); ///< select objects with absetamin <= |eta| <= absetamax
     892             : Selector SelectorPhiRange(double phimin, double phimax); ///< select objects with phimin <= phi <= phimax
     893             : Selector SelectorRapPhiRange(double rapmin, double rapmax, double phimin, double phimax);
     894             : Selector SelectorNHardest(unsigned int n);
     895             : Selector SelectorCircle(const double & radius);
     896             : Selector SelectorDoughnut(const double & radius_in, const double & radius_out);
     897             : Selector SelectorStrip(const double & half_width);
     898             : Selector SelectorRectangle(const double & half_rap_width, const double & half_phi_width);
     899             : Selector SelectorPtFractionMin(double fraction);
     900             : Selector SelectorIsZero();
     901             : FJCORE_END_NAMESPACE      // defined in fastjet/internal/base.hh
     902             : #endif // __FJCORE_SELECTOR_HH__
     903             : #ifndef __FJCORE_JETDEFINITION_HH__
     904             : #define __FJCORE_JETDEFINITION_HH__
     905             : #include<cassert>
     906             : #include<string>
     907             : #include<memory>
     908             : FJCORE_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
     909             : std::string fastjet_version_string();
     910             : enum Strategy {
     911             :   N2MinHeapTiled   = -4,
     912             :   N2Tiled     = -3,
     913             :   N2PoorTiled = -2,
     914             :   N2Plain     = -1,
     915             :   N3Dumb      =  0,
     916             :   Best        =  1,
     917             :   NlnN        =  2,
     918             :   NlnN3pi     =  3,
     919             :   NlnN4pi     =  4,
     920             :   NlnNCam4pi   = 14,
     921             :   NlnNCam2pi2R = 13,
     922             :   NlnNCam      = 12, // 2piMultD
     923             :   plugin_strategy = 999
     924             : };
     925             : enum JetAlgorithm {
     926             :   kt_algorithm=0,
     927             :   cambridge_algorithm=1,
     928             :   antikt_algorithm=2,
     929             :   genkt_algorithm=3,
     930             :   cambridge_for_passive_algorithm=11,
     931             :   genkt_for_passive_algorithm=13,
     932             :   ee_kt_algorithm=50,
     933             :   ee_genkt_algorithm=53,
     934             :   plugin_algorithm = 99,
     935             :   undefined_jet_algorithm = 999
     936             : };
     937             : typedef JetAlgorithm JetFinder;
     938             : const JetAlgorithm aachen_algorithm = cambridge_algorithm;
     939             : const JetAlgorithm cambridge_aachen_algorithm = cambridge_algorithm;
     940             : enum RecombinationScheme {
     941             :   E_scheme=0,
     942             :   pt_scheme=1,
     943             :   pt2_scheme=2,
     944             :   Et_scheme=3,
     945             :   Et2_scheme=4,
     946             :   BIpt_scheme=5,
     947             :   BIpt2_scheme=6,
     948             :   external_scheme = 99
     949             : };
     950             : class ClusterSequence;
     951           0 : class JetDefinition {
     952             : public:
     953             :   class Plugin;
     954             :   class Recombiner;
     955           0 :   JetDefinition(JetAlgorithm jet_algorithm_in,
     956             :                 double R_in,
     957             :                 RecombinationScheme recomb_scheme_in = E_scheme,
     958           0 :                 Strategy strategy_in = Best) {
     959           0 :     *this = JetDefinition(jet_algorithm_in, R_in, strategy_in, recomb_scheme_in, 1);
     960           0 :   }
     961             :   JetDefinition(JetAlgorithm jet_algorithm_in,
     962             :                 RecombinationScheme recomb_scheme_in = E_scheme,
     963             :                 Strategy strategy_in = Best) {
     964             :     double dummyR = 0.0;
     965             :     *this = JetDefinition(jet_algorithm_in, dummyR, strategy_in, recomb_scheme_in, 0);
     966             :   }
     967             :   JetDefinition(JetAlgorithm jet_algorithm_in,
     968             :                 double R_in,
     969             :                 double xtra_param_in,
     970             :                 RecombinationScheme recomb_scheme_in = E_scheme,
     971             :                 Strategy strategy_in = Best) {
     972             :     *this = JetDefinition(jet_algorithm_in, R_in, strategy_in, recomb_scheme_in, 2);
     973             :     set_extra_param(xtra_param_in);
     974             :   }
     975             :   JetDefinition(JetAlgorithm jet_algorithm_in,
     976             :                 double R_in,
     977             :                 const Recombiner * recombiner_in,
     978             :                 Strategy strategy_in = Best) {
     979             :     *this = JetDefinition(jet_algorithm_in, R_in, external_scheme, strategy_in);
     980             :     _recombiner = recombiner_in;
     981             :   }
     982             :   JetDefinition(JetAlgorithm jet_algorithm_in,
     983             :                 const Recombiner * recombiner_in,
     984             :                 Strategy strategy_in = Best) {
     985             :     *this = JetDefinition(jet_algorithm_in, external_scheme, strategy_in);
     986             :     _recombiner = recombiner_in;
     987             :   }
     988             :   JetDefinition(JetAlgorithm jet_algorithm_in,
     989             :                 double R_in,
     990             :                 double xtra_param_in,
     991             :                 const Recombiner * recombiner_in,
     992             :                 Strategy strategy_in = Best) {
     993             :     *this = JetDefinition(jet_algorithm_in, R_in, external_scheme, strategy_in);
     994             :     _recombiner = recombiner_in;
     995             :     set_extra_param(xtra_param_in);
     996             :   }
     997             :   JetDefinition()  {
     998             :     *this = JetDefinition(undefined_jet_algorithm, 1.0);
     999             :   }
    1000             :   JetDefinition(const Plugin * plugin_in) {
    1001             :     _plugin = plugin_in;
    1002             :     _strategy = plugin_strategy;
    1003             :     _Rparam = _plugin->R();
    1004             :     _jet_algorithm = plugin_algorithm;
    1005             :     set_recombination_scheme(E_scheme);
    1006             :   }
    1007             :   JetDefinition(JetAlgorithm jet_algorithm_in,
    1008             :                 double R_in,
    1009             :                 Strategy strategy_in,
    1010             :                 RecombinationScheme recomb_scheme_in = E_scheme,
    1011             :                 int nparameters_in = 1);
    1012             :   static const double max_allowable_R; //= 1000.0;
    1013             :   void set_recombination_scheme(RecombinationScheme);
    1014             :   void set_recombiner(const Recombiner * recomb) {
    1015             :     if (_recombiner_shared()) _recombiner_shared.reset(recomb);
    1016             :     _recombiner = recomb;
    1017             :     _default_recombiner = DefaultRecombiner(external_scheme);
    1018             :   }
    1019             :   void delete_recombiner_when_unused();
    1020           0 :   const Plugin * plugin() const {return _plugin;};
    1021             :   void delete_plugin_when_unused();
    1022           0 :   JetAlgorithm jet_algorithm  () const {return _jet_algorithm  ;}
    1023             :   JetAlgorithm jet_finder     () const {return _jet_algorithm  ;}
    1024           0 :   double    R           () const {return _Rparam      ;}
    1025           0 :   double    extra_param () const {return _extra_param ;}
    1026           0 :   Strategy  strategy    () const {return _strategy    ;}
    1027             :   RecombinationScheme recombination_scheme() const {
    1028           0 :     return _default_recombiner.scheme();}
    1029             :   void set_jet_algorithm(JetAlgorithm njf) {_jet_algorithm = njf;}
    1030             :   void set_jet_finder(JetAlgorithm njf)    {_jet_algorithm = njf;}
    1031           0 :   void set_extra_param(double xtra_param) {_extra_param = xtra_param;}
    1032             :   const Recombiner * recombiner() const {
    1033           0 :     return _recombiner == 0 ? & _default_recombiner : _recombiner;}
    1034             :   bool has_same_recombiner(const JetDefinition &other_jd) const;
    1035             :   std::string description() const;
    1036             : public:
    1037           0 :   class Recombiner {
    1038             :   public:
    1039             :     virtual std::string description() const = 0;
    1040             :     virtual void recombine(const PseudoJet & pa, const PseudoJet & pb,
    1041             :                            PseudoJet & pab) const = 0;
    1042           0 :     virtual void preprocess(PseudoJet & ) const {};
    1043           0 :     virtual ~Recombiner() {};
    1044             :     inline void plus_equal(PseudoJet & pa, const PseudoJet & pb) const {
    1045           0 :       PseudoJet pres;
    1046           0 :       recombine(pa,pb,pres);
    1047           0 :       pa = pres;
    1048           0 :     }
    1049             :   };
    1050           0 :   class DefaultRecombiner : public Recombiner {
    1051             :   public:
    1052           0 :     DefaultRecombiner(RecombinationScheme recomb_scheme = E_scheme) :
    1053           0 :       _recomb_scheme(recomb_scheme) {}
    1054             :     virtual std::string description() const;
    1055             :     virtual void recombine(const PseudoJet & pa, const PseudoJet & pb,
    1056             :                            PseudoJet & pab) const;
    1057             :     virtual void preprocess(PseudoJet & p) const;
    1058           0 :     RecombinationScheme scheme() const {return _recomb_scheme;}
    1059             :   private:
    1060             :     RecombinationScheme _recomb_scheme;
    1061             :   };
    1062             :   class Plugin{
    1063             :   public:
    1064             :     virtual std::string description() const = 0;
    1065             :     virtual void run_clustering(ClusterSequence &) const = 0;
    1066             :     virtual double R() const = 0;
    1067           0 :     virtual bool supports_ghosted_passive_areas() const {return false;}
    1068             :     virtual void set_ghost_separation_scale(double scale) const;
    1069           0 :     virtual double ghost_separation_scale() const {return 0.0;}
    1070           0 :     virtual bool exclusive_sequence_meaningful() const {return false;}
    1071           0 :     virtual ~Plugin() {};
    1072             :   };
    1073             : private:
    1074             :   JetAlgorithm _jet_algorithm;
    1075             :   double    _Rparam;
    1076             :   double    _extra_param ; ///< parameter whose meaning varies according to context
    1077             :   Strategy  _strategy  ;
    1078             :   const Plugin * _plugin;
    1079             :   SharedPtr<const Plugin> _plugin_shared;
    1080             :   DefaultRecombiner _default_recombiner;
    1081             :   const Recombiner * _recombiner;
    1082             :   SharedPtr<const Recombiner> _recombiner_shared;
    1083             : };
    1084             : PseudoJet join(const std::vector<PseudoJet> & pieces, const JetDefinition::Recombiner & recombiner);
    1085             : PseudoJet join(const PseudoJet & j1,
    1086             :                const JetDefinition::Recombiner & recombiner);
    1087             : PseudoJet join(const PseudoJet & j1, const PseudoJet & j2,
    1088             :                const JetDefinition::Recombiner & recombiner);
    1089             : PseudoJet join(const PseudoJet & j1, const PseudoJet & j2, const PseudoJet & j3,
    1090             :                const JetDefinition::Recombiner & recombiner);
    1091             : PseudoJet join(const PseudoJet & j1, const PseudoJet & j2, const PseudoJet & j3, const PseudoJet & j4,
    1092             :                const JetDefinition::Recombiner & recombiner);
    1093             : FJCORE_END_NAMESPACE
    1094             : #endif // __FJCORE_JETDEFINITION_HH__
    1095             : #ifndef __FJCORE_COMPOSITEJET_STRUCTURE_HH__
    1096             : #define __FJCORE_COMPOSITEJET_STRUCTURE_HH__
    1097             : FJCORE_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
    1098             : class CompositeJetStructure : public PseudoJetStructureBase{
    1099             : public:
    1100             :   CompositeJetStructure() : _area_4vector_ptr(0){};
    1101             :   CompositeJetStructure(const std::vector<PseudoJet> & initial_pieces,
    1102             :                         const JetDefinition::Recombiner * recombiner = 0);
    1103           0 :   virtual ~CompositeJetStructure(){
    1104           0 :     if (_area_4vector_ptr) delete _area_4vector_ptr;
    1105           0 :   };
    1106             :   virtual std::string description() const;
    1107             :   virtual bool has_constituents() const;
    1108             :   virtual std::vector<PseudoJet> constituents(const PseudoJet &jet) const;
    1109           0 :   virtual bool has_pieces(const PseudoJet & /*jet*/) const {return true;}
    1110             :   virtual std::vector<PseudoJet> pieces(const PseudoJet &jet) const;
    1111             : protected:
    1112             :   std::vector<PseudoJet> _pieces;  ///< the pieces building the jet
    1113             :   PseudoJet * _area_4vector_ptr;   ///< pointer to the 4-vector jet area
    1114             : };
    1115             : template<typename T> PseudoJet join(const std::vector<PseudoJet> & pieces){
    1116             :   PseudoJet result(0.0,0.0,0.0,0.0);
    1117             :   for (unsigned int i=0; i<pieces.size(); i++){
    1118             :     const PseudoJet it = pieces[i];
    1119             :     result += it;
    1120             :   }
    1121             :   T *cj_struct = new T(pieces);
    1122             :   result.set_structure_shared_ptr(SharedPtr<PseudoJetStructureBase>(cj_struct));
    1123             :   return result;
    1124             : }
    1125             : template<typename T> PseudoJet join(const PseudoJet & j1){
    1126             :   return join<T>(std::vector<PseudoJet>(1,j1));
    1127             : }
    1128             : template<typename T> PseudoJet join(const PseudoJet & j1, const PseudoJet & j2){
    1129             :   std::vector<PseudoJet> pieces;
    1130             :   pieces.push_back(j1);
    1131             :   pieces.push_back(j2);
    1132             :   return join<T>(pieces);
    1133             : }
    1134             : template<typename T> PseudoJet join(const PseudoJet & j1, const PseudoJet & j2,
    1135             :                                     const PseudoJet & j3){
    1136             :   std::vector<PseudoJet> pieces;
    1137             :   pieces.push_back(j1);
    1138             :   pieces.push_back(j2);
    1139             :   pieces.push_back(j3);
    1140             :   return join<T>(pieces);
    1141             : }
    1142             : template<typename T> PseudoJet join(const PseudoJet & j1, const PseudoJet & j2,
    1143             :                                     const PseudoJet & j3, const PseudoJet & j4){
    1144             :   std::vector<PseudoJet> pieces;
    1145             :   pieces.push_back(j1);
    1146             :   pieces.push_back(j2);
    1147             :   pieces.push_back(j3);
    1148             :   pieces.push_back(j4);
    1149             :   return join<T>(pieces);
    1150             : }
    1151             : template<typename T> PseudoJet join(const std::vector<PseudoJet> & pieces,
    1152             :                                     const JetDefinition::Recombiner & recombiner){
    1153             :   PseudoJet result;
    1154             :   if (pieces.size()>0){
    1155             :     result = pieces[0];
    1156             :     for (unsigned int i=1; i<pieces.size(); i++){
    1157             :       recombiner.plus_equal(result, pieces[i]);
    1158             :     }
    1159             :   }
    1160             :   T *cj_struct = new T(pieces, &recombiner);
    1161             :   result.set_structure_shared_ptr(SharedPtr<PseudoJetStructureBase>(cj_struct));
    1162             :   return result;
    1163             : }
    1164             : template<typename T> PseudoJet join(const PseudoJet & j1,
    1165             :                                     const JetDefinition::Recombiner & recombiner){
    1166             :   return join<T>(std::vector<PseudoJet>(1,j1), recombiner);
    1167             : }
    1168             : template<typename T> PseudoJet join(const PseudoJet & j1, const PseudoJet & j2,
    1169             :                                     const JetDefinition::Recombiner & recombiner){
    1170             :   std::vector<PseudoJet> pieces;
    1171             :   pieces.push_back(j1);
    1172             :   pieces.push_back(j2);
    1173             :   return join<T>(pieces, recombiner);
    1174             : }
    1175             : template<typename T> PseudoJet join(const PseudoJet & j1, const PseudoJet & j2,
    1176             :                                     const PseudoJet & j3,
    1177             :                                     const JetDefinition::Recombiner & recombiner){
    1178             :   std::vector<PseudoJet> pieces;
    1179             :   pieces.push_back(j1);
    1180             :   pieces.push_back(j2);
    1181             :   pieces.push_back(j3);
    1182             :   return join<T>(pieces, recombiner);
    1183             : }
    1184             : template<typename T> PseudoJet join(const PseudoJet & j1, const PseudoJet & j2,
    1185             :                                     const PseudoJet & j3, const PseudoJet & j4,
    1186             :                                     const JetDefinition::Recombiner & recombiner){
    1187             :   std::vector<PseudoJet> pieces;
    1188             :   pieces.push_back(j1);
    1189             :   pieces.push_back(j2);
    1190             :   pieces.push_back(j3);
    1191             :   pieces.push_back(j4);
    1192             :   return join<T>(pieces, recombiner);
    1193             : }
    1194             : FJCORE_END_NAMESPACE      // defined in fastjet/internal/base.hh
    1195             : #endif // __FJCORE_MERGEDJET_STRUCTURE_HH__
    1196             : #ifndef __FJCORE_CLUSTER_SEQUENCE_STRUCTURE_HH__
    1197             : #define __FJCORE_CLUSTER_SEQUENCE_STRUCTURE_HH__
    1198             : #include <vector>
    1199             : FJCORE_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
    1200             : class ClusterSequenceStructure : public PseudoJetStructureBase{
    1201             : public:
    1202             :   ClusterSequenceStructure() : _associated_cs(NULL){}
    1203           0 :   ClusterSequenceStructure(const ClusterSequence *cs){
    1204           0 :     set_associated_cs(cs);
    1205           0 :   };
    1206             :   virtual ~ClusterSequenceStructure();
    1207           0 :   virtual std::string description() const{ return "PseudoJet with an associated ClusterSequence"; }
    1208           0 :   virtual bool has_associated_cluster_sequence() const{ return true;}
    1209             :   virtual const ClusterSequence* associated_cluster_sequence() const;
    1210             :   virtual bool has_valid_cluster_sequence() const;
    1211             :   virtual const ClusterSequence * validated_cs() const;
    1212             :   virtual void set_associated_cs(const ClusterSequence * new_cs){
    1213           0 :     _associated_cs = new_cs;
    1214           0 :   }
    1215             :   virtual bool has_partner(const PseudoJet &reference, PseudoJet &partner) const;
    1216             :   virtual bool has_child(const PseudoJet &reference, PseudoJet &child) const;
    1217             :   virtual bool has_parents(const PseudoJet &reference, PseudoJet &parent1, PseudoJet &parent2) const;
    1218             :   virtual bool object_in_jet(const PseudoJet &reference, const PseudoJet &jet) const;
    1219             :   virtual bool has_constituents() const;
    1220             :   virtual std::vector<PseudoJet> constituents(const PseudoJet &reference) const;
    1221             :   virtual bool has_exclusive_subjets() const;
    1222             :   virtual std::vector<PseudoJet> exclusive_subjets(const PseudoJet &reference, const double & dcut) const;
    1223             :   virtual int n_exclusive_subjets(const PseudoJet &reference, const double & dcut) const;
    1224             :   virtual std::vector<PseudoJet> exclusive_subjets_up_to (const PseudoJet &reference, int nsub) const;
    1225             :   virtual double exclusive_subdmerge(const PseudoJet &reference, int nsub) const;
    1226             :   virtual double exclusive_subdmerge_max(const PseudoJet &reference, int nsub) const;
    1227             :   virtual bool has_pieces(const PseudoJet &reference) const;
    1228             :   virtual std::vector<PseudoJet> pieces(const PseudoJet &reference) const;
    1229             : protected:
    1230             :   const ClusterSequence *_associated_cs;
    1231             : };
    1232             : FJCORE_END_NAMESPACE
    1233             : #endif  //  __FJCORE_CLUSTER_SEQUENCE_STRUCTURE_HH__
    1234             : #ifndef __FJCORE_CLUSTERSEQUENCE_HH__
    1235             : #define __FJCORE_CLUSTERSEQUENCE_HH__
    1236             : #include<vector>
    1237             : #include<map>
    1238             : #include<memory>
    1239             : #include<cassert>
    1240             : #include<iostream>
    1241             : #include<string>
    1242             : #include<set>
    1243             : #include<cmath> // needed to get double std::abs(double)
    1244             : FJCORE_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
    1245             : class ClusterSequenceStructure;
    1246             : class DynamicNearestNeighbours;
    1247             : class ClusterSequence {
    1248             :  public:
    1249             :   ClusterSequence () : _deletes_self_when_unused(false) {}
    1250             :   template<class L> ClusterSequence (
    1251             :                                   const std::vector<L> & pseudojets,
    1252             :                                   const JetDefinition & jet_def,
    1253             :                                   const bool & writeout_combinations = false);
    1254             :   ClusterSequence (const ClusterSequence & cs) : _deletes_self_when_unused(false) {
    1255             :     transfer_from_sequence(cs);
    1256             :   }
    1257             :   virtual ~ClusterSequence (); //{}
    1258             :   std::vector<PseudoJet> inclusive_jets (const double & ptmin = 0.0) const;
    1259             :   int n_exclusive_jets (const double & dcut) const;
    1260             :   std::vector<PseudoJet> exclusive_jets (const double & dcut) const;
    1261             :   std::vector<PseudoJet> exclusive_jets (const int & njets) const;
    1262             :   std::vector<PseudoJet> exclusive_jets_up_to (const int & njets) const;
    1263             :   double exclusive_dmerge (const int & njets) const;
    1264             :   double exclusive_dmerge_max (const int & njets) const;
    1265             :   double exclusive_ymerge (int njets) const {return exclusive_dmerge(njets) / Q2();}
    1266             :   double exclusive_ymerge_max (int njets) const {return exclusive_dmerge_max(njets)/Q2();}
    1267             :   int n_exclusive_jets_ycut (double ycut) const {return n_exclusive_jets(ycut*Q2());}
    1268             :   std::vector<PseudoJet> exclusive_jets_ycut (double ycut) const {
    1269             :     int njets = n_exclusive_jets_ycut(ycut);
    1270             :     return exclusive_jets(njets);
    1271             :   }
    1272             :   std::vector<PseudoJet> exclusive_subjets (const PseudoJet & jet,
    1273             :                                             const double & dcut) const;
    1274             :   int n_exclusive_subjets(const PseudoJet & jet,
    1275             :                           const double & dcut) const;
    1276             :   std::vector<PseudoJet> exclusive_subjets (const PseudoJet & jet,
    1277             :                                             int nsub) const;
    1278             :   std::vector<PseudoJet> exclusive_subjets_up_to (const PseudoJet & jet,
    1279             :                                                   int nsub) const;
    1280             :   double exclusive_subdmerge(const PseudoJet & jet, int nsub) const;
    1281             :   double exclusive_subdmerge_max(const PseudoJet & jet, int nsub) const;
    1282             :   double Q() const {return _Qtot;}
    1283             :   double Q2() const {return _Qtot*_Qtot;}
    1284             :   bool object_in_jet(const PseudoJet & object, const PseudoJet & jet) const;
    1285             :   bool has_parents(const PseudoJet & jet, PseudoJet & parent1,
    1286             :                PseudoJet & parent2) const;
    1287             :   bool has_child(const PseudoJet & jet, PseudoJet & child) const;
    1288             :   bool has_child(const PseudoJet & jet, const PseudoJet * & childp) const;
    1289             :   bool has_partner(const PseudoJet & jet, PseudoJet & partner) const;
    1290             :   std::vector<PseudoJet> constituents (const PseudoJet & jet) const;
    1291             :   void print_jets_for_root(const std::vector<PseudoJet> & jets,
    1292             :                            std::ostream & ostr = std::cout) const;
    1293             :   void print_jets_for_root(const std::vector<PseudoJet> & jets,
    1294             :                            const std::string & filename,
    1295             :                            const std::string & comment = "") const;
    1296             :   void add_constituents (const PseudoJet & jet,
    1297             :                          std::vector<PseudoJet> & subjet_vector) const;
    1298             :   inline Strategy strategy_used () const {return _strategy;}
    1299           0 :   std::string strategy_string () const {return strategy_string(_strategy);}
    1300             :   std::string strategy_string (Strategy strategy_in) const;
    1301           0 :   const JetDefinition & jet_def() const {return _jet_def;}
    1302             :   void delete_self_when_unused();
    1303           0 :   bool will_delete_self_when_unused() const {return _deletes_self_when_unused;}
    1304             :   void signal_imminent_self_deletion() const;
    1305             :   double jet_scale_for_algorithm(const PseudoJet & jet) const;
    1306             :   void plugin_record_ij_recombination(int jet_i, int jet_j, double dij,
    1307             :                                       int & newjet_k) {
    1308           0 :     assert(plugin_activated());
    1309           0 :     _do_ij_recombination_step(jet_i, jet_j, dij, newjet_k);
    1310           0 :   }
    1311             :   void plugin_record_ij_recombination(int jet_i, int jet_j, double dij,
    1312             :                                       const PseudoJet & newjet,
    1313             :                                       int & newjet_k);
    1314             :   void plugin_record_iB_recombination(int jet_i, double diB) {
    1315             :     assert(plugin_activated());
    1316             :     _do_iB_recombination_step(jet_i, diB);
    1317             :   }
    1318             :   class Extras {
    1319             :   public:
    1320             :     virtual ~Extras() {}
    1321             :     virtual std::string description() const {return "This is a dummy extras class that contains no extra information! Derive from it if you want to use it to provide extra information from a plugin jet finder";}
    1322             :   };
    1323             :   inline void plugin_associate_extras(std::auto_ptr<Extras> extras_in) {
    1324             :     _extras.reset(extras_in.release());
    1325             :   }
    1326           0 :   inline bool plugin_activated() const {return _plugin_activated;}
    1327             :   const Extras * extras() const {return _extras.get();}
    1328             :   template<class GBJ> void plugin_simple_N2_cluster () {
    1329             :     assert(plugin_activated());
    1330             :     _simple_N2_cluster<GBJ>();
    1331             :   }
    1332             : public:
    1333             :   struct history_element{
    1334             :     int parent1; /// index in _history where first parent of this jet
    1335             :     int parent2; /// index in _history where second parent of this jet
    1336             :     int child;   /// index in _history where the current jet is
    1337             :                  /// recombined with another jet to form its child. It
    1338             :                  /// is Invalid if this jet does not further
    1339             :                  /// recombine.
    1340             :     int jetp_index; /// index in the _jets vector where we will find the
    1341             :     double dij;  /// the distance corresponding to the recombination
    1342             :                  /// at this stage of the clustering.
    1343             :     double max_dij_so_far; /// the largest recombination distance seen
    1344             :                            /// so far in the clustering history.
    1345             :   };
    1346             :   enum JetType {Invalid=-3, InexistentParent = -2, BeamJet = -1};
    1347             :   const std::vector<PseudoJet> & jets()    const;
    1348             :   const std::vector<history_element> & history() const;
    1349             :   unsigned int n_particles() const;
    1350             :   std::vector<int> particle_jet_indices(const std::vector<PseudoJet> &) const;
    1351             :   std::vector<int> unique_history_order() const;
    1352             :   std::vector<PseudoJet> unclustered_particles() const;
    1353             :   std::vector<PseudoJet> childless_pseudojets() const;
    1354             :   bool contains(const PseudoJet & object) const;
    1355             :   void transfer_from_sequence(const ClusterSequence & from_seq,
    1356             :                               const FunctionOfPseudoJet<PseudoJet> * action_on_jets = 0);
    1357             :   const SharedPtr<PseudoJetStructureBase> & structure_shared_ptr() const{
    1358             :     return _structure_shared_ptr;
    1359             :   }
    1360             :   typedef ClusterSequenceStructure StructureType;
    1361             :   static void print_banner();
    1362             :   static void set_fastjet_banner_stream(std::ostream * ostr) {_fastjet_banner_ostr = ostr;}
    1363             :   static std::ostream * fastjet_banner_stream() {return _fastjet_banner_ostr;}
    1364             : private:
    1365             :   static std::ostream * _fastjet_banner_ostr;
    1366             : protected:
    1367             :   JetDefinition _jet_def;
    1368             :   template<class L> void _transfer_input_jets(
    1369             :                                      const std::vector<L> & pseudojets);
    1370             :   void _initialise_and_run (const JetDefinition & jet_def,
    1371             :                             const bool & writeout_combinations);
    1372             :   void _initialise_and_run_no_decant();
    1373             :   void _decant_options(const JetDefinition & jet_def,
    1374             :                        const bool & writeout_combinations);
    1375             :   void _decant_options_partial();
    1376             :   void _fill_initial_history();
    1377             :   void _do_ij_recombination_step(const int & jet_i, const int & jet_j,
    1378             :                                  const double & dij, int & newjet_k);
    1379             :   void _do_iB_recombination_step(const int & jet_i, const double & diB);
    1380             :   void _set_structure_shared_ptr(PseudoJet & j);
    1381             :   void _update_structure_use_count();
    1382             :   std::vector<PseudoJet> _jets;
    1383             :   std::vector<history_element> _history;
    1384             :   void get_subhist_set(std::set<const history_element*> & subhist,
    1385             :                        const  PseudoJet & jet, double dcut, int maxjet) const;
    1386             :   bool _writeout_combinations;
    1387             :   int  _initial_n;
    1388             :   double _Rparam, _R2, _invR2;
    1389             :   double _Qtot;
    1390             :   Strategy    _strategy;
    1391             :   JetAlgorithm  _jet_algorithm;
    1392             :   SharedPtr<PseudoJetStructureBase> _structure_shared_ptr; //< will actually be of type ClusterSequenceStructure
    1393             :   int _structure_use_count_after_construction; //< info of use when CS handles its own memory
    1394             :   mutable bool _deletes_self_when_unused;
    1395             :  private:
    1396             :   bool _plugin_activated;
    1397             :   SharedPtr<Extras> _extras; // things the plugin might want to add
    1398             :   void _really_dumb_cluster ();
    1399             :   void _delaunay_cluster ();
    1400             :   template<class BJ> void _simple_N2_cluster ();
    1401             :   void _tiled_N2_cluster ();
    1402             :   void _faster_tiled_N2_cluster ();
    1403             :   void _minheap_faster_tiled_N2_cluster();
    1404             :   void _CP2DChan_cluster();
    1405             :   void _CP2DChan_cluster_2pi2R ();
    1406             :   void _CP2DChan_cluster_2piMultD ();
    1407             :   void _CP2DChan_limited_cluster(double D);
    1408             :   void _do_Cambridge_inclusive_jets();
    1409             :   void _fast_NsqrtN_cluster();
    1410             :   void _add_step_to_history(const int & step_number, const int & parent1,
    1411             :                                const int & parent2, const int & jetp_index,
    1412             :                                const double & dij);
    1413             :   void _extract_tree_children(int pos, std::valarray<bool> &,
    1414             :                 const std::valarray<int> &, std::vector<int> &) const;
    1415             :   void _extract_tree_parents (int pos, std::valarray<bool> &,
    1416             :                 const std::valarray<int> &,  std::vector<int> &) const;
    1417             :   typedef std::pair<int,int> TwoVertices;
    1418             :   typedef std::pair<double,TwoVertices> DijEntry;
    1419             :   typedef std::multimap<double,TwoVertices> DistMap;
    1420             :   void _add_ktdistance_to_map(const int & ii,
    1421             :                               DistMap & DijMap,
    1422             :                               const DynamicNearestNeighbours * DNN);
    1423             :   static bool _first_time;
    1424             :   static int _n_exclusive_warnings;
    1425             :   static LimitedWarning _changed_strategy_warning;
    1426             :   struct BriefJet {
    1427             :     double     eta, phi, kt2, NN_dist;
    1428             :     BriefJet * NN;
    1429             :     int        _jets_index;
    1430             :   };
    1431             :   class TiledJet {
    1432             :   public:
    1433             :     double     eta, phi, kt2, NN_dist;
    1434             :     TiledJet * NN, *previous, * next;
    1435             :     int        _jets_index, tile_index, diJ_posn;
    1436           0 :     inline void label_minheap_update_needed() {diJ_posn = 1;}
    1437           0 :     inline void label_minheap_update_done()   {diJ_posn = 0;}
    1438           0 :     inline bool minheap_update_needed() const {return diJ_posn==1;}
    1439             :   };
    1440             :   template <class J> void _bj_set_jetinfo( J * const jet,
    1441             :                                                  const int _jets_index) const;
    1442             :   void _bj_remove_from_tiles( TiledJet * const jet) const;
    1443             :   template <class J> double _bj_dist(const J * const jeta,
    1444             :                         const J * const jetb) const;
    1445             :   template <class J> double _bj_diJ(const J * const jeta) const;
    1446             :   template <class J> inline J * _bj_of_hindex(
    1447             :                           const int hist_index,
    1448             :                           J * const head, J * const tail)
    1449             :     const {
    1450             :     J * res;
    1451             :     for(res = head; res<tail; res++) {
    1452             :       if (_jets[res->_jets_index].cluster_hist_index() == hist_index) {break;}
    1453             :     }
    1454             :     return res;
    1455             :   }
    1456             :   template <class J> void _bj_set_NN_nocross(J * const jeta,
    1457             :             J * const head, const J * const tail) const;
    1458             :   template <class J> void _bj_set_NN_crosscheck(J * const jeta,
    1459             :             J * const head, const J * const tail) const;
    1460             :   static const int n_tile_neighbours = 9;
    1461             :   struct Tile {
    1462             :     Tile *   begin_tiles[n_tile_neighbours];
    1463             :     Tile **  surrounding_tiles;
    1464             :     Tile **  RH_tiles;
    1465             :     Tile **  end_tiles;
    1466             :     TiledJet * head;
    1467             :     bool     tagged;
    1468             :   };
    1469             :   std::vector<Tile> _tiles;
    1470             :   double _tiles_eta_min, _tiles_eta_max;
    1471             :   double _tile_size_eta, _tile_size_phi;
    1472             :   int    _n_tiles_phi,_tiles_ieta_min,_tiles_ieta_max;
    1473             :   inline int _tile_index (int ieta, int iphi) const {
    1474           0 :     return (ieta-_tiles_ieta_min)*_n_tiles_phi
    1475           0 :                   + (iphi+_n_tiles_phi) % _n_tiles_phi;
    1476             :   }
    1477             :   int  _tile_index(const double & eta, const double & phi) const;
    1478             :   void _tj_set_jetinfo ( TiledJet * const jet, const int _jets_index);
    1479             :   void  _bj_remove_from_tiles(TiledJet * const jet);
    1480             :   void _initialise_tiles();
    1481             :   void _print_tiles(TiledJet * briefjets ) const;
    1482             :   void _add_neighbours_to_tile_union(const int tile_index,
    1483             :                  std::vector<int> & tile_union, int & n_near_tiles) const;
    1484             :   void _add_untagged_neighbours_to_tile_union(const int tile_index,
    1485             :                  std::vector<int> & tile_union, int & n_near_tiles);
    1486             :   struct EEBriefJet {
    1487             :     double NN_dist;  // obligatorily present
    1488             :     double kt2;      // obligatorily present == E^2 in general
    1489             :     EEBriefJet * NN; // must be present too
    1490             :     int    _jets_index; // must also be present!
    1491             :     double nx, ny, nz;  // our internal storage for fast distance calcs
    1492             :   };
    1493             :   void _simple_N2_cluster_BriefJet();
    1494             :   void _simple_N2_cluster_EEBriefJet();
    1495             : };
    1496             : template<class L> void ClusterSequence::_transfer_input_jets(
    1497             :                                        const std::vector<L> & pseudojets) {
    1498           0 :   _jets.reserve(pseudojets.size()*2);
    1499           0 :   for (unsigned int i = 0; i < pseudojets.size(); i++) {
    1500           0 :     _jets.push_back(pseudojets[i]);}
    1501           0 : }
    1502           0 : template<class L> ClusterSequence::ClusterSequence (
    1503             :                                   const std::vector<L> & pseudojets,
    1504             :                                   const JetDefinition & jet_def_in,
    1505             :                                   const bool & writeout_combinations) :
    1506           0 :   _jet_def(jet_def_in), _writeout_combinations(writeout_combinations),
    1507           0 :   _structure_shared_ptr(new ClusterSequenceStructure(this))
    1508           0 : {
    1509           0 :   _transfer_input_jets(pseudojets);
    1510           0 :   _decant_options_partial();
    1511           0 :   _initialise_and_run_no_decant();
    1512           0 : }
    1513             : inline const std::vector<PseudoJet> & ClusterSequence::jets () const {
    1514             :   return _jets;
    1515             : }
    1516             : inline const std::vector<ClusterSequence::history_element> & ClusterSequence::history () const {
    1517           0 :   return _history;
    1518             : }
    1519           0 : inline unsigned int ClusterSequence::n_particles() const {return _initial_n;}
    1520             : template <class J> inline void ClusterSequence::_bj_set_jetinfo(
    1521             :                             J * const jetA, const int _jets_index) const {
    1522           0 :     jetA->eta  = _jets[_jets_index].rap();
    1523           0 :     jetA->phi  = _jets[_jets_index].phi_02pi();
    1524           0 :     jetA->kt2  = jet_scale_for_algorithm(_jets[_jets_index]);
    1525           0 :     jetA->_jets_index = _jets_index;
    1526           0 :     jetA->NN_dist = _R2;
    1527           0 :     jetA->NN      = NULL;
    1528           0 : }
    1529             : template <class J> inline double ClusterSequence::_bj_dist(
    1530             :                 const J * const jetA, const J * const jetB) const {
    1531           0 :   double dphi = std::abs(jetA->phi - jetB->phi);
    1532           0 :   double deta = (jetA->eta - jetB->eta);
    1533           0 :   if (dphi > pi) {dphi = twopi - dphi;}
    1534           0 :   return dphi*dphi + deta*deta;
    1535             : }
    1536             : template <class J> inline double ClusterSequence::_bj_diJ(const J * const jet) const {
    1537           0 :   double kt2 = jet->kt2;
    1538           0 :   if (jet->NN != NULL) {if (jet->NN->kt2 < kt2) {kt2 = jet->NN->kt2;}}
    1539           0 :   return jet->NN_dist * kt2;
    1540             : }
    1541             : template <class J> inline void ClusterSequence::_bj_set_NN_nocross(
    1542             :                  J * const jet, J * const head, const J * const tail) const {
    1543           0 :   double NN_dist = _R2;
    1544             :   J * NN  = NULL;
    1545           0 :   if (head < jet) {
    1546           0 :     for (J * jetB = head; jetB != jet; jetB++) {
    1547           0 :       double dist = _bj_dist(jet,jetB);
    1548           0 :       if (dist < NN_dist) {
    1549             :         NN_dist = dist;
    1550             :         NN = jetB;
    1551           0 :       }
    1552             :     }
    1553           0 :   }
    1554           0 :   if (tail > jet) {
    1555           0 :     for (J * jetB = jet+1; jetB != tail; jetB++) {
    1556           0 :       double dist = _bj_dist(jet,jetB);
    1557           0 :       if (dist < NN_dist) {
    1558             :         NN_dist = dist;
    1559             :         NN = jetB;
    1560           0 :       }
    1561             :     }
    1562           0 :   }
    1563           0 :   jet->NN = NN;
    1564           0 :   jet->NN_dist = NN_dist;
    1565           0 : }
    1566             : template <class J> inline void ClusterSequence::_bj_set_NN_crosscheck(J * const jet,
    1567             :                     J * const head, const J * const tail) const {
    1568           0 :   double NN_dist = _R2;
    1569             :   J * NN  = NULL;
    1570           0 :   for (J * jetB = head; jetB != tail; jetB++) {
    1571           0 :     double dist = _bj_dist(jet,jetB);
    1572           0 :     if (dist < NN_dist) {
    1573             :       NN_dist = dist;
    1574             :       NN = jetB;
    1575           0 :     }
    1576           0 :     if (dist < jetB->NN_dist) {
    1577           0 :       jetB->NN_dist = dist;
    1578           0 :       jetB->NN = jet;
    1579           0 :     }
    1580             :   }
    1581           0 :   jet->NN = NN;
    1582           0 :   jet->NN_dist = NN_dist;
    1583           0 : }
    1584             : FJCORE_END_NAMESPACE
    1585             : #endif // __FJCORE_CLUSTERSEQUENCE_HH__
    1586             : #ifndef __FJCORE_NNH_HH__
    1587             : #define __FJCORE_NNH_HH__
    1588             : FJCORE_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
    1589             : class _NoInfo {};
    1590             : template<class I> class NNHInfo {
    1591             : public:
    1592             :   NNHInfo()         : _info(NULL) {}
    1593             :   NNHInfo(I * info) : _info(info) {}
    1594             :   template<class NNBJ> void init_jet(NNBJ * briefjet, const fjcore::PseudoJet & jet, int index) { briefjet->init(jet, index, _info);}
    1595             : private:
    1596             :   I * _info;
    1597             : };
    1598             : template<> class NNHInfo<_NoInfo>  {
    1599             : public:
    1600             :   NNHInfo()           {}
    1601             :   NNHInfo(_NoInfo * ) {}
    1602             :   template<class NNBJ> void init_jet(NNBJ * briefjet, const fjcore::PseudoJet & jet, int index) { briefjet->init(jet, index);}
    1603             : };
    1604             : template<class BJ, class I = _NoInfo> class NNH : public NNHInfo<I> {
    1605             : public:
    1606             :   NNH(const std::vector<PseudoJet> & jets) {start(jets);}
    1607             :   NNH(const std::vector<PseudoJet> & jets, I * info) : NNHInfo<I>(info) {start(jets);}
    1608             :   void start(const std::vector<PseudoJet> & jets);
    1609             :   double dij_min(int & iA, int & iB);
    1610             :   void remove_jet(int iA);
    1611             :   void merge_jets(int iA, int iB, const PseudoJet & jet, int jet_index);
    1612             :   ~NNH() {
    1613             :     delete[] briefjets;
    1614             :   }
    1615             : private:
    1616             :   class NNBJ; // forward declaration
    1617             :   void set_NN_crosscheck(NNBJ * jet, NNBJ * begin, NNBJ * end);
    1618             :   void set_NN_nocross   (NNBJ * jet, NNBJ * begin, NNBJ * end);
    1619             :   NNBJ * briefjets;
    1620             :   NNBJ * head, * tail;
    1621             :   int n;
    1622             :   std::vector<NNBJ *> where_is;
    1623             :   class NNBJ : public BJ {
    1624             :   public:
    1625             :     void init(const PseudoJet & jet, int index_in) {
    1626             :       BJ::init(jet);
    1627             :       other_init(index_in);
    1628             :     }
    1629             :     void init(const PseudoJet & jet, int index_in, I * info) {
    1630             :       BJ::init(jet, info);
    1631             :       other_init(index_in);
    1632             :     }
    1633             :     void other_init(int index_in) {
    1634             :       _index = index_in;
    1635             :       NN_dist = BJ::beam_distance();
    1636             :       NN = NULL;
    1637             :     }
    1638             :     int index() const {return _index;}
    1639             :     double NN_dist;
    1640             :     NNBJ * NN;
    1641             :   private:
    1642             :     int _index;
    1643             :   };
    1644             : };
    1645             : template<class BJ, class I> void NNH<BJ,I>::start(const std::vector<PseudoJet> & jets) {
    1646             :   n = jets.size();
    1647             :   briefjets = new NNBJ[n];
    1648             :   where_is.resize(2*n);
    1649             :   NNBJ * jetA = briefjets;
    1650             :   for (int i = 0; i< n; i++) {
    1651             :     this->init_jet(jetA, jets[i], i);
    1652             :     where_is[i] = jetA;
    1653             :     jetA++; // move on to next entry of briefjets
    1654             :   }
    1655             :   tail = jetA; // a semaphore for the end of briefjets
    1656             :   head = briefjets; // a nicer way of naming start
    1657             :   for (jetA = head + 1; jetA != tail; jetA++) {
    1658             :     set_NN_crosscheck(jetA, head, jetA);
    1659             :   }
    1660             : }
    1661             : template<class BJ, class I> double NNH<BJ,I>::dij_min(int & iA, int & iB) {
    1662             :   double diJ_min = briefjets[0].NN_dist;
    1663             :   int diJ_min_jet = 0;
    1664             :   for (int i = 1; i < n; i++) {
    1665             :     if (briefjets[i].NN_dist < diJ_min) {
    1666             :       diJ_min_jet = i;
    1667             :       diJ_min  = briefjets[i].NN_dist;
    1668             :     }
    1669             :   }
    1670             :   NNBJ * jetA = & briefjets[diJ_min_jet];
    1671             :   iA = jetA->index();
    1672             :   iB = jetA->NN ? jetA->NN->index() : -1;
    1673             :   return diJ_min;
    1674             : }
    1675             : template<class BJ, class I> void NNH<BJ,I>::remove_jet(int iA) {
    1676             :   NNBJ * jetA = where_is[iA];
    1677             :   tail--; n--;
    1678             :   *jetA = *tail;
    1679             :   where_is[jetA->index()] = jetA;
    1680             :   for (NNBJ * jetI = head; jetI != tail; jetI++) {
    1681             :     if (jetI->NN == jetA) set_NN_nocross(jetI, head, tail);
    1682             :     if (jetI->NN == tail) {jetI->NN = jetA;}
    1683             :   }
    1684             : }
    1685             : template<class BJ, class I> void NNH<BJ,I>::merge_jets(int iA, int iB,
    1686             :                                         const PseudoJet & jet, int index) {
    1687             :   NNBJ * jetA = where_is[iA];
    1688             :   NNBJ * jetB = where_is[iB];
    1689             :   if (jetA < jetB) std::swap(jetA,jetB);
    1690             :   this->init_jet(jetB, jet, index);
    1691             :   if (index >= int(where_is.size())) where_is.resize(2*index);
    1692             :   where_is[jetB->index()] = jetB;
    1693             :   tail--; n--;
    1694             :   *jetA = *tail;
    1695             :   where_is[jetA->index()] = jetA;
    1696             :   for (NNBJ * jetI = head; jetI != tail; jetI++) {
    1697             :     if (jetI->NN == jetA || jetI->NN == jetB) {
    1698             :       set_NN_nocross(jetI, head, tail);
    1699             :     }
    1700             :     double dist = jetI->distance(jetB);
    1701             :     if (dist < jetI->NN_dist) {
    1702             :       if (jetI != jetB) {
    1703             :         jetI->NN_dist = dist;
    1704             :         jetI->NN = jetB;
    1705             :       }
    1706             :     }
    1707             :     if (dist < jetB->NN_dist) {
    1708             :       if (jetI != jetB) {
    1709             :         jetB->NN_dist = dist;
    1710             :         jetB->NN      = jetI;
    1711             :       }
    1712             :     }
    1713             :     if (jetI->NN == tail) {jetI->NN = jetA;}
    1714             :   }
    1715             : }
    1716             : template <class BJ, class I> void NNH<BJ,I>::set_NN_crosscheck(NNBJ * jet,
    1717             :                     NNBJ * begin, NNBJ * end) {
    1718             :   double NN_dist = jet->beam_distance();
    1719             :   NNBJ * NN      = NULL;
    1720             :   for (NNBJ * jetB = begin; jetB != end; jetB++) {
    1721             :     double dist = jet->distance(jetB);
    1722             :     if (dist < NN_dist) {
    1723             :       NN_dist = dist;
    1724             :       NN = jetB;
    1725             :     }
    1726             :     if (dist < jetB->NN_dist) {
    1727             :       jetB->NN_dist = dist;
    1728             :       jetB->NN = jet;
    1729             :     }
    1730             :   }
    1731             :   jet->NN = NN;
    1732             :   jet->NN_dist = NN_dist;
    1733             : }
    1734             : template <class BJ, class I>  void NNH<BJ,I>::set_NN_nocross(
    1735             :                  NNBJ * jet, NNBJ * begin, NNBJ * end) {
    1736             :   double NN_dist = jet->beam_distance();
    1737             :   NNBJ * NN      = NULL;
    1738             :   if (begin < jet) {
    1739             :     for (NNBJ * jetB = begin; jetB != jet; jetB++) {
    1740             :       double dist = jet->distance(jetB);
    1741             :       if (dist < NN_dist) {
    1742             :         NN_dist = dist;
    1743             :         NN = jetB;
    1744             :       }
    1745             :     }
    1746             :   }
    1747             :   if (end > jet) {
    1748             :     for (NNBJ * jetB = jet+1; jetB != end; jetB++) {
    1749             :       double dist = jet->distance (jetB);
    1750             :       if (dist < NN_dist) {
    1751             :         NN_dist = dist;
    1752             :         NN = jetB;
    1753             :       }
    1754             :     }
    1755             :   }
    1756             :   jet->NN = NN;
    1757             :   jet->NN_dist = NN_dist;
    1758             : }
    1759             : FJCORE_END_NAMESPACE      // defined in fastjet/internal/base.hh
    1760             : #endif // __FJCORE_NNH_HH__
    1761             : #endif

Generated by: LCOV version 1.11