// Example showing advanced usage of JetsWithoutJets classes.
// Please see example_basic_usage for usage of basic classes first.
//
// Compile it with "make example_advanced_usage" and run it with
//
// ./example_advanced_usage < ../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 .
//----------------------------------------------------------------------
#include
#include
#include
#include
#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::jwj;
// forward declaration to make things clearer
void read_event(vector &event);
void analyze(const vector & input_particles);
//----------------------------------------------------------------------
int main(){
//----------------------------------------------------------
// read in input particles
vector 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 &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 & 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
//////////
// Multiple pT analysis.
//////////
// These use classes derived from JetLikeEventShape_MultiplePtCutValues, 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_MultiplePtCutValues Nj_allPt(Rjet);
ShapeJetMultiplicity_MultiplePtCutValues 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 multiple pT analysis" << endl;
cout << "#########" << endl;
cout << "Jet parameters: R_jet=" << Rjet << ", pTcut=" << pTcut << " (unless otherwise stated)" < myShapes;
vector 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)->setUseLocalStorage(false);
double valueNoStorage = myShapes.at(i)->result(input_particles);
myShapes.at(i)->setUseLocalStorage(true);
double valueYesStorage = myShapes.at(i)->result(input_particles);
cout << myNames.at(i) << "="
<< valueNoStorage << endl;
cout << "(Local Storage works? " << (valueNoStorage == valueYesStorage ? "Yes" : "No!!") << ")" << endl;
cout << "#" << endl;
delete myShapes.at(i);
}
//////////
// User defined JetLikeEventShape and using EventStorage
//////////
// Need to write a measurement function. For example, use FunctionScalarPtSum (already pre-defined) to get the ShapeScalarPt
class ShapeScalarPt_new: public JetLikeEventShape {
public:
ShapeScalarPt_new(double Rjet, double ptcut): JetLikeEventShape(new FunctionScalarPtSum(),Rjet,ptcut) {}
ShapeScalarPt_new(double Rjet, double ptcut, double Rsub, double fcut) : JetLikeEventShape(new FunctionScalarPtSum(),Rjet,ptcut,Rsub,fcut) {}
~ShapeScalarPt_new(){}
};
ShapeScalarPt_new HT_new(Rjet,pTcut);
// Built-in HT
ShapeScalarPt HT(Rjet,pTcut);
cout << "#########" << endl;
cout << "## Example of JetLikeEventShape defined with an external measurement" << endl;
cout << "#########" << endl;
cout << "HT_new = " << HT_new(input_particles) << endl;
cout << "compare to built-in HT = "<< HT(input_particles)<*> myMeasurements;
vector myNames1;
myMeasurements.push_back( new FunctionUnity() );
myNames1.push_back("Njet");
myMeasurements.push_back( new FunctionScalarPtSum() );
myNames1.push_back("HT");
myMeasurements.push_back( new FunctionScalarPtSumToN(2) );
myNames1.push_back("HT^2");
myMeasurements.push_back( new FunctionInvariantMass() );
myNames1.push_back("SigmaM");
myMeasurements.push_back( new FunctionInvariantMassSquared() );
myNames1.push_back("SigmaM2");
cout << "#########" << endl;
cout << "## Example of multiple measurements using a single storage" << endl;
cout << "#########" << endl;
for(unsigned int i=0; i