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  Tauolapp::Log::IgnoreRedirection(true);
210 
211  return;
212 }
213 
215  if (!fRandomEngine) {
216  throw cms::Exception("LogicError")
217  << "TauolaInterface::flat: Attempt to generate random number when engine pointer is null\n"
218  << "This might mean that the code was modified to generate a random number outside the\n"
219  << "event and beginLuminosityBlock methods, which is not allowed.\n";
220  }
221  return fRandomEngine->flat();
222 }
223 
225  if (!fIsInitialized)
226  return evt;
227  Tauolapp::Tauola::setRandomGenerator(
228  gen::TauolappInterface::flat); // rest tauola++ random number incase other modules use tauola++
229  int NPartBefore = evt->particles_size();
230  int NVtxBefore = evt->vertices_size();
231 
232  // what do we do if Hep::GenEvent size is larger than 10K ???
233  // Tauola (& Photos, BTW) can only handle up to 10K via HEPEVT,
234  // and in case of CMS, it's only up to 4K !!!
235  // override decay mode if needs be
236 
237  if (fSelectDecayByEvent) {
239  }
240  if (dolhe && lhe != nullptr) {
241  std::vector<HepMC::GenParticle> particles;
242  std::vector<int> m_idx;
243  std::vector<double> spinup = lhe->getHEPEUP()->SPINUP;
244  std::vector<int> pdg = lhe->getHEPEUP()->IDUP;
245  for (unsigned int i = 0; i < spinup.size(); i++) {
246  particles.push_back(HepMC::GenParticle(HepMC::FourVector(lhe->getHEPEUP()->PUP.at(i)[0],
247  lhe->getHEPEUP()->PUP.at(i)[1],
248  lhe->getHEPEUP()->PUP.at(i)[2],
249  lhe->getHEPEUP()->PUP.at(i)[3]),
250  lhe->getHEPEUP()->IDUP.at(i)));
251  int status = lhe->getHEPEUP()->ISTUP.at(i);
252  particles.at(particles.size() - 1).set_generated_mass(lhe->getHEPEUP()->PUP.at(i)[4]);
253  particles.at(particles.size() - 1).set_status(status > 0 ? (status == 2 ? 3 : status) : 3);
254  m_idx.push_back(lhe->getHEPEUP()->MOTHUP.at(i).first - 1); // correct for fortran index offset
255  }
256  // match to taus in hepmc and identify mother of taus
257  bool hastaus(false);
258  std::vector<HepMC::GenParticle*> match;
259  for (HepMC::GenEvent::particle_const_iterator iter = evt->particles_begin(); iter != evt->particles_end(); iter++) {
260  if (abs((*iter)->pdg_id()) == 15) {
261  hastaus = true;
262  int mother_pid(0);
263  // check imediate parent to avoid parent tau ie tau->taugamma
264  for (HepMC::GenVertex::particle_iterator mother = (*iter)->production_vertex()->particles_begin(HepMC::parents);
265  mother != (*iter)->production_vertex()->particles_end(HepMC::parents);
266  mother++) {
267  mother_pid = (*mother)->pdg_id();
268  if (mother_pid != (*iter)->pdg_id()) {
269  // match against lhe record
270  if (abs(mother_pid) == 24 || // W
271  abs(mother_pid) == 37 || // H+/-
272  abs(mother_pid) == 23 || // Z
273  abs(mother_pid) == 22 || // gamma
274  abs(mother_pid) == 25 || // H0 SM
275  abs(mother_pid) == 35 || // H0
276  abs(mother_pid) == 36 // A0
277  ) {
278  bool isfound = false;
279  for (unsigned int k = 0; k < match.size(); k++) {
280  if ((*mother) == match.at(k))
281  isfound = true;
282  }
283  if (!isfound)
284  match.push_back(*mother);
285  }
286  }
287  }
288  }
289  }
290  if (hastaus) {
291  // if is single gauge boson decay and match helicities
292  if (match.size() == 1 && dolheBosonCorr) {
293  for (int i = 0; i < ntries; i++) {
294  // re-decay taus then check if helicities match
295  auto* t_event = new Tauolapp::TauolaHepMCEvent(evt);
296  t_event->undecayTaus();
297  t_event->decayTaus();
298  bool ismatch = true;
299  for (unsigned int j = 0; j < spinup.size(); j++) {
300  if (abs(pdg.at(j)) == 15) {
301  double diffhelminus = (-1.0 * (double)Tauolapp::Tauola::getHelMinus() -
302  spinup.at(j)); // -1.0 to correct for tauola feature
303  double diffhelplus = ((double)Tauolapp::Tauola::getHelPlus() - spinup.at(j));
304  if (pdg.at(j) == 15 && diffhelminus > 0.5)
305  ismatch = false;
306  if (pdg.at(j) == -15 && diffhelplus > 0.5)
307  ismatch = false;
308  }
309  }
310  delete t_event;
311  if (ismatch)
312  break;
313  }
314  } else {
315  // If the event does not contain a single gauge boson the code will be run with
316  // remove all tau decays
317  auto* t_event = new Tauolapp::TauolaHepMCEvent(evt);
318  t_event->undecayTaus();
319  delete t_event;
320  // decay all taus manually based on the helicity
321  for (HepMC::GenEvent::particle_const_iterator iter = evt->particles_begin(); iter != evt->particles_end();
322  iter++) {
323  if (abs((*iter)->pdg_id()) == 15 && isLastTauInChain(*iter)) {
324  TLorentzVector ltau(
325  (*iter)->momentum().px(), (*iter)->momentum().py(), (*iter)->momentum().pz(), (*iter)->momentum().e());
326  HepMC::GenParticle* m = GetMother(*iter);
327  TLorentzVector mother(m->momentum().px(), m->momentum().py(), m->momentum().pz(), m->momentum().e());
328  TVector3 boost = -1.0 * mother.BoostVector(); // boost into mother's CM frame
329  TLorentzVector ltau_lab = ltau;
330  ltau.Boost(boost);
331  mother.Boost(boost);
332  HepMC::GenEvent* tauevt = make_simple_tau_event(ltau, (*iter)->pdg_id(), (*iter)->status());
333  HepMC::GenParticle* p = (*(tauevt->particles_begin()));
334  Tauolapp::TauolaParticle* tp = new Tauolapp::TauolaHepMCParticle(p);
335  double helicity = MatchedLHESpinUp(*iter, particles, spinup, m_idx); // get helicity from lhe
336  if ((*iter)->pdg_id() == 15)
337  helicity *= -1.0;
338  tp->undecay();
339  // use |S_{tau}|=0.999999 to avoid issues with numerical roundoff
340  Tauolapp::Tauola::decayOne(tp, true, 0, 0, ((double)helicity) * 0.999999);
341  boost *= -1.0; // boost back to lab frame
342  mother.Boost(boost);
343  update_particles((*iter), evt, p, boost);
344  //correct tau liftetime for boost (change rest frame from mothers to taus)
345  BoostProdToLabLifeTimeInDecays((*iter), ltau_lab, ltau);
346  delete tauevt;
347  }
348  }
349  }
350  }
351  } else {
352  //construct tmp TAUOLA event
353  auto* t_event = new Tauolapp::TauolaHepMCEvent(evt);
354  //t_event->undecayTaus();
355  t_event->decayTaus();
356  delete t_event;
357  }
358 
359  for (int iv = NVtxBefore + 1; iv <= evt->vertices_size(); iv++) {
360  HepMC::GenVertex* GenVtx = evt->barcode_to_vertex(-iv);
361  //
362  // now find decay products with funky barcode, weed out and replace with clones of sensible barcode
363  // we can NOT change the barcode while iterating, because iterators do depend on the barcoding
364  // thus we have to take a 2-step procedure
365  //
366  std::vector<int> BCodes;
367  BCodes.clear();
368  for (HepMC::GenVertex::particle_iterator pitr = GenVtx->particles_begin(HepMC::children);
369  pitr != GenVtx->particles_end(HepMC::children);
370  ++pitr) {
371  if ((*pitr)->barcode() > 10000) {
372  BCodes.push_back((*pitr)->barcode());
373  }
374  }
375  if (!BCodes.empty()) {
376  for (size_t ibc = 0; ibc < BCodes.size(); ibc++) {
377  HepMC::GenParticle* p1 = evt->barcode_to_particle(BCodes[ibc]);
378  int nbc = p1->barcode() - 10000 + NPartBefore;
379  p1->suggest_barcode(nbc);
380  }
381  }
382  }
383 
384  for (HepMC::GenEvent::particle_const_iterator p = evt->particles_begin(); p != evt->particles_end(); ++p) {
385  if ((*p)->end_vertex() && (*p)->status() == 1)
386  (*p)->set_status(2);
387  if ((*p)->end_vertex() && (*p)->end_vertex()->particles_out_size() == 0)
388  edm::LogWarning("TauolappInterface::decay error: empty end vertex!");
389  }
390 
391  return evt;
392 }
393 
395 
397  // Note-1:
398  // I have to hack the common block directly because set<...>DecayMode(...)
399  // only changes it in the Tauola++ instance but does NOT passes it over
400  // to the Fortran core - this it does only one, via initialize() stuff...
401  //
402  // So I'll do both ways of settings, just for consistency...
403  // but I probably need to communicate it to the Tauola(++) team...
404  //
405 
406  // Note-2:
407  // originally, the 1xx settings are meant for tau's from hard event,
408  // and the 2xx settings are for any tau in the event record;
409  //
410  // later one, we'll have to take this into account...
411  // but first I'll have to sort out what happens in the 1xx case
412  // to tau's coming outside of hard event (if any in the record)
413  //
414 
415  if (mdtau == 101 || mdtau == 201) {
416  // override with electron mode for both tau's
417  //
418  Tauolapp::jaki_.jak1 = 1;
419  Tauolapp::jaki_.jak2 = 1;
420  Tauolapp::Tauola::setSameParticleDecayMode(1);
421  Tauolapp::Tauola::setOppositeParticleDecayMode(1);
422  return;
423  }
424 
425  if (mdtau == 102 || mdtau == 202) {
426  // override with muon mode for both tau's
427  //
428  Tauolapp::jaki_.jak1 = 2;
429  Tauolapp::jaki_.jak2 = 2;
430  Tauolapp::Tauola::setSameParticleDecayMode(2);
431  Tauolapp::Tauola::setOppositeParticleDecayMode(2);
432  return;
433  }
434 
435  if (mdtau == 111 || mdtau == 211) {
436  // override with electron mode for 1st tau
437  // and any mode for 2nd tau
438  //
439  Tauolapp::jaki_.jak1 = 1;
440  Tauolapp::jaki_.jak2 = 0;
441  Tauolapp::Tauola::setSameParticleDecayMode(1);
442  Tauolapp::Tauola::setOppositeParticleDecayMode(0);
443  return;
444  }
445 
446  if (mdtau == 112 || mdtau == 212) {
447  // override with muon mode for the 1st tau
448  // and any mode for the 2nd tau
449  //
450  Tauolapp::jaki_.jak1 = 2;
451  Tauolapp::jaki_.jak2 = 0;
452  Tauolapp::Tauola::setSameParticleDecayMode(2);
453  Tauolapp::Tauola::setOppositeParticleDecayMode(0);
454  return;
455  }
456 
457  if (mdtau == 121 || mdtau == 221) {
458  // override with any mode for the 1st tau
459  // and electron mode for the 2nd tau
460  //
461  Tauolapp::jaki_.jak1 = 0;
462  Tauolapp::jaki_.jak2 = 1;
463  Tauolapp::Tauola::setSameParticleDecayMode(0);
464  Tauolapp::Tauola::setOppositeParticleDecayMode(1);
465  return;
466  }
467 
468  if (mdtau == 122 || mdtau == 222) {
469  // override with any mode for the 1st tau
470  // and muon mode for the 2nd tau
471  //
472  Tauolapp::jaki_.jak1 = 0;
473  Tauolapp::jaki_.jak2 = 2;
474  Tauolapp::Tauola::setSameParticleDecayMode(0);
475  Tauolapp::Tauola::setOppositeParticleDecayMode(2);
476  return;
477  }
478 
479  if (mdtau == 140 || mdtau == 240) {
480  // override with pi+/- nutau mode for both tau's
481  //
482  Tauolapp::jaki_.jak1 = 3;
483  Tauolapp::jaki_.jak2 = 3;
484  Tauolapp::Tauola::setSameParticleDecayMode(3);
485  Tauolapp::Tauola::setOppositeParticleDecayMode(3);
486  return;
487  }
488 
489  if (mdtau == 141 || mdtau == 241) {
490  // override with pi+/- nutau mode for the 1st tau
491  // and any mode for the 2nd tau
492  //
493  Tauolapp::jaki_.jak1 = 3;
494  Tauolapp::jaki_.jak2 = 0;
495  Tauolapp::Tauola::setSameParticleDecayMode(3);
496  Tauolapp::Tauola::setOppositeParticleDecayMode(0);
497  return;
498  }
499 
500  if (mdtau == 142 || mdtau == 242) {
501  // override with any mode for the 1st tau
502  // and pi+/- nutau mode for 2nd tau
503  //
504  Tauolapp::jaki_.jak1 = 0;
505  Tauolapp::jaki_.jak2 = 3;
506  Tauolapp::Tauola::setSameParticleDecayMode(0);
507  Tauolapp::Tauola::setOppositeParticleDecayMode(3);
508  return;
509  }
510 
511  // OK, we come here for semi-inclusive modes
512  //
513 
514  // First of all, leptons and hadron modes sums
515  //
516  // re-scale branching ratios, just in case...
517  //
518  double sumBra = 0;
519 
520  // the number of decay modes is hardcoded at 22 because that's what it is right now in Tauola
521  // in the future, perhaps an asscess method would be useful - communicate to Tauola team...
522  //
523 
524  for (int i = 0; i < 22; i++) {
525  sumBra += Tauolapp::taubra_.gamprt[i];
526  }
527  if (sumBra == 0.)
528  return; // perhaps need to throw ?
529  for (int i = 0; i < 22; i++) {
530  double newBra = Tauolapp::taubra_.gamprt[i] / sumBra;
531  Tauolapp::Tauola::setTauBr(i + 1, newBra);
532  }
533  sumBra = 1.0;
534 
535  double sumLeptonBra = Tauolapp::taubra_.gamprt[0] + Tauolapp::taubra_.gamprt[1];
536  double sumHadronBra = sumBra - sumLeptonBra;
537 
538  for (int i = 0; i < 2; i++) {
539  fLeptonModes.push_back(i + 1);
540  fScaledLeptonBrRatios.push_back((Tauolapp::taubra_.gamprt[i] / sumLeptonBra));
541  }
542  for (int i = 2; i < 22; i++) {
543  fHadronModes.push_back(i + 1);
544  fScaledHadronBrRatios.push_back((Tauolapp::taubra_.gamprt[i] / sumHadronBra));
545  }
546 
547  fSelectDecayByEvent = true;
548  return;
549 }
550 
552  if (fMDTAU == 100 || fMDTAU == 200) {
553  int mode = selectLeptonic();
554  Tauolapp::jaki_.jak1 = mode;
555  Tauolapp::Tauola::setSameParticleDecayMode(mode);
556  mode = selectLeptonic();
557  Tauolapp::jaki_.jak2 = mode;
558  Tauolapp::Tauola::setOppositeParticleDecayMode(mode);
559  return;
560  }
561 
562  int modeL = selectLeptonic();
563  int modeH = selectHadronic();
564 
565  if (fMDTAU == 110 || fMDTAU == 210) {
566  Tauolapp::jaki_.jak1 = modeL;
567  Tauolapp::jaki_.jak2 = 0;
568  Tauolapp::Tauola::setSameParticleDecayMode(modeL);
569  Tauolapp::Tauola::setOppositeParticleDecayMode(0);
570  return;
571  }
572 
573  if (fMDTAU == 120 || fMDTAU == 22) {
574  Tauolapp::jaki_.jak1 = 0;
575  Tauolapp::jaki_.jak2 = modeL;
576  Tauolapp::Tauola::setSameParticleDecayMode(0);
577  Tauolapp::Tauola::setOppositeParticleDecayMode(modeL);
578  return;
579  }
580 
581  if (fMDTAU == 114 || fMDTAU == 214) {
582  Tauolapp::jaki_.jak1 = modeL;
583  Tauolapp::jaki_.jak2 = modeH;
584  Tauolapp::Tauola::setSameParticleDecayMode(modeL);
585  Tauolapp::Tauola::setOppositeParticleDecayMode(modeH);
586  return;
587  }
588 
589  if (fMDTAU == 124 || fMDTAU == 224) {
590  Tauolapp::jaki_.jak1 = modeH;
591  Tauolapp::jaki_.jak2 = modeL;
592  Tauolapp::Tauola::setSameParticleDecayMode(modeH);
593  Tauolapp::Tauola::setOppositeParticleDecayMode(modeL);
594  return;
595  }
596 
597  if (fMDTAU == 115 || fMDTAU == 215) {
598  Tauolapp::jaki_.jak1 = 1;
599  Tauolapp::jaki_.jak2 = modeH;
600  Tauolapp::Tauola::setSameParticleDecayMode(1);
601  Tauolapp::Tauola::setOppositeParticleDecayMode(modeH);
602  return;
603  }
604 
605  if (fMDTAU == 125 || fMDTAU == 225) {
606  Tauolapp::jaki_.jak1 = modeH;
607  Tauolapp::jaki_.jak2 = 1;
608  Tauolapp::Tauola::setSameParticleDecayMode(modeH);
609  Tauolapp::Tauola::setOppositeParticleDecayMode(1);
610  return;
611  }
612 
613  if (fMDTAU == 116 || fMDTAU == 216) {
614  Tauolapp::jaki_.jak1 = 2;
615  Tauolapp::jaki_.jak2 = modeH;
616  Tauolapp::Tauola::setSameParticleDecayMode(2);
617  Tauolapp::Tauola::setOppositeParticleDecayMode(modeH);
618  return;
619  }
620 
621  if (fMDTAU == 126 || fMDTAU == 226) {
622  Tauolapp::jaki_.jak1 = modeH;
623  Tauolapp::jaki_.jak2 = 2;
624  Tauolapp::Tauola::setSameParticleDecayMode(modeH);
625  Tauolapp::Tauola::setOppositeParticleDecayMode(2);
626  return;
627  }
628 
629  if (fMDTAU == 130 || fMDTAU == 230) {
630  Tauolapp::jaki_.jak1 = modeH;
631  Tauolapp::jaki_.jak2 = selectHadronic();
632  Tauolapp::Tauola::setSameParticleDecayMode(modeH);
633  Tauolapp::Tauola::setOppositeParticleDecayMode(Tauolapp::jaki_.jak2);
634  return;
635  }
636 
637  if (fMDTAU == 131 || fMDTAU == 231) {
638  Tauolapp::jaki_.jak1 = modeH;
639  Tauolapp::jaki_.jak2 = 0;
640  Tauolapp::Tauola::setSameParticleDecayMode(modeH);
641  Tauolapp::Tauola::setOppositeParticleDecayMode(0);
642  return;
643  }
644 
645  if (fMDTAU == 132 || fMDTAU == 232) {
646  Tauolapp::jaki_.jak1 = 0;
647  Tauolapp::jaki_.jak2 = modeH;
648  Tauolapp::Tauola::setSameParticleDecayMode(0);
649  Tauolapp::Tauola::setOppositeParticleDecayMode(modeH);
650  return;
651  }
652 
653  // unlikely that we get here on unknown mdtau
654  // - there's a protection earlier
655  // but if we do, just set defaults
656  // probably need to spit a warning...
657  //
658  Tauolapp::Tauola::setSameParticleDecayMode(0);
659  Tauolapp::Tauola::setOppositeParticleDecayMode(0);
660 
661  return;
662 }
663 
665  float prob = flat();
666 
667  if (prob > 0. && prob <= fScaledLeptonBrRatios[0]) {
668  return 1;
669  } else if (prob > fScaledLeptonBrRatios[1] && prob <= 1.) {
670  return 2;
671  }
672 
673  return 0;
674 }
675 
677  float prob = 0.;
678  int len = 1;
679  ranmar_(&prob, &len);
680 
681  double sumBra = fScaledHadronBrRatios[0];
682  if (prob > 0. && prob <= sumBra) {
683  return fHadronModes[0];
684  } else {
685  int NN = fScaledHadronBrRatios.size();
686  for (int i = 1; i < NN; i++) {
687  if (prob > sumBra && prob <= (sumBra + fScaledHadronBrRatios[i])) {
688  return fHadronModes[i];
689  }
690  sumBra += fScaledHadronBrRatios[i];
691  }
692  }
693 
694  return 0;
695 }
696 
698  HepMC::GenEvent* event = new HepMC::GenEvent();
699  // make tau's four vector
700  HepMC::FourVector momentum_tau1(l.Px(), l.Py(), l.Pz(), l.E());
701  // make particles
702  HepMC::GenParticle* tau1 = new HepMC::GenParticle(momentum_tau1, pdgid, status);
703  // make the vertex
704  HepMC::GenVertex* vertex = new HepMC::GenVertex();
705  vertex->add_particle_out(tau1);
706  event->add_vertex(vertex);
707  return event;
708 }
709 
711  HepMC::GenEvent* theEvent,
713  TVector3& boost) {
714  partHep->set_status(p->status());
715  if (p->end_vertex()) {
716  if (!partHep->end_vertex()) {
717  HepMC::GenVertex* vtx = new HepMC::GenVertex(p->end_vertex()->position());
718  theEvent->add_vertex(vtx);
719  vtx->add_particle_in(partHep);
720  }
721  if (p->end_vertex()->particles_out_size() != 0) {
722  for (HepMC::GenVertex::particles_out_const_iterator d = p->end_vertex()->particles_out_const_begin();
723  d != p->end_vertex()->particles_out_const_end();
724  d++) {
725  // Create daughter and add to event
726  TLorentzVector l((*d)->momentum().px(), (*d)->momentum().py(), (*d)->momentum().pz(), (*d)->momentum().e());
727  l.Boost(boost);
728  HepMC::FourVector momentum(l.Px(), l.Py(), l.Pz(), l.E());
729  HepMC::GenParticle* daughter = new HepMC::GenParticle(momentum, (*d)->pdg_id(), (*d)->status());
730  daughter->suggest_barcode(theEvent->particles_size() + 1);
731  partHep->end_vertex()->add_particle_out(daughter);
732  if ((*d)->end_vertex())
733  update_particles(daughter, theEvent, (*d), boost);
734  }
735  }
736  }
737 }
738 
740  if (tau->end_vertex()) {
741  HepMC::GenVertex::particle_iterator dau;
742  for (dau = tau->end_vertex()->particles_begin(HepMC::children);
743  dau != tau->end_vertex()->particles_end(HepMC::children);
744  dau++) {
745  int dau_pid = (*dau)->pdg_id();
746  if (dau_pid == tau->pdg_id())
747  return false;
748  }
749  }
750  return true;
751 }
752 
754  std::vector<HepMC::GenParticle>& p,
755  std::vector<double>& spinup,
756  std::vector<int>& m_idx) {
758  HepMC::GenParticle* mother = GetMother(Tau);
759  TLorentzVector t(tau->momentum().px(), tau->momentum().py(), tau->momentum().pz(), tau->momentum().e());
760  TLorentzVector m(mother->momentum().px(), mother->momentum().py(), mother->momentum().pz(), mother->momentum().e());
761  for (unsigned int i = 0; i < p.size(); i++) {
762  if (tau->pdg_id() == p.at(i).pdg_id()) {
763  if (mother->pdg_id() == p.at(m_idx.at(i)).pdg_id()) {
764  TLorentzVector pm(p.at(m_idx.at(i)).momentum().px(),
765  p.at(m_idx.at(i)).momentum().py(),
766  p.at(m_idx.at(i)).momentum().pz(),
767  p.at(m_idx.at(i)).momentum().e());
768  if (fabs(m.M() - pm.M()) < dmMatch)
769  return spinup.at(i);
770  }
771  }
772  }
773  return 0;
774 }
775 
777  if (tau->production_vertex()) {
778  HepMC::GenVertex::particle_iterator mother;
779  for (mother = tau->production_vertex()->particles_begin(HepMC::parents);
780  mother != tau->production_vertex()->particles_end(HepMC::parents);
781  mother++) {
782  if ((*mother)->pdg_id() == tau->pdg_id())
783  return FirstTauInChain(*mother); // recursive call to get mother with different pdgid
784  }
785  }
786  return tau;
787 }
788 
790  if (tau->production_vertex()) {
791  HepMC::GenVertex::particle_iterator mother;
792  for (mother = tau->production_vertex()->particles_begin(HepMC::parents);
793  mother != tau->production_vertex()->particles_end(HepMC::parents);
794  mother++) {
795  if ((*mother)->pdg_id() == tau->pdg_id())
796  return GetMother(*mother); // recursive call to get mother with different pdgid
797  return (*mother);
798  }
799  }
800  return tau;
801 }
802 
804  TLorentzVector& lab,
805  TLorentzVector& prod) {
806  if (p->end_vertex() && p->production_vertex()) {
807  HepMC::GenVertex* PGenVtx = p->production_vertex();
808  HepMC::GenVertex* EGenVtx = p->end_vertex();
809  double VxDec = PGenVtx->position().x() + lab.Px() / prod.Px() * (EGenVtx->position().x() - PGenVtx->position().x());
810  double VyDec = PGenVtx->position().y() + lab.Py() / prod.Py() * (EGenVtx->position().y() - PGenVtx->position().y());
811  double VzDec = PGenVtx->position().z() + lab.Pz() / prod.Pz() * (EGenVtx->position().z() - PGenVtx->position().z());
812  double VtDec = PGenVtx->position().t() + lab.Pt() / prod.Pt() * (EGenVtx->position().t() - PGenVtx->position().t());
813  EGenVtx->set_position(HepMC::FourVector(VxDec, VyDec, VzDec, VtDec));
814  for (HepMC::GenVertex::particle_iterator dau = p->end_vertex()->particles_begin(HepMC::children);
815  dau != p->end_vertex()->particles_end(HepMC::children);
816  dau++) {
817  BoostProdToLabLifeTimeInDecays((*dau), lab, prod); //recursively modify everything in the decay chain
818  }
819  }
820 }
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:130
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)
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)