Index: contrib/contribs/LundPlane/trunk/VERSION =================================================================== --- contrib/contribs/LundPlane/trunk/VERSION (revision 1459) +++ contrib/contribs/LundPlane/trunk/VERSION (revision 1460) @@ -1 +0,0 @@ -2.1.2-devel Index: contrib/contribs/LundPlane/trunk/LundJSON.hh =================================================================== --- contrib/contribs/LundPlane/trunk/LundJSON.hh (revision 1459) +++ contrib/contribs/LundPlane/trunk/LundJSON.hh (revision 1460) @@ -1,78 +0,0 @@ -#ifndef __FASTJET_CONTRIB_LUNDJSON_HH__ -#define __FASTJET_CONTRIB_LUNDJSON_HH__ - -#include "LundGenerator.hh" - -FASTJET_BEGIN_NAMESPACE - -namespace contrib{ - -// declaration of helper function -void lund_elements_to_json(std::ostream & ostr, const LundDeclustering & d); - -/// writes json to ostr for an individual declustering -inline std::ostream & lund_to_json(std::ostream & ostr, const LundDeclustering & d) { - // /// we hardcode 6 digits of precision -- is this the right way to do things? - // int prec_store = ostr.precision(); - // ostr.precision(6); - - ostr << "{"; - lund_elements_to_json(ostr, d); - ostr << "}"; - - return ostr; -} - - -/// writes json to ostr for a vector of declusterings -inline std::ostream & lund_to_json(std::ostream & ostr, const std::vector<LundDeclustering> & d) { - ostr << "["; - for (std::size_t i = 0; i < d.size(); i++) { - if (i != 0) ostr << ","; - lund_to_json(ostr, d[i]); - } - ostr << "]"; - return ostr; -} - -// /// writes a full Lund tree recursively to JSON -// inline std::ostream & lund_to_json(std::ostream & ostr, const LundGenerator & generator, const PseudoJet & jet) { -// // we will use these below in the loop; declare them here to avoid -// // repeated creation/destruction -// PseudoJet p1,p2; -// std::vector<LundDeclustering> d = generator(jet); -// ostr << "["; -// for (std::size_t i = 0; i < d.size(); i++) { -// if (i != 0) ostr << ","; -// ostr << "{"; -// lund_elements_to_json(ostr, d[i]); -// // add in information on the leaf if it exists -// if (d[i].softer().has_parents(p1,p2)) { -// ostr << ","; -// ostr << "\"leaf\":"; -// lund_to_json(ostr, generator, d[i].softer()); -// } -// ostr << "}"; -// } -// ostr << "]"; -// return ostr; -// } - -// helper function to write individual elements to json -inline void lund_elements_to_json(std::ostream & ostr, const LundDeclustering & d) { - ostr << "\"p_pt\":" << d.pair() .pt() << ","; - ostr << "\"p_m\":" << d.pair() .m () << ","; - ostr << "\"h_pt\":" << d.harder().pt() << ","; - ostr << "\"s_pt\":" << d.softer().pt() << ","; - ostr << "\"z\":" << d.z() << ","; - ostr << "\"Delta\":" << d.Delta() << ","; - ostr << "\"kt\":" << d.kt() << ","; - ostr << "\"psi\":" << d.psi() ; -} - - -} // namespace contrib - -FASTJET_END_NAMESPACE - -#endif // __FASTJET_CONTRIB_LUNDJSON_HH__ Index: contrib/contribs/LundPlane/trunk/LundEEHelpers.hh =================================================================== --- contrib/contribs/LundPlane/trunk/LundEEHelpers.hh (revision 1459) +++ contrib/contribs/LundPlane/trunk/LundEEHelpers.hh (revision 1460) @@ -1,270 +0,0 @@ -// $Id$ -// -// Copyright (c) 2018-, Frederic A. Dreyer, Keith Hamilton, Alexander Karlberg, -// Gavin P. Salam, Ludovic Scyboz, Gregory Soyez, Rob Verheyen -// -// This file is part of FastJet contrib. -// -// It is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2 of the License, or (at -// your option) any later version. -// -// It is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -// License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this code. If not, see <http://www.gnu.org/licenses/>. -//---------------------------------------------------------------------- - -#ifndef __FASTJET_CONTRIB_EEHELPERS_HH__ -#define __FASTJET_CONTRIB_EEHELPERS_HH__ - -#include "fastjet/PseudoJet.hh" -#include <array> -#include <limits> - -FASTJET_BEGIN_NAMESPACE - -namespace contrib{ -namespace lund_plane { - -//---------------------------------------------------------------------- -/// Returns the 3-vector cross-product of p1 and p2. If lightlike is false -/// then the energy component is zero; if it's true the the energy component -/// is arranged so that the vector is lighlike -inline PseudoJet cross_product(const PseudoJet & p1, const PseudoJet & p2, bool lightlike=false) { - double px = p1.py() * p2.pz() - p2.py() * p1.pz(); - double py = p1.pz() * p2.px() - p2.pz() * p1.px(); - double pz = p1.px() * p2.py() - p2.px() * p1.py(); - - double E; - if (lightlike) { - E = sqrt(px*px + py*py + pz*pz); - } else { - E = 0.0; - } - return PseudoJet(px, py, pz, E); -} - -/// Map angles to [-pi, pi] -inline const double map_to_pi(const double &phi) { - if (phi < -M_PI) return phi + 2 * M_PI; - else if (phi > M_PI) return phi - 2 * M_PI; - else return phi; -} - -inline double dot_product_3d(const PseudoJet & a, const PseudoJet & b) { - return a.px()*b.px() + a.py()*b.py() + a.pz()*b.pz(); -} - -/// Returns (1-cos theta) where theta is the angle between p1 and p2 -inline double one_minus_costheta(const PseudoJet & p1, const PseudoJet & p2) { - - if (p1.m2() == 0 && p2.m2() == 0) { - // use the 4-vector dot product. - // For massless particles it gives us E1*E2*(1-cos theta) - return dot_product(p1,p2) / (p1.E() * p2.E()); - } else { - double p1mod = p1.modp(); - double p2mod = p2.modp(); - double p1p2mod = p1mod*p2mod; - double dot = dot_product_3d(p1,p2); - - if (dot > (1-std::numeric_limits<double>::epsilon()) * p1p2mod) { - PseudoJet cross_result = cross_product(p1, p2, false); - // the mass^2 of cross_result is equal to - // -(px^2 + py^2 + pz^2) = (p1mod*p2mod*sintheta_ab)^2 - // so we can get - return -cross_result.m2()/(p1p2mod * (p1p2mod+dot)); - } - - return 1.0 - dot/p1p2mod; - - } -} - -/// Get the angle between two planes defined by normalized vectors -/// n1, n2. The sign is decided by the direction of a vector n, such that -/// if n1 x n2 points in the same direction as n, the angle is positive. -/// The result is in the range -pi < theta < pi. -/// -/// For example, labelling (x,y,z), and taking n1 = (1,0,0), -/// n2 = (0,1,0), n = (0,0,1), then the angle is +pi/2. -inline double signed_angle_between_planes(const PseudoJet& n1, - const PseudoJet& n2, const PseudoJet& n) { - - // Two vectors passed as arguments should be normalised to 1. - assert(fabs(n1.modp()-1) < sqrt(std::numeric_limits<double>::epsilon()) && fabs(n2.modp()-1) < sqrt(std::numeric_limits<double>::epsilon())); - - double omcost = one_minus_costheta(n1,n2); - double theta; - - // If theta ~ pi, we return pi. - if(fabs(omcost-2) < sqrt(std::numeric_limits<double>::epsilon())) { - theta = M_PI; - } else if (omcost > sqrt(std::numeric_limits<double>::epsilon())) { - double cos_theta = 1.0 - omcost; - theta = acos(cos_theta); - } else { - // we are at small angles, so use small-angle formulas - theta = sqrt(2. * omcost); - } - - PseudoJet cp = cross_product(n1,n2); - double sign = dot_product_3d(cp,n); - - if (sign > 0) return theta; - else return -theta; -} - -class Matrix3 { -public: - /// constructs an empty matrix - Matrix3() : matrix_({{{{0,0,0}}, {{0,0,0}}, {{0,0,0}}}}) {} - - /// constructs a diagonal matrix with "unit" along each diagonal entry - Matrix3(double unit) : matrix_({{{{unit,0,0}}, {{0,unit,0}}, {{0,0,unit}}}}) {} - - /// constructs a matrix from the array<array<...,3>,3> object - Matrix3(const std::array<std::array<double,3>,3> & mat) : matrix_(mat) {} - - /// returns the entry at row i, column j - inline double operator()(int i, int j) const { - return matrix_[i][j]; - } - - /// returns a matrix for carrying out azimuthal rotation - /// around the z direction by an angle phi - static Matrix3 azimuthal_rotation(double phi) { - double cos_phi = cos(phi); - double sin_phi = sin(phi); - Matrix3 phi_rot( {{ {{cos_phi, sin_phi, 0}}, - {{-sin_phi, cos_phi, 0}}, - {{0,0,1}}}}); - return phi_rot; - } - - /// returns a matrix for carrying out a polar-angle - /// rotation, in the z-x plane, by an angle theta - static Matrix3 polar_rotation(double theta) { - double cos_theta = cos(theta); - double sin_theta = sin(theta); - Matrix3 theta_rot( {{ {{cos_theta, 0, sin_theta}}, - {{0,1,0}}, - {{-sin_theta, 0, cos_theta}}}}); - return theta_rot; - } - - /// This provides a rotation matrix that takes the z axis to the - /// direction of p. With skip_pre_rotation = false (the default), it - /// has the characteristic that if p is close to the z axis then the - /// azimuthal angle of anything at much larger angle is conserved. - /// - /// If skip_pre_rotation is true, then the azimuthal angles are not - /// when p is close to the z axis. - template<class T> - static Matrix3 from_direction(const T & p, bool skip_pre_rotation = false) { - double pt = p.pt(); - double modp = p.modp(); - double cos_theta = p.pz() / modp; - double sin_theta = pt / modp; - double cos_phi, sin_phi; - if (pt > 0.0) { - cos_phi = p.px()/pt; - sin_phi = p.py()/pt; - } else { - cos_phi = 1.0; - sin_phi = 0.0; - } - - Matrix3 phi_rot({{ {{ cos_phi,-sin_phi, 0 }}, - {{ sin_phi, cos_phi, 0 }}, - {{ 0, 0, 1 }} }}); - Matrix3 theta_rot( {{ {{ cos_theta, 0, sin_theta }}, - {{ 0, 1, 0 }}, - {{-sin_theta, 0, cos_theta }} }}); - - // since we have orthogonal matrices, the inverse and transpose - // are identical; we use the transpose for the frontmost rotation - // because - if (skip_pre_rotation) { - return phi_rot * theta_rot; - } else { - return phi_rot * (theta_rot * phi_rot.transpose()); - } - } - - template<class T> - static Matrix3 from_direction_no_pre_rotn(const T & p) { - return from_direction(p,true); - } - - - - /// returns the transposed matrix - Matrix3 transpose() const { - // 00 01 02 - // 10 11 12 - // 20 21 22 - Matrix3 result = *this; - std::swap(result.matrix_[0][1],result.matrix_[1][0]); - std::swap(result.matrix_[0][2],result.matrix_[2][0]); - std::swap(result.matrix_[1][2],result.matrix_[2][1]); - return result; - } - - // returns the product with another matrix - Matrix3 operator*(const Matrix3 & other) const { - Matrix3 result; - // r_{ij} = sum_k this_{ik} & other_{kj} - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - for (int k = 0; k < 3; k++) { - result.matrix_[i][j] += this->matrix_[i][k] * other.matrix_[k][j]; - } - } - } - return result; - } - - friend std::ostream & operator<<(std::ostream & ostr, const Matrix3 & mat); -private: - std::array<std::array<double,3>,3> matrix_; -}; - -inline std::ostream & operator<<(std::ostream & ostr, const Matrix3 & mat) { - ostr << mat.matrix_[0][0] << " " << mat.matrix_[0][1] << " " << mat.matrix_[0][2] << std::endl; - ostr << mat.matrix_[1][0] << " " << mat.matrix_[1][1] << " " << mat.matrix_[1][2] << std::endl; - ostr << mat.matrix_[2][0] << " " << mat.matrix_[2][1] << " " << mat.matrix_[2][2] << std::endl; - return ostr; -} - -/// returns the project of this matrix with the PseudoJet, -/// maintaining the 4th component of the PseudoJet unchanged -inline PseudoJet operator*(const Matrix3 & mat, const PseudoJet & p) { - // r_{i} = m_{ij} p_j - std::array<double,3> res3{{0,0,0}}; - for (unsigned i = 0; i < 3; i++) { - for (unsigned j = 0; j < 3; j++) { - res3[i] += mat(i,j) * p[j]; - } - } - // return a jet that maintains all internal pointers by - // initialising the result from the input jet and - // then resetting the momentum. - PseudoJet result(p); - // maintain the energy component as it was - result.reset_momentum(res3[0], res3[1], res3[2], p[3]); - return result; -} - -} // namespace lund_plane -} // namespace contrib - -FASTJET_END_NAMESPACE - -#endif // __FASTJET_CONTRIB_EEHELPERS_HH__ - Index: contrib/contribs/LundPlane/trunk/LundWithSecondary.hh =================================================================== --- contrib/contribs/LundPlane/trunk/LundWithSecondary.hh (revision 1459) +++ contrib/contribs/LundPlane/trunk/LundWithSecondary.hh (revision 1460) @@ -1,126 +0,0 @@ -// $Id$ -// -// Copyright (c) 2018-, Frederic A. Dreyer, Keith Hamilton, Alexander Karlberg, -// Gavin P. Salam, Ludovic Scyboz, Gregory Soyez, Rob Verheyen -// -//---------------------------------------------------------------------- -// This file is part of FastJet contrib. -// -// It is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2 of the License, or (at -// your option) any later version. -// -// It is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -// License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this code. If not, see <http://www.gnu.org/licenses/>. -//---------------------------------------------------------------------- - -#ifndef __FASTJET_CONTRIB_LUNDWITHSECONDARY_HH__ -#define __FASTJET_CONTRIB_LUNDWITHSECONDARY_HH__ - -#include "LundGenerator.hh" -#include "SecondaryLund.hh" - -FASTJET_BEGIN_NAMESPACE - -namespace contrib{ - -//---------------------------------------------------------------------- -/// \class LundWithSecondary -/// Define a primary and secondary Lund plane -/// -/// \param secondary_def definition used for the leading emission. -// -class LundWithSecondary { -public: - /// LundWithSecondary constructor - LundWithSecondary(SecondaryLund * secondary_def = 0) - : secondary_def_(secondary_def) {} - - /// LundWithSecondary constructor with jet alg - LundWithSecondary(JetAlgorithm jet_alg, - SecondaryLund * secondary_def = 0) - : lund_gen_(jet_alg), secondary_def_(secondary_def) {} - - /// LundWithSecondary constructor with jet def - LundWithSecondary(const JetDefinition & jet_def, - SecondaryLund * secondary_def = 0) - : lund_gen_(jet_def), secondary_def_(secondary_def) {} - - /// destructor - virtual ~LundWithSecondary() {} - - /// primary Lund declustering - std::vector<LundDeclustering> primary(const PseudoJet& jet) const; - - /// secondary Lund declustering (slow) - std::vector<LundDeclustering> secondary(const PseudoJet& jet) const; - - /// secondary Lund declustering with primary sequence as input - std::vector<LundDeclustering> secondary( - const std::vector<LundDeclustering> & declusts) const; - - /// return the index associated of the primary declustering that is to be - /// used for the secondary plane. - int secondary_index(const std::vector<LundDeclustering> & declusts) const; - - /// description of the class - std::string description() const; - -private: - /// lund generator - LundGenerator lund_gen_; - - /// secondary definition - SecondaryLund * secondary_def_; -}; - - -// //---------------------------------------------------------------------- -// /// \class LundWithSecondaryAndTertiary -// /// Define a primary, secondary and tertiary Lund plane -// class LundWithSecondaryAndTertiary : public LundWithSecondary { -// public: -// /// LundWithSecondaryAndTertiary constructor -// LundWithSecondaryAndTertiary(SecondaryLund * secondary_def = 0, -// SecondaryLund * tertiary_def = 0) -// : LundWithSecondary(secondary_def), tertiary_def_(tertiary_def) {} - -// /// LundWithSecondaryAndTertiary constructor with jet alg -// LundWithSecondaryAndTertiary(JetAlgorithm jet_alg, -// SecondaryLund * secondary_def = 0, -// SecondaryLund * tertiary_def = 0) -// : LundWithSecondary(jet_alg, secondary_def), tertiary_def_(tertiary_def) {} - -// /// LundWithSecondaryAndTertiary constructor with jet def -// LundWithSecondaryAndTertiary(const JetDefinition & jet_def, -// SecondaryLund * secondary_def = 0, -// SecondaryLund * tertiary_def = 0) -// : LundWithSecondary(jet_def, secondary_def), tertiary_def_(tertiary_def) {} - -// /// destructor -// virtual ~LundWithSecondaryAndTertiary() {} - -// /// tertiary Lund declustering -// virtual std::vector<LundDeclustering> tertiary(const PseudoJet& jet) const; - -// /// description of the class -// virtual std::string description() const; - -// private: -// /// tertiary definition -// SecondaryLund * tertiary_def_; -// }; - - -} // namespace contrib - -FASTJET_END_NAMESPACE - -#endif // __FASTJET_CONTRIB_LUNDWITHSECONDARY_HH__ - Index: contrib/contribs/LundPlane/trunk/LundGenerator.hh =================================================================== --- contrib/contribs/LundPlane/trunk/LundGenerator.hh (revision 1459) +++ contrib/contribs/LundPlane/trunk/LundGenerator.hh (revision 1460) @@ -1,138 +0,0 @@ -// $Id$ -// -// Copyright (c) 2018-, Frederic A. Dreyer, Keith Hamilton, Alexander Karlberg, -// Gavin P. Salam, Ludovic Scyboz, Gregory Soyez, Rob Verheyen -// -//---------------------------------------------------------------------- -// This file is part of FastJet contrib. -// -// It is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2 of the License, or (at -// your option) any later version. -// -// It is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -// License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this code. If not, see <http://www.gnu.org/licenses/>. -//---------------------------------------------------------------------- - -#ifndef __FASTJET_CONTRIB_LUNDGENERATOR_HH__ -#define __FASTJET_CONTRIB_LUNDGENERATOR_HH__ - -#include <fastjet/internal/base.hh> -#include "fastjet/tools/Recluster.hh" -#include "fastjet/JetDefinition.hh" -#include "fastjet/PseudoJet.hh" -#include <string> -#include <vector> -#include <utility> - -// TODO: -// - add interface to write declusterings to json files -// [gps, possibly as a separate header, in order to factorise the json.hh dependence] -// - something for pileup subtraction? -// - do we want to update json.hh to latest? And handle -// the precision issue more elegantly than the current -// hack of editing json.hh -// - what do we do about the fact that json.hh is c++11? - -FASTJET_BEGIN_NAMESPACE - -namespace contrib{ - -class LundGenerator; - -//---------------------------------------------------------------------- -/// \class LundDeclustering -/// Contains the declustering variables associated with a single qnode -/// on the Lund plane -class LundDeclustering { -public: - - /// return the pair PseudoJet, i.e. sum of the two subjets - const PseudoJet & pair() const {return pair_;} - /// returns the subjet with larger transverse momentum - const PseudoJet & harder() const {return harder_;} - /// returns the subjet with smaller transverse momentum - const PseudoJet & softer() const {return softer_;} - - - /// returns pair().m() [cached] - double m() const {return m_;} - - /// returns the rapidity-azimuth separation of the pair of subjets [cached] - double Delta() const {return Delta_;} - - /// returns softer().pt() / (softer().pt() + harder().pt()) [cached] - double z() const {return z_;} - - /// returns softer().pt() * Delta() [cached] - double kt() const {return kt_;} - - /// returns z() * Delta() [cached] - double kappa() const {return kappa_;} - - /// returns an azimuthal type angle of softer() around harder() - double psi() const {return psi_;} - - /// returns the x,y coordinates that are used in the Lund-plane plots - /// of arXiv:1807.04758: ln(1/Delta()), and ln(kt()) respectively - std::pair<double,double> const lund_coordinates() const { - return std::pair<double,double>(std::log(1.0/Delta()),std::log(kt())); - } - - virtual ~LundDeclustering() {} - -private: - double m_, Delta_, z_, kt_, kappa_, psi_; - PseudoJet pair_, harder_, softer_; - -protected: - /// the constructor is private, because users will not generally be - /// constructing a LundDeclustering element themselves. - LundDeclustering(const PseudoJet& pair, - const PseudoJet& j1, const PseudoJet& j2); - - friend class LundGenerator; - -}; - - -//---------------------------------------------------------------------- -/// \class LundGenerator -/// Generates vector of LundDeclustering for a given jet -/// corresponding to its Lund plane. -class LundGenerator : public FunctionOfPseudoJet< std::vector<LundDeclustering> > { -public: - /// LundGenerator constructor - LundGenerator(JetAlgorithm jet_alg = cambridge_algorithm) - : recluster_(JetDefinition(jet_alg, JetDefinition::max_allowable_R)){} - - /// LundGenerator constructor with jet definition - LundGenerator(const JetDefinition & jet_def) : recluster_(jet_def){} - - /// destructor - virtual ~LundGenerator() {} - - /// obtain the declusterings of the primary plane of the jet - virtual std::vector<LundDeclustering> result(const PseudoJet& jet) const; - - /// description of the class - virtual std::string description() const; - -private: - /// recluster definition - Recluster recluster_; -}; - - -} // namespace contrib - -FASTJET_END_NAMESPACE - -#endif // __FASTJET_CONTRIB_LUNDGENERATOR_HH__ - Index: contrib/contribs/LundPlane/trunk/SecondaryLund.hh =================================================================== --- contrib/contribs/LundPlane/trunk/SecondaryLund.hh (revision 1459) +++ contrib/contribs/LundPlane/trunk/SecondaryLund.hh (revision 1460) @@ -1,122 +0,0 @@ -// $Id$ -// -// Copyright (c) 2018-, Frederic A. Dreyer, Keith Hamilton, Alexander Karlberg, -// Gavin P. Salam, Ludovic Scyboz, Gregory Soyez, Rob Verheyen -// -//---------------------------------------------------------------------- -// This file is part of FastJet contrib. -// -// It is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2 of the License, or (at -// your option) any later version. -// -// It is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -// License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this code. If not, see <http://www.gnu.org/licenses/>. -//---------------------------------------------------------------------- - -#ifndef __FASTJET_CONTRIB_SECONDARYLUND_HH__ -#define __FASTJET_CONTRIB_SECONDARYLUND_HH__ - -#include "LundGenerator.hh" - -FASTJET_BEGIN_NAMESPACE - -namespace contrib{ - -//---------------------------------------------------------------------- -/// \class SecondaryLund -/// Base class for definitions of the leading emission -class SecondaryLund { -public: - /// SecondaryLund constructor - SecondaryLund() {} - - /// destructor - virtual ~SecondaryLund() {} - - /// returns the index of branch corresponding to the root of the secondary plane - virtual int result(const std::vector<LundDeclustering> & declusts) const = 0; - - int operator()(const std::vector<LundDeclustering> & declusts) const { - return result(declusts); - } - - /// description of the class - virtual std::string description() const; -}; - -//---------------------------------------------------------------------- -/// \class SecondaryLund_mMDT -/// Contains a definition for the leading emission using mMDTZ -class SecondaryLund_mMDT : public SecondaryLund { -public: - /// SecondaryLund_mMDT constructor - SecondaryLund_mMDT(double zcut = 0.025) : zcut_(zcut) {} - - /// destructor - virtual ~SecondaryLund_mMDT() {} - - /// returns the index of branch corresponding to the root of the secondary plane - virtual int result(const std::vector<LundDeclustering> & declusts) const; - - /// description of the class - virtual std::string description() const; -private: - /// zcut parameter - double zcut_; -}; - -//---------------------------------------------------------------------- -/// \class SecondaryLund_dotmMDT -/// Contains a definition for the leading emission using dotmMDT -class SecondaryLund_dotmMDT : public SecondaryLund { -public: - /// SecondaryLund_dotmMDT constructor - SecondaryLund_dotmMDT(double zcut = 0.025) : zcut_(zcut) {} - - /// destructor - virtual ~SecondaryLund_dotmMDT() {} - - /// returns the index of branch corresponding to the root of the secondary plane - virtual int result(const std::vector<LundDeclustering> & declusts) const; - - /// description of the class - virtual std::string description() const; - -private: - /// zcut parameter - double zcut_; -}; - -//---------------------------------------------------------------------- -/// \class SecondaryLund_Mass -/// Contains a definition for the leading emission using mass -class SecondaryLund_Mass : public SecondaryLund { -public: - /// SecondaryLund_Mass constructor (default mass reference is W mass) - SecondaryLund_Mass(double ref_mass = 80.4) : mref2_(ref_mass*ref_mass) {} - - /// destructor - virtual ~SecondaryLund_Mass() {} - - /// returns the index of branch corresponding to the root of the secondary plane - virtual int result(const std::vector<LundDeclustering> & declusts) const; - - /// description of the class - virtual std::string description() const; -private: - double mref2_; -}; - -} // namespace contrib - -FASTJET_END_NAMESPACE - -#endif // __FASTJET_CONTRIB_SECONDARYLUND_HH__ - Index: contrib/contribs/LundPlane/trunk/RecursiveLundEEGenerator.hh =================================================================== --- contrib/contribs/LundPlane/trunk/RecursiveLundEEGenerator.hh (revision 1459) +++ contrib/contribs/LundPlane/trunk/RecursiveLundEEGenerator.hh (revision 1460) @@ -1,364 +0,0 @@ -// $Id$ -// -// Copyright (c) 2018-, Frederic A. Dreyer, Keith Hamilton, Alexander Karlberg, -// Gavin P. Salam, Ludovic Scyboz, Gregory Soyez, Rob Verheyen -// -//---------------------------------------------------------------------- -// This file is part of FastJet contrib. -// -// It is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the -// Free Software Foundation; either version 2 of the License, or (at -// your option) any later version. -// -// It is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -// License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this code. If not, see <http://www.gnu.org/licenses/>. -//---------------------------------------------------------------------- - -#ifndef __FASTJET_CONTRIB_RECURSIVELUNDEEGENERATOR_HH__ -#define __FASTJET_CONTRIB_RECURSIVELUNDEEGENERATOR_HH__ - -#include "LundEEHelpers.hh" - -#include <fastjet/internal/base.hh> -#include "fastjet/tools/Recluster.hh" -#include "fastjet/JetDefinition.hh" -#include "fastjet/PseudoJet.hh" -#include <string> -#include <vector> -#include <utility> -#include <queue> - -using namespace std; - -FASTJET_BEGIN_NAMESPACE - -namespace contrib{ - -//---------------------------------------------------------------------- -/// \class LundEEDeclustering -/// Contains the declustering variables associated with a single node -/// on the LundEE plane -class LundEEDeclustering { -public: - - /// return the pair PseudoJet, i.e. sum of the two subjets - const PseudoJet & pair() const {return pair_;} - /// returns the subjet with larger transverse momentum - const PseudoJet & harder() const {return harder_;} - /// returns the subjet with smaller transverse momentum - const PseudoJet & softer() const {return softer_;} - - - /// returns pair().m() [cached] - double m() const {return m_;} - - /// returns the effective pseudorapidity of the emission [cached] - double eta() const {return eta_;} - - /// returns sin(theta) of the branching [cached] - double sin_theta() const {return sin_theta_;} - - /// returns softer().modp() / (softer().modp() + harder().modp()) [cached] - double z() const {return z_;} - - /// returns softer().modp() * sin(theta()) [cached] - double kt() const {return kt_;} - - /// returns ln(softer().modp() * sin(theta())) [cached] - double lnkt() const {return lnkt_;} - - /// returns z() * Delta() [cached] - double kappa() const {return kappa_;} - - /// returns the index of the plane to which this branching belongs - int iplane() const {return iplane_;} - - /// returns the depth of the plane on which this declustering - /// occurred. 0 is the primary plane, 1 is the first set of leaves, etc. - int depth() const {return depth_;} - - /// returns iplane (plane index) of the leaf associated with the - /// potential further declustering of the softer of the objects in - /// this splitting - int leaf_iplane() const {return leaf_iplane_;} - - /// Returns sign_s, indicating the initial parent jet index of this splitting - int sign_s() const {return sign_s_;} - - /// returns an azimuthal angle psibar associated with this - /// declustering. The actual value of psibar is arbitrary and IR - /// unsafe (but see below), while differences in psibar values between - /// different clusterings are meaningful. - /// - /// The absolute value of psibar should in general not be used, but - /// it has the following properties. (1) the first (largest-angle) splitting - /// ("ref") in the positive-z hemisphere defines psibar=0 (if there is - /// no splitting in that hemisphere then the first splitting in - /// the negative-z hemisphere does). If the +z jet aligns along the z - /// axis, then psibar of collinear splitting i in that jet is - /// - /// psibar_i = phi_i - phi_ref - /// - /// For the negative-z jet, the psibar of collinear splitting i is - /// - /// psibar_i = phi_i - pi - phi_ref - /// - double psibar() const {return psibar_;} - - /// (DEPRECATED) - /// returns an azimuthal type angle between this declustering plane and the previous one - /// Note: one should use psibar() instead, since we found that this definition of psi is - /// not invariant under rotations of the event - double psi() const {return psi_;} - - /// update the azimuthal angle (deprecated) - void set_psi(double psi) {psi_ = psi;} - - - /// returns the coordinates in the Lund plane - std::pair<double,double> const lund_coordinates() const { - return std::pair<double,double>(eta_,lnkt_); - } - - virtual ~LundEEDeclustering() {} - -private: - int iplane_; - double psi_, psibar_, lnkt_, eta_; - double m_, z_, kt_, kappa_, sin_theta_; - PseudoJet pair_, harder_, softer_; - int depth_ = -1, leaf_iplane_ = -1; - int sign_s_; - -protected: - - /// default ctor (protected, should not normally be needed by users, - /// but can be useful for derived classes) - LundEEDeclustering() {} - - /// the constructor is protected, because users will not generally be - /// constructing a LundEEDeclustering element themselves. - LundEEDeclustering(const PseudoJet& pair, - const PseudoJet& j1, const PseudoJet& j2, - int iplane = -1, double psi = 0.0, double psibar = 0.0, int depth = -1, int leaf_iplane = -1, int sign_s = 1); - - friend class RecursiveLundEEGenerator; - -}; - - -/// Default comparison operator for LundEEDeclustering, using kt as the ordering. -/// Useful when including declusterings in structures like priority queues -inline bool operator<(const LundEEDeclustering& d1, const LundEEDeclustering& d2) { - return d1.kt() < d2.kt(); -} - -//---------------------------------------------------------------------- -/// Class to carry out Lund declustering to get anything from the -/// primary Lund plane declusterings to the full Lund diagram with all -/// its leaves, etc. -class RecursiveLundEEGenerator { - public: - /// constructs a RecursiveLundEEGenerator with the specified depth. - /// - depth = 0 means only primary declusterings are registered - /// - depth = 1 means the first set of leaves are declustered - /// - ... - /// - depth < 0 means no limit, i.e. recurse through all leaves - /// - /// The psibar values that are set in the result Lund tree have the - /// following property: - /// - /// - if the jet with the larger pz has splittings, then its - /// first splitting has psibar = 0 - /// - otherwise the first splitting of the other jet has psibar = 0 - /// - /// Note that this makes psibar IR unsafe (because an arbitrarily soft - /// splitting can be the one that gets the reference psibar=0 value), - /// but differences between psibar values are IR safe. - /// - /// NB: The dynamical_psi_ref option relates to the deprecated definition of psi - /// New code should use the psibar() function and dynamical_psi_ref - /// is irrelevant. - RecursiveLundEEGenerator(int max_depth = 0, bool dynamical_psi_ref = false) : - max_depth_(max_depth), nx_(1,0,0,0), ny_(0,1,0,0), dynamical_psi_ref_(dynamical_psi_ref) - {} - - /// destructor - virtual ~RecursiveLundEEGenerator() {} - - /// This takes a cluster sequence with an e+e- C/A style algorithm, e.g. - /// EECambridgePlugin(ycut=1.0). - /// - /// The output is a vector of LundEEDeclustering objects, ordered - /// according to kt - virtual std::vector<LundEEDeclustering> result(const ClusterSequence & cs) const { - std::vector<PseudoJet> exclusive_jets = cs.exclusive_jets(2); - assert(exclusive_jets.size() == 2); - - // order the two jets according to momentum along z axis - if (exclusive_jets[0].pz() < exclusive_jets[1].pz()) { - std::swap(exclusive_jets[0],exclusive_jets[1]); - } - - PseudoJet d_ev = exclusive_jets[0] - exclusive_jets[1]; - lund_plane::Matrix3 rotmat = lund_plane::Matrix3::from_direction(d_ev); - - std::vector<LundEEDeclustering> declusterings; - int depth = 0; - int max_iplane_sofar = 1; - -// 2024-01: new code, that fixes up issue of psibar differences -// between hemispheres. If RLEEG_NEWPSIBAR is false, answers -// will come out wrong. -#define RLEEG_NEWPSIBAR -#ifdef RLEEG_NEWPSIBAR - // 2024-01 -- attempt at new definition of psibar - PseudoJet ref_plane; - double last_psibar = 0.; - bool first_time = true; - - for (unsigned ijet = 0; ijet < exclusive_jets.size(); ijet++) { - int sign_s = ijet == 0? +1 : -1; - append_to_vector(declusterings, exclusive_jets[ijet], depth, ijet, max_iplane_sofar, - rotmat, sign_s, ref_plane, last_psibar, first_time); - } -#else - for (unsigned ijet = 0; ijet < exclusive_jets.size(); ijet++) { - - // reference direction for psibar calculation - PseudoJet axis = d_ev/sqrt(d_ev.modp2()); - PseudoJet ref_plane = axis; - - int sign_s = ijet == 0? +1 : -1; - bool - // We can pass a vector normal to a plane of reference for phi definitions - append_to_vector(declusterings, exclusive_jets[ijet], depth, ijet, max_iplane_sofar, - rotmat, sign_s, ref_plane, 0., true); - } -#endif - - // a typedef to save typing below - typedef LundEEDeclustering LD; - // sort so that declusterings are returned in order of decreasing - // kt (if result of the lambda is true, then first object appears - // before the second one in the final sorted list) - sort(declusterings.begin(), declusterings.end(), - [](const LD & d1, const LD & d2){return d1.kt() > d2.kt();}); - - return declusterings; - } - - private: - - /// internal routine to recursively carry out the declusterings, - /// adding each one to the declusterings vector; the primary - /// ones are dealt with first (from large to small angle), - /// and then secondary ones take place. - void append_to_vector(std::vector<LundEEDeclustering> & declusterings, - const PseudoJet & jet, int depth, - int iplane, int & max_iplane_sofar, - const lund_plane::Matrix3 & rotmat, int sign_s, - PseudoJet & psibar_ref_plane, - const double & last_psibar, bool & first_time) const { - PseudoJet j1, j2; - if (!jet.has_parents(j1, j2)) return; - if (j1.modp2() < j2.modp2()) std::swap(j1,j2); - - // calculation of azimuth psi - lund_plane::Matrix3 new_rotmat; - if (dynamical_psi_ref_) { - new_rotmat = lund_plane::Matrix3::from_direction(rotmat.transpose()*(sign_s*jet)) * rotmat; - } else { - new_rotmat = rotmat; - } - PseudoJet rx = new_rotmat * nx_; - PseudoJet ry = new_rotmat * ny_; - PseudoJet u1 = j1/j1.modp(), u2 = j2/j2.modp(); - PseudoJet du = u2 - u1; - double x = du.px() * rx.px() + du.py() * rx.py() + du.pz() * rx.pz(); - double y = du.px() * ry.px() + du.py() * ry.py() + du.pz() * ry.pz(); - double psi = atan2(y,x); - - // calculation of psibar - double psibar = 0.; - PseudoJet n1, n2; - - // First psibar for this jet - if (first_time) { - -#ifdef RLEEG_NEWPSIBAR -// 2024-01: new code, that fixes up issue of psibar differences -// between hemispheres - assert(last_psibar == 0.0); - psibar = 0.0; - n2 = lund_plane::cross_product(j1,j2); - n2 /= n2.modp(); - psibar_ref_plane = n2; - first_time = false; -#else - // Compute the angle between the planes spanned by (some axis,j1) and by (j1,j2) - n1 = lund_plane::cross_product(psibar_ref_plane,j1); - n2 = lund_plane::cross_product(j1,j2); - - double signed_angle = 0.; - n2 /= n2.modp(); - if (n1.modp() != 0) { - n1 /= n1.modp(); - signed_angle = lund_plane::signed_angle_between_planes(n1,n2,j1); - } - - psibar = lund_plane::map_to_pi(j1.phi() + signed_angle); -#endif - } - // Else take the value of psibar_i and the plane from the last splitting to define psibar_{i+1} - // The signed angle is multiplied by sign_s (+1 for the +z hemisphere, -1 for the -z hemisphere) - // to take the correct orientation into account. - else { - n2 = lund_plane::cross_product(j1,j2); - n2 /= n2.modp(); - psibar = lund_plane::map_to_pi(last_psibar + sign_s*lund_plane::signed_angle_between_planes(psibar_ref_plane, n2, j1)); - } - - int leaf_iplane = -1; - // we will recurse into the softer "parent" only if the depth is - // not yet at its limit or if there is no limit on the depth (max_depth<0) - bool recurse_into_softer = (depth < max_depth_ || max_depth_ < 0); - if (recurse_into_softer) { - max_iplane_sofar += 1; - leaf_iplane = max_iplane_sofar; - } - - LundEEDeclustering declust(jet, j1, j2, iplane, psi, psibar, depth, leaf_iplane, sign_s); - declusterings.push_back(declust); - - // now recurse - // for the definition of psibar, we recursively pass the last splitting plane (normal to n2) and the last value - // of psibar - bool lcl_first_time = false; - append_to_vector(declusterings, j1, depth, iplane, max_iplane_sofar, new_rotmat, sign_s, n2, psibar, lcl_first_time); - if (recurse_into_softer) { - append_to_vector(declusterings, j2, depth+1, leaf_iplane, max_iplane_sofar, new_rotmat, sign_s, n2, psibar, lcl_first_time); - } - } - - int max_depth_ = 0; - /// vectors used to help define psi - PseudoJet nx_; - PseudoJet ny_; - bool dynamical_psi_ref_; -}; - -} // namespace contrib - -FASTJET_END_NAMESPACE - -/// for output of declustering information -std::ostream & operator<<(std::ostream & ostr, const fastjet::contrib::LundEEDeclustering & d); - -#endif // __FASTJET_CONTRIB_RECURSIVELUNDEEGENERATOR_HH__ Index: contrib/contribs/LundPlane/trunk/include/fastjet/contrib/LundWithSecondary.hh =================================================================== --- contrib/contribs/LundPlane/trunk/include/fastjet/contrib/LundWithSecondary.hh (revision 0) +++ contrib/contribs/LundPlane/trunk/include/fastjet/contrib/LundWithSecondary.hh (revision 1460) @@ -0,0 +1,126 @@ +// $Id$ +// +// Copyright (c) 2018-, Frederic A. Dreyer, Keith Hamilton, Alexander Karlberg, +// Gavin P. Salam, Ludovic Scyboz, Gregory Soyez, Rob Verheyen +// +//---------------------------------------------------------------------- +// This file is part of FastJet contrib. +// +// It is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2 of the License, or (at +// your option) any later version. +// +// It is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +// License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this code. If not, see <http://www.gnu.org/licenses/>. +//---------------------------------------------------------------------- + +#ifndef __FASTJET_CONTRIB_LUNDWITHSECONDARY_HH__ +#define __FASTJET_CONTRIB_LUNDWITHSECONDARY_HH__ + +#include "LundGenerator.hh" +#include "SecondaryLund.hh" + +FASTJET_BEGIN_NAMESPACE + +namespace contrib{ + +//---------------------------------------------------------------------- +/// \class LundWithSecondary +/// Define a primary and secondary Lund plane +/// +/// \param secondary_def definition used for the leading emission. +// +class LundWithSecondary { +public: + /// LundWithSecondary constructor + LundWithSecondary(SecondaryLund * secondary_def = 0) + : secondary_def_(secondary_def) {} + + /// LundWithSecondary constructor with jet alg + LundWithSecondary(JetAlgorithm jet_alg, + SecondaryLund * secondary_def = 0) + : lund_gen_(jet_alg), secondary_def_(secondary_def) {} + + /// LundWithSecondary constructor with jet def + LundWithSecondary(const JetDefinition & jet_def, + SecondaryLund * secondary_def = 0) + : lund_gen_(jet_def), secondary_def_(secondary_def) {} + + /// destructor + virtual ~LundWithSecondary() {} + + /// primary Lund declustering + std::vector<LundDeclustering> primary(const PseudoJet& jet) const; + + /// secondary Lund declustering (slow) + std::vector<LundDeclustering> secondary(const PseudoJet& jet) const; + + /// secondary Lund declustering with primary sequence as input + std::vector<LundDeclustering> secondary( + const std::vector<LundDeclustering> & declusts) const; + + /// return the index associated of the primary declustering that is to be + /// used for the secondary plane. + int secondary_index(const std::vector<LundDeclustering> & declusts) const; + + /// description of the class + std::string description() const; + +private: + /// lund generator + LundGenerator lund_gen_; + + /// secondary definition + SecondaryLund * secondary_def_; +}; + + +// //---------------------------------------------------------------------- +// /// \class LundWithSecondaryAndTertiary +// /// Define a primary, secondary and tertiary Lund plane +// class LundWithSecondaryAndTertiary : public LundWithSecondary { +// public: +// /// LundWithSecondaryAndTertiary constructor +// LundWithSecondaryAndTertiary(SecondaryLund * secondary_def = 0, +// SecondaryLund * tertiary_def = 0) +// : LundWithSecondary(secondary_def), tertiary_def_(tertiary_def) {} + +// /// LundWithSecondaryAndTertiary constructor with jet alg +// LundWithSecondaryAndTertiary(JetAlgorithm jet_alg, +// SecondaryLund * secondary_def = 0, +// SecondaryLund * tertiary_def = 0) +// : LundWithSecondary(jet_alg, secondary_def), tertiary_def_(tertiary_def) {} + +// /// LundWithSecondaryAndTertiary constructor with jet def +// LundWithSecondaryAndTertiary(const JetDefinition & jet_def, +// SecondaryLund * secondary_def = 0, +// SecondaryLund * tertiary_def = 0) +// : LundWithSecondary(jet_def, secondary_def), tertiary_def_(tertiary_def) {} + +// /// destructor +// virtual ~LundWithSecondaryAndTertiary() {} + +// /// tertiary Lund declustering +// virtual std::vector<LundDeclustering> tertiary(const PseudoJet& jet) const; + +// /// description of the class +// virtual std::string description() const; + +// private: +// /// tertiary definition +// SecondaryLund * tertiary_def_; +// }; + + +} // namespace contrib + +FASTJET_END_NAMESPACE + +#endif // __FASTJET_CONTRIB_LUNDWITHSECONDARY_HH__ + Property changes on: contrib/contribs/LundPlane/trunk/include/fastjet/contrib/LundWithSecondary.hh ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: contrib/contribs/LundPlane/trunk/include/fastjet/contrib/LundGenerator.hh =================================================================== --- contrib/contribs/LundPlane/trunk/include/fastjet/contrib/LundGenerator.hh (revision 0) +++ contrib/contribs/LundPlane/trunk/include/fastjet/contrib/LundGenerator.hh (revision 1460) @@ -0,0 +1,138 @@ +// $Id$ +// +// Copyright (c) 2018-, Frederic A. Dreyer, Keith Hamilton, Alexander Karlberg, +// Gavin P. Salam, Ludovic Scyboz, Gregory Soyez, Rob Verheyen +// +//---------------------------------------------------------------------- +// This file is part of FastJet contrib. +// +// It is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2 of the License, or (at +// your option) any later version. +// +// It is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +// License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this code. If not, see <http://www.gnu.org/licenses/>. +//---------------------------------------------------------------------- + +#ifndef __FASTJET_CONTRIB_LUNDGENERATOR_HH__ +#define __FASTJET_CONTRIB_LUNDGENERATOR_HH__ + +#include <fastjet/internal/base.hh> +#include "fastjet/tools/Recluster.hh" +#include "fastjet/JetDefinition.hh" +#include "fastjet/PseudoJet.hh" +#include <string> +#include <vector> +#include <utility> + +// TODO: +// - add interface to write declusterings to json files +// [gps, possibly as a separate header, in order to factorise the json.hh dependence] +// - something for pileup subtraction? +// - do we want to update json.hh to latest? And handle +// the precision issue more elegantly than the current +// hack of editing json.hh +// - what do we do about the fact that json.hh is c++11? + +FASTJET_BEGIN_NAMESPACE + +namespace contrib{ + +class LundGenerator; + +//---------------------------------------------------------------------- +/// \class LundDeclustering +/// Contains the declustering variables associated with a single qnode +/// on the Lund plane +class LundDeclustering { +public: + + /// return the pair PseudoJet, i.e. sum of the two subjets + const PseudoJet & pair() const {return pair_;} + /// returns the subjet with larger transverse momentum + const PseudoJet & harder() const {return harder_;} + /// returns the subjet with smaller transverse momentum + const PseudoJet & softer() const {return softer_;} + + + /// returns pair().m() [cached] + double m() const {return m_;} + + /// returns the rapidity-azimuth separation of the pair of subjets [cached] + double Delta() const {return Delta_;} + + /// returns softer().pt() / (softer().pt() + harder().pt()) [cached] + double z() const {return z_;} + + /// returns softer().pt() * Delta() [cached] + double kt() const {return kt_;} + + /// returns z() * Delta() [cached] + double kappa() const {return kappa_;} + + /// returns an azimuthal type angle of softer() around harder() + double psi() const {return psi_;} + + /// returns the x,y coordinates that are used in the Lund-plane plots + /// of arXiv:1807.04758: ln(1/Delta()), and ln(kt()) respectively + std::pair<double,double> const lund_coordinates() const { + return std::pair<double,double>(std::log(1.0/Delta()),std::log(kt())); + } + + virtual ~LundDeclustering() {} + +private: + double m_, Delta_, z_, kt_, kappa_, psi_; + PseudoJet pair_, harder_, softer_; + +protected: + /// the constructor is private, because users will not generally be + /// constructing a LundDeclustering element themselves. + LundDeclustering(const PseudoJet& pair, + const PseudoJet& j1, const PseudoJet& j2); + + friend class LundGenerator; + +}; + + +//---------------------------------------------------------------------- +/// \class LundGenerator +/// Generates vector of LundDeclustering for a given jet +/// corresponding to its Lund plane. +class LundGenerator : public FunctionOfPseudoJet< std::vector<LundDeclustering> > { +public: + /// LundGenerator constructor + LundGenerator(JetAlgorithm jet_alg = cambridge_algorithm) + : recluster_(JetDefinition(jet_alg, JetDefinition::max_allowable_R)){} + + /// LundGenerator constructor with jet definition + LundGenerator(const JetDefinition & jet_def) : recluster_(jet_def){} + + /// destructor + virtual ~LundGenerator() {} + + /// obtain the declusterings of the primary plane of the jet + virtual std::vector<LundDeclustering> result(const PseudoJet& jet) const; + + /// description of the class + virtual std::string description() const; + +private: + /// recluster definition + Recluster recluster_; +}; + + +} // namespace contrib + +FASTJET_END_NAMESPACE + +#endif // __FASTJET_CONTRIB_LUNDGENERATOR_HH__ + Property changes on: contrib/contribs/LundPlane/trunk/include/fastjet/contrib/LundGenerator.hh ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: contrib/contribs/LundPlane/trunk/include/fastjet/contrib/SecondaryLund.hh =================================================================== --- contrib/contribs/LundPlane/trunk/include/fastjet/contrib/SecondaryLund.hh (revision 0) +++ contrib/contribs/LundPlane/trunk/include/fastjet/contrib/SecondaryLund.hh (revision 1460) @@ -0,0 +1,122 @@ +// $Id$ +// +// Copyright (c) 2018-, Frederic A. Dreyer, Keith Hamilton, Alexander Karlberg, +// Gavin P. Salam, Ludovic Scyboz, Gregory Soyez, Rob Verheyen +// +//---------------------------------------------------------------------- +// This file is part of FastJet contrib. +// +// It is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2 of the License, or (at +// your option) any later version. +// +// It is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +// License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this code. If not, see <http://www.gnu.org/licenses/>. +//---------------------------------------------------------------------- + +#ifndef __FASTJET_CONTRIB_SECONDARYLUND_HH__ +#define __FASTJET_CONTRIB_SECONDARYLUND_HH__ + +#include "LundGenerator.hh" + +FASTJET_BEGIN_NAMESPACE + +namespace contrib{ + +//---------------------------------------------------------------------- +/// \class SecondaryLund +/// Base class for definitions of the leading emission +class SecondaryLund { +public: + /// SecondaryLund constructor + SecondaryLund() {} + + /// destructor + virtual ~SecondaryLund() {} + + /// returns the index of branch corresponding to the root of the secondary plane + virtual int result(const std::vector<LundDeclustering> & declusts) const = 0; + + int operator()(const std::vector<LundDeclustering> & declusts) const { + return result(declusts); + } + + /// description of the class + virtual std::string description() const; +}; + +//---------------------------------------------------------------------- +/// \class SecondaryLund_mMDT +/// Contains a definition for the leading emission using mMDTZ +class SecondaryLund_mMDT : public SecondaryLund { +public: + /// SecondaryLund_mMDT constructor + SecondaryLund_mMDT(double zcut = 0.025) : zcut_(zcut) {} + + /// destructor + virtual ~SecondaryLund_mMDT() {} + + /// returns the index of branch corresponding to the root of the secondary plane + virtual int result(const std::vector<LundDeclustering> & declusts) const; + + /// description of the class + virtual std::string description() const; +private: + /// zcut parameter + double zcut_; +}; + +//---------------------------------------------------------------------- +/// \class SecondaryLund_dotmMDT +/// Contains a definition for the leading emission using dotmMDT +class SecondaryLund_dotmMDT : public SecondaryLund { +public: + /// SecondaryLund_dotmMDT constructor + SecondaryLund_dotmMDT(double zcut = 0.025) : zcut_(zcut) {} + + /// destructor + virtual ~SecondaryLund_dotmMDT() {} + + /// returns the index of branch corresponding to the root of the secondary plane + virtual int result(const std::vector<LundDeclustering> & declusts) const; + + /// description of the class + virtual std::string description() const; + +private: + /// zcut parameter + double zcut_; +}; + +//---------------------------------------------------------------------- +/// \class SecondaryLund_Mass +/// Contains a definition for the leading emission using mass +class SecondaryLund_Mass : public SecondaryLund { +public: + /// SecondaryLund_Mass constructor (default mass reference is W mass) + SecondaryLund_Mass(double ref_mass = 80.4) : mref2_(ref_mass*ref_mass) {} + + /// destructor + virtual ~SecondaryLund_Mass() {} + + /// returns the index of branch corresponding to the root of the secondary plane + virtual int result(const std::vector<LundDeclustering> & declusts) const; + + /// description of the class + virtual std::string description() const; +private: + double mref2_; +}; + +} // namespace contrib + +FASTJET_END_NAMESPACE + +#endif // __FASTJET_CONTRIB_SECONDARYLUND_HH__ + Property changes on: contrib/contribs/LundPlane/trunk/include/fastjet/contrib/SecondaryLund.hh ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: contrib/contribs/LundPlane/trunk/include/fastjet/contrib/RecursiveLundEEGenerator.hh =================================================================== --- contrib/contribs/LundPlane/trunk/include/fastjet/contrib/RecursiveLundEEGenerator.hh (revision 0) +++ contrib/contribs/LundPlane/trunk/include/fastjet/contrib/RecursiveLundEEGenerator.hh (revision 1460) @@ -0,0 +1,364 @@ +// $Id$ +// +// Copyright (c) 2018-, Frederic A. Dreyer, Keith Hamilton, Alexander Karlberg, +// Gavin P. Salam, Ludovic Scyboz, Gregory Soyez, Rob Verheyen +// +//---------------------------------------------------------------------- +// This file is part of FastJet contrib. +// +// It is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2 of the License, or (at +// your option) any later version. +// +// It is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +// License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this code. If not, see <http://www.gnu.org/licenses/>. +//---------------------------------------------------------------------- + +#ifndef __FASTJET_CONTRIB_RECURSIVELUNDEEGENERATOR_HH__ +#define __FASTJET_CONTRIB_RECURSIVELUNDEEGENERATOR_HH__ + +#include "LundEEHelpers.hh" + +#include <fastjet/internal/base.hh> +#include "fastjet/tools/Recluster.hh" +#include "fastjet/JetDefinition.hh" +#include "fastjet/PseudoJet.hh" +#include <string> +#include <vector> +#include <utility> +#include <queue> + +using namespace std; + +FASTJET_BEGIN_NAMESPACE + +namespace contrib{ + +//---------------------------------------------------------------------- +/// \class LundEEDeclustering +/// Contains the declustering variables associated with a single node +/// on the LundEE plane +class LundEEDeclustering { +public: + + /// return the pair PseudoJet, i.e. sum of the two subjets + const PseudoJet & pair() const {return pair_;} + /// returns the subjet with larger transverse momentum + const PseudoJet & harder() const {return harder_;} + /// returns the subjet with smaller transverse momentum + const PseudoJet & softer() const {return softer_;} + + + /// returns pair().m() [cached] + double m() const {return m_;} + + /// returns the effective pseudorapidity of the emission [cached] + double eta() const {return eta_;} + + /// returns sin(theta) of the branching [cached] + double sin_theta() const {return sin_theta_;} + + /// returns softer().modp() / (softer().modp() + harder().modp()) [cached] + double z() const {return z_;} + + /// returns softer().modp() * sin(theta()) [cached] + double kt() const {return kt_;} + + /// returns ln(softer().modp() * sin(theta())) [cached] + double lnkt() const {return lnkt_;} + + /// returns z() * Delta() [cached] + double kappa() const {return kappa_;} + + /// returns the index of the plane to which this branching belongs + int iplane() const {return iplane_;} + + /// returns the depth of the plane on which this declustering + /// occurred. 0 is the primary plane, 1 is the first set of leaves, etc. + int depth() const {return depth_;} + + /// returns iplane (plane index) of the leaf associated with the + /// potential further declustering of the softer of the objects in + /// this splitting + int leaf_iplane() const {return leaf_iplane_;} + + /// Returns sign_s, indicating the initial parent jet index of this splitting + int sign_s() const {return sign_s_;} + + /// returns an azimuthal angle psibar associated with this + /// declustering. The actual value of psibar is arbitrary and IR + /// unsafe (but see below), while differences in psibar values between + /// different clusterings are meaningful. + /// + /// The absolute value of psibar should in general not be used, but + /// it has the following properties. (1) the first (largest-angle) splitting + /// ("ref") in the positive-z hemisphere defines psibar=0 (if there is + /// no splitting in that hemisphere then the first splitting in + /// the negative-z hemisphere does). If the +z jet aligns along the z + /// axis, then psibar of collinear splitting i in that jet is + /// + /// psibar_i = phi_i - phi_ref + /// + /// For the negative-z jet, the psibar of collinear splitting i is + /// + /// psibar_i = phi_i - pi - phi_ref + /// + double psibar() const {return psibar_;} + + /// (DEPRECATED) + /// returns an azimuthal type angle between this declustering plane and the previous one + /// Note: one should use psibar() instead, since we found that this definition of psi is + /// not invariant under rotations of the event + double psi() const {return psi_;} + + /// update the azimuthal angle (deprecated) + void set_psi(double psi) {psi_ = psi;} + + + /// returns the coordinates in the Lund plane + std::pair<double,double> const lund_coordinates() const { + return std::pair<double,double>(eta_,lnkt_); + } + + virtual ~LundEEDeclustering() {} + +private: + int iplane_; + double psi_, psibar_, lnkt_, eta_; + double m_, z_, kt_, kappa_, sin_theta_; + PseudoJet pair_, harder_, softer_; + int depth_ = -1, leaf_iplane_ = -1; + int sign_s_; + +protected: + + /// default ctor (protected, should not normally be needed by users, + /// but can be useful for derived classes) + LundEEDeclustering() {} + + /// the constructor is protected, because users will not generally be + /// constructing a LundEEDeclustering element themselves. + LundEEDeclustering(const PseudoJet& pair, + const PseudoJet& j1, const PseudoJet& j2, + int iplane = -1, double psi = 0.0, double psibar = 0.0, int depth = -1, int leaf_iplane = -1, int sign_s = 1); + + friend class RecursiveLundEEGenerator; + +}; + + +/// Default comparison operator for LundEEDeclustering, using kt as the ordering. +/// Useful when including declusterings in structures like priority queues +inline bool operator<(const LundEEDeclustering& d1, const LundEEDeclustering& d2) { + return d1.kt() < d2.kt(); +} + +//---------------------------------------------------------------------- +/// Class to carry out Lund declustering to get anything from the +/// primary Lund plane declusterings to the full Lund diagram with all +/// its leaves, etc. +class RecursiveLundEEGenerator { + public: + /// constructs a RecursiveLundEEGenerator with the specified depth. + /// - depth = 0 means only primary declusterings are registered + /// - depth = 1 means the first set of leaves are declustered + /// - ... + /// - depth < 0 means no limit, i.e. recurse through all leaves + /// + /// The psibar values that are set in the result Lund tree have the + /// following property: + /// + /// - if the jet with the larger pz has splittings, then its + /// first splitting has psibar = 0 + /// - otherwise the first splitting of the other jet has psibar = 0 + /// + /// Note that this makes psibar IR unsafe (because an arbitrarily soft + /// splitting can be the one that gets the reference psibar=0 value), + /// but differences between psibar values are IR safe. + /// + /// NB: The dynamical_psi_ref option relates to the deprecated definition of psi + /// New code should use the psibar() function and dynamical_psi_ref + /// is irrelevant. + RecursiveLundEEGenerator(int max_depth = 0, bool dynamical_psi_ref = false) : + max_depth_(max_depth), nx_(1,0,0,0), ny_(0,1,0,0), dynamical_psi_ref_(dynamical_psi_ref) + {} + + /// destructor + virtual ~RecursiveLundEEGenerator() {} + + /// This takes a cluster sequence with an e+e- C/A style algorithm, e.g. + /// EECambridgePlugin(ycut=1.0). + /// + /// The output is a vector of LundEEDeclustering objects, ordered + /// according to kt + virtual std::vector<LundEEDeclustering> result(const ClusterSequence & cs) const { + std::vector<PseudoJet> exclusive_jets = cs.exclusive_jets(2); + assert(exclusive_jets.size() == 2); + + // order the two jets according to momentum along z axis + if (exclusive_jets[0].pz() < exclusive_jets[1].pz()) { + std::swap(exclusive_jets[0],exclusive_jets[1]); + } + + PseudoJet d_ev = exclusive_jets[0] - exclusive_jets[1]; + lund_plane::Matrix3 rotmat = lund_plane::Matrix3::from_direction(d_ev); + + std::vector<LundEEDeclustering> declusterings; + int depth = 0; + int max_iplane_sofar = 1; + +// 2024-01: new code, that fixes up issue of psibar differences +// between hemispheres. If RLEEG_NEWPSIBAR is false, answers +// will come out wrong. +#define RLEEG_NEWPSIBAR +#ifdef RLEEG_NEWPSIBAR + // 2024-01 -- attempt at new definition of psibar + PseudoJet ref_plane; + double last_psibar = 0.; + bool first_time = true; + + for (unsigned ijet = 0; ijet < exclusive_jets.size(); ijet++) { + int sign_s = ijet == 0? +1 : -1; + append_to_vector(declusterings, exclusive_jets[ijet], depth, ijet, max_iplane_sofar, + rotmat, sign_s, ref_plane, last_psibar, first_time); + } +#else + for (unsigned ijet = 0; ijet < exclusive_jets.size(); ijet++) { + + // reference direction for psibar calculation + PseudoJet axis = d_ev/sqrt(d_ev.modp2()); + PseudoJet ref_plane = axis; + + int sign_s = ijet == 0? +1 : -1; + bool + // We can pass a vector normal to a plane of reference for phi definitions + append_to_vector(declusterings, exclusive_jets[ijet], depth, ijet, max_iplane_sofar, + rotmat, sign_s, ref_plane, 0., true); + } +#endif + + // a typedef to save typing below + typedef LundEEDeclustering LD; + // sort so that declusterings are returned in order of decreasing + // kt (if result of the lambda is true, then first object appears + // before the second one in the final sorted list) + sort(declusterings.begin(), declusterings.end(), + [](const LD & d1, const LD & d2){return d1.kt() > d2.kt();}); + + return declusterings; + } + + private: + + /// internal routine to recursively carry out the declusterings, + /// adding each one to the declusterings vector; the primary + /// ones are dealt with first (from large to small angle), + /// and then secondary ones take place. + void append_to_vector(std::vector<LundEEDeclustering> & declusterings, + const PseudoJet & jet, int depth, + int iplane, int & max_iplane_sofar, + const lund_plane::Matrix3 & rotmat, int sign_s, + PseudoJet & psibar_ref_plane, + const double & last_psibar, bool & first_time) const { + PseudoJet j1, j2; + if (!jet.has_parents(j1, j2)) return; + if (j1.modp2() < j2.modp2()) std::swap(j1,j2); + + // calculation of azimuth psi + lund_plane::Matrix3 new_rotmat; + if (dynamical_psi_ref_) { + new_rotmat = lund_plane::Matrix3::from_direction(rotmat.transpose()*(sign_s*jet)) * rotmat; + } else { + new_rotmat = rotmat; + } + PseudoJet rx = new_rotmat * nx_; + PseudoJet ry = new_rotmat * ny_; + PseudoJet u1 = j1/j1.modp(), u2 = j2/j2.modp(); + PseudoJet du = u2 - u1; + double x = du.px() * rx.px() + du.py() * rx.py() + du.pz() * rx.pz(); + double y = du.px() * ry.px() + du.py() * ry.py() + du.pz() * ry.pz(); + double psi = atan2(y,x); + + // calculation of psibar + double psibar = 0.; + PseudoJet n1, n2; + + // First psibar for this jet + if (first_time) { + +#ifdef RLEEG_NEWPSIBAR +// 2024-01: new code, that fixes up issue of psibar differences +// between hemispheres + assert(last_psibar == 0.0); + psibar = 0.0; + n2 = lund_plane::cross_product(j1,j2); + n2 /= n2.modp(); + psibar_ref_plane = n2; + first_time = false; +#else + // Compute the angle between the planes spanned by (some axis,j1) and by (j1,j2) + n1 = lund_plane::cross_product(psibar_ref_plane,j1); + n2 = lund_plane::cross_product(j1,j2); + + double signed_angle = 0.; + n2 /= n2.modp(); + if (n1.modp() != 0) { + n1 /= n1.modp(); + signed_angle = lund_plane::signed_angle_between_planes(n1,n2,j1); + } + + psibar = lund_plane::map_to_pi(j1.phi() + signed_angle); +#endif + } + // Else take the value of psibar_i and the plane from the last splitting to define psibar_{i+1} + // The signed angle is multiplied by sign_s (+1 for the +z hemisphere, -1 for the -z hemisphere) + // to take the correct orientation into account. + else { + n2 = lund_plane::cross_product(j1,j2); + n2 /= n2.modp(); + psibar = lund_plane::map_to_pi(last_psibar + sign_s*lund_plane::signed_angle_between_planes(psibar_ref_plane, n2, j1)); + } + + int leaf_iplane = -1; + // we will recurse into the softer "parent" only if the depth is + // not yet at its limit or if there is no limit on the depth (max_depth<0) + bool recurse_into_softer = (depth < max_depth_ || max_depth_ < 0); + if (recurse_into_softer) { + max_iplane_sofar += 1; + leaf_iplane = max_iplane_sofar; + } + + LundEEDeclustering declust(jet, j1, j2, iplane, psi, psibar, depth, leaf_iplane, sign_s); + declusterings.push_back(declust); + + // now recurse + // for the definition of psibar, we recursively pass the last splitting plane (normal to n2) and the last value + // of psibar + bool lcl_first_time = false; + append_to_vector(declusterings, j1, depth, iplane, max_iplane_sofar, new_rotmat, sign_s, n2, psibar, lcl_first_time); + if (recurse_into_softer) { + append_to_vector(declusterings, j2, depth+1, leaf_iplane, max_iplane_sofar, new_rotmat, sign_s, n2, psibar, lcl_first_time); + } + } + + int max_depth_ = 0; + /// vectors used to help define psi + PseudoJet nx_; + PseudoJet ny_; + bool dynamical_psi_ref_; +}; + +} // namespace contrib + +FASTJET_END_NAMESPACE + +/// for output of declustering information +std::ostream & operator<<(std::ostream & ostr, const fastjet::contrib::LundEEDeclustering & d); + +#endif // __FASTJET_CONTRIB_RECURSIVELUNDEEGENERATOR_HH__ Property changes on: contrib/contribs/LundPlane/trunk/include/fastjet/contrib/RecursiveLundEEGenerator.hh ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: contrib/contribs/LundPlane/trunk/include/fastjet/contrib/LundJSON.hh =================================================================== --- contrib/contribs/LundPlane/trunk/include/fastjet/contrib/LundJSON.hh (revision 0) +++ contrib/contribs/LundPlane/trunk/include/fastjet/contrib/LundJSON.hh (revision 1460) @@ -0,0 +1,78 @@ +#ifndef __FASTJET_CONTRIB_LUNDJSON_HH__ +#define __FASTJET_CONTRIB_LUNDJSON_HH__ + +#include "LundGenerator.hh" + +FASTJET_BEGIN_NAMESPACE + +namespace contrib{ + +// declaration of helper function +void lund_elements_to_json(std::ostream & ostr, const LundDeclustering & d); + +/// writes json to ostr for an individual declustering +inline std::ostream & lund_to_json(std::ostream & ostr, const LundDeclustering & d) { + // /// we hardcode 6 digits of precision -- is this the right way to do things? + // int prec_store = ostr.precision(); + // ostr.precision(6); + + ostr << "{"; + lund_elements_to_json(ostr, d); + ostr << "}"; + + return ostr; +} + + +/// writes json to ostr for a vector of declusterings +inline std::ostream & lund_to_json(std::ostream & ostr, const std::vector<LundDeclustering> & d) { + ostr << "["; + for (std::size_t i = 0; i < d.size(); i++) { + if (i != 0) ostr << ","; + lund_to_json(ostr, d[i]); + } + ostr << "]"; + return ostr; +} + +// /// writes a full Lund tree recursively to JSON +// inline std::ostream & lund_to_json(std::ostream & ostr, const LundGenerator & generator, const PseudoJet & jet) { +// // we will use these below in the loop; declare them here to avoid +// // repeated creation/destruction +// PseudoJet p1,p2; +// std::vector<LundDeclustering> d = generator(jet); +// ostr << "["; +// for (std::size_t i = 0; i < d.size(); i++) { +// if (i != 0) ostr << ","; +// ostr << "{"; +// lund_elements_to_json(ostr, d[i]); +// // add in information on the leaf if it exists +// if (d[i].softer().has_parents(p1,p2)) { +// ostr << ","; +// ostr << "\"leaf\":"; +// lund_to_json(ostr, generator, d[i].softer()); +// } +// ostr << "}"; +// } +// ostr << "]"; +// return ostr; +// } + +// helper function to write individual elements to json +inline void lund_elements_to_json(std::ostream & ostr, const LundDeclustering & d) { + ostr << "\"p_pt\":" << d.pair() .pt() << ","; + ostr << "\"p_m\":" << d.pair() .m () << ","; + ostr << "\"h_pt\":" << d.harder().pt() << ","; + ostr << "\"s_pt\":" << d.softer().pt() << ","; + ostr << "\"z\":" << d.z() << ","; + ostr << "\"Delta\":" << d.Delta() << ","; + ostr << "\"kt\":" << d.kt() << ","; + ostr << "\"psi\":" << d.psi() ; +} + + +} // namespace contrib + +FASTJET_END_NAMESPACE + +#endif // __FASTJET_CONTRIB_LUNDJSON_HH__ Property changes on: contrib/contribs/LundPlane/trunk/include/fastjet/contrib/LundJSON.hh ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: contrib/contribs/LundPlane/trunk/include/fastjet/contrib/LundEEHelpers.hh =================================================================== --- contrib/contribs/LundPlane/trunk/include/fastjet/contrib/LundEEHelpers.hh (revision 0) +++ contrib/contribs/LundPlane/trunk/include/fastjet/contrib/LundEEHelpers.hh (revision 1460) @@ -0,0 +1,270 @@ +// $Id$ +// +// Copyright (c) 2018-, Frederic A. Dreyer, Keith Hamilton, Alexander Karlberg, +// Gavin P. Salam, Ludovic Scyboz, Gregory Soyez, Rob Verheyen +// +// This file is part of FastJet contrib. +// +// It is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2 of the License, or (at +// your option) any later version. +// +// It is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +// License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this code. If not, see <http://www.gnu.org/licenses/>. +//---------------------------------------------------------------------- + +#ifndef __FASTJET_CONTRIB_EEHELPERS_HH__ +#define __FASTJET_CONTRIB_EEHELPERS_HH__ + +#include "fastjet/PseudoJet.hh" +#include <array> +#include <limits> + +FASTJET_BEGIN_NAMESPACE + +namespace contrib{ +namespace lund_plane { + +//---------------------------------------------------------------------- +/// Returns the 3-vector cross-product of p1 and p2. If lightlike is false +/// then the energy component is zero; if it's true the the energy component +/// is arranged so that the vector is lighlike +inline PseudoJet cross_product(const PseudoJet & p1, const PseudoJet & p2, bool lightlike=false) { + double px = p1.py() * p2.pz() - p2.py() * p1.pz(); + double py = p1.pz() * p2.px() - p2.pz() * p1.px(); + double pz = p1.px() * p2.py() - p2.px() * p1.py(); + + double E; + if (lightlike) { + E = sqrt(px*px + py*py + pz*pz); + } else { + E = 0.0; + } + return PseudoJet(px, py, pz, E); +} + +/// Map angles to [-pi, pi] +inline const double map_to_pi(const double &phi) { + if (phi < -M_PI) return phi + 2 * M_PI; + else if (phi > M_PI) return phi - 2 * M_PI; + else return phi; +} + +inline double dot_product_3d(const PseudoJet & a, const PseudoJet & b) { + return a.px()*b.px() + a.py()*b.py() + a.pz()*b.pz(); +} + +/// Returns (1-cos theta) where theta is the angle between p1 and p2 +inline double one_minus_costheta(const PseudoJet & p1, const PseudoJet & p2) { + + if (p1.m2() == 0 && p2.m2() == 0) { + // use the 4-vector dot product. + // For massless particles it gives us E1*E2*(1-cos theta) + return dot_product(p1,p2) / (p1.E() * p2.E()); + } else { + double p1mod = p1.modp(); + double p2mod = p2.modp(); + double p1p2mod = p1mod*p2mod; + double dot = dot_product_3d(p1,p2); + + if (dot > (1-std::numeric_limits<double>::epsilon()) * p1p2mod) { + PseudoJet cross_result = cross_product(p1, p2, false); + // the mass^2 of cross_result is equal to + // -(px^2 + py^2 + pz^2) = (p1mod*p2mod*sintheta_ab)^2 + // so we can get + return -cross_result.m2()/(p1p2mod * (p1p2mod+dot)); + } + + return 1.0 - dot/p1p2mod; + + } +} + +/// Get the angle between two planes defined by normalized vectors +/// n1, n2. The sign is decided by the direction of a vector n, such that +/// if n1 x n2 points in the same direction as n, the angle is positive. +/// The result is in the range -pi < theta < pi. +/// +/// For example, labelling (x,y,z), and taking n1 = (1,0,0), +/// n2 = (0,1,0), n = (0,0,1), then the angle is +pi/2. +inline double signed_angle_between_planes(const PseudoJet& n1, + const PseudoJet& n2, const PseudoJet& n) { + + // Two vectors passed as arguments should be normalised to 1. + assert(fabs(n1.modp()-1) < sqrt(std::numeric_limits<double>::epsilon()) && fabs(n2.modp()-1) < sqrt(std::numeric_limits<double>::epsilon())); + + double omcost = one_minus_costheta(n1,n2); + double theta; + + // If theta ~ pi, we return pi. + if(fabs(omcost-2) < sqrt(std::numeric_limits<double>::epsilon())) { + theta = M_PI; + } else if (omcost > sqrt(std::numeric_limits<double>::epsilon())) { + double cos_theta = 1.0 - omcost; + theta = acos(cos_theta); + } else { + // we are at small angles, so use small-angle formulas + theta = sqrt(2. * omcost); + } + + PseudoJet cp = cross_product(n1,n2); + double sign = dot_product_3d(cp,n); + + if (sign > 0) return theta; + else return -theta; +} + +class Matrix3 { +public: + /// constructs an empty matrix + Matrix3() : matrix_({{{{0,0,0}}, {{0,0,0}}, {{0,0,0}}}}) {} + + /// constructs a diagonal matrix with "unit" along each diagonal entry + Matrix3(double unit) : matrix_({{{{unit,0,0}}, {{0,unit,0}}, {{0,0,unit}}}}) {} + + /// constructs a matrix from the array<array<...,3>,3> object + Matrix3(const std::array<std::array<double,3>,3> & mat) : matrix_(mat) {} + + /// returns the entry at row i, column j + inline double operator()(int i, int j) const { + return matrix_[i][j]; + } + + /// returns a matrix for carrying out azimuthal rotation + /// around the z direction by an angle phi + static Matrix3 azimuthal_rotation(double phi) { + double cos_phi = cos(phi); + double sin_phi = sin(phi); + Matrix3 phi_rot( {{ {{cos_phi, sin_phi, 0}}, + {{-sin_phi, cos_phi, 0}}, + {{0,0,1}}}}); + return phi_rot; + } + + /// returns a matrix for carrying out a polar-angle + /// rotation, in the z-x plane, by an angle theta + static Matrix3 polar_rotation(double theta) { + double cos_theta = cos(theta); + double sin_theta = sin(theta); + Matrix3 theta_rot( {{ {{cos_theta, 0, sin_theta}}, + {{0,1,0}}, + {{-sin_theta, 0, cos_theta}}}}); + return theta_rot; + } + + /// This provides a rotation matrix that takes the z axis to the + /// direction of p. With skip_pre_rotation = false (the default), it + /// has the characteristic that if p is close to the z axis then the + /// azimuthal angle of anything at much larger angle is conserved. + /// + /// If skip_pre_rotation is true, then the azimuthal angles are not + /// when p is close to the z axis. + template<class T> + static Matrix3 from_direction(const T & p, bool skip_pre_rotation = false) { + double pt = p.pt(); + double modp = p.modp(); + double cos_theta = p.pz() / modp; + double sin_theta = pt / modp; + double cos_phi, sin_phi; + if (pt > 0.0) { + cos_phi = p.px()/pt; + sin_phi = p.py()/pt; + } else { + cos_phi = 1.0; + sin_phi = 0.0; + } + + Matrix3 phi_rot({{ {{ cos_phi,-sin_phi, 0 }}, + {{ sin_phi, cos_phi, 0 }}, + {{ 0, 0, 1 }} }}); + Matrix3 theta_rot( {{ {{ cos_theta, 0, sin_theta }}, + {{ 0, 1, 0 }}, + {{-sin_theta, 0, cos_theta }} }}); + + // since we have orthogonal matrices, the inverse and transpose + // are identical; we use the transpose for the frontmost rotation + // because + if (skip_pre_rotation) { + return phi_rot * theta_rot; + } else { + return phi_rot * (theta_rot * phi_rot.transpose()); + } + } + + template<class T> + static Matrix3 from_direction_no_pre_rotn(const T & p) { + return from_direction(p,true); + } + + + + /// returns the transposed matrix + Matrix3 transpose() const { + // 00 01 02 + // 10 11 12 + // 20 21 22 + Matrix3 result = *this; + std::swap(result.matrix_[0][1],result.matrix_[1][0]); + std::swap(result.matrix_[0][2],result.matrix_[2][0]); + std::swap(result.matrix_[1][2],result.matrix_[2][1]); + return result; + } + + // returns the product with another matrix + Matrix3 operator*(const Matrix3 & other) const { + Matrix3 result; + // r_{ij} = sum_k this_{ik} & other_{kj} + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + for (int k = 0; k < 3; k++) { + result.matrix_[i][j] += this->matrix_[i][k] * other.matrix_[k][j]; + } + } + } + return result; + } + + friend std::ostream & operator<<(std::ostream & ostr, const Matrix3 & mat); +private: + std::array<std::array<double,3>,3> matrix_; +}; + +inline std::ostream & operator<<(std::ostream & ostr, const Matrix3 & mat) { + ostr << mat.matrix_[0][0] << " " << mat.matrix_[0][1] << " " << mat.matrix_[0][2] << std::endl; + ostr << mat.matrix_[1][0] << " " << mat.matrix_[1][1] << " " << mat.matrix_[1][2] << std::endl; + ostr << mat.matrix_[2][0] << " " << mat.matrix_[2][1] << " " << mat.matrix_[2][2] << std::endl; + return ostr; +} + +/// returns the project of this matrix with the PseudoJet, +/// maintaining the 4th component of the PseudoJet unchanged +inline PseudoJet operator*(const Matrix3 & mat, const PseudoJet & p) { + // r_{i} = m_{ij} p_j + std::array<double,3> res3{{0,0,0}}; + for (unsigned i = 0; i < 3; i++) { + for (unsigned j = 0; j < 3; j++) { + res3[i] += mat(i,j) * p[j]; + } + } + // return a jet that maintains all internal pointers by + // initialising the result from the input jet and + // then resetting the momentum. + PseudoJet result(p); + // maintain the energy component as it was + result.reset_momentum(res3[0], res3[1], res3[2], p[3]); + return result; +} + +} // namespace lund_plane +} // namespace contrib + +FASTJET_END_NAMESPACE + +#endif // __FASTJET_CONTRIB_EEHELPERS_HH__ + Property changes on: contrib/contribs/LundPlane/trunk/include/fastjet/contrib/LundEEHelpers.hh ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: contrib/contribs/LundPlane/trunk/example_secondary.cc =================================================================== --- contrib/contribs/LundPlane/trunk/example_secondary.cc (revision 1459) +++ contrib/contribs/LundPlane/trunk/example_secondary.cc (revision 1460) @@ -1,117 +1,118 @@ //---------------------------------------------------------------------- /// \file example_secondary.cc /// /// This example program is meant to illustrate how the /// fastjet::contrib::LundWithSecondary class is used. /// /// Run this example with /// /// \verbatim /// ./example_secondary < ../data/single-event.dat /// \endverbatim //---------------------------------------------------------------------- // $Id$ // // Copyright (c) 2018-, Frederic A. Dreyer, Keith Hamilton, Alexander Karlberg, // Gavin P. Salam, Ludovic Scyboz, Gregory Soyez, Rob Verheyen // //---------------------------------------------------------------------- // This file is part of FastJet contrib. // // It is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at // your option) any later version. // // It is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public // License for more details. // // You should have received a copy of the GNU General Public License // along with this code. If not, see <http://www.gnu.org/licenses/>. //---------------------------------------------------------------------- #include <iostream> #include <fstream> #include <sstream> #include "fastjet/PseudoJet.hh" #include <string> -#include "LundWithSecondary.hh" // In external code, this should be fastjet/contrib/LundWithSecondary.hh +#include "fastjet/contrib/LundWithSecondary.hh" + using namespace std; using namespace fastjet; // forward declaration to make things clearer void read_event(vector<PseudoJet> &event); //---------------------------------------------------------------------- int main(){ //---------------------------------------------------------- // read in input particles vector<PseudoJet> event; read_event(event); cout << "# read an event with " << event.size() << " particles" << endl; // first get some anti-kt jets double R = 1.0, ptmin = 100.0; JetDefinition jet_def(antikt_algorithm, R); ClusterSequence cs(event, jet_def); vector<PseudoJet> jets = sorted_by_pt(cs.inclusive_jets(ptmin)); //---------------------------------------------------------- // create an instance of LundWithSecondary, with default options contrib::SecondaryLund_mMDT secondary; contrib::LundWithSecondary lund(&secondary); cout << lund.description() << endl; for (unsigned ijet = 0; ijet < jets.size(); ijet++) { cout << endl << "Lund coordinates ( ln 1/Delta, ln kt ) of declusterings of jet " << ijet << " are:" << endl; vector<contrib::LundDeclustering> declusts = lund.primary(jets[ijet]); for (unsigned int idecl = 0; idecl < declusts.size(); ++idecl) { pair<double,double> coords = declusts[idecl].lund_coordinates(); cout << "["<< idecl<< "](" << coords.first << ", " << coords.second << ")"; if (idecl < declusts.size() - 1) cout << "; "; } cout << endl; vector<contrib::LundDeclustering> sec_declusts = lund.secondary(declusts); cout << endl << "with Lund coordinates for the secondary plane (from primary declustering [" << lund.secondary_index(declusts) <<"]):" << endl; for (unsigned int idecl = 0; idecl < sec_declusts.size(); ++idecl) { pair<double,double> coords = sec_declusts[idecl].lund_coordinates(); cout << "["<< idecl<< "](" << coords.first << ", " << coords.second << ")"; if (idecl < sec_declusts.size() - 1) cout << "; "; } cout << endl; } return 0; } // read in input particles void read_event(vector<PseudoJet> &event){ string line; while (getline(cin, line)) { istringstream linestream(line); // take substrings to avoid problems when there is extra "pollution" // characters (e.g. line-feed). if (line.substr(0,4) == "#END") {return;} if (line.substr(0,1) == "#") {continue;} double px,py,pz,E; linestream >> px >> py >> pz >> E; PseudoJet particle(px,py,pz,E); // push event onto back of full_event vector event.push_back(particle); } } Index: contrib/contribs/LundPlane/trunk/example_dpsi_collinear.cc =================================================================== --- contrib/contribs/LundPlane/trunk/example_dpsi_collinear.cc (revision 1459) +++ contrib/contribs/LundPlane/trunk/example_dpsi_collinear.cc (revision 1460) @@ -1,167 +1,168 @@ //---------------------------------------------------------------------- /// \file example_dpsi_collinear.cc /// /// This example program is meant to illustrate how the /// fastjet::contrib::RecursiveLundEEGenerator class is used. /// /// Run this example with /// /// \verbatim /// ./example_dpsi_collinear < ../data/single-ee-event.dat /// \endverbatim //---------------------------------------------------------------------- // $Id$ // // Copyright (c) 2018-, Frederic A. Dreyer, Keith Hamilton, Alexander Karlberg, // Gavin P. Salam, Ludovic Scyboz, Gregory Soyez, Rob Verheyen // //---------------------------------------------------------------------- // This file is part of FastJet contrib. // // It is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at // your option) any later version. // // It is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public // License for more details. // // You should have received a copy of the GNU General Public License // along with this code. If not, see <http://www.gnu.org/licenses/>. //---------------------------------------------------------------------- #include <iostream> #include <fstream> #include <sstream> #include <limits> #include "fastjet/PseudoJet.hh" #include "fastjet/EECambridgePlugin.hh" #include <string> -#include "RecursiveLundEEGenerator.hh" // In external code, this should be fastjet/contrib/RecursiveLundEEGenerator.hh +#include "fastjet/contrib/RecursiveLundEEGenerator.hh" + using namespace std; using namespace fastjet; // Definitions for the collinear observable double z1_cut = 0.1; double z2_cut = 0.1; // forward declaration to make things clearer void read_event(vector<PseudoJet> &event); //---------------------------------------------------------------------- int main(){ //---------------------------------------------------------- // read in input particles vector<PseudoJet> event; read_event(event); cout << "# read an event with " << event.size() << " particles" << endl; //---------------------------------------------------------- // create an instance of RecursiveLundEEGenerator, with default options int depth = -1; fastjet::contrib::RecursiveLundEEGenerator lund(depth); // first get some C/A jets double y3_cut = 1.0; JetDefinition::Plugin* ee_plugin = new EECambridgePlugin(y3_cut); JetDefinition jet_def(ee_plugin); ClusterSequence cs(event, jet_def); // Get the list of primary declusterings const vector<contrib::LundEEDeclustering> declusts = lund.result(cs); // Find the two highest-kt primary declustering (ordered in kt by default) int i_primary_1 = -1, i_primary_2 = -1; double psi_primary_1, psi_primary_2; double dpsi_11 = numeric_limits<double>::max(); //< initialisation prevents gcc warning for (unsigned int i=0; i<declusts.size(); ++i) { if (declusts[i].depth() == 0 && declusts[i].z() > z1_cut) { if (i_primary_1 < 0) { i_primary_1 = i; psi_primary_1 = declusts[i].psibar(); } else { i_primary_2 = i; psi_primary_2 = declusts[i].psibar(); dpsi_11 = contrib::lund_plane::map_to_pi(psi_primary_2-psi_primary_1); break; } } } // If no primary at all, just return if (i_primary_1 < 0) return 0; // For the highest-kt primary: find the highest-kt secondary associated to that Lund leaf // that passes the zcut of z2_cut int iplane_to_follow = declusts[i_primary_1].leaf_iplane(); vector<const contrib::LundEEDeclustering *> secondaries; for (const auto & declust: declusts){ if (declust.iplane() == iplane_to_follow) secondaries.push_back(&declust); } int i_secondary = -1; double dpsi_12 = numeric_limits<double>::max(); //< initialisation prevents gcc warning; if (secondaries.size() > 0) { for (unsigned int i=0; i<secondaries.size(); ++i) { if (secondaries[i]->z() > z2_cut) { i_secondary = i; double psi_2 = secondaries[i]->psibar(); dpsi_12 = contrib::lund_plane::map_to_pi(psi_2-psi_primary_1); break; } } } cout << "Highest-kt primary that passes the zcut of " << z1_cut << ", with Lund coordinates ( ln 1/Delta, ln kt, psibar ):" << endl; pair<double,double> coords = declusts[i_primary_1].lund_coordinates(); cout << "index [" << i_primary_1 << "](" << coords.first << ", " << coords.second << ", " << declusts[i_primary_1].psibar() << ")" << endl; // dpsi_12 is the angle between the primary and the secondary if (i_secondary >= 0) { cout << endl << "with Lund coordinates for the secondary plane that passes the zcut of " << z2_cut << endl; coords = secondaries[i_secondary]->lund_coordinates(); cout << "index [" << i_secondary << "](" << coords.first << ", " << coords.second << ", " << secondaries[i_secondary]->psibar() << ")"; cout << " --> delta_psi(primary,secondary) = " << dpsi_12 << endl; } // dpsi_11 is the angle between the two primaries if (i_primary_2 >= 0) { cout << endl << "with Lund coordinates for the second primary plane that passes the zcut of " << z1_cut << endl; coords = declusts[i_primary_2].lund_coordinates(); cout << "index [" << i_primary_2 << "](" << coords.first << ", " << coords.second << ", " << declusts[i_primary_2].psibar() << ")"; cout << " --> delta_psi(primary_1, primary_2) = " << dpsi_11 << endl; } // Delete the EECambridge plugin delete ee_plugin; return 0; } // read in input particles void read_event(vector<PseudoJet> &event){ string line; while (getline(cin, line)) { istringstream linestream(line); // take substrings to avoid problems when there is extra "pollution" // characters (e.g. line-feed). if (line.substr(0,4) == "#END") {return;} if (line.substr(0,1) == "#") {continue;} double px,py,pz,E; linestream >> px >> py >> pz >> E; PseudoJet particle(px,py,pz,E); // push event onto back of full_event vector event.push_back(particle); } } Index: contrib/contribs/LundPlane/trunk/ChangeLog =================================================================== --- contrib/contribs/LundPlane/trunk/ChangeLog (revision 1459) +++ contrib/contribs/LundPlane/trunk/ChangeLog (revision 1460) @@ -1,204 +1,231 @@ +2024-12-11 Gregory Soyez <soyez@fastjet.fr> + + * FJCONTRIB.cfg: *** ADDED *** + * VERSION: *** REMOVED *** + replaced the VERSION file witrh the new syntax which is a + "version" line in FJCONTRIB.cfg + + * LundGenerator.cc: + * LundWithSecondary.cc: + * RecursiveLundEEGenerator.cc: + * SecondaryLund.cc: + * example.cc: + * example_dpsi_collinear.cc: + * example_dpsi_slice.cc: + * example_secondary.cc: + * Makefile: + updated source code and build script to reflect the headre + relocation + + * LundEEHelpers.hh -> include/fastjet/contrib/LundEEHelpers.hh + * LundGenerator.hh -> include/fastjet/contrib/LundGenerator.hh + * LundJSON.hh -> include/fastjet/contrib/LundJSON.hh + * LundWithSecondary.hh -> include/fastjet/contrib/LundWithSecondary.hh + * RecursiveLundEEGenerator.hh -> include/fastjet/contrib/RecursiveLundEEGenerator.hh + * SecondaryLund.hh -> include/fastjet/contrib/SecondaryLund.hh + moved installed hjeaders to the include/fastjet/contrib/ directory + 2024-12-09 Mon <gavin.salam@physics.ox.ac.uk> * Makefile: fixed a bug in the `fastjet-config --libs` call, adding --plugins so that one gets a consistent set of plugin libraries according to the specific fastjet configuration. 2024-02-28 Gregory Soyez <soyez@fastjet.fr> * example_dpsi_collinear.cc: fixed maybe-uninitialized gcc warnings 2024-01-18 Ludo Scyboz (+ minor contribs from Gregory Soyez + Gavin Salam) * RecursiveLundEEGenerator.hh: * example_dpsi_collinear.ref: * example_dpsi_slice.ref: * python/gen-test-event.py: * NEWS: another bug-fix for opposite hemispheres differences of psibar, where a missing sign needed to be added in the second hemisphere. This changes the reference files for opposite hemisphere dpsibar. For same-hemisphere dpsibar, the sign can change (depending on the hemisphere). Also updated python/gen-test-event.py to have command-line options for more flexibility in examining output and for testing explanation of psibar absolute value in RecursiveLundEEGenerator comments. 2024-01-10 Gavin Salam + Alexander Karlberg * NEWS: * VERSION: preparing for release 2.1.0 (NEWS still needs correct date to be added) * AUTHORS: added publication info for soft spin paper 2024-01-10 Gavin Salam + Ludo Scyboz + Alexander Karlberg * LundEEHelpers.hh: extended the comments in the signed_angle_between_planes function * RecursiveLundEEGenerator.hh: changed definition of psibar, which fixes a bug in differences of psibar values between opposite hemispheres. Differences within a same hemisphere should stay the same. * example_dpsi_collinear.cc: added extra output showing the primary declustering in the second hemisphere. Also eliminated deprecated dynamic_psi_reference argument in setting up the RecursiveLundEEGenerator. * example_dpsi_collinear.ref: * example_dpsi_slice.ref: updated these reference files so that are consistent with the new definition of psibar. Note the delta psibar values do not change. The collinear reference has acquired extra output showing a primary declustering in the second hemisphere. * python/gen-test-event.py: *** ADDED *** small script to generate test events for verifying output from example_dpsi_collinear.ref 2024-01-08 Gavin Salam <gavin.salam@physics.ox.ac.uk> * example_dpsi_slice.cc: replaced a uint -> unsigned int, to resolve a compilation issue with gcc-13 on MacOS 2023-09-22 Fri <gavin.salam@physics.ox.ac.uk> * NEWS: * VERSION: preparing 2.0.4 release * RecursiveLundEEGenerator.hh: fixed const issue in in ternal lambda function (reported by Seryubin Seraphim) * LundPlane.hh: *** ADDED *** added this to provide a generic include for the main classes (absence of such a standard-looking reported by Seryubin Seraphim) 2022-10-04 Gregory Soyez <soyez@fastjet.fr> * example.cc: * example_secondary.cc: * example_dpsi_collinear.cc: * example_dpsi_slice.cc: removed (harmless) compilation warnings (+ minor uniformisation of indentation) 2022-10-04 Tue <gavin.salam@physics.ox.ac.uk> + Ludo Scyboz * VERSION: * NEWS: prepared for release 2.0.3 * EEHelpers.hh -> LundEEHelpers.hh: EEHelpers.hh was not being installed; given that it's a potentially common name, renamed it before including among the installation targets. Also placed whole contents in a new contrib::lund_plane namespace, because of certain potentially common names like cross_product * Makefile: replaced EEHelpers.hh -> LundEEHelpers.hh and made sure that LundEEHelpers.hh gets installed (without which RecursiveLundEEGenerator.hh cannot be used) * example_dpsi_collinear.cc: * example_dpsi_slice.cc: use of things from LundEEHelpers.hh updated to use of new namespace * RecursiveLundEEGenerator.hh: * RecursiveLundEEGenerator.cc: updated to use LundEEHelpers.hh (and associated namespace); also added a (protected) default constructor to LundEEDeclustering 2022-08-20 Gavin Salam <gavin.salam@physics.ox.ac.uk> * VERSION: * NEWS: prepared for release 2.0.2 * Makefile: updated some dependencies * EEHelpers.hh: added #include <limits>, as per request from Andy Buckley for compilation with g++-12 on some systems 2021-12-06 Gavin Salam <gavin.salam@physics.ox.ac.uk> * NEWS: * VERSION: prepared for release 2.0.1 * AUTHORS: fixed missing names and publication info 2021-12-06 Gregory Soyez <soyez@fastjet.fr> * SecondaryLund.cc: fixed int v. unsigned int in loop over vector indices 2021-12-06 Gavin Salam <gavin.salam@physics.ox.ac.uk> * example.py: fixed name of executable in comments about how to execute this (thanks to Matteo Cacciari) 2021-11-09 Ludovic Scyboz <ludovic.scyboz@physics.ox.ac.uk> * VERSION: preparing for release of 2.0.0 * RecursiveLundEEGenerator.hh: * RecursiveLundEEGenerator.cc: class for recursive Lund declustering in e+e- * example_dpsi_collinear.cc: spin-sensitive collinear observable from 2103.16526 * example_dpsi_slice.cc: spin-sensitive non-global observable from 2111.01161 2020-02-23 Gavin Salam <gavin.salam@cern.ch> * NEWS: * VERSION: preparing for release of 1.0.3 * example.cc: changed outfile open(filename) to outfile.open(filename.c_str()); to attempt to solve issue reported by Steven Schramm. 2018-10-26 Gavin Salam <gavin.salam@cern.ch> * read_lund_json.py: removed extraneous normalisation of zeroth bin in the LundImage class. Added documentation. 2018-08-30 Gavin Salam <gavin.salam@cern.ch> * VERSION: * NEWS: Release of version 1.0.1 2018-08-23 Gavin Salam <gavin.salam@cern.ch> * LundWithSecondary.hh: * LundWithSecondary.cc: added secondary_index(...), removed virtual qualifier from various functions * example_secondary.cc: * example_secondary.ref: example now prints out index of the primary declustering being used for the secondary. Referemce file updated accordingly. 2018-08-09 Frédéric Dreyer <fdreyer@mit.edu> First version of LundPlane. Index: contrib/contribs/LundPlane/trunk/LundWithSecondary.cc =================================================================== --- contrib/contribs/LundPlane/trunk/LundWithSecondary.cc (revision 1459) +++ contrib/contribs/LundPlane/trunk/LundWithSecondary.cc (revision 1460) @@ -1,78 +1,78 @@ // $Id$ // // Copyright (c) 2018-, Frederic A. Dreyer, Keith Hamilton, Alexander Karlberg, // Gavin P. Salam, Ludovic Scyboz, Gregory Soyez, Rob Verheyen // //---------------------------------------------------------------------- // This file is part of FastJet contrib. // // It is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at // your option) any later version. // // It is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public // License for more details. // // You should have received a copy of the GNU General Public License // along with this code. If not, see <http://www.gnu.org/licenses/>. //---------------------------------------------------------------------- -#include "LundWithSecondary.hh" +#include "fastjet/contrib/LundWithSecondary.hh" #include <sstream> FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh namespace contrib{ //---------------------------------------------------------------------- /// return LundDeclustering sequence of primary plane std::vector<LundDeclustering> LundWithSecondary::primary(const PseudoJet& jet) const { return lund_gen_(jet); } //---------------------------------------------------------------------- /// return LundDeclustering sequence of secondary plane (slow version) std::vector<LundDeclustering> LundWithSecondary::secondary(const PseudoJet& jet) const { // this is not optimal as one is computing the primary plane twice. std::vector<LundDeclustering> declusts = lund_gen_(jet); return secondary(declusts); } //---------------------------------------------------------------------- /// return LundDeclustering sequence of secondary plane with primary sequence as input std::vector<LundDeclustering> LundWithSecondary::secondary( const std::vector<LundDeclustering> & declusts) const { int sec_index = secondary_index(declusts); // if we found the index of secondary emission, return its declustering sequence if (sec_index >= 0) { return lund_gen_(declusts[sec_index].softer()); } else { return std::vector<LundDeclustering>(); } } //---------------------------------------------------------------------- /// return the index associated of the primary declustering that is to be /// used for the secondary plane. int LundWithSecondary::secondary_index(const std::vector<LundDeclustering> & declusts) const { if (secondary_def_ == 0) { throw Error("secondary class is a null pointer, cannot identify element to use for secondary plane"); } return (*secondary_def_)(declusts); } //---------------------------------------------------------------------- /// description std::string LundWithSecondary::description() const { std::ostringstream oss; oss << "LundWithSecondary using " << secondary_def_->description() << " and " << lund_gen_.description(); return oss.str(); } } // namespace contrib FASTJET_END_NAMESPACE Index: contrib/contribs/LundPlane/trunk/LundGenerator.cc =================================================================== --- contrib/contribs/LundPlane/trunk/LundGenerator.cc (revision 1459) +++ contrib/contribs/LundPlane/trunk/LundGenerator.cc (revision 1460) @@ -1,76 +1,76 @@ // $Id$ // // Copyright (c) 2018-, Frederic A. Dreyer, Keith Hamilton, Alexander Karlberg, // Gavin P. Salam, Ludovic Scyboz, Gregory Soyez, Rob Verheyen // //---------------------------------------------------------------------- // This file is part of FastJet contrib. // // It is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at // your option) any later version. // // It is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public // License for more details. // // You should have received a copy of the GNU General Public License // along with this code. If not, see <http://www.gnu.org/licenses/>. //---------------------------------------------------------------------- #include <sstream> -#include "LundGenerator.hh" +#include "fastjet/contrib/LundGenerator.hh" FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh namespace contrib{ LundDeclustering::LundDeclustering(const PseudoJet& pair, const PseudoJet& j1, const PseudoJet& j2) : m_(pair.m()), Delta_(j1.delta_R(j2)), pair_(pair) { // establish which of j1 and j2 is softer if (j1.pt2() > j2.pt2()) { harder_ = j1; softer_ = j2; } else { harder_ = j2; softer_ = j1; } // now work out the various Lund declustering variables double softer_pt = softer_.pt(); z_ = softer_pt / (softer_pt + harder_.pt()); kt_ = softer_pt * Delta_; psi_ = atan2(softer_.rap()-harder_.rap(), harder_.delta_phi_to(softer_)); kappa_ = z_ * Delta_; } //---------------------------------------------------------------------- /// retrieve the vector of declusterings of the primary plane of a jet std::vector<LundDeclustering> LundGenerator::result(const PseudoJet& jet) const { std::vector<LundDeclustering> result; PseudoJet j = recluster_(jet); PseudoJet pair, j1, j2; pair = j; while (pair.has_parents(j1, j2)) { if (j1.pt2() < j2.pt2()) std::swap(j1,j2); result.push_back(LundDeclustering(pair, j1, j2)); pair = j1; } return result; } //---------------------------------------------------------------------- /// description std::string LundGenerator::description() const { std::ostringstream oss; oss << "LundGenerator with " << recluster_.description(); return oss.str(); } } // namespace contrib FASTJET_END_NAMESPACE Index: contrib/contribs/LundPlane/trunk/SecondaryLund.cc =================================================================== --- contrib/contribs/LundPlane/trunk/SecondaryLund.cc (revision 1459) +++ contrib/contribs/LundPlane/trunk/SecondaryLund.cc (revision 1460) @@ -1,124 +1,124 @@ // $Id$ // // Copyright (c) 2018-, Frederic A. Dreyer, Keith Hamilton, Alexander Karlberg, // Gavin P. Salam, Ludovic Scyboz, Gregory Soyez, Rob Verheyen // //---------------------------------------------------------------------- // This file is part of FastJet contrib. // // It is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at // your option) any later version. // // It is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public // License for more details. // // You should have received a copy of the GNU General Public License // along with this code. If not, see <http://www.gnu.org/licenses/>. //---------------------------------------------------------------------- -#include "SecondaryLund.hh" +#include "fastjet/contrib/SecondaryLund.hh" #include <math.h> #include <sstream> #include <limits> FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh namespace contrib{ //---------------------------------------------------------------------- /// retrieve the vector of declusterings of the secondary plane of a jet int SecondaryLund_mMDT::result(const std::vector<LundDeclustering>& declusts) const { // iterate through primary branchings for (unsigned int i=0; i < declusts.size(); ++i) { // mMDTZ: find the first emission passing z>zcut if (declusts[i].z() > zcut_) return i; } return -1; } int SecondaryLund_dotmMDT::result(const std::vector<LundDeclustering>& declusts) const { // set up leading emission pointer and bookkeeping variables int secondary_index = -1; double dot_prod_max = 0.0; // iterate through primary branchings for (unsigned int i=0; i < declusts.size(); ++i) { // dotmMDTZ: find emission passing z>zcut with largest dot product if (declusts[i].z() > zcut_) { double dot_prod = declusts[i].harder().pt()*declusts[i].softer().pt() *declusts[i].Delta()*declusts[i].Delta(); if (dot_prod > dot_prod_max) { dot_prod_max = dot_prod; secondary_index = i; } } } // return index of secondary emission return secondary_index; } int SecondaryLund_Mass::result(const std::vector<LundDeclustering>& declusts) const { // set up leading emission pointer and bookkeeping variables int secondary_index = -1; double mass_diff = std::numeric_limits<double>::max(); // iterate through primary branchings for (unsigned int i=0; i < declusts.size(); ++i) { // Mass: find emission that minimises the distance to reference mass double dist = std::abs(log(declusts[i].harder().pt()*declusts[i].softer().pt() * declusts[i].Delta()*declusts[i].Delta() / mref2_) * log(1.0/declusts[i].z())); if (dist < mass_diff) { mass_diff = dist; secondary_index = i; } } // return index of secondary emission return secondary_index; } //---------------------------------------------------------------------- /// description std::string SecondaryLund::description() const { std::ostringstream oss; oss << "SecondaryLund"; return oss.str(); } //---------------------------------------------------------------------- /// description std::string SecondaryLund_mMDT::description() const { std::ostringstream oss; oss << "SecondaryLund (mMDT selection of leading emission, zcut=" << zcut_<<")"; return oss.str(); } //---------------------------------------------------------------------- /// description std::string SecondaryLund_dotmMDT::description() const { std::ostringstream oss; oss << "SecondaryLund (dotmMDT selection of leading emission, zcut=" << zcut_<<")"; return oss.str(); } //---------------------------------------------------------------------- /// description std::string SecondaryLund_Mass::description() const { std::ostringstream oss; oss << " (Mass selection of leading emission, m="<<sqrt(mref2_)<<")"; return oss.str(); } } // namespace contrib FASTJET_END_NAMESPACE Index: contrib/contribs/LundPlane/trunk/RecursiveLundEEGenerator.cc =================================================================== --- contrib/contribs/LundPlane/trunk/RecursiveLundEEGenerator.cc (revision 1459) +++ contrib/contribs/LundPlane/trunk/RecursiveLundEEGenerator.cc (revision 1460) @@ -1,88 +1,88 @@ // $Id$ // // Copyright (c) 2018-, Frederic A. Dreyer, Keith Hamilton, Alexander Karlberg, // Gavin P. Salam, Ludovic Scyboz, Gregory Soyez, Rob Verheyen // //---------------------------------------------------------------------- // This file is part of FastJet contrib. // // It is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at // your option) any later version. // // It is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public // License for more details. // // You should have received a copy of the GNU General Public License // along with this code. If not, see <http://www.gnu.org/licenses/>. //---------------------------------------------------------------------- #include <sstream> -#include "RecursiveLundEEGenerator.hh" +#include "fastjet/contrib/RecursiveLundEEGenerator.hh" using namespace std; FASTJET_BEGIN_NAMESPACE namespace contrib{ using namespace lund_plane; LundEEDeclustering::LundEEDeclustering(const PseudoJet& pair, const PseudoJet& j1, const PseudoJet& j2, int iplane, double psi, double psibar, int depth, int leaf_iplane, int sign_s) : iplane_(iplane), psi_(psi), psibar_(psibar), m_(pair.m()), pair_(pair), depth_(depth), leaf_iplane_(leaf_iplane), sign_s_(sign_s) { double omc = one_minus_costheta(j1,j2); if (omc > sqrt(numeric_limits<double>::epsilon())) { double cos_theta = 1.0 - omc; double theta = acos(cos_theta); sin_theta_ = sin(theta); eta_ = -log(tan(theta/2.0)); } else { // we are at small angles, so use small-angle formulas double theta = sqrt(2. * omc); sin_theta_ = theta; eta_ = -log(theta/2); } // establish which of j1 and j2 is softer if (j1.modp2() > j2.modp2()) { harder_ = j1; softer_ = j2; } else { harder_ = j2; softer_ = j1; } // now work out the various LundEE declustering variables double softer_modp = softer_.modp(); z_ = softer_modp / (softer_modp + harder_.modp()); kt_ = softer_modp * sin_theta_; lnkt_ = log(kt_); kappa_ = z_ * sin_theta_; } } // namespace contrib FASTJET_END_NAMESPACE std::ostream & operator<<(std::ostream & ostr, const fastjet::contrib::LundEEDeclustering & d) { ostr << "kt = " << d.kt() << " z = " << d.z() << " eta = " << d.eta() << " psi = " << d.psi() << " psibar = " << d.psibar() << " m = " << d.m() << " iplane = " << d.iplane() << " depth = " << d.depth() << " leaf_iplane = " << d.leaf_iplane(); return ostr; } Index: contrib/contribs/LundPlane/trunk/example_dpsi_slice.cc =================================================================== --- contrib/contribs/LundPlane/trunk/example_dpsi_slice.cc (revision 1459) +++ contrib/contribs/LundPlane/trunk/example_dpsi_slice.cc (revision 1460) @@ -1,174 +1,175 @@ //---------------------------------------------------------------------- /// \file example_dpsi_slice.cc /// /// This example program is meant to illustrate how the /// fastjet::contrib::RecursiveLundEEGenerator class is used. /// /// Run this example with /// /// \verbatim /// ./example_dpsi_slice < ../data/single-ee-event.dat /// \endverbatim //---------------------------------------------------------------------- // $Id$ // // Copyright (c) 2018-, Frederic A. Dreyer, Keith Hamilton, Alexander Karlberg, // Gavin P. Salam, Ludovic Scyboz, Gregory Soyez, Rob Verheyen // //---------------------------------------------------------------------- // This file is part of FastJet contrib. // // It is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at // your option) any later version. // // It is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public // License for more details. // // You should have received a copy of the GNU General Public License // along with this code. If not, see <http://www.gnu.org/licenses/>. //---------------------------------------------------------------------- #include <iostream> #include <fstream> #include <sstream> #include "fastjet/PseudoJet.hh" #include "fastjet/EECambridgePlugin.hh" #include <string> -#include "RecursiveLundEEGenerator.hh" // In external code, this should be fastjet/contrib/RecursiveLundEEGenerator.hh +#include "fastjet/contrib/RecursiveLundEEGenerator.hh" + using namespace std; using namespace fastjet; // Definitions for the slice observable (ymax = 1, zcut = 0.1) double abs_rap_slice = 1; double z2_cut = 0.1; // forward declaration to make things clearer void read_event(vector<PseudoJet> &event); // returns true if PseudoJet p is in the central slice of half-width abs_rap_slice // w.r.t. the event axis pref bool in_slice(const PseudoJet & p, const PseudoJet & pref) { // Rotate p, and use the rapidity to determine if p is in the slice contrib::lund_plane::Matrix3 rotmat = contrib::lund_plane::Matrix3::from_direction(pref).transpose(); const PseudoJet p_rot = rotmat*p; return fabs(p_rot.rap()) < abs_rap_slice; } //---------------------------------------------------------------------- int main(){ //---------------------------------------------------------- // read in input particles vector<PseudoJet> event; read_event(event); cout << "# read an event with " << event.size() << " particles" << endl; //---------------------------------------------------------- // create an instance of RecursiveLundEEGenerator, with default options int depth = -1; bool dynamic_psi_reference = true; fastjet::contrib::RecursiveLundEEGenerator lund(depth, dynamic_psi_reference); // first get some C/A jets double y3_cut = 1.0; JetDefinition::Plugin* ee_plugin = new EECambridgePlugin(y3_cut); JetDefinition jet_def(ee_plugin); ClusterSequence cs(event, jet_def); // Get the event axis (to be used for the slice) std::vector<PseudoJet> excl = cs.exclusive_jets(2); assert(excl.size() == 2); // order the two jets according to momentum along z axis if (excl[0].pz() < excl[1].pz()) { std::swap(excl[0],excl[1]); } const PseudoJet ev_axis = excl[0]-excl[1]; // Get the list of primary declusterings const vector<contrib::LundEEDeclustering> declusts = lund.result(cs); // find the declustering that throws something into a fixed slice // (from a parent that was not in the slice) and that throws the // largest pt (relative to the z axis) into that slice int index_of_max_pt_in_slice = -1; double max_pt_in_slice = 0.0; double psi_1 = 0.0; //< init just to avoid a compiler warning (the //< test in L115 makes it safe already) for (unsigned i = 0; i < declusts.size(); i++) { const auto & decl = declusts[i]; if (!in_slice(decl.harder(), ev_axis) && in_slice(decl.softer(), ev_axis)) { if (decl.softer().pt() > max_pt_in_slice) { index_of_max_pt_in_slice = i; max_pt_in_slice = decl.softer().pt(); psi_1 = decl.psibar(); } } } if (index_of_max_pt_in_slice < 0) return 0; // establish what we need to follow and the reference psi_1 int iplane_to_follow = declusts[index_of_max_pt_in_slice].leaf_iplane(); vector<const contrib::LundEEDeclustering *> secondaries; for (const auto & declust: declusts){ if (declust.iplane() == iplane_to_follow) secondaries.push_back(&declust); } int index_of_max_kt_secondary = -1; double dpsi; for (unsigned int i_secondary=0; i_secondary<secondaries.size(); i_secondary++) { if (secondaries[i_secondary]->z() > z2_cut) { index_of_max_kt_secondary = i_secondary; double psi_2 = secondaries[i_secondary]->psibar(); dpsi = contrib::lund_plane::map_to_pi(psi_2 - psi_1); break; } } if (index_of_max_kt_secondary < 0) return 0; cout << "Primary in the central slice, with Lund coordinates ( ln 1/Delta, ln kt, psibar ):" << endl; pair<double,double> coords = declusts[index_of_max_pt_in_slice].lund_coordinates(); cout << "index [" << index_of_max_pt_in_slice << "](" << coords.first << ", " << coords.second << ", " << declusts[index_of_max_pt_in_slice].psibar() << ")" << endl; cout << endl << "with Lund coordinates for the (highest-kT) secondary plane that passes the zcut of " << z2_cut << endl; coords = secondaries[index_of_max_kt_secondary]->lund_coordinates(); cout << "index [" << index_of_max_kt_secondary << "](" << coords.first << ", " << coords.second << ", " << secondaries[index_of_max_kt_secondary]->psibar() << ")"; cout << " --> delta_psi,slice = " << dpsi << endl; // Delete the EECambridge plugin delete ee_plugin; return 0; } // read in input particles void read_event(vector<PseudoJet> &event){ string line; while (getline(cin, line)) { istringstream linestream(line); // take substrings to avoid problems when there is extra "pollution" // characters (e.g. line-feed). if (line.substr(0,4) == "#END") {return;} if (line.substr(0,1) == "#") {continue;} double px,py,pz,E; linestream >> px >> py >> pz >> E; PseudoJet particle(px,py,pz,E); // push event onto back of full_event vector event.push_back(particle); } } Index: contrib/contribs/LundPlane/trunk/Makefile =================================================================== --- contrib/contribs/LundPlane/trunk/Makefile (revision 1459) +++ contrib/contribs/LundPlane/trunk/Makefile (revision 1460) @@ -1,91 +1,112 @@ # If you are using this Makefile standalone and fastjet-config is not # in your path, edit this line to specify the full path FASTJETCONFIG=fastjet-config PREFIX=`$(FASTJETCONFIG) --prefix` CXX=g++ CXXFLAGS= -O3 -Wall -g install_script = $(SHELL) ../utils/install-sh check_script = ../utils/check.sh # global contrib-wide Makefile include may override some of the above # variables (leading "-" means don't give an error if you can't find # the file) -include ../.Makefile.inc #------------------------------------------------------------------------ # things that are specific to this contrib NAME=LundPlane SRCS=LundGenerator.cc LundWithSecondary.cc SecondaryLund.cc RecursiveLundEEGenerator.cc EXAMPLES=example example_secondary example_dpsi_collinear example_dpsi_slice INSTALLED_HEADERS=LundGenerator.hh LundWithSecondary.hh SecondaryLund.hh RecursiveLundEEGenerator.hh LundJSON.hh LundEEHelpers.hh +# List here any dependencies on other contribs. Note that they +# must be listed (potentially with versioning constraints) also +# in the FJCONTRIB.cfg file. +DEPENDS_ON = #------------------------------------------------------------------------ CXXFLAGS+= $(shell $(FASTJETCONFIG) --cxxflags) LDFLAGS += -lm $(shell $(FASTJETCONFIG) --libs --plugins) +INCLUDE += -Iinclude/ +# loop over all entries in DEPENDS_ON and for each entry ENTRY +# add -I../ENTRY to INCLUDE, -L../ENTRY to LDFLAGS and -lENTRY to LDFLAGS +INCLUDE += $(foreach ENTRY,$(DEPENDS_ON),-I../$(ENTRY)/include) +LDFLAGS += $(foreach ENTRY,$(DEPENDS_ON),-L../$(ENTRY) -l$(ENTRY)) +CXXFLAGS+= $(INCLUDE) + OBJS = $(SRCS:.cc=.o) EXAMPLES_SRCS = $(EXAMPLES:=.cc) install_HEADER = $(install_script) -c -m 644 install_LIB = $(install_script) -c -m 644 install_DIR = $(install_script) -d install_DATA = $(install_script) -c -m 644 install_PROGRAM = $(install_script) -c -s install_SCRIPT = $(install_script) -c .PHONY: clean distclean examples check install # compilation of the code (default target) all: lib$(NAME).a lib$(NAME).a: $(OBJS) ar cru lib$(NAME).a $(OBJS) ranlib lib$(NAME).a # building the examples examples: $(EXAMPLES) # the following construct makes it possible to automatically build # each of the examples listed in $EXAMPLES $(EXAMPLES): % : %.o all $(CXX) $(CXXFLAGS) -o $@ $< -L. -l$(NAME) $(LDFLAGS) # check that everything went fine check: examples @for prog in $(EXAMPLES); do\ if [ "$${prog}" = "example_dpsi_collinear" ] || [ "$${prog}" = "example_dpsi_slice" ]; then \ $(check_script) $${prog} ../data/single-ee-event.dat || exit 1; \ else \ $(check_script) $${prog} ../data/single-event.dat || exit 1; \ fi; \ done @echo "All tests successful" # cleaning the directory clean: rm -f *~ *.o distclean: clean rm -f lib$(NAME).a $(EXAMPLES) # install things in PREFIX/... install: all $(install_DIR) $(PREFIX)/include/fastjet/contrib for header in $(INSTALLED_HEADERS); do\ - $(install_HEADER) $$header $(PREFIX)/include/fastjet/contrib/;\ + $(install_HEADER) include/fastjet/contrib/$$header $(PREFIX)/include/fastjet/contrib/;\ done $(install_DIR) $(PREFIX)/lib $(install_LIB) lib$(NAME).a $(PREFIX)/lib depend: - makedepend -Y -- -- $(SRCS) $(EXAMPLES_SRCS) + makedepend -Y -- -Iinclude -- $(SRCS) $(EXAMPLES_SRCS) # DO NOT DELETE -LundGenerator.o: LundGenerator.hh -LundWithSecondary.o: LundWithSecondary.hh LundGenerator.hh SecondaryLund.hh -SecondaryLund.o: SecondaryLund.hh LundGenerator.hh -RecursiveLundEEGenerator.o: RecursiveLundEEGenerator.hh LundEEHelpers.hh -example.o: LundGenerator.hh LundJSON.hh -example_secondary.o: LundWithSecondary.hh LundGenerator.hh SecondaryLund.hh -example_dpsi_collinear.o: RecursiveLundEEGenerator.hh LundEEHelpers.hh -example_dpsi_slice.o: RecursiveLundEEGenerator.hh LundEEHelpers.hh +LundGenerator.o: include/fastjet/contrib/LundGenerator.hh +LundWithSecondary.o: include/fastjet/contrib/LundWithSecondary.hh +LundWithSecondary.o: include/fastjet/contrib/LundGenerator.hh +LundWithSecondary.o: include/fastjet/contrib/SecondaryLund.hh +SecondaryLund.o: include/fastjet/contrib/SecondaryLund.hh +SecondaryLund.o: include/fastjet/contrib/LundGenerator.hh +RecursiveLundEEGenerator.o: include/fastjet/contrib/RecursiveLundEEGenerator.hh +RecursiveLundEEGenerator.o: include/fastjet/contrib/LundEEHelpers.hh +example.o: include/fastjet/contrib/LundGenerator.hh +example.o: include/fastjet/contrib/LundJSON.hh +example.o: include/fastjet/contrib/LundGenerator.hh +example_secondary.o: include/fastjet/contrib/LundWithSecondary.hh +example_secondary.o: include/fastjet/contrib/LundGenerator.hh +example_secondary.o: include/fastjet/contrib/SecondaryLund.hh +example_dpsi_collinear.o: include/fastjet/contrib/RecursiveLundEEGenerator.hh +example_dpsi_collinear.o: include/fastjet/contrib/LundEEHelpers.hh +example_dpsi_slice.o: include/fastjet/contrib/RecursiveLundEEGenerator.hh +example_dpsi_slice.o: include/fastjet/contrib/LundEEHelpers.hh Index: contrib/contribs/LundPlane/trunk/FJCONTRIB.cfg =================================================================== --- contrib/contribs/LundPlane/trunk/FJCONTRIB.cfg (revision 0) +++ contrib/contribs/LundPlane/trunk/FJCONTRIB.cfg (revision 1460) @@ -0,0 +1 @@ +version: 2.1.2-devel Index: contrib/contribs/LundPlane/trunk/example.cc =================================================================== --- contrib/contribs/LundPlane/trunk/example.cc (revision 1459) +++ contrib/contribs/LundPlane/trunk/example.cc (revision 1460) @@ -1,119 +1,120 @@ //---------------------------------------------------------------------- /// \file example.cc /// /// This example program is meant to illustrate how the /// fastjet::contrib::LundGenerator class is used. /// /// Run this example with /// /// \verbatim /// ./example < ../data/single-event.dat /// \endverbatim //---------------------------------------------------------------------- // $Id$ // // Copyright (c) 2018-, Frederic A. Dreyer, Keith Hamilton, Alexander Karlberg, // Gavin P. Salam, Ludovic Scyboz, Gregory Soyez, Rob Verheyen // //---------------------------------------------------------------------- // This file is part of FastJet contrib. // // It is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at // your option) any later version. // // It is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public // License for more details. // // You should have received a copy of the GNU General Public License // along with this code. If not, see <http://www.gnu.org/licenses/>. //---------------------------------------------------------------------- #include <iostream> #include <fstream> #include <sstream> #include "fastjet/PseudoJet.hh" #include <string> -#include "LundGenerator.hh" // In external code, this should be fastjet/contrib/LundGenerator.hh -#include "LundJSON.hh" // In external code, this should be fastjet/contrib/LundJSON.hh +#include "fastjet/contrib/LundGenerator.hh" +#include "fastjet/contrib/LundJSON.hh" + using namespace std; using namespace fastjet; // forward declaration to make things clearer void read_event(vector<PseudoJet> &event); //---------------------------------------------------------------------- int main(){ //---------------------------------------------------------- // read in input particles vector<PseudoJet> event; read_event(event); string filename = "jets.json"; cout << "# read an event with " << event.size() << " particles" << endl; cout << "# writing declusterings of primary and secondary plane to file " << filename << endl; ofstream outfile; outfile.open(filename.c_str()); // first get some anti-kt jets double R = 1.0, ptmin = 100.0; JetDefinition jet_def(antikt_algorithm, R); ClusterSequence cs(event, jet_def); vector<PseudoJet> jets = sorted_by_pt(cs.inclusive_jets(ptmin)); //---------------------------------------------------------- // create an instance of LundGenerator, with default options contrib::LundGenerator lund; cout << lund.description() << endl; for (unsigned ijet = 0; ijet < jets.size(); ijet++) { cout << endl << "Lund coordinates ( ln 1/Delta, ln kt ) of declusterings of jet " << ijet << " are:" << endl; vector<contrib::LundDeclustering> declusts = lund(jets[ijet]); for (unsigned int idecl = 0; idecl < declusts.size(); ++idecl) { pair<double,double> coords = declusts[idecl].lund_coordinates(); cout << "(" << coords.first << ", " << coords.second << ")"; if (idecl < declusts.size() - 1) cout << "; "; } cout << endl; // outputs the primary Lund plane lund_to_json(outfile, declusts); outfile << endl; // outputs the full Lund tree //to_json(cout, lund_gen, jets[ijet]); cout << endl; } cout << endl << "File " << filename << " written." << endl; return 0; } // read in input particles void read_event(vector<PseudoJet> &event){ string line; while (getline(cin, line)) { istringstream linestream(line); // take substrings to avoid problems when there is extra "pollution" // characters (e.g. line-feed). if (line.substr(0,4) == "#END") {return;} if (line.substr(0,1) == "#") {continue;} double px,py,pz,E; linestream >> px >> py >> pz >> E; PseudoJet particle(px,py,pz,E); // push event onto back of full_event vector event.push_back(particle); } }