/** * Example of use of tauola C++ interface. Pythia events are * generated with a stable tau. Taus are subsequently decay via * tauola. * * @author Nadia Davidson * @date 17 June 2008 */ #include "DebugParticle.h" #include "Log.h" #include "Tauola.h" #include "TauolaHepMCEvent.h" #include "TauolaParticlePair.h" //pythia header files #include "Pythia.h" #include "HepMCInterface.h" //MC-TESTER header files #include "Generate.h" #include "HepMCEvent.H" #include "Setup.H" #include "MC4Vector.H" #include using namespace std; using namespace Pythia8; bool initialized=false; // control variable for printouts of select method bool ShowersOn=false; int NumberOfEvents = 10000; double dot_product(MC4Vector v1, MC4Vector v2){ return v1.GetX1()*v2.GetX1()+v1.GetX2()*v2.GetX2()+v1.GetX3()*v2.GetX3(); } /** Recursive search for all daughters */ vector FindDaughters(HEPParticle *part,bool status=false) { vector ret; int id=part->GetPDGId(); HEPParticleList *list = part->GetDaughterList(NULL); HEPParticleListIterator da(*list); for(HEPParticle *d = da.first(); d!=0; d=da.next()) { if(d->GetPDGId()==id) { HEPParticleList *sub = d->GetDaughterList(NULL); HEPParticleListIterator subda(*sub); for(HEPParticle *sd = subda.first(); sd!=0; sd=subda.next()) list->push_back(sd); delete sub; } } for(HEPParticle *d = da.first(); d!=0; d=da.next()) { if(d->GetPDGId()==id) continue; if(status && d->GetStatus()!=1) continue; DebugParticle *x = new DebugParticle(d->GetPx(),d->GetPy(),d->GetPz(),d->GetE(),d->GetPDGId()); ret.push_back(x); } return ret; } /** Search for all mothers of given particle ignoring self-decays */ HEPParticleList* FindMothers(HEPParticle *part,HepMCEvent *evt,bool ignoreSelf) { int id = part->GetId(); HEPParticleList *ret = new HEPParticleList(); //Look throught whole event for(int i=1;iGetNumOfParticles();i++) { HEPParticle *p = evt->GetParticle(i); HEPParticleList *list = NULL; list = p->GetDaughterList(NULL); //Recursive search for daughters ignoring self-decays HEPParticleListIterator da(*list); if(ignoreSelf) for(HEPParticle *d = da.first(); d!=0; d=da.next()) { if(d->GetPDGId()==p->GetPDGId()) { HEPParticleList *sub = d->GetDaughterList(NULL); HEPParticleListIterator subda(*sub); for(HEPParticle *sd = subda.first(); sd!=0; sd=subda.next()) list->push_back(sd); delete sub; } } if(list->contains(id)) { if(ret->empty()) { ret->push_back(p); continue; } bool add=true; HEPParticleListIterator clean(*ret); for(HEPParticle *c = clean.first(); c!=0; c=clean.next()) if(c->GetPDGId()==p->GetPDGId()) add=false; if(add) ret->push_back(p); } delete list; } return ret; } bool select(HepMCEvent &temp_event,Pythia *pythia,HepMC::GenEvent *HepMCEvt){ // input parameters bool active=true; // Selection switch bool debug=true; double Csign= 1; // Sign of cos theta to be selected double Sqmin=10.; // Min Invariant mass of Z double Sqmax=394.; // Max Invariant mass of Z double IFlav=2; // Flavor of the beam // if(!active) {return true;}; if(!initialized){ cout<<" -------------------------------------"< tau gamma this is of course not necessary. " <GetPDGId(),idG1=mums->firstParticle->GetPDGId(); if(idTP==idG1) { tauPlus=mums->firstParticle; delete mums; mums = FindMothers(tauPlus,&temp_event,true); } HEPParticleList *mums2 = FindMothers(tauMinus,&temp_event,true); int idTM=tauMinus->GetPDGId(),idG2=mums2->firstParticle->GetPDGId(); if(idTM==idG2) { tauMinus=mums2->firstParticle; delete mums2; mums2 = FindMothers(tauMinus,&temp_event,true); } HEPParticleList *grandMums = FindMothers(mums->firstParticle,&temp_event,false); //Assuming only two grandmothers (it's easier that way but not necessary) HEPParticle *grand1 = grandMums->firstParticle; HEPParticle *grand2 = grandMums->lastParticle; vector daZ0 = FindDaughters(mums->firstParticle); vector daTP = FindDaughters(tauPlus); vector daTM = FindDaughters(tauMinus); //And so we get four particles: // cout<<"\n\nRESULTS:"<ls(); // tauMinus->ls(); // grand1->ls(); // grand2->ls(); /* MC4Vector QP=tauPlus->GetP4(); MC4Vector QM=tauMinus->GetP4(); MC4Vector PP=grand1->GetP4(); MC4Vector PM=grand2->GetP4(); MC4Vector QQ=QP+QM; double ss=sqrt(QQ.GetX0()*QQ.GetX0()-QQ.GetX1()*QQ.GetX1() -QQ.GetX2()*QQ.GetX2()-QQ.GetX3()*QQ.GetX3()); QQ.SetM(ss); QP.BoostP(QQ); QM.BoostP(QQ); PP.BoostP(QQ); PM.BoostP(QQ); double costheta1 = dot_product(QP,PP)/(QP.Length()*PP.Length()); if(grand1->GetPDGId()>0) costheta1 = -costheta1;*/ DebugParticle tP(tauPlus->GetPx(),tauPlus->GetPy(),tauPlus->GetPz(),tauPlus->GetE(),tauPlus->GetPDGId()); DebugParticle tM(tauMinus->GetPx(),tauMinus->GetPy(),tauMinus->GetPz(),tauMinus->GetE(),tauMinus->GetPDGId()); DebugParticle g1(grand1->GetPx(),grand1->GetPy(),grand1->GetPz(),grand1->GetE(),grand1->GetPDGId()); DebugParticle g2(grand2->GetPx(),grand2->GetPy(),grand2->GetPz(),grand2->GetE(),grand2->GetPDGId()); DebugParticle buff=tP+tM; DebugParticle tPL=tP; DebugParticle tML=tM; DebugParticle g1L=g1; DebugParticle g2L=g2; double ss = buff.GetM(); /* ZZ calculations not used at present, left for tests of physics algorithm options*/ /* HEPParticleList *doubleZ = grandMums->firstParticle->GetDaughterList(NULL); HEPParticle *sZ = doubleZ->firstParticle; if(sZ==mums->firstParticle) sZ = doubleZ->lastParticle; DebugParticle secondZ(sZ->GetPx(),sZ->GetPy(),sZ->GetPz(),sZ->GetE(),sZ->GetPDGId()); DebugParticle smallestV = secondZ.smallestVirtuality(g1,g1,g2,g2); // test is prepared for 4 particles cout<<"Second Z will be added to: "<0.0001); // rozne=(rozne || abs(cosTheta-costheta2)>0.0001); // rozne=(rozne || (abs(cosTheta-costheta1)>0.0001 && abs(cosTheta-costheta2)>0.0001) ); rozne=(rozne || abs(cosTheta-avg)>0.0001); rozne=(rozne || abs(sqrt(invariant_mass_squared)-ss)>0.0001*ss); if (rozne){ // temp_event.ls(); //Print whole event if needed to re-check // pythia->event.list(); // HepMCEvt->print(); cout<<" "<< endl; cout<<" there seem to be a difference in internal and testing Born level variables:"<1) //pre-set configs { pythia.readFile(argv[1]); // pythia.init( 11, -11, 500); //e+ e- collisions pythia.init( -2212, -2212, 14000.0); //proton proton collisions } else //default config { pythia.readString("WeakSingleBoson:ffbar2gmZ = on"); pythia.readString("23:onMode = off"); pythia.readString("23:onIfAny = 15"); //pythia.readString("23:onIfMatch = 15 -15"); pythia.init( 11, -11, 92.); //electron positron collisions } //Set up TAUOLA if(argc>4){ Tauola::setSameParticleDecayMode(atoi(argv[4])); Tauola::setOppositeParticleDecayMode(atoi(argv[4])); } if(argc>5){ Tauola::setHiggsScalarPseudoscalarMixingAngle(atof(argv[5])); Tauola::setHiggsScalarPseudoscalarPDG(25); } Tauola::initialize(); //Tauola::spin_correlation.setAll(false); MC_Initialize(); // Begin event loop. Generate event. for (int iEvent = 0; iEvent < NumberOfEvents; ++iEvent) { if(iEvent%10==0) Log::Info()<<"Event: "<decayTaus(); delete t_event; //run MC-TESTER on the event HepMCEvent temp_event(*HepMCEvt,false); bool selecto= select(temp_event,&pythia,HepMCEvt); if (selecto) MC_Analyze(&temp_event); //------------------------------------------------------------------------ //Filtering event record ends here --------------------------------------- //------------------------------------------------------------------------ //print some events at the end of the run if(iEvent>=NumberOfEvents-5){ Log::RedirectOutput(Log::Info()); pythia.event.list(); HepMCEvt->print(); Log::RevertOutput(); } //clean up HepMC event delete HepMCEvt; } Log::RedirectOutput(Log::Info()); pythia.statistics(); Log::RevertOutput(); MC_Finalize(); }