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 /* for old tauola27
2 #include <iostream>
3 
4 #include "GeneratorInterface/Pythia6Interface/interface/Pythia6Service.h"
5 
6 #include "GeneratorInterface/ExternalDecays/interface/TauolaInterface.h"
7 #include "GeneratorInterface/ExternalDecays/interface/TauolaWrapper.h"
8 
9 #include "FWCore/ServiceRegistry/interface/Service.h"
10 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
11 
12 #include "HepMC/GenEvent.h"
13 #include "HepMC/IO_HEPEVT.h"
14 #include "HepMC/HEPEVT_Wrapper.h"
15 
16 #include "SimGeneral/HepPDTRecord/interface/ParticleDataTable.h"
17 
18 #include "GeneratorInterface/ExternalDecays/interface/DecayRandomEngine.h"
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 
52 TauolaInterface::TauolaInterface( const ParameterSet& pset )
53  : fIsInitialized(false)
54 {
55  fPy6Service = new Pythia6Service;
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 
74 TauolaInterface::~TauolaInterface()
75 {
76  delete fPy6Service;
77 }
78 
79 void TauolaInterface::init( const edm::EventSetup& es )
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  //
122  fPy6Service->call( tauola_srs_, &mode, &fPolarization );
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 );
162  fPy6Service->call( tauola_srs_, &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 
262 void TauolaInterface::statistics()
263 {
264  int mode = 1;
265  // tauola_( &mode, &fPolarization ) ;
266  // tauola_srs_( &mode, &fPolarization ) ;
267  fPy6Service->call( tauola_srs_, &mode, &fPolarization );
268  return;
269 }
270 
271 */
272 
273 /* this is the code for the new Tauola++ */
274 
275 #include <iostream>
276 
278 
279 #include "Tauola/Tauola.h"
280 #include "Tauola/TauolaHepMCEvent.h"
281 #include "Tauola/Log.h"
282 
284 
285 #include "CLHEP/Random/RandomEngine.h"
286 
287 #include "HepMC/GenEvent.h"
288 #include "HepMC/IO_HEPEVT.h"
289 #include "HepMC/HEPEVT_Wrapper.h"
290 
292 
293 // #include "GeneratorInterface/ExternalDecays/interface/DecayRandomEngine.h"
294 
295 extern "C" {
296 
297  void gen::ranmar_( float *rvec, int *lenv )
298  {
299  TauolaInterface* instance = TauolaInterface::getInstance();
300  for(int i = 0; i < *lenv; i++)
301  // *rvec++ = decayRandomEngine->flat();
302  *rvec++ = instance->flat();
303  return;
304  }
305 
306  void gen::rmarin_( int*, int*, int* )
307  {
308  return;
309  }
310 
311 }
312 
313 using namespace gen;
314 using namespace edm;
315 using namespace std;
316 
318 
319 
321  : fRandomEngine(nullptr), fPolarization(false), fPSet(0),
322  fIsInitialized(false), fMDTAU(-1), fSelectDecayByEvent(false)
323 {
324 }
325 
326 
327 //TauolaInterface::TauolaInterface( const ParameterSet& pset )
328 // : fIsInitialized(false)
329 //{
330 //
331 // Tauola::setDecayingParticle(15);
332 // // --> ??? Tauola::setRadiation(false);
333 //
334 // // polarization switch
335 // //
336 // // fPolarization = pset.getParameter<bool>("UseTauolaPolarization") ? 1 : 0 ;
337 // fPolarization = pset.getParameter<bool>("UseTauolaPolarization");
338 //
339 // // read tau decay mode switches
340 // //
341 // ParameterSet cards = pset.getParameter< ParameterSet >("InputCards");
342 // Tauola::setSameParticleDecayMode( cards.getParameter< int >( "pjak1" ) ) ;
343 // Tauola::setOppositeParticleDecayMode( cards.getParameter< int >( "pjak2" ) ) ;
344 //
345 // Tauola::setTauLifetime(0.0);
346 // Tauola::spin_correlation.setAll(fPolarization);
347 //
348 // // some more options, copied over from an example
349 // // - maybe will use later...
350 // //
351 // //Tauola::setEtaK0sPi(0,0,0); // switches to decay eta K0_S and pi0 1/0 on/off.
352 // //
353 //
354 //}
355 
356 
358 {
359 
360  if ( fInstance == 0 ) fInstance = new TauolaInterface() ;
361  return fInstance;
362 
363 }
364 
365 
367 {
368 
369  if ( fPSet != 0 ) delete fPSet;
370  if ( fInstance == this ) fInstance = 0;
371 
372 }
373 
375 {
376 
377  if ( fPSet != 0 )
378  {
379  throw cms::Exception("TauolaInterfaceError")
380  << "Attempt to override Tauola an existing ParameterSet\n"
381  << std::endl;
382  }
383 
384  fPSet = new ParameterSet(pset);
385 
386  return;
387 
388 }
389 
391 {
392 
393  if ( fIsInitialized ) return; // do init only once
394 
395  if ( fPSet == 0 )
396  {
397 
398  throw cms::Exception("TauolaInterfaceError")
399  << "Attempt to initialize Tauola with an empty ParameterSet\n"
400  << std::endl;
401  }
402 
403  fIsInitialized = true;
404 
405  es.getData( fPDGTable ) ;
406 
407  Tauolapp::Tauola::setDecayingParticle(15);
408  // --> ??? Tauola::setRadiation(false);
409 
410  // polarization switch
411  //
412  // fPolarization = fPSet->getParameter<bool>("UseTauolaPolarization") ? 1 : 0 ;
413  fPolarization = fPSet->getParameter<bool>("UseTauolaPolarization");
414 
415  // read tau decay mode switches
416  //
417  ParameterSet cards = fPSet->getParameter< ParameterSet >("InputCards");
418 
419  fMDTAU = cards.getParameter< int >( "mdtau" );
420 
421  if ( fMDTAU == 0 || fMDTAU == 1 )
422  {
423  Tauolapp::Tauola::setSameParticleDecayMode( cards.getParameter< int >( "pjak1" ) ) ;
424  Tauolapp::Tauola::setOppositeParticleDecayMode( cards.getParameter< int >( "pjak2" ) ) ;
425  }
426 
427  Tauolapp::Tauola::setTauLifetime(0.0);
428  Tauolapp::Tauola::spin_correlation.setAll(fPolarization);
429 
430  // some more options, copied over from an example
431  // - maybe will use later...
432  //
433  //Tauola::setEtaK0sPi(0,0,0); // switches to decay eta K0_S and pi0 1/0 on/off.
434  //
435 
436 //
437 // const HepPDT::ParticleData*
438 // PData = fPDGTable->particle(HepPDT::ParticleID( abs(Tauola::getDecayingParticle()) )) ;
439 // double lifetime = PData->lifetime().value();
440 // Tauola::setTauLifetime( lifetime );
441 
442  fPDGs.push_back( Tauolapp::Tauola::getDecayingParticle() );
443 
444  Tauolapp::Tauola::setRandomGenerator(&gen::TauolappInterface_RandGetter);
445  Tauolapp::Tauola::initialize();
446 
447  Tauolapp::Tauola::spin_correlation.setAll(fPolarization);// Tauola switches this on during Tauola::initialise(); so we add this here to keep it on/off
448 
449  // override decay modes if needs be
450  //
451  // we have to do it AFTER init because otherwises branching ratios are NOT filled in
452  //
453  if ( fMDTAU != 0 && fMDTAU != 1 )
454  {
455  decodeMDTAU( fMDTAU );
456  }
457 
458  Tauolapp::Log::LogWarning(false);
459 
460  return;
461 }
462 
464 {
465 
466  if ( !fPSet )
467  {
468  // throw
469  throw cms::Exception("TauolaInterfaceError")
470  << "Attempt to run random number generator of un-initialized Tauola\n"
471  << std::endl;
472  }
473 
474  if ( !fIsInitialized )
475  {
476  // throw
477  throw cms::Exception("TauolaInterfaceError")
478  << "Attempt to run random number generator of un-initialized Tauola\n"
479  << std::endl;
480  }
481 
482  if ( !fRandomEngine ) {
483  throw cms::Exception("LogicError")
484  << "TauolaInterface::flat: Attempt to generate random number when engine pointer is null\n"
485  << "This might mean that the code was modified to generate a random number outside the\n"
486  << "event and beginLuminosityBlock methods, which is not allowed.\n";
487  }
488  return fRandomEngine->flat();
489 }
490 
491 HepMC::GenEvent* TauolaInterface::decay( HepMC::GenEvent* evt )
492 {
493 
494  if ( !fIsInitialized ) return evt;
495 
496  int NPartBefore = evt->particles_size();
497  int NVtxBefore = evt->vertices_size();
498 
499  // what do we do if Hep::GenEvent size is larger than 10K ???
500  // Tauola (& Photos, BTW) can only handle up to 10K via HEPEVT,
501  // and in case of CMS, it's only up to 4K !!!
502  //
503  // if ( NPartBefore > 10000 ) return evt;
504  //
505 
506  // override decay mode if needs be
507  if ( fSelectDecayByEvent )
508  {
510  }
511 
512  //construct tmp TAUOLA event
513  //
514  auto * t_event = new Tauolapp::TauolaHepMCEvent(evt);
515 
516  // another option: if one lets Pythia or another master gen to decay taus,
517  // we have to undecay them first
518  // t_event->undecayTaus();
519 
520  // run Tauola on the tmp event - HepMC::GenEvernt will be MODIFIED !!!
521  //
522  t_event->decayTaus();
523 
524  // delet tmp Tauola event
525  //
526  delete t_event;
527 
528  // do we also need to apply the lifetime and vtx position shift ???
529  // (see TauolaInterface, for example)
530  //
531  // NOTE: the procedure ASSYMES that vertex barcoding is COUNTIUOUS/SEQUENTIAL,
532  // and that the abs(barcode) corresponds to vertex "plain indexing"
533  //
534  for ( int iv=NVtxBefore+1; iv<=evt->vertices_size(); iv++ )
535  {
536  HepMC::GenVertex* GenVtx = evt->barcode_to_vertex(-iv);
537  HepMC::GenParticle* GenPart = *(GenVtx->particles_in_const_begin());
538  HepMC::GenVertex* ProdVtx = GenPart->production_vertex();
539  HepMC::FourVector PMom = GenPart->momentum();
540  double mass = GenPart->generated_mass();
541  const HepPDT::ParticleData*
542  PData = fPDGTable->particle(HepPDT::ParticleID(abs(GenPart->pdg_id()))) ;
543  double lifetime = PData->lifetime().value();
544  float prob = 0.;
545  int length=1;
546  ranmar_(&prob,&length);
547  double ct = -lifetime * std::log(prob);
548  double VxDec = GenVtx->position().x();
549  VxDec += ct * (PMom.px()/mass);
550  VxDec += ProdVtx->position().x();
551  double VyDec = GenVtx->position().y();
552  VyDec += ct * (PMom.py()/mass);
553  VyDec += ProdVtx->position().y();
554  double VzDec = GenVtx->position().z();
555  VzDec += ct * (PMom.pz()/mass);
556  VzDec += ProdVtx->position().z();
557  double VtDec = GenVtx->position().t();
558  VtDec += ct * (PMom.e()/mass);
559  VtDec += ProdVtx->position().t();
560  GenVtx->set_position( HepMC::FourVector(VxDec,VyDec,VzDec,VtDec) );
561  //
562  // now find decay products with funky barcode, weed out and replace with clones of sensible barcode
563  // we can NOT change the barcode while iterating, because iterators do depend on the barcoding
564  // thus we have to take a 2-step procedure
565  //
566  std::vector<int> BCodes;
567  BCodes.clear();
568  for (HepMC::GenVertex::particle_iterator pitr= GenVtx->particles_begin(HepMC::children);
569  pitr != GenVtx->particles_end(HepMC::children); ++pitr)
570  {
571  if ( (*pitr)->barcode() > 10000 )
572  {
573  BCodes.push_back( (*pitr)->barcode() );
574  }
575  }
576  if ( BCodes.size() > 0 )
577  {
578  for ( size_t ibc=0; ibc<BCodes.size(); ibc++ )
579  {
580  HepMC::GenParticle* p1 = evt->barcode_to_particle( BCodes[ibc] );
581  int nbc = p1->barcode() - 10000 + NPartBefore;
582  p1->suggest_barcode( nbc );
583  }
584  }
585  }
586 
587  return evt;
588 
589 }
590 
592 {
593  return;
594 }
595 
597 {
598 
599  // Note-1:
600  // I have to hack the common block directly because set<...>DecayMode(...)
601  // only changes it in the Tauola++ instance but does NOT passes it over
602  // to the Fortran core - this it does only one, via initialize() stuff...
603  //
604  // So I'll do both ways of settings, just for consistency...
605  // but I probably need to communicate it to the Tauola(++) team...
606  //
607 
608  // Note-2:
609  // originally, the 1xx settings are meant for tau's from hard event,
610  // and the 2xx settings are for any tau in the event record;
611  //
612  // later one, we'll have to take this into account...
613  // but first I'll have to sort out what happens in the 1xx case
614  // to tau's coming outside of hard event (if any in the record)
615  //
616 
617  if ( mdtau == 101 || mdtau == 201 )
618  {
619  // override with electron mode for both tau's
620  //
621  Tauolapp::jaki_.jak1 = 1;
622  Tauolapp::jaki_.jak2 = 1;
623  Tauolapp::Tauola::setSameParticleDecayMode( 1 ) ;
624  Tauolapp::Tauola::setOppositeParticleDecayMode( 1 ) ;
625  return;
626  }
627 
628  if ( mdtau == 102 || mdtau == 202 )
629  {
630  // override with muon mode for both tau's
631  //
632  Tauolapp::jaki_.jak1 = 2;
633  Tauolapp::jaki_.jak2 = 2;
634  Tauolapp::Tauola::setSameParticleDecayMode( 2 ) ;
635  Tauolapp::Tauola::setOppositeParticleDecayMode( 2 ) ;
636  return;
637  }
638 
639  if ( mdtau == 111 || mdtau == 211 )
640  {
641  // override with electron mode for 1st tau
642  // and any mode for 2nd tau
643  //
644  Tauolapp::jaki_.jak1 = 1;
645  Tauolapp::jaki_.jak2 = 0;
646  Tauolapp::Tauola::setSameParticleDecayMode( 1 ) ;
647  Tauolapp::Tauola::setOppositeParticleDecayMode( 0 ) ;
648  return;
649  }
650 
651  if ( mdtau == 112 || mdtau == 212 )
652  {
653  // override with muon mode for the 1st tau
654  // and any mode for the 2nd tau
655  //
656  Tauolapp::jaki_.jak1 = 2;
657  Tauolapp::jaki_.jak2 = 0;
658  Tauolapp::Tauola::setSameParticleDecayMode( 2 ) ;
659  Tauolapp::Tauola::setOppositeParticleDecayMode( 0 ) ;
660  return;
661  }
662 
663  if ( mdtau == 121 || mdtau == 221 )
664  {
665  // override with any mode for the 1st tau
666  // and electron mode for the 2nd tau
667  //
668  Tauolapp::jaki_.jak1 = 0;
669  Tauolapp::jaki_.jak2 = 1;
670  Tauolapp::Tauola::setSameParticleDecayMode( 0 ) ;
671  Tauolapp::Tauola::setOppositeParticleDecayMode( 1 ) ;
672  return;
673  }
674 
675  if ( mdtau == 122 || mdtau == 222 )
676  {
677  // override with any mode for the 1st tau
678  // and muon mode for the 2nd tau
679  //
680  Tauolapp::jaki_.jak1 = 0;
681  Tauolapp::jaki_.jak2 = 2;
682  Tauolapp::Tauola::setSameParticleDecayMode( 0 ) ;
683  Tauolapp::Tauola::setOppositeParticleDecayMode( 2 ) ;
684  return;
685  }
686 
687  if ( mdtau == 140 || mdtau == 240 )
688  {
689  // override with pi+/- nutau mode for both tau's
690  //
691  Tauolapp::jaki_.jak1 = 3;
692  Tauolapp::jaki_.jak2 = 3;
693  Tauolapp::Tauola::setSameParticleDecayMode( 3 ) ;
694  Tauolapp::Tauola::setOppositeParticleDecayMode( 3 ) ;
695  return;
696  }
697 
698  if ( mdtau == 141 || mdtau == 241 )
699  {
700  // override with pi+/- nutau mode for the 1st tau
701  // and any mode for the 2nd tau
702  //
703  Tauolapp::jaki_.jak1 = 3;
704  Tauolapp::jaki_.jak2 = 0;
705  Tauolapp::Tauola::setSameParticleDecayMode( 3 ) ;
706  Tauolapp::Tauola::setOppositeParticleDecayMode( 0 ) ;
707  return;
708  }
709 
710  if ( mdtau == 142 || mdtau == 242 )
711  {
712  // override with any mode for the 1st tau
713  // and pi+/- nutau mode for 2nd tau
714  //
715  Tauolapp::jaki_.jak1 = 0;
716  Tauolapp::jaki_.jak2 = 3;
717  Tauolapp::Tauola::setSameParticleDecayMode( 0 ) ;
718  Tauolapp::Tauola::setOppositeParticleDecayMode( 3 ) ;
719  return;
720  }
721 
722  // OK, we come here for semi-inclusive modes
723  //
724 
725  // First of all, leptons and hadron modes sums
726  //
727  // re-scale branching ratios, just in case...
728  //
729  double sumBra = 0;
730 
731  // the number of decay modes is hardcoded at 22 because that's what it is right now in Tauola
732  // in the future, perhaps an asscess method would be useful - communicate to Tauola team...
733  //
734 
735  for ( int i=0; i<22; i++ )
736  {
737  sumBra += Tauolapp::taubra_.gamprt[i];
738  }
739  if ( sumBra == 0. ) return ; // perhaps need to throw ?
740  for ( int i=0; i<22; i++ )
741  {
742  double newBra = Tauolapp::taubra_.gamprt[i] / sumBra;
743  Tauolapp::Tauola::setTauBr( i+1, newBra );
744  }
745  sumBra = 1.0;
746 
747  double sumLeptonBra = Tauolapp::taubra_.gamprt[0] + Tauolapp::taubra_.gamprt[1];
748  double sumHadronBra = sumBra - sumLeptonBra;
749 
750  for ( int i=0; i<2; i++ )
751  {
752  fLeptonModes.push_back( i+1 );
753  fScaledLeptonBrRatios.push_back( (Tauolapp::taubra_.gamprt[i]/sumLeptonBra) );
754  }
755  for ( int i=2; i<22; i++ )
756  {
757  fHadronModes.push_back( i+1 );
758  fScaledHadronBrRatios.push_back( (Tauolapp::taubra_.gamprt[i]/sumHadronBra) );
759  }
760 
761  fSelectDecayByEvent = true;
762  return;
763 
764 }
765 
767 {
768 
769 
770  if ( fMDTAU == 100 || fMDTAU == 200 )
771  {
772  int mode = selectLeptonic();
773  Tauolapp::jaki_.jak1 = mode;
774  Tauolapp::Tauola::setSameParticleDecayMode( mode );
775  mode = selectLeptonic();
776  Tauolapp::jaki_.jak2 = mode;
777  Tauolapp::Tauola::setOppositeParticleDecayMode( mode );
778  return ;
779  }
780 
781  int modeL = selectLeptonic();
782  int modeH = selectHadronic();
783 
784  if ( fMDTAU == 110 || fMDTAU == 210 )
785  {
786  Tauolapp::jaki_.jak1 = modeL;
787  Tauolapp::jaki_.jak2 = 0;
788  Tauolapp::Tauola::setSameParticleDecayMode( modeL );
789  Tauolapp::Tauola::setOppositeParticleDecayMode( 0 );
790  return ;
791  }
792 
793  if ( fMDTAU == 120 || fMDTAU == 22 )
794  {
795  Tauolapp::jaki_.jak1 = 0;
796  Tauolapp::jaki_.jak2 = modeL;
797  Tauolapp::Tauola::setSameParticleDecayMode( 0 );
798  Tauolapp::Tauola::setOppositeParticleDecayMode( modeL );
799  return;
800  }
801 
802  if ( fMDTAU == 114 || fMDTAU == 214 )
803  {
804  Tauolapp::jaki_.jak1 = modeL;
805  Tauolapp::jaki_.jak2 = modeH;
806  Tauolapp::Tauola::setSameParticleDecayMode( modeL );
807  Tauolapp::Tauola::setOppositeParticleDecayMode( modeH );
808  return;
809  }
810 
811  if ( fMDTAU == 124 || fMDTAU == 224 )
812  {
813  Tauolapp::jaki_.jak1 = modeH;
814  Tauolapp::jaki_.jak2 = modeL;
815  Tauolapp::Tauola::setSameParticleDecayMode( modeH );
816  Tauolapp::Tauola::setOppositeParticleDecayMode( modeL );
817  return;
818  }
819 
820  if ( fMDTAU == 115 || fMDTAU == 215 )
821  {
822  Tauolapp::jaki_.jak1 = 1;
823  Tauolapp::jaki_.jak2 = modeH;
824  Tauolapp::Tauola::setSameParticleDecayMode( 1 );
825  Tauolapp::Tauola::setOppositeParticleDecayMode( modeH );
826  return;
827  }
828 
829  if ( fMDTAU == 125 || fMDTAU == 225 )
830  {
831  Tauolapp::jaki_.jak1 = modeH;
832  Tauolapp::jaki_.jak2 = 1;
833  Tauolapp::Tauola::setSameParticleDecayMode( modeH );
834  Tauolapp::Tauola::setOppositeParticleDecayMode( 1 );
835  return;
836  }
837 
838  if ( fMDTAU == 116 || fMDTAU == 216 )
839  {
840  Tauolapp::jaki_.jak1 = 2;
841  Tauolapp::jaki_.jak2 = modeH;
842  Tauolapp::Tauola::setSameParticleDecayMode( 2 );
843  Tauolapp::Tauola::setOppositeParticleDecayMode( modeH );
844  return;
845  }
846 
847  if ( fMDTAU == 126 || fMDTAU == 226 )
848  {
849  Tauolapp::jaki_.jak1 = modeH;
850  Tauolapp::jaki_.jak2 = 2;
851  Tauolapp::Tauola::setSameParticleDecayMode( modeH );
852  Tauolapp::Tauola::setOppositeParticleDecayMode( 2 );
853  return;
854  }
855 
856  if ( fMDTAU == 130 || fMDTAU == 230 )
857  {
858  Tauolapp::jaki_.jak1 = modeH;
859  Tauolapp::jaki_.jak2 = selectHadronic();
860  Tauolapp::Tauola::setSameParticleDecayMode( modeH );
861  Tauolapp::Tauola::setOppositeParticleDecayMode( Tauolapp::jaki_.jak2 );
862  return;
863  }
864 
865  if ( fMDTAU == 131 || fMDTAU == 231 )
866  {
867  Tauolapp::jaki_.jak1 = modeH;
868  Tauolapp::jaki_.jak2 = 0;
869  Tauolapp::Tauola::setSameParticleDecayMode( modeH );
870  Tauolapp::Tauola::setOppositeParticleDecayMode( 0 );
871  return;
872  }
873 
874  if ( fMDTAU == 132 || fMDTAU == 232 )
875  {
876  Tauolapp::jaki_.jak1 = 0;
877  Tauolapp::jaki_.jak2 = modeH;
878  Tauolapp::Tauola::setSameParticleDecayMode( 0 );
879  Tauolapp::Tauola::setOppositeParticleDecayMode( modeH );
880  return;
881  }
882 
883  // unlikely that we get here on unknown mdtau
884  // - there's a protection earlier
885  // but if we do, just set defaults
886  // probably need to spit a warning...
887  //
888  Tauolapp::Tauola::setSameParticleDecayMode( 0 );
889  Tauolapp::Tauola::setOppositeParticleDecayMode( 0 );
890 
891  return;
892 
893 
894 }
895 
897 {
898 
899  float prob = flat();
900 
901  if ( prob > 0. && prob <= fScaledLeptonBrRatios[0] )
902  {
903  return 1;
904  }
905  else if ( prob > fScaledLeptonBrRatios[1] && prob <=1. )
906  {
907  return 2;
908  }
909 
910  return 0;
911 }
912 
914 {
915 
916  float prob = 0.;
917  int len = 1;
918  ranmar_(&prob,&len);
919 
920  double sumBra = fScaledHadronBrRatios[0];
921  if ( prob > 0. && prob <= sumBra )
922  {
923  return fHadronModes[0];
924  }
925  else
926  {
927  int NN = fScaledHadronBrRatios.size();
928  for ( int i=1; i<NN; i++ )
929  {
930  if ( prob > sumBra && prob <= (sumBra+fScaledHadronBrRatios[i]) )
931  {
932  return fHadronModes[i];
933  }
934  sumBra += fScaledHadronBrRatios[i];
935  }
936  }
937 
938  return 0;
939 
940 }
941 
944  return (double)instance->flat();
945 }
946 
947 /* */
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
HepMC::GenEvent * decay(HepMC::GenEvent *)
static PFTauRenderPlugin instance
void setPSet(const edm::ParameterSet &)
#define nullptr
void rmarin_(int *, int *, int *)
std::vector< double > fScaledLeptonBrRatios
void getData(T &iHolder) const
Definition: EventSetup.h:67
float gamprt[30]
Definition: TauolaWrapper.h:78
int jak2
Definition: TauolaWrapper.h:67
std::vector< int > fLeptonModes
static TauolaInterface * fInstance
double TauolappInterface_RandGetter()
edm::ESHandle< HepPDT::ParticleDataTable > fPDGTable
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void ranmar_(float *rvec, int *lenv)
HepPDT::ParticleData ParticleData
CLHEP::HepRandomEngine * fRandomEngine
edm::ParameterSet * fPSet
std::vector< int > fPDGs
static TauolaInterface * getInstance()
return(e1-e2)*(e1-e2)+dp *dp
std::vector< double > fScaledHadronBrRatios
double p1[4]
Definition: TauolaWrapper.h:89
void init(const edm::EventSetup &)
volatile std::atomic< bool > shutdown_flag false
std::vector< int > fHadronModes
int mdtau
Definition: TauolaWrapper.h:59
struct @357 taubra_