00001 #include "GeneratorInterface/CommonInterface/interface/TauolaInterface.h"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <stdio.h>
00013 #include <iostream>
00014 #include <cstdlib>
00015 #include <math.h>
00016
00017
00018
00019 #include "HepMC/PythiaWrapper6_2.h"
00020 #include "GeneratorInterface/CommonInterface/interface/TauolaWrapper.h"
00021
00022 using namespace edm;
00023
00024 int TauolaInterface::debug_ = 0;
00025
00026
00027
00028 TauolaInterface::TauolaInterface()
00029 {
00030
00031
00032 version_ = 1;
00033
00034
00035
00036 keypol_ = 1;
00037
00038
00039 }
00040
00041 TauolaInterface::~TauolaInterface()
00042 {}
00043
00044 void TauolaInterface::initialize()
00045 {
00046
00047
00048
00049
00050 if ( ki_taumod_.mdtau <= -1 ) return;
00051
00052
00053 std::cout << "----------------------------------------------" << std::endl;
00054 std::cout << "Disabling tau decays in Pythia" << std::endl;
00055 int pdgCode = 15;
00056 int pythiaCode = call_pycomp(pdgCode);
00057 char parameter[20];
00058 sprintf(parameter, "MDCY(%i,1)=0", pythiaCode);
00059 std::cout << "pythiaCode = " << pythiaCode << std::endl;
00060 std::cout << "strlen(parameter) = " << strlen(parameter) << std::endl;
00061 call_pygive(parameter, strlen(parameter));
00062 std::cout << "----------------------------------------------" << std::endl;
00063
00064
00065 std::cout << "----------------------------------------------" << std::endl;
00066 std::cout << "Initializing Tauola" << std::endl;
00067 int mode = -1;
00068 switch ( version_ ) {
00069 case 0 :
00070 call_tauola(mode, keypol_);
00071 break;
00072 case 1 :
00073 call_taurep(-2);
00074
00075 call_tauola_srs(mode, keypol_);
00076 break;
00077 }
00078 std::cout << "----------------------------------------------" << std::endl;
00079 }
00080
00081 void TauolaInterface::processEvent()
00082 {
00083 if ( debug_ ) {
00084 std::cout << "<TauolaInterface::processEvent>: begin of event processing..." << std::endl;
00085 }
00086
00087
00088 if ( debug_ ) std::cout << "converting PYJETS to HEPEVT common block structure..." << std::endl;
00089 switch ( version_ ) {
00090 case 0 :
00091 call_pyhepc( 1 );
00092 break;
00093 case 1 :
00094 call_pyhepc_t( 1 );
00095 break;
00096 }
00097
00098
00099 if ( debug_ ) std::cout << "determining number of generated particles **before** calling TAUOLA..." << std::endl;
00100 int dummy = -1;
00101 int numGenParticles_beforeTAUOLA = call_ihepdim(dummy);
00102
00103
00104 if ( debug_ ) std::cout << "calling TAUOLA..." << std::endl;
00105 int mode = 0;
00106 switch ( version_ ) {
00107 case 0 :
00108 call_tauola(mode, keypol_);
00109 break;
00110 case 1 :
00111 call_tauola_srs(mode, keypol_);
00112 break;
00113 }
00114
00115
00116 if ( debug_ ) std::cout << "determining number of generated particles **after** calling TAUOLA..." << std::endl;
00117
00118 int numGenParticles_afterTAUOLA = call_ihepdim(dummy);
00119
00120
00121
00122 if ( debug_ ) std::cout << "converting back HEPEVT to PYJETS common block structure..." << std::endl;
00123 switch ( version_ ) {
00124 case 0 :
00125 call_pyhepc( 2 );
00126 break;
00127 case 1 :
00128 call_pyhepc_t( 2 );
00129 break;
00130 }
00131
00132
00133
00134 if ( debug_ ) std::cout << "decaying unstable hadrons produced in tau decay..." << std::endl;
00135
00136 int numGenParticles_afterUnstableHadronDecays = decayUnstableHadrons(numGenParticles_beforeTAUOLA, numGenParticles_afterTAUOLA);
00137
00138
00139
00140
00141 if ( debug_ ) std::cout << "setting decay vertex of tau lepton and production vertices of decay products..." << std::endl;
00142
00143 setDecayVertex(numGenParticles_beforeTAUOLA, numGenParticles_afterUnstableHadronDecays);
00144
00145
00146
00147
00148
00149
00150
00151
00152 if ( debug_ > 1 ) {
00153 int nFirst = numGenParticles_beforeTAUOLA;
00154 int nLast = pyjets.n;
00155 for ( int iParticle = (nFirst + 1); iParticle <= nLast; ++iParticle ) {
00156 std::cout << "genParticle #" << iParticle << std::endl;
00157 std::cout << " type = "
00158 << pyjets.k[1][iParticle - 1] << std::endl;
00159 std::cout << " p(Px,Py,Pz,E) = {"
00160 << pyjets.p[0][iParticle - 1] << ","
00161 << pyjets.p[1][iParticle - 1] << ","
00162 << pyjets.p[2][iParticle - 1] << ","
00163 << pyjets.p[3][iParticle - 1] << "}" << std::endl;
00164 std::cout << " v(x,y,z) = {"
00165 << pyjets.v[0][iParticle - 1] << ","
00166 << pyjets.v[1][iParticle - 1] << ","
00167 << pyjets.v[2][iParticle - 1] << "}" << std::endl;
00168 }
00169 }
00170
00171 if ( debug_ ) {
00172 std::cout << "<TauolaInterface::processEvent>: end of event processing..." << std::endl;
00173 }
00174 }
00175
00176 void TauolaInterface::print()
00177 {
00178
00179
00180 int mode = 1;
00181 switch ( version_ ) {
00182 case 0 :
00183 call_tauola(mode, keypol_);
00184 break;
00185 case 1 :
00186 call_tauola_srs(mode, keypol_);
00187 break;
00188 }
00189 }
00190
00191 void TauolaInterface::setDecayVertex(int numGenParticles_beforeTAUOLA, int numGenParticles_afterTAUOLA)
00192 {
00193
00194
00195
00196
00197
00198 int numDocumentationLines = pypars.msti[3];
00199
00200 if ( debug_ > 1 ) {
00201 std::cout << "numGenParticles_beforeTAUOLA = " << numGenParticles_beforeTAUOLA << std::endl;
00202 std::cout << "numGenParticles_afterTAUOLA = " << numGenParticles_afterTAUOLA << std::endl;
00203 std::cout << "numDocumentationLines = " << numDocumentationLines << std::endl;
00204 }
00205
00206
00207
00208 if ( numGenParticles_beforeTAUOLA <= numDocumentationLines ) {
00209 std::cerr << "Error in <TauolaInterface::setDecayVertex>: index of first particle in PYJETS common block less than number of documentation lines !" << std::endl;
00210 return;
00211 }
00212
00213
00214
00215 double particleDecayVertex[4][maxNumberParticles];
00216 for ( int i = 0; i < 4; ++i ) {
00217 for ( int iParticle = 1; iParticle <= maxNumberParticles; ++iParticle ) {
00218 particleDecayVertex[i][iParticle] = 0.;
00219 }
00220 }
00221
00222 int nFirst = numDocumentationLines + 1;
00223 int nLast = numGenParticles_afterTAUOLA;
00224
00225 for ( int iParticle = nFirst; iParticle <= nLast; ++iParticle ) {
00226 int particleStatus = pyjets.k[0][iParticle - 1];
00227 if ( debug_ > 1 ) {
00228 std::cout << "genParticle[" << iParticle << "] status = " << particleStatus << std::endl;
00229 }
00230
00231
00232
00233
00234
00235 if ( particleStatus == 1 ||
00236 particleStatus == 11 ) {
00237 int particleType = abs(pyjets.k[1][iParticle - 1]);
00238 int particleType_PYTHIA = call_pycomp(particleType);
00239
00240 if ( debug_ > 1 ) {
00241 std::cout << "genParticle[" << iParticle << "] type = " << particleType << std::endl;
00242 }
00243
00244
00245 if ( particleType != 15 && iParticle <= numGenParticles_beforeTAUOLA ) continue;
00246
00247
00248
00249
00250 for ( int i = 0; i < 4; ++i ) {
00251 if ( particleType != 15 ) {
00252 int indexParticleMother_i = pyjets.k[2][iParticle - 1];
00253
00254 if ( indexParticleMother_i > iParticle ) {
00255 std::cerr << "Error in <TauolaInterface::setDecayVertex>: daughter found before mother particle in PYJETS common block !" << std::endl;
00256 }
00257
00258 if ( debug_ > 1 ) {
00259 if ( i == 0 ) std::cout << " --> setting production vertex for genParticle[" << iParticle << "]"
00260 << " to decay vertex of genParticle[" << indexParticleMother_i << "]" << std::endl;
00261 }
00262
00263 double particleProductionVertex_i = particleDecayVertex[i][indexParticleMother_i - 1];
00264 pyjets.v[i][iParticle - 1] = particleProductionVertex_i;
00265 }
00266 }
00267
00268
00269
00270
00271
00272 if ( particleStatus == 11 ) {
00273
00274
00275
00276
00277 double lifetime = pydat2.pmas[3][particleType_PYTHIA - 1];
00278 double u = call_pyr(0);
00279 double ct = -lifetime*log(u);
00280 pyjets.v[4][iParticle - 1] = ct;
00281
00282 if ( debug_ > 1 ) {
00283 std::cout << "lifetime = " << lifetime << std::endl;
00284 std::cout << "u = " << u << std::endl;
00285 std::cout << "ct = " << ct << std::endl;
00286 }
00287
00288
00289
00290
00291
00292
00293
00294
00295 for ( int i = 0; i < 4; ++i ) {
00296 double particleProductionVertex_i = pyjets.v[i][iParticle - 1];
00297
00298
00299
00300
00301
00302
00303
00304 double particleMomentum_i = pyjets.p[i][iParticle - 1];
00305 double particleEnergy = pyjets.p[3][iParticle - 1];
00306 double particleMass = pyjets.p[4][iParticle - 1];
00307 if ( particleEnergy >= particleMass && particleMass > 0. ) {
00308 double particleMomentum = sqrt(particleEnergy*particleEnergy - particleMass*particleMass);
00309
00310 double particleDecayVertex_i = particleProductionVertex_i + ct*(particleMomentum_i/particleMomentum)*(particleEnergy/particleMass);
00311
00312 if ( debug_ > 1 ) {
00313 if ( i == 0 ) {
00314 std::cout << "particleEnergy = " << particleEnergy << std::endl;
00315 std::cout << "particleMass = " << particleMass << std::endl;
00316 std::cout << "particleMomentum = " << particleMomentum << std::endl;
00317 }
00318 std::cout << "particleMomentum_" << i << " = " << particleMomentum_i << std::endl;
00319 if ( i == 0 ) std::cout << " --> setting decay vertex of genParticle[" << iParticle << "]" << std::endl;
00320 std::cout << "particleDecayVertex[" << i << "] = " << particleDecayVertex_i << std::endl;
00321 }
00322
00323 particleDecayVertex[i][iParticle - 1] = particleDecayVertex_i;
00324 } else {
00325 if ( particleMass == 0 )
00326 std::cerr << "Error in <TauolaInterface::setDecayVertex>: mass of unstable particle cannot be zero !" << std::endl;
00327 else
00328 std::cerr << "Error in <TauolaInterface::setDecayVertex>: energy of tau lepton cannot be smaller than its mass !" << std::endl;
00329 continue;
00330 }
00331 }
00332 }
00333 }
00334 }
00335 }
00336
00337 int TauolaInterface::decayUnstableHadrons(int numGenParticles_beforeTAUOLA, int numGenParticles_afterTAUOLA)
00338 {
00339
00340
00341
00342
00343
00344
00345
00346 int nFirst = numGenParticles_beforeTAUOLA + 1;
00347 int nLast = numGenParticles_afterTAUOLA;
00348 while ( nLast > nFirst && nLast < maxNumberParticles ) {
00349 if ( debug_ > 1 ) {
00350 std::cout << "before calling PYDECY:" << std::endl;
00351 std::cout << " nFirst = " << nFirst << std::endl;
00352 std::cout << " nLast = " << nLast << std::endl;
00353 }
00354
00355 for ( int iParticle = nFirst; iParticle <= nLast; ++iParticle ) {
00356 int particleStatus = pyjets.k[0][iParticle - 1];
00357 if ( debug_ > 1 ) {
00358 std::cout << "genParticle[" << iParticle << "] status = " << particleStatus << std::endl;
00359 }
00360
00361
00362
00363 if ( particleStatus > 0 &&
00364 particleStatus < 10 ) {
00365 int particleType = abs(pyjets.k[1][iParticle - 1]);
00366
00367 if ( debug_ > 1 ) {
00368 std::cout << "genParticle[" << iParticle << "] type = " << particleType << std::endl;
00369 }
00370
00371 if ( particleType >= 100 ) {
00372 if ( particleType != 211 &&
00373 particleType != 321 &&
00374 particleType != 130 &&
00375 particleType != 310 ) {
00376 if ( debug_ > 1 ) std::cout << "calling PYDECY for genParticle[" << iParticle << "]" << std::endl;
00377 call_pydecy(iParticle);
00378 }
00379 }
00380 }
00381 }
00382
00383 nFirst = nLast + 1;
00384 nLast = pyjets.n;
00385
00386 if ( debug_ > 1 ) {
00387 std::cout << "after calling PYDECY:" << std::endl;
00388 std::cout << " nFirst = " << nFirst << std::endl;
00389 std::cout << " nLast = " << nLast << std::endl;
00390 }
00391
00392
00393
00394 for ( int iParticle = nFirst; iParticle <= nLast; ++iParticle ) {
00395 int particleStatus = pyjets.k[0][iParticle - 1];
00396 int particleType = abs(pyjets.k[1][iParticle - 1]);
00397 int particleDaughters = pyjets.k[3][iParticle - 1];
00398 if ( particleStatus == 4 &&
00399 particleType >= 100 &&
00400 particleDaughters == 0 ) {
00401 if ( debug_ > 1 ) std::cout << "setting status = 1 for genParticle[" << iParticle << "]" << std::endl;
00402 pyjets.k[0][iParticle - 1] = 1;
00403 }
00404 }
00405 }
00406
00407
00408
00409 return nLast;
00410 }