CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/src/TauAnalysis/MCEmbeddingTools/src/ParticleReplacerParticleGun.cc

Go to the documentation of this file.
00001 #include "TauAnalysis/MCEmbeddingTools/interface/ParticleReplacerParticleGun.h"
00002 #include "TauAnalysis/MCEmbeddingTools/interface/extraPythia.h"
00003 
00004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00005 
00006 #include "HepMC/PythiaWrapper.h"
00007 #include "HepMC/IO_HEPEVT.h"
00008 
00009 ParticleReplacerParticleGun::ParticleReplacerParticleGun(const edm::ParameterSet& iConfig, bool verbose):
00010   ParticleReplacerBase(iConfig),
00011   tauola_(gen::TauolaInterface::getInstance()),
00012   pythia_(iConfig),
00013   particleOrigin_(iConfig.getParameter<std::string>("particleOrigin")),
00014   forceTauPolarization_(iConfig.getParameter<std::string>("forceTauPolarization")),
00015   forceTauDecay_(iConfig.getParameter<std::string>("forceTauDecay")),
00016   generatorMode_(iConfig.getParameter<std::string>("generatorMode")),
00017   gunParticle_(iConfig.getParameter<int>("gunParticle")),
00018   forceTauPlusHelicity_(iConfig.getParameter<int>("forceTauPlusHelicity")),
00019   forceTauMinusHelicity_(iConfig.getParameter<int>("forceTauMinusHelicity")),
00020   printout_(verbose) {
00021   tauola_->setPSet(iConfig.getParameter<edm::ParameterSet>("ExternalDecays").getParameter<edm::ParameterSet>("Tauola"));
00022   srand(time(NULL)); // Should we use RandomNumberGenerator service?
00023 
00024   if(forceTauPlusHelicity_ != 0) 
00025     edm::LogInfo("MuonReplacement") << "[ParticleReplacer::ParticleReplacer] "
00026                                     << "Forcing tau+ to helicity " << forceTauPlusHelicity_ << std::endl;
00027   if(forceTauMinusHelicity_ != 0)
00028     edm::LogInfo("MuonReplacement") << "[ParticleReplacer::ParticleReplacer] "
00029                                     << "Forcing tau- to helicity " << forceTauMinusHelicity_ << std::endl;
00030   if(forceTauPlusHelicity_ == 0 && forceTauMinusHelicity_ == 0)
00031     edm::LogInfo("MuonReplacement") << "[ParticleReplacer::ParticleReplacer] "
00032                                     << "     Forcing tau helicity as decayed from a " << forceTauPolarization_ << std::endl; 
00033   if(forceTauDecay_ != "" && forceTauDecay_ != "none")
00034     edm::LogInfo("MuonReplacement") << "[ParticleReplacer::ParticleReplacer] "
00035                                     << "Forcing tau decaying into " << forceTauDecay_ << std::endl;
00036 
00037   std::memset(pol1_, 0, 4*sizeof(float));
00038   std::memset(pol2_, 0, 4*sizeof(float));
00039 
00040   if(generatorMode_ != "Tauola")
00041     throw cms::Exception("Configuration") << "Generator mode other than Tauola is not supported" << std::endl;
00042 
00043   throw cms::Exception("UnimplementedFeature") << "ParticleReplacerParticleGun is not usable yet." << std::endl;
00044 }
00045 
00046 ParticleReplacerParticleGun::~ParticleReplacerParticleGun() {}
00047 
00048 void ParticleReplacerParticleGun::beginJob() {
00049   gen::Pythia6Service::InstanceWrapper guard(&pythia_);
00050 
00051   pythia_.setGeneralParams();
00052 
00053   if(abs(gunParticle_) == 15) {
00054     /* FIXME
00055     call_tauola(-1,1);
00056     */
00057   }
00058 }
00059 
00060 void ParticleReplacerParticleGun::endJob() {
00061   if(abs(gunParticle_) == 15) {
00062     /* FIXME
00063        call_tauola(1,1);
00064     */
00065   }
00066 }
00067 
00068 std::auto_ptr<HepMC::GenEvent> ParticleReplacerParticleGun::produce(const reco::MuonCollection& muons, const reco::Vertex *pvtx, const HepMC::GenEvent *genEvt) {
00069   if(genEvt != 0)
00070     throw cms::Exception("UnimplementedFeature") << "ParticleReplacerParticleGun does NOT support merging at HepMC level" << std::endl;
00071 
00072   std::auto_ptr<HepMC::GenEvent> evt(0);
00073   std::vector<HepMC::FourVector> muons_corrected;
00074   muons_corrected.reserve(muons.size());
00075   correctTauMass(muons, muons_corrected);
00076 
00077   gen::Pythia6Service::InstanceWrapper guard(&pythia_);
00078 
00079   for(unsigned int i=0; i<muons_corrected.size(); ++i) {
00080     HepMC::FourVector& muon = muons_corrected[i];
00081     call_py1ent(i+1, gunParticle_*muons[i].charge(), muon.e(), muon.theta(), muon.phi());
00082   }
00083 
00084   // Let's not do a call_pyexec here because it's unnecessary
00085 
00086   if(printout_) {
00087     std::cout << " /////////////////////  After py1ent, before pyhepc /////////////////////" << std::endl;
00088     call_pylist(3);
00089   }
00090 
00091   // Vertex shift
00092   call_pyhepc(1); // pythia -> hepevt
00093 
00094   if(printout_) {
00095     std::cout << " /////////////////////  After pyhepc, before vertex shift /////////////////////" << std::endl;
00096     HepMC::HEPEVT_Wrapper::print_hepevt();
00097   }
00098   // Search for HepMC/HEPEVT_Wrapper.h for the wrapper interface
00099   int nparticles = HepMC::HEPEVT_Wrapper::number_entries();
00100   HepMC::ThreeVector shift(0,0,0); 
00101   if(particleOrigin_ == "primaryVertex") {
00102     if(!pvtx)
00103       throw cms::Exception("LogicError") << "Particle origin set to primaryVertex, but pvtx is null!" << std::endl;
00104 
00105     shift.setX(pvtx->x()*10); // cm -> mm
00106     shift.setY(pvtx->y()*10); // cm -> mm
00107     shift.setZ(pvtx->z()*10); // cm -> mm
00108   }
00109   for(int i=1; i <= nparticles; ++i) {
00110     if(abs(HepMC::HEPEVT_Wrapper::id(i)) != abs(gunParticle_)) {
00111       throw cms::Exception("LogicError") << "Particle in HEPEVT is " << HepMC::HEPEVT_Wrapper::id(i)
00112                                          << " is not the same as gunParticle " << gunParticle_
00113                                          << " for index " << i << std::endl;
00114     }
00115 
00116     if(particleOrigin_ == "muonReferencePoint") {
00117       const reco::Muon& muon = muons[i-1];
00118       shift.setX(muon.vx()*10); // cm -> mm
00119       shift.setY(muon.vy()*10); // cm -> mm
00120       shift.setZ(muon.vz()*10); // cm -> mm
00121     }
00122 
00123     HepMC::HEPEVT_Wrapper::set_position(i,
00124                                         HepMC::HEPEVT_Wrapper::x(i) + shift.x(),
00125                                         HepMC::HEPEVT_Wrapper::y(i) + shift.y(),
00126                                         HepMC::HEPEVT_Wrapper::z(i) + shift.z(),
00127                                         HepMC::HEPEVT_Wrapper::t(i));
00128   }
00129 
00130   if(printout_) {
00131     std::cout << " /////////////////////  After vertex shift, before pyhepc/tauola /////////////////////" << std::endl;
00132     HepMC::HEPEVT_Wrapper::print_hepevt();
00133   }
00134 
00135   if(abs(gunParticle_) == 15){
00136     // Code example from TauolaInterface::processEvent()
00137     /* FIXME
00138     int dummy = -1;
00139     int numGenParticles_beforeTAUOLA = call_ihepdim(dummy);
00140     */
00141 
00142     forceTauolaTauDecays();
00143 
00144     for(unsigned int i=0; i<muons_corrected.size(); ++i) {
00145       tauola_forParticleGun(i+1, gunParticle_*muons[i].charge(), muons_corrected[i]);
00146     }
00147 
00148     if(printout_) {
00149       std::cout << " /////////////////////  After tauola, before pyhepc  /////////////////////" << std::endl;
00150       HepMC::HEPEVT_Wrapper::print_hepevt();
00151     }
00152     call_pyhepc(2); // hepevt->pythia
00153     if(printout_) {
00154       std::cout << " /////////////////////  After pyhepc, before vertex fix  /////////////////////" << std::endl;
00155       call_pylist(3);
00156     }
00157 
00158     // Fix tau decay vertex position
00159     /* FIXME
00160     int numGenParticles_afterTAUOLA = call_ihepdim(dummy);
00161     tauola_.setDecayVertex(numGenParticles_beforeTAUOLA, numGenParticles_afterTAUOLA);
00162     */
00163 
00164     if(printout_) {
00165       /* FIXME
00166       std::cout << "     numGenParticles_beforeTAUOLA " << numGenParticles_beforeTAUOLA << std::endl
00167                 << "     numGenParticles_afterTAUOLA  " << numGenParticles_afterTAUOLA << std::endl;
00168       */
00169       std::cout << " /////////////////////  After vertex fix, before pyexec  /////////////////////" << std::endl;
00170       call_pylist(3);
00171     }
00172   }
00173   else {
00174     call_pyhepc(2); // hepevt->pythia
00175     if(printout_) {
00176       std::cout << " /////////////////////  After pyhepc, before pyexec  /////////////////////" << std::endl;
00177       call_pylist(3);
00178     }
00179   }
00180 
00181   call_pyexec(); // taus: decay pi0's etc; others: decay whatever
00182 
00183   if(printout_) {
00184     std::cout << " /////////////////////  After pyexec, before pyhepc  /////////////////////" << std::endl;
00185     call_pylist(3);
00186   }
00187 
00188   call_pyhepc(1); // pythia -> hepevt
00189 
00190   HepMC::IO_HEPEVT conv;
00191   evt = std::auto_ptr<HepMC::GenEvent>(new HepMC::GenEvent(*conv.read_next_event()));
00192 
00193   if(printout_) {
00194     evt->print();
00195 
00196     std::cout << std::endl << "Vertices: " << std::endl;
00197     for(HepMC::GenEvent::vertex_const_iterator iter = evt->vertices_begin(); iter != evt->vertices_end(); ++iter) {
00198       std::cout << "Vertex " << (*iter)->id() << ", barcode " << (*iter)->barcode() << std::endl;
00199 
00200       HepMC::ThreeVector point = (*iter)->point3d();
00201       std::cout << "  Point (" << point.x() << ", " << point.y() << ", " << point.z() << ")" << std::endl;
00202 
00203       std::cout << "  Incoming particles: ";
00204       for(HepMC::GenVertex::particles_in_const_iterator pi = (*iter)->particles_in_const_begin(); pi != (*iter)->particles_in_const_end(); ++pi) {
00205         std::cout << (*pi)->pdg_id() << " ";
00206       }
00207       std::cout << std::endl;
00208       std::cout << "  Outgoing particles: ";
00209       for(HepMC::GenVertex::particles_out_const_iterator pi = (*iter)->particles_out_const_begin(); pi != (*iter)->particles_out_const_end(); ++pi) {
00210         std::cout << (*pi)->pdg_id() << " ";
00211       }
00212       std::cout << std::endl << std::endl;
00213     }
00214   }
00215 
00216   return evt;
00217 }
00218 
00219 void ParticleReplacerParticleGun::correctTauMass(const reco::MuonCollection& muons, std::vector<HepMC::FourVector>& corrected) {
00220   if(abs(gunParticle_) == 15) {
00221     // Correct energy for tau
00222     for(reco::MuonCollection::const_iterator iMuon = muons.begin(); iMuon != muons.end(); ++iMuon) {
00223       const reco::Muon::LorentzVector& vec = iMuon->p4();
00224 
00225       double E = sqrt(tauMass*tauMass + vec.x()*vec.x() + vec.y()*vec.y() + vec.z()*vec.z());
00226 
00227       corrected.push_back(HepMC::FourVector(vec.x(), vec.y(), vec.z(), E));
00228     }
00229   }
00230   else {
00231     // Just copy the LorentzVector
00232     for(reco::MuonCollection::const_iterator iMuon = muons.begin(); iMuon != muons.end(); ++iMuon) {
00233       corrected.push_back(iMuon->p4());
00234     }
00235   }
00236 }
00237 
00238 void ParticleReplacerParticleGun::forceTauolaTauDecays() {
00239   if(forceTauDecay_ == "" || forceTauDecay_ == "none") return;
00240 
00241   // for documentation look at Tauola file tauola_photos_ini.f
00242   // COMMON block COMMON / TAUBRA / GAMPRT(30),JLIST(30),NCHAN
00243 
00244   if(forceTauDecay_ == "hadrons"){
00245     /* FIXME
00246     taubra.gamprt[0] = 0; // disable branchings to electrons in Tauola
00247     taubra.gamprt[1] = 0; // disable branchings to muons in Tauola
00248     */
00249   }
00250   else if(forceTauDecay_ == "1prong"){
00251     /* FIXME
00252     taubra.gamprt[0]  = 0; // disable branchings to electrons in Tauola
00253     taubra.gamprt[1]  = 0; // disable branchings to muons in Tauola
00254     taubra.gamprt[7]  = 0;
00255     taubra.gamprt[9]  = 0;
00256     taubra.gamprt[10] = 0;
00257     taubra.gamprt[11] = 0;
00258     taubra.gamprt[12] = 0;
00259     taubra.gamprt[13] = 0;
00260     taubra.gamprt[17] = 0;
00261     */
00262   }
00263   else if(forceTauDecay_ == "3prong"){
00264     /* FIXME
00265     taubra.gamprt[0]  = 0; // disable branchings to electrons in Tauola
00266     taubra.gamprt[1]  = 0; // disable branchings to muons in Tauola
00267     taubra.gamprt[2]  = 0;
00268     taubra.gamprt[3]  = 0;
00269     taubra.gamprt[4]  = 0;
00270     taubra.gamprt[5]  = 0;
00271     taubra.gamprt[6]  = 0;
00272     taubra.gamprt[8]  = 0;
00273     taubra.gamprt[14] = 0;
00274     taubra.gamprt[15] = 0;
00275     taubra.gamprt[16] = 0;
00276     taubra.gamprt[18] = 0;
00277     taubra.gamprt[19] = 0;
00278     taubra.gamprt[20] = 0;
00279     taubra.gamprt[21] = 0;
00280     */
00281   }
00282   else 
00283     edm::LogError("MuonReplacement") << "[ParticleReplacerAlgoParticleGun::forceTauoladecays] "
00284                                      << "Unknown value for forcing tau decays: " << forceTauDecay_ << std::endl;
00285 }
00286 
00287 void ParticleReplacerParticleGun::tauola_forParticleGun(int tau_idx, int pdg_id, const HepMC::FourVector& particle_momentum) {
00288   if(abs(pdg_id) != 15) {
00289     edm::LogError("MuonReplacement") << "[ParticleReplacerAlgoParticleGun::tauola_forParticleGuns] "
00290                                      << "Trying to decay something else than tau: pdg_id = " << pdg_id << std::endl;
00291     return;
00292   }
00293 
00294   // By default the index of tau+ is 3 and tau- is 4. The TAUOLA
00295   // routine takes internally care of finding the correct
00296   // position of the tau which is decayed. However, since we are
00297   // calling DEXAY routine directly by ourselves, we must set
00298   // the index manually by ourselves. Fortunately, this seems to
00299   // be simple.
00300   /* FIXME
00301   if(printout_)
00302     std::cout << " Tauola taupos common block: np1 " << taupos.np1 << " np2 " << taupos.np2 << std::endl;
00303   taupos.np1 = tau_idx;
00304   taupos.np2 = tau_idx;
00305   if(printout_)
00306     std::cout << " Resetting taupos common block to: np1 " << taupos.np1 << " np2 " << taupos.np2 << std::endl;
00307   */
00308 
00309   if(pdg_id == -15){ // tau+
00310 
00311     pol1_[2] = tauHelicity(pdg_id);
00312 
00313     /* FIXME
00314     momdec.p1[0] = particle_momentum.x();
00315     momdec.p1[1] = particle_momentum.y();
00316     momdec.p1[2] = particle_momentum.z();
00317     momdec.p1[3] = particle_momentum.e();
00318 
00319     momdec.p2[0] = -momdec.p1[0];
00320     momdec.p2[1] = -momdec.p1[1];
00321     momdec.p2[2] = -momdec.p1[2];
00322     momdec.p2[3] =  momdec.p1[3];
00323 
00324     // "mother" p4
00325     momdec.q1[0] = 0;
00326     momdec.q1[1] = 0;
00327     momdec.q1[2] = 0;
00328     momdec.q1[3] = momdec.p1[3] + momdec.p2[3];
00329 
00330     call_dexay(1,pol1);
00331     */
00332   }
00333   else if (pdg_id == 15){ // tau-
00334 
00335     pol2_[2] = tauHelicity(pdg_id);
00336 
00337     /* FIXME
00338     momdec.p2[0] = particle_momentum.x();
00339     momdec.p2[1] = particle_momentum.y();
00340     momdec.p2[2] = particle_momentum.z();
00341     momdec.p2[3] = particle_momentum.e();
00342 
00343     momdec.p1[0] = -momdec.p2[0];
00344     momdec.p1[1] = -momdec.p2[1];
00345     momdec.p1[2] = -momdec.p2[2];
00346     momdec.p1[3] =  momdec.p2[3];
00347 
00348     // "mother" p4
00349     momdec.q1[0] = 0;
00350     momdec.q1[1] = 0;
00351     momdec.q1[2] = 0;
00352     momdec.q1[3] = momdec.p1[3] + momdec.p2[3];
00353 
00354     call_dexay(2,pol2);
00355     */
00356   }
00357 }
00358 
00359 float ParticleReplacerParticleGun::tauHelicity(int pdg_id) {
00360   /* tau polarization summary from Tauola source code:
00361      in all cases      W : pol1 = -1, pol2 = -1 (tau or neutrino)
00362      H+: pol1 = +1, pol2 = +1 (tau or neutrino)
00363 
00364      if neutral higgs    : pol1 = +1, pol2 = -1 OR pol1 = -1, pol2 = +1 (tau tau)
00365      if Z or undetermined: pol1 = +1, pol2 = +1 OR pol1 = -1, pol2 = -1 (tau tau)
00366   */
00367 
00368   if(pdg_id < 0) { // tau+
00369     if(forceTauPlusHelicity_ != 0) {
00370       return forceTauPlusHelicity_;
00371     }
00372     if(forceTauPolarization_ == "W") return -1;
00373     if(forceTauPolarization_ == "H+") return 1;
00374     if(pol2_[2] != 0) {
00375       if(forceTauPolarization_ == "h" ||
00376          forceTauPolarization_ == "H" ||
00377          forceTauPolarization_ == "A") return -pol2_[2];
00378       else return pol2_[2];
00379     }
00380     else {
00381       return randomPolarization(); //all other cases random, when first tau
00382     }
00383   }
00384   else {           // tau-
00385     if(forceTauMinusHelicity_ != 0) {
00386       return forceTauMinusHelicity_;
00387     }
00388     if(forceTauPolarization_ == "W") return -1;
00389     if(forceTauPolarization_ == "H+") return 1;
00390     if(pol1_[2] != 0){
00391       if(forceTauPolarization_ == "h" ||
00392          forceTauPolarization_ == "H" ||
00393          forceTauPolarization_ == "A") return -pol1_[2];
00394       else return pol1_[2];
00395     }
00396     else {
00397       return randomPolarization(); //all other cases random, when first tau
00398     }
00399   }
00400 
00401   edm::LogError("MuonReplacement") << "[ParticleReplacerAlgoParticleGun::tauHelicity] "
00402                                    << "tauHelicity undetermined, returning 0" << std::endl;
00403   return 0;
00404 }
00405 
00406 float ParticleReplacerParticleGun::randomPolarization() {
00407   uint32_t randomNumber = rand();
00408   if(randomNumber%2 > 0.5) return 1; 
00409   return -1;
00410 }