CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PhotosInterface53XLegacy.cc
Go to the documentation of this file.
1 #include <iostream>
2 
8 #include "HepMC/SimpleVector.h"
9 #include "HepMC/GenEvent.h"
10 #include "HepMC/IO_HEPEVT.h"
11 #include "HepMC/HEPEVT_Wrapper.h"
12 
13 using namespace gen;
14 
15 namespace PhotosInterface53XLegacyVar {
16  CLHEP::HepRandomEngine* decayRandomEngine;
17 }
18 
19 extern "C"{
20 
21  void phoini_( void );
22  void photos_( int& );
23 
24  double phoran_(int *idummy)
25  {
27  }
28  extern struct {
29  // bool qedrad[NMXHEP];
30  bool qedrad[4000]; // hardcoded for now...
31  } phoqed_;
32 
33 }
34 
35 
37  : fOnlyPDG(-1)
38 {
39  fSpecialSettings.push_back("QED-brem-off:all");
41  fIsInitialized = false;
42 }
43 
45  : fOnlyPDG(-1)
46 {
47  fSpecialSettings.push_back("QED-brem-off:all");
49  fIsInitialized = false;
50 }
51 
52 
55 }
56 
58 
59  if ( fIsInitialized ) return; // do init only once
60 
61  phoini_();
62 
63  fIsInitialized = true;
64 
65  return;
66 }
67 
68 HepMC::GenEvent* PhotosInterface53XLegacy::apply( HepMC::GenEvent* evt )
69 {
70 
71 
72  if ( !fIsInitialized ) return evt; // conv.read_next_event();
73 
74  // loop over HepMC::GenEvent, find vertices
75 
76  for ( int ip=0; ip<evt->particles_size(); ip++ )
77  {
78  phoqed_.qedrad[ip]=true;
79  }
80 
81 
82  // variables for special treatment of tau leptonic decays
83  //
84  bool tau_leptonic_decay = false;
85  int iTauDescCounter = 0;
86  int nTauDesc = 0;
87 
88  for ( int iv=1; iv<=evt->vertices_size(); iv++ )
89  {
90 
91  bool legalVtx = false;
92 
93  HepMC::GenVertex* vtx = evt->barcode_to_vertex( -iv ) ;
94 
95  if ( vtx->particles_in_size() != 1 ) continue; // more complex than we need
96  if ( vtx->particles_out_size() <= 1 ) continue; // no outcoming particles
97 
98  if ( (*(vtx->particles_in_const_begin()))->pdg_id() == 111 ) continue; // pi0 decay vtx - no point to try
99 
100  // --> if ( fOnlyPDG !=-1 && (*(vtx->particles_in_const_begin()))->pdg_id() == fOnlyPDG ) continue;
101 
102  for ( HepMC::GenVertex::particle_iterator pitr=vtx->particles_begin(HepMC::children);
103  pitr != vtx->particles_end(HepMC::children); ++pitr)
104  {
105 
106  // quark or gluon out of this vertex - no good !
107  if ( abs((*pitr)->pdg_id()) >=1 && abs((*pitr)->pdg_id()) <=8 ) break;
108  if ( abs((*pitr)->pdg_id()) == 21 ) break;
109 
110  if ( (*pitr)->status() == 1 || (*pitr)->end_vertex() )
111  {
112  // OK, legal already !
113  legalVtx = true;
114  break;
115  }
116  }
117 
118  if ( !legalVtx ) continue;
119 
120  // now do all the loops again
121  //
122  // first, flush out HEPEVT & tmp barcode storage
123  //
124  HepMC::HEPEVT_Wrapper::zero_everything();
125  fBarcodes.clear();
126 
127  // add incoming particle
128  //
129  int index = 1;
130  HepMC::HEPEVT_Wrapper::set_id( index, (*(vtx->particles_in_const_begin()))->pdg_id() );
131  HepMC::FourVector vec4;
132  vec4 = (*(vtx->particles_in_const_begin()))->momentum();
133  HepMC::HEPEVT_Wrapper::set_momentum( index, vec4.x(), vec4.y(), vec4.z(), vec4.e() );
134  HepMC::HEPEVT_Wrapper::set_mass( index, (*(vtx->particles_in_const_begin()))->generated_mass() );
135  HepMC::HEPEVT_Wrapper::set_position( index, vtx->position().x(), vtx->position().y(),
136  vtx->position().z(), vtx->position().t() );
137  HepMC::HEPEVT_Wrapper::set_status( index, (*(vtx->particles_in_const_begin()))->status() );
138  HepMC::HEPEVT_Wrapper::set_parents( index, 0, 0 );
139  fBarcodes.push_back( (*(vtx->particles_in_const_begin()))->barcode() );
140 
141  // special case: avoid tau leptonic decays
142  //
143 
144  if ( fAvoidTauLeptonicDecays && !tau_leptonic_decay && abs((*(vtx->particles_in_const_begin()))->pdg_id()) == 15 )
145  {
146  for ( HepMC::GenVertex::particle_iterator pitr=vtx->particles_begin(HepMC::children);
147  pitr != vtx->particles_end(HepMC::children); ++pitr)
148  {
149  if ( abs((*pitr)->pdg_id()) == 11 || abs((*pitr)->pdg_id()) == 13 ) // leptonic decay !!!
150  // do brem off tau but NOT off decay products
151  {
152  tau_leptonic_decay = true;
153  break;
154  }
155  }
156  if ( vtx->particles_begin(HepMC::children) == vtx->particles_begin(HepMC::descendants) &&
157  vtx->particles_end(HepMC::children) == vtx->particles_end(HepMC::descendants) ) // FIXME !!!!!
158  // Maybe better vtx nested loop(s)
159  // instead of "descendants" ???
160  {
161  nTauDesc = vtx->particles_out_size();
162  }
163  else
164  {
165  for ( HepMC::GenVertex::particle_iterator pitr1=vtx->particles_begin(HepMC::children);
166  pitr1 != vtx->particles_end(HepMC::children); ++pitr1)
167  {
168  nTauDesc++;
169  }
170  }
171  // this is just the 1st tau in the branch, so it's allowed to emit
172  phoqed_.qedrad[index-1]=true;
173  iTauDescCounter = 0;
174  }
175 
176  // add outcoming particles (decay products)
177  //
178  int lastDau = 1;
179  for ( HepMC::GenVertex::particle_iterator pitr=vtx->particles_begin(HepMC::children);
180  pitr != vtx->particles_end(HepMC::children); ++pitr)
181  {
182 
183  if ( (*pitr)->status() == 1 || (*pitr)->end_vertex() )
184  {
185  index++;
186  vec4 = (*pitr)->momentum();
187  HepMC::HEPEVT_Wrapper::set_id( index, (*pitr)->pdg_id() );
188  HepMC::HEPEVT_Wrapper::set_momentum( index, vec4.x(), vec4.y(), vec4.z(), vec4.e() );
189  HepMC::HEPEVT_Wrapper::set_mass( index, (*pitr)->generated_mass() );
190  vec4 = (*pitr)->production_vertex()->position();
191  HepMC::HEPEVT_Wrapper::set_position( index, vec4.x(), vec4.y(), vec4.z(), vec4.t() );
192  HepMC::HEPEVT_Wrapper::set_status( index, (*pitr)->status() );
193  HepMC::HEPEVT_Wrapper::set_parents( index, 1, 1 );
194  fBarcodes.push_back( (*pitr)->barcode() );
195  lastDau++;
196  if ( fAvoidTauLeptonicDecays && tau_leptonic_decay )
197  {
198  phoqed_.qedrad[index-1]=false;
199  iTauDescCounter++;
200  }
201  }
202  }
203 
204  // store, further to set NHEP in HEPEVT
205  //
206  int nentries = index;
207 
208  // reset master pointer to mother
209  index = 1;
210  HepMC::HEPEVT_Wrapper::set_children ( index, 2, lastDau ); // FIXME: need to check
211  // if last daughter>=2 !!!
212 
213  // finally, set number of entries (NHEP) in HEPEVT
214  //
215  HepMC::HEPEVT_Wrapper::set_number_entries( nentries );
216 
217  // cross-check printout HEPEVT
218  // HepMC::HEPEVT_Wrapper::print_hepevt();
219 
220  // OK, 1-level vertex is formed - now, call PHOTOS
221  //
222  photos_( index ) ;
223 
224  // another cross-check printout HEPEVT - after photos
225  // HepMC::HEPEVT_Wrapper::print_hepevt();
226 
227 
228  // now check if something has been generated
229  // and make all adjustments to underlying vtx/parts
230  //
231  attachParticles( evt, vtx, nentries );
232 
233  // ugh, done with this vertex !
234 
235  // now some resets
236  //
237  if ( fAvoidTauLeptonicDecays && tau_leptonic_decay && iTauDescCounter == nTauDesc ) // treated tau leptonic decay and have come to the last descendent
238  {
239  tau_leptonic_decay = false;
240  }
241 
242  }
243 
244  // restore event number in HEPEVT (safety measure, somehow needed by Hw6)
245  HepMC::HEPEVT_Wrapper::set_event_number( evt->event_number() );
246 
247  return evt;
248 
249 }
250 
251 void PhotosInterface53XLegacy::attachParticles( HepMC::GenEvent* evt, HepMC::GenVertex* vtx, int nentries )
252 {
253 
254  if ( HepMC::HEPEVT_Wrapper::number_entries() > nentries )
255  {
256  // yes, need all corrections and adjustments -
257  // figure out how many photons and what particles in
258  // the decay branch have changes;
259  // also, follow up each one and correct accordingly;
260  // at the same time, add photon(s) to the GenVertex
261  //
262 
263  // vtx->print();
264 
265  int largestBarcode = -1;
266  int Nbcodes = fBarcodes.size();
267 
268  for ( int ip=1; ip<Nbcodes; ip++ )
269  {
270 
271  int bcode = fBarcodes[ip];
272  HepMC::GenParticle* prt = evt->barcode_to_particle( bcode );
273  if ( bcode > largestBarcode ) largestBarcode = bcode;
274  double px = HepMC::HEPEVT_Wrapper::px(ip+1);
275  double py = HepMC::HEPEVT_Wrapper::py(ip+1);
276  double pz = HepMC::HEPEVT_Wrapper::pz(ip+1);
277  double e = HepMC::HEPEVT_Wrapper::e(ip+1);
278  double m = HepMC::HEPEVT_Wrapper::m(ip+1);
279 
280  if ( prt->end_vertex() )
281  {
282 
283  HepMC::GenVertex* endVtx = prt->end_vertex();
284 
285  std::vector<int> secVtxStorage;
286  secVtxStorage.clear();
287 
288  secVtxStorage.push_back( endVtx->barcode() );
289 
290  HepMC::FourVector mom4 = prt->momentum();
291 
292  // now rescale all descendants
293  double bet1[3], bet2[3], gam1, gam2, pb;
294  double mass = mom4.m();
295  bet1[0] = -(mom4.px()/mass);
296  bet1[1] = -(mom4.py()/mass);
297  bet1[2] = -(mom4.pz()/mass);
298  bet2[0] = px/m;
299  bet2[1] = py/m;
300  bet2[2] = pz/m;
301  gam1 = mom4.e()/mass;
302  gam2 = e/m;
303 
304  unsigned int vcounter = 0;
305 
306  while ( vcounter < secVtxStorage.size() )
307  {
308 
309  HepMC::GenVertex* theVtx = evt->barcode_to_vertex( secVtxStorage[vcounter] );
310 
311  for ( HepMC::GenVertex::particle_iterator pitr=theVtx->particles_begin(HepMC::children);
312  pitr != theVtx->particles_end(HepMC::children); ++pitr)
313  {
314 
315  if ( (*pitr)->end_vertex() )
316  {
317  secVtxStorage.push_back( (*pitr)->end_vertex()->barcode() );
318  }
319 
320  if ( theVtx->particles_out_size() == 1 && (*pitr)->pdg_id() == prt->pdg_id() )
321  {
322  // carbon copy
323  (*pitr)->set_momentum( HepMC::FourVector(px,py,pz,e) );
324  continue;
325  }
326 
327  HepMC::FourVector dmom4 = (*pitr)->momentum();
328 
329  // Boost vector to parent rest frame...
330  pb = bet1[0]*dmom4.px() + bet1[1]*dmom4.py() + bet1[2]*dmom4.pz();
331  double dpx = dmom4.px() + bet1[0] * (dmom4.e() + pb/(gam1+1.) );
332  double dpy = dmom4.py() + bet1[1] * (dmom4.e() + pb/(gam1+1.) );
333  double dpz = dmom4.pz() + bet1[2] * (dmom4.e() + pb/(gam1+1.) );
334  double de = gam1*dmom4.e() + pb;
335  // ...and boost back to modified parent frame
336  pb = bet2[0]*dpx + bet2[1]*dpy + bet2[2]*dpz;
337  dpx += bet2[0] * ( de + pb/(gam2+1.) );
338  dpy += bet2[1] * ( de + pb/(gam2+1.) );
339  dpz += bet2[2] * ( de + pb/(gam2+1.) );
340  de *= gam2;
341  de += pb;
342 
343  (*pitr)->set_momentum( HepMC::FourVector(dpx,dpy,dpz,de) );
344 
345  }
346  vcounter++;
347  }
348 
349  secVtxStorage.clear();
350  }
351 
352  prt->set_momentum( HepMC::FourVector(px,py,pz,e) );
353 
354  } // ok, all affected particles update, but the photon(s) still not inserted
355 
356  int newlyGen = HepMC::HEPEVT_Wrapper::number_entries() - nentries;
357 
358  if ( largestBarcode < evt->particles_size() )
359  {
360  // need to adjust barcodes down from the affected vertex/particles
361  // such that we "free up" barcodes for newly generated photons
362  // in the middle of the event record
363  //
364  for ( int ipp=evt->particles_size(); ipp>largestBarcode; ipp-- )
365  {
366  (evt->barcode_to_particle(ipp))->suggest_barcode( ipp+newlyGen );
367  }
368  }
369 
370  // now attach new generated photons to the vertex
371  //
372  for ( int ipnw=1; ipnw<=newlyGen; ipnw++ )
373  {
374  int nbcode = largestBarcode+ipnw;
375  int pdg_id = HepMC::HEPEVT_Wrapper::id( nentries+ipnw );
376  int status = HepMC::HEPEVT_Wrapper::status( nentries+ipnw );
377  double px = HepMC::HEPEVT_Wrapper::px( nentries+ipnw );
378  double py = HepMC::HEPEVT_Wrapper::py( nentries+ipnw );
379  double pz = HepMC::HEPEVT_Wrapper::pz( nentries+ipnw );
380  double e = HepMC::HEPEVT_Wrapper::e( nentries+ipnw );
381  double m = HepMC::HEPEVT_Wrapper::m( nentries+ipnw );
382 
383  HepMC::GenParticle* NewPart = new HepMC::GenParticle( HepMC::FourVector(px,py,pz,e),
384  pdg_id, status);
385  NewPart->set_generated_mass( m );
386  NewPart->suggest_barcode( nbcode );
387  vtx->add_particle_out( NewPart ) ;
388  }
389 
390  // vtx->print();
391  // std::cout << " leaving attachParticles() " << std::endl;
392 
393  } // end of global if-statement
394 
395  return;
396 }
397 
398 
399 
void attachParticles(HepMC::GenEvent *, HepMC::GenVertex *, int)
HepMC::GenEvent * apply(HepMC::GenEvent *)
CLHEP::HepRandomEngine * decayRandomEngine
double phoran_(int *idummy)
#define abs(x)
Definition: mlp_lapack.h:159
void photos_(int &)
void SetDecayRandomEngine(CLHEP::HepRandomEngine *decayRandomEngine)
CLHEP::HepRandomEngine * decayRandomEngine
tuple mass
Definition: scaleCards.py:27
#define DEFINE_EDM_PLUGIN(factory, type, name)
bool qedrad[4000]
tuple status
Definition: ntuplemaker.py:245
void phoini_(void)
struct @250 phoqed_
std::vector< std::string > fSpecialSettings