CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
TauolappInterface.cc
Go to the documentation of this file.
1 /* this is the code for the new Tauola++ */
2 
3 #include <iostream>
4 
6 
7 #include "Tauola/Tauola.h"
8 #include "Tauola/TauolaHepMCEvent.h"
9 #include "Tauola/Log.h"
10 #include "Tauola/TauolaHepMCParticle.h"
11 #include "Tauola/TauolaParticle.h"
16 
17 #include "CLHEP/Random/RandomEngine.h"
18 
19 #include "HepMC/GenEvent.h"
20 #include "HepMC/IO_HEPEVT.h"
21 #include "HepMC/HEPEVT_Wrapper.h"
22 
24 
25 // LHE Run
28 
29 // LHE Event
32 
33 using namespace gen;
34 using namespace edm;
35 using namespace std;
36 
37 CLHEP::HepRandomEngine* TauolappInterface::fRandomEngine = nullptr;
38 
39 extern "C" {
40 
41  void gen::ranmar_( float *rvec, int *lenv )
42  {
43  for(int i = 0; i < *lenv; i++)
44  *rvec++ = TauolappInterface::flat();
45  return;
46  }
47 
48  void gen::rmarin_( int*, int*, int* )
49  {
50  return;
51  }
52 
53 }
54 
56  fPolarization(false),
57  fPSet(0),
58  fIsInitialized(false),
59  fMDTAU(-1),
60  fSelectDecayByEvent(false),
61  lhe(NULL),
62  dmMatch(0.5),
63  dolhe(false),
64  dolheBosonCorr(false),
65  ntries(10)
66 {
67  if ( fPSet != 0 ) throw cms::Exception("TauolappInterfaceError") << "Attempt to override Tauola an existing ParameterSet\n" << std::endl;
68  fPSet = new ParameterSet(pset);
69 }
70 
72 
74  if ( fIsInitialized ) return; // do init only once
75  if ( fPSet == 0 ) throw cms::Exception("TauolappInterfaceError") << "Attempt to initialize Tauola with an empty ParameterSet\n" << std::endl;
76 
77  fIsInitialized = true;
78 
79  es.getData( fPDGTable ) ;
80 
81  Tauolapp::Tauola::setDecayingParticle(15);
82 
83  // LHE Information
84  dmMatch=fPSet->getUntrackedParameter<double>("dmMatch",0.5);
85  dolhe=fPSet->getUntrackedParameter<bool>("dolhe",false);
86  dolheBosonCorr=fPSet->getUntrackedParameter<bool>("dolheBosonCorr",true);
87  ntries=fPSet->getUntrackedParameter<int>("ntries",10);
88 
89  // polarization switch
90  // fPolarization = fPSet->getParameter<bool>("UseTauolaPolarization") ? 1 : 0 ;
91  fPolarization = fPSet->getParameter<bool>("UseTauolaPolarization");
92 
93  // read tau decay mode switches
94  //
95  ParameterSet cards = fPSet->getParameter< ParameterSet >("InputCards");
96 
97  fMDTAU = cards.getParameter< int >( "mdtau" );
98 
99  if ( fMDTAU == 0 || fMDTAU == 1 )
100  {
101  Tauolapp::Tauola::setSameParticleDecayMode( cards.getParameter< int >( "pjak1" ) ) ;
102  Tauolapp::Tauola::setOppositeParticleDecayMode( cards.getParameter< int >( "pjak2" ) ) ;
103  }
104 
105  Tauolapp::Tauola::spin_correlation.setAll(fPolarization);
106 
107  // some more options, copied over from an example
108  // Default values
109  //Tauola::setEtaK0sPi(0,0,0); // switches to decay eta K0_S and pi0 1/0 on/off.
110 
111  const HepPDT::ParticleData* PData = fPDGTable->particle(HepPDT::ParticleID( abs(Tauolapp::Tauola::getDecayingParticle()) )) ;
112  double lifetime = PData->lifetime().value();
113  Tauolapp::Tauola::setTauLifetime( lifetime );
114 
115  fPDGs.push_back( Tauolapp::Tauola::getDecayingParticle() );
116 
117  Tauolapp::Tauola::setRandomGenerator(gen::TauolappInterface::flat);
118 
119  if (fPSet->exists("parameterSets")){
120  std::vector<std::string> par = fPSet->getParameter< std::vector<std::string> >("parameterSets");
121  for (unsigned int ip=0; ip<par.size(); ++ip ){
122  std::string curSet = par[ip];
123  if(curSet=="setNewCurrents") Tauolapp::Tauola::setNewCurrents(fPSet->getParameter<int>(curSet));
124  }
125  }
126 
128 
129  Tauolapp::Tauola::spin_correlation.setAll(fPolarization);// Tauola switches this on during Tauola::initialise(); so we add this here to keep it on/off
130 
131  if (fPSet->exists("parameterSets")){
132  std::vector<std::string> par = fPSet->getParameter< std::vector<std::string> >("parameterSets");
133  for (unsigned int ip=0; ip<par.size(); ++ip ){
134  std::string curSet = par[ip];
135  if(curSet=="spinCorrelationSetAll") Tauolapp::Tauola::spin_correlation.setAll(fPSet->getParameter<bool>(curSet));
136  if(curSet=="spinCorrelationGAMMA") Tauolapp::Tauola::spin_correlation.GAMMA=fPSet->getParameter<bool>(curSet);
137  if(curSet=="spinCorrelationZ0") Tauolapp::Tauola::spin_correlation.Z0=fPSet->getParameter<bool>(curSet);
138  if(curSet=="spinCorrelationHIGGS") Tauolapp::Tauola::spin_correlation.HIGGS=fPSet->getParameter<bool>(curSet);
139  if(curSet=="spinCorrelationHIGGSH") Tauolapp::Tauola::spin_correlation.HIGGS_H=fPSet->getParameter<bool>(curSet);
140  if(curSet=="spinCorrelationHIGGSA") Tauolapp::Tauola::spin_correlation.HIGGS_A=fPSet->getParameter<bool>(curSet);
141  if(curSet=="spinCorrelationHIGGSPLUS") Tauolapp::Tauola::spin_correlation.HIGGS_PLUS=fPSet->getParameter<bool>(curSet);
142  if(curSet=="spinCorrelationHIGGSMINUS") Tauolapp::Tauola::spin_correlation.HIGGS_MINUS=fPSet->getParameter<bool>(curSet);
143  if(curSet=="spinCorrelationWPLUS") Tauolapp::Tauola::spin_correlation.W_PLUS=fPSet->getParameter<bool>(curSet);
144  if(curSet=="spinCorrelationWMINUS") Tauolapp::Tauola::spin_correlation.W_MINUS=fPSet->getParameter<bool>(curSet);
145 
146  if(curSet=="setHiggsScalarPseudoscalarPDG") Tauolapp::Tauola::setHiggsScalarPseudoscalarPDG(fPSet->getParameter<int>(curSet));
147  if(curSet=="setHiggsScalarPseudoscalarMixingAngle") Tauolapp::Tauola::setHiggsScalarPseudoscalarMixingAngle(fPSet->getParameter<double>(curSet));
148 
149  if(curSet=="setRadiation") Tauolapp::Tauola::setRadiation(fPSet->getParameter<bool>(curSet));
150  if(curSet=="setRadiationCutOff") Tauolapp::Tauola::setRadiationCutOff(fPSet->getParameter<double>(curSet));
151 
152  if(curSet=="setEtaK0sPi"){
153  std::vector<int> vpar = fPSet->getParameter<std::vector<int> >(curSet);
154  if(vpar.size()==3) Tauolapp::Tauola::setEtaK0sPi(vpar[0],vpar[1],vpar[2]);
155  else {std::cout << "WARNING invalid size for setEtaK0sPi: " << vpar.size() << " Require 3 elements " << std::endl;}
156  }
157 
158  if(curSet=="setTaukle"){
159  std::vector<double> vpar = fPSet->getParameter<std::vector<double> >(curSet);
160  if(vpar.size()==4) Tauolapp::Tauola::setTaukle(vpar[0], vpar[1], vpar[2], vpar[3]);
161  else {std::cout << "WARNING invalid size for setTaukle: " << vpar.size() << " Require 4 elements " << std::endl;}
162  }
163 
164  if(curSet=="setTauBr"){
166  std::vector<int> vJAK = cfg.getParameter<std::vector<int> >("JAK");
167  std::vector<double> vBR = cfg.getParameter<std::vector<double> >("BR");
168  if(vJAK.size() == vBR.size()){
169  for(unsigned int i=0;i<vJAK.size();i++) Tauolapp::Tauola::setTauBr(vJAK[i],vBR[i]);
170  }
171  else {std::cout << "WARNING invalid size for setTauBr - JAK: " << vJAK.size() << " BR: " << vBR.size() << std::endl;}
172  }
173  }
174  }
175 
176  // override decay modes if needs be
177  //
178  // we have to do it AFTER init because otherwises branching ratios are NOT filled in
179  //
180  if ( fMDTAU != 0 && fMDTAU != 1 )
181  {
182  decodeMDTAU( fMDTAU );
183  }
184 
185  Tauolapp::Log::LogWarning(false);
186 
187  return;
188 }
189 
191 {
192  if ( !fRandomEngine ) {
193  throw cms::Exception("LogicError")
194  << "TauolaInterface::flat: Attempt to generate random number when engine pointer is null\n"
195  << "This might mean that the code was modified to generate a random number outside the\n"
196  << "event and beginLuminosityBlock methods, which is not allowed.\n";
197  }
198  return fRandomEngine->flat();
199 }
200 
201 HepMC::GenEvent* TauolappInterface::decay( HepMC::GenEvent* evt ){
202  if ( !fIsInitialized ) return evt;
203  Tauolapp::Tauola::setRandomGenerator(gen::TauolappInterface::flat); // rest tauola++ random number incase other modules use tauola++
204  int NPartBefore = evt->particles_size();
205  int NVtxBefore = evt->vertices_size();
206 
207  // what do we do if Hep::GenEvent size is larger than 10K ???
208  // Tauola (& Photos, BTW) can only handle up to 10K via HEPEVT,
209  // and in case of CMS, it's only up to 4K !!!
210  // override decay mode if needs be
211 
214  }
215  if(dolhe && lhe!=NULL){
216  std::vector<HepMC::GenParticle> particles;
217  std::vector<int> m_idx;
218  std::vector<double> spinup=lhe->getHEPEUP()->SPINUP;
219  std::vector<int> pdg =lhe->getHEPEUP()->IDUP;
220  for(unsigned int i=0;i<spinup.size();i++){
221  particles.push_back(HepMC::GenParticle(HepMC::FourVector(lhe->getHEPEUP()->PUP.at(i)[0],lhe->getHEPEUP()->PUP.at(i)[1],lhe->getHEPEUP()->PUP.at(i)[2],lhe->getHEPEUP()->PUP.at(i)[3]),lhe->getHEPEUP()->IDUP.at(i)));
222  int status = lhe->getHEPEUP()->ISTUP.at(i);
223  particles.at(particles.size()-1).set_generated_mass(lhe->getHEPEUP()->PUP.at(i)[4]);
224  particles.at(particles.size()-1).set_status(status > 0 ? (status == 2 ? 3 : status) : 3);
225  m_idx.push_back(lhe->getHEPEUP()->MOTHUP.at(i).first-1);// correct for fortran index offset
226  }
227  // match to taus in hepmc and identify mother of taus
228  bool hastaus(false);
229  std::vector<HepMC::GenParticle*> match;
230  for(HepMC::GenEvent::particle_const_iterator iter = evt->particles_begin(); iter != evt->particles_end(); iter++) {
231  if(abs((*iter)->pdg_id())==15){
232  hastaus=true;
233  int mother_pid(0);
234  // check imediate parent to avoid parent tau ie tau->taugamma
235  for(HepMC::GenVertex::particle_iterator mother=(*iter)->production_vertex()->particles_begin(HepMC::parents); mother!=(*iter)->production_vertex()->particles_end(HepMC::parents); mother++) {
236  mother_pid = (*mother)->pdg_id();
237  if(mother_pid!=(*iter)->pdg_id()){
238  // match against lhe record
239  if(abs(mother_pid) == 24 || // W
240  abs(mother_pid) == 37 || // H+/-
241  abs(mother_pid) == 23 || // Z
242  abs(mother_pid) == 22 || // gamma
243  abs(mother_pid) == 25 || // H0 SM
244  abs(mother_pid) == 35 || // H0
245  abs(mother_pid) == 36 // A0
246  ){
247  bool isfound=false;
248  for(unsigned int k=0;k<match.size();k++){
249  if((*mother)==match.at(k))isfound=true;
250  }
251  if(!isfound) match.push_back(*mother);
252  }
253  }
254  }
255  }
256  }
257  if(hastaus){
258  // if is single gauge boson decay and match helicities
259  if(match.size()==1 && dolheBosonCorr){
260  for(int i=0; i<ntries;i++){
261  // re-decay taus then check if helicities match
262  auto * t_event = new Tauolapp::TauolaHepMCEvent(evt);
263  t_event->undecayTaus();
264  t_event->decayTaus();
265  bool ismatch=true;
266  for(unsigned int j=0;j<spinup.size();j++){
267  if(abs(pdg.at(j))==15){
268  double diffhelminus=(-1.0*(double)Tauolapp::Tauola::getHelMinus()-spinup.at(j)); // -1.0 to correct for tauola feature
269  double diffhelplus=((double)Tauolapp::Tauola::getHelPlus()-spinup.at(j));
270  if(pdg.at(j)==15 && diffhelminus>0.5) ismatch=false;
271  if(pdg.at(j)==-15 && diffhelplus>0.5) ismatch=false;
272  }
273  }
274  delete t_event;
275  if(ismatch) break;
276  }
277  }
278  else{
279  // If the event does not contain a single gauge boson the code will be run with
280  // remove all tau decays
281  auto * t_event = new Tauolapp::TauolaHepMCEvent(evt);
282  t_event->undecayTaus();
283  delete t_event;
284  // decay all taus manually based on the helicity
285  for(HepMC::GenEvent::particle_const_iterator iter = evt->particles_begin(); iter != evt->particles_end(); iter++) {
286  if(abs((*iter)->pdg_id())==15 && isLastTauInChain(*iter)){
287  TLorentzVector ltau((*iter)->momentum().px(),(*iter)->momentum().py(),(*iter)->momentum().pz(),(*iter)->momentum().e());
289  TLorentzVector mother(m->momentum().px(),m->momentum().py(),m->momentum().pz(),m->momentum().e());
290  TVector3 boost=-1.0*mother.BoostVector(); // boost into mother's CM frame
291  TLorentzVector ltau_lab=ltau;
292  ltau.Boost(boost);
293  mother.Boost(boost);
294  HepMC::GenEvent *tauevt=make_simple_tau_event(ltau,(*iter)->pdg_id(),(*iter)->status());
295  HepMC::GenParticle *p=(*(tauevt->particles_begin()));
296  Tauolapp::TauolaParticle *tp = new Tauolapp::TauolaHepMCParticle(p);
297  double helicity=MatchedLHESpinUp(*iter,particles,spinup,m_idx); // get helicity from lhe
298  if((*iter)->pdg_id()==15) helicity*=-1.0;
299  tp->undecay();
300  // use |S_{tau}|=0.999999 to avoid issues with numerical roundoff
301  Tauolapp::Tauola::decayOne(tp,true,0,0,((double)helicity)*0.999999);
302  boost*=-1.0; // boost back to lab frame
303  mother.Boost(boost);
304  update_particles((*iter),evt,p,boost);
305  //correct tau liftetime for boost (change rest frame from mothers to taus)
306  BoostProdToLabLifeTimeInDecays((*iter),ltau_lab,ltau);
307  delete tauevt;
308  }
309  }
310  }
311  }
312  }
313  else{
314  //construct tmp TAUOLA event
315  auto * t_event = new Tauolapp::TauolaHepMCEvent(evt);
316  //t_event->undecayTaus();
317  t_event->decayTaus();
318  delete t_event;
319  }
320 
321  for ( int iv=NVtxBefore+1; iv<=evt->vertices_size(); iv++ ){
322  HepMC::GenVertex* GenVtx = evt->barcode_to_vertex(-iv);
323  //
324  // now find decay products with funky barcode, weed out and replace with clones of sensible barcode
325  // we can NOT change the barcode while iterating, because iterators do depend on the barcoding
326  // thus we have to take a 2-step procedure
327  //
328  std::vector<int> BCodes;
329  BCodes.clear();
330  for (HepMC::GenVertex::particle_iterator pitr= GenVtx->particles_begin(HepMC::children);
331  pitr != GenVtx->particles_end(HepMC::children); ++pitr){
332  if ( (*pitr)->barcode() > 10000 ){
333  BCodes.push_back( (*pitr)->barcode() );
334  }
335  }
336  if ( BCodes.size() > 0 ){
337  for ( size_t ibc=0; ibc<BCodes.size(); ibc++ ){
338  HepMC::GenParticle* p1 = evt->barcode_to_particle( BCodes[ibc] );
339  int nbc = p1->barcode() - 10000 + NPartBefore;
340  p1->suggest_barcode( nbc );
341  }
342  }
343  }
344 
345  for (HepMC::GenEvent::particle_const_iterator p= evt->particles_begin(); p != evt->particles_end(); ++p){
346  if((*p)->end_vertex() && (*p)->status() == 1)(*p)->set_status(2);
347  if((*p)->end_vertex() && (*p)->end_vertex()->particles_out_size()==0) edm::LogWarning("TauolappInterface::decay error: empty end vertex!");
348  }
349 
350  return evt;
351 }
352 
354 {
355  return;
356 }
357 
359 {
360 
361  // Note-1:
362  // I have to hack the common block directly because set<...>DecayMode(...)
363  // only changes it in the Tauola++ instance but does NOT passes it over
364  // to the Fortran core - this it does only one, via initialize() stuff...
365  //
366  // So I'll do both ways of settings, just for consistency...
367  // but I probably need to communicate it to the Tauola(++) team...
368  //
369 
370  // Note-2:
371  // originally, the 1xx settings are meant for tau's from hard event,
372  // and the 2xx settings are for any tau in the event record;
373  //
374  // later one, we'll have to take this into account...
375  // but first I'll have to sort out what happens in the 1xx case
376  // to tau's coming outside of hard event (if any in the record)
377  //
378 
379  if ( mdtau == 101 || mdtau == 201 )
380  {
381  // override with electron mode for both tau's
382  //
383  Tauolapp::jaki_.jak1 = 1;
384  Tauolapp::jaki_.jak2 = 1;
385  Tauolapp::Tauola::setSameParticleDecayMode( 1 ) ;
386  Tauolapp::Tauola::setOppositeParticleDecayMode( 1 ) ;
387  return;
388  }
389 
390  if ( mdtau == 102 || mdtau == 202 )
391  {
392  // override with muon mode for both tau's
393  //
394  Tauolapp::jaki_.jak1 = 2;
395  Tauolapp::jaki_.jak2 = 2;
396  Tauolapp::Tauola::setSameParticleDecayMode( 2 ) ;
397  Tauolapp::Tauola::setOppositeParticleDecayMode( 2 ) ;
398  return;
399  }
400 
401  if ( mdtau == 111 || mdtau == 211 )
402  {
403  // override with electron mode for 1st tau
404  // and any mode for 2nd tau
405  //
406  Tauolapp::jaki_.jak1 = 1;
407  Tauolapp::jaki_.jak2 = 0;
408  Tauolapp::Tauola::setSameParticleDecayMode( 1 ) ;
409  Tauolapp::Tauola::setOppositeParticleDecayMode( 0 ) ;
410  return;
411  }
412 
413  if ( mdtau == 112 || mdtau == 212 )
414  {
415  // override with muon mode for the 1st tau
416  // and any mode for the 2nd tau
417  //
418  Tauolapp::jaki_.jak1 = 2;
419  Tauolapp::jaki_.jak2 = 0;
420  Tauolapp::Tauola::setSameParticleDecayMode( 2 ) ;
421  Tauolapp::Tauola::setOppositeParticleDecayMode( 0 ) ;
422  return;
423  }
424 
425  if ( mdtau == 121 || mdtau == 221 )
426  {
427  // override with any mode for the 1st tau
428  // and electron mode for the 2nd tau
429  //
430  Tauolapp::jaki_.jak1 = 0;
431  Tauolapp::jaki_.jak2 = 1;
432  Tauolapp::Tauola::setSameParticleDecayMode( 0 ) ;
433  Tauolapp::Tauola::setOppositeParticleDecayMode( 1 ) ;
434  return;
435  }
436 
437  if ( mdtau == 122 || mdtau == 222 )
438  {
439  // override with any mode for the 1st tau
440  // and muon mode for the 2nd tau
441  //
442  Tauolapp::jaki_.jak1 = 0;
443  Tauolapp::jaki_.jak2 = 2;
444  Tauolapp::Tauola::setSameParticleDecayMode( 0 ) ;
445  Tauolapp::Tauola::setOppositeParticleDecayMode( 2 ) ;
446  return;
447  }
448 
449  if ( mdtau == 140 || mdtau == 240 )
450  {
451  // override with pi+/- nutau mode for both tau's
452  //
453  Tauolapp::jaki_.jak1 = 3;
454  Tauolapp::jaki_.jak2 = 3;
455  Tauolapp::Tauola::setSameParticleDecayMode( 3 ) ;
456  Tauolapp::Tauola::setOppositeParticleDecayMode( 3 ) ;
457  return;
458  }
459 
460  if ( mdtau == 141 || mdtau == 241 )
461  {
462  // override with pi+/- nutau mode for the 1st tau
463  // and any mode for the 2nd tau
464  //
465  Tauolapp::jaki_.jak1 = 3;
466  Tauolapp::jaki_.jak2 = 0;
467  Tauolapp::Tauola::setSameParticleDecayMode( 3 ) ;
468  Tauolapp::Tauola::setOppositeParticleDecayMode( 0 ) ;
469  return;
470  }
471 
472  if ( mdtau == 142 || mdtau == 242 )
473  {
474  // override with any mode for the 1st tau
475  // and pi+/- nutau mode for 2nd tau
476  //
477  Tauolapp::jaki_.jak1 = 0;
478  Tauolapp::jaki_.jak2 = 3;
479  Tauolapp::Tauola::setSameParticleDecayMode( 0 ) ;
480  Tauolapp::Tauola::setOppositeParticleDecayMode( 3 ) ;
481  return;
482  }
483 
484  // OK, we come here for semi-inclusive modes
485  //
486 
487  // First of all, leptons and hadron modes sums
488  //
489  // re-scale branching ratios, just in case...
490  //
491  double sumBra = 0;
492 
493  // the number of decay modes is hardcoded at 22 because that's what it is right now in Tauola
494  // in the future, perhaps an asscess method would be useful - communicate to Tauola team...
495  //
496 
497  for ( int i=0; i<22; i++ )
498  {
499  sumBra += Tauolapp::taubra_.gamprt[i];
500  }
501  if ( sumBra == 0. ) return ; // perhaps need to throw ?
502  for ( int i=0; i<22; i++ )
503  {
504  double newBra = Tauolapp::taubra_.gamprt[i] / sumBra;
505  Tauolapp::Tauola::setTauBr( i+1, newBra );
506  }
507  sumBra = 1.0;
508 
509  double sumLeptonBra = Tauolapp::taubra_.gamprt[0] + Tauolapp::taubra_.gamprt[1];
510  double sumHadronBra = sumBra - sumLeptonBra;
511 
512  for ( int i=0; i<2; i++ )
513  {
514  fLeptonModes.push_back( i+1 );
515  fScaledLeptonBrRatios.push_back( (Tauolapp::taubra_.gamprt[i]/sumLeptonBra) );
516  }
517  for ( int i=2; i<22; i++ )
518  {
519  fHadronModes.push_back( i+1 );
520  fScaledHadronBrRatios.push_back( (Tauolapp::taubra_.gamprt[i]/sumHadronBra) );
521  }
522 
523  fSelectDecayByEvent = true;
524  return;
525 
526 }
527 
529 {
530 
531 
532  if ( fMDTAU == 100 || fMDTAU == 200 )
533  {
534  int mode = selectLeptonic();
535  Tauolapp::jaki_.jak1 = mode;
536  Tauolapp::Tauola::setSameParticleDecayMode( mode );
537  mode = selectLeptonic();
538  Tauolapp::jaki_.jak2 = mode;
539  Tauolapp::Tauola::setOppositeParticleDecayMode( mode );
540  return ;
541  }
542 
543  int modeL = selectLeptonic();
544  int modeH = selectHadronic();
545 
546  if ( fMDTAU == 110 || fMDTAU == 210 )
547  {
548  Tauolapp::jaki_.jak1 = modeL;
549  Tauolapp::jaki_.jak2 = 0;
550  Tauolapp::Tauola::setSameParticleDecayMode( modeL );
551  Tauolapp::Tauola::setOppositeParticleDecayMode( 0 );
552  return ;
553  }
554 
555  if ( fMDTAU == 120 || fMDTAU == 22 )
556  {
557  Tauolapp::jaki_.jak1 = 0;
558  Tauolapp::jaki_.jak2 = modeL;
559  Tauolapp::Tauola::setSameParticleDecayMode( 0 );
560  Tauolapp::Tauola::setOppositeParticleDecayMode( modeL );
561  return;
562  }
563 
564  if ( fMDTAU == 114 || fMDTAU == 214 )
565  {
566  Tauolapp::jaki_.jak1 = modeL;
567  Tauolapp::jaki_.jak2 = modeH;
568  Tauolapp::Tauola::setSameParticleDecayMode( modeL );
569  Tauolapp::Tauola::setOppositeParticleDecayMode( modeH );
570  return;
571  }
572 
573  if ( fMDTAU == 124 || fMDTAU == 224 )
574  {
575  Tauolapp::jaki_.jak1 = modeH;
576  Tauolapp::jaki_.jak2 = modeL;
577  Tauolapp::Tauola::setSameParticleDecayMode( modeH );
578  Tauolapp::Tauola::setOppositeParticleDecayMode( modeL );
579  return;
580  }
581 
582  if ( fMDTAU == 115 || fMDTAU == 215 )
583  {
584  Tauolapp::jaki_.jak1 = 1;
585  Tauolapp::jaki_.jak2 = modeH;
586  Tauolapp::Tauola::setSameParticleDecayMode( 1 );
587  Tauolapp::Tauola::setOppositeParticleDecayMode( modeH );
588  return;
589  }
590 
591  if ( fMDTAU == 125 || fMDTAU == 225 )
592  {
593  Tauolapp::jaki_.jak1 = modeH;
594  Tauolapp::jaki_.jak2 = 1;
595  Tauolapp::Tauola::setSameParticleDecayMode( modeH );
596  Tauolapp::Tauola::setOppositeParticleDecayMode( 1 );
597  return;
598  }
599 
600  if ( fMDTAU == 116 || fMDTAU == 216 )
601  {
602  Tauolapp::jaki_.jak1 = 2;
603  Tauolapp::jaki_.jak2 = modeH;
604  Tauolapp::Tauola::setSameParticleDecayMode( 2 );
605  Tauolapp::Tauola::setOppositeParticleDecayMode( modeH );
606  return;
607  }
608 
609  if ( fMDTAU == 126 || fMDTAU == 226 )
610  {
611  Tauolapp::jaki_.jak1 = modeH;
612  Tauolapp::jaki_.jak2 = 2;
613  Tauolapp::Tauola::setSameParticleDecayMode( modeH );
614  Tauolapp::Tauola::setOppositeParticleDecayMode( 2 );
615  return;
616  }
617 
618  if ( fMDTAU == 130 || fMDTAU == 230 )
619  {
620  Tauolapp::jaki_.jak1 = modeH;
621  Tauolapp::jaki_.jak2 = selectHadronic();
622  Tauolapp::Tauola::setSameParticleDecayMode( modeH );
623  Tauolapp::Tauola::setOppositeParticleDecayMode( Tauolapp::jaki_.jak2 );
624  return;
625  }
626 
627  if ( fMDTAU == 131 || fMDTAU == 231 )
628  {
629  Tauolapp::jaki_.jak1 = modeH;
630  Tauolapp::jaki_.jak2 = 0;
631  Tauolapp::Tauola::setSameParticleDecayMode( modeH );
632  Tauolapp::Tauola::setOppositeParticleDecayMode( 0 );
633  return;
634  }
635 
636  if ( fMDTAU == 132 || fMDTAU == 232 )
637  {
638  Tauolapp::jaki_.jak1 = 0;
639  Tauolapp::jaki_.jak2 = modeH;
640  Tauolapp::Tauola::setSameParticleDecayMode( 0 );
641  Tauolapp::Tauola::setOppositeParticleDecayMode( modeH );
642  return;
643  }
644 
645  // unlikely that we get here on unknown mdtau
646  // - there's a protection earlier
647  // but if we do, just set defaults
648  // probably need to spit a warning...
649  //
650  Tauolapp::Tauola::setSameParticleDecayMode( 0 );
651  Tauolapp::Tauola::setOppositeParticleDecayMode( 0 );
652 
653  return;
654 
655 
656 }
657 
659 {
660 
661  float prob = flat();
662 
663  if ( prob > 0. && prob <= fScaledLeptonBrRatios[0] )
664  {
665  return 1;
666  }
667  else if ( prob > fScaledLeptonBrRatios[1] && prob <=1. )
668  {
669  return 2;
670  }
671 
672  return 0;
673 }
674 
676 {
677 
678  float prob = 0.;
679  int len = 1;
680  ranmar_(&prob,&len);
681 
682  double sumBra = fScaledHadronBrRatios[0];
683  if ( prob > 0. && prob <= sumBra )
684  {
685  return fHadronModes[0];
686  }
687  else
688  {
689  int NN = fScaledHadronBrRatios.size();
690  for ( int i=1; i<NN; i++ )
691  {
692  if ( prob > sumBra && prob <= (sumBra+fScaledHadronBrRatios[i]) )
693  {
694  return fHadronModes[i];
695  }
696  sumBra += fScaledHadronBrRatios[i];
697  }
698  }
699 
700  return 0;
701 
702 }
703 
704 HepMC::GenEvent* TauolappInterface::make_simple_tau_event(const TLorentzVector &l,int pdgid,int status){
705  HepMC::GenEvent *event = new HepMC::GenEvent();
706  // make tau's four vector
707  HepMC::FourVector momentum_tau1(l.Px(),l.Py(),l.Pz(),l.E());
708  // make particles
709  HepMC::GenParticle *tau1 = new HepMC::GenParticle(momentum_tau1,pdgid,status);
710  // make the vertex
711  HepMC::GenVertex *vertex = new HepMC::GenVertex();
712  vertex->add_particle_out(tau1);
713  event->add_vertex(vertex);
714  return event;
715 }
716 
717 void TauolappInterface::update_particles(HepMC::GenParticle* partHep,HepMC::GenEvent* theEvent,HepMC::GenParticle* p,TVector3 &boost){
718  partHep->set_status(p->status());
719  if(p->end_vertex()){
720  if(!partHep->end_vertex()){
721  HepMC::GenVertex* vtx = new HepMC::GenVertex(p->end_vertex()->position());
722  theEvent->add_vertex(vtx);
723  vtx->add_particle_in(partHep);
724  }
725  if(p->end_vertex()->particles_out_size()!=0){
726  for(HepMC::GenVertex::particles_out_const_iterator d=p->end_vertex()->particles_out_const_begin(); d!=p->end_vertex()->particles_out_const_end();d++){
727  // Create daughter and add to event
728  TLorentzVector l((*d)->momentum().px(),(*d)->momentum().py(),(*d)->momentum().pz(),(*d)->momentum().e());
729  l.Boost(boost);
730  HepMC::FourVector momentum(l.Px(),l.Py(),l.Pz(),l.E());
731  HepMC::GenParticle *daughter = new HepMC::GenParticle(momentum,(*d)->pdg_id(),(*d)->status());
732  daughter->suggest_barcode(theEvent->particles_size()+1);
733  partHep->end_vertex()->add_particle_out(daughter);
734  if((*d)->end_vertex()) update_particles(daughter,theEvent,(*d),boost);
735  }
736  }
737  }
738 }
739 
741  if ( tau->end_vertex() ) {
742  HepMC::GenVertex::particle_iterator dau;
743  for (dau = tau->end_vertex()->particles_begin(HepMC::children); dau!= tau->end_vertex()->particles_end(HepMC::children); dau++ ) {
744  int dau_pid = (*dau)->pdg_id();
745  if(dau_pid == tau->pdg_id()) return false;
746  }
747  }
748  return true;
749 }
750 
751 double TauolappInterface::MatchedLHESpinUp(HepMC::GenParticle* tau, std::vector<HepMC::GenParticle> &p, std::vector<double> &spinup,
752  std::vector<int> &m_idx){
754  HepMC::GenParticle* mother=GetMother(Tau);
755  TLorentzVector t(tau->momentum().px(),tau->momentum().py(),tau->momentum().pz(),tau->momentum().e());
756  TLorentzVector m(mother->momentum().px(),mother->momentum().py(),mother->momentum().pz(),mother->momentum().e());
757  for(unsigned int i=0;i<p.size();i++){
758  if(tau->pdg_id()==p.at(i).pdg_id()){
759  if(mother->pdg_id()==p.at(m_idx.at(i)).pdg_id()){
760  TLorentzVector pm(p.at(m_idx.at(i)).momentum().px(),p.at(m_idx.at(i)).momentum().py(),p.at(m_idx.at(i)).momentum().pz(),p.at(m_idx.at(i)).momentum().e());
761  if(fabs(m.M()-pm.M())<dmMatch)return spinup.at(i);
762  }
763  }
764  }
765  return 0;
766 }
767 
769  if ( tau->production_vertex() ) {
770  HepMC::GenVertex::particle_iterator mother;
771  for (mother = tau->production_vertex()->particles_begin(HepMC::parents); mother!= tau->production_vertex()->particles_end(HepMC::parents); mother++ ) {
772  if((*mother)->pdg_id()==tau->pdg_id()) return FirstTauInChain(*mother); // recursive call to get mother with different pdgid
773  }
774  }
775  return tau;
776 }
777 
779  if ( tau->production_vertex() ) {
780  HepMC::GenVertex::particle_iterator mother;
781  for (mother = tau->production_vertex()->particles_begin(HepMC::parents); mother!= tau->production_vertex()->particles_end(HepMC::parents); mother++ ) {
782  if((*mother)->pdg_id() == tau->pdg_id()) return GetMother(*mother); // recursive call to get mother with different pdgid
783  return (*mother);
784  }
785  }
786  return tau;
787 }
788 
790  if(p->end_vertex() && p->production_vertex()){
791  HepMC::GenVertex* PGenVtx=p->production_vertex();
792  HepMC::GenVertex* EGenVtx=p->end_vertex();
793  double VxDec = PGenVtx->position().x()+lab.Px()/prod.Px()*(EGenVtx->position().x()-PGenVtx->position().x());
794  double VyDec = PGenVtx->position().y()+lab.Py()/prod.Py()*(EGenVtx->position().y()-PGenVtx->position().y());
795  double VzDec = PGenVtx->position().z()+lab.Pz()/prod.Pz()*(EGenVtx->position().z()-PGenVtx->position().z());
796  double VtDec = PGenVtx->position().t()+lab.Pt()/prod.Pt()*(EGenVtx->position().t()-PGenVtx->position().t());
797  EGenVtx->set_position(HepMC::FourVector(VxDec,VyDec,VzDec,VtDec));
798  for(HepMC::GenVertex::particle_iterator dau=p->end_vertex()->particles_begin(HepMC::children); dau!=p->end_vertex()->particles_end(HepMC::children); dau++){
799  BoostProdToLabLifeTimeInDecays((*dau),lab,prod); //recursively modify everything in the decay chain
800  }
801  }
802 }
T getParameter(std::string const &) const
static AlgebraicMatrix initialize()
TauolappInterface(const edm::ParameterSet &)
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
edm::ParameterSet * fPSet
TPRegexp parents
Definition: eve_filter.cc:21
tuple cfg
Definition: looper.py:293
std::vector< double > fScaledHadronBrRatios
bool exists(std::string const &parameterName) const
checks if a parameter exists
#define NULL
Definition: scimark2.h:8
HepMC::GenEvent * make_simple_tau_event(const TLorentzVector &l, int pdgid, int status)
void rmarin_(int *, int *, int *)
const HEPEUP * getHEPEUP() const
Definition: LHEEvent.h:43
void getData(T &iHolder) const
Definition: EventSetup.h:79
float gamprt[30]
Definition: TauolaWrapper.h:78
return((rh^lh)&mask)
int jak2
Definition: TauolaWrapper.h:67
tuple d
Definition: ztail.py:151
double p[5][pyjets_maxn]
std::vector< std::pair< int, int > > MOTHUP
Definition: LesHouches.h:236
std::vector< int > fPDGs
void BoostProdToLabLifeTimeInDecays(HepMC::GenParticle *p, TLorentzVector &lab, TLorentzVector &prod)
std::vector< int > fLeptonModes
std::vector< FiveVector > PUP
Definition: LesHouches.h:248
struct @581 taubra_
std::vector< double > SPINUP
Definition: LesHouches.h:261
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int j
Definition: DBlmapReader.cc:9
std::vector< int > ISTUP
Definition: LesHouches.h:230
void ranmar_(float *rvec, int *lenv)
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
HepPDT::ParticleData ParticleData
std::vector< int > IDUP
Definition: LesHouches.h:225
int k[5][pyjets_maxn]
void update_particles(HepMC::GenParticle *partHep, HepMC::GenEvent *theEvent, HepMC::GenParticle *p, TVector3 &boost)
void init(const edm::EventSetup &)
HepMC::GenParticle * FirstTauInChain(HepMC::GenParticle *tau)
HepMC::GenEvent * decay(HepMC::GenEvent *)
bool isLastTauInChain(const HepMC::GenParticle *tau)
std::vector< double > fScaledLeptonBrRatios
static CLHEP::HepRandomEngine * fRandomEngine
std::vector< int > fHadronModes
double p1[4]
Definition: TauolaWrapper.h:89
HepMC::GenParticle * GetMother(HepMC::GenParticle *tau)
tuple cout
Definition: gather_cfg.py:121
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
edm::ESHandle< HepPDT::ParticleDataTable > fPDGTable
volatile std::atomic< bool > shutdown_flag false
tuple status
Definition: ntuplemaker.py:245
double MatchedLHESpinUp(HepMC::GenParticle *tau, std::vector< HepMC::GenParticle > &p, std::vector< double > &spinup, std::vector< int > &m_idx)
int mdtau
Definition: TauolaWrapper.h:59