CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
TauolaInterface.cc
Go to the documentation of this file.
1 /* for old tauola27 */
2 #include <iostream>
3 
5 
10 #include "HepMC/GenEvent.h"
11 #include "HepMC/IO_HEPEVT.h"
12 #include "HepMC/HEPEVT_Wrapper.h"
13 
15 
16 namespace TauolaInterfaceVar {
17  CLHEP::HepRandomEngine* decayRandomEngine;
18 }
19 
20 
21 using namespace gen;
22 using namespace edm;
23 using namespace std;
24 
25 extern "C" {
26 
27  void ranmar_( float *rvec, int *lenv )
28  {
29 
30  for(int i = 0; i < *lenv; i++)
31  *rvec++ = TauolaInterfaceVar::decayRandomEngine->flat();
32 
33  return;
34 
35  }
36 
37  void rmarin_( int*, int*, int* )
38  {
39 
40  return;
41 
42  }
43 
44 }
45 
46 extern "C"{
47 
48  double phoran_(int *idummy)
49  {
51  }
52  extern struct {
53  // bool qedrad[NMXHEP];
54  bool qedrad[4000]; // hardcoded for now...
55  } phoqed_;
56 
57 }
58 
59 
60 //
61 // General Note: While there're no explicit calls or otherwise "links" to Pythia6 anywhere,
62 // we're using Pythia6Service here because we run pretauola rather than "core" tauola;
63 // pretauola is an extension on top of tauola, which is tied to Pythia6 via several routines;
64 // most heavily use one is PYR - we can't avoid it (other Pythia6-tied routines we avoid)
65 //
66 
68  : fIsInitialized(false)
69 {
71 
72  fPolarization = pset.getParameter<bool>("UseTauolaPolarization") ? 1 : 0 ;
73 
74  // set Tauola defaults
75  //
76  ki_taumod_.pjak1 = -1;
77  ki_taumod_.pjak2 = -1;
78  ki_taumod_.mdtau = -1;
79 
80  // read tau decay mode switches
81  //
82  ParameterSet cards = pset.getParameter< ParameterSet >("InputCards");
83  ki_taumod_.pjak1 = cards.getParameter< int >( "pjak1" );
84  ki_taumod_.pjak2 = cards.getParameter< int >( "pjak2" );
85  ki_taumod_.mdtau = cards.getParameter< int >( "mdtau" );
86 }
87 
89 {
90  delete fPy6Service;
91 }
92 
95 }
96 
97 
99 {
100  if ( fIsInitialized ) return; // do init only once
101 
102  if ( ki_taumod_.mdtau <= -1 ) // actually, need to throw exception !
103  return ;
104 
105  fPDGs.push_back( 15 ) ;
106  es.getData( fPDGTable ) ;
107 
108  cout << "----------------------------------------------" << endl;
109  cout << "Initializing Tauola" << endl;
110  if ( fPolarization == 0 )
111  {
112  cout << "Tauola: Polarization disabled" << endl;
113  }
114  else if ( fPolarization == 1 )
115  {
116  cout << "Tauola: Polarization enabled" << endl;
117  }
118 
119 // FIXME !!!
120 // This is a temporary hack - we're re-using master generator's seed to init RANMAR
121 // FIXME !!!
122 // This is now off because ranmar has been overriden (see code above) to use pyr_(...)
123 // - this way we're using guaranteed initialized rndm generator... BUT !!! in the long
124 // run we may want a separate random stream for tauola...
125 
126 // Service<RandomNumberGenerator> rng;
127 // int seed = rng->mySeed() ;
128 // int ntot=0, ntot2=0;
129 // rmarin_( &seed, &ntot, &ntot2 );
130 
131  int mode = -2;
132  taurep_( &mode ) ;
133  mode = -1;
134  // tauola_( &mode, &fPolarization );
135  // tauola_srs_( &mode, &fPolarization );
136  //
137  // We're using the call(...) method here because it'll make sure that Py6
138  // is initialized, and that's done only once, and will grab exatly that instance
139  //
141 
142  fIsInitialized = true;
143  return;
144 }
145 
146 HepMC::GenEvent* TauolaInterface::decay( HepMC::GenEvent* evt )
147 {
148  // event record convertor
149  //
150  HepMC::IO_HEPEVT conv;
151 
152  if ( !fIsInitialized ) return conv.read_next_event();
153 
154  // We are using random numbers, we are fetched through Pythia6Service
155  // (through ranmar_ below) -> so grab the instance during decay()
156 
157  Pythia6Service::InstanceWrapper pythia6InstanceGuard( fPy6Service );
158 
159  // fill up HEPEVT common block
160  //
161  // IDEALLY, this should be the way to go
162  // BUT !!! this utility fills it up in the "reshuffled" order,
163  // and later on Tauola chocks on it
164  //
165  // Needs to be sorted out, eith in HepMC, or in Tauola, or both !!!
166  //
167  // At present, this thing blindly relies on the assumption that
168  // HEPEVT is always there - which wont be the case with Py8 or Hwg++
169  //
170  //HepMC::IO_HEPEVT conv;
171  //conv.write_event( evt ) ;
172 
173  int numPartBeforeTauola = HepMC::HEPEVT_Wrapper::number_entries();
174  // HepMC::HEPEVT_Wrapper::print_hepevt();
175 
176  int mode = 0;
177  // tauola_( &mode, &fPolarization );
179 
180  int numPartAfterTauola = HepMC::HEPEVT_Wrapper::number_entries();
181  // HepMC::HEPEVT_Wrapper::print_hepevt();
182 
183  // before we do the conversion, we need to deal with decay vertexes
184  // since Tauola knows nothing about lifetimes, all decay vertexes are set to 0.
185  // nees to set them properly, knowing lifetime !
186  // here we do it on HEPEVT record, also for consistency, although it's probably
187  // even easier to deal with HepMC::GenEvent record
188 
189  // find 1st "non-doc" tau
190  //
191  bool foundTau = false;
192  for ( int ip=1; ip<=numPartAfterTauola; ip++ )
193  {
194  if ( std::abs( HepMC::HEPEVT_Wrapper::id( ip ) ) == 15
195  && HepMC::HEPEVT_Wrapper::status( ip ) != 3 )
196  {
197  foundTau = true;
198  break;
199  }
200  }
201 
202  if ( !foundTau )
203  {
204  // no tau found
205  // just give up here
206  //
207  return conv.read_next_event();
208  }
209 
210  std::vector<int> PrntIndx;
211 
212  for ( int ip=numPartAfterTauola; ip>numPartBeforeTauola; ip-- ) // Fortran indexing !
213  {
214 
215  // first of all, find out how many generations in decay chain
216  //
217  PrntIndx.clear();
218  int Prnt = HepMC::HEPEVT_Wrapper::first_parent(ip);
219  ip -= (HepMC::HEPEVT_Wrapper::number_children(Prnt)-1); // such that we don't go the same part again
220  PrntIndx.push_back( Prnt );
221  while ( abs( HepMC::HEPEVT_Wrapper::id(Prnt) ) != 15 ) // shortcut; need to loop over fPDGs...
222  {
223  int Prnt1 = HepMC::HEPEVT_Wrapper::first_parent( Prnt );
224  Prnt = Prnt1;
225  // such that the tau always appear at the start of the list
226  PrntIndx.insert( PrntIndx.begin(), Prnt );
227  ip -= HepMC::HEPEVT_Wrapper::number_children(Prnt); // such that we don't go the same part again
228  }
229  for ( size_t iprt=0; iprt<PrntIndx.size(); iprt++ )
230  {
231  int Indx = PrntIndx[iprt];
232  int PartID = HepMC::HEPEVT_Wrapper::id( Indx );
233  const HepPDT::ParticleData*
234  PData = fPDGTable->particle(HepPDT::ParticleID(abs(PartID))) ;
235  //
236  // prob = exp(-t/lifetime) ==> t = -lifetime * log(prob)
237  //
238  float prob = 0.;
239  int length=1;
240  ranmar_(&prob,&length);
241  double lifetime = PData->lifetime().value();
242  //
243  // in case of Py6, this would be copied into V(5,i)
244  // for HEPEVT, need to check...
245  //
246  double ct = -lifetime * std::log(prob);
247  //
248  double ee = HepMC::HEPEVT_Wrapper::e( Indx );
249  double px = HepMC::HEPEVT_Wrapper::px( Indx );
250  double py = HepMC::HEPEVT_Wrapper::py( Indx );
251  double pz = HepMC::HEPEVT_Wrapper::pz( Indx );
252  // double pp = std::sqrt( px*px + py*py + pz*pz );
253  double mass = HepMC::HEPEVT_Wrapper::m( Indx );
254  //
255  // this is in py6 terms:
256  // VDCY(J)=V(IP,J)+V(IP,5)*P(IP,J)/P(IP,5)
257  //
258  double VxDec = HepMC::HEPEVT_Wrapper::x( Indx );
259  VxDec += ct * (px/mass);
260  double VyDec = HepMC::HEPEVT_Wrapper::y( Indx );
261  VyDec += ct * (py/mass);
262  double VzDec = HepMC::HEPEVT_Wrapper::z( Indx );
263  VzDec += ct * (pz/mass);
264  double VtDec = HepMC::HEPEVT_Wrapper::t( Indx );
265  VtDec += ct * (ee/mass);
266  for ( int idau=HepMC::HEPEVT_Wrapper::first_child( Indx );
267  idau<=HepMC::HEPEVT_Wrapper::last_child( Indx ); idau++ )
268  {
269  HepMC::HEPEVT_Wrapper::set_position( idau, VxDec, VyDec, VzDec, VtDec );
270  }
271  }
272  }
273  return conv.read_next_event();
274 
275 }
276 
278 {
279  int mode = 1;
280  // tauola_( &mode, &fPolarization ) ;
281  // tauola_srs_( &mode, &fPolarization ) ;
283  return;
284 }
285 
286 
287 
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
void call(void(&fn)())
CLHEP::HepRandomEngine * decayRandomEngine
HepMC::GenEvent * decay(HepMC::GenEvent *)
static HepMC::IO_HEPEVT conv
double phoran_(int *idummy)
TauolaInterface(const edm::ParameterSet &)
struct @338 ki_taumod_
#define abs(x)
Definition: mlp_lapack.h:159
void rmarin_(int *, int *, int *)
void SetDecayRandomEngine(CLHEP::HepRandomEngine *decayRandomEngine)
double double double z
void getData(T &iHolder) const
Definition: EventSetup.h:67
void tauola_srs_(int *, int *)
void taurep_(int *)
edm::ESHandle< HepPDT::ParticleDataTable > fPDGTable
void ranmar_(float *rvec, int *lenv)
HepPDT::ParticleData ParticleData
CLHEP::HepRandomEngine * decayRandomEngine
Pythia6Service * fPy6Service
tuple mass
Definition: scaleCards.py:27
tuple cout
Definition: gather_cfg.py:121
void init(const edm::EventSetup &)
Definition: DDAxes.h:10
bool qedrad[4000]
tuple status
Definition: ntuplemaker.py:245
struct @250 phoqed_