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 #include <iostream>
4 #include "Tauola/Tauola.h"
5 #include "Tauola/TauolaHepMCEvent.h"
6 #include "Tauola/Log.h"
10 #include "CLHEP/Random/RandomEngine.h"
11 #include "HepMC/GenEvent.h"
12 #include "HepMC/IO_HEPEVT.h"
13 #include "HepMC/HEPEVT_Wrapper.h"
15 using namespace gen;
16 using namespace edm;
17 using namespace std;
18 CLHEP::HepRandomEngine* TauolappInterface::fRandomEngine = nullptr;
19 extern "C" {
20  void gen::ranmar_( float *rvec, int *lenv )
21  {
22  for(int i = 0; i < *lenv; i++)
23  *rvec++ = TauolappInterface::flat();
24  return;
25  }
26  void gen::rmarin_( int*, int*, int* )
27  {
28  return;
29  }
30 }
32  fPolarization(false),
33  fPSet(0),
34  fIsInitialized(false),
35  fMDTAU(-1),
36  fSelectDecayByEvent(false)
37 {
38  if ( fPSet != 0 ) throw cms::Exception("TauolappInterfaceError") << "Attempt to override Tauola an existing ParameterSet\n" << std::endl;
39  fPSet = new ParameterSet(pset);
40 }
43  if ( fIsInitialized ) return; // do init only once
44  if ( fPSet == 0 ) throw cms::Exception("TauolappInterfaceError") << "Attempt to initialize Tauola with an empty ParameterSet\n" << std::endl;
45  fIsInitialized = true;
46  es.getData( fPDGTable ) ;
47  Tauolapp::Tauola::setDecayingParticle(15);
48  // --> ??? Tauola::setRadiation(false);
49  // polarization switch
50  //
51  // fPolarization = fPSet->getParameter<bool>("UseTauolaPolarization") ? 1 : 0 ;
52  fPolarization = fPSet->getParameter<bool>("UseTauolaPolarization");
53  // read tau decay mode switches
54  //
55  ParameterSet cards = fPSet->getParameter< ParameterSet >("InputCards");
56  fMDTAU = cards.getParameter< int >( "mdtau" );
57  if ( fMDTAU == 0 || fMDTAU == 1 )
58  {
59  Tauolapp::Tauola::setSameParticleDecayMode( cards.getParameter< int >( "pjak1" ) ) ;
60  Tauolapp::Tauola::setOppositeParticleDecayMode( cards.getParameter< int >( "pjak2" ) ) ;
61  }
62  Tauolapp::Tauola::spin_correlation.setAll(fPolarization);
63  // some more options, copied over from an example
64  // Default values
65  //Tauola::setEtaK0sPi(0,0,0); // switches to decay eta K0_S and pi0 1/0 on/off.
66  const HepPDT::ParticleData* PData = fPDGTable->particle(HepPDT::ParticleID( abs(Tauolapp::Tauola::getDecayingParticle()) )) ;
67  double lifetime = PData->lifetime().value();
68  Tauolapp::Tauola::setTauLifetime( lifetime );
69  //std::cout << "Setting lifetime: ctau=" << lifetime << "m or tau=" << lifetime/(299792458.0*1000.0) << "s" << std::endl;
70  fPDGs.push_back( Tauolapp::Tauola::getDecayingParticle() );
71  Tauolapp::Tauola::setRandomGenerator(gen::TauolappInterface::flat);
73  Tauolapp::Tauola::spin_correlation.setAll(fPolarization);// Tauola switches this on during Tauola::initialise(); so we add this here to keep it on/off
74  if (fPSet->exists("parameterSets")){
75  std::vector<std::string> par = fPSet->getParameter< std::vector<std::string> >("parameterSets");
76  for (unsigned int ip=0; ip<par.size(); ++ip ){
77  std::string curSet = par[ip];
78  if(curSet=="setNewCurrents") Tauolapp::Tauola::setNewCurrents(fPSet->getParameter<int>(curSet));
79  if(curSet=="spinCorrelationSetAll") Tauolapp::Tauola::spin_correlation.setAll(fPSet->getParameter<bool>(curSet));
80  if(curSet=="spinCorrelationGAMMA") Tauolapp::Tauola::spin_correlation.GAMMA=fPSet->getParameter<bool>(curSet);
81  if(curSet=="spinCorrelationZ0") Tauolapp::Tauola::spin_correlation.Z0=fPSet->getParameter<bool>(curSet);
82  if(curSet=="spinCorrelationHIGGS") Tauolapp::Tauola::spin_correlation.HIGGS=fPSet->getParameter<bool>(curSet);
83  if(curSet=="spinCorrelationHIGGSH") Tauolapp::Tauola::spin_correlation.HIGGS_H=fPSet->getParameter<bool>(curSet);
84  if(curSet=="spinCorrelationHIGGSA") Tauolapp::Tauola::spin_correlation.HIGGS_A=fPSet->getParameter<bool>(curSet);
85  if(curSet=="spinCorrelationHIGGSPLUS") Tauolapp::Tauola::spin_correlation.HIGGS_PLUS=fPSet->getParameter<bool>(curSet);
86  if(curSet=="spinCorrelationHIGGSMINUS") Tauolapp::Tauola::spin_correlation.HIGGS_MINUS=fPSet->getParameter<bool>(curSet);
87  if(curSet=="spinCorrelationWPLUS") Tauolapp::Tauola::spin_correlation.W_PLUS=fPSet->getParameter<bool>(curSet);
88  if(curSet=="spinCorrelationWMINUS") Tauolapp::Tauola::spin_correlation.W_MINUS=fPSet->getParameter<bool>(curSet);
89  if(curSet=="setHiggsScalarPseudoscalarPDG") Tauolapp::Tauola::setHiggsScalarPseudoscalarPDG(fPSet->getParameter<int>(curSet));
90  if(curSet=="setHiggsScalarPseudoscalarMixingAngle") Tauolapp::Tauola::setHiggsScalarPseudoscalarMixingAngle(fPSet->getParameter<double>(curSet));
91  if(curSet=="setRadiation") Tauolapp::Tauola::setRadiation(fPSet->getParameter<bool>(curSet));
92  if(curSet=="setRadiationCutOff") Tauolapp::Tauola::setRadiationCutOff(fPSet->getParameter<double>(curSet));
93  if(curSet=="setEtaK0sPi"){
94  std::vector<int> vpar = fPSet->getParameter<std::vector<int> >(curSet);
95  if(vpar.size()==3) Tauolapp::Tauola::setEtaK0sPi(vpar[0],vpar[1],vpar[2]);
96  else {std::cout << "WARNING invalid size for setEtaK0sPi: " << vpar.size() << " Require 3 elements " << std::endl;}
97  }
98  if(curSet=="setTaukle"){
99  std::vector<double> vpar = fPSet->getParameter<std::vector<double> >(curSet);
100  if(vpar.size()==4) Tauolapp::Tauola::setTaukle(vpar[0], vpar[1], vpar[2], vpar[3]);
101  else {std::cout << "WARNING invalid size for setTaukle: " << vpar.size() << " Require 4 elements " << std::endl;}
102  }
103  if(curSet=="setTauBr"){
105  std::vector<int> vJAK = cfg.getParameter<std::vector<int> >("JAK");
106  std::vector<double> vBR = cfg.getParameter<std::vector<double> >("BR");
107  if(vJAK.size() == vBR.size()){
108  for(unsigned int i=0;i<vJAK.size();i++) Tauolapp::Tauola::setTauBr(vJAK[i],vBR[i]);
109  }
110  else {std::cout << "WARNING invalid size for setTauBr - JAK: " << vJAK.size() << " BR: " << vBR.size() << std::endl;}
111  }
112  }
113  }
114  // override decay modes if needs be
115  //
116  // we have to do it AFTER init because otherwises branching ratios are NOT filled in
117  //
118  if ( fMDTAU != 0 && fMDTAU != 1 )
119  {
120  decodeMDTAU( fMDTAU );
121  }
122  Tauolapp::Log::LogWarning(false);
123  return;
124 }
126 {
127  if ( !fRandomEngine ) {
128  throw cms::Exception("LogicError")
129  << "TauolaInterface::flat: Attempt to generate random number when engine pointer is null\n"
130  << "This might mean that the code was modified to generate a random number outside the\n"
131  << "event and beginLuminosityBlock methods, which is not allowed.\n";
132  }
133  return fRandomEngine->flat();
134 }
135 HepMC::GenEvent* TauolappInterface::decay( HepMC::GenEvent* evt ){
136  if ( !fIsInitialized ) return evt;
137  Tauolapp::Tauola::setRandomGenerator(gen::TauolappInterface::flat); // rest tauola++ random number incase other modules use tauola++
138  int NPartBefore = evt->particles_size();
139  int NVtxBefore = evt->vertices_size();
140  // what do we do if Hep::GenEvent size is larger than 10K ???
141  // Tauola (& Photos, BTW) can only handle up to 10K via HEPEVT,
142  // and in case of CMS, it's only up to 4K !!!
143  //
144  // if ( NPartBefore > 10000 ) return evt;
145  //
146  // override decay mode if needs be
147  if ( fSelectDecayByEvent )
148  {
150  }
151  //construct tmp TAUOLA event
152  //
153  auto * t_event = new Tauolapp::TauolaHepMCEvent(evt);
154  // another option: if one lets Pythia or another master gen to decay taus,
155  // we have to undecay them first
156  // t_event->undecayTaus();
157  // run Tauola on the tmp event - HepMC::GenEvernt will be MODIFIED !!!
158  //
159  t_event->decayTaus();
160  // delet tmp Tauola event
161  //
162  delete t_event;
163  // do we also need to apply the lifetime and vtx position shift ???
164  // (see TauolappInterface, for example)
165  //
166  // NOTE: the procedure ASSYMES that vertex barcoding is COUNTIUOUS/SEQUENTIAL,
167  // and that the abs(barcode) corresponds to vertex "plain indexing"
168  //
169  for ( int iv=NVtxBefore+1; iv<=evt->vertices_size(); iv++ )
170  {
171  HepMC::GenVertex* GenVtx = evt->barcode_to_vertex(-iv);
172  //
173  // now find decay products with funky barcode, weed out and replace with clones of sensible barcode
174  // we can NOT change the barcode while iterating, because iterators do depend on the barcoding
175  // thus we have to take a 2-step procedure
176  //
177  std::vector<int> BCodes;
178  BCodes.clear();
179  for (HepMC::GenVertex::particle_iterator pitr= GenVtx->particles_begin(HepMC::children);
180  pitr != GenVtx->particles_end(HepMC::children); ++pitr)
181  {
182  if ( (*pitr)->barcode() > 10000 )
183  {
184  BCodes.push_back( (*pitr)->barcode() );
185  }
186  }
187  if ( BCodes.size() > 0 )
188  {
189  for ( size_t ibc=0; ibc<BCodes.size(); ibc++ )
190  {
191  HepMC::GenParticle* p1 = evt->barcode_to_particle( BCodes[ibc] );
192  int nbc = p1->barcode() - 10000 + NPartBefore;
193  p1->suggest_barcode( nbc );
194  }
195  }
196  }
197  return evt;
198 }
200 {
201  return;
202 }
204 {
205  // Note-1:
206  // I have to hack the common block directly because set<...>DecayMode(...)
207  // only changes it in the Tauola++ instance but does NOT passes it over
208  // to the Fortran core - this it does only one, via initialize() stuff...
209  //
210  // So I'll do both ways of settings, just for consistency...
211  // but I probably need to communicate it to the Tauola(++) team...
212  //
213  // Note-2:
214  // originally, the 1xx settings are meant for tau's from hard event,
215  // and the 2xx settings are for any tau in the event record;
216  //
217  // later one, we'll have to take this into account...
218  // but first I'll have to sort out what happens in the 1xx case
219  // to tau's coming outside of hard event (if any in the record)
220  //
221  if ( mdtau == 101 || mdtau == 201 )
222  {
223  // override with electron mode for both tau's
224  //
225  Tauolapp::jaki_.jak1 = 1;
226  Tauolapp::jaki_.jak2 = 1;
227  Tauolapp::Tauola::setSameParticleDecayMode( 1 ) ;
228  Tauolapp::Tauola::setOppositeParticleDecayMode( 1 ) ;
229  return;
230  }
231  if ( mdtau == 102 || mdtau == 202 )
232  {
233  // override with muon mode for both tau's
234  //
235  Tauolapp::jaki_.jak1 = 2;
236  Tauolapp::jaki_.jak2 = 2;
237  Tauolapp::Tauola::setSameParticleDecayMode( 2 ) ;
238  Tauolapp::Tauola::setOppositeParticleDecayMode( 2 ) ;
239  return;
240  }
241  if ( mdtau == 111 || mdtau == 211 )
242  {
243  // override with electron mode for 1st tau
244  // and any mode for 2nd tau
245  //
246  Tauolapp::jaki_.jak1 = 1;
247  Tauolapp::jaki_.jak2 = 0;
248  Tauolapp::Tauola::setSameParticleDecayMode( 1 ) ;
249  Tauolapp::Tauola::setOppositeParticleDecayMode( 0 ) ;
250  return;
251  }
252  if ( mdtau == 112 || mdtau == 212 )
253  {
254  // override with muon mode for the 1st tau
255  // and any mode for the 2nd tau
256  //
257  Tauolapp::jaki_.jak1 = 2;
258  Tauolapp::jaki_.jak2 = 0;
259  Tauolapp::Tauola::setSameParticleDecayMode( 2 ) ;
260  Tauolapp::Tauola::setOppositeParticleDecayMode( 0 ) ;
261  return;
262  }
263  if ( mdtau == 121 || mdtau == 221 )
264  {
265  // override with any mode for the 1st tau
266  // and electron mode for the 2nd tau
267  //
268  Tauolapp::jaki_.jak1 = 0;
269  Tauolapp::jaki_.jak2 = 1;
270  Tauolapp::Tauola::setSameParticleDecayMode( 0 ) ;
271  Tauolapp::Tauola::setOppositeParticleDecayMode( 1 ) ;
272  return;
273  }
274  if ( mdtau == 122 || mdtau == 222 )
275  {
276  // override with any mode for the 1st tau
277  // and muon mode for the 2nd tau
278  //
279  Tauolapp::jaki_.jak1 = 0;
280  Tauolapp::jaki_.jak2 = 2;
281  Tauolapp::Tauola::setSameParticleDecayMode( 0 ) ;
282  Tauolapp::Tauola::setOppositeParticleDecayMode( 2 ) ;
283  return;
284  }
285  if ( mdtau == 140 || mdtau == 240 )
286  {
287  // override with pi+/- nutau mode for both tau's
288  //
289  Tauolapp::jaki_.jak1 = 3;
290  Tauolapp::jaki_.jak2 = 3;
291  Tauolapp::Tauola::setSameParticleDecayMode( 3 ) ;
292  Tauolapp::Tauola::setOppositeParticleDecayMode( 3 ) ;
293  return;
294  }
295  if ( mdtau == 141 || mdtau == 241 )
296  {
297  // override with pi+/- nutau mode for the 1st tau
298  // and any mode for the 2nd tau
299  //
300  Tauolapp::jaki_.jak1 = 3;
301  Tauolapp::jaki_.jak2 = 0;
302  Tauolapp::Tauola::setSameParticleDecayMode( 3 ) ;
303  Tauolapp::Tauola::setOppositeParticleDecayMode( 0 ) ;
304  return;
305  }
306  if ( mdtau == 142 || mdtau == 242 )
307  {
308  // override with any mode for the 1st tau
309  // and pi+/- nutau mode for 2nd tau
310  //
311  Tauolapp::jaki_.jak1 = 0;
312  Tauolapp::jaki_.jak2 = 3;
313  Tauolapp::Tauola::setSameParticleDecayMode( 0 ) ;
314  Tauolapp::Tauola::setOppositeParticleDecayMode( 3 ) ;
315  return;
316  }
317  // OK, we come here for semi-inclusive modes
318  //
319  // First of all, leptons and hadron modes sums
320  //
321  // re-scale branching ratios, just in case...
322  //
323  double sumBra = 0;
324  // the number of decay modes is hardcoded at 22 because that's what it is right now in Tauola
325  // in the future, perhaps an asscess method would be useful - communicate to Tauola team...
326  //
327  for ( int i=0; i<22; i++ )
328  {
329  sumBra += Tauolapp::taubra_.gamprt[i];
330  }
331  if ( sumBra == 0. ) return ; // perhaps need to throw ?
332  for ( int i=0; i<22; i++ )
333  {
334  double newBra = Tauolapp::taubra_.gamprt[i] / sumBra;
335  Tauolapp::Tauola::setTauBr( i+1, newBra );
336  }
337  sumBra = 1.0;
338  double sumLeptonBra = Tauolapp::taubra_.gamprt[0] + Tauolapp::taubra_.gamprt[1];
339  double sumHadronBra = sumBra - sumLeptonBra;
340  for ( int i=0; i<2; i++ )
341  {
342  fLeptonModes.push_back( i+1 );
343  fScaledLeptonBrRatios.push_back( (Tauolapp::taubra_.gamprt[i]/sumLeptonBra) );
344  }
345  for ( int i=2; i<22; i++ )
346  {
347  fHadronModes.push_back( i+1 );
348  fScaledHadronBrRatios.push_back( (Tauolapp::taubra_.gamprt[i]/sumHadronBra) );
349  }
350  fSelectDecayByEvent = true;
351  return;
352 }
354 {
355  if ( fMDTAU == 100 || fMDTAU == 200 )
356  {
357  int mode = selectLeptonic();
358  Tauolapp::jaki_.jak1 = mode;
359  Tauolapp::Tauola::setSameParticleDecayMode( mode );
360  mode = selectLeptonic();
361  Tauolapp::jaki_.jak2 = mode;
362  Tauolapp::Tauola::setOppositeParticleDecayMode( mode );
363  return ;
364  }
365  int modeL = selectLeptonic();
366  int modeH = selectHadronic();
367  if ( fMDTAU == 110 || fMDTAU == 210 )
368  {
369  Tauolapp::jaki_.jak1 = modeL;
370  Tauolapp::jaki_.jak2 = 0;
371  Tauolapp::Tauola::setSameParticleDecayMode( modeL );
372  Tauolapp::Tauola::setOppositeParticleDecayMode( 0 );
373  return ;
374  }
375  if ( fMDTAU == 120 || fMDTAU == 22 )
376  {
377  Tauolapp::jaki_.jak1 = 0;
378  Tauolapp::jaki_.jak2 = modeL;
379  Tauolapp::Tauola::setSameParticleDecayMode( 0 );
380  Tauolapp::Tauola::setOppositeParticleDecayMode( modeL );
381  return;
382  }
383  if ( fMDTAU == 114 || fMDTAU == 214 )
384  {
385  Tauolapp::jaki_.jak1 = modeL;
386  Tauolapp::jaki_.jak2 = modeH;
387  Tauolapp::Tauola::setSameParticleDecayMode( modeL );
388  Tauolapp::Tauola::setOppositeParticleDecayMode( modeH );
389  return;
390  }
391  if ( fMDTAU == 124 || fMDTAU == 224 )
392  {
393  Tauolapp::jaki_.jak1 = modeH;
394  Tauolapp::jaki_.jak2 = modeL;
395  Tauolapp::Tauola::setSameParticleDecayMode( modeH );
396  Tauolapp::Tauola::setOppositeParticleDecayMode( modeL );
397  return;
398  }
399  if ( fMDTAU == 115 || fMDTAU == 215 )
400  {
401  Tauolapp::jaki_.jak1 = 1;
402  Tauolapp::jaki_.jak2 = modeH;
403  Tauolapp::Tauola::setSameParticleDecayMode( 1 );
404  Tauolapp::Tauola::setOppositeParticleDecayMode( modeH );
405  return;
406  }
407  if ( fMDTAU == 125 || fMDTAU == 225 )
408  {
409  Tauolapp::jaki_.jak1 = modeH;
410  Tauolapp::jaki_.jak2 = 1;
411  Tauolapp::Tauola::setSameParticleDecayMode( modeH );
412  Tauolapp::Tauola::setOppositeParticleDecayMode( 1 );
413  return;
414  }
415  if ( fMDTAU == 116 || fMDTAU == 216 )
416  {
417  Tauolapp::jaki_.jak1 = 2;
418  Tauolapp::jaki_.jak2 = modeH;
419  Tauolapp::Tauola::setSameParticleDecayMode( 2 );
420  Tauolapp::Tauola::setOppositeParticleDecayMode( modeH );
421  return;
422  }
423  if ( fMDTAU == 126 || fMDTAU == 226 )
424  {
425  Tauolapp::jaki_.jak1 = modeH;
426  Tauolapp::jaki_.jak2 = 2;
427  Tauolapp::Tauola::setSameParticleDecayMode( modeH );
428  Tauolapp::Tauola::setOppositeParticleDecayMode( 2 );
429  return;
430  }
431  if ( fMDTAU == 130 || fMDTAU == 230 )
432  {
433  Tauolapp::jaki_.jak1 = modeH;
434  Tauolapp::jaki_.jak2 = selectHadronic();
435  Tauolapp::Tauola::setSameParticleDecayMode( modeH );
436  Tauolapp::Tauola::setOppositeParticleDecayMode( Tauolapp::jaki_.jak2 );
437  return;
438  }
439  if ( fMDTAU == 131 || fMDTAU == 231 )
440  {
441  Tauolapp::jaki_.jak1 = modeH;
442  Tauolapp::jaki_.jak2 = 0;
443  Tauolapp::Tauola::setSameParticleDecayMode( modeH );
444  Tauolapp::Tauola::setOppositeParticleDecayMode( 0 );
445  return;
446  }
447  if ( fMDTAU == 132 || fMDTAU == 232 )
448  {
449  Tauolapp::jaki_.jak1 = 0;
450  Tauolapp::jaki_.jak2 = modeH;
451  Tauolapp::Tauola::setSameParticleDecayMode( 0 );
452  Tauolapp::Tauola::setOppositeParticleDecayMode( modeH );
453  return;
454  }
455  // unlikely that we get here on unknown mdtau
456  // - there's a protection earlier
457  // but if we do, just set defaults
458  // probably need to spit a warning...
459  //
460  Tauolapp::Tauola::setSameParticleDecayMode( 0 );
461  Tauolapp::Tauola::setOppositeParticleDecayMode( 0 );
462  return;
463 }
465 {
466  float prob = flat();
467  if ( prob > 0. && prob <= fScaledLeptonBrRatios[0] )
468  {
469  return 1;
470  }
471  else if ( prob > fScaledLeptonBrRatios[1] && prob <=1. )
472  {
473  return 2;
474  }
475  return 0;
476 }
478 {
479  float prob = 0.;
480  int len = 1;
481  ranmar_(&prob,&len);
482  double sumBra = fScaledHadronBrRatios[0];
483  if ( prob > 0. && prob <= sumBra )
484  {
485  return fHadronModes[0];
486  }
487  else
488  {
489  int NN = fScaledHadronBrRatios.size();
490  for ( int i=1; i<NN; i++ )
491  {
492  if ( prob > sumBra && prob <= (sumBra+fScaledHadronBrRatios[i]) )
493  {
494  return fHadronModes[i];
495  }
496  sumBra += fScaledHadronBrRatios[i];
497  }
498  }
499  return 0;
500 }
T getParameter(std::string const &) const
static AlgebraicMatrix initialize()
TauolappInterface(const edm::ParameterSet &)
int i
Definition: DBlmapReader.cc:9
edm::ParameterSet * fPSet
struct @415 taubra_
std::vector< double > fScaledHadronBrRatios
bool exists(std::string const &parameterName) const
checks if a parameter exists
void rmarin_(int *, int *, int *)
void getData(T &iHolder) const
Definition: EventSetup.h:67
float gamprt[30]
Definition: TauolaWrapper.h:78
int jak2
Definition: TauolaWrapper.h:67
std::vector< int > fPDGs
std::vector< int > fLeptonModes
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void ranmar_(float *rvec, int *lenv)
HepPDT::ParticleData ParticleData
void init(const edm::EventSetup &)
HepMC::GenEvent * decay(HepMC::GenEvent *)
std::vector< double > fScaledLeptonBrRatios
static CLHEP::HepRandomEngine * fRandomEngine
return(e1-e2)*(e1-e2)+dp *dp
std::vector< int > fHadronModes
double p1[4]
Definition: TauolaWrapper.h:89
tuple cout
Definition: gather_cfg.py:121
edm::ESHandle< HepPDT::ParticleDataTable > fPDGTable
volatile std::atomic< bool > shutdown_flag false
int mdtau
Definition: TauolaWrapper.h:59