CMS 3D CMS Logo

SubjetFilterAlgorithm.cc
Go to the documentation of this file.
1 //
3 // SubjetFilterAlgorithm
4 // ---------------------
5 //
6 // This algorithm implements the Subjet/Filter jet reconstruction
7 // which was first proposed here: http://arXiv.org/abs/0802.2470
8 //
9 // The implementation is largely based on fastjet_boosted_higgs.cc provided
10 // with the fastjet package.
11 //
12 // see: https://twiki.cern.ch/twiki/bin/view/CMS/SWGuideSubjetFilterJetProducer
13 //
14 // David Lopes-Pegna <david.lopes-pegna@cern.ch>
15 // 25/11/2009 Philipp Schieferdecker <philipp.schieferdecker@cern.ch>
17 
18 
20 
21 #include <fastjet/ClusterSequenceArea.hh>
22 
23 #include <iostream>
24 #include <iomanip>
25 #include <sstream>
26 #include <cmath>
27 
28 
29 using namespace std;
30 
31 
32 ostream & operator<<(ostream & ostr, fastjet::PseudoJet & jet);
33 
34 
36 // construction / destruction
38 
39 //______________________________________________________________________________
42  unsigned nFatMax,
43  double rParam,
44  double rFilt,
45  double jetPtMin,
46  double massDropCut,
47  double asymmCut,
48  bool asymmCutLater,
49  bool doAreaFastjet,
50  double ghostEtaMax,
51  int activeAreaRepeats,
52  double ghostArea,
53  bool verbose)
54  : moduleLabel_(moduleLabel)
55  , jetAlgorithm_(jetAlgorithm)
56  , nFatMax_(nFatMax)
57  , rParam_(rParam)
58  , rFilt_(rFilt)
59  , jetPtMin_(jetPtMin)
60  , massDropCut_(massDropCut)
61  , asymmCut2_(asymmCut*asymmCut)
62  , asymmCutLater_(asymmCutLater)
63  , doAreaFastjet_(doAreaFastjet)
64  , ghostEtaMax_(ghostEtaMax)
65  , activeAreaRepeats_(activeAreaRepeats)
66  , ghostArea_(ghostArea)
67  , verbose_(verbose)
68  , nevents_(0)
69  , ntotal_(0)
70  , nfound_(0)
71  , fjJetDef_(nullptr)
72  , fjAreaDef_(nullptr)
73 {
74  // FASTJET JET DEFINITION
75  if (jetAlgorithm=="CambridgeAachen"||jetAlgorithm_=="ca")
76  fjJetDef_=new fastjet::JetDefinition(fastjet::cambridge_algorithm,rParam_);
77  else if (jetAlgorithm=="AntiKt"||jetAlgorithm_=="ak")
78  fjJetDef_=new fastjet::JetDefinition(fastjet::antikt_algorithm,rParam_);
79  else if (jetAlgorithm=="Kt"||jetAlgorithm_=="kt")
80  fjJetDef_=new fastjet::JetDefinition(fastjet::kt_algorithm,rParam_);
81  else
82  throw cms::Exception("InvalidJetAlgo")
83  <<"Jet Algorithm for SubjetFilterAlgorithm is invalid: "
84  <<jetAlgorithm_<<", use (ca|CambridgeAachen)|(Kt|kt)|(AntiKt|ak)"<<endl;
85 
86  // FASTJET AREA DEFINITION
87  if (doAreaFastjet_) {
88  fastjet::GhostedAreaSpec ghostSpec(ghostEtaMax_,activeAreaRepeats_,ghostArea_);
89  fjAreaDef_=new fastjet::AreaDefinition(fastjet::active_area_explicit_ghosts,
90  ghostSpec);
91  }
92 }
93 
94 
95 //______________________________________________________________________________
97 {
98  if (nullptr!=fjJetDef_) delete fjJetDef_;
99  if (nullptr!=fjAreaDef_) delete fjAreaDef_;
100 }
101 
102 
104 // implementation of member functions
106 
107 //______________________________________________________________________________
108 void SubjetFilterAlgorithm::run(const std::vector<fastjet::PseudoJet>& fjInputs,
109  std::vector<CompoundPseudoJet>& fjJets,
110  const edm::EventSetup& iSetup)
111 {
112  nevents_++;
113 
114  if (verbose_) cout<<endl<<nevents_<<". EVENT"<<endl;
115 
116  fastjet::ClusterSequence* cs = (doAreaFastjet_) ?
117  new fastjet::ClusterSequenceArea(fjInputs,*fjJetDef_,*fjAreaDef_) :
118  new fastjet::ClusterSequence (fjInputs,*fjJetDef_);
119 
120  vector<fastjet::PseudoJet> fjFatJets =
121  fastjet::sorted_by_pt(cs->inclusive_jets(jetPtMin_));
122 
123  size_t nFat =
124  (nFatMax_==0) ? fjFatJets.size() : std::min(fjFatJets.size(),(size_t)nFatMax_);
125 
126  for (size_t iFat=0;iFat<nFat;iFat++) {
127 
128  if (verbose_) cout<<endl<<iFat<<". FATJET: "<<fjFatJets[iFat]<<endl;
129 
130  fastjet::PseudoJet fjFatJet = fjFatJets[iFat];
131  fastjet::PseudoJet fjCurrentJet(fjFatJet);
132  fastjet::PseudoJet fjSubJet1,fjSubJet2;
133  bool hadSubJets;
134 
135  vector<CompoundPseudoSubJet> subJets;
136 
137 
138  // FIND SUBJETS PASSING MASSDROP [AND ASYMMETRY] CUT(S)
139  while ((hadSubJets = cs->has_parents(fjCurrentJet,fjSubJet1,fjSubJet2))) {
140 
141  if (fjSubJet1.m() < fjSubJet2.m()) swap(fjSubJet1,fjSubJet2);
142 
143  if (verbose_) cout<<"SUBJET CANDIDATES: "<<fjSubJet1<<endl
144  <<" "<<fjSubJet2<<endl;
145  if (verbose_) cout<<"md="<<fjSubJet1.m()/fjCurrentJet.m()
146  <<" y="<<fjSubJet1.kt_distance(fjSubJet2)/fjCurrentJet.m2()
147  <<endl;
148 
149  if (fjSubJet1.m()<massDropCut_*fjCurrentJet.m() &&
150  (asymmCutLater_||
151  fjSubJet1.kt_distance(fjSubJet2)>asymmCut2_*fjCurrentJet.m2())) {
152  break;
153  }
154  else {
155  fjCurrentJet = fjSubJet1;
156  }
157  }
158 
159  if (!hadSubJets) {
160  if (verbose_) cout<<"FAILED TO SELECT SUBJETS"<<endl;
161  }
162  // FOUND TWO GOOD SUBJETS PASSING MASSDROP CUT
163  else {
164  if (verbose_) cout<<"SUBJETS selected"<<endl;
165 
166  if (asymmCutLater_&&
167  fjSubJet1.kt_distance(fjSubJet2)<=asymmCut2_*fjCurrentJet.m2()) {
168  if (verbose_) cout<<"FAILED y-cut"<<endl;
169  }
170  // PASSED ASYMMETRY (Y) CUT
171  else {
172  if (verbose_) cout<<"PASSED y cut"<<endl;
173 
174  vector<fastjet::PseudoJet> fjFilterJets;
175  double Rbb = std::sqrt(fjSubJet1.squared_distance(fjSubJet2));
176  double Rfilt = std::min(0.5*Rbb,rFilt_);
177  double dcut = Rfilt*Rfilt/rParam_/rParam_;
178  fjFilterJets=fastjet::sorted_by_pt(cs->exclusive_subjets(fjCurrentJet,dcut));
179 
180  if (verbose_) {
181  cout<<"Rbb="<<Rbb<<", Rfilt="<<Rfilt<<endl;
182  cout<<"FILTER JETS: "<<flush;
183  for (size_t i=0;i<fjFilterJets.size();i++) {
184  if (i>0) cout<<" "<<flush;
185  cout<<fjFilterJets[i]<<endl;
186  }
187  }
188 
189  vector<fastjet::PseudoJet> fjSubJets;
190  fjSubJets.push_back(fjSubJet1);
191  fjSubJets.push_back(fjSubJet2);
192  size_t nFilter = fjFilterJets.size();
193  for (size_t iFilter=0;iFilter<nFilter;iFilter++)
194  fjSubJets.push_back(fjFilterJets[iFilter]);
195 
196  for (size_t iSub=0;iSub<fjSubJets.size();iSub++) {
197  vector<fastjet::PseudoJet> fjConstituents=
198  cs->constituents(fjSubJets[iSub]);
199  vector<int> constituents;
200  for (size_t iConst=0;iConst<fjConstituents.size();iConst++) {
201  int userIndex = fjConstituents[iConst].user_index();
202  if (userIndex>=0) constituents.push_back(userIndex);
203  }
204 
205  double subJetArea=(doAreaFastjet_) ?
206  ((fastjet::ClusterSequenceArea*)cs)->area(fjSubJets[iSub]) : 0.0;
207 
208  if (iSub<2||!constituents.empty())
209  subJets.push_back(CompoundPseudoSubJet(fjSubJets[iSub],
210  subJetArea,
211  constituents));
212  }
213 
214  } // PASSED Y CUT
215 
216  } // PASSED MASSDROP CUT
217 
218  if (verbose_) cout<<"write fatjet with "<<subJets.size()<<" sub+filter jets"
219  <<endl;
220 
221  double fatJetArea = (doAreaFastjet_) ?
222  ((fastjet::ClusterSequenceArea*)cs)->area(fjFatJet) : 0.0;
223 
224  fjJets.push_back(CompoundPseudoJet(fjFatJet,fatJetArea,subJets));
225 
226  ntotal_++;
227  if (subJets.size()>3) nfound_++;
228 
229  } // LOOP OVER FATJETS
230 
231  if (verbose_) cout<<endl<<fjJets.size()<<" FATJETS written\n"<<endl;
232 
233  delete cs;
234 
235  return;
236 }
237 
238 
239 //______________________________________________________________________________
241 {
242  double eff = (ntotal_>0) ? nfound_/(double)ntotal_ : 0;
243  std::stringstream ss;
244  ss<<"************************************************************\n"
245  <<"* "<<moduleLabel_<<" (SubjetFilterAlgorithm) SUMMARY:\n"
246  <<"************************************************************\n"
247  <<"nevents = "<<nevents_<<endl
248  <<"ntotal = "<<ntotal_<<endl
249  <<"nfound = "<<nfound_<<endl
250  <<"eff = "<<eff<<endl
251  <<"************************************************************\n";
252  return ss.str();
253 }
254 
255 
256 
258 ostream & operator<<(ostream & ostr, fastjet::PseudoJet & jet) {
259  ostr << "pt=" <<setw(10)<<jet.perp()
260  << " eta="<<setw(6) <<jet.eta()
261  << " m=" <<setw(10)<<jet.m();
262  return ostr;
263 }
doAreaFastjet
Definition: jets_cff.py:11
unique_ptr< ClusterSequence > cs
#define nullptr
fastjet::AreaDefinition * fjAreaDef_
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:116
void run(const std::vector< fastjet::PseudoJet > &inputs, std::vector< CompoundPseudoJet > &fatJets, const edm::EventSetup &iSetup)
T sqrt(T t)
Definition: SSEVec.h:18
CompoundPseudoJet holds an association of fastjet::PseudoJets that represent a "hard" top jet with su...
fastjet::JetDefinition * fjJetDef_
SubjetFilterAlgorithm(const std::string &moduleLabel, const std::string &jetAlgorithm, unsigned nFatMax, double rParam, double rFilt, double jetPtMin, double massDropCut, double asymmCut, bool asymmCutLater, bool doAreaFastjet, double ghostEtaMax, int activeAreaRepeats, double ghostArea, bool verbose)
ostream & operator<<(ostream &ostr, fastjet::PseudoJet &jet)
does the actual work for printing out a jet
T min(T a, T b)
Definition: MathUtil.h:58
std::ostream & operator<<(std::ostream &out, const std::tuple< Types... > &value)
Definition: Utilities.h:38
std::string summary() const