Index: external/fastjet/AUTHORS
===================================================================
--- external/fastjet/AUTHORS	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/AUTHORS	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -10,7 +10,7 @@
 ----------------------------------------------------------------------
 
-Many people have provided bug reports, suggestions for development and
-in some cases explicit code for plugin algorithms. We would in
-particular like to thank
+Many people have provided bug reports, suggestions for development,
+documentation and in some cases explicit code for plugin
+algorithms. We would in particular like to thank
 
 Vanya Belyaev
@@ -32,4 +32,5 @@
 Hartmut Stadie
 Mark Sutton
+Jesse Thaler
 Chris Vermilion
 Markus Wobisch 
Index: external/fastjet/ActiveAreaSpec.hh
===================================================================
--- external/fastjet/ActiveAreaSpec.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ActiveAreaSpec.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: ActiveAreaSpec.hh 2577 2011-09-13 15:11:38Z salam $
+//FJSTARTHEADER
+// $Id: ActiveAreaSpec.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
Index: external/fastjet/AreaDefinition.cc
===================================================================
--- external/fastjet/AreaDefinition.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/AreaDefinition.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: AreaDefinition.cc 3619 2014-08-13 14:17:19Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/AreaDefinition.hh"
@@ -68,7 +70,7 @@
     break;
   default:
-    cerr << "Error: unrecognized area_type in AreaDefinition::description():" 
+    ostr << "Error: unrecognized area_type in AreaDefinition::description():" 
          << area_type() << endl;
-    exit(-1);
+    throw Error(ostr.str());
   }
   return ostr.str();
Index: external/fastjet/AreaDefinition.hh
===================================================================
--- external/fastjet/AreaDefinition.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/AreaDefinition.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: AreaDefinition.hh 2687 2011-11-14 11:17:51Z soyez $
+//FJSTARTHEADER
+// $Id: AreaDefinition.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2006-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2006-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
Index: external/fastjet/BasicRandom.cc
===================================================================
--- external/fastjet/BasicRandom.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/BasicRandom.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,14 +1,23 @@
-//STARTHEADER
-// simple random number generator class taken from nlojet++.
-// $Id$
+//FJSTARTHEADER
+// $Id: BasicRandom.cc 3433 2014-07-23 08:17:03Z salam $
 //
-//  Copyright (C) 2002 Zoltan Nagy
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
-//  This program is free software; you can redistribute it and/or modify
+//----------------------------------------------------------------------
+// This file is part of FastJet.
+//
+//  FastJet 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.
 //
-//  This program is distributed in the hope that it will be useful,
+//  The algorithms that underlie FastJet have required considerable
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
+//  FastJet as part of work towards a scientific publication, please
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
+//
+//  FastJet 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
@@ -16,7 +25,7 @@
 //
 //  You should have received a copy of the GNU General Public License
-//  along with this program; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//ENDHEADER
+//  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
+//----------------------------------------------------------------------
+//FJENDHEADER
 
 //   nlo includes
Index: external/fastjet/CircularRange.hh
===================================================================
--- external/fastjet/CircularRange.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/CircularRange.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: CircularRange.hh 2577 2011-09-13 15:11:38Z salam $
+//FJSTARTHEADER
+// $Id: CircularRange.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
Index: external/fastjet/ClosestPair2D.cc
===================================================================
--- external/fastjet/ClosestPair2D.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClosestPair2D.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: ClosestPair2D.cc 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/internal/ClosestPair2D.hh"
@@ -36,5 +38,4 @@
 FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
 
-const unsigned int huge_unsigned = 4294967295U;
 const unsigned int twopow31      = 2147483648U;
 
@@ -183,4 +184,8 @@
   ID2 = _ID(_points[ID1].neighbour);
   distance2 = _points[ID1].neighbour_dist2;
+  // we make the swap explicitly in the std namespace to avoid
+  // potential conflict with the fastjet::swap introduced by
+  // SharedPtr.
+  // This is only an issue because we are in the fastjet namespace
   if (ID1 > ID2) std::swap(ID1,ID2);
 }
Index: external/fastjet/ClusterSequence.cc
===================================================================
--- external/fastjet/ClusterSequence.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequence.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: ClusterSequence.cc 3619 2014-08-13 14:17:19Z salam $
 //
-// Copyright (c) 2005-2013, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/Error.hh"
@@ -32,4 +34,8 @@
 #include "fastjet/ClusterSequenceStructure.hh"
 #include "fastjet/version.hh" // stores the current version number
+#include "fastjet/internal/LazyTiling9Alt.hh"
+#include "fastjet/internal/LazyTiling9.hh"
+#include "fastjet/internal/LazyTiling25.hh"
+#include "fastjet/internal/LazyTiling9SeparateGhosts.hh"
 #include<iostream>
 #include<sstream>
@@ -187,5 +193,5 @@
 //DEP //----------------------------------------------------------------------
 //DEP void ClusterSequence::_initialise_and_run (
-//DEP 				  const double & R,
+//DEP 				  const double R,
 //DEP 				  const Strategy & strategy,
 //DEP 				  const bool & writeout_combinations) {
@@ -273,4 +279,10 @@
   //             ./fastjet_timing_plugins -kt -nhardest 30 -repeat 50000 -strategy -3 -R 0.5 -nev 1  <  ../../data/Pythia-PtMin1000-LHC-1000ev.dat
   if (_strategy == Best) {
+    _strategy = _best_strategy();
+#ifdef DROP_CGAL
+    // fall back strategy for large N when CGAL is missing
+    if (_strategy == NlnN) _strategy = N2MHTLazy25;
+#endif  // DROP_CGAL
+  } else if (_strategy == BestFJ30) {
     int N = _jets.size();
     //if (N <= 55*max(0.5,min(1.0,_Rparam))) {// old empirical scaling with R
@@ -324,5 +336,5 @@
   // run the code containing the selected strategy
   // 
-  // We order the strategies stqrting from the ones used by the Best
+  // We order the strategies starting from the ones used by the Best
   // strategy in the order of increasing N, then the remaining ones
   // again in the order of increasing N.
@@ -334,4 +346,36 @@
   } else if (_strategy == N2MinHeapTiled) {
     this->_minheap_faster_tiled_N2_cluster();
+  } else if (_strategy == N2MHTLazy9Alt) {
+    // attempt to use an external tiling routine -- it manipulates
+    // the CS history via the plugin mechanism
+    _plugin_activated = true;
+    LazyTiling9Alt tiling(*this);
+    tiling.run();
+    _plugin_activated = false;
+
+  } else if (_strategy == N2MHTLazy25) {
+    // attempt to use an external tiling routine -- it manipulates
+    // the CS history via the plugin mechanism
+    _plugin_activated = true;
+    LazyTiling25 tiling(*this);
+    tiling.run();
+    _plugin_activated = false;
+
+  } else if (_strategy == N2MHTLazy9) {
+    // attempt to use an external tiling routine -- it manipulates
+    // the CS history via the plugin mechanism
+    _plugin_activated = true;
+    LazyTiling9 tiling(*this);
+    tiling.run();
+    _plugin_activated = false;
+
+  } else if (_strategy == N2MHTLazy9AntiKtSeparateGhosts) {
+    // attempt to use an external tiling routine -- it manipulates
+    // the CS history via the plugin mechanism
+    _plugin_activated = true;
+    LazyTiling9SeparateGhosts tiling(*this);
+    tiling.run();
+    _plugin_activated = false;
+
   } else if (_strategy == NlnN) {
     this->_delaunay_cluster();
@@ -359,5 +403,5 @@
 // these needs to be defined outside the class definition.
 bool ClusterSequence::_first_time = true;
-int ClusterSequence::_n_exclusive_warnings = 0;
+LimitedWarning ClusterSequence::_exclusive_warnings;
 
 
@@ -473,6 +517,4 @@
 
 //----------------------------------------------------------------------
-// Return the component corresponding to the specified index.
-// taken from CLHEP
 string ClusterSequence::strategy_string (Strategy strategy_in)  const {
   string strategy;
@@ -492,4 +534,12 @@
   case N2PoorTiled:
     strategy = "N2PoorTiled"; break;
+  case N2MHTLazy9:
+    strategy = "N2MHTLazy9"; break;
+  case N2MHTLazy9Alt:
+    strategy = "N2MHTLazy9Alt"; break;
+  case N2MHTLazy25:
+    strategy = "N2MHTLazy25"; break;
+  case N2MHTLazy9AntiKtSeparateGhosts:
+    strategy = "N2MHTLazy9AntiKtSeparateGhosts"; break;
   case N3Dumb:
     strategy = "N3Dumb"; break;
@@ -528,4 +578,148 @@
     } else {return 1.0;}
   } else {throw Error("Unrecognised jet algorithm");}
+}
+
+//----------------------------------------------------------------------
+// returns a suggestion for the best strategy to use on event
+// multiplicity, algorithm, R, etc.
+//
+// Some of the work to establish the best strategy is collected in
+// issue-tracker/2014-07-auto-strategy-selection;
+// transition_fit_v2.fit indicates the results of the fits that we're
+// using here. (Automatically generated by transition_fit_v2.gp).
+//
+// The transition to NlnN is always present, and it is the the
+// caller's responsibility to drop back down to N2MHTLazy25 if NlnN
+// isn't available.
+//
+// This routine should be called only if the jet alg is one of kt,
+// antikt, cam or genkt.
+Strategy ClusterSequence::_best_strategy() const {
+  int N = _jets.size();
+  // define bounded R, always above 0.1, because we don't trust any
+  // of our parametrizations below R = 0.1
+  double bounded_R = max(_Rparam, 0.1);
+
+  // the very first test thing is a quick hard-coded test to decide
+  // if we immediately opt for N2Plain
+  if (N <= 30 || N <= 39.0/(bounded_R + 0.6)) {
+    return N2Plain;
+  } 
+  
+  // Define objects that describe our various boundaries. A prefix N_
+  // indicates that boundary is for N, while L_ means it's for log(N).
+  //
+  // Hopefully having them static will ensure minimal overhead
+  // in creating them; collecting them in one place should
+  // help with updates?
+  //
+  const static _Parabola N_Tiled_to_MHT_lowR             (-45.4947,54.3528,44.6283);
+  const static _Parabola L_MHT_to_MHTLazy9_lowR          (0.677807,-1.05006,10.6994);
+  const static _Parabola L_MHTLazy9_to_MHTLazy25_akt_lowR(0.169967,-0.512589,12.1572);
+  const static _Parabola L_MHTLazy9_to_MHTLazy25_kt_lowR (0.16237,-0.484612,12.3373);
+  const static _Parabola L_MHTLazy9_to_MHTLazy25_cam_lowR = L_MHTLazy9_to_MHTLazy25_kt_lowR;
+  const static _Parabola L_MHTLazy25_to_NlnN_akt_lowR    (0.0472051,-0.22043,15.9196);
+  const static _Parabola L_MHTLazy25_to_NlnN_kt_lowR     (0.118609,-0.326811,14.8287);
+  const static _Parabola L_MHTLazy25_to_NlnN_cam_lowR    (0.10119,-0.295748,14.3924);
+
+  const static _Line     L_Tiled_to_MHTLazy9_medR         (-1.31304,7.29621);
+  const static _Parabola L_MHTLazy9_to_MHTLazy25_akt_medR = L_MHTLazy9_to_MHTLazy25_akt_lowR;
+  const static _Parabola L_MHTLazy9_to_MHTLazy25_kt_medR  = L_MHTLazy9_to_MHTLazy25_kt_lowR;
+  const static _Parabola L_MHTLazy9_to_MHTLazy25_cam_medR = L_MHTLazy9_to_MHTLazy25_cam_lowR;
+  const static _Parabola L_MHTLazy25_to_NlnN_akt_medR     = L_MHTLazy25_to_NlnN_akt_lowR;
+  const static _Parabola L_MHTLazy25_to_NlnN_kt_medR      = L_MHTLazy25_to_NlnN_kt_lowR;
+  const static _Parabola L_MHTLazy25_to_NlnN_cam_medR     = L_MHTLazy25_to_NlnN_cam_lowR;
+
+  const static double    N_Plain_to_MHTLazy9_largeR         = 75;
+  const static double    N_MHTLazy9_to_MHTLazy25_akt_largeR = 700;
+  const static double    N_MHTLazy9_to_MHTLazy25_kt_largeR  = 1000;
+  const static double    N_MHTLazy9_to_MHTLazy25_cam_largeR = 1000;
+  const static double    N_MHTLazy25_to_NlnN_akt_largeR     = 100000;
+  const static double    N_MHTLazy25_to_NlnN_kt_largeR      = 40000;
+  const static double    N_MHTLazy25_to_NlnN_cam_largeR     = 15000;
+
+  // We have timing studies only for kt, cam and antikt; for other
+  // algorithms we set the local jet_algorithm variable to the one of
+  // kt,cam,antikt that we think will be closest in behaviour to the
+  // other alg.
+  JetAlgorithm jet_algorithm;
+  if (_jet_algorithm == genkt_algorithm) {
+    // for genkt, then we set the local jet_algorithm variable (used
+    // only for strategy choice) to be either kt or antikt, depending on
+    // the p value.
+    double p   = jet_def().extra_param();
+    if (p < 0.0) jet_algorithm = antikt_algorithm;
+    else         jet_algorithm =     kt_algorithm;
+  } else if (_jet_algorithm == cambridge_for_passive_algorithm) {
+    // we assume (but haven't tested) that using the kt-alg timing
+    // transitions should be adequate for cambridge_for_passive_algorithm
+    jet_algorithm = kt_algorithm;
+  } else {
+    jet_algorithm = _jet_algorithm;
+  }
+
+  if (bounded_R < 0.65) {
+    // low R case
+    if          (N    < N_Tiled_to_MHT_lowR(bounded_R))              return N2Tiled;
+    double logN = log(double(N));
+    if          (logN < L_MHT_to_MHTLazy9_lowR(bounded_R))           return N2MinHeapTiled;
+    else {
+      if (jet_algorithm == antikt_algorithm){
+        if      (logN < L_MHTLazy9_to_MHTLazy25_akt_lowR(bounded_R)) return N2MHTLazy9;
+        else if (logN < L_MHTLazy25_to_NlnN_akt_lowR(bounded_R))     return N2MHTLazy25;
+        else                                                         return NlnN;
+      } else if (jet_algorithm == kt_algorithm){
+        if      (logN < L_MHTLazy9_to_MHTLazy25_kt_lowR(bounded_R))  return N2MHTLazy9;
+        else if (logN < L_MHTLazy25_to_NlnN_kt_lowR(bounded_R))      return N2MHTLazy25;
+        else                                                         return NlnN;
+      } else if (jet_algorithm == cambridge_algorithm)  {
+        if      (logN < L_MHTLazy9_to_MHTLazy25_cam_lowR(bounded_R)) return N2MHTLazy9;
+        else if (logN < L_MHTLazy25_to_NlnN_cam_lowR(bounded_R))     return N2MHTLazy25;
+        else                                                         return NlnNCam;
+      }
+    }
+  } else if (bounded_R < 0.5*pi) {
+    // medium R case
+    double logN = log(double(N));
+    if      (logN < L_Tiled_to_MHTLazy9_medR(bounded_R))             return N2Tiled;
+    else {
+      if (jet_algorithm == antikt_algorithm){
+        if      (logN < L_MHTLazy9_to_MHTLazy25_akt_medR(bounded_R)) return N2MHTLazy9;
+        else if (logN < L_MHTLazy25_to_NlnN_akt_medR(bounded_R))     return N2MHTLazy25;
+        else                                                         return NlnN;
+      } else if (jet_algorithm == kt_algorithm){
+        if      (logN < L_MHTLazy9_to_MHTLazy25_kt_medR(bounded_R))  return N2MHTLazy9;
+        else if (logN < L_MHTLazy25_to_NlnN_kt_medR(bounded_R))      return N2MHTLazy25;
+        else                                                         return NlnN;
+      } else if (jet_algorithm == cambridge_algorithm)  {
+        if      (logN < L_MHTLazy9_to_MHTLazy25_cam_medR(bounded_R)) return N2MHTLazy9;
+        else if (logN < L_MHTLazy25_to_NlnN_cam_medR(bounded_R))     return N2MHTLazy25;
+        else                                                         return NlnNCam;
+      }
+    }
+  } else {
+    // large R case (R > pi/2)
+    if      (N    < N_Plain_to_MHTLazy9_largeR)                      return N2Plain;
+    else {
+      if (jet_algorithm == antikt_algorithm){
+        if      (N < N_MHTLazy9_to_MHTLazy25_akt_largeR)             return N2MHTLazy9;
+        else if (N < N_MHTLazy25_to_NlnN_akt_largeR)                 return N2MHTLazy25;
+        else                                                         return NlnN;
+      } else if (jet_algorithm == kt_algorithm){
+        if      (N < N_MHTLazy9_to_MHTLazy25_kt_largeR)              return N2MHTLazy9;
+        else if (N < N_MHTLazy25_to_NlnN_kt_largeR)                  return N2MHTLazy25;
+        else                                                         return NlnN;
+      } else if (jet_algorithm == cambridge_algorithm)  {
+        if      (N < N_MHTLazy9_to_MHTLazy25_cam_largeR)             return N2MHTLazy9;
+        else if (N < N_MHTLazy25_to_NlnN_cam_largeR)                 return N2MHTLazy25;
+        else                                                         return NlnNCam;
+      }
+    }
+  }
+  
+  bool code_should_never_reach_here = false;
+  assert(code_should_never_reach_here); 
+  return N2MHTLazy9;
+
 }
 
@@ -662,5 +856,5 @@
 //----------------------------------------------------------------------
 // return all inclusive jets with pt > ptmin
-vector<PseudoJet> ClusterSequence::inclusive_jets (const double & ptmin) const{
+vector<PseudoJet> ClusterSequence::inclusive_jets (const double ptmin) const{
   double dcut = ptmin*ptmin;
   int i = _history.size() - 1; // last jet
@@ -714,5 +908,5 @@
 // return the number of exclusive jets that would have been obtained
 // running the algorithm in exclusive mode with the given dcut
-int ClusterSequence::n_exclusive_jets (const double & dcut) const {
+int ClusterSequence::n_exclusive_jets (const double dcut) const {
 
   // first locate the point where clustering would have stopped (i.e. the
@@ -733,5 +927,5 @@
 // return all exclusive jets that would have been obtained running
 // the algorithm in exclusive mode with the given dcut
-vector<PseudoJet> ClusterSequence::exclusive_jets (const double & dcut) const {
+vector<PseudoJet> ClusterSequence::exclusive_jets (const double dcut) const {
   int njets = n_exclusive_jets(dcut);
   return exclusive_jets(njets);
@@ -742,5 +936,5 @@
 // return the jets obtained by clustering the event to n jets.
 // Throw an error if there are fewer than n particles.
-vector<PseudoJet> ClusterSequence::exclusive_jets (const int & njets) const {
+vector<PseudoJet> ClusterSequence::exclusive_jets (const int njets) const {
 
   // make sure the user does not ask for more than jets than there
@@ -759,9 +953,9 @@
 // return the jets obtained by clustering the event to n jets.
 // If there are fewer than n particles, simply return all particles
-vector<PseudoJet> ClusterSequence::exclusive_jets_up_to (const int & njets) const {
+vector<PseudoJet> ClusterSequence::exclusive_jets_up_to (const int njets) const {
 
   // provide a warning when extracting exclusive jets for algorithms 
   // that does not support it explicitly.
-  // Native algorithm that support it are: kt, ee_kt, cambridge, 
+  // Native algorithm that support it are: kt, ee_kt, Cambridge/Aachen, 
   //   genkt and ee_genkt (both with p>=0)
   // For plugins, we check Plugin::exclusive_sequence_meaningful()
@@ -773,8 +967,6 @@
        (_jet_def.extra_param() <0)) &&
       ((_jet_def.jet_algorithm() != plugin_algorithm) ||
-       (!_jet_def.plugin()->exclusive_sequence_meaningful())) &&
-      (_n_exclusive_warnings < 5)) {
-    _n_exclusive_warnings++;
-    cerr << "FastJet WARNING: dcut and exclusive jets for jet-finders other than kt should be interpreted with care." << endl;
+       (!_jet_def.plugin()->exclusive_sequence_meaningful()))) {
+    _exclusive_warnings.warn("dcut and exclusive jets for jet-finders other than kt, C/A or genkt with p>=0 should be interpreted with care.");
   }
 
@@ -829,5 +1021,5 @@
 /// return the dmin corresponding to the recombination that went from
 /// n+1 to n jets
-double ClusterSequence::exclusive_dmerge (const int & njets) const {
+double ClusterSequence::exclusive_dmerge (const int njets) const {
   assert(njets >= 0);
   if (njets >= _initial_n) {return 0.0;}
@@ -841,5 +1033,5 @@
 /// exclusive_dmerge, except in cases where the dmin do not increase
 /// monotonically.
-double ClusterSequence::exclusive_dmerge_max (const int & njets) const {
+double ClusterSequence::exclusive_dmerge_max (const int njets) const {
   assert(njets >= 0);
   if (njets >= _initial_n) {return 0.0;}
@@ -853,5 +1045,5 @@
 /// the algorithm with the given dcut.
 std::vector<PseudoJet> ClusterSequence::exclusive_subjets 
-   (const PseudoJet & jet, const double & dcut) const {
+   (const PseudoJet & jet, const double dcut) const {
 
   set<const history_element*> subhist;
@@ -876,5 +1068,5 @@
 /// exclusive_subjets.size()
 int ClusterSequence::n_exclusive_subjets(const PseudoJet & jet, 
-                        const double & dcut) const {
+                        const double dcut) const {
   set<const history_element*> subhist;
   // get the set of history elements that correspond to subjets at
@@ -1181,5 +1373,5 @@
 // //----------------------------------------------------------------------
 // // print out all inclusive jets with pt > ptmin
-// void ClusterSequence::print_jets (const double & ptmin) const{
+// void ClusterSequence::print_jets (const double ptmin) const{
 //     vector<PseudoJet> jets = sorted_by_pt(inclusive_jets(ptmin));
 // 
@@ -1257,7 +1449,7 @@
 // initialise the history in a standard way
 void ClusterSequence::_add_step_to_history (
-	       const int & step_number, const int & parent1, 
-	       const int & parent2, const int & jetp_index,
-	       const double & dij) {
+	       const int step_number, const int parent1, 
+	       const int parent2, const int jetp_index,
+	       const double dij) {
 
   history_element element;
@@ -1429,6 +1621,6 @@
 /// of the recombined jet, newjet_k.
 void ClusterSequence::_do_ij_recombination_step(
-                               const int & jet_i, const int & jet_j, 
-			       const double & dij, 
+                               const int jet_i, const int jet_j, 
+			       const double dij, 
 			       int & newjet_k) {
 
@@ -1466,5 +1658,5 @@
 /// jet_i with the beam
 void ClusterSequence::_do_iB_recombination_step(
-				  const int & jet_i, const double & diB) {
+				  const int jet_i, const double diB) {
   // get history index
   int newstep_k = _history.size();
Index: external/fastjet/ClusterSequence.hh
===================================================================
--- external/fastjet/ClusterSequence.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequence.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,9 @@
-//STARTHEADER
-// $Id: ClusterSequence.hh 3114 2013-05-04 08:46:00Z salam $
+#ifndef __FASTJET_CLUSTERSEQUENCE_HH__
+#define __FASTJET_CLUSTERSEQUENCE_HH__
+
+//FJSTARTHEADER
+// $Id: ClusterSequence.hh 3619 2014-08-13 14:17:19Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,9 +30,6 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
-
-
-#ifndef __FASTJET_CLUSTERSEQUENCE_HH__
-#define __FASTJET_CLUSTERSEQUENCE_HH__
+//FJENDHEADER
+
 
 #include<vector>
@@ -65,21 +67,6 @@
   ClusterSequence () : _deletes_self_when_unused(false) {}
 
-//   /// create a clustersequence starting from the supplied set
-//   /// of pseudojets and clustering them with the long-invariant
-//   /// kt algorithm (E-scheme recombination) with the supplied
-//   /// value for R.
-//   ///
-//   /// If strategy=DumbN3 a very stupid N^3 algorithm is used for the
-//   /// clustering; otherwise strategy = NlnN* uses cylinders algorithms
-//   /// with some number of pi coverage. If writeout_combinations=true a
-//   /// summary of the recombination sequence is written out
-//   template<class L> ClusterSequence (const std::vector<L> & pseudojets, 
-// 		   const double & R = 1.0,
-// 		   const Strategy & strategy = Best,
-// 		   const bool & writeout_combinations = false);
-
-
-  /// create a clustersequence starting from the supplied set
-  /// of pseudojets and clustering them with jet definition specified
+  /// create a ClusterSequence, starting from the supplied set
+  /// of PseudoJets and clustering them with jet definition specified
   /// by jet_def (which also specifies the clustering strategy)
   template<class L> ClusterSequence (
@@ -104,15 +91,15 @@
   /// algorithm) with pt >= ptmin. Time taken should be of the order
   /// of the number of jets returned.
-  std::vector<PseudoJet> inclusive_jets (const double & ptmin = 0.0) const;
+  std::vector<PseudoJet> inclusive_jets (const double ptmin = 0.0) const;
 
   /// return the number of jets (in the sense of the exclusive
   /// algorithm) that would be obtained when running the algorithm
   /// with the given dcut.
-  int n_exclusive_jets (const double & dcut) const;
+  int n_exclusive_jets (const double dcut) const;
 
   /// return a vector of all jets (in the sense of the exclusive
   /// algorithm) that would be obtained when running the algorithm
   /// with the given dcut.
-  std::vector<PseudoJet> exclusive_jets (const double & dcut) const;
+  std::vector<PseudoJet> exclusive_jets (const double dcut) const;
 
   /// return a vector of all jets when the event is clustered (in the
@@ -121,5 +108,5 @@
   /// If there are fewer than njets particles in the ClusterSequence
   /// an error is thrown
-  std::vector<PseudoJet> exclusive_jets (const int & njets) const;
+  std::vector<PseudoJet> exclusive_jets (const int njets) const;
 
   /// return a vector of all jets when the event is clustered (in the
@@ -128,10 +115,10 @@
   /// If there are fewer than njets particles in the ClusterSequence
   /// the function just returns however many particles there were.
-  std::vector<PseudoJet> exclusive_jets_up_to (const int & njets) const;
+  std::vector<PseudoJet> exclusive_jets_up_to (const int njets) const;
 
   /// return the dmin corresponding to the recombination that went
   /// from n+1 to n jets (sometimes known as d_{n n+1}). If the number
   /// of particles in the event is <= njets, the function returns 0.
-  double exclusive_dmerge (const int & njets) const;
+  double exclusive_dmerge (const int njets) const;
 
   /// return the maximum of the dmin encountered during all recombinations 
@@ -139,5 +126,5 @@
   /// exclusive_dmerge, except in cases where the dmin do not increase
   /// monotonically.
-  double exclusive_dmerge_max (const int & njets) const;
+  double exclusive_dmerge_max (const int njets) const;
 
   /// return the ymin corresponding to the recombination that went from
@@ -158,5 +145,5 @@
 
 
-  //int n_exclusive_jets (const PseudoJet & jet, const double & dcut) const;
+  //int n_exclusive_jets (const PseudoJet & jet, const double dcut) const;
 
   /// return a vector of all subjets of the current jet (in the sense
@@ -169,5 +156,5 @@
   /// just getting that list of constituents.
   std::vector<PseudoJet> exclusive_subjets (const PseudoJet & jet, 
-                                            const double & dcut) const;
+                                            const double dcut) const;
 
   /// return the size of exclusive_subjets(...); still n ln n with same
@@ -175,5 +162,5 @@
   /// exclusive_subjets.size()
   int n_exclusive_subjets(const PseudoJet & jet, 
-                          const double & dcut) const;
+                          const double dcut) const;
 
   /// return the list of subjets obtained by unclustering the supplied
@@ -193,5 +180,5 @@
 						  int nsub) const;
 
-  /// return the dij that was present in the merging nsub+1 -> nsub 
+  /// returns the dij that was present in the merging nsub+1 -> nsub 
   /// subjets inside this jet.
   ///
@@ -199,5 +186,5 @@
   double exclusive_subdmerge(const PseudoJet & jet, int nsub) const;
 
-  /// return the maximum dij that occurred in the whole event at the
+  /// returns the maximum dij that occurred in the whole event at the
   /// stage that the nsub+1 -> nsub merge of subjets occurred inside 
   /// this jet.
@@ -207,6 +194,6 @@
 
   //std::vector<PseudoJet> exclusive_jets (const PseudoJet & jet, 
-  //                                       const int & njets) const;
-  //double exclusive_dmerge (const PseudoJet & jet, const int & njets) const;
+  //                                       const int njets) const;
+  //double exclusive_dmerge (const PseudoJet & jet, const int njets) const;
 
   /// returns the sum of all energies in the event (relevant mainly for e+e-)
@@ -272,5 +259,5 @@
 // Not yet. Perhaps in a future release.
 //   /// print out all inclusive jets with pt > ptmin
-//   virtual void print_jets (const double & ptmin=0.0) const;
+//   virtual void print_jets (const double ptmin=0.0) const;
 
   /// add on to subjet_vector the constituents of jet (for internal use mainly)
@@ -300,7 +287,6 @@
   ///
   /// NB: after having made this call, the user is still allowed to
-  /// delete the CS or let it go out of scope. Jets associated with it
-  /// will then simply not be able to access their substructure after
-  /// that point.
+  /// delete the CS. Jets associated with it will then simply not be
+  /// able to access their substructure after that point.
   void delete_self_when_unused();
 
@@ -313,6 +299,7 @@
 
   /// returns the scale associated with a jet as required for this
-  /// clustering algorithm (kt^2 for the kt-algorithm, 1 for the 
-  /// Cambridge algorithm). [May become virtual at some point]
+  /// clustering algorithm (kt^2 for the kt-algorithm, 1 for the
+  /// Cambridge algorithm). Intended mainly for internal use and not
+  /// valid for plugin algorithms.
   double jet_scale_for_algorithm(const PseudoJet & jet) const;
 
@@ -363,7 +350,17 @@
 
   /// the plugin can associate some extra information with the
+  /// ClusterSequence object by calling this function. The
+  /// ClusterSequence takes ownership of the pointer (and
+  /// responsibility for deleting it when the CS gets deleted).
+  inline void plugin_associate_extras(Extras * extras_in) {
+    _extras.reset(extras_in);
+  }
+
+  /// the plugin can associate some extra information with the
   /// ClusterSequence object by calling this function
+  /// 
+  /// As of FJ v3.1, this is deprecated, in line with the deprecation
+  /// of auto_ptr in C++11
   inline void plugin_associate_extras(std::auto_ptr<Extras> extras_in) {
-    //_extras = extras_in;
     _extras.reset(extras_in.release());
   }
@@ -599,5 +596,5 @@
 //DEP   /// clustering, provided for legacy purposes. The jet finder is that
 //DEP   /// specified in the static member _default_jet_algorithm.
-//DEP   void _initialise_and_run (const double & R,
+//DEP   void _initialise_and_run (const double R,
 //DEP 			    const Strategy & strategy,
 //DEP 			    const bool & writeout_combinations);
@@ -622,10 +619,10 @@
   /// jet_j, at distance scale dij; return the index newjet_k of the
   /// result of the recombination of i and j.
-  void _do_ij_recombination_step(const int & jet_i, const int & jet_j, 
-				 const double & dij, int & newjet_k);
+  void _do_ij_recombination_step(const int jet_i, const int jet_j, 
+				 const double dij, int & newjet_k);
 
   /// carry out an recombination step in which _jets[jet_i] merges with
   /// the beam, 
-  void _do_iB_recombination_step(const int & jet_i, const double & diB);
+  void _do_iB_recombination_step(const int jet_i, const double diB);
 
   /// every time a jet is added internally during clustering, this
@@ -640,4 +637,27 @@
   void _update_structure_use_count();
   
+  /// returns a suggestion for the best strategy to use on event
+  /// multiplicity, algorithm, R, etc.
+  Strategy _best_strategy() const;
+  
+  /// returns c*(a*R**2 + b*R + 1);
+  /// Written as a class in case we want to give names to different
+  /// parabolas
+  class _Parabola {
+  public:
+    _Parabola(double a, double b, double c) : _a(a), _b(b), _c(c) {}
+    inline double operator()(const double R) const {return _c*(_a*R*R + _b*R + 1);}
+  private:
+    double _a, _b, _c;
+  };
+
+  /// operator()(R) returns a*R+b;
+  class _Line {
+  public:
+    _Line(double a, double b) : _a(a), _b(b) {}
+    inline double operator()(const double R) const {return _a*R + _b;}
+  private:
+    double _a, _b;
+  };
 
   /// This contains the physical PseudoJets; for each PseudoJet one
@@ -681,5 +701,4 @@
 
   bool _plugin_activated;
-  //std::auto_ptr<Extras> _extras; // things the plugin might want to add
   SharedPtr<Extras> _extras; // things the plugin might want to add
 
@@ -705,7 +724,7 @@
   void _fast_NsqrtN_cluster();
 
-  void _add_step_to_history(const int & step_number, const int & parent1, 
-			       const int & parent2, const int & jetp_index,
-			       const double & dij);
+  void _add_step_to_history(const int step_number, const int parent1, 
+			       const int parent2, const int jetp_index,
+			       const double dij);
 
   /// internal routine associated with the construction of the unique
@@ -726,5 +745,5 @@
 
   /// currently used only in the Voronoi based code
-  void _add_ktdistance_to_map(const int & ii, 
+  void _add_ktdistance_to_map(const int ii, 
 			      DistMap & DijMap,
   			      const DynamicNearestNeighbours * DNN);
@@ -734,8 +753,6 @@
   static bool _first_time;
 
-  /// record the number of warnings provided about the exclusive
-  /// algorithm -- so that we don't print it out more than a few
-  /// times.
-  static int _n_exclusive_warnings;
+  /// manage warnings related to exclusive jets access
+  static LimitedWarning _exclusive_warnings;
 
   /// the limited warning member for notification of user that 
@@ -754,5 +771,4 @@
     int        _jets_index;
   };
-
 
   /// structure analogous to BriefJet, but with the extra information
@@ -862,5 +878,5 @@
   // routines for tiled case, including some overloads of the plain
   // BriefJet cases
-  int  _tile_index(const double & eta, const double & phi) const;
+  int  _tile_index(const double eta, const double phi) const;
   void _tj_set_jetinfo ( TiledJet * const jet, const int _jets_index);
   void  _bj_remove_from_tiles(TiledJet * const jet);
@@ -871,5 +887,4 @@
   void _add_untagged_neighbours_to_tile_union(const int tile_index, 
 		 std::vector<int> & tile_union, int & n_near_tiles);
-
 
   //----------------------------------------------------------------------
@@ -923,5 +938,5 @@
 // template<class L> ClusterSequence::ClusterSequence (
 // 			          const std::vector<L> & pseudojets,
-// 				  const double & R,
+// 				  const double R,
 // 				  const Strategy & strategy,
 // 				  const bool & writeout_combinations) {
@@ -966,4 +981,32 @@
 
 inline unsigned int ClusterSequence::n_particles() const {return _initial_n;}
+
+//----------------------------------------------------------------------
+// implementation of JetDefinition::operator() is here to avoid nasty
+// issues of order of implementations and includes
+template<class L>
+std::vector<PseudoJet> JetDefinition::operator()(const std::vector<L> & particles) const {
+  // create a new cluster sequence
+  ClusterSequence * cs = new ClusterSequence(particles, *this);
+
+  // get the jets, and sort them according to whether the algorithm
+  // is spherical or not
+  std::vector<PseudoJet> jets;
+  if (is_spherical()) {
+    jets = sorted_by_E(cs->inclusive_jets());
+  } else {
+    jets = sorted_by_pt(cs->inclusive_jets());
+  }
+  
+  // make sure the ClusterSequence gets deleted once it's no longer
+  // needed
+  if (jets.size() != 0) {
+    cs->delete_self_when_unused();
+  } else {
+    delete cs;
+  }
+
+  return jets;
+}
 
 
Index: external/fastjet/ClusterSequence1GhostPassiveArea.cc
===================================================================
--- external/fastjet/ClusterSequence1GhostPassiveArea.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequence1GhostPassiveArea.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: ClusterSequence1GhostPassiveArea.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/ClusterSequence1GhostPassiveArea.hh"
Index: external/fastjet/ClusterSequence1GhostPassiveArea.hh
===================================================================
--- external/fastjet/ClusterSequence1GhostPassiveArea.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequence1GhostPassiveArea.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: ClusterSequence1GhostPassiveArea.hh 2687 2011-11-14 11:17:51Z soyez $
+//FJSTARTHEADER
+// $Id: ClusterSequence1GhostPassiveArea.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __FASTJET_CLUSTERSEQUENCE1GHOSTPASSIVEAREA_HH__
Index: external/fastjet/ClusterSequenceActiveArea.cc
===================================================================
--- external/fastjet/ClusterSequenceActiveArea.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequenceActiveArea.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: ClusterSequenceActiveArea.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/PseudoJet.hh"
Index: external/fastjet/ClusterSequenceActiveArea.hh
===================================================================
--- external/fastjet/ClusterSequenceActiveArea.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequenceActiveArea.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: ClusterSequenceActiveArea.hh 2687 2011-11-14 11:17:51Z soyez $
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: ClusterSequenceActiveArea.hh 3619 2014-08-13 14:17:19Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __FASTJET_CLUSTERSEQUENCEACTIVEAREA_HH__
@@ -83,4 +85,7 @@
   /// the background (e.g. non-jet) activity in a highly populated event; the
   /// one that has been most extensively tested is median.
+  /// 
+  /// These strategies are OBSOLETE and deprecated (see comment
+  /// for pt_per_unit_area).
   enum mean_pt_strategies{median=0, non_ghost_median, pttot_over_areatot, 
 			  pttot_over_areatot_cut, mean_ratio_cut, play,
@@ -93,18 +98,10 @@
   /// have pt/area > median(pt/area)*range.
   ///
-  /// NB: This call is OBSOLETE; use media_pt_per_unit_area from the
-  //      ClusterSequenceAreaBase class instead
+  /// NB: This call is OBSOLETE and deprecated; use a
+  /// JetMedianBackgroundEstimator or GridMedianBackgroundEstimator
+  /// instead.
   double pt_per_unit_area(mean_pt_strategies strat=median, 
                           double range=2.0 ) const;
 
-  // following code removed -- now dealt with by AreaBase class (and
-  // this definition here conflicts with it).
-//   /// fits a form pt_per_unit_area(y) = a + b*y^2 in the range
-//   /// abs(y)<raprange (for negative raprange, it defaults to
-//   /// _safe_rap_for_area).
-//   void parabolic_pt_per_unit_area(double & a,double & b, double raprange=-1.0,
-// 				  double exclude_above=-1.0, 
-// 				  bool use_area_4vector=false ) const;
-// 
   /// rewrite the empty area from the parent class, so as to use
   /// all info at our disposal
Index: external/fastjet/ClusterSequenceActiveAreaExplicitGhosts.cc
===================================================================
--- external/fastjet/ClusterSequenceActiveAreaExplicitGhosts.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequenceActiveAreaExplicitGhosts.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: ClusterSequenceActiveAreaExplicitGhosts.cc 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/ClusterSequenceActiveAreaExplicitGhosts.hh"
Index: external/fastjet/ClusterSequenceActiveAreaExplicitGhosts.hh
===================================================================
--- external/fastjet/ClusterSequenceActiveAreaExplicitGhosts.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequenceActiveAreaExplicitGhosts.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: ClusterSequenceActiveAreaExplicitGhosts.hh 2687 2011-11-14 11:17:51Z soyez $
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: ClusterSequenceActiveAreaExplicitGhosts.hh 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __FASTJET_CLUSTERSEQUENCEACTIVEAREAEXPLICITGHOSTS_HH_
Index: external/fastjet/ClusterSequenceArea.cc
===================================================================
--- external/fastjet/ClusterSequenceArea.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequenceArea.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,2 +1,32 @@
+//FJSTARTHEADER
+// $Id: ClusterSequenceArea.cc 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2006-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//
+//----------------------------------------------------------------------
+// This file is part of FastJet.
+//
+//  FastJet 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.
+//
+//  The algorithms that underlie FastJet have required considerable
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
+//  FastJet as part of work towards a scientific publication, please
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
+//
+//  FastJet 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 FastJet. If not, see <http://www.gnu.org/licenses/>.
+//----------------------------------------------------------------------
+//FJENDHEADER
+
 #include "fastjet/ClusterSequenceArea.hh"
 
Index: external/fastjet/ClusterSequenceArea.hh
===================================================================
--- external/fastjet/ClusterSequenceArea.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequenceArea.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: ClusterSequenceArea.hh 2690 2011-11-14 14:57:54Z soyez $
-//
-// Copyright (c) 2006-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: ClusterSequenceArea.hh 3484 2014-07-29 21:39:39Z soyez $
+//
+// Copyright (c) 2006-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __FASTJET_CLUSTERSEQUENCEAREA_HH__
@@ -245,7 +247,9 @@
     break;
   default:
-    std::cerr << "Error: unrecognized area_type in ClusterSequenceArea:" 
-              << _area_def.area_type() << std::endl;
-    exit(-1);
+    std::ostringstream err;
+    err << "Error: unrecognized area_type in ClusterSequenceArea:" 
+	<< _area_def.area_type();
+    throw Error(err.str());
+    //exit(-1);
   }
   // now copy across the information from the area base class
Index: external/fastjet/ClusterSequenceAreaBase.cc
===================================================================
--- external/fastjet/ClusterSequenceAreaBase.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequenceAreaBase.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,7 +1,7 @@
 
-//STARTHEADER
-// $Id$
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: ClusterSequenceAreaBase.cc 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -14,7 +14,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -26,5 +28,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
Index: external/fastjet/ClusterSequenceAreaBase.hh
===================================================================
--- external/fastjet/ClusterSequenceAreaBase.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequenceAreaBase.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: ClusterSequenceAreaBase.hh 2687 2011-11-14 11:17:51Z soyez $
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: ClusterSequenceAreaBase.hh 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __FASTJET_CLUSTERSEQUENCEAREABASE_HH__
Index: external/fastjet/ClusterSequencePassiveArea.cc
===================================================================
--- external/fastjet/ClusterSequencePassiveArea.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequencePassiveArea.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: ClusterSequencePassiveArea.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/ClusterSequencePassiveArea.hh"
Index: external/fastjet/ClusterSequencePassiveArea.hh
===================================================================
--- external/fastjet/ClusterSequencePassiveArea.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequencePassiveArea.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: ClusterSequencePassiveArea.hh 2687 2011-11-14 11:17:51Z soyez $
+//FJSTARTHEADER
+// $Id: ClusterSequencePassiveArea.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __FASTJET_CLUSTERSEQUENCEPASSIVEAREA_HH__
Index: external/fastjet/ClusterSequenceStructure.cc
===================================================================
--- external/fastjet/ClusterSequenceStructure.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequenceStructure.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: ClusterSequenceStructure.cc 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/ClusterSequenceStructure.hh"
Index: external/fastjet/ClusterSequenceStructure.hh
===================================================================
--- external/fastjet/ClusterSequenceStructure.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequenceStructure.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: ClusterSequenceStructure.hh 3071 2013-04-01 12:52:46Z cacciari $
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: ClusterSequenceStructure.hh 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
Index: external/fastjet/ClusterSequenceVoronoiArea.cc
===================================================================
--- external/fastjet/ClusterSequenceVoronoiArea.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequenceVoronoiArea.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,9 +1,9 @@
-//STARTHEADER
-// $Id$
-//
-// Copyright (c) 2006-2007 Matteo Cacciari, Gavin Salam and Gregory Soyez
-//
-//----------------------------------------------------------------------
-// This file is part of a simple command-line handling environment
+//FJSTARTHEADER
+// $Id: ClusterSequenceVoronoiArea.cc 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2006-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//
+//----------------------------------------------------------------------
+// This file is part of FastJet.
 //
 //  FastJet is free software; you can redistribute it and/or modify
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/ClusterSequenceVoronoiArea.hh"
@@ -276,4 +278,5 @@
   //  -- first the initial ones
   _voronoi_area.reserve(2*n_particles());
+  _voronoi_area_4vector.reserve(2*n_particles());
   for (unsigned int i=0; i<n_particles(); i++) {
     _voronoi_area.push_back(_pa_calc->area(i));
Index: external/fastjet/ClusterSequenceVoronoiArea.hh
===================================================================
--- external/fastjet/ClusterSequenceVoronoiArea.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequenceVoronoiArea.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: ClusterSequenceVoronoiArea.hh 2687 2011-11-14 11:17:51Z soyez $
+//FJSTARTHEADER
+// $Id: ClusterSequenceVoronoiArea.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __FASTJET_CLUSTERSEQUENCEVORONOIAREA_HH__
@@ -66,5 +68,5 @@
     return _voronoi_area[jet.cluster_hist_index()];}
 
-  /// return a 4-vector area associated with the given jet -- stricly
+  /// return a 4-vector area associated with the given jet -- strictly
   /// this is not the exact 4-vector area, but rather an approximation
   /// made of sums of centres of all Voronoi cells in jet, each
Index: external/fastjet/ClusterSequenceWithArea.hh
===================================================================
--- external/fastjet/ClusterSequenceWithArea.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequenceWithArea.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: ClusterSequenceWithArea.hh 2577 2011-09-13 15:11:38Z salam $
+//FJSTARTHEADER
+// $Id: ClusterSequenceWithArea.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2006-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2006-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __FASTJET_CLUSTERSEQUENCEWITHAREA_HH__
Index: external/fastjet/ClusterSequence_CP2DChan.cc
===================================================================
--- external/fastjet/ClusterSequence_CP2DChan.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequence_CP2DChan.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: ClusterSequence_CP2DChan.cc 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/ClusterSequence.hh"
Index: external/fastjet/ClusterSequence_Delaunay.cc
===================================================================
--- external/fastjet/ClusterSequence_Delaunay.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequence_Delaunay.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: ClusterSequence_Delaunay.cc 3475 2014-07-29 11:57:23Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
@@ -85,11 +87,15 @@
     throw Error(err.str());
     //assert(false);
-  }
+  } else
 #endif // DROP_CGAL
   {
-    ostringstream err;
-    err << "ERROR: Unrecognized value for strategy: "<<_strategy<<endl;
+    //ostringstream err;
+    //err << "ERROR: Unrecognized value for strategy: "<<_strategy<<endl;
+    //throw Error(err.str());
+    //-----------------------------------------------------------------
+    // The code should never reach this point, because the checks above
+    // should always handle all _strategy values for which 
+    // _delaunay_cluster() is called 
     assert(false);
-    throw Error(err.str());
   }
 
@@ -217,5 +223,5 @@
 ///
 void ClusterSequence::_add_ktdistance_to_map(
-                          const int & ii, 
+                          const int ii, 
 			  DistMap & DijMap,
 			  const DynamicNearestNeighbours * DNN) {
Index: external/fastjet/ClusterSequence_DumbN3.cc
===================================================================
--- external/fastjet/ClusterSequence_DumbN3.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequence_DumbN3.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: ClusterSequence_DumbN3.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
Index: external/fastjet/ClusterSequence_N2.cc
===================================================================
--- external/fastjet/ClusterSequence_N2.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequence_N2.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: ClusterSequence_N2.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
Index: external/fastjet/ClusterSequence_TiledN2.cc
===================================================================
--- external/fastjet/ClusterSequence_TiledN2.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/ClusterSequence_TiledN2.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: ClusterSequence_TiledN2.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,8 +27,8 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
-
-
-// The plain N^2 part of the ClusterSequence class -- separated out
+//FJENDHEADER
+
+
+// The tiled N^2 part of the ClusterSequence class -- separated out
 // from the rest of the class implementation so as to speed up
 // compilation of this particular part while it is under test.
@@ -39,4 +41,5 @@
 #include "fastjet/ClusterSequence.hh"
 #include "fastjet/internal/MinHeap.hh"
+#include "fastjet/internal/TilingExtent.hh"
 
 FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
@@ -94,20 +97,24 @@
   _tile_size_phi = twopi / _n_tiles_phi; // >= _Rparam and fits in 2pi
 
-  // always include zero rapidity in the tiling region
-  _tiles_eta_min = 0.0;
-  _tiles_eta_max = 0.0;
-  // but go no further than following
-  const double maxrap = 7.0;
-
-  // and find out how much further one should go
-  for(unsigned int i = 0; i < _jets.size(); i++) {
-    double eta = _jets[i].rap();
-    // first check if eta is in range -- to avoid taking into account
-    // very spurious rapidities due to particles with near-zero kt.
-    if (abs(eta) < maxrap) {
-      if (eta < _tiles_eta_min) {_tiles_eta_min = eta;}
-      if (eta > _tiles_eta_max) {_tiles_eta_max = eta;}
-    }
-  }
+  TilingExtent tiling_analysis(*this);
+  _tiles_eta_min = tiling_analysis.minrap();
+  _tiles_eta_max = tiling_analysis.maxrap();
+
+  // // always include zero rapidity in the tiling region
+  // _tiles_eta_min = 0.0;
+  // _tiles_eta_max = 0.0;
+  // // but go no further than following
+  // const double maxrap = 7.0;
+  // 
+  // // and find out how much further one should go
+  // for(unsigned int i = 0; i < _jets.size(); i++) {
+  //   double eta = _jets[i].rap();
+  //   // first check if eta is in range -- to avoid taking into account
+  //   // very spurious rapidities due to particles with near-zero kt.
+  //   if (abs(eta) < maxrap) {
+  //     if (eta < _tiles_eta_min) {_tiles_eta_min = eta;}
+  //     if (eta > _tiles_eta_max) {_tiles_eta_max = eta;}
+  //   }
+  // }
 
   // now adjust the values
@@ -167,5 +174,5 @@
 //----------------------------------------------------------------------
 /// return the tile index corresponding to the given eta,phi point
-int ClusterSequence::_tile_index(const double & eta, const double & phi) const {
+int ClusterSequence::_tile_index(const double eta, const double phi) const {
   int ieta, iphi;
   if      (eta <= _tiles_eta_min) {ieta = 0;}
@@ -249,4 +256,21 @@
 /// their "tagged" status is false; when a neighbour is added its
 /// tagged status is set to true.
+///
+/// Note that with a high level of warnings (-pedantic -Wextra -ansi,
+/// gcc complains about tile_index maybe being used uninitialised for
+/// oldB in ClusterSequence::_minheap_faster_tiled_N2_cluster(). We
+/// have explicitly checked that it was harmless so we could disable
+/// the gcc warning by hand using the construct below
+///
+///  #pragma GCC diagnostic push
+///  #pragma GCC diagnostic ignored "-Wpragmas"
+///  #pragma GCC diagnostic ignored "-Wuninitialized"
+///  #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+///    ...
+///  #pragma GCC diagnostic pop
+///
+/// the @GCC diagnostic push/pop directive was only introduced in
+/// gcc-4.6, so for broader usage, we'd need to insert #pragma GCC
+/// diagnostic ignored "-Wpragmas" at the top of this file
 inline void ClusterSequence::_add_untagged_neighbours_to_tile_union(
                const int tile_index, 
@@ -274,5 +298,5 @@
   TiledJet * jetA = briefjets, * jetB;
   TiledJet oldB;
-  oldB.tile_index=0; // prevents a gcc warning  
+  oldB.tile_index=0; // prevents a gcc warning
 
   // will be used quite deep inside loops, but declare it here so that
@@ -517,5 +541,5 @@
   TiledJet * jetA = briefjets, * jetB;
   TiledJet oldB;
-  oldB.tile_index=0; // prevents a gcc warning  
+  oldB.tile_index=0; // prevents a gcc warning
 
   // will be used quite deep inside loops, but declare it here so that
@@ -555,5 +579,4 @@
     // when we set NN for both jetA and jetB on the RH tiles.
   }
-
   
   // now create the diJ (where J is i's NN) table -- remember that 
@@ -721,6 +744,4 @@
 }
 
-
-
 //----------------------------------------------------------------------
 /// run a tiled clustering, with our minheap for keeping track of the
@@ -735,5 +756,4 @@
   TiledJet oldB;
   oldB.tile_index=0; // prevents a gcc warning
-  
 
   // will be used quite deep inside loops, but declare it here so that
Index: external/fastjet/CompositeJetStructure.cc
===================================================================
--- external/fastjet/CompositeJetStructure.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/CompositeJetStructure.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: CompositeJetStructure.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include <fastjet/CompositeJetStructure.hh>
@@ -151,5 +153,5 @@
   double a_err=0;
   for (unsigned i = 0; i < _pieces.size(); i++)
-    a_err += _pieces[i].area();
+    a_err += _pieces[i].area_error();
 
   return a_err;
Index: external/fastjet/CompositeJetStructure.hh
===================================================================
--- external/fastjet/CompositeJetStructure.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/CompositeJetStructure.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: CompositeJetStructure.hh 3071 2013-04-01 12:52:46Z cacciari $
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: CompositeJetStructure.hh 3453 2014-07-25 07:44:32Z soyez $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
@@ -110,9 +112,25 @@
   virtual bool is_pure_ghost(const PseudoJet &reference) const;
 
-  // allow to modify the area information
-  // (for use in join())
-  //------------------------------------------------------------------------------
-  void set_area_information(PseudoJet *area_4vector_ptr){
-    _area_4vector_ptr = area_4vector_ptr;
+  //unused: // allows one to modify the area information
+  //unused: // (for use in join())
+  //unused: //
+  //unused: // This member cannot be used by users who need to create a jet with
+  //unused: // user-supplied area information, because it sets only the 4-vector
+  //unused: // part of the area, but not all the other area information
+  //unused: // (e.g. scalar area) -- that other information is always deduced
+  //unused: // dynamically from the individual constituents.
+  //unused: // ------------------------------------------------------------------------------
+  //unused: void set_area_information(PseudoJet *area_4vector_ptr){
+  //unused:   _area_4vector_ptr = area_4vector_ptr;
+  //unused: }
+
+  /// disable the area of the composite jet
+  /// 
+  /// this can be used e.g. to discard the area of a composite jet
+  /// made of pieces with non-explicit-ghost area since the area may
+  /// by erroneous in that case
+  void discard_area(){
+    if (_area_4vector_ptr) delete _area_4vector_ptr;
+    _area_4vector_ptr = 0;
   }
 
Index: external/fastjet/Dnn2piCylinder.cc
===================================================================
--- external/fastjet/Dnn2piCylinder.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/Dnn2piCylinder.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: Dnn2piCylinder.cc 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
Index: external/fastjet/Dnn3piCylinder.cc
===================================================================
--- external/fastjet/Dnn3piCylinder.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/Dnn3piCylinder.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: Dnn3piCylinder.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
Index: external/fastjet/Dnn4piCylinder.cc
===================================================================
--- external/fastjet/Dnn4piCylinder.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/Dnn4piCylinder.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: Dnn4piCylinder.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
Index: external/fastjet/DnnPlane.cc
===================================================================
--- external/fastjet/DnnPlane.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/DnnPlane.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: DnnPlane.cc 3442 2014-07-24 07:20:49Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
@@ -33,7 +35,10 @@
 #include<list>
 #include "fastjet/internal/DnnPlane.hh"
+
 using namespace std;
 
 FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
+
+const double DnnPlane::DISTANCE_FOR_CGAL_CHECKS=1.0e-12;  
 
 
@@ -53,12 +58,38 @@
        _TR.insert(Point(input_points[i].first, input_points[i].second));
 
-    // we are not up to dealing with coincident vertices, so make 
-    // sure the user knows!
-    _CrashIfVertexPresent(sv.vertex, i);
-    
-    // we need to assicate an index to each vertex -- thus when we get
-    // a vertex (e.g. as a nearest neighbour) from CGAL, we will be
-    // able to figure out which particle it corresponded to.
-    sv.vertex->info() = i;
+    // check if we are dealing with coincident vertices
+    int coinciding_index = _CheckIfVertexPresent(sv.vertex, i);
+    if (coinciding_index == i){
+      // we need to associate an index to each vertex -- thus when we get
+      // a vertex (e.g. as a nearest neighbour) from CGAL, we will be
+      // able to figure out which particle it corresponded to.
+      sv.vertex->info() = sv.coincidence = i;
+    } else {
+      //cout << "  coincident with " << coinciding_index << endl;
+      // the new vertex points to the already existing one and we
+      // record the coincidence
+      //
+      // Note that we must not only set the coincidence of the
+      // currently-added particle, the one it coincides with also
+      // needs be updated (taking into account that it might already
+      // coincide with another one)
+      //
+      // An example may help. Say coinciding_index = i1 and we're adding i2==i.
+      // Then _sv[i2].coincidence = i1; _sv[i1].coincidence = i2. In both
+      // cases sv.vertex->info() == i1;
+      //
+      // Later on we add i3; we find out that its coinciding index is i1;
+      // so we set _sv[i3].coincidence = i2 and sv[i1].coincidence = i3. 
+      //
+      // This gives us the structure 
+      //  _supervertex[i1].coincidence == in
+      //  _supervertex[i2].coincidence == i1
+      //  ...
+      //  _supervertex[in].coincidence == in-1
+      //
+      sv.coincidence = _supervertex[coinciding_index].coincidence; // handles cases with previous coincidences
+      _supervertex[coinciding_index].coincidence = i;
+    }
+      
     _supervertex.push_back(sv);    
   }
@@ -76,8 +107,6 @@
 /// Crashes if the given vertex handle already exists. Otherwise
 /// it does the bookkeeping for future such tests
-void DnnPlane::_CrashIfVertexPresent(
-	const Vertex_handle & vertex, const int & its_index) {
-  if (!_crash_on_coincidence) return;
-
+int DnnPlane::_CheckIfVertexPresent(
+	const Vertex_handle & vertex, const int its_index) {
   // vertices that do not have the same geometric position as any
   // other vertex so far added have info().val() == NEW_VERTEX -- this
@@ -90,10 +119,15 @@
   // DNN:DNN) to be equal to a vertex "index".
   if (vertex->info().val() != NEW_VERTEX) {
-    ostringstream err;
-    err << "ERROR in DnnPlane::_CrashIfVertexPresent"
-	 <<endl << "Point "<<its_index<<" coincides with point "
-	 <<vertex->info().val() << endl;
-    throw DnnError(err.str());
-  } 
+    if (_crash_on_coincidence){
+      ostringstream err;
+      err << "Error: DnnPlane::_CheckIfVertexPresent"
+	  << "Point "<<its_index<<" coincides with point "
+	  <<vertex->info().val() << endl;
+      throw DnnError(err.str());
+    }
+    return vertex->info().val();
+  }
+
+  return its_index;
 }
 
@@ -116,4 +150,5 @@
 			  vector<int> & indices_of_updated_neighbours) {
 
+  if (_verbose) cout << "Starting  DnnPlane::RemoveAndAddPoints" << endl;
 
   // build set of UNION of Voronoi neighbours of a pair of nearest
@@ -124,27 +159,50 @@
   set<int> indices_removed;
 
-  // for each of the indices to be removed add the voronoi neighbourhood to
-  // the NeighbourUnion set.
+  // for each of the indices to be removed add the voronoi
+  // neighbourhood to the NeighbourUnion set as well as the coinciding
+  // points that had the current point as coincidence before.
   for (size_t ir = 0; ir < indices_to_remove.size(); ir++) {
     int index = indices_to_remove[ir];
     indices_removed.insert(index);
-    if (_verbose) cout << " Starting  RemoveAndAddPoints" << endl; 
-    if (_verbose) cout << " point " << index << endl;			 
+    if (_verbose) cout << "  scheduling point " << index << " for removal" << endl;
+
+    if (_supervertex[index].coincidence != index){
+      // we have a coincidence
+      //
+      // The only one of the coincident points that has to be
+      // inserted in the neighbourhood list (and thus updated) is the
+      // one that has 'index' as coincidence.
+      int new_index = _supervertex[index].coincidence;
+      while (_supervertex[new_index].coincidence != index)
+	new_index = _supervertex[new_index].coincidence;
+      if (_verbose) cout << "  inserted coinciding " << new_index << " to neighbours union" << endl;
+      NeighbourUnion.insert(new_index);
+
+      // if this is the point among the coiciding ones that holds the
+      // CGAL vertex, then also insert the CGAL neighbours, otherwise
+      // just skip that step.
+      if (index != _supervertex[index].vertex->info().val()) continue;
+    } 
+
     // have a circulators that will go round the Voronoi neighbours of
     // _supervertex[index1].vertex
     Vertex_circulator vc = _TR.incident_vertices(_supervertex[index].vertex);
     Vertex_circulator done = vc;
-    do  {
-      // if a neighbouring vertex not the infinite vertex, then add it
-      // to our union of neighbouring vertices.
-      if (_verbose) cout << "examining " << vc->info().val() << endl;
-      if (vc->info().val() != INFINITE_VERTEX) {
-	// NB: from it=1 onwards occasionally it might already have
-	// been inserted -- but double insertion still leaves only one
-	// copy in the set, so there's no problem
-	NeighbourUnion.insert(vc->info().val());
-	if (_verbose) cout << "inserted " << vc->info().val() << endl;
-      } 
-    } while (++vc != done);
+    if (vc != NULL){ // a safety check in case there is no Voronoi
+		     // neighbour (which may happen e.g. if we just
+		     // have a bunch of coincident points)
+      do  {
+	// if a neighbouring vertex is not the infinite vertex, then add it
+	// to our union of neighbouring vertices.
+	if (_verbose) cout << "examining " << vc->info().val() << endl;
+	if (vc->info().val() != INFINITE_VERTEX) {
+	  // NB: from it=1 onwards occasionally it might already have
+	  // been inserted -- but double insertion still leaves only one
+	  // copy in the set, so there's no problem
+	  NeighbourUnion.insert(vc->info().val());
+	  if (_verbose) cout << "  inserted " << vc->info().val() << " to neighbours union" << endl;
+	} 
+      } while (++vc != done);
+    }
   }
   
@@ -160,9 +218,42 @@
   for (size_t ir = 0; ir < indices_to_remove.size(); ir++) {
     int index = indices_to_remove[ir];
+    if (_verbose) cout << "  removing " << index << endl;
 
     // NeighbourUnion should not contain the points to be removed
     // (because later we will assume they still exist).
     NeighbourUnion.erase(indices_to_remove[ir]);
-    
+
+    // first deal with  coincidences
+    if (_supervertex[index].coincidence != index){
+      int new_index = _supervertex[index].coincidence;
+
+      // if this is the point among the coiciding ones that "owns" the
+      // CGAL vertex we need to re-label the CGAL vertex so that it
+      // points to the coincident particle and set the current one to
+      // NULL
+      //
+      // This can be done only on the first point as they all share
+      // the same value
+      //
+      // Note that this has to be done before the following step since
+      // it will alter the coincidence information
+      if (index == _supervertex[index].vertex->info().val())
+	_supervertex[new_index].vertex->info() = new_index;
+
+      // we need to browse the coincidences until we end the loop, at
+      // which point we reset the coincidence of the point that has
+      // the current one as a coincidence
+      while (_supervertex[new_index].coincidence != index)
+	new_index = _supervertex[new_index].coincidence;
+      _supervertex[new_index].coincidence = _supervertex[index].coincidence;
+
+      // remove the coincidence on the point being removed and mark it
+      // as removed
+      _supervertex[index].coincidence = index;
+      _supervertex[index].vertex = NULL;
+
+      continue;
+    }
+
     // points to be removed should also be eliminated from the
     // triangulation and the supervertex structure should be updated
@@ -192,5 +283,7 @@
   // of the neighbour union happens to be on the wrong side.
   Face_handle face;
-  if (indices_to_remove.size() > 0) {
+  //if (indices_to_remove.size() > 0) { // GS: use NeighbourUnion instead
+                                        //     (safe also in case of coincidences)
+  if (NeighbourUnion.size() > 0) {
     // face can only be found if there were points to remove in first place
     face = _TR.incident_faces(
@@ -204,6 +297,8 @@
     int index = _supervertex.size()-1;
     indices_added.push_back(index);
-
-    if (indices_to_remove.size() > 0) {
+    if (_verbose) cout << "  adding " << index << endl;
+
+    //if (indices_to_remove.size() > 0) {
+    if (NeighbourUnion.size() > 0) {
       // be careful of using face (for location hinting) only when it exists
       _supervertex[index].vertex = _TR.insert(Point(points_to_add[ia].first, 
@@ -213,8 +308,34 @@
 						    points_to_add[ia].second));
     }
-    // we are not up to dealing with coincident vertices, so make 
-    // sure the user knows!
-    _CrashIfVertexPresent(_supervertex[index].vertex, index);
-    _supervertex[index].vertex->info() = index;
+
+    // check if this leads to a coincidence
+    int coinciding_index = _CheckIfVertexPresent(_supervertex[index].vertex, index);
+    if (coinciding_index == index){
+      // we need to associate an index to each vertex -- thus when we get
+      // a vertex (e.g. as a nearest neighbour) from CGAL, we will be
+      // able to figure out which particle it corresponded to.
+      _supervertex[index].vertex->info() = _supervertex[index].coincidence = index;
+    } else {
+      if (_verbose) cout << "  coinciding with vertex " << coinciding_index << endl;
+      // the new vertex points to an already existing one and we
+      // record the coincidence
+      //
+      // we also update the NN of the coinciding particle (to avoid
+      // having to loop over the list of coinciding neighbours later)
+      // This is done first as it allows us to check if this is a new
+      // coincidence or a coincidence added to a particle that was
+      // previously "alone"
+      _supervertex[coinciding_index].NNindex = index;
+      _supervertex[coinciding_index].NNdistance = 0.0;
+      indices_of_updated_neighbours.push_back(coinciding_index);
+
+      // Note that we must not only set the coincidence of the
+      // currently-added particle, the one it coincides with also
+      // needs be updated (taking into account that it might already
+      // coincide with another one)
+      _supervertex[index].coincidence = _supervertex[coinciding_index].coincidence; // handles cases with previous coincidences
+      _supervertex[coinciding_index].coincidence = index;
+
+    }
     
     // first find nearest neighbour of "newpoint" (shorthand for
@@ -227,4 +348,8 @@
     indices_of_updated_neighbours.push_back(index);
     _SetAndUpdateNearest(index, indices_of_updated_neighbours);
+
+    //cout << "Added: " << setprecision(20) << " (" 
+    //     << points_to_add[ia].first << "," << points_to_add[ia].second
+    //     << ") with index " << index << endl;
   }
 
@@ -251,11 +376,77 @@
   }
 
+  if (_verbose) cout << "Leaving  DnnPlane::RemoveAndAddPoints" << endl;
 }
-
 
 //----------------------------------------------------------------------
 /// Determines the index and distance of the nearest neighbour to 
 /// point j and puts the information into the _supervertex entry for j.
-void DnnPlane::_SetNearest (const int & j) {
+void DnnPlane::_SetNearest (const int j) {
+  // first deal with the cases where we have a coincidence
+  if (_supervertex[j].coincidence != j){
+    _supervertex[j].NNindex = _supervertex[j].coincidence;
+    _supervertex[j].NNdistance = 0.0;
+    return;
+  }
+
+  // The code below entirely uses CGAL distance comparisons to compute
+  // the nearest neighbour. It has the mais drawback to induice a
+  // 10-20% time penalty so we switched to our own comparison (which
+  // only turns to CGAL for dangerous situations)
+  //
+  //  Vertex_handle current = _supervertex[j].vertex;
+  //  Vertex_circulator vc = _TR.incident_vertices(current);
+  //  Vertex_circulator done = vc;
+  //  Vertex_handle nearest = _TR.infinite_vertex();
+  //  double mindist = HUGE_DOUBLE;
+  //
+  //   // when there is only one finite point left in the triangulation, 
+  //   // there are no triangles. Presumably this is why voronoi returns
+  //   // NULL for the incident vertex circulator. Check if this is
+  //   // happening before circulating over it... (Otherwise it crashes
+  //   // when looking for neighbours of last point)
+  //   if (vc != NULL){
+  //     // initialise the nearest vertex handle to the first incident
+  //     // vertex that is not INFINITE_VERTEX
+  //     while (vc->info().val() == INFINITE_VERTEX){
+  //       vc++;
+  //       if (vc==done) break; // if vc==done, then INFINITE_VERTEX is the
+  // 			   // only element in the neighbourhood
+  //     }
+  // 
+  //     // if there is just the infinite vertex, we have vc->info().val()
+  //     // == INFINITE_VERTEX and nothing has to be done
+  //     // otherwise, use the current vc as an initialisation
+  //     if (vc->info().val() != INFINITE_VERTEX){
+  //       nearest = vc; // initialisation to the first non-infinite vertex
+  // 
+  //       // and loop over the following ones
+  //       while (++vc != done){
+  // 	// we should not compare with the infinite vertex
+  // 	if (vc->info().val() == INFINITE_VERTEX) continue;
+  // 
+  // 	if (_verbose) cout << current->info().val() << " " << vc->info().val() << endl; 
+  // 	// use CGAL's distance comparison to check if 'vc' is closer to
+  // 	// 'current' than the nearest so far (we include the == case for
+  // 	// safety though it should not matter in this precise case)
+  // 	if (CGAL::compare_distance_to_point(current->point(), vc->point(), nearest->point())!=CGAL::LARGER){
+  // 	  nearest = vc;
+  // 	  if (_verbose) cout << "nearer";
+  // 	}
+  //       }
+  // 
+  //       // now compute the distance
+  //       //
+  //       // Note that since we're always using CGAL to compare distances
+  //       // (and never the distance computed using _euclid_distance) we
+  //       // should not worry about rounding errors in mindist
+  //       mindist = _euclid_distance(current->point(), nearest->point());
+  //     }
+  //   }
+  //
+  //  // set j's supervertex info about nearest neighbour
+  //  _supervertex[j].NNindex = nearest->info().val();
+  //  _supervertex[j].NNdistance = mindist;
+
   Vertex_handle current = _supervertex[j].vertex;
   Vertex_circulator vc = _TR.incident_vertices(current);
@@ -264,5 +455,5 @@
   double mindist = HUGE_DOUBLE; // change this to "HUGE" or max_double?
   Vertex_handle nearest = _TR.infinite_vertex();
-
+  
   // when there is only one finite point left in the triangulation, 
   // there are no triangles. Presumably this is why voronoi returns
@@ -274,14 +465,15 @@
       // find distance between j and its Voronoi neighbour (vc)
       if (_verbose) cout << current->info().val() << " " << vc->info().val() << endl;
-      dist = _euclid_distance(current->point(), vc->point());
+
       // check if j is closer to vc than vc's currently registered
       // nearest neighbour (and update things if it is)
-      if (dist < mindist) {
-	mindist = dist; nearest = vc; 
-	if (_verbose) cout << "nearer ";
+      if (_is_closer_to(current->point(), vc->point(), nearest, dist, mindist)){
+	nearest = vc; 
+      	if (_verbose) cout << "nearer ";
       } 
       if (_verbose) cout << vc->point() << "; "<< dist << endl;
     }
   } while (++vc != done); // move on to next Voronoi neighbour
+  
   // set j's supervertex info about nearest neighbour
   _supervertex[j].NNindex = nearest->info().val();
@@ -291,5 +483,5 @@
 //----------------------------------------------------------------------
 /// Determines and stores the nearest neighbour of j, and where
-/// necessary update the nearest-neighbour info of Voronoi neighbours
+/// necessary updates the nearest-neighbour info of Voronoi neighbours
 /// of j;
 ///
@@ -304,10 +496,18 @@
 /// NB: note that we have _SetAndUpdateNearest as a completely
 ///     separate routine from _SetNearest because we want to
-///     use one single ciruclation over voronoi neighbours to find the
+///     use one single circulation over voronoi neighbours to find the
 ///     nearest neighbour and to update the voronoi neighbours if need
 ///     be.
 void DnnPlane::_SetAndUpdateNearest(
-			  const int & j, 
+			  const int j, 
 			  vector<int> & indices_of_updated_neighbours) {
+  //cout << "SetAndUpdateNearest for point " << j << endl;
+  // first deal with coincidences
+  if (_supervertex[j].coincidence != j){
+    _supervertex[j].NNindex = _supervertex[j].coincidence;
+    _supervertex[j].NNdistance = 0.0;
+    //cout << "  set to coinciding point " << _supervertex[j].coincidence << endl;
+    return;
+  }
 
   Vertex_handle current = _supervertex[j].vertex;
@@ -326,25 +526,45 @@
     if (vc->info().val() != INFINITE_VERTEX) {
       if (_verbose) cout << current->info().val() << " " << vc->info().val() << endl;
-      // find distance between j and its Voronoi neighbour (vc)
-      dist = _euclid_distance(current->point(), vc->point());
+
       // update the mindist if we are closer than anything found so far
-      if (dist < mindist) {
-	mindist = dist; nearest = vc; 
-	if (_verbose) cout << "nearer ";
+      if (_is_closer_to(current->point(), vc->point(), nearest, dist, mindist)){
+	nearest = vc; 
+      	if (_verbose) cout << "nearer ";
       } 
+
       // find index corresponding to vc for easy manipulation
       int vcindx = vc->info().val();
       if (_verbose) cout << vc->point() << "; "<< dist << endl;
-      // check if j is closer to vc than vc's currently registered
-      // nearest neighbour (and update things if it is)
-      if (dist < _supervertex[vcindx].NNdistance) {
+
+      if (_is_closer_to_with_hint(vc->point(), current->point(), 
+				  _supervertex[_supervertex[vcindx].NNindex].vertex,
+				  dist, _supervertex[vcindx].NNdistance)){
 	if (_verbose) cout << vcindx << "'s NN becomes " << current->info().val() << endl;
-	_supervertex[vcindx].NNdistance = dist;
 	_supervertex[vcindx].NNindex = j;
 	indices_of_updated_neighbours.push_back(vcindx);
       }
+
+      // original code without the use of CGAL distance in potentially
+      // dangerous cases
+      //
+      // // check if j is closer to vc than vc's currently registered
+      // // nearest neighbour (and update things if it is)
+      // //
+      // // GS: originally, the distance test below was a strict <. It
+      // //     has to be <= because if the two distances are ==, it is
+      // //     possible that the old NN is no longer connected to vc in
+      // //     the triangulation, and we are sure that the newly
+      // //     inserted point (j) is (since we loop over j's
+      // //     neighbouring points in the triangulation).
+      // if (dist <= _supervertex[vcindx].NNdistance) {
+      // 	if (_verbose) cout << vcindx << "'s NN becomes " << current->info().val() << endl;
+      // 	_supervertex[vcindx].NNdistance = dist;
+      // 	_supervertex[vcindx].NNindex = j;
+      // 	indices_of_updated_neighbours.push_back(vcindx);
+      // }
     }
   } while (++vc != done); // move on to next Voronoi neighbour
   // set j's supervertex info about nearest neighbour
+  //cout << "  set to point " << nearest->info().val() << endl;
   _supervertex[j].NNindex = nearest->info().val();
   _supervertex[j].NNdistance = mindist;
Index: external/fastjet/Error.cc
===================================================================
--- external/fastjet/Error.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/Error.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: Error.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/Error.hh"
Index: external/fastjet/Error.hh
===================================================================
--- external/fastjet/Error.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/Error.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,8 +2,8 @@
 #define __FASTJET_ERROR_HH__
 
-//STARTHEADER
-// $Id: Error.hh 2577 2011-09-13 15:11:38Z salam $
+//FJSTARTHEADER
+// $Id: Error.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,5 +30,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include<iostream>
Index: external/fastjet/FunctionOfPseudoJet.cc
===================================================================
--- external/fastjet/FunctionOfPseudoJet.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/FunctionOfPseudoJet.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: FunctionOfPseudoJet.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include <fastjet/FunctionOfPseudoJet.hh>
Index: external/fastjet/FunctionOfPseudoJet.hh
===================================================================
--- external/fastjet/FunctionOfPseudoJet.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/FunctionOfPseudoJet.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,8 +2,8 @@
 #define __FASTJET_FUNCTION_OF_PSEUDOJET_HH__
 
-//STARTHEADER
-// $Id: FunctionOfPseudoJet.hh 2577 2011-09-13 15:11:38Z salam $
+//FJSTARTHEADER
+// $Id: FunctionOfPseudoJet.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,5 +30,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include <fastjet/PseudoJet.hh>
@@ -49,6 +51,10 @@
   FunctionOfPseudoJet(){}
 
-  /// ctor that creates a constant function
-  FunctionOfPseudoJet(const TOut &constant_value);
+  // ctor that creates a constant function
+  //----------
+  // this declaration was present in versions of FJ from 3.0.0 to 3.0.6,
+  // but never implemented. It is being removed from 3.0.7 upwards
+  // to avoid misleading users
+  //FunctionOfPseudoJet(const TOut &constant_value);
 
   /// default dtor (virtual to allow safe polymorphism)
Index: external/fastjet/GhostedAreaSpec.cc
===================================================================
--- external/fastjet/GhostedAreaSpec.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/GhostedAreaSpec.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: GhostedAreaSpec.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/GhostedAreaSpec.hh"
Index: external/fastjet/GhostedAreaSpec.hh
===================================================================
--- external/fastjet/GhostedAreaSpec.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/GhostedAreaSpec.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: GhostedAreaSpec.hh 2728 2011-11-20 14:18:59Z salam $
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: GhostedAreaSpec.hh 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
@@ -122,6 +124,8 @@
 
   // for accessing values set by the user
+  inline double ghost_rapmax () const {return _ghost_maxrap;}
+  inline double ghost_maxrap () const {return _ghost_maxrap;}
   inline double ghost_etamax () const {return _ghost_maxrap;}
-  inline double ghost_maxrap () const {return _ghost_maxrap;}
+  inline double ghost_maxeta () const {return _ghost_maxrap;}
   inline double ghost_area   () const {return _ghost_area   ;}
   inline double grid_scatter () const {return _grid_scatter;}
@@ -140,6 +144,8 @@
   // when explicitly modifying values, sometimes call the initializer
   inline void set_ghost_area   (double val) {_ghost_area    = val; _initialize();}
+  inline void set_ghost_rapmax (double val) {_ghost_maxrap = val; _initialize();}
+  inline void set_ghost_maxrap (double val) {_ghost_maxrap = val; _initialize();}
   inline void set_ghost_etamax (double val) {_ghost_maxrap = val; _initialize();}
-  inline void set_ghost_maxrap (double val) {_ghost_maxrap = val; _initialize();}
+  inline void set_ghost_maxeta (double val) {_ghost_maxrap = val; _initialize();}
   inline void set_grid_scatter (double val) {_grid_scatter   = val; }
   inline void set_pt_scatter   (double val) {_pt_scatter     = val; }
Index: external/fastjet/JetDefinition.cc
===================================================================
--- external/fastjet/JetDefinition.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/JetDefinition.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: JetDefinition.cc 3492 2014-07-30 16:58:20Z soyez $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/JetDefinition.hh"
@@ -68,30 +70,11 @@
   // cross-check the number of parameters that were declared in setting up the
   // algorithm (passed internally from the public constructors)
-  switch (jet_algorithm_in) {
-  case ee_kt_algorithm:
-    if (nparameters != 0) {
-      ostringstream oss;
-      oss << "ee_kt_algorithm should be constructed with 0 parameters but was called with " 
-          << nparameters << " parameter(s)\n";
-      throw Error(oss.str()); 
-    }
-    break;
-  case genkt_algorithm: 
-  case ee_genkt_algorithm: 
-    if (nparameters != 2) {
-      ostringstream oss;
-      oss << "(ee_)genkt_algorithm should be constructed with 2 parameters but was called with " 
-          << nparameters << " parameter(s)\n";
-      throw Error(oss.str()); 
-    }
-    break;
-  default:
-    if (nparameters != 1) {
-      ostringstream oss;
-      oss << "The jet algorithm you requested ("
-          << jet_algorithm_in << ") should be constructed with 1 parameter but was called with " 
-          << nparameters << " parameter(s)\n";
-      throw Error(oss.str()); 
-    }
+  unsigned int nparameters_expected = n_parameters_for_algorithm(jet_algorithm_in);
+  if (nparameters != (int) nparameters_expected){
+    ostringstream oss;
+    oss << "The jet algorithm you requested ("
+        << jet_algorithm_in << ") should be constructed with " << nparameters_expected 
+        << " parameter(s) but was called with " << nparameters << " parameter(s)\n";
+    throw Error(oss.str()); 
   }
 
@@ -106,43 +89,95 @@
 
 //----------------------------------------------------------------------
+// returns true if the jet definition involves an algorithm
+// intended for use on a spherical geometry (e.g. e+e- algorithms,
+// as opposed to most pp algorithms, which use a cylindrical,
+// rapidity-phi geometry).
+bool JetDefinition::is_spherical() const {
+  if (jet_algorithm() == plugin_algorithm) {
+    return plugin()->is_spherical();
+  } else {
+    return (jet_algorithm() == ee_kt_algorithm ||  // as of 2013-02-14, the two
+            jet_algorithm() == ee_genkt_algorithm  // native spherical algorithms
+            );
+  }
+}
+
+//----------------------------------------------------------------------
 string JetDefinition::description() const {
+  ostringstream name;
+  
+  name << description_no_recombiner();
+
+  if ((jet_algorithm() == plugin_algorithm) || (jet_algorithm() == undefined_jet_algorithm)){
+    return name.str();
+  }
+
+  if (n_parameters_for_algorithm(jet_algorithm()) == 0)
+    name << " with ";
+  else 
+    name << " and ";
+  name << recombiner()->description();
+
+  return name.str();
+}
+
+//----------------------------------------------------------------------
+string JetDefinition::description_no_recombiner() const {
+  
   ostringstream name;
   if (jet_algorithm() == plugin_algorithm) {
     return plugin()->description();
-  } else if (jet_algorithm() == kt_algorithm) {
-    name << "Longitudinally invariant kt algorithm with R = " << R();
-    name << " and " << recombiner()->description();
-  } else if (jet_algorithm() == cambridge_algorithm) {
-    name << "Longitudinally invariant Cambridge/Aachen algorithm with R = " 
-	 << R() ;
-    name << " and " << recombiner()->description();
-  } else if (jet_algorithm() == antikt_algorithm) {
-    name << "Longitudinally invariant anti-kt algorithm with R = " 
-	 << R() ;
-    name << " and " << recombiner()->description();
-  } else if (jet_algorithm() == genkt_algorithm) {
-    name << "Longitudinally invariant generalised kt algorithm with R = " 
-	 << R() << ", p = " << extra_param();
-    name << " and " << recombiner()->description();
-  } else if (jet_algorithm() == cambridge_for_passive_algorithm) {
-    name << "Longitudinally invariant Cambridge/Aachen algorithm with R = " 
-	 << R() << "and a special hack whereby particles with kt < " 
-         << extra_param() << "are treated as passive ghosts";
-  } else if (jet_algorithm() == ee_kt_algorithm) {
-    name << "e+e- kt (Durham) algorithm (NB: no R)";
-    name << " with " << recombiner()->description();
-  } else if (jet_algorithm() == ee_genkt_algorithm) {
-    name << "e+e- generalised kt algorithm with R = " 
-	 << R() << ", p = " << extra_param();
-    name << " and " << recombiner()->description();
   } else if (jet_algorithm() == undefined_jet_algorithm) {
-    name << "uninitialised JetDefinition (jet_algorithm=undefined_jet_algorithm)" ;
-  } else {
-    throw Error("JetDefinition::description(): unrecognized jet_algorithm");
-  }
+    return "uninitialised JetDefinition (jet_algorithm=undefined_jet_algorithm)" ;
+  }
+
+  name << algorithm_description(jet_algorithm());
+  switch (n_parameters_for_algorithm(jet_algorithm())){
+  case 0: name << " (NB: no R)"; break;
+  case 1: name << " with R = " << R(); break; // the parameter is always R
+  case 2: 
+    // the 1st parameter is always R
+    name << " with R = " << R();
+    // the 2nd depends on the algorithm
+    if (jet_algorithm() == cambridge_for_passive_algorithm){
+      name << "and a special hack whereby particles with kt < " 
+           << extra_param() << "are treated as passive ghosts";
+    } else {
+      name << ", p = " << extra_param();
+    }
+  };
+
   return name.str();
 }
 
-
+//----------------------------------------------------------------------
+string JetDefinition::algorithm_description(const JetAlgorithm jet_alg){
+  ostringstream name;
+  switch (jet_alg){
+  case plugin_algorithm:                return "plugin algorithm";
+  case kt_algorithm:                    return "Longitudinally invariant kt algorithm";
+  case cambridge_algorithm:             return "Longitudinally invariant Cambridge/Aachen algorithm";
+  case antikt_algorithm:                return "Longitudinally invariant anti-kt algorithm";
+  case genkt_algorithm:                 return "Longitudinally invariant generalised kt algorithm";
+  case cambridge_for_passive_algorithm: return "Longitudinally invariant Cambridge/Aachen algorithm";
+  case ee_kt_algorithm:                 return "e+e- kt (Durham) algorithm (NB: no R)";
+  case ee_genkt_algorithm:              return "e+e- generalised kt algorithm";
+  case undefined_jet_algorithm:         return "undefined jet algorithm";
+  default:
+    throw Error("JetDefinition::algorithm_description(): unrecognized jet_algorithm");
+  };
+}
+
+//----------------------------------------------------------------------
+unsigned int JetDefinition::n_parameters_for_algorithm(const JetAlgorithm jet_alg){
+  switch (jet_alg) {
+  case ee_kt_algorithm:    return 0;
+  case genkt_algorithm:
+  case ee_genkt_algorithm: return 2;
+  default:                 return 1;
+  };
+}
+
+//----------------------------------------------------------------------
 void JetDefinition::set_recombination_scheme(
                                RecombinationScheme recomb_scheme) {
@@ -150,7 +185,33 @@
 
   // do not forget to delete the existing recombiner if needed
-  if (_recombiner_shared()) _recombiner_shared.reset();
+  if (_shared_recombiner()) _shared_recombiner.reset();
 
   _recombiner = 0;
+}
+
+void JetDefinition::set_recombiner(const JetDefinition &other_jet_def){
+  // make sure the "invariants" of the other jet def are sensible
+  assert(other_jet_def._recombiner || 
+         other_jet_def.recombination_scheme() != external_scheme);
+
+  // first treat the situation where we're using the default recombiner
+  if (other_jet_def._recombiner == 0){
+    set_recombination_scheme(other_jet_def.recombination_scheme());
+    return;
+  }
+
+  // in other cases, copy the pointer to the recombiner
+  _recombiner = other_jet_def._recombiner;
+  // set the default recombiner appropriately
+  _default_recombiner = DefaultRecombiner(external_scheme);
+  // and set the _shared_recombiner to the same state
+  // as in the other_jet_def, whatever that was
+  _shared_recombiner.reset(other_jet_def._shared_recombiner);
+
+  // NB: it is tempting to go via set_recombiner and then to sort
+  // out the shared part, but this would be dangerous in the
+  // specific (rare?) case where other_jet_def is the same as this
+  // it deletes_recombiner_when_unused. In that case the shared
+  // pointer reset would delete the recombiner.
 }
 
@@ -163,5 +224,5 @@
   if (other_jd.recombination_scheme() != scheme) return false;
 
-  // if the scheme is "external", also check that they ahve the same
+  // if the scheme is "external", also check that they have the same
   // recombiner
   return (scheme != external_scheme) 
@@ -169,12 +230,14 @@
 }
 
-/// allows to let the JetDefinition handle the deletion of the
+/// causes the JetDefinition to handle the deletion of the
 /// recombiner when it is no longer used
 void JetDefinition::delete_recombiner_when_unused(){
   if (_recombiner == 0){
     throw Error("tried to call JetDefinition::delete_recombiner_when_unused() for a JetDefinition without a user-defined recombination scheme");
-  }
-
-  _recombiner_shared.reset(_recombiner);
+  } else if (_shared_recombiner.get()) {
+    throw Error("Error in JetDefinition::delete_recombiner_when_unused: the recombiner is already scheduled for deletion when unused (or was already set as shared)");
+  }
+
+  _shared_recombiner.reset(_recombiner);
 }
 
Index: external/fastjet/JetDefinition.hh
===================================================================
--- external/fastjet/JetDefinition.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/JetDefinition.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,9 @@
-//STARTHEADER
-// $Id: JetDefinition.hh 2687 2011-11-14 11:17:51Z soyez $
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+#ifndef __FASTJET_JETDEFINITION_HH__
+#define __FASTJET_JETDEFINITION_HH__
+
+//FJSTARTHEADER
+// $Id: JetDefinition.hh 3523 2014-08-02 13:15:21Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,8 +30,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
-
-#ifndef __FASTJET_JETDEFINITION_HH__
-#define __FASTJET_JETDEFINITION_HH__
+//FJENDHEADER
 
 #include<cassert>
@@ -47,5 +49,43 @@
 /// clustering events with kt and cambridge style algorithms.
 enum Strategy {
-  /// fastest form about 500..10^4
+  /// Like N2MHTLazy9 in a number of respects, but does not calculate
+  /// ghost-ghost distances and so does not carry out ghost-ghost
+  /// recombination. 
+  ///
+  /// If you want active ghosted areas, then this is only suitable for
+  /// use with the anti-kt algorithm (or genkt with negative p), and
+  /// does not produce any pure ghost jets. If used with active areas
+  /// with Kt or Cam algorithms it will actually produce a passive
+  /// area.
+  /// 
+  /// Particles are deemed to be ghosts if their pt is below a
+  /// threshold (currently 1e-50, hard coded as ghost_limit in
+  /// LazyTiling9SeparateGhosts).
+  ///
+  /// Currently for events with a couple of thousand normal particles
+  /// and O(10k) ghosts, this can be quicker than N2MHTLazy9, which
+  /// would otherwise be the best strategy. 
+  ///
+  /// New in FJ3.1
+  N2MHTLazy9AntiKtSeparateGhosts   = -10, 
+  /// only looks into a neighbouring tile for a particle's nearest
+  /// neighbour (NN) if that particle's in-tile NN is further than the
+  /// distance to the edge of the neighbouring tile. Uses tiles of
+  /// size R and a 3x3 tile grid around the particle.
+  /// New in FJ3.1
+  N2MHTLazy9   = -7, 
+  /// Similar to N2MHTLazy9, but uses tiles of size R/2 and a 5x5 tile
+  /// grid around the particle.
+  /// New in FJ3.1
+  N2MHTLazy25   = -6, 
+  /// Like to N2MHTLazy9 but uses slightly different optimizations,
+  /// e.g. for calculations of distance to nearest tile; as of
+  /// 2014-07-18 it is slightly slower and not recommended for
+  /// production use. To considered deprecated.
+  /// New in FJ3.1
+  N2MHTLazy9Alt   = -5, 
+  /// faster that N2Tiled above about 500 particles; differs from it
+  /// by retainig the di(closest j) distances in a MinHeap (sort of
+  /// priority queue) rather than a simple vector. 
   N2MinHeapTiled   = -4, 
   /// fastest from about 50..500
@@ -57,5 +97,6 @@
   /// worse even than the usual N^3 algorithms
   N3Dumb      =  0, 
-  /// automatic selection of the best (based on N)
+  /// automatic selection of the best (based on N), including 
+  /// the LazyTiled strategies that are new to FJ3.1
   Best        =  1, 
   /// best of the NlnN variants -- best overall for N>10^4.
@@ -79,4 +120,7 @@
   /// (Does not work for R>=2pi)
   NlnNCam      = 12, // 2piMultD
+  /// the automatic strategy choice that was being made in FJ 3.0
+  /// (restricted to strategies that were present in FJ 3.0)
+  BestFJ30     =  21, 
   /// the plugin has been used...
   plugin_strategy = 999
@@ -87,4 +131,7 @@
 /// \enum JetAlgorithm
 /// the various families of jet-clustering algorithm
+//
+// [Remember to update the "is_spherical()" routine if any further
+// spherical algorithms are added to the list below]
 enum JetAlgorithm {
   /// the longitudinally invariant kt algorithm
@@ -102,9 +149,12 @@
   /// where p = extra_param()
   genkt_algorithm=3, 
-  /// a version of cambridge with a special distance measure for particles
-  /// whose pt is < extra_param()
+  /// a version of cambridge with a special distance measure for
+  /// particles whose pt is < extra_param(); this is not usually
+  /// intended for end users, but is instead automatically selected
+  /// when requesting a passive Cambridge area.
   cambridge_for_passive_algorithm=11,
   /// a version of genkt with a special distance measure for particles
   /// whose pt is < extra_param() [relevant for passive areas when p<=0]
+  /// ***** NB: THERE IS CURRENTLY NO IMPLEMENTATION FOR THIS ALG *******
   genkt_for_passive_algorithm=13, 
   //.................................................................
@@ -244,7 +294,6 @@
                 const Recombiner * recombiner_in,
                 Strategy strategy_in = Best) {
-    *this = JetDefinition(jet_algorithm_in, R_in, external_scheme, strategy_in);
+    *this = JetDefinition(jet_algorithm_in, R_in, xtra_param_in, external_scheme, strategy_in);
     _recombiner = recombiner_in;
-    set_extra_param(xtra_param_in);
   }
 
@@ -284,4 +333,11 @@
                 RecombinationScheme recomb_scheme_in = E_scheme,
                 int nparameters_in = 1);
+
+  /// cluster the supplied particles and returns a vector of resulting
+  /// jets, sorted by pt (or energy in the case of spherical,
+  /// i.e. e+e-, algorithms). This routine currently only makes
+  /// sense for "inclusive" type algorithms.
+  template <class L> 
+  std::vector<PseudoJet> operator()(const std::vector<L> & particles) const;
   
   /// R values larger than max_allowable_R are not allowed.
@@ -297,12 +353,32 @@
 
   /// set the recombiner class to the one provided
+  ///
+  /// Note that in order to associate to a jet definition a recombiner
+  /// from another jet definition, it is strongly recommended to use
+  /// the set_recombiner(const JetDefinition &) method below. The
+  /// latter correctly handles the situations where the jet definition
+  /// owns the recombiner (i.e. where delete_recombiner_when_unused
+  /// has been called). In such cases, using set_recombiner(const
+  /// Recombiner *) may lead to memory corruption.
   void set_recombiner(const Recombiner * recomb) {
-    if (_recombiner_shared()) _recombiner_shared.reset(recomb);
+    if (_shared_recombiner()) _shared_recombiner.reset(recomb);
     _recombiner = recomb;
     _default_recombiner = DefaultRecombiner(external_scheme);
   }
 
+  /// set the recombiner to be the same as the one of 'other_jet_def'
+  ///
+  /// Note that this is the recommended method to associate to a jet
+  /// definition the recombiner from another jet definition. Compared
+  /// to the set_recombiner(const Recombiner *) above, it correctly
+  /// handles the case where the jet definition owns the recombiner
+  /// (i.e. where delete_recombiner_when_unused has been called)
+  void set_recombiner(const JetDefinition &other_jet_def);
+
   /// calling this tells the JetDefinition to handle the deletion of
-  /// the recombiner when it is no longer used
+  /// the recombiner when it is no longer used. (Should not be called
+  /// if the recombiner was initialised from a JetDef whose recombiner
+  /// was already scheduled to delete itself - memory handling will
+  /// already be automatic across both JetDef's in that case).
   void delete_recombiner_when_unused();
 
@@ -310,5 +386,5 @@
   const Plugin * plugin() const {return _plugin;};
 
-  /// allows to let the JetDefinition handle the deletion of the
+  /// calling this causes the JetDefinition to handle the deletion of the
   /// plugin when it is no longer used
   void delete_plugin_when_unused();
@@ -333,5 +409,5 @@
   void set_extra_param(double xtra_param) {_extra_param = xtra_param;}
 
-  /// return a pointer to the currently defined recombiner. 
+  /// returns a pointer to the currently defined recombiner. 
   ///
   /// Warning: the pointer may be to an internal recombiner (for
@@ -347,10 +423,24 @@
 
   /// returns true if the current jet definitions shares the same
-  /// recombiner as teh one passed as an argument
+  /// recombiner as the one passed as an argument
   bool has_same_recombiner(const JetDefinition &other_jd) const;
+
+  /// returns true if the jet definition involves an algorithm
+  /// intended for use on a spherical geometry (e.g. e+e- algorithms,
+  /// as opposed to most pp algorithms, which use a cylindrical,
+  /// rapidity-phi geometry).
+  bool is_spherical() const;
 
   /// return a textual description of the current jet definition 
   std::string description() const;
 
+  /// returns a description not including the recombiner information
+  std::string description_no_recombiner() const;
+
+  /// a short textual description of the algorithm jet_alg
+  static std::string algorithm_description(const JetAlgorithm jet_alg);
+
+  /// the number of parameters associated to a given jet algorithm
+  static unsigned int n_parameters_for_algorithm(const JetAlgorithm jet_alg);
 
 public:
@@ -462,4 +552,10 @@
     virtual bool exclusive_sequence_meaningful() const {return false;}
 
+    /// returns true if the plugin implements an algorithm intended
+    /// for use on a spherical geometry (e.g. e+e- algorithms, as
+    /// opposed to most pp algorithms, which use a cylindrical,
+    /// rapidity-phi geometry).
+    virtual bool is_spherical() const {return false;}
+
     /// a destructor to be replaced if necessary in derived classes...
     virtual ~Plugin() {};
@@ -481,5 +577,5 @@
   DefaultRecombiner _default_recombiner;
   const Recombiner * _recombiner;
-  SharedPtr<const Recombiner> _recombiner_shared;
+  SharedPtr<const Recombiner> _shared_recombiner;
 
 };
@@ -516,8 +612,10 @@
 
 
-
-
-
 FASTJET_END_NAMESPACE
 
+// include ClusterSequence which includes the implementation of the 
+// templated JetDefinition::operator()(...) member
+#include "fastjet/ClusterSequence.hh"
+
+
 #endif // __FASTJET_JETDEFINITION_HH__
Index: external/fastjet/LazyTiling25.cc
===================================================================
--- external/fastjet/LazyTiling25.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/LazyTiling25.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,753 @@
+//FJSTARTHEADER
+// $Id: LazyTiling25.cc 3477 2014-07-29 14:34:39Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//
+//----------------------------------------------------------------------
+// This file is part of FastJet.
+//
+//  FastJet 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.
+//
+//  The algorithms that underlie FastJet have required considerable
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
+//  FastJet as part of work towards a scientific publication, please
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
+//
+//  FastJet 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 FastJet. If not, see <http://www.gnu.org/licenses/>.
+//----------------------------------------------------------------------
+//FJENDHEADER
+
+#include <iomanip>
+#include "fastjet/internal/LazyTiling25.hh"
+#include "fastjet/internal/TilingExtent.hh"
+using namespace std;
+
+
+FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
+
+LazyTiling25::LazyTiling25(ClusterSequence & cs) :
+  _cs(cs), _jets(cs.jets())
+  //, _minheap(_jets.size()) 
+{
+#ifdef INSTRUMENT2
+  _ncall = 0; // gps tmp
+  _ncall_dtt = 0; // gps tmp
+#endif // INSTRUMENT2
+  _Rparam = cs.jet_def().R();
+  _R2 = _Rparam * _Rparam;
+  _invR2 = 1.0 / _R2;
+  _initialise_tiles();
+}
+
+
+//----------------------------------------------------------------------
+/// Set up the tiles:
+///  - decide the range in eta
+///  - allocate the tiles
+///  - set up the cross-referencing info between tiles
+///
+/// The neighbourhood of a tile is set up as follows
+///
+///          LLRRR
+///          LLRRR
+///          LLXRR
+///          LLLRR
+///          LLLRR
+///
+/// such that tiles is an array containing XLL..LLRR..RR with pointers
+///                                         |     \ RH_tiles
+///                                         \ surrounding_tiles
+///
+/// with appropriate precautions when close to the edge of the tiled
+/// region.
+///
+void LazyTiling25::_initialise_tiles() {
+
+  // first decide tile sizes (with a lower bound to avoid huge memory use with
+  // very small R)
+  double default_size = max(0.1,_Rparam)/2;
+  _tile_size_eta = default_size;
+  // it makes no sense to go below 5 tiles in phi -- 5 tiles is
+  // sufficient to make sure all pair-wise combinations up to pi in
+  // phi are possible
+  _n_tiles_phi   = max(5,int(floor(twopi/default_size)));
+  _tile_size_phi = twopi / _n_tiles_phi; // >= _Rparam and fits in 2pi
+
+#define _FASTJET_TILING25_USE_TILING_ANALYSIS_
+#ifdef  _FASTJET_TILING25_USE_TILING_ANALYSIS_
+  // testing
+  TilingExtent tiling_analysis(_cs);
+  _tiles_eta_min = tiling_analysis.minrap();
+  _tiles_eta_max = tiling_analysis.maxrap();
+  //cout << "Using timing analysis " << " " << _tiles_eta_min << " " << _tiles_eta_max << endl;
+#else // not _FASTJET_TILING25_USE_TILING_ANALYSIS_
+  // always include zero rapidity in the tiling region
+  _tiles_eta_min = 0.0;
+  _tiles_eta_max = 0.0;
+  // but go no further than following
+  const double maxrap = 7.0;
+  
+  // and find out how much further one should go
+  for(unsigned int i = 0; i < _jets.size(); i++) {
+    double eta = _jets[i].rap();
+    // first check if eta is in range -- to avoid taking into account
+    // very spurious rapidities due to particles with near-zero kt.
+    if (abs(eta) < maxrap) {
+      if (eta < _tiles_eta_min) {_tiles_eta_min = eta;}
+      if (eta > _tiles_eta_max) {_tiles_eta_max = eta;}
+    }
+  }
+  //cout << "NOT using timing analysis " << " " << _tiles_eta_min << " " << _tiles_eta_max << endl;
+#endif // _FASTJET_TILING25_USE_TILING_ANALYSIS_
+
+
+  // now adjust the values of the ieta extents 
+
+  // 2014-07-18: the following commented piece of code gives speed
+  // improvements for large-R jets, but occasionally it appears to
+  // hang, e.g. on 
+  //    gunzip -c  < ../data/Pythia-PtMin50-LHC-10kev.dat.gz  | time ./example/fastjet_timing_plugins -R 1000 -nev 1000 -strategy -6  -antikt  -rapmax 5.0 -repeat 1 -write
+  // 2014-07-23: this was understood because tile centres assumed 
+  //             tiles_ieta_min = tiles_eta_min (no longer true)
+  //
+#define FASTJET_LAZY25_MIN3TILESY
+#ifdef FASTJET_LAZY25_MIN3TILESY
+   if (_tiles_eta_max - _tiles_eta_min < 3*_tile_size_eta) {
+     // if we have a rapidity coverage that is small compared to the
+     // tile size then we can adjust the grid in rapidity so as to
+     // have exactly 3 tiles. This can give relevant speed improvements 
+     // for large R jets
+     _tile_size_eta = (_tiles_eta_max - _tiles_eta_min)/3;
+     _tiles_ieta_min = 0;
+     _tiles_ieta_max = 2;
+     // the eta max value is being taken as the lower edge of the
+     // highest-y tile
+     _tiles_eta_max -= _tile_size_eta;
+   } else {
+#endif //FASTJET_LAZY25_MIN3TILESY
+    _tiles_ieta_min = int(floor(_tiles_eta_min/_tile_size_eta));
+    _tiles_ieta_max = int(floor( _tiles_eta_max/_tile_size_eta));
+    _tiles_eta_min = _tiles_ieta_min * _tile_size_eta;
+    _tiles_eta_max = _tiles_ieta_max * _tile_size_eta;
+#ifdef FASTJET_LAZY25_MIN3TILESY
+   }
+#endif
+  _tile_half_size_eta = _tile_size_eta * 0.5;
+  _tile_half_size_phi = _tile_size_phi * 0.5;
+
+  // set up information about whether we need to allow for "periodic" 
+  // wrapping tests in delta_phi calculations
+  vector<bool> use_periodic_delta_phi(_n_tiles_phi, false);
+  if (_n_tiles_phi <= 5) {
+    fill(use_periodic_delta_phi.begin(), use_periodic_delta_phi.end(), true);
+  } else {
+    use_periodic_delta_phi[0] = true;
+    use_periodic_delta_phi[1] = true;
+    use_periodic_delta_phi[_n_tiles_phi-2] = true;
+    use_periodic_delta_phi[_n_tiles_phi-1] = true;
+  }
+
+  // allocate the tiles
+  _tiles.resize((_tiles_ieta_max-_tiles_ieta_min+1)*_n_tiles_phi);
+
+  // now set up the cross-referencing between tiles
+  for (int ieta = _tiles_ieta_min; ieta <= _tiles_ieta_max; ieta++) {
+    for (int iphi = 0; iphi < _n_tiles_phi; iphi++) {
+      Tile25 * tile = & _tiles[_tile_index(ieta,iphi)];
+      // no jets in this tile yet
+      tile->head = NULL; // first element of tiles points to itself
+      tile->begin_tiles[0] =  tile;
+      Tile25 ** pptile = & (tile->begin_tiles[0]);
+      pptile++;
+      //
+      // set up L's in column to the left of X
+      tile->surrounding_tiles = pptile;
+      if (ieta > _tiles_ieta_min) {
+	// with the itile subroutine, we can safely run tiles from
+	// idphi=-1 to idphi=+1, because it takes care of
+	// negative and positive boundaries
+	for (int idphi = -2; idphi <=+2; idphi++) {
+	  *pptile = & _tiles[_tile_index(ieta-1,iphi+idphi)];
+	  pptile++;
+	}	
+      }
+      // and the column twice to left of X
+      if (ieta > _tiles_ieta_min + 1) {
+	// with the itile subroutine, we can safely run tiles from
+	// idphi=-1 to idphi=+1, because it takes care of
+	// negative and positive boundaries
+	for (int idphi = -2; idphi <= +2; idphi++) {
+	  *pptile = & _tiles[_tile_index(ieta-2,iphi+idphi)];
+	  pptile++;
+	}	
+      }
+      // now set up last two L's (below X)
+      *pptile = & _tiles[_tile_index(ieta,iphi-1)];
+      pptile++;
+      *pptile = & _tiles[_tile_index(ieta,iphi-2)];
+      pptile++;
+      // set up first two R's (above X)
+      tile->RH_tiles = pptile;
+      *pptile = & _tiles[_tile_index(ieta,iphi+1)];
+      pptile++;
+      *pptile = & _tiles[_tile_index(ieta,iphi+2)];
+      pptile++;
+      // set up remaining R's, to the right of X
+      if (ieta < _tiles_ieta_max) {
+	for (int idphi = -2; idphi <= +2; idphi++) {
+	  *pptile = & _tiles[_tile_index(ieta+1,iphi+idphi)];
+	  pptile++;
+	}	
+      }
+      // set up remaining R's, and two cols to the right of X
+      if (ieta < _tiles_ieta_max - 1) {
+	for (int idphi = -2; idphi <= +2; idphi++) {
+	  *pptile = & _tiles[_tile_index(ieta+2,iphi+idphi)];
+	  pptile++;
+	}	
+      }
+      // now put semaphore for end tile
+      tile->end_tiles = pptile;
+      // finally make sure tiles are untagged
+      tile->tagged = false;
+      // and store the information about periodicity in phi
+      tile->use_periodic_delta_phi = use_periodic_delta_phi[iphi];
+      // and ensure max distance is sensibly initialised
+      tile->max_NN_dist = 0;
+      // and also position of centre of tile
+      tile->eta_centre = (ieta-_tiles_ieta_min+0.5)*_tile_size_eta + _tiles_eta_min;
+      tile->phi_centre = (iphi+0.5)*_tile_size_phi;
+    }
+  }
+
+}
+
+//----------------------------------------------------------------------
+/// return the tile index corresponding to the given eta,phi point
+int LazyTiling25::_tile_index(const double eta, const double phi) const {
+  int ieta, iphi;
+  if      (eta <= _tiles_eta_min) {ieta = 0;}
+  else if (eta >= _tiles_eta_max) {ieta = _tiles_ieta_max-_tiles_ieta_min;}
+  else {
+    //ieta = int(floor((eta - _tiles_eta_min) / _tile_size_eta));
+    ieta = int(((eta - _tiles_eta_min) / _tile_size_eta));
+    // following needed in case of rare but nasty rounding errors
+    if (ieta > _tiles_ieta_max-_tiles_ieta_min) {
+      ieta = _tiles_ieta_max-_tiles_ieta_min;} 
+  }
+  // allow for some extent of being beyond range in calculation of phi
+  // as well
+  //iphi = (int(floor(phi/_tile_size_phi)) + _n_tiles_phi) % _n_tiles_phi;
+  // with just int and no floor, things run faster but beware
+  iphi = int((phi+twopi)/_tile_size_phi) % _n_tiles_phi;
+  return (iphi + ieta * _n_tiles_phi);
+}
+
+
+//----------------------------------------------------------------------
+// sets up information regarding the tiling of the given jet
+inline void LazyTiling25::_tj_set_jetinfo( TiledJet * const jet,
+					      const int _jets_index) {
+  // first call the generic setup
+  _bj_set_jetinfo<>(jet, _jets_index);
+
+  // Then do the setup specific to the tiled case.
+
+  // Find out which tile it belonds to
+  jet->tile_index = _tile_index(jet->eta, jet->phi);
+
+  // Insert it into the tile's linked list of jets
+  Tile25 * tile = &_tiles[jet->tile_index];
+  jet->previous   = NULL;
+  jet->next       = tile->head;
+  if (jet->next != NULL) {jet->next->previous = jet;}
+  tile->head      = jet;
+}
+
+
+//----------------------------------------------------------------------
+void LazyTiling25::_bj_remove_from_tiles(TiledJet * const jet) {
+  Tile25 * tile = & _tiles[jet->tile_index];
+
+  if (jet->previous == NULL) {
+    // we are at head of the tile, so reset it.
+    // If this was the only jet on the tile then tile->head will now be NULL
+    tile->head = jet->next;
+  } else {
+    // adjust link from previous jet in this tile
+    jet->previous->next = jet->next;
+  }
+  if (jet->next != NULL) {
+    // adjust backwards-link from next jet in this tile
+    jet->next->previous = jet->previous;
+  }
+}
+
+
+//----------------------------------------------------------------------
+/// output the contents of the tiles
+void LazyTiling25::_print_tiles(TiledJet * briefjets ) const {
+  for (vector<Tile25>::const_iterator tile = _tiles.begin(); 
+       tile < _tiles.end(); tile++) {
+    cout << "Tile " << tile - _tiles.begin()
+         << " at " << setw(10) << tile->eta_centre << "," << setw(10) << tile->phi_centre
+         << " = ";
+    vector<int> list;
+    for (TiledJet * jetI = tile->head; jetI != NULL; jetI = jetI->next) {
+      list.push_back(jetI-briefjets);
+      //cout <<" "<<jetI-briefjets;
+    }
+    sort(list.begin(),list.end());
+    for (unsigned int i = 0; i < list.size(); i++) {cout <<" "<<list[i];}
+    cout <<"\n";
+  }
+}
+
+
+//----------------------------------------------------------------------
+/// Add to the vector tile_union the tiles that are in the neighbourhood
+/// of the specified tile_index, including itself -- start adding
+/// from position n_near_tiles-1, and increase n_near_tiles as
+/// you go along (could have done it more C++ like with vector with reserved
+/// space, but fear is that it would have been slower, e.g. checking
+/// for end of vector at each stage to decide whether to resize it)
+void LazyTiling25::_add_neighbours_to_tile_union(const int tile_index, 
+	       vector<int> & tile_union, int & n_near_tiles) const {
+  for (Tile25 * const * near_tile = _tiles[tile_index].begin_tiles; 
+       near_tile != _tiles[tile_index].end_tiles; near_tile++){
+    // get the tile number
+    tile_union[n_near_tiles] = *near_tile - & _tiles[0];
+    n_near_tiles++;
+  }
+}
+
+
+//----------------------------------------------------------------------
+/// Like _add_neighbours_to_tile_union, but only adds neighbours if 
+/// their "tagged" status is false; when a neighbour is added its
+/// tagged status is set to true.
+inline void LazyTiling25::_add_untagged_neighbours_to_tile_union(
+               const int tile_index, 
+	       vector<int> & tile_union, int & n_near_tiles)  {
+  for (Tile25 ** near_tile = _tiles[tile_index].begin_tiles; 
+       near_tile != _tiles[tile_index].end_tiles; near_tile++){
+    if (! (*near_tile)->tagged) {
+      (*near_tile)->tagged = true;
+      // get the tile number
+      tile_union[n_near_tiles] = *near_tile - & _tiles[0];
+      n_near_tiles++;
+    }
+  }
+}
+
+//----------------------------------------------------------------------
+/// Like _add_neighbours_to_tile_union, but adds tiles that are
+/// "neighbours" of a jet (rather than a tile) and only if a
+/// neighbouring tile's max_NN_dist is >= the distance between the jet
+/// and the nearest point on the tile. It ignores tiles that have
+/// already been tagged.
+inline void LazyTiling25::_add_untagged_neighbours_to_tile_union_using_max_info(
+               const TiledJet * jet, 
+	       vector<int> & tile_union, int & n_near_tiles)  {
+  Tile25 & tile = _tiles[jet->tile_index];
+  
+  for (Tile25 ** near_tile = tile.begin_tiles; near_tile != tile.end_tiles; near_tile++){
+    if ((*near_tile)->tagged) continue;
+    double dist = _distance_to_tile(jet, *near_tile);
+    // cout << "      max info looked at tile " << *near_tile - &_tiles[0] 
+    // 	 << ", dist = " << dist << " " << (*near_tile)->max_NN_dist
+    // 	 << endl;
+    if (dist > (*near_tile)->max_NN_dist) continue;
+
+    // cout << "      max info tagged tile " << *near_tile - &_tiles[0] << endl;
+    (*near_tile)->tagged = true;
+    // get the tile number
+    tile_union[n_near_tiles] = *near_tile - & _tiles[0];
+    n_near_tiles++;
+  }
+}
+
+////--------TMPTMPTMPTMPTMP-----GPS TEMP--------------------
+//ostream & operator<<(ostream & ostr, const TiledJet & jet) {
+//  ostr << "j" << setw(3) << jet._jets_index << ":pt2,rap,phi=" ; ostr.flush();
+//  ostr     << jet.kt2 << ","; ostr.flush();
+//  ostr     << jet.eta << ","; ostr.flush();
+//  ostr     << jet.phi; ostr.flush();
+//  ostr     << ", tile=" << jet.tile_index; ostr.flush();
+//  return ostr;
+//}
+
+
+//----------------------------------------------------------------------
+/// returns a particle's distance to the edge of the specified tile
+inline double LazyTiling25::_distance_to_tile(const TiledJet * bj, const Tile25 * tile) 
+#ifdef INSTRUMENT2
+   {
+  _ncall_dtt++; // GPS tmp
+#else
+  const {
+#endif // INSTRUMENT2
+  // Note the careful way of checking the minimum potential deta:
+  // unlike the phi case below, we don't calculate the distance to the
+  // centre and subtract spacing/2. This is because of issue of
+  // boundary tiles, which can extend far beyond spacing/2 in eta. 
+  // Using the positions of tile centers should instead be safe.
+  double deta;
+  if (_tiles[bj->tile_index].eta_centre == tile->eta_centre) deta = 0;
+  //else   deta = std::abs(bj->eta - tile->eta_centre) - 0.5*_tile_size_eta;
+  else   deta = std::abs(bj->eta - tile->eta_centre) - _tile_half_size_eta;
+  // ------
+  //   |
+  // A | B
+  // ------
+  //   |
+  // C | D
+  // ------
+
+  double dphi = std::abs(bj->phi - tile->phi_centre);
+  if (dphi > pi) dphi = twopi-dphi;
+  dphi -= _tile_half_size_phi;
+  //dphi -= 0.5*_tile_size_phi;
+  if (dphi < 0) dphi = 0;
+
+  return dphi*dphi + deta*deta;
+}
+
+
+
+
+//----------------------------------------------------------------------
+/// looks at distance between jetX and jetI and updates the NN
+/// information if relevant; also pushes identity of jetI onto
+/// the vector of jets for minheap, to signal that it will have
+/// to be handled later.
+///
+/// GPS TEMP GPS TMP: REMOVE THIS LATER: EVEN LABELLED AS INLINE, THE
+/// CALL ADDS A SUBSTANTIAL PENALTY...
+inline void LazyTiling25::_update_jetX_jetI_NN(TiledJet * jetX, TiledJet * jetI, vector<TiledJet *> & jets_for_minheap) {
+  double dist = _bj_dist(jetI,jetX);
+  if (dist < jetI->NN_dist) {
+    if (jetI != jetX) {
+      jetI->NN_dist = dist;
+      jetI->NN = jetX;
+      // label jetI as needing heap action...
+      if (!jetI->minheap_update_needed()) {
+	jetI->label_minheap_update_needed();
+	jets_for_minheap.push_back(jetI);
+      }
+    }
+  }
+  if (dist < jetX->NN_dist) {
+    if (jetI != jetX) {
+      jetX->NN_dist = dist;
+      jetX->NN      = jetI;}
+  }
+}
+
+
+inline void LazyTiling25::_set_NN(TiledJet * jetI, 
+                              vector<TiledJet *> & jets_for_minheap) {
+  jetI->NN_dist = _R2;
+  jetI->NN      = NULL;
+  // label jetI as needing heap action...
+  if (!jetI->minheap_update_needed()) {
+    jetI->label_minheap_update_needed();
+    jets_for_minheap.push_back(jetI);}
+  // now go over tiles that are neighbours of I (include own tile)
+  Tile25 * tile_ptr = &_tiles[jetI->tile_index];
+  //if (tile_ptr->is_near_zero_phi(_tile_size_phi)) {
+    for (Tile25 ** near_tile  = tile_ptr->begin_tiles; 
+         near_tile != tile_ptr->end_tiles; near_tile++) {
+      // for own tile, this will be zero automatically: should we be clever
+      // and skip the test? (With some doubling of code?)
+      if (jetI->NN_dist < _distance_to_tile(jetI, *near_tile)) continue;
+      // and then over the contents of that tile
+      for (TiledJet * jetJ  = (*near_tile)->head; 
+           jetJ != NULL; jetJ = jetJ->next) {
+        double dist = _bj_dist(jetI,jetJ);
+        if (dist < jetI->NN_dist && jetJ != jetI) {
+          jetI->NN_dist = dist; jetI->NN = jetJ;
+        }
+      }
+    }
+  // } else {
+  //   // second copy that exploits the fact that for this tile we needn't worry
+  //   // about periodicity
+  //   for (Tile25 ** near_tile  = tile_ptr->begin_tiles; 
+  //        near_tile != tile_ptr->end_tiles; near_tile++) {
+  //     // for own tile, this will be zero automatically: should we be clever
+  //     // and skip the test? (With some doubling of code?)
+  //     if (jetI->NN_dist < _distance_to_tile(jetI, *near_tile)) continue;
+  //     // and then over the contents of that tile
+  //     for (TiledJet * jetJ  = (*near_tile)->head; 
+  //          jetJ != NULL; jetJ = jetJ->next) {
+  //       double dist = _bj_dist_not_periodic(jetI,jetJ);
+  //       if (dist < jetI->NN_dist && jetJ != jetI) {
+  //         jetI->NN_dist = dist; jetI->NN = jetJ;
+  //       }
+  //     }
+  //   }
+  // }
+}
+
+
+void LazyTiling25::run() {
+
+  //_initialise_tiles();
+
+  int n = _jets.size();
+  if (n == 0) return; 
+
+  TiledJet * briefjets = new TiledJet[n];
+  TiledJet * jetA = briefjets, * jetB;
+  // avoid warning about uninitialised oldB below; 
+  // only valid for n>=1 (hence the test n==0 test above)
+  TiledJet oldB = briefjets[0]; 
+
+  // will be used quite deep inside loops, but declare it here so that
+  // memory (de)allocation gets done only once
+  vector<int> tile_union(3*25);
+  
+  // initialise the basic jet info 
+  for (int i = 0; i< n; i++) {
+    _tj_set_jetinfo(jetA, i);
+    //cout << i<<": "<<jetA->tile_index<<"\n";
+    jetA++; // move on to next entry of briefjets
+  }
+  TiledJet * head = briefjets; // a nicer way of naming start
+
+  // set up the initial nearest neighbour information
+  vector<Tile25>::iterator tile;
+  for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
+    // first do it on this tile
+    for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
+      for (jetB = tile->head; jetB != jetA; jetB = jetB->next) {
+	double dist = _bj_dist_not_periodic(jetA,jetB);
+	if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
+	if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
+      }
+    }
+    for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
+      if (jetA->NN_dist > tile->max_NN_dist) tile->max_NN_dist = jetA->NN_dist;
+    }
+  }
+  for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
+    if (tile->use_periodic_delta_phi) {
+      // then do it for RH tiles; 
+      for (Tile25 ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
+        for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
+          double dist_to_tile = _distance_to_tile(jetA, *RTile);
+          // it only makes sense to do a tile if jetA is close enough to the Rtile
+          // either for a jet in the Rtile to be closer to jetA than it's current NN
+          // or if jetA could be closer to something in the Rtile than the largest
+          // NN distance within the RTile.
+          //
+          // GPS note: also tried approach where we perform only the
+          //           first test and run over all surrounding tiles
+          //           (not just RH ones). The test is passed less
+          //           frequently, but one is running over more tiles
+          //           and on balance, for the trial event we used, it's
+          //           a bit slower.
+          bool relevant_for_jetA  = dist_to_tile <= jetA->NN_dist;
+          bool relevant_for_RTile = dist_to_tile <= (*RTile)->max_NN_dist;
+          if (relevant_for_jetA || relevant_for_RTile) {
+            for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
+              double dist = _bj_dist(jetA,jetB);
+              if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
+              if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
+            }
+          } 
+        }
+      }
+    } else {
+      // this second version of the code uses the faster
+      // "not_periodic" version because it knows that the tile is
+      // sufficiently far from the edge.
+      for (Tile25 ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
+        for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
+          double dist_to_tile = _distance_to_tile(jetA, *RTile);
+          bool relevant_for_jetA  = dist_to_tile <= jetA->NN_dist;
+          bool relevant_for_RTile = dist_to_tile <= (*RTile)->max_NN_dist;
+          if (relevant_for_jetA || relevant_for_RTile) {
+            for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
+              double dist = _bj_dist_not_periodic(jetA,jetB);
+              if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
+              if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
+            }
+          } 
+        }
+      }
+    }
+    // no need to do it for LH tiles, since they are implicitly done
+    // when we set NN for both jetA and jetB on the RH tiles.
+  }
+  // Now update the max_NN_dist within each tile. Not strictly
+  // necessary, because existing max_NN_dist is an upper bound.  but
+  // costs little and may give some efficiency gain later.
+  for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
+    tile->max_NN_dist = 0;
+    for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
+      if (jetA->NN_dist > tile->max_NN_dist) tile->max_NN_dist = jetA->NN_dist;
+    }
+  }
+
+#ifdef INSTRUMENT2
+  cout << "intermediate ncall, dtt = " << _ncall << " " << _ncall_dtt << endl; // GPS tmp
+#endif // INSTRUMENT2
+
+  // GPS debugging
+  // _print_tiles(briefjets);
+  // for (jetB = briefjets; jetB < briefjets+n; jetB++) {
+  //   cout << "Tiled jet " << jetB->_jets_index << " has NN " << jetB->NN-briefjets << endl;
+  // }
+
+  vector<double> diJs(n);
+  for (int i = 0; i < n; i++) {
+    diJs[i] = _bj_diJ(&briefjets[i]);
+    briefjets[i].label_minheap_update_done();
+  }
+  MinHeap minheap(diJs);
+  // have a stack telling us which jets we'll have to update on the heap
+  vector<TiledJet *> jets_for_minheap;
+  jets_for_minheap.reserve(n); 
+
+  // now run the recombination loop
+  int history_location = n-1;
+  while (n > 0) {
+
+    double diJ_min = minheap.minval() *_invR2;
+    jetA = head + minheap.minloc();
+
+    // do the recombination between A and B
+    history_location++;
+    jetB = jetA->NN;
+
+    if (jetB != NULL) {
+      // jet-jet recombination
+      // If necessary relabel A & B to ensure jetB < jetA, that way if
+      // the larger of them == newtail then that ends up being jetA and 
+      // the new jet that is added as jetB is inserted in a position that
+      // has a future!
+      if (jetA < jetB) {std::swap(jetA,jetB);}
+
+      int nn; // new jet index
+      _cs.plugin_record_ij_recombination(jetA->_jets_index, jetB->_jets_index, diJ_min, nn);
+      
+      // what was jetB will now become the new jet
+      _bj_remove_from_tiles(jetA);
+      oldB = * jetB;  // take a copy because we will need it...
+      _bj_remove_from_tiles(jetB);
+      _tj_set_jetinfo(jetB, nn); // cause jetB to become _jets[nn]
+                                 // (also registers the jet in the tiling)
+    } else {
+      // jet-beam recombination
+      // get the hist_index
+      _cs.plugin_record_iB_recombination(jetA->_jets_index, diJ_min);
+      _bj_remove_from_tiles(jetA);
+    }
+
+    // remove the minheap entry for jetA
+    minheap.remove(jetA-head);
+
+    int n_near_tiles = 0;
+
+    // Initialise jetB's NN distance as well as updating it for other
+    // particles. While doing so, examine whether jetA or old jetB was
+    // some other particle's NN.
+    if (jetB != NULL) {
+      Tile25 & jetB_tile = _tiles[jetB->tile_index];
+      for (Tile25 ** near_tile  = jetB_tile.begin_tiles; 
+	           near_tile != jetB_tile.end_tiles; near_tile++) {
+
+    	double dist_to_tile = _distance_to_tile(jetB, *near_tile);
+        // use <= in next line so that on first tile, relevant_for_jetB is 
+        // set to true
+    	bool relevant_for_jetB  = dist_to_tile <= jetB->NN_dist;
+    	bool relevant_for_near_tile = dist_to_tile <= (*near_tile)->max_NN_dist;
+        bool relevant = relevant_for_jetB || relevant_for_near_tile;
+        if (! relevant) continue;
+        // now label this tile as having been considered (so that we 
+        // don't go over it again later)
+        tile_union[n_near_tiles] = *near_tile - & _tiles[0];
+        (*near_tile)->tagged = true;
+        n_near_tiles++;
+        
+        // if going over the neighbouring tile's jets, check anyway
+        // whether A or B were nearest neighbours, since it comes at a
+        // modest cost relative to the distance computation (and we would
+        // in most cases have to do it again later anyway).
+        for (TiledJet * jetI = (*near_tile)->head; jetI != NULL; jetI = jetI->next) {
+          if (jetI->NN == jetA || jetI->NN == jetB) _set_NN(jetI, jets_for_minheap);
+          _update_jetX_jetI_NN(jetB, jetI, jets_for_minheap);
+        }
+      }
+    }
+
+    // first establish the set of tiles over which we are going to
+    // have to run searches for updated and new nearest-neighbours --
+    // basically a combination of vicinity of the tiles of the two old
+    // and one new jet.
+    int n_done_tiles = n_near_tiles;
+    _add_untagged_neighbours_to_tile_union_using_max_info(jetA, 
+       					   tile_union, n_near_tiles);
+    if (jetB != NULL) {
+	_add_untagged_neighbours_to_tile_union_using_max_info(&oldB,
+							      tile_union,n_near_tiles);
+      jetB->label_minheap_update_needed();
+      jets_for_minheap.push_back(jetB);
+    }
+
+
+    // first untag the tiles we have already dealt with
+    for (int itile = 0; itile < n_done_tiles; itile++) {
+      _tiles[tile_union[itile]].tagged = false;
+    }
+    // now run over the tiles that were tagged earlier and that we haven't yet
+    // had a change to visit.
+    for (int itile = n_done_tiles; itile < n_near_tiles; itile++) {
+      Tile25 * tile_ptr = &_tiles[tile_union[itile]];
+      tile_ptr->tagged = false;
+      // run over all jets in the current tile
+      for (TiledJet * jetI = tile_ptr->head; jetI != NULL; jetI = jetI->next) {
+        // see if jetI had jetA or jetB as a NN -- if so recalculate the NN
+        if (jetI->NN == jetA || (jetI->NN == jetB && jetB != NULL)) {
+          _set_NN(jetI, jets_for_minheap);
+        }
+      }
+    }
+
+    // deal with jets whose minheap entry needs updating
+    //if (verbose) cout << "  jets whose NN was modified: " << endl;
+    while (jets_for_minheap.size() > 0) {
+      TiledJet * jetI = jets_for_minheap.back(); 
+      jets_for_minheap.pop_back();
+      minheap.update(jetI-head, _bj_diJ(jetI));
+      jetI->label_minheap_update_done();
+      // handle max_NN_dist update for all jets that might have
+      // seen a change (increase) of distance
+      Tile25 & tile_I = _tiles[jetI->tile_index];
+      if (tile_I.max_NN_dist < jetI->NN_dist) tile_I.max_NN_dist = jetI->NN_dist;
+    }
+    n--;
+  }
+
+  // final cleaning up;
+  delete[] briefjets;
+#ifdef INSTRUMENT2
+  cout << "ncall, dtt = " << _ncall << " " << _ncall_dtt << endl; // GPS tmp
+#endif // INSTRUMENT2
+
+}
+
+FASTJET_END_NAMESPACE
Index: external/fastjet/LazyTiling9.cc
===================================================================
--- external/fastjet/LazyTiling9.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/LazyTiling9.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,749 @@
+//FJSTARTHEADER
+// $Id: LazyTiling9.cc 3477 2014-07-29 14:34:39Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//
+//----------------------------------------------------------------------
+// This file is part of FastJet.
+//
+//  FastJet 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.
+//
+//  The algorithms that underlie FastJet have required considerable
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
+//  FastJet as part of work towards a scientific publication, please
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
+//
+//  FastJet 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 FastJet. If not, see <http://www.gnu.org/licenses/>.
+//----------------------------------------------------------------------
+//FJENDHEADER
+
+
+#include <iomanip>
+#include <limits>
+#include <cmath>
+#include "fastjet/internal/LazyTiling9.hh"
+#include "fastjet/internal/TilingExtent.hh"
+using namespace std;
+
+// uncomment the line below to use TilingExtent in LazyTiling9
+#define _FASTJET_TILING2_USE_TILING_ANALYSIS_
+
+FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
+
+
+
+LazyTiling9::LazyTiling9(ClusterSequence & cs) :
+  _cs(cs), _jets(cs.jets())
+  //, _minheap(_jets.size()) 
+{
+#ifdef INSTRUMENT2
+  _ncall = 0; // gps tmp
+  _ncall_dtt = 0; // gps tmp
+#endif // INSTRUMENT2
+  _Rparam = cs.jet_def().R();
+  _R2 = _Rparam * _Rparam;
+  _invR2 = 1.0 / _R2;
+  _initialise_tiles();
+}
+
+
+//----------------------------------------------------------------------
+/// Set up the tiles:
+///  - decide the range in eta
+///  - allocate the tiles
+///  - set up the cross-referencing info between tiles
+///
+/// The neighbourhood of a tile is set up as follows
+///
+/// 	      LRR
+///           LXR
+///           LLR
+///
+/// such that tiles is an array containing XLLLLRRRR with pointers
+///                                         |   \ RH_tiles
+///                                         \ surrounding_tiles
+///
+/// with appropriate precautions when close to the edge of the tiled
+/// region.
+///
+void LazyTiling9::_initialise_tiles() {
+
+  // first decide tile sizes (with a lower bound to avoid huge memory use with
+  // very small R)
+  double default_size = max(0.1,_Rparam);
+  _tile_size_eta = default_size;
+  // it makes no sense to go below 3 tiles in phi -- 3 tiles is
+  // sufficient to make sure all pair-wise combinations up to pi in
+  // phi are possible
+  _n_tiles_phi   = max(3,int(floor(twopi/default_size)));
+  _tile_size_phi = twopi / _n_tiles_phi; // >= _Rparam and fits in 2pi
+
+#ifdef _FASTJET_TILING2_USE_TILING_ANALYSIS_
+  // testing
+  TilingExtent tiling_analysis(_cs);
+  _tiles_eta_min = tiling_analysis.minrap();
+  _tiles_eta_max = tiling_analysis.maxrap();
+  //cout << "Using timing analysis " << " " << _tiles_eta_min << " " << _tiles_eta_max << endl;
+#else
+  // always include zero rapidity in the tiling region
+  _tiles_eta_min = 0.0;
+  _tiles_eta_max = 0.0;
+  // but go no further than following
+  const double maxrap = 7.0;
+  
+  // and find out how much further one should go
+  for(unsigned int i = 0; i < _jets.size(); i++) {
+    double eta = _jets[i].rap();
+    // first check if eta is in range -- to avoid taking into account
+    // very spurious rapidities due to particles with near-zero kt.
+    if (abs(eta) < maxrap) {
+      if (eta < _tiles_eta_min) {_tiles_eta_min = eta;}
+      if (eta > _tiles_eta_max) {_tiles_eta_max = eta;}
+    }
+  }
+  //cout << "NOT using timing analysis " << " " << _tiles_eta_min << " " << _tiles_eta_max << endl;
+#endif
+
+  // Now adjust the values for the rapidity ("eta") range.
+  //
+  // When tile_size_eta is large, we have two options:
+  // - always have at least two tiles in rapidity (FASTJET_LAZY9_MIN2TILESY),
+  //   currently split down the middle of the rapidity extent of the particles
+  // - take whatever we get from the original 
+  //   _tiles_ieta_min[max] = int(floor(_tiles_eta_min[max]/_tile_size_eta));
+  //   which will sometimes leave us with just one tile in Y; 
+  //
+  // For events that are symetric in Y this should not change
+  // anything, but for asymmetric ones FASTJET_LAZY9_MIN2TILESY may be
+  // a bit faster.
+  // 
+#define FASTJET_LAZY9_MIN2TILESY
+#ifdef FASTJET_LAZY9_MIN2TILESY
+   if (_tiles_eta_max - _tiles_eta_min < 2*_tile_size_eta) {
+     // if we have a rapidity coverage that is small compared to the
+     // tile size then we can adjust the grid in rapidity so as to
+     // have exactly 3 tiles. This can give relevant speed improvements 
+     // for large R jets
+     _tile_size_eta = (_tiles_eta_max - _tiles_eta_min)/2;
+     _tiles_ieta_min = 0;
+     _tiles_ieta_max = 1;
+     // the eta max value is being taken as the lower edge of the
+     // highest-y tile
+     _tiles_eta_max -= _tile_size_eta;
+   } else {
+#endif //FASTJET_LAZY9_MIN2TILESY
+  _tiles_ieta_min = int(floor(_tiles_eta_min/_tile_size_eta));
+  _tiles_ieta_max = int(floor( _tiles_eta_max/_tile_size_eta));
+  _tiles_eta_min = _tiles_ieta_min * _tile_size_eta;
+  _tiles_eta_max = _tiles_ieta_max * _tile_size_eta;
+#ifdef FASTJET_LAZY9_MIN2TILESY
+   }
+#endif
+
+  _tile_half_size_eta = _tile_size_eta * 0.5;
+  _tile_half_size_phi = _tile_size_phi * 0.5;
+
+  // set up information about whether we need to allow for "periodic" 
+  // wrapping tests in delta_phi calculations
+  vector<bool> use_periodic_delta_phi(_n_tiles_phi, false);
+  if (_n_tiles_phi <= 3) {
+    fill(use_periodic_delta_phi.begin(), use_periodic_delta_phi.end(), true);
+  } else {
+    use_periodic_delta_phi[0] = true;
+    use_periodic_delta_phi[_n_tiles_phi-1] = true;
+  }
+
+  // allocate the tiles
+  _tiles.resize((_tiles_ieta_max-_tiles_ieta_min+1)*_n_tiles_phi);
+
+  // now set up the cross-referencing between tiles
+  for (int ieta = _tiles_ieta_min; ieta <= _tiles_ieta_max; ieta++) {
+    for (int iphi = 0; iphi < _n_tiles_phi; iphi++) {
+      Tile2 * tile = & _tiles[_tile_index(ieta,iphi)];
+      // no jets in this tile yet
+      tile->head = NULL; // first element of tiles points to itself
+      tile->begin_tiles[0] =  tile;
+      Tile2 ** pptile = & (tile->begin_tiles[0]);
+      pptile++;
+      //
+      // set up L's in column to the left of X
+      tile->surrounding_tiles = pptile;
+      if (ieta > _tiles_ieta_min) {
+	// with the itile subroutine, we can safely run tiles from
+	// idphi=-1 to idphi=+1, because it takes care of
+	// negative and positive boundaries
+	for (int idphi = -1; idphi <=+1; idphi++) {
+	  *pptile = & _tiles[_tile_index(ieta-1,iphi+idphi)];
+	  pptile++;
+	}	
+      }
+      // now set up last L (below X)
+      *pptile = & _tiles[_tile_index(ieta,iphi-1)];
+      pptile++;
+      // set up first R (above X)
+      tile->RH_tiles = pptile;
+      *pptile = & _tiles[_tile_index(ieta,iphi+1)];
+      pptile++;
+      // set up remaining R's, to the right of X
+      if (ieta < _tiles_ieta_max) {
+	for (int idphi = -1; idphi <= +1; idphi++) {
+	  *pptile = & _tiles[_tile_index(ieta+1,iphi+idphi)];
+	  pptile++;
+	}	
+      }
+      // now put semaphore for end tile
+      tile->end_tiles = pptile;
+      // finally make sure tiles are untagged
+      tile->tagged = false;
+      // and store the information about periodicity in phi
+      tile->use_periodic_delta_phi = use_periodic_delta_phi[iphi];
+      // and ensure max distance is sensibly initialised
+      tile->max_NN_dist = 0;
+      // and also position of centre of tile
+      tile->eta_centre = (ieta-_tiles_ieta_min+0.5)*_tile_size_eta + _tiles_eta_min;
+      tile->phi_centre = (iphi+0.5)*_tile_size_phi;
+    }
+  }
+
+}
+
+//----------------------------------------------------------------------
+/// return the tile index corresponding to the given eta,phi point
+int LazyTiling9::_tile_index(const double eta, const double phi) const {
+  int ieta, iphi;
+  if      (eta <= _tiles_eta_min) {ieta = 0;}
+  else if (eta >= _tiles_eta_max) {ieta = _tiles_ieta_max-_tiles_ieta_min;}
+  else {
+    //ieta = int(floor((eta - _tiles_eta_min) / _tile_size_eta));
+    ieta = int(((eta - _tiles_eta_min) / _tile_size_eta));
+    // following needed in case of rare but nasty rounding errors
+    if (ieta > _tiles_ieta_max-_tiles_ieta_min) {
+      ieta = _tiles_ieta_max-_tiles_ieta_min;} 
+  }
+  // allow for some extent of being beyond range in calculation of phi
+  // as well
+  //iphi = (int(floor(phi/_tile_size_phi)) + _n_tiles_phi) % _n_tiles_phi;
+  // with just int and no floor, things run faster but beware
+  iphi = int((phi+twopi)/_tile_size_phi) % _n_tiles_phi;
+  return (iphi + ieta * _n_tiles_phi);
+}
+
+
+//----------------------------------------------------------------------
+// sets up information regarding the tiling of the given jet
+inline void LazyTiling9::_tj_set_jetinfo( TiledJet * const jet,
+					      const int _jets_index) {
+  // first call the generic setup
+  _bj_set_jetinfo<>(jet, _jets_index);
+
+  // Then do the setup specific to the tiled case.
+
+  // Find out which tile it belonds to
+  jet->tile_index = _tile_index(jet->eta, jet->phi);
+
+  // Insert it into the tile's linked list of jets
+  Tile2 * tile = &_tiles[jet->tile_index];
+  jet->previous   = NULL;
+  jet->next       = tile->head;
+  if (jet->next != NULL) {jet->next->previous = jet;}
+  tile->head      = jet;
+}
+
+
+//----------------------------------------------------------------------
+void LazyTiling9::_bj_remove_from_tiles(TiledJet * const jet) {
+  Tile2 * tile = & _tiles[jet->tile_index];
+
+  if (jet->previous == NULL) {
+    // we are at head of the tile, so reset it.
+    // If this was the only jet on the tile then tile->head will now be NULL
+    tile->head = jet->next;
+  } else {
+    // adjust link from previous jet in this tile
+    jet->previous->next = jet->next;
+  }
+  if (jet->next != NULL) {
+    // adjust backwards-link from next jet in this tile
+    jet->next->previous = jet->previous;
+  }
+}
+
+
+//----------------------------------------------------------------------
+/// output the contents of the tiles
+void LazyTiling9::_print_tiles(TiledJet * briefjets ) const {
+  for (vector<Tile2>::const_iterator tile = _tiles.begin(); 
+       tile < _tiles.end(); tile++) {
+    cout << "Tile " << tile - _tiles.begin()<<" = ";
+    vector<int> list;
+    for (TiledJet * jetI = tile->head; jetI != NULL; jetI = jetI->next) {
+      list.push_back(jetI-briefjets);
+      //cout <<" "<<jetI-briefjets;
+    }
+    sort(list.begin(),list.end());
+    for (unsigned int i = 0; i < list.size(); i++) {cout <<" "<<list[i];}
+    cout <<"\n";
+  }
+}
+
+
+//----------------------------------------------------------------------
+/// Add to the vector tile_union the tiles that are in the neighbourhood
+/// of the specified tile_index, including itself -- start adding
+/// from position n_near_tiles-1, and increase n_near_tiles as
+/// you go along (could have done it more C++ like with vector with reserved
+/// space, but fear is that it would have been slower, e.g. checking
+/// for end of vector at each stage to decide whether to resize it)
+void LazyTiling9::_add_neighbours_to_tile_union(const int tile_index, 
+	       vector<int> & tile_union, int & n_near_tiles) const {
+  for (Tile2 * const * near_tile = _tiles[tile_index].begin_tiles; 
+       near_tile != _tiles[tile_index].end_tiles; near_tile++){
+    // get the tile number
+    tile_union[n_near_tiles] = *near_tile - & _tiles[0];
+    n_near_tiles++;
+  }
+}
+
+
+//----------------------------------------------------------------------
+/// Like _add_neighbours_to_tile_union, but only adds neighbours if 
+/// their "tagged" status is false; when a neighbour is added its
+/// tagged status is set to true.
+inline void LazyTiling9::_add_untagged_neighbours_to_tile_union(
+               const int tile_index, 
+	       vector<int> & tile_union, int & n_near_tiles)  {
+  for (Tile2 ** near_tile = _tiles[tile_index].begin_tiles; 
+       near_tile != _tiles[tile_index].end_tiles; near_tile++){
+    if (! (*near_tile)->tagged) {
+      (*near_tile)->tagged = true;
+      // get the tile number
+      tile_union[n_near_tiles] = *near_tile - & _tiles[0];
+      n_near_tiles++;
+    }
+  }
+}
+
+//----------------------------------------------------------------------
+/// Like _add_neighbours_to_tile_union, but adds tiles that are
+/// "neighbours" of a jet (rather than a tile) and only if a
+/// neighbouring tile's max_NN_dist is >= the distance between the jet
+/// and the nearest point on the tile. It ignores tiles that have
+/// already been tagged.
+inline void LazyTiling9::_add_untagged_neighbours_to_tile_union_using_max_info(
+               const TiledJet * jet, 
+	       vector<int> & tile_union, int & n_near_tiles)  {
+  Tile2 & tile = _tiles[jet->tile_index];
+  
+  for (Tile2 ** near_tile = tile.begin_tiles; near_tile != tile.end_tiles; near_tile++){
+    if ((*near_tile)->tagged) continue;
+    double dist = _distance_to_tile(jet, *near_tile);
+    // cout << "      max info looked at tile " << *near_tile - &_tiles[0] 
+    // 	 << ", dist = " << dist << " " << (*near_tile)->max_NN_dist
+    // 	 << endl;
+    if (dist > (*near_tile)->max_NN_dist) continue;
+
+    // cout << "      max info tagged tile " << *near_tile - &_tiles[0] << endl;
+    (*near_tile)->tagged = true;
+    // get the tile number
+    tile_union[n_near_tiles] = *near_tile - & _tiles[0];
+    n_near_tiles++;
+  }
+}
+
+////--------TMPTMPTMPTMPTMP-----GPS TEMP--------------------
+//ostream & operator<<(ostream & ostr, const TiledJet & jet) {
+//  ostr << "j" << setw(3) << jet._jets_index << ":pt2,rap,phi=" ; ostr.flush();
+//  ostr     << jet.kt2 << ","; ostr.flush();
+//  ostr     << jet.eta << ","; ostr.flush();
+//  ostr     << jet.phi; ostr.flush();
+//  ostr     << ", tile=" << jet.tile_index; ostr.flush();
+//  return ostr;
+//}
+
+
+//----------------------------------------------------------------------
+/// returns a particle's distance to the edge of the specified tile
+inline double LazyTiling9::_distance_to_tile(const TiledJet * bj, const Tile2 * tile) 
+#ifdef INSTRUMENT2
+   {
+  _ncall_dtt++; // GPS tmp
+#else
+  const {
+#endif // INSTRUMENT2
+  // Note the careful way of checking the minimum potential deta:
+  // unlike the phi case below, we don't calculate the distance to the
+  // centre and subtract spacing/2. This is because of issue of
+  // boundary tiles, which can extend far beyond spacing/2 in eta. 
+  // Using the positions of tile centers should instead be safe.
+  double deta;
+  if (_tiles[bj->tile_index].eta_centre == tile->eta_centre) deta = 0;
+  //else   deta = std::abs(bj->eta - tile->eta_centre) - 0.5*_tile_size_eta;
+  else   deta = std::abs(bj->eta - tile->eta_centre) - _tile_half_size_eta;
+  // ------
+  //   |
+  // A | B
+  // ------
+  //   |
+  // C | D
+  // ------
+
+  double dphi = std::abs(bj->phi - tile->phi_centre);
+  if (dphi > pi) dphi = twopi-dphi;
+  dphi -= _tile_half_size_phi;
+  //dphi -= 0.5*_tile_size_phi;
+  if (dphi < 0) dphi = 0;
+
+  return dphi*dphi + deta*deta;
+}
+
+
+
+
+//----------------------------------------------------------------------
+/// looks at distance between jetX and jetI and updates the NN
+/// information if relevant; also pushes identity of jetI onto
+/// the vector of jets for minheap, to signal that it will have
+/// to be handled later.
+///
+/// GPS TEMP GPS TMP: REMOVE THIS LATER: EVEN LABELLED AS INLINE, THE
+/// CALL ADDS A SUBSTANTIAL PENALTY...
+inline void LazyTiling9::_update_jetX_jetI_NN(TiledJet * jetX, TiledJet * jetI, vector<TiledJet *> & jets_for_minheap) {
+  double dist = _bj_dist(jetI,jetX);
+  if (dist < jetI->NN_dist) {
+    if (jetI != jetX) {
+      jetI->NN_dist = dist;
+      jetI->NN = jetX;
+      // label jetI as needing heap action...
+      if (!jetI->minheap_update_needed()) {
+	jetI->label_minheap_update_needed();
+	jets_for_minheap.push_back(jetI);
+      }
+    }
+  }
+  if (dist < jetX->NN_dist) {
+    if (jetI != jetX) {
+      jetX->NN_dist = dist;
+      jetX->NN      = jetI;}
+  }
+}
+
+
+inline void LazyTiling9::_set_NN(TiledJet * jetI, 
+                              vector<TiledJet *> & jets_for_minheap) {
+  jetI->NN_dist = _R2;
+  jetI->NN      = NULL;
+  // label jetI as needing heap action...
+  if (!jetI->minheap_update_needed()) {
+    jetI->label_minheap_update_needed();
+    jets_for_minheap.push_back(jetI);}
+  // now go over tiles that are neighbours of I (include own tile)
+  Tile2 * tile_ptr = &_tiles[jetI->tile_index];
+  //if (tile_ptr->is_near_zero_phi(_tile_size_phi)) {
+    for (Tile2 ** near_tile  = tile_ptr->begin_tiles; 
+         near_tile != tile_ptr->end_tiles; near_tile++) {
+      // for own tile, this will be zero automatically: should we be clever
+      // and skip the test? (With some doubling of code?)
+      if (jetI->NN_dist < _distance_to_tile(jetI, *near_tile)) continue;
+      // and then over the contents of that tile
+      for (TiledJet * jetJ  = (*near_tile)->head; 
+           jetJ != NULL; jetJ = jetJ->next) {
+        double dist = _bj_dist(jetI,jetJ);
+        if (dist < jetI->NN_dist && jetJ != jetI) {
+          jetI->NN_dist = dist; jetI->NN = jetJ;
+        }
+      }
+    }
+  // } else {
+  //   // second copy that exploits the fact that for this tile we needn't worry
+  //   // about periodicity
+  //   for (Tile2 ** near_tile  = tile_ptr->begin_tiles; 
+  //        near_tile != tile_ptr->end_tiles; near_tile++) {
+  //     // for own tile, this will be zero automatically: should we be clever
+  //     // and skip the test? (With some doubling of code?)
+  //     if (jetI->NN_dist < _distance_to_tile(jetI, *near_tile)) continue;
+  //     // and then over the contents of that tile
+  //     for (TiledJet * jetJ  = (*near_tile)->head; 
+  //          jetJ != NULL; jetJ = jetJ->next) {
+  //       double dist = _bj_dist_not_periodic(jetI,jetJ);
+  //       if (dist < jetI->NN_dist && jetJ != jetI) {
+  //         jetI->NN_dist = dist; jetI->NN = jetJ;
+  //       }
+  //     }
+  //   }
+  // }
+}
+
+
+void LazyTiling9::run() {
+
+  //_initialise_tiles();
+
+  int n = _jets.size();
+  if (n == 0) return; 
+
+  TiledJet * briefjets = new TiledJet[n];
+  TiledJet * jetA = briefjets, * jetB;
+  // avoid warning about uninitialised oldB below; 
+  // only valid for n>=1 (hence the test n==0 test above)
+  TiledJet oldB = briefjets[0]; 
+
+  // will be used quite deep inside loops, but declare it here so that
+  // memory (de)allocation gets done only once
+  vector<int> tile_union(3*n_tile_neighbours);
+  
+  // initialise the basic jet info 
+  for (int i = 0; i< n; i++) {
+    _tj_set_jetinfo(jetA, i);
+    //cout << i<<": "<<jetA->tile_index<<"\n";
+    jetA++; // move on to next entry of briefjets
+  }
+  TiledJet * head = briefjets; // a nicer way of naming start
+
+
+  // // count the contents of the tiles
+  // for (int ieta = _tiles_ieta_min; ieta <= _tiles_ieta_max; ieta++) {
+  //   for (int iphi = 0; iphi < _n_tiles_phi; iphi++) {
+  //     Tile2 * tile = & _tiles[_tile_index(ieta,iphi)];
+  //     int njets = 0;
+  //     const TiledJet * jet = tile->head;
+  //     while (jet != 0) {
+  //       njets++;
+  //       jet = jet->next;
+  //     }
+  //     cout << ieta 
+  //          << " " << iphi 
+  //          << " " << tile->jet_count()
+  //          << endl;
+  //   }
+  // }
+
+
+  // set up the initial nearest neighbour information
+  vector<Tile2>::iterator tile;
+  for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
+    // first do it on this tile
+    for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
+      for (jetB = tile->head; jetB != jetA; jetB = jetB->next) {
+	double dist = _bj_dist_not_periodic(jetA,jetB);
+	if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
+	if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
+      }
+    }
+    for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
+      if (jetA->NN_dist > tile->max_NN_dist) tile->max_NN_dist = jetA->NN_dist;
+    }
+  }
+  for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
+    if (tile->use_periodic_delta_phi) {
+      // then do it for RH tiles; 
+      for (Tile2 ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
+        for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
+          double dist_to_tile = _distance_to_tile(jetA, *RTile);
+          // it only makes sense to do a tile if jetA is close enough to the Rtile
+          // either for a jet in the Rtile to be closer to jetA than it's current NN
+          // or if jetA could be closer to something in the Rtile than the largest
+          // NN distance within the RTile.
+          //
+          // GPS note: also tried approach where we perform only the
+          //           first test and run over all surrounding tiles
+          //           (not just RH ones). The test is passed less
+          //           frequently, but one is running over more tiles
+          //           and on balance, for the trial event we used, it's
+          //           a bit slower.
+          bool relevant_for_jetA  = dist_to_tile <= jetA->NN_dist;
+          bool relevant_for_RTile = dist_to_tile <= (*RTile)->max_NN_dist;
+          if (relevant_for_jetA || relevant_for_RTile) {
+            for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
+              double dist = _bj_dist(jetA,jetB);
+              if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
+              if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
+            }
+          } 
+        }
+      }
+    } else {
+      // this second version of the code uses the faster
+      // "not_periodic" version because it knows that the tile is
+      // sufficiently far from the edge.
+      for (Tile2 ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
+        for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
+          double dist_to_tile = _distance_to_tile(jetA, *RTile);
+          bool relevant_for_jetA  = dist_to_tile <= jetA->NN_dist;
+          bool relevant_for_RTile = dist_to_tile <= (*RTile)->max_NN_dist;
+          if (relevant_for_jetA || relevant_for_RTile) {
+            for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
+              double dist = _bj_dist_not_periodic(jetA,jetB);
+              if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
+              if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
+            }
+          } 
+        }
+      }
+    }
+    // no need to do it for LH tiles, since they are implicitly done
+    // when we set NN for both jetA and jetB on the RH tiles.
+  }
+  // Now update the max_NN_dist within each tile. Not strictly
+  // necessary, because existing max_NN_dist is an upper bound.  but
+  // costs little and may give some efficiency gain later.
+  for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
+    tile->max_NN_dist = 0;
+    for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
+      if (jetA->NN_dist > tile->max_NN_dist) tile->max_NN_dist = jetA->NN_dist;
+    }
+  }
+
+#ifdef INSTRUMENT2
+  cout << "intermediate ncall, dtt = " << _ncall << " " << _ncall_dtt << endl; // GPS tmp
+#endif // INSTRUMENT2
+
+  vector<double> diJs(n);
+  for (int i = 0; i < n; i++) {
+    diJs[i] = _bj_diJ(&briefjets[i]);
+    briefjets[i].label_minheap_update_done();
+  }
+  MinHeap minheap(diJs);
+  // have a stack telling us which jets we'll have to update on the heap
+  vector<TiledJet *> jets_for_minheap;
+  jets_for_minheap.reserve(n); 
+
+  // now run the recombination loop
+  int history_location = n-1;
+  while (n > 0) {
+
+    double diJ_min = minheap.minval() *_invR2;
+    jetA = head + minheap.minloc();
+
+    // do the recombination between A and B
+    history_location++;
+    jetB = jetA->NN;
+
+    if (jetB != NULL) {
+      // jet-jet recombination
+      // If necessary relabel A & B to ensure jetB < jetA, that way if
+      // the larger of them == newtail then that ends up being jetA and 
+      // the new jet that is added as jetB is inserted in a position that
+      // has a future!
+      if (jetA < jetB) {std::swap(jetA,jetB);}
+
+      int nn; // new jet index
+      _cs.plugin_record_ij_recombination(jetA->_jets_index, jetB->_jets_index, diJ_min, nn);
+      
+      // what was jetB will now become the new jet
+      _bj_remove_from_tiles(jetA);
+      oldB = * jetB;  // take a copy because we will need it...
+      _bj_remove_from_tiles(jetB);
+      _tj_set_jetinfo(jetB, nn); // cause jetB to become _jets[nn]
+                                 // (also registers the jet in the tiling)
+    } else {
+      // jet-beam recombination
+      // get the hist_index
+      _cs.plugin_record_iB_recombination(jetA->_jets_index, diJ_min);
+      _bj_remove_from_tiles(jetA);
+    }
+
+    // remove the minheap entry for jetA
+    minheap.remove(jetA-head);
+
+    int n_near_tiles = 0;
+
+    // Initialise jetB's NN distance as well as updating it for other
+    // particles. While doing so, examine whether jetA or old jetB was
+    // some other particle's NN.
+    if (jetB != NULL) {
+      Tile2 & jetB_tile = _tiles[jetB->tile_index];
+      for (Tile2 ** near_tile  = jetB_tile.begin_tiles; 
+	           near_tile != jetB_tile.end_tiles; near_tile++) {
+
+    	double dist_to_tile = _distance_to_tile(jetB, *near_tile);
+        // use <= in next line so that on first tile, relevant_for_jetB is 
+        // set to true
+    	bool relevant_for_jetB  = dist_to_tile <= jetB->NN_dist;
+    	bool relevant_for_near_tile = dist_to_tile <= (*near_tile)->max_NN_dist;
+        bool relevant = relevant_for_jetB || relevant_for_near_tile;
+        if (! relevant) continue;
+        // now label this tile as having been considered (so that we 
+        // don't go over it again later)
+        tile_union[n_near_tiles] = *near_tile - & _tiles[0];
+        (*near_tile)->tagged = true;
+        n_near_tiles++;
+        
+        // if going over the neighbouring tile's jets, check anyway
+        // whether A or B were nearest neighbours, since it comes at a
+        // modest cost relative to the distance computation (and we would
+        // in most cases have to do it again later anyway).
+        for (TiledJet * jetI = (*near_tile)->head; jetI != NULL; jetI = jetI->next) {
+          if (jetI->NN == jetA || jetI->NN == jetB) _set_NN(jetI, jets_for_minheap);
+          _update_jetX_jetI_NN(jetB, jetI, jets_for_minheap);
+        }
+      }
+    }
+
+    // first establish the set of tiles over which we are going to
+    // have to run searches for updated and new nearest-neighbours --
+    // basically a combination of vicinity of the tiles of the two old
+    // and one new jet.
+    int n_done_tiles = n_near_tiles;
+    _add_untagged_neighbours_to_tile_union_using_max_info(jetA, 
+       					   tile_union, n_near_tiles);
+    if (jetB != NULL) {
+	_add_untagged_neighbours_to_tile_union_using_max_info(&oldB,
+							      tile_union,n_near_tiles);
+      jetB->label_minheap_update_needed();
+      jets_for_minheap.push_back(jetB);
+    }
+
+
+    // first untag the tiles we have already dealt with
+    for (int itile = 0; itile < n_done_tiles; itile++) {
+      _tiles[tile_union[itile]].tagged = false;
+    }
+    // now run over the tiles that were tagged earlier and that we haven't yet
+    // had a change to visit.
+    for (int itile = n_done_tiles; itile < n_near_tiles; itile++) {
+      Tile2 * tile_ptr = &_tiles[tile_union[itile]];
+      tile_ptr->tagged = false;
+      // run over all jets in the current tile
+      for (TiledJet * jetI = tile_ptr->head; jetI != NULL; jetI = jetI->next) {
+        // see if jetI had jetA or jetB as a NN -- if so recalculate the NN
+        if (jetI->NN == jetA || (jetI->NN == jetB && jetB != NULL)) {
+          _set_NN(jetI, jets_for_minheap);
+        }
+      }
+    }
+
+    // deal with jets whose minheap entry needs updating
+    //if (verbose) cout << "  jets whose NN was modified: " << endl;
+    while (jets_for_minheap.size() > 0) {
+      TiledJet * jetI = jets_for_minheap.back(); 
+      jets_for_minheap.pop_back();
+      minheap.update(jetI-head, _bj_diJ(jetI));
+      jetI->label_minheap_update_done();
+      // handle max_NN_dist update for all jets that might have
+      // seen a change (increase) of distance
+      Tile2 & tile_I = _tiles[jetI->tile_index];
+      if (tile_I.max_NN_dist < jetI->NN_dist) tile_I.max_NN_dist = jetI->NN_dist;
+    }
+    n--;
+  }
+
+  // final cleaning up;
+  delete[] briefjets;
+#ifdef INSTRUMENT2
+  cout << "ncall, dtt = " << _ncall << " " << _ncall_dtt << endl; // GPS tmp
+#endif // INSTRUMENT2
+
+}
+
+FASTJET_END_NAMESPACE
Index: external/fastjet/LazyTiling9Alt.cc
===================================================================
--- external/fastjet/LazyTiling9Alt.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/LazyTiling9Alt.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,724 @@
+//FJSTARTHEADER
+// $Id: LazyTiling9Alt.cc 3477 2014-07-29 14:34:39Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//
+//----------------------------------------------------------------------
+// This file is part of FastJet.
+//
+//  FastJet 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.
+//
+//  The algorithms that underlie FastJet have required considerable
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
+//  FastJet as part of work towards a scientific publication, please
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
+//
+//  FastJet 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 FastJet. If not, see <http://www.gnu.org/licenses/>.
+//----------------------------------------------------------------------
+//FJENDHEADER
+
+#include <iomanip>
+#include "fastjet/internal/LazyTiling9Alt.hh"
+#include "fastjet/internal/TilingExtent.hh"
+using namespace std;
+
+FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
+
+LazyTiling9Alt::LazyTiling9Alt(ClusterSequence & cs) :
+  _cs(cs), _jets(cs.jets())
+  //, _minheap(_jets.size()) 
+{
+  _Rparam = cs.jet_def().R();
+  _R2 = _Rparam * _Rparam;
+  _invR2 = 1.0 / _R2;
+  _initialise_tiles();
+}
+
+
+//----------------------------------------------------------------------
+/// Set up the tiles:
+///  - decide the range in eta
+///  - allocate the tiles
+///  - set up the cross-referencing info between tiles
+///
+/// The neighbourhood of a tile is set up as follows
+///
+/// 	      LRR
+///           LXR
+///           LLR
+///
+/// such that tiles is an array containing XLLLLRRRR with pointers
+///                                         |   \ RH_tiles
+///                                         \ surrounding_tiles
+///
+/// with appropriate precautions when close to the edge of the tiled
+/// region.
+///
+void LazyTiling9Alt::_initialise_tiles() {
+
+  // first decide tile sizes (with a lower bound to avoid huge memory use with
+  // very small R)
+  double default_size = max(0.1,_Rparam);
+  _tile_size_eta = default_size;
+  // it makes no sense to go below 3 tiles in phi -- 3 tiles is
+  // sufficient to make sure all pair-wise combinations up to pi in
+  // phi are possible
+  _n_tiles_phi   = max(3,int(floor(twopi/default_size)));
+  _tile_size_phi = twopi / _n_tiles_phi; // >= _Rparam and fits in 2pi
+
+  // always include zero rapidity in the tiling region
+  _tiles_eta_min = 0.0;
+  _tiles_eta_max = 0.0;
+  // but go no further than following
+  const double maxrap = 7.0;
+
+  // and find out how much further one should go
+  for(unsigned int i = 0; i < _jets.size(); i++) {
+    double eta = _jets[i].rap();
+    // first check if eta is in range -- to avoid taking into account
+    // very spurious rapidities due to particles with near-zero kt.
+    if (abs(eta) < maxrap) {
+      if (eta < _tiles_eta_min) {_tiles_eta_min = eta;}
+      if (eta > _tiles_eta_max) {_tiles_eta_max = eta;}
+    }
+  }
+
+  // now adjust the values
+  _tiles_ieta_min = int(floor(_tiles_eta_min/_tile_size_eta));
+  _tiles_ieta_max = int(floor( _tiles_eta_max/_tile_size_eta));
+  _tiles_eta_min = _tiles_ieta_min * _tile_size_eta;
+  _tiles_eta_max = _tiles_ieta_max * _tile_size_eta;
+
+  _tile_half_size_eta = _tile_size_eta * 0.5;
+  _tile_half_size_phi = _tile_size_phi * 0.5;
+
+  // set up information about whether we need to allow for "periodic" 
+  // wrapping tests in delta_phi calculations
+  vector<bool> use_periodic_delta_phi(_n_tiles_phi, false);
+  if (_n_tiles_phi <= 3) {
+    fill(use_periodic_delta_phi.begin(), use_periodic_delta_phi.end(), true);
+  } else {
+    use_periodic_delta_phi[0] = true;
+    use_periodic_delta_phi[_n_tiles_phi-1] = true;
+  }
+
+  // allocate the tiles
+  _tiles.resize((_tiles_ieta_max-_tiles_ieta_min+1)*_n_tiles_phi);
+
+  // now set up the cross-referencing between tiles
+  for (int ieta = _tiles_ieta_min; ieta <= _tiles_ieta_max; ieta++) {
+    for (int iphi = 0; iphi < _n_tiles_phi; iphi++) {
+      Tile * tile = & _tiles[_tile_index(ieta,iphi)];
+      // no jets in this tile yet
+      tile->head = NULL; // first element of tiles points to itself
+      tile->begin_tiles[0] =  Tile::TileFnPair(tile,&Tile::distance_to_centre);
+      Tile::TileFnPair * pptile = & (tile->begin_tiles[0]);
+      pptile++;
+      //
+      // set up L's in column to the left of X
+      tile->surrounding_tiles = pptile;
+      if (ieta > _tiles_ieta_min) {
+	// with the itile subroutine, we can safely run tiles from
+	// idphi=-1 to idphi=+1, because it takes care of
+	// negative and positive boundaries
+	//for (int idphi = -1; idphi <=+1; idphi++) {
+        //  *pptile = & _tiles[_tile_index(ieta-1,iphi+idphi)];
+        //  pptile++;
+        //}	
+        *pptile = Tile::TileFnPair(& _tiles[_tile_index(ieta-1,iphi-1)],
+                                   &Tile::distance_to_left_bottom);
+        pptile++;
+        *pptile = Tile::TileFnPair(& _tiles[_tile_index(ieta-1,iphi)],
+                                   &Tile::distance_to_left);
+        pptile++;
+        *pptile = Tile::TileFnPair(& _tiles[_tile_index(ieta-1,iphi+1)],
+                                   &Tile::distance_to_left_top);
+        pptile++;
+      }
+      // now set up last L (below X)
+      *pptile = Tile::TileFnPair(& _tiles[_tile_index(ieta,iphi-1)], 
+                                 &Tile::distance_to_bottom);
+      pptile++;
+      // set up first R (above X)
+      tile->RH_tiles = pptile;
+      *pptile = Tile::TileFnPair(& _tiles[_tile_index(ieta,iphi+1)], 
+                                 &Tile::distance_to_top);
+      pptile++;
+      // set up remaining R's, to the right of X
+      if (ieta < _tiles_ieta_max) {
+	//for (int idphi = -1; idphi <= +1; idphi++) {
+	//  *pptile = & _tiles[_tile_index(ieta+1,iphi+idphi)];
+	//  pptile++;
+	//}	
+        *pptile = Tile::TileFnPair(& _tiles[_tile_index(ieta+1,iphi-1)],
+                                   &Tile::distance_to_right_bottom);
+        pptile++;
+        *pptile = Tile::TileFnPair(& _tiles[_tile_index(ieta+1,iphi)],
+                                   &Tile::distance_to_right);
+        pptile++;
+        *pptile = Tile::TileFnPair(& _tiles[_tile_index(ieta+1,iphi+1)],
+                                   &Tile::distance_to_right_top);
+        pptile++;
+      }
+      // now put semaphore for end tile
+      tile->end_tiles = pptile;
+      // finally make sure tiles are untagged
+      tile->tagged = false;
+      // and store the information about periodicity in phi
+      tile->use_periodic_delta_phi = use_periodic_delta_phi[iphi];
+      // and ensure max distance is sensibly initialised
+      tile->max_NN_dist = 0;
+      // and also position of centre of tile
+      tile->eta_min = ieta*_tile_size_eta;
+      tile->eta_max = (ieta+1)*_tile_size_eta;
+      tile->phi_min = iphi*_tile_size_phi;
+      tile->phi_max = (iphi+1)*_tile_size_phi;
+    }
+  }
+
+}
+
+//----------------------------------------------------------------------
+/// return the tile index corresponding to the given eta,phi point
+int LazyTiling9Alt::_tile_index(const double eta, const double phi) const {
+  int ieta, iphi;
+  if      (eta <= _tiles_eta_min) {ieta = 0;}
+  else if (eta >= _tiles_eta_max) {ieta = _tiles_ieta_max-_tiles_ieta_min;}
+  else {
+    //ieta = int(floor((eta - _tiles_eta_min) / _tile_size_eta));
+    ieta = int(((eta - _tiles_eta_min) / _tile_size_eta));
+    // following needed in case of rare but nasty rounding errors
+    if (ieta > _tiles_ieta_max-_tiles_ieta_min) {
+      ieta = _tiles_ieta_max-_tiles_ieta_min;} 
+  }
+  // allow for some extent of being beyond range in calculation of phi
+  // as well
+  //iphi = (int(floor(phi/_tile_size_phi)) + _n_tiles_phi) % _n_tiles_phi;
+  // with just int and no floor, things run faster but beware
+  iphi = int((phi+twopi)/_tile_size_phi) % _n_tiles_phi;
+  return (iphi + ieta * _n_tiles_phi);
+}
+
+
+//----------------------------------------------------------------------
+// sets up information regarding the tiling of the given jet
+inline void LazyTiling9Alt::_tj_set_jetinfo( TiledJet * const jet,
+					      const int _jets_index) {
+  // first call the generic setup
+  _bj_set_jetinfo<>(jet, _jets_index);
+
+  // Then do the setup specific to the tiled case.
+
+  // Find out which tile it belonds to
+  jet->tile_index = _tile_index(jet->eta, jet->phi);
+
+  // Insert it into the tile's linked list of jets
+  Tile * tile = &_tiles[jet->tile_index];
+  jet->previous   = NULL;
+  jet->next       = tile->head;
+  if (jet->next != NULL) {jet->next->previous = jet;}
+  tile->head      = jet;
+}
+
+
+//----------------------------------------------------------------------
+void LazyTiling9Alt::_bj_remove_from_tiles(TiledJet * const jet) {
+  Tile * tile = & _tiles[jet->tile_index];
+
+  if (jet->previous == NULL) {
+    // we are at head of the tile, so reset it.
+    // If this was the only jet on the tile then tile->head will now be NULL
+    tile->head = jet->next;
+  } else {
+    // adjust link from previous jet in this tile
+    jet->previous->next = jet->next;
+  }
+  if (jet->next != NULL) {
+    // adjust backwards-link from next jet in this tile
+    jet->next->previous = jet->previous;
+  }
+}
+
+
+//----------------------------------------------------------------------
+/// output the contents of the tiles
+void LazyTiling9Alt::_print_tiles(TiledJet * briefjets ) const {
+  for (vector<Tile>::const_iterator tile = _tiles.begin(); 
+       tile < _tiles.end(); tile++) {
+    cout << "Tile " << tile - _tiles.begin()<<" = ";
+    vector<int> list;
+    for (TiledJet * jetI = tile->head; jetI != NULL; jetI = jetI->next) {
+      list.push_back(jetI-briefjets);
+      //cout <<" "<<jetI-briefjets;
+    }
+    sort(list.begin(),list.end());
+    for (unsigned int i = 0; i < list.size(); i++) {cout <<" "<<list[i];}
+    cout <<"\n";
+  }
+}
+
+
+//----------------------------------------------------------------------
+/// Add to the vector tile_union the tiles that are in the neighbourhood
+/// of the specified tile_index, including itself -- start adding
+/// from position n_near_tiles-1, and increase n_near_tiles as
+/// you go along (could have done it more C++ like with vector with reserved
+/// space, but fear is that it would have been slower, e.g. checking
+/// for end of vector at each stage to decide whether to resize it)
+void LazyTiling9Alt::_add_neighbours_to_tile_union(const int tile_index, 
+	       vector<int> & tile_union, int & n_near_tiles) const {
+  for (Tile::TileFnPair const * near_tile = _tiles[tile_index].begin_tiles; 
+       near_tile != _tiles[tile_index].end_tiles; near_tile++){
+    // get the tile number
+    tile_union[n_near_tiles] = near_tile->first - & _tiles[0];
+    n_near_tiles++;
+  }
+}
+
+
+//----------------------------------------------------------------------
+/// Like _add_neighbours_to_tile_union, but only adds neighbours if 
+/// their "tagged" status is false; when a neighbour is added its
+/// tagged status is set to true.
+inline void LazyTiling9Alt::_add_untagged_neighbours_to_tile_union(
+               const int tile_index, 
+	       vector<int> & tile_union, int & n_near_tiles)  {
+  for (Tile::TileFnPair * near_tile = _tiles[tile_index].begin_tiles; 
+       near_tile != _tiles[tile_index].end_tiles; near_tile++){
+    if (! (near_tile->first)->tagged) {
+      (near_tile->first)->tagged = true;
+      // get the tile number
+      tile_union[n_near_tiles] = near_tile->first - & _tiles[0];
+      n_near_tiles++;
+    }
+  }
+}
+
+//----------------------------------------------------------------------
+/// Like _add_neighbours_to_tile_union, but adds tiles that are
+/// "neighbours" of a jet (rather than a tile) and only if a
+/// neighbouring tile's max_NN_dist is >= the distance between the jet
+/// and the nearest point on the tile. It ignores tiles that have
+/// already been tagged.
+inline void LazyTiling9Alt::_add_untagged_neighbours_to_tile_union_using_max_info(
+               const TiledJet * jet, 
+	       vector<int> & tile_union, int & n_near_tiles)  {
+  Tile & tile = _tiles[jet->tile_index];
+  
+  for (Tile::TileFnPair * near_tile = tile.begin_tiles; near_tile != tile.end_tiles; near_tile++){
+    if ((near_tile->first)->tagged) continue;
+    double dist = (tile.*(near_tile->second))(jet);
+    // cout << "      max info looked at tile " << *near_tile - &_tiles[0] 
+    // 	 << ", dist = " << dist << " " << (*near_tile)->max_NN_dist
+    // 	 << endl;
+    if (dist > (near_tile->first)->max_NN_dist) continue;
+
+    // cout << "      max info tagged tile " << *near_tile - &_tiles[0] << endl;
+    (near_tile->first)->tagged = true;
+    // get the tile number
+    tile_union[n_near_tiles] = near_tile->first - & _tiles[0];
+    n_near_tiles++;
+  }
+}
+
+//--------TMPTMPTMPTMPTMP-----GPS TEMP--------------------
+ostream & operator<<(ostream & ostr, const TiledJet & jet) {
+  ostr << "j" << setw(3) << jet._jets_index << ":pt2,rap,phi=" ; ostr.flush();
+  ostr     << jet.kt2 << ","; ostr.flush();
+  ostr     << jet.eta << ","; ostr.flush();
+  ostr     << jet.phi; ostr.flush();
+  ostr     << ", tile=" << jet.tile_index; ostr.flush();
+  return ostr;
+}
+
+
+// //----------------------------------------------------------------------
+// /// returns a particle's distance to the edge of the specified tile
+// inline double LazyTiling9Alt::_distance_to_tile(const TiledJet * bj, const Tile * tile) const {
+// 
+// //   // Note the careful way of checking the minimum potential deta:
+// //   // unlike the phi case below, we don't calculate the distance to the
+// //   // centre and subtract spacing/2. This is because of issue of
+// //   // boundary tiles, which can extend far beyond spacing/2 in eta. 
+// //   // Using the positions of tile centers should instead be safe.
+// //   double deta;
+// //   if (_tiles[bj->tile_index].eta_centre == tile->eta_centre) deta = 0;
+// //   //else   deta = std::abs(bj->eta - tile->eta_centre) - 0.5*_tile_size_eta;
+// //   else   deta = std::abs(bj->eta - tile->eta_centre) - _tile_half_size_eta;
+// //   // ------
+// //   //   |
+// //   // A | B
+// //   // ------
+// //   //   |
+// //   // C | D
+// //   // ------
+// // 
+// //   double dphi = std::abs(bj->phi - tile->phi_centre);
+// //   if (dphi > pi) dphi = twopi-dphi;
+// //   dphi -= _tile_half_size_phi;
+// //   //dphi -= 0.5*_tile_size_phi;
+// //   if (dphi < 0) dphi = 0;
+// // 
+// //   return dphi*dphi + deta*deta;
+// 
+//   return 0.0;
+// }
+
+
+
+
+//----------------------------------------------------------------------
+/// looks at distance between jetX and jetI and updates the NN
+/// information if relevant; also pushes identity of jetI onto
+/// the vector of jets for minheap, to signal that it will have
+/// to be handled later.
+///
+/// GPS TEMP GPS TMP: REMOVE THIS LATER: EVEN LABELLED AS INLINE, THE
+/// CALL ADDS A SUBSTANTIAL PENALTY...
+inline void LazyTiling9Alt::_update_jetX_jetI_NN(TiledJet * jetX, TiledJet * jetI, vector<TiledJet *> & jets_for_minheap) {
+  double dist = _bj_dist(jetI,jetX);
+  if (dist < jetI->NN_dist) {
+    if (jetI != jetX) {
+      jetI->NN_dist = dist;
+      jetI->NN = jetX;
+      // label jetI as needing heap action...
+      if (!jetI->minheap_update_needed()) {
+	jetI->label_minheap_update_needed();
+	jets_for_minheap.push_back(jetI);
+      }
+    }
+  }
+  if (dist < jetX->NN_dist) {
+    if (jetI != jetX) {
+      jetX->NN_dist = dist;
+      jetX->NN      = jetI;}
+  }
+}
+
+
+inline void LazyTiling9Alt::_set_NN(TiledJet * jetI, 
+                            vector<TiledJet *> & jets_for_minheap) {
+  jetI->NN_dist = _R2;
+  jetI->NN      = NULL;
+  // label jetI as needing heap action...
+  if (!jetI->minheap_update_needed()) {
+    jetI->label_minheap_update_needed();
+    jets_for_minheap.push_back(jetI);}
+  // now go over tiles that are neighbours of I (include own tile)
+  Tile * tile_ptr = &_tiles[jetI->tile_index];
+  //if (tile_ptr->is_near_zero_phi(_tile_half_size_phi)) {
+    for (Tile::TileFnPair * near_tile  = tile_ptr->begin_tiles; 
+         near_tile != tile_ptr->end_tiles; near_tile++) {
+      // for own tile, this will be zero automatically: should we be clever
+      // and skip the test? (With some doubling of code?)
+      if (jetI->NN_dist < (tile_ptr->*(near_tile->second))(jetI)) continue;
+      // and then over the contents of that tile
+      for (TiledJet * jetJ  = (near_tile->first)->head; 
+           jetJ != NULL; jetJ = jetJ->next) {
+        double dist = _bj_dist(jetI,jetJ);
+        if (dist < jetI->NN_dist && jetJ != jetI) {
+          jetI->NN_dist = dist; jetI->NN = jetJ;
+        }
+      }
+    }
+  // } else {
+  //   // second copy that exploits the fact that for this tile we needn't worry
+  //   // about periodicity
+  //   for (Tile::TileFnPair * near_tile  = tile_ptr->begin_tiles; 
+  //        near_tile != tile_ptr->end_tiles; near_tile++) {
+  //     // for own tile, this will be zero automatically: should we be clever
+  //     // and skip the test? (With some doubling of code?)
+  //     if (jetI->NN_dist < tile_ptr->(*(near_tile->second)(jetI))) continue;
+  //     // and then over the contents of that tile
+  //     for (TiledJet * jetJ  = (*near_tile)->head; 
+  //          jetJ != NULL; jetJ = jetJ->next) {
+  //       double dist = _bj_dist_not_periodic(jetI,jetJ);
+  //       if (dist < jetI->NN_dist && jetJ != jetI) {
+  //         jetI->NN_dist = dist; jetI->NN = jetJ;
+  //       }
+  //     }
+  //   }
+  // }
+}
+
+
+void LazyTiling9Alt::run() {
+
+  //_initialise_tiles();
+
+  int n = _jets.size();
+  TiledJet * briefjets = new TiledJet[n];
+  TiledJet * jetA = briefjets, * jetB;
+  TiledJet oldB;
+  
+
+  // will be used quite deep inside loops, but declare it here so that
+  // memory (de)allocation gets done only once
+  vector<int> tile_union(3*n_tile_neighbours);
+  
+  // initialise the basic jet info 
+  for (int i = 0; i< n; i++) {
+    _tj_set_jetinfo(jetA, i);
+    //cout << i<<": "<<jetA->tile_index<<"\n";
+    jetA++; // move on to next entry of briefjets
+  }
+  TiledJet * head = briefjets; // a nicer way of naming start
+
+  // set up the initial nearest neighbour information
+  vector<Tile>::iterator tile;
+  for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
+    // first do it on this tile
+    for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
+      for (jetB = tile->head; jetB != jetA; jetB = jetB->next) {
+	double dist = _bj_dist_not_periodic(jetA,jetB);
+	if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
+	if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
+      }
+    }
+    for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
+      if (jetA->NN_dist > tile->max_NN_dist) tile->max_NN_dist = jetA->NN_dist;
+    }
+  }
+  for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
+    if (tile->use_periodic_delta_phi) {
+      // then do it for RH tiles; 
+      for (Tile::TileFnPair * RTileFnPair = tile->RH_tiles; 
+           RTileFnPair != tile->end_tiles; RTileFnPair++) {
+        Tile *RTile = RTileFnPair->first;
+        for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
+          double dist_to_tile = ((*tile).*(RTileFnPair->second))(jetA);
+          // it only makes sense to do a tile if jetA is close enough to the Rtile
+          // either for a jet in the Rtile to be closer to jetA than it's current NN
+          // or if jetA could be closer to something in the Rtile than the largest
+          // NN distance within the RTile.
+          //
+          // GPS note: also tried approach where we perform only the
+          //           first test and run over all surrounding tiles
+          //           (not just RH ones). The test is passed less
+          //           frequently, but one is running over more tiles
+          //           and on balance, for the trial event we used, it's
+          //           a bit slower.
+          bool relevant_for_jetA  = dist_to_tile <= jetA->NN_dist;
+          bool relevant_for_RTile = dist_to_tile <= RTile->max_NN_dist;
+          if (relevant_for_jetA || relevant_for_RTile) {
+            for (jetB = RTile->head; jetB != NULL; jetB = jetB->next) {
+              double dist = _bj_dist(jetA,jetB);
+              if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
+              if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
+            }
+          } 
+        }
+      }
+    } else {
+      // this second version of the code uses the faster
+      // "not_periodic" version because it knows that the tile is
+      // sufficiently far from the edge.
+      for (Tile::TileFnPair* RTileFnPair = tile->RH_tiles;
+           RTileFnPair != tile->end_tiles; RTileFnPair++) {
+        Tile *RTile = RTileFnPair->first;
+        for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
+          double dist_to_tile = ((*tile).*(RTileFnPair->second))(jetA);
+          bool relevant_for_jetA  = dist_to_tile <= jetA->NN_dist;
+          bool relevant_for_RTile = dist_to_tile <= RTile->max_NN_dist;
+          if (relevant_for_jetA || relevant_for_RTile) {
+            for (jetB = RTile->head; jetB != NULL; jetB = jetB->next) {
+              double dist = _bj_dist_not_periodic(jetA,jetB);
+              if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
+              if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
+            }
+          } 
+        }
+      }
+    }
+    // no need to do it for LH tiles, since they are implicitly done
+    // when we set NN for both jetA and jetB on the RH tiles.
+  }
+  // Now update the max_NN_dist within each tile. Not strictly
+  // necessary, because existing max_NN_dist is an upper bound.  but
+  // costs little and may give some efficiency gain later.
+  for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
+    tile->max_NN_dist = 0;
+    for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
+      if (jetA->NN_dist > tile->max_NN_dist) tile->max_NN_dist = jetA->NN_dist;
+    }
+  }
+
+
+  vector<double> diJs(n);
+  for (int i = 0; i < n; i++) {
+    diJs[i] = _bj_diJ(&briefjets[i]);
+    briefjets[i].label_minheap_update_done();
+  }
+  MinHeap minheap(diJs);
+  // have a stack telling us which jets we'll have to update on the heap
+  vector<TiledJet *> jets_for_minheap;
+  jets_for_minheap.reserve(n); 
+
+  // now run the recombination loop
+  int history_location = n-1;
+  while (n > 0) {
+
+    double diJ_min = minheap.minval() *_invR2;
+    jetA = head + minheap.minloc();
+
+    // do the recombination between A and B
+    history_location++;
+    jetB = jetA->NN;
+
+    if (jetB != NULL) {
+      // jet-jet recombination
+      // If necessary relabel A & B to ensure jetB < jetA, that way if
+      // the larger of them == newtail then that ends up being jetA and 
+      // the new jet that is added as jetB is inserted in a position that
+      // has a future!
+      if (jetA < jetB) {std::swap(jetA,jetB);}
+
+      int nn; // new jet index
+      _cs.plugin_record_ij_recombination(jetA->_jets_index, jetB->_jets_index, diJ_min, nn);
+      
+      // what was jetB will now become the new jet
+      _bj_remove_from_tiles(jetA);
+      oldB = * jetB;  // take a copy because we will need it...
+      _bj_remove_from_tiles(jetB);
+      _tj_set_jetinfo(jetB, nn); // cause jetB to become _jets[nn]
+                                 // (also registers the jet in the tiling)
+    } else {
+      // jet-beam recombination
+      // get the hist_index
+      _cs.plugin_record_iB_recombination(jetA->_jets_index, diJ_min);
+      _bj_remove_from_tiles(jetA);
+    }
+
+    // remove the minheap entry for jetA
+    minheap.remove(jetA-head);
+
+    // first establish the set of tiles over which we are going to
+    // have to run searches for updated and new nearest-neighbours --
+    // basically a combination of vicinity of the tiles of the two old
+    // and one new jet.
+    int n_near_tiles = 0;
+    _add_untagged_neighbours_to_tile_union_using_max_info(jetA, 
+       					   tile_union, n_near_tiles);
+    if (jetB != NULL) {
+	_add_untagged_neighbours_to_tile_union_using_max_info(&oldB,
+							      tile_union,n_near_tiles);
+      jetB->label_minheap_update_needed();
+      jets_for_minheap.push_back(jetB);
+    }
+
+
+    // Initialise jetB's NN distance as well as updating it for 
+    // other particles.
+    // Run over all tiles in our union 
+
+    if (jetB != NULL) {
+      Tile & jetB_tile = _tiles[jetB->tile_index];
+      for (Tile::TileFnPair * near_tile_fn_pair  = jetB_tile.begin_tiles; 
+	           near_tile_fn_pair != jetB_tile.end_tiles; near_tile_fn_pair++) {
+        Tile * near_tile = near_tile_fn_pair->first;
+
+    	double dist_to_tile = (jetB_tile.*(near_tile_fn_pair->second))(jetB);
+        // use <= in next line so that on first tile, relevant_for_jetB is 
+        // set to true
+    	bool relevant_for_jetB  = dist_to_tile <= jetB->NN_dist;
+    	bool relevant_for_near_tile = dist_to_tile <= near_tile->max_NN_dist;
+        bool relevant = relevant_for_jetB || relevant_for_near_tile;
+        // this first option decides exactly what loop to do based on whether 
+        // the near tile was tagged. You'd think it's more efficient, but
+        // not necessarily...
+        if (relevant) {
+          if (near_tile->tagged) {
+            for (TiledJet * jetI = near_tile->head; jetI != NULL; jetI = jetI->next) {
+              if (jetI->NN == jetA || jetI->NN == jetB) _set_NN(jetI, jets_for_minheap);
+              _update_jetX_jetI_NN(jetB, jetI, jets_for_minheap);
+            }
+          near_tile->tagged = false;
+          } else {
+            for (TiledJet * jetI = near_tile->head; jetI != NULL; jetI = jetI->next) {
+              _update_jetX_jetI_NN(jetB, jetI, jets_for_minheap);
+            }
+          }
+        }
+
+        // this second option does everything independently of whether the near tile
+        // was tagged -- somehow you'd expect it to be slower, but it may actually be
+        // marginally faster.
+        // if (relevant_for_jetB || relevant_for_near_tile) {
+        //   for (TiledJet * jetI = (*near_tile)->head; jetI != NULL; jetI = jetI->next) {
+        // 
+        //     if (jetI->NN == jetA || (jetI->NN == jetB && jetB != NULL)) {
+        //       _set_NN(jetI, jets_for_minheap);
+        //     }
+        // 
+        //     _update_jetX_jetI_NN(jetB, jetI, jets_for_minheap);
+	//     // -- Keep this old inline code for later speed tests
+        //     // double dist = _bj_dist(jetI,jetB);
+        //     // if (dist < jetI->NN_dist) {
+        //     //   if (jetI != jetB) {
+        //     //     jetI->NN_dist = dist;
+        //     //     jetI->NN = jetB;
+        //     //     // label jetI as needing heap action...
+        //     //     if (!jetI->minheap_update_needed()) {
+        //     //       jetI->label_minheap_update_needed();
+        //     //       jets_for_minheap.push_back(jetI);
+        //     //     }
+        //     //   }
+        //     // }
+        //     // if (dist < jetB->NN_dist) {
+        //     //   if (jetI != jetB) {
+        //     //     jetB->NN_dist = dist;
+        //     //     jetB->NN      = jetI;}
+        //     // }
+        //   }
+        //   (*near_tile)->tagged = false;
+        // }
+      }
+    }
+
+    // now run over the tiles that were tagged earlier and that we haven't yet
+    // had a change to visit.
+    for (int itile = 0; itile < n_near_tiles; itile++) {
+      Tile * tile_ptr = &_tiles[tile_union[itile]];
+      if (!tile_ptr->tagged) continue; // because earlier loop may have undone the tag
+      tile_ptr->tagged = false;
+      // run over all jets in the current tile
+      for (TiledJet * jetI = tile_ptr->head; jetI != NULL; jetI = jetI->next) {
+        // see if jetI had jetA or jetB as a NN -- if so recalculate the NN
+        if (jetI->NN == jetA || (jetI->NN == jetB && jetB != NULL)) {
+          _set_NN(jetI, jets_for_minheap);
+        }
+      }
+    }
+
+    // deal with jets whose minheap entry needs updating
+    //if (verbose) cout << "  jets whose NN was modified: " << endl;
+    while (jets_for_minheap.size() > 0) {
+      TiledJet * jetI = jets_for_minheap.back(); 
+      jets_for_minheap.pop_back();
+      minheap.update(jetI-head, _bj_diJ(jetI));
+      jetI->label_minheap_update_done();
+      // handle max_NN_dist update for all jets that might have
+      // seen a change (increase) of distance
+      Tile & tile_I = _tiles[jetI->tile_index];
+      if (tile_I.max_NN_dist < jetI->NN_dist) tile_I.max_NN_dist = jetI->NN_dist;
+    }
+    n--;
+  }
+
+  // final cleaning up;
+  delete[] briefjets;
+}
+
+
+FASTJET_END_NAMESPACE
Index: external/fastjet/LazyTiling9SeparateGhosts.cc
===================================================================
--- external/fastjet/LazyTiling9SeparateGhosts.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/LazyTiling9SeparateGhosts.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,771 @@
+//FJSTARTHEADER
+// $Id: LazyTiling9SeparateGhosts.cc 3596 2014-08-12 15:27:19Z soyez $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//
+//----------------------------------------------------------------------
+// This file is part of FastJet.
+//
+//  FastJet 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.
+//
+//  The algorithms that underlie FastJet have required considerable
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
+//  FastJet as part of work towards a scientific publication, please
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
+//
+//  FastJet 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 FastJet. If not, see <http://www.gnu.org/licenses/>.
+//----------------------------------------------------------------------
+//FJENDHEADER
+
+#include "fastjet/internal/LazyTiling9SeparateGhosts.hh"
+#include "fastjet/internal/TilingExtent.hh"
+#include <iomanip>
+using namespace std;
+
+FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
+
+double LazyTiling9SeparateGhosts::ghost_pt2_threshold = 1e-100; 
+
+LazyTiling9SeparateGhosts::LazyTiling9SeparateGhosts(ClusterSequence & cs) :
+  _cs(cs), _jets(cs.jets())
+  //, _minheap(_jets.size()) 
+{
+  _Rparam = cs.jet_def().R();
+  _R2 = _Rparam * _Rparam;
+  _invR2 = 1.0 / _R2;
+  _initialise_tiles();
+}
+
+
+//----------------------------------------------------------------------
+/// Set up the tiles:
+///  - decide the range in eta
+///  - allocate the tiles
+///  - set up the cross-referencing info between tiles
+///
+/// The neighbourhood of a tile is set up as follows
+///
+/// 	      LRR
+///           LXR
+///           LLR
+///
+/// such that tiles is an array containing XLLLLRRRR with pointers
+///                                         |   \ RH_tiles
+///                                         \ surrounding_tiles
+///
+/// with appropriate precautions when close to the edge of the tiled
+/// region.
+///
+void LazyTiling9SeparateGhosts::_initialise_tiles() {
+
+  // first decide tile sizes (with a lower bound to avoid huge memory use with
+  // very small R)
+  double default_size = max(0.1,_Rparam);
+  _tile_size_eta = default_size;
+  // it makes no sense to go below 3 tiles in phi -- 3 tiles is
+  // sufficient to make sure all pair-wise combinations up to pi in
+  // phi are possible
+  _n_tiles_phi   = max(3,int(floor(twopi/default_size)));
+  _tile_size_phi = twopi / _n_tiles_phi; // >= _Rparam and fits in 2pi
+
+  // always include zero rapidity in the tiling region
+  _tiles_eta_min = 0.0;
+  _tiles_eta_max = 0.0;
+  // but go no further than following
+  const double maxrap = 7.0;
+
+  // and find out how much further one should go
+  for(unsigned int i = 0; i < _jets.size(); i++) {
+    double eta = _jets[i].rap();
+    // first check if eta is in range -- to avoid taking into account
+    // very spurious rapidities due to particles with near-zero kt.
+    if (abs(eta) < maxrap) {
+      if (eta < _tiles_eta_min) {_tiles_eta_min = eta;}
+      if (eta > _tiles_eta_max) {_tiles_eta_max = eta;}
+    }
+  }
+
+  // now adjust the values
+  _tiles_ieta_min = int(floor(_tiles_eta_min/_tile_size_eta));
+  _tiles_ieta_max = int(floor( _tiles_eta_max/_tile_size_eta));
+  _tiles_eta_min = _tiles_ieta_min * _tile_size_eta;
+  _tiles_eta_max = _tiles_ieta_max * _tile_size_eta;
+
+  _tile_half_size_eta = _tile_size_eta * 0.5;
+  _tile_half_size_phi = _tile_size_phi * 0.5;
+
+  // allocate the tiles
+  _tiles.resize((_tiles_ieta_max-_tiles_ieta_min+1)*_n_tiles_phi);
+
+  // now set up the cross-referencing between tiles
+  for (int ieta = _tiles_ieta_min; ieta <= _tiles_ieta_max; ieta++) {
+    for (int iphi = 0; iphi < _n_tiles_phi; iphi++) {
+      Tile3 * tile = & _tiles[_tile_index(ieta,iphi)];
+      // no jets in this tile yet
+      tile->head = NULL; // first element of tiles points to itself
+      tile->ghost_head = NULL; // first element of tiles points to itself
+      tile->begin_tiles[0] =  tile;
+      Tile3 ** pptile = & (tile->begin_tiles[0]);
+      pptile++;
+      //
+      // set up L's in column to the left of X
+      tile->surrounding_tiles = pptile;
+      if (ieta > _tiles_ieta_min) {
+	// with the itile subroutine, we can safely run tiles from
+	// idphi=-1 to idphi=+1, because it takes care of
+	// negative and positive boundaries
+	for (int idphi = -1; idphi <=+1; idphi++) {
+	  *pptile = & _tiles[_tile_index(ieta-1,iphi+idphi)];
+	  pptile++;
+	}	
+      }
+      // now set up last L (below X)
+      *pptile = & _tiles[_tile_index(ieta,iphi-1)];
+      pptile++;
+      // set up first R (above X)
+      tile->RH_tiles = pptile;
+      *pptile = & _tiles[_tile_index(ieta,iphi+1)];
+      pptile++;
+      // set up remaining R's, to the right of X
+      if (ieta < _tiles_ieta_max) {
+	for (int idphi = -1; idphi <= +1; idphi++) {
+	  *pptile = & _tiles[_tile_index(ieta+1,iphi+idphi)];
+	  pptile++;
+	}	
+      }
+      // now put semaphore for end tile
+      tile->end_tiles = pptile;
+      // finally make sure tiles are untagged
+      tile->tagged = false;
+      // and ensure max distance is sensibly initialised
+      tile->max_NN_dist = 0;
+      // and also position of centre of tile
+      tile->eta_centre = (ieta+0.5)*_tile_size_eta;
+      tile->phi_centre = (iphi+0.5)*_tile_size_phi;
+    }
+  }
+
+}
+
+//----------------------------------------------------------------------
+/// return the tile index corresponding to the given eta,phi point
+int LazyTiling9SeparateGhosts::_tile_index(const double eta, const double phi) const {
+  int ieta, iphi;
+  if      (eta <= _tiles_eta_min) {ieta = 0;}
+  else if (eta >= _tiles_eta_max) {ieta = _tiles_ieta_max-_tiles_ieta_min;}
+  else {
+    //ieta = int(floor((eta - _tiles_eta_min) / _tile_size_eta));
+    ieta = int(((eta - _tiles_eta_min) / _tile_size_eta));
+    // following needed in case of rare but nasty rounding errors
+    if (ieta > _tiles_ieta_max-_tiles_ieta_min) {
+      ieta = _tiles_ieta_max-_tiles_ieta_min;} 
+  }
+  // allow for some extent of being beyond range in calculation of phi
+  // as well
+  //iphi = (int(floor(phi/_tile_size_phi)) + _n_tiles_phi) % _n_tiles_phi;
+  // with just int and no floor, things run faster but beware
+  iphi = int((phi+twopi)/_tile_size_phi) % _n_tiles_phi;
+  return (iphi + ieta * _n_tiles_phi);
+}
+
+
+//----------------------------------------------------------------------
+// sets up information regarding the tiling of the given jet
+inline void LazyTiling9SeparateGhosts::_tj_set_jetinfo( TiledJet3 * const jet,
+				      const int _jets_index, bool is_ghost) {
+  // first call the generic setup
+  _bj_set_jetinfo<>(jet, _jets_index);
+
+  // Then do the setup specific to the tiled case.
+  jet->is_ghost = is_ghost;
+
+  // Find out which tile it belonds to
+  jet->tile_index = _tile_index(jet->eta, jet->phi);
+
+  // Insert it into the tile's linked list of jets
+  Tile3 * tile = &_tiles[jet->tile_index];
+  jet->previous   = NULL;
+  if (is_ghost) {
+    jet->next        = tile->ghost_head;
+    tile->ghost_head = jet;
+  } else {
+    jet->next        = tile->head;
+    tile->head       = jet;
+  }
+  if (jet->next != NULL) {jet->next->previous = jet;}
+}
+
+
+//----------------------------------------------------------------------
+void LazyTiling9SeparateGhosts::_bj_remove_from_tiles(TiledJet3 * const jet) {
+  Tile3 * tile = & _tiles[jet->tile_index];
+
+  if (jet->previous == NULL) {
+    // we are at head of the tile, so reset it.
+    // If this was the only jet on the tile then tile->head will now be NULL
+    if (jet->is_ghost) {
+      tile->ghost_head = jet->next;
+    } else {
+      tile->head = jet->next;
+    }
+  } else {
+    // adjust link from previous jet in this tile
+    jet->previous->next = jet->next;
+  }
+  if (jet->next != NULL) {
+    // adjust backwards-link from next jet in this tile
+    jet->next->previous = jet->previous;
+  }
+}
+
+
+//----------------------------------------------------------------------
+/// output the contents of the tiles
+void LazyTiling9SeparateGhosts::_print_tiles(TiledJet3 * briefjets ) const {
+  for (vector<Tile3>::const_iterator tile = _tiles.begin(); 
+       tile < _tiles.end(); tile++) {
+    cout << "Tile " << tile - _tiles.begin()<<" = ";
+    vector<int> list;
+    for (TiledJet3 * jetI = tile->head; jetI != NULL; jetI = jetI->next) {
+      list.push_back(jetI-briefjets);
+      //cout <<" "<<jetI-briefjets;
+    }
+    sort(list.begin(),list.end());
+    for (unsigned int i = 0; i < list.size(); i++) {cout <<" "<<list[i];}
+    cout <<"\n";
+  }
+}
+
+
+//----------------------------------------------------------------------
+/// Add to the vector tile_union the tiles that are in the neighbourhood
+/// of the specified tile_index, including itself -- start adding
+/// from position n_near_tiles-1, and increase n_near_tiles as
+/// you go along (could have done it more C++ like with vector with reserved
+/// space, but fear is that it would have been slower, e.g. checking
+/// for end of vector at each stage to decide whether to resize it)
+void LazyTiling9SeparateGhosts::_add_neighbours_to_tile_union(const int tile_index, 
+	       vector<int> & tile_union, int & n_near_tiles) const {
+  for (Tile3 * const * near_tile = _tiles[tile_index].begin_tiles; 
+       near_tile != _tiles[tile_index].end_tiles; near_tile++){
+    // get the tile number
+    tile_union[n_near_tiles] = *near_tile - & _tiles[0];
+    n_near_tiles++;
+  }
+}
+
+
+//----------------------------------------------------------------------
+/// Like _add_neighbours_to_tile_union, but only adds neighbours if 
+/// their "tagged" status is false; when a neighbour is added its
+/// tagged status is set to true.
+inline void LazyTiling9SeparateGhosts::_add_untagged_neighbours_to_tile_union(
+               const int tile_index, 
+	       vector<int> & tile_union, int & n_near_tiles)  {
+  for (Tile3 ** near_tile = _tiles[tile_index].begin_tiles; 
+       near_tile != _tiles[tile_index].end_tiles; near_tile++){
+    if (! (*near_tile)->tagged) {
+      (*near_tile)->tagged = true;
+      // get the tile number
+      tile_union[n_near_tiles] = *near_tile - & _tiles[0];
+      n_near_tiles++;
+    }
+  }
+}
+
+//----------------------------------------------------------------------
+/// Like _add_neighbours_to_tile_union, but adds tiles that are
+/// "neighbours" of a jet (rather than a tile) and only if a
+/// neighbouring tile's max_NN_dist is >= the distance between the jet
+/// and the nearest point on the tile. It ignores tiles that have
+/// already been tagged.
+inline void LazyTiling9SeparateGhosts::_add_untagged_neighbours_to_tile_union_using_max_info(
+               const TiledJet3 * jet, 
+	       vector<int> & tile_union, int & n_near_tiles)  {
+  Tile3 & tile = _tiles[jet->tile_index];
+  
+  for (Tile3 ** near_tile = tile.begin_tiles; near_tile != tile.end_tiles; near_tile++){
+    if ((*near_tile)->tagged) continue;
+    double dist = _distance_to_tile(jet, *near_tile);
+    // cout << "      max info looked at tile " << *near_tile - &_tiles[0] 
+    // 	 << ", dist = " << dist << " " << (*near_tile)->max_NN_dist
+    // 	 << endl;
+    if (dist > (*near_tile)->max_NN_dist) continue;
+
+    // cout << "      max info tagged tile " << *near_tile - &_tiles[0] << endl;
+    (*near_tile)->tagged = true;
+    // get the tile number
+    tile_union[n_near_tiles] = *near_tile - & _tiles[0];
+    n_near_tiles++;
+  }
+}
+
+////--------TMPTMPTMPTMPTMP-----GPS TEMP--------------------
+//ostream & operator<<(ostream & ostr, const TiledJet3 & jet) {
+//  ostr << "j" << setw(3) << jet._jets_index << ":pt2,rap,phi=" ; ostr.flush();
+//  ostr     << jet.kt2 << ","; ostr.flush();
+//  ostr     << jet.eta << ","; ostr.flush();
+//  ostr     << jet.phi; ostr.flush();
+//  ostr     << ", tile=" << jet.tile_index; ostr.flush();
+//  return ostr;
+//}
+
+
+//----------------------------------------------------------------------
+/// returns a particle's distance to the edge of the specified tile
+inline double LazyTiling9SeparateGhosts::_distance_to_tile(const TiledJet3 * bj, const Tile3 * tile) const {
+
+  // Note the careful way of checking the minimum potential deta:
+  // unlike the phi case below, we don't calculate the distance to the
+  // centre and subtract spacing/2. This is because of issue of
+  // boundary tiles, which can extend far beyond spacing/2 in eta. 
+  // Using the positions of tile centers should instead be safe.
+  double deta;
+  if (_tiles[bj->tile_index].eta_centre == tile->eta_centre) deta = 0;
+  //else   deta = std::abs(bj->eta - tile->eta_centre) - 0.5*_tile_size_eta;
+  else   deta = std::abs(bj->eta - tile->eta_centre) - _tile_half_size_eta;
+  // ------
+  //   |
+  // A | B
+  // ------
+  //   |
+  // C | D
+  // ------
+
+  double dphi = std::abs(bj->phi - tile->phi_centre);
+  if (dphi > pi) dphi = twopi-dphi;
+  dphi -= _tile_half_size_phi;
+  //dphi -= 0.5*_tile_size_phi;
+  if (dphi < 0) dphi = 0;
+
+  return dphi*dphi + deta*deta;
+}
+
+
+
+
+//----------------------------------------------------------------------
+/// looks at distance between jetX and jetI and updates the NN
+/// information if relevant; also pushes identity of jetI onto
+/// the vector of jets for minheap, to signal that it will have
+/// to be handled later.
+///
+inline void LazyTiling9SeparateGhosts::_update_jetX_jetI_NN(TiledJet3 * jetX, TiledJet3 * jetI, vector<TiledJet3 *> & jets_for_minheap) {
+  assert(! (jetX->is_ghost || jetI->is_ghost));
+  double dist = _bj_dist(jetI,jetX);
+  if (dist < jetI->NN_dist) {
+    if (jetI != jetX) {
+      jetI->NN_dist = dist;
+      jetI->NN = jetX;
+      // label jetI as needing heap action...
+      if (!jetI->minheap_update_needed()) {
+	jetI->label_minheap_update_needed();
+	jets_for_minheap.push_back(jetI);
+      }
+    }
+  }
+  if (dist < jetX->NN_dist) {
+    if (jetI != jetX) {
+      jetX->NN_dist = dist;
+      jetX->NN      = jetI;}
+  }
+}
+
+
+inline void LazyTiling9SeparateGhosts::_set_NN(TiledJet3 * jetI, 
+                              vector<TiledJet3 *> & jets_for_minheap) {
+  assert(! jetI->is_ghost);
+  jetI->NN_dist = _R2;
+  jetI->NN      = NULL;
+  // label jetI as needing heap action...
+  if (!jetI->minheap_update_needed()) {
+    jetI->label_minheap_update_needed();
+    jets_for_minheap.push_back(jetI);}
+  // now go over tiles that are neighbours of I (include own tile)
+  Tile3 * tile_ptr = &_tiles[jetI->tile_index];
+  //if (tile_ptr->is_near_zero_phi(_tile_size_phi)) {
+    for (Tile3 ** near_tile  = tile_ptr->begin_tiles; 
+         near_tile != tile_ptr->end_tiles; near_tile++) {
+      // for own tile, this will be zero automatically: should we be clever
+      // and skip the test? (With some doubling of code?)
+      if (jetI->NN_dist < _distance_to_tile(jetI, *near_tile)) continue;
+      // and then over the contents of that tile
+      for (TiledJet3 * jetJ  = (*near_tile)->head; jetJ != NULL; jetJ = jetJ->next) {
+        double dist = _bj_dist(jetI,jetJ);
+        if (dist < jetI->NN_dist && jetJ != jetI) {
+          jetI->NN_dist = dist; jetI->NN = jetJ;
+        }
+      }
+      // deal with the ghosts
+      for (TiledJet3 * jetJ  = (*near_tile)->ghost_head; jetJ != NULL; jetJ = jetJ->next) {
+        double dist = _bj_dist(jetI,jetJ);
+        if (dist < jetI->NN_dist) {
+          jetI->NN_dist = dist; jetI->NN = jetJ;
+        }
+      }
+    }
+  // } else {
+  //   // second copy that exploits the fact that for this tile we needn't worry
+  //   // about periodicity
+  //   for (Tile3 ** near_tile  = tile_ptr->begin_tiles; 
+  //        near_tile != tile_ptr->end_tiles; near_tile++) {
+  //     // for own tile, this will be zero automatically: should we be clever
+  //     // and skip the test? (With some doubling of code?)
+  //     if (jetI->NN_dist < _distance_to_tile(jetI, *near_tile)) continue;
+  //     // and then over the contents of that tile
+  //     for (TiledJet3 * jetJ  = (*near_tile)->head; 
+  //          jetJ != NULL; jetJ = jetJ->next) {
+  //       double dist = _bj_dist_not_periodic(jetI,jetJ);
+  //       if (dist < jetI->NN_dist && jetJ != jetI) {
+  //         jetI->NN_dist = dist; jetI->NN = jetJ;
+  //       }
+  //     }
+  //   }
+  // }
+}
+
+
+void LazyTiling9SeparateGhosts::run() {
+
+  //_initialise_tiles();
+
+  int ntot = _jets.size();
+  if (ntot == 0) return;
+
+  TiledJet3 * briefjets = new TiledJet3[ntot];
+  TiledJet3 * jetA = briefjets, * jetB;
+  // avoid warning about uninitialised oldB below; 
+  // only valid for ntot>=1 (hence the test ntot==0 test above)
+  TiledJet3 oldB = briefjets[0];
+  
+
+  // will be used quite deep inside loops, but declare it here so that
+  // memory (de)allocation gets done only once
+  vector<int> tile_union(3*n_tile_neighbours);
+  
+  TiledJet3 * head = briefjets; // a nicer way of naming start
+
+  // initialise the basic jet info 
+  //
+  // Note that the threshold is a static member of the class
+  // first get the particles we'll keep as "real"
+  for (int i = 0; i< ntot; i++) {
+    bool is_ghost = _jets[i].perp2() < ghost_pt2_threshold; 
+    if (!is_ghost) {
+      _tj_set_jetinfo(jetA, i, is_ghost);
+      jetA++; // move on to next entry of briefjets
+    }
+  }
+  int nreal = jetA - briefjets;
+  // then the ones we will label as ghosts
+  for (int i = 0; i< ntot; i++) {
+    bool is_ghost = _jets[i].perp2() < ghost_pt2_threshold;
+    if (is_ghost) {
+      _tj_set_jetinfo(jetA, i, is_ghost);
+      jetA++; // move on to next entry of briefjets
+    }
+  }
+  
+
+  // set up the initial nearest neighbour information
+  vector<Tile3>::iterator tile;
+  for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
+    // first do it on this tile
+    for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
+      // real particles cluster with real particles
+      for (jetB = tile->head; jetB != jetA; jetB = jetB->next) {
+	double dist = _bj_dist_not_periodic(jetA,jetB);
+	if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
+	if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
+      }
+      // they can also cluster with ghosts
+      for (jetB = tile->ghost_head; jetB != NULL; jetB = jetB->next) {
+	double dist = _bj_dist_not_periodic(jetA,jetB);
+	if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
+      }
+    }
+    // only look out for NN dists of real particles, because ghosts never
+    // have NN in our structure
+    for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
+      if (jetA->NN_dist > tile->max_NN_dist) tile->max_NN_dist = jetA->NN_dist;
+    }
+  }
+  for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
+    //if (tile->is_near_zero_phi(_tile_size_phi)) {
+      // then do it for RH tiles; 
+      for (Tile3 ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
+        for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
+          double dist_to_tile = _distance_to_tile(jetA, *RTile);
+          // it only makes sense to do a tile if jetA is close enough to the Rtile
+          // either for a jet in the Rtile to be closer to jetA than it's current NN
+          // or if jetA could be closer to something in the Rtile than the largest
+          // NN distance within the RTile.
+          //
+          // GPS note: also tried approach where we perform only the
+          //           first test and run over all surrounding tiles
+          //           (not just RH ones). The test is passed less
+          //           frequently, but one is running over more tiles
+          //           and on balance, for the trial event we used, it's
+          //           a bit slower.
+          bool relevant_for_jetA  = dist_to_tile <= jetA->NN_dist;
+          bool relevant_for_RTile = dist_to_tile <= (*RTile)->max_NN_dist;
+          if (relevant_for_jetA || relevant_for_RTile) {
+            for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
+              double dist = _bj_dist(jetA,jetB);
+              if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
+              if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
+            }
+          } 
+	  // now do the check over ghosts
+          if (relevant_for_jetA) {
+            for (jetB = (*RTile)->ghost_head; jetB != NULL; jetB = jetB->next) {
+              double dist = _bj_dist(jetA,jetB);
+              if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
+            }
+	  }	  
+        }
+      }
+      // and do a special loop to catch ghosts that are among the LH tiles
+      for (Tile3 ** LTile = tile->surrounding_tiles; LTile != tile->RH_tiles; LTile++) {
+        for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
+          double dist_to_tile = _distance_to_tile(jetA, *LTile);
+          // it only makes sense to do a tile if jetA is close enough to the Rtile
+          // for a (ghost) jet in the Ltile to be closer to jetA than it's current NN.
+          bool relevant_for_jetA  = dist_to_tile <= jetA->NN_dist;
+          if (relevant_for_jetA) {
+            for (jetB = (*LTile)->ghost_head; jetB != NULL; jetB = jetB->next) {
+              double dist = _bj_dist(jetA,jetB);
+              if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
+            }
+          } 
+        }
+      }
+    // } else {
+    //   // this second version of the code uses the faster
+    //   // "not_periodic" version because it knows that the tile is
+    //   // sufficiently far from the edge.
+    //   for (Tile3 ** RTile = tile->RH_tiles; RTile != tile->end_tiles; RTile++) {
+    //     for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
+    //       double dist_to_tile = _distance_to_tile(jetA, *RTile);
+    //       bool relevant_for_jetA  = dist_to_tile <= jetA->NN_dist;
+    //       bool relevant_for_RTile = dist_to_tile <= (*RTile)->max_NN_dist;
+    //       if (relevant_for_jetA || relevant_for_RTile) {
+    //         for (jetB = (*RTile)->head; jetB != NULL; jetB = jetB->next) {
+    //           double dist = _bj_dist_not_periodic(jetA,jetB);
+    //           if (dist < jetA->NN_dist) {jetA->NN_dist = dist; jetA->NN = jetB;}
+    //           if (dist < jetB->NN_dist) {jetB->NN_dist = dist; jetB->NN = jetA;}
+    //         }
+    //       } 
+    //     }
+    //   }
+    // }
+    // no need to do it for LH tiles, since they are implicitly done
+    // when we set NN for both jetA and jetB on the RH tiles.
+  }
+  // Now update the max_NN_dist within each tile. Not strictly
+  // necessary, because existing max_NN_dist is an upper bound.  but
+  // costs little and may give some efficiency gain later.
+  // (Do it only for real particles -- ghosts don't come into the game).
+  for (tile = _tiles.begin(); tile != _tiles.end(); tile++) {
+    tile->max_NN_dist = 0;
+    for (jetA = tile->head; jetA != NULL; jetA = jetA->next) {
+      if (jetA->NN_dist > tile->max_NN_dist) tile->max_NN_dist = jetA->NN_dist;
+    }
+  }
+
+
+  vector<double> diJs(nreal);
+  for (int i = 0; i < nreal; i++) {
+    diJs[i] = _bj_diJ(&briefjets[i]);
+    briefjets[i].label_minheap_update_done();
+  }
+  MinHeap minheap(diJs);
+  // have a stack telling us which jets we'll have to update on the heap
+  vector<TiledJet3 *> jets_for_minheap;
+  jets_for_minheap.reserve(ntot);  // GPS TMP: return here
+
+  // now run the recombination loop
+  while (nreal > 0) {
+
+    double diJ_min = minheap.minval() *_invR2;
+    jetA = head + minheap.minloc();
+
+    // do the recombination between A and B
+    jetB = jetA->NN;
+
+    if (jetB != NULL) {
+      // jet-jet recombination
+      // If necessary relabel A & B to ensure jetB < jetA, that way if
+      // the larger of them == newtail then that ends up being jetA and 
+      // the new jet that is added as jetB is inserted in a position that
+      // has a future!
+      if (jetA < jetB) {std::swap(jetA,jetB);}
+
+      int nn; // new jet index
+      _cs.plugin_record_ij_recombination(jetA->_jets_index, jetB->_jets_index, diJ_min, nn);
+      
+      // what was jetB will now become the new jet
+      _bj_remove_from_tiles(jetA);
+      oldB = * jetB;  // take a copy because we will need it...
+      _bj_remove_from_tiles(jetB);
+      bool is_ghost = false;
+      _tj_set_jetinfo(jetB, nn, is_ghost); // cause jetB to become _jets[nn]
+                                 // (also registers the jet in the tiling); it will never be a ghost
+    } else {
+      // jet-beam recombination
+      // get the hist_index
+      _cs.plugin_record_iB_recombination(jetA->_jets_index, diJ_min);
+      _bj_remove_from_tiles(jetA);
+    }
+
+    // remove the minheap entry for jetA if jetA is a real particle;
+    // only in this case 
+    if (!jetA->is_ghost) {
+      minheap.remove(jetA-head);
+      // jetB cannot be a ghost; so when jetA is not a ghost we decrease
+      // our count of remaining real particles
+      nreal--;
+    }
+    
+
+    
+
+    // first establish the set of tiles over which we are going to
+    // have to run searches for updated and new nearest-neighbours --
+    // basically a combination of vicinity of the tiles of the two old
+    // and one new jet.
+    int n_near_tiles = 0;
+    // add tiles neighbouring A even if A is a ghost because a ghost
+    // could have been the NN of some other particle
+    _add_untagged_neighbours_to_tile_union_using_max_info(jetA, 
+       					   tile_union, n_near_tiles);
+    if (jetB != NULL) {
+	_add_untagged_neighbours_to_tile_union_using_max_info(&oldB,
+							      tile_union,n_near_tiles);
+      jetB->label_minheap_update_needed();
+      jets_for_minheap.push_back(jetB);
+    }
+
+
+    // Initialise jetB's NN distance as well as updating it for 
+    // other particles.
+    // Run over all tiles in our union 
+    if (jetB != NULL) {
+      Tile3 & jetB_tile = _tiles[jetB->tile_index];
+      for (Tile3 ** near_tile  = jetB_tile.begin_tiles; 
+	           near_tile != jetB_tile.end_tiles; near_tile++) {
+
+    	double dist_to_tile = _distance_to_tile(jetB, *near_tile);
+        // use <= in next line so that on first tile, relevant_for_jetB is 
+        // set to true
+    	bool relevant_for_jetB  = dist_to_tile <= jetB->NN_dist;
+    	bool relevant_for_near_tile = dist_to_tile <= (*near_tile)->max_NN_dist;
+        bool relevant = relevant_for_jetB || relevant_for_near_tile;
+        // this first option decides exactly what loop to do based on whether 
+        // the near tile was tagged. You'd think it's more efficient, but
+        // not necessarily...
+        if (relevant) {
+          if ((*near_tile)->tagged) {
+            for (TiledJet3 * jetI = (*near_tile)->head; jetI != NULL; jetI = jetI->next) {
+              if (jetI->NN == jetA || jetI->NN == jetB) _set_NN(jetI, jets_for_minheap);
+              _update_jetX_jetI_NN(jetB, jetI, jets_for_minheap);
+            }
+	    (*near_tile)->tagged = false;
+          } else {
+            for (TiledJet3 * jetI = (*near_tile)->head; jetI != NULL; jetI = jetI->next) {
+              _update_jetX_jetI_NN(jetB, jetI, jets_for_minheap);
+            }
+          }
+        }
+	// Now HANDLE GHOSTS
+	if (relevant_for_jetB) {
+	  for (TiledJet3 * jetI  = (*near_tile)->ghost_head; jetI != NULL; jetI = jetI->next) {
+	    double dist = _bj_dist(jetB,jetI);
+	    if (dist < jetB->NN_dist) {
+	      jetB->NN_dist = dist; jetB->NN = jetI;
+	    }
+	  }
+	}
+	
+
+        // this second option does everything independently of whether the near tile
+        // was tagged -- somehow you'd expect it to be slower, but it may actually be
+        // marginally faster.
+        // if (relevant_for_jetB || relevant_for_near_tile) {
+        //   for (TiledJet3 * jetI = (*near_tile)->head; jetI != NULL; jetI = jetI->next) {
+        // 
+        //     if (jetI->NN == jetA || (jetI->NN == jetB && jetB != NULL)) {
+        //       _set_NN(jetI, jets_for_minheap);
+        //     }
+        // 
+        //     _update_jetX_jetI_NN(jetB, jetI, jets_for_minheap);
+	//     // -- Keep this old inline code for later speed tests
+        //     // double dist = _bj_dist(jetI,jetB);
+        //     // if (dist < jetI->NN_dist) {
+        //     //   if (jetI != jetB) {
+        //     //     jetI->NN_dist = dist;
+        //     //     jetI->NN = jetB;
+        //     //     // label jetI as needing heap action...
+        //     //     if (!jetI->minheap_update_needed()) {
+        //     //       jetI->label_minheap_update_needed();
+        //     //       jets_for_minheap.push_back(jetI);
+        //     //     }
+        //     //   }
+        //     // }
+        //     // if (dist < jetB->NN_dist) {
+        //     //   if (jetI != jetB) {
+        //     //     jetB->NN_dist = dist;
+        //     //     jetB->NN      = jetI;}
+        //     // }
+        //   }
+        //   (*near_tile)->tagged = false;
+        // }
+      }
+    }
+
+    // now run over the tiles that were tagged earlier and that we haven't yet
+    // had a change to visit.
+    for (int itile = 0; itile < n_near_tiles; itile++) {
+      Tile3 * tile_ptr = &_tiles[tile_union[itile]];
+      if (!tile_ptr->tagged) continue; // because earlier loop may have undone the tag
+      tile_ptr->tagged = false;
+      // run over all jets in the current tile
+      for (TiledJet3 * jetI = tile_ptr->head; jetI != NULL; jetI = jetI->next) {
+        // see if jetI had jetA or jetB as a NN -- if so recalculate the NN
+        if (jetI->NN == jetA || (jetI->NN == jetB && jetB != NULL)) {
+          _set_NN(jetI, jets_for_minheap);
+        }
+      }
+    }
+
+    // deal with jets whose minheap entry needs updating
+    //if (verbose) cout << "  jets whose NN was modified: " << endl;
+    while (jets_for_minheap.size() > 0) {
+      TiledJet3 * jetI = jets_for_minheap.back(); 
+      jets_for_minheap.pop_back();
+      minheap.update(jetI-head, _bj_diJ(jetI));
+      jetI->label_minheap_update_done();
+      // handle max_NN_dist update for all jets that might have
+      // seen a change (increase) of distance
+      Tile3 & tile_I = _tiles[jetI->tile_index];
+      if (tile_I.max_NN_dist < jetI->NN_dist) tile_I.max_NN_dist = jetI->NN_dist;
+    }
+  }
+
+  // final cleaning up;
+  delete[] briefjets;
+}
+
+
+FASTJET_END_NAMESPACE
Index: external/fastjet/LimitedWarning.cc
===================================================================
--- external/fastjet/LimitedWarning.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/LimitedWarning.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: LimitedWarning.cc 3619 2014-08-13 14:17:19Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/LimitedWarning.hh"
@@ -40,10 +42,10 @@
 
 
-/// output a warning to ostr
-void LimitedWarning::warn(const std::string & warning) {
-  warn(warning, _default_ostr);
-}
+// /// output a warning to ostr
+// void LimitedWarning::warn(const std::string & warning) {
+//   warn(warning, _default_ostr);
+// }
 
-void LimitedWarning::warn(const std::string & warning, std::ostream * ostr) {
+void LimitedWarning::warn(const char * warning, std::ostream * ostr) {
   if (_this_warning_summary == 0) {
     // prepare the information for the summary
@@ -54,5 +56,5 @@
     // prepare the warning within a string stream
     ostringstream warnstr;
-    warnstr << "WARNING: ";
+    warnstr << "WARNING from FastJet: ";
     warnstr << warning;
     _n_warn_so_far++;
Index: external/fastjet/LimitedWarning.hh
===================================================================
--- external/fastjet/LimitedWarning.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/LimitedWarning.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,8 +2,8 @@
 #define __FASTJET_LIMITEDWARNING_HH__
 
-//STARTHEADER
-// $Id: LimitedWarning.hh 2577 2011-09-13 15:11:38Z salam $
+//FJSTARTHEADER
+// $Id: LimitedWarning.hh 3622 2014-08-13 14:45:45Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,5 +30,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
@@ -50,12 +52,19 @@
 
   /// constructor that provides a user-set max number of warnings
-  LimitedWarning(int max_warn) : _max_warn(max_warn), _n_warn_so_far(0), _this_warning_summary(0) {}
+  LimitedWarning(int max_warn_in) : _max_warn(max_warn_in), _n_warn_so_far(0), _this_warning_summary(0) {}
 
   /// outputs a warning to standard error (or the user's default
   /// warning stream if set)
-  void warn(const std::string & warning);
+  void warn(const char * warning) {warn(warning, _default_ostr);}
+
+  /// outputs a warning to standard error (or the user's default
+  /// warning stream if set)
+  void warn(const std::string & warning) {warn(warning.c_str(), _default_ostr);}
 
   /// outputs a warning to the specified stream
-  void warn(const std::string & warning, std::ostream * ostr);
+  void warn(const char * warning, std::ostream * ostr);
+
+  /// outputs a warning to the specified stream
+  void warn(const std::string & warning, std::ostream * ostr) {warn(warning.c_str(), ostr);}
 
   /// sets the default output stream for all warnings (by default
@@ -70,4 +79,12 @@
     _max_warn_default = max_warn;
   }
+
+  /// the maximum number of warning messages that will be printed
+  /// by this instance of the class
+  int max_warn() const {return _max_warn;}
+
+  /// the number of times so far that a warning has been registered
+  /// with this instance of the class.
+  int n_warn_so_far() const {return _n_warn_so_far;}
 
   /// returns a summary of all the warnings that came through the
Index: external/fastjet/MinHeap.cc
===================================================================
--- external/fastjet/MinHeap.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/MinHeap.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: MinHeap.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/internal/MinHeap.hh"
@@ -43,5 +45,5 @@
 ///
 ///   . for _heap[i], the "parent" is to be found at (i-1)/2
-void MinHeap::_initialise(const std::vector<double> & values){
+void MinHeap::initialise(const std::vector<double> & values){
   
   // fill the high-range of the heap with the largest possible value
Index: external/fastjet/NNH.hh
===================================================================
--- external/fastjet/NNH.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/NNH.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,8 +2,8 @@
 #define __FASTJET_NNH_HH__
 
-//STARTHEADER
-// $Id: NNH.hh 3203 2013-09-15 07:49:50Z salam $
-//
-// Copyright (c) 2009, Matteo Cacciari, Gavin Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: NNH.hh 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,5 +30,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include<fastjet/ClusterSequence.hh>
@@ -138,5 +140,5 @@
   class NNBJ; // forward declaration
   
-  /// establish the nearest neighbour for jet, and cross check constistency
+  /// establish the nearest neighbour for jet, and cross check consistency
   /// of distances for the other jets that are encountered. Assumes
   /// jet not contained within begin...end
Index: external/fastjet/PseudoJet.cc
===================================================================
--- external/fastjet/PseudoJet.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/PseudoJet.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: PseudoJet.cc 3565 2014-08-11 15:24:39Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
@@ -176,4 +178,8 @@
 // return the product, coeff * jet
 PseudoJet operator* (double coeff, const PseudoJet & jet) {
+  // see the comment in operator*= about ensuring valid rap phi
+  // before a multiplication to handle case of multiplication by
+  // zero, while maintaining rapidity and phi
+  jet._ensure_valid_rap_phi(); 
   //return PseudoJet(coeff*jet.four_mom());
   // the following code is hopefully more efficient
@@ -198,4 +204,12 @@
 /// multiply the jet's momentum by the coefficient
 void PseudoJet::operator*=(double coeff) {
+  // operator*= aims to maintain the rapidity and azimuth
+  // for the PseudoJet; if they have already been evaluated
+  // this is fine, but if they haven't and coeff is sufficiently
+  // small as to cause a zero or underflow result, then a subsequent
+  // invocation of rap or phi will lead to a non-sensical result. 
+  // So, here, we preemptively ensure that rapidity and phi
+  // are correctly cached
+  _ensure_valid_rap_phi(); 
   _px *= coeff;
   _py *= coeff;
@@ -261,6 +275,6 @@
 
 //----------------------------------------------------------------------
-/// transform this jet (given in lab) into a jet in the rest
-/// frame of prest
+/// transform this jet (given in the rest frame of prest) into a jet
+/// in the lab frame 
 //
 // NB: code adapted from that in herwig f77 (checked how it worked
@@ -288,6 +302,6 @@
 
 //----------------------------------------------------------------------
-/// transform this jet (given in the rest frame of prest) into a jet
-/// in the lab frame;
+/// transform this jet (given in lab) into a jet in the rest
+/// frame of prest  
 //
 // NB: code adapted from that in herwig f77 (checked how it worked
@@ -587,5 +601,5 @@
 // an Error is thrown if this PseudoJet has no currently valid
 // associated ClusterSequence
-std::vector<PseudoJet> PseudoJet::exclusive_subjets (const double & dcut) const {
+std::vector<PseudoJet> PseudoJet::exclusive_subjets (const double dcut) const {
   return validated_structure_ptr()->exclusive_subjets(*this, dcut);
 }
@@ -598,5 +612,5 @@
 // an Error is thrown if this PseudoJet has no currently valid
 // associated ClusterSequence
-int PseudoJet::n_exclusive_subjets(const double & dcut) const {
+int PseudoJet::n_exclusive_subjets(const double dcut) const {
   return validated_structure_ptr()->n_exclusive_subjets(*this, dcut);
 }
Index: external/fastjet/PseudoJet.hh
===================================================================
--- external/fastjet/PseudoJet.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/PseudoJet.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: PseudoJet.hh 3111 2013-05-04 08:17:27Z salam $
+//FJSTARTHEADER
+// $Id: PseudoJet.hh 3566 2014-08-11 15:36:34Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
@@ -571,5 +573,5 @@
   /// structure type
   ///
-  /// If there is no sructure associated, an Error is thrown.
+  /// If there is no structure associated, an Error is thrown.
   /// If the type is not met, a std::bad_cast error is thrown.
   template<typename StructureType>
@@ -664,5 +666,5 @@
   /// an Error is thrown if this PseudoJet has no currently valid
   /// associated ClusterSequence
-  std::vector<PseudoJet> exclusive_subjets (const double & dcut) const;
+  std::vector<PseudoJet> exclusive_subjets (const double dcut) const;
 
   /// return the size of exclusive_subjets(...); still n ln n with same
@@ -672,5 +674,5 @@
   /// an Error is thrown if this PseudoJet has no currently valid
   /// associated ClusterSequence
-  int n_exclusive_subjets(const double & dcut) const;
+  int n_exclusive_subjets(const double dcut) const;
 
   /// return the list of subjets obtained by unclustering the supplied
@@ -694,6 +696,8 @@
   std::vector<PseudoJet> exclusive_subjets_up_to (int nsub) const;
 
-  /// return the dij that was present in the merging nsub+1 -> nsub 
+  /// Returns the dij that was present in the merging nsub+1 -> nsub 
   /// subjets inside this jet.
+  ///
+  /// Returns 0 if there were nsub or fewer constituents in the jet.
   ///
   /// an Error is thrown if this PseudoJet has no currently valid
@@ -701,7 +705,9 @@
   double exclusive_subdmerge(int nsub) const;
 
-  /// return the maximum dij that occurred in the whole event at the
+  /// Returns the maximum dij that occurred in the whole event at the
   /// stage that the nsub+1 -> nsub merge of subjets occurred inside 
   /// this jet.
+  ///
+  /// Returns 0 if there were nsub or fewer constituents in the jet.
   ///
   /// an Error is thrown if this PseudoJet has no currently valid
@@ -802,4 +808,7 @@
   /// set cached rapidity and phi values
   void _set_rap_phi() const;
+
+  // needed for operator* to have access to _ensure_valid_rap_phi()
+  friend PseudoJet operator*(double, const PseudoJet &);
 };
 
@@ -825,8 +834,10 @@
 /// momentum components are equal to val (=0.0)
 bool operator==(const PseudoJet & jet, const double val);
+inline bool operator==(const double val, const PseudoJet & jet) {return jet == val;}
 
 /// Can only be used with val=0 and tests whether at least one of the
 /// four momentum components is different from val (=0.0)
-inline bool operator!=(const PseudoJet & a, const double & val) {return !(a==val);}
+inline bool operator!=(const PseudoJet & a, const double val)  {return !(a==val);}
+inline bool operator!=( const double val, const PseudoJet & a) {return !(a==val);}
 
 inline double dot_product(const PseudoJet & a, const PseudoJet & b) {
@@ -881,5 +892,5 @@
     _ref_values = reference_values;
   };
-  inline int operator() (const int & i1, const int & i2) const {
+  inline int operator() (const int i1, const int i2) const {
     return  (*_ref_values)[i1] < (*_ref_values)[i2];
   };
Index: external/fastjet/PseudoJetStructureBase.cc
===================================================================
--- external/fastjet/PseudoJetStructureBase.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/PseudoJetStructureBase.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: PseudoJetStructureBase.cc 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
Index: external/fastjet/PseudoJetStructureBase.hh
===================================================================
--- external/fastjet/PseudoJetStructureBase.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/PseudoJetStructureBase.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,8 +2,8 @@
 #define __FASTJET_PSEUDOJET_STRUCTURE_BASE_HH__
 
-//STARTHEADER
-// $Id: PseudoJetStructureBase.hh 3071 2013-04-01 12:52:46Z cacciari $
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: PseudoJetStructureBase.hh 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,5 +30,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
@@ -156,4 +158,9 @@
   ///
   /// By default, throws an Error
+  ///
+  /// Note: in a future major release of FastJet (4 or higher), 
+  /// "const double & dcut" may be replaced with "const double dcut",
+  /// requiring a modification of derived classes that overload
+  /// this function.
   virtual std::vector<PseudoJet> exclusive_subjets(const PseudoJet &reference, const double & dcut) const;
 
@@ -163,4 +170,9 @@
   ///
   /// By default, throws an Error
+  ///
+  /// Note: in a future major release of FastJet (4 or higher), 
+  /// "const double & dcut" may be replaced with "const double dcut",
+  /// requiring a modification of derived classes that overload
+  /// this function.
   virtual int n_exclusive_subjets(const PseudoJet &reference, const double & dcut) const;
 
Index: external/fastjet/RangeDefinition.cc
===================================================================
--- external/fastjet/RangeDefinition.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/RangeDefinition.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: RangeDefinition.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/RangeDefinition.hh"
Index: external/fastjet/RangeDefinition.hh
===================================================================
--- external/fastjet/RangeDefinition.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/RangeDefinition.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: RangeDefinition.hh 2577 2011-09-13 15:11:38Z salam $
+//FJSTARTHEADER
+// $Id: RangeDefinition.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __FASTJET_RANGEDEFINITION_HH__
Index: external/fastjet/RectangularGrid.cc
===================================================================
--- external/fastjet/RectangularGrid.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/RectangularGrid.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,135 @@
+//FJSTARTHEADER
+// $Id$
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//
+//----------------------------------------------------------------------
+// This file is part of FastJet.
+//
+//  FastJet 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.
+//
+//  The algorithms that underlie FastJet have required considerable
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
+//  FastJet as part of work towards a scientific publication, please
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
+//
+//  FastJet 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 FastJet. If not, see <http://www.gnu.org/licenses/>.
+//----------------------------------------------------------------------
+//FJENDHEADER
+
+
+
+#include "fastjet/RectangularGrid.hh"
+#include <sstream>
+using namespace std;
+
+FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
+
+  /// dummy ctor (will give an unusable grid)
+RectangularGrid::RectangularGrid()
+    : _ymax(-1.0), _ymin(1.0), _requested_drap(-1.0), _requested_dphi(-1.0) {
+  // put in nonsensical values for the other variables too, to keep coverity happy
+  _ntotal = -1;
+  _ngood  = -1;
+  _dy = 0.0;
+  _dphi = 0.0;
+  _cell_area = 0.0;
+  _inverse_dy = 0;
+  _inverse_dphi = 0;
+  _ny   = 0;
+  _nphi = 0;
+}
+
+
+int RectangularGrid::tile_index(const PseudoJet & p) const {
+  // the code below has seem some degree of optimization: don't change
+  // it without testing the speed again
+
+  // new version as of 2014-08-04
+  double y_minus_ymin = p.rap() - _ymin;
+  if (y_minus_ymin < 0) return -1;
+  int iy = int(y_minus_ymin * _inverse_dy); // guaranteed positive, so int is safe
+  if (iy >= _ny) return -1;
+
+  // old version: gives a SoftKiller that's about 10% slower on Gavin's retina mac.
+  // (though having it hard coded inside SoftKiller returns that advantage)
+  // BUT: some comments said that this was a factor of two faster than
+  //      something similar to the version above. What is going on?
+  // int iy = int(floor( (p.rap() - _ymin) * _inverse_dy ));
+  // if (iy < 0 || iy >= _ny) return -1;
+
+  int iphi = int( p.phi() * _inverse_dphi );
+  if (iphi == _nphi) iphi = 0; // just in case of rounding errors
+
+  return iy*_nphi + iphi;
+}
+
+
+//----------------------------------------------------------------------
+void RectangularGrid::_setup_grid() {
+  // initial sanity checks
+  assert(_ymax > _ymin);
+  assert(_requested_drap > 0);
+  assert(_requested_dphi > 0);
+
+  double ny_double = (_ymax-_ymin) / _requested_drap;
+  _ny = max(int(ny_double+0.5),1);
+  _dy = (_ymax-_ymin) / _ny;
+  _inverse_dy = _ny/(_ymax-_ymin);
+  
+  _nphi = int (twopi / _requested_dphi + 0.5);
+  _dphi = twopi / _nphi;
+  _inverse_dphi = _nphi/twopi;
+
+  // some sanity checking (could throw a fastjet::Error)
+  assert(_ny >= 1 && _nphi >= 1);
+
+  _ntotal = _nphi * _ny;
+  //_max_pt.resize(_ntotal);
+  _cell_area = _dy * _dphi;
+
+  // if we have a selector, establish which tiles are good;
+  // apply the selector to a 4-vector at the tile's centre
+  if (_tile_selector.worker()) {
+    _is_good.resize(n_tiles());
+    _ngood = 0;
+    for (int i = 0; i < n_tiles(); i++) {
+      int iphi = i % _nphi;
+      int irap = i / _nphi;
+      double phi = (iphi + 0.5)*_dphi;
+      double rap = (irap + 0.5)*_dy + _ymin;
+      _is_good[i] = _tile_selector.pass(PtYPhiM(1.0, rap, phi));
+      if (_is_good[i]) _ngood++;
+    }
+  } else {
+    _ngood = n_tiles();
+  }
+}
+
+//----------------------------------------------------------------------
+string RectangularGrid::description() const {
+  if (! is_initialised())
+    return "Uninitialised rectangular grid";
+
+  ostringstream oss;
+  oss << "rectangular grid with rapidity extent " << _ymin << " < rap < " << _ymax
+      << ", tile size drap x dphi = " << _dy << " x " << _dphi;
+
+  if (_tile_selector.worker()) {
+    oss << ", good tiles are those that pass selector " <<  _tile_selector.description();
+  }
+  return oss.str();
+}
+
+FASTJET_END_NAMESPACE      // defined in fastjet/internal/base.hh
Index: external/fastjet/RectangularGrid.hh
===================================================================
--- external/fastjet/RectangularGrid.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/RectangularGrid.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,172 @@
+#ifndef __FASTJET_RECTANGULARGRID_HH__
+#define __FASTJET_RECTANGULARGRID_HH__
+
+//FJSTARTHEADER
+// $Id$
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//
+//----------------------------------------------------------------------
+// This file is part of FastJet.
+//
+//  FastJet 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.
+//
+//  The algorithms that underlie FastJet have required considerable
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
+//  FastJet as part of work towards a scientific publication, please
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
+//
+//  FastJet 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 FastJet. If not, see <http://www.gnu.org/licenses/>.
+//----------------------------------------------------------------------
+//FJENDHEADER
+
+#include "fastjet/PseudoJet.hh"
+#include "fastjet/Selector.hh"
+
+FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
+
+
+//----------------------------------------------------------------------
+/// Class to indicate generic structure of tilings
+class TilingBase {
+public:
+  /// returns the index of the tile in which p is located, or -1 if p
+  /// is outside the tiling region
+  virtual int tile_index(const PseudoJet & p) const = 0;
+
+  /// returns the total number of tiles in the tiling; valid tile
+  /// indices run from 0 ... n_tiles()-1;
+  virtual int n_tiles() const = 0;
+
+  /// returns the number of tiles that are "good"; i.e. there is scope
+  /// for having tiles that, for whatever reason, should be ignored;
+  /// there are situations in which having "non-good" tiles may be the
+  /// simplest mechanism to obtain a tiling with holes in it
+  virtual int n_good_tiles() const {return n_tiles();}
+
+  /// returns whether a given tile is good
+  virtual bool tile_is_good(int /* itile */) const {return true;}
+
+  /// returns whether all tiles are good
+  virtual bool all_tiles_good() const {return n_good_tiles() == n_tiles();}
+
+  /// returns true if all tiles have the same area
+  virtual bool all_tiles_equal_area() const {return true;}
+
+  /// returns the area of tile itile. Here with a default
+  /// implementation to return mean_tile_area(), consistent with the
+  /// fact that all_tiles_equal_area() returns true.
+  virtual double tile_area(int /* itile */) const {return mean_tile_area();}
+
+  /// returns the mean area of the tiles.
+  virtual double mean_tile_area() const = 0;
+
+  /// returns a string to describe the tiling
+  virtual std::string description() const = 0;
+
+  /// returns true if the Tiling structure is in a suitably initialised state
+  virtual bool is_initialised() const = 0;
+  bool is_initialized() const {return is_initialised();}
+};
+
+//----------------------------------------------------------------------
+/// Class that holds a generic rectangular tiling
+class RectangularGrid : public TilingBase {
+public:
+  /// ctor with simple initialisation
+  ///  \param rapmax     the maximal absolute rapidity extent of the grid
+  ///  \param cell_size  the grid spacing (equivalently, cell size)
+  RectangularGrid(double rapmax, double cell_size) :
+      _ymax(rapmax), _ymin(-rapmax), 
+      _requested_drap(cell_size), _requested_dphi(cell_size) {
+    _setup_grid();
+  }
+
+  /// ctor with more control over initialisation
+  ///  \param rapmin         the minimum rapidity extent of the grid
+  ///  \param rapmax         the maximum rapidity extent of the grid
+  ///  \param drap           the grid spacing in rapidity
+  ///  \param dphi           the grid spacing in azimuth
+  ///  \param tile_selector  optional (geometric) selector to specify 
+  ///                        which tiles are good; a tile is good if
+  ///                        a massless 4-vector at the center of the tile passes
+  ///                        the selection
+  RectangularGrid(double rapmin, double rapmax, double drap, double dphi,
+                  Selector tile_selector = Selector()) 
+    : _ymax(rapmax), _ymin(rapmin), 
+      _requested_drap(drap), _requested_dphi(dphi),
+      _tile_selector(tile_selector)
+  {
+    _setup_grid();
+  }
+
+  /// dummy ctor (will give an unusable grid)
+  RectangularGrid();
+
+  virtual int n_tiles() const {return _ntotal;}
+
+  virtual int n_good_tiles() const {return _ngood;}
+
+  // this was being kept inline, but it seems to make little
+  // difference whether it is or not (at least on Gavin's mac)
+  virtual int tile_index(const PseudoJet & p) const;
+
+  /// returns whether a given tile is good
+  // tested in "issue" 2014-08-08-testing-rect-grid
+  virtual bool tile_is_good(int itile) const {return _tile_selector.worker() ? _is_good[itile] : true;}
+
+  /// returns the area of tile itile.
+  virtual double tile_area(int /* itile */) const {return mean_tile_area();}
+
+  /// returns the mean area of tiles.
+  virtual double mean_tile_area() const {return _dphi*_dy;};
+
+  /// returns a textual description of the grid
+  virtual std::string description() const;
+  
+  /// returns the minimum rapidity extent of the grid
+  double rapmin() const {return _ymin;}
+  /// returns the maxmium rapidity extent of the grid
+  double rapmax() const {return _ymax;}
+  /// returns the spacing of the grid in rapidity
+  double drap()   const {return _dy;}
+  /// returns the spacing of the grid in azimuth
+  double dphi()   const {return _dphi;}
+
+  /// returns true if the grid is in a suitably initialised state
+  virtual bool is_initialised() const {return _ntotal > 0;}
+
+private:
+  void _setup_grid();
+  
+  // information about the requested grid
+  double _ymax, _ymin;  ///< maximal and minimal rapidity coverage of the grid
+  double _requested_drap; ///< requested rapidity spacing
+  double _requested_dphi; ///< requested phi spacing
+
+  // information about the actual grid
+  double _dy, _dphi, _cell_area, _inverse_dy, _inverse_dphi;
+  int _ny, _nphi, _ntotal;
+  int _ngood;
+
+  // a tile selector
+  Selector _tile_selector;
+  // a cached 
+  std::vector<bool> _is_good;
+  
+};
+
+FASTJET_END_NAMESPACE        // defined in fastjet/internal/base.hh
+
+#endif // __FASTJET_RECTANGULARGRID_HH__
Index: external/fastjet/Selector.cc
===================================================================
--- external/fastjet/Selector.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/Selector.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: Selector.cc 3504 2014-08-01 06:07:54Z soyez $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
@@ -95,4 +97,54 @@
 }
 
+//----------------------------------------------------------------------
+// sum the momenta of the jets that pass the cuts
+PseudoJet Selector::sum(const std::vector<PseudoJet> & jets) const {
+  PseudoJet this_sum(0,0,0,0);
+  const SelectorWorker * worker_local = validated_worker();
+  
+  // separate strategies according to whether the worker applies jet by jet
+  if (worker_local->applies_jet_by_jet()) {
+    for (unsigned i = 0; i < jets.size(); i++) {
+      if (worker_local->pass(jets[i])) this_sum += jets[i];
+    }
+  } else {
+    std::vector<const PseudoJet *> jetptrs(jets.size());
+    for (unsigned i = 0; i < jets.size(); i++) {
+      jetptrs[i] = & jets[i];
+    }
+    worker_local->terminator(jetptrs);
+    for (unsigned i = 0; i < jetptrs.size(); i++) {
+      if (jetptrs[i]) this_sum += jets[i];
+    }
+  }
+
+  return this_sum;
+}
+
+//----------------------------------------------------------------------
+// sum the (scalar) pt of the jets that pass the cuts
+double Selector::scalar_pt_sum(const std::vector<PseudoJet> & jets) const {
+  double this_sum = 0.0;
+  const SelectorWorker * worker_local = validated_worker();
+  
+  // separate strategies according to whether the worker applies jet by jet
+  if (worker_local->applies_jet_by_jet()) {
+    for (unsigned i = 0; i < jets.size(); i++) {
+      if (worker_local->pass(jets[i])) this_sum += jets[i].pt();
+    }
+  } else {
+    std::vector<const PseudoJet *> jetptrs(jets.size());
+    for (unsigned i = 0; i < jets.size(); i++) {
+      jetptrs[i] = & jets[i];
+    }
+    worker_local->terminator(jetptrs);
+    for (unsigned i = 0; i < jetptrs.size(); i++) {
+      if (jetptrs[i]) this_sum += jets[i].pt();
+    }
+  }
+
+  return this_sum;
+}
+
 
 //----------------------------------------------------------------------
@@ -1055,5 +1107,5 @@
 class SW_Circle : public SW_WithReference {
 public:
-  SW_Circle(const double &radius) : _radius2(radius*radius) {}
+  SW_Circle(const double radius) : _radius2(radius*radius) {}
 
   /// return a copy of the current object
@@ -1100,5 +1152,5 @@
 
 // select on objets within a distance 'radius' of a variable location
-Selector SelectorCircle(const double & radius) {
+Selector SelectorCircle(const double radius) {
   return Selector(new SW_Circle(radius));
 }
@@ -1110,5 +1162,5 @@
 class SW_Doughnut : public SW_WithReference {
 public:
-  SW_Doughnut(const double &radius_in, const double &radius_out)
+  SW_Doughnut(const double radius_in, const double radius_out)
     : _radius_in2(radius_in*radius_in), _radius_out2(radius_out*radius_out) {}
 
@@ -1159,5 +1211,5 @@
 
 // select on objets with distance from the centre is between 'radius_in' and 'radius_out' 
-Selector SelectorDoughnut(const double & radius_in, const double & radius_out) {
+Selector SelectorDoughnut(const double radius_in, const double radius_out) {
   return Selector(new SW_Doughnut(radius_in, radius_out));
 }
@@ -1168,5 +1220,5 @@
 class SW_Strip : public SW_WithReference {
 public:
-  SW_Strip(const double &delta) : _delta(delta) {}
+  SW_Strip(const double delta) : _delta(delta) {}
 
   /// return a copy of the current object
@@ -1213,5 +1265,5 @@
 
 // select on objets within a distance 'radius' of a variable location
-Selector SelectorStrip(const double & half_width) {
+Selector SelectorStrip(const double half_width) {
   return Selector(new SW_Strip(half_width));
 }
@@ -1224,5 +1276,5 @@
 class SW_Rectangle : public SW_WithReference {
 public:
-  SW_Rectangle(const double &delta_rap, const double &delta_phi)
+  SW_Rectangle(const double delta_rap, const double delta_phi)
     : _delta_rap(delta_rap),  _delta_phi(delta_phi) {}
 
@@ -1270,5 +1322,5 @@
 
 // select on objets within a distance 'radius' of a variable location
-Selector SelectorRectangle(const double & half_rap_width, const double & half_phi_width) {
+Selector SelectorRectangle(const double half_rap_width, const double half_phi_width) {
   return Selector(new SW_Rectangle(half_rap_width, half_phi_width));
 }
Index: external/fastjet/Selector.hh
===================================================================
--- external/fastjet/Selector.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/Selector.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,8 +2,8 @@
 #define __FASTJET_SELECTOR_HH__
 
-//STARTHEADER
-// $Id: Selector.hh 3203 2013-09-15 07:49:50Z salam $
-//
-// Copyright (c) 2009-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: Selector.hh 3504 2014-08-01 06:07:54Z soyez $
+//
+// Copyright (c) 2009-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,5 +30,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/PseudoJet.hh"
@@ -67,12 +69,17 @@
   //----------------------------------------------------------
 
-  /// returns true if a given object passes the selection criterion.
-  /// This has to be overloaded by derived workers
+  /// returns true if a given object passes the selection criterion,
+  /// and is the main function that needs to be overloaded by derived
+  /// workers. 
+  ///
+  /// NB: this function is used only if applies_jet_by_jet() returns
+  /// true. If it does not, then derived classes are expected to
+  /// (re)implement the terminator function()
   virtual bool pass(const PseudoJet & jet) const = 0;
 
   /// For each jet that does not pass the cuts, this routine sets the 
-  /// pointer to 0. 
-  ///
-  /// It does not assume that the PseudoJet* passed as argumetn are not NULL
+  /// pointer to 0.
+  ///
+  /// It does not assume that the PseudoJet* passed as argument are not NULL
   virtual void terminator(std::vector<const PseudoJet *> & jets) const {
     for (unsigned i = 0; i < jets.size(); i++) {
@@ -133,4 +140,5 @@
     throw Error("this selector has no computable area");
   }
+
 };
 
@@ -151,5 +159,4 @@
   Selector(SelectorWorker * worker_in) {_worker.reset(worker_in);}
 
-
 #ifndef __FJCORE__
   /// ctor from a RangeDefinition
@@ -186,4 +193,16 @@
   /// passes and then evaluating the size of the vector
   unsigned int count(const std::vector<PseudoJet> & jets) const;
+
+  /// Return the 4-vector sum of the objects that pass the selection.
+  ///
+  /// This will often be more efficient that getting the vector of objects that
+  /// passes and then evaluating the size of the vector
+  PseudoJet sum(const std::vector<PseudoJet> & jets) const;
+
+  /// Return the scalar pt sum of the objects that pass the selection.
+  ///
+  /// This will often be more efficient that getting the vector of objects that
+  /// passes and then evaluating the size of the vector
+  double scalar_pt_sum(const std::vector<PseudoJet> & jets) const;
 
   /// sift the input jets into two vectors -- those that pass the selector
@@ -433,18 +452,18 @@
 /// select objets within a distance 'radius' from the location of the
 /// reference jet, set by Selector::set_reference(...)
-Selector SelectorCircle(const double & radius); 
+Selector SelectorCircle(const double radius); 
 
 /// select objets with distance from the reference jet is between 'radius_in'
 /// and 'radius_out'; the reference jet is set by Selector::set_reference(...)
-Selector SelectorDoughnut(const double & radius_in, const double & radius_out); 
+Selector SelectorDoughnut(const double radius_in, const double radius_out); 
 
 /// select objets within a rapidity distance 'half_width' from the
 /// location of the reference jet, set by Selector::set_reference(...)
-Selector SelectorStrip(const double & half_width);
+Selector SelectorStrip(const double half_width);
 
 /// select objets within rapidity distance 'half_rap_width' from the
 /// reference jet and azimuthal-angle distance within 'half_phi_width'; the
 /// reference jet is set by Selector::set_reference(...)
-Selector SelectorRectangle(const double & half_rap_width, const double & half_phi_width);
+Selector SelectorRectangle(const double half_rap_width, const double half_phi_width);
 
 
Index: external/fastjet/SharedPtr.hh
===================================================================
--- external/fastjet/SharedPtr.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/SharedPtr.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,8 +2,8 @@
 #define __FASTJET_SHARED_PTR_HH__
 
-//STARTHEADER
-// $Id: SharedPtr.hh 3129 2013-06-05 08:48:36Z salam $
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: SharedPtr.hh 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,5 +30,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/internal/base.hh"
Index: external/fastjet/TilingExtent.cc
===================================================================
--- external/fastjet/TilingExtent.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/TilingExtent.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,152 @@
+//FJSTARTHEADER
+// $Id: TilingExtent.cc 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//
+//----------------------------------------------------------------------
+// This file is part of FastJet.
+//
+//  FastJet 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.
+//
+//  The algorithms that underlie FastJet have required considerable
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
+//  FastJet as part of work towards a scientific publication, please
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
+//
+//  FastJet 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 FastJet. If not, see <http://www.gnu.org/licenses/>.
+//----------------------------------------------------------------------
+//FJENDHEADER
+
+#include <iomanip>
+#include <limits>
+#include <cmath>
+#include "fastjet/internal/TilingExtent.hh"
+using namespace std;
+
+
+FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
+
+TilingExtent::TilingExtent(ClusterSequence & cs) {
+  _determine_rapidity_extent(cs.jets());
+}
+  
+void TilingExtent::_determine_rapidity_extent(const vector<PseudoJet> & particles) {
+  // have a binning of rapidity that goes from -nrap to nrap
+  // in bins of size 1; the left and right-most bins include
+  // include overflows from smaller/larger rapidities
+  int nrap = 20; 
+  int nbins = 2*nrap;
+  vector<double> counts(nbins, 0);
+  
+  // get the minimum and maximum rapidities and at the same time bin
+  // the multiplicities as a function of rapidity to help decide how
+  // far out it's worth going
+  _minrap =  numeric_limits<double>::max();
+  _maxrap = -numeric_limits<double>::max();
+  int ibin;
+  for (unsigned i = 0; i < particles.size(); i++) {
+    // ignore particles with infinite rapidity
+    if (particles[i].E() == abs(particles[i].pz())) continue;
+    double rap = particles[i].rap();
+    if (rap < _minrap) _minrap = rap;
+    if (rap > _maxrap) _maxrap = rap;
+    // now bin the rapidity to decide how far to go with the tiling.
+    // Remember the bins go from ibin=0 (rap=-infinity..-19)
+    // to ibin = nbins-1 (rap=19..infinity for nrap=20)
+    ibin = int(rap+nrap); 
+    if (ibin < 0) ibin = 0;
+    if (ibin >= nbins) ibin = nbins - 1;
+    counts[ibin]++;
+  }
+
+  // now figure out the particle count in the busiest bin
+  double max_in_bin = 0;
+  for (ibin = 0; ibin < nbins; ibin++) {
+    if (max_in_bin < counts[ibin]) max_in_bin = counts[ibin];
+  }
+  
+  // and find _minrap, _maxrap such that edge bin never contains more
+  // than some fraction of busiest, and at least a few particles; first do
+  // it from left. NB: the thresholds chosen here are largely
+  // guesstimates as to what might work.
+  //
+  // 2014-07-17: in some tests at high multiplicity (100k) and particles going up to
+  //             about 7.3, anti-kt R=0.4, we found that 0.25 gave 20% better run times
+  //             than the original value of 0.5.
+  const double allowed_max_fraction = 0.25;
+  // the edge bins should also contain at least min_multiplicity particles
+  const double min_multiplicity = 4;
+  // now calculate how much we can accumulate into an edge bin
+  double allowed_max_cumul = floor(max(max_in_bin * allowed_max_fraction, min_multiplicity));
+  // make sure we don't require more particles in a bin than max_in_bin
+  if (allowed_max_cumul > max_in_bin) allowed_max_cumul = max_in_bin;
+
+  // start scan over rapidity bins from the left, to find out minimum rapidity of tiling
+  double cumul_lo = 0;
+  _cumul2 = 0;
+  for (ibin = 0; ibin < nbins; ibin++) {
+    cumul_lo += counts[ibin];
+    if (cumul_lo >= allowed_max_cumul) {
+      double y = ibin-nrap;
+      if (y > _minrap) _minrap = y;
+      break;
+    }
+  }
+  assert(ibin != nbins); // internal consistency check that you found a bin
+  _cumul2 += cumul_lo*cumul_lo;
+
+  // ibin_lo is the index of the leftmost bin that should be considered
+  int ibin_lo = ibin;
+
+  // then do it from right, to find out maximum rapidity of tiling
+  double cumul_hi = 0;
+  for (ibin = nbins-1; ibin >= 0; ibin--) {
+    cumul_hi += counts[ibin];
+    if (cumul_hi >= allowed_max_cumul) {
+      double y = ibin-nrap+1; // +1 here is the rapidity bin width
+      if (y < _maxrap) _maxrap = y;
+      break;
+    }
+  }
+  assert(ibin >= 0); // internal consistency check that you found a bin
+
+  // ibin_hi is the index of the rightmost bin that should be considered
+  int ibin_hi = ibin;
+
+  // consistency check 
+  assert(ibin_hi >= ibin_lo); 
+
+  // now work out cumul2
+  if (ibin_hi == ibin_lo) {
+    // if there is a single bin (potentially including overflows
+    // from both sides), cumul2 is the square of the total contents
+    // of that bin, which we obtain from cumul_lo and cumul_hi minus
+    // the double counting of part that is contained in both
+    // (putting double 
+    _cumul2 = pow(double(cumul_lo + cumul_hi - counts[ibin_hi]), 2);
+  } else {
+    // otherwise we have a straightforward sum of squares of bin
+    // contents
+    _cumul2 += cumul_hi*cumul_hi;
+
+    // now get the rest of the squared bin contents
+    for (ibin = ibin_lo+1; ibin < ibin_hi; ibin++) {
+      _cumul2 += counts[ibin]*counts[ibin];
+    }
+  }
+
+}
+
+
+FASTJET_END_NAMESPACE
Index: external/fastjet/VERSION
===================================================================
--- external/fastjet/VERSION	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/VERSION	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,1 +1,1 @@
-3.0.6
+3.1.0-beta.1
Index: external/fastjet/Voronoi.cc
===================================================================
--- external/fastjet/Voronoi.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/Voronoi.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,26 +1,31 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: Voronoi.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 1994 by AT&T Bell Laboratories (see below)
-//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
-// This file is included as part of FastJet but was mostly written by
-// S. Fortune in C, put into C++ with memory management by S
-// O'Sullivan, and with further interface and memory management
-// modifications by Gregory Soyez.
+// This file is part of FastJet.
 //
-// Permission to use, copy, modify, and distribute this software for
-// any purpose without fee is hereby granted, provided that this
-// entire notice is included in all copies of any software which is or
-// includes a copy or modification of this software and in all copies
-// of the supporting documentation for such software. THIS SOFTWARE IS
-// BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED WARRANTY.
-// IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY REPRESENTATION
-// OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS
-// SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+//  FastJet 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.
 //
+//  The algorithms that underlie FastJet have required considerable
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
+//  FastJet as part of work towards a scientific publication, please
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
+//
+//  FastJet 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 FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
Index: external/fastjet/WrappedStructure.hh
===================================================================
--- external/fastjet/WrappedStructure.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/WrappedStructure.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: WrappedStructure.hh 2577 2011-09-13 15:11:38Z salam $
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: WrappedStructure.hh 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
Index: external/fastjet/config_auto.h
===================================================================
--- external/fastjet/config_auto.h	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/config_auto.h	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -147,5 +147,5 @@
 /* Define to the full name and version of this package. */
 #ifndef FASTJET_PACKAGE_STRING 
-#define FASTJET_PACKAGE_STRING  "FastJet 3.0.6" 
+#define FASTJET_PACKAGE_STRING  "FastJet 3.1.0-beta.1" 
 #endif
 
@@ -157,5 +157,5 @@
 /* Define to the version of this package. */
 #ifndef FASTJET_PACKAGE_VERSION 
-#define FASTJET_PACKAGE_VERSION  "3.0.6" 
+#define FASTJET_PACKAGE_VERSION  "3.1.0-beta.1" 
 #endif
 
@@ -167,5 +167,30 @@
 /* Version number of package */
 #ifndef FASTJET_VERSION 
-#define FASTJET_VERSION  "3.0.6" 
+#define FASTJET_VERSION  "3.1.0-beta.1" 
+#endif
+
+/* Major version of this package */
+#ifndef FASTJET_VERSION_MAJOR 
+#define FASTJET_VERSION_MAJOR  3 
+#endif
+
+/* Minor version of this package */
+#ifndef FASTJET_VERSION_MINOR 
+#define FASTJET_VERSION_MINOR  1 
+#endif
+
+/* Version of the package under the form XYYZZ (instead of X.Y.Z) */
+#ifndef FASTJET_VERSION_NUMBER 
+#define FASTJET_VERSION_NUMBER  30103 
+#endif
+
+/* Patch version of this package */
+#ifndef FASTJET_VERSION_PATCHLEVEL 
+#define FASTJET_VERSION_PATCHLEVEL  3 
+#endif
+
+/* Pre-release version of this package */
+#ifndef FASTJET_VERSION_PRERELEASE 
+#define FASTJET_VERSION_PRERELEASE  ".1.0-beta.1" 
 #endif
  
Index: external/fastjet/config_raw.h
===================================================================
--- external/fastjet/config_raw.h	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/config_raw.h	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -88,5 +88,5 @@
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "FastJet 3.0.6"
+#define PACKAGE_STRING "FastJet 3.1.0-beta.1"
 
 /* Define to the one symbol short name of this package. */
@@ -94,5 +94,5 @@
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "3.0.6"
+#define PACKAGE_VERSION "3.1.0-beta.1"
 
 /* Define to 1 if you have the ANSI C header files. */
@@ -100,3 +100,18 @@
 
 /* Version number of package */
-#define VERSION "3.0.6"
+#define VERSION "3.1.0-beta.1"
+
+/* Major version of this package */
+#define VERSION_MAJOR 3
+
+/* Minor version of this package */
+#define VERSION_MINOR 1
+
+/* Version of the package under the form XYYZZ (instead of X.Y.Z) */
+#define VERSION_NUMBER 30103
+
+/* Patch version of this package */
+#define VERSION_PATCHLEVEL 3
+
+/* Pre-release version of this package */
+#define VERSION_PRERELEASE ".1.0-beta.1"
Index: external/fastjet/config_win.h
===================================================================
--- external/fastjet/config_win.h	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/config_win.h	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,4 +1,10 @@
-#define FASTJET_PACKAGE_STRING  "FastJet 3.0.6"
-#define FASTJET_PACKAGE_VERSION  "3.0.6"
+#define FASTJET_PACKAGE_STRING  "FastJet 3.1.0-beta.1"
+#define FASTJET_PACKAGE_VERSION  "3.1.0-beta.1"
+#define FASTJET_VERSION  "3.1.0-beta.1"
+#define FASTJET_VERSION_MAJOR       3
+#define FASTJET_VERSION_MINOR       1
+#define FASTJET_VERSION_PATCHLEVEL  3
+#define FASTJET_VERSION_PRERELEASE  ".1.0-beta.1"
+#define FASTJET_VERSION_NUMBER      30103
 
 /* The ATLASCone plugin is disabled by default*/
Index: external/fastjet/contribs/Nsubjettiness/AUTHORS
===================================================================
--- external/fastjet/contribs/Nsubjettiness/AUTHORS	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/contribs/Nsubjettiness/AUTHORS	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -18,3 +18,11 @@
    JHEP 1202:093 (2012), arXiv:1108.2701.
 
+New in v2.0 is the winner-take-all axis, described in:
+
+   Jet Shapes with the Broadening Axis. 
+   Andrew J. Larkoski, Duff Neill, and Jesse Thaler. 
+   JHEP 1404:017 (2014), arXiv:1401.2158.
+
+as well as in unpublished work by Gavin Salam.
+
 ----------------------------------------------------------------------
Index: external/fastjet/contribs/Nsubjettiness/AxesFinder.cc
===================================================================
--- external/fastjet/contribs/Nsubjettiness/AxesFinder.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/contribs/Nsubjettiness/AxesFinder.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -5,4 +5,5 @@
 //  Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason
 //
+//  $Id: AxesFinder.cc 670 2014-06-06 01:24:42Z jthaler $
 //----------------------------------------------------------------------
 // This file is part of FastJet contrib.
@@ -37,5 +38,5 @@
 template <int N>
 std::vector<LightLikeAxis> AxesFinderFromOnePassMinimization::UpdateAxesFast(const std::vector <LightLikeAxis> & old_axes, 
-                                  const std::vector <fastjet::PseudoJet> & inputJets) {
+                                  const std::vector <fastjet::PseudoJet> & inputJets) const {
    assert(old_axes.size() == N);
    
@@ -45,10 +46,5 @@
    for (int n = 0; n < N; ++n) {
       new_axes[n].reset(0.0,0.0,0.0,0.0);
-#ifdef FASTJET2
-      new_jets[n].reset(0.0,0.0,0.0,0.0);
-#else
-      // use cheaper reset if available
       new_jets[n].reset_momentum(0.0,0.0,0.0,0.0);
-#endif
    }
 
@@ -135,5 +131,5 @@
 // (This is just a wrapper for the templated version above.)
 std::vector<LightLikeAxis> AxesFinderFromOnePassMinimization::UpdateAxes(const std::vector <LightLikeAxis> & old_axes,
-                                      const std::vector <fastjet::PseudoJet> & inputJets) {
+                                      const std::vector <fastjet::PseudoJet> & inputJets) const {
    int N = old_axes.size();
    switch (N) {
@@ -166,5 +162,5 @@
 // uses minimization of N-jettiness to continually update axes until convergence.
 // The function returns the axes found at the (local) minimum
-std::vector<fastjet::PseudoJet> AxesFinderFromOnePassMinimization::getBetterAxes(int n_jets, const std::vector <fastjet::PseudoJet> & inputJets, const std::vector<fastjet::PseudoJet>& seedAxes) {
+std::vector<fastjet::PseudoJet> AxesFinderFromOnePassMinimization::getAxes(int n_jets, const std::vector <fastjet::PseudoJet> & inputJets, const std::vector<fastjet::PseudoJet>& seedAxes) const {
 	  
    // convert from PseudoJets to LightLikeAxes
@@ -211,5 +207,5 @@
 }
 
-PseudoJet AxesFinderFromKmeansMinimization::jiggle(const PseudoJet& axis) {
+PseudoJet AxesFinderFromKmeansMinimization::jiggle(const PseudoJet& axis) const {
    double phi_noise = ((double)rand()/(double)RAND_MAX) * _noise_range * 2.0 - _noise_range;
    double rap_noise = ((double)rand()/(double)RAND_MAX) * _noise_range * 2.0 - _noise_range;
@@ -226,5 +222,5 @@
    
 // Repeatedly calls the one pass finder to try to find global minimum
-std::vector<fastjet::PseudoJet> AxesFinderFromKmeansMinimization::getBetterAxes(int n_jets, const std::vector <fastjet::PseudoJet> & inputJets, const std::vector<fastjet::PseudoJet>& seedAxes) {
+std::vector<fastjet::PseudoJet> AxesFinderFromKmeansMinimization::getAxes(int n_jets, const std::vector <fastjet::PseudoJet> & inputJets, const std::vector<fastjet::PseudoJet>& seedAxes) const {
    
    // first iteration
@@ -256,8 +252,8 @@
 // It continually updates until it reaches convergence or it reaches the maximum number of attempts.
 // This is essentially the same as a stable cone finder.
-std::vector<fastjet::PseudoJet> AxesFinderFromGeometricMinimization::getBetterAxes(int n_jets, const std::vector <fastjet::PseudoJet> & particles, const std::vector<fastjet::PseudoJet>& currentAxes) {
+std::vector<fastjet::PseudoJet> AxesFinderFromGeometricMinimization::getAxes(int /*n_jets*/, const std::vector <fastjet::PseudoJet> & particles, const std::vector<fastjet::PseudoJet>& currentAxes) const {
 
    std::vector<fastjet::PseudoJet> seedAxes = currentAxes;
-   double seedTau = _function->tau(particles, seedAxes);
+   double seedTau = _function.tau(particles, seedAxes);
    
    for (int i = 0; i < _nAttempts; i++) {
@@ -270,9 +266,9 @@
          // start from unclustered beam measure
          int minJ = -1;
-         double minDist = _function->beam_distance_squared(particles[i]);
+         double minDist = _function.beam_distance_squared(particles[i]);
          
          // which axis am I closest to?
          for (unsigned int j = 0; j < seedAxes.size(); j++) {
-            double tempDist = _function->jet_distance_squared(particles[i],seedAxes[j]);
+            double tempDist = _function.jet_distance_squared(particles[i],seedAxes[j]);
             if (tempDist < minDist) {
                minDist = tempDist;
@@ -287,5 +283,5 @@
       // calculate tau on new axes
       seedAxes = newAxes;
-      double tempTau = _function->tau(particles, newAxes);
+      double tempTau = _function.tau(particles, newAxes);
       
       // close enough to stop?
Index: external/fastjet/contribs/Nsubjettiness/AxesFinder.hh
===================================================================
--- external/fastjet/contribs/Nsubjettiness/AxesFinder.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/contribs/Nsubjettiness/AxesFinder.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -5,4 +5,5 @@
 //  Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason
 //
+//  $Id: AxesFinder.hh 678 2014-06-12 20:43:03Z jthaler $
 //----------------------------------------------------------------------
 // This file is part of FastJet contrib.
@@ -53,36 +54,19 @@
 class AxesFinder {
    
-protected:
-   AxesFinder* _startingFinder; // storing a possible starting finder if needed
-   std::vector<fastjet::PseudoJet> _seedAxes;
-   
-   AxesFinder(AxesFinder* startingFinder = NULL) : _startingFinder(startingFinder) {}
-   
-public:
-   virtual ~AxesFinder(){
-      if (_startingFinder) delete _startingFinder;  //TODO: Convert to smart pointers to avoid this.
-   }
-   
-   // Allow setting of seedAxes from a starting finder
-   std::vector<fastjet::PseudoJet> getAxes(int n_jets, const std::vector<fastjet::PseudoJet> & inputs, const std::vector<fastjet::PseudoJet>& currentAxes) {
-      if (_startingFinder) {
-         _seedAxes = _startingFinder->getAxes(n_jets,inputs,currentAxes);
-         return getBetterAxes(n_jets,inputs,_seedAxes);
-      } else {
-         _seedAxes = getBetterAxes(n_jets,inputs,currentAxes);
-         return _seedAxes;
-      }
-   }
-   
-   // say what the current seed axes are
-   std::vector<fastjet::PseudoJet> seedAxes() const {
-      return _seedAxes;
-   }
-   
-   // This function should be overloaded, and updates the seedAxes
-   virtual std::vector<fastjet::PseudoJet> getBetterAxes(int n_jets, const std::vector<fastjet::PseudoJet> & inputs, const std::vector<fastjet::PseudoJet>& seedAxes) = 0;
-   
-};
-
+public:
+   
+   // This function should be overloaded, and updates the seedAxes to return new axes
+   virtual std::vector<fastjet::PseudoJet> getAxes(int n_jets,
+                                                   const std::vector<fastjet::PseudoJet>& inputs,
+                                                   const std::vector<fastjet::PseudoJet>& seedAxes) const = 0;
+   // convenient shorthand for squaring
+   static inline double sq(double x) {return x*x;}
+
+   //virtual destructor
+   virtual ~AxesFinder(){}
+   
+};
+
+   
 //------------------------------------------------------------------------
 /// \class AxesFinderFromExclusiveJetDefinition
@@ -90,15 +74,19 @@
 // with different jet algorithms.
 class AxesFinderFromExclusiveJetDefinition : public AxesFinder {
-
-   private:
-      fastjet::JetDefinition _def;
-   
-   public:
-      AxesFinderFromExclusiveJetDefinition(fastjet::JetDefinition def) : _def(def) {}
-      
-      virtual std::vector<fastjet::PseudoJet> getBetterAxes(int n_jets, const std::vector <fastjet::PseudoJet> & inputs, const std::vector<fastjet::PseudoJet>& currentAxes) {
-         fastjet::ClusterSequence jet_clust_seq(inputs, _def);
-         return jet_clust_seq.exclusive_jets(n_jets);
-      }
+   
+public:
+   AxesFinderFromExclusiveJetDefinition(fastjet::JetDefinition def)
+   : _def(def) {}
+   
+   virtual std::vector<fastjet::PseudoJet> getAxes(int n_jets,
+                                                   const std::vector <fastjet::PseudoJet> & inputs,
+                                                   const std::vector<fastjet::PseudoJet>& /*seedAxes*/) const {
+      fastjet::ClusterSequence jet_clust_seq(inputs, _def);
+      return jet_clust_seq.exclusive_jets(n_jets);
+   }
+   
+private:
+   fastjet::JetDefinition _def;
+
 };
 
@@ -108,14 +96,17 @@
 // winner take all recombination scheme.
 class AxesFinderFromWTA_KT : public AxesFinderFromExclusiveJetDefinition { 
-   private: 
-      const WinnerTakeAllRecombiner *recomb;
-   public:
-      AxesFinderFromWTA_KT() : AxesFinderFromExclusiveJetDefinition(
-         fastjet::JetDefinition(fastjet::kt_algorithm, 
-         fastjet::JetDefinition::max_allowable_R, //maximum jet radius constant
-         recomb = new WinnerTakeAllRecombiner(), 
-         fastjet::Best)) {}
-      ~AxesFinderFromWTA_KT() {delete recomb;}
-   };
+
+public:
+   AxesFinderFromWTA_KT()
+   : AxesFinderFromExclusiveJetDefinition(
+      fastjet::JetDefinition(fastjet::kt_algorithm,
+      fastjet::JetDefinition::max_allowable_R, //maximum jet radius constant
+      &_recomb,
+      fastjet::Best)) {}
+   
+private:
+   const WinnerTakeAllRecombiner _recomb;
+
+};
    
 //------------------------------------------------------------------------
@@ -124,48 +115,16 @@
 // winner take all recombination scheme.
 class AxesFinderFromWTA_CA : public AxesFinderFromExclusiveJetDefinition {
-   private: 
-      const WinnerTakeAllRecombiner *recomb;
-   public:
-      AxesFinderFromWTA_CA() : AxesFinderFromExclusiveJetDefinition(
-         fastjet::JetDefinition(fastjet::cambridge_algorithm, 
-         fastjet::JetDefinition::max_allowable_R, //maximum jet radius constant
-         recomb = new WinnerTakeAllRecombiner(), 
-         fastjet::Best)) {}
-      ~AxesFinderFromWTA_CA() {delete recomb;}
-};
-
-//  The following classes are for testing, and are commented out for initial release
-//
-////------------------------------------------------------------------------
-///// \class AxesFinderFromWTA2_KT
-//// This class finds axes by finding the exlusive jets after clustering according to a kT algorithm and a 
-//// winner take all recombination scheme with alpha = 2.
-//class AxesFinderFromWTA2_KT : public AxesFinderFromExclusiveJetDefinition { 
-//   private: 
-//      const WinnerTakeAllRecombiner *recomb;
-//   public:
-//      AxesFinderFromWTA2_KT() : AxesFinderFromExclusiveJetDefinition(
-//         fastjet::JetDefinition(fastjet::kt_algorithm, 
-//         fastjet::JetDefinition::max_allowable_R, //maximum jet radius constant
-//         recomb = new WinnerTakeAllRecombiner(2), // uses alpha = 2 here
-//         fastjet::Best)) {}
-//      ~AxesFinderFromWTA2_KT() {delete recomb;}
-//   };
-//   
-////------------------------------------------------------------------------
-///// \class AxesFinderFromWTA2_CA
-//// This class finds axes by finding the exlusive jets after clustering according to a CA algorithm and a 
-//// winner take all recombination scheme with alpha = 2.
-//class AxesFinderFromWTA2_CA : public AxesFinderFromExclusiveJetDefinition {
-//   private: 
-//      const WinnerTakeAllRecombiner *recomb;
-//   public:
-//      AxesFinderFromWTA2_CA() : AxesFinderFromExclusiveJetDefinition(
-//         fastjet::JetDefinition(fastjet::cambridge_algorithm, 
-//         fastjet::JetDefinition::max_allowable_R, //maximum jet radius constant
-//         recomb = new WinnerTakeAllRecombiner(2), //uses alpha = 2 here
-//         fastjet::Best)) {}
-//      ~AxesFinderFromWTA2_CA() {delete recomb;}
-//};
+public:
+   AxesFinderFromWTA_CA()
+   : AxesFinderFromExclusiveJetDefinition(
+      fastjet::JetDefinition(fastjet::cambridge_algorithm, 
+      fastjet::JetDefinition::max_allowable_R, //maximum jet radius constant
+      &_recomb,
+      fastjet::Best)) {}
+   
+private:
+   const WinnerTakeAllRecombiner _recomb;
+};
+
 
 //------------------------------------------------------------------------
@@ -174,10 +133,11 @@
 // E_scheme recombination.
 class AxesFinderFromKT : public AxesFinderFromExclusiveJetDefinition {
-   public:
-      AxesFinderFromKT() : AxesFinderFromExclusiveJetDefinition(
-         fastjet::JetDefinition(fastjet::kt_algorithm,
-         fastjet::JetDefinition::max_allowable_R, //maximum jet radius constant
-         fastjet::E_scheme,
-         fastjet::Best)) {}
+public:
+   AxesFinderFromKT()
+   : AxesFinderFromExclusiveJetDefinition(
+      fastjet::JetDefinition(fastjet::kt_algorithm,
+      fastjet::JetDefinition::max_allowable_R, //maximum jet radius constant
+      fastjet::E_scheme,
+      fastjet::Best)) {}
 };
 
@@ -187,10 +147,11 @@
 // E_scheme recombination.
 class AxesFinderFromCA : public AxesFinderFromExclusiveJetDefinition { 
-   public:
-      AxesFinderFromCA() : AxesFinderFromExclusiveJetDefinition(
-         fastjet::JetDefinition(fastjet::cambridge_algorithm,
-                                fastjet::JetDefinition::max_allowable_R,  //maximum jet radius constant
-         fastjet::E_scheme,
-         fastjet::Best)) {}
+public:
+   AxesFinderFromCA()
+   : AxesFinderFromExclusiveJetDefinition(
+      fastjet::JetDefinition(fastjet::cambridge_algorithm,
+                             fastjet::JetDefinition::max_allowable_R,  //maximum jet radius constant
+      fastjet::E_scheme,
+      fastjet::Best)) {}
 };
 
@@ -201,17 +162,19 @@
 // This can be implemented with different jet algorithms.
 class AxesFinderFromHardestJetDefinition : public AxesFinder {
-
-   private:
-      fastjet::JetDefinition _def;
-   
-   public:
-      AxesFinderFromHardestJetDefinition(fastjet::JetDefinition def) : _def(def) {}
-      
-      virtual std::vector<fastjet::PseudoJet> getBetterAxes(int n_jets, const std::vector <fastjet::PseudoJet> & inputs, const std::vector<fastjet::PseudoJet>& currentAxes) {
-         fastjet::ClusterSequence jet_clust_seq(inputs, _def);
-         std::vector<fastjet::PseudoJet> myJets = sorted_by_pt(jet_clust_seq.inclusive_jets());
-         myJets.resize(n_jets);  // only keep n hardest
-         return myJets;
-      }      
+public:
+   AxesFinderFromHardestJetDefinition(fastjet::JetDefinition def)
+   : _def(def) {}
+   
+   virtual std::vector<fastjet::PseudoJet> getAxes(int n_jets,
+                                                   const std::vector <fastjet::PseudoJet> & inputs,
+                                                   const std::vector<fastjet::PseudoJet>& /*seedAxes*/) const {
+      fastjet::ClusterSequence jet_clust_seq(inputs, _def);
+      std::vector<fastjet::PseudoJet> myJets = sorted_by_pt(jet_clust_seq.inclusive_jets());
+      myJets.resize(n_jets);  // only keep n hardest
+      return myJets;
+   }
+   
+private:
+   fastjet::JetDefinition _def;
 };
 
@@ -221,6 +184,9 @@
 // to an anti kT algorithm and E_scheme.
 class AxesFinderFromAntiKT : public AxesFinderFromHardestJetDefinition {
-   public:
-      AxesFinderFromAntiKT(double R0) : AxesFinderFromHardestJetDefinition(fastjet::JetDefinition(fastjet::antikt_algorithm,R0,fastjet::E_scheme,fastjet::Best)) {}
+public:
+   AxesFinderFromAntiKT(double R0)
+   : AxesFinderFromHardestJetDefinition(
+      fastjet::JetDefinition(fastjet::antikt_algorithm,
+                             R0,fastjet::E_scheme,fastjet::Best)) {}
 };
 
@@ -231,11 +197,12 @@
 class AxesFinderFromUserInput : public AxesFinder {
 
-   public:
-      AxesFinderFromUserInput() {}
-      
-      virtual std::vector<fastjet::PseudoJet> getBetterAxes(int n_jets, const std::vector <fastjet::PseudoJet> & inputs, const std::vector<fastjet::PseudoJet>& currentAxes) {
-         assert(currentAxes.size() == (unsigned int) n_jets);
-         return currentAxes;
-      }
+public:
+   AxesFinderFromUserInput() {}
+   
+   virtual std::vector<fastjet::PseudoJet> getAxes(int n_jets, const std::vector <fastjet::PseudoJet> & /*inputs*/, const std::vector<fastjet::PseudoJet>& currentAxes) const {
+      assert(currentAxes.size() == (unsigned int) n_jets);
+      (void)(n_jets);  // adding this line to fix unused-parameter warning
+      return currentAxes;
+   }
 };
 
@@ -249,32 +216,33 @@
 class AxesFinderFromOnePassMinimization : public AxesFinder {
 
-   private:
-      double _precision;  // Desired precision in axes alignment
-      int _halt;  // maximum number of steps per iteration
-      
-      double _beta;
-      double _Rcutoff;
-      
-      DefaultUnnormalizedMeasure _measureFunction;
-   
-   public:
-
-      // From a startingFinder, try to minimize the unnormalized_measure
-      AxesFinderFromOnePassMinimization(AxesFinder* startingFinder, double beta, double Rcutoff)
-         : AxesFinder(startingFinder),
-           _precision(0.0001), //hard coded for now
-           _halt(1000), //hard coded for now
-           _beta(beta),
-           _Rcutoff(Rcutoff),
-           _measureFunction(beta, Rcutoff)
-           {}
-   
-      virtual std::vector<fastjet::PseudoJet> getBetterAxes(int n_jets, const std::vector <fastjet::PseudoJet> & inputJets, const std::vector<fastjet::PseudoJet>& currentAxes);
-
-      template <int N> std::vector<LightLikeAxis> UpdateAxesFast(const std::vector <LightLikeAxis> & old_axes,
-                                  const std::vector <fastjet::PseudoJet> & inputJets);
-   
-      std::vector<LightLikeAxis> UpdateAxes(const std::vector <LightLikeAxis> & old_axes, 
-                                      const std::vector <fastjet::PseudoJet> & inputJets);
+public:
+
+   // From a startingFinder, try to minimize the unnormalized_measure
+   AxesFinderFromOnePassMinimization(double beta, double Rcutoff)
+      : _precision(0.0001), //hard coded for now
+        _halt(1000), //hard coded for now
+        _beta(beta),
+        _Rcutoff(Rcutoff),
+        _measureFunction(beta, Rcutoff)
+        {}
+
+   virtual std::vector<fastjet::PseudoJet> getAxes(int n_jets,
+                                                   const std::vector <fastjet::PseudoJet> & inputJets,
+                                                   const std::vector<fastjet::PseudoJet>& currentAxes) const;
+   
+private:
+   double _precision;  // Desired precision in axes alignment
+   int _halt;  // maximum number of steps per iteration
+   
+   double _beta;
+   double _Rcutoff;
+   
+   DefaultUnnormalizedMeasureFunction _measureFunction;
+   
+   template <int N> std::vector<LightLikeAxis> UpdateAxesFast(const std::vector <LightLikeAxis> & old_axes,
+                                                              const std::vector <fastjet::PseudoJet> & inputJets) const;
+   
+   std::vector<LightLikeAxis> UpdateAxes(const std::vector <LightLikeAxis> & old_axes,
+                                         const std::vector <fastjet::PseudoJet> & inputJets) const;
 
 };
@@ -288,25 +256,23 @@
 class AxesFinderFromKmeansMinimization : public AxesFinder{
 
-   private:
-      int _n_iterations;   // Number of iterations to run  (0 for no minimization, 1 for one-pass, >>1 for global minimum)
-      double _noise_range; // noise range for random initialization
-   
-      DefaultUnnormalizedMeasure _measureFunction; //function to test whether minimum is reached
-   
-      AxesFinderFromOnePassMinimization _onePassFinder;  //one pass finder for minimization
-
-      PseudoJet jiggle(const PseudoJet& axis);
-   
-   public:
-      AxesFinderFromKmeansMinimization(AxesFinder *startingFinder, double beta, double Rcutoff, int n_iterations) :
-         AxesFinder(startingFinder),
-         _n_iterations(n_iterations),
-         _noise_range(1.0), // hard coded for the time being
-         _measureFunction(beta, Rcutoff),
-         _onePassFinder(NULL, beta, Rcutoff)
-         {}
-
-      virtual std::vector<fastjet::PseudoJet> getBetterAxes(int n_jets, const std::vector <fastjet::PseudoJet> & inputJets, const std::vector<fastjet::PseudoJet>& currentAxes);
-
+public:
+   AxesFinderFromKmeansMinimization(double beta, double Rcutoff, int n_iterations)
+   :  _n_iterations(n_iterations),
+      _noise_range(1.0), // hard coded for the time being
+      _measureFunction(beta, Rcutoff),
+      _onePassFinder(beta, Rcutoff)
+      {}
+
+   virtual std::vector<fastjet::PseudoJet> getAxes(int n_jets, const std::vector <fastjet::PseudoJet> & inputJets, const std::vector<fastjet::PseudoJet>& currentAxes) const;
+   
+private:
+   int _n_iterations;   // Number of iterations to run  (0 for no minimization, 1 for one-pass, >>1 for global minimum)
+   double _noise_range; // noise range for random initialization
+   
+   DefaultUnnormalizedMeasureFunction _measureFunction; //function to test whether minimum is reached
+   
+   AxesFinderFromOnePassMinimization _onePassFinder;  //one pass finder that is repeatedly called
+   
+   PseudoJet jiggle(const PseudoJet& axis) const;
 };
 
@@ -317,28 +283,23 @@
 class AxesFinderFromGeometricMinimization : public AxesFinder {
 
-   private:
-      MeasureFunction* _function;
-      double _Rcutoff;
-      double _nAttempts;
-      double _accuracy;
-
-   
-   public:
-      AxesFinderFromGeometricMinimization(AxesFinder* startingFinder, double beta, double Rcutoff) : AxesFinder(startingFinder), _Rcutoff(Rcutoff) {
-         if (beta != 2.0) {
-            std::cerr << "Geometric minimization is currently only defined for beta = 2.0." << std::endl;
-            exit(1);
-         }
-         
-         _nAttempts = 100;
-         _accuracy = 0.000000001;
-         _function = new GeometricMeasure(beta,_Rcutoff);
+public:
+   AxesFinderFromGeometricMinimization(double beta, double Rcutoff)
+   :  _nAttempts(100),
+      _accuracy(0.000000001),
+      _function(beta,Rcutoff)
+   {
+      if (beta != 2.0) {
+         throw Error("Geometric minimization is currently only defined for beta = 2.0.");
       }
-
-      ~AxesFinderFromGeometricMinimization() {
-         delete _function;
-      }
-   
-      virtual std::vector<fastjet::PseudoJet> getBetterAxes(int n_jets, const std::vector <fastjet::PseudoJet> & particles, const std::vector<fastjet::PseudoJet>& currentAxes);
+   }
+
+   virtual std::vector<fastjet::PseudoJet> getAxes(int n_jets, const std::vector <fastjet::PseudoJet> & particles, const std::vector<fastjet::PseudoJet>& currentAxes) const;
+
+private:
+   double _nAttempts;
+   double _accuracy;
+   GeometricMeasureFunction _function;
+
+
 };
 
@@ -348,22 +309,5 @@
 // in order to better facilitate calculations.
 class LightLikeAxis {
-private:
-   double _rap, _phi, _weight, _mom;
-   
-   double DistanceSq(double rap2, double phi2) const {
-      double rap1 = _rap;
-      double phi1 = _phi;
-      
-      double distRap = rap1-rap2;
-      double distPhi = std::fabs(phi1-phi2);
-      if (distPhi > M_PI) {distPhi = 2.0*M_PI - distPhi;}
-      return sq(distRap) + sq(distPhi);
-   }
-   
-   double Distance(double rap2, double phi2) const {
-      return std::sqrt(DistanceSq(rap2,phi2));
-   }
-   
-   
+
 public:
    LightLikeAxis() : _rap(0.0), _phi(0.0), _weight(0.0), _mom(0.0) {}
@@ -399,4 +343,22 @@
    }
 
+private:
+   double _rap, _phi, _weight, _mom;
+   
+   double DistanceSq(double rap2, double phi2) const {
+      double rap1 = _rap;
+      double phi1 = _phi;
+      
+      double distRap = rap1-rap2;
+      double distPhi = std::fabs(phi1-phi2);
+      if (distPhi > M_PI) {distPhi = 2.0*M_PI - distPhi;}
+      return distRap*distRap + distPhi*distPhi;
+   }
+   
+   double Distance(double rap2, double phi2) const {
+      return std::sqrt(DistanceSq(rap2,phi2));
+   }
+   
+   
 };
 
Index: external/fastjet/contribs/Nsubjettiness/COPYING
===================================================================
--- external/fastjet/contribs/Nsubjettiness/COPYING	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/contribs/Nsubjettiness/COPYING	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,361 @@
+The Nsubjettiness contrib to FastJet is released 
+under the terms of the GNU General Public License v2 (GPLv2). 
+
+A copy of the GPLv2 is to be found at the end of this file.
+
+While the GPL license grants you considerable freedom, please bear in
+mind that this code's use falls under guidelines similar to those that
+are standard for Monte Carlo event generators
+(http://www.montecarlonet.org/GUIDELINES). In particular, if you use
+this code as part of work towards a scientific publication, whether
+directly or contained within another program you should include a citation 
+to
+
+  arXiv:1011.2268
+  arXiv:1108.2701
+
+
+
+======================================================================
+======================================================================
+======================================================================
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program 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.
+
+    This program 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 program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
Index: external/fastjet/contribs/Nsubjettiness/ChangeLog
===================================================================
--- external/fastjet/contribs/Nsubjettiness/ChangeLog	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/contribs/Nsubjettiness/ChangeLog	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,181 @@
+2014-07-09 <JDT>
+   Changed version for 2.1.0 release.
+   Updated NEWS to reflect 2.1.0 release
+2014-07-07 <JDT>
+   Added forward declaration of options in NjettinessDefinition for readability.
+   Updated README with some clarifications
+   Added usage information in the example file
+   Reran svn propset svn:keywords Id *.cc *.hh
+2014-06-25 <JDT>
+   Declaring release candidate of 2.1
+2014-06-11 <JDT>
+   Fixed virtual destructor issue in AxesFinder
+   Changing copy() to create() in NjettinessDefinition for "new" clarity
+   Converted some SharedPtr to regular pointers in NjettinessDefinition to be consistent on meaning of "create" commands.
+2014-06-10 <JDT>
+   Slight modification of example_advanced_usage
+   Fixed bug in GeometricCutoffMeasure (incorrect denominator setting)
+2014-06-05 <JDT>
+   Moved public before private in the .hh files for readability
+   Starting process of switching to SharedPtr internally
+   Clean up of AxesFinderFromGeometricMinimization
+   Simplified AxesFinder interface such that it doesn't know about starting axes finders (this is now handled in Njettiness).
+   Added const qualifiers in Njettiness
+2014-06-04 <JDT>
+   Implemented AxesDefinition class
+   Added descriptions to AxesDefinition and MeasureDefinition
+   Simplified example_advanced_usage with new Definitions
+   Made copy constructor private for Njettiness, to avoid copying 
+2014-06-03 <JDT>
+   Implemented remaining suggestions from FJ authors (Thanks!)
+   Fixed bug in example_advanced_usage where wrong beta value was used for NjettinessPlugin tests.
+   Removed NANs as signals for number of parameters in Nsubjettiness and NjettinessPlugin
+   Reduced the number of allowed parameters from 4 to 3.
+   Wrapped NEWS to 80 characters
+   Added MeasureDefinition as way to safely store information about the measures used
+   Converted a few NANs to std::numeric_limits<double>::quiet_NaN() when a parameter shouldn't be used.
+   Added AxesStruct and MeasureStruct to simplify the form of example_advanced_usage
+   Added example_v1p0p3 to check for backwards compatibility with v1.0.3
+   Changed the names of the MeasureFunctions in order to avoid conflicts with the new MeasureDefinitions
+   Fixed bug in correlation between subjets and tau values in NjettinessPlugin
+   Added currentTauComponents to Nsubjettiness
+   Added subTau information to example_basic_usage
+   Added file NjettinessDefinition to hold MeasureDefinition
+   Changed Njettiness constructors to treat MeasureSpecification as primary object
+   Fixed segmentation fault with ClusterSequenceAreas
+2014-06-02 <JDT>
+   Implemented many suggestions from FJ authors (Thanks!)
+   Removed FastJet 2 specific code
+   Made sq() function into internal namespace (as "inline static" to avoid conflicts with other packages)
+   Made setAxes() take const reference argument
+   Rewrapped README to 80 characters and updated/improved some of the descriptions
+   Clarified NEWS about what parts of the Nsubjettiness code is backwards compatible with v1.0.3
+   Clarified the para choices in Nsubjettiness constructor
+2014-04-30 <JDT>
+   Added (void)(n_jets) in AxesFinder.hh to fix unused-parameter warning
+2014-04-29 <JDT>
+   Added manual definition of NAN for compilers that don't have it.
+   Removed a few more unused parameters for compilation
+2014-04-22 <JDT>
+   Turned on -Wunused-parameter compiler flag to fix ATLAS compile issues.
+2014-04-18 <JDT>
+   Tweaks to NEWS and README.  Preparing for 2.0.0-rc1 release.
+2014-04-16 <JDT>
+   Decided that enough has changed that this should be v2.0
+   Added Id tags
+2014-04-14 <JDT>
+   Added get_partition_list to MeasureFunction
+   Removed do_cluster from MeasureFunction (no longer needed)
+   Fixed bug with NjettinessPlugin where jets were listed in backwards order from axes.
+   Removed various commented out pieces of code.
+2014-03-16 <JDT>
+   Added partitioning information to Nsubjettiness
+   Partitioning is now calculated in MeasureFunction and stored by Njettiness.
+   Rewrote MeasureFunction result() to call result_from_partition()
+   Added subjet (and constituent counting) information to example_basic_usage
+   Commented out redundant "getJets" function
+2014-02-25 <JDT>
+   Added access to seedAxes used for one-pass minimization routines.
+   Added axes print out to example_basic_usage, and fixed too many PrintJets declarations
+2014-02-24 <JDT>
+   Fixed embarrassing bug with min_axes (error introduced after v1.0 to make it the same as onepass_kt)
+   Simplified GeometricMeasure and added possibility of beta dependence
+   Commented out WTA2 options, since those have not been fully tested (nor do they seem particularly useful at the moment).  They can be reinstated if the physics case can be made to use them.
+   Split example into example_basic_usage and example_advanced_usage
+2014-01-28 <TJ>
+   Added new options in WinnerTakeAllRecombiner to use either pT or pT^2/E to recombine particles
+2014-01-24 <JDT>
+   Added access to currentAxes from Nsubjettiness.
+2014-01-18 <JDT>
+   Added beam regions to MeasureFunction, correspondingly renamed functions to have jet and beam regions
+   Renamed functions in TauComponents for consistency with MeasureFunction
+   Adding debugging code to AxesFinderFromOnePassMinimization::getAxes
+   Worked extensively on example.cc to make sure that it tests all available options.
+   Rewrote PrintJets command in example.cc for later improvements
+   Converted some magic numbers to std::numeric_limits<double>::max()
+2014-01-17 <JDT>
+   Rewrote KMeansMinimization to call OnePassMinimization, adding noise explicitly.
+   Removed any nothing of noise from OnePassMinimization
+   Removed Double32_t for root usage is Nsubjettiness
+   Clean up of many comments throughout the code, updating of README file
+   Removed unnecessary establishAxes in Njettiness
+   Removed bare constructor for Njettiness to avoid incompatibility with enum choices, may reinstate later.  Also removed setMeasureFunction, setAxesFinder for same reason
+   NjettinessExtras now calls TauComponents
+2014-01-16 <TJ>
+   Moved minimization functions to OnePassMinimization, changed KMeansMinimization class to simply call OnePassMinimization a specified number of times
+   Added extra tau function in TauComponents for users to get tau directly
+   Changed radius parameter in AxesFinderFromExclusiveJet subclasses to use max_allowable_R
+   Updated example.ref to account for changes due to change in radius parameter
+2014-01-15 <TJ>
+   Changed NjettinessComponents to TauComponents
+   Updated MeasureFunction with "result" function that returns TauComponents object
+   TauComponents changed to calculate all tau components given subtaus_numerator and tau_denominator
+   Njettiness updated to return TauComponents object rather than individual components
+   Nsubjettiness and NjettinessPlugin updated to have option for 4th parameter
+2014-01-14 <TJ>
+   Added NjettinessComponents class so Njettiness does not recalculate tau values
+   Removed old Njettiness constructors, updated Nsubjettiness and NjettinessPlugin constructors to use new constructor
+   Added geometric minimization to OnePassAxesFinders
+   Created new Njettiness function to set OnePassAxesFinders to reduce code
+   Updated LightLikeAxis with ConvertToPseudoJet function
+   Updated README with new functionality of code
+2014-01-12 <TJ>
+   Removed NsubGeometricParameters in all functions/constructors, replaced with Rcutoff double
+   Added three new measure mode options where Rcutoff is declared explicitly in parameters
+   Added checks so minimization axes finders are not used for geometric measures
+   AxesFinderFromOnePassMinimization class created as child of AxesFinderFromKmeansMinimization
+   Added new NsubjettinessRatio constructor to include MeasureMode option
+   Moved AxesFinder and MeasureFunction declarations from AxesMode and MeasureMode into separate Njettiness function
+   Removed R0 from AxesFinderFromKmeansMinimization
+   Changed example.cc to get rid of use of NsubGeometricParameters
+2014-01-9 <TJ>
+   Removed NsubParameters in all functions/constructors, replaced with three separate parameters
+   Added checks for correct number of parameters in Njettiness constructor
+2014-01-8 <TJ>
+   Removed normalization information from Nsubjettiness
+   Added flag to MeasureFunction to give option of using the denominator
+   Split DefaultMeasure into separate normalized and unnormalized classes
+2014-01-7 <TJ>
+   Added capability of choosing a specific Measure in Njettiness
+   Added new Nsubjettiness constructor to allow choice of both AxesMode and MeasureMode
+2014-01-6 <TJ>
+   Updated copyright information
+   Fixed bug in WinnerTakeAllRecombiner
+   Moved KMeansParameters to AxesFinder
+   Updated README with descriptions of new header files
+2013-12-30 <TJ>
+   Changed name of MeasureFunctor to MeasureFunction
+   Created separate .hh/.cc files for MeasureFunction, AxesFinder, and WinnerTakeAllRecombiner
+   Updated Makefile to account for new files
+   Removed getMinimumAxes in AxesFinderFromKMeansMinimization, consolidated with getAxes
+   Updated comments on classes and major functions
+2013-12-22 <TJ>
+   Created .cc files and moved all function definitions into .cc files
+   Updated Makefile to account for new .cc files
+2013-11-12 <TJ>
+   Added to fjcontrib svn
+2013-11-12 <jthaler>
+   Debugging svn
+2013-11-11 <TJ>
+   Changed MeasureFunctor to separately treat tau numerator and denominator
+   Changed some of the function names in MeasureFunctor.  Should not affect users
+   Added more informative function names to Njettiness.
+   Njettiness now allows finding unnormalized tau values
+   Added WTARecombiner to define winner-take-all axes
+   Added various WTA options to AxesMode
+   Added setAxes to Nsubjettiness
+   Added NsubjettinessRatio function
+2013-08-26 <jthaler>
+   Added inlines to fix compile issue
+   Put some of the minimization code inside of the AxesFinderFromKmeansMinimization class
+2013-02-23 <jthaler>
+   Fixed dependency issue (now using make depend)
+2013-02-22 <jthaler>
+   Fixed memory management and failed make check issues.
+2013-02-21 <jthaler>
+   First version submitted to fjcontrib
+2013-02-20 <jthaler>
+   Initial creation based on previous plugin hosted at http://www.jthaler.net/jets/
+
+
+
Index: external/fastjet/contribs/Nsubjettiness/Makefile
===================================================================
--- external/fastjet/contribs/Nsubjettiness/Makefile	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/contribs/Nsubjettiness/Makefile	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,101 @@
+# 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 -Woverloaded-virtual -g -Wunused-parameter
+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=Nsubjettiness
+SRCS=Nsubjettiness.cc Njettiness.cc NjettinessPlugin.cc MeasureFunction.cc AxesFinder.cc WinnerTakeAllRecombiner.cc NjettinessDefinition.cc
+EXAMPLES=example_basic_usage example_advanced_usage example_v1p0p3
+INSTALLED_HEADERS=Nsubjettiness.hh Njettiness.hh NjettinessPlugin.hh MeasureFunction.hh AxesFinder.hh WinnerTakeAllRecombiner.hh NjettinessDefinition.hh
+#------------------------------------------------------------------------
+
+CXXFLAGS+= $(shell $(FASTJETCONFIG) --cxxflags)
+LDFLAGS += -lm $(shell $(FASTJETCONFIG) --libs)
+
+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 alloews to build each of the examples listed
+# in $EXAMPLES automatically
+$(EXAMPLES): % : %.o all
+	$(CXX) -o $@ $< -L. -l$(NAME) $(LDFLAGS)
+
+# check that everything went fine
+check: examples
+	@for prog in $(EXAMPLES); do\
+	  $(check_script) $${prog} ../data/single-event.dat || exit 1; \
+	done
+	@echo "All tests successful"
+
+# cleaning the directory
+clean:
+	rm -f *~ *.o *.a
+
+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
+
+Nsubjettiness.o: Nsubjettiness.hh Njettiness.hh MeasureFunction.hh
+Nsubjettiness.o: AxesFinder.hh WinnerTakeAllRecombiner.hh
+Nsubjettiness.o: NjettinessDefinition.hh
+Njettiness.o: Njettiness.hh MeasureFunction.hh AxesFinder.hh
+Njettiness.o: WinnerTakeAllRecombiner.hh NjettinessDefinition.hh
+NjettinessPlugin.o: NjettinessPlugin.hh Njettiness.hh MeasureFunction.hh
+NjettinessPlugin.o: AxesFinder.hh WinnerTakeAllRecombiner.hh
+NjettinessPlugin.o: NjettinessDefinition.hh
+MeasureFunction.o: MeasureFunction.hh
+AxesFinder.o: AxesFinder.hh WinnerTakeAllRecombiner.hh MeasureFunction.hh
+WinnerTakeAllRecombiner.o: WinnerTakeAllRecombiner.hh
+NjettinessDefinition.o: NjettinessDefinition.hh MeasureFunction.hh
+NjettinessDefinition.o: AxesFinder.hh WinnerTakeAllRecombiner.hh
+example_basic_usage.o: Nsubjettiness.hh Njettiness.hh MeasureFunction.hh
+example_basic_usage.o: AxesFinder.hh WinnerTakeAllRecombiner.hh
+example_basic_usage.o: NjettinessDefinition.hh NjettinessPlugin.hh
+example_advanced_usage.o: Nsubjettiness.hh Njettiness.hh MeasureFunction.hh
+example_advanced_usage.o: AxesFinder.hh WinnerTakeAllRecombiner.hh
+example_advanced_usage.o: NjettinessDefinition.hh NjettinessPlugin.hh
+example_v1p0p3.o: Nsubjettiness.hh Njettiness.hh MeasureFunction.hh
+example_v1p0p3.o: AxesFinder.hh WinnerTakeAllRecombiner.hh
+example_v1p0p3.o: NjettinessDefinition.hh NjettinessPlugin.hh
Index: external/fastjet/contribs/Nsubjettiness/MeasureFunction.cc
===================================================================
--- external/fastjet/contribs/Nsubjettiness/MeasureFunction.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/contribs/Nsubjettiness/MeasureFunction.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -5,4 +5,5 @@
 //  Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason
 //
+//  $Id: MeasureFunction.cc 670 2014-06-06 01:24:42Z jthaler $
 //----------------------------------------------------------------------
 // This file is part of FastJet contrib.
@@ -36,10 +37,24 @@
 
 // Return all of the necessary TauComponents for specific input particles and axes
-TauComponents MeasureFunction::result(const std::vector<fastjet::PseudoJet>& particles, const std::vector<fastjet::PseudoJet>& axes) {
+TauComponents MeasureFunction::result(const std::vector<fastjet::PseudoJet>& particles, const std::vector<fastjet::PseudoJet>& axes) const {
+   
+   // first find partition
+   // this sets jetPartitionStorage and beamPartitionStorage
+   PseudoJet beamPartitionStorage;
+   std::vector<fastjet::PseudoJet> jetPartitionStorage = get_partition(particles,axes,&beamPartitionStorage);
+   
+   // then return result calculated from partition
+   return result_from_partition(jetPartitionStorage,axes,&beamPartitionStorage);
+}
 
-   std::vector<double> jetPieces(axes.size(), 0.0);
-   double beamPiece = 0.0;
+std::vector<fastjet::PseudoJet> MeasureFunction::get_partition(const std::vector<fastjet::PseudoJet>& particles,
+                                                               const std::vector<fastjet::PseudoJet>& axes,
+                                                               PseudoJet * beamPartitionStorage) const {
    
-   // Calculates the unnormalized sub-tau values, i.e. a std::vector of the contributions to tau_N of each Voronoi region (or region within R_0)
+   std::vector<std::vector<PseudoJet> > jetPartition(axes.size());
+   std::vector<PseudoJet> beamPartition;
+   
+   // Figures out the partiting of the input particles into the various jet pieces
+   // Based on which axis the parition is closest to
    for (unsigned i = 0; i < particles.size(); i++) {
       
@@ -60,23 +75,98 @@
       
       if (j_min == -1) {
-         if (_has_beam) beamPiece += beam_numerator(particles[i]);
+         if (_has_beam) beamPartition.push_back(particles[i]);
          else assert(_has_beam);  // this should never happen.
       } else {
-         jetPieces[j_min] += jet_numerator(particles[i],axes[j_min]);
+         jetPartition[j_min].push_back(particles[i]);
       }
    }
    
-   // Calculates normalization for tau and subTau if _has_denominator is true, otherwise returns 1.0 (i.e. no normalization)
-   double tauDen = 0.0;
-   if (_has_denominator) {
-      for (unsigned i = 0; i < particles.size(); i++) {
-         tauDen += denominator(particles[i]);
-      }
-   } else {
-      tauDen = 1.0; // if no denominator, then 1.0 for no normalization factor
+   // Store beam partition
+   if (beamPartitionStorage) {
+      *beamPartitionStorage = join(beamPartition);
+   }
+
+   // Store jet partitions
+   std::vector<PseudoJet> jetPartitionStorage(axes.size(),PseudoJet(0,0,0,0));
+   for (unsigned j = 0; j < axes.size(); j++) {
+      jetPartitionStorage[j] = join(jetPartition[j]);
    }
    
+   return jetPartitionStorage;
+}
+
+// does partition, but only stores index of PseudoJets
+std::vector<std::list<int> > MeasureFunction::get_partition_list(const std::vector<fastjet::PseudoJet>& particles,
+                                                                 const std::vector<fastjet::PseudoJet>& axes) const {
+
+   std::vector<std::list<int> > jetPartition(axes.size());
+   
+   // Figures out the partiting of the input particles into the various jet pieces
+   // Based on which axis the parition is closest to
+   for (unsigned i = 0; i < particles.size(); i++) {
+      
+      // find minimum distance; start with beam (-1) for reference
+      int j_min = -1;
+      double minRsq;
+      if (_has_beam) minRsq = beam_distance_squared(particles[i]);
+      else minRsq = std::numeric_limits<double>::max(); // make it large value
+      
+      // check to see which axis the particle is closest to
+      for (unsigned j = 0; j < axes.size(); j++) {
+         double tempRsq = jet_distance_squared(particles[i],axes[j]); // delta R distance
+         if (tempRsq < minRsq) {
+            minRsq = tempRsq;
+            j_min = j;
+         }
+      }
+      
+      if (j_min == -1) {
+         assert(_has_beam); // consistency check
+      } else {
+         jetPartition[j_min].push_back(i);
+      }
+   }
+   
+   return jetPartition;
+}
+   
+
+// Uses existing partition and calculates result
+// TODO:  Can we cache this for speed up when doing area subtraction?
+TauComponents MeasureFunction::result_from_partition(const std::vector<fastjet::PseudoJet>& jet_partition,
+                                                     const std::vector<fastjet::PseudoJet>& axes,
+                                                     PseudoJet * beamPartitionStorage) const {
+   
+   std::vector<double> jetPieces(axes.size(), 0.0);
+   double beamPiece = 0.0;
+   
+   double tauDen = 0.0;
+   if (!_has_denominator) tauDen = 1.0;  // if no denominator, then 1.0 for no normalization factor
+   
+   // first find jet pieces
+   for (unsigned j = 0; j < axes.size(); j++) {
+      std::vector<PseudoJet> thisPartition = jet_partition[j].constituents();
+      for (unsigned i = 0; i < thisPartition.size(); i++) {
+         jetPieces[j] += jet_numerator(thisPartition[i],axes[j]); //numerator jet piece
+         if (_has_denominator) tauDen += denominator(thisPartition[i]); // denominator
+      }
+   }
+   
+   // then find beam piece
+   if (_has_beam) {
+      assert(beamPartitionStorage); // make sure I have beam information
+      std::vector<PseudoJet> beamPartition = beamPartitionStorage->constituents();
+
+      for (unsigned i = 0; i < beamPartition.size(); i++) {
+         beamPiece += beam_numerator(beamPartition[i]); //numerator beam piece
+         if (_has_denominator) tauDen += denominator(beamPartition[i]); // denominator
+      }
+   }
    return TauComponents(jetPieces, beamPiece, tauDen, _has_denominator, _has_beam);
 }
+
+   
+   
+   
    
 } //namespace contrib
Index: external/fastjet/contribs/Nsubjettiness/MeasureFunction.hh
===================================================================
--- external/fastjet/contribs/Nsubjettiness/MeasureFunction.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/contribs/Nsubjettiness/MeasureFunction.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -5,4 +5,5 @@
 //  Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason
 //
+//  $Id: MeasureFunction.hh 678 2014-06-12 20:43:03Z jthaler $
 //----------------------------------------------------------------------
 // This file is part of FastJet contrib.
@@ -31,37 +32,21 @@
 #include <limits>
 
+
 FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
 
 namespace contrib{
 
-inline double sq(double x) {return x*x;}
-
-///////
-//
-// Measure Function
-//
-///////
-
+///////
+//
+// TauComponents
+// (eventually we might want to put this in a separate header file)
+//
+///////
+   
 /// \class TauComponents
 // This class creates a wrapper for the various tau/subtau values calculated in Njettiness. This class allows Njettiness access to these variables
 // without ever having to do the calculation itself. It takes in subtau numerators and tau denominator from MeasureFunction
 // and outputs tau numerator, and normalized tau and subtau.
-// TODO:  Consider merging with NjettinessExtras.  Add axes information?
 class TauComponents {
-private:
-   
-   // these values are input in the constructor
-   std::vector<double> _jet_pieces_numerator;
-   double _beam_piece_numerator;
-   double _denominator;
-   bool _has_denominator; //added so that TauComponents knows if denominator is used or not
-   bool _has_beam; //added so that TauComponents knows if beam regions is used or not
-   
-   // these values are derived from above values
-   std::vector<double> _jet_pieces;
-   double _beam_piece;
-   double _numerator;
-   double _tau;
-   
    
 public:
@@ -115,6 +100,28 @@
    double beam_piece() const { return _beam_piece; }
    double tau() const { return _tau; }
-   
-};
+
+private:
+   
+   // these values are input in the constructor
+   std::vector<double> _jet_pieces_numerator;
+   double _beam_piece_numerator;
+   double _denominator;
+   bool _has_denominator; //added so that TauComponents knows if denominator is used or not
+   bool _has_beam; //added so that TauComponents knows if beam regions is used or not
+   
+   // these values are derived from above values
+   std::vector<double> _jet_pieces;
+   double _beam_piece;
+   double _numerator;
+   double _tau;
+   
+};
+
+///////
+//
+// Measure Function
+//
+///////
+
 
 //------------------------------------------------------------------------
@@ -125,4 +132,47 @@
 class MeasureFunction {
    
+public:
+   //These functions define the measure by which tau_N is calculated,
+   //and are overloaded by the various measures below
+   
+   // Distanes to axes.  These are called many times, so need to be as fast as possible
+   virtual double jet_distance_squared(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const = 0;
+   virtual double beam_distance_squared(const fastjet::PseudoJet& particle) const = 0;
+   
+   // The actual measures used in N-(sub)jettiness
+   virtual double jet_numerator(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const  = 0;
+   virtual double beam_numerator(const fastjet::PseudoJet& particle) const = 0;
+   
+   // a possible normalization factor
+   virtual double denominator(const fastjet::PseudoJet& particle) const = 0;
+   
+   //------
+   // The functions below call the above functions and are not virtual
+   //------
+   
+   // Return all of the necessary TauComponents for specific input particles and axes
+   // Also have optional pointers to get out information about partitioning
+   TauComponents result(const std::vector<fastjet::PseudoJet>& particles, const std::vector<fastjet::PseudoJet>& axes) const;
+
+   // Just getting tau value if that is all that is needed
+   double tau(const std::vector<fastjet::PseudoJet>& particles, const std::vector<fastjet::PseudoJet>& axes) const {
+      return result(particles,axes).tau();
+   }
+   
+   // Create the partitioning and stores internally
+   std::vector<fastjet::PseudoJet> get_partition(const std::vector<fastjet::PseudoJet>& particles, const std::vector<fastjet::PseudoJet>& axes, PseudoJet * beamPartitionStorage = NULL) const;
+
+   // Essentially same as get_partition, but in the form needed for the jet algorithm
+   std::vector<std::list<int> > get_partition_list(const std::vector<fastjet::PseudoJet>& particles, const std::vector<fastjet::PseudoJet>& axes) const;
+
+   // calculates the tau result using an existing partition
+   TauComponents result_from_partition(const std::vector<fastjet::PseudoJet>& jet_partitioning, const std::vector<fastjet::PseudoJet>& axes, PseudoJet * beamPartitionStorage = NULL) const;
+
+   // shorthand for squaring
+   static inline double sq(double x) {return x*x;}
+
+   //virtual destructor
+   virtual ~MeasureFunction(){}
+   
 protected:
    //bool set by derived classes to choose whether or not to use the denominator
@@ -133,141 +183,113 @@
    MeasureFunction(bool has_denominator = true, bool has_beam = true) : _has_denominator(has_denominator), _has_beam(has_beam) {}
    
-public:
-   virtual ~MeasureFunction(){}
-   
-   //These functions define the measure by which tau_N is calculated,
-   //and are overloaded by the various measures below
-   
-   // Distanes to axes.  These are called many times, so need to be as fast as possible
-   virtual double jet_distance_squared(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) = 0;
-   virtual double beam_distance_squared(const fastjet::PseudoJet& particle) = 0;
-   
-   // The actual measures used in N-(sub)jettiness
-   virtual double jet_numerator(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) = 0;
-   virtual double beam_numerator(const fastjet::PseudoJet& particle) = 0;
-   
-   // a possible normalization factor
-   virtual double denominator(const fastjet::PseudoJet& particle) = 0;
-   
-   
-   // These functions call the above functions and are not virtual
-   
-   // Do I cluster a particle into a jet?
-   bool do_cluster(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) {
-      return (jet_distance_squared(particle,axis) <= beam_distance_squared(particle));
-   }
-   
-   // Return all of the necessary TauComponents for specific input particles and axes
-   TauComponents result(const std::vector<fastjet::PseudoJet>& particles, const std::vector<fastjet::PseudoJet>& axes);
-
-   double tau(const std::vector<fastjet::PseudoJet>& particles, const std::vector<fastjet::PseudoJet>& axes) {
-      return result(particles,axes).tau();
-   }
-
-   
-};
-
-
-/// \class DefaultNormalizedMeasure
+};
+
+
+/// \class DefaultNormalizedMeasureFunction
 // This class is the default measure, inheriting from the class above. This class will calculate tau_N 
 // of a jet according to this measure. This measure is defined as the pT of the particle multiplied by deltaR 
 // to the power of beta. This class includes the normalization factor determined by R0
-class DefaultNormalizedMeasure : public MeasureFunction {
-
-   private:
-      double _beta;
-      double _R0;
-      double _Rcutoff;
-
-   public:
-
-      DefaultNormalizedMeasure(double beta, double R0, double Rcutoff, bool normalized = true)
-      : MeasureFunction(normalized), _beta(beta), _R0(R0), _Rcutoff(Rcutoff) {}
-
-      virtual double jet_distance_squared(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) {
-         return particle.squared_distance(axis);
-      }
-   
-      virtual double beam_distance_squared(const fastjet::PseudoJet& particle) {
-         return sq(_Rcutoff);
-      }
-
-      virtual double jet_numerator(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) {
-         return particle.perp() * std::pow(jet_distance_squared(particle,axis),_beta/2.0);
-      }
-   
-      virtual double beam_numerator(const fastjet::PseudoJet& particle) {
-         return particle.perp() * std::pow(_Rcutoff,_beta);
-      }
-
-      virtual double denominator(const fastjet::PseudoJet& particle) {
-         return particle.perp() * std::pow(_R0,_beta);
-      }
-
+class DefaultNormalizedMeasureFunction : public MeasureFunction {
+
+public:
+
+   DefaultNormalizedMeasureFunction(double beta, double R0, double Rcutoff, bool normalized = true)
+   : MeasureFunction(normalized), _beta(beta), _R0(R0), _Rcutoff(Rcutoff) {}
+
+   virtual double jet_distance_squared(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const {
+      return particle.squared_distance(axis);
+   }
+
+   virtual double beam_distance_squared(const fastjet::PseudoJet& /*particle*/) const {
+      return sq(_Rcutoff);
+   }
+
+   virtual double jet_numerator(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const{
+      return particle.perp() * std::pow(jet_distance_squared(particle,axis),_beta/2.0);
+   }
+
+   virtual double beam_numerator(const fastjet::PseudoJet& particle) const {
+      return particle.perp() * std::pow(_Rcutoff,_beta);
+   }
+
+   virtual double denominator(const fastjet::PseudoJet& particle) const {
+      return particle.perp() * std::pow(_R0,_beta);
+   }
+   
+private:
+   double _beta;
+   double _R0;
+   double _Rcutoff;
+
+   
 };
 
 //------------------------------------------------------------------------
-/// \class DefaultUnnormalizedMeasure
+/// \class DefaultUnnormalizedMeasureFunction
 // This class is the unnormalized default measure, inheriting from the class above. The only difference from above
 // is that the denominator is defined to be 1.0 by setting _has_denominator to false.
-class DefaultUnnormalizedMeasure : public DefaultNormalizedMeasure {
-
-   public:
-      // Since all methods are identical, UnnormalizedMeasure inherits directly from NormalizedMeasure. R0 is defaulted to NAN since the value of R0 is unecessary for this class.
-      // the "false" flag sets _has_denominator in MeasureFunction to false so no denominator is used.
-      DefaultUnnormalizedMeasure(double beta, double Rcutoff) : DefaultNormalizedMeasure(beta, NAN, Rcutoff, false) {}
-
-      
+class DefaultUnnormalizedMeasureFunction : public DefaultNormalizedMeasureFunction {
+
+public:
+   // Since all methods are identical, UnnormalizedMeasure inherits directly
+   // from NormalizedMeasure. R0 is a dummy value since the value of R0 is unecessary for this class,
+   // and the "false" flag sets _has_denominator in MeasureFunction to false so no denominator is used.
+   DefaultUnnormalizedMeasureFunction(double beta, double Rcutoff)
+   : DefaultNormalizedMeasureFunction(beta, std::numeric_limits<double>::quiet_NaN(), Rcutoff, false) {}
 };
 
 //------------------------------------------------------------------------
-/// \class GeometricMeasure
+/// \class GeometricMeasureFunction
 // This class is the geometic measure, inheriting from the class above. This class will calculate tau_N 
 // of a jet according to this measure. This measure is defined by the Lorentz dot product between
 // the particle and the axis. This class includes normalization of tau_N.
-class GeometricMeasure : public MeasureFunction {
-
-   private:
-      double _jet_beta;
-      double _beam_beta;
-      double _Rcutoff;
-
-      // create light-like axis
-      fastjet::PseudoJet lightFrom(const fastjet::PseudoJet& input) const {
-         double length = sqrt(pow(input.px(),2) + pow(input.py(),2) + pow(input.pz(),2));
-         return fastjet::PseudoJet(input.px()/length,input.py()/length,input.pz()/length,1.0);
-      }
-
-   public:
-      // Right now, we are hard coded for beam_beta = 1.0, but that will need to change
-      GeometricMeasure(double jet_beta, double Rcutoff) : _jet_beta(jet_beta), _beam_beta(1.0), _Rcutoff(Rcutoff) {}
-   
-      virtual double jet_distance_squared(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) {
-         fastjet::PseudoJet lightAxis = lightFrom(axis);
-         double pseudoRsquared = 2.0*dot_product(lightFrom(axis),particle)/(lightAxis.pt()*particle.pt());
-         return pseudoRsquared;
-      }
-   
-      virtual double beam_distance_squared(const fastjet::PseudoJet& particle) {
-         return sq(_Rcutoff);
-      }
-
-      virtual double jet_numerator(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) {
-         fastjet::PseudoJet lightAxis = lightFrom(axis);
-         double weight = (_beam_beta == 1.0) ? 1.0 : std::pow(lightAxis.pt(),_beam_beta - 1.0);
-         return particle.pt() * weight * std::pow(jet_distance_squared(particle,axis),_jet_beta/2.0);
-      }
-   
-      virtual double beam_numerator(const fastjet::PseudoJet& particle) {
-         double weight = (_beam_beta == 1.0) ? 1.0 : std::pow(particle.pt()/particle.e(),_beam_beta - 1.0);
-         return particle.pt() * weight * std::pow(_Rcutoff,_jet_beta);
-      }
-
-      virtual double denominator(const fastjet::PseudoJet& particle) {
-         return 1.0;
-      }
-};
-
-
+class GeometricMeasureFunction : public MeasureFunction {
+
+public:
+   // Right now, we are hard coded for beam_beta = 1.0, but that will need to change
+   GeometricMeasureFunction(double jet_beta, double Rcutoff) : 
+     MeasureFunction(false), // doesn't have denominator
+     _jet_beta(jet_beta), _beam_beta(1.0), _Rcutoff(Rcutoff) {}
+
+   virtual double jet_distance_squared(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const {
+      fastjet::PseudoJet lightAxis = lightFrom(axis);
+      double pseudoRsquared = 2.0*dot_product(lightFrom(axis),particle)/(lightAxis.pt()*particle.pt());
+      return pseudoRsquared;
+   }
+
+   virtual double beam_distance_squared(const fastjet::PseudoJet&  /*particle*/) const {
+      return sq(_Rcutoff);
+   }
+
+   virtual double jet_numerator(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const {
+      fastjet::PseudoJet lightAxis = lightFrom(axis);
+      double weight = (_beam_beta == 1.0) ? 1.0 : std::pow(lightAxis.pt(),_beam_beta - 1.0);
+      return particle.pt() * weight * std::pow(jet_distance_squared(particle,axis),_jet_beta/2.0);
+   }
+
+   virtual double beam_numerator(const fastjet::PseudoJet& particle) const {
+      double weight = (_beam_beta == 1.0) ? 1.0 : std::pow(particle.pt()/particle.e(),_beam_beta - 1.0);
+      return particle.pt() * weight * std::pow(_Rcutoff,_jet_beta);
+   }
+
+   virtual double denominator(const fastjet::PseudoJet&  /*particle*/) const {
+      return std::numeric_limits<double>::quiet_NaN();
+   }
+   
+   
+private:
+   double _jet_beta;
+   double _beam_beta;
+   double _Rcutoff;
+   
+   // create light-like axis
+   fastjet::PseudoJet lightFrom(const fastjet::PseudoJet& input) const {
+      double length = sqrt(pow(input.px(),2) + pow(input.py(),2) + pow(input.pz(),2));
+      return fastjet::PseudoJet(input.px()/length,input.py()/length,input.pz()/length,1.0);
+   }
+
+};
+   
+   
 } //namespace contrib
 
Index: external/fastjet/contribs/Nsubjettiness/NEWS
===================================================================
--- external/fastjet/contribs/Nsubjettiness/NEWS	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/contribs/Nsubjettiness/NEWS	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,83 @@
+-------------------------
+Version 2
+-------------------------
+
+This is a streamlining of the N-subjettiness code, developed mainly by TJ
+Wilkason.  The core functionality is unchanged, but classes have been
+dramatically reorganized to allow for later expansion.  Because the API for
+Njettiness has changed, we have called this v2 (http://semver.org).
+
+Note that we have maintain backwards compatibility for the typical ways that
+Nsubjettiness was used.  In particular, all of the Nsubjettiness class code in
+the example file v1.0.3 from still compiles, as does the NjettinessPlugin class
+code that uses the default measure.
+
+The key new features are:
+
+  * NsubjettinessRatio:  Direct access to tau_N / tau_M (the most requested
+    feature)
+  * MeasureDefinition to allow access to both normalized and unnormalized measures
+  * AxesDefinition to allow for access to more general axes modes
+  * Winner-Take-All recombination axes:  a faster way to find axes than beta = 1
+    minimization, but with comparable performance.
+  * TauComponents to get access to the pieces of the N-(sub)jettiness
+    calculation.
+  * For clarity, split the example file into an example_basic_usage and
+    example_advanced_usage
+  * In Nsubjettiness, access to seedAxes() and currentAxes() to figure out the
+    axes used before and after minimization.
+  * In Nsubjettiness, access to currentSubjets() to get the subjet fourvectors.
+
+
+-- 2.1.0:  (July 9, 2014) Inclusion of MeasureDefinition/AxesDefinition interface.
+           This was the first publicly available version of Nsubjettiness v2.
+-- 2.0.0:  Initial release of v2.0.  This was never officially made public.
+
+-------------------------
+Version 1
+-------------------------
+
+This was a new release using FastJet contrib framework, primary developed by
+Jesse Thaler.
+
+-- 1.0.3:  Added inlines to fix compile issue (thanks Matthew Low)
+-- 1.0.2:  Fixed potential dependency issue (thanks FJ authors)
+-- 1.0.1:  Fixed memory leak in Njettiness.hh (thanks FJ authors)
+-- 1.0.0:  New release using FastJet contrib framework.  This includes a new
+makefile and a simplified example program.
+
+-------------------------
+Previous Versions
+-------------------------
+
+The previous versions of this code were developed initially by Ken Van Tilburg,
+tweaked by Jesse Thaler, and made into a robust FastJet add on by Chris
+Vermilion.
+
+Previous versions available from:
+   http://jthaler.net/jets/Njettiness-0.5.1.tar.gz (Experimental Version)
+   http://jthaler.net/jets/Njettiness-0.4.1.tar.gz (Stable Version)
+
+Previous version history:
+-- 0.5.1:  For Njettiness Plugin, added access to currentTau values and axes via
+           ClusterSequence::Extras class.  (thanks to Dinko Ferencek and John
+           Paul Chou)
+-- 0.5.0:  Corrected fatal error in ConstituentTauValue (TauValue unaffected).
+           Started process of allowing for more general measures and alternative
+           minimization schemes. Extremely preliminary inclusion of alternative
+           "geometric" measure.
+-- 0.4.1:  Corrected bug where a too-small value of Rcut would cause the
+           minimization procedure to fail (thanks Marat Freytsis, Brian Shuve)
+-- 0.4.0:  Adding Nsubjettiness FunctionOfPseudoJet<float>.  Re-organizing file
+           structure and doing some re-naming to clarify Njettiness vs.
+           Nsubjettiness.  Some speedup in UpdateAxes code. (CKV)
+-- 0.3.2:  Returns zero instead of a segmentation fault when the number of
+           particles in a jet is smaller than the N value in tau_N (thanks
+           Grigory Ovanesyan)
+-- 0.3.2:  Fixed -Wshadow errors (thanks Grigory Ovanesyan)
+-- 0.3.1:  Fixed stray comma/semicolon compiler error (thanks Grigory Ovanesyan)
+-- 0.3.1:  Corrected tarbomb issue (thanks Jonathan Walsh)
+-- 0.3.1:  Added anti-kT seeds as option
+-- 0.3.1:  Fixed bug in minimization code with R_cutoff (thanks Chris Vermilion)
+-- 0.3.1:  Added getPartition() and getJets() functions as helper functions for
+           Chris Vermilion. (JT)
Index: external/fastjet/contribs/Nsubjettiness/Njettiness.cc
===================================================================
--- external/fastjet/contribs/Nsubjettiness/Njettiness.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/contribs/Nsubjettiness/Njettiness.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -5,4 +5,5 @@
 //  Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason
 //
+//  $Id: Njettiness.cc 677 2014-06-12 18:56:46Z jthaler $
 //----------------------------------------------------------------------
 // This file is part of FastJet contrib.
@@ -35,28 +36,25 @@
 ///////
 
-// Helper function to correlate one pass minimization with appropriate measure
-void Njettiness::setOnePassAxesFinder(MeasureMode measure_mode, AxesFinder* startingFinder, double beta, double Rcutoff) {
-   if (measure_mode == normalized_measure || measure_mode == unnormalized_measure || measure_mode == normalized_cutoff_measure || measure_mode == unnormalized_cutoff_measure) {
-      _axesFinder = new AxesFinderFromOnePassMinimization(startingFinder, beta, Rcutoff);
-   }
-   else if (measure_mode == geometric_measure || measure_mode == geometric_cutoff_measure) {
-      _axesFinder = new AxesFinderFromGeometricMinimization(startingFinder, beta, Rcutoff);
-   }
-   else {
-      std::cerr << "Minimization only set up for normalized_measure, unnormalized_measure, normalized_cutoff_measure, unnormalized_cutoff_measure, geometric_measure, geometric_cutoff_measure" << std::endl;
-      exit(1); }
-}
-
-// Parsing needed for constructor to set AxesFinder and MeasureFunction
-// All of the parameter handling is here, and checking that number of parameters is correct.
-void Njettiness::setMeasureFunctionandAxesFinder(AxesMode axes_mode, MeasureMode measure_mode, double para1, double para2, double para3, double para4) {
+Njettiness::Njettiness(const AxesDefinition & axes_def, const MeasureDefinition & measure_def)
+: _axes_def(axes_def.create()), _measure_def(measure_def.create()) {
+   setMeasureFunctionAndAxesFinder();  // call helper function to do the hard work
+}
+
+Njettiness::Njettiness(AxesMode axes_mode, const MeasureDefinition & measure_def)
+: _axes_def(createAxesDef(axes_mode)), _measure_def(measure_def.create()) {
+   setMeasureFunctionAndAxesFinder();  // call helper function to do the hard work
+}
+   
+// Convert from MeasureMode enum to MeasureDefinition
+// This returns a pointer that will be claimed by a SharedPtr
+MeasureDefinition* Njettiness::createMeasureDef(MeasureMode measure_mode, int num_para, double para1, double para2, double para3) const {
 
    // definition of maximum Rcutoff for non-cutoff measures, changed later by other measures
    double Rcutoff = std::numeric_limits<double>::max();  //large number
-   // Most (but all measures have some kind of beta value)
-   double beta = NAN;
+   // Most (but not all) measures have some kind of beta value
+   double beta = std::numeric_limits<double>::quiet_NaN();
    // The normalized measures have an R0 value.
-   double R0 = NAN;
-
+   double R0 = std::numeric_limits<double>::quiet_NaN();
+   
    // Find the MeasureFunction and set the parameters.
    switch (measure_mode) {
@@ -64,25 +62,25 @@
          beta = para1;
          R0 = para2;
-         if(correctParameterCount(2, para1, para2, para3, para4)) 
-            _measureFunction = new DefaultNormalizedMeasure(beta, R0, Rcutoff); //normalized_measure requires 2 parameters, beta and R0
-         else { 
-            std::cerr << "normalized_measure needs 2 parameters (beta and R0)" << std::endl;
-            exit(1); }
+         if(num_para == 2) {
+            return new NormalizedMeasure(beta,R0);
+         } else {
+            throw Error("normalized_measure needs 2 parameters (beta and R0)");
+         }
          break;
       case unnormalized_measure:
          beta = para1;
-         if(correctParameterCount(1, para1, para2, para3, para4)) 
-            _measureFunction = new DefaultUnnormalizedMeasure(beta, Rcutoff); //unnormalized_measure requires 1 parameter, beta
-         else {
-            std::cerr << "unnormalized_measure needs 1 parameter (beta)" << std::endl;
-            exit(1); }
+         if(num_para == 1) {
+            return new UnnormalizedMeasure(beta);
+         } else {
+            throw Error("unnormalized_measure needs 1 parameter (beta)");
+         }
          break;
       case geometric_measure:
          beta = para1;
-         if(correctParameterCount(1, para1, para2, para3, para4))
-            _measureFunction = new GeometricMeasure(beta,Rcutoff); //geometric_measure requires 1 parameter, beta
-         else {
-            std::cerr << "geometric_measure needs 1 parameter (beta)" << std::endl;
-            exit(1); }
+         if (num_para == 1) {
+            return new GeometricMeasure(beta);
+         } else {
+            throw Error("geometric_measure needs 1 parameter (beta)");
+         }
          break;
       case normalized_cutoff_measure:
@@ -90,109 +88,88 @@
          R0 = para2;
          Rcutoff = para3; //Rcutoff parameter is 3rd parameter in normalized_cutoff_measure
-         if(correctParameterCount(3, para1, para2, para3, para4))
-            _measureFunction = new DefaultNormalizedMeasure(beta, R0, Rcutoff); //normalized_cutoff_measure requires 3 parameters, beta, R0, and Rcutoff
-         else { 
-            std::cerr << "normalized_cutoff_measure has 3 parameters (beta, R0, Rcutoff)" << std::endl;
-            exit(1); }
+         if (num_para == 3) {
+            return new NormalizedCutoffMeasure(beta,R0,Rcutoff);
+         } else {
+            throw Error("normalized_cutoff_measure has 3 parameters (beta, R0, Rcutoff)");
+         }
          break;
       case unnormalized_cutoff_measure:
          beta = para1;
          Rcutoff = para2; //Rcutoff parameter is 2nd parameter in normalized_cutoff_measure
-         if (correctParameterCount(2, para1, para2, para3, para4))
-            _measureFunction = new DefaultUnnormalizedMeasure(beta, Rcutoff); //unnormalized_cutoff_measure requires 2 parameters, beta and Rcutoff
-         else {
-            std::cerr << "unnormalized_cutoff_measure has 2 parameters (beta, Rcutoff)" << std::endl;
-            exit(1); }
+         if (num_para == 2) {
+            return new UnnormalizedCutoffMeasure(beta,Rcutoff);
+         } else {
+            throw Error("unnormalized_cutoff_measure has 2 parameters (beta, Rcutoff)");
+         }
          break;
       case geometric_cutoff_measure:
          beta = para1;
          Rcutoff = para2; //Rcutoff parameter is 2nd parameter in geometric_cutoff_measure
-         if(correctParameterCount(2, para1, para2, para3, para4))
-            _measureFunction = new GeometricMeasure(beta,Rcutoff); //geometric_cutoff_measure requires 2 parameters, beta and Rcutoff
-         else {
-            std::cerr << "geometric_cutoff_measure has 2 parameters (beta,Rcutoff)" << std::endl;
-            exit(1); }
+         if(num_para == 2) {
+           return new GeometricCutoffMeasure(beta,Rcutoff);
+         } else {
+            throw Error("geometric_cutoff_measure has 2 parameters (beta, Rcutoff)");
+         }
          break;
       default:
          assert(false);
          break;
-   }   
-
-   // Choose which AxesFinder from user input.
-   // Uses setOnePassAxesFinder helpful function to use beta and Rcutoff values about (if needed)
+   }
+   return NULL;
+}
+
+// Convert from AxesMode enum to AxesDefinition
+// This returns a pointer that will be claimed by a SharedPtr
+AxesDefinition* Njettiness::createAxesDef(Njettiness::AxesMode axes_mode) const {
+   
    switch (axes_mode) {
       case wta_kt_axes:
-         _axesFinder = new AxesFinderFromWTA_KT(); 
-         break;
+         return new WTA_KT_Axes();
       case wta_ca_axes:
-         _axesFinder = new AxesFinderFromWTA_CA(); 
-         break;
+         return new WTA_CA_Axes();
       case kt_axes:
-         _axesFinder = new AxesFinderFromKT();
-         break;
+         return new KT_Axes();
       case ca_axes:
-         _axesFinder = new AxesFinderFromCA();
-         break;
+         return new CA_Axes();
       case antikt_0p2_axes:
-         _axesFinder = new AxesFinderFromAntiKT(0.2);     
-         break;
+         return new AntiKT_Axes(0.2);
       case onepass_wta_kt_axes:
-         setOnePassAxesFinder(measure_mode, new AxesFinderFromWTA_KT(), beta, Rcutoff);
-         break;
+         return new OnePass_WTA_KT_Axes();
       case onepass_wta_ca_axes:
-         setOnePassAxesFinder(measure_mode, new AxesFinderFromWTA_CA(), beta, Rcutoff);
-         break;
+         return new OnePass_WTA_CA_Axes();
       case onepass_kt_axes:
-         setOnePassAxesFinder(measure_mode, new AxesFinderFromKT(), beta, Rcutoff);
-         break;
+         return new OnePass_KT_Axes();
       case onepass_ca_axes:
-         setOnePassAxesFinder(measure_mode, new AxesFinderFromCA(), beta, Rcutoff);
-         break;
+         return new OnePass_CA_Axes();
       case onepass_antikt_0p2_axes:
-         setOnePassAxesFinder(measure_mode, new AxesFinderFromAntiKT(0.2), beta, Rcutoff);
-         break;
+         return new OnePass_AntiKT_Axes(0.2);
       case onepass_manual_axes:
-         setOnePassAxesFinder(measure_mode, new AxesFinderFromUserInput(), beta, Rcutoff);
-         break;
-      case min_axes: //full minimization is not defined for geometric_measure.
-         if (measure_mode == normalized_measure || measure_mode == unnormalized_measure || measure_mode == normalized_cutoff_measure || measure_mode == unnormalized_cutoff_measure)
-            //Defaults to 100 iteration to find minimum
-            _axesFinder = new AxesFinderFromKmeansMinimization(new AxesFinderFromKT(), beta, Rcutoff, 100);
-         else {
-            std::cerr << "Multi-pass minimization only set up for normalized_measure, unnormalized_measure, normalized_cutoff_measure, unnormalized_cutoff_measure." << std::endl;
-            exit(1);
-         }
-         break;
+         return new OnePass_Manual_Axes();
+      case min_axes:
+         return new MultiPass_Axes(100);
       case manual_axes:
-         _axesFinder = new AxesFinderFromUserInput();
-         break;
-// These options have been commented out because they have not been fully tested
-//      case wta2_kt_axes: // option for alpha = 2 added
-//         _axesFinder = new AxesFinderFromWTA2_KT();
-//         break;
-//      case wta2_ca_axes: // option for alpha = 2 added
-//         _axesFinder = new AxesFinderFromWTA2_CA();
-//         break;
-//      case onepass_wta2_kt_axes: // option for alpha = 2 added
-//         setOnePassAxesFinder(measure_mode, new AxesFinderFromWTA2_KT(), beta, Rcutoff);
-//         break;
-//      case onepass_wta2_ca_axes: // option for alpha = 2 added
-//         setOnePassAxesFinder(measure_mode, new AxesFinderFromWTA2_CA(), beta, Rcutoff);
-//         break;
+         return new Manual_Axes();
       default:
          assert(false);
-         break;
-      }   
-
+         return NULL;
+   }
+}
+
+   
+// Parsing needed for constructor to set AxesFinder and MeasureFunction
+// All of the parameter handling is here, and checking that number of parameters is correct.
+void Njettiness::setMeasureFunctionAndAxesFinder() {
+   // Get the correct MeasureFunction and AxesFinders
+   _measureFunction.reset(_measure_def->createMeasureFunction());
+   _startingAxesFinder.reset(_axes_def->createStartingAxesFinder(*_measure_def));
+   _finishingAxesFinder.reset(_axes_def->createFinishingAxesFinder(*_measure_def));
 }
 
 // setAxes for Manual mode
-void Njettiness::setAxes(std::vector<fastjet::PseudoJet> myAxes) {
-   if (_current_axes_mode == manual_axes || _current_axes_mode == onepass_manual_axes) {
+void Njettiness::setAxes(const std::vector<fastjet::PseudoJet> & myAxes) {
+   if (_axes_def->supportsManualAxes()) {
       _currentAxes = myAxes;
-   }
-   else {
-      std::cerr << "You can only use setAxes if using manual_axes or onepass_manual_axes measure mode" << std::endl;
-      exit(1);
+   } else {
+      throw Error("You can only use setAxes for manual AxesDefinitions");
    }
 }
@@ -200,5 +177,5 @@
 // Calculates and returns all TauComponents that user would want.
 // This information is stored in _current_tau_components for later access as well.
-TauComponents Njettiness::getTauComponents(unsigned n_jets, const std::vector<fastjet::PseudoJet> & inputJets) {
+TauComponents Njettiness::getTauComponents(unsigned n_jets, const std::vector<fastjet::PseudoJet> & inputJets) const {
    if (inputJets.size() <= n_jets) {  //if not enough particles, return zero
       _currentAxes = inputJets;
@@ -206,8 +183,21 @@
       _current_tau_components = TauComponents();
       _seedAxes = _currentAxes;
+      _currentJets = _currentAxes;
+      _currentBeam = PseudoJet(0.0,0.0,0.0,0.0);
    } else {
-      _currentAxes = _axesFinder->getAxes(n_jets,inputJets,_currentAxes); // sets current Axes
-      _seedAxes = _axesFinder->seedAxes(); // sets seed Axes (if one pass minimization was used)
-      _current_tau_components = _measureFunction->result(inputJets, _currentAxes);  // sets current Tau Values
+
+      _seedAxes = _startingAxesFinder->getAxes(n_jets,inputJets,_currentAxes); //sets starting point for minimization
+      if (_finishingAxesFinder) {
+         _currentAxes = _finishingAxesFinder->getAxes(n_jets,inputJets,_seedAxes);
+      } else {
+         _currentAxes = _seedAxes;
+      }
+      
+      // Find partition and store information
+      // (jet information in _currentJets, beam in _currentBeam)
+      _currentJets = _measureFunction->get_partition(inputJets,_currentAxes,&_currentBeam);
+      
+      // Find tau value and store information
+      _current_tau_components = _measureFunction->result_from_partition(_currentJets, _currentAxes,&_currentBeam);  // sets current Tau Values
    }
    return _current_tau_components;
@@ -219,42 +209,10 @@
 // Each vector element is a list of ints corresponding to the indices in
 // particles of the particles belonging to that jet.
-// TODO:  Consider moving to MeasureFunction
-std::vector<std::list<int> > Njettiness::getPartition(const std::vector<fastjet::PseudoJet> & particles) {
-   std::vector<std::list<int> > partitions(_currentAxes.size());
-
-   for (unsigned i = 0; i < particles.size(); i++) {
-      
-      int j_min = -1;
-      // find minimum distance
-      double minR = std::numeric_limits<double>::max();  //large number
-      for (unsigned j = 0; j < _currentAxes.size(); j++) {
-         double tempR = _measureFunction->jet_distance_squared(particles[i],_currentAxes[j]); // delta R distance
-         if (tempR < minR) {
-            minR = tempR;
-            j_min = j;
-         }
-      }
-      if (_measureFunction->do_cluster(particles[i],_currentAxes[j_min])) partitions[j_min].push_back(i);
-   }
-   return partitions;
-}
-
-// Having found axes, assign each particle in particles to an axis, and return a set of jets.
-// Each jet is the sum of particles closest to an axis (Njet = Naxes).
-// TODO:  Consider moving to MeasureFunction
-std::vector<fastjet::PseudoJet> Njettiness::getJets(const std::vector<fastjet::PseudoJet> & particles) {
-   
-   std::vector<fastjet::PseudoJet> jets(_currentAxes.size());
-
-   std::vector<std::list<int> > partition = getPartition(particles);
-   for (unsigned j = 0; j < partition.size(); ++j) {
-      std::list<int>::const_iterator it, itE;
-      for (it = partition[j].begin(), itE = partition[j].end(); it != itE; ++it) {
-         jets[j] += particles[*it];
-      }
-   }
-   return jets;
-}
-
+std::vector<std::list<int> > Njettiness::getPartitionList(const std::vector<fastjet::PseudoJet> & particles) const {
+   // core code is in MeasureFunction
+   return _measureFunction->get_partition_list(particles,_currentAxes);
+}
+
+   
 } // namespace contrib
 
Index: external/fastjet/contribs/Nsubjettiness/Njettiness.hh
===================================================================
--- external/fastjet/contribs/Nsubjettiness/Njettiness.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/contribs/Nsubjettiness/Njettiness.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -5,4 +5,5 @@
 //  Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason
 //
+//  $Id: Njettiness.hh 670 2014-06-06 01:24:42Z jthaler $
 //----------------------------------------------------------------------
 // This file is part of FastJet contrib.
@@ -25,17 +26,21 @@
 #define __FASTJET_CONTRIB_NJETTINESS_HH__
 
+
 #include "MeasureFunction.hh"
 #include "AxesFinder.hh"
+#include "NjettinessDefinition.hh"
 
 #include "fastjet/PseudoJet.hh"
+#include "fastjet/SharedPtr.hh"
+#include <fastjet/LimitedWarning.hh>
+
 #include <cmath>
 #include <vector>
 #include <list>
 
-
 FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
 
 namespace contrib {
-
+   
 ///////
 //
@@ -54,4 +59,5 @@
    
    // The various axes choices available to the user
+   // It is recommended to use AxesDefinition instead of these.
    enum AxesMode {
       kt_axes,             // exclusive kt axes
@@ -78,4 +84,5 @@
    // "normalized_cutoff_measure" was the default in v1.0 of Nsubjettiness
    // "unnormalized_measure" is now the recommended default usage
+   // But it is recommended to use MeasureDefinition instead of these.
    enum MeasureMode {
       normalized_measure,           //default normalized measure
@@ -87,93 +94,86 @@
    };
 
-private:
-   // The chosen axes/measure modes
-   AxesFinder* _axesFinder;  // The chosen axes
-   MeasureFunction* _measureFunction; // The chosen measure
+   // Main constructor that uses AxesMode and MeasureDefinition to specify measure
+   // Unlike Nsubjettiness or NjettinessPlugin, the value N is not chosen
+   Njettiness(const AxesDefinition & axes_def, const MeasureDefinition & measure_def);
 
-   // Enum information so functions can specify output based on specific options, primarily for setAxes
-   AxesMode _current_axes_mode;
-   MeasureMode _current_measure_mode;
-   
-   // Information about the current information
-   TauComponents _current_tau_components; //automatically set to have components of 0; these values will be set by the getTau function call
-   std::vector<fastjet::PseudoJet> _currentAxes;
-   std::vector<fastjet::PseudoJet> _seedAxes; // axes used prior to minimization (if applicable)
-   
-   // Needed for compilation of non C++11 users
-   bool isnan(double para) { return para != para; }
+   // Intermediate constructor (needed to enable v1.0.3 backwards compatibility?)
+   Njettiness(AxesMode axes_mode, const MeasureDefinition & measure_def);
 
-   // Helpful function to check to make sure input has correct number of parameters
-   bool correctParameterCount(int n, double para1, double para2, double para3, double para4){
-      int numpara;
-      if (!isnan(para1) && !isnan(para2) && !isnan(para3) && !isnan(para4)) numpara = 4;
-      else if (!isnan(para1) && !isnan(para2) && !isnan(para3) && isnan(para4)) numpara = 3;
-      else if (!isnan(para1) && !isnan(para2) && isnan(para3) && isnan(para4)) numpara = 2;
-      else if (!isnan(para1) && isnan(para2) && isnan(para3) && isnan(para4)) numpara = 1;
-      else numpara = 0;
-      return n == numpara;
+   // Alternative constructor which takes axes/measure information as enums with measure parameters
+   // This version is not recommended
+   Njettiness(AxesMode axes_mode,
+              MeasureMode measure_mode,
+              int num_para,
+              double para1 = std::numeric_limits<double>::quiet_NaN(),
+              double para2 = std::numeric_limits<double>::quiet_NaN(),
+              double para3 = std::numeric_limits<double>::quiet_NaN())
+   : _axes_def(createAxesDef(axes_mode)), _measure_def(createMeasureDef(measure_mode, num_para, para1, para2, para3)) {
+      setMeasureFunctionAndAxesFinder();  // call helper function to do the hard work
    }
 
-   // Helper function to set onepass_axes depending on input measure_mode and startingFinder
-   void setOnePassAxesFinder(MeasureMode measure_mode, AxesFinder* startingFinder, double para1, double Rcutoff);
- 
-   // created separate function to set MeasureFunction and AxesFinder in order to keep constructor cleaner.
-   void setMeasureFunctionandAxesFinder(AxesMode axes_mode, MeasureMode measure_mode, double para1, double para2, double para3, double para4);
-
-public:
-
-
-   // Main constructor which takes axes/measure information, and possible parameters.
-   // Unlike Nsubjettiness or NjettinessPlugin, the value N is not chosen
-   Njettiness(AxesMode axes_mode,
-              MeasureMode measure_mode,
-              double para1 = NAN,
-              double para2 = NAN,
-              double para3 = NAN,
-              double para4 = NAN)
-   : _current_axes_mode(axes_mode),
-   _current_measure_mode(measure_mode) {
-      setMeasureFunctionandAxesFinder(axes_mode, measure_mode, para1, para2, para3, para4);  // call helper function to do the hard work
-   }
-
-   ~Njettiness() {
-      // clean house
-      delete _measureFunction;
-      delete _axesFinder;
-   }
+   // destructor
+   ~Njettiness() {};
    
    // setAxes for Manual mode
-   void setAxes(std::vector<fastjet::PseudoJet> myAxes);
+   void setAxes(const std::vector<fastjet::PseudoJet> & myAxes);
    
    // Calculates and returns all TauComponents that user would want.
    // This information is stored in _current_tau_components for later access as well.
-   TauComponents getTauComponents(unsigned n_jets, const std::vector<fastjet::PseudoJet> & inputJets);
+   TauComponents getTauComponents(unsigned n_jets, const std::vector<fastjet::PseudoJet> & inputJets) const;
 
    // Calculates the value of N-subjettiness,
    // but only returns the tau value from _current_tau_components
-   double getTau(unsigned n_jets, const std::vector<fastjet::PseudoJet> & inputJets) {
+   double getTau(unsigned n_jets, const std::vector<fastjet::PseudoJet> & inputJets) const {
       return getTauComponents(n_jets, inputJets).tau();
    }
-   
-   // returns enum information
-   MeasureMode currentMeasureMode() { return _current_measure_mode;}
-   AxesMode currentAxesMode() { return _current_axes_mode;}
 
    // Return all relevant information about tau components
-   TauComponents currentTauComponents() {return _current_tau_components;}
-   
+   TauComponents currentTauComponents() const {return _current_tau_components;}
    // Return axes found by getTauComponents.
-   std::vector<fastjet::PseudoJet> currentAxes() { return _currentAxes;}
+   std::vector<fastjet::PseudoJet> currentAxes() const { return _currentAxes;}
    // Return seedAxes used if onepass minimization (otherwise, same as currentAxes)
-   std::vector<fastjet::PseudoJet> seedAxes() { return _seedAxes;}
+   std::vector<fastjet::PseudoJet> seedAxes() const { return _seedAxes;}
+   // Return jet partition found by getTauComponents.
+   std::vector<fastjet::PseudoJet> currentJets() const {return _currentJets;}
+   // Return beam partition found by getTauComponents.
+   fastjet::PseudoJet currentBeam() const {return _currentBeam;}
    
    // partition inputs by Voronoi (each vector stores indices corresponding to inputJets)
-   std::vector<std::list<int> > getPartition(const std::vector<fastjet::PseudoJet> & inputJets);
+   std::vector<std::list<int> > getPartitionList(const std::vector<fastjet::PseudoJet> & inputJets) const;
 
-   // partition inputs by Voronoi
-   std::vector<fastjet::PseudoJet> getJets(const std::vector<fastjet::PseudoJet> & inputJets);
+private:
+   
+   // Information about Axes and Measures to be Used
+   // Implemented as SharedPtrs to avoid memory management headaches
+   SharedPtr<const AxesDefinition> _axes_def;
+   SharedPtr<const MeasureDefinition> _measure_def;
+   
+   // The chosen axes/measure mode workers
+   // Implemented as SharedPtrs to avoid memory management headaches
+   // TODO: make into a SharedPtr<const AxesFinder>?
+   SharedPtr<MeasureFunction> _measureFunction;  // The chosen measure
+   SharedPtr<AxesFinder> _startingAxesFinder;    // The initial axes finder
+   SharedPtr<AxesFinder> _finishingAxesFinder;   // A possible minimization step
+   
+   // Information about the current information
+   // Defined as mutables, so user should be aware that these change when getTau is called.
+   mutable TauComponents _current_tau_components; //automatically set to have components of 0; these values will be set by the getTau function call
+   mutable std::vector<fastjet::PseudoJet> _currentAxes; //axes found after minimization
+   mutable std::vector<fastjet::PseudoJet> _seedAxes; // axes used prior to minimization (if applicable)
+   mutable std::vector<fastjet::PseudoJet> _currentJets; //partitioning information
+   mutable fastjet::PseudoJet _currentBeam; //return beam, if requested
+   
+   // created separate function to set MeasureFunction and AxesFinder in order to keep constructor cleaner.
+   void setMeasureFunctionAndAxesFinder();
+   
+   // Convert old style enums into new style MeasureDefinition
+   AxesDefinition* createAxesDef(AxesMode axes_mode) const;
+   
+   // Convert old style enums into new style MeasureDefinition
+   MeasureDefinition* createMeasureDef(MeasureMode measure_mode, int num_para, double para1, double para2, double para3) const;
 
 };
-
+   
 } // namespace contrib
 
Index: external/fastjet/contribs/Nsubjettiness/NjettinessDefinition.cc
===================================================================
--- external/fastjet/contribs/Nsubjettiness/NjettinessDefinition.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/contribs/Nsubjettiness/NjettinessDefinition.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,76 @@
+//  Nsubjettiness Package
+//  Questions/Comments?  jthaler@jthaler.net
+//
+//  Copyright (c) 2011-14
+//  Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason
+//
+//  $Id: NjettinessDefinition.cc 704 2014-07-07 14:30:43Z jthaler $
+//----------------------------------------------------------------------
+// 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 "NjettinessDefinition.hh"
+
+FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
+
+namespace contrib {
+
+   std::string NormalizedMeasure::description() const {
+      std::stringstream stream;
+      stream << std::fixed << std::setprecision(2)
+      << "Normalized Measure (beta = " << _beta << ", R0 = " << _R0 << ")";
+      return stream.str();
+   };
+   
+   std::string UnnormalizedMeasure::description() const {
+      std::stringstream stream;
+      stream << std::fixed << std::setprecision(2)
+      << "Unnormalized Measure (beta = " << _beta << ", in GeV)";
+      return stream.str();
+   };
+   
+   std::string GeometricMeasure::description() const {
+      std::stringstream stream;
+      stream << std::fixed << std::setprecision(2)
+      << "Geometric Measure (beta = " << _beta << ", in GeV)";
+      return stream.str();
+   };
+   
+   std::string NormalizedCutoffMeasure::description() const {
+      std::stringstream stream;
+      stream << std::fixed << std::setprecision(2)
+      << "Normalized Cutoff Measure (beta = " << _beta << ", R0 = " << _R0 << ", Rcut = " << _Rcutoff << ")";
+      return stream.str();
+   };
+   
+   std::string UnnormalizedCutoffMeasure::description() const {
+      std::stringstream stream;
+      stream << std::fixed << std::setprecision(2)
+      << "Unnormalized Cutoff Measure (beta = " << _beta << ", Rcut = " << _Rcutoff << ", in GeV)";
+      return stream.str();
+   };
+   
+   std::string GeometricCutoffMeasure::description() const {
+      std::stringstream stream;
+      stream << std::fixed << std::setprecision(2)
+      << "Geometric Cutoff Measure (beta = " << _beta << ", Rcut = " << _Rcutoff << ", in GeV)";
+      return stream.str();
+   };
+   
+   
+} // namespace contrib
+
+FASTJET_END_NAMESPACE
Index: external/fastjet/contribs/Nsubjettiness/NjettinessDefinition.hh
===================================================================
--- external/fastjet/contribs/Nsubjettiness/NjettinessDefinition.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/contribs/Nsubjettiness/NjettinessDefinition.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,721 @@
+//  Nsubjettiness Package
+//  Questions/Comments?  jthaler@jthaler.net
+//
+//  Copyright (c) 2011-14
+//  Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason
+//
+//  $Id: NjettinessDefinition.hh 704 2014-07-07 14:30:43Z jthaler $
+//----------------------------------------------------------------------
+// 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_NJETTINESS_DEFINITION_HH__
+#define __FASTJET_CONTRIB_NJETTINESS_DEFINITION_HH__
+
+
+#include "MeasureFunction.hh"
+#include "AxesFinder.hh"
+
+#include "fastjet/PseudoJet.hh"
+#include <fastjet/LimitedWarning.hh>
+
+#include <iomanip>
+#include <cmath>
+#include <vector>
+#include <list>
+
+FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
+
+namespace contrib {
+   
+// Eventually this file might contains an NjettinessDefinition that combines an
+// AxesDefinition with a MeasureDefinition. It's not clear how useful that would be, though
+  
+// The following Measures are available (and the relevant arguments):
+class NormalizedMeasure;         // (beta,R0)
+class UnnormalizedMeasure;       // (beta)
+class GeometricMeasure;          // (beta)
+class NormalizedCutoffMeasure;   // (beta,R0,Rcutoff)
+class UnnormalizedCutoffMeasure; // (beta,Rcutoff)
+class GeometricCutoffMeasure;    // (beta,Rcutoff)
+
+// The following Axes are available (and the relevant arguments, if needed)
+class KT_Axes;
+class CA_Axes;
+class AntiKT_Axes;   // (R0)
+class WTA_KT_Axes;
+class WTA_CA_Axes;
+class Manual_Axes;
+class OnePass_KT_Axes;
+class OnePass_CA_Axes;
+class OnePass_AntiKT_Axes;   // (R0)
+class OnePass_WTA_KT_Axes;
+class OnePass_WTA_CA_Axes;
+class OnePass_Manual_Axes;
+class MultiPass_Axes;
+
+// Below are just technical implementations of the variable axes and measures.
+  
+///////
+//
+// MeasureDefinition
+//
+///////
+
+//The MeasureDefinition is a way to set the MeasureMode and
+//parameters used by Njettiness, with errors in the number of parameters given at
+//compile time (instead of at run time).  The MeasureDefintion knows which core objects
+//to call to make the measurement, as well as properties of the MeasureFunction
+class MeasureDefinition {
+   
+public:
+
+   // Description of measure and parameters
+   virtual std::string description() const = 0;
+   
+   // In derived classes, this should return a copy of the corresponding
+   // derived class
+   virtual MeasureDefinition* create() const = 0;
+   
+   //Return the MeasureFunction corresponding to this definition
+   virtual MeasureFunction* createMeasureFunction() const = 0;
+   
+   //Return the AxesFinder that should be used for one-pass minimization
+   virtual AxesFinder* createOnePassAxesFinder() const = 0;
+
+   //Specify whether multi-pass minimization makes sense, and if so, return the AxesFinder that should be used for multi-pass minimization
+   virtual bool supportsMultiPassMinimization() const = 0;
+   virtual AxesFinder* createMultiPassAxesFinder( unsigned int) const = 0;
+   
+   virtual ~MeasureDefinition(){};
+};
+
+// The normalized measure, with two parameters: beta and R0
+class NormalizedMeasure : public MeasureDefinition {
+   
+public:
+   NormalizedMeasure(double beta, double R0)
+   : _beta(beta), _R0(R0) {}
+   
+   virtual std::string description() const;
+
+   virtual MeasureFunction* createMeasureFunction() const {
+      return (new DefaultNormalizedMeasureFunction(_beta,_R0,std::numeric_limits<double>::max()));
+   }
+
+   virtual NormalizedMeasure* create() const {return new NormalizedMeasure(*this);}
+   
+   virtual AxesFinder* createOnePassAxesFinder() const {
+      return (new AxesFinderFromOnePassMinimization(_beta, std::numeric_limits<double>::max()));
+   }
+   virtual AxesFinder* createMultiPassAxesFinder( unsigned int Npass) const {
+      return (new AxesFinderFromKmeansMinimization(_beta, std::numeric_limits<double>::max(),Npass));
+   }
+
+   virtual bool supportsMultiPassMinimization() const { return true; }
+   
+private:
+   double _beta;
+   double _R0;
+};
+   
+// The unnormalized measure, with just one parameter: beta
+class UnnormalizedMeasure : public MeasureDefinition {
+
+public:
+   UnnormalizedMeasure(double beta)
+   : _beta(beta) {}
+
+   virtual UnnormalizedMeasure* create() const {return new UnnormalizedMeasure(*this);}
+   
+   virtual std::string description() const;
+   
+   virtual MeasureFunction* createMeasureFunction() const {
+      return (new DefaultUnnormalizedMeasureFunction(_beta,std::numeric_limits<double>::max()));
+   }
+
+   
+   virtual AxesFinder* createOnePassAxesFinder() const {
+      return (new AxesFinderFromOnePassMinimization(_beta, std::numeric_limits<double>::max()));
+   }
+   virtual AxesFinder* createMultiPassAxesFinder( unsigned int Npass) const {
+      return (new AxesFinderFromKmeansMinimization(_beta, std::numeric_limits<double>::max(),Npass));
+   }
+
+   virtual bool supportsMultiPassMinimization() const { return true; }
+
+private:
+   double _beta;
+};
+   
+   
+// The geometric  measure, with 1 parameter: beta
+// This measure is still evolving and shouldn't be used for any critial applications yet
+class GeometricMeasure : public MeasureDefinition {
+   
+public:
+   GeometricMeasure(double beta)
+   : _beta(beta) {}
+   
+   virtual GeometricMeasure* create() const {return new GeometricMeasure(*this);}
+   
+   virtual std::string description() const;
+   
+   virtual MeasureFunction* createMeasureFunction() const {
+      return (new GeometricMeasureFunction(_beta,std::numeric_limits<double>::max()));
+   }
+   
+   virtual AxesFinder* createOnePassAxesFinder() const {
+      return (new AxesFinderFromGeometricMinimization(_beta, std::numeric_limits<double>::max()));
+   }
+   virtual AxesFinder* createMultiPassAxesFinder(unsigned int) const {
+      throw Error("GeometricMeasure does not support multi-pass minimization.");
+      return NULL;
+   }
+   
+   virtual bool supportsMultiPassMinimization() const { return false; }
+
+private:
+   double _beta;
+
+};
+
+
+// The normalized cutoff measure, with 3 parameters: beta, R0, Rcutoff
+class NormalizedCutoffMeasure : public MeasureDefinition {
+
+public:
+   NormalizedCutoffMeasure(double beta, double R0, double Rcutoff)
+   : _beta(beta), _R0(R0), _Rcutoff(Rcutoff) {}
+
+   virtual std::string description() const;
+   
+   virtual NormalizedCutoffMeasure* create() const {return new NormalizedCutoffMeasure(*this);}
+   
+   virtual MeasureFunction* createMeasureFunction() const {
+      return (new DefaultNormalizedMeasureFunction(_beta,_R0,_Rcutoff));
+   }
+   
+   virtual AxesFinder* createOnePassAxesFinder() const {
+      return (new AxesFinderFromOnePassMinimization(_beta, _Rcutoff));
+   }
+   virtual AxesFinder* createMultiPassAxesFinder( unsigned int Npass) const {
+      return (new AxesFinderFromKmeansMinimization(_beta, std::numeric_limits<double>::max(),Npass));
+   }
+  
+   virtual bool supportsMultiPassMinimization() const { return true; }
+
+private:
+   double _beta;
+   double _R0;
+   double _Rcutoff;
+   
+};
+
+// The unnormalized cutoff measure, with 2 parameters: beta, Rcutoff
+class UnnormalizedCutoffMeasure : public MeasureDefinition {
+   
+public:
+   UnnormalizedCutoffMeasure(double beta, double Rcutoff)
+   : _beta(beta), _Rcutoff(Rcutoff) {}
+
+   virtual std::string description() const;
+   
+   virtual UnnormalizedCutoffMeasure* create() const {return new UnnormalizedCutoffMeasure(*this);}
+
+   virtual MeasureFunction* createMeasureFunction() const {
+      return (new DefaultUnnormalizedMeasureFunction(_beta,_Rcutoff));
+   }
+   
+   virtual AxesFinder* createOnePassAxesFinder() const {
+      return (new AxesFinderFromOnePassMinimization(_beta, _Rcutoff));
+   }
+   virtual AxesFinder* createMultiPassAxesFinder( unsigned int Npass) const {
+      return (new AxesFinderFromKmeansMinimization(_beta, std::numeric_limits<double>::max(),Npass));
+   }
+
+   virtual bool supportsMultiPassMinimization() const { return true; }
+
+private:
+   double _beta;
+   double _Rcutoff;
+   
+};
+
+// The Geometric  measure, with 2 parameters: beta, Rcutoff
+// This measure is still evolving and shouldn't be used for any critial applications yet
+class GeometricCutoffMeasure : public MeasureDefinition {
+   
+public:
+   GeometricCutoffMeasure(double beta, double Rcutoff)
+   : _beta(beta), _Rcutoff(Rcutoff) {}
+
+   virtual GeometricCutoffMeasure* create() const {return new GeometricCutoffMeasure(*this);}
+
+   virtual std::string description() const;
+   
+   virtual MeasureFunction* createMeasureFunction() const {
+      return (new GeometricMeasureFunction(_beta,_Rcutoff));
+   }
+   
+   virtual AxesFinder* createOnePassAxesFinder() const {
+      return (new AxesFinderFromGeometricMinimization(_beta, _Rcutoff));
+   }
+   virtual AxesFinder* createMultiPassAxesFinder(unsigned int) const {
+      throw Error("GeometricCutoffMeasure does not support multi-pass minimization.");
+      return NULL;
+   }
+   
+   virtual bool supportsMultiPassMinimization() const { return false; }
+
+private:
+   double _beta;
+   double _Rcutoff;
+   
+};
+   
+   
+///////
+//
+// AxesDefinition
+//
+///////
+
+//Analogous to MeasureDefinition, AxesDefinition defines which AxesFinder to use
+//At the moment, most AxesDefinition do not have an arugment (except the Anti-KT ones)
+class AxesDefinition {
+   
+public:
+   // description of axes (and any parameters)
+   virtual std::string short_description() const = 0;
+   virtual std::string description() const = 0;
+   
+   // In derived classes, this should return a copy of the corresponding
+   // derived class
+   virtual AxesDefinition* create() const = 0;
+   
+   // These describe how the axes finder works
+   virtual bool givesRandomizedResults() const = 0;
+   virtual bool supportsManualAxes() const = 0;
+   
+   //for best testing
+   virtual AxesFinder* createStartingAxesFinder(const MeasureDefinition &) const = 0;
+   virtual AxesFinder* createFinishingAxesFinder(const MeasureDefinition &) const {
+      return NULL;  //By default, nothing.
+   };
+
+   virtual ~AxesDefinition() {};
+};
+
+// kt axes
+class KT_Axes : public AxesDefinition {
+public:
+   KT_Axes() {}
+
+   virtual std::string short_description() const {
+      return "KT";
+   };
+   
+   virtual std::string description() const {
+      std::stringstream stream;
+      stream << std::fixed << std::setprecision(2)
+      << "KT Axes";
+      return stream.str();
+   };
+   
+   virtual KT_Axes* create() const {return new KT_Axes(*this);}
+
+   virtual bool givesRandomizedResults() const {return false;}
+   virtual bool supportsManualAxes() const {return false;}
+
+   virtual AxesFinder* createStartingAxesFinder(const MeasureDefinition &) const {
+      return (new AxesFinderFromKT());
+   }
+   
+};
+
+// ca axes
+class CA_Axes : public AxesDefinition {
+public:
+   CA_Axes() {}
+
+   virtual std::string short_description() const {
+      return "CA";
+   };
+   
+   virtual std::string description() const {
+      std::stringstream stream;
+      stream << std::fixed << std::setprecision(2)
+      << "CA Axes";
+      return stream.str();
+   };
+   
+   virtual CA_Axes* create() const {return new CA_Axes(*this);}
+
+   virtual bool givesRandomizedResults() const {return false;}
+   virtual bool supportsManualAxes() const {return false;}
+
+   virtual AxesFinder* createStartingAxesFinder(const MeasureDefinition &) const {
+      return (new AxesFinderFromCA());
+   }
+   
+};
+
+// anti-kt axes, one parameter R0 is subjet radius
+class AntiKT_Axes : public AxesDefinition {
+
+public:
+   AntiKT_Axes(double R0 = 0.2): _R0(R0) {}
+
+   virtual std::string short_description() const {
+      std::stringstream stream;
+      stream << std::fixed << std::setprecision(2)
+      << "AKT" << _R0;
+      return stream.str();
+   };
+   
+   virtual std::string description() const {
+      std::stringstream stream;
+      stream << std::fixed << std::setprecision(2)
+      << "Anti-KT Axes (R0 = " << _R0 << ")";
+      return stream.str();
+   };
+   
+   virtual AntiKT_Axes* create() const {return new AntiKT_Axes(*this);}
+
+   virtual bool givesRandomizedResults() const {return false;}
+   virtual bool supportsManualAxes() const {return false;}
+
+   virtual AxesFinder* createStartingAxesFinder(const MeasureDefinition &) const {
+      return (new AxesFinderFromAntiKT(_R0));
+   }
+   
+   
+private:
+   double _R0;
+
+};
+
+// winner-take-all recombination with kt axes
+class WTA_KT_Axes : public AxesDefinition {
+public:
+   WTA_KT_Axes() {}
+
+   virtual std::string short_description() const {
+      return "WTA KT";
+   };
+   
+   virtual std::string description() const {
+      std::stringstream stream;
+      stream << std::fixed << std::setprecision(2)
+      << "Winner-Take-All KT Axes";
+      return stream.str();
+   };
+   
+   virtual WTA_KT_Axes* create() const {return new WTA_KT_Axes(*this);}
+
+   virtual bool givesRandomizedResults() const {return false;}
+   virtual bool supportsManualAxes() const {return false;}
+
+   virtual AxesFinder* createStartingAxesFinder(const MeasureDefinition &) const {
+      return (new AxesFinderFromWTA_KT());
+   }
+
+   
+};
+
+// winner-take-all recombination with CA axes
+class WTA_CA_Axes : public AxesDefinition {
+public:
+   WTA_CA_Axes() {}
+
+   virtual std::string short_description() const {
+      return "WTA CA";
+   };
+   
+   virtual std::string description() const {
+      std::stringstream stream;
+      stream << std::fixed << std::setprecision(2)
+      << "Winner-Take-All CA Axes";
+      return stream.str();
+   };
+   
+   virtual WTA_CA_Axes* create() const {return new WTA_CA_Axes(*this);}
+
+   virtual bool givesRandomizedResults() const {return false;}
+   virtual bool supportsManualAxes() const {return false;}
+
+   virtual AxesFinder* createStartingAxesFinder(const MeasureDefinition &) const {
+      return (new AxesFinderFromWTA_CA());
+   }
+   
+};
+   
+// Onepass minimization from kt axes
+class OnePass_KT_Axes : public AxesDefinition {
+public:
+   OnePass_KT_Axes() {}
+   
+   virtual std::string short_description() const {
+      return "OnePass KT";
+   };
+   
+   virtual std::string description() const {
+      std::stringstream stream;
+      stream << std::fixed << std::setprecision(2)
+      << "One-Pass Minimization from KT Axes";
+      return stream.str();
+   };
+   
+   virtual OnePass_KT_Axes* create() const {return new OnePass_KT_Axes(*this);}
+   
+   virtual bool givesRandomizedResults() const {return false;}
+   virtual bool supportsManualAxes() const {return false;}
+
+   virtual AxesFinder* createStartingAxesFinder(const MeasureDefinition & ) const {
+      return (new AxesFinderFromKT());
+   }
+   virtual AxesFinder* createFinishingAxesFinder(const MeasureDefinition & measure_def) const {
+      return measure_def.createOnePassAxesFinder();
+   }
+
+};
+
+// Onepass minimization from CA axes
+class OnePass_CA_Axes : public AxesDefinition {
+public:
+   OnePass_CA_Axes() {}
+
+   virtual std::string short_description() const {
+      return "OnePass CA";
+   };
+   
+   virtual std::string description() const {
+      std::stringstream stream;
+      stream << std::fixed << std::setprecision(2)
+      << "One-Pass Minimization from CA Axes";
+      return stream.str();
+   };
+   
+   virtual OnePass_CA_Axes* create() const {return new OnePass_CA_Axes(*this);}
+
+   virtual bool givesRandomizedResults() const {return false;}
+   virtual bool supportsManualAxes() const {return false;}
+
+   virtual AxesFinder* createStartingAxesFinder(const MeasureDefinition & ) const {
+      return (new AxesFinderFromCA());
+   }
+   virtual AxesFinder* createFinishingAxesFinder(const MeasureDefinition & measure_def) const {
+      return measure_def.createOnePassAxesFinder();
+   }
+};
+
+// Onepass minimization from AntiKT axes, one parameter R0
+class OnePass_AntiKT_Axes : public AxesDefinition {
+
+public:
+   OnePass_AntiKT_Axes(double R0): _R0(R0) {}
+   
+   virtual std::string short_description() const {
+      std::stringstream stream;
+      stream << std::fixed << std::setprecision(2)
+      << "OnePassAKT" << _R0;
+      return stream.str();
+   };
+   
+   virtual std::string description() const {
+      std::stringstream stream;
+      stream << std::fixed << std::setprecision(2)
+      << "One-Pass Minimization from Anti-KT Axes (R0 = " << _R0 << ")";
+      return stream.str();
+   };
+   
+   virtual OnePass_AntiKT_Axes* create() const {return new OnePass_AntiKT_Axes(*this);}
+
+   virtual bool givesRandomizedResults() const {return false;}
+   virtual bool supportsManualAxes() const {return false;}
+
+   virtual AxesFinder* createStartingAxesFinder(const MeasureDefinition & ) const {
+      return (new AxesFinderFromAntiKT(_R0));
+   }
+   virtual AxesFinder* createFinishingAxesFinder(const MeasureDefinition & measure_def) const {
+      return measure_def.createOnePassAxesFinder();
+   }
+
+private:
+   double _R0;
+};
+
+// Onepass minimization from winner-take-all kt axes
+class OnePass_WTA_KT_Axes : public AxesDefinition {
+public:
+   OnePass_WTA_KT_Axes() {}
+   
+   virtual std::string short_description() const {
+      return "OnePass WTA KT";
+   };
+   
+   virtual std::string description() const {
+      std::stringstream stream;
+      stream << std::fixed << std::setprecision(2)
+      << "One-Pass Minimization from Winner-Take-All KT Axes";
+      return stream.str();
+   };
+   
+   virtual OnePass_WTA_KT_Axes* create() const {return new OnePass_WTA_KT_Axes(*this);}
+   
+   virtual bool givesRandomizedResults() const {return false;}
+   virtual bool supportsManualAxes() const {return false;}
+
+   virtual AxesFinder* createStartingAxesFinder(const MeasureDefinition & ) const {
+      return (new AxesFinderFromWTA_KT());
+   }
+   virtual AxesFinder* createFinishingAxesFinder(const MeasureDefinition & measure_def) const {
+      return measure_def.createOnePassAxesFinder();
+   }
+};
+
+
+// Onepass minimization from winner-take-all CA axes
+class OnePass_WTA_CA_Axes : public AxesDefinition {
+public:
+   OnePass_WTA_CA_Axes() {}
+
+   virtual std::string short_description() const {
+      return "OnePass WTA CA";
+   };
+   
+   virtual std::string description() const {
+      std::stringstream stream;
+      stream << std::fixed << std::setprecision(2)
+      << "One-Pass Minimization from Winner-Take-All CA Axes";
+      return stream.str();
+   };
+   
+   virtual OnePass_WTA_CA_Axes* create() const {return new OnePass_WTA_CA_Axes(*this);}
+   
+
+   virtual bool givesRandomizedResults() const {return false;}
+   virtual bool supportsManualAxes() const {return false;}
+
+   
+   virtual AxesFinder* createStartingAxesFinder(const MeasureDefinition & ) const {
+      return (new AxesFinderFromWTA_CA());
+   }
+   virtual AxesFinder* createFinishingAxesFinder(const MeasureDefinition & measure_def) const {
+      return measure_def.createOnePassAxesFinder();
+   }
+
+   
+};
+   
+// set axes manually
+class Manual_Axes : public AxesDefinition {
+public:
+   Manual_Axes() {}
+   
+   virtual std::string short_description() const {
+      return "Manual";
+   };
+   
+   virtual std::string description() const {
+      std::stringstream stream;
+      stream << std::fixed << std::setprecision(2)
+      << "Manual Axes";
+      return stream.str();
+   };
+   
+   virtual Manual_Axes* create() const {return new Manual_Axes(*this);}
+
+   virtual bool givesRandomizedResults() const {return false;}
+   virtual bool supportsManualAxes() const {return true;}
+
+   virtual AxesFinder* createStartingAxesFinder(const MeasureDefinition &) const {
+      return (new AxesFinderFromUserInput());
+   }
+};
+
+// one pass minimization from manual starting point
+class OnePass_Manual_Axes : public AxesDefinition {
+public:
+   OnePass_Manual_Axes() {}
+
+   virtual std::string short_description() const {
+      return "OnePass Manual";
+   };
+   
+   virtual std::string description() const {
+      std::stringstream stream;
+      stream << std::fixed << std::setprecision(2)
+      << "One-Pass Minimization from Manual Axes";
+      return stream.str();
+   };
+   
+   virtual OnePass_Manual_Axes* create() const {return new OnePass_Manual_Axes(*this);}
+
+   virtual bool givesRandomizedResults() const {return false;}
+   virtual bool supportsManualAxes() const {return true;}
+
+   virtual AxesFinder* createStartingAxesFinder(const MeasureDefinition & ) const {
+      return (new AxesFinderFromUserInput());
+   }
+   virtual AxesFinder* createFinishingAxesFinder(const MeasureDefinition & measure_def) const {
+      return measure_def.createOnePassAxesFinder();
+   }
+
+   
+};
+   
+// multi-pass minimization from kT starting point
+class MultiPass_Axes : public AxesDefinition {
+
+public:
+   MultiPass_Axes(unsigned int Npass) : _Npass(Npass) {}
+
+   virtual std::string short_description() const {
+      return "MultiPass";
+   };
+   
+   virtual std::string description() const {
+      std::stringstream stream;
+      stream << std::fixed << std::setprecision(2)
+      << "Multi-Pass Axes (Npass = " << _Npass << ")";
+      return stream.str();
+   };
+   
+   virtual MultiPass_Axes* create() const {return new MultiPass_Axes(*this);}
+
+   virtual bool givesRandomizedResults() const {return true;}
+   virtual bool supportsManualAxes() const {return false;}
+
+   virtual AxesFinder* createStartingAxesFinder(const MeasureDefinition & ) const {
+      return (new AxesFinderFromKT());
+   }
+   virtual AxesFinder* createFnishingAxesFinder(const MeasureDefinition & measure_def) const {
+      return measure_def.createMultiPassAxesFinder(_Npass);
+   }
+   
+private:
+   unsigned int _Npass;
+   
+};
+   
+} // namespace contrib
+
+FASTJET_END_NAMESPACE
+
+#endif  // __FASTJET_CONTRIB_NJETTINESS_HH__
+
Index: external/fastjet/contribs/Nsubjettiness/NjettinessPlugin.cc
===================================================================
--- external/fastjet/contribs/Nsubjettiness/NjettinessPlugin.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/contribs/Nsubjettiness/NjettinessPlugin.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -5,4 +5,5 @@
 //  Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason
 //
+//  $Id: NjettinessPlugin.cc 663 2014-06-03 21:26:41Z jthaler $
 //----------------------------------------------------------------------
 // This file is part of FastJet contrib.
@@ -29,26 +30,31 @@
 
 
-// Constructor with same arguments as Nsubjettiness.
-NjettinessPlugin::NjettinessPlugin(int N, Njettiness::AxesMode axes_mode, Njettiness::MeasureMode measure_mode, double para1, double para2, double para3, double para4)
-  : _N(N), _njettinessFinder(axes_mode, measure_mode, para1, para2, para3, para4) {}
-
-// Old constructor for compatibility
-NjettinessPlugin::NjettinessPlugin(int N, Njettiness::AxesMode mode, double beta, double R0, double Rcutoff)
-   : _N(N), _njettinessFinder(mode, Njettiness::normalized_cutoff_measure, beta, R0, Rcutoff) {}
 
 std::string NjettinessPlugin::description() const {return "N-jettiness jet finder";}
 
+
 // Clusters the particles according to the Njettiness jet algorithm
-// TODO: this code should be revisited to see if if can be made more clear.
+// Apologies for the complication with this code, but we need to make
+// a fake jet clustering tree.  The partitioning is done by getPartitionList
 void NjettinessPlugin::run_clustering(ClusterSequence& cs) const
 {
    std::vector<fastjet::PseudoJet> particles = cs.jets();
+
+   // HACK: remove area information from particles (in case this is called by
+   // a ClusterSequenceArea.  Will be fixed in a future FastJet release)
+   for (unsigned i = 0; i < particles.size(); i++) {
+      particles[i].set_structure_shared_ptr(SharedPtr<PseudoJetStructureBase>());
+   }
+   
+   
    _njettinessFinder.getTau(_N, particles);
-   std::vector<std::list<int> > partition = _njettinessFinder.getPartition(particles);
+
+   std::vector<std::list<int> > partition = _njettinessFinder.getPartitionList(particles);
 
    std::vector<fastjet::PseudoJet> jet_indices_for_extras;
 
    // output clusterings for each jet
-   for (size_t i = 0; i < partition.size(); ++i) {
+   for (size_t i0 = 0; i0 < partition.size(); ++i0) {
+      size_t i = partition.size() - 1 - i0; // reversed order of reading to match axes order
       std::list<int>& indices = partition[i];
       if (indices.size() == 0) continue;
@@ -70,4 +76,7 @@
    }
 
+   //HACK:  Re-reverse order of reading to match CS order
+   reverse(jet_indices_for_extras.begin(),jet_indices_for_extras.end());
+
    NjettinessExtras * extras = new NjettinessExtras(_njettinessFinder.currentTauComponents(),jet_indices_for_extras,_njettinessFinder.currentAxes());
    cs.plugin_associate_extras(std::auto_ptr<ClusterSequence::Extras>(extras));
Index: external/fastjet/contribs/Nsubjettiness/NjettinessPlugin.hh
===================================================================
--- external/fastjet/contribs/Nsubjettiness/NjettinessPlugin.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/contribs/Nsubjettiness/NjettinessPlugin.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,4 +1,2 @@
-// $Id$
-//
 //  Nsubjettiness Package
 //  Questions/Comments?  jthaler@jthaler.net
@@ -7,4 +5,5 @@
 //  Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason
 //
+//  $Id: NjettinessPlugin.hh 671 2014-06-10 17:47:52Z jthaler $
 //----------------------------------------------------------------------
 // This file is part of FastJet contrib.
@@ -49,21 +48,5 @@
 // to similar information
 class NjettinessExtras : public ClusterSequence::Extras {
-   private:
-   
-      TauComponents _tau_components;
-      std::vector<fastjet::PseudoJet> _jets;
-      std::vector<fastjet::PseudoJet> _axes;
-      
-      int labelOf(const fastjet::PseudoJet& jet) const {
-         int thisJet = -1;
-         for (unsigned int i = 0; i < _jets.size(); i++) {
-            if (_jets[i].cluster_hist_index() == jet.cluster_hist_index()) {
-               thisJet = i;
-               break;
-            }
-         }
-         return thisJet;
-      }
-      
+   
    public:
       NjettinessExtras(TauComponents tau_components, std::vector<fastjet::PseudoJet> jets, std::vector<fastjet::PseudoJet> axes) : _tau_components(tau_components), _jets(jets), _axes(axes) {}
@@ -74,9 +57,10 @@
       std::vector<fastjet::PseudoJet> axes() const {return _axes;}
       
-      double totalTau(const fastjet::PseudoJet& jet) const {
+      double totalTau(const fastjet::PseudoJet& /*jet*/) const {
          return _tau_components.tau();
       }
+      
       double subTau(const fastjet::PseudoJet& jet) const {
-         if (labelOf(jet) == -1) return NAN;
+         if (labelOf(jet) == -1) return std::numeric_limits<double>::quiet_NaN(); // nonsense
          return _tau_components.jet_pieces()[labelOf(jet)];
       }
@@ -93,5 +77,21 @@
          return (labelOf(jet) >= 0);
       }
-
+   
+private:
+   
+   TauComponents _tau_components;
+   std::vector<fastjet::PseudoJet> _jets;
+   std::vector<fastjet::PseudoJet> _axes;
+   
+   int labelOf(const fastjet::PseudoJet& jet) const {
+      int thisJet = -1;
+      for (unsigned int i = 0; i < _jets.size(); i++) {
+         if (_jets[i].cluster_hist_index() == jet.cluster_hist_index()) {
+            thisJet = i;
+            break;
+         }
+      }
+      return thisJet;
+   }
 };
 
@@ -122,5 +122,5 @@
  * onepass_wta_kt_axes  : one-pass minimization seeded by wta_kt
  *
- * For the unnormalized_measure, N-jettiness is defined as:
+ * For the UnnormalizedMeasure(beta), N-jettiness is defined as:
  *
  * tau_N = Sum_{all particles i} p_T^i min((DR_i1)^beta, (DR_i2)^beta, ...)
@@ -129,5 +129,5 @@
  *   and jet j.
  * 
- * The normalized_meausure include an extra parameter R0, and the various cutoff
+ * The NormalizedMeausure include an extra parameter R0, and the various cutoff
  * measures include an Rcutoff, which effectively defines an angular cutoff
  * similar in effect to a cone-jet radius.
@@ -138,19 +138,52 @@
 public:
 
-   NjettinessPlugin(int N,
-                    Njettiness::AxesMode axes_mode,
-                    Njettiness::MeasureMode measure_mode,
-                    double para1 = NAN,
-                    double para2 = NAN,
-                    double para3 = NAN,
-                    double para4 = NAN);
+   // Constructor with same arguments as Nsubjettiness.
+   NjettinessPlugin(int N,
+                    const AxesDefinition & axes_def,
+                    const MeasureDefinition & measure_def)
+   : _njettinessFinder(axes_def, measure_def), _N(N) {}
+   
+   
+   // Alternative constructors that define the measure via enums and parameters
+   // These constructors are likely be removed
+   NjettinessPlugin(int N,
+                 Njettiness::AxesMode axes_mode,
+                 Njettiness::MeasureMode measure_mode)
+   : _njettinessFinder(axes_mode, measure_mode, 0), _N(N) {}
+   
+   
+   NjettinessPlugin(int N,
+                 Njettiness::AxesMode axes_mode,
+                 Njettiness::MeasureMode measure_mode,
+                 double para1)
+   : _njettinessFinder(axes_mode, measure_mode, 1, para1), _N(N) {}
+   
+   
+   NjettinessPlugin(int N,
+                 Njettiness::AxesMode axes_mode,
+                 Njettiness::MeasureMode measure_mode,
+                 double para1,
+                 double para2)
+   : _njettinessFinder(axes_mode, measure_mode, 2, para1, para2), _N(N) {}
+   
+   
+   NjettinessPlugin(int N,
+                 Njettiness::AxesMode axes_mode,
+                 Njettiness::MeasureMode measure_mode,
+                 double para1,
+                 double para2,
+                 double para3)
+   : _njettinessFinder(axes_mode, measure_mode, 3, para1, para2, para3), _N(N) {}
+
 
    // Old constructor for backwards compatibility with v1.0,
-   // where normalized_cutoff_measure was the only option
+   // where NormalizedCutoffMeasure was the only option
    NjettinessPlugin(int N,
                     Njettiness::AxesMode mode,
                     double beta,
                     double R0,
-                    double Rcutoff=std::numeric_limits<double>::max());
+                    double Rcutoff=std::numeric_limits<double>::max())
+   : _njettinessFinder(mode, NormalizedCutoffMeasure(beta, R0, Rcutoff)), _N(N) {}
+
 
 
@@ -164,6 +197,6 @@
 private:
 
+   Njettiness _njettinessFinder;
    int _N;
-   mutable Njettiness _njettinessFinder; // TODO:  should muck with this so run_clustering can be const without this mutable
 
 };
Index: external/fastjet/contribs/Nsubjettiness/Nsubjettiness.cc
===================================================================
--- external/fastjet/contribs/Nsubjettiness/Nsubjettiness.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/contribs/Nsubjettiness/Nsubjettiness.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -5,4 +5,5 @@
 //  Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason
 //
+//  $Id: Nsubjettiness.cc 597 2014-04-16 23:07:55Z jthaler $
 //----------------------------------------------------------------------
 // This file is part of FastJet contrib.
Index: external/fastjet/contribs/Nsubjettiness/Nsubjettiness.hh
===================================================================
--- external/fastjet/contribs/Nsubjettiness/Nsubjettiness.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/contribs/Nsubjettiness/Nsubjettiness.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -5,4 +5,5 @@
 //  Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason
 //
+//  $Id: Nsubjettiness.hh 670 2014-06-06 01:24:42Z jthaler $
 //----------------------------------------------------------------------
 // This file is part of FastJet contrib.
@@ -32,5 +33,4 @@
 #include <string>
 #include <climits>
-
 
 FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
@@ -49,14 +49,67 @@
 public:
 
-   // Main constructor, which takes N, axes/measure modes,
-   // and up to four parameters for parameters (i.e. beta, Rcutoff, etc depending on measure)
+   
+   // Main constructor, which takes N, the AxesDefiniation, and the MeasureDefinition.
+   // The Definitions are given in NjettinessDefinition.hh
+   //
+   // The recommended AxesDefinitions are (more are available as listed in the README
+   // and defined in NjettinessDefinition.hh):
+   //   KT_Axes             : exclusive kt axes
+   //   WTA_KT_Axes         : exclusive kt with winner-take-all recombination
+   //   OnePass_KT_Axes     : one-pass minimization from kt starting point
+   //   OnePass_WTA_KT_Axes : one-pass min. from wta_kt starting point
+   //
+   // The recommended measure definitions are (with the corresponding parameters)
+   //   NormalizedMeasure(beta,R0)
+   //      :  This was the original N-subjettiness measure (dimensionless)
+   //   UnnormalizedMeasure(beta)
+   //      :  This is the new recommended default, same as above but without
+   //      :  the normalization factor, and hence has units of GeV
+   //   NormalizedCutoffMeasure(beta,R0,Rcutoff)
+   //      :  Same as normalized_measure, but cuts off at Rcutoff
+   //   UnnormalizedCutoffMeasure(beta,Rcutoff)
+   //      :  Same as unnormalized_measure, but cuts off at Rcutoff
+   Nsubjettiness(int N,
+                 const AxesDefinition& axes_def,
+                 const MeasureDefinition& measure_def)
+   : _njettinessFinder(axes_def,measure_def), _N(N) {}
+   
+   
+   // Alternative constructors that define the measure via enums and parameters
+   // These constructors are likely be removed
+   // Zero parameter arguments
+   // (Currently, no measure uses this)
+   Nsubjettiness(int N,
+                 Njettiness::AxesMode axes_mode,
+                 Njettiness::MeasureMode measure_mode)
+   : _njettinessFinder(axes_mode, measure_mode, 0), _N(N) {}
+
+   // One parameter argument
+   // (for unnormalized_measure, para1=beta)
    Nsubjettiness(int N,
                  Njettiness::AxesMode axes_mode,
                  Njettiness::MeasureMode measure_mode,
-                 double para1 = NAN,
-                 double para2 = NAN,
-                 double para3 = NAN,
-                 double para4 = NAN)
-   : _njettinessFinder(axes_mode, measure_mode, para1, para2, para3, para4), _N(N) {}
+                 double para1)
+   : _njettinessFinder(axes_mode, measure_mode, 1, para1), _N(N) {}
+
+   // Two parameter arguments
+   // (for normalized_measure, para1=beta, para2=R0)
+   // (for unnormalized_cutoff_measure, para1=beta, para2=Rcutoff)
+   Nsubjettiness(int N,
+                 Njettiness::AxesMode axes_mode,
+                 Njettiness::MeasureMode measure_mode,
+                 double para1,
+                 double para2)
+   : _njettinessFinder(axes_mode, measure_mode, 2, para1, para2), _N(N) {}
+
+   // Three parameter arguments
+   // (for unnormalized_cutoff_measure, para1=beta, para2=R0, para3=Rcutoff)
+   Nsubjettiness(int N,
+                 Njettiness::AxesMode axes_mode,
+                 Njettiness::MeasureMode measure_mode,
+                 double para1,
+                 double para2,
+                 double para3)
+   : _njettinessFinder(axes_mode, measure_mode, 3, para1, para2, para3), _N(N) {}
 
    // Old constructor for backwards compatibility with v1.0,
@@ -67,7 +120,6 @@
                  double R0,
                  double Rcutoff=std::numeric_limits<double>::max())
-   : _njettinessFinder(axes_mode, Njettiness::normalized_cutoff_measure, beta, R0, Rcutoff), _N(N) {}
-
-
+   : _njettinessFinder(axes_mode, NormalizedCutoffMeasure(beta,R0,Rcutoff)), _N(N) {}
+   
    /// returns tau_N, measured on the constituents of this jet 
    double result(const PseudoJet& jet) const;
@@ -86,6 +138,17 @@
    }
    
+   /// returns subjet regions found by result() calculation (these have valid constituents)
+   /// Note that the axes and the subjets are not the same
+   std::vector<fastjet::PseudoJet> currentSubjets() const {
+      return _njettinessFinder.currentJets();
+   }
+
+   /// returns components of tau_N without recalculating anything
+   TauComponents currentTauComponents() const {
+      return _njettinessFinder.currentTauComponents();
+   }
+   
    // To set axes for manual use
-   void setAxes(std::vector<fastjet::PseudoJet> myAxes) {
+   void setAxes(const std::vector<fastjet::PseudoJet> & myAxes) {
       // Cross check that manual axes are being used is in Njettiness
     	_njettinessFinder.setAxes(myAxes);
@@ -95,5 +158,5 @@
 private:
    
-   mutable Njettiness _njettinessFinder; // TODO:  should muck with this so result can be const without this mutable
+   Njettiness _njettinessFinder; // TODO:  should muck with this so result can be const without this mutable
    int _N;
 
@@ -112,14 +175,47 @@
    NsubjettinessRatio(int N,
                       int M,
+                      const AxesDefinition & axes_def,
+                      const MeasureDefinition & measure_def)
+   : _nsub_numerator(N,axes_def,measure_def),
+   _nsub_denominator(M,axes_def,measure_def) {}
+   
+   // Alternative constructor with enums and parameters
+   // Again, likely to be removed
+   NsubjettinessRatio(int N,
+                      int M,
+                      Njettiness::AxesMode axes_mode,
+                      Njettiness::MeasureMode measure_mode)
+   : _nsub_numerator(N, axes_mode, measure_mode),
+   _nsub_denominator(M, axes_mode, measure_mode) {}
+
+   
+   NsubjettinessRatio(int N,
+                      int M,
                       Njettiness::AxesMode axes_mode,
                       Njettiness::MeasureMode measure_mode,
-                      double para1 = NAN,
-                      double para2 = NAN,
-                      double para3 = NAN,
-                      double para4 = NAN)
-   : _nsub_numerator(N, axes_mode, measure_mode, para1, para2, para3, para4),
-   _nsub_denominator(M, axes_mode, measure_mode, para1, para2, para3, para4) {}
-
-   //returns tau_N/tau_M based off the input jet using result function from Nsubjettiness 
+                      double para1)
+   : _nsub_numerator(N, axes_mode, measure_mode, para1),
+   _nsub_denominator(M, axes_mode, measure_mode, para1) {}
+
+   NsubjettinessRatio(int N,
+                      int M,
+                      Njettiness::AxesMode axes_mode,
+                      Njettiness::MeasureMode measure_mode,
+                      double para1,
+                      double para2)
+   : _nsub_numerator(N, axes_mode, measure_mode, para1, para2),
+   _nsub_denominator(M, axes_mode, measure_mode, para1, para2) {}
+   
+   NsubjettinessRatio(int N,
+                      int M,
+                      Njettiness::AxesMode axes_mode,
+                      Njettiness::MeasureMode measure_mode,
+                      double para1,
+                      double para2,
+                      double para3)
+   : _nsub_numerator(N, axes_mode, measure_mode, para1, para2, para3),
+   _nsub_denominator(M, axes_mode, measure_mode, para1, para2, para3) {}
+
+   //returns tau_N/tau_M based off the input jet using result function from Nsubjettiness
    double result(const PseudoJet& jet) const;
 
Index: external/fastjet/contribs/Nsubjettiness/README
===================================================================
--- external/fastjet/contribs/Nsubjettiness/README	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/contribs/Nsubjettiness/README	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,244 @@
+--------------------------------------------------------------------------------
+Nsubjettiness Package
+--------------------------------------------------------------------------------
+
+The Nsubjettiness package is based on the physics described in:
+
+   Identifying Boosted Objects with N-subjettiness.
+   Jesse Thaler and Ken Van Tilburg.
+   JHEP 1103:015 (2011), arXiv:1011.2268.
+
+   Maximizing Boosted Top Identification by Minimizing N-subjettiness. 
+   Jesse Thaler and Ken Van Tilburg. 
+   JHEP 1202:093 (2012), arXiv:1108.2701.
+
+New in v2.0 is the winner-take-all axis, which is described in:
+
+   Jet Shapes with the Broadening Axis. 
+   Andrew J. Larkoski, Duff Neill, and Jesse Thaler. 
+   JHEP 1404:017 (2014), arXiv:1401.2158.
+
+as well as in unpublished work by Gavin Salam.
+
+--------------------------------------------------------------------------------
+Core Classes
+--------------------------------------------------------------------------------
+
+There are various ways to access N-(sub)jettiness variables, described
+in more detail below:
+
+Nsubjettiness       [Nsubjettiness.hh]:
+   A FunctionOfPseudoJet<double> interface to measure N-subjettiness
+   (Recommended for most users)
+NsubjettinessRatio  [Nsubjettiness.hh]:
+   A FunctionOfPseudoJet<double> interface to measure ratios of
+   two different N-subjettiness (i.e. tau3/tau2)
+NjettinessPlugin    [NjettinessPlugin.hh]:
+   A FastJet plugin for finding jets by minimizing N-jettiness
+   (Recommended for advanced users)
+Njettiness          [Njettiness.hh]:
+   Access to the core Njettiness code.
+   (Not recommended for users, since the interface might change)
+
+The code assumes that you have FastJet 3.
+
+--------------------------------------------------------------------------------
+Basic Usage: Nsubjettiness and NsubjettinessRatio  [Nsubjettiness.hh]
+--------------------------------------------------------------------------------
+
+Most users will only need to use the Nsubjettiness class.  The basic
+functionality is given by:
+
+   Nsubjettiness nSub(N, AxesDefinition, MeasureDefinition)
+   // N specifies the number of (sub) jets to measure
+   // AxesDefinition is WTA_KT_Axes, OnePass_KT_Axes, etc.
+   // MeasureDefinition is UnnormalizedMeasure(beta),
+   //                      NormalizedMeasure(beta,R0), etc.
+      
+   // get tau value
+   double tauN = nSub.result(PseudoJet);
+
+Also available are ratios of N-subjettiness values
+    NsubjettinessRatio nSubRatio(N, M, AxesDefinition,
+                                 MeasureDefinition)
+    // N and M give tau_N / tau_M, all other options the same
+
+--------------------------------------------------------------------------------
+AxesDefinition  [NjettinessDefinition.hh]
+--------------------------------------------------------------------------------
+
+N-(sub)jettiness requires choosing axes as well as a measure (see below). There
+are a number of axes choices available to the user, though modes with a (*) are
+recommended. Arguments in parentheses are parameters that the user must set.
+
+Axes can be found using standard recursive clustering procedures.  New is the
+option to use the "winner-take-all" recombination scheme:
+(*) KT_Axes           // exclusive kt axes
+    CA_Axes           // exclusive ca axes
+    AntiKT_Axes(R0)   // inclusive hardest axes with antikt, R0 = radius
+(*) WTA_KT_Axes       // exclusive kt with winner-take-all recombination
+    WTA_CA_Axes       // exclusive ca with winner-take-all recombination
+
+One can also run a minimization routine to find a (local) minimum of
+N-(sub)jettiness:
+(*) OnePass_KT_Axes          // one-pass minimization from kt starting point
+    OnePass_CA_Axes          // one-pass min. from ca starting point
+    OnePass_AntiKT(R0)       // one-pass min. from antikt starting point,R0=rad
+(*) OnePass_WTA_KT_Axes      // one-pass min. from wta_kt starting point
+    OnePass_WTA_CA_Axes      // one-pass min. from wta_ca starting point
+
+In general, it is difficult to finding the global minimum, but this mode
+attempts to do so
+    MultiPass_Axes(Npass)    // axes that (attempt to) minimize N-subjettiness
+                             // (NPass = 100 is typical)
+
+Finally, one can set manual axes:
+    Manual_Axes          // set your own axes with setAxes()
+    OnePass_Manual_Axes  // one-pass minimization from manual starting point
+
+For most cases, running with OnePass_KT_Axes or OnePass_WTA_KT_Axes gives
+reasonable results (and the results are IRC safe).  Because it uses random
+number seeds, MultiPass_Axes is not IRC safe (and the code is rather slow).  Note
+that for the minimization routines, beta = 1.1 is faster than beta = 1, with
+comparable performance.
+
+--------------------------------------------------------------------------------
+MeasureDefinition  [NjettinessDefinition.hh]
+--------------------------------------------------------------------------------
+
+At the moment, there are only a few measures.  Note that each one has a
+different number of parameters.  The one indicated by (*)
+is the one recommended for use by users new to Nsubjettiness.
+
+The original N-subjettiness measures are:
+    NormalizedMeasure(beta,R0)  //default normalized measure with
+                                //parameters beta and R0 (dimensionless)
+(*) UnnormalizedMeasure(beta)   //default unnormalized measure with just
+                                //parameter beta (dimensionful)
+
+There are also measures that incorporate a radial cutoff:
+    NormalizedCutoffMeasure(beta,R0,Rcutoff) //normalized measure with
+                                             //additional Rcutoff
+    UnnormalizedCutoffMeasure(beta,Rcutoff)  //unnormalized measure with
+                                             //additional Rcutoff
+
+In beta testing are "geometric" measures where distances are measured using the
+Lorentz dot product (N.B. the formula for the geometric measure is likely to
+change since there should be separate beam and jet beta factors.)
+    GeometricMeasure(beta)               //geometric measure with exponent beta
+    GeometricCutoffMeasure(beta,Rcutoff) //geometric measure with Rcutoff
+
+--------------------------------------------------------------------------------
+A note on beta dependence
+--------------------------------------------------------------------------------
+
+The angular exponent in N-subjettiness is called beta.  The original
+N-subjettiness paper advocated beta = 1, but it is now understood that different
+beta values can be useful in different contexts.  The two main choices are:
+
+beta = 1:  aka broadening/girth/width measure
+   wta_kt_axes are approximately the same as minimizing beta = 1 measure
+
+beta = 2:  aka thrust/mass measure
+   kt_axes are approximately the same as minimizing beta = 2 measure
+
+N.B. The minimization routines are only valid for 1 < beta < 3.
+
+For quark/gluon discrimination with N = 1, beta~0.2 with wta_kt_axes appears
+to be a good choice. 
+
+--------------------------------------------------------------------------------
+TauComponents  [MeasureFunction.hh]
+--------------------------------------------------------------------------------
+
+For most users, they will only need the value of N-subjettiness (i.e. tau)
+itself.  For advanced users, they can access individual tau components (i.e. 
+the individual numerator pieces, the denominator, etc.)  
+
+   TauComponents tauComp = nSub.component_result(jet);
+   vector<double> numer = tauComp.jet_pieces_numerator(); //tau for each subjet
+   double denom = tauComp.denominator();  //normalization factor
+
+--------------------------------------------------------------------------------
+WinnerTakeAllRecombiner  [WinnerTakeAllRecombiner.hh]
+--------------------------------------------------------------------------------
+
+New for version 2.0 of Nsubjettiness are winner-take-all axes.  They are found
+with the help of the WinnerTakeAllRecombiner. This class defines a new
+recombination scheme for clustering particles. This scheme recombines two
+PseudoJets into a PseudoJet with pT of the sum of the two input PseudoJet pTs
+and direction of the harder PseudoJet.  This is a "recoil-free" recombination
+scheme that guarantees that the axes is aligned with one of the input particles.
+It is IRC safe.  Axes found with the standard E-scheme recombiner at similar to
+the beta = 2 minimization, while winner-take-all is similar to the beta = 1
+measure.
+
+Note that the WinnerTakeAllRecombiner can be used outside of Nsubjettiness
+itself for jet finding.  For example, the direction of anti-kT jets found
+with the WinnerTakeAllRecombiner is particularly robust against soft jet
+contamination.
+
+--------------------------------------------------------------------------------
+Advanced Usage:  NjettinessPlugin  [NjettinessPlugin.hh]
+--------------------------------------------------------------------------------
+
+The Njettiness FastJet plugin represents an exclusive jet finder (yielding a
+fixed N number of jets). The algorithm finds N axes, and jets are simply the sum
+of particles closest to a given axis (or unclustered if they are closest to the
+beam).  The axes finding methods and measures are the same as for Nsubjettiness.
+
+   NjettinessPlugin plugin(N, AxesDefinition, MeasureDefinition);
+   JetDefinition def(&plugin);
+   ClusterSequence cs(vector<PseudoJet>,def);
+   vector<PseudoJet> jets = cs.inclusive_jets();
+
+Note that despite being an exclusive jet algorithm, one finds the jets using the
+inclusive_jets() call.
+
+--------------------------------------------------------------------------------
+Very Advanced Usage:  Njettiness  [Njettiness.hh]
+--------------------------------------------------------------------------------
+
+Most users will want to use the Nsubjettiness or NjettinessPlugin classes to
+access N-(sub)jettiness information.  For direct access to the Njettiness class,
+one can use Njettiness.hh directly. This class is still evolving, so users who
+wish to extend its functionality should contact the authors first.
+
+--------------------------------------------------------------------------------
+Technical Details
+--------------------------------------------------------------------------------
+
+In general, the user will never need access to these header files.  Here is a
+brief description about how they are used to help the calculation of
+N-(sub)jettiness:
+
+AxesFinder.hh:
+
+The AxesFinder class (and derived classes) defines the axes used in the
+calculation of N-(sub)jettiness.  These axes can be defined from the exclusive
+jets from a kT or CA algorithm, the hardest jets from an anti-kT algorithm,
+manually, or from minimization of N-jettiness.  In the future, the user will be
+able to write their own axes finder, though currently the interface is still
+evolving.  At the moment, the user should stick to the options allowed by
+AxesDefinition.
+
+MeasureFunction.hh:
+
+The MeasureFunction class (and derived classes) defines the measure by which
+N-(sub)jettiness is calculated. This measure is calculated between each
+particle and its corresponding axis, and then summed and normalized to
+produce N-(sub)jettiness. The default measure for this calculation is
+pT*dR^beta, where dR is the rapidity-azimuth distance between the particle
+and its axis, and beta is the angular exponent.  Again, in the future the user
+will be able to write their own measures, but for the time being, only the
+predefined MeasureDefinition values should be used.
+
+--------------------------------------------------------------------------------
+Known Issues
+--------------------------------------------------------------------------------
+
+-- The MultiPass_Axes mode gives different answers on different runs, since
+   random numbers are used.
+-- In rare cases, one pass minimization can give a larger value of Njettiness
+   than without minimization.
+-- Nsubjettiness is not thread safe, since there are mutables in Njettiness.
Index: external/fastjet/contribs/Nsubjettiness/VERSION
===================================================================
--- external/fastjet/contribs/Nsubjettiness/VERSION	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/contribs/Nsubjettiness/VERSION	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,1 +1,1 @@
-1.1.0-beta4
+2.1.0
Index: external/fastjet/contribs/Nsubjettiness/WinnerTakeAllRecombiner.cc
===================================================================
--- external/fastjet/contribs/Nsubjettiness/WinnerTakeAllRecombiner.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/contribs/Nsubjettiness/WinnerTakeAllRecombiner.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -5,4 +5,5 @@
 //  Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason
 //
+//  $Id: WinnerTakeAllRecombiner.cc 597 2014-04-16 23:07:55Z jthaler $
 //----------------------------------------------------------------------
 // This file is part of FastJet contrib.
@@ -33,5 +34,4 @@
 
 // recombine pa and pb by creating pab with energy of the sum of particle energies in the direction of the harder particle
-
 // updated recombiner to use more general form of a metric equal to E*(pT/E)^(alpha), which reduces to pT*cosh(rap)^(1-alpha)
 // alpha is specified by the user. The default is alpha = 1, which is the typical behavior. alpha = 2 provides a metric which more 
Index: external/fastjet/contribs/Nsubjettiness/WinnerTakeAllRecombiner.hh
===================================================================
--- external/fastjet/contribs/Nsubjettiness/WinnerTakeAllRecombiner.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/contribs/Nsubjettiness/WinnerTakeAllRecombiner.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -5,4 +5,5 @@
 //  Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason
 //
+//  $Id: WinnerTakeAllRecombiner.hh 670 2014-06-06 01:24:42Z jthaler $
 //----------------------------------------------------------------------
 // This file is part of FastJet contrib.
@@ -50,5 +51,7 @@
    
    /// recombine pa and pb and put result into pab
-   virtual void recombine(const fastjet::PseudoJet & pa, const fastjet::PseudoJet & pb, fastjet::PseudoJet & pab) const;
+   virtual void recombine(const fastjet::PseudoJet & pa,
+                          const fastjet::PseudoJet & pb,
+                          fastjet::PseudoJet & pab) const;
 
 private:
Index: external/fastjet/contribs/SoftKiller/AUTHORS
===================================================================
--- external/fastjet/contribs/SoftKiller/AUTHORS	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/contribs/SoftKiller/AUTHORS	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,9 @@
+The SoftKiller FastJet contrib was written and is maintained 
+and developed by
+
+  Matteo Cacciari <cacciari@lpthe.jussieu.fr>
+  Gavin P. Salam  <gavin.salam@cern.ch>
+  Gregory Soyez   <soyez@fastjet.fr>
+
+See http://arxiv.org/abs/1407.0408 for all the details about the
+physics. 
Index: external/fastjet/contribs/SoftKiller/COPYING
===================================================================
--- external/fastjet/contribs/SoftKiller/COPYING	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/contribs/SoftKiller/COPYING	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,343 @@
+======================================================================
+======================================================================
+======================================================================
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program 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.
+
+    This program 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 program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
Index: external/fastjet/contribs/SoftKiller/ChangeLog
===================================================================
--- external/fastjet/contribs/SoftKiller/ChangeLog	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/contribs/SoftKiller/ChangeLog	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,99 @@
+2014-08-17  Gavin Salam  <gavin.salam@cern.ch>
+
+	* NEWS:
+	* VERSION:
+	release of version 1.0.0
+
+2014-08-16  Matteo Cacciari <cacciari@lpthe.jusssieu.fr>
+
+        * AUTHORS
+        * README
+        Some typos fixed and small tweaks
+
+2014-08-11  Gavin Salam  <gavin.salam@cern.ch> + Gregory (later)
+
+	* SoftKiller.hh|cc:
+	replaced index()->tile_index() and is_good() -> tile_is_good() in
+	line with name changes in RectangularGrid
+
+2014-08-11  Gavin Salam  <gavin.salam@cern.ch>
+
+	* SoftKiller.cc:
+	added a constructor that takes a RectangularGrid and implemented
+	support for the is_good(itile) aspect of RectangularGrid.
+
+	Rather than doing a direct push_back of the PJs that pass the cut,
+	introduced an intermediate stage of a vector of indices; gains
+	about a factor of two in that part of the code; 
+
+	For both above changes, see
+	issue-tracker/2014-08-08-testing-rect-grid/README
+
+2014-08-08  Gavin Salam  <gavin.salam@cern.ch>
+
+	* SoftKiller.cc: 
+	added check for all_tiles_equal_area(), in view of possible future
+	cases where they don't (some thought would then be needed).
+
+2014-08-04  Gavin Salam  <gavin.salam@cern.ch>
+
+	* SoftKiller.hh|cc:
+	started experimenting with using a rectangular grid that is being
+	developed in FJ3.1. Still preliminary, and controlled through a
+	symbol FJC_SOFTKILLER_USEFJGRID that is set in the header
+
+2014-07-16  Gavin Salam  <gavin.salam@cern.ch>
+
+	* Makefile:
+	added dependencies
+
+	* example.cc:
+	added output of the pt threshold.
+
+	* SoftKiller.hh|cc:
+	added a constructor that allows the user to specify separate
+	rapmin, rapmax, as well as different requested rapidity and
+	azimuth cell spacing.
+
+	added an apply(...) member, which enables access also to the
+	pt_threshold.
+
+	sifter is now by default an uninitialised Selector (and the
+	description and code simply ignore it if it's uninitialised).
+
+	grid contents now stored in a C++ vector rather than a C-style
+	array. 
+
+	+ various mods to comments
+
+	* example.ref:
+	updated this to reflect new output of pt threshold info.
+
+	* NEWS:
+	added a draft entry for the 1.0.0 release
+
+2014-07-10  Gregory Soyez  <soyez@fastjet.fr>
+
+	* README:
+	added a desctription of the contrib
+
+2014-07-09  Gregory Soyez  <soyez@fastjet.fr>
+
+	* AUTHORS:
+	included the arXiv number
+
+2014-05-15  Gregory Soyez  <soyez@fastjet.fr>
+
+	* VERSION:
+	set version number to 1.0.0-alpha-PUWS14.1 in preparation for a
+	fastjet-contrib release for the pileup-workshop at CERN on May
+	2014.
+
+2014-04-29  Gregory Soyez  <soyez@fastjet.fr>
+
+	* Imported the soft killer code from the fast implementation we've
+	  used for the results in the paper.
+
+2014-04-29  Gregory Soyez  <soyez@fastjet.fr>
+
+	* Initial creation
Index: external/fastjet/contribs/SoftKiller/Makefile
===================================================================
--- external/fastjet/contribs/SoftKiller/Makefile	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/contribs/SoftKiller/Makefile	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,81 @@
+# 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=SoftKiller
+SRCS=SoftKiller.cc
+EXAMPLES=example
+INSTALLED_HEADERS=SoftKiller.hh
+#------------------------------------------------------------------------
+
+CXXFLAGS+= $(shell $(FASTJETCONFIG) --cxxflags)
+LDFLAGS += -lm $(shell $(FASTJETCONFIG) --libs)
+
+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) -o $@ $< -L. -l$(NAME) $(LDFLAGS)
+
+# check that everything went fine
+check: examples
+	@for prog in $(EXAMPLES); do\
+	  $(check_script) $${prog} ../data/Pythia-Zp2jets-lhc-pileup-1ev.dat || exit 1; \
+	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
+
+SoftKiller.o: SoftKiller.hh
+example.o: SoftKiller.hh
Index: external/fastjet/contribs/SoftKiller/NEWS
===================================================================
--- external/fastjet/contribs/SoftKiller/NEWS	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/contribs/SoftKiller/NEWS	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,2 @@
+2014/08/17: initial release, version 1.0.0
+
Index: external/fastjet/contribs/SoftKiller/README
===================================================================
--- external/fastjet/contribs/SoftKiller/README	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/contribs/SoftKiller/README	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,70 @@
+------------------------------------------------------------------------
+SoftKiller FastJet contrib
+------------------------------------------------------------------------
+
+The SoftKiller FastJet contrib aims to provide an implementation of
+the pileup removal technique introduced in
+	
+  SoftKiller, a particle-level pileup removal method
+  Matteo Cacciari, Gavin P. Salam, Gregory Soyez
+  arXiv:1407.0408
+
+The SoftKiller class progressively kills soft particles in order of
+increasing pt until half of the event is empty (i.e. rho is zero). 
+It is constructed using
+
+  SoftKiller soft_killer(double rapmax, double grid_spacing,
+                         Selector sifter = Selector());
+
+with
+
+  rapmax        the maximal (absolute) rapidity extent of the grid
+  tile_size     the requested grid spacing (or equivalent tile size)
+  sifter        when provided, the soft killer is applied
+                only to particles that pass the sifter (the
+                others are kept untouched)
+
+For a given event, the SoftKiller is then applied to an event as follows
+
+  vector<PseudoJet> event;
+  vector<PseudoJet> killed_event = soft_killer(event);
+
+For an explicit illustration of how this works, see the example.cc
+file which can be built using
+
+    make example
+
+and should be run with
+
+   ./example < ../data/Pythia-Zp2jets-lhc-pileup-1ev.dat
+ 
+The expected output can be found in example.ref
+
+----------------------------------------------------------------------
+More advanced usage
+===================
+
+If you have FastJet 3.1, then you can use its RectangularGrid to have
+obtain control over the grid; for example to apply a soft killer
+separately to central and forward particles you might have:
+
+   double central_rapmax = 2.5, forward_rapmax = 5.0, tile_size = 0.5;
+
+   // the central SK runs from -central_rapmax to central_rapmax; we
+   // can have separate rapidity and phi tile sizes, but here keep
+   // them the same
+   RectangularGrid central_grid(-central_rapmax, central_rapmax, tile_size, tile_size);
+   SoftKiller central_killer(central_grid);
+   Selector central_selector = SelectorAbsRapMax(central_rapmax); // for later use
+   
+   // for the forward SK, we have a grid from -5.0 to 5.0 but then use
+   // only grid tiles whose central point passes the forward selector
+   Selector forward_selector = SelectorAbsRapRange(central_rapmax, forward_rapmax);
+   RectangularGrid forward_grid(-forward_rapma, forward_rapmax, tile_size, tile_size, forward_selector);
+   SoftKiller central_killer(forward_grid);
+
+   // now process central and forward particles separately
+   vector<PseudoJet> central_kept_particles = central_killer(central_selector(particles));
+   vector<PseudoJet> forward_kept_particles = forward_killer(forward_selector(particles));
+
+
Index: external/fastjet/contribs/SoftKiller/SoftKiller.cc
===================================================================
--- external/fastjet/contribs/SoftKiller/SoftKiller.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/contribs/SoftKiller/SoftKiller.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,345 @@
+// $Id$
+//
+// Copyright (c) 2014-, Matteo Cacciari, Gavin. P. Salam and Gregory Soyez
+//
+//----------------------------------------------------------------------
+// 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 "SoftKiller.hh"
+#include <sstream>
+
+using namespace std;
+
+FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
+
+namespace contrib{
+
+/// ctor with simple initialisation
+///  \param rapmax     the maximal absolute rapidity extent of the grid
+///  \param cell_size  the grid spacing (equivalently, cell size)
+///  \param sifter     when provided, the soft killer is applied
+///                    only to particles that pass the sifter (the
+///                    others are kept untouched)
+SoftKiller::SoftKiller(double rapmax, double cell_size,
+                       Selector sifter) :
+#ifdef FJCONTRIB_SOFTKILLER_USEFJGRID
+  RectangularGrid(rapmax, cell_size), _sifter(sifter) {}
+#else // not FJCONTRIB_SOFTKILLER_USEFJGRID
+  _ymax(rapmax), _ymin(-rapmax), 
+  _requested_drap(cell_size), _requested_dphi(cell_size),
+  _sifter(sifter) {
+    _setup_grid();
+}
+#endif
+
+/// ctor with more control over initialisation
+///  \param rapmin     the minimum rapidity extent of the grid
+///  \param rapmax     the maximum rapidity extent of the grid
+///  \param drap       the grid spacing in rapidity
+///  \param dphi       the grid spacing in azimuth
+///  \param sifter     when provided, the soft killer is applied
+///                    onyl to particles that pass the sifter (the
+///                    others are kept untouched)
+SoftKiller::SoftKiller(double rapmin, double rapmax, double drap, double dphi,
+                       Selector sifter) :
+#ifdef FJCONTRIB_SOFTKILLER_USEFJGRID
+  RectangularGrid(rapmin, rapmax, drap, dphi), _sifter(sifter) {}
+#else
+   _ymax(rapmax), _ymin(rapmin), 
+    _requested_drap(drap), _requested_dphi(dphi),
+    _sifter(sifter) {
+  _setup_grid();
+}
+#endif
+
+#ifdef FJCONTRIB_SOFTKILLER_USEFJGRID
+SoftKiller::SoftKiller(const RectangularGrid & grid, Selector sifter) : 
+            RectangularGrid(grid), _sifter(sifter) {}
+#endif 
+
+/// dummy ctor (will give an unusable SoftKiller)
+SoftKiller::SoftKiller() 
+#ifdef FJCONTRIB_SOFTKILLER_USEFJGRID
+  {}  
+#else
+  : _ymax(-1.0), _ymin(1.0), _requested_drap(-1.0), _requested_dphi(-1.0) {
+  _ntotal = 0;
+}
+#endif // FJCONTRIB_SOFTKILLER_USEFJGRID
+
+
+//------------------------------------------------------------------------
+// description of the soft killer
+std::string SoftKiller::description() const{
+  ostringstream oss;
+
+
+#ifdef FJCONTRIB_SOFTKILLER_USEFJGRID
+  oss << "SoftKiller with " << RectangularGrid::description();
+#else
+  if (_requested_drap < 0 || _requested_dphi < 0)
+    return "Uninitialised SoftKiller";
+
+  oss << "SoftKiller with rapidity extent " << _ymin << " < rap < " << _ymax
+      << ", cell size drap x dphi = " << _dy << " x " << _dphi;
+#endif
+  if (_sifter.worker()) {
+    oss << " and applied to particles passing the selection (" 
+        << _sifter.description() << ")";
+  }
+  return oss.str();
+}
+
+//------------------------------------------------------------------------
+// similarly to Transformers in FastJet, introduce a 'result'
+// method equivalent to the () operator, i.e. returns the event
+// after the soft killer has been applied
+//vector<PseudoJet> SoftKiller::result(const vector<PseudoJet> & event) const {
+void SoftKiller::apply(const vector<PseudoJet> & event, 
+                       vector<PseudoJet> & reduced_event, 
+                         double & pt_threshold) const {
+  // a safety check: we impose at least 2 cells (otherwise, this is
+  // equivalent to asking an empty event and there are more
+  // efficient ways to do that)
+  if (n_tiles()<2){
+    throw Error("SoftKiller not properly initialised.");
+  }
+
+  // we're not set up to handle the case where the event and reduced
+  // event are the same vector; so crash in that case.
+  assert(&event != &reduced_event);
+  // currently we can only handle the case where all tiles have equal
+  // area; that is the case for Rectangular tilings, but in the future
+  // one might imagine having non-rectangular tilings.
+  assert(all_tiles_equal_area());
+
+  //profiling: CPUTimer t;
+  //profiling: t.start();
+
+  // init an array to hold the max pt in each grid cell
+  //
+  // This is better (stack) but only C99 (fails with pedantic):
+  //   double max_pt2[n_tiles()];
+  // See 
+  //   http://binglongx.wordpress.com/2011/05/08/create-variable-length-array-on-the-stack-in-c/
+  // for a possible workaround
+  vector<double> max_pt2(n_tiles(), 0.0);
+  //double max_pt2[n_tiles()];
+  //memset(max_pt2, 0, n_tiles()*sizeof(double));
+  //double *max_pt2 = new double[n_tiles()]; // if this is reinstated, reinstate also the delete, below
+  //for (int i = 0; i < n_tiles(); i++) {max_pt2[i] = 0;}
+
+  //profiling: t.stop();
+  //profiling: cout << "   copy ptrs: " << t.total() << endl;
+  //profiling: t.start();
+
+  // leave away particles that are sifted
+  // vector<PseudoJet> reduced_event, saved_particles;
+  // _sifter.sift(event, reduced_event, saved_particles);
+
+  vector<const PseudoJet *> event_ptrs(event.size());
+  for (unsigned i = 0; i < event.size(); i++) {
+    event_ptrs[i] = & event[i];
+  }
+  // only run the sifter if it serves a purpose
+  if (_sifter.worker()) _sifter.nullify_non_selected(event_ptrs);
+    
+  //profiling: t.stop();
+  //profiling: cout << "   sifter   : " << t.total() << endl;
+  //profiling: t.start();
+    
+  //vector<PseudoJet> reduced_event = event;
+
+  // browse the particles and figure which is the min pt in each cell
+  for(unsigned int i=0;i<event.size(); i++){
+    if (event_ptrs[i] == 0) continue;
+    int idx = tile_index(event[i]);
+    if (idx<0) continue;
+    max_pt2[idx] = max(max_pt2[idx], event[i].pt2());
+  }
+    
+  //profiling: t.stop();
+  //profiling: cout << "   browsing : " << t.total() << endl;
+  //profiling: t.start();
+  
+  
+  // if there are some "bad" tiles, then we need to exclude them from
+  // the calculation of the median. We'll do this by condensing the
+  // max_pt2 vector down to just the values for the tiles that are
+  // good.
+  //
+  // tested answers look right in "issue" 2014-08-08-testing-rect-grid
+  if (n_good_tiles() != n_tiles()) {
+    int newn = 0;
+    for (unsigned i = 0; i < max_pt2.size(); i++) {
+      if (tile_is_good(i)) {
+        // clang gets confused with the SharedPtr swap if we don't
+        // have std:: here
+        std::swap(max_pt2[i],max_pt2[newn]);
+        newn++;
+      }
+    }
+    max_pt2.resize(newn);
+  }
+
+  // sort the list of max values (sort works with arrays)
+  //sort(max_pt2, max_pt2+n_tiles()); // use this one if we have the allocated C-style array above
+  sort(max_pt2.begin(), max_pt2.end());
+
+  // Note that if we ask that half of the event is empty that means
+  // that we need at least half of the cells empty... so we need to
+  // round up
+  //
+  // For a potentially faster median search, see
+  //
+  //   http://ndevilla.free.fr/median/median/index.html?utm_source=feedburner&utm_medium=twitter&utm_campaign=Feed%3A+hnycombinator+%28HN+-+hnycombinator%29
+  int int_median_pos = max_pt2.size()/2;
+
+  //--------------------------------------------------------------
+  // alternative to what is below:
+  //
+  // apply the pt cut manually (always on pt^2): first get a vector of
+  // indices that we'll want to keep and then when we know the size of
+  // the resulting vector we actually do the transfer of the
+  // PseudoJets.  
+  //
+  // This is almost a factor of two faster than doing a
+  // push_back on the PseudoJets themselves (which is logical, since a
+  // push_back probably averages out as doing the copy twice).
+  // (2014-08-11, also tried it with pointers, which seemed 
+  // marginally slower).
+  double pt2cut = (1+1e-12)*max_pt2[int_median_pos];
+
+  vector<int> indices;
+  for(unsigned int i=0;i<event.size(); i++){
+    if ((event_ptrs[i] == 0) || (event[i].pt2() >= pt2cut))
+      indices.push_back(i);
+  }
+  reduced_event.reserve(indices.size());
+  for(unsigned int i=0;i<indices.size(); i++){
+    reduced_event.push_back(event[indices[i]]);
+  }
+  
+  // //vector<PseudoJet> reduced_event;
+  // reduced_event.clear();
+  // for(unsigned int i=0;i<event.size(); i++){
+  //   if ((event_ptrs[i] == 0) ||
+  //       (event[i].pt2() >= pt2cut))
+  //     reduced_event.push_back(event[i]);
+  // }
+
+  // free memory: reinstate this is max_pt2 becomes an allocated variable again
+  //delete max_pt2;
+
+  //return reduced_event;
+  pt_threshold = sqrt(pt2cut);
+    
+  // end of alternative
+  //--------------------------------------------------------------
+    
+  // double median_maxpt = sqrt(max_pt2[int_median_pos]);
+  // 
+  // //profiling: t.stop();
+  // //profiling: cout << "   median   : " << t.total() << endl;
+  // //profiling: t.start();
+  // 
+  // // apply a cut on pt using a selector
+  // //
+  // // Watch out that the Selector checks pt >= ptcut, and, since it
+  // // uses pt2 to perform the comparison, may lead to rounding
+  // // errors. By multiplying the ptcut by a small amount, we make
+  // // sure the particle with pt=ptcut is killed.
+  // //
+  // // We're actually going to set to null the ones that will be kept
+  // SelectorPtMax((1+1e-12)*median_maxpt).nullify_non_selected(event_ptrs);
+  // 
+  // // basic information
+  // _ptcut = median_maxpt; // a good first start
+  // 
+  // //profiling: t.stop();
+  // //profiling: cout << "   cutting  : " << t.total() << endl;
+  // //profiling: t.start();
+  // 
+  // // then put back in the saved particles
+  // //
+  // // Note that here we may want to use the killer independently on
+  // // the 2 sets of particles but then the best woulb be to move most
+  // // of the above in a separate method and call it twice (left for
+  // // future experimentation)
+  // //copy(saved_particles.begin(), saved_particles.end(), back_inserter(reduced_event));
+  // 
+  // vector<PseudoJet> reduced_event;
+  // // no sizeable speed gain: reduced_event.reserve(event.size());
+  // for (unsigned int i=0;i<event.size();i++)
+  //   if (event_ptrs[i] == 0) reduced_event.push_back(event[i]);
+  // 
+  // // free memory
+  // delete max_pt2;
+  // 
+  // //profiling: t.stop();
+  // //profiling: cout << "   finishing: " << t.total() << endl;
+  // 
+  // return reduced_event;
+}
+
+#ifndef FJCONTRIB_SOFTKILLER_USEFJGRID
+
+// configure the grid
+void SoftKiller::_setup_grid() {
+  // this grid-definition code is becoming repetitive -- it should
+  // probably be moved somewhere central...
+  double ny_double = (_ymax-_ymin) / _requested_drap;
+  _ny = max(int(ny_double+0.5),1);
+  _dy = (_ymax-_ymin) / _ny;
+  _inverse_dy = _ny/(_ymax-_ymin);
+  
+  _nphi = int (twopi / _requested_dphi + 0.5);
+  _dphi = twopi / _nphi;
+  _inverse_dphi = _nphi/twopi;
+
+  // some sanity checking (could throw a fastjet::Error)
+  assert(_ny >= 1 && _nphi >= 1);
+
+  _ntotal = _nphi * _ny;
+  //_max_pt.resize(_ntotal);
+  _cell_area = _dy * _dphi;
+}
+
+// retrieve the grid cell index for a given PseudoJet
+inline int SoftKiller::tile_index(const PseudoJet & p) const {
+  // writing it as below gives a huge speed gain (factor two!). Even
+  // though answers are identical and the routine here is not the
+  // speed-critical step. It's not at all clear why.
+  int iy = int(floor( (p.rap() - _ymin) * _inverse_dy ));
+  if (iy < 0 || iy >= _ny) return -1;
+
+  int iphi = int( p.phi() * _inverse_dphi );
+  //assert(iphi >= 0 && iphi <= _nphi);
+  if (iphi == _nphi) iphi = 0; // just in case of rounding errors
+
+  //int igrid_res = iy*_nphi + iphi;
+  //assert (igrid_res >= 0 && igrid_res < _ny*_nphi);
+  return iy*_nphi + iphi; //igrid_res;
+}
+
+#endif // not FJCONTRIB_SOFTKILLER_USEFJGRID
+
+
+
+} // namespace contrib
+
+FASTJET_END_NAMESPACE
Index: external/fastjet/contribs/SoftKiller/SoftKiller.hh
===================================================================
--- external/fastjet/contribs/SoftKiller/SoftKiller.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/contribs/SoftKiller/SoftKiller.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,157 @@
+// $Id$
+//
+// Copyright (c) 2014-, Matteo Cacciari, Gavin. P. Salam and Gregory Soyez
+//
+//----------------------------------------------------------------------
+// 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_SOFTKILLER_HH__
+#define __FASTJET_CONTRIB_SOFTKILLER_HH__
+
+#include <fastjet/internal/base.hh>
+#include <fastjet/Selector.hh>
+#include "fastjet/config.h"
+
+#if FASTJET_VERSION_NUMBER >= 30100
+#define FJCONTRIB_SOFTKILLER_USEFJGRID
+#endif
+
+#ifdef FJCONTRIB_SOFTKILLER_USEFJGRID
+#include "fastjet/RectangularGrid.hh"
+#endif
+
+FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
+
+
+namespace contrib{
+
+//------------------------------------------------------------------------
+/// \class SoftKiller
+/// Progressively kills soft particles in order of increasing pt until
+/// half of the event is empty.
+///
+/// More precisely, the event up to |rap|=rapmax is split into grid
+/// cells of size "cell_size". Soft particles are removed from the
+/// event in order of increasing pt until half the cells are empty.
+/// By default, that same pt cut is applied to _all_ the particles in
+/// the event, not just those in the grid region.
+///
+/// If a sifter is provided, then only particles that pass the selector
+/// are put onto the grid, and the pt threshold is then applied just 
+/// to those particles, while all other particles are left untouched.
+///
+/// This is convenient, for example, if you want to apply SK just to
+/// neutral particles.
+#ifdef FJCONTRIB_SOFTKILLER_USEFJGRID
+class SoftKiller : public RectangularGrid {
+#else 
+class SoftKiller {
+#endif
+public:
+  /// ctor with simple initialisation
+  ///  \param rapmax     the maximal absolute rapidity extent of the grid
+  ///  \param tile_size  the requested grid spacing (equivalently, tile size)
+  ///  \param sifter     when provided, the soft killer is applied
+  ///                    only to particles that pass the sifter (the
+  ///                    others are kept untouched)
+  SoftKiller(double rapmax, double tile_size,
+	     Selector sifter = Selector());
+
+  /// ctor with more control over initialisation
+  ///  \param rapmin     the minimum rapidity extent of the grid
+  ///  \param rapmax     the maximum rapidity extent of the grid
+  ///  \param drap       the grid spacing in rapidity
+  ///  \param dphi       the grid spacing in azimuth
+  ///  \param sifter     when provided, the soft killer is applied
+  ///                    only to particles that pass the sifter (the
+  ///                    others are kept untouched)
+  SoftKiller(double rapmin, double rapmax, double drap, double dphi,
+	     Selector sifter = Selector());
+
+#ifdef FJCONTRIB_SOFTKILLER_USEFJGRID
+  /// constructor that takes RectangularGrid object to flexibly
+  /// specify the details of the grid (works only with FJ3.1)
+  SoftKiller(const RectangularGrid & grid, Selector sifter = Selector());
+#endif 
+
+  /// dummy ctor (will give an unusable SoftKiller)
+  SoftKiller();
+
+  /// returns description of the soft killer
+  std::string description() const;
+  
+  /// applies the soft killer to a given event. The result is the
+  /// "reduced" event.
+  std::vector<PseudoJet> operator()(const std::vector<PseudoJet> & event) const{
+    return result(event);
+  }
+  
+  /// similarly to Transformers in FastJet, introduce a 'result'
+  /// method equivalent to the () operator.
+  //std::vector<PseudoJet> result(const std::vector<PseudoJet> & event) const;
+  std::vector<PseudoJet> result(const std::vector<PseudoJet> & event) const {
+    double pt_threshold;
+    std::vector<PseudoJet> reduced_event;
+    apply(event, reduced_event, pt_threshold);
+    return reduced_event;
+  }
+
+  /// alternative invocation that puts the resulting SK "reduced" event
+  /// into the reduced_event vector, and also provides information about the
+  /// pt threshold that was applied.
+  ///
+  /// The event and reduced_event must _not_ be the same variable.
+  void apply(const std::vector<PseudoJet> & event, 
+             std::vector<PseudoJet> & reduced_event,
+             double & pt_threshold) const;
+
+private:
+
+#ifndef FJCONTRIB_SOFTKILLER_USEFJGRID
+  /// initial setup of the grid 
+  void _setup_grid();
+
+  // retrieve the grid cell index for a given PseudoJet
+  inline int tile_index(const PseudoJet & p) const;
+
+  inline int n_tiles() const {return _ntotal;}
+  inline int n_good_tiles() const {return n_tiles();}
+  inline bool tile_is_good(int itile) const {return true;}
+  
+  inline bool all_tiles_equal_area() const {return true;}
+
+  // ctor arguments
+  double _ymax, _ymin;  ///< maximal and minimal rapidity coverage of the grid
+  //double _cell_size;    ///< grid cell size
+  double _requested_drap; ///< requested rapidity spacing
+  double _requested_dphi; ///< requested phi spacing
+
+  // information about the grid
+  double _dy, _dphi, _cell_area, _inverse_dy, _inverse_dphi;
+  int _ny, _nphi, _ntotal;
+
+#endif // FJCONTRIB_SOFTKILLER_USEFJGRID
+
+  Selector _sifter;     ///< optional sifter
+
+};
+
+} // namespace contrib
+
+FASTJET_END_NAMESPACE
+
+#endif  // __FASTJET_CONTRIB_SOFTKILLER_HH__
Index: external/fastjet/contribs/SoftKiller/VERSION
===================================================================
--- external/fastjet/contribs/SoftKiller/VERSION	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/contribs/SoftKiller/VERSION	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,1 @@
+1.0.0
Index: external/fastjet/internal/ClosestPair2D.hh
===================================================================
--- external/fastjet/internal/ClosestPair2D.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/internal/ClosestPair2D.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: ClosestPair2D.hh 2577 2011-09-13 15:11:38Z salam $
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: ClosestPair2D.hh 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __FASTJET_CLOSESTPAIR2D__HH__
Index: external/fastjet/internal/ClosestPair2DBase.hh
===================================================================
--- external/fastjet/internal/ClosestPair2DBase.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/internal/ClosestPair2DBase.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: ClosestPair2DBase.hh 2577 2011-09-13 15:11:38Z salam $
+//FJSTARTHEADER
+// $Id: ClosestPair2DBase.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __FASTJET_CLOSESTPAIR2DBASE__HH__
Index: external/fastjet/internal/ClusterSequence_N2.icc
===================================================================
--- external/fastjet/internal/ClusterSequence_N2.icc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/internal/ClusterSequence_N2.icc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -4,8 +4,8 @@
 #include "fastjet/ClusterSequence.hh"
 
-//STARTHEADER
+//FJSTARTHEADER
 // $Id: ClusterSequence_N2.cc 1351 2009-01-09 18:03:03Z salam $
 //
-// Copyright (c) 2005-2009, Matteo Cacciari, Gavin Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -18,7 +18,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,9 +30,7 @@
 //
 //  You should have received a copy of the GNU General Public License
-//  along with FastJet; if not, write to the Free Software
-//  Foundation, Inc.:
-//      59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 //----------------------------------------------------------------------
Index: external/fastjet/internal/Dnn2piCylinder.hh
===================================================================
--- external/fastjet/internal/Dnn2piCylinder.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/internal/Dnn2piCylinder.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: Dnn2piCylinder.hh 2577 2011-09-13 15:11:38Z salam $
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: Dnn2piCylinder.hh 3442 2014-07-24 07:20:49Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
@@ -73,14 +75,14 @@
   /// Returns the index of  the nearest neighbour of point labelled
   /// by ii (assumes ii is valid)
-  int NearestNeighbourIndex(const int & ii) const ;
+  int NearestNeighbourIndex(const int ii) const ;
 
   /// Returns the distance to the nearest neighbour of point labelled
   /// by index ii (assumes ii is valid)
-  double NearestNeighbourDistance(const int & ii) const ;
+  double NearestNeighbourDistance(const int ii) const ;
 
   /// Returns true iff the given index corresponds to a point that
   /// exists in the DNN structure (meaning that it has been added, and
   /// not removed in the meantime)
-  bool Valid(const int & index) const;
+  bool Valid(const int index) const;
 
   void RemoveAndAddPoints(const std::vector<int> & indices_to_remove,
@@ -216,5 +218,5 @@
 /// initialised the class with instructions to ignore this problem the
 /// program will detect and ignore it, or crash.
-inline int Dnn2piCylinder::NearestNeighbourIndex(const int & current) const {
+inline int Dnn2piCylinder::NearestNeighbourIndex(const int current) const {
   int main_index = _mirror_info[current].main_index;
   int mirror_index = _mirror_info[current].mirror_index;
@@ -241,5 +243,5 @@
 }
 
-inline double Dnn2piCylinder::NearestNeighbourDistance(const int & current) const {
+inline double Dnn2piCylinder::NearestNeighbourDistance(const int current) const {
   int main_index = _mirror_info[current].main_index;
   int mirror_index = _mirror_info[current].mirror_index;
@@ -256,5 +258,5 @@
 }
 
-inline bool Dnn2piCylinder::Valid(const int & index) const {
+inline bool Dnn2piCylinder::Valid(const int index) const {
   return (_DNN->Valid(_mirror_info[index].main_index));
 }
Index: external/fastjet/internal/Dnn3piCylinder.hh
===================================================================
--- external/fastjet/internal/Dnn3piCylinder.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/internal/Dnn3piCylinder.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: Dnn3piCylinder.hh 2577 2011-09-13 15:11:38Z salam $
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: Dnn3piCylinder.hh 3442 2014-07-24 07:20:49Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
@@ -70,14 +72,14 @@
   /// Returns the index of  the nearest neighbour of point labelled
   /// by ii (assumes ii is valid)
-  int NearestNeighbourIndex(const int & ii) const ;
+  int NearestNeighbourIndex(const int ii) const ;
 
   /// Returns the distance to the nearest neighbour of point labelled
   /// by index ii (assumes ii is valid)
-  double NearestNeighbourDistance(const int & ii) const ;
+  double NearestNeighbourDistance(const int ii) const ;
 
   /// Returns true iff the given index corresponds to a point that
   /// exists in the DNN structure (meaning that it has been added, and
   /// not removed in the meantime)
-  bool Valid(const int & index) const;
+  bool Valid(const int index) const;
 
   void RemoveAndAddPoints(const std::vector<int> & indices_to_remove,
@@ -204,5 +206,5 @@
 /// initialised the class with instructions to ignore this problem the
 /// program will detect and ignore it, or crash.
-inline int Dnn3piCylinder::NearestNeighbourIndex(const int & current) const {
+inline int Dnn3piCylinder::NearestNeighbourIndex(const int current) const {
   int main_index = _mirror_info[current].main_index;
   int mirror_index = _mirror_info[current].mirror_index;
@@ -229,5 +231,5 @@
 }
 
-inline double Dnn3piCylinder::NearestNeighbourDistance(const int & current) const {
+inline double Dnn3piCylinder::NearestNeighbourDistance(const int current) const {
   int main_index = _mirror_info[current].main_index;
   int mirror_index = _mirror_info[current].mirror_index;
@@ -244,5 +246,5 @@
 }
 
-inline bool Dnn3piCylinder::Valid(const int & index) const {
+inline bool Dnn3piCylinder::Valid(const int index) const {
   return (_DNN->Valid(_mirror_info[index].main_index));
 }
Index: external/fastjet/internal/Dnn4piCylinder.hh
===================================================================
--- external/fastjet/internal/Dnn4piCylinder.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/internal/Dnn4piCylinder.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: Dnn4piCylinder.hh 2577 2011-09-13 15:11:38Z salam $
+//FJSTARTHEADER
+// $Id: Dnn4piCylinder.hh 3442 2014-07-24 07:20:49Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
@@ -57,14 +59,14 @@
   /// Returns the index of  the nearest neighbour of point labelled
   /// by ii (assumes ii is valid)
-  int NearestNeighbourIndex(const int & ii) const ;
+  int NearestNeighbourIndex(const int ii) const ;
 
   /// Returns the distance to the nearest neighbour of point labelled
   /// by index ii (assumes ii is valid)
-  double NearestNeighbourDistance(const int & ii) const ;
+  double NearestNeighbourDistance(const int ii) const ;
 
   /// Returns true iff the given index corresponds to a point that
   /// exists in the DNN structure (meaning that it has been added, and
   /// not removed in the meantime)
-  bool Valid(const int & index) const;
+  bool Valid(const int index) const;
 
   void RemoveAndAddPoints(const std::vector<int> & indices_to_remove,
@@ -98,5 +100,5 @@
 // functions defined above
 
-inline int Dnn4piCylinder::NearestNeighbourIndex(const int & current) const {
+inline int Dnn4piCylinder::NearestNeighbourIndex(const int current) const {
   return (_DNN1->NearestNeighbourDistance(current) < 
 	  _DNN2->NearestNeighbourDistance(current)) ? 
@@ -105,5 +107,5 @@
 }
 
-inline double Dnn4piCylinder::NearestNeighbourDistance(const int & current) const {
+inline double Dnn4piCylinder::NearestNeighbourDistance(const int current) const {
   return (_DNN1->NearestNeighbourDistance(current) < 
 	  _DNN2->NearestNeighbourDistance(current)) ? 
@@ -112,5 +114,5 @@
 }
 
-inline bool Dnn4piCylinder::Valid(const int & index) const {
+inline bool Dnn4piCylinder::Valid(const int index) const {
   return (_DNN1->Valid(index) && _DNN2->Valid(index));
 }
Index: external/fastjet/internal/DnnPlane.hh
===================================================================
--- external/fastjet/internal/DnnPlane.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/internal/DnnPlane.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: DnnPlane.hh 2577 2011-09-13 15:11:38Z salam $
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: DnnPlane.hh 3442 2014-07-24 07:20:49Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
@@ -44,4 +46,11 @@
 /// class derived from DynamicNearestNeighbours that provides an
 /// implementation for the Euclidean plane
+///
+/// This class that uses CGAL Delaunay triangulation for most of the
+/// work (it allows for easy and efficient removal and addition of
+/// points and circulation over a point's neighbours). The treatment
+/// of coincident points is not supported by CGAL and is implemented
+/// according to the method specified in
+/// issue-tracker/2012-02-CGAL-coincident/METHOD
 /// \endif
 class DnnPlane : public DynamicNearestNeighbours {
@@ -57,14 +66,14 @@
   /// Returns the index of  the nearest neighbour of point labelled
   /// by ii (assumes ii is valid)
-  int NearestNeighbourIndex(const int & ii) const ;
+  int NearestNeighbourIndex(const int ii) const ;
 
   /// Returns the distance to the nearest neighbour of point labelled
   /// by index ii (assumes ii is valid)
-  double NearestNeighbourDistance(const int & ii) const ;
+  double NearestNeighbourDistance(const int ii) const ;
 
   /// Returns true iff the given index corresponds to a point that
   /// exists in the DNN structure (meaning that it has been added, and
   /// not removed in the meantime)
-  bool Valid(const int & index) const;
+  bool Valid(const int index) const;
 
   void RemoveAndAddPoints(const std::vector<int> & indices_to_remove,
@@ -80,5 +89,5 @@
   double phi(const int i) const;
 
- private:
+private:
 
   /// Structure containing a vertex_handle and cached information on
@@ -88,4 +97,6 @@
     double NNdistance;
     int NNindex;
+    int coincidence;  // ==vertex->info.val() if no coincidence
+                      // points to the coinciding SV in case of coincidence
     // later on for cylinder put a second vertex?
   };
@@ -95,6 +106,6 @@
   bool _verbose;
 
-  static const bool _crash_on_coincidence = true;
-  //static const bool _crash_on_coincidence = false;
+  //static const bool _crash_on_coincidence = true;
+  static const bool _crash_on_coincidence = false;
 
   Triangulation _TR; /// CGAL object for dealing with triangulations
@@ -111,5 +122,5 @@
   /// Determines the index and distance of the nearest neighbour to 
   /// point j and puts the information into the _supervertex entry for j
-  void _SetNearest(const int & j);
+  void _SetNearest(const int j);
 
   //----------------------------------------------------------------------
@@ -123,13 +134,93 @@
   /// Note that j is NOT pushed onto indices_of_updated_neighbours --
   /// if you want it there, put it there yourself.
-  void _SetAndUpdateNearest(const int & j, 
+  void _SetAndUpdateNearest(const int j, 
 			    std::vector<int> & indices_of_updated_neighbours);
 
   /// given a vertex_handle returned by CGAL on insertion of a new
-  /// points, crash if it turns out that it corresponds to a vertex
-  /// that we already knew about (usually because two points coincide)
-  void _CrashIfVertexPresent(const Vertex_handle & vertex, 
-			     const int & its_index);
-
+  /// points, returns the coinciding vertex's value if it turns out
+  /// that it corresponds to a vertex that we already knew about
+  /// (usually because two points coincide)
+  int _CheckIfVertexPresent(const Vertex_handle & vertex, 
+			    const int its_index);
+
+  //----------------------------------------------------------------------
+  /// if the distance between 'pref' and 'candidate' is smaller (or
+  /// equal) than the one between 'pref' and 'near', return true and
+  /// set 'mindist' to that distance. Note that it is assumed that
+  /// 'mindist' is the euclidian distance between 'pref' and 'near'
+  ///
+  /// Note that the 'near' point is passed through its vertex rather
+  /// than as a point. This allows us to handle cases where we have no min
+  /// yet (near is the infinite vertex)
+  inline bool _is_closer_to(const Point &pref, 
+			    const Point &candidate,
+			    const Vertex_handle &near,
+			    double & dist,
+			    double & mindist){
+    dist = _euclid_distance(pref, candidate);
+    return _is_closer_to_with_hint(pref, candidate, near, dist, mindist);
+  }
+
+  /// same as '_is_closer_to' except that 'dist' already contains the
+  /// distance between 'pref' and 'candidate'
+  inline bool _is_closer_to_with_hint(const Point &pref, 
+				      const Point &candidate,
+				      const Vertex_handle &near,
+				      const double & dist,
+				      double & mindist){
+    
+    // check if 'dist', the pre-computed distance between 'candidate'
+    // and 'pref' is smaller than the distance between 'pref' and its
+    // currently registered nearest neighbour 'near' (and update
+    // things if it is)
+    //
+    // Interestingly enough, it has to be pointed out that the use of
+    // 'abs' instead of 'std::abs' returns wrong results (apparently
+    // ints without any compiler warning)
+    //
+    // The (near != NULL) test is there for one single reason: when
+    // checking that a newly inserted point is not closer than a
+    // previous NN, if that distance comparison involves a "nearly
+    // degenerate" distance we need to access near->point. But
+    // sometimes, in the course of RemoveAndAddPoints, its previous NN
+    // has been deleted and its vertex (corresponding to 'near') set
+    // to NULL. This is not a problem as all points having a deleted
+    // point as NN will have their NN explicitly recomputed at the end
+    // of RemoveAndAddPoints so here we should just make sure there is
+    // no crash... that's done by checking (near != NULL)
+    if ((std::abs(dist-mindist)<DISTANCE_FOR_CGAL_CHECKS) &&
+	(near != NULL) &&
+	(_euclid_distance(candidate, near->point())<DISTANCE_FOR_CGAL_CHECKS)){
+      // we're in a situation where there might be a rounding issue,
+      // use CGAL's distance computation to get it right
+      //
+      // Note that in the test right above,
+      // (abs(dist-mindist)<1e-12) guarantees that the current
+      // nearest point is not the infinite vertex and thus
+      // nearest->point() is not ill-defined
+      if (_verbose) std::cout << "using CGAL's distance ordering" << std::endl;
+      if (CGAL::compare_distance_to_point(pref, candidate, near->point())!=CGAL::LARGER){
+	mindist = dist;
+	return true;
+      }
+    } else if (dist <= mindist) {
+      // Note that the use of a <= in the above expression (instead of
+      // a strict ordering <) is important in one case: when checking
+      // if a new point is the new NN of one of the points in its
+      // neighbourhood, in case of distances being ==, we are sure
+      // that 'candidate' is in a cell adjacent to 'pref' while it may
+      // no longer be the case for 'near'
+      mindist = dist;
+      return true;
+    } 
+    
+    return false;
+  }
+
+  /// if a distance between a point and 2 others is smaller than this
+  /// and the distance between the two points is also smaller than this
+  /// then use CGAL to compare the distances. 
+  static const double DISTANCE_FOR_CGAL_CHECKS;  
+  
 };
 
@@ -138,11 +229,11 @@
 // functions defined above
 
-inline int DnnPlane::NearestNeighbourIndex(const int & ii) const {
+inline int DnnPlane::NearestNeighbourIndex(const int ii) const {
   return _supervertex[ii].NNindex;}
 
-inline double DnnPlane::NearestNeighbourDistance(const int & ii) const {
+inline double DnnPlane::NearestNeighbourDistance(const int ii) const {
   return _supervertex[ii].NNdistance;}
 
-inline bool DnnPlane::Valid(const int & index) const {
+inline bool DnnPlane::Valid(const int index) const {
   if (index >= 0 && index < static_cast<int>(_supervertex.size())) {
     return (_supervertex[index].vertex != NULL);} else {return false;} }
Index: external/fastjet/internal/DynamicNearestNeighbours.hh
===================================================================
--- external/fastjet/internal/DynamicNearestNeighbours.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/internal/DynamicNearestNeighbours.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: DynamicNearestNeighbours.hh 2687 2011-11-14 11:17:51Z soyez $
+//FJSTARTHEADER
+// $Id: DynamicNearestNeighbours.hh 3619 2014-08-13 14:17:19Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
@@ -37,4 +39,5 @@
 #include<cassert>
 #include "fastjet/internal/numconsts.hh"
+#include "fastjet/Error.hh"
 
 FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
@@ -68,15 +71,9 @@
 /// Nearest Neighbours code
 /// \endif
-class DnnError {
+class DnnError : public Error {
 public:
   // constructors
-  DnnError() {;};
-  DnnError(const std::string & message_in) {
-    _message = message_in; std::cerr << message_in << std::endl;};
-
-  std::string message() const {return _message;};
-
-private:
-  std::string _message;
+  //DnnError() {}
+  DnnError(const std::string & message_in) : Error(message_in) {}
 };
 
@@ -112,14 +109,14 @@
   /// Returns the index of the nearest neighbour of point labelled
   /// by ii (assumes ii is valid)
-  virtual int NearestNeighbourIndex(const int & ii) const = 0;
+  virtual int NearestNeighbourIndex(const int ii) const = 0;
 
   /// Returns the distance to the nearest neighbour of point labelled
   /// by index ii (assumes ii is valid)
-  virtual double NearestNeighbourDistance(const int & ii) const = 0;
+  virtual double NearestNeighbourDistance(const int ii) const = 0;
 
   /// Returns true iff the given index corresponds to a point that
   /// exists in the DNN structure (meaning that it has been added, and
   /// not removed in the meantime)
-  virtual bool Valid(const int & index) const = 0;
+  virtual bool Valid(const int index) const = 0;
 
   /// remove the points labelled by the std::vector indices_to_remove, and
@@ -141,5 +138,5 @@
   /// Remove the point labelled by index and return the list of
   /// points whose nearest neighbours have changed in the process
-  inline void RemovePoint (const int & index,
+  inline void RemovePoint (const int index,
 			   std::vector<int> & indices_of_updated_neighbours) {
     std::vector<int> indices_added;
@@ -158,5 +155,5 @@
   /// point).
   inline void RemoveCombinedAddCombination(
-			const int & index1, const int & index2,
+			const int index1, const int index2,
 			const EtaPhi & newpoint,
 			int & index3,
Index: external/fastjet/internal/IsBase.hh
===================================================================
--- external/fastjet/internal/IsBase.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/internal/IsBase.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: IsBase.hh 3071 2013-04-01 12:52:46Z cacciari $
+//FJSTARTHEADER
+// $Id: IsBase.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __FASTJET_INTERNAL_IS_BASE_HH__
Index: external/fastjet/internal/LazyTiling25.hh
===================================================================
--- external/fastjet/internal/LazyTiling25.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/internal/LazyTiling25.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,195 @@
+#ifndef __FASTJET_LAZYTILING25_HH__
+#define __FASTJET_LAZYTILING25_HH__
+
+// #define INSTRUMENT2 1
+
+//FJSTARTHEADER
+// $Id: LazyTiling25.hh 3477 2014-07-29 14:34:39Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//
+//----------------------------------------------------------------------
+// This file is part of FastJet.
+//
+//  FastJet 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.
+//
+//  The algorithms that underlie FastJet have required considerable
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
+//  FastJet as part of work towards a scientific publication, please
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
+//
+//  FastJet 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 FastJet. If not, see <http://www.gnu.org/licenses/>.
+//----------------------------------------------------------------------
+//FJENDHEADER
+
+//#include "fastjet/PseudoJet.hh"
+#include "fastjet/internal/MinHeap.hh"
+#include "fastjet/ClusterSequence.hh"
+#include "fastjet/internal/LazyTiling9Alt.hh"
+#include "fastjet/internal/LazyTiling9.hh"
+
+
+
+FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
+
+typedef Tile2Base<25> Tile25;
+
+
+// class Tile25 {
+// public:
+//   /// pointers to neighbouring tiles, including self
+//   Tile25 *   begin_tiles[25];
+//   /// neighbouring tiles, excluding self
+//   Tile25 **  surrounding_tiles; 
+//   /// half of neighbouring tiles, no self
+//   Tile25 **  RH_tiles;  
+//   /// just beyond end of tiles
+//   Tile25 **  end_tiles; 
+//   /// start of list of BriefJets contained in this tile
+//   TiledJet * head;    
+//   /// sometimes useful to be able to tag a tile
+//   bool     tagged;    
+//   /// for all particles in the tile, this stores the largest of the
+//   /// (squared) nearest-neighbour distances.
+//   double max_NN_dist;
+//   double eta_centre, phi_centre;
+// 
+//   bool is_near_zero_phi(double tile_size_phi) const {
+//     return phi_centre < 2*tile_size_phi || (twopi-phi_centre) < 2*tile_size_phi;
+//   }
+// };
+
+
+//----------------------------------------------------------------------
+class LazyTiling25 {
+public:
+  LazyTiling25(ClusterSequence & cs);
+
+  void run();
+
+protected:
+  ClusterSequence & _cs;
+  const std::vector<PseudoJet> & _jets;
+  std::vector<Tile25> _tiles;
+
+#ifdef INSTRUMENT2
+  int _ncall; // GPS tmp
+  int _ncall_dtt; // GPS tmp
+#endif // INSTRUMENT2
+
+  double _Rparam, _R2, _invR2;
+  double _tiles_eta_min, _tiles_eta_max;
+  double _tile_size_eta, _tile_size_phi;
+  double _tile_half_size_eta, _tile_half_size_phi;
+  int    _n_tiles_phi,_tiles_ieta_min,_tiles_ieta_max;
+
+  std::vector<TiledJet *> _jets_for_minheap;
+  
+  //MinHeap _minheap;
+
+  void _initialise_tiles();
+
+  // reasonably robust return of tile index given ieta and iphi, in particular
+  // it works even if iphi is negative
+  inline int _tile_index (int ieta, int iphi) const {
+    // note that (-1)%n = -1 so that we have to add _n_tiles_phi
+    // before performing modulo operation
+    return (ieta-_tiles_ieta_min)*_n_tiles_phi
+                  + (iphi+_n_tiles_phi) % _n_tiles_phi;
+  }
+
+  void  _bj_remove_from_tiles(TiledJet * const jet);
+
+  /// returns the tile index given the eta and phi values of a jet
+  int _tile_index(const double eta, const double phi) const;
+
+  // sets up information regarding the tiling of the given jet
+  void _tj_set_jetinfo(TiledJet * const jet, const int _jets_index);
+
+  void _print_tiles(TiledJet * briefjets ) const;
+  void _add_neighbours_to_tile_union(const int tile_index, 
+		 std::vector<int> & tile_union, int & n_near_tiles) const;
+  void _add_untagged_neighbours_to_tile_union(const int tile_index, 
+		 std::vector<int> & tile_union, int & n_near_tiles);
+  void _add_untagged_neighbours_to_tile_union_using_max_info(const TiledJet * const jet, 
+		 std::vector<int> & tile_union, int & n_near_tiles);
+  double _distance_to_tile(const TiledJet * bj, const Tile25 *) 
+#ifdef INSTRUMENT2
+    ;
+#else
+    const;
+#endif 
+  void _update_jetX_jetI_NN(TiledJet * jetX, TiledJet * jetI, std::vector<TiledJet *> & jets_for_minheap);
+
+  void _set_NN(TiledJet * jetI, std::vector<TiledJet *> & jets_for_minheap);
+
+  // return the diJ (multiplied by _R2) for this jet assuming its NN
+  // info is correct
+  template <class J> double _bj_diJ(const J * const jet) const {
+    double kt2 = jet->kt2;
+    if (jet->NN != NULL) {if (jet->NN->kt2 < kt2) {kt2 = jet->NN->kt2;}}
+    return jet->NN_dist * kt2;
+  }
+
+
+  //----------------------------------------------------------------------
+  template <class J> inline void _bj_set_jetinfo(
+                            J * const jetA, const int _jets_index) const {
+    jetA->eta  = _jets[_jets_index].rap();
+    jetA->phi  = _jets[_jets_index].phi_02pi();
+    jetA->kt2  = _cs.jet_scale_for_algorithm(_jets[_jets_index]);
+    jetA->_jets_index = _jets_index;
+    // initialise NN info as well
+    jetA->NN_dist = _R2;
+    jetA->NN      = NULL;
+  }
+
+
+  //----------------------------------------------------------------------
+  template <class J> inline double _bj_dist(
+                const J * const jetA, const J * const jetB) 
+#ifdef INSTRUMENT2
+    {
+    _ncall++; // GPS tmp
+#else
+    const {
+#endif 
+    double dphi = std::abs(jetA->phi - jetB->phi);
+    double deta = (jetA->eta - jetB->eta);
+    if (dphi > pi) {dphi = twopi - dphi;}
+    return dphi*dphi + deta*deta;
+  }
+
+
+  //----------------------------------------------------------------------
+  template <class J> inline double _bj_dist_not_periodic(
+                const J * const jetA, const J * const jetB)
+#ifdef INSTRUMENT2
+    {
+    _ncall++; // GPS tmp
+#else
+    const {
+#endif 
+    //_ncall++; // GPS tmp
+    double dphi = jetA->phi - jetB->phi;
+    double deta = (jetA->eta - jetB->eta);
+    return dphi*dphi + deta*deta;
+  }
+
+};
+
+
+FASTJET_END_NAMESPACE
+
+#endif // __FASTJET_LAZYTILING25_HH__
Index: external/fastjet/internal/LazyTiling9.hh
===================================================================
--- external/fastjet/internal/LazyTiling9.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/internal/LazyTiling9.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,240 @@
+#ifndef __FASTJET_LAZYTILING9_HH__
+#define __FASTJET_LAZYTILING9_HH__
+
+//#define INSTRUMENT2 1
+
+//FJSTARTHEADER
+// $Id: LazyTiling9.hh 3477 2014-07-29 14:34:39Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//
+//----------------------------------------------------------------------
+// This file is part of FastJet.
+//
+//  FastJet 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.
+//
+//  The algorithms that underlie FastJet have required considerable
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
+//  FastJet as part of work towards a scientific publication, please
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
+//
+//  FastJet 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 FastJet. If not, see <http://www.gnu.org/licenses/>.
+//----------------------------------------------------------------------
+//FJENDHEADER
+
+//#include "fastjet/PseudoJet.hh"
+#include "fastjet/internal/MinHeap.hh"
+#include "fastjet/ClusterSequence.hh"
+#include "fastjet/internal/LazyTiling9Alt.hh"
+
+
+FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
+template<int NN>
+class Tile2Base {
+public:
+  /// pointers to neighbouring tiles, including self
+  Tile2Base *   begin_tiles[NN]; 
+  /// neighbouring tiles, excluding self
+  Tile2Base **  surrounding_tiles; 
+  /// half of neighbouring tiles, no self
+  Tile2Base **  RH_tiles;  
+  /// just beyond end of tiles
+  Tile2Base **  end_tiles; 
+  /// start of list of BriefJets contained in this tile
+  TiledJet * head;    
+  /// sometimes useful to be able to tag a tile
+  bool     tagged;    
+  /// true for tiles where the delta phi calculation needs
+  /// potentially to account for periodicity in phi
+  bool     use_periodic_delta_phi;
+  /// for all particles in the tile, this stores the largest of the
+  /// (squared) nearest-neighbour distances.
+  double max_NN_dist;
+  double eta_centre, phi_centre;
+
+  /// returns the number of jets in the tile; useful principally for
+  /// diagnostics
+  int jet_count() const {
+    int count = 0;
+    const TiledJet * jet = head;
+    while (jet != 0) {
+      count++;
+      jet = jet->next;
+    }
+    return count;
+  }
+};
+
+
+typedef Tile2Base<9> Tile2;
+
+// class Tile2 : public Tile2Base {
+// public:
+//   /// pointers to neighbouring tiles, including self
+//   Tile2 *   begin_tiles[n_tile_neighbours]; 
+//   bool is_near_zero_phi(double tile_size_phi) const {
+//     return phi_centre < tile_size_phi || (twopi-phi_centre) < tile_size_phi;
+//   }
+// };
+
+// class Tile2  {
+// public:
+//   /// pointers to neighbouring tiles, including self
+//   Tile2 *   begin_tiles[n_tile_neighbours]; 
+//   /// neighbouring tiles, excluding self
+//   Tile2 **  surrounding_tiles; 
+//   /// half of neighbouring tiles, no self
+//   Tile2 **  RH_tiles;  
+//   /// just beyond end of tiles
+//   Tile2 **  end_tiles; 
+//   /// start of list of BriefJets contained in this tile
+//   TiledJet * head;    
+//   /// sometimes useful to be able to tag a tile
+//   bool     tagged;    
+//   /// for all particles in the tile, this stores the largest of the
+//   /// (squared) nearest-neighbour distances.
+//   double max_NN_dist;
+//   double eta_centre, phi_centre;
+//   bool is_near_zero_phi(double tile_size_phi) const {
+//     return phi_centre < tile_size_phi || (twopi-phi_centre) < tile_size_phi;
+//   }
+// };
+
+
+
+//----------------------------------------------------------------------
+class LazyTiling9 {
+public:
+  LazyTiling9(ClusterSequence & cs);
+
+  void run();
+
+  //void get_next_clustering(int & jetA_index, int & jetB_index, double & dij);
+  
+
+protected:
+  ClusterSequence & _cs;
+  const std::vector<PseudoJet> & _jets;
+  std::vector<Tile2> _tiles;
+
+#ifdef INSTRUMENT2
+  int _ncall; // GPS tmp
+  int _ncall_dtt; // GPS tmp
+#endif // INSTRUMENT2
+
+  double _Rparam, _R2, _invR2;
+  double _tiles_eta_min, _tiles_eta_max;
+  double _tile_size_eta, _tile_size_phi;
+  double _tile_half_size_eta, _tile_half_size_phi;
+  int    _n_tiles_phi,_tiles_ieta_min,_tiles_ieta_max;
+
+  std::vector<TiledJet *> _jets_for_minheap;
+  
+  //MinHeap _minheap;
+
+  void _initialise_tiles();
+
+  // reasonably robust return of tile index given ieta and iphi, in particular
+  // it works even if iphi is negative
+  inline int _tile_index (int ieta, int iphi) const {
+    // note that (-1)%n = -1 so that we have to add _n_tiles_phi
+    // before performing modulo operation
+    return (ieta-_tiles_ieta_min)*_n_tiles_phi
+                  + (iphi+_n_tiles_phi) % _n_tiles_phi;
+  }
+
+  void  _bj_remove_from_tiles(TiledJet * const jet);
+
+  /// returns the tile index given the eta and phi values of a jet
+  int _tile_index(const double eta, const double phi) const;
+
+  // sets up information regarding the tiling of the given jet
+  void _tj_set_jetinfo(TiledJet * const jet, const int _jets_index);
+
+  void _print_tiles(TiledJet * briefjets ) const;
+  void _add_neighbours_to_tile_union(const int tile_index, 
+		 std::vector<int> & tile_union, int & n_near_tiles) const;
+  void _add_untagged_neighbours_to_tile_union(const int tile_index, 
+		 std::vector<int> & tile_union, int & n_near_tiles);
+  void _add_untagged_neighbours_to_tile_union_using_max_info(const TiledJet * const jet, 
+		 std::vector<int> & tile_union, int & n_near_tiles);
+  double _distance_to_tile(const TiledJet * bj, const Tile2 *) 
+#ifdef INSTRUMENT2
+    ;
+#else
+    const;
+#endif 
+  void _update_jetX_jetI_NN(TiledJet * jetX, TiledJet * jetI, std::vector<TiledJet *> & jets_for_minheap);
+
+  void _set_NN(TiledJet * jetI, std::vector<TiledJet *> & jets_for_minheap);
+
+  // return the diJ (multiplied by _R2) for this jet assuming its NN
+  // info is correct
+  template <class J> double _bj_diJ(const J * const jet) const {
+    double kt2 = jet->kt2;
+    if (jet->NN != NULL) {if (jet->NN->kt2 < kt2) {kt2 = jet->NN->kt2;}}
+    return jet->NN_dist * kt2;
+  }
+
+
+  //----------------------------------------------------------------------
+  template <class J> inline void _bj_set_jetinfo(
+                            J * const jetA, const int _jets_index) const {
+    jetA->eta  = _jets[_jets_index].rap();
+    jetA->phi  = _jets[_jets_index].phi_02pi();
+    jetA->kt2  = _cs.jet_scale_for_algorithm(_jets[_jets_index]);
+    jetA->_jets_index = _jets_index;
+    // initialise NN info as well
+    jetA->NN_dist = _R2;
+    jetA->NN      = NULL;
+  }
+
+
+  //----------------------------------------------------------------------
+  template <class J> inline double _bj_dist(
+                const J * const jetA, const J * const jetB) 
+#ifdef INSTRUMENT2
+    {
+    _ncall++; // GPS tmp
+#else
+    const {
+#endif 
+    double dphi = std::abs(jetA->phi - jetB->phi);
+    double deta = (jetA->eta - jetB->eta);
+    if (dphi > pi) {dphi = twopi - dphi;}
+    return dphi*dphi + deta*deta;
+  }
+
+
+  //----------------------------------------------------------------------
+  template <class J> inline double _bj_dist_not_periodic(
+                const J * const jetA, const J * const jetB)
+#ifdef INSTRUMENT2
+    {
+    _ncall++; // GPS tmp
+#else
+    const {
+#endif 
+    //_ncall++; // GPS tmp
+    double dphi = jetA->phi - jetB->phi;
+    double deta = (jetA->eta - jetB->eta);
+    return dphi*dphi + deta*deta;
+  }
+
+};
+
+
+FASTJET_END_NAMESPACE
+
+#endif // __FASTJET_LAZYTILING9_HH__
Index: external/fastjet/internal/LazyTiling9Alt.hh
===================================================================
--- external/fastjet/internal/LazyTiling9Alt.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/internal/LazyTiling9Alt.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,226 @@
+#ifndef __FASTJET_LAZYTILING9ALT_HH__
+#define __FASTJET_LAZYTILING9ALT_HH__
+
+//FJSTARTHEADER
+// $Id: LazyTiling9Alt.hh 3477 2014-07-29 14:34:39Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//
+//----------------------------------------------------------------------
+// This file is part of FastJet.
+//
+//  FastJet 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.
+//
+//  The algorithms that underlie FastJet have required considerable
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
+//  FastJet as part of work towards a scientific publication, please
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
+//
+//  FastJet 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 FastJet. If not, see <http://www.gnu.org/licenses/>.
+//----------------------------------------------------------------------
+//FJENDHEADER
+
+//#include "fastjet/PseudoJet.hh"
+#include "fastjet/internal/MinHeap.hh"
+#include "fastjet/ClusterSequence.hh"
+
+FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
+
+/// structure analogous to BriefJet, but with the extra information
+/// needed for dealing with tiles
+class TiledJet {
+public:
+  double     eta, phi, kt2, NN_dist;
+  TiledJet * NN, *previous, * next; 
+  int        _jets_index, tile_index;
+  bool _minheap_update_needed;
+
+  // indicate whether jets need to have their minheap entries
+  // updated).
+  inline void label_minheap_update_needed() {_minheap_update_needed = true;}
+  inline void label_minheap_update_done()   {_minheap_update_needed = false;}
+  inline bool minheap_update_needed() const {return _minheap_update_needed;}
+};
+
+const int n_tile_neighbours = 9;
+
+class Tile {
+public:
+  typedef double (Tile::*DistToTileFn)(const TiledJet*) const;
+  typedef std::pair<Tile *, DistToTileFn> TileFnPair;
+  /// pointers to neighbouring tiles, including self
+  TileFnPair begin_tiles[n_tile_neighbours]; 
+  /// neighbouring tiles, excluding self
+  TileFnPair *  surrounding_tiles; 
+  /// half of neighbouring tiles, no self
+  TileFnPair *  RH_tiles;  
+  /// just beyond end of tiles
+  TileFnPair *  end_tiles; 
+  /// start of list of BriefJets contained in this tile
+  TiledJet * head;    
+  /// sometimes useful to be able to tag a tile
+  bool     tagged;    
+  /// true for tiles where the delta phi calculation needs
+  /// potentially to account for periodicity in phi
+  bool     use_periodic_delta_phi;
+  /// for all particles in the tile, this stores the largest of the
+  /// (squared) nearest-neighbour distances.
+  double max_NN_dist;
+  double eta_min, eta_max, phi_min, phi_max;
+
+  double distance_to_centre(const TiledJet *) const {return 0;}
+  double distance_to_left(const TiledJet * jet) const {
+    double deta = jet->eta - eta_min;
+    return deta*deta;
+  }
+  double distance_to_right(const TiledJet * jet) const {
+    double deta = jet->eta - eta_max;
+    return deta*deta;
+  }
+  double distance_to_bottom(const TiledJet * jet) const {
+    double dphi = jet->phi - phi_min;
+    return dphi*dphi;
+  }
+  double distance_to_top(const TiledJet * jet) const {
+    double dphi = jet->phi - phi_max;
+    return dphi*dphi;
+  }
+
+  double distance_to_left_top(const TiledJet * jet) const {
+    double deta = jet->eta - eta_min;
+    double dphi = jet->phi - phi_max;
+    return deta*deta + dphi*dphi;
+  }
+  double distance_to_left_bottom(const TiledJet * jet) const {
+    double deta = jet->eta - eta_min;
+    double dphi = jet->phi - phi_min;
+    return deta*deta + dphi*dphi;
+  }
+  double distance_to_right_top(const TiledJet * jet) const {
+    double deta = jet->eta - eta_max;
+    double dphi = jet->phi - phi_max;
+    return deta*deta + dphi*dphi;
+  }
+  double distance_to_right_bottom(const TiledJet * jet) const {
+    double deta = jet->eta - eta_max;
+    double dphi = jet->phi - phi_min;
+    return deta*deta + dphi*dphi;
+  }
+
+  
+};
+
+//----------------------------------------------------------------------
+class LazyTiling9Alt {
+public:
+  LazyTiling9Alt(ClusterSequence & cs);
+
+  void run();
+
+  //void get_next_clustering(int & jetA_index, int & jetB_index, double & dij);
+  
+
+protected:
+  ClusterSequence & _cs;
+  const std::vector<PseudoJet> & _jets;
+  std::vector<Tile> _tiles;
+
+
+  double _Rparam, _R2, _invR2;
+  double _tiles_eta_min, _tiles_eta_max;
+  double _tile_size_eta, _tile_size_phi;
+  double _tile_half_size_eta, _tile_half_size_phi;
+  int    _n_tiles_phi,_tiles_ieta_min,_tiles_ieta_max;
+
+  std::vector<TiledJet *> _jets_for_minheap;
+  
+  //MinHeap _minheap;
+
+  void _initialise_tiles();
+
+  // reasonably robust return of tile index given ieta and iphi, in particular
+  // it works even if iphi is negative
+  inline int _tile_index (int ieta, int iphi) const {
+    // note that (-1)%n = -1 so that we have to add _n_tiles_phi
+    // before performing modulo operation
+    return (ieta-_tiles_ieta_min)*_n_tiles_phi
+                  + (iphi+_n_tiles_phi) % _n_tiles_phi;
+  }
+
+  void  _bj_remove_from_tiles(TiledJet * const jet);
+
+  /// returns the tile index given the eta and phi values of a jet
+  int _tile_index(const double eta, const double phi) const;
+
+  // sets up information regarding the tiling of the given jet
+  void _tj_set_jetinfo(TiledJet * const jet, const int _jets_index);
+
+  void _print_tiles(TiledJet * briefjets ) const;
+  void _add_neighbours_to_tile_union(const int tile_index, 
+		 std::vector<int> & tile_union, int & n_near_tiles) const;
+  void _add_untagged_neighbours_to_tile_union(const int tile_index, 
+		 std::vector<int> & tile_union, int & n_near_tiles);
+  void _add_untagged_neighbours_to_tile_union_using_max_info(const TiledJet * const jet, 
+		 std::vector<int> & tile_union, int & n_near_tiles);
+  //double _distance_to_tile(const TiledJet * bj, const Tile *) const;
+  void _update_jetX_jetI_NN(TiledJet * jetX, TiledJet * jetI, std::vector<TiledJet *> & jets_for_minheap);
+
+  void _set_NN(TiledJet * jetI, std::vector<TiledJet *> & jets_for_minheap);
+
+  // return the diJ (multiplied by _R2) for this jet assuming its NN
+  // info is correct
+  template <class J> double _bj_diJ(const J * const jet) const {
+    double kt2 = jet->kt2;
+    if (jet->NN != NULL) {if (jet->NN->kt2 < kt2) {kt2 = jet->NN->kt2;}}
+    return jet->NN_dist * kt2;
+  }
+
+
+  //----------------------------------------------------------------------
+  template <class J> inline void _bj_set_jetinfo(
+                            J * const jetA, const int _jets_index) const {
+    jetA->eta  = _jets[_jets_index].rap();
+    jetA->phi  = _jets[_jets_index].phi_02pi();
+    jetA->kt2  = _cs.jet_scale_for_algorithm(_jets[_jets_index]);
+    jetA->_jets_index = _jets_index;
+    // initialise NN info as well
+    jetA->NN_dist = _R2;
+    jetA->NN      = NULL;
+  }
+
+
+  //----------------------------------------------------------------------
+  template <class J> inline double _bj_dist(
+                const J * const jetA, const J * const jetB) const {
+    double dphi = std::abs(jetA->phi - jetB->phi);
+    double deta = (jetA->eta - jetB->eta);
+    if (dphi > pi) {dphi = twopi - dphi;}
+    return dphi*dphi + deta*deta;
+  }
+
+
+  //----------------------------------------------------------------------
+  template <class J> inline double _bj_dist_not_periodic(
+                const J * const jetA, const J * const jetB) const {
+    double dphi = jetA->phi - jetB->phi;
+    double deta = (jetA->eta - jetB->eta);
+    return dphi*dphi + deta*deta;
+  }
+
+};
+
+
+FASTJET_END_NAMESPACE
+
+#endif // __FASTJET_LAZYTILING9ALT_HH__
Index: external/fastjet/internal/LazyTiling9SeparateGhosts.hh
===================================================================
--- external/fastjet/internal/LazyTiling9SeparateGhosts.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/internal/LazyTiling9SeparateGhosts.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,195 @@
+#ifndef __FASTJET_LAZYTILING9SEPARATEGHOSTS_HH__
+#define __FASTJET_LAZYTILING9SEPARATEGHOSTS_HH__
+
+//FJSTARTHEADER
+// $Id: LazyTiling9SeparateGhosts.hh 3596 2014-08-12 15:27:19Z soyez $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//
+//----------------------------------------------------------------------
+// This file is part of FastJet.
+//
+//  FastJet 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.
+//
+//  The algorithms that underlie FastJet have required considerable
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
+//  FastJet as part of work towards a scientific publication, please
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
+//
+//  FastJet 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 FastJet. If not, see <http://www.gnu.org/licenses/>.
+//----------------------------------------------------------------------
+//FJENDHEADER
+
+//#include "fastjet/PseudoJet.hh"
+#include "fastjet/internal/MinHeap.hh"
+#include "fastjet/ClusterSequence.hh"
+#include "fastjet/internal/LazyTiling9Alt.hh"
+
+FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
+
+class TiledJet3 {
+public:
+  double     eta, phi, kt2, NN_dist;
+  TiledJet3 * NN, *previous, * next; 
+  int        _jets_index, tile_index;
+  bool _minheap_update_needed;
+  bool is_ghost;
+
+  // indicate whether jets need to have their minheap entries
+  // updated).
+  inline void label_minheap_update_needed() {_minheap_update_needed = true;}
+  inline void label_minheap_update_done()   {_minheap_update_needed = false;}
+  inline bool minheap_update_needed() const {return _minheap_update_needed;}
+};
+
+
+class Tile3 {
+public:
+  /// pointers to neighbouring tiles, including self
+  Tile3 *   begin_tiles[n_tile_neighbours]; 
+  /// neighbouring tiles, excluding self
+  Tile3 **  surrounding_tiles; 
+  /// half of neighbouring tiles, no self
+  Tile3 **  RH_tiles;  
+  /// just beyond end of tiles
+  Tile3 **  end_tiles; 
+  /// start of list of BriefJets contained in this tile
+  TiledJet3 * head;    
+  /// start of list of BriefJets contained in this tile
+  TiledJet3 * ghost_head;    
+  /// sometimes useful to be able to tag a tile
+  bool     tagged;    
+  /// for all particles in the tile, this stores the largest of the
+  /// (squared) nearest-neighbour distances.
+  double max_NN_dist;
+  double eta_centre, phi_centre;
+
+  bool is_near_zero_phi(double tile_size_phi) const {
+    return phi_centre < tile_size_phi || (twopi-phi_centre) < tile_size_phi;
+  }
+};
+
+
+//----------------------------------------------------------------------
+class LazyTiling9SeparateGhosts {
+public:
+  LazyTiling9SeparateGhosts(ClusterSequence & cs);
+
+  void run();
+
+  //void get_next_clustering(int & jetA_index, int & jetB_index, double & dij);
+
+  /// this is the pt2 threshold below which particles will be
+  /// considered as ghosts.
+  ///
+  /// Note that as it stands, a user can decide to change that
+  /// value. Note however that this has to be done at the user's own
+  /// risk (this is an internal part of fastjet).In a similar spirit,
+  /// the interface to access this valus might also change in a future
+  /// release of FastJet.
+  static double ghost_pt2_threshold;
+
+protected:
+  ClusterSequence & _cs;
+  const std::vector<PseudoJet> & _jets;
+  std::vector<Tile3> _tiles;
+
+
+  double _Rparam, _R2, _invR2;
+  double _tiles_eta_min, _tiles_eta_max;
+  double _tile_size_eta, _tile_size_phi;
+  double _tile_half_size_eta, _tile_half_size_phi;
+  int    _n_tiles_phi,_tiles_ieta_min,_tiles_ieta_max;
+
+  std::vector<TiledJet3 *> _jets_for_minheap;
+  
+  //MinHeap _minheap;
+
+  void _initialise_tiles();
+
+  // reasonably robust return of tile index given ieta and iphi, in particular
+  // it works even if iphi is negative
+  inline int _tile_index (int ieta, int iphi) const {
+    // note that (-1)%n = -1 so that we have to add _n_tiles_phi
+    // before performing modulo operation
+    return (ieta-_tiles_ieta_min)*_n_tiles_phi
+                  + (iphi+_n_tiles_phi) % _n_tiles_phi;
+  }
+
+  void  _bj_remove_from_tiles(TiledJet3 * const jet);
+
+  /// returns the tile index given the eta and phi values of a jet
+  int _tile_index(const double eta, const double phi) const;
+
+  // sets up information regarding the tiling of the given jet
+  void _tj_set_jetinfo(TiledJet3 * const jet, const int _jets_index, bool is_ghost);
+
+  void _print_tiles(TiledJet3 * briefjets ) const;
+  void _add_neighbours_to_tile_union(const int tile_index, 
+		 std::vector<int> & tile_union, int & n_near_tiles) const;
+  void _add_untagged_neighbours_to_tile_union(const int tile_index, 
+		 std::vector<int> & tile_union, int & n_near_tiles);
+  void _add_untagged_neighbours_to_tile_union_using_max_info(const TiledJet3 * const jet, 
+		 std::vector<int> & tile_union, int & n_near_tiles);
+  double _distance_to_tile(const TiledJet3 * bj, const Tile3 *) const;
+  void _update_jetX_jetI_NN(TiledJet3 * jetX, TiledJet3 * jetI, std::vector<TiledJet3 *> & jets_for_minheap);
+
+  void _set_NN(TiledJet3 * jetI, std::vector<TiledJet3 *> & jets_for_minheap);
+
+  // return the diJ (multiplied by _R2) for this jet assuming its NN
+  // info is correct
+  template <class J> double _bj_diJ(const J * const jet) const {
+    double kt2 = jet->kt2;
+    if (jet->NN != NULL) {if (jet->NN->kt2 < kt2) {kt2 = jet->NN->kt2;}}
+    return jet->NN_dist * kt2;
+  }
+
+
+  //----------------------------------------------------------------------
+  template <class J> inline void _bj_set_jetinfo(
+                            J * const jetA, const int _jets_index) const {
+    jetA->eta  = _jets[_jets_index].rap();
+    jetA->phi  = _jets[_jets_index].phi_02pi();
+    jetA->kt2  = _cs.jet_scale_for_algorithm(_jets[_jets_index]);
+    jetA->_jets_index = _jets_index;
+    // initialise NN info as well
+    jetA->NN_dist = _R2;
+    jetA->NN      = NULL;
+  }
+
+
+  //----------------------------------------------------------------------
+  template <class J> inline double _bj_dist(
+                const J * const jetA, const J * const jetB) const {
+    double dphi = std::abs(jetA->phi - jetB->phi);
+    double deta = (jetA->eta - jetB->eta);
+    if (dphi > pi) {dphi = twopi - dphi;}
+    return dphi*dphi + deta*deta;
+  }
+
+
+  //----------------------------------------------------------------------
+  template <class J> inline double _bj_dist_not_periodic(
+                const J * const jetA, const J * const jetB) const {
+    double dphi = jetA->phi - jetB->phi;
+    double deta = (jetA->eta - jetB->eta);
+    return dphi*dphi + deta*deta;
+  }
+
+};
+
+
+FASTJET_END_NAMESPACE
+
+#endif // __FASTJET_LAZYTILING9SEPARATEGHOSTS_HH__
Index: external/fastjet/internal/LimitedWarning.hh
===================================================================
--- external/fastjet/internal/LimitedWarning.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/internal/LimitedWarning.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,8 +2,8 @@
 #define __FASTJET_INTERNALLIMITEDWARNING_HH__
 
-//STARTHEADER
-// $Id: LimitedWarning.hh 2577 2011-09-13 15:11:38Z salam $
+//FJSTARTHEADER
+// $Id: LimitedWarning.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,5 +30,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
Index: external/fastjet/internal/MinHeap.hh
===================================================================
--- external/fastjet/internal/MinHeap.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/internal/MinHeap.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: MinHeap.hh 2577 2011-09-13 15:11:38Z salam $
+//FJSTARTHEADER
+// $Id: MinHeap.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __FASTJET_MINHEAP__HH__
@@ -50,18 +52,26 @@
   /// expansion to a maximum size max_size;
   MinHeap (const std::vector<double> & values, unsigned int max_size) :
-    _heap(max_size) {_initialise(values);};
+    _heap(max_size) {initialise(values);}
+
+  /// do the minimal setup for a MinHeap that can reach max_size;
+  /// initialisation must be performed later with the actual values.
+  MinHeap (unsigned int max_size) : _heap(max_size) {}
 
   /// constructor in which the the maximum size is the size of the values array
   MinHeap (const std::vector<double> & values) :
-    _heap(values.size()) {_initialise(values);};
-  
+    _heap(values.size()) {initialise(values);}
+
+  /// initialise the heap with the supplied values. Should only be called if
+  /// the constructor did not supply values.
+  void initialise(const std::vector<double> & values);
+
   /// return the location of the minimal value on the heap
   inline unsigned int minloc() const {
-    return (_heap[0].minloc) - &(_heap[0]);};
+    return (_heap[0].minloc) - &(_heap[0]);}
   
   /// return the minimal value on the heap
-  inline double       minval() const {return _heap[0].minloc->value;};
+  inline double       minval() const {return _heap[0].minloc->value;}
 
-  inline double operator[](int i) const {return _heap[i].value;};
+  inline double operator[](int i) const {return _heap[i].value;}
 
   /// remove the value at the specified location (i.e. replace it with
@@ -82,5 +92,4 @@
   std::vector<ValueLoc> _heap;
 
-  void _initialise(const std::vector<double> & values);
 
 
Index: external/fastjet/internal/SearchTree.hh
===================================================================
--- external/fastjet/internal/SearchTree.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/internal/SearchTree.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: SearchTree.hh 3107 2013-05-03 15:47:47Z salam $
+//FJSTARTHEADER
+// $Id: SearchTree.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
@@ -188,7 +190,12 @@
 public:
 
-  // so that it can access out _node object;
+  // so that it can access our _node object;
   // note: "class U" needed for clang (v1.1 branches/release_27) compilation
-  template<class U> friend class SearchTree<U>::const_circulator;
+  // 2014-07-22: as reported by Torbjorn Sjostrand,
+  // the next line was giving a warning with Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
+  // (dependent nested name specifier 'SearchTree<U>::' for friend class declaration is not supported)
+  // Just commenting it out, things still seem to work; same with a template of type T
+  //template<class U> friend class SearchTree<U>::const_circulator;
+  friend class SearchTree<T>::const_circulator;
   friend class SearchTree<T>;
 
Index: external/fastjet/internal/TilingExtent.hh
===================================================================
--- external/fastjet/internal/TilingExtent.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/internal/TilingExtent.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,69 @@
+#ifndef __FASTJET_TILINGEXTENT_HH__
+#define __FASTJET_TILINGEXTENT_HH__
+
+#include "fastjet/ClusterSequence.hh"
+
+//FJSTARTHEADER
+// $Id: TilingExtent.hh 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//
+//----------------------------------------------------------------------
+// This file is part of FastJet.
+//
+//  FastJet 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.
+//
+//  The algorithms that underlie FastJet have required considerable
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
+//  FastJet as part of work towards a scientific publication, please
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
+//
+//  FastJet 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 FastJet. If not, see <http://www.gnu.org/licenses/>.
+//----------------------------------------------------------------------
+//FJENDHEADER
+
+FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
+
+//----------------------------------------------------------------------
+/// class to perform a fast analysis of the appropriate rapidity range
+/// in which to perform tiling
+class TilingExtent {
+public:
+  /// constructor that takes a ClusterSequence in a state where the
+  /// initial particles have been set up, but before clustering has
+  /// started.
+  TilingExtent(ClusterSequence & cs);
+
+  /// returns the suggested minimum rapidity for the tiling
+  double minrap() const {return _minrap;}
+  /// returns the suggested maximum rapidity for the tiling
+  double maxrap() const {return _maxrap;}
+
+  /// internally, the class bins the particle multiplicity versus
+  /// rapidity, in bins of size 1 running roughly from minrap to maxrap
+  /// (including overflows); this function returns the sum of squares
+  /// of bin contents, which may be informative for deciding strategy
+  /// choices.
+  double sum_of_binned_squared_multiplicity() const {return _cumul2;}
+
+private:
+  double _minrap, _maxrap, _cumul2;
+
+  /// attempts to calculate a sensible rapidity extent for the tiling
+  void _determine_rapidity_extent(const std::vector<PseudoJet> & particles);
+};
+
+FASTJET_END_NAMESPACE      // defined in fastjet/internal/base.hh
+
+#endif // __FASTJET_TILINGEXTENT_HH__
Index: external/fastjet/internal/Triangulation.hh
===================================================================
--- external/fastjet/internal/Triangulation.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/internal/Triangulation.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -3,8 +3,8 @@
 #define __FASTJET_TRIANGULATION__
 
-//STARTHEADER
-// $Id: Triangulation.hh 2595 2011-09-23 09:05:04Z salam $
+//FJSTARTHEADER
+// $Id: Triangulation.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -17,7 +17,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -29,5 +31,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
Index: external/fastjet/internal/Voronoi.hh
===================================================================
--- external/fastjet/internal/Voronoi.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/internal/Voronoi.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,28 +2,33 @@
 #define __FASTJET__VORONOI_H__
 
-//STARTHEADER
-// $Id: Voronoi.hh 2686 2011-11-14 09:28:22Z soyez $
-//
-// Copyright (c) 1994 by AT&T Bell Laboratories (see below)
-//
+//FJSTARTHEADER
+// $Id: Voronoi.hh 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
-// This file is included as part of FastJet but was mostly written by
-// S. Fortune in C, put into C++ with memory management by S
-// O'Sullivan, and with further interface and memeory management
-// modifications by Gregory Soyez.
-//
-// Permission to use, copy, modify, and distribute this software for
-// any purpose without fee is hereby granted, provided that this
-// entire notice is included in all copies of any software which is or
-// includes a copy or modification of this software and in all copies
-// of the supporting documentation for such software. THIS SOFTWARE IS
-// BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED WARRANTY.
-// IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY REPRESENTATION
-// OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS
-// SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
-//
+// This file is part of FastJet.
+//
+//  FastJet 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.
+//
+//  The algorithms that underlie FastJet have required considerable
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
+//  FastJet as part of work towards a scientific publication, please
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
+//
+//  FastJet 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 FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
Index: external/fastjet/internal/base.hh
===================================================================
--- external/fastjet/internal/base.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/internal/base.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,7 +1,7 @@
 
-//STARTHEADER
-// $Id: base.hh 2717 2011-11-17 14:15:46Z salam $
+//FJSTARTHEADER
+// $Id: base.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -14,7 +14,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -26,5 +28,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __FASTJET_FASTJET_BASE_HH__
Index: external/fastjet/internal/numconsts.hh
===================================================================
--- external/fastjet/internal/numconsts.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/internal/numconsts.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: numconsts.hh 2577 2011-09-13 15:11:38Z salam $
+//FJSTARTHEADER
+// $Id: numconsts.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
Index: external/fastjet/plugins/ATLASCone/ATLASConePlugin.cc
===================================================================
--- external/fastjet/plugins/ATLASCone/ATLASConePlugin.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/ATLASCone/ATLASConePlugin.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: ATLASConePlugin.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2007-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2007-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 // fastjet stuff
Index: external/fastjet/plugins/ATLASCone/fastjet/ATLASConePlugin.hh
===================================================================
--- external/fastjet/plugins/ATLASCone/fastjet/ATLASConePlugin.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/ATLASCone/fastjet/ATLASConePlugin.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: ATLASConePlugin.hh 2758 2011-11-24 08:31:58Z soyez $
+//FJSTARTHEADER
+// $Id: ATLASConePlugin.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2007-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2007-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 // Note on the implementation:
Index: external/fastjet/plugins/CDFCones/CDFJetCluPlugin.cc
===================================================================
--- external/fastjet/plugins/CDFCones/CDFJetCluPlugin.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/CDFCones/CDFJetCluPlugin.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: CDFJetCluPlugin.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/CDFJetCluPlugin.hh"
Index: external/fastjet/plugins/CDFCones/CDFMidPointPlugin.cc
===================================================================
--- external/fastjet/plugins/CDFCones/CDFMidPointPlugin.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/CDFCones/CDFMidPointPlugin.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: CDFMidPointPlugin.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/CDFMidPointPlugin.hh"
Index: external/fastjet/plugins/CDFCones/JetCluAlgorithm.cc
===================================================================
--- external/fastjet/plugins/CDFCones/JetCluAlgorithm.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/CDFCones/JetCluAlgorithm.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -11,4 +11,8 @@
 // History of changes compared to the original JetCluAlgorithm.cc file
 // 
+// 2014-08-13 Matteo Cacciari and Gavin Salam
+//        * commented out towers variable in JetCluAlgorithm::buildPreClusters
+//          interface to avoid compiler warning
+//
 // 2011-11-14  Gregory Soyez  <soyez@fastjet.fr>
 //
@@ -55,5 +59,7 @@
 }
 
-void JetCluAlgorithm::buildPreClusters(std::vector<Cluster>& seedTowers, std::vector<PhysicsTower>& towers,
+// MC+GPS 2014-08-13, commented out the towers variable to avoid an
+// unused variable warning
+void JetCluAlgorithm::buildPreClusters(std::vector<Cluster>& seedTowers, std::vector<PhysicsTower>& /*towers*/,
 				       std::vector<Cluster>& preClusters)
 {
Index: external/fastjet/plugins/CDFCones/MidPointAlgorithm.cc
===================================================================
--- external/fastjet/plugins/CDFCones/MidPointAlgorithm.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/CDFCones/MidPointAlgorithm.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -11,4 +11,9 @@
 // History of changes compared to the original MidPointAlgorithm.cc file
 // 
+// 2014-08-13 Matteo Cacciari and Gavin Salam
+//        * changed a number of int -> unsigned (and in one case
+//          added explicit conversion to int) to eliminate
+//          long-standing compiler warnings
+//
 // 2009-01-17  Gregory Soyez  <soyez@fastjet.fr>
 // 
@@ -68,9 +73,11 @@
   std::vector< std::vector<bool> > distanceOK;
   distanceOK.resize(stableCones.size() - 1);
-  for(int nCluster1 = 1; nCluster1 < stableCones.size(); nCluster1++){
+  // MC+GPS 2014-08-13, replaced int with unsigned
+  for(unsigned nCluster1 = 1; nCluster1 < stableCones.size(); nCluster1++){
     distanceOK[nCluster1 - 1].resize(nCluster1);
     double cluster1Rapidity = stableCones[nCluster1].fourVector.y();
     double cluster1Phi      = stableCones[nCluster1].fourVector.phi();
-    for(int nCluster2 = 0; nCluster2 < nCluster1; nCluster2++){
+    // MC+GPS 2014-08-13, replaced int with unsigned
+    for(unsigned nCluster2 = 0; nCluster2 < nCluster1; nCluster2++){
       double cluster2Rapidity = stableCones[nCluster2].fourVector.y();
       double cluster2Phi      = stableCones[nCluster2].fourVector.phi();
@@ -94,8 +101,10 @@
   // Loop over all combinations. Calculate MidPoint. Make midPointClusters.
   bool reduceConeSize = false;
-  for(int iPair = 0; iPair < pairs.size(); iPair++){
+  // MC+GPS 2014-08-13, replaced int with unsigned
+  for(unsigned iPair = 0; iPair < pairs.size(); iPair++){
     // Calculate rapidity, phi and pT of MidPoint.
     LorentzVector midPoint(0,0,0,0);
-    for(int iPairMember = 0; iPairMember < pairs[iPair].size(); iPairMember++)
+    // MC+GPS 2014-08-13, replaced int with unsigned
+    for(unsigned iPairMember = 0; iPairMember < pairs[iPair].size(); iPairMember++)
       midPoint.add(stableCones[pairs[iPair][iPairMember]].fourVector);
     iterateCone(midPoint.y(),midPoint.phi(),midPoint.pt(),towers,stableCones,reduceConeSize);
@@ -174,8 +183,10 @@
   if(testPair.size())
     nextClusterStart = testPair.back() + 1;
-  for(int nextCluster = nextClusterStart; nextCluster <= distanceOK.size(); nextCluster++){
+  // MC+GPS 2014-08-13, replaced int nextCluster with unsigned
+  for(unsigned nextCluster = nextClusterStart; nextCluster <= distanceOK.size(); nextCluster++){
     // Is new SeedCone less than 2*_coneRadius apart from all clusters in testPair?
     bool addCluster = true;
-    for(int iCluster = 0; iCluster < testPair.size() && addCluster; iCluster++)
+    // MC+GPS 2014-08-13, replaced int iCluster with unsigned
+    for(unsigned iCluster = 0; iCluster < testPair.size() && addCluster; iCluster++)
       if(!distanceOK[nextCluster - 1][testPair[iCluster]])
 	addCluster = false;
@@ -187,5 +198,6 @@
 	pairs.push_back(testPair);
       // If not bigger than allowed, find more clusters within 2*_coneRadius.
-      if(testPair.size() < maxClustersInPair)
+      // GPS+MC 2014-08-13, replaced testPair.size() with int(testPair.size())
+      if(int(testPair.size()) < maxClustersInPair)
 	addClustersToPairs(testPair,pairs,distanceOK,maxClustersInPair);
       // All combinations containing testPair found. Remove last element.
Index: external/fastjet/plugins/CDFCones/fastjet/CDFJetCluPlugin.hh
===================================================================
--- external/fastjet/plugins/CDFCones/fastjet/CDFJetCluPlugin.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/CDFCones/fastjet/CDFJetCluPlugin.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: CDFJetCluPlugin.hh 2758 2011-11-24 08:31:58Z soyez $
+//FJSTARTHEADER
+// $Id: CDFJetCluPlugin.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __CDFJETCLUPLUGIN_HH__
Index: external/fastjet/plugins/CDFCones/fastjet/CDFMidPointPlugin.hh
===================================================================
--- external/fastjet/plugins/CDFCones/fastjet/CDFMidPointPlugin.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/CDFCones/fastjet/CDFMidPointPlugin.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: CDFMidPointPlugin.hh 2758 2011-11-24 08:31:58Z soyez $
+//FJSTARTHEADER
+// $Id: CDFMidPointPlugin.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __CDFMIDPOINTPLUGIN_HH__
Index: external/fastjet/plugins/CMSIterativeCone/CMSIterativeConePlugin.cc
===================================================================
--- external/fastjet/plugins/CMSIterativeCone/CMSIterativeConePlugin.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/CMSIterativeCone/CMSIterativeConePlugin.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,38 +1,31 @@
-//STARTHEADER
-// $Id$
-//
-// Copyright (c) 2007-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
-// Copyright (c) ????-????, CMS [for the iterative-cone code itself]
+//FJSTARTHEADER
+// $Id: CMSIterativeConePlugin.cc 1504 2009-04-10 13:39:48Z salam $
+//
+// Copyright (c) 2007-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
-// This file is part of FastJet. It contains code that has been
-// obtained from the CMS collaboration, revision 1.14 of the
-// CMSIterativeConeAlgorithm.cc file in CMSSW, see
-//   http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/CMSSW/RecoJets/JetAlgorithms/src/CMSIterativeConeAlgorithm.cc?hideattic=0&revision=1.14&view=markup
-//
-// Permission has been granted by the CMS collaboration to release it
-// in FastJet under the terms of the GNU Public License(v2) (see the
-// COPYING file in the main FastJet directory for details).
-// Changes from the original file are listed below.
-//
-// FastJet 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.
-//
-// The algorithms that underlie FastJet have required considerable
-// development and are described in hep-ph/0512210. If you use
-// FastJet as part of work towards a scientific publication, please
-// include a citation to the FastJet paper.
-//
-// FastJet 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 FastJet. If not, see <http://www.gnu.org/licenses/>.
+// This file is part of FastJet.
+//
+//  FastJet 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.
+//
+//  The algorithms that underlie FastJet have required considerable
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
+//  FastJet as part of work towards a scientific publication, please
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
+//
+//  FastJet 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 FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 // List of changes compared to the original CMS code (revision 1.14 of
Index: external/fastjet/plugins/CMSIterativeCone/fastjet/CMSIterativeConePlugin.hh
===================================================================
--- external/fastjet/plugins/CMSIterativeCone/fastjet/CMSIterativeConePlugin.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/CMSIterativeCone/fastjet/CMSIterativeConePlugin.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
+//FJSTARTHEADER
 // $Id: CMSIterativeConePlugin.hh 1508 2009-04-10 22:46:49Z soyez $
 //
-// Copyright (c) 2007-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2007-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __CMSITERATIVECONEPLUGIN_HH__
Index: external/fastjet/plugins/D0RunICone/D0RunIBaseConePlugin.cc
===================================================================
--- external/fastjet/plugins/D0RunICone/D0RunIBaseConePlugin.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/D0RunICone/D0RunIBaseConePlugin.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
-//
-// Copyright (c) 2009-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: D0RunIBaseConePlugin.cc 1779 2010-10-25 10:32:59Z soyez $
+//
+// Copyright (c) 2009-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 // D0 stuff
Index: external/fastjet/plugins/D0RunICone/fastjet/D0RunIBaseConePlugin.hh
===================================================================
--- external/fastjet/plugins/D0RunICone/fastjet/D0RunIBaseConePlugin.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/D0RunICone/fastjet/D0RunIBaseConePlugin.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,8 +2,8 @@
 #define __D0RUNIBASECONEPLUGIN_HH__
 
-//STARTHEADER
+//FJSTARTHEADER
 // $Id: D0RunIBaseConePlugin.hh 1778 2010-10-25 10:02:58Z soyez $
 //
-// Copyright (c) 2009-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2009-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,5 +30,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/JetDefinition.hh"
Index: external/fastjet/plugins/D0RunICone/fastjet/D0RunIConePlugin.hh
===================================================================
--- external/fastjet/plugins/D0RunICone/fastjet/D0RunIConePlugin.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/D0RunICone/fastjet/D0RunIConePlugin.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,8 +2,8 @@
 #define __D0RUNICONEPLUGIN_HH__
 
-//STARTHEADER
+//FJSTARTHEADER
 // $Id: D0RunIConePlugin.hh 1778 2010-10-25 10:02:58Z soyez $
 //
-// Copyright (c) 2009-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2009-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,5 +30,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "D0RunIBaseConePlugin.hh"
Index: external/fastjet/plugins/D0RunICone/fastjet/D0RunIpre96ConePlugin.hh
===================================================================
--- external/fastjet/plugins/D0RunICone/fastjet/D0RunIpre96ConePlugin.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/D0RunICone/fastjet/D0RunIpre96ConePlugin.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,8 +2,8 @@
 #define __D0RUNIPRE96CONEPLUGIN_HH__
 
-//STARTHEADER
+//FJSTARTHEADER
 // $Id: D0RunIpre96ConePlugin.hh 1778 2010-10-25 10:02:58Z soyez $
 //
-// Copyright (c) 2009-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2009-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,5 +30,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "D0RunIBaseConePlugin.hh"
Index: external/fastjet/plugins/D0RunIICone/D0RunIIConePlugin.cc
===================================================================
--- external/fastjet/plugins/D0RunIICone/D0RunIIConePlugin.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/D0RunIICone/D0RunIIConePlugin.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: D0RunIIConePlugin.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/D0RunIIConePlugin.hh"
Index: external/fastjet/plugins/D0RunIICone/ILConeAlgorithm.hpp
===================================================================
--- external/fastjet/plugins/D0RunIICone/ILConeAlgorithm.hpp	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/D0RunIICone/ILConeAlgorithm.hpp	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -49,5 +49,4 @@
 //
 // 2012-06-12  Gregory Soyez  <soyez@fastjet.fr>
-//
 //        * Replaced addItem(...) by this->addItem(...) to allow
 //          compilation with gcc 4.7 which no longer performs
Index: external/fastjet/plugins/D0RunIICone/fastjet/D0RunIIConePlugin.hh
===================================================================
--- external/fastjet/plugins/D0RunIICone/fastjet/D0RunIIConePlugin.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/D0RunIICone/fastjet/D0RunIIConePlugin.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,8 +2,8 @@
 #define __D0RUNIICONEPLUGIN_HH__
 
-//STARTHEADER
-// $Id: D0RunIIConePlugin.hh 2761 2011-11-24 13:54:05Z soyez $
+//FJSTARTHEADER
+// $Id: D0RunIIConePlugin.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,5 +30,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/JetDefinition.hh"
Index: external/fastjet/plugins/EECambridge/EECambridgePlugin.cc
===================================================================
--- external/fastjet/plugins/EECambridge/EECambridgePlugin.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/EECambridge/EECambridgePlugin.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: EECambridgePlugin.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2007-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2007-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 // fastjet stuff
Index: external/fastjet/plugins/EECambridge/fastjet/EECambridgePlugin.hh
===================================================================
--- external/fastjet/plugins/EECambridge/fastjet/EECambridgePlugin.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/EECambridge/fastjet/EECambridgePlugin.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,8 +2,8 @@
 #define __EECAMBRIDGEPLUGIN_HH__
 
-//STARTHEADER
-// $Id: EECambridgePlugin.hh 2692 2011-11-14 16:27:44Z soyez $
+//FJSTARTHEADER
+// $Id: EECambridgePlugin.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2009, Matteo Cacciari, Gavin Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,5 +30,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
@@ -82,4 +84,8 @@
   virtual bool exclusive_sequence_meaningful() const {return true;}
 
+  /// returns true because this plugin is intended for spherical
+  /// geometries (i.e. it's an e+e- algorithm).
+  virtual bool is_spherical() const {return true;}
+
 private:
   double _ycut;
Index: external/fastjet/plugins/GridJet/GridJetPlugin.cc
===================================================================
--- external/fastjet/plugins/GridJet/GridJetPlugin.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/GridJet/GridJetPlugin.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
-//
-// Copyright (c) 2011, Matteo Cacciari, Gavin Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: GridJetPlugin.cc 2268 2011-06-20 15:12:26Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 // fastjet stuff
@@ -43,4 +45,8 @@
                               double requested_grid_spacing, 
                               const JetDefinition & post_jet_def) :
+#ifdef FASTJET_GRIDJET_USEFJGRID
+  RectangularGrid(ymax, requested_grid_spacing), _post_jet_def(post_jet_def) {
+}
+#else
   _ymin(-ymax), _ymax(ymax), 
   _requested_grid_spacing(requested_grid_spacing) ,
@@ -49,5 +55,16 @@
   setup_grid();
 }
-
+#endif
+
+#ifdef FASTJET_GRIDJET_USEFJGRID
+GridJetPlugin::GridJetPlugin (const RectangularGrid & grid,
+                              const JetDefinition & post_jet_def) : 
+  RectangularGrid(grid), _post_jet_def(post_jet_def) {
+  if (!RectangularGrid::is_initialised()) 
+    throw Error("attempt to construct GridJetPlugin with uninitialised RectangularGrid");
+}
+#endif // FASTJET_GRIDJET_USEFJGRID
+
+#ifndef FASTJET_GRIDJET_USEFJGRID
 void GridJetPlugin::setup_grid() {
   // since we've exchanged the arguments of the constructor,
@@ -69,22 +86,6 @@
 }
 
-
-//----------------------------------------------------------------------
-string GridJetPlugin::description () const {
-  ostringstream desc;
-  desc << "GridJetPlugin plugin with ymax = " << _ymax << ", dy = " << _dy << ", dphi = " << _dphi << " (requested grid spacing was " << _requested_grid_spacing << ")";
-  if (_post_jet_def.jet_algorithm() != undefined_jet_algorithm) {
-    desc << ", followed by " << _post_jet_def.description();
-  }
-  return desc.str();
-}
-
-
-//----------------------------------------------------------------------
-double GridJetPlugin::R() const {return sqrt(_dy*_dphi/pi);}
-
-
-//----------------------------------------------------------------------
-int GridJetPlugin::igrid(const PseudoJet & p) const {
+//----------------------------------------------------------------------
+int GridJetPlugin::tile_index(const PseudoJet & p) const {
   // directly taking int does not work for values between -1 and 0
   // so use floor instead
@@ -108,4 +109,25 @@
   return igrid_res;
 }
+#endif // not FASTJET_GRIDJET_USEFJGRID
+
+
+//----------------------------------------------------------------------
+string GridJetPlugin::description () const {
+  ostringstream desc;
+  desc << "GridJetPlugin plugin with ";
+#ifndef FASTJET_GRIDJET_USEFJGRID
+  desc << "ymax = " << _ymax << ", dy = " << _dy << ", dphi = " << _dphi << " (requested grid spacing was " << _requested_grid_spacing << ")";
+#else
+  desc << RectangularGrid::description();
+#endif
+  if (_post_jet_def.jet_algorithm() != undefined_jet_algorithm) {
+    desc << ", followed by " << _post_jet_def.description();
+  }
+  return desc.str();
+}
+
+
+//----------------------------------------------------------------------
+double GridJetPlugin::R() const {return sqrt(drap()*dphi()/pi);}
 
 
@@ -117,5 +139,5 @@
   //  * a number >= 0 will mean that particle indicated by the index
   //    is currently the jet on the grid
-  vector<int> grid(_ntotal, -1);
+  vector<int> grid(n_tiles(), -1);
  
   int nparticles = cs.jets().size();
@@ -126,9 +148,9 @@
   // combine particles with whatever is in the grid
   for (int i = 0; i < nparticles; i++) {
-    int igrd = igrid(cs.jets()[i]);
+    int igrd = tile_index(cs.jets()[i]);
     //cout << i << " " << cs.jets()[i].rap() << " " << cs.jets()[i].phi() 
     // 	 << " " << igrd << " " << grid.size() << " " << _ntotal << endl;
     if (igrd < 0) continue;
-    assert(igrd <= _ntotal);
+    assert(igrd <= n_tiles());
     if (grid[igrd] == -1) {
       grid[igrd] = i; // jet index of initial particle i is i
@@ -145,6 +167,6 @@
     // make the final jets via iB recombinations
     for (unsigned igrd = 0; igrd < grid.size(); igrd++) {
-      if (grid[igrd] != -1) cs.plugin_record_iB_recombination(grid[igrd], 
-							      dij_or_diB);
+      if (grid[igrd] != -1 && tile_is_good(igrd)) 
+                   cs.plugin_record_iB_recombination(grid[igrd], dij_or_diB);
     }
   } else {
Index: external/fastjet/plugins/GridJet/fastjet/GridJetPlugin.hh
===================================================================
--- external/fastjet/plugins/GridJet/fastjet/GridJetPlugin.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/GridJet/fastjet/GridJetPlugin.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,9 +1,9 @@
-#ifndef __GRIDJETPLUGIN_HH__
-#define __GRIDJETPLUGIN_HH__
+#ifndef __FASTJET_GRIDJETPLUGIN_HH__
+#define __FASTJET_GRIDJETPLUGIN_HH__
 
-//STARTHEADER
+//FJSTARTHEADER
 // $Id: GridJetPlugin.hh 2267 2011-06-20 15:10:23Z salam $
 //
-// Copyright (c) 2011, Matteo Cacciari, Gavin Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,8 +30,16 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
 #include "fastjet/JetDefinition.hh"
+
+// makes it easy to switch back and forth between use of
+// RectangularGrid or not; this got enabled in FJ3.1
+#define FASTJET_GRIDJET_USEFJGRID
+
+#ifdef FASTJET_GRIDJET_USEFJGRID
+#include "fastjet/RectangularGrid.hh"
+#endif
 
 FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
@@ -49,7 +59,11 @@
 /// but is rather provided for comparison purposes with the 
 /// GridMedianBackgroundEstimator (which is even faster).
-class GridJetPlugin : public JetDefinition::Plugin {
+class GridJetPlugin : public JetDefinition::Plugin 
+#ifdef FASTJET_GRIDJET_USEFJGRID
+                                      , RectangularGrid
+#endif 
+{
 public:
-  /// Main constructor for the GridJetPlugin Plugin class.
+  /// Basic constructor for the GridJetPlugin Plugin class.
   ///
   /// \param ymax           The maximal rapidity extent of the grid
@@ -62,8 +76,23 @@
 		 const JetDefinition & post_jet_def = JetDefinition());
 
-  /// copy constructor
-  GridJetPlugin (const GridJetPlugin & plugin) {
-    *this = plugin;
-  }
+#ifdef FASTJET_GRIDJET_USEFJGRID
+  /// Constructor for the GridJetPlugin Plugin class that allows
+  /// full control over the underlying grid. New in FastJet 3.1.
+  ///
+  /// \param grid           The maximal rapidity extent of the grid
+  /// \param post_jet_def   if present, and not == JetDefinition()
+  ///                       (which has undefined_jet_algorithm), then
+  ///                       run the post_jet_def on the result of the grid
+  ///                       clustering.
+  GridJetPlugin (const RectangularGrid & grid,
+		 const JetDefinition & post_jet_def = JetDefinition());
+#endif // FASTJET_GRIDJET_USEFJGRID
+
+  
+
+  // /// copy constructor
+  // GridJetPlugin (const GridJetPlugin & plugin) {
+  //   *this = plugin;
+  // }
 
   // the things that are required by base class
@@ -75,4 +104,7 @@
   virtual double R() const;
 
+  // As of FastJet 3.1 the following functions become available through
+  // the underlying RectangularGrid class.
+#ifndef FASTJET_GRIDJET_USEFJGRID
   /// returns the actual rapidity spacing of the grid
   double drap()   const {return _dy;}
@@ -83,13 +115,20 @@
   /// returns the maximum rapidity of the grid
   double rapmax() const {return _ymax;}
+#endif
 
 private:
 
+#ifndef FASTJET_GRIDJET_USEFJGRID
   void setup_grid();
 
-  int igrid(const PseudoJet & p) const;
+  int n_tiles() const {return _ntotal;}
+  int n_good_tiles() const {return _ntotal;}
+
+  int tile_index(const PseudoJet & p) const;
+  bool tile_is_good(int /* itile */) const {return true;}
 
   double _ymin, _ymax, _dy, _dphi, _requested_grid_spacing;
   int _ny, _nphi, _ntotal;
+#endif
 
   JetDefinition _post_jet_def;
@@ -99,4 +138,4 @@
 FASTJET_END_NAMESPACE        // defined in fastjet/internal/base.hh
 
-#endif // __GRIDJETPLUGIN_HH__
+#endif // __FASTJET_GRIDJETPLUGIN_HH__
 
Index: external/fastjet/plugins/Jade/JadePlugin.cc
===================================================================
--- external/fastjet/plugins/Jade/JadePlugin.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/Jade/JadePlugin.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: JadePlugin.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2007-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2007-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 // fastjet stuff
Index: external/fastjet/plugins/Jade/fastjet/JadePlugin.hh
===================================================================
--- external/fastjet/plugins/Jade/fastjet/JadePlugin.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/Jade/fastjet/JadePlugin.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,8 +2,8 @@
 #define __JADEPLUGIN_HH__
 
-//STARTHEADER
-// $Id: JadePlugin.hh 2577 2011-09-13 15:11:38Z salam $
+//FJSTARTHEADER
+// $Id: JadePlugin.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2009, Matteo Cacciari, Gavin Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,5 +30,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/JetDefinition.hh"
Index: external/fastjet/plugins/NestedDefs/NestedDefsPlugin.cc
===================================================================
--- external/fastjet/plugins/NestedDefs/NestedDefsPlugin.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/NestedDefs/NestedDefsPlugin.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: NestedDefsPlugin.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2007-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2007-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 // TODO
Index: external/fastjet/plugins/NestedDefs/fastjet/NestedDefsPlugin.hh
===================================================================
--- external/fastjet/plugins/NestedDefs/fastjet/NestedDefsPlugin.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/NestedDefs/fastjet/NestedDefsPlugin.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: NestedDefsPlugin.hh 2577 2011-09-13 15:11:38Z salam $
+//FJSTARTHEADER
+// $Id: NestedDefsPlugin.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2007-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2007-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __NESTEDALGSPLUGIN_HH__
Index: external/fastjet/plugins/SISCone/SISConePlugin.cc
===================================================================
--- external/fastjet/plugins/SISCone/SISConePlugin.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/SISConePlugin.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -207,5 +207,10 @@
 
   // give the extras object to the cluster sequence.
-  clust_seq.plugin_associate_extras(std::auto_ptr<ClusterSequence::Extras>(extras));
+  // 
+  // As of v3.1 of FastJet, extras are automatically owned (as
+  // SharedPtr) by the ClusterSequence and auto_ptr is deprecated. So
+  // we can use a simple pointer here
+  //clust_seq.plugin_associate_extras(std::auto_ptr<ClusterSequence::Extras>(extras));
+  clust_seq.plugin_associate_extras(extras);
 }
 
Index: external/fastjet/plugins/SISCone/area.cc
===================================================================
--- external/fastjet/plugins/SISCone/area.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/area.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -22,6 +22,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 149                                                          $//
+// $Date:: 2007-03-15 00:13:58 +0100 (Thu, 15 Mar 2007)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/area.h
===================================================================
--- external/fastjet/plugins/SISCone/area.h	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/area.h	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -22,6 +22,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 149                                                          $//
+// $Date:: 2007-03-15 00:13:58 +0100 (Thu, 15 Mar 2007)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/circulator.h
===================================================================
--- external/fastjet/plugins/SISCone/circulator.h	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/circulator.h	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -22,6 +22,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 103                                                          $//
+// $Date:: 2007-02-18 17:07:34 +0100 (Sun, 18 Feb 2007)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/config.h
===================================================================
--- external/fastjet/plugins/SISCone/config.h	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/config.h	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -54,7 +54,4 @@
 #define PACKAGE_TARNAME "siscone"
 
-/* Define to the home page for this package. */
-/* #undef PACKAGE_URL */
-
 /* Define to the version of this package. */
 #define PACKAGE_VERSION "2.0.6"
Index: external/fastjet/plugins/SISCone/defines.h
===================================================================
--- external/fastjet/plugins/SISCone/defines.h	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/defines.h	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -22,6 +22,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 225                                                          $//
+// $Date:: 2008-05-20 16:59:47 +0200 (Tue, 20 May 2008)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/fastjet/SISConeSphericalPlugin.hh
===================================================================
--- external/fastjet/plugins/SISCone/fastjet/SISConeSphericalPlugin.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/fastjet/SISConeSphericalPlugin.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -152,4 +152,8 @@
   virtual void run_clustering(ClusterSequence &) const ;
 
+  /// returns true because this plugin is intended for spherical
+  /// geometries (i.e. it's an e+e- algorithm).
+  virtual bool is_spherical() const {return true;}
+
 protected:
   virtual void reset_stored_plugin() const;
Index: external/fastjet/plugins/SISCone/geom_2d.cc
===================================================================
--- external/fastjet/plugins/SISCone/geom_2d.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/geom_2d.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -21,6 +21,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 171                                                          $//
+// $Date:: 2007-06-19 16:26:05 +0200 (Tue, 19 Jun 2007)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/geom_2d.h
===================================================================
--- external/fastjet/plugins/SISCone/geom_2d.h	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/geom_2d.h	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -22,6 +22,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 268                                                          $//
+// $Date:: 2009-03-12 21:24:16 +0100 (Thu, 12 Mar 2009)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/hash.cc
===================================================================
--- external/fastjet/plugins/SISCone/hash.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/hash.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -21,6 +21,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 225                                                          $//
+// $Date:: 2008-05-20 16:59:47 +0200 (Tue, 20 May 2008)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/hash.h
===================================================================
--- external/fastjet/plugins/SISCone/hash.h	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/hash.h	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -22,6 +22,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 224                                                          $//
+// $Date:: 2008-05-16 19:58:30 +0200 (Fri, 16 May 2008)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/momentum.cc
===================================================================
--- external/fastjet/plugins/SISCone/momentum.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/momentum.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -21,6 +21,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 123                                                          $//
+// $Date:: 2007-03-01 02:52:16 +0100 (Thu, 01 Mar 2007)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/momentum.h
===================================================================
--- external/fastjet/plugins/SISCone/momentum.h	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/momentum.h	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -22,6 +22,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 163                                                          $//
+// $Date:: 2007-04-26 22:31:02 +0200 (Thu, 26 Apr 2007)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/protocones.cc
===================================================================
--- external/fastjet/plugins/SISCone/protocones.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/protocones.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -21,6 +21,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 322                                                          $//
+// $Date:: 2011-11-15 10:12:36 +0100 (Tue, 15 Nov 2011)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/protocones.h
===================================================================
--- external/fastjet/plugins/SISCone/protocones.h	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/protocones.h	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -22,6 +22,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 224                                                          $//
+// $Date:: 2008-05-16 19:58:30 +0200 (Fri, 16 May 2008)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/quadtree.cc
===================================================================
--- external/fastjet/plugins/SISCone/quadtree.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/quadtree.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -21,6 +21,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 320                                                          $//
+// $Date:: 2011-11-15 09:54:50 +0100 (Tue, 15 Nov 2011)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/quadtree.h
===================================================================
--- external/fastjet/plugins/SISCone/quadtree.h	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/quadtree.h	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -22,6 +22,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 123                                                          $//
+// $Date:: 2007-03-01 02:52:16 +0100 (Thu, 01 Mar 2007)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/reference.cc
===================================================================
--- external/fastjet/plugins/SISCone/reference.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/reference.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -21,6 +21,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 311                                                          $//
+// $Date:: 2011-10-05 23:27:09 +0200 (Wed, 05 Oct 2011)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/reference.h
===================================================================
--- external/fastjet/plugins/SISCone/reference.h	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/reference.h	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -22,6 +22,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 123                                                          $//
+// $Date:: 2007-03-01 02:52:16 +0100 (Thu, 01 Mar 2007)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/siscone.cc
===================================================================
--- external/fastjet/plugins/SISCone/siscone.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/siscone.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -21,6 +21,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 341                                                          $//
+// $Date:: 2013-04-08 12:21:06 +0200 (Mon, 08 Apr 2013)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/siscone.h
===================================================================
--- external/fastjet/plugins/SISCone/siscone.h	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/siscone.h	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -22,6 +22,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 325                                                          $//
+// $Date:: 2011-11-25 12:41:17 +0100 (Fri, 25 Nov 2011)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/siscone_error.cc
===================================================================
--- external/fastjet/plugins/SISCone/siscone_error.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/siscone_error.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -21,6 +21,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 123                                                          $//
+// $Date:: 2007-03-01 02:52:16 +0100 (Thu, 01 Mar 2007)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/siscone_error.h
===================================================================
--- external/fastjet/plugins/SISCone/siscone_error.h	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/siscone_error.h	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -22,6 +22,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 327                                                          $//
+// $Date:: 2011-11-25 15:19:39 +0100 (Fri, 25 Nov 2011)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/split_merge.cc
===================================================================
--- external/fastjet/plugins/SISCone/split_merge.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/split_merge.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -21,6 +21,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 322                                                          $//
+// $Date:: 2011-11-15 10:12:36 +0100 (Tue, 15 Nov 2011)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/split_merge.h
===================================================================
--- external/fastjet/plugins/SISCone/split_merge.h	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/split_merge.h	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -22,6 +22,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 268                                                          $//
+// $Date:: 2009-03-12 21:24:16 +0100 (Thu, 12 Mar 2009)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/vicinity.cc
===================================================================
--- external/fastjet/plugins/SISCone/vicinity.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/vicinity.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -21,6 +21,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 123                                                          $//
+// $Date:: 2007-03-01 02:52:16 +0100 (Thu, 01 Mar 2007)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/SISCone/vicinity.h
===================================================================
--- external/fastjet/plugins/SISCone/vicinity.h	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/SISCone/vicinity.h	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -22,6 +22,6 @@
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA //
 //                                                                           //
-// $Revision::                                                              $//
-// $Date::                                                                  $//
+// $Revision:: 123                                                          $//
+// $Date:: 2007-03-01 02:52:16 +0100 (Thu, 01 Mar 2007)                     $//
 ///////////////////////////////////////////////////////////////////////////////
 
Index: external/fastjet/plugins/TrackJet/TrackJetPlugin.cc
===================================================================
--- external/fastjet/plugins/TrackJet/TrackJetPlugin.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/TrackJet/TrackJetPlugin.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,14 +1,9 @@
-//STARTHEADER
-// $Id$
-//
-// Copyright (c) 2007-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: TrackJetPlugin.cc 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2007-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
-// This file is part of FastJet. It contains code that has been
-// obtained from the Rivet project by Leif Lonnblad, Andy Buckley and
-// Jon Butterworth. See http://www.hepforge.org/downloads/rivet.
-// Rivet is free software released under the terms of the GNU Public
-// License(v2).
-// Changes from the original file are listed below.
+// This file is part of FastJet.
 //
 //  FastJet is free software; you can redistribute it and/or modify
@@ -18,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -30,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 // History of changes from the original TrackJet.cc file in Rivet <=1.1.2
Index: external/fastjet/plugins/TrackJet/fastjet/TrackJetPlugin.hh
===================================================================
--- external/fastjet/plugins/TrackJet/fastjet/TrackJetPlugin.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/plugins/TrackJet/fastjet/TrackJetPlugin.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: TrackJetPlugin.hh 2758 2011-11-24 08:31:58Z soyez $
+//FJSTARTHEADER
+// $Id: TrackJetPlugin.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2007-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2007-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __TRACKJETPLUGIN_HH__
Index: external/fastjet/tools/BackgroundEstimatorBase.cc
===================================================================
--- external/fastjet/tools/BackgroundEstimatorBase.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/BackgroundEstimatorBase.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: BackgroundEstimatorBase.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
Index: external/fastjet/tools/BackgroundEstimatorBase.hh
===================================================================
--- external/fastjet/tools/BackgroundEstimatorBase.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/BackgroundEstimatorBase.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,8 +2,8 @@
 #define __FASTJET_BACKGROUND_ESTIMATOR_BASE_HH__
 
-//STARTHEADER
-// $Id: BackgroundEstimatorBase.hh 2689 2011-11-14 14:51:06Z soyez $
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: BackgroundEstimatorBase.hh 3516 2014-08-01 14:07:58Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,5 +30,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include <fastjet/ClusterSequenceAreaBase.hh>
@@ -43,7 +45,6 @@
 ///
 /// Abstract base class that provides the basic interface for classes
-/// that estimate levels of background radiation in hadrion and
+/// that estimate levels of background radiation in hadron and
 /// heavy-ion collider events.
-///
 ///
 class BackgroundEstimatorBase {
@@ -99,6 +100,40 @@
   /// determination of sigma
   virtual bool has_sigma() {return false;}
-  //\}
-  
+
+  //----------------------------------------------------------------
+  // now do the same thing for rho_m and sigma_m
+
+  /// returns rho_m, the purely longitudinal, particle-mass-induced
+  /// component of the background density per unit area
+  virtual double rho_m() const{
+    throw Error("rho_m() not supported for this Background Estimator");
+  }
+
+  /// returns sigma_m, a measure of the fluctuations in the purely
+  /// longitudinal, particle-mass-induced component of the background
+  /// density per unit area; must be multipled by sqrt(area) to get
+  /// fluctuations for a region of a given area.
+  virtual double sigma_m() const { 
+    throw Error("sigma_m() not supported for this Background Estimator");
+  }
+
+  /// Returns rho_m locally at the jet position. As for rho(jet), it is non-const.
+  virtual double rho_m(const PseudoJet & /*jet*/){
+    throw Error("rho_m(jet) not supported for this Background Estimator");
+  }
+
+  /// Returns sigma_m locally at the jet position. As for rho(jet), it is non-const.
+  virtual double sigma_m(const PseudoJet & /*jet*/) { 
+    throw Error("sigma_m(jet) not supported for this Background Estimator");
+  }
+
+  /// Returns true if this background estimator has support for
+  /// determination of rho_m.
+  ///
+  /// Note that support for sigma_m is automatic is one has sigma and
+  /// rho_m support.
+  virtual bool has_rho_m() const {return false;}
+  //\}
+
 
   /// @name configuring the behaviour
@@ -114,4 +149,7 @@
   /// The BackgroundRescalingYPolynomial class can be used to get a
   /// rescaling that depends just on rapidity.
+  ///
+  /// There is currently no support for different rescaling classes 
+  /// for rho and rho_m determinations.
   virtual void set_rescaling_class(const FunctionOfPseudoJet<double> * rescaling_class_in) { _rescaling_class = rescaling_class_in; }
 
Index: external/fastjet/tools/Boost.hh
===================================================================
--- external/fastjet/tools/Boost.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/Boost.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: Boost.hh 2689 2011-11-14 14:51:06Z soyez $
+//FJSTARTHEADER
+// $Id: Boost.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __FASTJET_TOOL_BOOST_HH__
Index: external/fastjet/tools/CASubJetTagger.cc
===================================================================
--- external/fastjet/tools/CASubJetTagger.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/CASubJetTagger.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: CASubJetTagger.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include <fastjet/tools/CASubJetTagger.hh>
Index: external/fastjet/tools/CASubJetTagger.hh
===================================================================
--- external/fastjet/tools/CASubJetTagger.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/CASubJetTagger.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: CASubJetTagger.hh 2616 2011-09-30 18:03:40Z salam $
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: CASubJetTagger.hh 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __CASUBJET_TAGGER_HH__
Index: external/fastjet/tools/Filter.cc
===================================================================
--- external/fastjet/tools/Filter.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/Filter.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: Filter.cc 3633 2014-08-15 13:23:52Z soyez $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,7 +27,8 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/tools/Filter.hh"
+#include "fastjet/tools/Recluster.hh"
 #include <fastjet/ClusterSequenceActiveAreaExplicitGhosts.hh>
 #include <cassert>
@@ -45,4 +48,8 @@
 // class description
 string Filter::description() const {
+  if (!_initialised){
+    return "uninitialised Filter";
+  }
+
   ostringstream ostr;
   ostr << "Filter with subjet_def = ";
@@ -73,4 +80,9 @@
 // by the filtering
 PseudoJet Filter::result(const PseudoJet &jet) const {
+  if (!_initialised){
+    //Q: do we throw or do we return an empty PJ?
+    throw Error("uninitialised Filter");
+  }
+
   // start by getting the list of subjets (including a list of sanity
   // checks)
@@ -78,10 +90,18 @@
   //     _set_filtered_elements_cafilt)
   vector<PseudoJet> subjets; 
-  JetDefinition subjet_def;
-  bool discard_area;
-  // NB: on return, subjet_def is set to the jet definition actually
-  //     used (so that we can make use of its recombination scheme 
-  //     when joining the jets to be kept).
-  _set_filtered_elements(jet, subjets, subjet_def, discard_area);
+  //JetDefinition subjet_def;
+  bool ca_optimised = _set_filtered_elements(jet, subjets);
+
+  // apply subtraction if needed:
+  if (_subtractor){
+    subjets = (*_subtractor)(subjets);
+  } else if (_rho!=0){
+    if (subjets.size()>0){
+      const ClusterSequenceAreaBase *csab = subjets[0].validated_csab();
+      for (unsigned int i=0;i<subjets.size();i++){
+        subjets[i]=csab->subtracted_jet(subjets[i], _rho);
+      }
+    }
+  }
 
   // now build the vector of kept and rejected subjets
@@ -94,199 +114,25 @@
 
   // gather the info under the form of a PseudoJet
-  return _finalise(jet, kept, rejected, subjet_def, discard_area);
+  return _finalise(jet, kept, rejected, ca_optimised);
 }
 
 
 // sets filtered_elements to be all the subjets on which filtering will work
-void Filter::_set_filtered_elements(const PseudoJet & jet,
-                                    vector<PseudoJet> & filtered_elements,
-                                    JetDefinition & subjet_def,
-                                    bool & discard_area) const {
-  // sanity checks
-  //-------------------------------------------------------------------
-  // make sure that the jet has constituents
-  if (! jet.has_constituents())
-    throw Error("Filter can only be applied on jets having constituents");
+//
+// return true when the subjets have been optained using teh optimised
+// method for C/A
+bool Filter::_set_filtered_elements(const PseudoJet & jet,
+                                    vector<PseudoJet> & filtered_elements) const {
+  // create the recluster instance
+  Recluster recluster;
+  if ((_Rfilt>=0) || (_Rfiltfunc))
+    recluster = Recluster(cambridge_algorithm, (_Rfiltfunc) ? (*_Rfiltfunc)(jet) : _Rfilt, Recluster::keep_all);
+  else
+    recluster = Recluster(_subjet_def, false, Recluster::keep_all);
 
-  // for a whole variety of checks, we shall need the "recursive"
-  // pieces of the jet (the jet itself or recursing down to its most
-  // fundamental pieces).
-  // So we do compute these once and for all
-  vector<PseudoJet> all_pieces; //.clear();
-  if ((!_get_all_pieces(jet, all_pieces)) || (all_pieces.size()==0))
-    throw Error("Attempt to filter a jet that has no associated ClusterSequence or is not a superposition of jets associated with a ClusterSequence");
-  
-  // if the filter uses subtraction, make sure we have a CS that supports area and has
-  // explicit ghosts 
-  if (_uses_subtraction()) {
-    if (!jet.has_area())   
-      throw Error("Attempt to filter and subtract (non-zero rho or subtractor) without area info for the original jet");
-
-    if (!_check_explicit_ghosts(all_pieces))
-      throw Error("Attempt to filter and subtract (non-zero rho or subtractor) without explicit ghosts");
-  }
-
-  // if we're dealing with a dynamic determination of the filtering
-  // radius, do it now
-  if ((_Rfilt>=0) || (_Rfiltfunc)){
-    double Rfilt = (_Rfiltfunc) ? (*_Rfiltfunc)(jet) : _Rfilt;
-    const JetDefinition::Recombiner * common_recombiner = _get_common_recombiner(all_pieces);
-    if (common_recombiner) {
-      if (typeid(*common_recombiner) == typeid(JetDefinition::DefaultRecombiner)) {
-        RecombinationScheme scheme = 
-          static_cast<const JetDefinition::DefaultRecombiner *>(common_recombiner)->scheme();
-        subjet_def = JetDefinition(cambridge_algorithm, Rfilt, scheme);
-      } else {
-        subjet_def = JetDefinition(cambridge_algorithm, Rfilt, common_recombiner);
-      }
-    } else {
-      subjet_def = JetDefinition(cambridge_algorithm, Rfilt);
-    }
-  } else {
-    subjet_def = _subjet_def;
-  }
-
-  // get the jet definition to be use and whether we can apply our
-  // simplified C/A+C/A filter
-  //
-  // we apply C/A clustering iff
-  //  - the request subjet_def is C/A
-  //  - the jet is either directly coming from C/A or if it is a
-  //    superposition of C/A jets
-  //  - the pieces agree with the recombination scheme of subjet_def
-  //------------------------------------------------------------------
-  bool simple_cafilt = _check_ca(all_pieces);
-
-  // extract the subjets
-  //-------------------------------------------------------------------
-  discard_area = false;
-  if (simple_cafilt){
-    // first make sure that 'filtered_elements' is empty
-    filtered_elements.clear();
-    _set_filtered_elements_cafilt(jet, filtered_elements, subjet_def.R());
-    // in the following case, areas can be erroneous and will be discarded
-    discard_area = (!_uses_subtraction()) && (jet.has_area()) && (!_check_explicit_ghosts(all_pieces));
-  } else {
-    // here we'll simply recluster the jets.
-    //
-    // To include an area support we need
-    //  - the jet to have an area
-    //  - subtraction requested or explicit ghosts
-    bool do_areas = (jet.has_area()) && ((_uses_subtraction()) || (_check_explicit_ghosts(all_pieces))); 
-    _set_filtered_elements_generic(jet, filtered_elements, subjet_def, do_areas);
-  }
-
-  // order the filtered elements in pt
-  filtered_elements = sorted_by_pt(filtered_elements);
+  // get the subjets
+  //JetDefinition subjet_def;
+  return recluster.get_new_jets_and_def(jet, filtered_elements);
 }
-
-// set the filtered elements in the simple case of C/A+C/A
-//
-// WATCH OUT: this could be recursively called, so filtered elements
-//            of 'jet' are APPENDED to 'filtered_elements'
-void Filter::_set_filtered_elements_cafilt(const PseudoJet & jet, 
-                                           vector<PseudoJet> & filtered_elements, 
-                                           double Rfilt) const{
-  // we know that the jet is either a C/A jet or a superposition of
-  // such pieces
-  if (jet.has_associated_cluster_sequence()){
-    // just extract the exclusive subjets of 'jet'
-    const ClusterSequence *cs = jet.associated_cluster_sequence(); 
-    vector<PseudoJet> local_fe;
-
-    double dcut = Rfilt / cs->jet_def().R();
-    if (dcut>=1.0){
-      local_fe.push_back(jet);
-    } else {
-      dcut *= dcut;
-      local_fe = jet.exclusive_subjets(dcut);
-    }
-
-    // subtract the jets if needed
-    // Note that this one would work on pieces!!
-    //-----------------------------------------------------------------
-    if (_uses_subtraction()){
-      const ClusterSequenceAreaBase * csab = jet.validated_csab();
-      for (unsigned int i=0;i<local_fe.size();i++) {
-        if (_subtractor) {
-          local_fe[i] = (*_subtractor)(local_fe[i]);
-        } else {
-          local_fe[i] = csab->subtracted_jet(local_fe[i], _rho);
-        }
-      }
-    }
-
-    copy(local_fe.begin(), local_fe.end(), back_inserter(filtered_elements));
-    return;
-  }
-
-  // just recurse into the pieces
-  const vector<PseudoJet> & pieces = jet.pieces();
-  for (vector<PseudoJet>::const_iterator it = pieces.begin(); 
-       it!=pieces.end(); it++)
-    _set_filtered_elements_cafilt(*it, filtered_elements, Rfilt);
-}
-
-
-// set the filtered elements in the generic re-clustering case (wo
-// subtraction)
-void Filter::_set_filtered_elements_generic(const PseudoJet & jet, 
-                                            vector<PseudoJet> & filtered_elements,
-                                            const JetDefinition & subjet_def,
-					    bool do_areas) const{
-  // create a new, internal, ClusterSequence from the jet constituents
-  // get the subjets directly from there
-  //
-  // If the jet has area support then we separate the ghosts from the
-  // "regular" particles so the subjets will also have area
-  // support. Note that we do this regardless of whether rho is zero
-  // or not.
-  //
-  // Note that to be able to separate the ghosts, one needs explicit
-  // ghosts!!
-  // ---------------------------------------------------------------
-  if (do_areas){
-    vector<PseudoJet> all_constituents = jet.constituents();
-    vector<PseudoJet> regular_constituents, ghosts;  
-
-    for (vector<PseudoJet>::iterator it = all_constituents.begin(); 
-         it != all_constituents.end(); it++){
-      if (it->is_pure_ghost())
-        ghosts.push_back(*it);
-      else
-        regular_constituents.push_back(*it);
-    }
-
-    // figure out the ghost area from the 1st ghost (if none, any value
-    // would probably do as the area will be 0 and subtraction will have
-    // no effect!)
-    double ghost_area = (ghosts.size()) ? ghosts[0].area() : 0.01;
-    ClusterSequenceActiveAreaExplicitGhosts * csa
-      = new ClusterSequenceActiveAreaExplicitGhosts(regular_constituents, 
-                                                    subjet_def, 
-                                                    ghosts, ghost_area);
-
-    // get the subjets: we use the subtracted or unsubtracted ones
-    // depending on rho or _subtractor being non-zero
-    if (_uses_subtraction()) {
-      if (_subtractor) {
-        filtered_elements = (*_subtractor)(csa->inclusive_jets());
-      } else {
-        filtered_elements = csa->subtracted_jets(_rho);
-      }
-    } else {
-      filtered_elements = csa->inclusive_jets();
-    }
-
-    // allow the cs to be deleted when it's no longer used
-    csa->delete_self_when_unused();
-  } else {
-    ClusterSequence * cs = new ClusterSequence(jet.constituents(), subjet_def);
-    filtered_elements = cs->inclusive_jets();
-    // allow the cs to be deleted when it's no longer used
-    cs->delete_self_when_unused();
-  }
-}
-
 
 // gather the information about what is kept and rejected under the
@@ -295,118 +141,36 @@
                             vector<PseudoJet> & kept, 
                             vector<PseudoJet> & rejected,
-                            const JetDefinition & subjet_def,
-                            const bool discard_area) const {
-  // figure out which recombiner to use
-  const JetDefinition::Recombiner &rec = *(subjet_def.recombiner());
+			    bool ca_optimisation_used) const {
+  PseudoJet filtered_jet;
 
-  // create an appropriate structure and transfer the info to it
-  PseudoJet filtered_jet = join<StructureType>(kept, rec);
+  if (kept.size()+rejected.size()>0){
+    // figure out which recombiner to use
+    const JetDefinition::Recombiner &rec = (kept.size()>0)
+      ? *(kept[0].associated_cs()->jet_def().recombiner())
+      : *(rejected[0].associated_cs()->jet_def().recombiner());
+
+    // create an appropriate structure and transfer the info to it
+    filtered_jet = join<StructureType>(kept, rec);
+  } else {
+    filtered_jet = join<StructureType>(kept);
+  }
   StructureType *fs = (StructureType*) filtered_jet.structure_non_const_ptr();
-//  fs->_original_jet = jet;
   fs->_rejected = rejected;
+  
+  // if we've used C/A optimisation, we need to get rid of the area
+  // information if it comes from a non-explicit-ghost clustering.
+  // (because in that case it can be erroneous due the lack of
+  // information about empty areas)
+  if ((ca_optimisation_used) && (kept.size()+rejected.size()>0)){
+    bool has_non_explicit_ghost_area = (kept.size()>0)
+      ? (kept[0].has_area()     && kept[0].validated_csab()->has_explicit_ghosts())
+      : (rejected[0].has_area() && rejected[0].validated_csab()->has_explicit_ghosts());
+    if (has_non_explicit_ghost_area)
+      fs->discard_area();
+  }
 
-  if (discard_area){
-    // safety check: make sure there is an area to discard!!!
-    assert(fs->_area_4vector_ptr);
-    delete fs->_area_4vector_ptr;
-    fs->_area_4vector_ptr=0;
-  }
-  
   return filtered_jet;
 }
 
-// various checks
-//----------------------------------------------------------------------
-
-// get the pieces down to the fundamental pieces
-// 
-// Note that this just checks that there is an associated CS to the
-// fundamental pieces, not that it is still valid
-bool Filter::_get_all_pieces(const PseudoJet &jet, vector<PseudoJet> &all_pieces) const{
-  if (jet.has_associated_cluster_sequence()){
-    all_pieces.push_back(jet);
-    return true;
-  }
-
-  if (jet.has_pieces()){
-    const vector<PseudoJet> pieces = jet.pieces();
-    for (vector<PseudoJet>::const_iterator it=pieces.begin(); it!=pieces.end(); it++)
-      if (!_get_all_pieces(*it, all_pieces)) return false;
-    return true;
-  }
-
-  return false;
-}
-
-// get the common recombiner to all pieces (NULL if none)
-//
-// Note that if the jet has an associated cluster sequence that is no
-// longer valid, an error will be thrown (needed since it could be the
-// 1st check called after the enumeration of the pieces)
-const JetDefinition::Recombiner* Filter::_get_common_recombiner(const vector<PseudoJet> &all_pieces) const{
-  const JetDefinition & jd_ref = all_pieces[0].validated_cs()->jet_def();
-  for (unsigned int i=1; i<all_pieces.size(); i++)
-    if (!all_pieces[i].validated_cs()->jet_def().has_same_recombiner(jd_ref)) return NULL;
-
-  return jd_ref.recombiner();
-}
-
-// check if the jet (or all its pieces) have explicit ghosts
-// (assuming the jet has area support
-//
-// Note that if the jet has an associated cluster sequence that is no
-// longer valid, an error will be thrown (needed since it could be the
-// 1st check called after the enumeration of the pieces)
-bool Filter::_check_explicit_ghosts(const vector<PseudoJet> &all_pieces) const{
-  for (vector<PseudoJet>::const_iterator it=all_pieces.begin(); it!=all_pieces.end(); it++)
-    if (! it->validated_csab()->has_explicit_ghosts()) return false;
-  return true;
-}
-
-// check if one can apply the simplification for C/A subjets
-//
-// This includes:
-//  - the subjet definition asks for C/A subjets
-//  - all the pieces share the same CS
-//  - that CS is C/A with the same recombiner as the subjet def
-//  - the filtering radius is not larger than any of the pairwise
-//    distance between the pieces
-//
-// Note that if the jet has an associated cluster sequence that is no
-// longer valid, an error will be thrown (needed since it could be the
-// 1st check called after the enumeration of the pieces)
-bool Filter::_check_ca(const vector<PseudoJet> &all_pieces) const{
-  if (_subjet_def.jet_algorithm() != cambridge_algorithm) return false;
-
-  // check that the 1st of all the pieces (we're sure there is at
-  // least one) is coming from a C/A clustering. Then check that all
-  // the following pieces share the same ClusterSequence
-  const ClusterSequence * cs_ref = all_pieces[0].validated_cs();
-  if (cs_ref->jet_def().jet_algorithm() != cambridge_algorithm) return false;
-  for (unsigned int i=1; i<all_pieces.size(); i++)
-    if (all_pieces[i].validated_cs() != cs_ref) return false;
-
-  // check that the 1st peice has the same recombiner as the one used
-  // for the subjet clustering
-  // Note that since they share the same CS, checking the 2st one is enough
-  if (!cs_ref->jet_def().has_same_recombiner(_subjet_def)) return false;
-
-  // we also have to make sure that the filtering radius is not larger
-  // than any of the inter-pieces distance
-  double Rfilt2 = _subjet_def.R();
-  Rfilt2 *= Rfilt2;
-  for (unsigned int i=0; i<all_pieces.size()-1; i++){
-    for (unsigned int j=i+1; j<all_pieces.size(); j++){
-      if (all_pieces[i].squared_distance(all_pieces[j]) <  Rfilt2) return false;
-    }
-  }
-
-  return true;
-}
-
-//----------------------------------------------------------------------
-// FilterInterface implementation 
-//----------------------------------------------------------------------
-
 
 FASTJET_END_NAMESPACE      // defined in fastjet/internal/base.hh
Index: external/fastjet/tools/Filter.hh
===================================================================
--- external/fastjet/tools/Filter.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/Filter.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,8 +2,8 @@
 #define __FASTJET_TOOLS_FILTER_HH__
 
-//STARTHEADER
-// $Id: Filter.hh 2694 2011-11-14 22:27:51Z salam $
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: Filter.hh 3494 2014-07-30 20:38:48Z soyez $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,5 +30,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include <fastjet/ClusterSequence.hh>
@@ -98,5 +100,5 @@
   /// Note: this is just for derived classes
   ///       a Filter initialised through this constructor will not work!
-  Filter() : _Rfiltfunc(0){};
+  Filter() : _Rfiltfunc(0), _initialised(false){};
 
   /// define a filter that decomposes a jet into subjets using a
@@ -113,5 +115,5 @@
   /// ghosts
   Filter(JetDefinition subjet_def, Selector selector, double rho = 0.0) : 
-    _subjet_def(subjet_def), _Rfiltfunc(0), _Rfilt(-1), _selector(selector), _rho(rho), _subtractor(0) {}
+    _subjet_def(subjet_def), _Rfiltfunc(0), _Rfilt(-1), _selector(selector), _rho(rho), _subtractor(0), _initialised(true) {}
 
   /// Same as the full constructor (see above) but just specifying the radius
@@ -121,5 +123,5 @@
   ///  \param Rfilt   the filtering radius
   Filter(double Rfilt, Selector selector, double rho = 0.0) : 
-    _Rfiltfunc(0), _Rfilt(Rfilt), _selector(selector), _rho(rho), _subtractor(0) { 
+    _Rfiltfunc(0), _Rfilt(Rfilt), _selector(selector), _rho(rho), _subtractor(0), _initialised(true) { 
     if (_Rfilt<0)
       throw Error("Attempt to create a Filter with a negative filtering radius");
@@ -133,5 +135,5 @@
   ///  \param Rfilt_func   the filtering radius function of a PseudoJet
   Filter(FunctionOfPseudoJet<double> *Rfilt_func, Selector selector, double rho = 0.0) : 
-    _Rfiltfunc(Rfilt_func), _Rfilt(-1), _selector(selector), _rho(rho), _subtractor(0) {}
+    _Rfiltfunc(Rfilt_func), _Rfilt(-1), _selector(selector), _rho(rho), _subtractor(0), _initialised(true) {}
 
   /// default dtor
@@ -140,5 +142,5 @@
   /// Set a subtractor that is applied to all individual subjets before
   /// deciding which ones to keep. It takes precedence over a non-zero rho.
-  void set_subtractor(const Transformer * subtractor) {_subtractor = subtractor;}
+  void set_subtractor(const FunctionOfPseudoJet<PseudoJet> * subtractor) {_subtractor = subtractor;}
 
   /// runs the filtering and sets kept and rejected to be the jets of interest
@@ -159,45 +161,20 @@
   /// It also sets the subjet_def to be used in joining things (the bit of
   /// subjet def that is of interest for later is the recombiner).
-  void _set_filtered_elements(const PseudoJet & jet,
-                              std::vector<PseudoJet> & filtered_elements,
-                              JetDefinition & subjet_def,
-                              bool & discard_area) const;
+  ///
+  /// this returns true if teh optimisation trick for C/A reclustering has been used
+  bool _set_filtered_elements(const PseudoJet & jet,
+                              std::vector<PseudoJet> & filtered_elements) const;
   
-  /// set the filtered elements in the simple case of C/A+C/A
-  void _set_filtered_elements_cafilt(const PseudoJet & jet,
-                                     std::vector<PseudoJet> & filtered_elements,
-                                     double Rfilt) const;
-
-  /// set the filtered elements in the generic re-clustering case
-  void _set_filtered_elements_generic(const PseudoJet & jet, 
-                                      std::vector<PseudoJet> & filtered_elements,
-                                      const JetDefinition & subjet_def,
-				      bool do_areas) const;
-
   /// gather the information about what is kept and rejected under the
   /// form of a PseudoJet with a special ClusterSequenceInfo
+  ///
+  /// The last argument (ca_optimisation_used) should be true if the
+  /// optimisation trick for C/A reclustering has been used (in which
+  /// case some extra tests have to be run for non-explicit-ghost
+  /// areas)
   PseudoJet _finalise(const PseudoJet & jet, 
                       std::vector<PseudoJet> & kept, 
                       std::vector<PseudoJet> & rejected,
-                      const JetDefinition & subjet_def,
-                      const bool discard_area) const;
-
-  // a series of checks
-  //--------------------------------------------------------------------
-  /// get the pieces down to the fundamental pieces
-  bool _get_all_pieces(const PseudoJet &jet, std::vector<PseudoJet> &all_pieces) const;
-
-  /// get the common recombiner to all pieces (NULL if none)
-  const JetDefinition::Recombiner* _get_common_recombiner(const std::vector<PseudoJet> &all_pieces) const;
-
-  /// check if one can apply the simplified trick for C/A subjets
-  bool _check_ca(const std::vector<PseudoJet> &all_pieces) const;
-
-  /// check if the jet (or all its pieces) have explicit ghosts
-  /// (assuming the jet has area support
-  ///
-  /// Note that if the jet has an associated cluster sequence that is no
-  /// longer valid, an error will be thrown
-  bool _check_explicit_ghosts(const std::vector<PseudoJet> &all_pieces) const;
+		      bool ca_optimisation_used) const;
 
   bool _uses_subtraction() const {return (_subtractor || _rho != 0);}
@@ -209,5 +186,7 @@
   Selector _selector;  ///< the subjet selection criterium
   double _rho;                 ///< the background density (used for subtraction when possible)
-  const Transformer * _subtractor; ///< for subtracting bkgd density from subjets
+  const FunctionOfPseudoJet<PseudoJet> * _subtractor; ///< for subtracting bkgd density from subjets
+
+  bool _initialised;    ///< true when the Filter has been properly intialised
 };
 
Index: external/fastjet/tools/GridMedianBackgroundEstimator.cc
===================================================================
--- external/fastjet/tools/GridMedianBackgroundEstimator.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/GridMedianBackgroundEstimator.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: GridMedianBackgroundEstimator.cc 3555 2014-08-11 09:56:35Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
@@ -32,4 +34,5 @@
 
 FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
+
 
 //----------------------------------------------------------------------
@@ -39,15 +42,87 @@
 // of the specified particles.
 void GridMedianBackgroundEstimator::set_particles(const vector<PseudoJet> & particles) {
-  fill(_scalar_pt.begin(), _scalar_pt.end(), 0.0);
-  for (unsigned i = 0; i < particles.size(); i++) {
-    int j = igrid(particles[i]);
-    if (j >= 0){
-      if (_rescaling_class == 0)
-        _scalar_pt[j] += particles[i].perp();
-      else
-        _scalar_pt[j] += particles[i].perp()/(*_rescaling_class)(particles[i]);
+  vector<double> scalar_pt(n_tiles(), 0.0);
+
+#ifdef FASTJET_GMBGE_USEFJGRID
+  assert(all_tiles_equal_area());
+  //assert(n_good_tiles() == n_tiles()); // not needed now that we have an implementation
+#endif
+
+  // check if we need to compute only rho or both rho and rho_m
+  if (_enable_rho_m){
+    // both rho and rho_m
+    //
+    // this requires a few other variables
+    vector<double> scalar_dt(n_tiles(), 0.0);
+    double pt, dt;
+    for (unsigned i = 0; i < particles.size(); i++) {
+      int j = tile_index(particles[i]);
+      if (j >= 0){
+	pt = particles[i].pt();
+	dt = particles[i].mt() - pt;
+	if (_rescaling_class == 0){
+	  scalar_pt[j] += pt;
+	  scalar_dt[j] += dt;
+	} else {
+	  double r = (*_rescaling_class)(particles[i]);
+	  scalar_pt[j] += pt/r;
+	  scalar_dt[j] += dt/r;
+	}
+      }
+    }
+    // sort things for _percentile
+    sort(scalar_dt.begin(), scalar_dt.end());
+
+    // compute rho_m and sigma_m (see comment below for the
+    // normaliosation of sigma)
+    double p50 = _percentile(scalar_dt, 0.5);
+    _rho_m   = p50 / mean_tile_area();
+    _sigma_m = (p50-_percentile(scalar_dt, (1.0-0.6827)/2.0))/sqrt(mean_tile_area());
+  } else {
+    // only rho
+    //fill(_scalar_pt.begin(), _scalar_pt.end(), 0.0);
+    for (unsigned i = 0; i < particles.size(); i++) {
+      int j = tile_index(particles[i]);
+      if (j >= 0){
+	if (_rescaling_class == 0){
+	  scalar_pt[j] += particles[i].pt();
+	} else {
+	  scalar_pt[j] += particles[i].pt()/(*_rescaling_class)(particles[i]);
+	}
+      }
     }
   }
-  sort(_scalar_pt.begin(), _scalar_pt.end());
+
+  // if there are some "bad" tiles, then we need to exclude them from
+  // the calculation of the median. We'll do this by condensing the
+  // scalar_pt vector down to just the values for the tiles that are
+  // good.
+  //
+  // tested answers look right in "issue" 2014-08-08-testing-rect-grid
+  if (n_good_tiles() != n_tiles()) {
+    int newn = 0;
+    for (unsigned i = 0; i < scalar_pt.size(); i++) {
+      if (tile_is_good(i)) {
+        // clang gets confused with the SharedPtr swap if we don't
+        // have std:: here
+        std::swap(scalar_pt[i],scalar_pt[newn]);
+        newn++;
+      }
+    }
+    scalar_pt.resize(newn);
+  }
+
+  // in all cases, carry on with the computation of rho
+  // 
+  // first sort
+  sort(scalar_pt.begin(), scalar_pt.end());
+
+  // then compute rho
+  //
+  // watch out: by definition, our sigma is the standard deviation of
+  // the pt density multiplied by the square root of the cell area
+  double p50 = _percentile(scalar_pt, 0.5);
+  _rho   = p50 / mean_tile_area();
+  _sigma = (p50-_percentile(scalar_pt, (1.0-0.6827)/2.0))/sqrt(mean_tile_area());
 
   _has_particles = true;
@@ -61,5 +136,5 @@
 double GridMedianBackgroundEstimator::rho() const {
   verify_particles_set();
-  return _percentile(_scalar_pt, 0.5) / _cell_area;
+  return _rho;
 }
 
@@ -71,9 +146,5 @@
 double GridMedianBackgroundEstimator::sigma() const{
   verify_particles_set();
-  // watch out: by definition, our sigma is the standard deviation of
-  // the pt density multiplied by the square root of the cell area
-  return (_percentile(_scalar_pt, 0.5) -
-          _percentile(_scalar_pt, (1.0-0.6827)/2.0)
-          )/sqrt(_cell_area);
+  return _sigma; 
 }
 
@@ -85,5 +156,5 @@
 // determination.
 double GridMedianBackgroundEstimator::rho(const PseudoJet & jet)  {
-  verify_particles_set();
+  //verify_particles_set();
   double rescaling = (_rescaling_class == 0) ? 1.0 : (*_rescaling_class)(jet);
   return rescaling*rho();
@@ -95,7 +166,49 @@
 // the position of a given jet. As for rho(jet), it is non-const.
 double GridMedianBackgroundEstimator::sigma(const PseudoJet & jet){
-  verify_particles_set();
+  //verify_particles_set();
   double rescaling = (_rescaling_class == 0) ? 1.0 : (*_rescaling_class)(jet);
   return rescaling*sigma();
+}
+
+//----------------------------------------------------------------------
+// returns rho_m (particle-masses contribution to the 4-vector density)
+double GridMedianBackgroundEstimator::rho_m() const {
+  if (! _enable_rho_m){
+    throw Error("GridMediamBackgroundEstimator: rho_m requested but rho_m calculation has been disabled.");
+  }
+  verify_particles_set();
+  return _rho_m;
+}
+
+
+//----------------------------------------------------------------------
+// returns sigma_m (particle-masses contribution to the 4-vector
+// density); must be multipled by sqrt(area) to get fluctuations
+// for a region of a given area.
+double GridMedianBackgroundEstimator::sigma_m() const{
+  if (! _enable_rho_m){
+    throw Error("GridMediamBackgroundEstimator: sigma_m requested but rho_m/sigma_m calculation has been disabled.");
+  }
+  verify_particles_set();
+  return _sigma_m; 
+}
+
+//----------------------------------------------------------------------
+// returns rho_m locally at the position of a given jet. As for
+// rho(jet), it is non-const.
+double GridMedianBackgroundEstimator::rho_m(const PseudoJet & jet)  {
+  //verify_particles_set();
+  double rescaling = (_rescaling_class == 0) ? 1.0 : (*_rescaling_class)(jet);
+  return rescaling*rho_m();
+}
+
+
+//----------------------------------------------------------------------
+// returns sigma_m locally at the position of a given jet. As for
+// rho(jet), it is non-const.
+double GridMedianBackgroundEstimator::sigma_m(const PseudoJet & jet){
+  //verify_particles_set();
+  double rescaling = (_rescaling_class == 0) ? 1.0 : (*_rescaling_class)(jet);
+  return rescaling*sigma_m();
 }
 
@@ -112,6 +225,11 @@
 string GridMedianBackgroundEstimator::description() const { 
   ostringstream desc;
+#ifdef FASTJET_GMBGE_USEFJGRID
+  desc << "GridMedianBackgroundEstimator, with " << RectangularGrid::description();
+#else
   desc << "GridMedianBackgroundEstimator, with grid extension |y| < " << _ymax 
-       << " and requested grid spacing = " << _requested_grid_spacing;
+       << ", and grid cells of size dy x dphi = " << _dy << " x " << _dphi
+       << " (requested size = " << _requested_grid_spacing << ")";
+#endif
   return desc.str();
 }       
@@ -144,4 +262,5 @@
 
 
+#ifndef FASTJET_GMBGE_USEFJGRID
 //----------------------------------------------------------------------
 // protected material
@@ -168,12 +287,12 @@
 
   _ntotal = _nphi * _ny;
-  _scalar_pt.resize(_ntotal);
-  _cell_area = _dy * _dphi;
-}
-
-
-//----------------------------------------------------------------------
-// retrieve the grid cell index for a given PseudoJet
-int GridMedianBackgroundEstimator::igrid(const PseudoJet & p) const {
+  //_scalar_pt.resize(_ntotal);
+  _tile_area = _dy * _dphi;
+}
+
+
+//----------------------------------------------------------------------
+// retrieve the grid tile index for a given PseudoJet
+int GridMedianBackgroundEstimator::tile_index(const PseudoJet & p) const {
   // directly taking int does not work for values between -1 and 0
   // so use floor instead
@@ -193,8 +312,10 @@
   if (iphi == _nphi) iphi = 0; // just in case of rounding errors
 
-  int igrid_res = iy*_nphi + iphi;
-  assert (igrid_res >= 0 && igrid_res < _ny*_nphi);
-  return igrid_res;
-}
+  int index_res = iy*_nphi + iphi;
+  assert (index_res >= 0 && index_res < _ny*_nphi);
+  return index_res;
+}
+#endif // FASTJET_GMBGE_USEFJGRID
+
 
 
Index: external/fastjet/tools/GridMedianBackgroundEstimator.hh
===================================================================
--- external/fastjet/tools/GridMedianBackgroundEstimator.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/GridMedianBackgroundEstimator.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,8 +2,8 @@
 #define __GRID_MEDIAN_BACKGROUND_ESTIMATOR_HH__
 
-//STARTHEADER
-// $Id: GridMedianBackgroundEstimator.hh 2580 2011-09-13 17:25:43Z salam $
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: GridMedianBackgroundEstimator.hh 3610 2014-08-13 09:49:28Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,8 +30,20 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
 #include "fastjet/tools/BackgroundEstimatorBase.hh"
+
+// if defined then we'll use the RectangularGrid class
+//
+// (For FastJet 3.2, maybe remove the symbol and simply clean up the
+// code below to use exclusively the RectangularGrid)
+#define FASTJET_GMBGE_USEFJGRID
+
+#ifdef FASTJET_GMBGE_USEFJGRID
+#include "fastjet/RectangularGrid.hh"
+#endif
+
+
 
 FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
@@ -61,8 +75,14 @@
 ///   rho() [Without rescaling, they are identical]
 ///
-class GridMedianBackgroundEstimator : public BackgroundEstimatorBase {
+class GridMedianBackgroundEstimator : public BackgroundEstimatorBase
+#ifdef FASTJET_GMBGE_USEFJGRID
+                                                                    , RectangularGrid
+#endif 
+{
+
 public:
   /// @name  constructors and destructors
   //\{
+#ifdef FASTJET_GMBGE_USEFJGRID
   //----------------------------------------------------------------
   ///   \param ymax   maximal absolute rapidity extent of the grid
@@ -71,7 +91,26 @@
   ///             periodicity in azimuthal angle (size, not area)
   GridMedianBackgroundEstimator(double ymax, double requested_grid_spacing) :
+    RectangularGrid(ymax, requested_grid_spacing),
+    _has_particles(false), _enable_rho_m(true) {} 
+
+  //----------------------------------------------------------------
+  /// Constructor based on a user's fully specified RectangularGrid
+  GridMedianBackgroundEstimator(const RectangularGrid & grid) :
+    RectangularGrid(grid),
+    _has_particles(false), _enable_rho_m(true) {
+    if (!RectangularGrid::is_initialised()) 
+      throw Error("attempt to construct GridMedianBackgroundEstimator with uninitialised RectangularGrid");
+  }    
+
+#else  // alternative in old framework where we didn't have the rectangular grid
+  GridMedianBackgroundEstimator(double ymax, double requested_grid_spacing) :
     _ymin(-ymax), _ymax(ymax), 
     _requested_grid_spacing(requested_grid_spacing),
-    _has_particles(false){setup_grid();}
+    _has_particles(false), _enable_rho_m(true)
+  {
+     setup_grid();
+  }
+#endif // FASTJET_GMBGE_USEFJGRID
+
   //\}
 
@@ -84,4 +123,8 @@
   /// of the specified particles.
   void set_particles(const std::vector<PseudoJet> & particles);
+
+  /// determine whether the automatic calculation of rho_m and sigma_m
+  /// is enabled (by default true)
+  void set_compute_rho_m(bool enable){ _enable_rho_m = enable;}
 
   //\}
@@ -114,7 +157,32 @@
   bool has_sigma() {return true;}
 
+  //-----------------------------------------------------------------
+  /// Returns rho_m, the purely longitudinal, particle-mass-induced
+  /// component of the background density per unit area
+  double rho_m() const;
+
+  /// returns sigma_m, a measure of the fluctuations in the purely
+  /// longitudinal, particle-mass-induced component of the background
+  /// density per unit area; must be multipled by sqrt(area) to get
+  /// fluctuations for a region of a given area.
+  double sigma_m() const;
+
+  /// Returns rho_m locally at the jet position. As for rho(jet), it is non-const.
+  double rho_m(const PseudoJet & jet);
+
+  /// Returns sigma_m locally at the jet position. As for rho(jet), it is non-const.
+  double sigma_m(const PseudoJet & jet);
+
+  /// Returns true if this background estimator has support for
+  /// determination of rho_m.
+  ///
+  /// Note that support for sigma_m is automatic is one has sigma and
+  /// rho_m support.
+  bool has_rho_m() const {return _enable_rho_m;}
+
+
   /// returns the area of the grid cells (all identical, but
   /// referred to as "mean" area for uniformity with JetMedianBGE).
-  double mean_area() const {return _cell_area;}
+  double mean_area() const {return mean_tile_area();}
   //\}
 
@@ -134,4 +202,8 @@
   /// Note that this has to be called BEFORE any attempt to do an
   /// actual computation
+  ///
+  /// The same profile will be used for both pt and mt (this is
+  /// probabaly a good approximation since the particle density
+  /// changes is what dominates the rapidity profile)
   virtual void set_rescaling_class(const FunctionOfPseudoJet<double> * rescaling_class);
 
@@ -149,22 +221,35 @@
 
 private:
+
+#ifndef FASTJET_GMBGE_USEFJGRID
+
   /// configure the grid
   void setup_grid();
 
   /// retrieve the grid cell index for a given PseudoJet
-  int igrid(const PseudoJet & p) const;
+  int tile_index(const PseudoJet & p) const;
+
+  // information about the grid
+  double _ymin, _ymax, _dy, _dphi, _requested_grid_spacing, _tile_area;
+  int _ny, _nphi, _ntotal;
+
+  int n_tiles() const {return _ntotal;}
+  int n_good_tiles() const {return n_tiles();}
+  int tile_is_good(int /* itile */) const {return true;}
+
+  double mean_tile_area() const {return _tile_area;}
+#endif // FASTJET_GMBGE_USEFJGRID
+
 
   /// verify that particles have been set and throw an error if not
   void verify_particles_set() const;
 
-  // information about the grid
-  double _ymin, _ymax, _dy, _dphi, _requested_grid_spacing, _cell_area;
-  int _ny, _nphi, _ntotal;
-
   // information abotu the event
-  std::vector<double> _scalar_pt;
+  //std::vector<double> _scalar_pt;
+  double _rho, _sigma, _rho_m, _sigma_m;
   bool _has_particles;
-
-  // various warnings to let people aware of potential dangers
+  bool _enable_rho_m;
+
+  // various warnings to inform people of potential dangers
   LimitedWarning _warning_rho_of_jet;
   LimitedWarning _warning_rescaling;
Index: external/fastjet/tools/JHTopTagger.cc
===================================================================
--- external/fastjet/tools/JHTopTagger.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/JHTopTagger.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: JHTopTagger.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include <fastjet/tools/JHTopTagger.hh>
Index: external/fastjet/tools/JHTopTagger.hh
===================================================================
--- external/fastjet/tools/JHTopTagger.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/JHTopTagger.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,8 +2,8 @@
 #define __FASTJET_JH_TOP_TAGGER_HH__
 
-//STARTHEADER
-// $Id: JHTopTagger.hh 2689 2011-11-14 14:51:06Z soyez $
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: JHTopTagger.hh 3433 2014-07-23 08:17:03Z salam $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,5 +30,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 
Index: external/fastjet/tools/JetMedianBackgroundEstimator.cc
===================================================================
--- external/fastjet/tools/JetMedianBackgroundEstimator.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/JetMedianBackgroundEstimator.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: JetMedianBackgroundEstimator.cc 3517 2014-08-01 14:23:13Z soyez $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/tools/JetMedianBackgroundEstimator.hh"
@@ -31,4 +33,5 @@
 #include <fastjet/ClusterSequenceStructure.hh>
 #include <iostream>
+#include <sstream>
 
 FASTJET_BEGIN_NAMESPACE     // defined in fastjet/internal/base.hh
@@ -37,5 +40,7 @@
 
 double BackgroundJetScalarPtDensity::result(const PseudoJet & jet) const {
-  std::vector<PseudoJet> constituents = jet.constituents();
+  // do not include the ghosts in the list of constituents to have a
+  // correct behaviour when _pt_power is <= 0
+  std::vector<PseudoJet> constituents = (!SelectorIsPureGhost())(jet.constituents());
   double scalar_pt = 0;
   for (unsigned i = 0; i < constituents.size(); i++) {
@@ -43,4 +48,12 @@
   }
   return scalar_pt / jet.area();
+}
+
+
+std::string BackgroundJetScalarPtDensity::description() const {
+  ostringstream oss;
+  oss << "BackgroundScalarJetPtDensity";
+  if (_pt_power != 1.0) oss << " with pt_power = " << _pt_power;
+  return oss.str();
 }
 
@@ -72,5 +85,5 @@
                                          const JetDefinition &jet_def,
                                          const AreaDefinition &area_def)
-  : _rho_range(rho_range), _jet_def(jet_def), _area_def(area_def) {
+  : _rho_range(rho_range), _jet_def(jet_def), _area_def(area_def){
 
   // initialise things decently
@@ -261,4 +274,56 @@
 
 //----------------------------------------------------------------------
+// returns rho_m (particle-masses contribution to the 4-vector density)
+double JetMedianBackgroundEstimator::rho_m() const {
+  if (! has_rho_m()){
+    throw Error("JetMediamBackgroundEstimator: rho_m requested but rho_m calculation is disabled (either eplicitly or due to the presence of a jet density class).");
+  }
+  if (_rho_range.takes_reference())
+    throw Error("The background estimation is obtained from a selector that takes a reference jet. rho(PseudoJet) should be used in that case");
+  _recompute_if_needed();
+  return _rho_m;
+}
+
+
+//----------------------------------------------------------------------
+// returns sigma_m (particle-masses contribution to the 4-vector
+// density); must be multipled by sqrt(area) to get fluctuations
+// for a region of a given area.
+double JetMedianBackgroundEstimator::sigma_m() const{
+  if (! has_rho_m()){
+    throw Error("JetMediamBackgroundEstimator: sigma_m requested but rho_m/sigma_m calculation is disabled (either explicitly or due to the presence of a jet density class).");
+  }
+  if (_rho_range.takes_reference())
+    throw Error("The background estimation is obtained from a selector that takes a reference jet. rho(PseudoJet) should be used in that case");
+  _recompute_if_needed();
+  return _sigma_m;
+}
+
+//----------------------------------------------------------------------
+// returns rho_m locally at the position of a given jet. As for
+// rho(jet), it is non-const.
+double JetMedianBackgroundEstimator::rho_m(const PseudoJet & jet)  {
+  _recompute_if_needed(jet);
+  double our_rho = _rho_m;
+  if (_rescaling_class != 0) { 
+    our_rho *= (*_rescaling_class)(jet);
+  }
+  return our_rho;
+}
+
+
+//----------------------------------------------------------------------
+// returns sigma_m locally at the position of a given jet. As for
+// rho(jet), it is non-const.
+double JetMedianBackgroundEstimator::sigma_m(const PseudoJet & jet){
+  _recompute_if_needed(jet);
+  double our_sigma = _sigma_m;
+  if (_rescaling_class != 0) { 
+    our_sigma *= (*_rescaling_class)(jet);
+  }
+  return our_sigma;
+}
+
+//----------------------------------------------------------------------
 // configuring behaviour
 //----------------------------------------------------------------------
@@ -271,6 +336,9 @@
   set_provide_fj2_sigma(false);
 
+  _enable_rho_m = true;
+
   // reset the computed values
   _rho = _sigma = 0.0;
+  _rho_m = _sigma_m = 0.0;
   _n_jets_used = _n_empty_jets = 0;
   _empty_area = _mean_area = 0.0;
@@ -289,5 +357,5 @@
 // is used (as occurs also if this function is not called).
 void JetMedianBackgroundEstimator::set_jet_density_class(const FunctionOfPseudoJet<double> * jet_density_class_in) {
-  _warnings_preliminary.warn("JetMedianBackgroundEstimator::set_jet_density_class: density classes are still preliminary in FastJet 3.0. Their interface may differ in future releases (without guaranteeing backward compatibility).");
+  _warnings_preliminary.warn("JetMedianBackgroundEstimator::set_jet_density_class: density classes are still preliminary in FastJet 3.1. Their interface may differ in future releases (without guaranteeing backward compatibility). Note that since FastJet 3.1, rho_m and sigma_m are accessible direclty in JetMedianBackgroundEstimator and GridMedianBackgroundEstimator(with no need for a density class).");
   _jet_density_class = jet_density_class_in;
   _uptodate = false;
@@ -338,5 +406,6 @@
   // fill the vector of pt/area (or the quantity from the jet density class) 
   //  - in the range
-  vector<double> vector_for_median;
+  vector<double> vector_for_median_pt;
+  vector<double> vector_for_median_dt;
   double total_area  = 0.0;
   _n_jets_used = 0;
@@ -346,20 +415,38 @@
 
   // compute the pt/area for the selected jets
+  double median_input_pt, median_input_dt=0.0;
+  BackgroundJetPtMDensity m_density;
+  bool do_rho_m = has_rho_m();
   for (unsigned i = 0; i < selected_jets.size(); i++) {
     const PseudoJet & current_jet = selected_jets[i];
 
     double this_area = (_use_area_4vector) ? current_jet.area_4vector().perp() : current_jet.area(); 
-
     if (this_area>0){
-      double median_input;
+      // for the pt component, we either use pt or the user-provided
+      // density class
       if (_jet_density_class == 0) {
-        median_input = current_jet.perp()/this_area;
+        median_input_pt = current_jet.perp()/this_area;
       } else {
-        median_input = (*_jet_density_class)(current_jet);
+        median_input_pt = (*_jet_density_class)(current_jet);
       }
+
+      // handle the rho_m part if requested
+      // note that we're using the scalar area as a normalisation inside the
+      // density class!
+      if (do_rho_m) 
+	median_input_dt = m_density(current_jet);
+    
+      // perform rescaling if needed
       if (_rescaling_class != 0) {
-        median_input /= (*_rescaling_class)(current_jet);
+	double resc = (*_rescaling_class)(current_jet);;
+        median_input_pt /= resc;
+        median_input_dt /= resc;
       }
-      vector_for_median.push_back(median_input);
+      
+      // store the result for future computation of the median
+      vector_for_median_pt.push_back(median_input_pt);
+      if (do_rho_m) 
+	vector_for_median_dt.push_back(median_input_dt);
+
       total_area  += this_area;
       _n_jets_used++;
@@ -367,11 +454,12 @@
       _warnings_zero_area.warn("JetMedianBackgroundEstimator::_compute(...): discarded jet with zero area. Zero-area jets may be due to (i) too large a ghost area (ii) a jet being outside the ghost range (iii) the computation not being done using an appropriate algorithm (kt;C/A).");
     }
-      
   }
   
   // there is nothing inside our region, so answer will always be zero
-  if (vector_for_median.size() == 0) {
+  if (vector_for_median_pt.size() == 0) {
     _rho        = 0.0;
     _sigma      = 0.0;
+    _rho_m      = 0.0;
+    _sigma_m    = 0.0;
     _mean_area  = 0.0;
     return;
@@ -392,5 +480,5 @@
 
   double stand_dev;
-  _median_and_stddev(vector_for_median, _n_empty_jets, _rho, stand_dev, 
+  _median_and_stddev(vector_for_median_pt, _n_empty_jets, _rho, stand_dev, 
                      _provide_fj2_sigma);
 
@@ -398,4 +486,11 @@
   _mean_area  = total_area / total_njets;
   _sigma      = stand_dev * sqrt(_mean_area);
+
+  // compute the rho_m part now
+  if (do_rho_m){
+    _median_and_stddev(vector_for_median_dt, _n_empty_jets, _rho_m, stand_dev, 
+		       _provide_fj2_sigma);
+    _sigma_m = stand_dev * sqrt(_mean_area);
+  }
 
   // record that the computation has been performed  
@@ -439,5 +534,4 @@
 
 
-
 FASTJET_END_NAMESPACE
 
Index: external/fastjet/tools/JetMedianBackgroundEstimator.hh
===================================================================
--- external/fastjet/tools/JetMedianBackgroundEstimator.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/JetMedianBackgroundEstimator.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,8 +2,8 @@
 #define __FASTJET_BACKGROUND_ESTIMATOR_HH__
 
-//STARTHEADER
-// $Id: JetMedianBackgroundEstimator.hh 2689 2011-11-14 14:51:06Z soyez $
+//FJSTARTHEADER
+// $Id: JetMedianBackgroundEstimator.hh 3517 2014-08-01 14:23:13Z soyez $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,5 +30,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include <fastjet/ClusterSequenceAreaBase.hh>
@@ -121,5 +123,6 @@
   ///
   JetMedianBackgroundEstimator(const Selector &rho_range = SelectorIdentity())
-    : _rho_range(rho_range), _jet_def(JetDefinition()) { reset(); }
+    : _rho_range(rho_range), _jet_def(JetDefinition()),
+      _enable_rho_m(true){ reset(); }
   
 
@@ -168,4 +171,8 @@
   }
 
+  /// determine whether the automatic calculation of rho_m and sigma_m
+  /// is enabled (by default true)
+  void set_compute_rho_m(bool enable){ _enable_rho_m = enable;}
+
   //\}
 
@@ -201,4 +208,32 @@
   virtual bool has_sigma() {return true;}
 
+  //----------------------------------------------------------------
+  // now do the same thing for rho_m and sigma_m
+
+  /// returns rho_m, the purely longitudinal, particle-mass-induced
+  /// component of the background density per unit area
+  virtual double rho_m() const;
+
+  /// returns sigma_m, a measure of the fluctuations in the purely
+  /// longitudinal, particle-mass-induced component of the background
+  /// density per unit area; must be multipled by sqrt(area) to get
+  /// fluctuations for a region of a given area.
+  virtual double sigma_m() const;
+
+  /// Returns rho_m locally at the jet position. As for rho(jet), it is non-const.
+  virtual double rho_m(const PseudoJet & /*jet*/);
+
+  /// Returns sigma_m locally at the jet position. As for rho(jet), it is non-const.
+  virtual double sigma_m(const PseudoJet & /*jet*/);
+
+  /// Returns true if this background estimator has support for
+  /// determination of rho_m.
+  ///
+  /// In te presence of a density class, support for rho_m is
+  /// automatically disabled
+  ///
+  /// Note that support for sigma_m is automatic is one has sigma and
+  /// rho_m support.
+  virtual bool has_rho_m() const {return _enable_rho_m && (_jet_density_class == 0);}
   //\}
   
@@ -208,6 +243,9 @@
   /// Returns the mean area of the jets used to actually compute the
   /// background properties in the last call of rho() or sigma()
+  /// If the configuration has changed in the meantime, throw an error.
   double mean_area() const{
-    _recompute_if_needed();
+    if (!_uptodate)
+      throw Error("JetMedianBackgroundEstimator::mean_area(): one may not retrieve information about the last call to rho() or sigma() when the configuration has changed in the meantime.");
+    //_recompute_if_needed();
     return _mean_area;
   }
@@ -215,7 +253,23 @@
   /// returns the number of jets used to actually compute the
   /// background properties in the last call of rho() or sigma()
+  /// If the configuration has changed in the meantime, throw an error.
   unsigned int n_jets_used() const{
-    _recompute_if_needed();
+    if (!_uptodate)
+      throw Error("JetMedianBackgroundEstimator::n_jets_used(): one may not retrieve information about the last call to rho() or sigma() when the configuration has changed in the meantime.");
+    //_recompute_if_needed();
     return _n_jets_used;
+  }
+
+  /// returns the jets used to actually compute the background
+  /// properties
+  std::vector<PseudoJet> jets_used() const{
+    if (!_uptodate) throw Error("JetMedianBackgroundEstimator::n_jets_used(): one may not retrieve information about the last call to rho() or sigma() when the configuration has changed in the meantime.");
+    _check_csa_alive();
+    std::vector<PseudoJet> tmp_jets = _rho_range(_included_jets);
+    std::vector<PseudoJet> used_jets;
+    for (unsigned int i=0; i<tmp_jets.size(); i++){
+      if (tmp_jets[i].area()>0) used_jets.push_back(tmp_jets[i]);
+    }
+    return used_jets;
   }
 
@@ -223,4 +277,5 @@
   /// the selector) that is not occupied by jets. The value is that
   /// for the last call of rho() or sigma()
+  /// If the configuration has changed in the meantime, throw an error.
   ///
   /// The answer is defined to be zero if the area calculation
@@ -234,5 +289,7 @@
   /// call to the ClusterSequenceAreaBase function.
   double empty_area() const{
-    _recompute_if_needed();
+    if (!_uptodate)
+      throw Error("JetMedianBackgroundEstimator::empty_area(): one may not retrieve information about the last call to rho() or sigma() when the configuration has changed in the meantime.");
+    //_recompute_if_needed();
     return _empty_area;
   }
@@ -241,4 +298,5 @@
   /// background properties. The value is that for the last call of
   /// rho() or sigma().
+  /// If the configuration has changed in the meantime, throw an error.
   ///
   /// If the area has explicit ghosts the result is zero; for active
@@ -250,5 +308,7 @@
   /// call to the ClusterSequenceAreaBase function.
   double n_empty_jets() const{
-    _recompute_if_needed();
+    if (!_uptodate)
+      throw Error("JetMedianBackgroundEstimator::n_empty_jets(): one may not retrieve information about the last call to rho() or sigma() when the configuration has changed in the meantime.");
+    //_recompute_if_needed();
     return _n_empty_jets;
   }
@@ -361,5 +421,5 @@
   /// Issue a warning otherwise
   void _check_jet_alg_good_for_median() const;
-  
+
   // the basic parameters of this class (passed through the variou ctors)
   Selector _rho_range;                   ///< range to compute the background in
@@ -368,13 +428,16 @@
   std::vector<PseudoJet> _included_jets; ///< jets to be used
   
-  // the tunable aprameters of the class
+  // the tunable parameters of the class
   bool _use_area_4vector;
   bool _provide_fj2_sigma;
   const FunctionOfPseudoJet<double> * _jet_density_class;
   //SharedPtr<BackgroundRescalingBase> _rescaling_class_sharedptr;
+  bool _enable_rho_m;
   
   // the actual results of the computation
   mutable double _rho;               ///< background estimated density per unit area
   mutable double _sigma;             ///< background estimated fluctuations
+  mutable double _rho_m;             ///< "mass" background estimated density per unit area
+  mutable double _sigma_m;           ///< "mass" background estimated fluctuations
   mutable double _mean_area;         ///< mean area of the jets used to estimate the background
   mutable unsigned int _n_jets_used; ///< number of jets used to estimate the background
@@ -429,5 +492,5 @@
   virtual double result(const PseudoJet & jet) const;
 
-  virtual std::string description() const {return "BackgroundScalarJetPtDensity";}
+  virtual std::string description() const;
 
 private:
Index: external/fastjet/tools/MassDropTagger.cc
===================================================================
--- external/fastjet/tools/MassDropTagger.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/MassDropTagger.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: MassDropTagger.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include <fastjet/tools/MassDropTagger.hh>
Index: external/fastjet/tools/MassDropTagger.hh
===================================================================
--- external/fastjet/tools/MassDropTagger.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/MassDropTagger.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: MassDropTagger.hh 2731 2011-11-21 12:15:21Z soyez $
+//FJSTARTHEADER
+// $Id: MassDropTagger.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __FASTJET_MASS_DROP_TAGGER_HH__
Index: external/fastjet/tools/Pruner.cc
===================================================================
--- external/fastjet/tools/Pruner.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/Pruner.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: Pruner.cc 3481 2014-07-29 17:24:12Z soyez $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/tools/Pruner.hh"
@@ -47,10 +49,10 @@
 //----------------------------------------------------------------------
 // alternative (dynamic) ctor
-//  \param jet_def the jet definition for the internal clustering
+//  \param jet_def     the jet definition for the internal clustering
 //  \param zcut_dyn    dynamic pt-fraction cut in the pruning
 //  \param Rcut_dyn    dynamic angular distance cut in the pruning
 Pruner::Pruner(const JetDefinition &jet_def, 
-         FunctionOfPseudoJet<double> *zcut_dyn,
-         FunctionOfPseudoJet<double> *Rcut_dyn)
+         const FunctionOfPseudoJet<double> *zcut_dyn,
+         const FunctionOfPseudoJet<double> *Rcut_dyn)
   : _jet_def(jet_def), _zcut(0), _Rcut_factor(0),
     _zcut_dyn(zcut_dyn), _Rcut_dyn(Rcut_dyn), _get_recombiner_from_jet(false)  {
@@ -74,25 +76,17 @@
   double zcut = (_zcut_dyn) ? (*_zcut_dyn)(jet) : _zcut;
   PruningPlugin * pruning_plugin;
+
   // for some constructors, we get the recombiner from the 
-  // input jet -- some acrobatics are needed (see plans for FJ3.1
-  // for a hopefully better solution).
+  // input jet -- some acrobatics are needed
   if (_get_recombiner_from_jet) {
-    const JetDefinition::Recombiner * common_recombiner = 
-                                              _get_common_recombiner(jet);
-    if (common_recombiner) {
-      JetDefinition jet_def = _jet_def;
-      if (typeid(*common_recombiner) == typeid(JetDefinition::DefaultRecombiner)) {
-        RecombinationScheme scheme = 
-          static_cast<const JetDefinition::DefaultRecombiner *>(common_recombiner)->scheme();
-        jet_def.set_recombination_scheme(scheme);
-      } else {
-        jet_def.set_recombiner(common_recombiner);
-      }
-      pruning_plugin = new PruningPlugin(jet_def, zcut, Rcut);
-    } else {
-      // if there wasn't a common recombiner, we just use the default
-      // recombiner that was in _jet_def
-      pruning_plugin = new PruningPlugin(_jet_def, zcut, Rcut);
-    }
+    JetDefinition jet_def = _jet_def;
+
+    // if all the pieces have a shared recombiner, we'll use that
+    // one. Otherwise, use the one from _jet_def as a fallback.
+    JetDefinition jet_def_for_recombiner;
+    if (_check_common_recombiner(jet, jet_def_for_recombiner)){
+      jet_def.set_recombiner(jet_def_for_recombiner);
+    }
+    pruning_plugin = new PruningPlugin(jet_def, zcut, Rcut);
   } else {
     pruning_plugin = new PruningPlugin(_jet_def, zcut, Rcut);
@@ -122,4 +116,6 @@
   PseudoJet result_local = SelectorNHardest(1)(cs->inclusive_jets())[0];
   PrunerStructure * s = new PrunerStructure(result_local);
+  s->_Rcut = Rcut;
+  s->_zcut = zcut;
   result_local.set_structure_shared_ptr(SharedPtr<PseudoJetStructureBase>(s));
   
@@ -155,31 +151,36 @@
 }
 
-// see if there is a common recombiner among the pieces; if there
-// is return a pointer to it; otherwise, return NULL.
-// 
-// NB: this way of doing things is not ideal, because quite some work
-//     is needed to get a correct handling of the final recombiner
-//     (e.g. default v. non-default). In future add
-//     set_recombiner(jet_def) to JetDefinition, maybe also add
-//     an invalid_scheme to the default recombiner and then 
-//     do all the work below directly with a JetDefinition directly
-//     together with JD::has_same_recombiner(...)
-const JetDefinition::Recombiner * Pruner::_get_common_recombiner(const PseudoJet &jet) const{
-  if (jet.has_associated_cluster_sequence())
-    return jet.validated_cs()->jet_def().recombiner();
+// see if there is a common recombiner among the pieces; if there is
+// return true and set jet_def_for_recombiner so that the recombiner
+// can be taken from that JetDefinition. Otherwise, return
+// false. 'assigned' is initially false; when true, each time we meet
+// a new jet definition, we'll check it shares the same recombiner as
+// jet_def_for_recombiner.
+bool Pruner::_check_common_recombiner(const PseudoJet &jet, 
+				      JetDefinition &jet_def_for_recombiner,
+				      bool assigned) const{
+  if (jet.has_associated_cluster_sequence()){
+    // if the jet def for recombination has already been assigned, check if we have the same
+    if (assigned)
+      return jet.validated_cs()->jet_def().has_same_recombiner(jet_def_for_recombiner);
+
+    // otherwise, assign it.
+    jet_def_for_recombiner = jet.validated_cs()->jet_def();
+    assigned = true;
+    return true;
+  }
 
   // if the jet has pieces, recurse in the pieces
   if (jet.has_pieces()){
     vector<PseudoJet> pieces = jet.pieces();
-    if (pieces.size() == 0) return 0;
-    const JetDefinition::Recombiner * reco = _get_common_recombiner(pieces[0]);
-    for (unsigned int i=1;i<pieces.size(); i++)
-      if (_get_common_recombiner(pieces[i]) != reco) return 0;
+    if (pieces.size() == 0) return false;
+    for (unsigned int i=0;i<pieces.size(); i++)
+      if (!_check_common_recombiner(pieces[i], jet_def_for_recombiner, assigned)) return false;
     // never returned false, so we're OK.
-    return reco;
+    return true;
   }
 
   // return false for any other (unknown) structure
-  return 0;
+  return false;
 }
 
Index: external/fastjet/tools/Pruner.hh
===================================================================
--- external/fastjet/tools/Pruner.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/Pruner.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,8 +2,8 @@
 #define __FASTJET_TOOLS_PRUNER_HH__
 
-//STARTHEADER
-// $Id: Pruner.hh 2616 2011-09-30 18:03:40Z salam $
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: Pruner.hh 3481 2014-07-29 17:24:12Z soyez $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,5 +30,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/ClusterSequence.hh"
@@ -43,4 +45,9 @@
 class PruningRecombiner;
 class PruningPlugin;
+
+// This tells third-party code that the pruner structure 
+// stores Rcut info; the alternative is for the user to 
+// get the information from the version number
+#define FASTJET_PRUNER_STRUCTURE_STORES_RCUT
 
 //----------------------------------------------------------------------
@@ -135,6 +142,6 @@
   ///  \param Rcut_dyn    dynamic angular distance cut in the pruning
   Pruner(const JetDefinition &jet_def, 
-         FunctionOfPseudoJet<double> *zcut_dyn,
-         FunctionOfPseudoJet<double> *Rcut_dyn);
+         const FunctionOfPseudoJet<double> *zcut_dyn,
+         const FunctionOfPseudoJet<double> *Rcut_dyn);
 
   /// action on a single jet
@@ -152,13 +159,19 @@
   bool _check_explicit_ghosts(const PseudoJet &jet) const;
 
-  /// return a pointer to a "common" recombiner if there is one,
-  /// alternatively a null pointer.
-  const JetDefinition::Recombiner * _get_common_recombiner(const PseudoJet &jet) const;
+  /// see if there is a common recombiner among the pieces; if there
+  /// is return true and set jet_def_for_recombiner so that the
+  /// recombiner can be taken from that JetDefinition. Otherwise,
+  /// return false. 'assigned' is initially false; when true, each
+  /// time we meet a new jet definition, we'll check it shares the
+  /// same recombiner as jet_def_for_recombiner.
+  bool _check_common_recombiner(const PseudoJet &jet, 
+				JetDefinition &jet_def_for_recombiner,
+				bool assigned=false) const;
 
   JetDefinition _jet_def; ///< the internal jet definition
   double _zcut;        	  ///< the pt-fraction cut
   double _Rcut_factor;    ///< the angular separation cut factor
-  FunctionOfPseudoJet<double> *_zcut_dyn; ///< dynamic zcut
-  FunctionOfPseudoJet<double> *_Rcut_dyn; ///< dynamic Rcut
+  const FunctionOfPseudoJet<double> *_zcut_dyn; ///< dynamic zcut
+  const FunctionOfPseudoJet<double> *_Rcut_dyn; ///< dynamic Rcut
   bool   _get_recombiner_from_jet; ///< true for minimal constructor,
                                    ///< causes recombiner to be set equal 
@@ -194,6 +207,15 @@
   std::vector<PseudoJet> extra_jets() const;
 
+  /// return the value of Rcut that was used for this specific pruning.
+  double Rcut() const {return _Rcut;}
+
+  /// return the value of Rcut that was used for this specific pruning.
+  double zcut() const {return _zcut;}
+
 protected:
   friend class Pruner; ///< to allow setting the internal information
+
+private:
+  double _Rcut, _zcut;
 };
 
Index: external/fastjet/tools/Recluster.cc
===================================================================
--- external/fastjet/tools/Recluster.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/tools/Recluster.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,417 @@
+// $Id: Recluster.cc 3629 2014-08-14 17:21:15Z salam $
+//
+// Copyright (c) 2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//
+//----------------------------------------------------------------------
+// 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 "fastjet/tools/Recluster.hh"
+#include "fastjet/CompositeJetStructure.hh"
+#include <fastjet/ClusterSequenceActiveAreaExplicitGhosts.hh>
+#include <sstream>
+#include <typeinfo>
+
+using namespace std;
+
+// Comments:
+//
+//  - If the jet comes from a C/A clustering (or is a composite jet
+//    made of C/A clusterings) and we recluster it with a C/A
+//    algorithm, we just use exclusive jets instead of doing the
+//    clustering explicitly. In this specific case, we need to make
+//    sure that all the pieces share the same cluster sequence.
+//
+//  - If the recombiner has to be taken from the original jet and that
+//    jet is composite, we need to check that all the pieces were
+//    obtained with the same recombiner.
+//
+//  - Note that a preliminary version of this code has been
+//    distributed in the RecursiveTools fastjet-contrib. The present
+//    version has a few minor fixed
+
+FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
+
+LimitedWarning Recluster::_explicit_ghost_warning;
+
+// ctor
+Recluster::Recluster(JetAlgorithm new_jet_alg, double new_jet_radius, Keep keep_in)
+  : _new_jet_def(JetDefinition(new_jet_alg, new_jet_radius)), 
+    _acquire_recombiner(true), _keep(keep_in), _cambridge_optimisation_enabled(true){}
+
+Recluster::Recluster(JetAlgorithm new_jet_alg, Keep keep_in)
+    : _acquire_recombiner(true), _keep(keep_in), _cambridge_optimisation_enabled(true){
+  switch (JetDefinition::n_parameters_for_algorithm(new_jet_alg)){
+  case 0: _new_jet_def = JetDefinition(new_jet_alg); break;
+  case 1: _new_jet_def = JetDefinition(new_jet_alg, JetDefinition::max_allowable_R); break;
+  default:
+    throw Error("Recluster(): tried to construct specifying only a jet algorithm ("+JetDefinition::algorithm_description(new_jet_alg)+") which takes more than 1 parameter");
+  };
+}
+
+
+// class description
+string Recluster::description() const {
+  ostringstream ostr;
+  ostr << "Recluster with new_jet_def = ";
+  if (_acquire_recombiner){
+    ostr << _new_jet_def.description_no_recombiner();
+    ostr << ", using a recombiner obtained from the jet being reclustered";
+  } else {
+    ostr << _new_jet_def.description();
+  }
+
+  if (_keep == keep_only_hardest)
+    ostr << " and keeping the hardest inclusive jet";
+  else
+    ostr << " and joining all inclusive jets into a composite jet";
+
+  return ostr.str();
+}
+
+
+// the main piece of code that performs the reclustering
+PseudoJet Recluster::result(const PseudoJet &jet) const {
+  // get the incljets and the exact jet definition that has been used
+  // to get them
+  vector<PseudoJet> incljets;
+  bool ca_optimised = get_new_jets_and_def(jet, incljets);
+
+  return generate_output_jet(incljets, ca_optimised);
+}
+
+
+// a lower-level method that does the actual work of reclustering the
+// input jet. The resulting incljets are stored in output_jets and the
+// jet definition that has been used can be deduced from their
+// associated ClusterSequence
+//
+//  - input_jet       the (input) jet that one wants to recluster
+//  - output_jets     incljets resulting from the new clustering
+//
+// returns true if the C/A optimisation has been used (this means
+// that generate_output_jet will watch out for non-explicit-ghost
+// areas that might be leftover)
+bool Recluster::get_new_jets_and_def(const PseudoJet & input_jet, 
+                                     vector<PseudoJet> & output_jets) const{
+  // generic sanity checks
+  //-------------------------------------------------------------------
+  // make sure that the jet has constituents
+  if (! input_jet.has_constituents())
+    throw Error("Recluster can only be applied on jets having constituents");
+
+  // tests particular to certain configurations
+  //-------------------------------------------------------------------
+
+  // for a whole variety of tests, we shall need the "recursive"
+  // pieces of the jet (the jet itself or recursing down to its most
+  // fundamental pieces). So we do compute these once and for all.
+  //
+  // Note that the pieces are always needed (either for C/A or for the
+  // area checks)
+  vector<PseudoJet> all_pieces;
+  if ((!_get_all_pieces(input_jet, all_pieces)) || (all_pieces.size()==0)){
+    throw Error("Recluster: failed to retrieve all the pieces composing the jet.");
+  }
+
+  // decide which jet definition to use
+  //-------------------------------------------------------------------
+  JetDefinition new_jet_def = _new_jet_def;
+  if (_acquire_recombiner){
+    _acquire_recombiner_from_pieces(all_pieces, new_jet_def);
+  }
+
+  // the vector that will ultimately hold the incljets
+  output_jets.clear();
+
+  // check if we can apply the simplification for C/A jets reclustered
+  // with C/A
+  //
+  // we apply C/A clustering iff
+  //  - the requested new_jet_def is C/A
+  //  - the jet is either directly coming from C/A or if it is a
+  //    superposition of C/A jets from the same cluster sequence
+  //  - the pieces agree with the recombination scheme of new_jet_def
+  //
+  // In this case area support will be automatically inherited so we
+  // can only worry about this later
+  // -------------------------------------------------------------------
+  if (_check_ca(all_pieces, new_jet_def)){
+    _recluster_ca(all_pieces, output_jets, new_jet_def.R());
+    output_jets = sorted_by_pt(output_jets);
+    return true;
+  }
+
+  // decide if area support has to be kept
+  //-------------------------------------------------------------------
+  bool include_area_support = input_jet.has_area();
+  if ((include_area_support) &&  (!_check_explicit_ghosts(all_pieces))){
+    _explicit_ghost_warning.warn("Recluster: the original cluster sequence is lacking explicit ghosts; area support will no longer be available after re-clustering");
+    include_area_support = false;
+  }
+
+  // extract the incljets
+  //-------------------------------------------------------------------
+  _recluster_generic(input_jet, output_jets, new_jet_def, include_area_support);
+  output_jets = sorted_by_pt(output_jets);
+
+  return false;
+}
+
+// given a set of incljets and a jet definition used, create the
+// resulting PseudoJet
+PseudoJet Recluster::generate_output_jet(std::vector<PseudoJet> & incljets, 
+                                         bool ca_optimisation_used) const{
+  // first handle the case where we only need to keep the hardest incljet
+  if (_keep == keep_only_hardest) {
+    if (incljets.size() > 0) {
+      return incljets[0];
+    } else {
+      return PseudoJet();
+    }
+  }
+
+  // now the case where all incljets have to be joined
+
+  // safekeeper
+  if (incljets.size()==0) return join(incljets);
+
+  PseudoJet reclustered = join(incljets, 
+			       *(incljets[0].associated_cluster_sequence()->jet_def().recombiner()));
+
+  // if we've used C/A optimisation, we need to get rid of the area
+  // information if it comes from a non-explicit-ghost clustering.
+  // (because in that case it can be erroneous due to the lack of
+  // information about empty areas)
+  if (ca_optimisation_used){
+    if (reclustered.has_area() &&
+        (incljets.size() > 0) &&
+        (! incljets[0].validated_csab()->has_explicit_ghosts())){
+      CompositeJetStructure *css = dynamic_cast<CompositeJetStructure *>(reclustered.structure_non_const_ptr());
+      assert(css);
+      css->discard_area();
+    }
+  }
+  
+  return reclustered;
+}
+
+//----------------------------------------------------------------------
+// the parts that really do the reclustering
+//----------------------------------------------------------------------
+
+// get the subjets in the simple case of C/A+C/A
+void Recluster::_recluster_ca(const vector<PseudoJet> & all_pieces, 
+                              vector<PseudoJet> & subjets, 
+                              double Rfilt) const{
+  subjets.clear();
+
+  // each individual piece should have a C/A cluster sequence
+  // associated to it. So a simple loop would do the job
+  for (vector<PseudoJet>::const_iterator piece_it = all_pieces.begin(); 
+       piece_it!=all_pieces.end(); piece_it++){
+    // just extract the exclusive subjets of 'jet'
+    const ClusterSequence *cs = piece_it->associated_cluster_sequence(); 
+    vector<PseudoJet> local_subjets;
+
+    double dcut = Rfilt / cs->jet_def().R();
+    if (dcut>=1.0){
+      // remember that in this case all the pairwise interpiece
+      // distances are supposed to be larger than Rfilt (this was
+      // tested in _check_ca), which means that they can never
+      // recombine with each other.
+      local_subjets.push_back(*piece_it);
+    } else {
+      local_subjets = piece_it->exclusive_subjets(dcut*dcut);
+    }
+
+    copy(local_subjets.begin(), local_subjets.end(), back_inserter(subjets));
+  }
+}
+
+
+// perform the reclustering itself for all cases where the "C/A trick"
+// does not apply
+void Recluster::_recluster_generic(const PseudoJet & jet, 
+                                   vector<PseudoJet> & incljets,
+                                   const JetDefinition & new_jet_def,
+                                   bool do_areas) const{
+  // create a new, internal, ClusterSequence from the jet constituents
+  // get the incljets directly from there
+  //
+  // If the jet has area support then we separate the ghosts from the
+  // "regular" particles so the incljets will also have area
+  // support. Note that we do this regardless of whether rho is zero
+  // or not.
+  //
+  // Note that to be able to separate the ghosts, one needs explicit
+  // ghosts!!
+  // ---------------------------------------------------------------
+  if (do_areas){
+    //vector<PseudoJet> all_constituents = jet.constituents();
+    vector<PseudoJet> regular_constituents, ghosts;  
+    SelectorIsPureGhost().sift(jet.constituents(), ghosts, regular_constituents);
+
+    // figure out the ghost area from the 1st ghost (if none, any value
+    // would probably do as the area will be 0 and subtraction will have
+    // no effect!)
+    double ghost_area = (ghosts.size()) ? ghosts[0].area() : 0.01;
+    ClusterSequenceActiveAreaExplicitGhosts * csa
+      = new ClusterSequenceActiveAreaExplicitGhosts(regular_constituents, 
+                                                    new_jet_def, 
+                                                    ghosts, ghost_area);
+
+    incljets = csa->inclusive_jets();
+
+    // allow the cs to be deleted when it's no longer used
+    // 
+    // Note that there is at least one constituent in the jet so there
+    // is in principle at least one incljet. But one may have used a
+    // nasty recombiner or jet def that left an empty set of incljets,
+    // so we'd rather play it safe (e.g. GridJetPlugin, with the
+    // constituents outside the range of the grid)
+    if (incljets.size())
+      csa->delete_self_when_unused();
+    else
+      delete csa;
+  } else {
+    ClusterSequence * cs = new ClusterSequence(jet.constituents(), new_jet_def);
+    incljets = cs->inclusive_jets();
+    // allow the cs to be deleted when it's no longer used (again, we
+    // add an extra safety check)
+    if (incljets.size())
+      cs->delete_self_when_unused();
+    else 
+      delete cs;
+  }
+}
+
+//----------------------------------------------------------------------
+// various checks and internal constructs
+//----------------------------------------------------------------------
+
+// fundamental info for CompositeJets
+//----------------------------------------------------------------------
+ 
+// get the pieces down to the fundamental pieces
+// 
+// Note that this just checks that there is an associated CS to the
+// fundamental pieces, not that it is still valid
+bool Recluster::_get_all_pieces(const PseudoJet &jet, vector<PseudoJet> &all_pieces) const{
+  if (jet.has_associated_cluster_sequence()){
+    all_pieces.push_back(jet);
+    return true;
+  }
+
+  if (jet.has_pieces()){
+    const vector<PseudoJet> pieces = jet.pieces();
+    for (vector<PseudoJet>::const_iterator it=pieces.begin(); it!=pieces.end(); it++)
+      if (!_get_all_pieces(*it, all_pieces)) return false;
+    return true;
+  }
+
+  return false;
+}
+
+// construct the re-clustering jet definition using the recombiner
+// from whatever definition has been used to obtain the original jet
+//----------------------------------------------------------------------
+void Recluster::_acquire_recombiner_from_pieces(const vector<PseudoJet> &all_pieces, 
+                                                JetDefinition &new_jet_def) const{
+  // a quick safety check
+  assert(_acquire_recombiner);
+
+  // check that all the pieces have the same recombiner
+  //
+  // Note that if the jet has an associated cluster sequence that is no
+  // longer valid, an error will be thrown (needed since it could be the
+  // 1st check called after the enumeration of the pieces)
+  const JetDefinition & jd_ref = all_pieces[0].validated_cs()->jet_def();
+  for (unsigned int i=1; i<all_pieces.size(); i++){
+    if (!all_pieces[i].validated_cs()->jet_def().has_same_recombiner(jd_ref)){
+      throw Error("Recluster instance is configured to determine the recombination scheme (or recombiner) from the original jet, but different pieces of the jet were found to have non-equivalent recombiners.");
+    }
+  }
+
+  // get the recombiner from the original jet_def
+  new_jet_def.set_recombiner(jd_ref);
+}
+
+// area support
+//----------------------------------------------------------------------
+
+// check if the jet (or all its pieces) have explicit ghosts
+// (assuming the jet has area support).
+//
+// Note that if the jet has an associated cluster sequence that is no
+// longer valid, an error will be thrown (needed since it could be the
+// 1st check called after the enumeration of the pieces)
+bool Recluster::_check_explicit_ghosts(const vector<PseudoJet> &all_pieces) const{
+  for (vector<PseudoJet>::const_iterator it=all_pieces.begin(); it!=all_pieces.end(); it++)
+    if (! it->validated_csab()->has_explicit_ghosts()) return false;
+  return true;
+}
+
+// C/A specific tests
+//----------------------------------------------------------------------
+
+// check if one can apply the simplification for C/A incljets
+//
+// This includes:
+//  - the incljet definition asks for C/A incljets
+//  - all the pieces share the same CS
+//  - that CS is C/A with the same recombiner as the incljet def
+//  - the re-clustering radius is not larger than any of the pairwise
+//    distance between the pieces
+//
+// Note that if the jet has an associated cluster sequence that is no
+// longer valid, an error will be thrown (needed since it could be the
+// 1st check called after the enumeration of the pieces)
+bool Recluster::_check_ca(const vector<PseudoJet> &all_pieces, 
+                          const JetDefinition &new_jet_def) const{
+  // check that optimisation is enabled
+  if (!_cambridge_optimisation_enabled) return false;
+
+  // check that we're reclustering with C/A
+  if (new_jet_def.jet_algorithm() != cambridge_algorithm) return false;
+
+  // check that the 1st of all the pieces (we're sure there is at
+  // least one) is coming from a C/A clustering. Then check that all
+  // the following pieces share the same ClusterSequence
+  const ClusterSequence * cs_ref = all_pieces[0].validated_cs();
+  if (cs_ref->jet_def().jet_algorithm() != cambridge_algorithm) return false;
+  for (unsigned int i=1; i<all_pieces.size(); i++)
+    if (all_pieces[i].validated_cs() != cs_ref) return false;
+
+  // check that the 1st piece has the same recombiner as the one used
+  // for the incljet clustering
+  // Note that since they share the same CS, checking the 1st one is enough
+  if (!cs_ref->jet_def().has_same_recombiner(new_jet_def)) return false;
+
+  // we also have to make sure that the reclustering radius is not larger
+  // than any of the inter-piece distances
+  double Rnew2 = new_jet_def.R();
+  Rnew2 *= Rnew2;
+  for (unsigned int i=0; i<all_pieces.size()-1; i++){
+    for (unsigned int j=i+1; j<all_pieces.size(); j++){
+      if (all_pieces[i].squared_distance(all_pieces[j]) <  Rnew2) return false;
+    }
+  }
+
+  return true;
+}
+
+FASTJET_END_NAMESPACE      // defined in fastjet/internal/base.hh
Index: external/fastjet/tools/Recluster.hh
===================================================================
--- external/fastjet/tools/Recluster.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
+++ external/fastjet/tools/Recluster.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -0,0 +1,262 @@
+#ifndef __FASTJET_TOOLS_RECLUSTER_HH__
+#define __FASTJET_TOOLS_RECLUSTER_HH__
+
+// $Id: Recluster.hh 3632 2014-08-15 10:42:53Z salam $
+//
+// Copyright (c) 2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//
+//----------------------------------------------------------------------
+// This file is part of FastJet
+//
+// 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 <fastjet/JetDefinition.hh>
+#include <fastjet/FunctionOfPseudoJet.hh>   // to derive Recluster from FOfPJ<PJ>
+#include <iostream>
+#include <string>
+
+// TODO:
+//
+//  - maintain Voronoi areas? Requires CSAB:has_voronoi_area()    {->UNASSIGNED}
+//  - make sure the description of the class is OK
+
+
+
+FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
+
+//----------------------------------------------------------------------
+/// \class Recluster
+/// Recluster a jet's constituents with a new jet definition.
+///
+/// When Recluster is constructed from a JetDefinition, it is that
+/// definition that will be used to obtain the new jets. The user may
+/// then decide if the recombiner should be the one from that jet
+/// definition or if it should be acquired from the jet being
+/// processed (the default).
+///
+/// Alternatively, Recluster can be constructed from a jet algorithm
+/// and an optional radius. In that case the recombiner is
+/// systematically obtained fromn the jet being processed (unless you
+/// call set_acquire_recombiner(false)). If only the jet algorithm is
+/// specified, a default radius of max_allowable_R will be assumed if
+/// needed.
+///
+/// Recluster has two possible behaviours:
+///
+///  - if it is constructed with keep=keep_only_hardest the hardest
+///    inclusive jet is returned as a "standard" jet with an
+///    associated cluster sequence (unless there were no inclusive
+///    jets, in which case a zero jet is returned, with no associated
+///    cluster sequence)
+///
+///  - if it is constructed with keep=keep_all
+///    all the inclusive jets are joined into a composite jet
+///
+/// [Note that since the structure of the resulting PseudoJet depends
+/// on its usage, this class inherits from
+/// FunctionOfPseudoJet<PseudoJet> (including a description) rather
+/// than being a full-fledged Transformer]
+///
+class Recluster : public FunctionOfPseudoJet<PseudoJet> {
+public:
+  /// the various options for the output of Recluster
+  enum Keep{
+    /// keep only the hardest inclusive jet and return a "standard" jet with
+    /// an associated ClusterSequence [this will be the default]
+    keep_only_hardest,
+    /// keep all the inclusive jets. result() will join them into a composite
+    /// jet
+    keep_all
+  };
+
+  /// default constructor (uses an undefined JetDefinition, and so cannot
+  /// be used directly).
+  Recluster() : _new_jet_def(), _acquire_recombiner(true),
+                _keep(keep_only_hardest), _cambridge_optimisation_enabled(true){}
+
+  /// Constructs a Recluster object that reclusters a jet into a new jet
+  /// using a generic JetDefinition
+  ///
+  ///  \param new_jet_def   the jet definition applied to do the reclustering
+  ///  \param acquire_recombiner
+  ///                       when true, the reclustering will guess the
+  ///                       recombiner from the input jet instead of
+  ///                       the one in new_jet_def. An error is then
+  ///                       thrown if no consistent recombiner is found
+  ///  \param keep_in       Recluster::keep_only_hardest: the result is
+  ///                       the hardest inclusive jet after reclustering,
+  ///                       returned as a "standard" jet.
+  ///                       Recluster::keep_all: the result is a
+  ///                       composite jet with the inclusive jets as pieces.
+  Recluster(const JetDefinition & new_jet_def, 
+            bool acquire_recombiner_in = false, 
+            Keep keep_in = keep_only_hardest)
+    : _new_jet_def(new_jet_def), _acquire_recombiner(acquire_recombiner_in), 
+      _keep(keep_in), _cambridge_optimisation_enabled(true) {}
+
+  /// Constructs a Recluster object that reclusters a jet into a new jet
+  /// using a JetAlgorithm and its parameters
+  ///
+  ///  \param new_jet_alg    the jet algorithm applied to obtain the new clustering
+  ///  \param new_jet_radius the jet radius
+  ///  \param keep_in        Recluster::keep_only_hardest: the result is
+  ///                        the hardest inclusive jet after reclustering,
+  ///                        returned as a "standard" jet.
+  ///                        Recluster::keep_all: the result is a
+  ///                        composite jet with the inclusive jets as pieces.
+  /// 
+  /// This ctor will always acquire the recombiner from the jet being
+  /// reclustered (it will throw if none can be found).  If you wish
+  /// to use Recluster with an algorithm that requires an extra
+  /// parameter (like the genkt algorithm), please specify the jet
+  /// definition fully using the constructor above.
+  Recluster(JetAlgorithm snew_jet_alg, double new_jet_radius, Keep keep_in = keep_only_hardest);
+
+  /// constructor with just a jet algorithm, but no jet radius. If the
+  /// algorithm requires a jet radius, JetDefinition::max_allowable_R will be used. 
+  ///
+  Recluster(JetAlgorithm new_jet_alg, Keep keep_in = keep_only_hardest);
+
+  /// default dtor
+  virtual ~Recluster(){}
+
+  //----------------------------------------------------------------------
+  // tweaking the behaviour and corresponding enquiry functions
+
+  /// set whether the reclustering should attempt to acquire a
+  /// recombiner from the input jet
+  void set_acquire_recombiner(bool acquire) {_acquire_recombiner = acquire;}
+
+  /// returns true if this reclusterer is set to acquire the
+  /// recombiner from the input jet
+  bool acquire_recombiner() const{ return _acquire_recombiner;}
+
+
+  /// sets whether to try to optimise reclustering with
+  /// Cambridge/Aachen algorithms (by not reclustering if the
+  /// requested C/A reclustering can be obtained by using subjets of
+  /// an input C/A jet or one composed of multiple C/A pieces from the
+  /// same clustering sequence). By default this is enabled, and
+  /// _should_ always be correct; disable it to test this statement!
+  void set_cambridge_optimisation(bool enabled){ _cambridge_optimisation_enabled = enabled;}
+  /// sets whether to try to optimise reclustering with Cambridge/Aachen algorithms (US spelling!)
+  void set_cambridge_optimization(bool enabled){ _cambridge_optimisation_enabled = enabled;}
+
+  /// returns true if the reclusterer tries to optimise reclustering
+  /// with Cambridge/Aachen algorithms
+  bool cambridge_optimization(){return _cambridge_optimisation_enabled;}
+  bool cambridge_optimisation(){return _cambridge_optimisation_enabled;}
+
+  /// set the behaviour with regards to keeping all resulting jets or
+  /// just the hardest.
+  void set_keep(Keep keep_in) {_keep = keep_in;}
+
+  /// returns the current "keep" mode i.e. whether only the hardest
+  /// inclusive jet is returned or all of them (see the Keep enum above)
+  Keep keep() const{ return _keep;}
+
+
+  //----------------------------------------------------------------------
+  // retrieving info about the behaviour
+
+  /// class description
+  virtual std::string description() const;
+
+
+  //----------------------------------------------------------------------
+  // core action of ths class
+
+  /// runs the reclustering and sets kept and rejected to be the jets
+  /// of interest (with non-zero rho, they will have been
+  /// subtracted). Normally this will be accessed through the base
+  /// class's operator().
+  ///
+  /// \param jet    the jet that gets reclustered
+  /// \return the reclustered jet
+  virtual PseudoJet result(const PseudoJet & jet) const;
+
+  /// A lower-level method that does the actual work of reclustering
+  /// the input jet. The resulting jets are stored in output_jets.
+  /// The jet definition that has been used can be accessed from the
+  /// output_jets' ClusterSequence.
+  ///
+  /// \param input_jet       the (input) jet that one wants to recluster
+  /// \param output_jets     inclusive jets resulting from the new clustering
+  ///
+  /// Returns true if the C/A optimisation has been used (this means
+  /// that generate_output_jet then has to watch out for non-explicit-ghost
+  /// areas that might be leftover)
+  bool get_new_jets_and_def(const PseudoJet & input_jet, 
+                            std::vector<PseudoJet> & output_jets) const;
+
+  /// given a set of inclusive jets and a jet definition used, create the
+  /// resulting PseudoJet;
+  /// 
+  /// If ca_optimisation_used then special care will be taken in
+  /// deciding whether the final jet can legitimately have an area.
+  PseudoJet generate_output_jet(std::vector<PseudoJet> & incljets,
+                                bool ca_optimisation_used) const;
+
+
+private:
+  /// set the reclustered elements in the simple case of C/A+C/A
+  void _recluster_ca(const std::vector<PseudoJet> & all_pieces,
+                     std::vector<PseudoJet> & incljets,
+                     double Rfilt) const;
+
+  /// set the reclustered elements in the generic re-clustering case
+  void _recluster_generic(const PseudoJet & jet, 
+                          std::vector<PseudoJet> & incljets,
+                          const JetDefinition & new_jet_def,
+                          bool do_areas) const;
+  
+  // a series of checks
+  //--------------------------------------------------------------------
+  /// get the pieces down to the fundamental pieces
+  bool _get_all_pieces(const PseudoJet &jet, std::vector<PseudoJet> &all_pieces) const;
+
+  /// associate the proper recombiner taken from the underlying pieces
+  /// (an error is thrown if the pieces do no share a common
+  /// recombiner)
+  void _acquire_recombiner_from_pieces(const std::vector<PseudoJet> &all_pieces, 
+                                       JetDefinition &new_jet_def) const;
+
+  /// check if one can apply the simplified trick for C/A subjets
+  bool _check_ca(const std::vector<PseudoJet> &all_pieces, 
+                 const JetDefinition &new_jet_def) const;
+
+  /// check if the jet (or all its pieces) have explicit ghosts
+  /// (assuming the jet has area support
+  ///
+  /// Note that if the jet has an associated cluster sequence that is no
+  /// longer valid, an error will be thrown
+  bool _check_explicit_ghosts(const std::vector<PseudoJet> &all_pieces) const;
+
+  JetDefinition _new_jet_def;  ///< the jet definition to use to extract the jets
+  bool _acquire_recombiner;    ///< get the recombiner from the input
+                               ///< jet rather than from _new_jet_def
+  Keep _keep;                  ///< dictates which inclusive jets are kept and
+                               ///< which are returned (see Keep above)
+
+  bool _cambridge_optimisation_enabled; ///<enable the checks to
+                                        ///< perform optimisation when
+                                        ///< C/A reclustering is asked
+
+  static LimitedWarning   _explicit_ghost_warning;
+};
+
+FASTJET_END_NAMESPACE      // defined in fastjet/internal/base.hh
+
+#endif   // __FASTJET_TOOLS_RECLUSTER_HH__
Index: external/fastjet/tools/RestFrameNSubjettinessTagger.cc
===================================================================
--- external/fastjet/tools/RestFrameNSubjettinessTagger.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/RestFrameNSubjettinessTagger.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: RestFrameNSubjettinessTagger.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include <fastjet/tools/RestFrameNSubjettinessTagger.hh>
Index: external/fastjet/tools/RestFrameNSubjettinessTagger.hh
===================================================================
--- external/fastjet/tools/RestFrameNSubjettinessTagger.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/RestFrameNSubjettinessTagger.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,8 +2,8 @@
 #define __FASTJET_RESTFRAMENSUBJETTINESS_TAGGER_HH__
 
-//STARTHEADER
-// $Id: RestFrameNSubjettinessTagger.hh 2689 2011-11-14 14:51:06Z soyez $
+//FJSTARTHEADER
+// $Id: RestFrameNSubjettinessTagger.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,5 +30,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include <fastjet/PseudoJet.hh>
Index: external/fastjet/tools/Subtractor.cc
===================================================================
--- external/fastjet/tools/Subtractor.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/Subtractor.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: Subtractor.cc 3594 2014-08-12 15:25:11Z soyez $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include "fastjet/tools/Subtractor.hh"
@@ -38,13 +40,127 @@
 
 
+//----------------------------------------------------------------------
+// ctor
 Subtractor::Subtractor(double rho) : _bge(0), _rho(rho) {
   assert(_rho>0.0);
+  set_defaults();
 }
 
+//----------------------------------------------------------------------
+void Subtractor::set_defaults(){
+  _use_rho_m = false; // likely to change in future releases!!
+  _safe_mass = false; // likely to change in future releases!!
+
+  _sel_known_vertex = Selector();
+  _sel_leading_vertex = Selector();
+}
+
+//----------------------------------------------------------------------
+// perform the subtraction of a given jet
 PseudoJet Subtractor::result(const PseudoJet & jet) const {
   if (!jet.has_area()){
     throw Error("Trying to subtract a jet without area support");
   }
-  
+
+  PseudoJet known_lv, known_pu;
+  PseudoJet unknown = jet;
+  if (_sel_known_vertex.worker()){
+    // separate the jet constituents in 3 groups:
+    //   unknown vertex
+    //   known vertex, leading vertex
+    //   known vertex, non-leading vertex (PU)
+    vector<PseudoJet> constits_unknown, constits_known;
+    _sel_known_vertex.sift(jet.constituents(), 
+			   constits_known,
+			   constits_unknown);
+    vector<PseudoJet> constits_known_lv, constits_known_pu;
+    _sel_leading_vertex.sift(constits_known,
+			     constits_known_lv,
+			     constits_known_pu);
+
+    // For the parts related to the known vertices (LV or PU), we just
+    // sum the 4-momenta. For the unknown part, we assign it the full
+    // jet area.
+    known_lv = (constits_known_lv.size()!=0) 
+      ? SelectorIdentity().sum(constits_known_lv) : 0.0*jet;
+    known_pu = (constits_known_pu.size()!=0) 
+      ? SelectorIdentity().sum(constits_known_pu) : 0.0*jet;
+    if (constits_unknown.size()==0){
+      // no need for any form of subtraction!
+      PseudoJet subtracted_jet = jet;
+      subtracted_jet.reset_momentum(known_lv);
+      return subtracted_jet;
+    }
+    unknown = jet; // that keeps all info including area
+    unknown.reset_momentum(SelectorIdentity().sum(constits_unknown));
+  } else {
+    known_lv = jet; // ensures correct rap-phi!
+    known_lv *= 0.0;
+    known_pu = known_lv;
+  }
+
+  // prepare for the subtraction and compute the 4-vector to be
+  // subtracted
+  PseudoJet subtracted_jet = jet;
+  PseudoJet to_subtract = known_pu + _amount_to_subtract(unknown);
+
+  // sanity check for the transverse momentum
+  if (to_subtract.pt2() < jet.pt2() ) { 
+    // this subtraction should retain the jet's structural
+    // information
+    subtracted_jet -= to_subtract;
+  } else { 
+    // this sets the jet's momentum while maintaining all of the jet's
+    // structural information
+    subtracted_jet.reset_momentum(known_lv);
+    return subtracted_jet;
+  }
+
+  // make sure that in the end the pt is at least the one known to
+  // come from the leading vertex
+  if (subtracted_jet.pt2() < known_lv.pt2()){
+    subtracted_jet.reset_momentum(known_lv);
+    return subtracted_jet;
+  }
+
+  // sanity check for the mass (if needed)
+  if ((_safe_mass) && (subtracted_jet.m2() < known_lv.m2())){
+    // in this case, we keep pt and phi as obtained from the
+    // subtraction above and take rap and m from the part that comes
+    // from the leading vertex (or the original jet if nothing comes
+    // from the leading vertex)
+    subtracted_jet.reset_momentum(PtYPhiM(subtracted_jet.pt(),
+					  known_lv.rap(),
+					  subtracted_jet.phi(),
+					  known_lv.m()));
+  }
+
+  return subtracted_jet;
+}
+
+//----------------------------------------------------------------------
+std::string Subtractor::description() const{
+  if (_bge != 0) {
+    string desc = "Subtractor that uses the following background estimator to determine rho: "+_bge->description();
+    if (use_rho_m()) desc += "; including the rho_m correction";
+    if (safe_mass()) desc += "; including mass safety tests";
+    if (_sel_known_vertex.worker()){
+      desc += "; using known vertex selection: "+_sel_known_vertex.description()+" and leading vertex selection: "+_sel_leading_vertex.description();
+    }
+    return desc;
+  } else if (_rho != _invalid_rho) {
+    ostringstream ostr;
+    ostr << "Subtractor that uses a fixed value of rho = " << _rho;
+    return ostr.str();
+  } else {
+    return "Uninitialised subtractor";
+  }
+}
+
+//----------------------------------------------------------------------
+// compute the 4-vector that should be subtracted from the given
+// jet
+PseudoJet Subtractor::_amount_to_subtract(const PseudoJet &jet) const{
+  // the "transverse momentum" part
   double rho;
   if (_bge != 0) {
@@ -56,31 +172,22 @@
   }
 
-  PseudoJet subtracted_jet = jet;
-  PseudoJet area4vect = jet.area_4vector();
-  // sanity check
-  if (rho*area4vect.perp() < jet.perp() ) { 
-    // this subtraction should retain the jet's structural
-    // information
-    subtracted_jet -= rho*area4vect;
-  } else { 
-    // this sets the jet's momentum to zero while
-    // maintaining all of the jet's structural information
-    subtracted_jet *= 0;
+  PseudoJet area = jet.area_4vector();
+  PseudoJet to_subtract = rho*area;
+
+  double const rho_m_warning_threshold = 1e-5;
+
+  // add an optional contribution from the unknown particles masses
+  if (_use_rho_m){
+    assert(_bge != 0); // test done in "set_use_rho_m()"
+    to_subtract += _bge->rho_m(jet) * PseudoJet(0.0, 0.0, area.pz(), area.E());
+  } else if (_bge && 
+             _bge->has_rho_m() && 
+             _bge->rho_m(jet) > rho_m_warning_threshold * rho) {
+    _unused_rho_m_warning.warn("Background estimator indicates non-zero rho_m, but use_rho_m()==false in subtractor; consider calling set_use_rho_m(true) to include the rho_m information");
   }
-  return subtracted_jet;
+
+  return to_subtract;
 }
 
-//----------------------------------------------------------------------
-std::string Subtractor::description() const{
-  if (_bge != 0) {
-    return "Subtractor that uses the following background estimator to determine rho: "+_bge->description();
-  } else if (_rho != _invalid_rho) {
-    ostringstream ostr;
-    ostr << "Subtractor that uses a fixed value of rho = " << _rho;
-    return ostr.str();
-  } else {
-    return "Uninitialised subtractor";
-  }
-}
 
 FASTJET_END_NAMESPACE
Index: external/fastjet/tools/Subtractor.hh
===================================================================
--- external/fastjet/tools/Subtractor.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/Subtractor.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: Subtractor.hh 2577 2011-09-13 15:11:38Z salam $
-//
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+//FJSTARTHEADER
+// $Id: Subtractor.hh 3584 2014-08-12 12:40:10Z soyez $
+//
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __FASTJET_TOOLS_SUBTRACTOR_HH__
@@ -61,5 +63,5 @@
   /// define a subtractor based on a BackgroundEstimator
   Subtractor(BackgroundEstimatorBase * bge) : 
-    _bge(bge), _rho(-1.0) {}
+    _bge(bge), _rho(-1.0) { set_defaults(); }
 
   /// define a subtractor that uses a fixed value of rho, the background
@@ -68,8 +70,91 @@
 
   /// default constructor
-  Subtractor() : _bge(0), _rho(_invalid_rho) {}
+  Subtractor() : _bge(0), _rho(_invalid_rho) { set_defaults(); }
 
   /// default dtor
   virtual ~Subtractor(){};
+
+  /// @name configuring the behaviour
+  //\{
+  //----------------------------------------------------------------
+
+  /// reset all parameters to default values
+  ///
+  /// Note: by default, the rho_m term is not included and the safety
+  /// test for the mass is not done. This is mostly for backwards
+  /// compatibility with FastJet 3.0 and is highly likely to change in
+  /// a future release of FastJet
+  void set_defaults();
+
+  /// when 'use_rho_m' is true, include in the subtraction the
+  /// correction from rho_m, the purely longitudinal,
+  /// particle-mass-induced component of the background density per
+  /// unit area
+  ///
+  /// Note: this will be switched off by default (for backwards
+  /// compatibility with FastJet 3.0) but is highly likely to change
+  /// in a future release of FastJet
+  void set_use_rho_m(bool use_rho_m_in = true){
+    if (_bge == 0) {
+      throw Error("Subtractor: rho_m support works only for Subtractors constructed with background estimator");
+    }
+    _use_rho_m=use_rho_m_in;
+  }
+  
+  /// returns whether or not the rho_m component is used
+  bool use_rho_m() const{ return _use_rho_m;}
+
+  /// when 'safe_mass' is true, ensure that the mass of the subtracted
+  /// 4-vector remain positive
+  ///
+  /// when true, if the subtracted mass is negative, we return a
+  /// 4-vector with 0 mass, pt and phi from the subtracted 4-vector
+  /// and the rapidity of the original, unsubtracted jet.
+  ///
+  /// Note: this will be switched off by default (for backwards
+  /// compatibility with FastJet 3.0) but is highly likely to change
+  /// in a future release of FastJet
+  void set_safe_mass(bool safe_mass_in=true){ _safe_mass=safe_mass_in;}
+
+  /// returns whether or not safety tests on the mass are included
+  bool safe_mass() const{ return _safe_mass;}
+
+  /// This is mostly intended for cherge-hadron-subtracted type of
+  /// events where we wich to use vertex information to improve the
+  /// subtraction.
+  ///
+  /// Given the following parameters:
+  ///   \param sel_known_vertex    selects the particles with a
+  ///                              known vertex origin
+  ///   \param sel_leading_vertex  amongst the particles with a
+  ///                              known vertex origin, select those
+  ///                              coming from the leading vertex
+  /// Momentum identified as coming from the leading vertex will be
+  /// kept, momentum identified as coming from a non-leading vertex
+  /// will be eliminated and a regular area-median subtraction will be
+  /// applied on the 4-vector sum of the particles with unknown vertex
+  /// origin.
+  ///
+  /// When this is set, we shall ensure that the pt of the subtracted
+  /// 4-vector is at least the pt of the particles that are known to
+  /// come from the leading vertex (if it fails, subtraction returns
+  /// the component that is known to come from the leading vertex ---
+  /// or, the original unsubtracted jet if it contains no particles
+  /// from the leading vertex).  Furthermore, when safe_mass() is on, we
+  /// also impose a similar constraint on the mass of the subtracted
+  /// 4-vector (if the test fails, the longitudinal part of the
+  /// subtracted 4-vector is taken from the component that is known to
+  /// come from the leading vertex).
+  void set_known_selectors(const Selector &sel_known_vertex,
+			   const Selector &sel_leading_vertex){
+    _sel_known_vertex   = sel_known_vertex;
+    _sel_leading_vertex = sel_leading_vertex;
+  }
+
+  //\}
+
+  /// @name description and action
+  //\{
+  //----------------------------------------------------------------
 
   /// returns a jet that's subtracted
@@ -82,5 +167,9 @@
   virtual std::string description() const;
 
+  //\}
 protected:
+  /// compute the 4-vector that should be subtracted from the given
+  /// jet
+  PseudoJet _amount_to_subtract(const PseudoJet &jet) const;
 
   /// the tool used to estimate the background
@@ -89,4 +178,14 @@
   /// the fixed value of rho to use if the user has selected that option
   double _rho;
+
+  // configuration parameters/flags
+  bool _use_rho_m;   ///< include the rho_m correction
+  bool _safe_mass;   ///< ensures that the subtracted mass is +ve
+
+  Selector _sel_known_vertex;   ///< selects the particles with a
+				///< known vertex origin
+  Selector _sel_leading_vertex; ///< amongst the particles with a
+				///< known vertex origin, select those
+				///< coming from the leading vertex
 
   /// a value of rho that is used as a default to label that the stored
@@ -98,4 +197,6 @@
   // that's not allowed in an include file.
   static const double _invalid_rho;
+
+  mutable LimitedWarning _unused_rho_m_warning;
 };
 
Index: external/fastjet/tools/TopTaggerBase.cc
===================================================================
--- external/fastjet/tools/TopTaggerBase.cc	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/TopTaggerBase.cc	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id$
+//FJSTARTHEADER
+// $Id: TopTaggerBase.cc 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include <fastjet/tools/TopTaggerBase.hh>
Index: external/fastjet/tools/TopTaggerBase.hh
===================================================================
--- external/fastjet/tools/TopTaggerBase.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/TopTaggerBase.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -2,8 +2,8 @@
 #define __FASTJET_TOP_TAGGER_BASE_HH__
 
-//STARTHEADER
-// $Id: TopTaggerBase.hh 2689 2011-11-14 14:51:06Z soyez $
+//FJSTARTHEADER
+// $Id: TopTaggerBase.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -16,7 +16,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -28,5 +30,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #include <fastjet/internal/base.hh>
Index: external/fastjet/tools/Transformer.hh
===================================================================
--- external/fastjet/tools/Transformer.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/tools/Transformer.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: Transformer.hh 2577 2011-09-13 15:11:38Z salam $
+//FJSTARTHEADER
+// $Id: Transformer.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __FASTJET_TRANSFORMER_HH__
Index: external/fastjet/version.hh
===================================================================
--- external/fastjet/version.hh	(revision be6c1c802edfcf2f0bab07b4dfe691afa5010c27)
+++ external/fastjet/version.hh	(revision 35cdc461e095e63247ab9dded070d76bc2c888e2)
@@ -1,6 +1,6 @@
-//STARTHEADER
-// $Id: version.hh 2577 2011-09-13 15:11:38Z salam $
+//FJSTARTHEADER
+// $Id: version.hh 3433 2014-07-23 08:17:03Z salam $
 //
-// Copyright (c) 2005-2011, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
+// Copyright (c) 2005-2014, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
 //
 //----------------------------------------------------------------------
@@ -13,7 +13,9 @@
 //
 //  The algorithms that underlie FastJet have required considerable
-//  development and are described in hep-ph/0512210. If you use
+//  development. They are described in the original FastJet paper,
+//  hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
 //  FastJet as part of work towards a scientific publication, please
-//  include a citation to the FastJet paper.
+//  quote the version you use and include a citation to the manual and
+//  optionally also to hep-ph/0512210.
 //
 //  FastJet is distributed in the hope that it will be useful,
@@ -25,5 +27,5 @@
 //  along with FastJet. If not, see <http://www.gnu.org/licenses/>.
 //----------------------------------------------------------------------
-//ENDHEADER
+//FJENDHEADER
 
 #ifndef __FASTJET_VERSION_HH__
