CMS 3D CMS Logo

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