Index: contrib/contribs/LundPlane/trunk/VERSION
===================================================================
--- contrib/contribs/LundPlane/trunk/VERSION	(revision 1291)
+++ contrib/contribs/LundPlane/trunk/VERSION	(revision 1292)
@@ -1 +1 @@
-1.0.4
+2.0.0
Index: contrib/contribs/LundPlane/trunk/example_dpsi_collinear.cc
===================================================================
--- contrib/contribs/LundPlane/trunk/example_dpsi_collinear.cc	(revision 1291)
+++ contrib/contribs/LundPlane/trunk/example_dpsi_collinear.cc	(revision 1292)
@@ -1,145 +1,145 @@
 //----------------------------------------------------------------------
 /// \file example_dpsi_collinear.cc
 ///
 /// This example program is meant to illustrate how the
-/// fastjet::contrib::LundEEGenerator class is used.
+/// fastjet::contrib::RecursiveLundEEGenerator class is used.
 ///
 /// Run this example with
 ///
 /// \verbatim
 ///     ./example_dpsi_collinear < ../data/single-ee-event.dat
 /// \endverbatim
 
 //----------------------------------------------------------------------
-// $Id: example_dpsi_collinear.cc 1164 2018-08-23 10:06:45Z gsalam $
+// $Id$
 //
-// Copyright (c) 2018-, Frederic A. Dreyer, A. Karlberg, Gavin P. Salam,
-// Ludovic Scyboz, Gregory Soyez
+// 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 "LundEEGenerator.hh" // In external code, this should be fastjet/contrib/LundEEGenerator.hh
+#include "RecursiveLundEEGenerator.hh" // In external code, this should be 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;
   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 list of primary declusterings
   const vector<contrib::LundEEDeclustering> declusts = lund.result(cs);
   
   // Find the highest-kt primary declustering (ordered in kt by default)
   int i_primary = -1;
   double psi_1;
   for (int i=0; i<declusts.size(); i++) {
     if (declusts[i].depth() == 0 && declusts[i].z() > z1_cut) {
         i_primary = i;
         psi_1 = declusts[i].psibar();
         break;
     }
   }
   if (i_primary < 0) return 0;
 
   // Find the highest-kt secondary associated to that Lund leaf
   int iplane_to_follow = declusts[i_primary].leaf_iplane();
   vector<const contrib::LundEEDeclustering *> secondaries;
   for (const auto & declust: declusts){
       if (declust.iplane() == iplane_to_follow) secondaries.push_back(&declust);
   }
   if(secondaries.size() < 1) return 0;
 
   int i_secondary = -1;
   double dpsi;
   for (int i=0; i<secondaries.size(); i++) {
       if (secondaries[i]->z() > z2_cut) {
           i_secondary = i;
           double psi_2 = secondaries[i]->psibar();
           dpsi = contrib::map_to_pi(psi_2-psi_1);
           break;
       }
   }
   if (i_secondary < 0) return 0;
 
   cout << "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].lund_coordinates();
   cout << "index [" << i_primary << "](" << coords.first << ", " << coords.second << ", "
        << declusts[i_primary].psibar() << ")" << endl;
   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 = " << 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);
   }
 }

Property changes on: contrib/contribs/LundPlane/trunk/example_dpsi_collinear.cc
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: contrib/contribs/LundPlane/trunk/ChangeLog
===================================================================
--- contrib/contribs/LundPlane/trunk/ChangeLog	(revision 1291)
+++ contrib/contribs/LundPlane/trunk/ChangeLog	(revision 1292)
@@ -1,41 +1,54 @@
+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/EEHelpers.hh
===================================================================
--- contrib/contribs/LundPlane/trunk/EEHelpers.hh	(revision 1291)
+++ contrib/contribs/LundPlane/trunk/EEHelpers.hh	(revision 1292)
@@ -1,262 +1,262 @@
-// $Id: EEHelpers.hh 1153 2018-08-22 11:56:35Z akarlberg, lscyboz $
+// $Id$
 //
-// Copyright (c) 2018-, Frederic A. Dreyer, A. Karlberg, Gavin P. Salam,
-// Ludovic Scyboz, Gregory Soyez
+// 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>
 
 FASTJET_BEGIN_NAMESPACE
 
 namespace contrib{
 
 //----------------------------------------------------------------------
 /// 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.
 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 contrib
 
 FASTJET_END_NAMESPACE
 
 #endif // __FASTJET_CONTRIB_EEHELPERS_HH__
 

Property changes on: contrib/contribs/LundPlane/trunk/EEHelpers.hh
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: contrib/contribs/LundPlane/trunk/example_dpsi_slice.cc
===================================================================
--- contrib/contribs/LundPlane/trunk/example_dpsi_slice.cc	(revision 1291)
+++ contrib/contribs/LundPlane/trunk/example_dpsi_slice.cc	(revision 1292)
@@ -1,173 +1,173 @@
 //----------------------------------------------------------------------
 /// \file example_dpsi_slice.cc
 ///
 /// This example program is meant to illustrate how the
-/// fastjet::contrib::LundEEGenerator class is used.
+/// fastjet::contrib::RecursiveLundEEGenerator class is used.
 ///
 /// Run this example with
 ///
 /// \verbatim
 ///     ./example_dpsi_slice < ../data/single-ee-event.dat
 /// \endverbatim
 
 //----------------------------------------------------------------------
-// $Id: example_dpsi_slice.cc 1164 2018-08-23 10:06:45Z gsalam $
+// $Id$
 //
-// Copyright (c) 2018-, Frederic A. Dreyer, A. Karlberg, Gavin P. Salam,
-// Ludovic Scyboz, Gregory Soyez
+// 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 "LundEEGenerator.hh" // In external code, this should be fastjet/contrib/LundEEGenerator.hh
+#include "RecursiveLundEEGenerator.hh" // In external code, this should be 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::Matrix3 rotmat = contrib::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;
   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 (uint 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::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);
   }
 }

Property changes on: contrib/contribs/LundPlane/trunk/example_dpsi_slice.cc
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Index: contrib/contribs/LundPlane/trunk/Makefile
===================================================================
--- contrib/contribs/LundPlane/trunk/Makefile	(revision 1291)
+++ contrib/contribs/LundPlane/trunk/Makefile	(revision 1292)
@@ -1,88 +1,88 @@
 # 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 LundEEGenerator.cc
+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 LundEEGenerator.hh LundJSON.hh
+INSTALLED_HEADERS=LundGenerator.hh LundWithSecondary.hh SecondaryLund.hh RecursiveLundEEGenerator.hh LundJSON.hh
 #------------------------------------------------------------------------
 
 CXXFLAGS+= $(shell $(FASTJETCONFIG) --cxxflags)
 LDFLAGS += -lm $(shell $(FASTJETCONFIG) --libs) -lfastjetplugins
 
 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/;\
 	done
 	$(install_DIR) $(PREFIX)/lib
 	$(install_LIB) lib$(NAME).a $(PREFIX)/lib
 
 depend:
 	makedepend -Y --   -- $(SRCS) $(EXAMPLES_SRCS)
 # DO NOT DELETE
 
 LundGenerator.o: LundGenerator.hh
 LundWithSecondary.o: LundWithSecondary.hh LundGenerator.hh SecondaryLund.hh
 SecondaryLund.o: SecondaryLund.hh LundGenerator.hh
 example.o: LundGenerator.hh SecondaryLund.hh LundJSON.hh
 example_secondary.o: LundWithSecondary.hh LundGenerator.hh SecondaryLund.hh