CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
JetMatchingMGFastJet.cc
Go to the documentation of this file.
1 
4 #include <iomanip>
10 
11 namespace gen
12 {
13 
14 extern "C" {
15 
16  extern struct UPPRIV {
17  int lnhin, lnhout;
18  int mscal, ievnt;
19  int ickkw, iscale;
20  } uppriv_;
21 
22  extern struct MEMAIN {
25  int mektsc,nexcres, excres[30];
26  int nqmatch,excproc,iexcproc[1000],iexcval[1000];
27  bool nosingrad,jetprocs;
28  } memain_;
29 
30 }
31 
33 {
34 
35  if ( fIsInit ) return true;
36 
37  //
39  // doMerge = true;
40  qCut = memain_.qcut; //
42  clFact = 1.; // Default value
43  // NOTE: ME2pythia seems to default to 1.5 - need to check !!!
44  // in general, needs to read key ALPSFACT from LHE file - fix CMSSW code !!!
47 
49 
50  coneRadius = 1.0;
51  jetAlgoPower = 1; // this is the kT algorithm !!!
52 
53  // Matching procedure
54  //
55  qCutSq = pow(qCut,2);
56  // this should be something like memaev_.iexc
57  fExcLocal = true;
58 
59 
60  // If not merging, then done (?????)
61  //
62  // if (!doMerge) return true;
63 
64  // Initialise chosen jet algorithm.
65  //
66  fJetFinder = new fastjet::JetDefinition( fastjet::kt_algorithm, coneRadius );
67  fClusJets.clear();
68  fPtSortedJets.clear();
69 
70  fIsInit = true;
71 
72  return true;
73 
74 }
75 
77 {
78 
79  if (!runInitialized)
80  throw cms::Exception("Generator|PartonShowerVeto")
81  << "Run not initialized in JetMatchingMadgraph"
82  << std::endl;
83 
84  for (int i = 0; i < 3; i++)
85  {
86  typeIdx[i].clear();
87  }
88 
89  // Sort original process final state into light/heavy jets and 'other'.
90  // Criteria:
91  // 1 <= ID <= 5 and massless, or ID == 21 --> light jet (typeIdx[0])
92  // 4 <= ID <= 6 and massive --> heavy jet (typeIdx[1])
93  // All else --> other (typeIdx[2])
94  //
95  const lhef::HEPEUP& hepeup = *lhee->getHEPEUP();
96  int idx = 2;
97  for ( int i=0; i < hepeup.NUP; i++ )
98  {
99  if ( hepeup.ISTUP[i] < 0 ) continue;
100  if ( hepeup.MOTHUP[i].first != 1 && hepeup.MOTHUP[i].second !=2 ) continue; // this way we skip entries that come
101  // from resonance decays;
102  // we only take those that descent
103  // directly from "incoming partons"
104  idx = 2;
105  if ( hepeup.IDUP[i] == ID_GLUON || (fabs(hepeup.IDUP[i]) <= nQmatch) ) // light jet
106  // light jet
107  idx = 0;
108  else if ( fabs(hepeup.IDUP[i]) > nQmatch && fabs(hepeup.IDUP[i]) <= ID_TOP) // heavy jet
109  idx = 1;
110  // Store
111  typeIdx[idx].push_back(i);
112  }
113 
114  // NOTE: In principle, I should use exclusive, inclusive, or soup !!!
115  // should be like this:
116  if ( soup )
117  {
118  int NPartons = typeIdx[0].size();
119  fExcLocal = ( NPartons < nJetMax );
120  }
121  else
123 
124  return;
125 
126 }
127 
129  const std::vector<fastjet::PseudoJet>* jetInput )
130 {
131 
132  // Number of hard partons
133  //
134  int NPartons = typeIdx[0].size();
135 
136  fClusJets.clear();
137  fPtSortedJets.clear();
138 
139  int ClusSeqNJets = 0;
140 
141  fastjet::ClusterSequence ClusSequence( *jetInput, *fJetFinder );
142 
143  if ( fExcLocal )
144  {
145  fClusJets = ClusSequence.exclusive_jets( qCutSq );
146  }
147  else
148  {
149  fClusJets = ClusSequence.inclusive_jets( qCut );
150  }
151 
152  ClusSeqNJets = fClusJets.size();
153 
154 
155  if ( ClusSeqNJets < NPartons ) return LESS_JETS;
156 
157  double localQcutSq = qCutSq;
158 
159  if ( fExcLocal ) // exclusive
160  {
161  if( ClusSeqNJets > NPartons ) return MORE_JETS;
162  }
163  else // inclusive
164  {
165  fPtSortedJets = fastjet::sorted_by_pt( *jetInput );
166  localQcutSq = std::max( qCutSq, fPtSortedJets[0].pt2() );
167  fClusJets = ClusSequence.exclusive_jets( NPartons ); // override
168  ClusSeqNJets = NPartons;
169  }
170 
171  if( clFact != 0 ) localQcutSq *= pow(clFact,2);
172 
173  std::vector<fastjet::PseudoJet> MatchingInput;
174 
175  std::vector<bool> jetAssigned;
176  jetAssigned.assign( fClusJets.size(), false );
177 
178  int counter = 0;
179 
180  const lhef::HEPEUP& hepeup = *partonLevel->getHEPEUP();
181 
182  while ( counter < NPartons )
183  {
184 
185  MatchingInput.clear();
186 
187  for ( int i=0; i<ClusSeqNJets; i++ )
188  {
189  if ( jetAssigned[i] ) continue;
190  if ( i == NPartons ) break;
191  //
192  // this looks "awkward" but this way we do NOT pass in cluster_hist_index
193  // which would actually indicate position in "history" of the "master" ClusSeq
194  //
195  fastjet::PseudoJet exjet = fClusJets[i];
196  MatchingInput.push_back( fastjet::PseudoJet( exjet.px(), exjet.py(), exjet.pz(), exjet.e() ) );
197  MatchingInput.back().set_user_index(i);
198  }
199 
200  int idx = typeIdx[0][counter];
201  MatchingInput.push_back( fastjet::PseudoJet( hepeup.PUP[idx][0],
202  hepeup.PUP[idx][1],
203  hepeup.PUP[idx][2],
204  hepeup.PUP[idx][3]) );
205 
206  //
207  // in principle, one can use ClusterSequence::n_particles()
208  //
209  int NBefore = MatchingInput.size();
210 
211  // Create new clustering object - which includes the 1st clustering run !!!
212  // NOTE-1: it better be a new object for each try, or history will be "too crowded".
213  // NOTE-2: when created, the it ALWAYS makes at least 1 clustering step, so in most
214  // cases at least 1 new jet object will be added; although in some cases
215  // no jet is added, if the system doesn't cluster to anything (for example,
216  // input jet(s) and parton(s) are going opposite directions)
217  //
218  fastjet::ClusterSequence ClusSeq( MatchingInput, *fJetFinder );
219 
220  const std::vector<fastjet::PseudoJet>& output = ClusSeq.jets();
221  int NClusJets = output.size() - NBefore;
222 
223  //
224  // JVY - I think this is the right idea:
225  // at least 1 (one) new jet needs to be added
226  // however, need to double check details and refine, especially for inclusive mode
227  //
228  //
229  if ( NClusJets < 1 )
230  {
231  return UNMATCHED_PARTON;
232  }
233  //
234  // very unlikely case but let's do it just to be safe
235  //
236  if ( NClusJets >= NBefore )
237  {
238  return MORE_JETS;
239  }
240 
241  // Now browse history and see how close the clustering distance
242  //
243  // NOTE: Remember, there maybe more than one new jet in the list (for example,
244  // for process=2,3,...);
245  // in this case we take the ** first ** one that satisfies the distance/cut,
246  // which is ** typically ** also the best one
247  //
248  bool matched = false;
249  const std::vector<fastjet::ClusterSequence::history_element>& history = ClusSeq.history();
250 
251  // for ( unsigned int i=nBefore; i<history.size(); i++ )
252  for ( unsigned int i=NBefore; i<output.size(); i++ )
253  {
254 
255  int hidx = output[i].cluster_sequence_history_index();
256  double dNext = history[hidx].dij;
257  if ( dNext < localQcutSq )
258  {
259  //
260  // the way we form input, parent1 is always jet, and parent2 can be any,
261  // but if it's a good match/cluster, it should point at the parton
262  //
263  int parent1 = history[hidx].parent1;
264  int parent2 = history[hidx].parent2;
265  if ( parent1 < 0 || parent2 < 0 ) break; // bad cluster, no match
266  //
267  // pull up jet's "global" index
268  //
269  int pidx = MatchingInput[parent1].user_index();
270  jetAssigned[pidx] = true;
271  matched = true;
272  break;
273  }
274  }
275  if ( !matched )
276  {
277  return UNMATCHED_PARTON;
278  }
279 
280  counter++;
281  }
282 
283  // Now save some info for DJR analysis (if requested).
284  // This mimics what is done in ME2pythia.f
285  // Basically, NJets and matching scale for these 4 cases:
286  // 1->0, 2->1, 3->2, and 4->3
287  //
288  if ( fDJROutFlag > 0 )
289  {
290  std::vector<double> MergingScale;
291  MergingScale.clear();
292  for ( int nj=0; nj<4; nj++ )
293  {
294  double dmscale2 = ClusSequence.exclusive_dmerge( nj );
295  double dmscale = sqrt( dmscale2 );
296  MergingScale.push_back( dmscale );
297  }
298  fDJROutput.open( "events.tree", std::ios_base::app );
299  double dNJets = (double)NPartons;
300  fDJROutput << " " << dNJets << " " << MergingScale[0] << " "
301  << MergingScale[1] << " "
302  << MergingScale[2] << " "
303  << MergingScale[3] << std::endl;
304  fDJROutput.close();
305  }
306 
307  return NONE;
308 
309 }
310 
311 } // end namespace
struct gen::MEMAIN memain_
int i
Definition: DBlmapReader.cc:9
fastjet::JetDefinition * fJetFinder
const HEPEUP * getHEPEUP() const
Definition: LHEEvent.h:42
std::vector< std::pair< int, int > > MOTHUP
Definition: LesHouches.h:236
const T & max(const T &a, const T &b)
T sqrt(T t)
Definition: SSEVec.h:48
std::vector< FiveVector > PUP
Definition: LesHouches.h:248
std::vector< int > ISTUP
Definition: LesHouches.h:230
std::vector< int > IDUP
Definition: LesHouches.h:225
std::vector< fastjet::PseudoJet > fClusJets
std::vector< fastjet::PseudoJet > fPtSortedJets
std::vector< int > typeIdx[3]
void beforeHadronisation(const lhef::LHEEvent *)
tuple idx
DEBUGGING if hasattr(process,&quot;trackMonIterativeTracking2012&quot;): print &quot;trackMonIterativeTracking2012 D...
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
struct gen::UPPRIV uppriv_
int match(const lhef::LHEEvent *partonLevel, const std::vector< fastjet::PseudoJet > *jetInput)