├── event-gen ├── Nsubjettiness │ ├── VERSION │ ├── AUTHORS │ ├── Nsubjettiness.cc │ ├── WinnerTakeAllRecombiner.hh │ ├── WinnerTakeAllRecombiner.cc │ ├── NjettinessDefinition.cc │ ├── NjettinessPlugin.cc │ ├── Makefile │ ├── NEWS │ ├── MeasureFunction.cc │ ├── example_basic_usage.ref │ ├── NjettinessPlugin.hh │ ├── Njettiness.cc │ ├── example_v1p0p3.ref │ ├── Njettiness.hh │ ├── Nsubjettiness.hh │ ├── ChangeLog │ ├── README │ ├── MeasureFunction.hh │ ├── example_basic_usage.cc │ ├── AxesFinder.cc │ └── AxesFinder.hh ├── include │ ├── myFastJetBase.h │ ├── MITools.h │ └── MIAnalysis.h ├── Makefile └── src │ ├── MITools.cc │ ├── MI.cc │ └── MIAnalysis.cc ├── jettools ├── __init__.py ├── processing.py └── jettools.py ├── .gitignore ├── setup.sh ├── README.md ├── jetconverter.py └── generateEvents.py /event-gen/Nsubjettiness/VERSION: -------------------------------------------------------------------------------- 1 | 2.1.0 -------------------------------------------------------------------------------- /jettools/__init__.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Import control for jet simulations. 3 | ''' 4 | from .jettools import plot_jet, plot_mean_jet 5 | from .processing import buffer_to_jet, is_signal 6 | __all__ = ['plot_jet', 7 | 'plot_mean_jet', 8 | 'buffer_to_jet', 9 | 'is_signal'] -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | 30 | # Python stuff 31 | # -- Byte-compiled / optimized / DLL files 32 | __pycache__/ 33 | *.py[cod] 34 | *$py.class 35 | 36 | # ROOT files 37 | *.root 38 | *.roo* 39 | -------------------------------------------------------------------------------- /event-gen/include/myFastJetBase.h: -------------------------------------------------------------------------------- 1 | #ifndef MYFASTJETBASE_H 2 | #define MYFASTJETBASE_H 3 | 4 | #include "fastjet/PseudoJet.hh" 5 | 6 | using namespace fastjet; 7 | 8 | class MyUserInfo : public PseudoJet::UserInfoBase{ 9 | public: 10 | MyUserInfo(const int & pdg_id_in,const int & pythia_id_in, const double & charge_in, const bool & pileup_in) : 11 | _pdg_id(pdg_id_in),_pythia_id(pythia_id_in), _charge(charge_in){} 12 | int pdg_id() const { return _pdg_id;} 13 | int pythia_id() const {return _pythia_id;} 14 | double charge() const { return _charge;} 15 | bool pileup() const { return _pileup;} 16 | protected: 17 | int _pdg_id; // the associated pdg id 18 | int _pythia_id; // index in pythia.event 19 | double _charge; // the particle charge 20 | bool _pileup; 21 | }; 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /event-gen/Nsubjettiness/AUTHORS: -------------------------------------------------------------------------------- 1 | The Nsubjettiness FastJet contrib was written and is maintained and developed by: 2 | 3 | Jesse Thaler 4 | Ken Van Tilburg 5 | Christopher K. Vermilion 6 | TJ Wilkason 7 | 8 | Questions and comments should be directed to: jthaler@jthaler.net. 9 | 10 | For physics details, see: 11 | 12 | Identifying Boosted Objects with N-subjettiness. 13 | Jesse Thaler and Ken Van Tilburg. 14 | JHEP 1103:015 (2011), arXiv:1011.2268. 15 | 16 | Maximizing Boosted Top Identification by Minimizing N-subjettiness. 17 | Jesse Thaler and Ken Van Tilburg. 18 | JHEP 1202:093 (2012), arXiv:1108.2701. 19 | 20 | New in v2.0 is the winner-take-all axis, described in: 21 | 22 | Jet Shapes with the Broadening Axis. 23 | Andrew J. Larkoski, Duff Neill, and Jesse Thaler. 24 | JHEP 1404:017 (2014), arXiv:1401.2158. 25 | 26 | as well as in unpublished work by Gavin Salam. 27 | 28 | ---------------------------------------------------------------------- 29 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | setup_GCC() 4 | { 5 | source /cvmfs/atlas.cern.ch/repo/sw/atlas-gcc/491/x86_64/setup.sh 6 | } 7 | 8 | 9 | setup_PYTHIA() { 10 | #export PYTHIA8LOCATION=/u/at/pnef/Work/Code/pythia8183/ 11 | export PYTHIA8LOCATION=/u/at/lukedeo/software/pythia8210 12 | export PYTHIA8DATA=${PYTHIA8LOCATION}/xmldoc/ 13 | export LD_LIBRARY_PATH=${PYTHIA8LOCATION}/lib/:$LD_LIBRARY_PATH 14 | } 15 | 16 | setup_ROOT() { 17 | source /u/at/pnef/Work/Code/root_v5.34.17/bin/thisroot.sh 18 | } 19 | 20 | setup_fastjet() { 21 | export FASTJETLOCATION=/u/at/pnef/Work/Code/TrackBasedGrooming/stable/fastjet-3.0.3/fastjet-install/ 22 | #export FASTJETLOCATION=/u/at/pnef/Work/Code/TrackBasedGrooming/fastjet-3.0.3/fastjet-install/ 23 | #export FASTJETLOCATION=/u/at/pnef/Work/Code/fastjet-install/ 24 | export LD_LIBRARY_PATH=${FASTJETPATH}lib/:$LD_LIBRARY_PATH 25 | } 26 | 27 | setup_atlint() { 28 | export PATH+=:$PYTHIA8LOCATION/bin 29 | export PATH+=:$FASTJETLOCATION/bin 30 | } 31 | 32 | setup_ROOT 33 | setup_PYTHIA 34 | setup_fastjet 35 | setup_atlint -------------------------------------------------------------------------------- /event-gen/include/MITools.h: -------------------------------------------------------------------------------- 1 | #ifndef MITOOLS_H 2 | #define MITOOLS_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "fastjet/ClusterSequence.hh" 9 | #include "fastjet/PseudoJet.hh" 10 | 11 | #include "Pythia8/Pythia.h" 12 | 13 | #include "myFastJetBase.h" 14 | 15 | using namespace std; 16 | using fastjet::PseudoJet; 17 | 18 | class MITools { 19 | private: 20 | int m_test; 21 | 22 | 23 | 24 | public: 25 | MITools(); 26 | 27 | // methods 28 | double JetCharge(fastjet::PseudoJet jet,double kappa); 29 | bool IsBHadron(int pdgId); 30 | bool IsCHadron(int pdgId); 31 | bool Btag(fastjet::PseudoJet jet,vector bhadrons,vector chadrons,double jetrad,double b, double c, double uds); 32 | bool BosonMatch(fastjet::PseudoJet jet, vector Bosons, double jetrad, int BosonID); 33 | bool IsIsolated(Pythia8::Particle* particle, Pythia8::Pythia* pythia8, float rel_iso, float conesize); 34 | int Match(fastjet::PseudoJet jet,vector jets); 35 | }; 36 | 37 | #endif 38 | 39 | -------------------------------------------------------------------------------- /jettools/processing.py: -------------------------------------------------------------------------------- 1 | ''' 2 | processing.py 3 | author: Luke de Oliveira, July 2015 4 | 5 | Simple utilities for processing the junk that comes out of the ntuple event generation. 6 | ''' 7 | 8 | import numpy as np 9 | from .jettools import rotate_jet, flip_jet, plot_mean_jet 10 | 11 | def buffer_to_jet(entry, tag = 0, side = 'r', max_entry = 2000, pix = 25): 12 | """ 13 | Takes an *single* entry from an structured ndarray, i.e., X[i], 14 | and a tag = {0, 1} indicating if its a signal entry or not. 15 | The parameter 'side' indicates which side of the final 16 | jet image we want the highest energy. 17 | 18 | The `entry` must have the following fields (as produced by event-gen) 19 | * Intensity 20 | * RotationAngle 21 | * LeadingPt 22 | * LeadingEta 23 | * LeadingPhi 24 | * LeadingM 25 | * Tau32 26 | * Tau21 27 | """ 28 | 29 | image = flip_jet(rotate_jet(np.array(entry['Intensity']), -entry['RotationAngle'], normalizer=max_entry, dim=pix), side) 30 | return (image / np.linalg.norm(image), tag, 31 | entry['LeadingPt'], entry['LeadingEta'], entry['LeadingPhi'], entry['LeadingM'], entry['Tau32'], entry['Tau21']) 32 | 33 | 34 | def is_signal(f, matcher = 'Wprime'): 35 | """ 36 | Takes as input a filename and a string to match. If the 37 | 'matcher' string is found in the filename, the file is 38 | taken to be a signal file. 39 | """ 40 | key = matcher.lower().replace(' ', '').replace('-', '') 41 | if key in f.lower().replace(' ', '').replace('-', ''): 42 | return 1.0 43 | return 0.0 44 | -------------------------------------------------------------------------------- /event-gen/Nsubjettiness/Nsubjettiness.cc: -------------------------------------------------------------------------------- 1 | // Nsubjettiness Package 2 | // Questions/Comments? jthaler@jthaler.net 3 | // 4 | // Copyright (c) 2011-14 5 | // Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason 6 | // 7 | // $Id: Nsubjettiness.cc 597 2014-04-16 23:07:55Z jthaler $ 8 | //---------------------------------------------------------------------- 9 | // This file is part of FastJet contrib. 10 | // 11 | // It is free software; you can redistribute it and/or modify it under 12 | // the terms of the GNU General Public License as published by the 13 | // Free Software Foundation; either version 2 of the License, or (at 14 | // your option) any later version. 15 | // 16 | // It is distributed in the hope that it will be useful, but WITHOUT 17 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 18 | // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 19 | // License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this code. If not, see . 23 | //---------------------------------------------------------------------- 24 | 25 | #include "Nsubjettiness.hh" 26 | 27 | FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 28 | 29 | namespace contrib { 30 | 31 | //result returns tau_N with normalization dependent on what is specified in constructor 32 | double Nsubjettiness::result(const PseudoJet& jet) const { 33 | std::vector particles = jet.constituents(); 34 | return _njettinessFinder.getTau(_N, particles); 35 | } 36 | 37 | TauComponents Nsubjettiness::component_result(const PseudoJet& jet) const { 38 | std::vector particles = jet.constituents(); 39 | return _njettinessFinder.getTauComponents(_N, particles); 40 | } 41 | 42 | //ratio result uses Nsubjettiness result to find the ratio tau_N/tau_M, where N and M are specified by user 43 | double NsubjettinessRatio::result(const PseudoJet& jet) const { 44 | double numerator = _nsub_numerator.result(jet); 45 | double denominator = _nsub_denominator.result(jet); 46 | return numerator/denominator; 47 | } 48 | 49 | } // namespace contrib 50 | 51 | FASTJET_END_NAMESPACE 52 | -------------------------------------------------------------------------------- /jettools/jettools.py: -------------------------------------------------------------------------------- 1 | ''' 2 | file: jettools.py 3 | author: Luke de Oliveira, Mar. 2015 4 | 5 | Provides support for jet rotation and flipping 6 | 7 | ''' 8 | import numpy as np 9 | import skimage.transform as sk 10 | import matplotlib.pyplot as plt 11 | from matplotlib.colors import LogNorm 12 | 13 | def rotate_jet(jet, angle, in_radians = True, normalizer = 1800, dim=25): 14 | """ 15 | Take an *flat* unrotated in the form of an array from MI.exe, and an angle, 16 | and rotates the jet to that angle using a passively rotated cubic spline 17 | interpolation 18 | """ 19 | im = jet.reshape((dim, dim)) 20 | np.clip(im, -1, normalizer, out=im) 21 | im = np.flipud(im.T) / normalizer 22 | 23 | if in_radians: 24 | angle = np.rad2deg(angle) 25 | 26 | return sk.rotate(im, angle, order = 3) 27 | 28 | 29 | def flip_jet(jet, pool = 'r'): 30 | """ 31 | Takes a rotated jet (25, 25) from rotate_jet() and flips it across the 32 | vertical axis according to whether you want the right side 33 | (pool = {r, R, right, Right, ...}) or the 34 | left side (pool = {l, L, Left, left, ...}) to contain the most energy. 35 | """ 36 | weight = jet.sum(axis = 0) 37 | 38 | halfway = jet.shape[0] / 2. 39 | l, r = np.int(np.floor(halfway)), np.int(np.ceil(halfway)) 40 | l_weight, r_weight = np.sum(weight[:l]), np.sum(weight[r:]) 41 | 42 | if ('r' in pool.lower()) and ('l' in pool.lower()): 43 | raise ValueError('Jet pooling side must have l -OR- r in the name.') 44 | if 'r' in pool.lower(): 45 | if r_weight > l_weight: 46 | return jet 47 | return np.fliplr(jet) 48 | elif 'l' in pool.lower(): 49 | if l_weight > r_weight: 50 | return jet 51 | return np.fliplr(jet) 52 | else: 53 | raise ValueError('Jet pooling side must have l -OR- r in the name.') 54 | 55 | 56 | def plot_mean_jet(rec, field = 'image', title = 'Average Jet Image'): 57 | fig = plt.figure(figsize=(8, 8), dpi=100) 58 | ax = fig.add_subplot(111) 59 | im = ax.imshow(np.mean(rec[field], axis = 0), norm=LogNorm(vmin=0.00001, vmax=1), interpolation='nearest') 60 | plt.title(r''+title) 61 | return fig 62 | 63 | 64 | def plot_jet(rec, title = 'Jet Image', log=True): 65 | fig = plt.figure(figsize=(8, 8), dpi=100) 66 | ax = fig.add_subplot(111) 67 | if log: 68 | im = ax.imshow(rec, norm=LogNorm(vmin=0.00001, vmax=1), interpolation='nearest') 69 | else: 70 | im = ax.imshow(rec, interpolation='nearest') 71 | plt.title(r''+title) 72 | return fig 73 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # `jet-simulations` 2 | 3 | ## Dependencies 4 | 5 | * `numpy`, `matplotlib`, `rootpy`, `PyROOT`, and `scikit-image` for python. 6 | * `fastjet` version >= 3.1.0 7 | * `Pythia` version >= 8.1 8 | * `ROOT` 9 | 10 | ## Building the framework 11 | 12 | Typing `make -j` should do the trick on most systems if `fastjet-config`, `pythia8-config`, and `root-config` are all in your `$PATH`. If you're on the SLAC computers, run `./setup.sh` first. This generates the low level event generation script (contained in the `./event-gen` folder), which can be invoked as `./event-gen/event-gen`, if you really need to. 13 | 14 | ## Event generation. 15 | 16 | To speed things up, there is a multicore wrapper around this generation process in `generateEvents.py`. Calling `python generateEvents.py --help` yields: 17 | 18 | ``` 19 | usage: generateEvents.py [-h] [--outfile OUTFILE] [--nevents NEVENTS] 20 | [--ncpu NCPU] [--process PROCESS] [--pixels PIXELS] 21 | [--range RANGE] [--pileup PILEUP] 22 | [--pt_hat_min PT_HAT_MIN] [--pt_hat_max PT_HAT_MAX] 23 | [--bosonmass BOSONMASS] 24 | 25 | optional arguments: 26 | -h, --help show this help message and exit 27 | --outfile OUTFILE 28 | --nevents NEVENTS 29 | --ncpu NCPU 30 | --process PROCESS Can be one of ZprimeTottbar, WprimeToWZ_lept, 31 | WprimeToWZ_had, or QCD 32 | --pixels PIXELS 33 | --range RANGE 34 | --pileup PILEUP 35 | --pt_hat_min PT_HAT_MIN 36 | --pt_hat_max PT_HAT_MAX 37 | --bosonmass BOSONMASS 38 | ``` 39 | 40 | So, let's say you wanted to generate 1000 jet images `(25, 25)`, `R = 1.0` from a QCD process over all CPUs. You would invoke 41 | 42 | ```bash 43 | python generateEvents.py --outfile=events.root --nevents=1000 --process=QCD --pixels=25 --range=1.0 44 | ``` 45 | 46 | This will generate files `events_cpuN.root` for `N = 1, ..., N_cpus`. 47 | 48 | 49 | 50 | ## Image processing 51 | 52 | Image processing is handled in the parent directory. 53 | 54 | 55 | ``` 56 | me@mycomputer$ python jetconverter.py --help 57 | usage: jetconverter.py [-h] [--verbose] [--signal SIGNAL] [--save SAVE] 58 | [--plot PLOT] 59 | [files [files ...]] 60 | 61 | positional arguments: 62 | files Files to pass in 63 | 64 | optional arguments: 65 | -h, --help show this help message and exit 66 | --verbose Verbose output 67 | --signal SIGNAL String to search for in filenames to indicate a signal file 68 | --save SAVE Filename to write out the data. 69 | --plot PLOT File prefix that will be part of plotting filenames. 70 | ``` 71 | 72 | An example invocation could look like `./jetconverter.py --signal=Wprime --save=data.npy ./data/*.root`. 73 | 74 | 75 | -------------------------------------------------------------------------------- /event-gen/Nsubjettiness/WinnerTakeAllRecombiner.hh: -------------------------------------------------------------------------------- 1 | // Nsubjettiness Package 2 | // Questions/Comments? jthaler@jthaler.net 3 | // 4 | // Copyright (c) 2011-14 5 | // Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason 6 | // 7 | // $Id: WinnerTakeAllRecombiner.hh 670 2014-06-06 01:24:42Z jthaler $ 8 | //---------------------------------------------------------------------- 9 | // This file is part of FastJet contrib. 10 | // 11 | // It is free software; you can redistribute it and/or modify it under 12 | // the terms of the GNU General Public License as published by the 13 | // Free Software Foundation; either version 2 of the License, or (at 14 | // your option) any later version. 15 | // 16 | // It is distributed in the hope that it will be useful, but WITHOUT 17 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 18 | // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 19 | // License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this code. If not, see . 23 | //---------------------------------------------------------------------- 24 | 25 | #ifndef __FASTJET_CONTRIB_WINNERTAKEALLRECOMBINER_HH__ 26 | #define __FASTJET_CONTRIB_WINNERTAKEALLRECOMBINER_HH__ 27 | 28 | #include "fastjet/PseudoJet.hh" 29 | #include "fastjet/JetDefinition.hh" 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 36 | 37 | namespace contrib { 38 | 39 | //------------------------------------------------------------------------ 40 | /// \class WinnerTakeAllRecombiner 41 | // WinnerTakeAllRecombiner defines a new recombination scheme by inheriting from JetDefinition::Recombiner. 42 | // This scheme compares the energy of two input particles, and then combines them into a particle with 43 | // an energy equal to the sum of the two particle energies and a direction identical to that of the harder 44 | // particle. This creates a jet with an axis guaranteed to align with a particle in the event. 45 | class WinnerTakeAllRecombiner : public fastjet::JetDefinition::Recombiner { 46 | public: 47 | // Constructor to choose value of alpha (defaulted to 1 for normal pT sum) 48 | WinnerTakeAllRecombiner(double alpha = 1.0) : _alpha(alpha) {} 49 | 50 | virtual std::string description() const; 51 | 52 | /// recombine pa and pb and put result into pab 53 | virtual void recombine(const fastjet::PseudoJet & pa, 54 | const fastjet::PseudoJet & pb, 55 | fastjet::PseudoJet & pab) const; 56 | 57 | private: 58 | double _alpha; //power of (pt/E) term when recombining particles 59 | }; 60 | 61 | } //namespace contrib 62 | 63 | FASTJET_END_NAMESPACE 64 | 65 | #endif // __FASTJET_CONTRIB_WINNERTAKEALLRECOMBINER_HH__ 66 | -------------------------------------------------------------------------------- /event-gen/include/MIAnalysis.h: -------------------------------------------------------------------------------- 1 | #ifndef MIAnalysis_H 2 | #define MIAnalysis_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "fastjet/ClusterSequence.hh" 9 | #include "fastjet/PseudoJet.hh" 10 | #include "fastjet/tools/Filter.hh" 11 | #include "fastjet/Selector.hh" 12 | 13 | #include "TFile.h" 14 | #include "TTree.h" 15 | #include "TClonesArray.h" 16 | #include "TParticle.h" 17 | 18 | #include "MITools.h" 19 | #include "myFastJetBase.h" 20 | #include "Pythia8/Pythia.h" 21 | 22 | #include "TH2F.h" 23 | 24 | using namespace std; 25 | using namespace fastjet; 26 | 27 | class MIAnalysis 28 | { 29 | public: 30 | MIAnalysis(int imagesize = 25); 31 | ~MIAnalysis(); 32 | 33 | void Begin(); 34 | void AnalyzeEvent(int iEvt, Pythia8::Pythia *pythia8, 35 | Pythia8::Pythia *pythia_MB, int NPV, int pixels, float range); 36 | 37 | void End(); 38 | void DeclareBranches(); 39 | void ResetBranches(); 40 | 41 | void Debug(int debug) 42 | { 43 | fDebug = debug; 44 | } 45 | 46 | void SetOutName(const string &outname) 47 | { 48 | fOutName = outname; 49 | } 50 | private: 51 | int ftest; 52 | int fDebug; 53 | string fOutName; 54 | 55 | TFile *tF; 56 | TTree *tT; 57 | MITools *tool; 58 | 59 | // Tree Vars --------------------------------------- 60 | int fTEventNumber; 61 | int fTNPV; 62 | 63 | void SetupInt(int & val, TString name); 64 | void SetupFloat(float & val, TString name); 65 | 66 | vector names; 67 | vector pts; 68 | vector ms; 69 | vector etas; 70 | vector nsub21s; 71 | vector nsub32s; 72 | vector nsubs; 73 | 74 | TH2F* detector; 75 | 76 | int MaxN; 77 | 78 | int fTNFilled; 79 | 80 | float fTLeadingEta; 81 | float fTLeadingPhi; 82 | float fTLeadingPt; 83 | float fTLeadingM; 84 | 85 | float fTSubLeadingEta; 86 | float fTSubLeadingPhi; 87 | 88 | float fTRotationAngle; 89 | 90 | float fTTau1; 91 | float fTTau2; 92 | float fTTau3; 93 | 94 | float fTTau21; 95 | float fTTau32; 96 | 97 | 98 | float *fTIntensity; 99 | float *fTRotatedIntensity; 100 | 101 | // float fTPt [MaxN]; 102 | // double fTEta [MaxN]; 103 | // double fTPhi [MaxN]; 104 | 105 | // float fTIntensity[MaxN]; 106 | // float fTRotatedIntensity[MaxN]; 107 | // int fTPixx[MaxN]; 108 | // int fTPixy[MaxN]; 109 | 110 | 111 | 112 | 113 | 114 | }; 115 | 116 | #endif 117 | 118 | -------------------------------------------------------------------------------- /event-gen/Nsubjettiness/WinnerTakeAllRecombiner.cc: -------------------------------------------------------------------------------- 1 | // Nsubjettiness Package 2 | // Questions/Comments? jthaler@jthaler.net 3 | // 4 | // Copyright (c) 2011-14 5 | // Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason 6 | // 7 | // $Id: WinnerTakeAllRecombiner.cc 597 2014-04-16 23:07:55Z jthaler $ 8 | //---------------------------------------------------------------------- 9 | // This file is part of FastJet contrib. 10 | // 11 | // It is free software; you can redistribute it and/or modify it under 12 | // the terms of the GNU General Public License as published by the 13 | // Free Software Foundation; either version 2 of the License, or (at 14 | // your option) any later version. 15 | // 16 | // It is distributed in the hope that it will be useful, but WITHOUT 17 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 18 | // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 19 | // License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this code. If not, see . 23 | //---------------------------------------------------------------------- 24 | 25 | #include "WinnerTakeAllRecombiner.hh" 26 | 27 | FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 28 | 29 | namespace contrib{ 30 | 31 | std::string WinnerTakeAllRecombiner::description() const { 32 | return "Winner Take All scheme recombination"; 33 | } 34 | 35 | // recombine pa and pb by creating pab with energy of the sum of particle energies in the direction of the harder particle 36 | // updated recombiner to use more general form of a metric equal to E*(pT/E)^(alpha), which reduces to pT*cosh(rap)^(1-alpha) 37 | // alpha is specified by the user. The default is alpha = 1, which is the typical behavior. alpha = 2 provides a metric which more 38 | // favors central jets 39 | void WinnerTakeAllRecombiner::recombine(const fastjet::PseudoJet & pa, const fastjet::PseudoJet & pb, fastjet::PseudoJet & pab) const { 40 | double a_pt = pa.perp(), b_pt = pb.perp(), a_rap = pa.rap(), b_rap = pb.rap(); 41 | 42 | // special case of alpha = 1, everything is just pt (made separate so that pow function isn't called) 43 | if (_alpha == 1.0) { 44 | if (a_pt >= b_pt) { 45 | pab.reset_PtYPhiM(a_pt + b_pt, a_rap, pa.phi()); 46 | } 47 | else if (b_pt > a_pt) { 48 | pab.reset_PtYPhiM(a_pt + b_pt, b_rap, pb.phi()); 49 | } 50 | } 51 | 52 | // every other case uses additional cosh(rap) term 53 | else { 54 | double a_metric = a_pt*pow(cosh(a_rap), 1.0-_alpha); 55 | double b_metric = b_pt*pow(cosh(b_rap), 1.0-_alpha); 56 | if (a_metric >= b_metric) { 57 | double new_pt = a_pt + b_pt*pow(cosh(b_rap)/cosh(a_rap), 1.0-_alpha); 58 | pab.reset_PtYPhiM(new_pt, a_rap, pa.phi()); 59 | } 60 | if (b_metric > a_metric) { 61 | double new_pt = b_pt + a_pt*pow(cosh(a_rap)/cosh(b_rap), 1.0-_alpha); 62 | pab.reset_PtYPhiM(new_pt, b_rap, pb.phi()); 63 | } 64 | } 65 | } 66 | 67 | } //namespace contrib 68 | 69 | FASTJET_END_NAMESPACE 70 | -------------------------------------------------------------------------------- /event-gen/Nsubjettiness/NjettinessDefinition.cc: -------------------------------------------------------------------------------- 1 | // Nsubjettiness Package 2 | // Questions/Comments? jthaler@jthaler.net 3 | // 4 | // Copyright (c) 2011-14 5 | // Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason 6 | // 7 | // $Id: NjettinessDefinition.cc 704 2014-07-07 14:30:43Z jthaler $ 8 | //---------------------------------------------------------------------- 9 | // This file is part of FastJet contrib. 10 | // 11 | // It is free software; you can redistribute it and/or modify it under 12 | // the terms of the GNU General Public License as published by the 13 | // Free Software Foundation; either version 2 of the License, or (at 14 | // your option) any later version. 15 | // 16 | // It is distributed in the hope that it will be useful, but WITHOUT 17 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 18 | // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 19 | // License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this code. If not, see . 23 | //---------------------------------------------------------------------- 24 | 25 | #include "NjettinessDefinition.hh" 26 | 27 | FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 28 | 29 | namespace contrib { 30 | 31 | std::string NormalizedMeasure::description() const { 32 | std::stringstream stream; 33 | stream << std::fixed << std::setprecision(2) 34 | << "Normalized Measure (beta = " << _beta << ", R0 = " << _R0 << ")"; 35 | return stream.str(); 36 | }; 37 | 38 | std::string UnnormalizedMeasure::description() const { 39 | std::stringstream stream; 40 | stream << std::fixed << std::setprecision(2) 41 | << "Unnormalized Measure (beta = " << _beta << ", in GeV)"; 42 | return stream.str(); 43 | }; 44 | 45 | std::string GeometricMeasure::description() const { 46 | std::stringstream stream; 47 | stream << std::fixed << std::setprecision(2) 48 | << "Geometric Measure (beta = " << _beta << ", in GeV)"; 49 | return stream.str(); 50 | }; 51 | 52 | std::string NormalizedCutoffMeasure::description() const { 53 | std::stringstream stream; 54 | stream << std::fixed << std::setprecision(2) 55 | << "Normalized Cutoff Measure (beta = " << _beta << ", R0 = " << _R0 << ", Rcut = " << _Rcutoff << ")"; 56 | return stream.str(); 57 | }; 58 | 59 | std::string UnnormalizedCutoffMeasure::description() const { 60 | std::stringstream stream; 61 | stream << std::fixed << std::setprecision(2) 62 | << "Unnormalized Cutoff Measure (beta = " << _beta << ", Rcut = " << _Rcutoff << ", in GeV)"; 63 | return stream.str(); 64 | }; 65 | 66 | std::string GeometricCutoffMeasure::description() const { 67 | std::stringstream stream; 68 | stream << std::fixed << std::setprecision(2) 69 | << "Geometric Cutoff Measure (beta = " << _beta << ", Rcut = " << _Rcutoff << ", in GeV)"; 70 | return stream.str(); 71 | }; 72 | 73 | 74 | } // namespace contrib 75 | 76 | FASTJET_END_NAMESPACE 77 | -------------------------------------------------------------------------------- /event-gen/Makefile: -------------------------------------------------------------------------------- 1 | # --------------------------------------------- # 2 | # Makefile for Jet Images Framework # 3 | # Luke de Oliveira, April 3, 2015 # 4 | # lukedeo@stanford.edu # 5 | # --------------------------------------------- # 6 | 7 | # --- set directories 8 | BIN := bin 9 | SRC := src 10 | INC := include 11 | LIB := $(CURDIR)/lib 12 | 13 | NSUBDIR := Nsubjettiness 14 | 15 | # --- set search path 16 | vpath %.o $(BIN) 17 | vpath %.cc $(SRC) 18 | vpath %.h $(INC) 19 | 20 | # --- set compiler and flags 21 | 22 | CXX ?= g++ 23 | CXXFLAGS := -Wall -fPIC -I$(INC) -I$(NSUBDIR) -g -std=c++11 24 | 25 | ifeq ($(CXX),clang++) 26 | CXXFLAGS += -stdlib=libc++ 27 | endif 28 | 29 | # --- HEP flags 30 | FASTJETFLAGS := $(shell fastjet-config --cxxflags --plugins) 31 | FASTJETLDFLAGS = 32 | FASTJETLIBS = $(shell fastjet-config --libs --plugins) 33 | 34 | ROOTFLAGS := $(shell root-config --cflags) 35 | ROOTLDFLAGS := $(shell root-config --ldflags) 36 | ROOTLIBS := $(shell root-config --glibs) 37 | 38 | PYTHIAFLAGS := $(shell pythia8-config --cxxflags) 39 | PYTHIALDFLAGS := $(shell pythia8-config --ldflags) 40 | PYTHIALIBS = $(shell pythia8-config --libs) 41 | 42 | 43 | HEPLIBS += $(FASTJETLIBS) 44 | HEPLIBS += $(ROOTLIBS) 45 | HEPLIBS += $(PYTHIALIBS) 46 | 47 | # --- Add HEP flags to common stuff 48 | CXXFLAGS += $(ROOTFLAGS) 49 | CXXFLAGS += $(FASTJETFLAGS) 50 | CXXFLAGS += $(PYTHIAFLAGS) 51 | 52 | LIBS += $(HEPLIBS) 53 | 54 | LDFLAGS = $(ROOTLDFLAGS) $(PYTHIALDFLAGS) $(FASTJETLDFLAGS) 55 | 56 | # --- building excecutable 57 | OBJ := MI.o MIAnalysis.o MITools.o 58 | 59 | EXECUTABLE := event-gen 60 | 61 | EXTERNALS := njettiness 62 | 63 | 64 | all: $(EXTERNALS) $(EXECUTABLE) 65 | @echo "jet-images build sucessful." 66 | 67 | njettiness: 68 | @echo "Building $@" 69 | @$(MAKE) -C $(NSUBDIR) 70 | 71 | $(EXECUTABLE): $(OBJ:%=$(BIN)/%) 72 | @echo "linking $^ --> $@" 73 | @$(CXX) -o $@ $^ $(shell find ./Nsubjettiness/ | grep "\.o") $(LDFLAGS) $(LIBS) 74 | 75 | 76 | # --- auto dependency generation for build --- # 77 | # ---------------------------------------------# 78 | 79 | # compile rule 80 | $(BIN)/%.o: %.cc 81 | @echo compiling $< 82 | @mkdir -p $(BIN) 83 | @$(CXX) -c $(CXXFLAGS) $< -o $@ 84 | 85 | # use auto dependency generation 86 | DEP = $(BIN) 87 | 88 | ifneq ($(MAKECMDGOALS),clean) 89 | ifneq ($(MAKECMDGOALS),rmdep) 90 | ifneq ($(MAKECMDGOALS),purge) 91 | include $(OBJ:%.o=$(DEP)/%.d) 92 | endif 93 | endif 94 | endif 95 | 96 | DEPTARGSTR = -MT $(BIN)/$*.o -MT $(DEP)/$*.d 97 | $(DEP)/%.d: %.cc 98 | @echo making dependencies for $< 99 | @mkdir -p $(DEP) 100 | @$(CXX) -MM -MP $(DEPTARGSTR) $(CXXFLAGS) $< -o $@ 101 | 102 | # clean 103 | .PHONY : clean rmdep 104 | CLEANLIST = *~ *.o *.o~ *.d core 105 | 106 | clean: 107 | rm -fr $(CLEANLIST) $(CLEANLIST:%=$(BIN)/%) $(CLEANLIST:%=$(DEP)/%) 108 | rm -fr $(BIN) 109 | @$(MAKE) $@ -C $(NSUBDIR) 110 | 111 | purge: 112 | rm -fr $(CLEANLIST) $(CLEANLIST:%=$(BIN)/%) $(CLEANLIST:%=$(DEP)/%) 113 | rm -fr $(BIN) 114 | rm -fr $(EXECUTABLE) 115 | @$(MAKE) $@ -C $(NSUBDIR) 116 | 117 | rmdep: 118 | rm -f $(DEP)/*.d 119 | @$(MAKE) $@ -C $(NSUBDIR) -------------------------------------------------------------------------------- /event-gen/Nsubjettiness/NjettinessPlugin.cc: -------------------------------------------------------------------------------- 1 | // Nsubjettiness Package 2 | // Questions/Comments? jthaler@jthaler.net 3 | // 4 | // Copyright (c) 2011-14 5 | // Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason 6 | // 7 | // $Id: NjettinessPlugin.cc 663 2014-06-03 21:26:41Z jthaler $ 8 | //---------------------------------------------------------------------- 9 | // This file is part of FastJet contrib. 10 | // 11 | // It is free software; you can redistribute it and/or modify it under 12 | // the terms of the GNU General Public License as published by the 13 | // Free Software Foundation; either version 2 of the License, or (at 14 | // your option) any later version. 15 | // 16 | // It is distributed in the hope that it will be useful, but WITHOUT 17 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 18 | // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 19 | // License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this code. If not, see . 23 | //---------------------------------------------------------------------- 24 | 25 | #include "NjettinessPlugin.hh" 26 | 27 | FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 28 | 29 | namespace contrib{ 30 | 31 | 32 | 33 | std::string NjettinessPlugin::description() const {return "N-jettiness jet finder";} 34 | 35 | 36 | // Clusters the particles according to the Njettiness jet algorithm 37 | // Apologies for the complication with this code, but we need to make 38 | // a fake jet clustering tree. The partitioning is done by getPartitionList 39 | void NjettinessPlugin::run_clustering(ClusterSequence& cs) const 40 | { 41 | std::vector particles = cs.jets(); 42 | 43 | // HACK: remove area information from particles (in case this is called by 44 | // a ClusterSequenceArea. Will be fixed in a future FastJet release) 45 | for (unsigned i = 0; i < particles.size(); i++) { 46 | particles[i].set_structure_shared_ptr(SharedPtr()); 47 | } 48 | 49 | 50 | _njettinessFinder.getTau(_N, particles); 51 | 52 | std::vector > partition = _njettinessFinder.getPartitionList(particles); 53 | 54 | std::vector jet_indices_for_extras; 55 | 56 | // output clusterings for each jet 57 | for (size_t i0 = 0; i0 < partition.size(); ++i0) { 58 | size_t i = partition.size() - 1 - i0; // reversed order of reading to match axes order 59 | std::list& indices = partition[i]; 60 | if (indices.size() == 0) continue; 61 | while (indices.size() > 1) { 62 | int merge_i = indices.back(); indices.pop_back(); 63 | int merge_j = indices.back(); indices.pop_back(); 64 | int newIndex; 65 | double fakeDij = -1.0; 66 | 67 | cs.plugin_record_ij_recombination(merge_i, merge_j, fakeDij, newIndex); 68 | 69 | indices.push_back(newIndex); 70 | } 71 | double fakeDib = -1.0; 72 | 73 | int finalJet = indices.back(); 74 | cs.plugin_record_iB_recombination(finalJet, fakeDib); 75 | jet_indices_for_extras.push_back(cs.jets()[finalJet]); // Get the four vector for the final jets to compare later. 76 | } 77 | 78 | //HACK: Re-reverse order of reading to match CS order 79 | reverse(jet_indices_for_extras.begin(),jet_indices_for_extras.end()); 80 | 81 | NjettinessExtras * extras = new NjettinessExtras(_njettinessFinder.currentTauComponents(),jet_indices_for_extras,_njettinessFinder.currentAxes()); 82 | cs.plugin_associate_extras(std::auto_ptr(extras)); 83 | 84 | } 85 | 86 | 87 | } // namespace contrib 88 | 89 | FASTJET_END_NAMESPACE 90 | -------------------------------------------------------------------------------- /event-gen/Nsubjettiness/Makefile: -------------------------------------------------------------------------------- 1 | # If you are using this Makefile standalone and fastjet-config is not 2 | # in your path, edit this line to specify the full path 3 | FASTJETCONFIG=fastjet-config 4 | PREFIX=`$(FASTJETCONFIG) --prefix` 5 | # CXX=g++ 6 | CXXFLAGS= -O3 -Wall -Woverloaded-virtual -g -Wunused-parameter 7 | install_script = $(SHELL) ../utils/install-sh 8 | check_script = ../utils/check.sh 9 | 10 | # global contrib-wide Makefile include may override some of the above 11 | # variables (leading "-" means don't give an error if you can't find 12 | # the file) 13 | -include ../.Makefile.inc 14 | 15 | #------------------------------------------------------------------------ 16 | # things that are specific to this contrib 17 | NAME=Nsubjettiness 18 | SRCS=Nsubjettiness.cc Njettiness.cc NjettinessPlugin.cc MeasureFunction.cc AxesFinder.cc WinnerTakeAllRecombiner.cc NjettinessDefinition.cc 19 | EXAMPLES=example_basic_usage example_advanced_usage example_v1p0p3 20 | INSTALLED_HEADERS=Nsubjettiness.hh Njettiness.hh NjettinessPlugin.hh MeasureFunction.hh AxesFinder.hh WinnerTakeAllRecombiner.hh NjettinessDefinition.hh 21 | #------------------------------------------------------------------------ 22 | 23 | CXXFLAGS+= $(shell $(FASTJETCONFIG) --cxxflags) 24 | LDFLAGS += -lm $(shell $(FASTJETCONFIG) --libs) 25 | 26 | OBJS = $(SRCS:.cc=.o) 27 | EXAMPLES_SRCS = $(EXAMPLES:=.cc) 28 | 29 | install_HEADER = $(install_script) -c -m 644 30 | install_LIB = $(install_script) -c -m 644 31 | install_DIR = $(install_script) -d 32 | install_DATA = $(install_script) -c -m 644 33 | install_PROGRAM = $(install_script) -c -s 34 | install_SCRIPT = $(install_script) -c 35 | 36 | 37 | 38 | 39 | 40 | 41 | CXX ?= g++ 42 | CXXFLAGS := -Wall -fPIC -I$(INC) -I$(NSUBDIR) -g -std=c++11 43 | 44 | ifeq ($(CXX),clang++) 45 | CXXFLAGS += -stdlib=libc++ 46 | endif 47 | 48 | # --- HEP flags 49 | FASTJETFLAGS := $(shell fastjet-config --cxxflags --plugins) 50 | FASTJETLDFLAGS = 51 | FASTJETLIBS = $(shell fastjet-config --libs --plugins) 52 | 53 | ROOTFLAGS := $(shell root-config --cflags) 54 | ROOTLDFLAGS := $(shell root-config --ldflags) 55 | ROOTLIBS := $(shell root-config --glibs) 56 | 57 | PYTHIAFLAGS := $(shell pythia8-config --cxxflags) 58 | PYTHIALDFLAGS := $(shell pythia8-config --ldflags) 59 | PYTHIALIBS = $(shell pythia8-config --libs) 60 | 61 | 62 | HEPLIBS += $(FASTJETLIBS) 63 | 64 | # --- For n-subjettiness calculation 65 | # HEPLIBS += -lNsubjettiness 66 | 67 | HEPLIBS += $(ROOTLIBS) 68 | HEPLIBS += $(PYTHIALIBS) 69 | 70 | 71 | 72 | 73 | 74 | # --- Add HEP flags to common stuff 75 | CXXFLAGS += $(ROOTFLAGS) 76 | CXXFLAGS += $(FASTJETFLAGS) 77 | CXXFLAGS += $(PYTHIAFLAGS) 78 | 79 | 80 | 81 | 82 | 83 | 84 | .PHONY: clean distclean examples check install 85 | 86 | # compilation of the code (default target) 87 | all: lib$(NAME).a 88 | 89 | lib$(NAME).a: $(OBJS) 90 | ar cru lib$(NAME).a $(OBJS) 91 | ranlib lib$(NAME).a 92 | 93 | # building the examples 94 | examples: $(EXAMPLES) 95 | 96 | # the following construct alloews to build each of the examples listed 97 | # in $EXAMPLES automatically 98 | $(EXAMPLES): % : %.o all 99 | $(CXX) -o $@ $< -L. -l$(NAME) $(LDFLAGS) 100 | 101 | # check that everything went fine 102 | check: examples 103 | @for prog in $(EXAMPLES); do\ 104 | $(check_script) $${prog} ../data/single-event.dat || exit 1; \ 105 | done 106 | @echo "All tests successful" 107 | 108 | # cleaning the directory 109 | clean: 110 | rm -f *~ *.o *.a 111 | 112 | distclean: clean 113 | rm -f lib$(NAME).a $(EXAMPLES) 114 | 115 | # install things in PREFIX/... 116 | install: all 117 | $(install_DIR) $(PREFIX)/include/fastjet/contrib 118 | for header in $(INSTALLED_HEADERS); do\ 119 | $(install_HEADER) $$header $(PREFIX)/include/fastjet/contrib/;\ 120 | done 121 | $(install_DIR) $(PREFIX)/lib 122 | $(install_LIB) lib$(NAME).a $(PREFIX)/lib 123 | 124 | depend: 125 | makedepend -Y -- -- $(SRCS) $(EXAMPLES_SRCS) 126 | # DO NOT DELETE 127 | 128 | 129 | %.o: %.cc 130 | @echo compiling $< 131 | @$(CXX) -c $(CXXFLAGS) $< -o $@ -------------------------------------------------------------------------------- /event-gen/Nsubjettiness/NEWS: -------------------------------------------------------------------------------- 1 | ------------------------- 2 | Version 2 3 | ------------------------- 4 | 5 | This is a streamlining of the N-subjettiness code, developed mainly by TJ 6 | Wilkason. The core functionality is unchanged, but classes have been 7 | dramatically reorganized to allow for later expansion. Because the API for 8 | Njettiness has changed, we have called this v2 (http://semver.org). 9 | 10 | Note that we have maintain backwards compatibility for the typical ways that 11 | Nsubjettiness was used. In particular, all of the Nsubjettiness class code in 12 | the example file v1.0.3 from still compiles, as does the NjettinessPlugin class 13 | code that uses the default measure. 14 | 15 | The key new features are: 16 | 17 | * NsubjettinessRatio: Direct access to tau_N / tau_M (the most requested 18 | feature) 19 | * MeasureDefinition to allow access to both normalized and unnormalized measures 20 | * AxesDefinition to allow for access to more general axes modes 21 | * Winner-Take-All recombination axes: a faster way to find axes than beta = 1 22 | minimization, but with comparable performance. 23 | * TauComponents to get access to the pieces of the N-(sub)jettiness 24 | calculation. 25 | * For clarity, split the example file into an example_basic_usage and 26 | example_advanced_usage 27 | * In Nsubjettiness, access to seedAxes() and currentAxes() to figure out the 28 | axes used before and after minimization. 29 | * In Nsubjettiness, access to currentSubjets() to get the subjet fourvectors. 30 | 31 | 32 | -- 2.1.0: (July 9, 2014) Inclusion of MeasureDefinition/AxesDefinition interface. 33 | This was the first publicly available version of Nsubjettiness v2. 34 | -- 2.0.0: Initial release of v2.0. This was never officially made public. 35 | 36 | ------------------------- 37 | Version 1 38 | ------------------------- 39 | 40 | This was a new release using FastJet contrib framework, primary developed by 41 | Jesse Thaler. 42 | 43 | -- 1.0.3: Added inlines to fix compile issue (thanks Matthew Low) 44 | -- 1.0.2: Fixed potential dependency issue (thanks FJ authors) 45 | -- 1.0.1: Fixed memory leak in Njettiness.hh (thanks FJ authors) 46 | -- 1.0.0: New release using FastJet contrib framework. This includes a new 47 | makefile and a simplified example program. 48 | 49 | ------------------------- 50 | Previous Versions 51 | ------------------------- 52 | 53 | The previous versions of this code were developed initially by Ken Van Tilburg, 54 | tweaked by Jesse Thaler, and made into a robust FastJet add on by Chris 55 | Vermilion. 56 | 57 | Previous versions available from: 58 | http://jthaler.net/jets/Njettiness-0.5.1.tar.gz (Experimental Version) 59 | http://jthaler.net/jets/Njettiness-0.4.1.tar.gz (Stable Version) 60 | 61 | Previous version history: 62 | -- 0.5.1: For Njettiness Plugin, added access to currentTau values and axes via 63 | ClusterSequence::Extras class. (thanks to Dinko Ferencek and John 64 | Paul Chou) 65 | -- 0.5.0: Corrected fatal error in ConstituentTauValue (TauValue unaffected). 66 | Started process of allowing for more general measures and alternative 67 | minimization schemes. Extremely preliminary inclusion of alternative 68 | "geometric" measure. 69 | -- 0.4.1: Corrected bug where a too-small value of Rcut would cause the 70 | minimization procedure to fail (thanks Marat Freytsis, Brian Shuve) 71 | -- 0.4.0: Adding Nsubjettiness FunctionOfPseudoJet. Re-organizing file 72 | structure and doing some re-naming to clarify Njettiness vs. 73 | Nsubjettiness. Some speedup in UpdateAxes code. (CKV) 74 | -- 0.3.2: Returns zero instead of a segmentation fault when the number of 75 | particles in a jet is smaller than the N value in tau_N (thanks 76 | Grigory Ovanesyan) 77 | -- 0.3.2: Fixed -Wshadow errors (thanks Grigory Ovanesyan) 78 | -- 0.3.1: Fixed stray comma/semicolon compiler error (thanks Grigory Ovanesyan) 79 | -- 0.3.1: Corrected tarbomb issue (thanks Jonathan Walsh) 80 | -- 0.3.1: Added anti-kT seeds as option 81 | -- 0.3.1: Fixed bug in minimization code with R_cutoff (thanks Chris Vermilion) 82 | -- 0.3.1: Added getPartition() and getJets() functions as helper functions for 83 | Chris Vermilion. (JT) 84 | -------------------------------------------------------------------------------- /event-gen/src/MITools.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "fastjet/ClusterSequence.hh" 8 | #include "fastjet/PseudoJet.hh" 9 | 10 | #include "MITools.h" 11 | #include "myFastJetBase.h" 12 | 13 | #include "TRandom3.h" 14 | 15 | using namespace std; 16 | using fastjet::PseudoJet; 17 | 18 | 19 | // Constructor 20 | MITools::MITools(){ 21 | m_test = 0; 22 | } 23 | 24 | int MITools::Match(fastjet::PseudoJet jet,vector jets){ 25 | 26 | double close=500; 27 | int found=-1; 28 | double closePt = 0.; 29 | for (unsigned int i=0; i closePt && myR < 0.7){ 32 | found=i; 33 | myR=close; 34 | closePt = jet.pt(); 35 | } 36 | } 37 | 38 | return found; 39 | 40 | } 41 | 42 | double MITools::JetCharge(fastjet::PseudoJet jet,double kappa){ 43 | //Returns the jet charge with weighting factor kappa 44 | double charge=0.; 45 | for (unsigned int i=0; i().charge()*pow(jet.constituents()[i].pt(),kappa); 47 | } 48 | return charge/pow(jet.pt(),kappa); 49 | } 50 | 51 | bool MITools::IsBHadron(int pdgId){ 52 | int abs_pdgId = abs(pdgId); 53 | int abs_pdgId_mod10k = (abs(pdgId)%10000); 54 | if( (abs_pdgId_mod10k>=500 && abs_pdgId_mod10k<600) /*mesons*/ || 55 | (abs_pdgId>=5000 && abs_pdgId<6000) /*baryons*/ ) 56 | return true; 57 | 58 | return false; 59 | } 60 | 61 | bool MITools::IsCHadron(int pdgId){ 62 | int abs_pdgId = abs(pdgId); 63 | int abs_pdgId_mod10k = (abs(pdgId)%10000); 64 | if( (abs_pdgId_mod10k>=400 && abs_pdgId_mod10k<500) /*mesons*/ || 65 | (abs_pdgId>=4000 && abs_pdgId<5000) /*baryons*/ ) 66 | return true; 67 | 68 | return false; 69 | } 70 | 71 | bool MITools::Btag(fastjet::PseudoJet jet,vector bhadrons,vector chadrons,double jetrad,double b,double c,double uds){ 72 | 73 | TRandom3 *rand = new TRandom3(0); 74 | 75 | int foundb=0; 76 | int foundc=0; 77 | 78 | for (unsigned int i=0; iUniform(0.,1.); 92 | if (flip < b){ 93 | delete rand; 94 | return true; 95 | } 96 | } 97 | if (foundc==1){ 98 | double flip= rand->Uniform(0.,1.); 99 | if (flip < 1./c){ 100 | delete rand; 101 | return true; 102 | } 103 | } 104 | double flip= rand->Uniform(0.,1.); 105 | if (flip < 1./uds){ 106 | delete rand; 107 | return true; 108 | } 109 | 110 | delete rand; 111 | return false; 112 | } 113 | 114 | bool MITools::BosonMatch(fastjet::PseudoJet jet, vector Bosons, double jetrad, int BosonID ){ 115 | 116 | for (unsigned int i=0; i().pdg_id() != BosonID) continue; 118 | if (Bosons[i].delta_R(jet)px(), particle->py(), particle->pz(),particle->e() ); 128 | for (unsigned int ip=0; ipevent.size(); ++ip){ 129 | if (!pythia8->event[ip].isFinal() ) continue; 130 | if (fabs(pythia8->event[ip].id()) ==12) continue; 131 | if (fabs(pythia8->event[ip].id()) ==14) continue; 132 | if (fabs(pythia8->event[ip].id()) ==16) continue; 133 | if (pythia8->event[ip].pT() < 0.5) continue; 134 | if (&pythia8->event[ip] == particle ) continue; //same particle 135 | fastjet::PseudoJet p(pythia8->event[ip].px(), pythia8->event[ip].py(), pythia8->event[ip].pz(),pythia8->event[ip].e() ); 136 | if(p.delta_R(part)>ConeSize) continue; 137 | sumpT+=p.pt(); 138 | } 139 | if(sumpT/part.pt()>rel_iso) return false; 140 | else return true; 141 | } 142 | -------------------------------------------------------------------------------- /jetconverter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ''' 3 | file: jetconverter.py 4 | author: Luke de Oliveira, July 2015 5 | 6 | This file takes files (*.root) produced by the event-gen 7 | portion of the jet-simulations codebase and converts them into 8 | a more usable format. In particular, this produces a 9 | numpy record array with the following fields: 10 | 11 | * 'image' : (25, 25) numpy arrays that have been 12 | rotated using cubic spline interpolation 13 | to have the leading and subleading 14 | subjets aligned. In additon, the images 15 | are pooled/flipped so one side of the image 16 | holds the most energy. 17 | 18 | * 'signal' : {0, 1} for whether or not the sample 19 | matches signal or not. Invoke: 20 | python jetconverter.py -h for more help 21 | 22 | * 'jet_{x}': x is {pt, eta, phi}, and is the value of x 23 | for the leading subjet. 24 | 25 | * 'tau_{NM}': N-subjettiness. 26 | 27 | ''' 28 | 29 | 30 | from argparse import ArgumentParser 31 | import sys 32 | import logging 33 | 34 | import numpy as np 35 | 36 | from jettools import plot_mean_jet, buffer_to_jet, is_signal 37 | 38 | 39 | logging.basicConfig(level=logging.INFO) 40 | logger = logging.getLogger(__name__) 41 | 42 | def perfectsquare(n): 43 | ''' 44 | I hope this is self explanatory... 45 | ''' 46 | return n % n**0.5 == 0 47 | 48 | if __name__ == '__main__': 49 | parser = ArgumentParser() 50 | parser.add_argument('--verbose', 51 | action='store_true', 52 | help='Verbose output') 53 | 54 | parser.add_argument('--signal', 55 | default='Wprime', 56 | help = 'String to search for in\ 57 | filenames to indicate a signal file') 58 | 59 | parser.add_argument('--save', 60 | default='output.npy', 61 | help = 'Filename to write out the data.') 62 | parser.add_argument('--plot', 63 | help = 'File prefix that\ 64 | will be part of plotting filenames.') 65 | 66 | parser.add_argument('files', nargs='*', help='Files to pass in') 67 | 68 | args = parser.parse_args() 69 | 70 | if len(args.files) < 1: 71 | logger.error('Must pass at least one file in -- terminating with error.') 72 | exit(1) 73 | 74 | signal_match = args.signal 75 | files = args.files 76 | savefile = args.save 77 | plt_prefix = '' 78 | if args.plot: 79 | plt_prefix = args.plot 80 | 81 | try: 82 | from rootpy.io import root_open 83 | except ImportError: 84 | raise ImportError('rootpy (www.rootpy.org) not installed\ 85 | -- install, then try again!') 86 | 87 | pix_per_side = -999 88 | entries = [] 89 | for fname in files: 90 | logger.info('working on file: {}'.format(fname)) 91 | with root_open(fname) as f: 92 | df = f.EventTree.to_array() 93 | 94 | n_entries = df.shape[0] 95 | 96 | pix = df[0]['Intensity'].shape[0] 97 | 98 | if not perfectsquare(pix): 99 | raise ValueError('shape of image array must be square.') 100 | 101 | if (pix_per_side > 1) and (int(np.sqrt(pix)) != pix_per_side): 102 | raise ValueError('all files must have same sized images.') 103 | 104 | pix_per_side = int(np.sqrt(pix)) 105 | 106 | tag = is_signal(fname, signal_match) 107 | for jet_nb, jet in enumerate(df): 108 | if jet_nb % 1000 == 0: 109 | logger.info('processing jet {} of {} for file {}'.format( 110 | jet_nb, n_entries, fname 111 | )) 112 | entries.append( 113 | buffer_to_jet(jet, tag, max_entry=2600, pix=pix_per_side) 114 | ) 115 | 116 | 117 | # -- datatypes for outputted file. 118 | _bufdtype = [('image', 'float64', (pix_per_side, pix_per_side)), 119 | ('signal', float), 120 | ('jet_pt', float), 121 | ('jet_eta', float), 122 | ('jet_phi', float), 123 | ('jet_mass', float), 124 | ('tau_32', float), 125 | ('tau_21', float)] 126 | 127 | df = np.array(entries, dtype=_bufdtype) 128 | logger.info('saving to file: {}'.format(savefile)) 129 | np.save(savefile, df) 130 | 131 | if plt_prefix != '': 132 | logger.info('plotting...') 133 | plot_mean_jet(df[df['signal'] == 0], title="Average Jet Image, Background").savefig(plt_prefix + '_bkg.pdf') 134 | plot_mean_jet(df[df['signal'] == 1], title="Average Jet Image, Signal").savefig(plt_prefix + '_signal.pdf') 135 | -------------------------------------------------------------------------------- /generateEvents.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from multiprocessing import Pool, cpu_count 3 | from numpy import floor 4 | import os 5 | import sys 6 | import argparse 7 | from subprocess import Popen, PIPE, STDOUT 8 | 9 | DEVNULL = open(os.devnull, 'wb') 10 | 11 | def parallel_run(f, parms): 12 | pool = Pool() 13 | ret = pool.map(f, parms) 14 | pool.close(); pool.join() 15 | return ret 16 | 17 | def determine_allocation(n_samples, n_cpus = -1): 18 | if n_cpus < 0: 19 | n_cpus = cpu_count() - 1 20 | if n_cpus > (cpu_count() - 1): 21 | n_cpus = cpu_count() - 1 22 | 23 | allocation = n_cpus * [0] 24 | 25 | if n_samples <= n_cpus: 26 | for i in xrange(0, n_samples): 27 | allocation[i] += 1 28 | return allocation 29 | 30 | per_cpu = int(floor(float(n_samples) / n_cpus)) 31 | 32 | added = 0 33 | to_add = n_samples 34 | 35 | for i in xrange(n_cpus): 36 | if i == (n_cpus - 1): 37 | if added + to_add < n_samples: 38 | to_add = n_samples - added 39 | leftover_allocation = determine_allocation(to_add - per_cpu, n_cpus) 40 | for i in xrange(n_cpus): 41 | allocation[i] += leftover_allocation[i] 42 | to_add = per_cpu 43 | else: 44 | to_add = min(per_cpu, n_samples - added) 45 | allocation[i] += to_add 46 | added += to_add 47 | return allocation 48 | 49 | 50 | def generate_calls(n_events, n_cpus=-1, outfile='gen.root', process='WprimeToWZ_lept', pixels=25, imrange=1, pileup=0, pt_hat_min=100, pt_hat_max = 500, bosonmass=800): 51 | if n_cpus < 0: 52 | n_cpus = cpu_count() - 1 53 | if n_cpus > (cpu_count() - 1): 54 | n_cpus = cpu_count() - 1 55 | print 'Splitting event generation over {} CPUs'.format(n_cpus) 56 | events_per_core = zip(determine_allocation(n_events, n_cpus), range(n_cpus)) 57 | 58 | def _filename_prepare(f): 59 | if f.find('.root') < 0: 60 | return f + '.root' 61 | return f 62 | 63 | lookup = {'ZprimeTottbar' : "1", 64 | 'WprimeToWZ_lept' : "2", 65 | 'WprimeToWZ_had' : "3", 66 | 'QCD' : "4"} 67 | 68 | if n_cpus == 1: 69 | _call = ['./event-gen/event-gen', 70 | '--OutFile', _filename_prepare(outfile), 71 | '--NEvents', str(n_events), 72 | '--Proc', lookup[process], 73 | '--Pixels', str(pixels), 74 | '--Range', str(imrange), 75 | '--Pileup', str(pileup), 76 | '--pThatMin', str(pt_hat_min), 77 | '--pThatMax', str(pt_hat_max), 78 | '--BosonMass', str(bosonmass)] 79 | return [_call] 80 | 81 | 82 | def _generate_call(par): 83 | 84 | try: 85 | _ = lookup[process] 86 | except: 87 | raise ValueError('process can be one of ' + ', '.join(a for a in lookup.keys())) 88 | 89 | _call = ['./event-gen/event-gen', 90 | '--OutFile', _filename_prepare(outfile).replace('.root', '_cpu{}.root'.format(par[1])), 91 | '--NEvents', str(par[0]), 92 | '--Proc', lookup[process], 93 | '--Pixels', str(pixels), 94 | '--Range', str(imrange), 95 | '--Pileup', str(pileup), 96 | '--pThatMin', str(pt_hat_min), 97 | '--pThatMax', str(pt_hat_max), 98 | '--BosonMass', str(bosonmass)] 99 | return _call 100 | 101 | return [_generate_call(c) for c in events_per_core] 102 | 103 | 104 | 105 | 106 | def excecute_call(f): 107 | return Popen(f, stdin=PIPE, stderr=STDOUT) 108 | 109 | 110 | 111 | # 'Can be one of ZprimeTottbar, WprimeToWZ_lept, WprimeToWZ_had, or QCD' 112 | if __name__ == '__main__': 113 | parser = argparse.ArgumentParser() 114 | parser.add_argument('--outfile', type=str, default='events.root') 115 | parser.add_argument('--nevents', type=int, default=1000) 116 | parser.add_argument('--ncpu', type=int, default=-1) 117 | parser.add_argument('--process', type=str, default='WprimeToWZ_lept', help = 'Can be one of ZprimeTottbar, WprimeToWZ_lept, WprimeToWZ_had, or QCD') 118 | parser.add_argument('--pixels', type=int, default=25) 119 | parser.add_argument('--range', type=float, default=1) 120 | parser.add_argument('--pileup', type=int, default=0) 121 | parser.add_argument('--pt_hat_min', type=float, default=100) 122 | parser.add_argument('--pt_hat_max', type=float, default=500) 123 | parser.add_argument('--bosonmass', type=float, default=800) 124 | # parser.add_argument('--verbose', type=float, default=800) 125 | args = parser.parse_args() 126 | 127 | calls = generate_calls(args.nevents, 128 | args.ncpu, 129 | args.outfile, 130 | args.process, 131 | args.pixels, 132 | args.range, 133 | args.pileup, 134 | args.pt_hat_min, 135 | args.pt_hat_max, 136 | args.bosonmass) 137 | 138 | _ = parallel_run(excecute_call, calls) 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /event-gen/Nsubjettiness/MeasureFunction.cc: -------------------------------------------------------------------------------- 1 | // Nsubjettiness Package 2 | // Questions/Comments? jthaler@jthaler.net 3 | // 4 | // Copyright (c) 2011-14 5 | // Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason 6 | // 7 | // $Id: MeasureFunction.cc 670 2014-06-06 01:24:42Z jthaler $ 8 | //---------------------------------------------------------------------- 9 | // This file is part of FastJet contrib. 10 | // 11 | // It is free software; you can redistribute it and/or modify it under 12 | // the terms of the GNU General Public License as published by the 13 | // Free Software Foundation; either version 2 of the License, or (at 14 | // your option) any later version. 15 | // 16 | // It is distributed in the hope that it will be useful, but WITHOUT 17 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 18 | // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 19 | // License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this code. If not, see . 23 | //---------------------------------------------------------------------- 24 | 25 | 26 | #include "MeasureFunction.hh" 27 | 28 | FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 29 | 30 | namespace contrib{ 31 | 32 | /////// 33 | // 34 | // Measure Function 35 | // 36 | /////// 37 | 38 | // Return all of the necessary TauComponents for specific input particles and axes 39 | TauComponents MeasureFunction::result(const std::vector& particles, const std::vector& axes) const { 40 | 41 | // first find partition 42 | // this sets jetPartitionStorage and beamPartitionStorage 43 | PseudoJet beamPartitionStorage; 44 | std::vector jetPartitionStorage = get_partition(particles,axes,&beamPartitionStorage); 45 | 46 | // then return result calculated from partition 47 | return result_from_partition(jetPartitionStorage,axes,&beamPartitionStorage); 48 | } 49 | 50 | std::vector MeasureFunction::get_partition(const std::vector& particles, 51 | const std::vector& axes, 52 | PseudoJet * beamPartitionStorage) const { 53 | 54 | std::vector > jetPartition(axes.size()); 55 | std::vector beamPartition; 56 | 57 | // Figures out the partiting of the input particles into the various jet pieces 58 | // Based on which axis the parition is closest to 59 | for (unsigned i = 0; i < particles.size(); i++) { 60 | 61 | // find minimum distance; start with beam (-1) for reference 62 | int j_min = -1; 63 | double minRsq; 64 | if (_has_beam) minRsq = beam_distance_squared(particles[i]); 65 | else minRsq = std::numeric_limits::max(); // make it large value 66 | 67 | // check to see which axis the particle is closest to 68 | for (unsigned j = 0; j < axes.size(); j++) { 69 | double tempRsq = jet_distance_squared(particles[i],axes[j]); // delta R distance 70 | if (tempRsq < minRsq) { 71 | minRsq = tempRsq; 72 | j_min = j; 73 | } 74 | } 75 | 76 | if (j_min == -1) { 77 | if (_has_beam) beamPartition.push_back(particles[i]); 78 | else assert(_has_beam); // this should never happen. 79 | } else { 80 | jetPartition[j_min].push_back(particles[i]); 81 | } 82 | } 83 | 84 | // Store beam partition 85 | if (beamPartitionStorage) { 86 | *beamPartitionStorage = join(beamPartition); 87 | } 88 | 89 | // Store jet partitions 90 | std::vector jetPartitionStorage(axes.size(),PseudoJet(0,0,0,0)); 91 | for (unsigned j = 0; j < axes.size(); j++) { 92 | jetPartitionStorage[j] = join(jetPartition[j]); 93 | } 94 | 95 | return jetPartitionStorage; 96 | } 97 | 98 | // does partition, but only stores index of PseudoJets 99 | std::vector > MeasureFunction::get_partition_list(const std::vector& particles, 100 | const std::vector& axes) const { 101 | 102 | std::vector > jetPartition(axes.size()); 103 | 104 | // Figures out the partiting of the input particles into the various jet pieces 105 | // Based on which axis the parition is closest to 106 | for (unsigned i = 0; i < particles.size(); i++) { 107 | 108 | // find minimum distance; start with beam (-1) for reference 109 | int j_min = -1; 110 | double minRsq; 111 | if (_has_beam) minRsq = beam_distance_squared(particles[i]); 112 | else minRsq = std::numeric_limits::max(); // make it large value 113 | 114 | // check to see which axis the particle is closest to 115 | for (unsigned j = 0; j < axes.size(); j++) { 116 | double tempRsq = jet_distance_squared(particles[i],axes[j]); // delta R distance 117 | if (tempRsq < minRsq) { 118 | minRsq = tempRsq; 119 | j_min = j; 120 | } 121 | } 122 | 123 | if (j_min == -1) { 124 | assert(_has_beam); // consistency check 125 | } else { 126 | jetPartition[j_min].push_back(i); 127 | } 128 | } 129 | 130 | return jetPartition; 131 | } 132 | 133 | 134 | // Uses existing partition and calculates result 135 | // TODO: Can we cache this for speed up when doing area subtraction? 136 | TauComponents MeasureFunction::result_from_partition(const std::vector& jet_partition, 137 | const std::vector& axes, 138 | PseudoJet * beamPartitionStorage) const { 139 | 140 | std::vector jetPieces(axes.size(), 0.0); 141 | double beamPiece = 0.0; 142 | 143 | double tauDen = 0.0; 144 | if (!_has_denominator) tauDen = 1.0; // if no denominator, then 1.0 for no normalization factor 145 | 146 | // first find jet pieces 147 | for (unsigned j = 0; j < axes.size(); j++) { 148 | std::vector thisPartition = jet_partition[j].constituents(); 149 | for (unsigned i = 0; i < thisPartition.size(); i++) { 150 | jetPieces[j] += jet_numerator(thisPartition[i],axes[j]); //numerator jet piece 151 | if (_has_denominator) tauDen += denominator(thisPartition[i]); // denominator 152 | } 153 | } 154 | 155 | // then find beam piece 156 | if (_has_beam) { 157 | assert(beamPartitionStorage); // make sure I have beam information 158 | std::vector beamPartition = beamPartitionStorage->constituents(); 159 | 160 | for (unsigned i = 0; i < beamPartition.size(); i++) { 161 | beamPiece += beam_numerator(beamPartition[i]); //numerator beam piece 162 | if (_has_denominator) tauDen += denominator(beamPartition[i]); // denominator 163 | } 164 | } 165 | return TauComponents(jetPieces, beamPiece, tauDen, _has_denominator, _has_beam); 166 | } 167 | 168 | 169 | 170 | 171 | 172 | } //namespace contrib 173 | 174 | FASTJET_END_NAMESPACE 175 | -------------------------------------------------------------------------------- /event-gen/Nsubjettiness/example_basic_usage.ref: -------------------------------------------------------------------------------- 1 | # read an event with 354 particles 2 | #-------------------------------------------------------------------------- 3 | # FastJet release 3.0.6 4 | # M. Cacciari, G.P. Salam and G. Soyez 5 | # A software package for jet finding and analysis at colliders 6 | # http://fastjet.fr 7 | # 8 | # Please cite EPJC72(2012)1896 [arXiv:1111.6097] if you use this package 9 | # for scientific work and optionally PLB641(2006)57 [hep-ph/0512210]. 10 | # 11 | # FastJet is provided without warranty under the terms of the GNU GPLv2. 12 | # It uses T. Chan's closest pair algorithm, S. Fortune's Voronoi code 13 | # and 3rd party plugin jet algorithms. See COPYING file for details. 14 | #-------------------------------------------------------------------------- 15 | ------------------------------------------------------------------------------------- 16 | Analyzing Jet 1: 17 | ------------------------------------------------------------------------------------- 18 | ------------------------------------------------------------------------------------- 19 | N-subjettiness with Unnormalized Measure (in GeV) 20 | beta = 1.0: One-pass Winner-Take-All kT Axes 21 | beta = 2.0: One-pass E-Scheme kT Axes 22 | ------------------------------------------------------------------------------------- 23 | ------------------------------------------------------------------------------------- 24 | beta tau1 tau2 tau3 tau2/tau1 tau3/tau2 25 | 1.000000 11.804760 9.219812 6.725069 0.781025 0.729415 26 | 2.000000 1.293815 0.827980 0.756863 0.639953 0.914107 27 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 28 | Subjets found using beta = 1.0 tau values 29 | jet # rap phi pt m e constit tau1 30 | 1 -0.8673 2.9051 983.3873 39.9912 1378.1622 35 11.804760 31 | total -0.8673 2.9051 983.3873 39.9912 1378.1622 35 11.804760 32 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 33 | jet # rap phi pt m e constit tau2 34 | 1 -0.7959 2.8213 36.9260 4.1240 49.5577 14 2.024139 35 | 2 -0.8701 2.9084 946.5959 25.7449 1328.6045 21 7.195672 36 | total -0.8673 2.9051 983.3873 39.9912 1378.1622 35 9.219812 37 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 38 | jet # rap phi pt m e constit tau3 39 | 1 -0.8900 2.9133 149.6693 8.2524 213.2875 10 1.052931 40 | 2 -0.8664 2.9075 796.9288 11.6617 1115.3170 11 3.647998 41 | 3 -0.7959 2.8213 36.9260 4.1240 49.5577 14 2.024139 42 | total -0.8673 2.9051 983.3873 39.9912 1378.1622 35 6.725069 43 | ------------------------------------------------------------------------------------- 44 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 45 | Axes used for above beta = 1.0 tau values 46 | jet # rap phi pt m e tau1 47 | 1 -0.8679 2.9071 983.3836 0.0000 1377.5818 11.804760 48 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 49 | jet # rap phi pt m e tau2 50 | 1 -0.8223 2.8273 36.3776 0.0000 49.3858 2.024139 51 | 2 -0.8670 2.9082 948.8123 0.0000 1328.3550 7.195672 52 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 53 | jet # rap phi pt m e tau3 54 | 1 -0.8882 2.9123 149.9765 0.0000 213.1278 1.052931 55 | 2 -0.8670 2.9082 796.6396 0.0000 1115.2561 3.647998 56 | 3 -0.8223 2.8273 36.3776 0.0000 49.3858 2.024139 57 | ------------------------------------------------------------------------------------- 58 | ------------------------------------------------------------------------------------- 59 | Analyzing Jet 2: 60 | ------------------------------------------------------------------------------------- 61 | ------------------------------------------------------------------------------------- 62 | N-subjettiness with Unnormalized Measure (in GeV) 63 | beta = 1.0: One-pass Winner-Take-All kT Axes 64 | beta = 2.0: One-pass E-Scheme kT Axes 65 | ------------------------------------------------------------------------------------- 66 | ------------------------------------------------------------------------------------- 67 | beta tau1 tau2 tau3 tau2/tau1 tau3/tau2 68 | 1.000000 16.052840 12.479353 10.253741 0.777392 0.821656 69 | 2.000000 6.953861 3.804487 3.737265 0.547104 0.982331 70 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 71 | Subjets found using beta = 1.0 tau values 72 | jet # rap phi pt m e constit tau1 73 | 1 0.2195 6.0349 908.0979 87.7124 934.3868 47 16.052840 74 | total 0.2195 6.0349 908.0979 87.7124 934.3868 47 16.052840 75 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 76 | jet # rap phi pt m e constit tau2 77 | 1 0.2716 0.3354 8.9852 3.7341 10.0912 15 2.078777 78 | 2 0.2189 6.0294 900.6142 59.5448 924.2956 32 10.400576 79 | total 0.2195 6.0349 908.0979 87.7124 934.3868 47 12.479353 80 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 81 | jet # rap phi pt m e constit tau3 82 | 1 -0.1831 5.9784 10.1884 3.5582 10.9733 8 2.314550 83 | 2 0.2239 6.0300 890.4392 28.4501 913.3223 24 5.860407 84 | 3 0.2716 0.3354 8.9852 3.7341 10.0912 15 2.078784 85 | total 0.2195 6.0349 908.0979 87.7124 934.3868 47 10.253741 86 | ------------------------------------------------------------------------------------- 87 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 88 | Axes used for above beta = 1.0 tau values 89 | jet # rap phi pt m e tau1 90 | 1 0.2214 6.0293 907.9230 0.0000 930.2608 16.052840 91 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 92 | jet # rap phi pt m e tau2 93 | 1 0.2222 0.3213 9.1481 0.0000 9.3749 2.078777 94 | 2 0.2214 6.0293 900.2269 0.0000 922.3756 10.400576 95 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 96 | jet # rap phi pt m e tau3 97 | 1 -0.0366 5.9036 10.3734 0.0000 10.3804 2.314550 98 | 2 0.2214 6.0293 890.9582 0.0000 912.8791 5.860407 99 | 3 0.2226 0.3214 9.1473 0.0000 9.3749 2.078784 100 | ------------------------------------------------------------------------------------- 101 | -------------------------------------------------------------------------------- /event-gen/Nsubjettiness/NjettinessPlugin.hh: -------------------------------------------------------------------------------- 1 | // Nsubjettiness Package 2 | // Questions/Comments? jthaler@jthaler.net 3 | // 4 | // Copyright (c) 2011-14 5 | // Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason 6 | // 7 | // $Id: NjettinessPlugin.hh 671 2014-06-10 17:47:52Z jthaler $ 8 | //---------------------------------------------------------------------- 9 | // This file is part of FastJet contrib. 10 | // 11 | // It is free software; you can redistribute it and/or modify it under 12 | // the terms of the GNU General Public License as published by the 13 | // Free Software Foundation; either version 2 of the License, or (at 14 | // your option) any later version. 15 | // 16 | // It is distributed in the hope that it will be useful, but WITHOUT 17 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 18 | // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 19 | // License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this code. If not, see . 23 | //---------------------------------------------------------------------- 24 | 25 | #ifndef __FASTJET_CONTRIB_NJETTINESSPLUGIN_HH__ 26 | #define __FASTJET_CONTRIB_NJETTINESSPLUGIN_HH__ 27 | 28 | #include "Njettiness.hh" 29 | #include "MeasureFunction.hh" 30 | #include "AxesFinder.hh" 31 | 32 | #include "fastjet/ClusterSequence.hh" 33 | #include "fastjet/JetDefinition.hh" 34 | 35 | #include 36 | #include 37 | 38 | FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 39 | 40 | 41 | namespace contrib { 42 | 43 | //------------------------------------------------------------------------ 44 | /// \class NjettinessExtras 45 | // This class contains the same information as Njettiness, but redoes it in terms of the ClusterSequence::Extras class. 46 | // This is done in order to help improve the interface for the main NjettinessPlugin class. 47 | // TODO: This class should probably be merged with TauComponents, since both have access 48 | // to similar information 49 | class NjettinessExtras : public ClusterSequence::Extras { 50 | 51 | public: 52 | NjettinessExtras(TauComponents tau_components, std::vector jets, std::vector axes) : _tau_components(tau_components), _jets(jets), _axes(axes) {} 53 | 54 | double totalTau() const {return _tau_components.tau();} 55 | std::vector subTaus() const {return _tau_components.jet_pieces();} 56 | std::vector jets() const {return _jets;} 57 | std::vector axes() const {return _axes;} 58 | 59 | double totalTau(const fastjet::PseudoJet& /*jet*/) const { 60 | return _tau_components.tau(); 61 | } 62 | 63 | double subTau(const fastjet::PseudoJet& jet) const { 64 | if (labelOf(jet) == -1) return std::numeric_limits::quiet_NaN(); // nonsense 65 | return _tau_components.jet_pieces()[labelOf(jet)]; 66 | } 67 | 68 | double beamTau() const { 69 | return _tau_components.beam_piece(); 70 | } 71 | 72 | fastjet::PseudoJet axis(const fastjet::PseudoJet& jet) const { 73 | return _axes[labelOf(jet)]; 74 | } 75 | 76 | bool has_njettiness_extras(const fastjet::PseudoJet& jet) const { 77 | return (labelOf(jet) >= 0); 78 | } 79 | 80 | private: 81 | 82 | TauComponents _tau_components; 83 | std::vector _jets; 84 | std::vector _axes; 85 | 86 | int labelOf(const fastjet::PseudoJet& jet) const { 87 | int thisJet = -1; 88 | for (unsigned int i = 0; i < _jets.size(); i++) { 89 | if (_jets[i].cluster_hist_index() == jet.cluster_hist_index()) { 90 | thisJet = i; 91 | break; 92 | } 93 | } 94 | return thisJet; 95 | } 96 | }; 97 | 98 | inline const NjettinessExtras * njettiness_extras(const fastjet::PseudoJet& jet) { 99 | const ClusterSequence * myCS = jet.associated_cluster_sequence(); 100 | if (myCS == NULL) return NULL; 101 | const NjettinessExtras* extras = dynamic_cast(myCS->extras()); 102 | return extras; 103 | } 104 | 105 | inline const NjettinessExtras * njettiness_extras(const fastjet::ClusterSequence& myCS) { 106 | const NjettinessExtras* extras = dynamic_cast(myCS.extras()); 107 | return extras; 108 | } 109 | 110 | /// The Njettiness jet algorithm 111 | /** 112 | * An exclusive jet finder that identifies N jets; first N axes are found, then 113 | * particles are assigned to the nearest (DeltaR) axis and for each axis the 114 | * corresponding jet is simply the four-momentum sum of these particles. 115 | * 116 | * Axes can be found in several ways, specified by the AxesMode argument. The 117 | * recommended choices are 118 | * 119 | * kt_axes : exclusive kT 120 | * wta_kt_axes : exclusive kT with winner-take-all-recombination 121 | * onepass_kt_axes : one-pass minimization seeded by kt (pretty good) 122 | * onepass_wta_kt_axes : one-pass minimization seeded by wta_kt 123 | * 124 | * For the UnnormalizedMeasure(beta), N-jettiness is defined as: 125 | * 126 | * tau_N = Sum_{all particles i} p_T^i min((DR_i1)^beta, (DR_i2)^beta, ...) 127 | * 128 | * DR_ij is the distance sqrt(Delta_phi^2 + Delta_rap^2) between particle i 129 | * and jet j. 130 | * 131 | * The NormalizedMeausure include an extra parameter R0, and the various cutoff 132 | * measures include an Rcutoff, which effectively defines an angular cutoff 133 | * similar in effect to a cone-jet radius. 134 | * 135 | */ 136 | 137 | class NjettinessPlugin : public JetDefinition::Plugin { 138 | public: 139 | 140 | // Constructor with same arguments as Nsubjettiness. 141 | NjettinessPlugin(int N, 142 | const AxesDefinition & axes_def, 143 | const MeasureDefinition & measure_def) 144 | : _njettinessFinder(axes_def, measure_def), _N(N) {} 145 | 146 | 147 | // Alternative constructors that define the measure via enums and parameters 148 | // These constructors are likely be removed 149 | NjettinessPlugin(int N, 150 | Njettiness::AxesMode axes_mode, 151 | Njettiness::MeasureMode measure_mode) 152 | : _njettinessFinder(axes_mode, measure_mode, 0), _N(N) {} 153 | 154 | 155 | NjettinessPlugin(int N, 156 | Njettiness::AxesMode axes_mode, 157 | Njettiness::MeasureMode measure_mode, 158 | double para1) 159 | : _njettinessFinder(axes_mode, measure_mode, 1, para1), _N(N) {} 160 | 161 | 162 | NjettinessPlugin(int N, 163 | Njettiness::AxesMode axes_mode, 164 | Njettiness::MeasureMode measure_mode, 165 | double para1, 166 | double para2) 167 | : _njettinessFinder(axes_mode, measure_mode, 2, para1, para2), _N(N) {} 168 | 169 | 170 | NjettinessPlugin(int N, 171 | Njettiness::AxesMode axes_mode, 172 | Njettiness::MeasureMode measure_mode, 173 | double para1, 174 | double para2, 175 | double para3) 176 | : _njettinessFinder(axes_mode, measure_mode, 3, para1, para2, para3), _N(N) {} 177 | 178 | 179 | // Old constructor for backwards compatibility with v1.0, 180 | // where NormalizedCutoffMeasure was the only option 181 | NjettinessPlugin(int N, 182 | Njettiness::AxesMode mode, 183 | double beta, 184 | double R0, 185 | double Rcutoff=std::numeric_limits::max()) 186 | : _njettinessFinder(mode, NormalizedCutoffMeasure(beta, R0, Rcutoff)), _N(N) {} 187 | 188 | 189 | 190 | // The things that are required by base class. 191 | virtual std::string description () const; 192 | virtual double R() const {return -1.0;} // TODO: make this not stupid 193 | virtual void run_clustering(ClusterSequence&) const; 194 | 195 | virtual ~NjettinessPlugin() {} 196 | 197 | private: 198 | 199 | Njettiness _njettinessFinder; 200 | int _N; 201 | 202 | }; 203 | 204 | } // namespace contrib 205 | 206 | FASTJET_END_NAMESPACE 207 | 208 | #endif // __FASTJET_CONTRIB_NJETTINESSPLUGIN_HH__ -------------------------------------------------------------------------------- /event-gen/src/MI.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "TString.h" 11 | #include "TSystem.h" 12 | #include "TError.h" 13 | //#include "TPythia8.h" 14 | #include "TClonesArray.h" 15 | #include "TParticle.h" 16 | #include "TDatabasePDG.h" 17 | 18 | #include "fastjet/PseudoJet.hh" 19 | #include "fastjet/ClusterSequence.hh" 20 | #include "fastjet/Selector.hh" 21 | 22 | #include "Pythia8/Pythia.h" 23 | 24 | #include "MITools.h" 25 | #include "MIAnalysis.h" 26 | 27 | // #include "boost/program_options.hpp" 28 | 29 | #include "parser.hh" 30 | 31 | 32 | 33 | 34 | using std::cout; 35 | using std::endl; 36 | using std::string; 37 | using std::map; 38 | using namespace std; 39 | 40 | int getSeed(int seed) 41 | { 42 | if (seed > -1) 43 | { 44 | return seed; 45 | } 46 | int timeSeed = time(NULL); 47 | return abs(((timeSeed*181)*((getpid()-83)*359))%104729); 48 | } 49 | 50 | int main(int argc, const char* argv[]) 51 | { 52 | // argument parsing ------------------------ 53 | cout << "Called as: "; 54 | 55 | for(int ii = 0; ii < argc; ++ii) 56 | { 57 | cout << argv[ii] << " "; 58 | } 59 | cout << endl; 60 | 61 | // agruments 62 | string outName = "MI.root"; 63 | int pileup = 0; 64 | int nEvents = 0; 65 | int pixels = 25; 66 | int fDebug = 0; 67 | float pThatmin = 100; 68 | float pThatmax = 500; 69 | float boson_mass = 1500; 70 | float image_range = 1.0; 71 | int proc = 1; 72 | int seed = -1; 73 | 74 | optionparser::parser parser("Allowed options"); 75 | 76 | parser.add_option("--NEvents").mode(optionparser::store_value).default_value(10).help("Number of Events"); 77 | parser.add_option("--Pixels").mode(optionparser::store_value).default_value(25).help("Number of pixels per dimension"); 78 | parser.add_option("--Range").mode(optionparser::store_value).default_value(1).help("Image captures [-w, w] x [-w, w], where w is the value passed."); 79 | parser.add_option("--Debug").mode(optionparser::store_value).default_value(0).help("Debug flag"); 80 | parser.add_option("--Pileup").mode(optionparser::store_value).default_value(0).help("Number of Additional Interactions"); 81 | parser.add_option("--OutFile").mode(optionparser::store_value).default_value("test.root").help("output file name"); 82 | parser.add_option("--Proc").mode(optionparser::store_value).default_value(2).help("Process: 1=ZprimeTottbar, 2=WprimeToWZ_lept, 3=WprimeToWZ_had, 4=QCD"); 83 | parser.add_option("--Seed").mode(optionparser::store_value).default_value(-1).help("seed. -1 means random seed"); 84 | parser.add_option("--pThatMin").mode(optionparser::store_value).default_value(100).help("pThatMin for QCD"); 85 | parser.add_option("--pThatMax").mode(optionparser::store_value).default_value(500).help("pThatMax for QCD"); 86 | parser.add_option("--BosonMass").mode(optionparser::store_value).default_value(800).help("Z' or W' mass in GeV"); 87 | 88 | parser.eat_arguments(argc, argv); 89 | 90 | nEvents = parser.get_value("NEvents"); 91 | pixels = parser.get_value("Pixels"); 92 | image_range = parser.get_value("Range"); 93 | fDebug = parser.get_value("Debug"); 94 | pileup = parser.get_value("Pileup"); 95 | outName = parser.get_value("OutFile"); 96 | proc = parser.get_value("Proc"); 97 | seed = parser.get_value("Seed"); 98 | pThatmin = parser.get_value("pThatMin"); 99 | pThatmax = parser.get_value("pThatMax"); 100 | boson_mass = parser.get_value("BosonMass"); 101 | 102 | 103 | //seed 104 | seed = getSeed(seed); 105 | 106 | // Configure and initialize pythia 107 | Pythia8::Pythia* pythia8 = new Pythia8::Pythia(); 108 | 109 | pythia8->readString("Random:setSeed = on"); 110 | std::stringstream ss; ss << "Random:seed = " << seed; 111 | cout << ss.str() << endl; 112 | pythia8->readString(ss.str()); 113 | 114 | pythia8->readString("Next:numberShowInfo = 0"); 115 | pythia8->readString("Next:numberShowEvent = 0"); 116 | pythia8->readString("Next:numberShowLHA = 0"); 117 | pythia8->readString("Next:numberShowProcess = 0"); 118 | 119 | if(proc == 1) 120 | { 121 | std::stringstream bosonmass_str; bosonmass_str<< "32:m0=" << boson_mass ; 122 | pythia8->readString(bosonmass_str.str()); 123 | pythia8->readString("NewGaugeBoson:ffbar2gmZZprime= on"); 124 | pythia8->readString("Zprime:gmZmode=3"); 125 | pythia8->readString("32:onMode = off"); 126 | pythia8->readString("32:onIfAny = 6"); 127 | pythia8->readString("24:onMode = off"); 128 | pythia8->readString("24:onIfAny = 1 2 3 4"); 129 | pythia8->init(); 130 | } 131 | else if(proc == 2) 132 | { 133 | std::stringstream bosonmass_str; bosonmass_str<< "34:m0=" << boson_mass ; 134 | pythia8->readString(bosonmass_str.str()); 135 | pythia8->readString("NewGaugeBoson:ffbar2Wprime = on"); 136 | pythia8->readString("Wprime:coup2WZ=1"); 137 | pythia8->readString("34:onMode = off"); 138 | pythia8->readString("34:onIfAny = 23 24"); 139 | pythia8->readString("24:onMode = off"); 140 | pythia8->readString("24:onIfAny = 1 2 3 4"); 141 | pythia8->readString("23:onMode = off"); 142 | pythia8->readString("23:onIfAny = 12"); 143 | pythia8->init(); 144 | } 145 | else if(proc == 3) 146 | { 147 | std::stringstream bosonmass_str; bosonmass_str<< "34:m0=" << boson_mass ; 148 | pythia8->readString(bosonmass_str.str()); 149 | pythia8->readString("NewGaugeBoson:ffbar2Wprime = on"); 150 | pythia8->readString("Wprime:coup2WZ=1"); 151 | pythia8->readString("34:onMode = off"); 152 | pythia8->readString("34:onIfAny = 23 24"); 153 | pythia8->readString("24:onMode = off"); 154 | pythia8->readString("24:onIfAny = 11 12"); 155 | pythia8->readString("23:onMode = off"); 156 | pythia8->readString("23:onIfAny = 1 2 3 4 5"); 157 | pythia8->init(); 158 | } 159 | else if(proc == 4) 160 | { 161 | pythia8->readString("HardQCD:all = on"); 162 | std::stringstream ptHatMin; 163 | std::stringstream ptHatMax; 164 | ptHatMin << "PhaseSpace:pTHatMin =" << pThatmin; 165 | ptHatMax << "PhaseSpace:pTHatMax =" << pThatmax; 166 | pythia8->readString(ptHatMin.str()); 167 | pythia8->readString(ptHatMax.str()); 168 | pythia8->init(); 169 | } 170 | else 171 | { 172 | throw std::invalid_argument("received invalid 'process'"); 173 | } 174 | 175 | //Setup the pileup 176 | Pythia8::Pythia* pythia_MB = new Pythia8::Pythia(); 177 | pythia_MB->readString("Random:setSeed = on"); 178 | ss.clear(); ss.str(""); ss << "Random:seed = " << seed+1; 179 | cout << ss.str() << endl; 180 | pythia_MB->readString(ss.str()); 181 | pythia_MB->readString("SoftQCD:nonDiffractive = on"); 182 | pythia_MB->readString("HardQCD:all = off"); 183 | pythia_MB->readString("PhaseSpace:pTHatMin = .1"); 184 | pythia_MB->readString("PhaseSpace:pTHatMax = 20000"); 185 | pythia_MB->init(); 186 | 187 | MIAnalysis * analysis = new MIAnalysis(pixels); 188 | analysis->SetOutName(outName); 189 | analysis->Begin(); 190 | analysis->Debug(fDebug); 191 | 192 | std::cout << pileup << " is the number of pileu pevents " << std::endl; 193 | 194 | // Event loop 195 | for (Int_t iev = 0; iev < nEvents; iev++) 196 | { 197 | if (iev%1000==0) 198 | { 199 | std::cout << "Generating event number " << iev << std::endl; 200 | } 201 | analysis->AnalyzeEvent(iev, pythia8, pythia_MB, pileup, pixels, image_range); 202 | } 203 | 204 | analysis->End(); 205 | 206 | // that was it 207 | delete pythia8; 208 | delete analysis; 209 | 210 | return 0; 211 | } 212 | -------------------------------------------------------------------------------- /event-gen/Nsubjettiness/Njettiness.cc: -------------------------------------------------------------------------------- 1 | // Nsubjettiness Package 2 | // Questions/Comments? jthaler@jthaler.net 3 | // 4 | // Copyright (c) 2011-14 5 | // Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason 6 | // 7 | // $Id: Njettiness.cc 677 2014-06-12 18:56:46Z jthaler $ 8 | //---------------------------------------------------------------------- 9 | // This file is part of FastJet contrib. 10 | // 11 | // It is free software; you can redistribute it and/or modify it under 12 | // the terms of the GNU General Public License as published by the 13 | // Free Software Foundation; either version 2 of the License, or (at 14 | // your option) any later version. 15 | // 16 | // It is distributed in the hope that it will be useful, but WITHOUT 17 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 18 | // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 19 | // License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this code. If not, see . 23 | //---------------------------------------------------------------------- 24 | 25 | #include "Njettiness.hh" 26 | 27 | FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 28 | 29 | namespace contrib { 30 | 31 | 32 | /////// 33 | // 34 | // Main Njettiness Class 35 | // 36 | /////// 37 | 38 | Njettiness::Njettiness(const AxesDefinition & axes_def, const MeasureDefinition & measure_def) 39 | : _axes_def(axes_def.create()), _measure_def(measure_def.create()) { 40 | setMeasureFunctionAndAxesFinder(); // call helper function to do the hard work 41 | } 42 | 43 | Njettiness::Njettiness(AxesMode axes_mode, const MeasureDefinition & measure_def) 44 | : _axes_def(createAxesDef(axes_mode)), _measure_def(measure_def.create()) { 45 | setMeasureFunctionAndAxesFinder(); // call helper function to do the hard work 46 | } 47 | 48 | // Convert from MeasureMode enum to MeasureDefinition 49 | // This returns a pointer that will be claimed by a SharedPtr 50 | MeasureDefinition* Njettiness::createMeasureDef(MeasureMode measure_mode, int num_para, double para1, double para2, double para3) const { 51 | 52 | // definition of maximum Rcutoff for non-cutoff measures, changed later by other measures 53 | double Rcutoff = std::numeric_limits::max(); //large number 54 | // Most (but not all) measures have some kind of beta value 55 | double beta = std::numeric_limits::quiet_NaN(); 56 | // The normalized measures have an R0 value. 57 | double R0 = std::numeric_limits::quiet_NaN(); 58 | 59 | // Find the MeasureFunction and set the parameters. 60 | switch (measure_mode) { 61 | case normalized_measure: 62 | beta = para1; 63 | R0 = para2; 64 | if(num_para == 2) { 65 | return new NormalizedMeasure(beta,R0); 66 | } else { 67 | throw Error("normalized_measure needs 2 parameters (beta and R0)"); 68 | } 69 | break; 70 | case unnormalized_measure: 71 | beta = para1; 72 | if(num_para == 1) { 73 | return new UnnormalizedMeasure(beta); 74 | } else { 75 | throw Error("unnormalized_measure needs 1 parameter (beta)"); 76 | } 77 | break; 78 | case geometric_measure: 79 | beta = para1; 80 | if (num_para == 1) { 81 | return new GeometricMeasure(beta); 82 | } else { 83 | throw Error("geometric_measure needs 1 parameter (beta)"); 84 | } 85 | break; 86 | case normalized_cutoff_measure: 87 | beta = para1; 88 | R0 = para2; 89 | Rcutoff = para3; //Rcutoff parameter is 3rd parameter in normalized_cutoff_measure 90 | if (num_para == 3) { 91 | return new NormalizedCutoffMeasure(beta,R0,Rcutoff); 92 | } else { 93 | throw Error("normalized_cutoff_measure has 3 parameters (beta, R0, Rcutoff)"); 94 | } 95 | break; 96 | case unnormalized_cutoff_measure: 97 | beta = para1; 98 | Rcutoff = para2; //Rcutoff parameter is 2nd parameter in normalized_cutoff_measure 99 | if (num_para == 2) { 100 | return new UnnormalizedCutoffMeasure(beta,Rcutoff); 101 | } else { 102 | throw Error("unnormalized_cutoff_measure has 2 parameters (beta, Rcutoff)"); 103 | } 104 | break; 105 | case geometric_cutoff_measure: 106 | beta = para1; 107 | Rcutoff = para2; //Rcutoff parameter is 2nd parameter in geometric_cutoff_measure 108 | if(num_para == 2) { 109 | return new GeometricCutoffMeasure(beta,Rcutoff); 110 | } else { 111 | throw Error("geometric_cutoff_measure has 2 parameters (beta, Rcutoff)"); 112 | } 113 | break; 114 | default: 115 | assert(false); 116 | break; 117 | } 118 | return NULL; 119 | } 120 | 121 | // Convert from AxesMode enum to AxesDefinition 122 | // This returns a pointer that will be claimed by a SharedPtr 123 | AxesDefinition* Njettiness::createAxesDef(Njettiness::AxesMode axes_mode) const { 124 | 125 | switch (axes_mode) { 126 | case wta_kt_axes: 127 | return new WTA_KT_Axes(); 128 | case wta_ca_axes: 129 | return new WTA_CA_Axes(); 130 | case kt_axes: 131 | return new KT_Axes(); 132 | case ca_axes: 133 | return new CA_Axes(); 134 | case antikt_0p2_axes: 135 | return new AntiKT_Axes(0.2); 136 | case onepass_wta_kt_axes: 137 | return new OnePass_WTA_KT_Axes(); 138 | case onepass_wta_ca_axes: 139 | return new OnePass_WTA_CA_Axes(); 140 | case onepass_kt_axes: 141 | return new OnePass_KT_Axes(); 142 | case onepass_ca_axes: 143 | return new OnePass_CA_Axes(); 144 | case onepass_antikt_0p2_axes: 145 | return new OnePass_AntiKT_Axes(0.2); 146 | case onepass_manual_axes: 147 | return new OnePass_Manual_Axes(); 148 | case min_axes: 149 | return new MultiPass_Axes(100); 150 | case manual_axes: 151 | return new Manual_Axes(); 152 | default: 153 | assert(false); 154 | return NULL; 155 | } 156 | } 157 | 158 | 159 | // Parsing needed for constructor to set AxesFinder and MeasureFunction 160 | // All of the parameter handling is here, and checking that number of parameters is correct. 161 | void Njettiness::setMeasureFunctionAndAxesFinder() { 162 | // Get the correct MeasureFunction and AxesFinders 163 | _measureFunction.reset(_measure_def->createMeasureFunction()); 164 | _startingAxesFinder.reset(_axes_def->createStartingAxesFinder(*_measure_def)); 165 | _finishingAxesFinder.reset(_axes_def->createFinishingAxesFinder(*_measure_def)); 166 | } 167 | 168 | // setAxes for Manual mode 169 | void Njettiness::setAxes(const std::vector & myAxes) { 170 | if (_axes_def->supportsManualAxes()) { 171 | _currentAxes = myAxes; 172 | } else { 173 | throw Error("You can only use setAxes for manual AxesDefinitions"); 174 | } 175 | } 176 | 177 | // Calculates and returns all TauComponents that user would want. 178 | // This information is stored in _current_tau_components for later access as well. 179 | TauComponents Njettiness::getTauComponents(unsigned n_jets, const std::vector & inputJets) const { 180 | if (inputJets.size() <= n_jets) { //if not enough particles, return zero 181 | _currentAxes = inputJets; 182 | _currentAxes.resize(n_jets,fastjet::PseudoJet(0.0,0.0,0.0,0.0)); 183 | _current_tau_components = TauComponents(); 184 | _seedAxes = _currentAxes; 185 | _currentJets = _currentAxes; 186 | _currentBeam = PseudoJet(0.0,0.0,0.0,0.0); 187 | } else { 188 | 189 | _seedAxes = _startingAxesFinder->getAxes(n_jets,inputJets,_currentAxes); //sets starting point for minimization 190 | if (_finishingAxesFinder) { 191 | _currentAxes = _finishingAxesFinder->getAxes(n_jets,inputJets,_seedAxes); 192 | } else { 193 | _currentAxes = _seedAxes; 194 | } 195 | 196 | // Find partition and store information 197 | // (jet information in _currentJets, beam in _currentBeam) 198 | _currentJets = _measureFunction->get_partition(inputJets,_currentAxes,&_currentBeam); 199 | 200 | // Find tau value and store information 201 | _current_tau_components = _measureFunction->result_from_partition(_currentJets, _currentAxes,&_currentBeam); // sets current Tau Values 202 | } 203 | return _current_tau_components; 204 | } 205 | 206 | 207 | // Partition a list of particles according to which N-jettiness axis they are closest to. 208 | // Return a vector of length _currentAxes.size() (which should be N). 209 | // Each vector element is a list of ints corresponding to the indices in 210 | // particles of the particles belonging to that jet. 211 | std::vector > Njettiness::getPartitionList(const std::vector & particles) const { 212 | // core code is in MeasureFunction 213 | return _measureFunction->get_partition_list(particles,_currentAxes); 214 | } 215 | 216 | 217 | } // namespace contrib 218 | 219 | FASTJET_END_NAMESPACE 220 | -------------------------------------------------------------------------------- /event-gen/Nsubjettiness/example_v1p0p3.ref: -------------------------------------------------------------------------------- 1 | # read an event with 354 particles 2 | #-------------------------------------------------------------------------- 3 | # FastJet release 3.0.3 4 | # M. Cacciari, G.P. Salam and G. Soyez 5 | # A software package for jet finding and analysis at colliders 6 | # http://fastjet.fr 7 | # 8 | # Please cite EPJC72(2012)1896 [arXiv:1111.6097] if you use this package 9 | # for scientific work and optionally PLB641(2006)57 [hep-ph/0512210]. 10 | # 11 | # FastJet is provided without warranty under the terms of the GNU GPLv2. 12 | # It uses T. Chan's closest pair algorithm, S. Fortune's Voronoi code 13 | # and 3rd party plugin jet algorithms. See COPYING file for details. 14 | #-------------------------------------------------------------------------- 15 | ------------------------------------------------------------------------------------- 16 | ------------------------------------------------------------------------------------- 17 | ### 18 | # Note: This reference file has been modified from v1.0.3 as follows: 19 | # -- The order of the subjets changed from v1.0.3 to v2.0.0 20 | # -- The interface to the GeometricMeasure has changed, so that 21 | # part has been commented out 22 | # -- There was a bug in one-pass kT minimization, so Event-wide Jets are not 23 | # directly comparable. 24 | ## 25 | Beta = 1 26 | kT Axes: 27 | jet # rapidity phi pt m e subTau 28 | 0 -0.867 2.905 983.387 39.991 1378.162 0.012519 29 | total -0.867 2.905 983.387 39.991 1378.162 0.012519 30 | jet # rapidity phi pt m e subTau 31 | 0 -0.795 2.822 37.055 4.246 49.708 0.002465 32 | 1 -0.870 2.908 946.464 25.237 1328.454 0.007675 33 | total -0.867 2.905 983.387 39.991 1378.162 0.010140 34 | jet # rapidity phi pt m e subTau 35 | 0 -0.890 2.913 149.669 8.252 213.287 0.001190 36 | 1 -0.866 2.907 798.567 11.098 1117.518 0.003876 37 | 2 -0.795 2.819 35.290 4.099 47.357 0.002325 38 | total -0.867 2.905 983.387 39.991 1378.162 0.007390 39 | One Pass Minimization Axes from kT 40 | jet # rapidity phi pt m e subTau 41 | 0 -0.867 2.905 983.387 39.991 1378.162 0.011996 42 | total -0.867 2.905 983.387 39.991 1378.162 0.011996 43 | jet # rapidity phi pt m e subTau 44 | 0 -0.796 2.821 36.926 4.124 49.558 0.002058 45 | 1 -0.870 2.908 946.596 25.745 1328.604 0.007213 46 | total -0.867 2.905 983.387 39.991 1378.162 0.009271 47 | jet # rapidity phi pt m e subTau 48 | 0 -0.890 2.913 149.669 8.252 213.287 0.001073 49 | 1 -0.866 2.907 796.929 11.662 1115.317 0.003672 50 | 2 -0.796 2.821 36.926 4.124 49.558 0.002058 51 | total -0.867 2.905 983.387 39.991 1378.162 0.006802 52 | ------------------------------------------------------------------------------------- 53 | Beta = 1 54 | kT: tau1: 0.0125188 tau2: 0.0101401 tau3: 0.00739039 tau2/tau1: 0.809988 tau3/tau2: 0.728831 55 | OnePass: tau1: 0.0119958 tau2: 0.00927143 tau3: 0.00680249 tau2/tau1: 0.772888 tau3/tau2: 0.733704 56 | 57 | ------------------------------------------------------------------------------------- 58 | ------------------------------------------------------------------------------------- 59 | ------------------------------------------------------------------------------------- 60 | ------------------------------------------------------------------------------------- 61 | Beta = 1 62 | kT Axes: 63 | jet # rapidity phi pt m e subTau 64 | 0 0.219 6.035 908.098 87.712 934.387 0.021411 65 | total 0.219 6.035 908.098 87.712 934.387 0.021411 66 | jet # rapidity phi pt m e subTau 67 | 0 0.272 0.335 8.985 3.734 10.091 0.002302 68 | 1 0.219 6.029 900.614 59.545 924.296 0.013311 69 | total 0.219 6.035 908.098 87.712 934.387 0.015613 70 | jet # rapidity phi pt m e subTau 71 | 0 0.232 6.038 213.757 10.389 219.808 0.002692 72 | 1 0.215 6.027 686.868 48.049 704.488 0.010855 73 | 2 0.272 0.335 8.985 3.734 10.091 0.002302 74 | total 0.219 6.035 908.098 87.712 934.387 0.015849 75 | One Pass Minimization Axes from kT 76 | jet # rapidity phi pt m e subTau 77 | 0 0.219 6.035 908.098 87.712 934.387 0.017650 78 | total 0.219 6.035 908.098 87.712 934.387 0.017650 79 | jet # rapidity phi pt m e subTau 80 | 0 0.272 0.335 8.985 3.734 10.091 0.002284 81 | 1 0.219 6.029 900.614 59.545 924.296 0.011429 82 | total 0.219 6.035 908.098 87.712 934.387 0.013713 83 | jet # rapidity phi pt m e subTau 84 | 0 0.232 6.038 213.757 10.389 219.808 0.002580 85 | 1 0.215 6.027 686.868 48.049 704.488 0.007144 86 | 2 0.272 0.335 8.985 3.734 10.091 0.002284 87 | total 0.219 6.035 908.098 87.712 934.387 0.012008 88 | ------------------------------------------------------------------------------------- 89 | Beta = 1 90 | kT: tau1: 0.0214112 tau2: 0.0156127 tau3: 0.015849 tau2/tau1: 0.729182 tau3/tau2: 1.01514 91 | OnePass: tau1: 0.0176497 tau2: 0.0137131 tau3: 0.0120083 tau2/tau1: 0.776959 tau3/tau2: 0.875683 92 | 93 | ------------------------------------------------------------------------------------- 94 | ------------------------------------------------------------------------------------- 95 | #------------------------------------------------------------------------------------- 96 | #Event-wide Jets from One-Pass Minimization (beta = 1.0) 97 | #jet # rapidity phi pt m e subTau 98 | # 0 -1.179 6.109 74.906 25.817 140.954 0.023411 99 | # 1 0.221 6.035 906.441 79.121 932.274 0.027116 100 | # 2 -0.867 2.905 983.387 39.991 1378.162 0.017703 101 | #total -0.375 4.107 6.220 2288.668 2451.390 0.068230 102 | #Event-wide Axis Location for Above Jets 103 | #jet # rapidity phi pt m e 104 | # 0 -0.868 2.907 983.287 0.000 1377.582 105 | # 1 0.221 6.029 906.605 -0.000 928.911 106 | # 2 -1.188 6.105 77.311 0.000 138.569 107 | #Event-wide Jets from Geometric Measure 108 | #jet # rapidity phi pt m e subTau 109 | # 0 -1.168 6.113 73.982 22.784 136.469 0.145343 110 | # 1 0.221 6.034 905.364 68.865 930.274 0.138958 111 | # 2 -0.867 2.905 983.280 36.457 1377.658 0.045771 112 | #total -0.374 3.920 7.900 2282.722 2444.400 0.330072 113 | #------------------------------------------------------------------------------------- 114 | #------------------------------------------------------------------------------------- 115 | #Event-wide Jets from One-Pass Minimization (beta = 1.0) (with area information) 116 | #jet # rapidity phi pt m e subTau area 117 | # 0 -1.179 6.109 74.906 25.817 140.954 0.023411 2.842 118 | # 1 0.221 6.035 906.441 79.121 932.274 0.027116 2.822 119 | # 2 -0.867 2.905 983.387 39.991 1378.162 0.017703 3.122 120 | #total -0.375 4.107 6.220 2288.668 2451.390 0.068230 0.000 121 | #Event-wide Axis Location for Above Jets (with area information) 122 | #jet # rapidity phi pt m e 123 | # 0 -0.868 2.907 983.287 0.000 1377.582 124 | # 1 0.221 6.029 906.605 -0.000 928.911 125 | # 2 -1.188 6.105 77.311 0.000 138.569 126 | #Event-wide Jets from Geometric Measure (with area information) 127 | #jet # rapidity phi pt m e subTau area 128 | # 0 -0.867 2.905 983.280 36.457 1377.658 0.002435 3.191 129 | # 1 0.221 6.034 905.364 68.865 930.274 0.007393 2.912 130 | # 2 -1.168 6.113 73.982 22.784 136.469 0.007732 2.922 131 | #total -0.374 3.920 7.900 2282.722 2444.400 0.017560 0.000 132 | #------------------------------------------------------------------------------------- 133 | -------------------------------------------------------------------------------- /event-gen/Nsubjettiness/Njettiness.hh: -------------------------------------------------------------------------------- 1 | // Nsubjettiness Package 2 | // Questions/Comments? jthaler@jthaler.net 3 | // 4 | // Copyright (c) 2011-14 5 | // Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason 6 | // 7 | // $Id: Njettiness.hh 670 2014-06-06 01:24:42Z jthaler $ 8 | //---------------------------------------------------------------------- 9 | // This file is part of FastJet contrib. 10 | // 11 | // It is free software; you can redistribute it and/or modify it under 12 | // the terms of the GNU General Public License as published by the 13 | // Free Software Foundation; either version 2 of the License, or (at 14 | // your option) any later version. 15 | // 16 | // It is distributed in the hope that it will be useful, but WITHOUT 17 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 18 | // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 19 | // License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this code. If not, see . 23 | //---------------------------------------------------------------------- 24 | 25 | #ifndef __FASTJET_CONTRIB_NJETTINESS_HH__ 26 | #define __FASTJET_CONTRIB_NJETTINESS_HH__ 27 | 28 | 29 | #include "MeasureFunction.hh" 30 | #include "AxesFinder.hh" 31 | #include "NjettinessDefinition.hh" 32 | 33 | #include "fastjet/PseudoJet.hh" 34 | #include "fastjet/SharedPtr.hh" 35 | #include 36 | 37 | #include 38 | #include 39 | #include 40 | 41 | FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 42 | 43 | namespace contrib { 44 | 45 | /////// 46 | // 47 | // Main Njettiness Class 48 | // 49 | /////// 50 | 51 | //------------------------------------------------------------------------ 52 | /// \class Njettiness 53 | // Njettiness uses AxesFinder and MeasureFunction together in order to find tau_N for the event. The user specifies 54 | // which AxesFinder and which MeasureFunction to use in the calculation, and then Njettiness returns tau_N for the event. 55 | // It also can return information about the axes and jets it used in the calculation, as well as information about 56 | // how the event was partitioned. 57 | class Njettiness { 58 | public: 59 | 60 | // The various axes choices available to the user 61 | // It is recommended to use AxesDefinition instead of these. 62 | enum AxesMode { 63 | kt_axes, // exclusive kt axes 64 | ca_axes, // exclusive ca axes 65 | antikt_0p2_axes, // inclusive hardest axes with antikt-0.2 66 | wta_kt_axes, // Winner Take All axes with kt 67 | wta_ca_axes, // Winner Take All axes with CA 68 | onepass_kt_axes, // one-pass minimization from kt starting point 69 | onepass_ca_axes, // one-pass minimization from ca starting point 70 | onepass_antikt_0p2_axes, // one-pass minimization from antikt-0.2 starting point 71 | onepass_wta_kt_axes, //one-pass minimization of WTA axes with kt 72 | onepass_wta_ca_axes, //one-pass minimization of WTA axes with ca 73 | min_axes, // axes that minimize N-subjettiness (100 passes by default) 74 | manual_axes, // set your own axes with setAxes() 75 | onepass_manual_axes // one-pass minimization from manual starting point 76 | // These options are commented out because they have not been fully tested 77 | // wta2_kt_axes, // Winner Take All (alpha = 2) with kt 78 | // wta2_ca_axes, // Winner Take All (alpha = 2) with CA 79 | // onepass_wta2_kt_axes, //one-pass minimization of WTA (alpha = 2) axes with kt 80 | // onepass_wta2_ca_axes, //one-pass minimization of WTA (alpha = 2) axes with ca 81 | }; 82 | 83 | // The measures available to the user. 84 | // "normalized_cutoff_measure" was the default in v1.0 of Nsubjettiness 85 | // "unnormalized_measure" is now the recommended default usage 86 | // But it is recommended to use MeasureDefinition instead of these. 87 | enum MeasureMode { 88 | normalized_measure, //default normalized measure 89 | unnormalized_measure, //default unnormalized measure 90 | geometric_measure, //geometric measure 91 | normalized_cutoff_measure, //default normalized measure with explicit Rcutoff 92 | unnormalized_cutoff_measure, //default unnormalized measure with explicit Rcutoff 93 | geometric_cutoff_measure //geometric measure with explicit Rcutoff 94 | }; 95 | 96 | // Main constructor that uses AxesMode and MeasureDefinition to specify measure 97 | // Unlike Nsubjettiness or NjettinessPlugin, the value N is not chosen 98 | Njettiness(const AxesDefinition & axes_def, const MeasureDefinition & measure_def); 99 | 100 | // Intermediate constructor (needed to enable v1.0.3 backwards compatibility?) 101 | Njettiness(AxesMode axes_mode, const MeasureDefinition & measure_def); 102 | 103 | // Alternative constructor which takes axes/measure information as enums with measure parameters 104 | // This version is not recommended 105 | Njettiness(AxesMode axes_mode, 106 | MeasureMode measure_mode, 107 | int num_para, 108 | double para1 = std::numeric_limits::quiet_NaN(), 109 | double para2 = std::numeric_limits::quiet_NaN(), 110 | double para3 = std::numeric_limits::quiet_NaN()) 111 | : _axes_def(createAxesDef(axes_mode)), _measure_def(createMeasureDef(measure_mode, num_para, para1, para2, para3)) { 112 | setMeasureFunctionAndAxesFinder(); // call helper function to do the hard work 113 | } 114 | 115 | // destructor 116 | ~Njettiness() {}; 117 | 118 | // setAxes for Manual mode 119 | void setAxes(const std::vector & myAxes); 120 | 121 | // Calculates and returns all TauComponents that user would want. 122 | // This information is stored in _current_tau_components for later access as well. 123 | TauComponents getTauComponents(unsigned n_jets, const std::vector & inputJets) const; 124 | 125 | // Calculates the value of N-subjettiness, 126 | // but only returns the tau value from _current_tau_components 127 | double getTau(unsigned n_jets, const std::vector & inputJets) const { 128 | return getTauComponents(n_jets, inputJets).tau(); 129 | } 130 | 131 | // Return all relevant information about tau components 132 | TauComponents currentTauComponents() const {return _current_tau_components;} 133 | // Return axes found by getTauComponents. 134 | std::vector currentAxes() const { return _currentAxes;} 135 | // Return seedAxes used if onepass minimization (otherwise, same as currentAxes) 136 | std::vector seedAxes() const { return _seedAxes;} 137 | // Return jet partition found by getTauComponents. 138 | std::vector currentJets() const {return _currentJets;} 139 | // Return beam partition found by getTauComponents. 140 | fastjet::PseudoJet currentBeam() const {return _currentBeam;} 141 | 142 | // partition inputs by Voronoi (each vector stores indices corresponding to inputJets) 143 | std::vector > getPartitionList(const std::vector & inputJets) const; 144 | 145 | private: 146 | 147 | // Information about Axes and Measures to be Used 148 | // Implemented as SharedPtrs to avoid memory management headaches 149 | SharedPtr _axes_def; 150 | SharedPtr _measure_def; 151 | 152 | // The chosen axes/measure mode workers 153 | // Implemented as SharedPtrs to avoid memory management headaches 154 | // TODO: make into a SharedPtr? 155 | SharedPtr _measureFunction; // The chosen measure 156 | SharedPtr _startingAxesFinder; // The initial axes finder 157 | SharedPtr _finishingAxesFinder; // A possible minimization step 158 | 159 | // Information about the current information 160 | // Defined as mutables, so user should be aware that these change when getTau is called. 161 | mutable TauComponents _current_tau_components; //automatically set to have components of 0; these values will be set by the getTau function call 162 | mutable std::vector _currentAxes; //axes found after minimization 163 | mutable std::vector _seedAxes; // axes used prior to minimization (if applicable) 164 | mutable std::vector _currentJets; //partitioning information 165 | mutable fastjet::PseudoJet _currentBeam; //return beam, if requested 166 | 167 | // created separate function to set MeasureFunction and AxesFinder in order to keep constructor cleaner. 168 | void setMeasureFunctionAndAxesFinder(); 169 | 170 | // Convert old style enums into new style MeasureDefinition 171 | AxesDefinition* createAxesDef(AxesMode axes_mode) const; 172 | 173 | // Convert old style enums into new style MeasureDefinition 174 | MeasureDefinition* createMeasureDef(MeasureMode measure_mode, int num_para, double para1, double para2, double para3) const; 175 | 176 | }; 177 | 178 | } // namespace contrib 179 | 180 | FASTJET_END_NAMESPACE 181 | 182 | #endif // __FASTJET_CONTRIB_NJETTINESS_HH__ 183 | 184 | -------------------------------------------------------------------------------- /event-gen/Nsubjettiness/Nsubjettiness.hh: -------------------------------------------------------------------------------- 1 | // Nsubjettiness Package 2 | // Questions/Comments? jthaler@jthaler.net 3 | // 4 | // Copyright (c) 2011-14 5 | // Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason 6 | // 7 | // $Id: Nsubjettiness.hh 670 2014-06-06 01:24:42Z jthaler $ 8 | //---------------------------------------------------------------------- 9 | // This file is part of FastJet contrib. 10 | // 11 | // It is free software; you can redistribute it and/or modify it under 12 | // the terms of the GNU General Public License as published by the 13 | // Free Software Foundation; either version 2 of the License, or (at 14 | // your option) any later version. 15 | // 16 | // It is distributed in the hope that it will be useful, but WITHOUT 17 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 18 | // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 19 | // License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this code. If not, see . 23 | //---------------------------------------------------------------------- 24 | 25 | #ifndef __FASTJET_CONTRIB_NSUBJETTINESS_HH__ 26 | #define __FASTJET_CONTRIB_NSUBJETTINESS_HH__ 27 | 28 | #include 29 | 30 | #include "Njettiness.hh" 31 | 32 | #include "fastjet/FunctionOfPseudoJet.hh" 33 | #include 34 | #include 35 | 36 | FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 37 | 38 | namespace contrib { 39 | 40 | //------------------------------------------------------------------------ 41 | /// \class Nsubjettiness 42 | /// Nsubjettiness extends the concept of Njettiness to a jet shape, but other 43 | /// than the set of particles considered, they are identical. This class 44 | /// wraps the core Njettiness code to provide the fastjet::FunctionOfPseudoJet 45 | /// interface for convenience in larger analyses. See NjettinessPlugin.hh for 46 | /// definitions of tau_N and the constructor options. 47 | class Nsubjettiness : public FunctionOfPseudoJet { 48 | 49 | public: 50 | 51 | 52 | // Main constructor, which takes N, the AxesDefiniation, and the MeasureDefinition. 53 | // The Definitions are given in NjettinessDefinition.hh 54 | // 55 | // The recommended AxesDefinitions are (more are available as listed in the README 56 | // and defined in NjettinessDefinition.hh): 57 | // KT_Axes : exclusive kt axes 58 | // WTA_KT_Axes : exclusive kt with winner-take-all recombination 59 | // OnePass_KT_Axes : one-pass minimization from kt starting point 60 | // OnePass_WTA_KT_Axes : one-pass min. from wta_kt starting point 61 | // 62 | // The recommended measure definitions are (with the corresponding parameters) 63 | // NormalizedMeasure(beta,R0) 64 | // : This was the original N-subjettiness measure (dimensionless) 65 | // UnnormalizedMeasure(beta) 66 | // : This is the new recommended default, same as above but without 67 | // : the normalization factor, and hence has units of GeV 68 | // NormalizedCutoffMeasure(beta,R0,Rcutoff) 69 | // : Same as normalized_measure, but cuts off at Rcutoff 70 | // UnnormalizedCutoffMeasure(beta,Rcutoff) 71 | // : Same as unnormalized_measure, but cuts off at Rcutoff 72 | Nsubjettiness(int N, 73 | const AxesDefinition& axes_def, 74 | const MeasureDefinition& measure_def) 75 | : _njettinessFinder(axes_def,measure_def), _N(N) {} 76 | 77 | 78 | // Alternative constructors that define the measure via enums and parameters 79 | // These constructors are likely be removed 80 | // Zero parameter arguments 81 | // (Currently, no measure uses this) 82 | Nsubjettiness(int N, 83 | Njettiness::AxesMode axes_mode, 84 | Njettiness::MeasureMode measure_mode) 85 | : _njettinessFinder(axes_mode, measure_mode, 0), _N(N) {} 86 | 87 | // One parameter argument 88 | // (for unnormalized_measure, para1=beta) 89 | Nsubjettiness(int N, 90 | Njettiness::AxesMode axes_mode, 91 | Njettiness::MeasureMode measure_mode, 92 | double para1) 93 | : _njettinessFinder(axes_mode, measure_mode, 1, para1), _N(N) {} 94 | 95 | // Two parameter arguments 96 | // (for normalized_measure, para1=beta, para2=R0) 97 | // (for unnormalized_cutoff_measure, para1=beta, para2=Rcutoff) 98 | Nsubjettiness(int N, 99 | Njettiness::AxesMode axes_mode, 100 | Njettiness::MeasureMode measure_mode, 101 | double para1, 102 | double para2) 103 | : _njettinessFinder(axes_mode, measure_mode, 2, para1, para2), _N(N) {} 104 | 105 | // Three parameter arguments 106 | // (for unnormalized_cutoff_measure, para1=beta, para2=R0, para3=Rcutoff) 107 | Nsubjettiness(int N, 108 | Njettiness::AxesMode axes_mode, 109 | Njettiness::MeasureMode measure_mode, 110 | double para1, 111 | double para2, 112 | double para3) 113 | : _njettinessFinder(axes_mode, measure_mode, 3, para1, para2, para3), _N(N) {} 114 | 115 | // Old constructor for backwards compatibility with v1.0, 116 | // where normalized_cutoff_measure was the only option 117 | Nsubjettiness(int N, 118 | Njettiness::AxesMode axes_mode, 119 | double beta, 120 | double R0, 121 | double Rcutoff=std::numeric_limits::max()) 122 | : _njettinessFinder(axes_mode, NormalizedCutoffMeasure(beta,R0,Rcutoff)), _N(N) {} 123 | 124 | /// returns tau_N, measured on the constituents of this jet 125 | double result(const PseudoJet& jet) const; 126 | 127 | /// returns components of tau_N, so that user can find individual tau values. 128 | TauComponents component_result(const PseudoJet& jet) const; 129 | 130 | /// returns current axes found by result() calculation 131 | std::vector currentAxes() const { 132 | return _njettinessFinder.currentAxes(); 133 | } 134 | 135 | /// returns seed axes used for onepass minimization (otherwise same as currentAxes) 136 | std::vector seedAxes() const { 137 | return _njettinessFinder.seedAxes(); 138 | } 139 | 140 | /// returns subjet regions found by result() calculation (these have valid constituents) 141 | /// Note that the axes and the subjets are not the same 142 | std::vector currentSubjets() const { 143 | return _njettinessFinder.currentJets(); 144 | } 145 | 146 | /// returns components of tau_N without recalculating anything 147 | TauComponents currentTauComponents() const { 148 | return _njettinessFinder.currentTauComponents(); 149 | } 150 | 151 | // To set axes for manual use 152 | void setAxes(const std::vector & myAxes) { 153 | // Cross check that manual axes are being used is in Njettiness 154 | _njettinessFinder.setAxes(myAxes); 155 | } 156 | 157 | 158 | private: 159 | 160 | Njettiness _njettinessFinder; // TODO: should muck with this so result can be const without this mutable 161 | int _N; 162 | 163 | }; 164 | 165 | 166 | //------------------------------------------------------------------------ 167 | /// \class NsubjettinessRatio 168 | // NsubjettinessRatio uses the results from Nsubjettiness to calculate the ratio 169 | // tau_N/tau_M, where N and M are specified by the user. The ratio of different tau values 170 | // is often used in analyses, so this class is helpful to streamline code. 171 | class NsubjettinessRatio : public FunctionOfPseudoJet { 172 | public: 173 | 174 | // Main constructor. Apart from specifying both N and M, the same options as Nsubjettiness 175 | NsubjettinessRatio(int N, 176 | int M, 177 | const AxesDefinition & axes_def, 178 | const MeasureDefinition & measure_def) 179 | : _nsub_numerator(N,axes_def,measure_def), 180 | _nsub_denominator(M,axes_def,measure_def) {} 181 | 182 | // Alternative constructor with enums and parameters 183 | // Again, likely to be removed 184 | NsubjettinessRatio(int N, 185 | int M, 186 | Njettiness::AxesMode axes_mode, 187 | Njettiness::MeasureMode measure_mode) 188 | : _nsub_numerator(N, axes_mode, measure_mode), 189 | _nsub_denominator(M, axes_mode, measure_mode) {} 190 | 191 | 192 | NsubjettinessRatio(int N, 193 | int M, 194 | Njettiness::AxesMode axes_mode, 195 | Njettiness::MeasureMode measure_mode, 196 | double para1) 197 | : _nsub_numerator(N, axes_mode, measure_mode, para1), 198 | _nsub_denominator(M, axes_mode, measure_mode, para1) {} 199 | 200 | NsubjettinessRatio(int N, 201 | int M, 202 | Njettiness::AxesMode axes_mode, 203 | Njettiness::MeasureMode measure_mode, 204 | double para1, 205 | double para2) 206 | : _nsub_numerator(N, axes_mode, measure_mode, para1, para2), 207 | _nsub_denominator(M, axes_mode, measure_mode, para1, para2) {} 208 | 209 | NsubjettinessRatio(int N, 210 | int M, 211 | Njettiness::AxesMode axes_mode, 212 | Njettiness::MeasureMode measure_mode, 213 | double para1, 214 | double para2, 215 | double para3) 216 | : _nsub_numerator(N, axes_mode, measure_mode, para1, para2, para3), 217 | _nsub_denominator(M, axes_mode, measure_mode, para1, para2, para3) {} 218 | 219 | //returns tau_N/tau_M based off the input jet using result function from Nsubjettiness 220 | double result(const PseudoJet& jet) const; 221 | 222 | private: 223 | 224 | Nsubjettiness _nsub_numerator; 225 | Nsubjettiness _nsub_denominator; 226 | 227 | }; 228 | 229 | } // namespace contrib 230 | 231 | FASTJET_END_NAMESPACE 232 | 233 | #endif // __FASTJET_CONTRIB_NSUBJETTINESS_HH__ 234 | -------------------------------------------------------------------------------- /event-gen/Nsubjettiness/ChangeLog: -------------------------------------------------------------------------------- 1 | 2014-07-09 2 | Changed version for 2.1.0 release. 3 | Updated NEWS to reflect 2.1.0 release 4 | 2014-07-07 5 | Added forward declaration of options in NjettinessDefinition for readability. 6 | Updated README with some clarifications 7 | Added usage information in the example file 8 | Reran svn propset svn:keywords Id *.cc *.hh 9 | 2014-06-25 10 | Declaring release candidate of 2.1 11 | 2014-06-11 12 | Fixed virtual destructor issue in AxesFinder 13 | Changing copy() to create() in NjettinessDefinition for "new" clarity 14 | Converted some SharedPtr to regular pointers in NjettinessDefinition to be consistent on meaning of "create" commands. 15 | 2014-06-10 16 | Slight modification of example_advanced_usage 17 | Fixed bug in GeometricCutoffMeasure (incorrect denominator setting) 18 | 2014-06-05 19 | Moved public before private in the .hh files for readability 20 | Starting process of switching to SharedPtr internally 21 | Clean up of AxesFinderFromGeometricMinimization 22 | Simplified AxesFinder interface such that it doesn't know about starting axes finders (this is now handled in Njettiness). 23 | Added const qualifiers in Njettiness 24 | 2014-06-04 25 | Implemented AxesDefinition class 26 | Added descriptions to AxesDefinition and MeasureDefinition 27 | Simplified example_advanced_usage with new Definitions 28 | Made copy constructor private for Njettiness, to avoid copying 29 | 2014-06-03 30 | Implemented remaining suggestions from FJ authors (Thanks!) 31 | Fixed bug in example_advanced_usage where wrong beta value was used for NjettinessPlugin tests. 32 | Removed NANs as signals for number of parameters in Nsubjettiness and NjettinessPlugin 33 | Reduced the number of allowed parameters from 4 to 3. 34 | Wrapped NEWS to 80 characters 35 | Added MeasureDefinition as way to safely store information about the measures used 36 | Converted a few NANs to std::numeric_limits::quiet_NaN() when a parameter shouldn't be used. 37 | Added AxesStruct and MeasureStruct to simplify the form of example_advanced_usage 38 | Added example_v1p0p3 to check for backwards compatibility with v1.0.3 39 | Changed the names of the MeasureFunctions in order to avoid conflicts with the new MeasureDefinitions 40 | Fixed bug in correlation between subjets and tau values in NjettinessPlugin 41 | Added currentTauComponents to Nsubjettiness 42 | Added subTau information to example_basic_usage 43 | Added file NjettinessDefinition to hold MeasureDefinition 44 | Changed Njettiness constructors to treat MeasureSpecification as primary object 45 | Fixed segmentation fault with ClusterSequenceAreas 46 | 2014-06-02 47 | Implemented many suggestions from FJ authors (Thanks!) 48 | Removed FastJet 2 specific code 49 | Made sq() function into internal namespace (as "inline static" to avoid conflicts with other packages) 50 | Made setAxes() take const reference argument 51 | Rewrapped README to 80 characters and updated/improved some of the descriptions 52 | Clarified NEWS about what parts of the Nsubjettiness code is backwards compatible with v1.0.3 53 | Clarified the para choices in Nsubjettiness constructor 54 | 2014-04-30 55 | Added (void)(n_jets) in AxesFinder.hh to fix unused-parameter warning 56 | 2014-04-29 57 | Added manual definition of NAN for compilers that don't have it. 58 | Removed a few more unused parameters for compilation 59 | 2014-04-22 60 | Turned on -Wunused-parameter compiler flag to fix ATLAS compile issues. 61 | 2014-04-18 62 | Tweaks to NEWS and README. Preparing for 2.0.0-rc1 release. 63 | 2014-04-16 64 | Decided that enough has changed that this should be v2.0 65 | Added Id tags 66 | 2014-04-14 67 | Added get_partition_list to MeasureFunction 68 | Removed do_cluster from MeasureFunction (no longer needed) 69 | Fixed bug with NjettinessPlugin where jets were listed in backwards order from axes. 70 | Removed various commented out pieces of code. 71 | 2014-03-16 72 | Added partitioning information to Nsubjettiness 73 | Partitioning is now calculated in MeasureFunction and stored by Njettiness. 74 | Rewrote MeasureFunction result() to call result_from_partition() 75 | Added subjet (and constituent counting) information to example_basic_usage 76 | Commented out redundant "getJets" function 77 | 2014-02-25 78 | Added access to seedAxes used for one-pass minimization routines. 79 | Added axes print out to example_basic_usage, and fixed too many PrintJets declarations 80 | 2014-02-24 81 | Fixed embarrassing bug with min_axes (error introduced after v1.0 to make it the same as onepass_kt) 82 | Simplified GeometricMeasure and added possibility of beta dependence 83 | 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. 84 | Split example into example_basic_usage and example_advanced_usage 85 | 2014-01-28 86 | Added new options in WinnerTakeAllRecombiner to use either pT or pT^2/E to recombine particles 87 | 2014-01-24 88 | Added access to currentAxes from Nsubjettiness. 89 | 2014-01-18 90 | Added beam regions to MeasureFunction, correspondingly renamed functions to have jet and beam regions 91 | Renamed functions in TauComponents for consistency with MeasureFunction 92 | Adding debugging code to AxesFinderFromOnePassMinimization::getAxes 93 | Worked extensively on example.cc to make sure that it tests all available options. 94 | Rewrote PrintJets command in example.cc for later improvements 95 | Converted some magic numbers to std::numeric_limits::max() 96 | 2014-01-17 97 | Rewrote KMeansMinimization to call OnePassMinimization, adding noise explicitly. 98 | Removed any nothing of noise from OnePassMinimization 99 | Removed Double32_t for root usage is Nsubjettiness 100 | Clean up of many comments throughout the code, updating of README file 101 | Removed unnecessary establishAxes in Njettiness 102 | Removed bare constructor for Njettiness to avoid incompatibility with enum choices, may reinstate later. Also removed setMeasureFunction, setAxesFinder for same reason 103 | NjettinessExtras now calls TauComponents 104 | 2014-01-16 105 | Moved minimization functions to OnePassMinimization, changed KMeansMinimization class to simply call OnePassMinimization a specified number of times 106 | Added extra tau function in TauComponents for users to get tau directly 107 | Changed radius parameter in AxesFinderFromExclusiveJet subclasses to use max_allowable_R 108 | Updated example.ref to account for changes due to change in radius parameter 109 | 2014-01-15 110 | Changed NjettinessComponents to TauComponents 111 | Updated MeasureFunction with "result" function that returns TauComponents object 112 | TauComponents changed to calculate all tau components given subtaus_numerator and tau_denominator 113 | Njettiness updated to return TauComponents object rather than individual components 114 | Nsubjettiness and NjettinessPlugin updated to have option for 4th parameter 115 | 2014-01-14 116 | Added NjettinessComponents class so Njettiness does not recalculate tau values 117 | Removed old Njettiness constructors, updated Nsubjettiness and NjettinessPlugin constructors to use new constructor 118 | Added geometric minimization to OnePassAxesFinders 119 | Created new Njettiness function to set OnePassAxesFinders to reduce code 120 | Updated LightLikeAxis with ConvertToPseudoJet function 121 | Updated README with new functionality of code 122 | 2014-01-12 123 | Removed NsubGeometricParameters in all functions/constructors, replaced with Rcutoff double 124 | Added three new measure mode options where Rcutoff is declared explicitly in parameters 125 | Added checks so minimization axes finders are not used for geometric measures 126 | AxesFinderFromOnePassMinimization class created as child of AxesFinderFromKmeansMinimization 127 | Added new NsubjettinessRatio constructor to include MeasureMode option 128 | Moved AxesFinder and MeasureFunction declarations from AxesMode and MeasureMode into separate Njettiness function 129 | Removed R0 from AxesFinderFromKmeansMinimization 130 | Changed example.cc to get rid of use of NsubGeometricParameters 131 | 2014-01-9 132 | Removed NsubParameters in all functions/constructors, replaced with three separate parameters 133 | Added checks for correct number of parameters in Njettiness constructor 134 | 2014-01-8 135 | Removed normalization information from Nsubjettiness 136 | Added flag to MeasureFunction to give option of using the denominator 137 | Split DefaultMeasure into separate normalized and unnormalized classes 138 | 2014-01-7 139 | Added capability of choosing a specific Measure in Njettiness 140 | Added new Nsubjettiness constructor to allow choice of both AxesMode and MeasureMode 141 | 2014-01-6 142 | Updated copyright information 143 | Fixed bug in WinnerTakeAllRecombiner 144 | Moved KMeansParameters to AxesFinder 145 | Updated README with descriptions of new header files 146 | 2013-12-30 147 | Changed name of MeasureFunctor to MeasureFunction 148 | Created separate .hh/.cc files for MeasureFunction, AxesFinder, and WinnerTakeAllRecombiner 149 | Updated Makefile to account for new files 150 | Removed getMinimumAxes in AxesFinderFromKMeansMinimization, consolidated with getAxes 151 | Updated comments on classes and major functions 152 | 2013-12-22 153 | Created .cc files and moved all function definitions into .cc files 154 | Updated Makefile to account for new .cc files 155 | 2013-11-12 156 | Added to fjcontrib svn 157 | 2013-11-12 158 | Debugging svn 159 | 2013-11-11 160 | Changed MeasureFunctor to separately treat tau numerator and denominator 161 | Changed some of the function names in MeasureFunctor. Should not affect users 162 | Added more informative function names to Njettiness. 163 | Njettiness now allows finding unnormalized tau values 164 | Added WTARecombiner to define winner-take-all axes 165 | Added various WTA options to AxesMode 166 | Added setAxes to Nsubjettiness 167 | Added NsubjettinessRatio function 168 | 2013-08-26 169 | Added inlines to fix compile issue 170 | Put some of the minimization code inside of the AxesFinderFromKmeansMinimization class 171 | 2013-02-23 172 | Fixed dependency issue (now using make depend) 173 | 2013-02-22 174 | Fixed memory management and failed make check issues. 175 | 2013-02-21 176 | First version submitted to fjcontrib 177 | 2013-02-20 178 | Initial creation based on previous plugin hosted at http://www.jthaler.net/jets/ 179 | 180 | 181 | 182 | -------------------------------------------------------------------------------- /event-gen/src/MIAnalysis.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "TFile.h" 8 | #include "TTree.h" 9 | #include "TClonesArray.h" 10 | #include "TParticle.h" 11 | #include "TDatabasePDG.h" 12 | #include "TMath.h" 13 | #include "TH2F.h" 14 | 15 | #include "MIAnalysis.h" 16 | #include "MITools.h" 17 | 18 | #include "myFastJetBase.h" 19 | #include "fastjet/ClusterSequence.hh" 20 | #include "fastjet/PseudoJet.hh" 21 | #include "fastjet/tools/Filter.hh" 22 | #include "fastjet/Selector.hh" 23 | #include "fastjet/ClusterSequenceArea.hh" 24 | #include "fastjet/ClusterSequenceActiveAreaExplicitGhosts.hh" 25 | 26 | #include "Pythia8/Pythia.h" 27 | 28 | // #include "Nsubjettiness.h" 29 | #include "Njettiness.hh" 30 | #include "Nsubjettiness.hh" 31 | 32 | 33 | using namespace std; 34 | using namespace fastjet; 35 | using namespace fastjet::contrib; 36 | 37 | // Constructor 38 | MIAnalysis::MIAnalysis(int imagesize) 39 | { 40 | imagesize *= imagesize; 41 | MaxN = imagesize; 42 | fTIntensity = new float[imagesize]; 43 | fTRotatedIntensity = new float[imagesize]; 44 | 45 | 46 | if(fDebug) cout << "MIAnalysis::MIAnalysis Start " << endl; 47 | ftest = 0; 48 | fDebug = false; 49 | fOutName = "test.root"; 50 | tool = new MITools(); 51 | 52 | //model the detector as a 2D histogram 53 | // xbins y bins 54 | detector = new TH2F("", "", 100, -5, 5, 200, -10, 10); 55 | for(int i = 1; i <= 100; i++) 56 | { 57 | for (int j = 1; j <= 200; j++) 58 | { 59 | detector->SetBinContent(i,j,0); 60 | } 61 | } 62 | 63 | if(fDebug) cout << "MIAnalysis::MIAnalysis End " << endl; 64 | } 65 | 66 | // Destructor 67 | MIAnalysis::~MIAnalysis() 68 | { 69 | delete tool; 70 | 71 | delete[] fTIntensity; 72 | delete[] fTRotatedIntensity; 73 | } 74 | 75 | // Begin method 76 | void MIAnalysis::Begin() 77 | { 78 | // Declare TTree 79 | tF = new TFile(fOutName.c_str(), "RECREATE"); 80 | tT = new TTree("EventTree", "Event Tree for MI"); 81 | 82 | // for shit you want to do by hand 83 | DeclareBranches(); 84 | ResetBranches(); 85 | 86 | return; 87 | } 88 | 89 | // End 90 | void MIAnalysis::End() 91 | { 92 | tT->Write(); 93 | tF->Close(); 94 | return; 95 | } 96 | 97 | // Analyze 98 | void MIAnalysis::AnalyzeEvent(int ievt, Pythia8::Pythia* pythia8, Pythia8::Pythia* pythia_MB, int NPV, 99 | int pixels, float range) 100 | { 101 | 102 | if(fDebug) cout << "MIAnalysis::AnalyzeEvent Begin " << endl; 103 | 104 | // ------------------------- 105 | if (!pythia8->next()) return; 106 | if(fDebug) cout << "MIAnalysis::AnalyzeEvent Event Number " << ievt << endl; 107 | 108 | // reset branches 109 | ResetBranches(); 110 | 111 | // new event----------------------- 112 | fTEventNumber = ievt; 113 | std::vector particlesForJets; 114 | 115 | detector->Reset(); 116 | 117 | // Particle loop ---------------------------------------------------------- 118 | for (int ip=0; ipevent.size(); ++ip){ 119 | 120 | fastjet::PseudoJet p(pythia8->event[ip].px(), 121 | pythia8->event[ip].py(), 122 | pythia8->event[ip].pz(), 123 | pythia8->event[ip].e() ); 124 | 125 | // particles for jets -------------- 126 | if (!pythia8->event[ip].isFinal()) continue; 127 | 128 | //Skip neutrinos, PDGid = 12, 14, 16 129 | if (fabs(pythia8->event[ip].id()) ==12) continue; 130 | if (fabs(pythia8->event[ip].id()) ==14) continue; 131 | if (fabs(pythia8->event[ip].id()) ==16) continue; 132 | 133 | 134 | // find the particles rapidity and phi, then get the detector bins 135 | int ybin = detector->GetXaxis()->FindBin(p.rapidity()); 136 | int phibin = detector->GetYaxis()->FindBin(p.phi()); 137 | 138 | // do bin += value in the associated detector bin 139 | detector->SetBinContent(ybin, phibin, 140 | detector->GetBinContent(ybin, phibin) + p.e()); 141 | 142 | } 143 | // end particle loop ----------------------------------------------- 144 | 145 | //Now, we extract the energy from the calorimeter for processing by fastjet 146 | for (int i = 1; i <= detector->GetNbinsX(); i++) 147 | { 148 | for (int j = 1; j <= detector->GetNbinsY(); j++) 149 | { 150 | if (detector->GetBinContent(i, j) > 0) 151 | { 152 | double phi = detector->GetYaxis()->GetBinCenter(j); 153 | double eta = detector->GetXaxis()->GetBinCenter(i); 154 | double E = detector->GetBinContent(i, j); 155 | fastjet::PseudoJet p(0., 0., 0., 0.); 156 | 157 | //We measure E (not pT)! And treat 'clusters' as massless. 158 | p.reset_PtYPhiM(E/cosh(eta), eta, phi, 0.); 159 | particlesForJets.push_back(p); 160 | } 161 | } 162 | } 163 | 164 | fastjet::JetDefinition *m_jet_def = new fastjet::JetDefinition( 165 | fastjet::antikt_algorithm, 1.0); 166 | 167 | fastjet::Filter trimmer(fastjet::JetDefinition(fastjet::kt_algorithm, 0.3), 168 | fastjet::SelectorPtFractionMin(0.05)); 169 | 170 | fastjet::ClusterSequence csLargeR(particlesForJets, *m_jet_def); 171 | 172 | vector considered_jets = fastjet::sorted_by_pt( 173 | csLargeR.inclusive_jets(10.0)); 174 | fastjet::PseudoJet leading_jet = trimmer(considered_jets[0]); 175 | 176 | //Now, let's make an image out of the leading jet. 177 | vector subjets = sorted_by_pt(leading_jet.pieces()); 178 | 179 | if (subjets.size() < 2) 180 | { 181 | return; 182 | } 183 | 184 | bool overall = true; 185 | // Dump kinematics of the leading jet. 186 | // For the leading SUBjet, put subjets[0]. 187 | fTLeadingEta = leading_jet.eta(); 188 | fTLeadingPhi = leading_jet.phi(); 189 | fTLeadingPt = leading_jet.perp(); 190 | fTLeadingM = leading_jet.m(); 191 | 192 | 193 | vector > consts_image; 194 | vector > subjets_image; 195 | 196 | for (int i = 0; i < 2; i++) 197 | { 198 | pair subjet_hold; 199 | subjet_hold.first = subjets[i].eta(); 200 | subjet_hold.second = subjets[i].phi(); 201 | subjets_image.push_back(subjet_hold); 202 | } 203 | 204 | vector sorted_consts = sorted_by_pt(leading_jet.constituents()); 205 | 206 | for(int i = 0; i < sorted_consts.size(); i++) 207 | { 208 | pair const_hold; 209 | const_hold.first = sorted_consts[i].eta(); 210 | const_hold.second = sorted_consts[i].phi(); 211 | consts_image.push_back(const_hold); 212 | } 213 | 214 | //Step 1: Center on the leading subjet 215 | for (int i =0; i < sorted_consts.size(); i++) 216 | { 217 | consts_image[i].first = consts_image[i].first-subjets_image[0].first; 218 | consts_image[i].second = consts_image[i].second-subjets_image[0].second; 219 | } 220 | for (int i =1; i >= 0; i--) 221 | { 222 | subjets_image[i].first = subjets_image[i].first - subjets_image[0].first; 223 | subjets_image[i].second = subjets_image[i].second- subjets_image[0].second; 224 | } 225 | 226 | //Step 2: Fill in the unrotated image 227 | //------------------------------------------------------------------------- 228 | TH2F* orig_im = new TH2F("", "", pixels, -range, range, pixels, -range, range); 229 | 230 | for (int i = 0; i < sorted_consts.size(); i++) 231 | { 232 | orig_im->Fill(consts_image[i].first,consts_image[i].second,sorted_consts[i].e()); 233 | //std::cout << i << " " << consts_image[i].first << " " << consts_image[i].second << std::endl; 234 | } 235 | 236 | 237 | //Step 3: Rotate so the subleading subjet is at -pi/2 238 | //------------------------------------------------------------------------- 239 | fTSubLeadingEta = subjets_image[1].first; 240 | fTSubLeadingPhi = subjets_image[1].second; 241 | double theta = atan(subjets_image[1].second/subjets_image[1].first)+2.*atan(1.); //atan(1) = pi/4 242 | 243 | if (-sin(theta)*subjets_image[1].first+cos(theta)*subjets_image[1].second > 0) 244 | { 245 | theta+=-4.*atan(1.); 246 | } 247 | 248 | fTRotationAngle = theta; 249 | 250 | for (int i=0; iFill(consts_image[i].first,consts_image[i].second,sorted_consts[i].e()); 274 | } 275 | 276 | //Step 5: Dump the images in the tree! 277 | //------------------------------------------------------------------------- 278 | int counter=0; 279 | for (int i=1; i<=rotatedimage->GetNbinsX(); i++) 280 | { 281 | for (int j=1; j<=rotatedimage->GetNbinsY(); j++) 282 | { 283 | fTRotatedIntensity[counter] = rotatedimage->GetBinContent(i,j); 284 | fTIntensity[counter] = orig_im->GetBinContent(i,j); 285 | 286 | counter++; 287 | } 288 | } 289 | 290 | // Step 6: Fill in nsubjettiness 291 | //---------------------------------------------------------------------------- 292 | OnePass_WTA_KT_Axes axis_spec; 293 | NormalizedMeasure parameters(1.0, 1.0); 294 | 295 | // NormalizedMeasure parameters(1.0, 1.0); 296 | Nsubjettiness subjettiness_1(1, axis_spec, parameters); 297 | Nsubjettiness subjettiness_2(2, axis_spec, parameters); 298 | Nsubjettiness subjettiness_3(3, axis_spec, parameters); 299 | 300 | fTTau1 = (float) subjettiness_1.result(leading_jet); 301 | fTTau2 = (float) subjettiness_2.result(leading_jet); 302 | fTTau3 = (float) subjettiness_3.result(leading_jet); 303 | 304 | fTTau32 = (abs(fTTau2) < 1e-4 ? -10 : fTTau3 / fTTau2); 305 | fTTau21 = (abs(fTTau1) < 1e-4 ? -10 : fTTau2 / fTTau1); 306 | 307 | tT->Fill(); 308 | 309 | return; 310 | } 311 | 312 | // declate branches 313 | void MIAnalysis::DeclareBranches() 314 | { 315 | 316 | // Event Properties 317 | tT->Branch("NFilled", &fTNFilled, "NFilled/I"); 318 | 319 | tT->Branch("Intensity", *&fTIntensity, "Intensity[NFilled]/F"); 320 | 321 | tT->Branch("RotatedIntensity", 322 | *&fTRotatedIntensity, "RotatedIntensity[NFilled]/F"); 323 | 324 | tT->Branch("SubLeadingEta", &fTSubLeadingEta, "SubLeadingEta/F"); 325 | tT->Branch("SubLeadingPhi", &fTSubLeadingPhi, "SubLeadingPhi/F"); 326 | 327 | tT->Branch("LeadingEta", &fTLeadingEta, "LeadingEta/F"); 328 | tT->Branch("LeadingPhi", &fTLeadingPhi, "LeadingPhi/F"); 329 | tT->Branch("LeadingPt", &fTLeadingPt, "LeadingPt/F"); 330 | tT->Branch("LeadingM", &fTLeadingM, "LeadingM/F"); 331 | tT->Branch("RotationAngle", &fTRotationAngle, "RotationAngle/F"); 332 | 333 | // tT->Branch("Tau1", &fTTau1, "Tau1/F"); 334 | // tT->Branch("Tau2", &fTTau2, "Tau2/F"); 335 | // tT->Branch("Tau3", &fTTau3, "Tau3/F"); 336 | 337 | tT->Branch("Tau32", &fTTau32, "Tau32/F"); 338 | tT->Branch("Tau21", &fTTau21, "Tau21/F"); 339 | return; 340 | } 341 | 342 | // resets vars 343 | void MIAnalysis::ResetBranches(){ 344 | // reset branches 345 | fTNFilled = MaxN; 346 | fTSubLeadingPhi = -999; 347 | fTSubLeadingEta = -999; 348 | fTRotationAngle = -999; 349 | 350 | fTTau32 = -999; 351 | fTTau21 = -999; 352 | 353 | fTLeadingEta = -999; 354 | fTLeadingPhi = -999; 355 | fTLeadingPt = -999; 356 | fTLeadingM = -999; 357 | 358 | for (int iP=0; iP < MaxN; ++iP) 359 | { 360 | fTIntensity[iP]= -999; 361 | fTRotatedIntensity[iP]= -999; 362 | } 363 | } 364 | -------------------------------------------------------------------------------- /event-gen/Nsubjettiness/README: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | Nsubjettiness Package 3 | -------------------------------------------------------------------------------- 4 | 5 | The Nsubjettiness package is based on the physics described in: 6 | 7 | Identifying Boosted Objects with N-subjettiness. 8 | Jesse Thaler and Ken Van Tilburg. 9 | JHEP 1103:015 (2011), arXiv:1011.2268. 10 | 11 | Maximizing Boosted Top Identification by Minimizing N-subjettiness. 12 | Jesse Thaler and Ken Van Tilburg. 13 | JHEP 1202:093 (2012), arXiv:1108.2701. 14 | 15 | New in v2.0 is the winner-take-all axis, which is described in: 16 | 17 | Jet Shapes with the Broadening Axis. 18 | Andrew J. Larkoski, Duff Neill, and Jesse Thaler. 19 | JHEP 1404:017 (2014), arXiv:1401.2158. 20 | 21 | as well as in unpublished work by Gavin Salam. 22 | 23 | -------------------------------------------------------------------------------- 24 | Core Classes 25 | -------------------------------------------------------------------------------- 26 | 27 | There are various ways to access N-(sub)jettiness variables, described 28 | in more detail below: 29 | 30 | Nsubjettiness [Nsubjettiness.hh]: 31 | A FunctionOfPseudoJet interface to measure N-subjettiness 32 | (Recommended for most users) 33 | NsubjettinessRatio [Nsubjettiness.hh]: 34 | A FunctionOfPseudoJet interface to measure ratios of 35 | two different N-subjettiness (i.e. tau3/tau2) 36 | NjettinessPlugin [NjettinessPlugin.hh]: 37 | A FastJet plugin for finding jets by minimizing N-jettiness 38 | (Recommended for advanced users) 39 | Njettiness [Njettiness.hh]: 40 | Access to the core Njettiness code. 41 | (Not recommended for users, since the interface might change) 42 | 43 | The code assumes that you have FastJet 3. 44 | 45 | -------------------------------------------------------------------------------- 46 | Basic Usage: Nsubjettiness and NsubjettinessRatio [Nsubjettiness.hh] 47 | -------------------------------------------------------------------------------- 48 | 49 | Most users will only need to use the Nsubjettiness class. The basic 50 | functionality is given by: 51 | 52 | Nsubjettiness nSub(N, AxesDefinition, MeasureDefinition) 53 | // N specifies the number of (sub) jets to measure 54 | // AxesDefinition is WTA_KT_Axes, OnePass_KT_Axes, etc. 55 | // MeasureDefinition is UnnormalizedMeasure(beta), 56 | // NormalizedMeasure(beta,R0), etc. 57 | 58 | // get tau value 59 | double tauN = nSub.result(PseudoJet); 60 | 61 | Also available are ratios of N-subjettiness values 62 | NsubjettinessRatio nSubRatio(N, M, AxesDefinition, 63 | MeasureDefinition) 64 | // N and M give tau_N / tau_M, all other options the same 65 | 66 | -------------------------------------------------------------------------------- 67 | AxesDefinition [NjettinessDefinition.hh] 68 | -------------------------------------------------------------------------------- 69 | 70 | N-(sub)jettiness requires choosing axes as well as a measure (see below). There 71 | are a number of axes choices available to the user, though modes with a (*) are 72 | recommended. Arguments in parentheses are parameters that the user must set. 73 | 74 | Axes can be found using standard recursive clustering procedures. New is the 75 | option to use the "winner-take-all" recombination scheme: 76 | (*) KT_Axes // exclusive kt axes 77 | CA_Axes // exclusive ca axes 78 | AntiKT_Axes(R0) // inclusive hardest axes with antikt, R0 = radius 79 | (*) WTA_KT_Axes // exclusive kt with winner-take-all recombination 80 | WTA_CA_Axes // exclusive ca with winner-take-all recombination 81 | 82 | One can also run a minimization routine to find a (local) minimum of 83 | N-(sub)jettiness: 84 | (*) OnePass_KT_Axes // one-pass minimization from kt starting point 85 | OnePass_CA_Axes // one-pass min. from ca starting point 86 | OnePass_AntiKT(R0) // one-pass min. from antikt starting point,R0=rad 87 | (*) OnePass_WTA_KT_Axes // one-pass min. from wta_kt starting point 88 | OnePass_WTA_CA_Axes // one-pass min. from wta_ca starting point 89 | 90 | In general, it is difficult to finding the global minimum, but this mode 91 | attempts to do so 92 | MultiPass_Axes(Npass) // axes that (attempt to) minimize N-subjettiness 93 | // (NPass = 100 is typical) 94 | 95 | Finally, one can set manual axes: 96 | Manual_Axes // set your own axes with setAxes() 97 | OnePass_Manual_Axes // one-pass minimization from manual starting point 98 | 99 | For most cases, running with OnePass_KT_Axes or OnePass_WTA_KT_Axes gives 100 | reasonable results (and the results are IRC safe). Because it uses random 101 | number seeds, MultiPass_Axes is not IRC safe (and the code is rather slow). Note 102 | that for the minimization routines, beta = 1.1 is faster than beta = 1, with 103 | comparable performance. 104 | 105 | -------------------------------------------------------------------------------- 106 | MeasureDefinition [NjettinessDefinition.hh] 107 | -------------------------------------------------------------------------------- 108 | 109 | At the moment, there are only a few measures. Note that each one has a 110 | different number of parameters. The one indicated by (*) 111 | is the one recommended for use by users new to Nsubjettiness. 112 | 113 | The original N-subjettiness measures are: 114 | NormalizedMeasure(beta,R0) //default normalized measure with 115 | //parameters beta and R0 (dimensionless) 116 | (*) UnnormalizedMeasure(beta) //default unnormalized measure with just 117 | //parameter beta (dimensionful) 118 | 119 | There are also measures that incorporate a radial cutoff: 120 | NormalizedCutoffMeasure(beta,R0,Rcutoff) //normalized measure with 121 | //additional Rcutoff 122 | UnnormalizedCutoffMeasure(beta,Rcutoff) //unnormalized measure with 123 | //additional Rcutoff 124 | 125 | In beta testing are "geometric" measures where distances are measured using the 126 | Lorentz dot product (N.B. the formula for the geometric measure is likely to 127 | change since there should be separate beam and jet beta factors.) 128 | GeometricMeasure(beta) //geometric measure with exponent beta 129 | GeometricCutoffMeasure(beta,Rcutoff) //geometric measure with Rcutoff 130 | 131 | -------------------------------------------------------------------------------- 132 | A note on beta dependence 133 | -------------------------------------------------------------------------------- 134 | 135 | The angular exponent in N-subjettiness is called beta. The original 136 | N-subjettiness paper advocated beta = 1, but it is now understood that different 137 | beta values can be useful in different contexts. The two main choices are: 138 | 139 | beta = 1: aka broadening/girth/width measure 140 | wta_kt_axes are approximately the same as minimizing beta = 1 measure 141 | 142 | beta = 2: aka thrust/mass measure 143 | kt_axes are approximately the same as minimizing beta = 2 measure 144 | 145 | N.B. The minimization routines are only valid for 1 < beta < 3. 146 | 147 | For quark/gluon discrimination with N = 1, beta~0.2 with wta_kt_axes appears 148 | to be a good choice. 149 | 150 | -------------------------------------------------------------------------------- 151 | TauComponents [MeasureFunction.hh] 152 | -------------------------------------------------------------------------------- 153 | 154 | For most users, they will only need the value of N-subjettiness (i.e. tau) 155 | itself. For advanced users, they can access individual tau components (i.e. 156 | the individual numerator pieces, the denominator, etc.) 157 | 158 | TauComponents tauComp = nSub.component_result(jet); 159 | vector numer = tauComp.jet_pieces_numerator(); //tau for each subjet 160 | double denom = tauComp.denominator(); //normalization factor 161 | 162 | -------------------------------------------------------------------------------- 163 | WinnerTakeAllRecombiner [WinnerTakeAllRecombiner.hh] 164 | -------------------------------------------------------------------------------- 165 | 166 | New for version 2.0 of Nsubjettiness are winner-take-all axes. They are found 167 | with the help of the WinnerTakeAllRecombiner. This class defines a new 168 | recombination scheme for clustering particles. This scheme recombines two 169 | PseudoJets into a PseudoJet with pT of the sum of the two input PseudoJet pTs 170 | and direction of the harder PseudoJet. This is a "recoil-free" recombination 171 | scheme that guarantees that the axes is aligned with one of the input particles. 172 | It is IRC safe. Axes found with the standard E-scheme recombiner at similar to 173 | the beta = 2 minimization, while winner-take-all is similar to the beta = 1 174 | measure. 175 | 176 | Note that the WinnerTakeAllRecombiner can be used outside of Nsubjettiness 177 | itself for jet finding. For example, the direction of anti-kT jets found 178 | with the WinnerTakeAllRecombiner is particularly robust against soft jet 179 | contamination. 180 | 181 | -------------------------------------------------------------------------------- 182 | Advanced Usage: NjettinessPlugin [NjettinessPlugin.hh] 183 | -------------------------------------------------------------------------------- 184 | 185 | The Njettiness FastJet plugin represents an exclusive jet finder (yielding a 186 | fixed N number of jets). The algorithm finds N axes, and jets are simply the sum 187 | of particles closest to a given axis (or unclustered if they are closest to the 188 | beam). The axes finding methods and measures are the same as for Nsubjettiness. 189 | 190 | NjettinessPlugin plugin(N, AxesDefinition, MeasureDefinition); 191 | JetDefinition def(&plugin); 192 | ClusterSequence cs(vector,def); 193 | vector jets = cs.inclusive_jets(); 194 | 195 | Note that despite being an exclusive jet algorithm, one finds the jets using the 196 | inclusive_jets() call. 197 | 198 | -------------------------------------------------------------------------------- 199 | Very Advanced Usage: Njettiness [Njettiness.hh] 200 | -------------------------------------------------------------------------------- 201 | 202 | Most users will want to use the Nsubjettiness or NjettinessPlugin classes to 203 | access N-(sub)jettiness information. For direct access to the Njettiness class, 204 | one can use Njettiness.hh directly. This class is still evolving, so users who 205 | wish to extend its functionality should contact the authors first. 206 | 207 | -------------------------------------------------------------------------------- 208 | Technical Details 209 | -------------------------------------------------------------------------------- 210 | 211 | In general, the user will never need access to these header files. Here is a 212 | brief description about how they are used to help the calculation of 213 | N-(sub)jettiness: 214 | 215 | AxesFinder.hh: 216 | 217 | The AxesFinder class (and derived classes) defines the axes used in the 218 | calculation of N-(sub)jettiness. These axes can be defined from the exclusive 219 | jets from a kT or CA algorithm, the hardest jets from an anti-kT algorithm, 220 | manually, or from minimization of N-jettiness. In the future, the user will be 221 | able to write their own axes finder, though currently the interface is still 222 | evolving. At the moment, the user should stick to the options allowed by 223 | AxesDefinition. 224 | 225 | MeasureFunction.hh: 226 | 227 | The MeasureFunction class (and derived classes) defines the measure by which 228 | N-(sub)jettiness is calculated. This measure is calculated between each 229 | particle and its corresponding axis, and then summed and normalized to 230 | produce N-(sub)jettiness. The default measure for this calculation is 231 | pT*dR^beta, where dR is the rapidity-azimuth distance between the particle 232 | and its axis, and beta is the angular exponent. Again, in the future the user 233 | will be able to write their own measures, but for the time being, only the 234 | predefined MeasureDefinition values should be used. 235 | 236 | -------------------------------------------------------------------------------- 237 | Known Issues 238 | -------------------------------------------------------------------------------- 239 | 240 | -- The MultiPass_Axes mode gives different answers on different runs, since 241 | random numbers are used. 242 | -- In rare cases, one pass minimization can give a larger value of Njettiness 243 | than without minimization. 244 | -- Nsubjettiness is not thread safe, since there are mutables in Njettiness. -------------------------------------------------------------------------------- /event-gen/Nsubjettiness/MeasureFunction.hh: -------------------------------------------------------------------------------- 1 | // Nsubjettiness Package 2 | // Questions/Comments? jthaler@jthaler.net 3 | // 4 | // Copyright (c) 2011-14 5 | // Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason 6 | // 7 | // $Id: MeasureFunction.hh 678 2014-06-12 20:43:03Z jthaler $ 8 | //---------------------------------------------------------------------- 9 | // This file is part of FastJet contrib. 10 | // 11 | // It is free software; you can redistribute it and/or modify it under 12 | // the terms of the GNU General Public License as published by the 13 | // Free Software Foundation; either version 2 of the License, or (at 14 | // your option) any later version. 15 | // 16 | // It is distributed in the hope that it will be useful, but WITHOUT 17 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 18 | // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 19 | // License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this code. If not, see . 23 | //---------------------------------------------------------------------- 24 | 25 | #ifndef __FASTJET_CONTRIB_MEASUREFUNCTION_HH__ 26 | #define __FASTJET_CONTRIB_MEASUREFUNCTION_HH__ 27 | 28 | #include "fastjet/PseudoJet.hh" 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | 35 | FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 36 | 37 | namespace contrib{ 38 | 39 | /////// 40 | // 41 | // TauComponents 42 | // (eventually we might want to put this in a separate header file) 43 | // 44 | /////// 45 | 46 | /// \class TauComponents 47 | // This class creates a wrapper for the various tau/subtau values calculated in Njettiness. This class allows Njettiness access to these variables 48 | // without ever having to do the calculation itself. It takes in subtau numerators and tau denominator from MeasureFunction 49 | // and outputs tau numerator, and normalized tau and subtau. 50 | class TauComponents { 51 | 52 | public: 53 | // empty constructor necessary to initialize tau_components in Njettiness 54 | // later set correctly in Njettiness::getTau function 55 | TauComponents() { 56 | _jet_pieces_numerator.resize(1, 0.0); 57 | _beam_piece_numerator = 0.0; 58 | _denominator = 0; 59 | _numerator = 0; 60 | _jet_pieces.resize(1, 0.0); 61 | _beam_piece = 0.0; 62 | _tau = 0; 63 | _has_denominator = false; 64 | _has_beam = false; 65 | } 66 | 67 | // This constructor takes input vector and double and calculates all necessary tau components 68 | TauComponents(std::vector jet_pieces_numerator, double beam_piece_numerator, double denominator, bool has_denominator, bool has_beam) 69 | : _jet_pieces_numerator(jet_pieces_numerator), 70 | _beam_piece_numerator(beam_piece_numerator), 71 | _denominator(denominator), 72 | _has_denominator(has_denominator), 73 | _has_beam(has_beam) { 74 | 75 | if (!_has_denominator) assert(_denominator == 1.0); //make sure no effect from _denominator if _has_denominator is false 76 | if (!_has_beam) assert (_beam_piece_numerator == 0.0); //make sure no effect from _beam_piece_numerator if _has_beam is false 77 | 78 | _numerator = _beam_piece_numerator; 79 | _jet_pieces.resize(_jet_pieces_numerator.size(),0.0); 80 | for (unsigned j = 0; j < _jet_pieces_numerator.size(); j++) { 81 | _jet_pieces[j] = _jet_pieces_numerator[j]/_denominator; 82 | _numerator += _jet_pieces_numerator[j]; 83 | } 84 | 85 | _beam_piece = _beam_piece_numerator/_denominator; 86 | _tau = _numerator/_denominator; 87 | } 88 | 89 | 90 | // return values 91 | std::vector jet_pieces_numerator() const { return _jet_pieces_numerator; } 92 | double beam_piece_numerator() const { return _beam_piece_numerator; } 93 | double denominator() const { return _denominator; } 94 | double numerator() const { return _numerator; } 95 | 96 | bool has_denominator() const { return _has_denominator; } 97 | bool has_beam() const { return _has_beam; } 98 | 99 | std::vector jet_pieces() const { return _jet_pieces; } 100 | double beam_piece() const { return _beam_piece; } 101 | double tau() const { return _tau; } 102 | 103 | private: 104 | 105 | // these values are input in the constructor 106 | std::vector _jet_pieces_numerator; 107 | double _beam_piece_numerator; 108 | double _denominator; 109 | bool _has_denominator; //added so that TauComponents knows if denominator is used or not 110 | bool _has_beam; //added so that TauComponents knows if beam regions is used or not 111 | 112 | // these values are derived from above values 113 | std::vector _jet_pieces; 114 | double _beam_piece; 115 | double _numerator; 116 | double _tau; 117 | 118 | }; 119 | 120 | /////// 121 | // 122 | // Measure Function 123 | // 124 | /////// 125 | 126 | 127 | //------------------------------------------------------------------------ 128 | /// \class MeasureFunction 129 | // This class calculates the tau_N of a jet given a specific measure. 130 | // It serves as a base class for calculating tau_N according to different measures that are implemented 131 | // in further derived classes, but does not define a particular measure itself. 132 | class MeasureFunction { 133 | 134 | public: 135 | //These functions define the measure by which tau_N is calculated, 136 | //and are overloaded by the various measures below 137 | 138 | // Distanes to axes. These are called many times, so need to be as fast as possible 139 | virtual double jet_distance_squared(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const = 0; 140 | virtual double beam_distance_squared(const fastjet::PseudoJet& particle) const = 0; 141 | 142 | // The actual measures used in N-(sub)jettiness 143 | virtual double jet_numerator(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const = 0; 144 | virtual double beam_numerator(const fastjet::PseudoJet& particle) const = 0; 145 | 146 | // a possible normalization factor 147 | virtual double denominator(const fastjet::PseudoJet& particle) const = 0; 148 | 149 | //------ 150 | // The functions below call the above functions and are not virtual 151 | //------ 152 | 153 | // Return all of the necessary TauComponents for specific input particles and axes 154 | // Also have optional pointers to get out information about partitioning 155 | TauComponents result(const std::vector& particles, const std::vector& axes) const; 156 | 157 | // Just getting tau value if that is all that is needed 158 | double tau(const std::vector& particles, const std::vector& axes) const { 159 | return result(particles,axes).tau(); 160 | } 161 | 162 | // Create the partitioning and stores internally 163 | std::vector get_partition(const std::vector& particles, const std::vector& axes, PseudoJet * beamPartitionStorage = NULL) const; 164 | 165 | // Essentially same as get_partition, but in the form needed for the jet algorithm 166 | std::vector > get_partition_list(const std::vector& particles, const std::vector& axes) const; 167 | 168 | // calculates the tau result using an existing partition 169 | TauComponents result_from_partition(const std::vector& jet_partitioning, const std::vector& axes, PseudoJet * beamPartitionStorage = NULL) const; 170 | 171 | // shorthand for squaring 172 | static inline double sq(double x) {return x*x;} 173 | 174 | //virtual destructor 175 | virtual ~MeasureFunction(){} 176 | 177 | protected: 178 | //bool set by derived classes to choose whether or not to use the denominator 179 | bool _has_denominator; 180 | bool _has_beam; 181 | 182 | // This constructor allows _has_denominator to be set by derived classes 183 | MeasureFunction(bool has_denominator = true, bool has_beam = true) : _has_denominator(has_denominator), _has_beam(has_beam) {} 184 | 185 | }; 186 | 187 | 188 | /// \class DefaultNormalizedMeasureFunction 189 | // This class is the default measure, inheriting from the class above. This class will calculate tau_N 190 | // of a jet according to this measure. This measure is defined as the pT of the particle multiplied by deltaR 191 | // to the power of beta. This class includes the normalization factor determined by R0 192 | class DefaultNormalizedMeasureFunction : public MeasureFunction { 193 | 194 | public: 195 | 196 | DefaultNormalizedMeasureFunction(double beta, double R0, double Rcutoff, bool normalized = true) 197 | : MeasureFunction(normalized), _beta(beta), _R0(R0), _Rcutoff(Rcutoff) {} 198 | 199 | virtual double jet_distance_squared(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const { 200 | return particle.squared_distance(axis); 201 | } 202 | 203 | virtual double beam_distance_squared(const fastjet::PseudoJet& /*particle*/) const { 204 | return sq(_Rcutoff); 205 | } 206 | 207 | virtual double jet_numerator(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const{ 208 | return particle.perp() * std::pow(jet_distance_squared(particle,axis),_beta/2.0); 209 | } 210 | 211 | virtual double beam_numerator(const fastjet::PseudoJet& particle) const { 212 | return particle.perp() * std::pow(_Rcutoff,_beta); 213 | } 214 | 215 | virtual double denominator(const fastjet::PseudoJet& particle) const { 216 | return particle.perp() * std::pow(_R0,_beta); 217 | } 218 | 219 | private: 220 | double _beta; 221 | double _R0; 222 | double _Rcutoff; 223 | 224 | 225 | }; 226 | 227 | //------------------------------------------------------------------------ 228 | /// \class DefaultUnnormalizedMeasureFunction 229 | // This class is the unnormalized default measure, inheriting from the class above. The only difference from above 230 | // is that the denominator is defined to be 1.0 by setting _has_denominator to false. 231 | class DefaultUnnormalizedMeasureFunction : public DefaultNormalizedMeasureFunction { 232 | 233 | public: 234 | // Since all methods are identical, UnnormalizedMeasure inherits directly 235 | // from NormalizedMeasure. R0 is a dummy value since the value of R0 is unecessary for this class, 236 | // and the "false" flag sets _has_denominator in MeasureFunction to false so no denominator is used. 237 | DefaultUnnormalizedMeasureFunction(double beta, double Rcutoff) 238 | : DefaultNormalizedMeasureFunction(beta, std::numeric_limits::quiet_NaN(), Rcutoff, false) {} 239 | }; 240 | 241 | //------------------------------------------------------------------------ 242 | /// \class GeometricMeasureFunction 243 | // This class is the geometic measure, inheriting from the class above. This class will calculate tau_N 244 | // of a jet according to this measure. This measure is defined by the Lorentz dot product between 245 | // the particle and the axis. This class includes normalization of tau_N. 246 | class GeometricMeasureFunction : public MeasureFunction { 247 | 248 | public: 249 | // Right now, we are hard coded for beam_beta = 1.0, but that will need to change 250 | GeometricMeasureFunction(double jet_beta, double Rcutoff) : 251 | MeasureFunction(false), // doesn't have denominator 252 | _jet_beta(jet_beta), _beam_beta(1.0), _Rcutoff(Rcutoff) {} 253 | 254 | virtual double jet_distance_squared(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const { 255 | fastjet::PseudoJet lightAxis = lightFrom(axis); 256 | double pseudoRsquared = 2.0*dot_product(lightFrom(axis),particle)/(lightAxis.pt()*particle.pt()); 257 | return pseudoRsquared; 258 | } 259 | 260 | virtual double beam_distance_squared(const fastjet::PseudoJet& /*particle*/) const { 261 | return sq(_Rcutoff); 262 | } 263 | 264 | virtual double jet_numerator(const fastjet::PseudoJet& particle, const fastjet::PseudoJet& axis) const { 265 | fastjet::PseudoJet lightAxis = lightFrom(axis); 266 | double weight = (_beam_beta == 1.0) ? 1.0 : std::pow(lightAxis.pt(),_beam_beta - 1.0); 267 | return particle.pt() * weight * std::pow(jet_distance_squared(particle,axis),_jet_beta/2.0); 268 | } 269 | 270 | virtual double beam_numerator(const fastjet::PseudoJet& particle) const { 271 | double weight = (_beam_beta == 1.0) ? 1.0 : std::pow(particle.pt()/particle.e(),_beam_beta - 1.0); 272 | return particle.pt() * weight * std::pow(_Rcutoff,_jet_beta); 273 | } 274 | 275 | virtual double denominator(const fastjet::PseudoJet& /*particle*/) const { 276 | return std::numeric_limits::quiet_NaN(); 277 | } 278 | 279 | 280 | private: 281 | double _jet_beta; 282 | double _beam_beta; 283 | double _Rcutoff; 284 | 285 | // create light-like axis 286 | fastjet::PseudoJet lightFrom(const fastjet::PseudoJet& input) const { 287 | double length = sqrt(pow(input.px(),2) + pow(input.py(),2) + pow(input.pz(),2)); 288 | return fastjet::PseudoJet(input.px()/length,input.py()/length,input.pz()/length,1.0); 289 | } 290 | 291 | }; 292 | 293 | 294 | } //namespace contrib 295 | 296 | FASTJET_END_NAMESPACE 297 | 298 | #endif // __FASTJET_CONTRIB_MEASUREFUNCTION_HH__ 299 | -------------------------------------------------------------------------------- /event-gen/Nsubjettiness/example_basic_usage.cc: -------------------------------------------------------------------------------- 1 | // Nsubjettiness Package 2 | // Questions/Comments? jthaler@jthaler.net 3 | // 4 | // Copyright (c) 2011-13 5 | // Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason 6 | // 7 | // Run this example with: 8 | // ./example_basic_usage < ../data/single-event.dat 9 | // 10 | // $Id: example_basic_usage.cc 704 2014-07-07 14:30:43Z jthaler $ 11 | //---------------------------------------------------------------------- 12 | // This file is part of FastJet contrib. 13 | // 14 | // It is free software; you can redistribute it and/or modify it under 15 | // the terms of the GNU General Public License as published by the 16 | // Free Software Foundation; either version 2 of the License, or (at 17 | // your option) any later version. 18 | // 19 | // It is distributed in the hope that it will be useful, but WITHOUT 20 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 21 | // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 22 | // License for more details. 23 | // 24 | // You should have received a copy of the GNU General Public License 25 | // along with this code. If not, see . 26 | //---------------------------------------------------------------------- 27 | 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include "fastjet/PseudoJet.hh" 40 | #include "fastjet/ClusterSequenceArea.hh" 41 | #include 42 | #include "Nsubjettiness.hh" // In external code, this should be fastjet/contrib/Nsubjettiness.hh 43 | #include "Njettiness.hh" 44 | #include "NjettinessPlugin.hh" 45 | 46 | 47 | using namespace std; 48 | using namespace fastjet; 49 | using namespace fastjet::contrib; 50 | 51 | // forward declaration to make things clearer 52 | void read_event(vector &event); 53 | void analyze(const vector & input_particles); 54 | 55 | //---------------------------------------------------------------------- 56 | int main(){ 57 | 58 | //---------------------------------------------------------- 59 | // read in input particles 60 | vector event; 61 | read_event(event); 62 | cout << "# read an event with " << event.size() << " particles" << endl; 63 | 64 | //---------------------------------------------------------- 65 | // illustrate how Nsubjettiness contrib works 66 | 67 | analyze(event); 68 | 69 | return 0; 70 | } 71 | 72 | // read in input particles 73 | void read_event(vector &event){ 74 | string line; 75 | while (getline(cin, line)) { 76 | istringstream linestream(line); 77 | // take substrings to avoid problems when there are extra "pollution" 78 | // characters (e.g. line-feed). 79 | if (line.substr(0,4) == "#END") {return;} 80 | if (line.substr(0,1) == "#") {continue;} 81 | double px,py,pz,E; 82 | linestream >> px >> py >> pz >> E; 83 | PseudoJet particle(px,py,pz,E); 84 | 85 | // push event onto back of full_event vector 86 | event.push_back(particle); 87 | } 88 | } 89 | 90 | // Helper Function for Printing out Jet Information 91 | void PrintJets(const vector & jets, TauComponents components, bool showTotal = true); 92 | 93 | //////// 94 | // 95 | // Main Routine for Analysis 96 | // 97 | /////// 98 | 99 | void analyze(const vector & input_particles) { 100 | 101 | //////// 102 | // 103 | // Start of analysis. First find anti-kT jets, then find N-subjettiness values of those jets 104 | // 105 | /////// 106 | 107 | // Initial clustering with anti-kt algorithm 108 | JetAlgorithm algorithm = antikt_algorithm; 109 | double jet_rad = 1.00; // jet radius for anti-kt algorithm 110 | JetDefinition jetDef = JetDefinition(algorithm,jet_rad,E_scheme,Best); 111 | ClusterSequence clust_seq(input_particles,jetDef); 112 | vector antikt_jets = sorted_by_pt(clust_seq.inclusive_jets()); 113 | 114 | for (int j = 0; j < 2; j++) { // Two hardest jets per event 115 | if (antikt_jets[j].perp() < 200) continue; 116 | 117 | vector jet_constituents = clust_seq.constituents(antikt_jets[j]); 118 | 119 | cout << "-------------------------------------------------------------------------------------" << endl; 120 | cout << "Analyzing Jet " << j + 1 << ":" << endl; 121 | cout << "-------------------------------------------------------------------------------------" << endl; 122 | 123 | 124 | //////// 125 | // 126 | // Basic checks of tau values first 127 | // 128 | // If you don't want to know the directions of the subjets, 129 | // then you can use the simple function Nsubjettiness. 130 | // 131 | // Recommended usage for Nsubjettiness: 132 | // AxesMode: kt_axes, wta_kt_axes, onepass_kt_axes, or onepass_wta_kt_axes 133 | // MeasureMode: unnormalized_measure 134 | // beta with kt_axes: 2.0 135 | // beta with wta_kt_axes: anything greater than 0.0 (particularly good for 1.0) 136 | // beta with onepass_kt_axes or onepass_wta_kt_axes: between 1.0 and 3.0 137 | // 138 | /////// 139 | 140 | 141 | cout << "-------------------------------------------------------------------------------------" << endl; 142 | cout << "N-subjettiness with Unnormalized Measure (in GeV)" << endl; 143 | cout << "beta = 1.0: One-pass Winner-Take-All kT Axes" << endl; 144 | cout << "beta = 2.0: One-pass E-Scheme kT Axes" << endl; 145 | cout << "-------------------------------------------------------------------------------------" << endl; 146 | 147 | 148 | // Now loop through all options 149 | cout << setprecision(6) << right << fixed; 150 | 151 | cout << "-------------------------------------------------------------------------------------" << endl; 152 | cout << setw(15) << "beta" 153 | << setw(14) << "tau1" 154 | << setw(14) << "tau2" 155 | << setw(14) << "tau3" 156 | << setw(14) << "tau2/tau1" 157 | << setw(14) << "tau3/tau2" 158 | << endl; 159 | 160 | 161 | // Axes modes to try 162 | OnePass_WTA_KT_Axes axisMode1; 163 | OnePass_KT_Axes axisMode2; 164 | 165 | 166 | // Measure modes to try 167 | double beta1 = 1.0; 168 | double beta2 = 2.0; 169 | UnnormalizedMeasure measureSpec1(beta1); 170 | UnnormalizedMeasure measureSpec2(beta2); 171 | 172 | // define Nsubjettiness functions (beta = 1.0) 173 | Nsubjettiness nSub1_beta1(1, axisMode1,measureSpec1); 174 | // an alternative (but more prone to error) constructor is nSub1_beta1(1, axisMode1,Njettiness::unnormalized_measure,beta1); 175 | Nsubjettiness nSub2_beta1(2, axisMode1,measureSpec1); 176 | Nsubjettiness nSub3_beta1(3, axisMode1,measureSpec1); 177 | NsubjettinessRatio nSub21_beta1(2,1,axisMode1,measureSpec1); 178 | NsubjettinessRatio nSub32_beta1(3,2,axisMode1,measureSpec1); 179 | 180 | // define Nsubjettiness functions (beta = 2.0) 181 | Nsubjettiness nSub1_beta2(1, axisMode2,measureSpec2); 182 | Nsubjettiness nSub2_beta2(2, axisMode2,measureSpec2); 183 | Nsubjettiness nSub3_beta2(3, axisMode2,measureSpec2); 184 | NsubjettinessRatio nSub21_beta2(2,1,axisMode2,measureSpec2); 185 | NsubjettinessRatio nSub32_beta2(3,2,axisMode2,measureSpec2); 186 | 187 | // calculate Nsubjettiness values (beta = 1.0) 188 | double tau1_beta1 = nSub1_beta1(antikt_jets[j]); 189 | double tau2_beta1 = nSub2_beta1(antikt_jets[j]); 190 | double tau3_beta1 = nSub3_beta1(antikt_jets[j]); 191 | double tau21_beta1 = nSub21_beta1(antikt_jets[j]); 192 | double tau32_beta1 = nSub32_beta1(antikt_jets[j]); 193 | 194 | // calculate Nsubjettiness values (beta = 2.0) 195 | double tau1_beta2 = nSub1_beta2(antikt_jets[j]); 196 | double tau2_beta2 = nSub2_beta2(antikt_jets[j]); 197 | double tau3_beta2 = nSub3_beta2(antikt_jets[j]); 198 | double tau21_beta2 = nSub21_beta2(antikt_jets[j]); 199 | double tau32_beta2 = nSub32_beta2(antikt_jets[j]); 200 | 201 | // Output results (beta = 1.0) 202 | cout << setw(15) << beta1 203 | << setw(14) << tau1_beta1 204 | << setw(14) << tau2_beta1 205 | << setw(14) << tau3_beta1 206 | << setw(14) << tau21_beta1 207 | << setw(14) << tau32_beta1 208 | << endl; 209 | 210 | // Output results (beta = 2.0) 211 | cout << setw(15) << beta2 212 | << setw(14) << tau1_beta2 213 | << setw(14) << tau2_beta2 214 | << setw(14) << tau3_beta2 215 | << setw(14) << tau21_beta2 216 | << setw(14) << tau32_beta2 217 | << endl; 218 | 219 | 220 | cout << "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" << endl; 221 | cout << "Subjets found using beta = 1.0 tau values" << endl; 222 | PrintJets(nSub1_beta1.currentSubjets(),nSub1_beta1.currentTauComponents()); // these subjets have valid constituents 223 | cout << "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -" << endl; 224 | PrintJets(nSub2_beta1.currentSubjets(),nSub2_beta1.currentTauComponents()); // these subjets have valid constituents 225 | cout << "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -" << endl; 226 | PrintJets(nSub3_beta1.currentSubjets(),nSub3_beta1.currentTauComponents()); // these subjets have valid constituents 227 | cout << "-------------------------------------------------------------------------------------" << endl; 228 | 229 | cout << "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" << endl; 230 | cout << "Axes used for above beta = 1.0 tau values" << endl; 231 | 232 | PrintJets(nSub1_beta1.currentAxes(),nSub1_beta1.currentTauComponents(),false); 233 | //PrintJets(nSub1_beta1.seedAxes()); // For one-pass minimization, this would show starting seeds 234 | cout << "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -" << endl; 235 | PrintJets(nSub2_beta1.currentAxes(),nSub2_beta1.currentTauComponents(),false); 236 | //PrintJets(nSub2_beta1.seedAxes()); // For one-pass minimization, this would show starting seeds 237 | cout << "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -" << endl; 238 | PrintJets(nSub3_beta1.currentAxes(),nSub3_beta1.currentTauComponents(),false); 239 | //PrintJets(nSub3_beta1.seedAxes()); // For one-pass minimization, this would show starting seeds 240 | 241 | cout << "-------------------------------------------------------------------------------------" << endl; 242 | 243 | } 244 | 245 | } 246 | 247 | void PrintJets(const vector & jets, TauComponents components, bool showTotal) { 248 | 249 | string commentStr = ""; 250 | 251 | // gets extras information 252 | if (jets.size() == 0) return; 253 | 254 | // For printing out component tau information 255 | vector subTaus = components.jet_pieces(); 256 | double totalTau = components.tau(); 257 | 258 | bool useArea = jets[0].has_area(); 259 | 260 | // define nice tauN header 261 | int N = jets.size(); 262 | stringstream ss(""); ss << "tau" << N; string tauName = ss.str(); 263 | 264 | cout << fixed << right; 265 | 266 | cout << commentStr << setw(5) << "jet #" << " " 267 | << setw(10) << "rap" 268 | << setw(10) << "phi" 269 | << setw(11) << "pt" 270 | << setw(11) << "m" 271 | << setw(11) << "e"; 272 | if (jets[0].has_constituents()) cout << setw(11) << "constit"; 273 | cout << setw(13) << tauName; 274 | if (useArea) cout << setw(10) << "area"; 275 | cout << endl; 276 | 277 | 278 | // print out individual jet information 279 | for (unsigned i = 0; i < jets.size(); i++) { 280 | cout << commentStr << setw(5) << i+1 << " " 281 | << setprecision(4) << setw(10) << jets[i].rap() 282 | << setprecision(4) << setw(10) << jets[i].phi() 283 | << setprecision(4) << setw(11) << jets[i].perp() 284 | << setprecision(4) << setw(11) << max(jets[i].m(),0.0) // needed to fix -0.0 issue on some compilers. 285 | << setprecision(4) << setw(11) << jets[i].e(); 286 | if (jets[i].has_constituents()) cout << setprecision(4) << setw(11) << jets[i].constituents().size(); 287 | cout << setprecision(6) << setw(13) << max(subTaus[i],0.0); 288 | if (useArea) cout << setprecision(4) << setw(10) << (jets[i].has_area() ? jets[i].area() : 0.0 ); 289 | cout << endl; 290 | } 291 | 292 | // print out total jet 293 | if (showTotal) { 294 | fastjet::PseudoJet total = join(jets); 295 | 296 | cout << commentStr << setw(5) << "total" << " " 297 | << setprecision(4) << setw(10) << total.rap() 298 | << setprecision(4) << setw(10) << total.phi() 299 | << setprecision(4) << setw(11) << total.perp() 300 | << setprecision(4) << setw(11) << max(total.m(),0.0) // needed to fix -0.0 issue on some compilers. 301 | << setprecision(4) << setw(11) << total.e(); 302 | if (jets[0].has_constituents()) cout << setprecision(4) << setw(11) << total.constituents().size(); 303 | cout << setprecision(6) << setw(13) << totalTau; 304 | if (useArea) cout << setprecision(4) << setw(10) << (total.has_area() ? total.area() : 0.0); 305 | cout << endl; 306 | } 307 | } 308 | 309 | -------------------------------------------------------------------------------- /event-gen/Nsubjettiness/AxesFinder.cc: -------------------------------------------------------------------------------- 1 | // Nsubjettiness Package 2 | // Questions/Comments? jthaler@jthaler.net 3 | // 4 | // Copyright (c) 2011-14 5 | // Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason 6 | // 7 | // $Id: AxesFinder.cc 670 2014-06-06 01:24:42Z jthaler $ 8 | //---------------------------------------------------------------------- 9 | // This file is part of FastJet contrib. 10 | // 11 | // It is free software; you can redistribute it and/or modify it under 12 | // the terms of the GNU General Public License as published by the 13 | // Free Software Foundation; either version 2 of the License, or (at 14 | // your option) any later version. 15 | // 16 | // It is distributed in the hope that it will be useful, but WITHOUT 17 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 18 | // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 19 | // License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this code. If not, see . 23 | //---------------------------------------------------------------------- 24 | 25 | #include "AxesFinder.hh" 26 | 27 | FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 28 | 29 | namespace contrib{ 30 | 31 | /////// 32 | // 33 | // Functions for minimization. 34 | // 35 | /////// 36 | 37 | // Given starting axes, update to find better axes by using Kmeans clustering around the old axes 38 | template 39 | std::vector AxesFinderFromOnePassMinimization::UpdateAxesFast(const std::vector & old_axes, 40 | const std::vector & inputJets) const { 41 | assert(old_axes.size() == N); 42 | 43 | // some storage, declared static to save allocation/re-allocation costs 44 | static LightLikeAxis new_axes[N]; 45 | static fastjet::PseudoJet new_jets[N]; 46 | for (int n = 0; n < N; ++n) { 47 | new_axes[n].reset(0.0,0.0,0.0,0.0); 48 | new_jets[n].reset_momentum(0.0,0.0,0.0,0.0); 49 | } 50 | 51 | double precision = _precision; 52 | 53 | /////////////// Assignment Step ////////////////////////////////////////////////////////// 54 | std::vector assignment_index(inputJets.size()); 55 | int k_assign = -1; 56 | 57 | for (unsigned i = 0; i < inputJets.size(); i++){ 58 | double smallestDist = std::numeric_limits::max(); //large number 59 | for (int k = 0; k < N; k++) { 60 | double thisDist = old_axes[k].DistanceSq(inputJets[i]); 61 | if (thisDist < smallestDist) { 62 | smallestDist = thisDist; 63 | k_assign = k; 64 | } 65 | } 66 | if (smallestDist > sq(_Rcutoff)) {k_assign = -1;} 67 | assignment_index[i] = k_assign; 68 | } 69 | 70 | //////////////// Update Step ///////////////////////////////////////////////////////////// 71 | double distPhi, old_dist; 72 | for (unsigned i = 0; i < inputJets.size(); i++) { 73 | int old_jet_i = assignment_index[i]; 74 | if (old_jet_i == -1) {continue;} 75 | 76 | const fastjet::PseudoJet& inputJet_i = inputJets[i]; 77 | LightLikeAxis& new_axis_i = new_axes[old_jet_i]; 78 | double inputPhi_i = inputJet_i.phi(); 79 | double inputRap_i = inputJet_i.rap(); 80 | 81 | // optimize pow() call 82 | // add noise (the precision term) to make sure we don't divide by zero 83 | if (_beta == 1.0) { 84 | double DR = std::sqrt(sq(precision) + old_axes[old_jet_i].DistanceSq(inputJet_i)); 85 | old_dist = 1.0/DR; 86 | } else if (_beta == 2.0) { 87 | old_dist = 1.0; 88 | } else if (_beta == 0.0) { 89 | double DRSq = sq(precision) + old_axes[old_jet_i].DistanceSq(inputJet_i); 90 | old_dist = 1.0/DRSq; 91 | } else { 92 | old_dist = sq(precision) + old_axes[old_jet_i].DistanceSq(inputJet_i); 93 | old_dist = std::pow(old_dist, (0.5*_beta-1.0)); 94 | } 95 | 96 | // TODO: Put some of these addition functions into light-like axes 97 | // rapidity sum 98 | new_axis_i.set_rap(new_axis_i.rap() + inputJet_i.perp() * inputRap_i * old_dist); 99 | // phi sum 100 | distPhi = inputPhi_i - old_axes[old_jet_i].phi(); 101 | if (fabs(distPhi) <= M_PI){ 102 | new_axis_i.set_phi( new_axis_i.phi() + inputJet_i.perp() * inputPhi_i * old_dist ); 103 | } else if (distPhi > M_PI) { 104 | new_axis_i.set_phi( new_axis_i.phi() + inputJet_i.perp() * (-2*M_PI + inputPhi_i) * old_dist ); 105 | } else if (distPhi < -M_PI) { 106 | new_axis_i.set_phi( new_axis_i.phi() + inputJet_i.perp() * (+2*M_PI + inputPhi_i) * old_dist ); 107 | } 108 | // weights sum 109 | new_axis_i.set_weight( new_axis_i.weight() + inputJet_i.perp() * old_dist ); 110 | // momentum magnitude sum 111 | new_jets[old_jet_i] += inputJet_i; 112 | } 113 | // normalize sums 114 | for (int k = 0; k < N; k++) { 115 | if (new_axes[k].weight() == 0) { 116 | // no particles were closest to this axis! Return to old axis instead of (0,0,0,0) 117 | new_axes[k] = old_axes[k]; 118 | } else { 119 | new_axes[k].set_rap( new_axes[k].rap() / new_axes[k].weight() ); 120 | new_axes[k].set_phi( new_axes[k].phi() / new_axes[k].weight() ); 121 | new_axes[k].set_phi( std::fmod(new_axes[k].phi() + 2*M_PI, 2*M_PI) ); 122 | new_axes[k].set_mom( std::sqrt(new_jets[k].modp2()) ); 123 | } 124 | } 125 | std::vector new_axes_vec(N); 126 | for (unsigned k = 0; k < N; ++k) new_axes_vec[k] = new_axes[k]; 127 | return new_axes_vec; 128 | } 129 | 130 | // Given N starting axes, this function updates all axes to find N better axes. 131 | // (This is just a wrapper for the templated version above.) 132 | std::vector AxesFinderFromOnePassMinimization::UpdateAxes(const std::vector & old_axes, 133 | const std::vector & inputJets) const { 134 | int N = old_axes.size(); 135 | switch (N) { 136 | case 1: return UpdateAxesFast<1>(old_axes, inputJets); 137 | case 2: return UpdateAxesFast<2>(old_axes, inputJets); 138 | case 3: return UpdateAxesFast<3>(old_axes, inputJets); 139 | case 4: return UpdateAxesFast<4>(old_axes, inputJets); 140 | case 5: return UpdateAxesFast<5>(old_axes, inputJets); 141 | case 6: return UpdateAxesFast<6>(old_axes, inputJets); 142 | case 7: return UpdateAxesFast<7>(old_axes, inputJets); 143 | case 8: return UpdateAxesFast<8>(old_axes, inputJets); 144 | case 9: return UpdateAxesFast<9>(old_axes, inputJets); 145 | case 10: return UpdateAxesFast<10>(old_axes, inputJets); 146 | case 11: return UpdateAxesFast<11>(old_axes, inputJets); 147 | case 12: return UpdateAxesFast<12>(old_axes, inputJets); 148 | case 13: return UpdateAxesFast<13>(old_axes, inputJets); 149 | case 14: return UpdateAxesFast<14>(old_axes, inputJets); 150 | case 15: return UpdateAxesFast<15>(old_axes, inputJets); 151 | case 16: return UpdateAxesFast<16>(old_axes, inputJets); 152 | case 17: return UpdateAxesFast<17>(old_axes, inputJets); 153 | case 18: return UpdateAxesFast<18>(old_axes, inputJets); 154 | case 19: return UpdateAxesFast<19>(old_axes, inputJets); 155 | case 20: return UpdateAxesFast<20>(old_axes, inputJets); 156 | default: std::cout << "N-jettiness is hard-coded to only allow up to 20 jets!" << std::endl; 157 | return std::vector(); 158 | } 159 | 160 | } 161 | 162 | // uses minimization of N-jettiness to continually update axes until convergence. 163 | // The function returns the axes found at the (local) minimum 164 | std::vector AxesFinderFromOnePassMinimization::getAxes(int n_jets, const std::vector & inputJets, const std::vector& seedAxes) const { 165 | 166 | // convert from PseudoJets to LightLikeAxes 167 | std::vector< LightLikeAxis > old_axes(n_jets, LightLikeAxis(0,0,0,0)); 168 | for (int k = 0; k < n_jets; k++) { 169 | old_axes[k].set_rap( seedAxes[k].rap() ); 170 | old_axes[k].set_phi( seedAxes[k].phi() ); 171 | } 172 | 173 | // Find new axes by iterating (only one pass here) 174 | std::vector< LightLikeAxis > new_axes(n_jets, LightLikeAxis(0,0,0,0)); 175 | double cmp = std::numeric_limits::max(); //large number 176 | int h = 0; 177 | while (cmp > _precision && h < _halt) { // Keep updating axes until near-convergence or too many update steps 178 | cmp = 0.0; 179 | h++; 180 | new_axes = UpdateAxes(old_axes, inputJets); // Update axes 181 | for (int k = 0; k < n_jets; k++) { 182 | cmp += old_axes[k].Distance(new_axes[k]); 183 | } 184 | cmp = cmp / ((double) n_jets); 185 | old_axes = new_axes; 186 | } 187 | 188 | // Convert from internal LightLikeAxes to PseudoJet 189 | std::vector outputAxes; 190 | for (int k = 0; k < n_jets; k++) { 191 | fastjet::PseudoJet temp = old_axes[k].ConvertToPseudoJet(); 192 | outputAxes.push_back(temp); 193 | } 194 | 195 | // this is used to debug the minimization routine to make sure that it works. 196 | bool do_debug = false; 197 | if (do_debug) { 198 | // get this information to make sure that minimization is working properly 199 | TauComponents seed_tau_components = _measureFunction.result(inputJets, seedAxes); 200 | double seed_tau = seed_tau_components.tau(); 201 | TauComponents tau_components = _measureFunction.result(inputJets, outputAxes); 202 | double outputTau = tau_components.tau(); 203 | assert(outputTau <= seed_tau); 204 | } 205 | 206 | return outputAxes; 207 | } 208 | 209 | PseudoJet AxesFinderFromKmeansMinimization::jiggle(const PseudoJet& axis) const { 210 | double phi_noise = ((double)rand()/(double)RAND_MAX) * _noise_range * 2.0 - _noise_range; 211 | double rap_noise = ((double)rand()/(double)RAND_MAX) * _noise_range * 2.0 - _noise_range; 212 | 213 | double new_phi = axis.phi() + phi_noise; 214 | if (new_phi >= 2.0*M_PI) new_phi -= 2.0*M_PI; 215 | if (new_phi <= -2.0*M_PI) new_phi += 2.0*M_PI; 216 | 217 | PseudoJet newAxis(0,0,0,0); 218 | newAxis.reset_PtYPhiM(axis.perp(),axis.rap() + rap_noise,new_phi); 219 | return newAxis; 220 | } 221 | 222 | 223 | // Repeatedly calls the one pass finder to try to find global minimum 224 | std::vector AxesFinderFromKmeansMinimization::getAxes(int n_jets, const std::vector & inputJets, const std::vector& seedAxes) const { 225 | 226 | // first iteration 227 | std::vector bestAxes = _onePassFinder.getAxes(n_jets, inputJets, seedAxes); 228 | 229 | double bestTau = (_measureFunction.result(inputJets,bestAxes)).tau(); 230 | 231 | for (int l = 1; l < _n_iterations; l++) { // Do minimization procedure multiple times (l = 1 to start since first iteration is done already) 232 | 233 | // Add noise to current best axes 234 | std::vector< PseudoJet > noiseAxes(n_jets, PseudoJet(0,0,0,0)); 235 | for (int k = 0; k < n_jets; k++) { 236 | noiseAxes[k] = jiggle(bestAxes[k]); 237 | } 238 | 239 | std::vector testAxes = _onePassFinder.getAxes(n_jets, inputJets, noiseAxes); 240 | double testTau = (_measureFunction.result(inputJets,testAxes)).tau(); 241 | 242 | if (testTau < bestTau) { 243 | bestTau = testTau; 244 | bestAxes = testAxes; 245 | } 246 | } 247 | 248 | return bestAxes; 249 | } 250 | 251 | // Uses minimization of the geometric distance in order to find the minimum axes. 252 | // It continually updates until it reaches convergence or it reaches the maximum number of attempts. 253 | // This is essentially the same as a stable cone finder. 254 | std::vector AxesFinderFromGeometricMinimization::getAxes(int /*n_jets*/, const std::vector & particles, const std::vector& currentAxes) const { 255 | 256 | std::vector seedAxes = currentAxes; 257 | double seedTau = _function.tau(particles, seedAxes); 258 | 259 | for (int i = 0; i < _nAttempts; i++) { 260 | 261 | std::vector newAxes(seedAxes.size(),fastjet::PseudoJet(0,0,0,0)); 262 | 263 | // find closest axis and assign to that 264 | for (unsigned int i = 0; i < particles.size(); i++) { 265 | 266 | // start from unclustered beam measure 267 | int minJ = -1; 268 | double minDist = _function.beam_distance_squared(particles[i]); 269 | 270 | // which axis am I closest to? 271 | for (unsigned int j = 0; j < seedAxes.size(); j++) { 272 | double tempDist = _function.jet_distance_squared(particles[i],seedAxes[j]); 273 | if (tempDist < minDist) { 274 | minDist = tempDist; 275 | minJ = j; 276 | } 277 | } 278 | 279 | // if not unclustered, then cluster 280 | if (minJ != -1) newAxes[minJ] += particles[i]; 281 | } 282 | 283 | // calculate tau on new axes 284 | seedAxes = newAxes; 285 | double tempTau = _function.tau(particles, newAxes); 286 | 287 | // close enough to stop? 288 | if (fabs(tempTau - seedTau) < _accuracy) break; 289 | seedTau = tempTau; 290 | } 291 | 292 | return seedAxes; 293 | } 294 | 295 | // Go from internal LightLikeAxis to PseudoJet 296 | fastjet::PseudoJet LightLikeAxis::ConvertToPseudoJet() { 297 | double px, py, pz, E; 298 | E = _mom; 299 | pz = (std::exp(2.0*_rap) - 1.0) / (std::exp(2.0*_rap) + 1.0) * E; 300 | px = std::cos(_phi) * std::sqrt( std::pow(E,2) - std::pow(pz,2) ); 301 | py = std::sin(_phi) * std::sqrt( std::pow(E,2) - std::pow(pz,2) ); 302 | return fastjet::PseudoJet(px,py,pz,E); 303 | } 304 | 305 | } //namespace contrib 306 | 307 | FASTJET_END_NAMESPACE 308 | -------------------------------------------------------------------------------- /event-gen/Nsubjettiness/AxesFinder.hh: -------------------------------------------------------------------------------- 1 | // Nsubjettiness Package 2 | // Questions/Comments? jthaler@jthaler.net 3 | // 4 | // Copyright (c) 2011-14 5 | // Jesse Thaler, Ken Van Tilburg, Christopher K. Vermilion, and TJ Wilkason 6 | // 7 | // $Id: AxesFinder.hh 678 2014-06-12 20:43:03Z jthaler $ 8 | //---------------------------------------------------------------------- 9 | // This file is part of FastJet contrib. 10 | // 11 | // It is free software; you can redistribute it and/or modify it under 12 | // the terms of the GNU General Public License as published by the 13 | // Free Software Foundation; either version 2 of the License, or (at 14 | // your option) any later version. 15 | // 16 | // It is distributed in the hope that it will be useful, but WITHOUT 17 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 18 | // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 19 | // License for more details. 20 | // 21 | // You should have received a copy of the GNU General Public License 22 | // along with this code. If not, see . 23 | //---------------------------------------------------------------------- 24 | 25 | 26 | #ifndef __FASTJET_CONTRIB_AXESFINDER_HH__ 27 | #define __FASTJET_CONTRIB_AXESFINDER_HH__ 28 | 29 | #include "WinnerTakeAllRecombiner.hh" 30 | #include "MeasureFunction.hh" 31 | 32 | #include "fastjet/PseudoJet.hh" 33 | #include "fastjet/ClusterSequence.hh" 34 | #include "fastjet/JetDefinition.hh" 35 | 36 | #include 37 | #include 38 | #include 39 | 40 | FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 41 | 42 | namespace contrib{ 43 | 44 | /////// 45 | // 46 | // Axes Finder Options 47 | // 48 | /////// 49 | 50 | //------------------------------------------------------------------------ 51 | /// \class AxesFinder 52 | // This is the base class for all axes finders. These axes are used along with the MeasureFunctions to calculate 53 | // tau_N. There are different implementations of axes finding that are defined in derived classes below. 54 | class AxesFinder { 55 | 56 | public: 57 | 58 | // This function should be overloaded, and updates the seedAxes to return new axes 59 | virtual std::vector getAxes(int n_jets, 60 | const std::vector& inputs, 61 | const std::vector& seedAxes) const = 0; 62 | // convenient shorthand for squaring 63 | static inline double sq(double x) {return x*x;} 64 | 65 | //virtual destructor 66 | virtual ~AxesFinder(){} 67 | 68 | }; 69 | 70 | 71 | //------------------------------------------------------------------------ 72 | /// \class AxesFinderFromExclusiveJetDefinition 73 | // This class finds axes by clustering the particles and then finding the exclusive jets. This can be implemented 74 | // with different jet algorithms. 75 | class AxesFinderFromExclusiveJetDefinition : public AxesFinder { 76 | 77 | public: 78 | AxesFinderFromExclusiveJetDefinition(fastjet::JetDefinition def) 79 | : _def(def) {} 80 | 81 | virtual std::vector getAxes(int n_jets, 82 | const std::vector & inputs, 83 | const std::vector& /*seedAxes*/) const { 84 | fastjet::ClusterSequence jet_clust_seq(inputs, _def); 85 | return jet_clust_seq.exclusive_jets(n_jets); 86 | } 87 | 88 | private: 89 | fastjet::JetDefinition _def; 90 | 91 | }; 92 | 93 | //------------------------------------------------------------------------ 94 | /// \class AxesFinderFromWTA_KT 95 | // This class finds axes by finding the exlusive jets after clustering according to a kT algorithm and a 96 | // winner take all recombination scheme. 97 | class AxesFinderFromWTA_KT : public AxesFinderFromExclusiveJetDefinition { 98 | 99 | public: 100 | AxesFinderFromWTA_KT() 101 | : AxesFinderFromExclusiveJetDefinition( 102 | fastjet::JetDefinition(fastjet::kt_algorithm, 103 | fastjet::JetDefinition::max_allowable_R, //maximum jet radius constant 104 | &_recomb, 105 | fastjet::Best)) {} 106 | 107 | private: 108 | const WinnerTakeAllRecombiner _recomb; 109 | 110 | }; 111 | 112 | //------------------------------------------------------------------------ 113 | /// \class AxesFinderFromWTA_CA 114 | // This class finds axes by finding the exlusive jets after clustering according to a CA algorithm and a 115 | // winner take all recombination scheme. 116 | class AxesFinderFromWTA_CA : public AxesFinderFromExclusiveJetDefinition { 117 | public: 118 | AxesFinderFromWTA_CA() 119 | : AxesFinderFromExclusiveJetDefinition( 120 | fastjet::JetDefinition(fastjet::cambridge_algorithm, 121 | fastjet::JetDefinition::max_allowable_R, //maximum jet radius constant 122 | &_recomb, 123 | fastjet::Best)) {} 124 | 125 | private: 126 | const WinnerTakeAllRecombiner _recomb; 127 | }; 128 | 129 | 130 | //------------------------------------------------------------------------ 131 | /// \class AxesFinderFromKT 132 | // This class finds axes by finding the exlusive jets after clustering according to a kT algorithm and a 133 | // E_scheme recombination. 134 | class AxesFinderFromKT : public AxesFinderFromExclusiveJetDefinition { 135 | public: 136 | AxesFinderFromKT() 137 | : AxesFinderFromExclusiveJetDefinition( 138 | fastjet::JetDefinition(fastjet::kt_algorithm, 139 | fastjet::JetDefinition::max_allowable_R, //maximum jet radius constant 140 | fastjet::E_scheme, 141 | fastjet::Best)) {} 142 | }; 143 | 144 | //------------------------------------------------------------------------ 145 | /// \class AxesFinderFromCA 146 | // This class finds axes by finding the exlusive jets after clustering according to a CA algorithm and a 147 | // E_scheme recombination. 148 | class AxesFinderFromCA : public AxesFinderFromExclusiveJetDefinition { 149 | public: 150 | AxesFinderFromCA() 151 | : AxesFinderFromExclusiveJetDefinition( 152 | fastjet::JetDefinition(fastjet::cambridge_algorithm, 153 | fastjet::JetDefinition::max_allowable_R, //maximum jet radius constant 154 | fastjet::E_scheme, 155 | fastjet::Best)) {} 156 | }; 157 | 158 | 159 | //------------------------------------------------------------------------ 160 | /// \class AxesFinderFromHardestJetDefinition 161 | // This class finds axes by clustering the particles and then finding the n hardest inclusive jets. 162 | // This can be implemented with different jet algorithms. 163 | class AxesFinderFromHardestJetDefinition : public AxesFinder { 164 | public: 165 | AxesFinderFromHardestJetDefinition(fastjet::JetDefinition def) 166 | : _def(def) {} 167 | 168 | virtual std::vector getAxes(int n_jets, 169 | const std::vector & inputs, 170 | const std::vector& /*seedAxes*/) const { 171 | fastjet::ClusterSequence jet_clust_seq(inputs, _def); 172 | std::vector myJets = sorted_by_pt(jet_clust_seq.inclusive_jets()); 173 | myJets.resize(n_jets); // only keep n hardest 174 | return myJets; 175 | } 176 | 177 | private: 178 | fastjet::JetDefinition _def; 179 | }; 180 | 181 | //------------------------------------------------------------------------ 182 | /// \class AxesFinderFromAntiKT 183 | // This class finds axes by finding the n hardest jets after clustering the particles according 184 | // to an anti kT algorithm and E_scheme. 185 | class AxesFinderFromAntiKT : public AxesFinderFromHardestJetDefinition { 186 | public: 187 | AxesFinderFromAntiKT(double R0) 188 | : AxesFinderFromHardestJetDefinition( 189 | fastjet::JetDefinition(fastjet::antikt_algorithm, 190 | R0,fastjet::E_scheme,fastjet::Best)) {} 191 | }; 192 | 193 | 194 | //------------------------------------------------------------------------ 195 | /// \class AxesFinderFromUserInput 196 | // This class allows the user to manually define the axes. 197 | class AxesFinderFromUserInput : public AxesFinder { 198 | 199 | public: 200 | AxesFinderFromUserInput() {} 201 | 202 | virtual std::vector getAxes(int n_jets, const std::vector & /*inputs*/, const std::vector& currentAxes) const { 203 | assert(currentAxes.size() == (unsigned int) n_jets); 204 | (void)(n_jets); // adding this line to fix unused-parameter warning 205 | return currentAxes; 206 | } 207 | }; 208 | 209 | //This is a helper class for the Minimum Axes Finders. It is defined later. 210 | class LightLikeAxis; 211 | 212 | 213 | //------------------------------------------------------------------------ 214 | /// \class AxesFinderFromOnePassMinimization 215 | // This class defines an AxesFinder that uses Kmeans minimization, but only on a single pass. 216 | class AxesFinderFromOnePassMinimization : public AxesFinder { 217 | 218 | public: 219 | 220 | // From a startingFinder, try to minimize the unnormalized_measure 221 | AxesFinderFromOnePassMinimization(double beta, double Rcutoff) 222 | : _precision(0.0001), //hard coded for now 223 | _halt(1000), //hard coded for now 224 | _beta(beta), 225 | _Rcutoff(Rcutoff), 226 | _measureFunction(beta, Rcutoff) 227 | {} 228 | 229 | virtual std::vector getAxes(int n_jets, 230 | const std::vector & inputJets, 231 | const std::vector& currentAxes) const; 232 | 233 | private: 234 | double _precision; // Desired precision in axes alignment 235 | int _halt; // maximum number of steps per iteration 236 | 237 | double _beta; 238 | double _Rcutoff; 239 | 240 | DefaultUnnormalizedMeasureFunction _measureFunction; 241 | 242 | template std::vector UpdateAxesFast(const std::vector & old_axes, 243 | const std::vector & inputJets) const; 244 | 245 | std::vector UpdateAxes(const std::vector & old_axes, 246 | const std::vector & inputJets) const; 247 | 248 | }; 249 | 250 | 251 | //------------------------------------------------------------------------ 252 | /// \class AxesFinderFromKmeansMinimization 253 | // This class finds finds axes by using Kmeans clustering to minimizaiton N-jettiness. Given a first set of 254 | // starting axes, it updates n times to get as close to the global minimum as possible. This class calls OnePass many times, 255 | // added noise to the axes. 256 | class AxesFinderFromKmeansMinimization : public AxesFinder{ 257 | 258 | public: 259 | AxesFinderFromKmeansMinimization(double beta, double Rcutoff, int n_iterations) 260 | : _n_iterations(n_iterations), 261 | _noise_range(1.0), // hard coded for the time being 262 | _measureFunction(beta, Rcutoff), 263 | _onePassFinder(beta, Rcutoff) 264 | {} 265 | 266 | virtual std::vector getAxes(int n_jets, const std::vector & inputJets, const std::vector& currentAxes) const; 267 | 268 | private: 269 | int _n_iterations; // Number of iterations to run (0 for no minimization, 1 for one-pass, >>1 for global minimum) 270 | double _noise_range; // noise range for random initialization 271 | 272 | DefaultUnnormalizedMeasureFunction _measureFunction; //function to test whether minimum is reached 273 | 274 | AxesFinderFromOnePassMinimization _onePassFinder; //one pass finder that is repeatedly called 275 | 276 | PseudoJet jiggle(const PseudoJet& axis) const; 277 | }; 278 | 279 | //------------------------------------------------------------------------ 280 | /// \class AxesFinderFromGeometricMinimization 281 | // This class finds axes by minimizing the Lorentz dot product distance between axes and particles. Given a first set of starting axes, 282 | // it essentially does stable cone finxing. 283 | class AxesFinderFromGeometricMinimization : public AxesFinder { 284 | 285 | public: 286 | AxesFinderFromGeometricMinimization(double beta, double Rcutoff) 287 | : _nAttempts(100), 288 | _accuracy(0.000000001), 289 | _function(beta,Rcutoff) 290 | { 291 | if (beta != 2.0) { 292 | throw Error("Geometric minimization is currently only defined for beta = 2.0."); 293 | } 294 | } 295 | 296 | virtual std::vector getAxes(int n_jets, const std::vector & particles, const std::vector& currentAxes) const; 297 | 298 | private: 299 | double _nAttempts; 300 | double _accuracy; 301 | GeometricMeasureFunction _function; 302 | 303 | 304 | }; 305 | 306 | //------------------------------------------------------------------------ 307 | /// \class LightLikeAxis 308 | // This is a helper class for the minimum Axes Finders classes above. It creates a convenient way of defining axes 309 | // in order to better facilitate calculations. 310 | class LightLikeAxis { 311 | 312 | public: 313 | LightLikeAxis() : _rap(0.0), _phi(0.0), _weight(0.0), _mom(0.0) {} 314 | LightLikeAxis(double my_rap, double my_phi, double my_weight, double my_mom) : 315 | _rap(my_rap), _phi(my_phi), _weight(my_weight), _mom(my_mom) {} 316 | double rap() const {return _rap;} 317 | double phi() const {return _phi;} 318 | double weight() const {return _weight;} 319 | double mom() const {return _mom;} 320 | void set_rap(double my_set_rap) {_rap = my_set_rap;} 321 | void set_phi(double my_set_phi) {_phi = my_set_phi;} 322 | void set_weight(double my_set_weight) {_weight = my_set_weight;} 323 | void set_mom(double my_set_mom) {_mom = my_set_mom;} 324 | void reset(double my_rap, double my_phi, double my_weight, double my_mom) {_rap=my_rap; _phi=my_phi; _weight=my_weight; _mom=my_mom;} 325 | 326 | // return PseudoJet with information 327 | fastjet::PseudoJet ConvertToPseudoJet(); 328 | 329 | double DistanceSq(const fastjet::PseudoJet& input) const { 330 | return DistanceSq(input.rap(),input.phi()); 331 | } 332 | 333 | double Distance(const fastjet::PseudoJet& input) const { 334 | return std::sqrt(DistanceSq(input)); 335 | } 336 | 337 | double DistanceSq(const LightLikeAxis& input) const { 338 | return DistanceSq(input.rap(),input.phi()); 339 | } 340 | 341 | double Distance(const LightLikeAxis& input) const { 342 | return std::sqrt(DistanceSq(input)); 343 | } 344 | 345 | private: 346 | double _rap, _phi, _weight, _mom; 347 | 348 | double DistanceSq(double rap2, double phi2) const { 349 | double rap1 = _rap; 350 | double phi1 = _phi; 351 | 352 | double distRap = rap1-rap2; 353 | double distPhi = std::fabs(phi1-phi2); 354 | if (distPhi > M_PI) {distPhi = 2.0*M_PI - distPhi;} 355 | return distRap*distRap + distPhi*distPhi; 356 | } 357 | 358 | double Distance(double rap2, double phi2) const { 359 | return std::sqrt(DistanceSq(rap2,phi2)); 360 | } 361 | 362 | 363 | }; 364 | 365 | } //namespace contrib 366 | 367 | FASTJET_END_NAMESPACE 368 | 369 | #endif // __FASTJET_CONTRIB_AXESFINDER_HH__ 370 | --------------------------------------------------------------------------------