CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
TauolaInterface.cc
Go to the documentation of this file.
1 
2 #include <iostream>
3 
5 
8 
11 
12 #include "HepMC/GenEvent.h"
13 #include "HepMC/IO_HEPEVT.h"
14 #include "HepMC/HEPEVT_Wrapper.h"
15 
17 
19 
20 using namespace gen;
21 using namespace edm;
22 using namespace std;
23 
24 extern "C" {
25 
26  void ranmar_( float *rvec, int *lenv )
27  {
28 
29  for(int i = 0; i < *lenv; i++)
30  *rvec++ = decayRandomEngine->flat();
31 
32  return;
33 
34  }
35 
36  void rmarin_( int*, int*, int* )
37  {
38 
39  return;
40 
41  }
42 
43 }
44 
45 //
46 // General Note: While there're no explicit calls or otherwise "links" to Pythia6 anywhere,
47 // we're using Pythia6Service here because we run pretauola rather than "core" tauola;
48 // pretauola is an extension on top of tauola, which is tied to Pythia6 via several routines;
49 // most heavily use one is PYR - we can't avoid it (other Pythia6-tied routines we avoid)
50 //
51 
53  : fIsInitialized(false)
54 {
56 
57  fPolarization = pset.getParameter<bool>("UseTauolaPolarization") ? 1 : 0 ;
58 
59  // set Tauola defaults
60  //
61  ki_taumod_.pjak1 = -1;
62  ki_taumod_.pjak2 = -1;
63  ki_taumod_.mdtau = -1;
64 
65  // read tau decay mode switches
66  //
67  ParameterSet cards = pset.getParameter< ParameterSet >("InputCards");
68  ki_taumod_.pjak1 = cards.getParameter< int >( "pjak1" );
69  ki_taumod_.pjak2 = cards.getParameter< int >( "pjak2" );
70  ki_taumod_.mdtau = cards.getParameter< int >( "mdtau" );
71 
72 }
73 
75 {
76  delete fPy6Service;
77 }
78 
80 {
81 
82  if ( fIsInitialized ) return; // do init only once
83 
84  if ( ki_taumod_.mdtau <= -1 ) // actually, need to throw exception !
85  return ;
86 
87  fPDGs.push_back( 15 ) ;
88  es.getData( fPDGTable ) ;
89 
90  cout << "----------------------------------------------" << endl;
91  cout << "Initializing Tauola" << endl;
92  if ( fPolarization == 0 )
93  {
94  cout << "Tauola: Polarization disabled" << endl;
95  }
96  else if ( fPolarization == 1 )
97  {
98  cout << "Tauola: Polarization enabled" << endl;
99  }
100 
101 // FIXME !!!
102 // This is a temporary hack - we're re-using master generator's seed to init RANMAR
103 // FIXME !!!
104 // This is now off because ranmar has been overriden (see code above) to use pyr_(...)
105 // - this way we're using guaranteed initialized rndm generator... BUT !!! in the long
106 // run we may want a separate random stream for tauola...
107 
108 // Service<RandomNumberGenerator> rng;
109 // int seed = rng->mySeed() ;
110 // int ntot=0, ntot2=0;
111 // rmarin_( &seed, &ntot, &ntot2 );
112 
113  int mode = -2;
114  taurep_( &mode ) ;
115  mode = -1;
116  // tauola_( &mode, &fPolarization );
117  // tauola_srs_( &mode, &fPolarization );
118  //
119  // We're using the call(...) method here because it'll make sure that Py6
120  // is initialized, and that's done only once, and will grab exatly that instance
121  //
123 
124  fIsInitialized = true;
125 
126  return;
127 }
128 
129 HepMC::GenEvent* TauolaInterface::decay( HepMC::GenEvent* evt )
130 {
131 
132  // event record convertor
133  //
134  HepMC::IO_HEPEVT conv;
135 
136  if ( !fIsInitialized ) return conv.read_next_event();
137 
138  // We are using random numbers, we are fetched through Pythia6Service
139  // (through ranmar_ below) -> so grab the instance during decay()
140 
141  Pythia6Service::InstanceWrapper pythia6InstanceGuard( fPy6Service );
142 
143  // fill up HEPEVT common block
144  //
145  // IDEALLY, this should be the way to go
146  // BUT !!! this utility fills it up in the "reshuffled" order,
147  // and later on Tauola chocks on it
148  //
149  // Needs to be sorted out, eith in HepMC, or in Tauola, or both !!!
150  //
151  // At present, this thing blindly relies on the assumption that
152  // HEPEVT is always there - which wont be the case with Py8 or Hwg++
153  //
154  //HepMC::IO_HEPEVT conv;
155  //conv.write_event( evt ) ;
156 
157  int numPartBeforeTauola = HepMC::HEPEVT_Wrapper::number_entries();
158  // HepMC::HEPEVT_Wrapper::print_hepevt();
159 
160  int mode = 0;
161  // tauola_( &mode, &fPolarization );
163 
164  int numPartAfterTauola = HepMC::HEPEVT_Wrapper::number_entries();
165  // HepMC::HEPEVT_Wrapper::print_hepevt();
166 
167  // before we do the conversion, we need to deal with decay vertexes
168  // since Tauola knows nothing about lifetimes, all decay vertexes are set to 0.
169  // nees to set them properly, knowing lifetime !
170  // here we do it on HEPEVT record, also for consistency, although it's probably
171  // even easier to deal with HepMC::GenEvent record
172 
173  // find 1st "non-doc" tau
174  //
175  bool foundTau = false;
176  for ( int ip=1; ip<=numPartAfterTauola; ip++ )
177  {
178  if ( std::abs( HepMC::HEPEVT_Wrapper::id( ip ) ) == 15
179  && HepMC::HEPEVT_Wrapper::status( ip ) != 3 )
180  {
181  foundTau = true;
182  break;
183  }
184  }
185 
186  if ( !foundTau )
187  {
188  // no tau found
189  // just give up here
190  //
191  return conv.read_next_event();
192  }
193 
194  std::vector<int> PrntIndx;
195 
196  for ( int ip=numPartAfterTauola; ip>numPartBeforeTauola; ip-- ) // Fortran indexing !
197  {
198 
199  // first of all, find out how many generations in decay chain
200  //
201  PrntIndx.clear();
202  int Prnt = HepMC::HEPEVT_Wrapper::first_parent(ip);
203  ip -= (HepMC::HEPEVT_Wrapper::number_children(Prnt)-1); // such that we don't go the same part again
204  PrntIndx.push_back( Prnt );
205  while ( abs( HepMC::HEPEVT_Wrapper::id(Prnt) ) != 15 ) // shortcut; need to loop over fPDGs...
206  {
207  int Prnt1 = HepMC::HEPEVT_Wrapper::first_parent( Prnt );
208  Prnt = Prnt1;
209  // such that the tau always appear at the start of the list
210  PrntIndx.insert( PrntIndx.begin(), Prnt );
211  ip -= HepMC::HEPEVT_Wrapper::number_children(Prnt); // such that we don't go the same part again
212  }
213  for ( size_t iprt=0; iprt<PrntIndx.size(); iprt++ )
214  {
215  int Indx = PrntIndx[iprt];
216  int PartID = HepMC::HEPEVT_Wrapper::id( Indx );
217  const HepPDT::ParticleData*
218  PData = fPDGTable->particle(HepPDT::ParticleID(abs(PartID))) ;
219  //
220  // prob = exp(-t/lifetime) ==> t = -lifetime * log(prob)
221  //
222  float prob = 0.;
223  int length=1;
224  ranmar_(&prob,&length);
225  double lifetime = PData->lifetime().value();
226  //
227  // in case of Py6, this would be copied into V(5,i)
228  // for HEPEVT, need to check...
229  //
230  double ct = -lifetime * std::log(prob);
231  //
232  double ee = HepMC::HEPEVT_Wrapper::e( Indx );
233  double px = HepMC::HEPEVT_Wrapper::px( Indx );
234  double py = HepMC::HEPEVT_Wrapper::py( Indx );
235  double pz = HepMC::HEPEVT_Wrapper::pz( Indx );
236  // double pp = std::sqrt( px*px + py*py + pz*pz );
237  double mass = HepMC::HEPEVT_Wrapper::m( Indx );
238  //
239  // this is in py6 terms:
240  // VDCY(J)=V(IP,J)+V(IP,5)*P(IP,J)/P(IP,5)
241  //
242  double VxDec = HepMC::HEPEVT_Wrapper::x( Indx );
243  VxDec += ct * (px/mass);
244  double VyDec = HepMC::HEPEVT_Wrapper::y( Indx );
245  VyDec += ct * (py/mass);
246  double VzDec = HepMC::HEPEVT_Wrapper::z( Indx );
247  VzDec += ct * (pz/mass);
248  double VtDec = HepMC::HEPEVT_Wrapper::t( Indx );
249  VtDec += ct * (ee/mass);
250  for ( int idau=HepMC::HEPEVT_Wrapper::first_child( Indx );
251  idau<=HepMC::HEPEVT_Wrapper::last_child( Indx ); idau++ )
252  {
253  HepMC::HEPEVT_Wrapper::set_position( idau, VxDec, VyDec, VzDec, VtDec );
254  }
255  }
256  }
257 
258  return conv.read_next_event();
259 
260 }
261 
263 {
264  int mode = 1;
265  // tauola_( &mode, &fPolarization ) ;
266  // tauola_srs_( &mode, &fPolarization ) ;
268  return;
269 }
270 
271 
272 /* this is the code for the new Tauola++
273 
274 #include <iostream>
275 
276 #include "GeneratorInterface/ExternalDecays/interface/TauolaInterface.h"
277 
278 #include "Tauola.h"
279 #include "TauolaHepMCEvent.h"
280 #include "Log.h"
281 
282 #include "FWCore/ServiceRegistry/interface/Service.h"
283 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
284 
285 #include "HepMC/GenEvent.h"
286 #include "HepMC/IO_HEPEVT.h"
287 #include "HepMC/HEPEVT_Wrapper.h"
288 
289 #include "SimGeneral/HepPDTRecord/interface/ParticleDataTable.h"
290 
291 using namespace gen;
292 using namespace edm;
293 using namespace std;
294 
295 CLHEP::HepRandomEngine* tauolaRandomEngine;
296 
297 extern "C" {
298 
299  void ranmar_( float *rvec, int *lenv )
300  {
301 
302  for(int i = 0; i < *lenv; i++)
303  *rvec++ = tauolaRandomEngine->flat();
304 
305  return;
306 
307  }
308 
309  void rmarin_( int*, int*, int* )
310  {
311 
312  return;
313 
314  }
315 
316 }
317 
318 TauolaInterface::TauolaInterface( const ParameterSet& pset )
319  : fIsInitialized(false)
320 {
321 
322  Tauola::setDecayingParticle(15);
323  Tauola::setRadiation(false);
324 
325  // polarization switch
326  //
327  // fPolarization = pset.getParameter<bool>("UseTauolaPolarization") ? 1 : 0 ;
328  fPolarization = pset.getParameter<bool>("UseTauolaPolarization");
329 
330  // read tau decay mode switches
331  //
332  ParameterSet cards = pset.getParameter< ParameterSet >("InputCards");
333  Tauola::setSameParticleDecayMode( cards.getParameter< int >( "pjak1" ) ) ;
334  Tauola::setOppositeParticleDecayMode( cards.getParameter< int >( "pjak2" ) ) ;
335 
336  Tauola::setTauLifetime(0.0);
337  Tauola::spin_correlation.setAll(fPolarization);
338 
339  // some more options, copied over from an example
340  // - maybe will use later...
341  //
342  //Tauola::setEtaK0sPi(0,0,0); // switches to decay eta K0_S and pi0 1/0 on/off.
343  //
344 
345 }
346 
347 TauolaInterface::~TauolaInterface()
348 {
349 }
350 
351 void TauolaInterface::init( const edm::EventSetup& es )
352 {
353 
354  if ( fIsInitialized ) return; // do init only once
355 
356  fPDGs.push_back( Tauola::getDecayingParticle() );
357 
358  es.getData( fPDGTable ) ;
359 
360  Tauola::initialise();
361  Log::LogWarning(false);
362 
363  fIsInitialized = true;
364 
365  return;
366 }
367 
368 HepMC::GenEvent* TauolaInterface::decay( HepMC::GenEvent* evt )
369 {
370 
371  if ( !fIsInitialized ) return evt;
372 
373  int NPartBefore = evt->particles_size();
374  int NVtxBefore = evt->vertices_size();
375 
376  // what do we do if Hep::GenEvent size is larger than 10K ???
377  // Tauola (& Photos, BTW) can only handle up to 10K via HEPEVT,
378  // and in case of CMS, it's only up to 4K !!!
379  //
380  // if ( NPartBefore > 10000 ) return evt;
381  //
382 
383  //construct tmp TAUOLA event
384  //
385  TauolaHepMCEvent * t_event = new TauolaHepMCEvent(evt);
386 
387  // another option: if one lets Pythia or another master gen to decay taus,
388  // we have to undecay them first
389  // t_event->undecayTaus();
390 
391  // run Tauola on the tmp event - HepMC::GenEvernt will be MODIFIED !!!
392  //
393  t_event->decayTaus();
394 
395  // delet tmp Tauola event
396  //
397  delete t_event;
398 
399  // fix barcodes of the newly added particles
400  //
401  for(HepMC::GenEvent::particle_const_iterator it = evt->particles_begin();
402  it != evt->particles_end(); ++it )
403  {
404  //HepMC::GenParticle* GenPrt = (*it);
405  if ( (*it)->barcode() > 10000 )
406  {
407  int NewBarcode = ((*it)->barcode()-10000) + NPartBefore;
408  (*it)->suggest_barcode( NewBarcode );
409  }
410  }
411 
412 
413  // do we also need to apply the lifetime and vtx position shift ???
414  // (see TauolaInterface, for example)
415  //
416  for ( int iv=NVtxBefore+1; iv<=evt->vertices_size(); iv++ )
417  {
418  HepMC::GenVertex* GenVtx = evt->barcode_to_vertex(-iv);
419  HepMC::GenParticle* GenPart = *(GenVtx->particles_in_const_begin());
420  HepMC::FourVector PMom = GenPart->momentum();
421  double mass = GenPart->generated_mass();
422  const HepPDT::ParticleData*
423  PData = fPDGTable->particle(HepPDT::ParticleID(abs(GenPart->pdg_id()))) ;
424  double lifetime = PData->lifetime().value();
425  float prob = 0.;
426  int length=1;
427  ranmar_(&prob,&length);
428  double ct = -lifetime * std::log(prob);
429  double VxDec = GenVtx->position().x();
430  VxDec += ct * (PMom.px()/mass);
431  double VyDec = GenVtx->position().y();
432  VyDec += ct * (PMom.py()/mass);
433  double VzDec = GenVtx->position().z();
434  VzDec += ct * (PMom.pz()/mass);
435  double VtDec = GenVtx->position().t();
436  VtDec += ct * (PMom.e()/mass);
437  GenVtx->set_position( HepMC::FourVector(VxDec,VyDec,VzDec,VtDec) );
438  }
439 
440  return evt;
441 
442 }
443 
444 void TauolaInterface::statistics()
445 {
446  return;
447 }
448 
449 
450 */
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
void call(void(&fn)())
HepMC::GenEvent * decay(HepMC::GenEvent *)
static HepMC::IO_HEPEVT conv
TauolaInterface(const edm::ParameterSet &)
#define abs(x)
Definition: mlp_lapack.h:159
double double double z
void getData(T &iHolder) const
Definition: EventSetup.h:67
return((rh^lh)&mask)
void tauola_srs_(int *, int *)
void taurep_(int *)
edm::ESHandle< HepPDT::ParticleDataTable > fPDGTable
void ranmar_(float *, int *)
void rmarin_(int *, int *, int *)
struct @246 ki_taumod_
HepPDT::ParticleData ParticleData
Log< T >::type log(const T &t)
Definition: Log.h:22
std::vector< int > fPDGs
int mode
Definition: AMPTWrapper.h:139
Pythia6Service * fPy6Service
tuple cout
Definition: gather_cfg.py:41
void init(const edm::EventSetup &)
Definition: DDAxes.h:10
CLHEP::HepRandomEngine * decayRandomEngine
tuple status
Definition: ntuplemaker.py:245