tom is hosted by Hepforge, IPPP Durham
Template Overlap Method  0.3.0
A Template Matching Tool for Jet Substructure
matching.hh
1 #ifndef Cone_H
2 #define Cone_H
3 
4 #include <string>
5 #include <vector>
6 #include <iostream>
7 #include <fstream>
8 #include <sstream>
9 #include <utility>
10 
11 
12 
13 #include "fastjet/PseudoJet.hh"
14 #include "fastjet/ClusterSequence.hh"
15 
16 using namespace std;
17 
18 namespace TemplateOverlap{
19 
20 enum {CONE, GAUSSIAN};
21 enum {HADRONIC, SEMILEPTONIC};
22 
24 class Settings {
25 private:
26  double _subConeRadius; // subCone radius
27  double _coneRadius; // characteristic jet radius
28  double _sigma; // Gaussian energy resolution relative to parton pT
29  double _coneRadius2; // subjet radius
30  bool _variableCone; // Dynamically change cone radius based on parton pT
31  double _minPtParton; //For infrared safety, partons are not too soft
32 
33 public:
34  Settings(const double subConeRadiusIn=0.20,
35  const double sigmaIn=0.33, const double coneRadiusIn = 1.0, const double coneRadius2In=0.40, const bool variableConeIn=false,
36  const double minPtPartonIn = 10.) :
37  _subConeRadius(subConeRadiusIn), _coneRadius(coneRadiusIn), _sigma(sigmaIn),
38  _coneRadius2(coneRadius2In),_variableCone(variableConeIn), _minPtParton(minPtPartonIn) {}
39  double r() const {return _subConeRadius;}
40  double R0() const {return _coneRadius;}
41  double R1() const {return _coneRadius2;}
42  double sigma() const {return _sigma;}
43  bool variableCone() const {return _variableCone;}
44  double minPtParton() const {return _minPtParton;}
45 };
46 
47 
48 
51 
52 public:
53 
54  // Constructors.
55  SingleParticle( double pTIn = 0., double yIn = 0., double phiIn = 0.)
56  : pT(pTIn), y(yIn), phi(phiIn), mult(1), isUsed(false), radius(0.), sigma(0.) { }
57  SingleParticle(const SingleParticle& ssj) : pT(ssj.pT),
58  y(ssj.y), phi(ssj.phi), mult(ssj.mult), isUsed(ssj.isUsed), radius(ssj.radius), sigma(ssj.sigma) { }
59  SingleParticle& operator=(const SingleParticle& ssj) { if (this != &ssj)
60  { pT = ssj.pT; y = ssj.y; phi = ssj.phi;
61  mult = ssj.mult; isUsed = ssj.isUsed; radius =ssj.radius; sigma=ssj.sigma;} return *this; }
62 
63  // Properties of particle.
64  double pT, y, phi;
65  int mult;
66  bool isUsed;
67  double radius; //For templates
68  double sigma;
69 
70  double deltaR2(const SingleParticle & other) const {
71  double dPhi = abs(phi - other.phi );
72  if (dPhi > M_PI) dPhi = 2. * M_PI - dPhi;
73  double dEta = y - other.y;
74  return (dEta * dEta + dPhi * dPhi );
75  }
76 
77 };
78 
79 typedef std::vector<SingleParticle> jet_t;
80 typedef std::pair<double, std::vector<fastjet::PseudoJet> > templ_t;
81 bool checkTemplate (const jet_t & probe_template);
82 void matchTemplate( jet_t & jet, const vector<jet_t> & templates, vector<double> & result, int match_method=CONE, int normalization=HADRONIC);
83 void maximize(const vector<double> & result, double & maxVal, int & maxLoc );
84 
85 std::vector<fastjet::PseudoJet> ConvertToPseudoJet(const jet_t& particles) ;
86 std::vector<fastjet::PseudoJet> ConvertToPseudoJet(const jet_t& particles, const fastjet::PseudoJet & tilt_axis) ;
87 
88 jet_t ConvertToJet(const fastjet::PseudoJet & jet) ;
89 double DeltaPhi(double phi1, double phi2);
90 
91 
92 
95 private:
96 
97  ifstream _mystream;
98  vector<jet_t> _templates;
99  double _subConeRadius;
100  double _sigma;
101  double _minPtParton;
102  double _maxVal;
103  int _maxLoc;
104 
105  int templateRead(ifstream& is);
106  bool checkTemplate (const jet_t & probe_template);
107 
108 public:
109  MatchingMethod(const string & templateFile, Settings mySettings) :
110  _mystream(templateFile.c_str()), _subConeRadius(mySettings.r()), _sigma(mySettings.sigma()), _minPtParton(mySettings.minPtParton()) {templateRead(_mystream);}
111  templ_t getOv (const fastjet::PseudoJet & jet);
112 };
113 
115 templ_t MatchingMethod::getOv(const fastjet::PseudoJet& jet)
116 {
118  int match_method = CONE;
119  int normalize = HADRONIC;
120 
122  jet_t jet_mat;
123  jet_mat = ConvertToJet(jet);
124 
126  vector<double> result;
127 
129  matchTemplate(jet_mat, _templates, result, match_method, normalize);
130 
132  maximize(result, _maxVal, _maxLoc );
133 
135  std::vector<fastjet::PseudoJet> peak_template = ConvertToPseudoJet(_templates[_maxLoc], jet);
136  return std::make_pair<double, std::vector<fastjet::PseudoJet> >(_maxVal, peak_template);
137 }
138 
140 int MatchingMethod::templateRead(ifstream& is) {
141 
142  string line, tag;
143 
144  //Event particlesSave;
145 
146 jet_t particlesSave;
147 _templates.clear();
148 
149  while (getline(is,line)){
150  istringstream getpro(line);
151  int nupSave;
152  getpro >> nupSave;
153  if (!getpro) return false;
154 
155  // Reset particlesSave vector.
156  particlesSave.clear();
157 
158  // Read in particle info one by one, and store it.
159  double pup1, pup2, pup3, pup4;
160 
161  if (!getline(is, line)) return false;
162  istringstream getall(line);
163  getall >> pup1 >> pup2 >> pup3 >> pup4;
164 
165  for (int ip = 0; ip < nupSave; ++ip) {
166  if (!getline(is, line)) return false;
167  istringstream getall(line);
168  getall >> pup1 >> pup2 >> pup3 >> pup4;
169  if (!getall) return false;
170 
171  fastjet::PseudoJet pTemp(pup1,pup2,pup3,pup4);
172  SingleParticle pAux= SingleParticle( pTemp.perp(), pTemp.rapidity(), pTemp.phi());
173  pAux.radius = _subConeRadius;
174  pAux.sigma = _sigma;
175  particlesSave.push_back(pAux);
176  }
177 
178  if (checkTemplate (particlesSave) ) _templates.push_back(particlesSave);
179 
180 
181 
182  // Reading worked.
183 
184 }
185  return (_templates.size());
186 
187 }
188 
190 bool MatchingMethod::checkTemplate(const jet_t& probe_template)
191 {
192  bool isOK = true;
193  for (jet_t::const_iterator i = probe_template.begin() ; i != probe_template.end() && isOK ; ++i) {
194  if ((*i).pT < _minPtParton) { isOK = false; break;}
195  for (jet_t::const_iterator j = i + 1 ; j != probe_template.end(); ++j){
196  if((*i).deltaR2((*j)) < ((*i).radius+(*j).radius) * ((*i).radius+(*j).radius))
197  { isOK = false; break ;}
198  }
199  }
200  return (isOK);
201 }
202 
203 
204 
206 void reset(jet_t & jet){
207  for (jet_t::iterator j = jet.begin(); j != jet.end(); ++j)
208  if ((*j).isUsed) (*j).isUsed = false;
209 
210 }
211 
212 
214 double overlapDistance (jet_t & jet1, jet_t & jet2, double R0)
215 {
216  double sum = 0.;
217  for(jet_t::const_iterator k = jet1.begin(); k != jet1.end(); ++k) {
218  double eTjetNow = 0.;
219  // Sum up unused particles within required distance of parton.
220  for (jet_t::iterator j = jet2.begin(); j !=jet2.end(); ++j) {
221  if ((*j).isUsed) continue;
222  if ((*j).deltaR2(*k) > R0 * R0 ) continue;
223  eTjetNow += (*j).pT;
224  (*j).isUsed = true;
225  }
226  double eTcenterNow = (*k).pT;
227  //change sigma to E/3
228  sum += 4.5 * (eTjetNow - eTcenterNow) * (eTjetNow - eTcenterNow)/(eTcenterNow * eTcenterNow);
229 
230 }
231 
232 reset(jet2);
233 return (exp(-sum));
234  }
235 
236 
237 void matchTemplate(jet_t & jet, const vector<jet_t> & templates, vector<double> & result, int match_method, int normalization)
238 {
239  for (int i = 0; i < int (templates.size()); ++i){
240  double sum = 0.;
241 
242  for(jet_t::const_iterator t_particle = templates[i].begin(); t_particle !=
243  templates[i].end(); ++t_particle)
244  {
245  double eTjetNow = 0.;
246  // Sum up unused particles within required distance of parton.
247  for ( jet_t::iterator particle = jet.begin(); particle != jet.end(); ++particle)
248  {
249  if ((*particle).isUsed) continue;
250  if ((*particle).deltaR2(*t_particle) > (*t_particle).radius * (*t_particle).radius ) continue;
251  eTjetNow += (*particle).pT;
252  (*particle).isUsed = true;
253  }
254  double eTcenterNow = (*t_particle).pT;
255 
256  // change sigma to E/3
257  sum += 0.5*1/ ( ((*t_particle).sigma)*((*t_particle).sigma) ) * (eTjetNow - eTcenterNow) * (eTjetNow - eTcenterNow)/(eTcenterNow * eTcenterNow);
258  // if one overlap is too low, we skip the rest.
259  if (sum > 4.6 ) break;
260 
261  }
262 // Clean flags.
263  reset(jet);
264 
265  result.push_back(exp(-sum));
266  }
267 
268 
269 }
270 
271 void maximize(const vector<double> & result, double & maxVal, int & maxLoc )
272 {
273  maxVal = 0;
274  maxLoc = 0;
275 
276  for (int i = 0; i < int (result.size()); ++i){
277  double thisVal = result[i];
278  if (thisVal > maxVal){ maxLoc = i; maxVal = thisVal;}
279  }
280 }
281 
282 
283 //--------------------------------------------------------------------------
284 
285 
286 std::vector<fastjet::PseudoJet> ConvertToPseudoJet(const jet_t& particles)
287 {
288  std::vector<fastjet::PseudoJet> Jets;
289  for (jet_t::const_iterator part = particles.begin(); part != particles.end(); part++) {
290  fastjet::PseudoJet temp = fastjet::PtYPhiM((*part).pT, (*part).y, (*part).phi);
291  Jets.push_back(temp);
292  }
293  return Jets;
294 }
295 
296 std::vector<fastjet::PseudoJet> ConvertToPseudoJet(const jet_t& particles, const fastjet::PseudoJet & tilt_axis)
297 {
298  std::vector<fastjet::PseudoJet> Jets;
299  double etaJet = tilt_axis.rapidity();
300  double phiJet = tilt_axis.phi();
301  for (jet_t::const_iterator part = particles.begin(); part != particles.end(); part++) {
302  fastjet::PseudoJet temp = fastjet::PtYPhiM((*part).pT, (*part).y + etaJet, (*part).phi + phiJet);
303  Jets.push_back(temp);
304  }
305  return Jets;
306 }
307 
308 jet_t ConvertToJet(const fastjet::PseudoJet& jet)
309 {
310  std::vector<fastjet::PseudoJet> particles = jet.constituents();
311  jet_t jet_mat;
312 
313  double jetRapidity = jet.rapidity() ;
314  double jetPhi = jet.phi() ;
315 
316  for (unsigned int i = 0; i < particles.size(); ++i) {
317  double etaNow = particles[i].eta();
318  double phiNow = particles[i].phi();
319  double pTnow = particles[i].perp();
320 
321  jet_mat.push_back( SingleParticle( pTnow, etaNow - jetRapidity, phiNow - jetPhi) );
322  }
323  return jet_mat;
324 }
325 
326 //--------------------------------------------------------------------------
327 double DeltaPhi(double phi1, double phi2)
328 {
329  double dphi = phi1-phi2;
330 
331  if (dphi > M_PI) dphi -= 2* M_PI;
332  if (dphi < -M_PI) dphi += 2* M_PI;
333  // if (abs (temp) > M_PI) temp = 2 * M_PI - abs(temp);
334 return dphi;
335 }
336 
337 
338 
339 } //end namespace
340 
341 
342 #endif // end Event_H