Page MenuHomeHEPForge

No OneTemporary

Index: contrib/contribs/JetsWithoutJets/trunk/example.ref
===================================================================
--- contrib/contribs/JetsWithoutJets/trunk/example.ref (revision 347)
+++ contrib/contribs/JetsWithoutJets/trunk/example.ref (revision 348)
@@ -1,175 +1,182 @@
#########
## Read an event with 354 particles
#########
## Example of basic event shape analysis
#########
Jet parameters: R_jet=1, pTcut=200
Trimming parameters: R_sub=0.2, fcut=0.05
#####
N_jet=1.99971
N_jet_trim (using built-in)=1.97156
N_jet_trim (using trimmer)=2
#####
H_T=1893.67
H_T_trim (using built-in)=1867.45
H_T_trim (using trimmer)=1867.45
#####
Missing H_T=76.1162
Missing H_T_trim (using built-in)=91.8116
Missing H_T_trim (using trimmer)=91.8116
#####
#--------------------------------------------------------------------------
-# FastJet release 3.0.2
+# FastJet release 3.0.3
# M. Cacciari, G.P. Salam and G. Soyez
# A software package for jet finding and analysis at colliders
# http://fastjet.fr
-#
-# Please cite arXiv:1111.6097 if you use this package for scientific
-# work and optionally also Phys. Lett. B641 (2006) [hep-ph/0512210].
+#
+# Please cite EPJC72(2012)1896 [arXiv:1111.6097] if you use this package
+# for scientific work and optionally PLB641(2006)57 [hep-ph/0512210].
#
# FastJet is provided without warranty under the terms of the GNU GPLv2.
# It uses T. Chan's closest pair algorithm, S. Fortune's Voronoi code
# and 3rd party plugin jet algorithms. See COPYING file for details.
#--------------------------------------------------------------------------
#########
## Example of different trimming methods
#########
Anti-kT jet parameters: R_jet=1, pTcut=200
Trimming parameters: R_sub=0.2, fcut=0.05
Untrimmed Mass = 39.9912
Tree Trimmed Mass = 22.6675
Jet Shape Trimmed Mass = 25.4948
Event Shape Trimmed Mass = 25.4948
#####
#########
## Example of variable pT analysis
#########
Jet parameters: R_jet=1, pTcut=200 (unless otherwise stated)
Trimming parameters: R_sub=0.2, fcut=0.05
#####
N_jet from full pT_cut function=1.99971
N_jet_trim from full pT_cut function=1.97156
#####
Variable pT_cut
pT_cut=10, N_jet=4.57942
pT_cut=20, N_jet=2.98989
pT_cut=50, N_jet=2.96953
pT_cut=100, N_jet=1.99971
pT_cut=150, N_jet=1.99971
#####
pT of the hardest jet=983.637
pT of the hardest trimmed jet=983.637
#####
#########
## Example of variable R analysis
#########
Jet parameters: R_jet=1 (unless otherwise stated), pTcut=200
Trimming parameters: R_sub=0.2, fcut=0.05
#####
N_jet from full R function=1.99971
N_jet_trim from full R function=1.97156
#####
Variable Rjet
R=0.2, N_jet=1.99997
R=0.4, N_jet=2.00011
R=0.6, N_jet=1.99988
R=0.8, N_jet=2.00023
R=1, N_jet=1.99971
#########
## Hardest jet axis and weights
#########
-Eta_hardest_jet=-0.868432
+Without global consistency:
+Rap_hardest_jet=-0.868431
+Phi_hardest_jet=2.90578
+pt_weight_hardest_jet=983.637
+N_jet_weight_hardest_jet=0.999981
+#
+With global consistency:
+Rap_hardest_jet=-0.868431
Phi_hardest_jet=2.90578
-pt_weight_hardest_jet=984.706
+pt_weight_hardest_jet=983.637
N_jet_weight_hardest_jet=0.999981
#########
## Examples showing more general shapes
#########
Jet parameters: R_jet=1, pTcut=200
Trimming parameters: R_sub=0.2, fcut=0.05
#####
Summed Jet Count as event shape, R_jet=1, pT_cut=200
Njet=1.99971
(Storage array works? Yes)
#
Summed Jet Count as event shape, R_jet=1, pT_cut=200, trimming with R_sub=0.2, fcut=0.05
Njet_trim=1.97156
(Storage array works? Yes)
#
Summed Jet Scalar Pt as event shape, R_jet=1, pT_cut=200
HT=1893.67
(Storage array works? Yes)
#
Summed Jet Scalar Pt as event shape, R_jet=1, pT_cut=200, trimming with R_sub=0.2, fcut=0.05
HT_trim=1867.45
(Storage array works? Yes)
#
Missing Transverse Momentum as event shape, R_jet=1, pT_cut=200
MissHT=76.1162
(Storage array works? Yes)
#
Missing Transverse Momentum as event shape, R_jet=1, pT_cut=200, trimming with R_sub=0.2, fcut=0.05
MissHT_trim=91.8116
(Storage array works? Yes)
#
Summed Jet Mass as event shape, R_jet=1, pT_cut=200
SigmaM=129.472
(Storage array works? Yes)
#
Summed Jet Mass as event shape, R_jet=1, pT_cut=200, trimming with R_sub=0.2, fcut=0.05
SigmaM_trim=125.566
(Storage array works? Yes)
#
Summed Jet Mass^2 as event shape, R_jet=1, pT_cut=200
SigmaM2=9852.27
(Storage array works? Yes)
#
Summed Jet Mass^2 as event shape, R_jet=1, pT_cut=200, trimming with R_sub=0.2, fcut=0.05
SigmaM2_trim=9114.19
(Storage array works? Yes)
#
Trimmed Subjet multiplicity with R_jet=1, pT_cut=200, R_sub=0.2, and fcut=0.05
SigmaNsub_trim=2.04888
(Storage array works? Yes)
#
Summed Jet Scalar Pt^-2 as event shape, R_jet=1, pT_cut=200
GenHT_-2=2.24003e-06
(Storage array works? Yes)
#
Summed Jet Scalar Pt^-2 as event shape, R_jet=1, pT_cut=200, trimming with R_sub=0.2, fcut=0.05
GenHT_-2_trim=2.2075e-06
(Storage array works? Yes)
#
Summed Jet Scalar Pt^-1 as event shape, R_jet=1, pT_cut=200
GenHT_-1=0.00211487
(Storage array works? Yes)
#
Summed Jet Scalar Pt^-1 as event shape, R_jet=1, pT_cut=200, trimming with R_sub=0.2, fcut=0.05
GenHT_-1_trim=0.00208462
(Storage array works? Yes)
#
Summed Jet Scalar Pt^0 as event shape, R_jet=1, pT_cut=200
GenHT_0=1.99971
(Storage array works? Yes)
#
Summed Jet Scalar Pt^0 as event shape, R_jet=1, pT_cut=200, trimming with R_sub=0.2, fcut=0.05
GenHT_0_trim=1.97156
(Storage array works? Yes)
#
Summed Jet Scalar Pt^1 as event shape, R_jet=1, pT_cut=200
GenHT_1=1893.67
(Storage array works? Yes)
#
Summed Jet Scalar Pt^1 as event shape, R_jet=1, pT_cut=200, trimming with R_sub=0.2, fcut=0.05
GenHT_1_trim=1867.45
(Storage array works? Yes)
#
Summed Jet Scalar Pt^2 as event shape, R_jet=1, pT_cut=200
GenHT_2=1.79595e+06
(Storage array works? Yes)
#
Summed Jet Scalar Pt^2 as event shape, R_jet=1, pT_cut=200, trimming with R_sub=0.2, fcut=0.05
GenHT_2_trim=1.77151e+06
(Storage array works? Yes)
#
#####
Index: contrib/contribs/JetsWithoutJets/trunk/JetsWithoutJets.hh
===================================================================
--- contrib/contribs/JetsWithoutJets/trunk/JetsWithoutJets.hh (revision 347)
+++ contrib/contribs/JetsWithoutJets/trunk/JetsWithoutJets.hh (revision 348)
@@ -1,672 +1,689 @@
// JetsWithoutJets Package
// Questions/Comments? danbert@mit.edu jthaler@mit.edu
//
// Copyright (c) 2013
// Daniele Bertolini and Jesse Thaler
//
// $Id: $
//----------------------------------------------------------------------
// 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_JETSWITHOUTJETS_HH__
#define __FASTJET_CONTRIB_JETSWITHOUTJETS_HH__
#include <fastjet/internal/base.hh>
#include "fastjet/FunctionOfPseudoJet.hh"
#include "fastjet/tools/Transformer.hh"
#include "fastjet/JetDefinition.hh"
#include "fastjet/PseudoJet.hh"
#include "fastjet/ClusterSequence.hh"
#include "fastjet/SharedPtr.hh"
#include <string>
#include <sstream>
#include <algorithm>
FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh
namespace contrib {
//////
//
// Defining a function of a vector of PseudoJets
//
//////
//----------------------------------------------------------------------
//In current version of FastJet there is no standard interface for a function that takes a vector of PseudoJets as argument.
//This class serves as a base class and it is the analog of FunctionOfPseudoJet, it only differs in taking a vector of PseudoJets as argument.
//Should a standard interface become available, this class can be removed and the classes below
//(JetMultiplicity,TransverseMomentum,MissingTransverseMomentum) should be derived from the standard base class.
template<typename TOut>
class MyFunctionOfVectorOfPseudoJets{
public:
MyFunctionOfVectorOfPseudoJets(){}
MyFunctionOfVectorOfPseudoJets(const TOut &constant_value);
virtual ~MyFunctionOfVectorOfPseudoJets(){}
virtual std::string description() const{ return "";}
virtual TOut result(const std::vector<PseudoJet> &pjs) const = 0;
TOut operator()(const std::vector<PseudoJet> &pjs) const { return result(pjs);}
};
//----------------------------------------------------------------------
// The following are example Functors to Use
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// Counts the number of jets (i.e. 1 per jet)
class FunctorJetCount : public MyFunctionOfVectorOfPseudoJets<double> {
double result(const std::vector<PseudoJet> & particles) const { return 1.0; }
std::string description() const { return "Jet Count";}
};
//----------------------------------------------------------------------
// Finds the summed pt of the jet constituents (NOT the pT of the jet)
class FunctorJetScalarPt : public MyFunctionOfVectorOfPseudoJets<double> {
double result(const std::vector<PseudoJet> & particles) const {
double myPt = 0.0;
for (unsigned int i = 0; i<particles.size(); i++) {
myPt += particles[i].pt();
}
return myPt;
}
std::string description() const { return "Jet Scalar Pt";}
};
//----------------------------------------------------------------------
// Raises FunctorJetScalarTransverseMomentum to an arbitrary Power
class FunctorJetScalarPtToN : public MyFunctionOfVectorOfPseudoJets<double> {
private:
int _n;
public:
FunctorJetScalarPtToN(int n) : _n(n) {}
double result(const std::vector<PseudoJet> & particles) const {
FunctorJetScalarPt sumPt = FunctorJetScalarPt();
return pow(sumPt(particles),_n);
}
std::string description() const {
std::stringstream myStream;
myStream << "Jet Scalar Pt^" << _n;
return myStream.str();
}
};
//----------------------------------------------------------------------
// Finds the mass of the jet
class FunctorJetMass : public MyFunctionOfVectorOfPseudoJets<double> {
double result(const std::vector<PseudoJet> & particles) const {
PseudoJet myJet(0,0,0,0);
for (unsigned int i = 0; i<particles.size(); i++) {
myJet += particles[i];
}
return myJet.m();
}
std::string description() const { return "Jet Mass";}
};
//----------------------------------------------------------------------
// Finds the squared mass of the jet
class FunctorJetMassSquared : public MyFunctionOfVectorOfPseudoJets<double> {
double result(const std::vector<PseudoJet> & particles) const {
PseudoJet myJet(0,0,0,0);
for (unsigned int i = 0; i<particles.size(); i++) {
myJet += particles[i];
}
return myJet.m2();
}
std::string description() const { return "Jet Mass^2";}
};
//////
//
// Storage Array (beta, to reduce computation time, only used in trimming at the moment)
// Currently makes strips in rapidity, but could also do the same for azimuth if further speed up is needed.
//
//////
class JWJStorageArray {
private:
double _Rjet;
double _ptcut;
std::vector<std::vector<std::vector<fastjet::PseudoJet> > > _regionStorage;
std::vector<std::vector<bool> > _aboveCutBool;
double _rapmax;
int _maxRapIndex;
double _rapSpread;
int _maxPhiIndex;
double _phiSpread;
int getRapIndex(const fastjet::PseudoJet & currentJet) const;
int getPhiIndex(const fastjet::PseudoJet & currentJet) const;
public:
JWJStorageArray() : _Rjet(0.0) {
// at the moment, this value is hard coded
_rapmax = 10.0;
}
void establishStorage(const std::vector<fastjet::PseudoJet> & my_jets, double Rjet, double ptcut);
std::vector<fastjet::PseudoJet> & getStorageFor(const fastjet::PseudoJet & currentJet);
bool aboveCutFor(const fastjet::PseudoJet & currentJet);
};
//////
//
// Extendable Jet-like Event Shapes (works on any function of PseudoJet that returns double)
//
//////
//----------------------------------------------------------------------
// Generic JetLikeEventShape which takes a Functor as an argument and then
// sums over all "jets" in an event.
// Optional trimming built in. Note that trimming first, then applying the event
// shape gives a slightly different answer.
// Only works with quantities that are doubles for each jet
// (could templatize, but easier to deal with case by case)
class JetLikeEventShape : public MyFunctionOfVectorOfPseudoJets<double> {
protected:
MyFunctionOfVectorOfPseudoJets<double> * _measurement;
double _Rjet, _ptcut, _Rsub, _fcut;
bool _trim;
mutable bool _includeParticle;
mutable double _weightParticle, _pt_in_Rjet, _pt_in_Rsub;
mutable std::vector<PseudoJet> _nearbyParticles;
void establishWeights(const PseudoJet myParticle, const std::vector<PseudoJet> & particles) const;
bool _useStorageArray;
mutable JWJStorageArray _myStorageArray;
void establishStorage(const std::vector<PseudoJet> & particles) const;
public:
JetLikeEventShape(): _measurement(NULL), _useStorageArray(true), _myStorageArray() {}
JetLikeEventShape(MyFunctionOfVectorOfPseudoJets<double> * measurement, double Rjet, double ptcut)
: _measurement(measurement), _Rjet(Rjet), _ptcut(ptcut), _Rsub(Rjet), _fcut(1.0), _trim(false), _useStorageArray(true), _myStorageArray() {}
JetLikeEventShape(MyFunctionOfVectorOfPseudoJets<double> * measurement, double Rjet, double ptcut, double Rsub, double fcut, bool useStorageArray = false)
: _measurement(measurement), _Rjet(Rjet), _ptcut(ptcut), _Rsub(Rsub), _fcut(fcut), _trim(true), _useStorageArray(true), _myStorageArray() {}
virtual ~JetLikeEventShape(){ if(_measurement) delete _measurement;}
virtual double result(const std::vector<PseudoJet> & particles) const;
void setUseStorageArray(bool useStorageArray) {_useStorageArray = useStorageArray;}
std::string jetParameterString() const {
std::stringstream stream;
stream << "R_jet=" << _Rjet << ", pT_cut=" << _ptcut;
if (_trim) stream << ", trimming with R_sub=" << _Rsub <<", fcut=" << _fcut;
return stream.str();
}
virtual std::string description() const {
return "Summed " + _measurement->description() + " as event shape, " + jetParameterString();
}
};
//////
//
// Built-In Jet-like Event Shapes
//
//////
//----------------------------------------------------------------------
// JetMultiplicity defines event shape jet counting.
class ShapeJetMultiplicity: public JetLikeEventShape {
public:
ShapeJetMultiplicity(double Rjet, double ptcut): JetLikeEventShape(new FunctorJetCount(),Rjet,ptcut) {}
ShapeJetMultiplicity(double Rjet, double ptcut, double Rsub, double fcut) : JetLikeEventShape(new FunctorJetCount(),Rjet,ptcut,Rsub,fcut) {}
virtual ~ShapeJetMultiplicity(){}
};
//----------------------------------------------------------------------
// ScalarPT defines scalar pT sum.
class ShapeScalarPt: public JetLikeEventShape {
public:
ShapeScalarPt(double Rjet, double ptcut): JetLikeEventShape(new FunctorJetScalarPt(),Rjet,ptcut) {}
ShapeScalarPt(double Rjet, double ptcut, double Rsub, double fcut) : JetLikeEventShape(new FunctorJetScalarPt(),Rjet,ptcut,Rsub,fcut) {}
virtual ~ShapeScalarPt(){}
};
//----------------------------------------------------------------------
// TransverseMomentum defines scalar pT sum.
class ShapeScalarPtToN: public JetLikeEventShape {
public:
ShapeScalarPtToN(double n, double Rjet, double ptcut): JetLikeEventShape(new FunctorJetScalarPtToN(n),Rjet,ptcut) {}
ShapeScalarPtToN(double n, double Rjet, double ptcut, double Rsub, double fcut) :
JetLikeEventShape(new FunctorJetScalarPtToN(n),Rjet,ptcut,Rsub,fcut) {}
virtual ~ShapeScalarPtToN(){}
};
//----------------------------------------------------------------------
// Sum over jet masses
class ShapeSummedMass: public JetLikeEventShape {
public:
ShapeSummedMass(double Rjet, double ptcut): JetLikeEventShape(new FunctorJetMass(),Rjet,ptcut) {}
ShapeSummedMass(double Rjet, double ptcut, double Rsub, double fcut) : JetLikeEventShape(new FunctorJetMass(),Rjet,ptcut,Rsub,fcut) {}
virtual ~ShapeSummedMass(){}
};
//----------------------------------------------------------------------
// Sum over jet mass^2
class ShapeSummedMassSquared: public JetLikeEventShape {
public:
ShapeSummedMassSquared(double Rjet, double ptcut): JetLikeEventShape(new FunctorJetMassSquared(),Rjet,ptcut) {}
ShapeSummedMassSquared(double Rjet, double ptcut, double Rsub, double fcut) : JetLikeEventShape(new FunctorJetMassSquared(),Rjet,ptcut,Rsub,fcut) {}
virtual ~ShapeSummedMassSquared(){}
};
//////
//
// More complicated Jet-like Event Shapes that need special coding
//
//////
//----------------------------------------------------------------------
// ShapeMissingPt is pT of the vector sum of jets momenta.
// Needs special coding
class ShapeMissingPt : public JetLikeEventShape {
public:
ShapeMissingPt(double Rjet, double ptcut): JetLikeEventShape(NULL,Rjet,ptcut) {}
ShapeMissingPt(double Rjet, double ptcut, double Rsub, double fcut) : JetLikeEventShape(NULL,Rjet,ptcut,Rsub,fcut) {}
virtual ~ShapeMissingPt(){}
double result(const std::vector<PseudoJet> & particles) const;
std::string description() const;
};
//----------------------------------------------------------------------
// ShapeTrimmedSubjetMultiplicity is a counter for subjets within trimmed fat jets.
class ShapeTrimmedSubjetMultiplicity: public JetLikeEventShape {
private:
double _ptsubcut; // additional subjet pT cut, if desired
public:
ShapeTrimmedSubjetMultiplicity(double Rjet, double ptcut, double Rsub, double fcut, double ptsubcut = 0.0) : JetLikeEventShape(NULL,Rjet,ptcut,Rsub,fcut), _ptsubcut(ptsubcut) {}
virtual ~ShapeTrimmedSubjetMultiplicity(){}
double result(const std::vector<PseudoJet> & particles) const;
std::string description() const;
};
//////
//
// Shape Trimming
//
//////
//----------------------------------------------------------------------
//Shape Trimming. It is implemented as a selector.
Selector SelectorShapeTrimming(double Rjet, double ptcut, double Rsub, double fcut);
//----------------------------------------------------------------------
//Jet Shape Trimming. It is implemented as a selector, and takes the jet pT as the sum of the given four-vectors
Selector SelectorJetShapeTrimming(double Rsub, double fcut);
//----------------------------------------------------------------------
//Also implement a transformer version to act on individual jets
class JetShapeTrimmer : public Transformer {
private:
double _Rsub, _fcut;
Selector _selector;
public:
JetShapeTrimmer(double Rsub, double fcut) : _Rsub(Rsub), _fcut(fcut){
_selector = SelectorJetShapeTrimming(_Rsub,_fcut);
}
virtual PseudoJet result(const PseudoJet & original) const {
return join(_selector(original.constituents()));
}
std::string jetParameterString() const {
std::stringstream stream;
stream << "R_sub=" << _Rsub <<", fcut=" << _fcut;
return stream.str();
}
virtual std::string description() const {
return "Jet shape trimmer, " + jetParameterString();
}
};
//////
//
// Variable pT_cut
//
//////
class JetLikeEventShape_VariablePtCut {
protected:
MyFunctionOfVectorOfPseudoJets<double> * _measurement;
double _Rjet, _Rsub, _fcut, _offset;
bool _trim;
void _buildStepFunction(const std::vector<PseudoJet> particles) const;
mutable std::vector<double> _ptR_values, _eventShape_values;
mutable std::vector<PseudoJet> _nearbyParticles;
mutable double _pt_in_Rjet, _pt_in_Rsub;
public:
JetLikeEventShape_VariablePtCut(): _measurement(NULL) {}
JetLikeEventShape_VariablePtCut(MyFunctionOfVectorOfPseudoJets<double> * measurement, double Rjet, double offset = 0.0):
_measurement(measurement), _Rjet(Rjet), _Rsub(Rjet), _fcut(1.0), _offset(offset), _trim(false) {}
JetLikeEventShape_VariablePtCut(MyFunctionOfVectorOfPseudoJets<double> * measurement, double Rjet, double Rsub, double fcut, double offset = 0.0):
_measurement(measurement), _Rjet(Rjet), _Rsub(Rsub), _fcut(fcut), _offset(offset), _trim(true) {}
virtual ~JetLikeEventShape_VariablePtCut() {if(_measurement) delete _measurement;}
// Initialization: input particles and build step function.
void set_input(const std::vector<PseudoJet> & particles) const {_buildStepFunction(particles);}
// Get the event shape for any value of ptcut.
virtual double eventShapeFor(const double ptcut_0) const;
// Pseudo-inverse: get ptcut for a given event shape value. If initialized it uses an offset, default offset is zero.
virtual double ptCutFor(const double eventShape_0) const;
// Get the full arrays.
virtual std::vector<double> ptCutArray() const {return _ptR_values;}
virtual std::vector<double> eventShapeArray() const {return _eventShape_values;}
std::string ParameterString() const {
std::stringstream stream;
stream << "R_jet=" << _Rjet;
if (_trim) stream << ", trimming with R_sub=" << _Rsub <<", fcut=" << _fcut;
stream << ", offset for inverse function=" << _offset;
return stream.str();
}
virtual std::string description() const {
return _measurement->description() + "as function of pT_cut, " + ParameterString();
}
};
//----------------------------------------------------------------------
// Njet with variable pT_cut
class ShapeJetMultiplicity_VariablePtCut: public JetLikeEventShape_VariablePtCut {
public:
// Default offset is 0.5
ShapeJetMultiplicity_VariablePtCut(double Rjet, double offset = 0.5):
JetLikeEventShape_VariablePtCut(new FunctorJetCount(), Rjet, offset) {};
ShapeJetMultiplicity_VariablePtCut(double Rjet, double Rsub, double fcut, double offset = 0.5):
JetLikeEventShape_VariablePtCut(new FunctorJetCount(), Rjet, Rsub, fcut, offset) {};
virtual ~ShapeJetMultiplicity_VariablePtCut(){}
};
//////
//
// Njet with variable R_jet
//
//////
class ShapeJetMultiplicity_VariableR {
protected:
double _ptcut, _Rsub, _fcut;
bool _trim;
void _buildStepFunction(const std::vector<PseudoJet> particles) const;
mutable std::vector<double> _dR_values, _eventShape_values;
mutable std::vector<PseudoJet> _nearbyParticles;
mutable double _pt_in_Rjet;
public:
ShapeJetMultiplicity_VariableR() {}
ShapeJetMultiplicity_VariableR(double ptcut): _ptcut(ptcut), _Rsub(0.0), _fcut(1.0), _trim(false) {}
ShapeJetMultiplicity_VariableR(double ptcut, double Rsub, double fcut): _ptcut(ptcut), _Rsub(Rsub), _fcut(fcut), _trim(true) {}
virtual ~ShapeJetMultiplicity_VariableR() {}
// Initialization: input particles and build step function.
void set_input(const std::vector<PseudoJet> & particles) const {_buildStepFunction(particles);}
// Get the event shape for any value of R.
virtual double eventShapeFor(const double Rjet_0) const;
// Get the full arrays.
virtual std::vector<double> RArray() const {return _dR_values;}
virtual std::vector<double> eventShapeArray() const {return _eventShape_values;}
std::string ParameterString() const {
std::stringstream stream;
stream << "pT_cut=" << _ptcut;
if (_trim) stream << ", trimming with R_sub=" << _Rsub <<", fcut=" << _fcut;
return stream.str();
}
virtual std::string description() const {
return "Jet multiplicity as function of Rjet, " + ParameterString();
}
};
//////
//
-// Jet Axes
+// Finding Jet Axes with the Event Shape Density
//
//////
//--------------------------------------------------------
//Functor to find jet axis according to a given jet definition
-class FunctorJetAxis : public MyFunctionOfVectorOfPseudoJets< std::vector<PseudoJet> > {
+class FunctorJetAxis : public MyFunctionOfVectorOfPseudoJets< PseudoJet > {
public:
FunctorJetAxis(): _jetDef(NULL) {}
- FunctorJetAxis(fastjet::JetDefinition *jetDef) : _jetDef(jetDef) {}
+ FunctorJetAxis(fastjet::JetDefinition *jetDef) : _jetDef(jetDef) {
+ _jetDef->delete_recombiner_when_unused();
+ }
~FunctorJetAxis(){ if(_jetDef) delete _jetDef;}
- std::vector<PseudoJet> result(const std::vector<PseudoJet> & particles) const {
-
- fastjet::ClusterSequence clustSeq(particles, *_jetDef);
- std::vector <fastjet::PseudoJet> myAxes = clustSeq.inclusive_jets(0.0);
-
- return(myAxes);
+ PseudoJet result(const std::vector<PseudoJet> & particles) const {
+ fastjet::ClusterSequence clustSeq(particles, *_jetDef);
+ fastjet::PseudoJet myAxis = clustSeq.exclusive_jets(1)[0]; // should cluster everything
+ return(myAxis);
}
- std::string description() const { return "Jet axes with " + _jetDef->description();}
-
+
+ std::string description() const { return "Jet axis with " + _jetDef->description();}
private:
fastjet::JetDefinition *_jetDef;
};
//--------------------------------------------------------
+// FunctorJetAxis
+
+class FunctorLightLikeVersion : public FunctionOfPseudoJet< PseudoJet > {
+
+public:
+
+ FunctorLightLikeVersion() {}
+
+ // Convert to light-like object
+ PseudoJet result(const PseudoJet & jet) const {
+ PseudoJet p;
+ p.reset_PtYPhiM(1.0, jet.rap(), jet.phi(),0.0);
+ p.set_user_index(jet.user_index()); // carry user index infomation
+ return p;
+ }
+
+ std::string description() const { return "Light-like version";}
+
+};
+
+//--------------------------------------------------------
//Winner-take-all recombiner
-class WinnerTakeAll : public fastjet::JetDefinition::Recombiner {
+class WinnerTakeAllRecombiner : public fastjet::JetDefinition::Recombiner {
public:
- WinnerTakeAll() {}
+ WinnerTakeAllRecombiner() {}
/// return a textual description of the recombination scheme implemented here
virtual std::string description() const {
return "WinnerTakeAll Recombination Scheme";
}
/// recombine pa and pb and put result into pab
virtual void recombine(const PseudoJet & pa, const PseudoJet & pb, PseudoJet & pab) const {
PseudoJet harder = pa;
PseudoJet softer = pb;
if (harder.pt() < softer.pt()) std::swap(harder,softer);
PseudoJet direction = lightLikeVersion(harder);
double newpT = harder.pt() + softer.pt();
pab = newpT * direction;
}
protected:
- // Convert to light-like object
- PseudoJet lightLikeVersion(const PseudoJet& jet) const {
- double eta = jet.eta();
- double phi = jet.phi();
- PseudoJet p(cos(phi),sin(phi),sinh(eta),cosh(eta));
- p.set_user_index(jet.user_index()); // carry user index infomation
- return p;
- }
+ FunctorLightLikeVersion lightLikeVersion;
};
//--------------------------------------------------------
//Hybrid probability density shape for jet axes position
class EventShapeDensity_JetAxes {
public:
EventShapeDensity_JetAxes(){}
- EventShapeDensity_JetAxes(double Rjet, double ptcut) : _Rjet(Rjet), _ptcut(ptcut), _applyGlobalConsistency(false) {}
+ EventShapeDensity_JetAxes(double Rjet, double ptcut, bool applyGlobalConsistency = false)
+ : _Rjet(Rjet), _ptcut(ptcut), _applyGlobalConsistency(applyGlobalConsistency), _useStorageArray(true) {}
~EventShapeDensity_JetAxes(){}
-
//Set input and find local axes
- void set_input(const std::vector<PseudoJet> & particles) const {_find_local_axes(particles);}
+ void set_input(const std::vector<PseudoJet> & particles) const {
+ _find_local_axes(particles);
+ find_axes_and_weights();
+ }
//Turn on/off global consistency requirement
void setGlobalConsistencyCheck(bool applyGlobalConsistency) {_applyGlobalConsistency = applyGlobalConsistency;}
- //Find axes and weights
+ //(re)find axes and weights
void find_axes_and_weights() const;
//Return a vector of PseudoJets sorted by pT. pT of each axis is its corresponding pT weight.
std::vector<PseudoJet> axes() const { return _distinctAxes; }
+
//Return the corresponding vector of Njet weights
std::vector<double> Njet_weights() const { return _tot_Njet_weights; }
+ void setUseStorageArray(bool useStorageArray) {_useStorageArray = useStorageArray;}
private:
double _Rjet, _ptcut;
bool _applyGlobalConsistency;
- void _find_local_axes(const std::vector<PseudoJet> particles) const;
+ void _find_local_axes(const std::vector<PseudoJet> & particles) const;
bool _isStable(const int thisAxis) const;
mutable unsigned int _N;
mutable std::vector<double> _Njet_weights, _pt_weights, _tot_Njet_weights;
mutable std::vector<int> _axes;
+
mutable std::vector<PseudoJet> _myParticles, _distinctAxes;
- // Convert to light-like object with pt=1
- PseudoJet _lightLikeVersion(const PseudoJet& jet) const {
- double eta = jet.eta();
- double phi = jet.phi();
- PseudoJet p(cos(phi),sin(phi),sinh(eta),cosh(eta));
- p.set_user_index(jet.user_index()); // carry user index infomation
- return p;
- }
+ FunctorLightLikeVersion _lightLikeVersion;
+
+ bool _useStorageArray;
+ mutable JWJStorageArray _myStorageArray;
+
};
} // namespace contrib
FASTJET_END_NAMESPACE
#endif // __FASTJET_CONTRIB_JETSWITHOUTJETS_HH__
Index: contrib/contribs/JetsWithoutJets/trunk/example.cc
===================================================================
--- contrib/contribs/JetsWithoutJets/trunk/example.cc (revision 347)
+++ contrib/contribs/JetsWithoutJets/trunk/example.cc (revision 348)
@@ -1,387 +1,390 @@
// Example showing usage of JetsWithoutJets classes.
//
// Compile it with "make example" and run it with
//
// ./example < ../data/single-event.dat
//
// Copyright (c) 2013
// Daniele Bertolini and Jesse Thaler
//
// $Id: $
//----------------------------------------------------------------------
// 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 <iomanip>
#include <iostream>
#include <sstream>
#include <ctime>
#include "fastjet/PseudoJet.hh"
#include "fastjet/ClusterSequence.hh"
#include "fastjet/JetDefinition.hh"
#include "fastjet/tools/Filter.hh"
#include "JetsWithoutJets.hh" // In external code, this should be fastjet/contrib/JetsWithoutJets.hh
using namespace std;
using namespace fastjet;
using namespace fastjet::contrib;
// forward declaration to make things clearer
void read_event(vector<PseudoJet> &event);
void analyze(const vector<PseudoJet> & input_particles);
//----------------------------------------------------------------------
int main(){
//----------------------------------------------------------
// read in input particles
vector<PseudoJet> event;
read_event(event);
cout << "#########" << endl;
cout << "## Read an event with " << event.size() << " particles" << endl;
//----------------------------------------------------------
// illustrate how this JetsWithoutJets contrib works
analyze(event);
return 0;
}
// read in input particles
void read_event(vector<PseudoJet> &event){
string line;
while (getline(cin, line)) {
istringstream linestream(line);
// take substrings to avoid problems when there are extra "pollution"
// characters (e.g. line-feed).
if (line.substr(0,4) == "#END") {return;}
if (line.substr(0,1) == "#") {continue;}
double px,py,pz,E;
linestream >> px >> py >> pz >> E;
PseudoJet particle(px,py,pz,E);
// push event onto back of full_event vector
event.push_back(particle);
}
}
// Main code
void analyze(const vector<PseudoJet> & input_particles) {
// Jet parameters.
double Rjet = 1.0;
double pTcut = 200.0;
// Subjet parameters. Need for trimming.
double Rsub = 0.2;
double fcut = 0.05;
double ptsubcut = 50.0; // additional ptsubcut for subjet multiplicity
//////////
// Basic event shape analysis.
//////////
// Selectors of the type SelectorEventTrimmer are trimmers of the event.
Selector trimmer=SelectorShapeTrimming(Rjet,pTcut,Rsub,fcut);
// Classes derived from JetLikeEventShape take as input a vector<PseudoJet>
// representing the event, and return a number.
// They have two constructors: you can specify Rjet and pTcut solely or
// in addition to those also Rsub and fcut (if you want to implement
// built-in trimming at the same time).
// N.B.: trimming an event and then calculating the event shape is NOT
// the same as calculating the trimmed event shape. See the README for
// more information.
// ShapeJetMultiplicity = jet counting
ShapeJetMultiplicity Nj(Rjet,pTcut);
ShapeJetMultiplicity Nj_trim(Rjet,pTcut,Rsub,fcut); // with trimming
// ShapeScalarPt = HT (summed jet pT)
ShapeScalarPt HT(Rjet,pTcut);
ShapeScalarPt HT_trim(Rjet,pTcut,Rsub,fcut); // with trimming
// ShapeMissingPt = missing pT
ShapeMissingPt HTmiss(Rjet,pTcut);
ShapeMissingPt HTmiss_trim(Rjet,pTcut,Rsub,fcut); // with trimming
cout << setprecision(6);
cout << "#########" << endl;
cout << "## Example of basic event shape analysis" << endl;
cout << "#########" << endl;
cout << "Jet parameters: R_jet=" << Rjet << ", pTcut=" << pTcut <<endl;
cout << "Trimming parameters: R_sub=" << Rsub << ", fcut=" << fcut <<endl;
cout << "#####" << endl;
cout << "N_jet=" << Nj(input_particles) << endl;
cout << "N_jet_trim (using built-in)=" << Nj_trim(input_particles) << endl;
cout << "N_jet_trim (using trimmer)=" << Nj(trimmer(input_particles)) << endl; // N.B.: Not exactly equivalent
cout << "#####" << endl;
cout << "H_T=" << HT(input_particles) << endl;
cout << "H_T_trim (using built-in)=" << HT_trim(input_particles) << endl;
cout << "H_T_trim (using trimmer)=" << HT(trimmer(input_particles)) << endl; // N.B.: Not exactly equivalent
cout << "#####" << endl;
cout << "Missing H_T=" << HTmiss(input_particles) << endl;
cout << "Missing H_T_trim (using built-in)=" << HTmiss_trim(input_particles) << endl;
cout << "Missing H_T_trim (using trimmer)=" << HTmiss(trimmer(input_particles)) << endl; // N.B.: Not exactly equivalent
cout << "#####" << endl;
//////////
// Testing different trimming methods
//////////
// Different trimming mechanisms
Selector eventShapeTrimmer=SelectorShapeTrimming(Rjet,pTcut,Rsub,fcut);
JetShapeTrimmer jetShapeTrimmer(Rsub,fcut);
Filter treeTrimmer(Rsub, SelectorPtFractionMin(fcut));
// Clustering with anti-kt algorithm
JetAlgorithm algorithm = antikt_algorithm;
JetDefinition jetDef = JetDefinition(algorithm,Rjet);
ClusterSequence clust_seq(input_particles,jetDef);
PseudoJet hardestJet = sorted_by_pt(clust_seq.inclusive_jets(pTcut))[0];
// Clustering after applying event shape trimming
ClusterSequence clust_seq_estrim(eventShapeTrimmer(input_particles),jetDef);
PseudoJet hardestJet_estrim = sorted_by_pt(clust_seq_estrim.inclusive_jets(pTcut))[0];
double untrimmedMass = hardestJet.m();
double treeTrimmedMass = treeTrimmer(hardestJet).m();
double jetShapeTrimmedMass = jetShapeTrimmer(hardestJet).m();
double eventShapeTrimmedMass = hardestJet_estrim.m();
cout << setprecision(6);
cout << "#########" << endl;
cout << "## Example of different trimming methods" << endl;
cout << "#########" << endl;
cout << "Anti-kT jet parameters: R_jet=" << Rjet << ", pTcut=" << pTcut <<endl;
cout << "Trimming parameters: R_sub=" << Rsub << ", fcut=" << fcut <<endl;
cout << "Untrimmed Mass = " << untrimmedMass << endl;
cout << "Tree Trimmed Mass = " << treeTrimmedMass << endl;
cout << "Jet Shape Trimmed Mass = " << jetShapeTrimmedMass << endl;
cout << "Event Shape Trimmed Mass = " << eventShapeTrimmedMass << endl;
cout << "#####" << endl;
//////////
// Variable pT analysis.
//////////
// These use classes derived from JetLikeEventShape_VariablePtCut, where
// the full pT information is kept in calculating the event shape.
// One can calculate the value of the event shape at a given pT cut, or
// one can calculate the inverse function to find the value of the pT cut
// needed to return a given value of the event shape.
ShapeJetMultiplicity_VariablePtCut Nj_allPt(Rjet);
ShapeJetMultiplicity_VariablePtCut Nj_allPt_trim(Rjet,Rsub,fcut); // with trimming
Nj_allPt.set_input(input_particles);
Nj_allPt_trim.set_input(input_particles);
cout << "#########" << endl;
cout << "## Example of variable pT analysis" << endl;
cout << "#########" << endl;
cout << "Jet parameters: R_jet=" << Rjet << ", pTcut=" << pTcut << " (unless otherwise stated)" <<endl;
cout << "Trimming parameters: R_sub=" << Rsub << ", fcut=" << fcut <<endl;
cout << "#####" << endl;
cout << "N_jet from full pT_cut function=" << Nj_allPt.eventShapeFor(pTcut) << endl;
cout << "N_jet_trim from full pT_cut function=" << Nj_allPt_trim.eventShapeFor(pTcut) << endl;
cout << "#####" << endl;
cout << "Variable pT_cut" << endl;
double pTcut_values[] = {10,20,50,100,150};
for (unsigned int i=0; i<5; i++){
cout << "pT_cut=" << pTcut_values[i] << ", N_jet=" << Nj_allPt.eventShapeFor(pTcut_values[i]) << endl;
}
cout << "#####" << endl;
cout << "pT of the hardest jet=" << Nj_allPt.ptCutFor(1) << endl;
cout << "pT of the hardest trimmed jet=" << Nj_allPt_trim.ptCutFor(1) << endl;
cout << "#####" << endl;
// Can get the full arrays too, though these are not output on the example.ref file
std::vector<double> ptval = Nj_allPt.ptCutArray();
std::vector<double> NjPtval = Nj_allPt.eventShapeArray();
//////////
// Variable R analysis.
//////////
// These use the class ShapeJetMultiplicity_VariableR (at present there is no
// general class for variable R observables because of the high computational time).
// Here, the full R information is kept.
ShapeJetMultiplicity_VariableR Nj_allR(pTcut);
ShapeJetMultiplicity_VariableR Nj_allR_trim(pTcut,Rsub,fcut); // with trimming
Nj_allR.set_input(input_particles);
Nj_allR_trim.set_input(input_particles);
cout << "#########" << endl;
cout << "## Example of variable R analysis" << endl;
cout << "#########" << endl;
cout << "Jet parameters: R_jet=" << Rjet << " (unless otherwise stated), pTcut=" << pTcut <<endl;
cout << "Trimming parameters: R_sub=" << Rsub << ", fcut=" << fcut <<endl;
cout << "#####" << endl;
cout << "N_jet from full R function=" << Nj_allR.eventShapeFor(Rjet) << endl;
cout << "N_jet_trim from full R function=" << Nj_allR_trim.eventShapeFor(Rjet) << endl;
cout << "#####" << endl;
cout << "Variable Rjet" << endl;
double Rjet_values[] = {0.2,0.4,0.6,0.8,1};
for(unsigned int i=0; i<5; i++){
cout << "R=" << Rjet_values[i] << ", N_jet=" << Nj_allR.eventShapeFor(Rjet_values[i]) << endl;
}
// Can get the full arrays too, though these are not output on the example.ref file
std::vector<double> Rval = Nj_allR.RArray();
std::vector<double> NjRval = Nj_allR.eventShapeArray();
//////////
- // Jet Axes
+ // Finding Jet Axes
//////////
- EventShapeDensity_JetAxes axes_eventShape(Rjet,0);
- axes_eventShape.set_input(input_particles);
-
- //Find axes and weights
- axes_eventShape.find_axes_and_weights();
+ EventShapeDensity_JetAxes axes_eventShape(Rjet,pTcut);
+ axes_eventShape.set_input(input_particles); //Loads particles and finds axes and weights
+
//Get jet axes (by default sorted by pt). Pt of each axis corresponds to its pt weight.
vector<PseudoJet> axes = axes_eventShape.axes();
//Get N_jet weights
vector<double> Njw = axes_eventShape.Njet_weights();
- //If you want turn on global consistency and recalculate axes and weights. Default is no.
+ //If you want turn on global consistency and recalculate axes and weights
axes_eventShape.setGlobalConsistencyCheck(true);
- axes_eventShape.find_axes_and_weights();
-
- axes = axes_eventShape.axes();
- Njw = axes_eventShape.Njet_weights();
+ axes_eventShape.find_axes_and_weights(); // uses stored information to save time; don't need to set_input again
+ vector<PseudoJet> axes_gc = axes_eventShape.axes();
+ vector<double> Njw_gc = axes_eventShape.Njet_weights();
//Output hardest jet eta/phi/pT/N_jet weight
cout << "#########" << endl;
cout << "## Hardest jet axis and weights" << endl;
cout << "#########" << endl;
- cout << "Eta_hardest_jet=" << axes[0].eta() <<endl;
+ cout << "Without global consistency:" << endl;
+ cout << "Rap_hardest_jet=" << axes[0].rap() <<endl;
cout << "Phi_hardest_jet=" << axes[0].phi() <<endl;
cout << "pt_weight_hardest_jet=" << axes[0].pt() <<endl;
cout << "N_jet_weight_hardest_jet=" << Njw[0] <<endl;
-
+ cout << "#" << endl;
+ cout << "With global consistency:" << endl;
+ cout << "Rap_hardest_jet=" << axes_gc[0].rap() <<endl;
+ cout << "Phi_hardest_jet=" << axes_gc[0].phi() <<endl;
+ cout << "pt_weight_hardest_jet=" << axes_gc[0].pt() <<endl;
+ cout << "N_jet_weight_hardest_jet=" << Njw_gc[0] <<endl;
//////////
// Showing a wide range of event shapes
//////////
// This emphasizes that the jet-like event shapes are all derived from
// MyFunctionOfVectorOfPseudoJets
vector<JetLikeEventShape*> myShapes;
vector<string > myNames;
myShapes.push_back( new ShapeJetMultiplicity(Rjet,pTcut) );
myNames.push_back( "Njet");
myShapes.push_back( new ShapeJetMultiplicity(Rjet,pTcut,Rsub,fcut) ); //with trimming
myNames.push_back( "Njet_trim");
myShapes.push_back( new ShapeScalarPt(Rjet,pTcut) );
myNames.push_back( "HT");
myShapes.push_back( new ShapeScalarPt(Rjet,pTcut,Rsub,fcut) ); //with trimming
myNames.push_back( "HT_trim");
myShapes.push_back( new ShapeMissingPt(Rjet,pTcut) );
myNames.push_back( "MissHT");
myShapes.push_back( new ShapeMissingPt(Rjet,pTcut,Rsub,fcut) ); //with trimming
myNames.push_back( "MissHT_trim");
myShapes.push_back( new ShapeSummedMass(Rjet,pTcut) );
myNames.push_back( "SigmaM");
myShapes.push_back( new ShapeSummedMass(Rjet,pTcut,Rsub,fcut) ); //with trimming
myNames.push_back( "SigmaM_trim");
myShapes.push_back( new ShapeSummedMassSquared(Rjet,pTcut) );
myNames.push_back( "SigmaM2");
myShapes.push_back( new ShapeSummedMassSquared(Rjet,pTcut,Rsub,fcut) ); //with trimming
myNames.push_back( "SigmaM2_trim");
myShapes.push_back( new ShapeTrimmedSubjetMultiplicity(Rjet,pTcut,Rsub,fcut,ptsubcut) ); //with trimming
myNames.push_back( "SigmaNsub_trim");
for (int n = -2; n <= 2; n++) {
myShapes.push_back( new ShapeScalarPtToN(n,Rjet,pTcut) );
myShapes.push_back( new ShapeScalarPtToN(n,Rjet,pTcut,Rsub,fcut) ); //with trimming
stringstream myStream;
myStream << "GenHT_" << n;
myNames.push_back( myStream.str());
myNames.push_back( myStream.str() + "_trim");
}
// outputing the variables
cout << "#########" << endl;
cout << "## Examples showing more general shapes" << endl;
cout << "#########" << endl;
cout << "Jet parameters: R_jet=" << Rjet << ", pTcut=" << pTcut << endl;
cout << "Trimming parameters: R_sub=" << Rsub << ", fcut=" << fcut << endl;
cout << "#####" << endl;
for (unsigned int i = 0; i < myShapes.size(); i++) {
cout << myShapes.at(i)->description() << endl; // ideally each even shape should have a description
myShapes.at(i)->setUseStorageArray(false);
double valueNoStorage = myShapes.at(i)->result(input_particles);
myShapes.at(i)->setUseStorageArray(true);
double valueYesStorage = myShapes.at(i)->result(input_particles);
cout << myNames.at(i) << "="
<< valueNoStorage << endl;
cout << "(Storage array works? " << (valueNoStorage == valueYesStorage ? "Yes" : "No!!") << ")" << endl;
cout << "#" << endl;
delete myShapes.at(i);
}
cout << "#####" << endl;
// timing tests for the developers
double do_timing_test = false;
if (do_timing_test) {
clock_t clock_begin, clock_end;
double num_iter;
cout << setprecision(6);
num_iter = 1000;
clock_begin = clock();
ShapeScalarPt NjetA(Rjet,pTcut);
cout << "timing " << NjetA.description() << endl;
for (int t = 0; t < num_iter; t++) {
NjetA(input_particles);
}
clock_end = clock();
cout << "Method A: " << (clock_end-clock_begin)/double(CLOCKS_PER_SEC*num_iter)*1000 << " ms per Njet"<< endl;
num_iter = 1000;
clock_begin = clock();
JetLikeEventShape NjetB(new FunctorJetScalarPt(),Rjet,pTcut);
NjetB.setUseStorageArray(false);
cout << "timing " << NjetB.description() << endl;
for (int t = 0; t < num_iter; t++) {
NjetB(input_particles);
}
clock_end = clock();
cout << "Method B: " << (clock_end-clock_begin)/double(CLOCKS_PER_SEC*num_iter)*1000 << " ms per Njet"<< endl;
}
}
Index: contrib/contribs/JetsWithoutJets/trunk/JetsWithoutJets.cc
===================================================================
--- contrib/contribs/JetsWithoutJets/trunk/JetsWithoutJets.cc (revision 347)
+++ contrib/contribs/JetsWithoutJets/trunk/JetsWithoutJets.cc (revision 348)
@@ -1,788 +1,803 @@
// JetsWithoutJets Package
// Questions/Comments? danbert@mit.edu jthaler@mit.edu
//
// Copyright (c) 2013
// Daniele Bertolini and Jesse Thaler
//
// $Id: $
//----------------------------------------------------------------------
// 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 "JetsWithoutJets.hh"
#include <sstream>
using namespace std;
FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh
namespace contrib {
//////
//
// Storage Array (beta, to reduce computation time, only used in trimming at the moment)
// Currently makes strips in rapidity, but could also do the same for azimuth if further speed up is needed.
//
//////
void JWJStorageArray::establishStorage(const vector<fastjet::PseudoJet> & my_jets, double Rjet, double ptcut) {
// set radius and ptcut
_Rjet = Rjet;
_ptcut = ptcut;
FunctorJetScalarPt sumPt = FunctorJetScalarPt();
// Dividing up Phase Space (need to be synced with getRapIndex/getPhiIndex)
// Make sure that there are equal spacing of regions
_maxRapIndex = (int) floor((_rapmax)/_Rjet);// 2 rapmax / 2 Rjet
_rapSpread = 2.0*_rapmax/(floor((_rapmax)/_Rjet));
_maxPhiIndex = (int) floor((M_PI)/_Rjet); // 2 pi / 2 Rjet
_phiSpread = 2.0*M_PI/(floor((M_PI)/_Rjet));
// Initializing storage
_regionStorage.resize(_maxRapIndex);
_aboveCutBool.resize(_maxRapIndex);
for (int rapIndex = 0 ; rapIndex < _maxRapIndex ; rapIndex++) {
_regionStorage[rapIndex].resize(_maxPhiIndex);
_aboveCutBool[rapIndex].resize(_maxPhiIndex);
for (int phiIndex = 0; phiIndex < _maxPhiIndex; phiIndex++) {
_regionStorage[rapIndex][phiIndex].clear();
}
}
// looping through particles and assigning to bins of size 2R by 2R (approximately)
for (unsigned int i = 0; i < my_jets.size(); i++) {
PseudoJet currentJet = my_jets[i];
double rap = currentJet.rap();
double phi = currentJet.phi();
int lowRap = (int) floor((rap + _rapmax)/_rapSpread);
int highRap = (int) ceil((rap + _rapmax)/_rapSpread);
int lowPhi = (int) floor(phi/_phiSpread);
int highPhi = (int) ceil(phi/_phiSpread);
if (highPhi >= _maxPhiIndex) highPhi = highPhi - _maxPhiIndex; // loop around
if (lowRap < 0) lowRap = 0;
if (lowRap >= _maxRapIndex) lowRap = _maxRapIndex-1;
if (highRap < 0) highRap = 0;
if (highRap >= _maxRapIndex) highRap = _maxRapIndex-1;
// Fill in storage. For particles at periphery in rapidity, only fill two bins instead of four. If phi overlaps, do the same thing.
_regionStorage[lowRap][lowPhi].push_back(currentJet);
if (lowPhi != highPhi) _regionStorage[lowRap][highPhi].push_back(currentJet);
if (lowRap != highRap) _regionStorage[highRap][lowPhi].push_back(currentJet);
if (lowRap != highRap && lowPhi != highPhi) _regionStorage[highRap][highPhi].push_back(currentJet);
}
// store whether above ptCut values
for (int rapIndex = 0; rapIndex < _maxRapIndex; rapIndex++) {
for (int phiIndex = 0; phiIndex < _maxPhiIndex; phiIndex++) {
_aboveCutBool[rapIndex][phiIndex] = (sumPt(_regionStorage[rapIndex][phiIndex]) >= ptcut);
}
}
}
int JWJStorageArray::getRapIndex(const fastjet::PseudoJet & currentJet) const {
double rap = currentJet.rap();
int rapIndex = round((rap + _rapmax)/_rapSpread);
if (rapIndex < 0) rapIndex = 0;
if (rapIndex >= _maxRapIndex) rapIndex = _maxRapIndex - 1;
return rapIndex;
}
int JWJStorageArray::getPhiIndex(const fastjet::PseudoJet & currentJet) const {
double phi = currentJet.phi();
int phiIndex = round(phi/_phiSpread);
if (phiIndex >= _maxPhiIndex) phiIndex = phiIndex - _maxPhiIndex;
return phiIndex;
}
vector<fastjet::PseudoJet> & JWJStorageArray::getStorageFor(const fastjet::PseudoJet & currentJet) {
return _regionStorage[getRapIndex(currentJet)][getPhiIndex(currentJet)];
}
bool JWJStorageArray::aboveCutFor(const fastjet::PseudoJet & currentJet) {
return _aboveCutBool[getRapIndex(currentJet)][getPhiIndex(currentJet)];
}
//////
//
// Extendable Jet-like Event Shape
//
//////
// If called, this helper function establishes the storage array for speed up
void JetLikeEventShape::establishStorage(const std::vector<PseudoJet> & particles) const {
if (_useStorageArray) {
_myStorageArray.establishStorage(particles,_Rjet, _ptcut);
} else {
// do nothing
}
}
// This helper function calculates the weights assigned to each particle.
// In most cases, the user does not need to access the information set by this function
void JetLikeEventShape::establishWeights(const PseudoJet myParticle, const std::vector<PseudoJet> & particles) const {
FunctorJetScalarPt sumPt = FunctorJetScalarPt();
_includeParticle = false;
_weightParticle = 0.0;
_pt_in_Rjet = 0.0;
_pt_in_Rsub = 0.0;
// Find particles in my _Rjet neighborhood
fastjet::Selector sel = fastjet::SelectorCircle(_Rjet);
sel.set_reference(myParticle);
- if (_useStorageArray) { // start from rapidity strips
+ if (_useStorageArray) { // start from rapidity/phi blocks
if (!_myStorageArray.aboveCutFor(myParticle)) {
return; //don't do any further analysis if not above jet pTcut
} else {
_nearbyParticles = sel(_myStorageArray.getStorageFor(myParticle));
}
} else { // use all particles
_nearbyParticles = sel(particles);
}
// See if there is enough pt in the neighborhood to pass _ptcut
_pt_in_Rjet = sumPt(_nearbyParticles);
if (_pt_in_Rjet < _ptcut) return;
// If trimming is on, do check of _fcut as well
if (_trim) {
assert(_Rsub <= _Rjet);
fastjet::Selector sel_sub = fastjet::SelectorCircle(_Rsub);
sel_sub.set_reference(myParticle);
std::vector<fastjet::PseudoJet> near_particles_sub = sel_sub(_nearbyParticles); // Save time and only look at near particles
_pt_in_Rsub = sumPt(near_particles_sub);
if (_pt_in_Rsub/_pt_in_Rjet < _fcut) return;
}
// If enough pt, find weight and apply measurement
_includeParticle = true;
_weightParticle = myParticle.pt()/_pt_in_Rjet;
}
// For a generic event shape, the result is obtained by simply multiplying the weight
// of a given particle by the _measurement acting on the _nearbyParticles
double JetLikeEventShape::result(const std::vector<PseudoJet> & particles) const {
double answer = 0.0;
establishStorage(particles);
for (unsigned int i = 0; i < particles.size(); i++) {
establishWeights(particles[i],particles);
if (_includeParticle) {
double measurement = _measurement->result(_nearbyParticles);
answer += measurement*_weightParticle;
}
}
return(answer);
}
//////
//
// MissingTransverseMomentum
//
//////
// To calculate missing pT, we cannot use a standard _measurement, so we code this by hand.
double ShapeMissingPt::result(const std::vector<PseudoJet> & particles) const {
PseudoJet p_tot(0,0,0,0);
establishStorage(particles);
for (unsigned int i = 0; i < particles.size(); i++) {
establishWeights(particles[i],particles);
if (_includeParticle) {
p_tot += particles[i];
}
}
return(p_tot.pt());
}
string ShapeMissingPt::description() const {
return "Missing Transverse Momentum as event shape, " + jetParameterString();
}
//////
//
// TrimmedSubjetMultiplicity
//
//////
// While it would be possible to calculate trimmed subjet multiplicity using a
// _measurement functor, it is computationally more efficient to use the information
// already captured by establishWeights().
double ShapeTrimmedSubjetMultiplicity::result(const vector<PseudoJet> & particles) const {
double answer = 0.0;
establishStorage(particles);
for (unsigned int i = 0; i < particles.size(); i++) {
establishWeights(particles[i],particles);
if (_includeParticle && _pt_in_Rsub > _ptsubcut) {
answer += particles[i].pt()/_pt_in_Rsub;
}
}
return(answer);
}
string ShapeTrimmedSubjetMultiplicity::description() const {
ostringstream oss;
oss << "Trimmed Subjet multiplicity with R_jet=" << _Rjet << ", pT_cut=" << _ptcut << ", R_sub=" << _Rsub << ", and fcut=" << _fcut;
return oss.str();
}
//////
//
// Shape Trimming
//
//////
//----------------------------------------------------------------------
// Helper for SelectorShapeTrimming.
// Class derived from SelectorWorker: pass, terminator, applies_jet_by_jet, and description are overloaded.
// It can't be applied to an individual jet since it requires information about the neighbourhood of the jet.
class SW_ShapeTrimming: public SelectorWorker {
private:
double _Rjet, _ptcut, _Rsub, _fcut;
bool _useTempStorage;
public:
SW_ShapeTrimming(double Rjet, double ptcut, double Rsub, double fcut, bool useTempStorage = true) : _Rjet(Rjet), _ptcut(ptcut), _Rsub(Rsub), _fcut(fcut), _useTempStorage(useTempStorage) {};
virtual bool pass(const PseudoJet &) const {
if (!applies_jet_by_jet())
throw Error("Cannot apply this selector worker to an individual jet");
return false;
}
virtual void terminator(vector<const PseudoJet *> & jets) const {
// Copy pointers content to a vector of PseudoJets. Check if the pointer has been already nullified.
vector<PseudoJet> my_jets;
vector<unsigned int> indices;
for (unsigned int i=0; i < jets.size(); i++){
if (jets[i]){
indices.push_back(i);
my_jets.push_back(*jets[i]);
}
}
FunctorJetScalarPt sumPt = FunctorJetScalarPt();
JWJStorageArray myStorageArray = JWJStorageArray();
-
- // to increase speed in very high multiplicity events, make a grid of rapidity strips
+ // to increase speed in very high multiplicity events, make a grid of rapidity/phi blocks
if (_useTempStorage) {
myStorageArray.establishStorage(my_jets,_Rjet,_ptcut);
}
for (unsigned int i=0; i < my_jets.size(); i++){
// Select particles in radius _Rjet
fastjet::Selector sel = fastjet::SelectorCircle(_Rjet);
sel.set_reference(my_jets[i]);
vector<PseudoJet> near_particles;
- if (_useTempStorage) { // start from rapidity strips
+ if (_useTempStorage) { // start from rapidity/phi blocks
if (!myStorageArray.aboveCutFor(my_jets[i])) {
jets[indices[i]] = NULL;
continue; // no need to consider that particle further
} else {
near_particles = sel(myStorageArray.getStorageFor(my_jets[i]));
}
} else { // use all particles
near_particles = sel(my_jets);
}
// Calculate enclosed pT
double pt_Rjet = sumPt(near_particles);
// Check if pT is enough
// Need to have < instead of <= in order to have consistent description with shape variables
if (pt_Rjet < _ptcut) {
jets[indices[i]] = NULL;
continue;
}
// If so, select particles in radius
fastjet::Selector sel_sub = fastjet::SelectorCircle(_Rsub);
sel_sub.set_reference(my_jets[i]);
vector<PseudoJet> near_particles_sub = sel_sub(near_particles);
// Calculate enclosed pT
double pt_Rsub = sumPt(near_particles_sub);
// Need to have < instead of <= in order to have consistent description with shape variables
if (pt_Rsub/pt_Rjet < _fcut) {
jets[indices[i]] = NULL;
continue;
}
}
}
virtual bool applies_jet_by_jet() const {return false;}
std::string jetParameterString() const {
std::stringstream stream;
stream << "R_jet=" << _Rjet << ", pT_cut=" << _ptcut << ", R_sub=" << _Rsub <<", fcut=" << _fcut;
return stream.str();
}
virtual string description() const {
return "Shape trimmer, " + jetParameterString();
}
};
//----------------------------------------------------------------------
// Helper for SelectorJetShapeTrimming.
// Class derived from SelectorWorker: pass, terminator, applies_jet_by_jet, and description are overloaded.
// This cannot be applied to an individual jet.
class SW_JetShapeTrimming: public SelectorWorker {
private:
double _Rsub, _fcut;
public:
SW_JetShapeTrimming(double Rsub, double fcut) : _Rsub(Rsub), _fcut(fcut) {};
virtual bool pass(const PseudoJet &) const {
if (!applies_jet_by_jet())
throw Error("Cannot apply this selector worker to an individual jet");
return false;
}
virtual void terminator(vector<const PseudoJet *> & jets) const {
// Copy pointers content to a vector of PseudoJets. Check if the pointer has been already nullified.
vector<PseudoJet> my_jets;
vector<unsigned int> indices;
for (unsigned int i=0; i < jets.size(); i++){
if (jets[i]){
indices.push_back(i);
my_jets.push_back(*jets[i]);
}
}
FunctorJetScalarPt sumPt = FunctorJetScalarPt();
// take sum pt of given jet
double pt_Rjet = sumPt(my_jets);
for (unsigned int i=0; i < my_jets.size(); i++){
// Select particles in sub radius
fastjet::Selector sel_sub = fastjet::SelectorCircle(_Rsub);
sel_sub.set_reference(my_jets[i]);
vector<PseudoJet> near_particles_sub = sel_sub(my_jets);
// Calculate enclosed pT
double pt_Rsub = sumPt(near_particles_sub);
// Need to have < instead of <= in order to have consistent description with shape variables
if (pt_Rsub/pt_Rjet < _fcut) {
jets[indices[i]] = NULL;
continue;
}
}
}
virtual bool applies_jet_by_jet() const {return false;}
std::string jetParameterString() const {
std::stringstream stream;
stream << "R_sub=" << _Rsub <<", fcut=" << _fcut;
return stream.str();
}
virtual string description() const {
return "Jet shape trimmer, " + jetParameterString();
}
};
Selector SelectorShapeTrimming(double Rjet, double ptcut, double Rsub, double fcut){
return Selector(new SW_ShapeTrimming(Rjet,ptcut,Rsub,fcut));
}
Selector SelectorJetShapeTrimming(double Rsub, double fcut){
return Selector(new SW_JetShapeTrimming(Rsub,fcut));
}
//////
//
// Variable pT_cut
//
//////
-
// helper to sort a vector of vector<double> by comparing just the first entry.
bool _mySortFunction (std::vector<double> v_0, std::vector<double> v_1) { return (v_0[0] > v_1[0]); }
// As described in the appendix of the physics paper, one can construct the inverse
// of an event shape with respect to pT by calculating all of the possible pTi,R values and sorting them.
// This helper function accomplishes that task.
void JetLikeEventShape_VariablePtCut::_buildStepFunction(const std::vector<PseudoJet> particles) const {
FunctorJetScalarPt sumPt = FunctorJetScalarPt();
fastjet::Selector sel = fastjet::SelectorCircle(_Rjet);
_pt_in_Rjet = 0.0;
_pt_in_Rsub = 0.0;
std::vector< std::vector<double> > myValues;
myValues.resize(0);
// this acts much like establishWeights did for JetLikeEventShape,
// except each value of _pt_in_Rjet is associated with the corresponding
// weighted measurement.
for (unsigned int i = 0; i < particles.size(); i++){
sel.set_reference(particles[i]);
_nearbyParticles = sel(particles);
_pt_in_Rjet = sumPt(_nearbyParticles);
if(_trim) {
assert(_Rsub <= _Rjet);
fastjet::Selector sel_sub = fastjet::SelectorCircle(_Rsub);
sel_sub.set_reference(particles[i]);
std::vector<PseudoJet> near_particles_sub = sel_sub(_nearbyParticles);
_pt_in_Rsub = sumPt(near_particles_sub);
if (_pt_in_Rsub / _pt_in_Rjet >= _fcut) {
double measurement = _measurement->result(_nearbyParticles);
std::vector<double> point(2);
point[0] = _pt_in_Rjet;
point[1] = measurement*particles[i].pt()/_pt_in_Rjet;
myValues.push_back(point);
}
}
else {
double measurement = _measurement->result(_nearbyParticles);
std::vector<double> point(2);
point[0] = _pt_in_Rjet;
point[1] = measurement*particles[i].pt()/_pt_in_Rjet;
myValues.push_back(point);
}
}
std::sort (myValues.begin(), myValues.end(), _mySortFunction);
// Calculating the cumulative sum of the measurements up to a given pt value
_ptR_values.resize(0);
_eventShape_values.resize(0);
if (!myValues.empty()){
_ptR_values.push_back(myValues[0][0]);
_eventShape_values.push_back(myValues[0][1]);
for (unsigned int i = 1; i < myValues.size(); i++){
_ptR_values.push_back(myValues[i][0]);
_eventShape_values.push_back(_eventShape_values[i-1] + myValues[i][1]);
}
}
myValues.clear();
}
double JetLikeEventShape_VariablePtCut::eventShapeFor(const double ptcut_0) const {
// TODO: find a more efficient data structure to do this searching
double eventShape = 0.0;
if ( ptcut_0 <= _ptR_values.back() ) eventShape = _eventShape_values.back();
else if (ptcut_0 > _ptR_values.back() && ptcut_0 <= _ptR_values.front()) {
for (unsigned int i = 0; i < _ptR_values.size()-1; i++){
if (ptcut_0 <= _ptR_values[i] && ptcut_0 > _ptR_values[i+1]){
eventShape = _eventShape_values[i];
break;
}
}
}
return (eventShape);
}
double JetLikeEventShape_VariablePtCut::ptCutFor(const double eventShape_0) const {
// TODO: find a more efficient data structure to do this searching
double ptcut = 0.0;
double new_eventShape_0 = eventShape_0 - _offset;
if ( new_eventShape_0 < 0 || new_eventShape_0 > _eventShape_values.back() ) {
cout << ">>> ERROR: "<< _measurement->description() <<" min allowed value is 0, max allowed value is " << _eventShape_values.back() << endl;
} else if ( new_eventShape_0 <= _eventShape_values.front() ) ptcut = _ptR_values.front();
else {
for (unsigned int i = 0; i < _eventShape_values.size()-1; i++){
if (new_eventShape_0 > _eventShape_values[i] && new_eventShape_0 <= _eventShape_values[i+1]){
ptcut = _ptR_values[i+1];
break;
}
}
}
return(ptcut);
}
//////
//
// Njet with variable R_jet
//
//////
// Similar to the same named function in JetLikeEventShape_VariablePtCut, except now we have
// to store a lot more information.
void ShapeJetMultiplicity_VariableR::_buildStepFunction(const std::vector<PseudoJet> particles) const {
unsigned int N = particles.size();
FunctorJetScalarPt sumPt = FunctorJetScalarPt();
std::vector< std::vector<double> > myValues;
myValues.resize(0);
for(unsigned int i = 0; i < N; i++) {
unsigned int j = i+1;
while(j < N) {
vector<double> myPair(3);
myPair[0] = particles[i].delta_R(particles[j]);
myPair[1] = i;
myPair[2] = j;
myValues.push_back(myPair);
j++;
}
}
std::sort (myValues.begin(), myValues.end(), _mySortFunction);
_eventShape_values.resize(0);
_dR_values.resize(0);
// Initialize
double _tot_pt = sumPt(particles);
if(_tot_pt >= _ptcut) _eventShape_values.push_back(1.0);
else _eventShape_values.push_back(0.0);
std::vector<double> pTR(N);
std::fill(pTR.begin(), pTR.end(), _tot_pt);
if (_trim) {
std::vector<double> pTRsub;
fastjet::Selector sel_sub = fastjet::SelectorCircle(_Rsub);
for (unsigned int i = 0; i < N; i++) {
sel_sub.set_reference(particles[i]);
std::vector<PseudoJet> near_particles_sub = sel_sub(particles);
pTRsub.push_back(sumPt(near_particles_sub));
}
for (unsigned int i = 0; i < myValues.size(); i++) {
_dR_values.push_back(myValues[i][0]);
int id1 = (int)myValues[i][1];
int id2 = (int)myValues[i][2];
pTR[id1] -= particles[id2].pt();
pTR[id2] -= particles[id1].pt();
double myEventShape = 0;
for(unsigned int j = 0; j < N; j++) {
if(pTR[j] >= _ptcut && pTRsub[j] / pTR[j] >= _fcut) myEventShape += particles[j].pt() / pTR[j];
}
_eventShape_values.push_back(myEventShape);
}
}
else {
for (unsigned int i = 0; i < myValues.size(); i++) {
_dR_values.push_back(myValues[i][0]);
int id1 = (int)myValues[i][1];
int id2 = (int)myValues[i][2];
pTR[id1] -= particles[id2].pt();
pTR[id2] -= particles[id1].pt();
double myEventShape = 0;
for(unsigned int j = 0; j < N; j++) {
if(pTR[j] >= _ptcut) myEventShape += particles[j].pt() / pTR[j];
}
_eventShape_values.push_back(myEventShape);
}
}
_dR_values.push_back(0.0);
myValues.clear();
}
double ShapeJetMultiplicity_VariableR::eventShapeFor(const double Rjet_0) const {
double eventShape = 0.0;
if( Rjet_0 < _Rsub ) cout <<">>> WARNING: R_jet < R_sub= " << _Rsub << endl;
if( Rjet_0 >= _dR_values.front() ) eventShape = _eventShape_values.front();
else if ( Rjet_0 < _dR_values.front() && Rjet_0 >= _dR_values.back() ){
for(unsigned int i = 0; i < _dR_values.size()-1; i++) {
if( Rjet_0 < _dR_values[i] && Rjet_0 >= _dR_values[i+1]) {
eventShape = _eventShape_values[i+1];
break;
}
}
}
else cout <<">>> ERROR: R_jet should be >= 0" << endl;
return(eventShape);
}
//////
//
-// Jet Axes
+// Finding Jet Axes with the Event Shape Density
//
//////
-void EventShapeDensity_JetAxes::_find_local_axes(const std::vector<PseudoJet> particles) const {
-
+void EventShapeDensity_JetAxes::_find_local_axes(const std::vector<PseudoJet> & particles) const {
+
_myParticles = particles;
_N = particles.size();
_axes.resize(0);
_Njet_weights.resize(0);
_pt_weights.resize(0);
+
+ // Indexing particles (note that this is happening internally, so shouldn't modify user input)
+ for (unsigned int i=0; i<_N; i++) _myParticles[i].set_user_index(i);
- //Indexing particles.
- for(unsigned int i=0; i<_N; i++) _myParticles[i].set_user_index(i);
-
- //Find axis associated with each particle.
- for(unsigned int i=0; i<_N; i++) {
+ // For speed up/
+ if (_useStorageArray) {
+ _myStorageArray.establishStorage(_myParticles,_Rjet, _ptcut);
+ }
+
+ // Find axis associated with each particle.
+ for (unsigned int i=0; i<_N; i++) {
+
+ PseudoJet myParticle = _myParticles[i];
+ FunctorJetScalarPt sumPt = FunctorJetScalarPt();
+
+ //Recombiner has to carry user_index information.
+ FunctorJetAxis axis(new fastjet::JetDefinition(fastjet::cambridge_algorithm, 2.0*_Rjet, new WinnerTakeAllRecombiner(), fastjet::Best));
- FunctorJetScalarPt sumPt = FunctorJetScalarPt();
- //Recombiner has to carry user_index information.
- FunctorJetAxis axis(new fastjet::JetDefinition(fastjet::cambridge_algorithm, 2*_Rjet, new WinnerTakeAll(), fastjet::Best));
-
- fastjet::Selector sel = SelectorCircle(_Rjet);
- sel.set_reference(_myParticles[i]);
- vector<PseudoJet> nearbyParticles = sel(_myParticles);
-
- int myAxis = -1;
- double pt_w = 0;
- double Njet_w = 0;
-
- double pt_in_Rjet = sumPt(nearbyParticles);
- if(pt_in_Rjet >= _ptcut) {
- myAxis = axis(nearbyParticles)[0].user_index();
- pt_w = _myParticles[i].pt();
- Njet_w = pt_w / pt_in_Rjet;
- }
-
- _axes.push_back(myAxis);
- _pt_weights.push_back(pt_w);
- _Njet_weights.push_back(Njet_w);
+ fastjet::Selector sel = SelectorCircle(_Rjet);
+ sel.set_reference(myParticle);
+ vector<PseudoJet> nearbyParticles;
+ if (_useStorageArray) { // start from phi/rapidity strips
+ if (!_myStorageArray.aboveCutFor(myParticle)) {
+ nearbyParticles.resize(0); //don't do any further analysis if not above jet pTcut
+ } else {
+ nearbyParticles = sel(_myStorageArray.getStorageFor(myParticle));
+ }
+ } else { // use all particles
+ nearbyParticles = sel(_myParticles);
+ }
+
+ int myAxis = -1;
+ double pt_w = 0;
+ double Njet_w = 0;
+
+ double pt_in_Rjet = sumPt(nearbyParticles);
+ if(pt_in_Rjet >= _ptcut) {
+ myAxis = axis(nearbyParticles).user_index();
+ pt_w = _myParticles[i].pt();
+ Njet_w = pt_w / pt_in_Rjet;
+ }
+
+ _axes.push_back(myAxis);
+ _pt_weights.push_back(pt_w);
+ _Njet_weights.push_back(Njet_w);
+
}
}
-
+
void EventShapeDensity_JetAxes::find_axes_and_weights() const {
//If requested establish global consistency.
- if(_applyGlobalConsistency) {
+ if (_applyGlobalConsistency) {
for(unsigned int i=0; i < _N; i++) {
- while(_axes[i]!= -1 && !_isStable(_axes[i])) _axes[i] = _axes[_axes[i]];
+ while(_axes[i]!= -1 && !_isStable(_axes[i])) _axes[i] = _axes[_axes[i]];
}
}
//Find distinct axes.
//Output a vector of Pseudojets (sorted by pT), with pT of each axis corresponding to the pT weight.
vector<double> tot_Njet_weights(_N,0), tot_pt_weights(_N,0);
- for(unsigned int i=0; i<_N; i++) {
- if(_axes[i] != -1) {
- tot_pt_weights[_axes[i]] += _pt_weights[i];
- tot_Njet_weights[_axes[i]] += _Njet_weights[i];
- }
+ for (unsigned int i=0; i<_N; i++) {
+ if (_axes[i] != -1) {
+ tot_pt_weights[_axes[i]] += _pt_weights[i];
+ tot_Njet_weights[_axes[i]] += _Njet_weights[i];
+ }
}
- for(unsigned int i=0; i<_N; i++){
- if(tot_pt_weights[i] > 0) {
- PseudoJet myAxis = _lightLikeVersion(_myParticles[i]) * tot_pt_weights[i];
- _distinctAxes.push_back(myAxis);
- }
+ for (unsigned int i=0; i<_N; i++){
+ if(tot_pt_weights[i] > 0) {
+ PseudoJet myAxis = _lightLikeVersion(_myParticles[i]) * tot_pt_weights[i];
+ _distinctAxes.push_back(myAxis);
+ }
}
_distinctAxes = sorted_by_pt(_distinctAxes);
//Find the corresponding N_jet weights.
for(unsigned int i=0; i<_distinctAxes.size(); i++) _tot_Njet_weights.push_back(tot_Njet_weights[_distinctAxes[i].user_index()]);
}
bool EventShapeDensity_JetAxes::_isStable(const int thisAxis) const {
bool answer = false;
if(_axes[thisAxis] == thisAxis) answer = true;
return(answer);
}
} // namespace contrib
FASTJET_END_NAMESPACE

File Metadata

Mime Type
text/x-diff
Expires
Wed, May 14, 11:38 AM (10 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5111473
Default Alt Text
(74 KB)

Event Timeline